OmniAICreator/Qiita-1.07M huggingface dataset:
AndroidStudio3.3にスマイリーフェイスが出現！（小ネタ）

**AndroidStudioが3.3になったら、一部環境のみ右下にスマイリーフェイス（日本ではニコちゃんマーク）が出現！**

![image.jpg](https://qiita-image-store.s3.amazonaws.com/0/252283/5e7ce350-3145-ba27-f65d-ae7881c18b0c.jpeg)

気になって調べたところ、ちゃんと記載がありました。（読んだはずが頭に入ってなかった・・・）
https://android-developers.googleblog.com/2019/01/android-studio-33.html


###IDE User Feedback
AndroidStudioの開発を応援するために匿名情報をシェアしてくれている人にだけ表示。
ボタンを押してFeedbackを頂戴ということです。
プライバシーポリシーはこちら
https://policies.google.com/privacy

笑顔を押すと

```
Thanks for the feedback!
We are glad to hear you are having a positive experience with Android Studio!
```

悲しい顔を押すと

```
Thanks for the feedback!
We are sorry to hear you are having problems using Android Studio. Please share detailed feedback.
```

が表示され、リンクをクリックすると
GoogleのIssue Trackerへジャンプします。

###表示設定
Settings dialog (Preferences on a Mac), navigating to Appearance & Behavior > System Settings > Data Sharing, and checking Send usage statistics to Google.
設定後再起動すると表示が切り替わります。

こういう匿名情報送る系は送らない設定にするんですが、遊び心があって表示しておきたくなりますね:smiley:
仮想スクロールのすヽめ

平日の早朝に道玄坂を下るアベックに破滅と滅亡を。どうも、[@neer_chan](https://twitter.com/neer_chan)です。

皆さん、仮想スクロールしてますか？

## 概要

- 仮想スクロールとは
- 仮想スクロールの仕組み
- 仮想スクロールの魅力

前提として、縦スクロールの話をします。

## 仮想スクロールとは

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.amazonaws.com/0/192145/6d101376-8577-adf1-e58a-80d118ab983c.gif)

GIFの通り、見えている範囲(+α)のみレンダリングするもの。
要は、ロケット鉛筆みたいなものです。（絶対に違う）

## 仮想スクロールの仕組み

###イカれたメンバーを紹介するぜ！

![parts.png](https://qiita-image-store.s3.amazonaws.com/0/192145/545bc13c-ba7e-4a3a-79ca-5d413018f043.png)

1. 見える範囲を指定するためのDiv
2. スクロールする高さを指定するDiv
3. ListItemを置くUnorderdList
4. いつかの、いくつかのきみとListItem

以上の4つが登場するメンバーだ！
ちなみに、通常のスクロールの場合は2の役割を3が行う感じになります。

また、以下の要素をあらかじめ指定する必要があります。

1. 見える範囲に表示する4のListItemの個数（あるいは1のDivの高さとかでも大丈夫）
2. 4のListItemの総数
3. 4のListItemの高さ

### スクロールした時の動き

![scrolling.png](https://qiita-image-store.s3.amazonaws.com/0/192145/b3942d71-f825-ae65-3fff-e72bbf940485.png)

このようなイメージです。
要は、**スクロールする時に2のDivが上に移動し、スクロールした量に応じてインデックスを割り出して、インデックス x リストアイテムの個数分（実際はもうちょっと少ない）だけ3のULが下に移動します**。


インデックスに関しては、 `表示すべき最初のリストアイテムの番号` 的なもので、以下のような感じで求める。

```js
// スクロール量
const scrollPosition = e.currentTarget.scrollTop;
 
// スクロール量 / ListItemの高さ で インデックスを求める
const index = Math.floor(scrollPosition / itemHeight);
```

細かいところもう少しあるけど、本質的ではない（魅力を知らせたい）ため、割愛します。

## 仮想スクロールの魅力

さて、本題です！
通常のスクロールと比べると、やや難易度が上がる仮想スクロールについて、どのような魅力があるのでしょうか。

それはズバリ、**レンダリング速度**です。

### 計測する

計測パターンとして

- 仮想スクロール - リストアイテム100, 1000, 10000個
- 通常スクロール - リストアイテム100, 1000, 10000個

の6パターンを試します。

### 計測結果

3分クッキングの「ここで昨日あらかじめ仕込んでおいた〜...」みたいなノリですぐ結果見ていきましょう。

　はいドン！

![perform.png](https://qiita-image-store.s3.amazonaws.com/0/192145/b7b10b5c-8afa-dabf-d6f7-9987f4bf1fb2.png)


種別と個数|100|1000|10000
-----|-----|-----|-----
仮想スクロール|2ms|3ms|3ms
通常スクロール|10ms|80ms|850ms

超超超ざっくりこんな感じですね
どうでしょうか、結果からは下記の2点がわかると思います。

1. 仮想スクロールの場合は、レンダリング時間にあまり変化がない
2. 通常スクロールの場合は、レンダリング時間がリストアイテムの個数だけ増えていっている（1倍,10倍,100倍）

圧倒的に仮想スクロールは早いですね！　
これこそが仮想スクロールの魅力です！

## 無限スクロールとの違い

レンダリング速度の改善という意味では、近いところに無限スクロールがあります。
無限スクロールとは、ツイッターのタイムラインのように適宜読み込んでいくものですね。

大きく違うところは、総数がわかるかどうかというあたりです。
そう考えるとそれぞれの用途は

無限スクロール | 仮想スクロール
--------|--------
俯瞰して見る必要はない|俯瞰して見る必要がある

こう分かれます。

ですので、仮想スクロールを選択する場面としては、フォームなどであらかじめ用意しておいた選択肢から選んでもらう時などですね。

## おわりに

実際は同じような感じで色々と実装方法あります。

Reactであれば、 `react-virtualized` や `react-tiny-virtual-list` のようなモジュールで超簡単に実装できるので、早速実装しましょう！


-------

弊社ではWebエンジニアを募集してます。（小声）
https://www.wantedly.com/projects/115932
【Mac】gccのバージョン確認、新しいバージョン（8.2.0）をインストール


Macにあらかじめインストールされているgccのバージョンは古いです。

```
$ gcc -dumpversion
4.2.1
```

```
$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin18.0.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
```

Homebrewで新しいバージョンをインストールできます。

```
$ brew install gcc
```

8系がインストールされました。コマンド名が変わっているので注意しましょう。


```
$ gcc-8 -dumpversion
8.2.0
```

```
$ gcc-8 --version
gcc-8 (Homebrew GCC 8.2.0) 8.2.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```
AWS AthenaのPartitionに関して

# Athenaとは

S3上のデータに対して、SQLで集計を可能にしてくれるAWSのサービス

# テーブル作成

S3のDirとColumnを指定し、テーブルを作成する

```
CREATE EXTERNAL TABLE IF NOT EXISTS <database_name>.<table_name> (
  `id` bigint,
  `year` int,
  `month` int,
  `day` int,
  `column` int
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '\t',
  'field.delim' = '\t'
) LOCATION 's3://<my_bucket>/<path>/<to>/<data>'
TBLPROPERTIES ('has_encrypted_data'='false')
```

ただ、これだけだと検索するときに、全データを毎回スキャンしてしまい、データが蓄積するとQuery代がどんどん大きくなるので、検索範囲を絞れるようにするためにパーティションというものがある

# パーティション

## 概要
パーティションは、データの検索範囲を指定するためのもの


## テーブル作成

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/partitions.html

S3を指定してテーブル作成

1. `PARTITIONED BY `のあとに、パーティションに使いたいcolumnを書く(複数のカラムをおけば、複数カラムでのパーティションも可能)
2. パーティションに使ったカラムは、table定義からは除く
3. 今回の場合は、`s3://<my_bucket>/<path>/<to>/<data>/year=<year>/month=<month>/day=<day>`以下に実際のデータファイルが存在し、そのファイルが`tsv`形式で、`id`と`column`をカラムに持っている必要がある
4. パーティションの順番には特に意味はないようで、今回の例で query上で`month`だけを指定して検索することも可能

```
CREATE EXTERNAL TABLE IF NOT EXISTS <database_name>.<table_name> (
  `id` bigint,
  `column` int
)
PARTITIONED BY (year int, month int, day int)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '\t',
  'field.delim' = '\t'
) LOCATION 's3://<my_bucket>/<path>/<to>/<data>'
TBLPROPERTIES ('has_encrypted_data'='false')
```

CREATE TABLEだけでは、ダメなので、登録する

```
MSCK REPAIR TABLE <table_name>
```

## あとから増えたS3パスに対してパーティションを追加する

```
ALTER TABLE <athena_database>.<athena_table> ADD IF NOT EXISTS PARTITION (year=2019, month=02, day=01)
```

## あとからパーティションを削除する

### 一つパーティションを消す

```
ALTER TABLE <athena_database>.<athena_table> DROP IF EXISTS PARTITION (year=2019, month=02, day=01)
```

### 複数同時に消す

今回の例では、2019年2月のパーティションはすべて消す(1日~28日)

```
ALTER TABLE <athena_database>.<athena_table> DROP IF EXISTS PARTITION (year=2019, month=02)
```

## パーティションがなくてデータだけがあると

パーティション指定したときに、パーティションリストから対応するDirリストをみてデータを見に行くので、パーティションがない場合には、検索対象に入らない模様。

## パーティションが増えすぎると

パーティションが増えすぎると検索のたびに全てのパーティションリストをロードして対応するパーティションのパスリストからデータを見に行くので、オーバーヘッドが大きくなるため、検索が遅くなる

https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/#OptimizeFileSizes こいつを参考にして、いろいろチューニングする必要あり
どうやって効率よく論文を読むか？

#記事を書いたきっかけ
AIなど最新テクノロジーは日々新たな技術が世に出されているため、最新トレンドについていくには最新の論文を主体的に読む必要があると感じている。
が、論文なんて全然読んだことないのでどうやるのが効率的なのか分からず、過去何回か「読むぞ！」->「無理だ。。。」の流れを繰り返してきたので、良い方法を探そうと思ったため。

以下記事を参考にし、自分なりにアレンジしてみた。
(論文の読み方の論文 "How to Read a Paper" 和訳まとめ)
https://qiita.com/tk_01/items/2eec9ad01c7db74559f8
(高速で論文がバリバリ読める落合先生のフォーマットがいい感じだったのでメモ)
http://lafrenze.hatenablog.com/entry/2015/08/04/120205

#読み方まとめ
###①近年のその分野のトレンドや主要な論文・執筆者、カンファレンスを特定する。
・Google Scholar, CiteSeerなどのアカデミックな検索エンジンで、「その分野において最近のもので多く引用されてる論文」を探す。
・その中で繰り返し引用されている論文や執筆者を見つける。更にそれがどのカンファレンスで発表されたか確認する。
・そのカンファレンスでの最新の論文を読む。
https://scholar.google.co.jp/
http://citeseerx.ist.psu.edu/index

###②最初から細部まで把握しようとはしない、5~10分で以下を行う。
1. 論文のtitle, abstract, introductionを注意深く読む
2. 各section、sub-sectionの頭だけを読む
3. 数学的な内容に軽く目を通し、論文で扱われている理論的な分野を把握する
4. conclusionを読む
5. referenceを確認し、自分がすでに読んでいる文献があればチェックする

###③上記を終えたら、もう一度読みながら以下をまとめてみる(自問自答する)。
・どんな種類？（何かの評価論文なのか、既存のシステムの分析論文なのか、など）
・どんな内容？
・技術や手法のキモはどこ？
・先行研究と比べてどこがすごい？
・論文内での考察・検証は妥当か？
・関連する論文、次に読むべき論文は？
->読みづらい論文はこの段階でやめておいた方が良さそう。

###④今度は全体を注意深く読み、論文の趣旨を要約して誰かに説明できるようになる。
・細かい根拠までは理解する必要はないが、大まかな流れをつかむ。
・「興味があるけど専門分野ではない論文」はこのレベルで理解するのが良いらしい。
・ここまでやっても理解出来なければ①諦める、②別の文献で知識を補完して再挑戦、③無視して次のステップへ、のどれか

###⑤論文を自分自身で再構築する。
細部まで含め全ての記載内容を検証し、自分自身で表現するとしたらどうするか、ということまで考える。
その上で論文の原文と比較することで、論文の根拠についての深い洞察や、論文における表現技術が得られる。
またこの作業中に、自分の将来の活動についてのアイデアを書き留めるべき。
->現実的にはここまでやるのはなかなか難しいか。


#所感
英語論文を読むのに慣れていないので、現実的には②は30分ぐらいかけてやる感じか。
今の自分のレベルで⑤までやるのは厳しいので、少なくとも③、出来れば④までやりたい。
時間の確保が一番の課題、毎日論文を読む習慣をつけたい。
実際に論文を読んでみて、適宜自分に合ったやり方を見つけようと思う。
7日目はSwiftでしょぼいアプリを作りました。

7日目はSwiftにチャレンジしました。
iPhoneアプリを作れる言語なんだそうです！

変数や関数の扱いが独特で、なんじゃこりゃーとびっくり。
iPhoneを動かすために、こういう作りになっているのかな。
なんとも不思議な言語です。

Swiftの特徴をまとめてみました。

-変数はVar、定数はLetで定義
-変数、定数の指定は コロンでデータ型を指定して代入。
-変数、定数の頭文字は<span style="color: red; ">小</span>文字
-データ型の頭文字は<span style="color: red; ">大</span>文文字 
　・・・大文字・小文字は何回もまちがいました。こんな違いでも動かないんだから・・・！
-先頭子、終了子は不要
`例）let test:Int = 5`

-四則演算は共通

-文字列の代入 
例）print ("\(name)さん、こんにちは”) ←バックスラッシュカッコってふしぎ！

・データ型が異なるもの同士の処理はキャストしてどれかに揃える・・・めんどくさいなあ。

・条件式は素で書いて、中括弧に処理を書く。
例）if 条件式 {
    処理
}

・真偽値の設定
例）
let isSpeedOver:Bool = carSpeed > 60
・・・こんなん初めてみた。独特・・・！

・Switch
Break句がいらない！
Caseで範囲指定ができる！

そんなこんなで、後半はProgate上でXcodeのエミュレータを動かしてアプリ作成の練習、それから自分のパソコンでXcodeを動かしてしょぼいアプリをつくりました。これは楽しい！動く、動くぞ！！！
rails test でエラーが出た時の対処法(Rails Tutorial)

##Rails Tutorial ３章でエラー

Rails Tutorial第３章にて初めて `rails test`した時に上手くいかなったのでメモ。

エラー内容は

**3 runs, 2 assertions, 0 failures, 1 errors, 0 skips**
という`rails test`の結果の後に

**/usr/local/rvm/gems/ruby-2.5.3/gems/notiffany-0.1.1/lib/notiffany/notifier/tmux/client.rb:12:in version': undefined method []' for nil:NilClass(NoMethodError)**
**from /usr/local/rvm/gems/ruby-2.5.3/gems/notiffany-0.1.1/lib/notiffany/notifier/tmux.rb:69:in _check_available'
...大量のgemパスの表示...
from /usr/local/rvm/rubies/ruby-2.5.3/lib/ruby/site_ruby/2.5.0/rubygems/core_ext/kernel_require.rb:55:in require'from -e:1:in <main>'**

という形。

結果から言うと

[【NomethodError】Rails Tutorial 3章でエラーが出たので調べてみたらtmuxが原因だった](https://ty-engineer.com/ruby-on-rails/rails-tutorial-3-error-tmux/)

上記リンク先の方法で解決しました。

おそらくAWS Cloud9を使ってチュートリアルを進めている人に同じようなエラーが出ます。


##対処法

`sudo yum install -y tmux `

を実行してtmuxをインストールすれば解決します。
なお Railsチュートリアル内でも３章後半で説明がありますので気にせずチュートリアつを進めればエラーは無くなります。

チュートリアル内の説明。
>Cloud9を使っている場合は、Guardの通知を有効にするためにtmuxをインストールする必要があります。Cloud9をお使いの場合は次のコマンドでtmuxをインストールしてください。

なお、上記の説明は同章後半に出てくるのでモヤモヤしながら進むことになる。
それが嫌な場合は事前に
`sudo yum install -y tmux`
をしておきましょう。
6日目のPythonが素直すぎる

6日目はPythonに挑戦しました。
これまでやってきた言語と比べて圧倒的に素直！
変数の宣言がいらないとか、カッコの数も少ない。分かりやすい。
コスパ最高なんじゃないかなと思います。

ProgateでPython学習コースの１を完了して、つくったアプリをHerokuにアップ。
しかしこれもまた動かず。
あとでまた見てみようと思います。ふう。

##Pythonに触れてみよう
目標物を確認しよう
##Pythonの基礎を学ぼう
文字列
数値
計算してみよう
##変数を使ってみよう
変数
変数を使ってみよう
変数の値を更新してみよう
文字列の連結
データ型
##真偽値と条件分岐
if文
真偽値
else
elif
条件式を組み合わせよう
##お買い物代金を計算しよう
代金を計算しよう
入力を受け取ろう
条件分岐をしよう
写真アプリの謎のキャッシュ「com.apple.iLifeMediaBrowser.ILPhotosTranscodeCache」の正体

# はじめに
**このmacについて > ストレージ**を見てみると**システム**が多くのストレージを使用していた。
調査すると１つの原因としてキャッシュ`com.apple.iLifeMediaBrowser.ILPhotosTranscodeCache`の容量が大きかったため、その問題を解決するまでのフローを以下に示す。

# ストレージ容量の調査
まず、以下のコマンドで、5GB以上のフォルダを調べてみた

```bash
sudo du -g -x -d 5 / | awk '$1 >= 5{print}'
```

いくつか表示された中に約**20GB**程度の以下のフォルダを発見した
`~/Library/Containers/com.apple.MediaLibraryService`


上のコマンドでは、ルートから深さ５までのフォルダまでしか表示されない。そこで以下のコマンドでより深くフォルダを調べる。

```bash
sudo du -g -x ~/Library/Containers/com.apple.MediaLibraryService
```

すると以下のフォルダに大量の写真や動画が保存されていた
`~/Library/Containers/com.apple.MediaLibraryService/Data/Library/Caches/com.apple.iLifeMediaBrowser.ILPhotosTranscodeCache`
どうやら、Mac標準のアプリケーションである**写真アプリ**のキャッシュらしい。

# 写真管理環境
私は**iPhoneXS**で写真を結構撮るのだが、その管理には写真アプリを使っている。
写真アプリのライブラリは外付けストレージに保存するようにしている。

`com.apple.iLifeMediaBrowser.ILPhotosTranscodeCache`に保存されたキャッシュは、
iOS11から導入された写真と動画のフォーマット**HEIF／HEVC（H.265）を写真アプリでサムネイル表示する際に必要なキャッシュ**らしい。

つまり、私のような外付けストレージで写真アプリのライブラリ管理を管理する場合、外付けストレージとローカルストレージの2つに二重で写真や動画を保存することになる。

ローカルストレージを節約するために、外付けストレージを使っているのにこれでは本末転倒である。

# 対策
## iPhoneのカメラ設定の変更
iPhoneで取った写真をjpgなどの従来のフォーマットで保存するように変更。
iPhoneの設定から`カメラ>フォーマット`で`互換性優先`を選択。
![IMG_60A0456DA7B7-1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/133979/b4194bd9-c653-b1ce-e897-f17a029b66e1.jpeg)

## 写真アプリに保存されたHEIF/HEVC形式画像・動画の変換
私の場合は、iPhoneXSの前はiPhone6sで、そもそも端末がHEIF/HEVCに対応していなかった。そのため、macの写真アプリの`スマートアルバム機能`を使って、`カメラ機種:iPhoneXS`を選択することで、HEIF/HEVC形式の写真・動画のみを選択することが容易だった。

もし、iPhone7からiPhoneXSなどに買い替えた場合は、iOS11にアップデートした以降の日付の写真を選択すれば良いと思う。

それらの選択した写真を`ファイル>書き出し>○○項目を書き出す`を選択し、書き出し設定では写真フォーマットでjpgを選択し、一時フォルダなどに書き出す。

## キャッシュの削除
そして、元のHEIF/HEVC形式の写真を削除した後で、書き出した写真をインポートする。
その後、
`rm -rf ~/Library/Containers/com.apple.MediaLibraryService/Data/Library/Caches/com.apple.iLifeMediaBrowser.ILPhotosTranscodeCache`
で写真・動画を削除する。

# おわりに
これで、キャッシュ`com.apple.iLifeMediaBrowser.ILPhotosTranscodeCache`を削除でき、今後キャッシュが新たに生成されないようになり、ストレージの節約につながった。
you-get使用技巧

## 安装环境
>python3环境
>pip3

## 安装you-get
```
pip3 install you-get
```
## 解析视频
>you-get -i vudio-url

```
you-get -i https://panda.tv/513085
```

## 下载视频
>you-get -o path viodo-url

```
you-get -o https://panda.tv/513085
```

## 更换画质
>you-get --format format-type -o path vidio-url
【NuGet】C#、.NETでライブラリを公開する【2019年版】

「C#、.NETでライブラリを作って、それを公開したい」

そんなときは、NuGetを使いましょう。

NuGetはMicrosoftがサポートする.NETのコード共有メカニズムです。「[nuget.org](https://www.nuget.org/)」には、100000個以上のライブラリがあるらしいです！NuGetは、Windowsだけでなく、MacやLinuxでも使えます。

やり方は公式ドキュメントにまとまっていますので、本投稿では公式ドキュメントのピックアップ、チップス、サンプルを紹介します。

# 公式ドキュメントピックアップ

NuGetの概要は次のドキュメントを！

* [NuGet の概要](https://docs.microsoft.com/ja-jp/nuget/what-is-nuget)
* [An introduction to NuGet](https://docs.microsoft.com/en-us/nuget/what-is-nuget)

---

dotnet CLIを使ったNuGetのライブラリの作成・公開方法をサクッと確認したい方はこちら！

* [クイック スタート: パッケージの作成と公開 (dotnet CLI)](https://docs.microsoft.com/ja-jp/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli)
* [Quickstart: Create and publish a package (dotnet CLI)](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli)

---

NuGetのライブラリの作成・公開方法のワークフローはこちらから！

* [パッケージ作成ワークフロー](https://docs.microsoft.com/ja-jp/nuget/create-packages/overview-and-workflow)
* [Package creation workflow](https://docs.microsoft.com/en-us/nuget/create-packages/overview-and-workflow)

---

NuGetでライブラリを作成・公開するにはいくつかの方法があります。方法によって、読むべきドキュメントが異なるので注意してください。

また、NuGetのバージョンアップによっていろいろ設定方法が変更されている点に注意してください。

NuGet4.0以降では、ライブラリのためのメタデータをプロジェクトファイル(.csproj)に直接保存できます。（それより前は別のファイルを作る必要がありました）

どのような項目で設定をすればいいかは次のドキュメントを参照してください。

* [MSBuild ターゲットとしての NuGet の pack と restore](https://docs.microsoft.com/ja-JP/nuget/reference/msbuild-targets)
* [NuGet pack and restore as MSBuild targets](https://docs.microsoft.com/en-US/nuget/reference/msbuild-targets)

# チップス

「[クイック スタート: パッケージの作成と公開 (dotnet CLI)](https://docs.microsoft.com/ja-jp/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli)」では最小限の設定として、次の4項目を設定するようにという指示があります。


```xml
<PackageId>AppLogger</PackageId>
<Version>1.0.0</Version>
<Authors>your_name</Authors>
<Company>your_company</Company>
```

ところが、この状態で`nuget.org`に公開すると次のようなライセンス関連の警告が表示されます。


![スクリーンショット 2019-02-16 13.52.53.png](https://qiita-image-store.s3.amazonaws.com/0/4125/af9ac785-409f-c5ec-de15-69b62bebe1cd.png)

これは`PackageLicenseExpression`を設定することで消えます。

# サンプル

`LinqAlias`というライブラリを作成しました。こちらをサンプルとして参照してください。

* コード : https://github.com/RyotaMurohoshi/LinqAlias
* NuGet : https://www.nuget.org/packages/LinqAlias/

以下に、LinqAliasの`.csproj`を示します。


```xml
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <Title>LinqAlias</Title>
        <Description>Aliases of System.Linq extension methods.</Description>
        <AssemblyName>LinqAlias</AssemblyName>
        <Version>0.0.1.0</Version>
        <Authors>RyotaMurohoshi</Authors>
        <TargetFramework>netstandard1.0</TargetFramework>
        <PackageLicenseExpression>MIT</PackageLicenseExpression>
        <PackageProjectUrl>https://github.com/RyotaMurohoshi/LinqAlias</PackageProjectUrl>
        <RepositoryUrl>https://github.com/RyotaMurohoshi/LinqAlias</RepositoryUrl>
        <PackageTags>linq;extensions;alias</PackageTags>
        <Copyright>Copyright (c) 2019 RyotaMurohoshi</Copyright>
        <RepositoryType>git</RepositoryType>
    </PropertyGroup>

</Project>
```
STSでSpringBootプロジェクトを作ってバージョン管理を始めるまで

SpringBoot／STS初学者なので忘れないようにメモです。

## プロジェクトを作ろう

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/27090/91601c18-f37d-60c5-1896-b5f2956c78d8.jpeg)


File > New > Spring Starter Project と選択しています。

![2.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/8eefaae7-b430-f7b9-f8e1-fd1f296966a2.jpeg)


全部デフォルトのままでNextをクリック。

![3.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/29e34531-c582-63bc-f4b9-4a4221bea197.jpeg)


以下を選択して、Finishをクリック。

- MySQL
- JDBC
- MyBatis
- Thymeleaf
- Web

![4.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/eae8b4fc-2296-f82b-5177-c4da5493ad18.jpeg)

はい、プロジェクトの作成完了です。

## 最近の流行りはapplication.yml

と、先輩から言われたので `application.properties` を `application.yml` にrenameします。

![5.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/6c5a46aa-fd32-c0a2-5ffa-e2e23f92f33b.jpeg)

application.propertiesを右クリックして Refactor > Rename を選択

![6.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/8d1031c9-5457-7a81-4dc4-17365a2c07a4.jpeg)

拡張子を properties から yml に変更します。

![7.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/ff97540a-34ab-b1e3-5111-3e0a22959454.jpeg)

## バージョン管理しときましょう。


![8.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/184cb758-5f22-08bf-d7cd-f7ee65cbdd8b.jpeg)

プロジェクトを右クリックして Team > Share Project... を選択

![9.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/20f2da3f-9681-e910-c955-6516591c5aca.jpeg)

![10.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/9284743a-f3c5-0228-71e4-f7a71c025cce.jpeg)

Use or create repository in pararent folder of project を選択してFinish。

これでgitでバージョン管理できるようになりました。

## コミット

最初のコミットをしましょう。

![11.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/ce7d648f-0585-0968-5956-dfbd58cd69c8.jpeg)

プロジェクトを右クリックして Team > Commit を選択。

![12.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/beac5145-1240-ea3c-a151-85564f265130.jpeg)

右上の方の＋が重なったようなアイコンをクリック

![13.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27090/a8e66ea4-3cf4-63c5-06f1-9e27bca8660b.jpeg)

Unstaged Changesにあったファイルが全て Staged Changesに移ったら、コミット準備完了です。
Commit Messageに `first commit` と入力して右下のCommitをクリック。

これでプロジェクトができた段階でのバージョンがコミットできました。
さ、ゴリゴリ開発していきましょう。
Next.jsでデータを取得する 〜getInitialProps〜

:bangbang: 2020.05 Next.js 9.3から、データ取得用の新しいメソッド(getServerSidePropsなど)が推奨になりました。新しいコードをgetInitialPropsで書く理由はありません https://qiita.com/matamatanot/items/1735984f40540b8bdf91　

---

Next.jsでページロード前に必要なデータをfetchするには、getInitialPropsを利用しますが、ちょっと引数が複雑だったのでメモ。

以下、概ね↓の和訳です。
https://nextjs.org/docs/#fetching-data-and-component-lifecycle


#データのfetchとコンポーネントライフサイクル
state,ライフサイクルhook,初期データが必要なときは、SFCの代わりに`React.Component`をexportします。

```JSX
import React from 'react'

class HelloUA extends React.Component {
  static async getInitialProps({ req }) {
    const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
    return { userAgent }
  }

  render() {
    return (
      <div>
        Hello World {this.props.userAgent}
      </div>
    )
  }
}

export default HelloUA
```

ページロード時にデータを取得するには、`getInitialProps`という非同期で静的なメソッドを使います。このメソッドは、JavaScriptの単純な`Object`なら何でも非同期に取得でき、返り値は`props`に注入されます。
`getInitialProps`から返されたデータは、サーバー側のレンダリング時に`JSON.stringify`がするのと似た形でシリアライズされます。`Date`,`Map`,`Set`を扱うことはできないのでご注意ください。

最初のページロード時には、`getInitialProps`はサーバー側でのみ実行されます。クライアントサイドで実行されるのは、別のルートから`Link`コンポーネントまたはルーティングAPIで移動してきたときだけです。

`getInitialProps`は子コンポーネントでは利用できません。`pages`のみです。

`getInitialProps`をステートレスなコンポーネントで使うこともできます。

```JSX
function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.getInitialProps = async ({ req }) => {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}

export default Page

```

`getInitialProps`は以下のプロパティを持つオブジェクトを引数として受け取っています。

- `pathname` - URLのパス部分
- `query` - URLのクエリ部分をパースしたオブジェクト
- `asPath` - ブラウザに実際に表示されているパス＋クエリの文字列
- `req` - HTTPリクエストオブジェクト(サーバーサイドのみ)
- `res` - HTTPレスポンスオブジェクト(サーバーサイドのみ)
- `jsonPageRes` - [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response)オブジェクト(クライアントサイドのみ)
- `err` - レンダー中にエラーが起きた場合のエラーオブジェクト
JavaScript の Array.prototype.some が何故他の言語のように any じゃないか調べてみたけど分からなかった

# JavaScript の Array.prototype.some が何故他の言語のように any じゃないか調べてみたけど分からなかった

[JavaScriptのsomeがanyって名前じゃなかったから探しにくかった話](https://qiita.com/RyotaMurohoshi/items/4ca8e8cb566bbc2a23ae)を見てて、ホントなんでなんだろうと思ったので少し調べてみたけど、分からなかったという話.

最初は一瞬 TypeScript の any と被るのが嫌だったのかなあと思ったが、some の出元は Firefox 1.5(2005年11月29日) に搭載された JavaScript 1.6 由来だったので、2010年代の TypeScript はおろか、C# 3.0 (2007年11月19日) と共にリリースされた Linq の Any ですら開発中だった.

当時の開発者向けの記事を [Internet Archive: Wayback Machine](https://archive.org/web/) で漁ってみたが何も書かれていなかったし、Mozilla の Bugzilla で some array で検索しても議論等はでてこなかったので、謎のまま終了.

まあ、これだけ古いと、他の言語に合わせなかったというよりは、他の言語が実装する際に some と any のうち any を選択したため、ぼっちになってしまったということになるのだろう.

## 追記

そういえば、すっかり忘れていたけど、JavaScript は Scheme をベースに作られている. Scheme のこの手の関数は exists, for-all なのだが、それが定義されたのは r6rs (2007年9月) であり時期的に逆転してしまう. 1994年に成立した ANSI Common Lisp の仕様書ではこの手の関数は every, some, notevery, notany であり、標準になかった頃は Schemer も every, some を自作し、利用していたことは想像に難くない.

## 追記の追記

Scheme の SRFI-1 は any, every だったので、実装時期に素直に Scheme 脳だとこっちになりそうで不思議.
Laravelのログのフォーマットをカスタマイズし、フィールドの1つとしてセッションが管理している値を出す

## 概要

Laravelのログのフォーマット（tsv形式）を変更し、フィールドの1つとしてセッションが管理している値を出します。
出力対象は下記とします。

* 実行中のクラス名
* ログ出力した行番号
* メソッド名
* セッションに格納された情報を表示（メッセージとしてではなくフィールドの1つとして）

## 環境

```
>php --version
PHP 7.2.12 (cli) (built: Nov  8 2018 05:47:24) ( NTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v2.6.1, Copyright (c) 2002-2018, by Derick Rethans
```

```
>php artisan --version
Laravel Framework 5.7.15
```

## 実装

### ログのフォーマットを定義するクラスを作成する。

カスタマイズの内容を記載したカスタム実装を用意する。

```php5

<?php

namespace App\Logging;

use Monolog\Formatter\LineFormatter;
use Monolog\Logger;
use Monolog\Processor\IntrospectionProcessor;

class CustomizeFormatter
{
    private $logFormat = "";
    private $dateFormat = 'Y/m/d-H:i:s.v';

    public function __construct()
    {
        // ログ出力するカラムを設定
        $cols = [
            "%datetime%",
            "%level_name%",
            "session_value:%extra.session_value%", // セッション情報出力用のフィールド
            "%extra.class%::%extra.function%#%extra.line%", // クラス名::メソッド名#行
            "%message%",
            "%context%",
        ];

        // タブ区切りでフォーマットを生成
        $this->logFormat = implode("\t", $cols) . PHP_EOL;
    }

    /**
     * 渡されたロガーインスタンスのカスタマイズ
     *
     * @param $monolog
     * @return void
     */
    public function __invoke($monolog)
    {
        // フォーマットを指定
        $formatter = new LineFormatter($this->logFormat, $this->dateFormat, true, true);

        // extraフィールドの追加
        $ip = new IntrospectionProcessor(Logger::DEBUG, ['Illuminate\\']);

        foreach ($monolog->getHandlers() as $handler) {
            $handler->setFormatter($formatter);
            $handler->pushProcessor($ip);

            // extraフィールドにログ出力対象となるセッション情報を設定する
            $handler->pushProcessor(function ($record) {

                // 対象となるセッションキー設定
                $cols = ["session_value"];
                foreach ($cols as $col) {

                    if (session()->has($col)) {
                        $record['extra'][$col] = session()->get($col);
                    }
                }
                return $record;
            });
        }
    }
}

```

### logging.phpにカスタムフォーマットを設定する。

チャンネルの設定に`tap`を追加し、カスタマイズしたログのクラスを指定すると該当のカスタム実装が適用される。

```php5:logging.php

'daily' => [
    'driver' => 'daily',
    'tap' => [App\Logging\CustomizeFormatter::class], // ここを追加する
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
    'days' => 14,
],

```

## 実行

`session->put("session_value", 1234)`を実行し、`Log::info()`すると、session_valueのフィールドが追加され、1234が出力されていることが分かる。

**ログ出力に`info()`を使うとログフィールドの`クラス名::メソッド名#行`部分が常にinfo()になってしまうので注意**

## 参考
* [Laravelでログのフォーマット変更する方法](https://blog.nobug-nolife.com/entry/20181202/1543762300)
* [How can I add the session ID to all log entries in Laravel 5.2](https://stackoverflow.com/questions/36316984/how-can-i-add-the-session-id-to-all-log-entries-in-laravel-5-2)
AWS CLI を勉強してみる

AWSインスタンスをコマンドで再起動する

準備として必要なこと
　1. AWSのインスタンス環境
　2. コマンドを実行するコンソールにAWS-CLIをインストール
　3. AWSでIAMユーザを作成
　4. IAMユーザの認証情報でアクセスキーを作成する
　5. コマンドを実行するコンソールでaws configにてアクセスキーを登録

AWS-CLIでインスタンスを再起動する
　aws ec2 reboot-instances --instance-ids {インスタンスＩＤ}
HomebrewでMonoをインストールしたのにVisualStudioを使うときに "This application requires Mono 5.10.0.171 or newer." がでる

MacにUnityを入れて、Scriptを編集しようとしたところ、VisualStudioの起動時に、すでにHomebrewでインストールしてあるはずのMonoのインストールを求められてしまう。
VisualStudioが使うMonoはpkgでのインストールを前提としている様子。

# 環境

- macOS Mojave 10.14.3
- Unity 2018.3.5.f1
- VisualStudio

# HomebrewでのMonoインストール

Monoをインストールする際、Homebrewからインストールを行なっていた。

```bash
$ brew install mono
$ ./mcs --version
Mono C# compiler version 5.18.0.240
```

# Monoをダウンロードするように案内

しかし、この状態でVisualStudioを起動すると、以下の表示が出る。

![unity.png](https://qiita-image-store.s3.amazonaws.com/0/75564/4a520735-4832-2d76-c03b-84d70745779e.png)

## 他の人たちの対応

https://forums.xamarin.com/discussion/90339/visual-studio-for-mac-wont-start-with-homebrew-mono-install

> I do not know of a way to get that to work. Easiest, and supported, solution would be to install mono via the .pkg installer. 
http://www.mono-project.com/download/
Xamarin Studio / Visual Studio for Mac does require mono to be installed at /Library/Frameworks/Mono.framework

# 対処

大人しく、Monoのサイトのインストーラーpkgからインストールする。
https://www.mono-project.com/download/preview/

起動した！
![vs.png](https://qiita-image-store.s3.amazonaws.com/0/75564/19c81288-2f14-9a7b-a973-0ee0989ce24c.png)

## 注意点

shellで実行するmcsの設定が、pkgからインストールされたものになってしまう。

```bash
$ which mcs
/Library/Frameworks/Mono.framework/Versions/Current/Commands/mcs
$ mcs --version
Mono C# compiler version 5.20.0.0
```

Homebrewで入れたMonoは以下にあるので、必要に応じて使い分ける。

```
/usr/local/Cellar/mono/5.18.0.240/bin
```
Lravelのフォームリクエストクラス内で依存解決されたクラスを取得する

putやdeleteの際に、idに対応するモデルを自動で取得してくれますが、フォームリクエストのauthorizeメソッド内でも取得されるモデルに含まれる値を使いたかったので、どのようにすれば良いのか確認をしました。


[モデル結合ルート](https://readouble.com/laravel/5.7/ja/routing.html#route-model-binding)
> ルートかコントローラアクションへモデルIDが指定される場合、IDに対応するそのモデルを取得するため、大抵の場合クエリします。Laravelのモデル結合はルートへ直接、そのモデルインスタンスを自動的に注入する便利な手法を提供しています。つまり、ユーザーのIDが渡される代わりに、指定されたIDに一致するUserモデルインスタンスが渡されます。

## 公式のドキュメントの確認
[フォームリクエストの認可](https://readouble.com/laravel/5.7/ja/validation.html#authorizing-form-requests)に記載がありました。
ドキュメントで紹介されているコードです。

```php
public function authorize()
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}
```

findで取得をしていますが、下記の記述を見る分にはわざわざfindで取得する必要はなさそうです。
コードサンプルがなかったので確認をしてみます。
> Tip!! authorizeメソッドの引数として、必要な依存をタイプヒントで指定できます。それらはLaravelのサービスコンテナにより、自動的に依存解決されます。

### 確認内容
ルーティングに関してはドキュメント通り下記の通りです。

```php
Route::post('comment/{comment}');
```

#### コントローラーでidとして受け取る場合

```php
// controller
public function update(Request $request, $id)
{
    $comment = Comment::find($id);
}
```

```php
// フォームリクエスト
public function authorize()
{
    // $this->route('comment')の返り値がコントローラーの$idと同じになるため、findで取得をする
    $comment = Comment::find($this->route('comment'));
}
```

#### コントローラーでモデルインスタンスとして受け取る場合

```php
// controller
public function update(Request $request, Comment $comment)
{
    // $commentがモデルインスタンスのためfindは不要
}
```

```php
// フォームリクエスト
public function authorize()
{
    // $this->route('comment')の返り値がコントローラーの$commentと同じモデルインスタンス
    $comment = $this->route('comment');
}
```

コントローラーではモデルインスタンスとして受け取ることの方が多いと思います。
そのため2番目の書き方がもしかしたらよくされているかもです。
ALBとECSサービスの関連付けの制約

Amazon Web Serviceの現在の仕様では、以下の制約のために1つのECSサービスには1つのALBからのみしか通信を転送できない。

* 1つのTarget Groupは1つのALBのみにしか設定できない。（参考：[ALBの制限](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-limits.html)）
* 1つのECSサービスには1つのALB（Target Group）のみしか設定できない。（参考：[ECSサービスの制限](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/service_limits.html)）

このため、インターネットALBと内部ALBを1つのECSサービスに転送するといった構成を組むことができない。この制約の緩和はコミュニティからも強くリクエストされているようであるが、今のところロードマップは示されていない。（参考：[関連するGitHub Issue](https://github.com/aws/containers-roadmap/issues/104)）

#### 参考：代替手段（開発環境向け）

上記のGitHub Issueの議論の中で、以下の方法でTarget Groupをミラーリングする代替手段が提案されている。

* ECSサービスをTarget Group Aに関連付けておく。
* [ECSタスク状態変更イベント](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs_cwe_events.html)（[CloudWatch Events](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html)）をトリガーにAWS Lambdaを起動する。
* Lambaの処理で追加（削除）されたタスクを取得し、Target Group Bを更新する。

ただし、この方法ではTarget Group Bへのタスク追加・削除の完全性が保証されないため、本番環境では推奨されない。（例えば、Lambdaの処理がタスク削除より遅くなった場合や、Lambdaの処理がエラーとなった場合にサービス停止となってしまう。）
手軽にコーディングするならやっぱりBootstrapよりTACHYONSだなぁ

とりあえず生🍺といったくらいにBootstrapを使う機会があると思いますが、個人的には先にTACHYONSから入ったもので、知っている/使っている人が皆無なので紹介したいと思います

# 覚える作法は一つ
クラス名末尾に以下の文字を付与してデバイス間の調整を行います

* 「-ns」 not-smallの略。(min-width: 30em)
* 「-m」 mediumの略。(min-width: 30em) and (max-width: 60em)
* 「-l」 largeの略。screen and (min-width: 60em)

何も付与しなければ、どのサイズにも適用されます
案件に応じて値を変更してあげればよいと思います
# ファイルサイズの軽さ
v4.11.2で73kbという容量です
Bootstrapはv4.3.1で156kbあるので、半分以下の容量です

# ドキュメントの探しやすさ
<img width="1359" alt="ドキュメント" src="https://qiita-image-store.s3.amazonaws.com/0/359978/17b4573b-f002-5113-404c-5295ba9e57e2.png">
自分の使用しているMacbook Air 13inchの１画面範囲内でも、何について調べたいか一目瞭然です
[TACHYONS / Docs](http://tachyons.io/docs/)

# サンプルの見やすさ
Bootstrapだと、まずは結果があり、その下にコードといった構成でスクロールして見ていくことになります

**Bootstrap Flexの例**
<img width="923" alt="Bootstrap Flexの例" src="https://qiita-image-store.s3.amazonaws.com/0/359978/eb50c7ae-d92c-f9bf-b4cd-26d2f1148084.png">

TACHYONSの場合は左にコード、右に結果という構成で一画面に収まっているため、Bootstrapと比較したとき、非常に見やすいと思います

**TACHYONS Flexの例**
<img width="1353" alt="TACHYONS Flexの例" src="https://qiita-image-store.s3.amazonaws.com/0/359978/b63b1811-059b-0f3b-e7d8-bf9d317380fd.png">
# 実際の生のCSSがどうなっているか
全部が全部TACHYONSで書くわけにもいかず、自分でCSSを書くことはあるはずです
そんな時、どういったプロパティ・値を使っているか確認したくなることがあると思います
いちいちCSSファイルをひらなかくても、ドキュメント各ページの下部に生のCSSが記述されているので、それを確認したらよいです
# もどかしいところもあります
tableのリセットにcollapseが当たっていないので、わざわざtable.collapseといった感じに、クラスを付与してあげます
また、モバイルファーストな設計なので、スマホサイズにだけクラスを当てたい！って場合は、いちいち`-m -l`で上書いてリセットしてあげるか、素直にCSSを書く必要があります

もし良さそうだなと感じたら、是非、案件に応じてTACHYONSを使ってみてください！
きっと一つの武器として使えると思います

**P.S.**
意外なことにTACHYONSのタグがついた記事が全くなかった
try! Swift Tokyo 2019に向けて

try! Swift はSwift言語に関するカンファレンスでNYでも開催される有名なイベントです。
try! Swift Tokyo 2019 に参加するので予習のための情報を整理しておきます。

# 公式資料
- サイト：https://www.tryswift.co/events/2019/tokyo/jp/
- GitHub：https://github.com/tryswift
- Twitter：https://twitter.com/tryswiftconf

Twitterではいろいろアナウンスがあるようなのでウォッチしておくと良さそうです。

# 動画
Youtube：https://www.youtube.com/channel/UCuPue-GLK4nVX8klxQITIOw
crash.academy：https://crash.academy/community/try!swift

# try! Swift Tokyo 2018

## まとめ
https://qiita.com/ozwio/items/71fb765b48905d6a2193

## レポート
https://engineer.dena.jp/2018/03/try-swift.html
https://jp.corp-sansan.com/mimi/2018/04/tryswifttokyo2018.html
http://blog.kushii.net/archives/2075274.html
http://natmark.hateblo.jp/entry/2018/03/14/023520
https://blog.japantaxi.co.jp/2018/04/02/531
https://medium.com/eureka-engineering/try-swift-tokyo2018-report-11ebe484160f
https://developers.freee.co.jp/entry/we-sponsored-tryswift2018

## レポート（ワークショップ）
http://developer.hatenastaff.com/entry/tryswift2018-swift-workshop
https://blog.ookami.me/tech/first-contribution-to-swift-at-try-swift-tokyo-2018

# try! Swift Tokyo 2017

## まとめ
https://qiita.com/roothybrid7/items/267ad11df4f87765588c
https://qiita.com/yanap/items/15ba41ead4822b48c750

## レポート
http://tech.toreta.in/entry/2017/03/07/170324

## レポート（ハッカソン）
https://techblog.yahoo.co.jp/ios/try_swift_2017_hack/

# try! Swift NYC 2017

## レポート
https://developers.cyberagent.co.jp/blog/archives/11530/

# try! Swift Tokyo 2016

## まとめ
https://qiita.com/mishimay/items/895d676eb9940d75e639

# try! Swift Tokyo ２０１９に向けて
https://dev.classmethod.jp/etc/ready-for-try-swift-tokyo-2019/
Pythonでファイルをダウンロード＆プログレスバーを表示させる

## 概要

表題の通りです。**Python3**で動きます。
指定したURLのファイルを取得して、コンソールにプログレスバーをprintします。
書いたんですが不要になって結局使わなかったので、供養のために置いておきます。

## 仕様

```python
from download import download

url = 'http://download.hogehoge~~~~~~~~~~~~~~~~.zip'
download(url, './donwloaded_file.zip') # urlと保存先のパス、ファイル名
```
みたいに書くと、
![スクリーンショット 2019-02-16 11.51.52.png](https://qiita-image-store.s3.amazonaws.com/0/265900/112e212f-06be-e7e0-4a12-f9896d9b699e.png)
こんな感じにコンソールに出る。

## コード

ダウンロードとファイルの保存自体は`urllib.request.urlretrieve`を使います。
ここでダウンロードが進むごとに呼ばれる引数のコールバック関数に、
プログレスバーを表示させる関数（progress_print）を渡します。
色をつけるために`colorama`を使用しています。

バーを短くしたければmax_barの値を小さくすればいいです。

```python:download.py
import urllib.request
from colorama import init, Fore, Back, Style

# 進捗を表示させるためのコールバック関数
# イメージ：[=====>    ] 50.54% ( 1050KB )
def progress_print(block_count, block_size, total_size):
  percentage = 100.0 * block_count * block_size / total_size
  # 100より大きいと見た目が悪いので……
  if percentage > 100:
    percentage = 100
  # バーはmax_bar個で100％とする
  max_bar = 50
  bar_num = int(percentage / (100 / max_bar))
  progress_element = '=' * bar_num
  if bar_num != max_bar:
    progress_element += '>'
  bar_fill = ' ' # これで空のとこを埋める
  bar = progress_element.ljust(max_bar, bar_fill)
  total_size_kb = total_size / 1024
  print(
    Fore.LIGHTCYAN_EX,
    f'[{bar}] {percentage:.2f}% ( {total_size_kb:.0f}KB )\r',
    end=''
  )

def download(url, filepath_and_filename):
  init()
  print(Fore.LIGHTGREEN_EX, 'download from:', end="")
  print(Fore.WHITE, url)
  # コールバックでprogress_printを呼んで進捗表示
  urllib.request.urlretrieve(url, filepath_and_filename, progress_print)
  print('') # 改行
  print(Style.RESET_ALL, end="")
```

### 使用イメージ

```python:index.py
from download import download

url = 'http://download.hogehoge~~~~~~~~~~~~~~~~.zip'
download(url, './donwloaded_file.zip')
```

※この使用イメージのファイルの階層はこんな感じ。

```bash
projectroot/
  ├download.py
  └index.py ← これを実行した
```
WebVR開発フレームワーク集めてみました．

###メインストリーム
[Three.js](https://threejs.org/)
[A-Frame](https://aframe.io/) - Mozilla
[PlayCanvas](https://playcanvas.com/)
[React 360](https://facebook.github.io/react-360/) -Facebook

###サブストリーム
[Sketchfab](https://sketchfab.com/)
[Vizor](https://site.vizor.io/)
[Blend4Web](https://www.blend4web.com/en/)
[JanusVR](https://janusvr.com/)
[PRIMROSE](https://www.primrosevr.com/)
[Boilerplate](https://github.com/borismus/webvr-boilerplate)
[Babylon.js](https://www.babylonjs.com/)

メインかサブかは，恣意的に分けたものなのであまり気になさらずにいただけると幸いです．

##Inspectorとは
すごくざっくりいうと，WebVRのUnityみたいなものです．
簡単なGUI操作で作品を作ることができるというのが特徴です．

###A-Frame Inspector
![AFrameInspector.gif](https://qiita-image-store.s3.amazonaws.com/0/274029/940d0655-3372-9957-1f97-18b78f44988d.gif)
https://github.com/aframevr/aframe-inspector

###PlayCanvas Inspector
![PlayCanvasInspector.png](https://qiita-image-store.s3.amazonaws.com/0/274029/4359b794-43c8-38d6-acb7-05c73ed01e5b.png)
https://developer.playcanvas.com/en/user-manual/designer/inspector/

###参考ブログ
A-Frame Inspectorを使ってみる（前半）
https://taigayonemoto.hateblo.jp/entry/inspector1

A-Frame Inspectorを使ってみる（後半）
https://taigayonemoto.hateblo.jp/entry/inspector2
JavaScriptのsomeがanyって名前じゃなかったから探しにくかった話

「JavaScript、mapと同時期に実装された、someとかeveryの知名度低いんじゃないかな？」

こんな感じのツイートを見かけました。

JavaScriptの[some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)は「配列のメソッドで、引数で渡した条件を満たす要素が、少なくても一つは存在すればtrue、なければfalseを返す」です。

JavaScriptの[every](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every)は「配列のメソッドで、引数で渡した条件を、全ての要素が満たしたらtrue、そうでなければfalseを返す」です。

このツイートを見つけたその日、「`some`メソッド」を探すのに手間取った私は、

「確かにそうかもなー。あと多分も名前がよくないよなー」

と思いました。

---

「配列（やそれに近いもの）で、引数で渡した条件を満たす要素が、少なくても一つは存在すればtrue、なければfalseを返す」というメソッドは、他の多くのプログラミング言語では、`any`というメソッド名で存在します。

* C# [Any](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=netframework-4.7.2)
* Kotlin [any](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html)
* Groovy [any](http://docs.groovy-lang.org/next/html/groovy-jdk/java/lang/Iterable.html#any(groovy.lang.Closure))
* Ruby [any?](https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/any=3f.html) JPN
* Python [any](https://docs.python.org/3.6/library/functions.html#any)
* Haskell [any](http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Foldable.html#v:any)

`any`以外にもありますが、こんな感じ。

* Java [anyMatch](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html#anyMatch-java.util.function.Predicate-)
* F# [exists](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/list.exists%5B't%5D-function-%5Bfsharp%5D)
* Scala [exists](https://www.scala-lang.org/api/2.12.0/scala/collection/Traversable.html#exists(p:A=%3EBoolean):Boolean)
* Swift [contains(where:)](https://developer.apple.com/documentation/swift/array/2297359-contains)

---

私の一番好きな言語はC#です。JavaやKotlinでAndroidアプリも作ってました。まれにGroovyも使います。最近TypeScript・JavaScriptを仕事で使い始めました。

そんな私は、「JavaScriptの`some`メソッド」を見つけるのに手間取りました。理由は名前が`any`じゃなかったからです。

他の言語で`any`ならば、多分JavaScriptにも`any`なのかなーという予想が外れました。（実は、`exists`や`contains`は調べてた）

JavaScriptの「配列のメソッドで、引数で渡した条件を満たす要素が、少なくても一つは存在すればtrue、なければfalseを返す」なんで、`any`じゃないんや！

（多分、歴史的な経緯で標準化の時に`any`って名前は使えなかったとかかな？）

---

さて、

* 複数のプロジェクトを掛け持ちしていて、プロジェクトごとに違う言語を使う人
* 同じプロジェクトでも、部分部分で異なるプログラミング言語を使うと人

は少なくないと思います。

言語を切り替える際の頭の切り替え、大変ですよね。

各言語のコレクションライブラリは、射影・選択・数え上げ・グループ化など似たようなメソッドも多くがありますが、その実装方法・文化・流儀は異なります。そして、この投稿であげた`any`や`all`のように、言語ごとに似たようなメソッドでも名前が違います。

多くのプログラミング言語では、「射影は`map`、選択は`filter`」です。しかし、C#では「射影は`Select`、選択は`Where`」です。これには理由があり、[`LINQ `](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/linq/)というC#の言語機能に由来します。理由はしっかりあって、`Select`と`Where`という名前がSQL由来で覚えやすいという人も、なんで`Map`や`Filter`じゃないんだという人もどちらもいると思います。

また、Java、Groovy、Scala、F#に`collect`というメソッドがありますが、その仕様は全て異なります。

---

色々書きましたが、私の結論は

「コレクションライブラリ言語ごとに違って、大変だけれども、郷に入っては郷に従えだよね。大変だけれども」

です。

その言語を書いているときは、その言語の作法に従うのが良いと思っています。

正直、JavaScriptの`some`と`every`は覚えるのが大変だけど、頑張って覚えようと思います。

多分、忘れるなー

---

PS

こんな事書いておいてあれですが、C# で`Select`を`Map`で、`Where`を`Filter`で呼び出すライブラリを作りました。

LinqAliasです！

よかったらみてね！！！

https://github.com/RyotaMurohoshi/LinqAlias
Linuxでのファイルの比較(commコマンドを図示化してみた話)

# 1.はじめに
久しぶりにLinuxに触れあい、虫の息な今日この頃です。
久しぶりの投稿はLinuxのコマンド、「comm」についてです。


# 2. commコマンドとは？
* **ソート済み**のテキストファイルを比較するもの。
  - 2つのテキストファイルを比較し、ファイル1にだけあるもの、ファイル2にだけあるもの、共通するものを出力してくれます。
* コマンド  

  ``` comm [オプション] ファイル1 ファイル2 ```

| オプション                |説明　　　　　　    　| 
|:-------------------------|:------------------|
| -1                       |1列目（ファイル1のみに含まれる行）を出力しない|
| -2                       |2列目（ファイル2のみに含まれる行）を出力しない|
| -3                       |3列目（両方のファイルに含まれる行）を出力しない|
| --check-order            |全ての行の組み合わせが一致していても、ソートされているかどうかを確認する|
| --output-delimiter=文字列 |列を区切る文字列を指定する（デフォルトはTAB|


# 3. 図示化しようと思ったわけ
* オプションが難しいから。
 - オプションで指定したものを「出力しない」というのが分かりづらい。（落ち着いて考えればわかるものの、慌てているときに落ち着いて考えるのは不可能…orz)

# 4. 例

|ファイル1           |ファイル2　　　　　  | 
|:------------------|:------------------|
|111||
||222|
|333|333|
||444|
|555||
|666|666|

ファイル1は濃い青、ファイル2は薄い青で示します。

![説明.png](https://qiita-image-store.s3.amazonaws.com/0/180558/97955817-dc80-3ef9-ddcb-25c298c1adb8.png)


## 4.1  ファイル1のみにあるものを出したい場合


![only1.png](https://qiita-image-store.s3.amazonaws.com/0/180558/5eccf1da-03e4-767a-5998-af46f6be668f.png)

```
 comm -23 ファイル1 ファイル2
```


## 4.2 ファイル2のみにあるものを出したい場合

![only2.png](https://qiita-image-store.s3.amazonaws.com/0/180558/0c71de5a-09da-b3f5-81da-2f0f378a8633.png)

```
 comm -13 ファイル1 ファイル2
```


## 4.3 ファイル1,2 に共通するものを出したい場合(黄色いところ）

![common12.png](https://qiita-image-store.s3.amazonaws.com/0/180558/cde33304-6186-eed3-64e1-60b0f888d31e.png)

```
 comm -12 ファイル1 ファイル2
```


## 4.4 ファイル1,2に共通しないものを出したい場合（白抜き以外のところ）

![only12.png](https://qiita-image-store.s3.amazonaws.com/0/180558/aeec8f26-fb4b-017d-d3d2-9037c6b1778a.png)

```
 comm -3 ファイル1 ファイル2
```


# 5. 他
* ベン図を書くのはパワポが便利！
Windows10環境でExpoからGenymotionをAndroidエミュレーターとして起動する方法

#はじめに
ExpoからAndroid開発する上で実機確認が面倒くさい！
Android Studioのエミュレーターは重いみたいだから、Genymotionを使いたい！
というわけで、ExpoからGenymotionを使ったエミュレーションに挑戦してみたところ、
想像以上にスタックしたため、備忘録とQiita投稿への練習も兼ねてまとめます。

#必要なもの
* expo-cli@2.10.1
* Genymorion@3.30

#1. Expoをインストール

* [Expo](https://expo.io/)

ReactNative開発環境をお手軽に作れる凄いやつ

``` npm i -g expo-cli```でインストールします。簡単！

```expo-cli init プロジェクト名```でプロジェクトが作られます。簡単！！

プロジェクトは```npm start```で開始します。簡単！！！


#2. Genymotionをインストール

* [Genymotion](https://www.genymotion.com/)

Androidの軽量エミュレーター。
起動は早いし、UIも明快なので使いやすい
Personal Useの場合は無料なのも嬉しい。
無料版はFUN ZONEからアカウント登録をしてダウンロードできる

![qiita2.jpg](https://qiita-image-store.s3.amazonaws.com/0/200212/6b0331a5-52a8-55d1-33d9-0e7bcdb36ed7.jpeg)


#3. Genymotionの設定について
Expoの公式ドキュメントやネットの情報を見ると、Android Studio入れろとあるが、実際は不要。
Genymotion側は特に設定は必要ない。
ただ、adbの環境変数はGenymotionのものにする必要がある。
Genymotionのadbはデフォルトだと```C:\Program Files\Genymobile\Genymotion\tools```にある。
(コマンドプロンプトの方はPathが通っていたものの、vscodeから実行しているPowerShellにPathが通っていなくて、ここでも無駄にスタックしてしまった…。)

#4.エミュレーター起動
エミュレーターはGenymotionから適切なものを起動してください。私はPixelにしました。
~~最初からDeveloper Optionsに行けるので、USB デバッグを有効にします。~~
**(2019年2月20日追記)**
USBデバッグを有効にしなくてもいけました。ほとんど設定いらないですね。


ここまで来たら、あとはExpoを起動するだけ！
```npm start```で以下のような画面が出れば、
```Run on Android device/emulator```を押すとGenymotionのエミュレーターでExpoが起動します。
![qiita3.jpg](https://qiita-image-store.s3.amazonaws.com/0/200212/3719465c-17ee-2591-2ca2-dc0f70143090.jpeg)


完了！！！！！
![qiita5.jpg](https://qiita-image-store.s3.amazonaws.com/0/200212/30f4615e-3863-06f1-b62f-93ba8949143f.jpeg)


ということで、ExpoからGenymotionを起動することに成功しました。
ReactNative周り、面白いし熱いので、今後も取り組んでいきます！
typescript でT[]へのアクセスはTに推論されるが当然 undefined の時もある

typescript 3.2です。

以下のようなコードはタイプチェックを当然通るがランタイムエラーとなる。

```ts
function getFirst<T>(arr: T[]): T {
    return arr[0];
}

function splitSlash(s: string): string[] {
    return s.split("/")
}

console.log(splitSlash(getFirst([])))
```


```console
Uncaught TypeError: Cannot read property 'split' of undefined
    at splitSlash (<anonymous>:5:14)
    at <anonymous>:7:13
    at HTMLButtonElement.excuteButton.onclick (https://www.typescriptlang.org/play/playground.js:247)
```

「メソッドの戻り値の型はそのメソッドが保証する。戻り値やシグネチャは信頼する」が原則なのだけど、ArrayやObjectは低レベルなデータ構造としての側面を持っている。というかうっかり型がついているので油断してはならない。そこには JavaScript 世界がそのまま露出している。

JavaScript の Array はインデックスの範囲チェックを持っていないので存在しないインデックスにはただ `undefined` を返すだけだ。

翻ると、要素数 0 の可能性がある `T[]` を受け取って `T` の要素を必ず返すことは不可能なのでこのメソッドシグネチャが間違っていると考えられる。これはこのようにシンプルな例に限らず、コレクションのラッパークラスなどを書いているときにもよく見かける。

```ts
class Users {
    constructor(private users: User[]) { }

    public firstUser(): User {
        return this.users[0];
    }
}
```

これは `undefined` が入るはずのない箇所で突然現れる `undefined` として顕在化する。この種のコードは型による保護の便益を破壊してしまう。

例えば以下のように、`null/undefined` は除外されているはずの箇所でランタイムエラーが発生することになる。

```ts
function checkUserId(user: User, id: number): boolean {
    return user.id === id; // user.id に必ずアクセスできると思った?
}
```

で、以下のようなコードが生まれる。`User` 型はnull非許容型なのに。

```ts
function checkUserId(user: User, id: number): boolean {
    if(!user) return false;
    return user.id === id;
}
```

結局この `firstUser` メソッドが存在するために、`User` 型を受け取る箇所では常に `undefined` チェックが必要になる。そうしなければランタイムエラーの可能性を合理的に除外できない。型チェックをすり抜けて発生するリファレンスエラーは面倒だ。エラーが発生した箇所ではなく、「その値がどこで生成されたか」を追わないといけない。これはつらい。

たぶん書いていて気持ちが悪いのは、 `User | undefined` 型と区別がつかないことかもしれない。`User | undefined` 型は「もしかすると `undefined` かもしれない `User`」型より1000倍くらい優秀だ。なんたって、`undefined` かもしれない文脈で無造作に触るとコンパイルで弾いてくれる。

この不安の連鎖を断ち切るには、結局 `firstUser` メソッドを修正するしかない。素直に `User | undeflined` にしておいて後のことはそれから考えよう。例外投げてもいいし `Option` とか導入してもいいけど typescript のつくり的には `undefined` は型としてすでに表現されておりコンパイル時チェック対象なので殊更に避ける必要はないと思う。

## 結論

- シグネチャ通りの動作をさせるのはメソッド実装者の責任
- `T[]` へのインデックスアクセスは T 型に推論されるけど、`out of bound` 的例外はスローされないので騙されないこと 
- strictNullChecks を無効にして運用している人は周りにいないので割愛する。
 
ということで一つよろしくお願いいたします。
CubeMXのオプション Do not generate the main()について

# はじめに

stm32のGUIツール「stm32　CubeMX」内部の「Project Setting」内部に
「Do not generate the main()」という関数がある．最近全然stm32の開発をしていなかったこともありこれがどう役立つのかあまり考えたことがなかった．  
自分の考え結果としての，利点，欠点をメモする．

## 利点

**CPPでの開発がしやすくなる**  
デフォルトだと，main関数が`.c`ファイルないから呼ばれると，CからCPPの関数を呼び出すのがめんどくさい（個人的に）.　　
このため，main関数は`.cpp`ファイルないに記載されていると都合が良さそう，
しかし，CubeMXは基本的に`main.c`にmain関数が記載されているため，別途`.cpp`ファイル内にmain関数を書いても，main関数の競合が生じかねない．このオプションを指定することで問題が解決する．

## 欠点

CubeMXで生成された初期設定の関数`MX_○○_Init()`系の関数，Systickまわりの初期化関数を自分で呼び出す（自分で書く必要がある）
この結果，ペリフェラルを追加したり削除してもこれがmain関数には反映されないので注意が必要．

# まとめ

組み込みでもcppを使ってみたいなと感じていたので，このオプションはうれしいと感じた．
Shell でリダイレクトされない出力の書き方

## 訂正
`read -sp "Password: " PASSWORD` の出力先が標準入力になっているものと勘違いしていたが、これは誤りで標準エラーになっていました。
また、コメントで @akinomyoga さんに指摘して頂いた部分も含め大幅に修正した内容となっています。

古い記事は Qiita の編集履歴でご確認ください。

## 問題

[MySQLで該当DBの全\`table create statement\`を出力する \- Qiita](https://qiita.com/HAZI/items/fac6d0b081f9a793e386) の ShellScirpt を書いているときに困ったこと。

`read -sp "Password: " PASSWORD` 実行後改行が出力されないので、パスワード入力後のエラー発生時などに

```console
$ mysql-all-table-info -p -u master_db > report.txt
Password: mysql command error
```

と、`Password:` の後にエラー文が出てしまう問題。

これを解決するため`read -sp`の後に`echo`を書いて改行を挟むようにしたのだが、「`echo`はリダイレクトされてしまい消えてしまうが、`read`はされない」ということに気が付いた。
これは`read -sp`の出力先が標準エラー出力になっていたため。`echo`も標準エラーにしてあげることでこれが回避できる。

```shell
read -sp "Password: " PASSWORD
echo >&2
```

ただ、そもそも標準出力、標準エラー出力をリダイレクトさせる前提の場合、パスワードの入力を求めても何も表示されなくなってしまう。
かつ、そもそも今回の場合は入力を求める場合、標準入力以外からは求めない。

例えば、`mysql`コマンドの場合、標準出力・標準エラー出力・標準入力全てをリダイレクトしてもパスワードの入力が求められる。これと同じことをするにはどうしたらいいのか。

## 解決

標準出力、標準エラー、標準入力はどれもリダイレクトされる可能性があるので使用できない。
なので、直接端末に出力する方法をとる。

```shell
read -sp "Password:" PASSWORD 2> /dev/tty
echo > /dev/tty
```

- `read` は 標準エラー（ファイル・ディスクリプター番号`2`）に出力されるので、それを現在の端末(`/dev/tty`)にリダイレクト
- echo は標準出力を端末(`/dev/tty`)にリダイレクト

## おわりに

今回ググってもそれっぽい情報になかなかたどり着けなかったので書きました。
そもそも、この辺りのことはちゃんと勉強しているエンジニアの方々であれば知っていることだからわざわざ記事にならないのかな…という感じがしました。

今のところの自分の理解では、

- シェルには標準で3つのファイル・ディスクリプタが用意されている
  - 0：標準入力（stdin）、1：標準出力（stdout）、2：標準エラー出力（stderr）
  - これらはデフォルトでは端末に繋がっている(`/dev/tty`)
  - パイプ(`|`)やリダイレクト(`>`)を使うことで、それらの入出力先を変更できる
  - パイプやリダイレクトに影響されないようにするには、直接端末のファイル(`/dev/tty`)に出力する
- 出力の流れは `echo => 標準出力(>&1) => /dev/tty => /dev/ttys001 => Terminal`
- 今回は標準出力を飛ばすことによって、リダイレクトの影響を受けないようにした

という感じです。

`tty` コマンドで、現在の端末のファイル名(`/dev/ttys001`など)を調べることができるので、別ウィンドウを開いて`tty` を実行し端末ファイル名を調べたら
`command 2>> /dev/ttys002` などとすれば、エラー用のファイルを作らずに別端末に直接エラーだけを出力するようにできるというのが面白かった。

**参考**

- [ttyとかptsとかについて確認してみる \- Qiita](https://qiita.com/toshihirock/items/22de12f99b5c40365369)
- [Text\-Terminal\-HOWTO : /dev/tty のような端末スペシャルファイル](http://archive.linux.or.jp/JF/JFdocs/Text-Terminal-HOWTO-6.html)
- [ファイルディスクリプタについて理解する \- Qiita](https://qiita.com/toshihirock/items/78286fccf07dbe6df38f)
KNeighborsRegressorの解析

```
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
#subplots　=　figure内のplot生成数。(行数, 列数, plot番号)　 plot番号は生成した行列数の左上から右、左下と1,2,3,,,と続く
#figsize　=　inch表記のオプション引数。(縦サイズ, 横サイズ)　 グラフサイズ変更可能。デフォルトは(8,6)

line = np.linspace(-3, 3, 1000).reshape(-1, 1)
#linspace　=　等差数列生成。(start, stop, num) num=生成する配列(ndarray)の要素数を設定可。
#reshape = (行数, 列数) -1を設定すると元の形状から推測された値が自動で入る (-1, 1)なら1列ベクトルに自動で数値が入る

for n_neighbors, ax in zip([1, 3, 9], axes):
    #1, 3, 9の近傍点で比較
    reg = KNeighborsRegressor(n_neighbors=n_neighbors) #インスタンス生成
    
    reg.fit(X_train, y_train) #モデル学習
    
    ax.plot(line, reg.predict(line))
    ax.plot(X_train, y_train, '^', c=mglearn.cm2(0), markersize=8)
    ax.plot(X_test, y_test, 'v', c=mglearn.cm2(1), markersize=8)
    
    ax.set_title(
            "{} neighbor(s) \n train score: {: .2f} test score {: .2f}".format(
                    n_neighbors, reg.score(X_train, y_train), 
                    reg.score(X_test, y_test)))
    ax.set_xlabel("feature")
    ax.set_ylabel("target")

axes[1].legend(["model predictions", "training data/target", "test data/target"], loc="best");
```
PHP cURLを使って自動で経路情報の取得・保存を行う．（Google Map版）

##Google Map API 
については以下の記事を御覧ください． 

Google Map API で経路情報を取得する．
https://qiita.com/keijipoon/items/0394dab6b434a34a6ae7

今回は，上記の記事で行った処理を自動でファイルに保存しようというものです．

##PHPのcURLを使って，経路取得の処理を自動化する

PHPファイル(例:GoogleMapAPI.php)を作成し，以下のような処理を書きます．

```PHP:GoogleMapAPI.php
<?php
//phpでこのURLをたたく
$url = "https://maps.googleapis.com/maps/api/directions/json?origin=東京都庁&destination=東京タワー&key=YOUR_API_KEY";
 
//cURLセッションを初期化する
$ch = curl_init();

//URLとオプションを指定する
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//URLの情報を取得する
$res =  curl_exec($ch);

//結果を表示する  
//var_dump($res);

//結果を保存する
//ファイルの作成
$fp = fopen("./GoogleAPI.json", "a+" );
//ファイルにデータを入れる
fputs($fp, $res);
//ファイルを閉じる
fclose($fp);

//セッションを終了する
//curl_close($conn);
curl_close($ch);
?>

```

`php GoogleMapAPI.php`　と実行すると，
JSONファイル形式で取得してきたデータが GoogleAPI.json というファイルに保存されます．

これでとても簡単に経路情報を取得・保存することができるようになりました．