OmniAICreator/Qiita-1.07M huggingface dataset:
[メモ] 少人数グループへの一斉通知方法に関する調査

## この記事について

有名サービスのWebAPI活用についての調査メモ。

### 前提

以下の条件のとき、どのようなサービスを活用すれば効率が良いかを考える。

- 100人以下のグループに対して業務連絡を行う。
- スマートフォンユーザーが大半でガラケーユーザーもいる。
- 無料or少額で使えるサービスを使う

### 結論

- スマートフォンユーザーにはチャットサービス経由でスマホアプリにPush通知を送信する。
 - 基本Slack、もしくはChatWorkを使う。
- 一部のガラケーユーザーにはメールを送信する。
  - WebアプリSESやSendGridなどを想定
  
Push通知とメールの組み合わせで大体カバーができる。
どちらも少人数・通知目的で使うなら無料枠の範囲で収まる。

結構応答時間があるので、Webアプリで利用する場合は非同期処理での実装が望ましい。

以下、各サービスを使ってみたときのメモ。

## チャットサービス

### Slack

概要

- 世界的に勢いのあるビジネス向けグループチャットサービス。2017年11月に日本語に対応した。
- スマートフォンのアプリがある。投稿内容をPush通知で受け取ることができる。

WebAPI設定方法

- ワークスペース（≒組織アカウント）にアプリ（追加機能）をインストールすることで外部との連携が可能になる。
 - 「着信Webフック(incoming webhooks)」で投稿リクエストを受け、
 - 「発信Webフック(Outgoing Webhooks)」で投稿内容を外部サービスに通知する。

参考

