OmniAICreator/Qiita-1.07M huggingface dataset:
【PlayCanvas】WebARで遊ぶ

この記事は [PlayCanvas Advent Calendar 2017](https://qiita.com/advent-calendar/2017/playcanvas) の18日目の記事です。

#何
iOS 11でもsafariがカメラアクセスできるようになり、カメラアクセスができるターゲットではPlayCanvasを使って簡単にWebARアプリケーションが作れるようになりました
https://caniuse.com/#feat=stream
動画
[![動画http://www.youtube.com/watch?v=2Yo6hqr_tZw](http://img.youtube.com/vi/2Yo6hqr_tZw/0.jpg)](http://www.youtube.com/watch?v=2Yo6hqr_tZw)

#仕組み
昔懐かしARToolKitをemscriptenでJavaScriptにしたものを使用してやっています。
まだエンジンに組み込まれているわけではなく、ライブラリを別途アップロードする必要があります。
[PlayCanvas AR | Github](https://github.com/playcanvas/playcanvas-ar)

#とりあえず始める
公式プロジェクトの[AR Starter Kit](https://playcanvas.com/project/481413/overview/ar-starter-kit)を見てみるのが一番手っ取り早いです。
[PLAY]をクリックし、実行してカメラアクセスを許可したら、[HIRO](https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Hiro%20pattern.pdf)と[KANJI](https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Kanji%20pattern.pdf)をそれぞれ見てみましょう。印刷しなくても、ディスプレイに写すだけでOKです

#作ってみる
##環境構築
現状はライブラリ関係のアップロード作業が発生するので、とりあえずAR Starter Kitからforkして開発開始するのが無難です。

##設計
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/d8ef036d-39a1-7b19-869b-b85d9460f21d.png)
マーカー用のエンティティを用意し、arMarkerスクリプトをアタッチするようです。マーカーの登録はPatternにセットします。実行してカメラを通してマーカーを見ると、マーカー用エンティティ配下のモデルがAR表示されます

##ARマーカーの登録
.pattファイルはただの文字列なので、以下のサービスから独自でマーカーを登録、作成することもできます。
http://flash.tarotaro.org/ar/MarkerGeneratorOnline.html
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/6a9c7489-c7a7-8ea7-ff15-04139c4fb066.png)

saveすると.patファイルがダウンロードできます。中身を見てみると正しくパターンと座標に応じた色情報が載っていることが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/b53d02c3-1aad-de3f-6df4-3a55262b32f7.png)

これをPlayCanvasへアップロードすることで独自のARマーカーを設定できます。
systemd-nspawnの--registerオプション

[systemd-nspawn Advent Calendar 2017](https://qiita.com/advent-calendar/2017/systemd-nspawn) 17日目の記事です。

systemd-nspawnには--registerオプションというものがあり, machinectlから見えるかどうかを制御できます

```bash
# 通常だと見える
systemd-nspawn -D ubuntu2/
machinectl
    MACHINE CLASS     SERVICE        OS     VERSION ADDRESSES
    ubuntu2 container systemd-nspawn ubuntu 16.04   -

# 見えない
systemd-nspawn -D ubuntu2/ --register no
machinectl
    No machines.

```


例えば、本番サーバ等で、systemd-nspawnを使っている場合、起動中のコンテナを監視等しているかもしれません。
そう言った場合でも、machinectlコマンドから見えなくして影響がないようにすることができます。
innodb_force_recoveryの値によってdumpが流し込めない

# はじめに
innodbを愛用するみなさんこんにちは。

dumpを流し込もうとすると以下のエラーで失敗しました。(バージョンはMariaDB 10.2.10です)

```
# zcat /var/db_dump/dump.sql.gz | mysql -u root
ERROR 1030 (HY000) at line 54: Got error -1 from storage engine
```

どうしたんだ困った子だね。

ログを見ると

```
InnoDB: A new raw disk partition was initialized or
InnoDB: innodb_force_recovery is on: we do not allow
InnoDB: database modifications by the user. Shut down
InnoDB: mysqld and edit my.cnf so that newraw is replaced
InnoDB: with raw, and innodb_force_... is removed.
```

どうしたんだ困った子だね。

新しいraw diskパーティションが作られたか、innodb_force_recoveryがonになっているよ。ユーザによってDB変更を許可していないよ。mysqldをshutdownしてmy.cnfのnewrawを変更して、innodb_force_recoveryオプションを取り除くんだ。

対処としてはinnodb_force_recovery=1が設定されてあったので0に書き直して再起動しました。dumpは流し込めました。

# newrawとは
新しいRAWディスクパーティションのことだろう。

参考：[14.5.8 共有テーブルスペースでの RAW ディスクパーティションの使用](https://dev.mysql.com/doc/refman/5.6/ja/innodb-raw-devices.html)

データベースを作成するとき、データディレクトリに指定した場所にデータベース専用のディレクトリが作成されますが、このときにファイルシステムを介さずに書き込むための設定がRAWディスクパーティションのようです。

で、たぶんnewraw指定で作った場合ユーザ指定で作成はできないようです。ただ、今回はこの事象ではありませんでした。

# innodb_force_recoveryとは
[XtraDB/InnoDB Server System Variables - innodb_force_recovery](https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_force_recovery)

クラッシュ時のリカバリ挙動。デフォルトは0。値ごとの詳細は次。

[XtraDB/InnoDB Recovery Modes](https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/)

0はデフォルト。MariaDB10.2.7まではデータ変更可能な唯一のモードであった。10.2.7以降は3以下の値でトランザクションが可能となった。

1はクラッシュ時、REDOログをベースにリカバリを試みる。壊れてるテーブルはskipする。

2以降とだんだんレベルがあがってくる。4以上はデータは永続的に壊れる可能性があるので注意すること。

さて、なぜinnodb_force_recovery=1だとCREATE TABLEが実施できなかったのだろうか？

>安全策として、innodb_force_recovery が 0 より大きい場合、InnoDB は INSERT、UPDATE、または DELETE 操作を回避します。MySQL 5.6.15 の時点では、4 以上の innodb_force_recovery 設定は InnoDB を読み取り専用モードにします。

そもそもおそらくクラッシュ時に一時的に1に設定したconfigを持ってきたのが悪かったですね。

(しかしおかしいな、なんで1の状態でしばらく動いていたんだろう。。。。)

# おわりに
innodb_force_recoveryはinnodbがクラッシュしたときに1ずつあげて起動し、dumpをとろう。用が済んだらすぐ0に戻そう。
sshでリモートサーバから特定の条件に合致するファイルのみを持ってくる方法

## やりたいこと
リモートサーバから`ssh`(`scp`でもいいんですが)で特定の条件を満たすファイルのみをローカルに持ってきたい(スクリプトで)。

## 調査した結果
単一のファイルやディレクトリをまとめてごっそり持ってくる方法はヒットしましたが、何か条件でフィルタした結果を持ってくる方法は特に見つかりませんでした。

## 結局どうするか？
A.リモートサーバで実行したいコマンドをヒアドキュメントに書いてそれを`ssh`に読み込ませました。
(クォーテーションを深く考えなくてよいのでこれが楽かと。)

### コマンドバージョン
```bash
$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
$ tar --version
tar (GNU tar) 1.26
```

### 例

```bash:sample.bash
DATE=$(date '+%Y-%m-%d')
cat << EOF >cmd.txt
  mkdir ${DATE}
  grep -l keyword * |  # or [awk '/keyword/{print FILENAME}' * | uniq]
  [or awk '\$1==keyword{print FILENAME}' | uniq]
  xargs -If cp -p f ${DATE}
  tar -zcf - ${DATE}
  rm -fr ${DATE}
EOF

cat cmd.txt |
ssh user@remoteServerAddress |
tar -zxf - -C localDirectory
```

## 説明　その１
リモート側で実行するコマンド

①

```bash
  mkdir ${DATE}
```

圧縮用のディレクトリーを作成します。
このディレクトリーに、ローカルに持ってきたいファイルを詰め込みます。
この`${DATE}`はローカルサーバ側で解釈するので、展開されてからリモートサーバへ渡されます。
というより`cmd.txt`の段階で既に展開されています。

②

```bash
  grep -l keyword * |  # or [awk '/keyword/{print FILENAME}' * | uniq]
  [or awk '\$1==keyword{print FILENAME}' | uniq]
```

検索の仕方は何でもいいので、ファイル名だけ抽出します。
ファイル名がフルパスかどうかは、ローカルに持ってきたいファイルの置いてあるディレクトリ次第ですね。

`awk`で使用している`$1`はローカル側(シェルスクリプト)ではなく`awk`に解釈して欲しいので`\`を付けます。

③

```bash
  xargs -If cp -p f ${DATE}
```

ファイルを作成したディレクトリへ放り込みます。

④

```bash
  tar -zcf - ${DATE}
```

この辺が正直説明できるほど詳しくないのですが、ファイルを放り込んだディレクトリを圧縮します。
`-`には本来圧縮後ファイル名を記載するのですが、すぐ解凍するからかパイプで渡すからなのか`-`にしています。

⑤

```bash
  rm -fr ${DATE}
```

お掃除です。不要であればしなくてもいいです。

## 説明　その２

ローカル側で実行するコマンド

```bash
cat cmd.txt |
ssh user@remoteServerAddress |
tar -zxf - -C localDirectory
```

リモート側で実行するコマンドをまとめて`ssh`に渡して実行させます。
その結果が圧縮ファイルになりますが、それをパイプで受け取って`tar`ですぐに解凍してしまいます。
`-C localDirectory`は解凍場所の指定です。

## 補足

全てパイプでつなげることも可能です。

```bash:sample.bash
DATE=$(date '+%Y-%m-%d')
cat << EOF | ssh user@remoteServerAddress | tar -zxf - -C localDirectory
  mkdir ${DATE}
  grep -l keyword * |  # or [awk '/keyword/{print FILENAME}' * | uniq]
  [or awk '\$1==keyword{print FILENAME}' | uniq]
  xargs -If cp -p f ${DATE}
  tar -zcf - ${DATE}
  rm -fr ${DATE}
EOF
```

## 参考にさせて頂いたサイト様
[sshでリモートシェル実行時に``で括ったコマンドを使う - Qiita](https://qiita.com/tkhm/items/d3c7e9d755e17bb8209c)
[ssh経由でのtarによるフォルダの圧縮・解凍方法 _ 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2015/02/ssh%E7%B5%8C%E7%94%B1%E3%81%A7%E3%81%AEtar%E3%81%AB%E3%82%88%E3%82%8B%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%AE%E5%9C%A7%E7%B8%AE%E3%83%BB%E8%A7%A3%E5%87%8D%E6%96%B9%E6%B3%95/#3)
[[Linux]ファイルの圧縮、解凍方法 - Qiita](https://qiita.com/supersaiakujin/items/c6b54e9add21d375161f)
プログラミング 9 か月目

プログラミングを始めて 9 か月が経とうとしています。

　前回から復習メインとなっていますが、新しいことにも少しずつ触れています。今回も前回と同様に書きたいと思います。

# :pencil2: 進捗状況

**Paiza**

　Sinatra 入門 : 新登場のレッスンです。Rails の骨格部分を学習している感じです。



**ドットインストール**

　Sinatra 入門 : Paiza のついでに深く学習したいと思い、こちらも受講。


# :pencil2: 新着事項
　9 か月目で新たに取り入れたことや、プログラミングで意識したことを書いていこうと思います。

### :page_facing_up: 複雑なプログラミングでも…
　ある一連の大きな処理は、それより小さい複数の処理があり、その小さい複数の処理もさらに小さな処理が複数個あり…

　…というふうに細かく分析していくと、どんなに複雑なプログラミングでも、**「順次」「分岐」「反復」**の 3 つに分かれているということを知りました。

　最初の頃は覚えたりすることで精一杯であったり、プログラミングってなんか複雑そうと思っていて、なかなかその意識が回らなかったと思います。ひととおり学び終えて、CODEPREP の「プログラミング超入門」でこの記事を見たときに目からウロコが落ちました。

```
// 構造化プログラム

ある一連の大きな処理　→　小さな処理 × 複数個　 →　
さらに小さな処理 × 複数個　→  ・・・ → 順次、分岐、反復
```

　これによって、プログラミングをする意識というより「見方」が変わりました。複雑そうに見えたプログラムが、少しずつですが「単純な処理の集まり」というふうに変化しています。

　**どの順番で処理するのか**、**どこで条件分岐させるのか**、**どの部分を繰り返せばいいのか**というのが分かるようになり、プログラムを組む時もこれらのことをはっきり意識できるようなった気がします。
　 
# :star: 最後に
　
　プログラムの構造の仕組みを理解して、それに対する見方や意識が変わったことにより、どのようにプログラムを組み立てればよいのかが以前よりはっきりとわかるようになったような気がします。

　まだ分からないことがたくさんありますが、一日でも早く上達できるように頑張りたいと思います。
Fetch API でHeadersを操作する時の落とし穴

2017/12現在

Google Search ConsoleのFetch as googleでSPAサイトのレンダリング確認をした際に通信しない問題が起きた。

結論から言うと、 `Headers.entries` が存在しないため、全非同期通信が止まってた。
Googlebotはchrome41なので、`Fetch API`の実装が部分的で、FetchやHeaders自体は存在するが、entriesメソッドが存在しなかった。ただFetch, Headersクラス自体が存在するためpolyfillされていなかった。

Edgeでも同様の問題が起きていた。
edgeで実装済みのメソッド

| Method | Description |
|:--|:--|
| append | Appends a new value to an already existing header inside a Headers object. |
| delete | Deletes a header from the current Headers object. |
| get | Gets the first value of a header from the current Headers object. |
| has | Checks whether or not a header exists within the current Headers object. |
| set | Sets a new value to an already existing header inside a Headers object. |

https://docs.microsoft.com/en-us/microsoft-edge/dev-guide/performance/fetch-api#headers

whatwg-fetchではissueあがってるが直接の対応はしないようだ。
https://github.com/github/fetch/issues/407


## 対策

* 最低限のAPIしか使わない
    * 上記のedgeの実装にあるようなset, get, hasなどは恐らくどのFetch対応ブラウザでも実装されていると思うのでそれのみを使う
* 特定のブラウザの場合はpolyfillを強制する
    * https://github.com/github/fetch/issues/407#issuecomment-255724541
* 別のpolyfillを使う
    * https://github.com/jimmywarting/fetch-headers
    * https://github.com/qubyte/fetch-ponyfill
2. drbd8.9でスプリットブレインの手動回復

2台構成で両方のサーバーを電源OFFして、同時期に電源ONすると発生する?

## スプリットブレインの状態

* proxmox56 : 通常Primary
* proxmox55 : 通常Secondary

```sh:通常PrimaryがStandAlone
root@proxmox56:~# drbd-overview 
 0:mysqldrbd/0  StandAlone Primary/Unknown UpToDate/DUnknown /var/lib/mysql ext4 3.9G 37M 3.7G 1% 
```

```sh:通常SecondaryがStandAlone
root@proxmox55:~# drbd-overview 
 0:mysqldrbd/0  StandAlone Secondary/Unknown UpToDate/DUnknown 
```


## 手動回復

* [第7章 トラブルシューティングとエラーからの回復](https://blog.3ware.co.jp/drbd-users-guide-8.4/ch-troubleshooting.html)

```sh:通常Primary側で実施
drbdadm connect <resource>
```

```sh:通常Secondary側で実施
drbdadm secondary <resource>
drbdadm connect --discard-my-data <resource>
```

```sh:通常PrimaryでPrimary/Secondaryになったことを確認
root@proxmox56:~# drbd-overview 
 0:mysqldrbd/0  Connected Primary/Secondary UpToDate/UpToDate /var/lib/mysql ext4 3.9G 37M 3.7G 1%
```


## 中身の確認

<resource>に何か書き込んでPrimaryとSecondaryを切り替えデーターが残っていることを確認する。

```sh:通常PrimaryをSecondaryに切り替える
# 通常PrimaryをSecondaryに切り替えるためstandbyにする
root@proxmox56:~# crm node standby proxmox56
# standbyのままだと次回切り替わらないため、onlineにして切り替わるようにする
root@proxmox56:~# crm node online  proxmox56
```
puma & puma-dev で利用中の.devを.testなどに変更する

# やってくれたな。GoogleChromeよ。

> **HSTS(HTTP Strict Transport Security)**
> HTTP Strict Transport Security (エイチティーティーピー・ストリクト・トランスポート・セキュリティ、略称 HSTS)とは、WebサーバーがWebブラウザに対して、現在接続しているドメイン（サブドメインを含む場合もある）に対するアクセスにおいて、次回以降HTTPの代わりにHTTPSを使うように伝達するセキュリティ機構である。RFC 6797 で規定されている。([Wikipedia](https://ja.wikipedia.org/wiki/HTTP_Strict_Transport_Security)より抜粋)。

HSTSというのがあって、この度GoogleChromeのVer.63から、「.dev」ドメインに対して強制化されました。簡単にいうとHTTPSへ強制連行される仕組み。
.devドメインでHTTPへのredirectとかが書いてあると絶望的なループが始まります。

※尚、HTST(牛乳とかの食品殺菌方法の一つ、高温短時間殺菌法のこと)ではない。


# puma-devを.devではなく.testに変更する。

## 1. まずpuma-devをアンインストール

```
puma-dev -uninstall
```

## 2. 入れ直す

```
puma-dev -install -d test
```
testの部分が、従来.devだった部分の.testになる箇所。

## 3. シンボリックリンクを付け直す

上記の2で大丈夫な人もいるようなんですが、僕は動かなかったのでシンボリックリンク付け直した。

```
cd ~/.puma-dev
rm FAVY_SYM_LINK
ln -s ~/FAVY_PATH FAVY_SYM_LINK

ex)
cd ~/.puma-dev
rm favy
ln -s ~/Sites/favy favy

```
FAVY_PATHやFAVY_SYM_LINKは自分の環境に合わせて変えてね。
一応これで動きました。

# .testじゃなきゃ駄目なの？
.testは、別の名前でも良いのですがトップレベルドメインで運用されそうにない名前が良いです。
海外だと「.test」や「.localhost」などにしてる人がいるよう(但し本人たちは「マジでスマートじゃねぇ」と不評)なので、僕も「.test」で運用することとします。
コマンドプロンプト起動テク

# 普通に操作
1. windowsキー + R
2. cmd Enterキー

```
C:\Users\xxxxx> cd /d D:\新しいフォルダー
D:\新しいフォルダー> type hogehoge.txt
```

# GUI操作
![cmd.png](https://qiita-image-store.s3.amazonaws.com/0/218363/916eae26-5260-ac06-15ce-1854b0ac1de2.png)

1. 対象フォルダを開く
2. アドレスバーに「cmd」Enterキー

```
D:\新しいフォルダー> type hogehoge.txt
```

# 備考
コマンドプロンプトじゃなくてpowershellでももちろんOKです。

＿人人人人人人人人人＿
＞わりとどうでもいい＜
￣ＹＹＹＹＹＹＹＹＹ￣
MESHの明るさタグを使って、トイレセンサーシステムを作った

[MESHの7タグセット](https://www.amazon.co.jp/%E3%82%BD%E3%83%8B%E3%83%BC-Sony-MESH-7%E3%82%BF%E3%82%B0%E3%82%BB%E3%83%83%E3%83%88-MESH-100B7A/dp/B01N3PBAOS/ref=as_li_ss_tl?m=A38OC9QVSVLJH0&s=merchant-items&ie=UTF8&qid=1513051446&sr=1-6&&linkCode=sl1&tag=meshprj-22&linkId=5904a1b6d242cfb5b881c58c6bbdcf6f)がタダで手に入ったので、その中の[明るさタグ](http://meshprj.com/jp/tag/MESH-100PA-Brightness.html)を使って、会社の男子トイレの空き状態を調べるシステムを作ってみました。

<img width="352" alt="スクリーンショット 2017-12-18 13.33.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/b1ab5de4-2709-0e66-b1d8-a47d8046fddf.png">





# 必要なもの
- [MESHの明るさタグ](http://meshprj.com/jp/tag/MESH-100PA-Brightness.html)

<img width="113" alt="スクリーンショット 2017-12-18 13.35.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/afb4b684-3803-fadb-abd2-1f7d57e94bb3.png">

- iPhone(又はAndroid)

# システム概要

- 明るさタグでトイレのドアの開閉を検知します。
- トイレのドアが開いたときに、Googleスプレッドシートに「Open」と書き込みます。
- トイレのドアが閉じたときに、Googleスプレッドシートに「Closed」と書き込みます。

# システム構築手順

## 1.トイレに明るさタグを設置

ドアを開いたときだけ影ができる場所に、明るさタグを両面テープで貼り付けます。

ドアを開いた時 | ドアを閉じた時
-----|-----
<img width="791" alt="スクリーンショット 2017-12-18 13.44.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/f9023d86-d3d1-a29d-7bce-36e5d65676b2.png"> | <img width="819" alt="スクリーンショット 2017-12-18 13.44.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/9928bc71-d76e-3e20-3cf5-16059ae3c773.png">

## 2. IFTTTの設定

IFTTTはMESHとGoogleスプレッドシートを連携するために必要です。

1. [IFTTT](https://ifttt.com)のアカウントを作ります。
2. Add row to Google Sheets using MESHというアプレットを有効にします。
<img width="419" alt="スクリーンショット 2017-12-18 14.03.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/808a1d37-b1d7-7d25-006c-3f433fb8f6dc.png">


## 3.MESHアプリでプログラミング

App Storeで[MESHアプリ](https://itunes.apple.com/jp/app/mesh-creative-diy-toolkit/id981090691?mt=8)をダウンロードし、以下のようにロジックを組みます。

<img width="350" src="https://qiita-image-store.s3.amazonaws.com/0/9875/1d706162-1fc9-fa8c-bfbe-0d259e29a773.png" />

番号 | 設定
-----|-----
1 | <img width="200" alt="IMG_0665.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/f4cc3146-4aad-63ec-acfa-05d7a26d0e61.png">
2 |<img width="200" alt="IMG_0666.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/251b0b01-6a61-00db-90ca-5704abaf923d.png">
3 |<img width="200" alt="IMG_0667.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/a7eb359e-7f78-53e9-809a-0ae9b5008019.png">
4 |<img width="200" alt="IMG_0668.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/58b53bd5-64dd-35b1-d9f7-3960af783f5a.png">

これで、ドアの開閉時にGoogleスプレッドシートの一番下の行に、「Open」か「Closed」が書き込まれるようになります。

## 4.Googleスプレッドシートの設定

最後に、スプレッドシートのB2セルに`=INDEX(A1:A1000,COUNTA(A1:A1000), 1)`という関数をセットします。
これはA列の最下行のセルの値を取得する関数です。

<img width="315" alt="スクリーンショット 2017-12-18 14.15.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/5a41ba9b-088e-c9c7-309e-ad974f78a3b6.png">



これでトイレセンサーシステムは完成です!
InstantWordpress 5.3.5が使えない

現在(2017/12/18)の最新バージョンである、InstantWordpress 5.3.5をインストール
したところ、Home画面やボタンなどが機能していないみたいです。

私もインストールしましたが、失敗しました。
以下のリンクから過去のバージョン5.3.4をインストールすると成功します。
https://github.com/corvideon/InstantWP/releases


もし、5.3.5に解決策があるようでしたら、コメントお願いします。
表示ページのGETパラメータをObjectで取得する方法

死ぬほど長いクエリパラメータがあるページの調査で使用しました。

GETパラメータに対して処理するロジックでも使用できると思います。


## コード

```js:code
function getQueryParams() {
  var params = {};
  var url = window.location.href;

  url.replace(/([^(?|#)=&]+)(=([^&]*))?/g, function($0,$1, $2, $3) {
    if (typeof $3 === 'undefined') return;
    params[$1] = $3;
  });

  return params;
}

// 取得
var params = getQueryParams();
```

```js:結果
{
   type: "",
   tag_id: "",
   tag_off: "",
   dcolor: "1",
   dstore: "1",
   p_isize: "2",
}
```
facebook/screenshot-tests-for-android でスクリーンショットテスト

PLAID Advent Calendar 2017 18日目の記事です。

- Androidのスクリーンショットテストだと[square/spoon](https://github.com/square/spoon)が少し有名ですが、もう少し新しめのライブラリで[facebook/screenshot-tests-for-android](https://github.com/facebook/screenshot-tests-for-android)なるものがあったので紹介します。
- [こちら](https://qiita.com/takaaki7/items/92af58c55dca39a4faed)で紹介した[wikipediaのアプリ](https://github.com/wikimedia/apps-android-wikipedia/blob/master/app/src/androidTest/java/org/wikipedia/test/view/ViewTest.java)でも使われてます。
- spoonとの違いとして、スクショを保存するモードとスクショを比較してtestするモードがあります。(`recordMode`と`verifyMode`)

### セットアップ
- OSXとLinuxのみサポートされてる。

- python-2.7と画像比較に使われるpython-pillowが必要。

```
pip install pillow
```

- build.gradleに依存関係とapply pluginを追記。

```groovy:build.gradle
  buildscript {
    // ...
    dependencies {
      // ...
      classpath 'com.facebook.testing.screenshot:plugin:0.5.0'
    }
  }
  apply plugin: 'com.facebook.testing.screenshot'
```


- [testing-support-libの依存を強制したくないとのことで](https://github.com/facebook/screenshot-tests-for-android/issues/51#issuecomment-269682742)、デフォルトで使われる`ScreenshotTestRunner`は`InstrumentationTestRunner`を継承してる。
`AndroidJUnitRunner`や自前のTestRunnerを使いたければ、TestRunnerの`onCreate()`と`finish()`で下記のように`ScreenshotRunner`のメソッドを呼び出す。

```java:CustomTestRunner.java
public class CustomTestRunner extends AndroidJUnitRunner {

    @Override
    public void onCreate(Bundle arguments) {
        ScreenshotRunner.onCreate(this, arguments);
        super.onCreate(arguments);
    }

    @Override
    public void finish(int resultCode, Bundle results) {
        ScreenshotRunner.onDestroy();
        super.finish(resultCode, results);
    }
}
```

- build.gradleにもCustomTestRunnerの利用を設定(上書きされないよう`apply plugin: 'com.facebook.testing.screenshot'`よりも後に書く)

```groovy:build.gradle
android {
    // ...
    defaultConfig {
        // ...
        testInstrumentationRunner "com.example.takaaki.screenshotsample.CustomTestRunner"
    }
```

- screenshotは一時的に端末内に掻き出されるので`WRITE_EXTERNAL_STORAGE`のパーミッションをアプリに追加。

```xml:AndroidManifest.xml
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```

- 以上で`./gradlew screenshotTests`でテストを実行し生成されたスクショ一覧をreportとして見れる。

### 運用
- `./gradlew recordMode screenshotTests`でテストを実行すればapp/screenshots以下にscreenshotが保存される。UI変更の修正をした時はこれを実行しスクショもコミットすれば良さそう。

- CIでは`./gradlew verifyMode screenshotTests
`で実行することで、生成されたスクショとapp/screenshots以下のスクショが等しいかをテストすれば良さそう。

### 結び
- サンプルアプリは[takaaki7/ScreenshotTestSample](https://github.com/takaaki7/ScreenshotTestSample)にあげました。
- Firebase Test Lab for Androidでもスクリーンショットテストできるのでこちらも調べたい。
Nginx をリバースプロキシとして使い上位パスへの削除を禁止するためのメモ

REST をサポートしたデバイスで、個別 URL への削除は許可しますが、上位 URL への削除は禁止する必要がありました。Nginx をリバースプロキシとして使って実現することができたので、その際のメモです。

まず達成したいことはこんな感じです。

下記のような個別の URL への DLETE は許可します。


```URL
http://127.0.0.1:8080/api/running/services/bgpmgr/test1
http://127.0.0.1:8080/api/running/services/bgpmgr/test2
...
```

しかし次のように、上位の URL に対する DELETE は禁止します。

```URL
http://127.0.0.1:8080/api/running/services
```

## Nginx の設定
Nginx は基本的に上から評価するため、個別 URL はそのまま pass し、それ以外は GET のみ許可するようにしてみます。nginx.conf は下記ような感じ。

```nginx
events {
    worker_connections 1024;
}
http {
    server {
        listen 9000;
        server_name localhost;

        location /api/running/services/bgpmgr {
            # Device URL
            proxy_pass http://127.0.0.1:8080/api/running/services/bgpmgr;
        }

        location / {
            limit_except GET {
              deny all;
            }
            # Device URL
            proxy_pass http://127.0.0.1:8080/;
        }

    }
}

```

上記設定後、Nginx を起動します（すでに起動している場合は "nginx -s reload"）。

```console
$ nginx -p . -c nginx.conf
```


## 動作結果
オリジナルのデバイスのポート 8080 の代わりに Nginx の 9000 に対して REST message を投げます。

```console
$ curl http://127.0.0.1:9000/api/running/services -X DELETE
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>
$
```

上位 URL は無事にフィルタされました。

```console
$ curl http://127.0.0.1:9000/api/running/services/bgpmgr/test1 -X DELETE
$ 
```

個別 URL は問題なく削除できます。
あとは、必要に応じてエラー処理などを実装して行けば良さそうです。
最近そこまで身体を動かすのはキライではない、

#元々は体育がキライな子でした

というより、ただ単に協調制がないだけであって、

そんな感じだからエンジニアになってしまったのかと、最近思っております。

でもあまり激しい運動でなければ割と好きな方なのかな？

って最近思ったりして、


現にここ数ヶ月の帰り道は渋谷から大崎まで（ざっと６.5キロww）徒歩で帰ったりしてます！

特にWantedlyの入っているビルの脇道が
***緑でいっぱい！天気の良い日は気持ちいい！***

#MacとVScodeの相性が良すぎる！
もちろん個人的主観です！多くの方が「ハイハイ、そうですね」と思うでしょうが、MSらしい個性的すぎない、トレンドに合わせつつ安定した操作ができるUIがたまらないのです。


##これからやりたい事
1. laravel or wordpressなどのフレームワークの研究
2. webpackとgulpの併用で開発環境の構築
3. Vue.js　Anguler　Typescriptの学習
4. ちょっと自分のサイト作ってみる。。

###お家で勉強出来ない子
そう、お家で勉強とか作業できない子なんです。。ここをクリアしなければ、、

というかこれが自分にとって初めての投稿になります。もっとCSSの事とか書いた方がいいと思うけど、一言だけ言います！

***CSSは詰め込み学習で８割イケます！！ Sassに手を出すのはそれからだ！！***

じゃあの、
Unity4系→Unity5系へのバージョンアップ時にハマったことと解決策


## ■PlayerSettings.applicationIdentifierが反映されない
Jenkinsを使ってバッチモードでビルドする際にデバッグモードのみアプリIDを書き換えしていたが
Unityバージョンアップ後からIDの上書きがうまく行かなくなった

```
PlayerSettings.applicationIdentifier = "hogehoge";
```
だとアクティブなプラットフォームのIDしか書き換わらなかったため

```
PlayerSettings.SetApplicationIdentifier(BuildTarget.iOS, "hogehoge");
```
とすることで任意のプラットフォームのIDの書き換えが可能

## ■iOSでコードの重複エラー
プロジェクトではUnityが出力するClasses配下のコードを
Assets/Plugins/iOS/UI/Keyboard.mmのように配置して上書きを行っていたが
Unity5へバージョンアップ後から上書きされずビルド時にコード重複のエラーが発生していた

PostProcessBuildとPBXProject.RemoveFileFromBuild/RemoveFileを使って
Unityのビルド後にXcodeプロジェクトを編集することでコードの重複を回避

```iOSPostBuildProcess.cs
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget buildTarget, string buidlProjectPath) {
    if (buildTarget != BuildTarget.iOS) {
        return;
    }

    // Plugins配下のファイルをコピー
    var src = Path.Combine("Libraries/Plugin/iOS/UI/Keyboard.mm");
    var dest = Path.Combine("Classes/UI/Keyboard.mm");
    File.Copy(Path.Combind(buidlProjectPath, src), Path.Combine(buidlProjectPath, dest), true);

    // Xcodeのプロジェクトからコピーしたファイルを削除
    var projectPath = Path.Combine(buidlProjectPath, "Unity-iPhone.xcodeproj/project.pbxproj");
    var project = new PBXProject();
    project.ReadFromFile(projectPath);
    
    var targetGuid = project.TargetGuidByName("Unity-iPhone");
    var guid = project.FindFileGuidByProjectPath(src);
    project.RemoveFileFromBuild(targetGuid, guid);
    project.RemoveFile(guid);

    project.WriteToFile(projectPath);
}
```

## ■突然Unityがクラッシュする
C:\Users\ユーザ名\AppData\Local\Unity\Editor\Editor.log
Unityがクラッシュする直前のログを見て直前に何の処理をしていたかを確認する
今回の場合
・原因　AssetBundleが古い
・対策　Unity5.6.4ｆ1でAssetBundleの再ビルド

```
========== OUTPUTING STACK TRACE ==================

0x00000001414D9351 (Unity) SerializedFile::ReadMetadata<0>
0x00000001414DC7CC (Unity) SerializedFile::ReadHeader
0x00000001414DEADF (Unity) SerializedFile::FinalizeInit
0x00000001414DEF49 (Unity) SerializedFile::InitializeRead
0x0000000141098280 (Unity) PersistentManager::LoadFileStream
0x00000001408C1012 (Unity) AssetBundleLoadFromAsyncOperation::TryToLoadAndInitializeAssetBundle
0x00000001408C1D0E (Unity) AssetBundleLoadFromAsyncOperation::IntegrateMainThread
0x0000000141036868 (Unity) PreloadManager::UpdatePreloadingSingleStep
0x0000000141036BAD (Unity) PreloadManager::UpdatePreloading
0x00000001414A3DCC (Unity) PlayerCleanupCachedData
0x0000000140D89530 (Unity) PlayerLoop
0x00000001417482BE (Unity) Application::UpdateScene
0x0000000141749A8F (Unity) Application::UpdateSceneIfNeeded
0x000000014175231A (Unity) Application::TickTimer
0x000000014181D96C (Unity) CrashCallback
0x000000014181F4F4 (Unity) WinMain
0x0000000141B05BCC (Unity) strnlen
0x00000000771959CD (kernel32) BaseThreadInitThunk
0x00000000773CA561 (ntdll) RtlUserThreadStart

========== END OF STACKTRACE ===========

```
Django 画面の置き場所はよく考えよう


環境：Django 1.11

#問題

DjangoのRest API Frameworkを使ってシングルページアプリケーション(以下SPA)を作ろうと勉強していました。

しかし、プロジェクトの構成にどうにも違和感を感じ、しばらく悩んだあげくこちらのサイトを参考にしてようやく原因がわかりました。

Creating a SPA in Django
http://www.adamwester.me/blog/creating-a-spa-in-django/

#原因

Djangoのチュートリアルでは、テンプレートの配置場所について、アプリケーションのディレクトリの中に作成するようにしています。

>最初に、 polls ディレクトリの中に、 templates ディレクトリを作成します。 Django はそこからテンプレートを探します。
https://docs.djangoproject.com/ja/2.0/intro/tutorial03/

最近のDjangoのバージョンでは、静的コンテンツやモデルクラスを各アプリケーション内に分散して作成させ、実行時に仮想的に統合する機構を持っています。
この機構により各アプリケーションが疎結合になり、プラグインとして自由に追加、削除が可能になります。

ただし、通常のプロジェクトでは個別のアプリケーションは疎結合であることがのぞましいのですけど、SPAでは一つの画面から複数のアプリケーションを横断して利用できるほうが望ましいです。

無理にアプリケーションに所属させようとして構成をこねくりまわしてしまいました。

#対応

SPAの画面については、いずれのアプリケーションにも所属させずプロジェクトの共通ディレクトリを作ってそこで管理するということにしました。

プロジェクトに共通ディレクトリを作る方法はチュートリアルに書かれていないので、Djangoではできないものと思い込んでいましたが、そんなことはありませんでした。むしろ一般的かもしれません。

SPAのプロジェクトでは、以下の方針でDjangoを利用していこうと思います。

・アプリケーションの役割はWebAPIの提供とし、画面は持たない。
・画面はプロジェクト内に専用ディレクトリを作って管理する。
・画面へのリクエストは、プロジェクトのルートurls.pyから直接応答する。
※SPAでは画面に埋め込みタグを使う必要が無いので問題ない。

全て前述の[サイト](http://www.adamwester.me/blog/creating-a-spa-in-django/
)で言及されています。

クッキーカッターの構成も参考になります
https://github.com/pydanny/cookiecutter-django

共用フォルダを作った場合、設定ファイルの変更が必要です。
以下の設定に絶対パスを追加しましょう。

setting.py
・TEMPLATES.DIRS
・STATICFILES_DIRS

もっと自由に使いこなせるように勉強したいと思います。
コマンドラインツールとしてのperl

みなさん！Perlつかってますか！
ぼくは日常的に使ってます。

さて、PerlはCPANモジュールを駆使して適切な設計さえ行えば、大規模なWebアプリも構築できるほどパワフルな言語ではありますが、その本領はやはりコマンドラインツールやスクリプトとしての使われ方でしょう。
今回はコマンドラインツールとしての`perl`の使い方を簡単に紹介します。

# コマンドラインツール

多くのコマンドラインツールにはGNU系とBSD系の異なる実装が存在します。
たとえば、文字列置換によく使う`sed`はBSD系とGNU系でちょっとオプションが異なったりしますよね。
`perl`は`sed`や`grep`の代替としても使うことができるわけですが、`perl`でそれら代替する最大の利点はOSが異なっても同じインターフェイスで扱えることでしょう。
一度覚えて手癖にしてしまえば急場でもOSの違いを気にせずにサッとログをまとめたりCSVなどを処理したりできるわけです。便利でしょー。
簡単に`sed`や`grep`をどのように代替することができるのかを見ていきます。

## sedの代替

`sed`にpipeされた入力を`Foo`から`Bar`に置換するにはたとえばこのようにすれば良いでしょう。

```bash
... | sed -e 's/Foo/Bar/g'
``` 

`perl`で代替するとこうなります。

```bash
... | perl -pe 's/Foo/Bar/g'
```

ほぼ変わらないですね！
`perl -pe` で `sed -e` の代わりとして使うことが出来ます。
もちろん、ファイルを置換してバックアップをつくる `-i` オプションも同様に使うことが出来ます。簡単ですね！

### 原理

これがどのように動いているのかを簡単に解説します。

`-e` オプションは続く引数をコードとして解釈するものです。
`-p` オプションはコードを以下のように展開して実行するモードになります。(`-MO=Deparse`を付けて実行するとどのようなコードが実行されるのかよくわかります。)

```perl
LINE: while (defined($_ = readline ARGV)) {
    s/Foo/Bar/g;
}
continue {
    die "-p destination: $!\n" unless print $_;
}
```

`ARGV` という特殊なファイルハンドルを読むことで、引数または標準入力を`$_`に読んでからコードを実行することになります。
このとき、 `s/Foo/Bar/g` はそのマッチ対象が指定されていないため `$_` を対象に動作し、`continue`ブロックの`print $_`で出力されるというカラクリになっています。

詳しくはARGVなどについてのドキュメントを参照するとよいでしょう:

* http://perldoc.jp/variable/ARGV
* http://perldoc.jp/docs/perl/5.10.0/perlopentut.pod#Filters

## grepの代替


`grep`にpipeされた入力から`Foo`を含むものだけに絞るにはたとえばこのようにすれば良いでしょう。

```bash
... | grep 'Foo'
``` 

`perl`で代替するとこうなります。

```bash
... | perl -ne 'print if /Foo/'
```

ちょっとコードっぽくなりましたが、分かりやすいかとおもいます。
`perl -ne` で `grep` の代わりとして使うことが出来ます。

当然ながら、Perlなのでもう少し凝ったマッチをさせることもできます。
たとえば、名前解決をした上で `192.168.` で開始するものを抽出したいとなればこのようにすることでそれができます。

```bash
... | perl -MSocket -nle 'print if Socket::inet_ntoa(scalar gethostbyname($_)) =~ /^192\.168\.*/'
```

また、応用として `Foo`を含む行をカウントしたければこのようにするとよいです。

```bash
... | perl -nle '$foo++ if /Foo/; END{ print $foo }'
```

ね、簡単でしょ？

### 原理

`-e` オプションは先程と同じです。
`-n` オプションは`-p`オプションと似た動きをしますが`print`をしません。

よって `perl -ne 'print if /Foo/'` は以下のように展開されます。

```bash
LINE: while (defined($_ = readline ARGV)) {
    print $_ if /Foo/;
}
```

## まとめ

`perl`は`sed`などの各種コマンドラインツールを代替できるほか、パワフルなのでちょっと書くだけで様々な処理が行えることを示しました。
これを期に日常の仕事をより豊かにするために`perl`をもっと活用してみては如何でしょうか。

最後に`perl`のワンライナーでよく僕が使うdirty hackを紹介して終わりにします。
`Foo`を含む行をカウントするワンライナーです。

```bash
... | perl -nle '$foo++ if /Foo/}{print $foo'
```

答え合わせは `-MO=Deparse` でどうぞ。
homebrewでrabbitmqのクリーンアップ

homebrewでrabbitmqのバージョンアップをしようと思ったら、かなりつまづいたので、homebrew環境における環境のクリーンアップに簡単に触れておく。

## 発生した前後関係

```
brew upgrade rabbitmq
```

でrabbitmq3.6.6 -> rabbitmq3.7.0へのアップグレードを行いました。また、そこから、gitを使って、3.6.14や3.6.12などのバージョンを入れ、複数の環境が混在する環境が出来上がってしまっていました。

## エラーの内容

```
brew services start rabbitmq
```

では正常にスタートしたように見えるのですが、/usr/local/sbinの下にあるユーティリティを使うとnodeが動いていないことがわかる。実際に、brewを使わず、rabbitmq-serverだけを動かすと

```
$ /usr/local/sbin/rabbitmq-server

  ##  ##
  ##  ##      RabbitMQ 3.7.0. Copyright (C) 2007-2017 Pivotal Software, Inc.
  ##########  Licensed under the MPL.  See http://www.rabbitmq.com/
  ######  ##
  ##########  Logs: /usr/local/var/log/rabbitmq/rabbit@localhost.log
                    /usr/local/var/log/rabbitmq/rabbit@localhost_upgrade.log

              Starting broker...
{"Kernel pid terminated",application_controller,"{application_start_failure,rabbit,{{schema_integrity_check_failed,[{table_attributes_mismatch,rabbit_exchange,[name,type,durable,auto_delete,internal,arguments,scratches,policy,operator_policy,decorators,options],[name,type,durable,auto_delete,internal,arguments]}]},{rabbit,start,[normal,[]]}}}"}

Crash dump is being written to: /usr/local/var/log/rabbitmq/erl_crash.dump...done
```

上記のように"Kernel pid terminated"というエラーが出ます。/usr/local/var/log/rabbitmq/err_crash.dumpをみても、同じエラーが見つかるだけでこれ以上の情報がでてきません。

/usr/local/var/log/rabbitmq/rabbit@localhost.logというファイルもあり、こちらを見ると、"schema_integrity_check_failed"というエラーメッセージが出てきます。

結局、バージョン情報が錯綜していることが原因っぽいので、brewでのrabbitmqのクリーンインストールをする必要が出てきました。

## brewにおけるrabbitmqのクリーンインストール

Stack Overflow等で解決策を探すも、情報が色々なところに散らばっていたので、トライアンドエラーで環境をクリーンアップすることに・・。結局、以下を実行したらうまく動きました。

```
$ brew uninstall rabbitmq
$ brew cleanup -s
$ rm -rf /usr/local/var/rabbitmq/
$ rm -rf /usr/local/var/lib/rabbitmq
$ rm -ff /usr/local/var/log/rabbitmq
$ rm -rf /usr/local/etc/rabbitmq
$ brew install rabbitmq
```

ポイントは、/usr/local/var（特にlib）の下に色々と展開されていて、それらはuninstall後も残ること。これらをちゃんと削除しないと上記のようなエラーが出る場合があるようです。

```brew cleanup -s```は一回ダウンロードしたインストールパッケージを削除するコマンド、これを実行するとパッケージのダウンロードから再度やり直すことができます（が、今回のエラーとは関係なさそうです）。

他のパッケージでもクリーンインストールしたいときに参考になるかも。。。
Swiftで困った時に役立つ機能別記事一覧

##きっかけ
正直ブラウザでサイトを開きまくるのは非効率だし、一覧の方が助かりますね〜、と思って作りました。開発するたびに更新すると思います。


##UINavigationBar
 - UINavigationBarのカスタマイズ。背景の透明化など
https://qiita.com/usagimaru/items/7f5c63d5cb75d8c479ed

 - この記事はNavitationBarのボタン一覧があってとても助かりました
http://blog.kazuya.co/ios/2014/07/08/ios-cutom-navibar.html
ソースからビルドしたMySQLをmake installせずに起動する

特定バージョンの動作確認をしたいときなど、`make install`せずにMySQLを使う方法。

```
$ cd mysql-5.7.20/
$ cmake -DDOWNLOAD_BOOST=1 -DWITH_BOOST=$(pwd)/boost
$ make -j4
```

でビルドして

```
$ sql/mysqld --user=$(whoami) --datadir=$(pwd)/data --lc-messages-dir=$(pwd)/sql/share --initialize
$ sql/mysqld --user=$(whoami) --datadir=$(pwd)/data --lc-messages-dir=$(pwd)/sql/share --port=13306
```

で13306番ポートで起動。別のシェルから

```
$ client/mysql --port=13306 -u root -p
```

で接続。パスワードは`--initialize`時に自動生成されているもので入った上で、適当に変更する。

```
SET PASSWORD = PASSWORD('12root34');
```

mysqldを終了させるときはkillコマンドを使う。
Laravelでフラッシュスコープってあるのか調べてみた

# はじめに
このページは [Laravel Advent Calender 2017](https://qiita.com/advent-calendar/2017/laravel) 17日目の記事です。
期日守らなくてすみません・・

PHPをはじめて7カ月、Laravelも7カ月ということで、
はじめに思った「入力フォームって共通的に処理できないの？」のやり方がようやく判ったのでその共有をします。

かなりポエム入ってます。

# Laravelをいじりはじめて気持ち悪かったこと
作成画面と編集画面とで入力フォームがそれぞれ存在する。
今までの環境（Java）だと、header/footer用のjspから入力フォーム部分のjspを読み込ませて、表示しているだけだったので、
PHPって割と気持ち悪い構成だなーってずっと思ってました。

# 腑に落ちない
作成画面と編集画面で入力フォームを分けてるけど、
フォームリクエストバリデーションでバリデーションエラーになると、エラーの入力値が入力フォームに復元される。
このときはoldヘルパーってものから復元されるのかーふーん程度で飛ばしてた。

で、最近は業務外での資料作ったりとか余裕も出てきたので、
このoldヘルパーの正体を探してみることにしたわけです。

このoldヘルパーはフラッシュスコープだよなーとは調べはじめる前から思ってて、
そもそもPHPってフラッシュスコープって言葉を聞いたことがないけど、あるのか？
ってのが気になって、PHPのフラッシュスコープについて調べてみることにしました。
（oldヘルパーとかもうどうでもよくなってる）

# 低いぐぐり力でぐぐってみた
## 検索ワード
* フラッシュスコープ php
* flashscope php
* フラッシュスコープ Laravel
* fla・・・

なぜかspringとかの話題ばかりで出てきて、ぐぐるの時間の無駄そうだと思ったので、Googleで探すのやめた。
（ちなみに、フラッシュメッセージの話題は出てくる）

# Laravel APIドキュメントを雑に検索する
https://laravel.com/api/5.5/index.html

flashなんて単語はどこにも出てこない。

# 基礎に立ち返って調べる
フラッシュスコープはリダイレクトも含んだリクエスト内で有効なセッションスコープってことで、
Laravelのsession周りのメソッド調べてみること。

そしたら、速攻でドンピシャなメソッド発見。

```php:controller
request()->session()->flash($key, $value);
request()->session()->flashInput($array);
```

中身見てみると、キー「_old_input」に何かやってるから、oldってのもこれっぽい。

で、実際に使ってみると復元された。
コードは以下みたいに書くだけ。

```php:controller
request()->session()->flashInput($eloquent_model->toArray());
```

これでbladeテンプレート内で変数の展開を自分でしなくて良くなり楽に。
また、当初の入力画面と編集画面でそれぞれフォームを持つという気持ち悪い構成を取らなくて済むので、気分が晴れた。
(ide_helperがちゃんと動いてれば、もっと簡単に調べられたけど・・・)

# 終わりに
フラッシュスコープ使うと、開発が楽になるよってのをお届けしました。
ここは一例でもっと使うのにいい場面もあると思います。

こういうテーストで書きたいように書くのも久しぶりなので書いてしまうと、
PHPさん、フラッシュスコープってあるんだから、フラッシュスコープって言葉を使って欲しい。
（実際この一言を言いたかっただけで書いた記事）

手元の最古環境のLaravel5.2で既にこのメソッドは存在しているので、上手く活用してください。
ニアショアvsオフショアweb開発

デジタルクエストのアドベントカレンダー 18日目、綿引が担当いたします。

# デジタルクエストの事業
弊社デジタルクエストは、元々自社サービス運営・開発を生業としておりましたが、今年1年は大きく舵を切り、受託開発事業に注力して参りました。
ありがたいことにたくさんの開発案件のご相談をいただきつつも小規模の体制ですので、お請けできるキャパシティに限りがありました。
そこで、外部のパートナーを開拓・実践してみた話を書かせていただきます。

# 外部ベンダー選定
規模の大きい案件であれば、十分な実績・万全の体制が構築できる企業さまにお願いをするのが良いのでしょうが、プロジェクト自体が小規模 (エンジニア1or2名) のものも多く、また、単価の観点でもできるだけ努力をしなければなりません。
その前提に立ちながら、パートナーシップを結ぶからには両社・両者が同じ心持ちで臨めるような企業さまを見つけることに専心しました。
→ **要は弊社と同様に小規模ながら開発を軸に事業展開されている会社を探した！**ということです。

# 「そうだ! 仙台へ行こう!」 ニアショア開発
2017年の春先から仙台の企業さまと縁あってお仕事を一緒にさせてもらっています。
### 進め方
毎朝11時のデイリースタンドアップ
**チャットワーク Live**のビデオ通話で同じかんばんを見ながら実施

### メリット
- エンジニアリソース供給
- リソース増減の調整がより柔軟に可能
- 首都圏のエンジニア単価相場より**若干**低い

### デメリット
- 温度感の共有 (コミュニケーション) の難度が高い
- doneの定義 ... 依頼タスクの完了を一つ一つ定義しないとゴールがブレる

### 実際やってみて
仙台⇔東京 は「ちょっと行ってくる！」ぐらいの距離・費用で往復が可能なので、定期的な面と向かってのコミュニケーションを実施しました。
また、人づてに話を聞けば聞くほど、「**他人事感**」が増していきます。そのため、一緒にお客さんの話を聞いてもらったり、要件定義のフェーズから一緒に入ってもらうことで、プロジェクトの進行が驚くほどスムーズになりました。
普段から如何にコミュニケーションに頼っているかを痛感しながらも、上手く進める方法について1つの答えが出たのが収穫だと思っています。
仙台で食べたタン刺しも収穫の1つでした！

# 「そうだ! ベトナムへ行こう!」 オフショア開発
2011年頃に属していた会社で手痛い失敗を目の当たりにしていたこともあり、オフショア・ベトナムにネガティブなイメージを持っていました。
チャレンジするつもりもあまりなかったのが本音ですが、縁あって2017年の夏から弊社の自社サービス (二桁万円程度) の発注を皮切りに、一緒にお仕事をさせていただいてもらっています。

### ベトナムに行ってみた
開発現場を見て、直接話をしたかったので、ベトナム (ハノイ) に行ってきました。
働いている方々はとても真面目な印象で、日本よりもハラスメントには厳しいようです。
また、昼休みが少し長く、その間に自席で昼寝するんだそうです。
街の中はマスクなしでは歩けないぐらいの排気ガスでしたが、気候も暖かく、野菜中心の食事も健康的な気がしました！
（パクチーが苦手なのでとても苦労しましたが…）
ちなみにハノイの方のスマートフォンを覗いてみると、エンターテインメント系のアプリはあまり使われていないようでした。
(きっとゲームとかこれからですね！)

### 進め方
言葉の壁がまざまざと存在しているので、ニアショアとは比較にならない難度です。
また**日本独特の表現**が通じないのも当たり前の話なので、仕事の依頼の仕方を工夫することに時間を割かなければ成功させることは難しいでしょう。
英語のデキる方が何人もいたので、できる限りドキュメントには英語での説明を入れ、ソースコードのレビューを実施することで、ある程度の品質は担保できると思います。
国内のコストとは雲泥の差がありますが、的確なアウトプットを要求するための努力・コミュニケーションのコストを考えると、必ずしも高パフォーマンスとは言えません。

### 理想
5名以上の稼働が見込まれるプロジェクトを、現地にいってリードしながらやり切るのが最も効率的でパフォーマンスが高いでしょう。
社員の誰かがベトナムに住んでくれる奴を探すところがネックです。

### 圧倒的なメリット
様々なスキルセットを所有しているエンジニアが在籍しているため、開発言語によって案件受注に躊躇いがない点にとても魅力を感じています。
当然ながらリソースのキャパ拡大も日本より速いです。 (中期的に見ると辞めてしまう方も多いですが)

# 今後
20名弱の規模の弊社ですが、ニアショア・オフショアでの開発によって、キャパシティの拡大に成功しています。
ニアショアもオフショアもやり方は様々あるでしょうし、一概にどちらが良いかの答えはありません。
ただ一つ言えることは、誰と仕事をするにしても、**相手が仕事をし易い環境を構築する努力**が成功の確度を上げてくれると思っています。

弊社では、この取り組みを更に前進させていくために、積極的に外国籍の方の採用に踏み切っています。
英語のデキる日本人ってスゴい！ってなりますが、海外の方は当たり前のように英語で会話ができるので、なんだか恥ずかしくなってしまいました。
だからといって、英会話勉強しよう！とかデキもしないことは宣言せずに、現地の言葉でコミュニケーションのできる人材を積極採用して、より円滑なパートナー企業との協業を軸に、規模を拡大していきます！

### web系の開発案件 ご相談お待ちしております！！
vagrantにCentOS7を入れる

久しぶりvagrantの環境を作ろうとしたら忘れてたからメモ

1. Vagrantfile作成（vagrant init）
2. vagrant環境構築作成（vagrant up）
3. vagrant環境接続（vagrant ssh）

##Vagrantfile作成（vagrant init）
今回はpythonのお試し環境を作る為なので、~/develop/pythonを作成
pythonディレクトリ配下で下記を実施
`vagrant init`

#vagrant環境構築作成（vagrant up）

https://www.vagrantup.com/
このサイトからboxの情報を取得
<img width="793" alt="スクリーンショット 2017-12-18 12.10.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/8b9a2fb2-93a0-b1cb-98bc-6732eb71dd62.png">

3つのボタンの右にある「FIND BOXES」をクリック
下記画面の「centos」と入力して検索。今回は「bento/centos-7.2」をクリック
<img width="1234" alt="スクリーンショット 2017-12-18 12.13.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/7c1ad658-cda0-442b-2814-cd2cb2b97e84.png">

下記表示が出る。「vagrant init」で作成したVagrantfileに「config.vm.box」という箇所があるので、表示と同じ様に修正
<img width="743" alt="スクリーンショット 2017-12-18 12.17.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/320cdd45-a0c0-a901-a36f-98b95a67c3db.png">

##vagrant環境構築作成（vagrant up）
下記コマンドでエラーが出なければOK
`vagrant up`

vagrant環境接続（vagrant ssh）
下記コマンドでvagrant環境に接続
`vagrant ssh`

下記コマンドでOSの確認
`cat /etc/centos-release`
CentOS Linux release 7.2.1511
と表示されました！

これでCentoOS7を入れるところまでは完了！
androidエミュレータ内のSQLiteにADBでアクセスする方法

メモ書き。
adbの環境変数パスが通っていることを前提。
コマンドプロンプトにて以下コマンドを順に実行。

```cmd.exe
 // 初回のみでOK、文字コードの設定(s-jis->UTF-8)
 chcp 65001

 //ルート権取得 たまに外れるので毎回しておいたほうが吉
 adb root

 //adb起動
 adb shell

 //dbレコード格納フォルダに移動(権限でダメなときはrootちゃんと取ろう)
 cd data/data/{パッケージ名}/databases

 //sqlite起動(名前間違ってても起動する、注意)
 sqlite3 {db名}
```

sqlite> とコンソールに出たら後はSQL打ち込むだけ。
終端文字は";"、終了したいときは".exit"でadbに戻る。
なんかセミコロン打っても終わらないときは
ダブルクォート、シングルクォートが奇数個クエリ文にはいってないかを確認。

adbは基本リナックスもどきらしい(cygwinとも違う)のでlsコマンドとか使える。
が、それよりなにより過去に打ち込んだSQLを上下で呼び出させてほしい。
Docker-composeでJupyterLabを簡単構築

## 1.目的
JupyterLabをdocekr-composeでサクッと立ち上げる。自分用のメモ。
dockerもdocker-composeもはじめて数日なので他によりよい方法はあるのかもしれない。

Docker導入までは以下を参照。
https://qiita.com/tsnb/items/d10d2770c08abc60b500

## 2.前提

- ホスト（物理サーバ）
- OS：CentOS Linux 7 (Core)
- docker Ver：17.09.0-ce
- docker-compose Ver：1.17.0

## 3.docker-compose.ymlを書く

```bash:docker-compose.yml
version: '3'

services:
  jupyterlab:
    image: jupyter/tensorflow-notebook:latest
    user: root
    environment:
      NB_UID: 1000
      NB_GID: 100
      GRANT_SUDO: "yes"
    volumes:
       - "./work:/home/jovyan/work"
    privileged: true
    ports:
      - "8888:8888"
    restart: unless-stopped
    command: start.sh jupyter lab --NotebookApp.token=''
```

詳細なtensorflow-notebookに関する情報は以下を確認する。
https://github.com/jupyter/docker-stacks/tree/master/tensorflow-notebook

```bash:コメント付き
# docker-composeのバージョン、最新は3
version: '3'

services:
  jupyterlab:
    # 今回はこのtensorflow-notebook:latestイメージを利用する。
    # JupyterLabが既にインストール済。
    # pipで何か追加したい場合などはDockerfileを書く。
    image: jupyter/tensorflow-notebook:latest
    user: root
    # URLに書いてある設定を読んで以下のenvironmentを書く。
    environment:
      NB_UID: 1000
      NB_GID: 100
      GRANT_SUDO: "yes"
    # コンテナの/jobyan/work以下をホストの./workにおいてデータ永続化する。
    volumes:
       - "./work:/home/jovyan/work"
    privileged: true
    # (ホストポート:コンテナポート)
    ports:
      - "8888:8888"
    restart: unless-stopped
    # パスワード設定などとりあえずめんどくさいのでtokenを空にしてすぐ使えるようにする。
    # (起動テスト用なので実際にはパスワードなどを設定してください)
    command: start.sh jupyter lab --NotebookApp.token=''
```
Apple TVで社内ツールアプリ作成のススメ - tvOS -

[**tvOS Advent Calendar 2017**](https://qiita.com/advent-calendar/2017/tvos) 18日目担当の @dekatotoroです。
**[AbemaTV](https://itunes.apple.com/jp/app/abematv/id1074866833?mt=8)**のiOSアプリやtvOSアプリを開発しています。

### 突然ですがみなさん**Apple TV**のアプリ開発していますか？

最近は様々なサービスが**Apple TV**向けにもリリースされてきましたが、まだまだ業務で**Apple TV**のアプリを開発する機会はなかなかないのではないでしょうか。

サービスとして**Apple TV**向けに開発することはiOSに比べると少ないと思いますが、社内向けに**Apple TV**でモニタリングツールなどを作ってみるのはどうでしょうか。特に動画は非常に相性が良いのでおすすめです。

今回は**AbemaTV**で活用している**Apple TV**のツールアプリを紹介します。

# **AbemaTVのtvOSツールアプリ**
**AbemaTV**では**Apple TV**のアプリをリリースしていますが、それ以外に社内用の**Apple TV**のツールアプリをいくつかつくっています。ランキングや視聴数のモニタリングアプリだったり、CDNとORIGINリクエストを比較した再生監視用のアプリなどです。

キャプチャをいくつか載せたいと思います。
※ **数字や動画は適当なものに差し替えており実際とは異なります**

#### **視聴数 / ランキングのモニタリングアプリ**
![monitor_original.gif](https://qiita-image-store.s3.amazonaws.com/0/48971/06f9e60f-ea1f-6052-de4e-fad99316179f.gif)

#### **視聴数 / ランキングのモニタリングアプリ** （上記のUI違い）
![ranking_monitor.gif](https://qiita-image-store.s3.amazonaws.com/0/48971/12b52081-8921-0a39-f891-cff2190a38ee.gif)

#### **CDNとORIGINリクエスト再生比較用アプリ**
![monitor_origin_vs_cdn.gif](https://qiita-image-store.s3.amazonaws.com/0/48971/219a944b-98d7-743e-cdcf-8e26985360f8.gif)

#### **チャンネル再生チェック用アプリ**
![9slice.gif](https://qiita-image-store.s3.amazonaws.com/0/48971/59cd23f4-f100-8e66-8311-1de9461e3482.gif)


# **まとめ**
いかがでしょうか。
**AbemaTV**ではオフィスの天井吊りモニターや各所のモニター、イベントなどにもこれらの**Apple TV**アプリを活用しています。
モニタリングツールなどはwebでつくることが多いと思いますが、tvOSでつくってみるのも一興ではないでしょうか。
かっこいいものをつくると開発チームのテンションも上がると思います :smile: 


[**tvOS Advent Calendar 2017**](https://qiita.com/advent-calendar/2017/tvos) 明日は @hagacotton さんです！
Google App Engineはリージョンの変更ができない

仕事でGoogle App Engine(GAE)を使ってるのですが、`us-central`以外にアプリのデプロイができなくて色々調べていたら、以下のような記事を発見しました。

> 1. Can’t change region

> Careful, because once you create your first app engine you can NEVER EVER move it to a different region. I had mistakenly placed mine in us-central only to later realize my users are mostly in us-east.
Sure, I can create another project and be more cautions but Google forces you into this long, useless app tutorial that makes it unclear if you are just starting out.

https://lugassy.net/things-that-sucks-in-google-app-engine-843fe7affc1d

どうやら、GAEでは最初にアプリを作るときにリージョンの選択画面があるようで、
前任者(既に退職)がその画面で`us-central`を選択してしまったようです。
うちのサービスはアジア向けなので、`us-central`だとレイテンシが...(泣)

## この画面

自分のプライベートアカウントでリージョン選択の画面を確認してみました。

![Screen Shot 2017-12-18 at 11.15.08.png](https://qiita-image-store.s3.amazonaws.com/0/172612/fccbca95-8d3e-c2ba-0b79-f3ab2bf7f085.png)


ちゃんと注意書き書いてありますね、前任者は読まずに`us-central`のまま[次へ]をクリックしちゃったのでしょうか...
(デフォルトで`us-central`が選択されているのもどうかとは思いますが)

## 解決策
Googleの担当者に問い合わせたところ、以下のような解答をいただきました。

```
リージョンについては一度作成いただいた後の変更が出来なくなっております。
カスタムドメインを設定いただきますとエンドポイントの変更無しでgaeプロジェクトの切り替えをする事も可能です。
```

つまり、そのプロジェクトは諦めて他のプロジェクトを作ってそちらにデプロイしてくれという事ですね...
あまりこんなミスをする人はいないと思いますが、GAEを使い始めるときは気をつけましょう！
ionic androidビルドで、「com.android.build.api.transform.TransformException: com.android.dex.DexException: Multiple dex files define」エラーに遭遇したら試してみて

stackoverflow感謝。

今回、ionicでandroidをビルドしようとしてぶつかった問題と解決について。
ググるとバージョンのちがいによって起こるらしいのだけど、なかなか解決しなかったので、私が採用した解決法です。

## バージョン

```
cli packages:

    @ionic/cli-utils  : 1.19.0
    ionic (Ionic CLI) : 3.19.0

global packages:

    cordova (Cordova CLI) : 7.1.0

local packages:

    @ionic/app-scripts : 3.1.5
    Cordova Platforms  : android 6.3.0 ios 4.5.4
    Ionic Framework    : ionic-angular 3.9.2

System:

    ios-deploy : 1.9.2
    Node       : v9.2.0
    npm        : 5.5.1
    OS         : macOS High Sierra
    Xcode      : Xcode 9.2 Build version 9C40b

```

## androidでビルドが通らない。

```
ionic cordova build  android --debug
```

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lcom/google/android/gms/internal/zzex;
```

## バージョンのミスマッチにより発生する


> This issue is caused by a mismatch of versions of the Google Play Services library specified by two or more plugins. 

[cordova \- Multiple dex files define Lcom/google/android/gms/iid/zzc \- Stack Overflow](https://stackoverflow.com/questions/44550703/cordova-multiple-dex-files-define-lcom-google-android-gms-iid-zzc)

- 以下のプラグインを追加して

```
cordova plugin add cordova-android-play-services-gradle-release
```

- ビルド

```
ionic cordova build  android --debug


BUILD SUCCESSFUL

Total time: 28.126 secs
Built the following apk(s):
        /Users/bohebohechan/（略）/apk/android-debug.apk

```

できた。

かなりググってようやく見つけたので、お役に立てば。
Windows10のSecureTime機能の無効化方法

Windows10 1511から追加されたセキュリティ機能により、ドメイン環境下のWindows10クライアントの時刻同期がうまく動作しなくなる場合がある。

## 作業手順
コマンドプロンプトを**管理者権限**で起動し、以下のコマンドを実行する。

```bat:Cmd(Administrator)
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config /v UtilizeSslTimeData /t REG_DWORD /d 0 /f
```
イーサリアムのノードをAPIとして提供してくれるinfura.ioを使ってみる

## 課題
- 一般的に、イーサリアムのブロックチェーンと通信するためには、自分で何らかのサーバーにイーサリアムのクライアントを入れて、常に最新のブロックチェーンのデータを同期しておく必要がある。
- 本番で使う場合は、おそらく稼働率などを保証するため、ちゃんと複数ノードにする必要があったりする
- https://infura.io は、その課題を解決してくれるサービスである。

## 使ってみる
- 手順的には [Ropstenのテストネット上でERC20トークンを作成・送付してみる - ペパボテックブログ](https://tech.pepabo.com/2017/12/06/erc20-token-on-ropsten/) を参考しています。
- 確認したいことは、たとえ自分のサーバーからトランザクションを送信する時、普通は自分のサーバにある`JSON RPC`と通信し、`sendTransaction`メソッドを使っていました。ただ、毎回`unlock`しないと行けないので、infura.io 場合はどうなるかを確認したい

## コントラクトのデプロイ周り
- 参考記事のまんまですが、 `truffle` を使ってデプロイする場合、`truffle.js` で設定できる

```javascript
// ROPSTEN_MNEMONICとINFURA_ACCESS_TOKEN環境変数は事前時設定されている前提
// HDはどの言葉の略語だろう。。。
var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = process.env.ROPSTEN_MNEMONIC;
var accessToken = process.env.INFURA_ACCESS_TOKEN;

module.exports = {
  networks: {
    ropsten: {
      provider: function() {
        return new HDWalletProvider(
          mnemonic,
          "https://ropsten.infura.io/" + accessToken
        );
      },
      network_id: 3,
      gas: 500000
    }   
  }
};
```

## 自分のアカウントから送金する
- ユースケースで言うと
    - Slack上で動くボットを実装したい
    - `@bot send to 0xBA333d667eECA936b02B614fDD805028E5B2C38A 5`のように叩かれると送金したい
- 自分でノード運用する場合は、`unlockAccount`実行してから、`sendTransaction`すればよいが、**ノードが自分で運用してセキュリティ問題がないこと**が前提である
- https://infura.io の場合は、その前提がないので、上記で行けない
- 解決方法： [sendRawTransaction](https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethsendrawtransaction)リンク先のコードのまんまですが、下記の感じで、トランザクションデータをサインしてから、`sendRawTransaction`を使う

```javascript
var Tx = require('ethereumjs-tx');
var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')

var rawTx = {
  nonce: '0x00',
  gasPrice: '0x09184e72a000', 
  gasLimit: '0x2710',
  to: '0x0000000000000000000000000000000000000000', 
  value: '0x00', 
  data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'
}

var tx = new Tx(rawTx);
tx.sign(privateKey);

var serializedTx = tx.serialize();

//console.log(serializedTx.toString('hex'));
//f889808609184e72a00082271094000000000000000000000000000000000000000080a47f74657374320000000000000000000000000000000000000000000000000000006000571ca08a8bbf888cfa37bbf0bb965423625641fc956967b81d12e23709cead01446075a01ce999b56a8a88504be365442ea61239198e23d1fce7d00fcfc5cd3b44b7215f

web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function(err, hash) {
  if (!err)
    console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385"
});
```

## まとめ
- トランザクションさえセキュアで送信できれば、他の処理はたぶん問題ないと思われるので、運用が面倒と思うなら、 infura.io を使うのは良いと思います。

## 参考記事
- [Ethereumホスティングサービス「Infura」の使い方とは？ - ワクワク仮想通貨(暗号通貨) 〜 ICOやらbitcoin(ビットコイン) Ethereum(イーサリアム) etc...](https://wakuwaku-currency.com/virtual-currency/ethereum/about-use-hosting-service-infura.html#InfuraJSON-RPC)
- [Ethereum上のトークンを送金するWebアプリを作ってDecentralizedな方法で公開してみる - lotz84の日記](http://lotz84.hatenablog.com/entry/2017/12/13/081920)
- [tiperc20: Slack上でERC20トークンを送りあってコミュニケーション - ペパボテックブログ](https://tech.pepabo.com/2017/12/09/tiperc20/)
- [Infura.io サポートするAPI Reference](https://infura.io/docs/#supported-json-rpc-methods)
私の英語勉強法（30歳から勉強開始・海外在住経験なし・TOEIC920点）

[ヴァル研究所 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/val)の19日目です。

エンジニアのご多分にもれず、私もけっこう長い間英語を勉強してきました。最近はわりと成果も出てきて、勉強していてよかったと思えることも増えているので、自分はこうやってきたという経歴を紹介したいと思います。


# 私の英語力

TOEIC 920 / 990（Listening 450 / Reading 470）

## Reading
けっこう読める。
ここ1，2年、身構えること無く気軽に英語を読めるようになった。

## Writing
まあなんとか伝えられる。
サポートに問い合わせとかはできる。

## Listening
字幕なしで映画は理解できない。
Youtubeの技術系の動画ならわりと理解できる。

## Speaking
言いたいことの1割も言えない。
なので英語で何かしゃべってくれと言われても恥ずかしくてできないです。

# 英語を学ぶメリット

- ネット上の情報量が段違い
- 感覚的に言うと日本語の10倍
- 質も数段上

# どうやって学んだか

## 英会話スクール

- 一念発起するために入会
- 高い
- 週1回1時間のレッスンで年間20万以上（？）
- 内容薄い
- 金がかかるので、自分に本気を出させるためにはいいかも

本格的に英語の勉強を始めようと決意した時、自分を背水の陣に置くつもりで入会しました。内容は予想通りというか、あまり効果なかったと思います。
ただし、テキストや教える内容の取捨選択は非常によく出来ていると思いました。

## 文法の復習（オススメ！）

- [フォレスト](https://www.amazon.co.jp/dp/4342010453/)やっとけ
  - 文法が得意な人でも、きっと再発見がある
- 文法の勉強は多読と並行してやるとよい
  - 「あ、これフォレストで見た文法だ！」

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79394/5d271748-755c-3953-9030-9e32d05d8525.png)

## 単語帳

- つけてました
- 本を読んでいて知らない単語が出てきたら記入
- 週一くらいで見直して復習
- どれくらい効果あったか疑問
- ただし単語力は絶対必要なので、[DUO](https://www.amazon.co.jp/dp/4900790052/)とかやるのはいいと思います

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79394/747ffd66-ff13-f11d-a882-e0101953edc3.png)


## 英会話カフェ（オススメ！）
- LeafCupとか
- 外国人1人＋日本人客数人でフリートーク
- 英米以外の色んな国の人がいて、色んな話を聞ける
- 楽しい！
- 1時間800円くらい
- 1時期は毎週末土日とも行って、6時間くらい居座っていた
- いい店ほどつぶれてしまう…
- 新大久保のTake One’s Timeとか、恵比寿のコムインとか…


## 発音記号　超大事

- 辞書を見るだけで正しい発音が分かるようになる
- 義務教育で教えるべきだと思う

## 音読（オススメ！）
- 文章を声を出して音読する
- 同じ文章を何度も読む
- 暗記するまで
- 専門家もおすすめする勉強法
- [オーディオ版ドラえもん](https://www.amazon.co.jp/dp/4092270313)
  - 全２巻の全セリフを覚えました
  - 似たようなシチュエーションになったとき、セリフが自然と口から出てくる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79394/bd725d82-17e0-e44b-c219-9ac876de21a3.png)


## 多読（オススメ！）
- 簡単な本をたくさん読む
- 子供向けの本
  - ジュンク堂とかいくとそういうコーナーがある
  - わりと面白い
 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79394/6860ee97-617a-a14b-fcc4-ab7f3c694aa5.png)


## Skype英会話
- フィリピン人と1対1で
- コスパはすごくいい！
- 全然話せない状態で始めると、本当になんにも話せないと思う。ある程度の会話力が必要
- 1対1がちょっとプレッシャー
  - プレッシャー感じない人にはかなりオススメ



## 日記を書く
- [Lang-8](http://lang-8.com/)
- 外国語で日記を書いて、添削してもらうサイト
- 代わりに日本語の日記を添削してあげる
- 英語ネイティブは少ない
- 日本人は多い
- 面白い記事を書かないと（あるいは女性で写真を載せないと）添削してもらえないかも

## おすすめサイト

[Reddit /Programming/](https://www.reddit.com/r/programming/)

- はてなブックマークみたいなもの
- 1日に上がってくる記事の量がちょうどいい
- 本文が分からなくても、コメントで何言ってるか分かることも
- レベル高い
- タイトル見て興味のある記事を読む

# まとめ

- フォレスト
- 音読
- 多読
- 英会話カフェ

がオススメ！