- [公式：Slack での着信 WebHook の利用](https://get.slack.help/hc/ja/articles/115005265063)
- [SlackのIncoming Webhooksを使い倒す](https://qiita.com/ik-fib/items/b4a502d173a22b3947a0)
- [SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)
- [ずぶの素人がITでビジネスを作り上げるまで slackからメール送信する方法](https://itbiz.keorgia.com/2018/01/04/slack%E3%81%8B%E3%82%89%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
- [公式：Send data into Slack in real-time.](https://api.slack.com/custom-integrations/incoming-webhooks)

メモ

ChatWorkより以下の点で優れている。
- Push通知に投稿内容が表示される。
- 業務時間外の通知OFF設定をサービス側で調整できる。
- 対応するWeb自動連携サービス(IFTTT等)の種類が多い

### ChatWork

概要

- 日本発のチャットサービス。日本ではSlackよりユーザー数が多い。
- Slackより機能面が少ない分シンプルで使いやすいという評価がある。
- 日本のサービスなのでサポート面で安心
- チャット部屋のことを「チャット」と呼ぶ。

WebAPI設定方法

- 外部投稿用のアカウントを作成しチャットに招待する。
- ユーザーの設定メニューより「API」を選び、APIトークンを取得する。
- エンドポイントに対してトークンを使って投稿リクエストを送る。

参考

[公式：ChatWork API ドキュメント](http://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms-room_id-messages)

### Line

概要

- 説明不要の国内最大手チャットサービス。
- 特定メンバーのチャット機能は「グループ」と呼ぶ

設定作業

ここの通りに進めればOK
- [LINE Messaging APIでgroupIdを取得してPush APIでグループにメッセージを送る](https://qiita.com/kenichi_odo/items/18badf7c069334d9c3a2)
- グループIDの取得のためにGASを利用する。
[三十路街道　ボンバィエ GASでLINEのグループIDを確認する](https://cyuraharuto.com/gas-line-gid-get/)

メモ

一斉通知には広告用の機能を使うことになる。
アプリの性質を考えると、業務連絡で使うのは避けた方がいいと思う。

## SNS

### Twitter

概要

- 公的な情報公開をするときに使うことがあるかも

WebAPI設定作業

ここの通りに進めればOK
[PythonでTwitter API を利用していろいろ遊んでみる](https://qiita.com/bakira/items/00743d10ec42993f85eb)

認証処理が厳しくcurlコマンドで一発投稿というのはできない。何かしらのプログラムが必要となる。

## 電話・SMS・FAX

### Twilio

概要

- WebAPI経由で自動読み上げの電話を掛けたりSMSやFAXを送ったりできる
- サンプルコードを使えば割と簡単に実装できる。
- 海外のサービスから日本の電話への通知は不通や文字化けの問題があるが、TwilioならKDDIが代理店なので日本語サポートも安心。

参考

- [TwilioでSMSの送信方法。（初心者がつまずくポイント）](http://shared-blog.kddi-web.com/webinfo/131)
- [CloudWatchのアラームをTwilioで電話通知してみた](https://dev.classmethod.jp/cloud/aws/cloudwatch-twilio/)
- [TWILIO PYTHON ヘルパーライブラリー](https://jp.twilio.com/docs/libraries/python)
EC-CUBE4でインストールしてテストデータ作ってサーバを起動してくれるコマンドを作った

.zshrcに記述すれば使える。
DBへの接続情報とかは適宜変えて利用してください。

```zsh
function bc-eifr (){
    bin/console e:i --no-interaction
    bin/console e:f:g --products=1 --orders=1 --customers=1
    psql -h localhost -U postgres eccube -c "UPDATE dtb_customer SET email = 'hogehoge@example.com' where id = 1;"
    bin/console s:r --env=dev
}
```
Jupyter Notebook テーマのカスタマイズ

#はじめに

この記事では、Jupyter Notebookのテーマをカスタマイズする方法を紹介します。
# 準備
まずは、jupyterthemesをインストールします。

```:terminal

 pip install jupyterthemes 
```

#カスタマイズ
jupyterthemesをインストールして、準備ができたら以下を参照にJupyter notebookをカスタマイズしましょう。
https://github.com/dunovank/jupyter-themes

#自分の場合
自分が利用している環境についてです。
テーマは、目に優しいmonokaiを使っています。

```:terminal

jt -t monokai -T -N -ofs 11 -f inconsolata -tfs 11 -cellw 75%
```
### 各コマンドについて
| コマンド | 指定すること | 
|:-----------:|:------------:|
| -t | 大まかなテーマのデザインを指定します. (今回は「monokai」) |
| -T | ツールバーを表示するようにします.  |
| -N | ノートの名前を表示するようにする． | 
| -ofs | 実行結果の文字サイズを指定します. (今回は「11」) | 
| -f | フォントを指定します. (今回は「inconsolata」) | 
| -tfs | 実行結果のフォントサイズを指定します. (今回は「11」) | 
| -cellw | 画面横幅に対する, コードを書くスペースの大きさを指定します．(今回は「75%」) | 
###完成したテーマ
![スクリーンショット 2018-12-04 15.09.11.png](https://qiita-image-store.s3.amazonaws.com/0/257347/1e2a5bfe-87c7-ea6b-da4a-0ae63ed9b6d9.png)

#元に戻したいとき
```:terminal

jt -r
```
カスタマイズしたテーマをリセットしたいときは、上記のコマンドで元の白いデザインに戻せます。
laravel5.4のMiddlewareでユーザーエージェントによる振り分けを行う

##やりたいこと

ユーザーエージェントがSPだったらトップページへリダイレクトしたい

##コード

Middlewareの基本的な使い方は[こちら](https://readouble.com/laravel/5.4/ja/middleware.html)をご覧ください。

```app/Http/Middleware/SampleRedirect.php
    public function handle($request, Closure $next)
    {
        $ua = $_SERVER['HTTP_USER_AGENT'];
        //spの場合
        if((strpos($ua, 'Android') !== false) && (strpos($ua, 'Mobile') !== false) || (strpos($ua, 'iPhone') !== false) || (strpos($ua, 'Windows Phone') !== false)) {
            return redirect('/');
        }
        return $next($request);
    }
```
```app/Http/Kernel.php
    protected $routeMiddleware = [
        'sampleRedirect' => \App\Http\Middleware\SampleRedirect::class,
    ];
```
```web.php
Route::match(['get', 'post'], '/abcd/', 'sampleController@mainMethod')->middleware('sampleRedirect');
```

上記のように書いた場合、`/abcd/`にアクセスがあった際、`sampleController.phpのmainMethod`の処理をする前に`SampleRedirect.phpのhandle`の処理をします。
リダイレクトする条件以外の場合はそのまま`sampleController.phpのmainMethod`が処理されます。

Middlewareに書くことでルーティングファイルがすっきりし、汎用的に利用でき、リクエストが処理された後に何かしたいという場合にも使えるため、便利だと思います。
Amazon Linux(EC2)でシンプルにWordPressを構築する

# 概要
- apacheのデフォルトのドキュメントルート直下にWordPressを構築
- 下記コマンドを実行していくだけでできるようにした
- AmazonLinux2ではなく、AmazonLinux版
- rootユーザーで行う

# インストール

## ミドルウェアインストール
```
yum install httpd24 gd mysql-server wget -y
yum install -y php56 php56-mcrypt php56-mbstring php56-mysqlnd php56-devel
```
## PHP設定
```
cp /etc/php.ini /etc/php.ini.org
vi /etc/php.ini
------------------------------------
date.timezone = 'Asia/Tokyo'
------------------------------------
```

## mysql設定
```
/etc/init.d/mysqld start

chkconfig mysqld on

mysql -u root
mysql> create database wp;
Query OK, 1 row affected (0.04 sec)

mysql> grant all privileges on wp.* to wp@localhost identified by 'wp用の任意パスワード';
Query OK, 0 rows affected (0.06 sec)

mysqladmin -u root password '任意のルートパスワード'
```

## WordPressインストール
```
wget https://ja.wordpress.org/latest-ja.tar.gz

tar zxvf latest-ja.tar.gz

cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org

tar zxvf latest-ja.tar.gz
mv wordpress/* /var/www/html/
```

## apache設定
```
sudo cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
vi /etc/httpd/conf/httpd.conf
------------------------------------
<Directory "/var/www/html">
     AllowOverride All
------------------------------------
service httpd restart
chkconfig httpd on
```

## アクセスチェック
ブラウザで以下にアクセス

http://設定したIPアドレス

あとは画面の指示にしたがってインストールすれば立ち上がります。
【Laravel】リレーション先の検索方法


## Userのnameカラムで検索したい場合

`<input type="text" name="name">`
ここに記述したのが下の`$request->name`になる

```Post.php
public static function search(Request $request)
    {
        $query = self::query();
        if ($request->name) {
            $query->whereHas('user', function ($query) use ($request) {
                $query->where('name', 'like', "%{$request->name}%")
            });
        return $query->all();
    }
```
コントローラから呼び出します。


```PostController.php
public function index(Request $request)
    {
        return view('post.index', [
            'posts' => Post::search($request),
        ]);
    }
```
ビューで表示

```post/index.blade.php
@foreach ($posts as $post)
    {{ $post->title }}
@endforeach
```

formはgetメソッドで渡します。
こんな感じでできるはず。
SQL初心者が出会う7つの問題と解決策をまとめました

#まずは初心者になる
「SQLまったくわからないよ」という方は[この記事](https://qiita.com/okamuuu/items/c4efb7dc606d9efe4282)で手を動かしながら最速で入門できます。僕もこの記事を読んで初心者になることができました。感謝です。
MySQLとSQLのわかりやすい説明が欲しいよっていう方はこれらの記事がおすすめです。↓
[MySQL](https://wa3.i-3-i.info/word11774.html)
[SQL](https://wa3.i-3-i.info/word1217.html)
入門ができたらこの記事に戻ってきていただけると嬉しいです！！

#取得したテーブルが長すぎて折り返される
出力された表が長すぎて折り返され、超絶見にくいことがあります。
そういうときはpagerという機能を使います。といっても簡単でこのコマンドを打てば一発です。

```sql
mysql > pager less -S;
```

| -S | 画面幅より長い行を折り返さない |
|:--|:--|

という意味です。

「やっぱこのpagerいらねーわ」となったらこれを打ち込めば元に戻ります。

```sql
mysql > nopager;
```

#テーブル幅が長すぎる
「テーブル幅長くない?横スクロールもできないしどうしよ〜😭」
となった場合テーブルのカラム名だけ取得するという技が使えます。

カラム一覧を取得

```sql
mysql > describe テーブル名;
```
カラム名がわかればどこからデータを取ってくればいいかわかるのでこれで十分です。

#sqlファイルを書いて実行
SQL初心者のうちは

```sql
select * from database;
```
みたいなことしか書かないのでいいですがどんどんレベルが上がっていくにつれて6行、、、、10行と
書く量が増えてきます。そんな長いコードをいちいちコマンドラインから打ち込むのは面倒です。
そのようなときは拡張子が`.sql`のファイルを作ってコマンドラインから実行してあげます。こんな感じです。

```sql
mysql > source ファイルのパス;
```

例えば`/Users/kota/test.sql`にsqlのファイルがあった場合

```sql
mysql > source /Users/kota/test.sql;
```

こんな感じで実行します。
#「nullじゃない」という条件指定をしてデータを取りたいとき

usersテーブルからnullじゃないuser_idをとるというシチュエーションを考えます。
これでいいと思いきや、エラーがでます。

```sql
mysql > select user_id from users where user_id <> null;
```

なので`!=`ではなく`is not null`を使います。

```sql
mysql > select user_id from users where user_id is not null; 
```



#whereでの複数条件指定
普通にandでつなげていきます。
例えば「3月1日〜3月31日の間に登録」してて「user_idがnullじゃない」みたいデータを取りたい場合はこう書きます。`select`、`from`、`where`それぞれでインデントするとこなれ感が出せることもポイントです。

```sql:test.sql
select 
   user_id from users 
from 
   users
where 
   created_at between '2018-03-01 00:00:00' and '2018-03-31 23:59:59' and
   user_id is not null;
```


#変数を使いたい
同じ値を使う必要が出てきたとき変数が使いたくなります。SQLでも変数は使えます。
例えばさっき出てきた`'2018-03-01 00:00:00'`や`'2018-03-31 23:59:59'`を二回使いたい場合、
`'2018-03-01 00:00:00'`みたいなのを二回書くのは面倒なので`@startDate`という変数に入れることもできます。
3月に登録して3月に退会したみたいなユーザーのidを取りたいというようなシチュエーションを考えてみましょう。
退会日を`deleted_at`で表します。

```sql:test.sql
set @startDate = '2018-03-01 00:00:00';
set @endDate = '2018-03-31 23:59:59';

select 
   user_id from users 
where 
   created_at between @startDate and @endDate and
   deleted_at between @startDate and @endDate;
```
という感じです。スマートに見えますね。

#「30日以内」とかで絞ってデータを取りたい
そんなときは日付の引き算をやってくれる`datediff()`関数を使うとうまくできます。
例えば「3月1日にアカウントを作って3月31日までに退会したユーザー」を取りたい！
となった場合、退会日(`deleted_at`)から登録日(`created_at`)を引いた日数が30日未満であればいいので次のように書けます。

```sql
select 
    user_id
from 
    users
where 
    datediff(deleted_at, created_at) < 30
    and deleted_at is not null;
```


以上です！
またSQL初心者(僕)が問題に出会ったら追記していきたいと思います〜
間違いや意見がありましたら教えていただけると嬉しいです！🙂 


#参考文献
https://qiita.com/kandachime11/items/915bf3a515eaea431b4e
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html
GoogleAppEngineのapp.yamlの罠（と、思っているもの）

Google App Engine便利ですよね。
いかに利用者にインフラの負担をかけずサービスを運用させていかせるか、凄い考えられてると思います。
standard環境でpython3.7やphp7.2も将来的に使用できるようになりますし、今後にも期待できます。

ただ……たまに罠のような何かがあるんですよね。
こう、予期していなかったエラーというか、桶狭間でいうところの今川義元感というか。

# app.yaml

```yaml
runtime: python27
api_version: 1
threadsafe: yes
service: trap-service

handlers:
- url: (/|/(.+)/|/index\.html)
  script: main.app

- url: /(.+)
  static_files: dist/\1
  upload: dist\/(?!(index\.html))
  expiration: "15m"

skip_files:
- ^(?!(dist|main\.py|\.env)).*$
```

という訳で問題の発生したapp.yamlです。

- 「/」か、「foo/bar/」とかの末尾/系か、/index.htmlであればpythonを呼び出す
- それ以外であればdistフォルダからURLに応じたファイルを参照して返却する
- gaeにアップロードするのは、distフォルダとmain.pyと、.envファイルだけ！

という構成です。一見問題なさそうに見えます。
いや、自分も問題ないだろうと思っていました。
ここでエラーに気づける人は凄いと思います。

# エラー！！

```bash
gcloud app deploy --project foobar --version 1 app.yaml

ERROR: (gcloud.app.deploy) INVALID_ARGUMENT: The request is invalid.
- '@type': type.googleapis.com/google.rpc.BadRequest
  fieldViolations:
  - description: 'Value "dist\/(?!(index\.html))" must be a valid regular expression.
      Details: invalid or unsupported Perl syntax.'
    field: version.handlers[1].static_files.upload_path_regex
```

- **「?!」の正規表現は使えないというエラー……！！**
- **そして現れるperl syntaxのエラー**
- googleではperlを使っているのか……というちょっとした驚き

原因は書いてある通り、否定の正規表現「?!」が通らないというエラーでした:sob:

https://cloud.google.com/appengine/docs/standard/python/config/appref#syntax

> URL and file path patterns use POSIX extended regular expression syntax, excluding collating elements and collation classes. Back-references to grouped matches (e.g. \1) are supported, as are these Perl extensions: \w \W \s \S \d \D.

と書いてあるから仕方ない……

# だがしかし

**skip_filesでは?!の指定が使えるんですよね！**
ドキュメントには書いてある……けれども、skip_filesで使えるのであれば、urlでも使えると嬉しかった……:pensive:

# 最後に
[株式会社ネコカリ](https://www.nekokari.co.jp/)では猫の手も借りたい🔥炎上中🔥なお仕事を募集しています！
一緒に働くメンバーも募集していますので、よかったら是非！
（レポート）「価値を楽しむプロダクトデザイン 〜価値を獲得するための越境へのチャレンジ〜」参加メモ

- https://guildworks.doorkeeper.jp/events/76163

# 講演１「共創によるプロダクトデザイン」
- 市谷さん 0 → 1をたくさんやっている。
- 正しいものを正しくつくる
- ゴールデンサークル
    - whyから始めよ
- 仮説、エピック、ストーリー
    - 粒度と具体性のレベル分けや認識が出来ているかが大事
- わかってないことを分かるための旅が必要
    - 何が価値なのか
    - どうやって届けるのか
    - もっと届けるには
- 何が価値なのか
    - すでに代替手段はある状態で、代替手段に成り代るものであるのか。が重要
    - 提案にはその価値があるか
    - ユーザーインタビューなどを使って仮説の正しさを確認する
        - ユーザーインタビューの教科書
- どうやって届けるのか
    - チャネル
    - 現状どうやって解決のソリューションに出会って、使っているかを確認する
    - 傾向
        - 置かれている状況から自ずと取られる行動
- もっと届けるには
    - サービスの成長のためにどのような戦略を立てるか

- チームが1人の人間として動けることが理想である
    - 考える
    - 聴く
    - 見る
    - 話す
    - 手を使う
    - 移動する
        - クリティカル・メイキング

# 講演２「プロダクトの価値を描くことの意義とは」
- 匠メソッド
    - ビジネス企画　SDMと相性が良い
- 活動のデザインをすることをする
- 匠メソッドのなぜ
    1. なぜ、日本企業はビジネス慣習化た脱却出来ないのか
        - 計画主導のプロジェクトの弱点
            - 価値を見失う
                - インパクトのある要求を合意形成する
            - クリエイティブな課題に取り組めない
            - 人が育たない
        - 価値創造サイクル
            - 価値を描き、価値共感と価値検証を行う

    2.aaa
    3.bbb
    4.シーズ思考とニーズ思考による価値のデザイン
    5.プロダクトの真相価値をデザインする

# パネルディスカッション「価値のデザインとプロダクトデザインの勘所」
## 書籍のおすすめポイント
### 匠メソッド
- エンジニアの意識を変えてきた

### カイゼン・ジャーニー
- 読み手の立場によって、各章から読み進められる読んでいける

## ビジネス価値の検証を行っている中で大事にしている観点
- 市谷さん 
　　　　- 選択肢をすぼめていく　→　選択肢を広げていく
　　　　- 左が終わってから右があるように見えるが、左でもものは作る。
　　　　- １ヶ月半〜３ヶ月
        - （インタビューに時間がかかる）
        - キャンバスを埋める。顧客とやると２Hくらい。1人では30分くらい。
-　匠メソッド
　　　　- 左から右には２４hでやる。

## 筋の悪そうなアイディアはどうするか？
- 市谷
    - キャンバスで整合性が取れないようなもの。
    - 指摘はする。馬が合わない時には、お別れする
- 匠
    -
NLogでDotNetZipを組み合わせてアーカイブを圧縮する

# 環境
- C# 2017
- .NET Framework 3.5
- NLog 4.5.7
- DotNetZip 1.11.0

# 経緯
昔作られていた自前のログ出力の仕組みを刷新してNLogを利用することにした。
ファイルローテートされ、そのアーカイブは圧縮してほしかった。
.NET Frameworkは3.5でなければならない。

# .NET 3.5 だと素直に圧縮できない
調べたら、NLogのenableArchiveFileCompressionを指定すれば圧縮できると思ったけど、よくよく調べたら[説明](https://github.com/nlog/NLog/wiki/File-target)のenableArchiveFileCompressionにこんな記述が・・・！！
> Supported in:
> NLog v4.0 for .NET 4.5

散々調べてたら、たまたまIFileCompressorなるインターフェースを見つけた。
[APIのIFileCompressor Interface](http://nlog-project.org/documentation/v4.5.0/html/T_NLog_Targets_IFileCompressor.htm)を見たら、どうもenableArchiveFileCompressionによって圧縮動作をしようとした時に動作するインターフェースっぽい予感。

そこで、DotNetZipを組み合わせて、このインターフェースのCompressFile()メソッド内でやればできるんじゃないかと思ってやったら出来た。

# DotNetZipを組み合わせる
- ローテートするファイル名をzipとする。
- FileTarget.FileCompressorに、ZipFileCompressorを指定する。
- ZipFileCompressorで、DotNetZipを利用してローテートされたファイルを圧縮する。

これをやったらできた。

```xml:NLog.config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

  <targets>
    <target xsi:type="File"
            name="file"
            fileName="${basedir}/logs/${var:bhtid}_${shortdate}.log"
            layout="${longdate} [${uppercase:${level}}] ${message}"
            archiveFileName="${basedir}/logs/archives/archive_rolling.{#}.zip"
            archiveEvery="Day"
            archiveAboveSize="200"
            archiveNumbering="Rolling"
            maxArchiveFiles="7"
            enableArchiveFileCompression="true" />
  </targets>

  <rules>
    <logger name="*" minlevel="Debug" writeTo="file" />
  </rules>
</nlog>
```

```C#:ZipFileCompressor.cs
internal class ZipFileCompressor : IFileCompressor
{
    internal ZipFileCompressor() { }

    public void CompressFile(string fileName, string archiveFileName)
    {
        var zip = new Ionic.Zip.ZipFile(Encoding.UTF8);
        var entry = zip.AddFile(fileName);
        entry.FileName = Path.GetFileName(fileName);
        zip.Save(archiveFileName);
    }
}
```

```C#:Test.cs
var logger = NLog.LogManager.GetCurrentClassLogger();
NLog.Targets.FileTarget.FileCompressor = new ZipFileCompressor();

logger.Info("これはテストです。" + DateTime.Now.ToLongTimeString());
```
Shell | 複数のキーワードが含まれるファイルを grep で一斉検索する ( find + xargs + grep )

# 課題

`first_text` と `second_text` の両方が含まれるファイルを一斉検索したい。

# 検証

両方のキーワードが含まれるものを用意する

```example1.txt
first_text
second_text
```

片方のキーワードしか含まれないものを用意する


```example2.txt
first_text
```

```example3.txt
second_text
```

# コマンド

```
$ find ./ -name "*.txt" | xargs -I %FILE% sh -c 'grep first_text >/dev/null "%FILE%" && grep second_text >/dev/null "%FILE%" && echo "%FILE%"'
```

---

- `find` で見つかったファイル名を `xargs` で `sh` に渡している
- grep の標準出力は捨てて、 `true` / `false` の判定だけをしている

# 結果

両方のキーワードが含まれる `example1.txt` だけが HIT した。

```
./example1.txt
```

# 環境

- Ubuntu 16.04.2 LTS (Xenial Xerus)
- Docker version 18.03.1-ce, build 9ee9f40

# Gist

- https://gist.github.com/YumaInaura/57cbca6355de53f5a1cfa85928dc960a








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[関数系] php.iniで設定できる内容 (set_include_path, ini_set)

# 概要

php.iniでできる内容を把握しておかないとphp.ini以外で余計な設定をしてしまうというリスクがある。そのため、その内容をまとめておく。


# php.iniとは

そもそもの話だが、php.iniとはphpの設定を一手に担うファイルのことである。

# どこにあるのか

基本的には「/etc/php.ini」となっているが、設定することもできるので場合によっては違うことも疑う必要がある。


```探す用のコマンド
php -r "echo phpinfo();" | grep "php.ini"
```


# いつ読み込まれるのか

これはCGI版とmodule版でおそらく(まだ確かめてないのでそのうち更新)違う。

## module版

これはApacheが起動したタイミング。であるため、
後述のとおり、php.iniが変更されるたびにApacheの再起動が必要となる。

## CGI版

CGI 版と CLI 版では、スクリプトが呼び出される度に読み込まれる。
これは[公式](http://php.net/manual/ja/configuration.file.php)にも書いてある。

# CGI版とmodule版で違いはあるのか

またモジュール版のメリットとして、WebサーバーのプロセスでPHPが実行されるため、CGI版に比べて動作速度が高速になるという点がある。

# 何を設定できるのか

### エラー表示の設定を変更

* error_reportingの設定を変更(513行目あたり)
	error_reporting = E_ALL | E_STRICT (開発環境においてはSTRICTを含めたすべてのレポートをさせる)

* display_errorsの設定を変更(530行目あたり)
	display_errors = On	(エラーがあった際にブラウザなどにエラー内容を表示するように設定）

* log_errorsの設定を変更(551行目あたり)
	log_errors = On	（エラーログを吐く設定を有効にしておく）

* error_logの設定を変更(636行目あたり)
	error_log = /var/log/php.log(phpに関連するエラーログを/var/log/php.logに吐くように設定)


### 文字コード関連の設定

* default_charset = "UTF-8"
* mbstring.language = Japanese
* mbstring.internal_encoding = UTF-8
* mbstring.encoding_translation = Off
* mbstring.http_input = pass
* mbstring.http_output = pass
* mbstring.detect_order = auto


### メモリ管理に関する設定

* memory_limit = 32MB  
PHPの1プロセスが利用可能なメモリー容量の設定。
* post_max_size = 16M
POSTのリクエストを受け付ける際の、最大のPOSTリクエストサイズを設定
* upload_max_filesize = 8M
ファイルアップロードを受け付ける際の、最大のファイル受付サイズを設定


### セキュリティに関する設定

* expose_php = Off  
これがOnだとレスポンスヘッダにPHPのバージョン情報などが露呈してしまう
* session.hash_function = 1  
セッションID発行のハッシュアルゴリズムをSHA-1(160bit)へ変更, 0だとMD5(128bit)。生成されたハッシュを32桁にしたい場合は、併せてsession.hash_bits_per_character = 5とする
* session.entropy_file = /dev/urandom  
  /dev/urandomが存在するときのみ
* session.entropy_length = 32


### その他の設定

* short_open_tag = Off  
PHPファイルのタグを<?php ?>のみ利用可能と制限(<? ?>などを使用不可にする)
* register_argc_argv = On  
バッチのようなコマンドラインプログラムを書く場合は必須の設定
* max_execution_time = 30  
PHPプログラムの１つの最大実行時間の設定。これも大きなファイルアップロードや大きいバッチ処理がある場合はプログラム側のini_set()などで随時設定する


## 変更した設定を読み込み

## module版

php.iniでの設定はApacheを再起動することによって再読込されるので、Apacheを再起動します。

> service httpd restart

## CGI版

CGI 版と CLI 版では、スクリプトが呼び出される度に読み込まれるため、もう一度スクリプトが呼び出すだけで良い。これは[公式](http://php.net/manual/ja/configuration.file.php)にも書いてある。


## パスを複数設定したい場合


```
.:/usr/dir/dir2/dir3.:/usr/dir_a/dir_b/dir_b 
```

上記のように「:」(コロン)で区切って記述する。

# ソースコードにおける設定内容

　set_include_pathメソッドかini_setメソッドを利用することでソースコードからもinclude_pathを設定することができる。

## set_include_path

```php:set_include_pathの例
string set_include_path ( string $new_include_path )
```

成功した場合には追加したinclude_pathの値
失敗した場合にはFALSEを返す

## ini_set

```php:ini_setの例
ini_set('include_path', '/usr/lib/pear');
```

## まとめ
上記でPHPをインストールし、開発環境として利用する上での最小限の設定は完了です。
詳細な設定内容についてはより調べていただくか、[『パーフェクトPHP』](http://www.amazon.co.jp/gp/product/4774144371?ie=UTF8&camp=1207&creative=8411&creativeASIN=4774144371&linkCode=shr&tag=knife0125-22)の12章などに詳しいので、参考にしてみてください。
pythonのjsonライブラリの扱い

pythonのjsonライブラリがたまに使い方を間違えてJSONDecodeErrorになりがちなのでメモ

# dictからjson文字列
dictで定義したものをそのままjsonとして使いたい場合

```python
import json
sample_dict = {'test_key': 'test_val'}
json.dumps(sample_dict)
```
# json文字列からdict
```python
import json
sample_json_str = '{"test_key": "test_val"}'
json.loads(sample_json_str)
```

# ファイルからdict
```python
import json
with open('test.json', 'r') as f:
    data = json.load(f)
```

# pandas.dataFrameからjson文字列
```python
import pandas as pd
df = pd.DataFrame({'col1': [1, 2, 3], 'col2': [4, 5, 6]})
json_str = df.to_json()
```

出力は

```python
{"col1":{"0":1,"1":2,"2":3},"col2":{"0":4,"1":5,"2":6}}
```
なぜかindexも介入している...


一行ずつ読ませていくと

```python
for index, d in df.iterrows():
    print(d.to_json())
```
出力は

```python
{"col1":1,"col2":4}
{"col1":2,"col2":5}
{"col1":3,"col2":6}
```
このようにindexは介入しない
LU分解でC言語

#連立方程式をLU分解で解いたのでC言語のソースだけ貼っておく

```cpp
#include<iostream>
#include<stdio.h>
#define N 3
/*
2 5 7 4
4 13 20 11
8 29 50 29
*/
using namespace std;
int main(){
    double mat[N][N+1]={{2,5,7,4},{4,13,20,11},{8,29,50,29}};//元々の拡大係数行列
    double mat_l[N][N]={{0,},{0,}}; //L
    double mat_u[N][N]={{0,},{0,}};//U
    double pivot = 0.0,tmp=0.0;    
    double fl[N]={4,11,29};//拡大係数成分格納 
    double u[N]={0,};//行列uの解
    double l[N]={0,};//最終解
    int i=0,j=0;//カウント変数
    for(int i=0;i<N;i++)//Lを単位行列にする
        mat_l[i][i]=1;

    
    for( i = 0; i < N; i++){
        for( j = 0; j < N; j++){
            mat_u[i][j]=mat[i][j];//行列コピー
        }
    }
    
    for(i = 0; i < N ; i++){
        pivot=mat_u[i][i];//pivotを取り出す
        for(j=i+1;j<N;j++){
            tmp=mat_u[j][i];//被掃き出し行のpivot列の成分を取り出してtmpに代入
            for(int k=0; k < N ;k++){
                mat_u[j][k] = mat_u[j][k] - (tmp/pivot)*mat_u[i][k];//行列Uを掃き出し法で上三角行列にする
             }
                mat_l[j][i]=tmp/pivot;//行列Lの被掃き出し行,pivot列の成分にtmpをpivotで割ったものを代入すると
                                     //なぜかちゃんとLU分解の行列Lになる
        }
    }    
    u[0]=mat_l[0][0]*fl[0];

    for(i=1;i<N;i++){
        u[i]=fl[i];//拡大係数成分を代入
        for(j=0;j<i;j++){ 
         u[i]=u[i]-mat_l[i][j]*u[j];//行列Lの解を求める(代入法）
        }
    
    }

    l[N-1]=mat_u[N-1][N-1]/u[N-1];//zを求める（N*N+1)拡大係数行列なら最終行の変数の解

    for(i=N-2;i >= 0 ;i--){
        l[i]=u[i];
        for(j=N-1; j > i;j-- ){
            
           l[i]=l[i] - mat_u[i][j]*l[j];
        }
        l[i]=l[i]/mat_u[i][i];
    }

  

  for( i = 0; i < 3; i++)
  {
      cout << l[i] << endl;
  }
    
return 0;
}
```

クッソ適当です
python3にpipがインストールされてないし、できなくてハマってる人へ

# こんな人向けの内容です

1. デフォルトで用意されているはずのpython3.4以降でpipがない
2. じゃあpipダウンロードしよう、けどインストールができない

以下「起きたこと」で悩んでいる人には、助けになるかな。と思います
※vagrant, centos7で実施しました。

# 起きたこと

**上記①のパターン**

```
$ python3 -m pip list
/usr/bin/python3: No module named pip
```

**上記②のパターン**

```
$ sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ sudo python3 get-pip.py 
Traceback (most recent call last):
  File "get-pip.py", line 20651, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
zipimport.ZipImportError: can't decompress data; zlib not available
```

もしくは、

```
$ sudo python3 get-pip.py
Traceback (most recent call last):
  File "get-pip.py", line 20651, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmpfmhu0bvn/pip.zip/pip/_internal/__init__.py", line 42, in <module>
  File "/tmp/tmpfmhu0bvn/pip.zip/pip/_internal/cmdoptions.py", line 16, in <module>
  File "/tmp/tmpfmhu0bvn/pip.zip/pip/_internal/index.py", line 24, in <module>
  File "/tmp/tmpfmhu0bvn/pip.zip/pip/_internal/download.py", line 38, in <module>
  File "/tmp/tmpfmhu0bvn/pip.zip/pip/_internal/utils/glibc.py", line 3, in <module>
  File "/usr/local/lib/python3.7/ctypes/__init__.py", line 7, in <module>
    from _ctypes import Union, Structure, Array
ModuleNotFoundError: No module named '_ctypes'
```

# 解決策

`python3`より、`zlib-devel`と`libffi-devel`をインストールしておく

```
$ sudo yum install -y zlib-devel
$ sudo yum install -y libffi-devel

## これを実行してからpython3をインストール
## すでにに実施してたら、もう一回やる（もちろん、wget、tar解凍は不要です）
$ sudo wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
$ sudo tar xvzf Python-3.7.0.tgz
$ cd Python-3.7.0/
$ sudo ./configure
$ sudo make altinstall
```

思ったより、ハマってしまった。。。
ご注文は選択することですか？

cdコマンド改造記事第4回です。
前回の記事：[ご注文は親ディレクトリに戻ることですか？](https://qiita.com/Riliumph/items/48f7e84211db188048f8)

また、cdコマンドに手を入れていきます。

今回は、Simplistic interactive filtering toolの[Peco](https://github.com/peco/peco)を使っていきます。

# 第４羽「pecoをするお話」
何番煎じか分かりませんが、pecoという選択ツールを導入して使っていこうと思います。
fzfとかもあるので、シェル変数とか環境変数にして色んなツールを選択できるように汎用的にしていけたらいいですね。（その予定はないですけど）

# pecoの導入
[リポジトリ通り](https://github.com/peco/peco)にいれてください。
普通に、[リリースページ](https://github.com/peco/peco/releases)からバイナリ落としてPATHに入れるだけです。

# なにをpecoるのか？
まず、サンプルとして一番記事の多いコマンド履歴をpecoってみましょう。

仕様はテキトーな感じでいいよね。
- 新しい履歴が上に来ること
- 同じ履歴は最近のモノだけでいいこと（重複して表示しない）


```bash:bashrc
peco_history()
{
  local descending_order
  if which sort &> /dev/null; then
    descending_order='sort -r'
  elif which tac &> /dev/null; then
    descending_order='tac'
  else
    descending_order='tail -r'
  fi
  local trim_line_number='sed -re "s/^\s+[0-9]+\s+//"'
  local trim_duplication='awk '\''!dictionaty[$0]++'\'''
  local CMD=$(\history \
              | eval $descending_order \
              | eval $trim_line_number \
              | eval $trim_duplication \
              | peco --query "${READLINE_LINE}")
  READLINE_LINE="${CMD}"  # Input to terminal's readline
  READLINE_POINT=${#CMD}  # Set cursor
}

bind -x '"\C-r": peco_history'
```

## スクリプト解説
まず、このスクリプトは処理したいことをコマンドで示し、それをローカル変数に格納するスタイルを取っています。

でないと、アホの私は土日を過ぎると「このコマンドは何を実現したいんだ……？」となってしまうからです。

- **descending_order**  
新しい履歴を上に持ってくる仕様を満たすために、降順に並び替える処理を担当しています。
どれもこれもbashのビルトインじゃなかったので持ってるかどうかを調べています。  
とりあえず3つも調べたらどれかは持ってるでしょ(´･_･`)tacはMacではダメとかなんとか
- **trim_line_number**  
今回は履歴の取得にhistoryコマンドをビルトイン実行しているのですが、履歴番号を付与してしまうのでそれを取り除きます。
- **trim_duplication**  
履歴表示は重複させない仕様を満たすため、<font color="red">辞書式配列を作ること</font>で実現しています。  
awkでこんなの考えた人天才ですね

これらは変数に格納されるので、所定の順番にevalコマンドで実行して最後にpecoへパイプします。

- --queryオプション  
pecoのqueryオプションは初期QUERYとして文字列を渡すようです。  
既に入力されている文字列を渡すことで、入力途中で実行すると<font color="red">最初からその文字列で絞込ませておく</font>ことができます。

最後にterminalへ反映させるために変数に結果を格納します。

- **READLINE_LINE**  
terminalへ入力されている文字列をpecoで選択した結果に置き換えます。  
pecoで複数選択した場合のケア？知らねー
- **READLINE_POINT**  
terminalのカーソルの位置を文字列の最後にしています。  
変数に#をつけると、変数展開が行われて文字列を取得することができます。  
参考：[【シェル芸人への道】Bashの変数展開と真摯に向き合う](https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51
)

最後は、これをデフォルトでは履歴検索を担当しているショートカットキーをbindコマンドで上書きして終わりです。

# 最後
こんな感じで使えます。
結構便利ですね。

![peco_history.gif](https://qiita-image-store.s3.amazonaws.com/0/54925/03fe715c-7f98-b46b-2f7e-24b2b923f5c4.gif)

git logをパースするとか色々しておくと便利かもしれませんね。
もうちょっと、このpecoを使っていきたいと思います。

というか、コマンド名タイポしたときに、 
**その間違えたコマンドを履歴に書き込まない方法**とかありませんかね？(´･_･`)ﾀﾞﾚｶｰ
HTMLの基礎構造

#はじめに
この記事はProgate（プログラミング学習サービス）を使ってHTMLについて学習した内容を忘れないように逐一書き留めたものです。なので、ところどころ間違ってる可能性があるので、参考程度にとどめていただけると幸いです。

###目次
1．HTMLの骨組み
2．head要素
3．body要素


##1．HTMLの骨組み
ここではHTMLの構造について簡単に説明します。下に載せたコードが最も簡単な形のHTMLの構造です。

```html
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
  </body>
</html>
```
一行目の<font color="DeepPink"><!DOCTYPE html></font>は単にHTMLのバージョンを宣言するためのものです。もう何も考えずに機械的に書いちゃいましょう。

##2．head要素
次に続く<font color="DeepPink">\<head></font>要素内には、Webページの設定に関する情報を書いていきます。
具体的には

- 文字コードの情報 
- ページのタイトル情報
- cssの読み込み情報

などです。これらの情報は以下のような定型文を<font color="DeepPink">\<head></font>要素内に記述することで設定できます。


1. 文字コード情報の設定　  <<font color="DeepPink">meta <font color="Blue">charset = </font>  <font color="LightSeaGreen">"文字コード名"</font></font>>
2.   ページのタイトル情報　　 \<<font color="DeepPink">title</font>> タイトル名\</<font color="DeepPink">title</font>>
3. css読み込み情報      　　　　   <<font color="DeepPink">link</font> <font color="Blue">rel = </font> <font color="LightSeaGreen"> "stylesheet"</font>  <font color="Blue">href = </font>  <font color="LightSeaGreen">"cssファイル名"</font>>


実際の具体例でいうと下の感じです。


```html
<html>
  <head>
    <meta charset ="utf-8">
    <title>Progate</title>
    <link rel ="stylesheet" href ="stylesheet.css">
  </head>
  <body>
  </body>
</html>
```

ちなみに"タイトル"というのは、下の画像のようにブラウザのタイトルバーに表示される名前のことです。

<div align="center">
<img src=https://s3-ap-northeast-1.amazonaws.com/mash-jp/staging/uploads/3401/8528868d085074d2d1fee5a720343246672dccf5.3498.original.png?1488165254　width=50%>
</div>

\<head>要素は基本的にこの3つの要素だけ書いておけば大丈夫かと思います。

##3．body要素
先に述べた\<head>要素内での記述がWebページに表示されないのに対して、\<body>要素内での記述はダイレクトにWebページに表示されます。\<head>要素に比べると、書くことも多くなり、難しいです。
では順を追って見ていきましょう。

まず初めに、多くのホームページは大きく**”ヘッダー”**、**”メイン”**、**”フッター”**の3パートに分けることができます。下の図のヘッダーとフッターの間の領域はメインと呼ばれます。

<div align = "center">
<img src = "https://www.pc-master.jp/words/image/header2.jpg"　"ヘッダー、フッターのイメージ図">
</div>  

- ヘッダー　:　どのページが開かれても常に共通して表示される上の部分
- メイン　　:  　主なコンテンツが含まれる
- フッター　:  　ホームページ一番下の部分　「会社概要」などを書いてたりする。

この3つのパートはそれぞれ違う背景色であったり、文字の大きさを使ったり、異なった設定を用いることが多くなります。そのため、\<body>要素はあらかじめ3パートに分けておくとよい。分け方は以下のとおりです。

```html
<body>
    <div class ="header">
    </div>
    <div class ="main">
    </div>
    <div class ="footer">
    </div>  
  </body>
```

ここで用いられた\<div>はdivision(分割)からきています。その名の通り、ここでは\<body>要素を3つのパートに分割するために使われています。<font color="DeepPink">class</font>というのはわかりやすいようにそれぞれのパートにつけたパート名と思って問題ないと思います。

##4．終わりに
今回は本当に基礎的なHTMLの構造についてだけ説明をしてみました。
次回以降CSSやより細かなHTMLの書き方について説明をしていきたいと思います。
私も勉強を始めたばかりなので、初心者のみなさん一緒に頑張っていきましょう:）
プロジェクトを円滑にすすめたい

とおい過去にこんばことを考えていたらしい

プロジェクトを円滑にすすめるには何より情報の透明性が必要だと思う
やること、やりたいこと、やりたくないこと、できないことなどが個人レベルまで共有できれば上手くいきそう！

そこでどうやって意思統一、考え方の共有をするのが良いか考えてみた。
成果物へのFBを確実に実施することが一番の近道だと感じる。

人は自分のやったことに対しての賞賛、批判ならどちらも受け止めてくれる。

そこで考えを伝えたり、聞いたりすることで自然と個人レベルまでの情報共有が出来てくると思う。
あとは2週間～1ヵ月くらいでチーム内振返を実施すればチーム全体で話合ができる。
これもある意味成果物へのFBになるかと

FB、振返で意識したいのはKPT(Keep, Problem, Try)

継続（良いとこ）、問題（悪いとこ）、改善（やること）をしっかり話合、チーム文化を作っていけばプロジェクト上手くまわりそう

アジャイルの考えはやっぱ素晴らしい．．．

http://suea.hatenablog.com/entry/2015/02/20/051014
仕事しないでプログラミングを覚えれる？

とおい過去にこんなこと考えてたみたい．．．

とても厳しい道だと思われる
趣味でプログラミングが出来る人ならいけるかもです．．．

時間、情報、確認の差が仕事、自学習だと歴然としていると思いました

- 時間：1ヶ月で160Hを確保
- 情報：周りを見渡せばサンプルソース、有識者、Tipsがいっぱい
- 確認：進捗チェック、成果物へのフィードバック

仕事の環境を考えると学習するうえですごい恵まれていることが分かります
自学習するならこんな感じですか．．．相当がんばらないとです．．．

- 時間：薄く長く根気よく、継続は力なり
- 情報：ネット検索、書籍購入、コミュニティ、研修への参加
- 確認：自分も情報発信、転職系サイトのコードチェック


http://suea.hatenablog.com/entry/2014/12/12/132557
[Docker-Toolbox]npm install, yarn installに失敗する

# エラー
```console
npm ERR! EPROTO: protocol error, symlink ...
```
```console
error An unexpected error occurred: "EPROTO: protocol error, symlink ...
```
詳しくはわからないけれど、どうやら共有フォルダの権限の関係でシンボリックリンクの生成でエラーが出ているようでした。


# 対処
- Docker quick start terminal を管理者権限で起動する
- install 時に --no-bin-links オプションをつける  

#  Docker quick start terminal を管理者権限で起動する
正確には仮想マシンを管理者権限で立ち上げることにより、共有フォルダ内で正常にシンボリックリンクがはれてインストールが成功するようです。

ここでよくあるミスとしては、一度 Docker quick start terminal を立ち上げたあとでウィンドウを閉じ、管理者権限で再び開こうとしても起動時にエラーが起きてしまいます。
ウィンドウを閉じるだけでなく、きちんと仮想マシンを終了させないと、Docker quick start terminal が自動で立ち上げる default という仮想マシンが存在し続けているために競合して新しくマシンを立てられません。
そのため `$ docker-machine stop` コマンドを打ってマシンを止めてから管理者権限で Docker quick start terminal を立ち上げなおしましょう。仮想マシン側の操作で行ってもよいです。

Docker-Toolboxは仕組み上この手のエラーで詰まりやすい気がするので、これ以降私は常に管理者モードで起動するようにしています。

>余談：
いつも docker を使った後はシャットダウン時に「強制的に終了」させないと電源を切れずに「あまりよくないなぁ」と思っていましたが、終了時にきちんと `$ docker-machine stop` することによってプロセスが起動中だと怒られなくなりました。知らなかったの私だけ…？

# install 時に --no-bin-links オプションをつける
```
$ npm install --no-bin-links
```
ググるとまず第一にこれを勧められます。
シンボリックリンクの作成をしないよう指定するオプションらしいです。
さしあたりこれで解決する場合も多いですが、後々ファイルのパスが通らなかったりといった不具合につながることがあるので、個人的には先に前者を試してみることをお勧めします。
私の場合、 `npm install` ではこれでうまくいきましたが、これが原因でconfigファイルのパスを指定しなおさないと他のエラーで引っ掛かりました。 `yarn install` では `--no-bin-link` オプションをつけてもinstallが成功せず、前者は問題なく通りました。

# おわりに
場当たり的な対処法の紹介ですので、誤りがありましたら是非指摘をお願いします。
OneNote (iPad版)で作成したノートがmacOS版で同期されない（Error code: 0xE00009C8 bb0ur）ときの解決法

<h1>概要</h1>
iPad版のOneNoteで作成したセクションをMac上のOneNoteで同期しようとしても、
<ul>
<li>Error code: 0xE00009C8 bb0urによって同期できない<img width="463" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/273403/c7d449b8-341d-ce3c-39ca-13ce5d9b94b2.png"></li>
<li>OneNote Onlineではきちんと表示されている</li>
<li>OneNoteの再起動や再インストール、Microsoft accountからのログアウト・再ログインなどを一通り試したけど治らない</li>
</ul>
ときの解決法。実験ノートをiPad Pro＆OneNoteに移行しようとした矢先にこの問題に遭遇したが、下記の方法で解決できたので、まとめておく。
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_onenote-mso_mac-mso_mac2016/error-code-0xe00009c8-bb0ur/160dfc39-394b-4ce6-8fb1-06540a1b7c6e

<h1>解決法</h1>
<ul>
<li>Mac上のOneNoteアプリを閉じる</li>
<li>OneNote Onlineで問題のセクションを開く</li>
<li>下記の「OneNoteで開く」をクリック</li>
<img width="463" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/273403/eee8d009-ce38-f6a0-660b-e19bfc7bc56b.png">
<li>きちんと開けた</li>
</ul>

セクションごとにこの作業を行わないといけないが、一度この作業を行えばそのセクション内の同期はうまくいく模様。
Raspberry Pi で systemd を使ってプログラムを自動実行する

ラズパイのプログラムを、起動時や定刻に自動実行したい。
cronとかもあるが比較的新しくてイケてるらしいので、systemdとやらを使ってみようと思う。

脱コピペの思いで唸りながら理解したので、同じく脱コピペしたい初心者の同志に向けて書いた。

※20190312 sounisi5011さんより指摘を受け、プログラムの置き場所に関する項目を修正
※↑のついでに日本語の表現をちょこちょこ修正。

#筆者
- 非プログラマ
- プログラミングにはpythonで入門して、ちまちまラズパイで遊んでる
- 間違ってたらグサグサ教えて下さい

#systemdとは
プロセスの起動を管理するソフトウェア。ユニットと呼ばれる単位で処理が行われ、並列処理だったり、ユニット同士の依存関係を定義できるところがすごいらしい。

単にスケジューリングがしたかったらcron等の方がお手軽だが、これからはsystemdの時代が来るらしいのでsysytemdを使い倒して行きたい。

そんなsystemdだが、たくさん機能を備えているのは置いておいて、なるべく最小限の記述する。
仕組みを理解するにはよくわからんままコピペするよりその方が良いと思うから。
#ラズパイ起動時のプログラム自動実行

1. serviceファイルを作成
2. serviceファイルをenable

大きく言えばたったこれだけです。まず定義ファイルを作って、次に登録するイメージ。

それでは具体的に行きましょう。

##1. service ファイルを作成
###手順
`.service` ファイルは`/etc/systemd/system`に作ります。

```
$ sudo nano /etc/systemd/system/a.service
```
たとえば`a.py`を起動時に自動実行したいとすれば、こんな感じ。

```a.service
[Unit]
Description=do something

[Service]
ExecStart=/usr/bin/python /home/pi/systemd/a.py

[Install]
WantedBy=multi-user.target
```
###解説

####[unit]
ユニット自体の定義をします。
このセクションでは、セットで起動したいユニットなどが指定できます。
Descriptionは動作に影響しませんが、しっかりわかりやすく記述しましょう。

####[service]
ユニットにどんな仕事をさせるかを記述します。
実行したい処理をExecStartに記述しましょう。
ここではpythonで`/home/pi/systemd/a.py`を実行させています。
他にも、失敗時の再起動の設定などができます。

####[install]
サービスの有効化/無効化に関する設定をします。
ここは正直あんまり理解できてません（ああ、脱コピペしたいのに・・・。）ブート中のどのタイミングで起動するかを指定しているはず。
上記が常套句のようなので、とりあえずこれで。

ちなみに、このセクションが無いとenable（後述)できません。
systemdがどのタイミングで起動していいかわからなくなるからっぽい。

###※プログラムの置き場所
sounisi5011さんの指摘を受け修正

~~絶対参照で指定するので、置き場所はどこでもいいっぽい。~~
~~私は`home/pi/systemd`というディレクトリを作りましたが、わかりやすいように各自でどうぞ。~~
`/opt/`以下に置くのが良いようです。詳細はコメント欄にsounisi5011さんが書いて下さっています。


##2. serviceファイルをenable
serviceファイルを作ったら、systemdにこいつを登録してあげる必要があります。

```
$ sudo systemctl enable a.service
```
これで[install]セクションで指定した場所にシンボリックリンクが張られました。
早速rebootして動作を確認してみて下さい。

ちなみに、rebootする前にコマンドの動作確認しときたいな〜って時は

```
$ sudo systemctl start a.service
```

です。


#定刻でのプログラム自動起動
1. serviceファイルを作成
2. timerファイルを作成
3. timerファイルをenable

さっきより手順が１つ増えました。
サービスを作って、それを呼び出すタイマーを作って、最後にタイマーを登録です。
それでは具体的に行きましょう。

##1. serviceファイルを作成
###手順
自動起動の時と同じです

```
$ sudo nano /etc/systemd/system/b.service
```

```b.service
[Unit]
Description=do something

[Service]
ExecStart=/usr/bin/python /home/pi/systemd/b.py
```
###解説
自動起動の時との違い、serviceファイルに[install]セクションは不要です。
タイマーから呼び出すので、このserviceはenableしないからです。

##2. timerファイルを作成
###手順
これも一緒です。
```
$ sudo nano /etc/systemd/system/b.timer
```

```b.timer
[Unit]
Description=daily do something

[Timer]
OnCalendar=*-*-* 8:00

[Install]
WantedBy=timers.target
```
###解説
####[Unit]
このセクションの書き方はserviceと一緒です。

####[Timer]
タイマーとしての動作を設定します。
ここでは、毎朝8時に実行されるよう設定しました。他にもn秒間隔や、ブートn秒後なども可能です。
呼び出すサービスですが、省略した場合のデフォルトは同名のサービスです（ここではb.serviceが実行されるということ)。
Unit=hoge.service
などとすれば、別名のserviceを呼び出すこともできます。

####[install]
このセクションの書き方もserviceと一緒です。
##3. timerファイルをenable
これもさっきと同じです。

```
$ sudo systemctl enable b.timer
```

これでタイマーを使う準備ができたので、rebootして動作させましょう。


ちなみに、

```
$ sudo systemctl start b.timer
```

とし、手動で起動させちゃってもOKです。この場合はrebootは必要ありません。
※startだけやってenable忘れたら再起動時にタイマー止まっちゃいますからね！

#おわりに
systemdの使い方は以上です。

私は設定ファイルが苦手でおまじない扱いしがちなのですが、こんな風に骨組みをきちんと理解したら、ちゃんと「情報」として見えてくるようになりました。

見える世界が変わるのは良い気分ですね。
CentOS6にscreen-4.6.2をインストールする

## ソースを取ってくる

[このサイト](https://ftp.gnu.org/gnu/screen/)から、`screen-4.6.2.tar.gz`のリンク先をコピーして/usr/local/src/下にダウンロードする。

```bash
$ cd /usr/local/src/
$ sudo wget https://ftp.gnu.org/gnu/screen/screen-4.6.2.tar.gz
```

## インストール

まずは解凍

```bash
$ sudo tar -zxvf screen-4.6.2.tar.gz
```

インストール手順書を見てみる

```bash
$ cd screen-4.6.2
$ less INSTALL
```

コピペすると長いので割愛。
手順がいくつかに別れていて、手順0(./autogen.sh の実行。中身は /bin/autoreconf を実行するだけ)は普通やる必要ないみたい。
なので、手順1からやる。`./configure`の実行。
ただし、そのままやると下記のようなエラーが出る。

```bash
$ ./configure
...
- select can't count
configure: checking for tgetent...
configure: checking libcurses... 
configure: checking libtermcap...
configure: checking libtermlib...
configure: checking libncursesw...
configure: checking libtinfow...
configure: checking libncurses...
configure: checking libtinfo...
configure: error: !!! no tgetent - no screen
```

どうやら[tgetent](https://linux.die.net/man/3/tgetent)なる端末制御関連のライブラリがないらしいので入れよう。

```bash
$ sudo yum install ncurses-devel
```

もう一度 `./configure`を実行すると、最後に下のようなメッセージが出て `Makefile` と `config.h`ファイルが作られる。

```text
 Now please check the pathnames in the Makefile and in the user
configuration section in config.h.
Then type 'make' to make screen. Good luck.
```

`sudo make`を実行すると、`screen`ファイルが作られるので任意の場所に置くかシンボリックリンクを貼る。
自分は下のようなやり方で、既存のscreenをoldに変えて、新しくできたscreenにシンボリックリンクを貼った。

```bash
$ sudo make
$ sudo mv /usr/bin/screen /usr/bin/screen.old
$ sudo ln -s /usr/local/src/screen-4.6.2/screen /usr/bin/
```

以上。
あとは必要に応じて、`~/.screenrc`を変えてもらうと良いかと。
多分CentOS7でもやり方は同じだと思う。
Ajaxで画像ダウンロードしたときに、エラーが起こったら？

```js
function download () {
  return axios.get('download_url', { responseType: 'blob' })
    .then(res => Promise.resolve(res), error => Promise.reject(error))
}
```
としたときに、どうやってエラーを表示するか？とりあえずメモ

```js
download().then(res => {
  // FileSaverを使って保存
  FileSaver.saveAs(new Blob([res.data], { type: 'image/jpeg' }))
}, async error => {
  try {
    let resText = await new Promise(resolve => {
      let reader = new FileReader()
      reader.addEventListener('loadend', () => {
        resolve(reader.result)
      })
      reader.readAsText(error.response.data)
    })
    // エラー表示
    alert(JSON.parse(resText))
  } catch (e) {

  }
})
```
dockerコマンドチートシート

自分用のメモ

## sudoなしでdockerコマンドを実行する
```bash
sudo groupadd docker
sudo gpasswd -a $USER docker
sudo systemctl restart docker
```

## docker-composeを使う

aptで入るのは古いので，

```bash
sudo pip install docker-compose
```

でインストールすると新し目になる．


## ``docker run``を試す

```bash
docker run -it --rm -v `pwd`:/tmp eisoku9618/kuroiwa_dockefiles_for_latexmk /bin/sh -c "cd /tmp"
```

- ``--rm``: コンテナ終了時にコンテナを削除してくれる
- ``-it``: コンテナ内を操作できる

### ``--rm``を付け忘れている場合にコンテナを削除する

```bash
docker rm `docker ps -a -q`
```

とすれば一括削除できる．

## passwordなどのcredential情報を渡す

``docker secret``を使って渡してみる．
``docker secret``を使うためには

```bash
docker swarm init
```
を最初にしておく必要がある．

ベストな方法かどうかは分からないが，　https://qiita.com/ktooi/items/ba156bb1848c31f04949 を参考に，``.bash_histroy``にcredential情報が残らないように配慮しつつ

```bash:docker-compose.yml
version: "3.1"

services:
  app:
    image: nginx
    secrets:
      - my-secret

secrets:
  my-secret:
    external: true
```

を作って，

```bash
read -sp "Please input your password: " __pass; echo
echo ${__pass} | sudo docker secret create my-secret -
docker stack deploy --compose-file=docker-compose.yml hoge
```

で起動し，

```bash
docker ps -a
```

でコンテナ名を調べて

```bash
docker exec -it hoge_app.1.ujwxaonx80ml8qig0ise3kp1s /bin/bash -c "cat /run/secrets/my-secret"
```

とすると，秘密にしていた情報が渡っていることが分かる．

このように，コンテナ内では秘密に成っていないことに注意．
Elixir で md5 暗号化


特に必要はなかったのだが、ちょっとお試しで書いてみた。
ちなみに、`erlang20.0` で、`crypto:md5/1` は廃止されているようなので、`crypto:hash/2` を使用するようだ。

```
crypto:md5/1 will fail, since it was removed in 20.0; use crypto:hash/2
```

```crypto.ex
defmodule Crypto do
	def convert_md5 do
	#   :crypto.md5("Whoocus") 非推奨
	  :crypto.hash(:md5, "Whoocus")
	    |> Base.encode16(case: :lower)
	end
end
```

また、そのままだとバイナリで表示されてしまう。

```
iex(1)> Crypto.convert_md5
<<254, 97, 249, 200, 73, 189, 91, 193, 23, 19, 37, 187, 163, 17, 159, 144>>
```

そのため、`Base.encode16` で文字列化すること。

```
iex(2)> Crypto.convert_md5
"fe61f9c849bd5bc1171325bba3119f90"
```


参考URL: http://www.whoocus.com/blog/?p=2659
MySQLサーバの文字コードをコマンドで変える

## MySQLサーバの文字コード情報を取得

```sql
show variables like "chara%";
```

## データベースの文字コード変更

`utf8mb4`に変更

```sql
ALTER DATABASE データベース名
CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;
```

## いろいろ

`utf8mb4`に変更

```sql
set character_set_client = utf8mb4;
set character_set_connection = utf8mb4;
set character_set_database = utf8mb4;
set character_set_results = utf8mb4;
```
Railsで特定のデータ形式をスクレイピングしたい

とあるサイトに陳列されるデータのうち
指定の形式で並べられているものをスクレイピングしたい。

最終的には、その中から必要なものだけを並べたものを作りたい

```data.html
<div class="lis-se" data-index="0" data-type="sure">
<img src="http://s/2.jpg">
<div class="prt-having-num">1034
```

こういうデータが数千件並ぶ中で、
必要な"data-index"の値を持つ"prt-having-num"クラスの値　を取得したい

##参考にしているサンプルコード
まずここに自分なりの翻訳をかけてみる

```rb
require 'open-uri'　#URLを読み取るためのライブラリ
require 'nokogiri'　#スクレイピングに必要なライブラリ


# スクレイピング先のURL
url = 'http://matome.naver.jp/tech'

charset = nil　#ページ内の文字コードに nil　(nilガードってやつ？)
html = open(url) do |f|　# html に 開いたURL、fオブジェクトを実行
  charset = f.charset　  # URL中で指定された文字種別を取得(文字化け対策？)
  f.read 　　　　　　　　　 # htmlを読み込んで変数htmlに渡す
end

# htmlをパース(解析)してオブジェクトを作成、docに入れる
# なんでHTMLが大文字なんだっけ……
doc = Nokogiri::HTML.parse(html, nil, charset)

# docを読み込んで、xpathをかける……
doc.xpath('//li[@class="mdTopMTMList01Item"]').each do |node|
#理解した。
#ページ内の li要素を探し 
#classに "mdTopMTMList01Item" を指定してあるものを見つけたら
#それぞれにdoするんだ。多分



  # tilte cssファイルのh3タグを検出して、その中のテキストをpしてる？
  # pメソッドは、引数のオブジェクトを文字列にして標準出力します。 なるほど？
  p node.css('h3').inner_text

  # 記事のサムネイル画像 imgもタグ検出かな？
  # .attributeメソッド は モデルの全てのカラムと属性を取得する… 'src'　は？
  p node.css('img').attribute('src').value

  # 記事のサムネイル画像 aタグ検出、href属性
  # .valueメソッドは読み込んだものの値を配列として取得……
  p node.css('a').attribute('href').value
end
```

ええと、これの必要なところを書き換えてみるとして……

```rb
require 'open-uri'　
require 'nokogiri'　

url = 'http://data.html'　#該当のURLを入力

charset = nil　
  html = open(url) do |f|　
  charset = f.charset 
  f.read 
end


doc = Nokogiri::HTML.parse(html, nil, charset)

#xpathで、div要素で囲まれたclass lis-se がかかったテキストを取るには
doc.xpath('//div[@class="lis-se"]').each do |node|

#data-index が指定の値 がかかったテキストを取る方法　【不明】


#xpathで、div要素で囲まれたclass prt-having-num がかかったテキストを取るには
doc.xpath('//div[@class="prt-having-num"]').each do |node|

解決
#んっと……？ devタグを取る…？
#特定のclass がかかった数列を取得もどうやるんだ？

未解決
#deta-index を参照ってどうやるんだ？

取るべきデータのデータの特定に必要なのは
class="lis-se"　と　data-index="0"
class="prt-having-num"　の　1034

end
```

自分なりの翻訳を経てわかったことは……
どこがわからないか、何を見つければいいかはなんとなーくわかった。
ようなわかってないような……

ので、引き続きそれぞれの取得方法について調べてみる。

###参考になりそうな情報

のこぎりの使い方
https://rails-school.net/rails-nokogiri/

Xpathってなんや
https://tech.starttoday-tech.com/entry/xpath
PHPのモジュール版とCGI版の違い

# 概要

PHPにはモジュール版とCGI版が存在する。その場合の違いをまとめる。

# 説明

## CGI版

実行ファイル形式とも呼ばれ、Webサーバーとは別のプロセスで実行される。

### メリット

#### セキュリティ

CGI（版のPHP）を動かす各ユーザーは、Webサーバー本体を動かすユーザーとは異なる。
アプリケーションサーバとwebサーバーが別に存在する状態となる。
そのため、**誤って他ユーザーに干渉してしまうといった危険がない**。
また、**副次的な効果としてサーバの複数台運用の際に依存が少ないことによる移行しやすさ**がある。

### デメリット

#### 実行速度

Webサーバーとは別個のプロセスとして動かすぶん、実行するたびにメモリのロードが必要となり、**処理速度がモジュール版に比べて遅くなる。**
なお処理速度の問題を解決するためにFastCGIという仕様も存在する。
レンタルサーバーによってはこのFastCGIを採用しているところもある。

## モジュール版

CGI版の逆で、WebサーバーのプロセスのなかでPHPを実行してしまう方法。
現在**多くのレンタルサーバーはWebサーバーにApache（アパッチ）を採用**しているため、モジュール版というと、通常はApacheのモジュール版を意味する。

#### メリット

WebサーバーのプロセスでPHPが実行されるため、**CGI版に比べて動作速度が高速になりやすい**という点がある。

#### デメリット

HPがWebサーバーを動かすユーザー（root権限など）で動作するため、**Linuxユーザーが複数用いられる共用サーバーではセキュリティ面に不安がある**。
この課題を解決するために、**モジュール版には「セーフモード」という設定があり、ユーザー間のファイル干渉を防止できる**ようになっている。
ただし、諸々設定が必要であるため、そこはデメリットの一つになりうる。

## 一言でまとめると

### モジュール版
Apache の拡張機能で直接処理する方法

### CGI版

Apache で直接処理せず、CGI プログラムを別途起動して処理する方法

# 補足情報

モジュール版の欠点として

> ユーザーが複数いる共用サーバーではセキュリティ面に不安がある

と書いたが、これは複数のユーザで一つのミドルウェア(Apache)を利用することによることが要因。
そのため、共用サーバーでは導入がためらわれる時もある。
RAML: api-designer実行時にrequestが見つからずにエラーになる件について

# はじめに
※この記事はnpmからインストールするapi-designerのバージョンが0.4.1の場合の話です。お読みいただいている時点でそれより新しいバージョンをnpm経由で使用している場合はこの記事の内容は参考にならないと思います。

APIのドキュメント作成に[RAML](https://raml.org/)を使っていて、記述にはRAML用エディタの[api-designer](https://github.com/mulesoft/api-designer)が便利です。

# エラー

しかし、2018年7月現在、[READMEのRunning Locally](https://github.com/mulesoft/api-designer#running-locally)通りnpmからインストールしても実行時に以下のようなエラーになります。

```
Error: Cannot find module 'request'
at Function.Module._resolveFilename (module.js:538:15)
at Function.Module._load (module.js:468:25)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at Object. (/Users/jvarg25/.nvm/versions/node/v8.9.4/lib/node_modules/api-designer/bin/api-designer.js:6:15)
at Module._compile (module.js:643:30)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
```

# 原因

[request](https://www.npmjs.com/package/request)っていうHTTP通信するパッケージに依存しているのですが、このrequestが0.4.1ではdevDependenciesにいます。https://github.com/mulesoft/api-designer/blob/support/v0.4.1/package.json#L58
devDependenciesにいるパッケージはnpm install時に依存パッケージとしてインストールされません。そのためrequestはインストールされず、上記のエラーが発生します。
実行に必要なパッケージは本来はdependenciesにいるべきです。

# 対応策

しかしmasterではdependenciesの中にいます。https://github.com/mulesoft/api-designer/blob/master/package.json#L22
なので、masterにあるコードをインストールすることで上記のエラーは回避できます。

```
npm install -g mulesoft/api-designer#master
```

エラーなくインストールされると思います。あとは普通に`api-designer`を実行すればlocalhost:3000で立ち上がります。

npxで実行する場合はこちら

```
npx github: mulesoft/api-designer
```

# 対応策(非推奨)

個人的には良くないと思っていますが、requestをグローバルにインストールすればエラーは発生しなくなります。

```
npm install -g api-designer request
```

# 最後に
masterにあるコードをnpmにpublishすれば解決するが対応されない。issueはあります。https://github.com/mulesoft/api-designer/issues/509

不備や質問があればコメント欄かTwitter([@shisama_](https://twitter.com/shisama_))までお願いいたします。
多次元配列を1次元配列に変換

JavaScriptで多次元配列を1次元配列に変換する方法

### 方法1

flatten( )を使う

* install

```.shell
npm install flatten
```
* example

```.js
> var flatten = require('flatten');
> var array = [['a','b','c'],['d']];
> console.log(flatten(array));
  [ 'a', 'b', 'c', 'd' ]
```

### 方法2

Array.prototype.concat.apply( )を使う

* example

```.js
> var array = [['a','b','c'],['d']];
> console.log(Array.prototype.concat.apply([],array));
[ 'a', 'b', 'c', 'd' ]
```
【JavaScript】うるせぇお前がGolangになるんだよ


最近、Golangの`if err != nil`がどうのこうのと盛り上がっていますが、いかがお過ごしでしょうか？エラーを多値で返すのは面白いですね。

jsでもこれを実現するライブラリを書いてみました。

[akameco/golangify: Golang like error handling for async/await](https://github.com/akameco/golangify)

```
$ yarn add golangify
```

```js
const go = require('golangify')

const success = x => Promise.resolve(x + x)
const failure = () => Promise.reject(new Error('err'))

const main = async () => {
  console.log(await go(success)(1))
  // => [ 2, null ]

  const [result, err] = await go(failure)()
  if (err !== null) {
    console.log(err.message)
    // => err
  }
  console.log(result)
  // => null
}

main()
```

はい、`golangify`でラップされたasyncな関数はその関数の結果とエラーを多値で返します。

```js
const [result, err] = await go(failure)()
```

エラーがない場合は`[result, null]`、エラーがある場合は、`[null, error]`を返します。

面倒なのでsync関数は対応してないですが、実装自体はシンプルです。

```js
const golangify = target => new Proxy(target, {
  apply(target, prop, args) {
    const result = Reflect.apply(target, prop, args)
    return result.then
      ? result.then(v => [v, null]).catch(err => [null, err])
      : result
  },
})
```

`Reflect.apply`で実行して、`Promise`ならばそれを解決してthen/catchでそれぞれ配列を返すようにしてるだけです。
Proxyを使うとメタ的な処理を追加できるので楽しいですね。

## おわり

気が向いたらスターしてください。

[akameco/golangify: Golang like error handling for async/await](https://github.com/akameco/golangify)

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">うるせぇお前がGo言語になるんだよ <a href="https://t.co/KVFjvg614F">https://t.co/KVFjvg614F</a> <a href="https://t.co/5nURgUDsxk">pic.twitter.com/5nURgUDsxk</a></p>&mdash; あかめ@17時退勤.js (@akameco) <a href="https://twitter.com/akameco/status/1021053654558654464?ref_src=twsrc%5Etfw">July 22, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">だいたいReflectを使うとダークサイドに落ちるので普通に使わないほうがいい</p>&mdash; あかめ@17時退勤.js (@akameco) <a href="https://twitter.com/akameco/status/1019795084169043968?ref_src=twsrc%5Etfw">July 19, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## 関連
[【Proxy】JavaScriptでRubyのtimesを使う - Qiita](https://qiita.com/akameco/items/73f1f49092b49667dc3a)
Railsでherokuに上げた時に「Uglifier::Error: Unexpected token: operator」のエラー



```ruby:config/environments/production.rb

config.assets.js_compressor = :uglifier
↓↓↓これに変える
config.assets.js_compressor = Uglifier.new(harmony: true)
```


参考
[Uglifier::Error: Unexpected token: punc ((). To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true)](https://github.com/lautis/uglifier/issues/127)