OmniAICreator/Qiita-1.07M huggingface dataset:
Colaboratoryでmatplotlibの日本語表示

## はじめに
Googleが機械学習の教育や研究用に提供しているColaboratoryを試してみた。
即座にjupyter環境が使えていい感じだったが、matplotlibで日本語を使うのに少し詰まったのでメモ。

[Colaboratory - よくある質問](https://research.google.com/colaboratory/faq.html)

## 日本語フォントをインストール
Colaboratoryはapt-getが使えるのでセルに

```
!apt-get -y install fonts-ipafont-gothic
```

などと打ち込み実行。


## キャッシュを消す
### フォントキャッシュの場所を確認

```
import matplotlib
matplotlib.get_cachedir()
```

を実行すると

```
'/root/.cache/matplotlib'
```
などとかえってくる。
ここにある`fontList.json`というのがフォントのキャッシュなので

```
rm /root/.cache/matplotlib/fontList.json
```

などとして一旦消す。

## ランタイムをリスタート
一度ランタイムをリスタートする。

## 再度描画

```
import matplotlib.pyplot as plt
 
jp_font = {'fontname':'IPAGothic'}
 
plt.plot([0, 1], [0, 1])
plt.xlabel('横軸', **jp_font)
plt.ylabel('縦軸', **jp_font)
plt.title('タイトル', **jp_font)
plt.show()
```
や、seabornを使って

```
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font='IPAGothic')
 
plt.plot([0, 1], [0, 1])
plt.xlabel('横軸')
plt.ylabel('縦軸')
plt.title('タイトル')
plt.show()
```
といった感じで試しに描画してみると

![image.png](https://qiita-image-store.s3.amazonaws.com/0/140790/ca6730d0-de3e-776f-17f9-1b03d9dee54b.png)

日本語が使える。


## 参考
- [Colaboratoryで「豆腐」をなんとかしたい](https://funmatu.wordpress.com/2017/11/24/colaboratoryで「豆腐」をなんとかしたい/)
【ColdFusion】時間のかかるダウンロード処理をタイムアウトさせる

##ファイルを生成してダウンロードさせる処理でタイムアウト時間を設けたい
Excelファイルを生成する処理なんかは何分も返ってこないことがありますね。
そこで1分経ったら諦めてもらう処理です。

```php
<!--- ダウンロードファイル作成 --->
<CFTHREAD action="run" name="making_file">
	<!--- makingFile()は成功時ファイル名を返します --->
	<CFSET variables.sOutputFileNm = makingFile()>
</CFTHREAD>

<!--- 終わるまで最大1分待つ --->
<CFTHREAD action="join" name="making_file" timeout="60000" />

<CFIF isDefined("sOutputFileNm") && sOutputFileNm neq "">
	<!--- ファイルが出来ていたらダウンロード --->
	<CFSET downloadFile(sOutputFileNm)>
<CFELSE>
	<CFIF findNoCase("RUNNING", CFTHREAD.making_file.status)>
		<!--- 終わってなければ中断 --->
		<CFTHREAD action="terminate" name="making_file" />
		<CFSET errmes = "ダウンロード処理でタイムアウトしました。">
	<CFELSE>
		<!--- 終わってるのにファイル名が返ってないのは何かのエラー --->
		<CFSET errmes = "ダウンロードに失敗しました。">
	</CFIF>
</CFIF>
```

`CFTHREAD`内の変数は、明示的に`variables`スコープを付けないと`CFTHREAD`外からはアクセスできませんので注意してください。
オレオレ機械学習ライブラリ構想（機械学習名古屋第１7回勉強会）

# 自己紹介・近況
名前: 中西克典
所属: 有限会社 来栖川電算
twitter: [@n_kats_](https://twitter.com/n_kats_)

最近、Oculus Goを買って、OculusRoomとかでVR会議とか夢見るも、する相手がいない問題等で挫折

---
# 話すこと

* 機械学習の開発
* オレオレライブラリでしたいこと

---
# 最近何をしているか
面白いモデルを思いついた、試そう

→ あ、ここ一般化してライブラリ化しとこ

→ 新しいこと思いついた（元の奴、試してないやつ）

で、そのライブラリ化しているものは、
https://github.com/n-kats/mlbase

こんなことしている中で何を思っているかの話をします

---
# 機械学習で困るところ
* 世の中に手法がたくさんあって試しきれない
* パラメータをいじっているうちにもとに戻せなくなった
* 色々作っているうちにカオスに

というか、機械学習のアルゴリズムに関係ないところに時間がかかる・・・

---
# 機械学習のアルゴリズムに関係ない部分多すぎ問題
![機械学習のコードの部分小さすぎ.png](https://qiita-image-store.s3.amazonaws.com/0/51820/fb41c0d3-d105-a1cc-444f-48fdf4a0c118.png)

機械学習のコードは黒い部分・・・

"Hidden Technical Debt in Machine Learning Systems"より

実際にこれでサービス化したりする部分を含めると・・・

---
# 最近では
機械学習工学研究会とかで機械学習開発についての議論が行われている

https://www.youtube.com/watch?v=da7BmJ9QsDU

いい動画。みんなみよう（4時間）

アルゴリズム以外に気にスべきところ多すぎ（理想では）

---
# 機械学習とは一体・・・
AI人材がーーーって世間で言われているけど、

* いかにもAI人材って人だけが機械学習のプレイヤーではない
* 色んな切り口で機械学習に関われるからみんなやろう！

---
# ここから作っているものの話

## 注意
* 気まぐれで作っている
* 完成からは程遠い
* 以下ポエム

---
# 理想(夢)
* アイデアをすぐに試せる・色んな機能をつけたい
* 複数のデータセットとかモデルをもとに構成する複雑なモデルをつくりたい
* 標準的なライブラリのインターフェースを大切にすべき  
  * scikit-learn
  * OpenAI-gym

---
# 理想(頑張りたい)
* 試したものがちゃんと記録される・再現できる
* 煩わしいデータ管理をどうにかしたい
* モデル管理をちゃんとしたい

---
# 興味のないこと
* かっこいい可視化
* 畳み込みをかっこよくかける何か
* 色んな機械学習ライブラリを統一する何か
* python2系 非unix環境

---
# 理想は結局・・・
煩雑なものを管理したい

とりあえずは、次がターゲット

* データ
* 研究
* アイデア

---
# データの管理、雑にすると
* 評価用データが訓練用にまざちゃった
* あのデータどこに置いたっけ？
* このデータ何だっけ？

---
# データの管理、管理するとすると
* 一覧が見える
* 簡単な情報も見たい
    * 数
    * 簡単な説明
    * 公開元URL
* データ内容をなんらかの「型」として表現  
入出力の形は決まりきったものが多い  
どんな意味なのかは大切

みたいな管理をすることになるのかなー

---
# 研究の管理、雑にすると
* 上手く行ったパラメータが分からんくなった
* なんでこれしたんだっけ？
* 色々やったけど、どれが大切だっけ？

---
# 研究の管理、管理するとすると
* 実験の設定の記録
* 整理
* 実験目的の記録
* アイデア段階のものの記録

のような機能が必要かなー

---
# 現状
* 設定管理系はできてきた
    * パラメータ
    * サブコマンド
    * ツール自体の設定
* データの型より先の層の型を考えたけど頓挫
* 記録書く系は適当にエディタを起動させるだけで良い気がしてきたところ

---
# まとめ？
* 機械学習には色んなプレイヤーが活躍できる
* オレオレライブラリは、ぼちぼちやってきます
* ささっと研究できるような状態に速くしたいな
Watson Studio で YOLO V3 物体検出

Watson Studio の Notebook で YOLO V3 を使って物体検出をしてみたので紹介します。
YOLOは [こちら](https://pjreddie.com/darknet/yolo/) が本家のサイトになりますが、さまざまなディープラーニングのフレームワークにも移植されています。今回は以下のKeras版を参考に、Watson StudioのNotebookでも動かせることを確認しました。

https://github.com/experiencor/keras-yolo3

# 手順
Watson Studioでプロジェクトを作成して、以下リンク先から Notebook を作成します。
https://github.com/schiyoda/YOLOV3-Keras/blob/master/yolov3_keras.ipynb

Notebookでは本家のサイトでも公開されている学習済みモデルをKerasで使用できるように変換した上で、物体検出のテストをしています。今回は有名な犬の写真で物体検出できたことが確認できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/0d22a322-f01a-fd87-bd8a-e437501ee8c2.png)

[その他の写真](https://github.com/pjreddie/darknet/tree/master/data)でも試してみましたが、いい感じで検出できています。（学習済みモデルなので当然ですが）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/d5b2e44d-6d12-3fa7-84ed-586194fa3bc9.png)
短形パルスのフーリエ変換と離散フーリエ変換の違い

# 背景

短形パルスのフーリエ変換はsinc関数と呼ばれる $\sin(x)/x$ で表現できるが、離散フーリエ変換の場合は、$\sin(Nx)/\sin(x)$ のように sinc 関数にはならない理由を疑問に思った or 理由を忘れた人向け。


## 離散短形パルスの離散フーリエ変換の式

参考文献に notation は従う($\Omega$はkをする)と、n = -q,...,0,,,q で 1 となる短形パルスの離散フーリエ変換は、

```math

y(k) = \Sigma_{n=-q}^{q} \exp(-jnk)

```

とかける。実直に計算すると、

```math

y(k) = \frac{\sin((q+1/2)k)}{ \sin(k/2)}

```

となる。式変形のコツは、$ 1- \exp(ix)$ を見たときに、$ \exp(ix/2)$ でくくり出して、
$ \exp(ix/2) \times ( \exp(-ix/2) - \exp(ix/2) ) = \exp(ix/2) \times -2i \sin(x/2)$ と変形すること。


## 離散短形パルスのフーリエ変換と離散フーリエ変換の比較

フーリエ変換で得られる sinc関数 (=$\sin(x)/x$)と、離散フーリエ変換で得られる$\sin(Nx)/\sin(x)$ を図を書いて比較してみよう。gnuplot を使うと下記のような絵が得られる。

``` bash:
>gnuplot
gnuplot> g(x,a) = sin( (a+0.5)*x ) / (0.5*x)
gnuplot> f(x,a) = sin( (a+0.5)*x ) / sin(0.5*x) 
gnuplot> set samples 10000
gnuplot> plot f(x,10), g(x,10) 
```

<img width="400" src="https://qiita-image-store.s3.amazonaws.com/0/179652/1dd82dcd-db05-82fc-fd73-6e2f7cd4acfe.png">

フーリエ変換は、無限に長い時系列データを仮定して、そのある時間だけに短形パルスがあると考えるので、周波数の高い成分は存在しない。

一方の離散フーリエ変換では、サンプリングが離散化されているため、周波数が高い波が現実的なサンプリングによって見えなくなっている可能性が残るため、どこまでも高い周波数成分が周期的にずっと存在することを許してしまう。


# 参考文献

- http://www.ssc.pe.titech.ac.jp/lectures/SignalAndAnalysis/SignalsAndSystemsAnalysis9_050627.pdf
少人数のチームでWebサービスを開発／運用するときに気を付けていること

私たちは、受注管理システムと在庫管理システム（WMS）を統合したクラウドアプリケーション「ロジレス」の提供を行っています。

![sales_orders.png](https://qiita-image-store.s3.amazonaws.com/0/644/82c1b859-4ca1-5322-70cb-187d2616d84c.png)

ロジレスの利用者は、ECサイトを運営する事業者さんと、その事業者さんの商品在庫を管理し、出荷する業務を請け負う物流倉庫さんに大別されます。

サービスの開始から3年ほどが経ち、いまでは日々たくさんの方々にご利用いただいていて、私もとても嬉しいのですが、
弊社も多くのスタートアップと同様、**めちゃくちゃ少人数でこのプロダクトを運用しています**。

しかも、受注処理から出荷までの一連の流れをすべて一元的に処理するシステムである特性上、**なんらかの理由でサービスが提供できなくなった場合の影響範囲がめちゃくちゃデカい**という特徴もあります。EC事業者さんはお客様に納期をお約束しており、一方でヤマト運輸などの配送会社さんには締め時間（当日出荷可能な最後の時間）があるからです。

幸い、サービス開始からこれまで大規模な障害は発生していませんが、少ない人数で、プロダクトの開発、運用、保守を行うにあたって気を付けていることをまとめてみようと思いました。

# (1) リスクを評価する

少人数のチームでシステムを開発／運用するうえで、私が最も大事だと考えることは**致命的な障害を起こさないことです**。

当たり前といえば当たり前なのですが、私のなかでは次のように分類しています。

- 致命的なトラブル - システムが完全に使えない／データを復元できない
- それ以外のトラブル - 一部の機能は使える／データはあとから復元できる

少人数で開発する以上、トラブルをすぐに検知し、修正できる体制を維持できるのであれば、ある程度のトラブルは覚悟してリリースしています。

一方で、ひとたび暫定的な対応で追いつけないような致命的なトラブルを起こしてしまうと、ただでさえ少ない人的リソースを莫大に消費し、開発計画を壊滅させます。もちろん、利用者の方に大変なご迷惑をおかけしてしまいます。

トラブルはないことに越したことはないですし、「軽微なバグなら利用者に迷惑をかけてもいい」と思っているわけでは決してないのですが、発生する可能性があるトラブルの規模によってリスクを正しく評価し、
リスクが高いところは手厚く、リスクが低いところはそれなりに、といったメリハリをつけた開発／運用の体制が重要だと思います。

# (2) 技術的に"攻めない"

昨今のスタートアップのトレンドとは逆行するのですが、メインとなる機能には基本的に、「枯れた」技術をなるべく使用するようにしています。

枯れた、と聞くとネガティブに聞こえますが、技術の世界ではどちらかというと「古くからある技術なので不具合が出尽くしており、またその解決も終わっている」ことを指すことが多いです。つまり、ものすごい勢いで進化するこのWebの世界で、比較的安定した技術のことなのです。

最新の技術は、劇的な効果をもたらすこともある半面、問題が起きやすく、また問題が起きた時の解決策も発見されていないこともあります。

人的リソースに余裕がない時は、なるべく新しい技術に飛びつかず、使い古されたベストプラクティスがあればそちらを使うように心がけたほうが、安定した運用につながると考えています。

# (3) 考えることを手放す

ロジレスはすべてのシステムインフラをAWS（Amazon Web Services）に統一しています。
また、UIはBootstrapを全面的に使用し、手を加える箇所は最小限に留めています。（意外と気付かれないです。）
ほかにもすでにプロダクトとして存在し、自社で開発する必要性が薄いもの機能は、可能な限り既存のシステムを組み合わせて使用しています。

Webサービスの開発／運用は、技術の範囲が非常に広範で、考えるべきことが膨大にあります。
そのすべてを細かに検証する時間は少人数チームにはありません。

サービスを提供するうえで、考えるべき内容をなるべく大きなブロックに切り出して、外注したり、既存のプロダクトを使ったり、あるいは外部のシステムとつなぎ合わせるなどして、自分たちはプロダクトのコアとなるロジックや、UI／UXに集中するようにしています。

# (4) シンプルにする

これは、プログラムもそうですし、UIもそうなのですが、一目で構造を見通することができるシンプルなものであることにこだわりを持っています。

**複雑性は悪です**。明日の自分は、今日の自分よりも頭が悪い前提で、究極はなんのドキュメントも残さなくても、機能の改修や改善に、誰でも着手できることを目指したいと考えています。

とはいえ、特定の利用者からの要求や、プロジェクトを完遂するために不可欠な暫定対応で、シンプルではないものを作らざるを得ないときもあります。
そのときは、シンプルではない領域を**可能な限り狭い範囲に閉じ込めるよう**努力します。

複雑性は、そのまわりをどんどん浸潤します。
狭い範囲に複雑性を閉じ込め、余裕があるときにきちんと除去しておかないとプロダクト全体に悪影響が及びます。

# (5) 復元できるようにする

ロジレスには在庫管理の仕組みが備わっていますが、ある商品の在庫数を正しい状態で常に表示することは、非常に難易度が高いです。
在庫はデータ上だけのものではなく物理的に移動しますし、その状態の変化を、たとえば購入者の注文などのデジタルなデータと常に関連付けておく必要があります。
在庫数が増減する要因は非常に幅広く、そのすべてをトラッキングしながら正しい在庫数を表示を維持しなければなりません。

私たちのプロダクトでは、すべての在庫数が変動するイベントをログテーブルに保存し、またほか様々なテーブルにも在庫数の断面を保管しています。
たとえ、なんらかの理由で在庫数が一時的にずれてしまったとしても、ほかのログや、在庫情報をもとに整合性を自動的に維持する仕組みがあります。

少人数のチームでは、難易度の高い機能であったとしても時間をかけて十分満足なテストを行うことが難しいケースがあります。
その場合は、ログなどの単純なデータを蓄積し、そのデータから正しい値を自動的に復元できる仕組みを用意することで、複雑な計算や出力を伴う処理を、ある程度ストレスなく開発／運用することができます。
リリースした後に、ズレを検知し、そのズレの原因を確認し、修正していけば、自然とアプリケーションの品質は上がっていきます。

# （まとめ）考えることを少なく、シンプルに

私は大変遺憾ながら天才的な頭脳は持ち合わせていなかったため、
自分のような凡人でも、Webサービスを開発し、運用するための方法を模索してきました。

そのなかで得た大事なノウハウは、「**とにかくシンプルに**」でした。
シンプルにできない問題に直面したときは、まずはシンプルに考えられる大きさまで問題を分解し、解決できるものから順番に解決していくことが大事なのです。

（少しずつ、この記事は書き足していきたいと思います。まずは暫定。）
ブラウザで完結するP2P型分散ファイル共有プラットフォーム「Orcinus Orca」

# はじめに

ブラウザで完結するP2P型分散ファイル共有プラットフォームを作ってみたので紹介します。
[Orcinus Orca](https://gateway.ipfs.io/ipns/QmYe7mLpKT557Tu1iy3hCZqp81Zu4ZfLFJruKufFAhvWYs/index.html)

# Orcinus Orcaとは
- Orcinus Orcaは分散ファイルシステムです
- Orcinus Orcaはサーバーを必要としません。誰も管理者が居ないシステムであり自立して稼働し続けます。
- Orcinus Orca自体はファイルを保持しません。
- Orcinus OrcaはP2Pで分散されたファイルアップロード機能を提供します。これはブラウザでのみで動作しています。
- Orcinus Orcaはどの国にも属していません。 あなたのブラウザにのみ存在しています。
- Orcinus Orcaはインターネットが死なない限り如何なる権力によっても止めることはできないでしょう。
- ファイルをアップロードすると、Orcinus Orcaはファイル名とファイルパスを分散KVSに記録します。 分散型KVSはすべての人が同一のデータを保持しています。
- ファイルをダウンロードしたい場合、Orcinus Orcaはファイルを探し、それをあなたに送信します。
- Orcinus Orcaはあなたのブラウザでインメモリデータベースを必要とします。 あなたのブラウザはそれをサポートしなければなりません。
- IPFSのネットワーク内で動作しているので、利用者が増えれば増えるほど強固なものになります。

要するに、まったく新しい形のファイルアップローダの実験体です。
使ってみた感想を教えてください。改善できるようにがんばります。
くれぐれも違法なファイルはアップロードしないようにしてください。本当にこればかりはお願いします…。
やるなよ！ぜったいにやるなよ！おねーさんとの約束だからな！

# 使い道

- 自作のポエムをアップロードする
- 自作の音楽を配信する
- 猫さんの写真をアップロードする

くれぐれも合法な使い方をお願いしますm(_ _)m

# 技術解説

## ストレージ層

- ストレージ層にはIPFSを使っています。javascript版の[js-ipfs](https://github.com/ipfs/js-ipfs)を使うことで、webブラウザから直接IPFSに対してファイルのアップロード/ダウンロードができるようになっています。
- アップロードしたファイルはブラウザのストレージに一時保管されます。ダウンロードのリクエストが来ると、ここから配信します。
- IPFSの制約上、ダウンロードリクエストが来た時にファイルを持ってる人がOrcinus Orcaを起動していないと、アップロードしたファイルは配信されません。
- ダウンロードした人も再配信することができるので、torrentと似ている気がしますがtorrentとは全く異なるものです。
- 同じファイルを保持する人が増えれば増えるほど、ダウンロード速度が速くなるのが特徴です。

## KVS層

- IPFSのネットワークで動作する[orbit-db](https://github.com/orbitdb/orbit-db)を使っています。
- これを使うことで、複数の利用者間で同一のKVSを扱うことができるようになりました。
- サーバーレスのシステムを構築するにあたっては、複数人が同時に読み書きできる仕組みが必要ですが、orbit-dbが解決してくれました。
- KVS自体は利用者全員で持ち合うので、止まることはありません。

#最後に

感想、改善点、バグ報告、マサカリお待ちしてます
説明文に絵が欲しいな...そのうち追加します。
pythonで日経平均株価を取得してみた・ 

今回は日経平均株価を取得してみました。今回もurllib3とBeautifulsoup4を使用しています。

まず日経平均株価のURLにアクセスしないといけません。
"http://www.nikkei.com/markets/kabu/

日経平均株価を取得するためには、データ上でHTMLを取得する必要があります。日経平均株価を右クリックして検証して、span要素のところに日経平均株価があります。

```python:qiita.rb
import urllib.request
from bs4 import BeautifulSoup

url =  "http://www.nikkei.com/markets/kabu/"

html = urllib.request.urlopen(url)

soup = BeautifulSoup(html,"html.parser")

span = soup.find(class_="mkc-stock_prices")

print(span.string)
```
AWSにてUbuntu AMIを使ったsshでおきる Permission denied (publickey).

#AWSでUbuntu AMIを使いたい
訳あってUbuntu Server 14.04 LTS (HVM) AMIが使いたくなり、sshでハマりました.

```
ssh -i <your key pass> ec2-user@<instance's IPv4>
ec2-user@<instance's IPv4>: Permission denied (publickey).
```

#解決策
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html
を見て解決しましたが,
ubuntu AMI の場合初期ユーザがubuntu でないといけないそうです.


```
ssh -i <your key pass> ubuntu@<Ipv4>
```
pythonを使って日本経済新聞のページタイトルを取得してみた。

pythonを最近始めたのですが、ある程度は基礎がついてきたので何か開発をしてみようと思い、web系には興味があるのでwebスクレイピングを始めようと思いやってみました。もっといいやり方や間違っていたら教えてくれるとありがたいです。

総合開発環境は、pycharmを使用しました。ライブラリは、urllib3とbeautifulsoup4を使用しました。

```python:qiita.rb

import urllib.request
from  bs4 import BeautifulSoup

url = "http://www.nikkei.com/markets/kabu/"

html = urllib.request.urlopen(url)

soup = BeautifulSoup(html,"html.parser")

print(soup.title.string)
```

```python:qiita.rb
株式　：マーケット　：日経電子版
```


urllib3とBeautifulSoupを使用すれば結構簡単に日経平均のページタイトルを取得することができます。
[PHP] 祝日APIを使って月末営業日を求める

## 月末営業日を求める
日本の土日祝日を除く月末最終日を求めたいときー！←
祝日データをDBに持つのも煩わしいし、APIが公開されていないだろうかとぐぐってみると、Googleカレンダーを使ったものが数多く出てきますね。
[Google Calendar API を使って祝日を取る PHP編](https://qiita.com/Chrowa3/items/93c55d83b972d0ddfa10)

上が正攻法だと思いますが、今回はちょっと実験してみたい…ということで次のAPIをお試しで使わせていただきました。
[日本の祝日を JSON / CSV 形式で返す API](https://qiita.com/matsuoshi/items/7c19e7dcf404b7d921d6)

```php:祝日を取得
function getHolidays($year) {
    $ch = curl_init();

    $options = array(
        CURLOPT_URL => "https://holidays-jp.github.io/api/v1/{$year}/date.json",
    	CURLOPT_RETURNTRANSFER => true,
    );

    curl_setopt_array($ch, $options);

    $res = curl_exec($ch);

    return array_keys((array)json_decode($res));
}
```

年をパラメータに一覧を取得して、日付だけの配列を返す関数にしました。

```php:月末営業日
$year = 2018; //パラメータ「年」
$month = 4; //パラメータ「月」

$holidays = getHolidays($year);

$last = date('Y-m-d', strtotime('last day of ' . $year . '-' . $month)); //月の最終日
$date = new DateTime($last);
while(true) {
    $w = (int)$date->format('w');
    //土日以外
    if ($w > 0 && $w < 6) {
        //祝日リストにない
        if (!in_array($date->format('Y-m-d'), $holidays, true)) {
            echo $date->format('Y/m/d');
            break;
        }
    }
    $date->modify('-1 days');
}
```

月末の取り方は↓を参考
[PHPで指定月の月初と月末の日付を取得](https://qiita.com/HamaTech/items/20b37b614ef84fb3197c)

これでいい感じに月末営業日が取れました。
さて、実サービスで使うときはどうしよう～。
みんなのPython勉強会 #38 勉強会メモ

# 実施概要

詳細は[こちら](https://startpython.connpass.com/event/92358/)

> 「Stapy秋祭り第1弾：秋の夜長のショートトーク会」
9/15～18にPyCon JP 2018が開催されます。年に一度のPythonのお祭りに合わせて、Stapyでも秋祭りを開催します！第1弾として、「秋の夜長のショートトーク会」と題し、Python好きなGeekのみなさんに、自分の好きなテーマについて自由に語ってもらうショートトークをしていただきます。LTよりは長いけど、通常の講演（GT: General Talk）より短いトークを7件、ご用意しました。秋の夜長の季節です。Pythonの楽しい話で盛り上がりましょう


# 各発表

一部の人の発表しか載せないし、大分サマってるので、詳細は勉強会ページより資料参照してください。

## 機械学習と数学 〜この秋出版される2冊の本の話〜
辻真吾さん（Start Python Club）

### 本の紹介

- [Pythonによるあたらしいデータ分析の教科書](https://www.seshop.com/product/detail/22028)
 - python3エンジニア認定データ分析試験の教科書になる らしい
 - 数学も線形代数、微分積分、確率統計の基本をおさえる
- [Pythonで理解する統計解析の基礎](https://gihyo.jp/book/2018/978-4-297-10049-0)
 - 統計をpythonで確認しながら理解するような内容
 - 著者が修士2年の方 つよい

### 機械学習と数学の関係性

- 機械学習は数学を基礎にしている
- つまり、数学でモデル化できないものは、機械学習(AI)の枠組みに乗らない
- 数学が何をモデル化しているのかという本質的な部分が重要
- 数学の限界を知れば、AIの限界もある程度わかる


## ヘルスケアアプリのグロースをpythonでした話
Takehiro Sugayaさん（株式会社FiNC）

### 背景
FiNC(ヘルステックベンチャー)のメディアサービスについて

個々のコンテンツのCTR,お気に入り率、滞在時間はわかるが、
どんなコンテンツが受けているのか、感覚的にしかわからない。

どんな単語が入った記事だとよいか、分析してみた

### 分析内容

1. コンテンツの内容を形態素解析
2. 名詞を使ってtf-idf
3. KPIとtf-idfが相関する名詞を特定する

### 施策

KPIに効いてる単語を参考にコンテンツを作成
　→　DAUあたりのPV上昇

## Pythonで始める筋トレ(競技プログラミング) 
@renjikari　さん

- コーディング速度が遅い、実装毎回ググってるのを何とかしたい
- 競技プログラミングは筋トレみたいなものでプログラミングの基礎づくりにつながる → タイトル
- プログラミングの筋トレで、基礎的な機能をググる必要がない強さが
- 難しそうに見えて、誰でも簡単に参加できる
 - AtCoderは日本語
 - 初心者はBeginners Selectionからがおすすめ
 - 土日はABC(Atcoder Beginners Contest)に参加する
 - 中級者、上級者はRegular、Grand Contestへ
 
## 物体検出の動向とPythonで動かすまで
Masato Fujitake さん（@Swall0wTech）

### 物体検出の概要

- 画像認識のモデル
 - 特徴量抽出と識別機を組み合わせたNN

- 物体検出のモデル
 - 特徴量抽出器の後段に、識別機と座標位置推定、識別機の組み合わせ
 - 2段式（Faster-R-CNN）、1段式（YOLO,SSD）に分かれる

### 今後の技術的課題
- 高精度化、高速化
- 2次元から3次元構造の推定への拡張
- 動画への展開（ブレやフォーカスずれへの対応）

- 他分野への応用
 - [DensePose](http://densepose.org/): 動画から人の3Dモデルを作成
 - [Soccer On Your Tabletop](http://grail.cs.washington.edu/projects/soccer/):　サッカー動画の選手を検出→トレースして、ARで再現


### 既存の物体検出モデルを実装する際の選択肢

- 公開されている公式のコード
- 非公式の再現実装
 - 再現性に問題があることが多く、研究での比較用途には問題がある
- chainerCV
 - コンピュータビジョン用のNNライブラリ 
 - 再現性確保を目指したモデルが用意されている
TreasureDataのレコード数の整理をした備忘録

# 何が起こったのか

現在TreasureDataを使っており、日々のデータの蓄積の他に、営業の人など様々な人が抽出したりしたものや、実験などで出力したテーブルを1つのデータベースに入れまくっており、結果無秩序に使っていたせいで、契約の約5倍ほどのレコード数となってしまい、TreasureDataの担当者に怒られてしまいました。
そして、整理しようにも、何が必要で何が不要なのかが分からない状態になっていました。

# 直近どうしたのか

基本的に全テーブルに対して、「不要」「必要」「直近のデータのみ必要」に分けました。
直近のデータのみ必要はExpireを指定するようにしました。
どうしても不明なテーブルに関しては、みんなに一定期間後に削除する旨を通知して、連絡がない場合はリネーム（論理削除）＞一定期間後に削除という手段を取りました。
既存のシステムに異常が発生する際は論理削除の時に大体発覚するので、あまり大事にはならなかった。

# これからどうするのか

今回、担当者不明のテーブルなどがありすぎたりして、それを探し出したりするのに非常に無駄な時間を費やしてしまいました。
この反省点を踏まえて、以下のルールを設けました。

- メインのデータベースは仕組み上必要なもののみとする
    - 一般のユーザーは読み込みのみとする
    - このデータベースはテーブル毎に連絡先を決める
- 実験したり、抽出結果などを出力する専用のデータベースを用意する
    - 上記データベースは作成から30日で自動削除される

とりあえずこれで運用していき、問題が出次第修正していこうと思います。

# 自動削除用シェル

TreasureDataのREST APIを利用して、作成日を取得して一定期間後にDROP TABLEで削除するシェルを作ってみました。
汚いソースですが、備忘録として残しておきます。

```bash
#!/bin/bash
##########
# TDのテーブルを作成日時を見て削除していくバッチ
# 要jq：https://stedolan.github.io/jq/
##########

##### 設定する場所
# 残しておく期間
EXPIRE_DAY=30
# TD API KEY
TD_API_KEY="Your TD API KEY"
# 削除対象のdatabase名
DATABASE_NAME="Your Database Name"

##### 以降プログラム部分
BASE_URL="https://api.treasuredata.com"

# テーブル一覧を取得する
RESULT=$(curl -H "AUTHORIZATION: TD1 ${TD_API_KEY}" "${BASE_URL}/v3/table/list/${DATABASE_NAME}")
# テーブル数をカウントする
LEN=$(echo ${RESULT} | jq length)
# 現在のtimestampを取得する
NOW=$(date "+%s")

for i in $(seq 0 $((${LEN} - 1))); do
    # テーブル名を取得
    TABLE_NAME=$(echo ${RESULT} | jq -r ".tables[${i}].name")
    # テーブル作成日
    TABLE_CREATED=$(echo ${RESULT} | jq -r ".tables[${i}].created_at")
    # テーブル作成日のUNIXタイムスタンプを求める
    CREATED_TIMESTAMP=$(date -d "${TABLE_CREATED}" "+%s")
    # 経過日を求める(小数点は切り捨てされる)
    PERIOD_DAY=$(((${NOW}-${CREATED_TIMESTAMP})/86400))
    # 作成より一定期間経っていたらDROP TABLE文発行
    if [ ${EXPIRE_DAY} -lt ${PERIOD_DAY} ]; then
        # DROP TABLE文を発行
        curl -X POST -H "AUTHORIZATION: TD1 ${TD_API_KEY}" "${BASE_URL}/v3/job/issue/presto/${DATABASE_NAME}?query=DROP+TABLE+${TABLE_NAME}" &>/dev/null
    fi
done
```

特定のプレフィックスにより、生存期間を調整できたりすると尚良いと思います。

# 終わりに

こんな事書いて欲しいとか、こんな場合どうしたのとかあれば書き足して行きますので、ご意見ください。
leafletを鍛える。その7

#概要
leafletを鍛えてみた。
地図タイルを、自作してみた。


#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/k/3/0/k30E.jpg?t=1536914950)

#サンプルコード

```
var map = L.map('map').setView([37.9, 140.1], 13);
var mvr = L.tileLayer("", {
    attribution: 'mvr',
    maxZoom: 18,
});
mvr.getTileUrl = function(coord) {
    var zoom = coord.z;
    var s = Math.pow(2, coord.z);
    var llp = L.point((coord.x * 256 + 128) / s, (coord.y * 256 + 128) / s);
    var ll = fromPointToLatLng(llp, s);
    var lng = ll.lng;    
    var lat = ll.lat;
    return "http://yumeblog.dip.jp/yb2g0.php?zoom=" + zoom + "&long=" + lng + "&lat=" + lat;
};
mvr.addTo(map);
function fromPointToLatLng(point, max_zoom) {
	var size = (1 << max_zoom) * 256,
		lat = (2 * Math.atan(Math.exp((point.y - size / 2) / -(size / (2 * Math.PI)))) - (Math.PI / 2)) * (180 / Math.PI),
		lng = (point.x - size / 2) * (360 / size);
	return L.latLng(lat, lng);
}
```

#成果物
http://jsdo.it/ohisama1/k30E


以上。
Windows10 (1803) USBの仮想プリンターポートを固定化する

#仮想プリンターポートUSB001がいつのまにかUSB002に変わり印刷できなくなる
POSプリンターをGeneric Printer Driver等で使っている場合、USBの仮想プリンターポートが使われていますが、なぜかこのポートがWindows起動中に変更されてしまうことがあります。するとプリンターがオフラインとなり印刷ができなくなります。
Windows7の頃、この現象はUSBケーブルを抜き差ししたりした時以外はありませんでしたが、Windows10になると何もしなくても頻繁に起きてしまいます。

#原因
Windows10はデスクトップ型だけでなく、ラップトップ型やタブレット型に対応するためなのか、省エネ設定に最適化されています。USBハブの給電もその設定がデフォルトになっており、電源プランが「パフォーマンス」であっても自動で変更されません。

#USBポートが停止されないようにするためには？
デバイスマネージャの「ユニバーサル シリアル バス コントローラー」の中の**``USB Root Hub``**もしくは**``USB ルート ハブ(USB 3.0)``**のプロパティを開き、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/102207/ef7f584b-4008-6952-66df-b7d387ca85d0.png)

「電源の管理」タブの**「電力の節約のために、コンピューターでこのデバイスの電源をオフにできるようにする(A)」のチェックを外します。**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/102207/33248744-61dc-6d50-656c-96553766fa43.png)
Ethereum[CryptoZombies][コントラクト・状態変数・四則演算]

#EthereumをSolidityで開発する

[CryptoZombies](https://cryptozombies.io/jp/)のチュートリアルで学習を進めて行きます。
その前にMetaMask
[MetaMastインストール参考](https://www.bitcoin-trade.info/entry/metamask)
環境はRemixで行なっていきます。
Remixのインストールの仕方は[こちら](https://qiita.com/kagami-r0927/items/1c24a8b461ac4a6396a8#solidity%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9solc%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)を参考にしてください。

#1. Version pragma
これは、コードが使用するSolidityのコンパイラのバージョンを宣言するものですあり、コンパイラのバージョンを原因でコードが壊れることを防ぐために必要なものです。
以下のように書きます。

```contract.sol
pragma solidity ^0.4.19;
```





#2. コントラクト
コントラクトとはイーサリアムアプリケーションの基本ブロックのことです。
変数や関数は全てコントラクトに属しています。
コントラクトは以下のように書きます。

```contract.sol
contract HelloWorld{

}
```

### 復習
ZombieFactoryという空のコントラクトを作成してください。
また、バージョンは0.4.19を指定してください。

```contract.sol
pragma solidity ^0.4.19;

contract ZombieFactory{
    
}
```

#3. 状態変数
状態変数とは、コントラクト内に保管され、イーサリアムのブロックチェーン上に記載されます。

```contract.sol
contract Example {
  // この部分がブロックチェーン上に記載される
  uint myUnsignedInteger = 100;
}
```

###uintとは
整数のデータ型で、負の数ではないことを示しています。
>注: Solidityでは、 uintは256ビットの符号なし整数であるuint256のエイリアスです。 uint8、uint16、 uint32など、少ないビット数でuintを宣言することもできます。しかし、一般的には、後で説明するような特定の場合を除いて、単にuintを使います。

### 復習
dnaDigitsというuintを16に設定してください。

```contract.sol
pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits =16;

}
```

#4.四則演算
・加算（足し算）: `x + y`
・減算（引き算）: `x - y`
・乗算（掛け算）: `x * y`
・除算（割り算）: `x / y`
・剰余（余り）: `x % y`
・乗数(乗数計算): `x ** y`

###復習
dnaModulusというuintを作成し、10のdnaDigits乗に設定してください。

```contract.sol
pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

}
```

次は、構造体などを扱っていきます。

こちらも参考にしてください。
[Ethereum [基礎知識]](https://qiita.com/kagami-r0927/items/d73492e3a9207c8345dc)
[thereum [プライベートネットワークに接続する]](https://qiita.com/kagami-r0927/items/af31aa6d51053787de43)
[Ethereum [etherの採掘・送金]](https://qiita.com/kagami-r0927/items/6bfe493c49f713ca6331)

# 次回

[Ethereum[CryptoZombies][ハッシュ関数・キャスト・イベント]](https://qiita.com/kagami-r0927/items/35955a5dfe6a36eacbd8)
SEO

<a href="https://www.ankarawebtasarim.net/seo/"><img src="https://ankarawebtasarimssl-59e2.kxcdn.com/wp-content/uploads/2018/09/seo-mga-bilisim.jpg"></a>

# <a href="https://www.ankarawebtasarim.net/seo/"> SEO </a>
SEO | SEO Nedir? | SEO Analiz Kıstasları

<a href="https://www.ankarawebtasarim.net/seo/"> SEO </a> hakkındaki bilgilere geçmeden önce yabancı kökenli olduğu için SEO Açılımı Nedir konusuna açıklık getirelim. SEO, İngilizce Search Engine Optimization söz dizisinin baş harflerinden elde edilmiş bir kısaltmadır. Türkçe karşılığı Arama Motoru Optimizasyonu olan bu sözcüklerin kelime anlamı dışındaki açılımı ise web sayfalarının hedefledikleri alanlarda üst sırada yer alması için yapılan çalışmalar bütünüdür.

Adres : Konur 2 Sokak 57/3 Kızılay – Çankaya | ANKARA

Telefon: 0312 418 50 66
Nim nimble install jester -d:release

### nimble install jester バージョンエラー
Windows

```terminal
>nimble install jester
Downloading https://github.com/dom96/jester using git
  Verifying dependencies for jester@0.4.1
       Tip: 4 messages have been suppressed, use --verbose to show them.
     Error: Unsatisfied dependency: nim (>= 0.18.1)
```

```terminal
>nim -v
Nim Compiler Version 0.18.0 [Windows: i386]
Copyright (c) 2006-2018 by Andreas Rumpf

git hash: 855956bf617f68ac0be3717329e9e1181e5dc0c6
active boot switches: -d:release
```

### 方法

1. 公式でダウンロードしたNimのフォルダとPATHを削除
2. choosenimをインストール [https://github.com/dom96/choosenim](https://github.com/dom96/choosenim)
 1. リリースページからzipでダウンロード [link](https://github.com/dom96/choosenim/releases)
 2. 解凍して```runme.bat```を実行
 3. Nimがインストールされる
 4. cmdに表示されたchoosenimのPATHを追加
 5. 例```C:\Users\ergop\.nimble\bin```
 6. コマンド```choosenim devel```を打つ

```terminal
>choosenim devel
Switched to Nim #devel
```

```
>nim -v
Nim Compiler Version 0.18.1 [Windows: i386]
Compiled at 2018-09-13
Copyright (c) 2006-2018 by Andreas Rumpf

active boot switches: -d:release
```

コンパイルしてバージョン変わらなかったのはなんでだろう...
nextjsのルーティングまとめ

# はじめに
nextjsの[routing](https://github.com/zeit/next.js/#routing)のREADMEに書いてあることをベースに遷移先のgetInitialPropsで取得できる内容をまとめてます

遷移後のページでは以下のコードでpath情報周りを取得してます

```jsx
import React from 'react';

export default class extends React.Component {
  static async getInitialProps({ pathname, query, asPath }) {
    return { pathname, query, asPath };
  }

  render() {
    return (
      <ul>
        <li>pathname: {this.props.pathname}</li>
        <li>query: {JSON.stringify(this.props.query)}</li>
        <li>asPath: {this.props.asPath}</li>
      </ul>
    );
  }
}
```

## ベーシックなやつ

`<Link>`にhrefに遷移先のurlを指定します

```jsx:index.jsx
import React from 'react';
import Link from 'next/link';

export default () => (
  <Link href='/general'>
    <a>general</a>
  </Link>
);
```
```
pathname: /general
query: {}
asPath: /general
```
しっかりとpathの情報が取得できてます
いまはpathnameとasPathは一緒ですが、この後で違いが出てきます

## クエリパラメーター付き
見たまんまですが、`pathname`にpathを`query`にオブジェクトを渡します
以下が生成後のpath
`/withQuery?hoge=fuga`

```jsx:index.jsx
import React from 'react';
import Link from 'next/link';

export default () => (
  <Link href={{ pathname: '/withQuery', query: { hoge: 'fuga' } }}>
    <a>withQuery</a>
  </Link>
);
```
```
pathname: /withQuery
query: {"hoge":"fuga"}
asPath: /withQuery?hoge=fuga
```
queryでしっかりと取得できてます
pathnameとasPathの違いはクエリパラメーターが付いてるかどうかでした

## ファイル名そのまま、pathを変えたい場合

nextjsは`pages/`配下のファイル名を元にルーティングしてくれますが、urlで表示されるpathは別名がいいときは`as`を使います

以下のやつのurlのpathは`/dummy`になります

```jsx:index.jsx
import React from 'react';
import Link from 'next/link';

export default () => (
  <Link href='/general' as='dummy'>
    <a>general</a>
  </Link>
);
```
```
pathname: /general
query: {}
asPath: /dummy
```

`pathname`に`href`に指定したもの、`asPath`に`as`に指定したものが取得できます

# おわりに
※追記していくと思います
【供養】アセットコピーするの作ったけどCtrl+Dで大体解決してた

エディタ拡張書いたの初めてなので記念に
ただの供養です

```
using UnityEditor;
using UnityEngine;
using System.Linq;
using System.IO;


/// <summary>
/// 指定したオブジェクトをコピーするやつ～
/// </summary>
public class CopyWizard : ScriptableWizard
{

	public Object copyBaseAsset;
	public string baseName = "";

	[Multiline(20)]
	public string createNameList;


	private Object prevObject = null;
	[MenuItem("Custom/Copy")]
	static void Open()
	{
		DisplayWizard<CopyWizard>("一括コピー");
	}

	void OnWizardUpdate()
	{
		if (prevObject == copyBaseAsset) {
			return;
		}
		prevObject = copyBaseAsset;
		baseName = copyBaseAsset.name;
	}

	void OnWizardCreate()
	{
		var path = AssetDatabase.GetAssetPath(copyBaseAsset);

		var extension = Path.GetExtension(path);
		string dirPath = Path.GetDirectoryName(path);

		var list = createNameList.SplitLine().ToList();
		list.RemoveAll(str => {
			return str.IsNullOrEmpty();
		});

		for (int i = 0; i < list.Count; i++) {

			string fileName = baseName + list[i] + extension;
			fileName = fileName.Trim();
			string createPath = Path.Combine(dirPath, fileName);
			AssetDatabase.CopyAsset(path, createPath);
			AssetDatabase.ImportAsset(createPath);
		}
	}
}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64558/d96e1159-165f-76d3-91d0-55cbbdfd7b5d.png)
BaseName + CreateNameListの改行で区切った分データができます

material_001 ~ 008まで　できるよ
ヒアドキュメントと連想配列

こんなサンプルコードを書いてみた。

```php
<?php

$size = array(
    'height' => 157.5,
    'width' => 77.4,
    'depth' => 7.7
);

echo <<<EOT
The height of "iPhone XS Max" is $size[height] mm.

EOT;
echo <<<EOT
The width of "iPhone XS Max" is ${size["width"]} mm.

EOT;
echo <<<EOT
The depth of "iPhone XS Max" is {$size["depth"]} mm.

EOT;
```

実行結果は、このように3つのケースで正しく表示できている。
![SS_20180914_110910_00.png](https://qiita-image-store.s3.amazonaws.com/0/45595/7678d488-822f-50ed-b3a7-0690428a39bf.png)


このように書くとエラーになる：

```php
echo <<<EOT
The height of "iPhone XS Max" is $size["height"] mm.

EOT;
```

> Parse error: syntax error, unexpected '"', expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING)


heightのケースが、個人的にはとても気持ち悪く感じるというか、配列でキーを文字列で与えるときは引用符で括るっていう文法を、そこだけ無視できていることがしっくりこない。
なので私はwidthかdepthのケースで書くことが多い。~~このブログみたいに~~カラー文法表示がうまく働かないケースも考慮すると、depthのケース「{$size["depth"]}」が無難なのかもしれない。
（[PHP: ヒアドキュメントと連想配列 - m6uのエンジニアっぽい日記](http://m6u.hatenablog.com/entry/2018/09/14/111609)からの転載）

---

参考文献
[変数のパース - 文字列](http://jp2.php.net/manual/ja/language.types.string.php#language.types.string.parsing)
【超簡単】Swift4で配列の中身をシャッフルする方法

##はじめに
今回はすごく簡単に配列の中身をシャッフルする方法をご紹介します。
ちなみに僕は神経衰弱のゲームアプリを使ってた時に利用しました。


##手順

※追記
Swift4.2からshuffled()という関数が追加されていたそうです。
https://developer.apple.com/documentation/swift/array/2994757-shuffled


```swift
let originalArray = [1, 2, 3, 4, 5]
let shuffledArray = originalArray.shuffled()
print(shuffledArray) // [3, 5, 2, 1, 4]
```

瞬殺ですね。
@sakuraihiromiさん、教えていただきありがとうございます。


以下自分で関数を作ったやり方

```swift

import Foundation

// 配列シャッフル
func shuffleArray(array: [String]) -> [String] {
    
    // シャッフルしたい配列
    var originalArray = array
    
    // シャッフル後の配列
    var newArray = [String]()
    
    // 乱数
    var randomNumber: Int
    
    // 配列の中身をシャッフルする処理
    for _ in array {
        randomNumber = Int(arc4random_uniform(UInt32(originalArray.count - 1)))
        newArray.append(originalArray[randomNumber])
        originalArray.remove(at: randomNumber)
    }
    
    // シャッフルした配列を返す
    return newArray
    
}
```

これで配列の中身をシャッフルする関数は完成です。
あとはこれに中身をシャッフルしたい配列を渡してあげると、

```swift

var emojis = ["🎃","💩","👾","👻","😺","😈"]

shuffleArray(array: emojis)
```
結果は以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/259967/624b018a-f778-a9fa-b472-357af9b7e70b.png)


ちゃんと中身がシャッフルされてますね！
今度は違う配列を渡してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/259967/7824662d-d11e-f0e5-97b0-41daee3efa83.png)

こちらもしっかりとシャッフルされています！
こんな感じで簡単に作れちゃいました。

##終わりに
関数にまとめておけばどの配列にも簡単に使えるので楽チン！
もっと簡単な方法があればぜひコメントください！
DynamoDB


Amazon の DynamoDB というのを使うことになった。タイミングよく DynamoDB をローカルで動かす Docker image が本家から出てたので試します。

https://aws.amazon.com/jp/about-aws/whats-new/2018/08/use-amazon-dynamodb-local-more-easily-with-the-new-docker-image/

## 準備

私は心配性なので、うっかり AWS の関係無い所に書き込んでしまわないようウソ情報を設定しておきます。

```shell
$ aws configure
AWS Access Key ID [None]: hoge
AWS Secret Access Key [None]: hoge
Default region name [None]: hoge
Default output format [None]: 
```

これで accesskey=hoge という嘘ユーザと hoge という嘘リージョンを使う設定になります。続いて dynamodb の Docker image を起動します。

    docker run -p 8000:8000 amazon/dynamodb-local

## テーブル作成

aws cli でローカルの DynamoDB にアクセスするためには常に `--endpoint-url http://localhost:8000` で接続先を指定します。

```
aws dynamodb create-table \
    --table-name hoge \
    --attribute-definitions AttributeName=HogeName,AttributeType=S \
    --key-schema AttributeName=HogeName,KeyType=HASH \
    --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 \
    --endpoint-url http://localhost:8000
```

[使用に関する注意事項](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html) の分かりづらい解説によると、DynamoDB local は内部的に access key ごと、リージョンごとにデータベースを作成します。なのでここで作成したテーブルを aws cli 以外の方法でアクセスする場合 API によっては accesskey が hoge で region が hoge である事を指定する必要があります。

引数の説明

* --attribute-definitions: [AttributeDefinition](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html#DDB-CreateTable-request-AttributeDefinitions) プライマリキーの型
  * AttributeName: プライマリキーの名前
  * AttributeType: プライマリキーの型。S (文字列) または N (数値) または B (バイナリ)
* --key-schema: [KeySchema](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html#DDB-CreateTable-request-KeySchema) プライマリキーの設定
  * AttributeName: プライマリキーの名前
  * AttributeType: プライマリキーの種類。HASH (Partition key) または RANGE (Sort key)
* --provisioned-throughput: スループット
  * ReadCapacityUnits: 一秒ごとに何回 strongly consistent reads 出来るか。(eventually consistent read はその二倍)
  * WriteCapacityUnits: 一秒ごと何回 書き込めるか。
* 属性名に予約語を使うと query に使えず面倒な事になる。[予約語](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ReservedWords.html)が沢山あるので注意。

(注意): aws dynamodb の開発者ガイドやマニュアルは肝心な内容がかなり省略されているので、引数の意味などは [API Reference](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/APIReference/Welcome.html) という別の文書を探す必要があります。

## アイテム追加

```
aws dynamodb put-item \
    --table-name hoge \
    --item '{"HogeName" : {"S": "Hogeyama Hogeta"}, "Sex" : {"S": "Male"}}' \
    --endpoint-url http://localhost:8000
aws dynamodb put-item \
    --table-name hoge \
    --item '{"HogeName" : {"S": "Higeoka Hanako"}, "Sex" : {"S": "Femele"}}' \
    --endpoint-url http://localhost:8000
```

## アイテム取得

```
aws dynamodb get-item \
    --table-name hoge \
    --key '{"HogeName" : {"S": "Higeoka Hanako"}}' \
    --endpoint-url http://localhost:8000
```


## アイテム検索

```
aws dynamodb query \
    --table-name hoge \
    --key-condition-expression 'HogeName = :a' \
    --expression-attribute-values '{":a": {"S": "Hogeyama Hogeta"}}' \
    --endpoint-url http://localhost:8000
```

## 削除

    aws dynamodb delete-table --table-name hoge --endpoint-url http://localhost:8000
Monaca の PWA 対応について

現在、ベータ版での提供ですが、Monaca で PWA アプリのビルドができるようになりました。
また、Monaca で提供しているデプロイサービスに PWA アプリの検証として利用できる Firebase が追加されました。

Monaca で PWA アプリのビルドをした後に Firebase の Hosting 用プロジェクトにアップロードすることで、PWA アプリを検証することができるようになります。

# PWA アプリの設定

Monaca プロジェクトを開き、`設定` > `PWAアプリ設定`から、必要事項を設定し、`保存`ボタンをクリックすると、`www`フォルダー配下に`manifest.json`ファイルが作成されます。

この`manifest.json`ファイルを`index.html`に設定します。

```html:設定例
<head>
  <link rel="manifest" href="/manifest.json">
</head>
```

# Firebase デプロイサービスの設定

Monaca の Firebase デプロイサービスを利用する場合は、はじめに Firebase コンソールからHosting 用のプロジェクトを作成する必要があります。

Firebase プロジェクトの作成については、Google から提供されているドキュメント等を参照してください。

Firebase コンソールからプロジェクトを作成後、`プロジェクトの設定` > `全般`に記載されている `プロジェクト ID` を確認します。

次に、Monaca で PWA アプリのビルドをしたファイルを Firebase プロジェクトにアップロードするためには、`認証用トークン`を取得する必要があります。

この認証用のトークンを取得するためには、PC に Firebase CLI をインストールし、`login:ci`コマンドを実行する必要があります。

```shell:コマンド
firebase login:ci
```

Firebase CLI コマンドについては、[Firebase CLI リファレンス](https://firebase.google.com/docs/cli/?hl=ja) を参照していください。


login:ci コマンドを実行すると、ブラウザーが起動します。
起動したブラウザーからログインすると、コマンドを実行したターミナル上に、

```
Success! Use this token to login on a CI server:
```

と表示され、下に認証用トークンが表示されるので、表示された認証用トークン確認します。


`プロジェクト ID`と`認証用トークン`の確認ができたら、Monaca プロジェクトの`設定` > `デプロイサービス`を開き、`新しく追加する`ボタンをクリックします。

「サービス名」で「Firebase」を選択し、下記の項目を入力後、`追加ボタン`をクリックします。

| 項目名        |  説明 |
|:-----------  |:------------------|
| エイリアス名   | デプロイサービスで使用する名前 |
| APIトークン   | login:ci コマンドで取得した認証用トークン |
| プロジェクトID | Firebase コンソールで作成したプロジェクト ID |


# firebase.json を設定する

Firebase デプロイサービスを利用するためには、Monacaプロジェクトのルートに`firebase.json`ファイルが必要になります。

新しい Monaca テンプレートからは、firebase.json が追加される予定になっていますが、現在は、firebase.json を新規に作成する必要があります。

firebase.json の作成は、Monacaプロジェクトの`ファイル` > `新規ファイル` を選択し、

| 項目名        |  入力内容 |
|:-----------  |:------------------|
| フォルダ   | / |
| ファイル名   | firebase.json |

を入力後、`OK`ボタンをクリックします。

firebase.json　の記述例です。

```json:firebase.json
{
  "hosting": {
    "public": "www",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

# 確認してみる

Firebase デプロイサービスの設定を行なっている場合、PWA アプリのビルドを実行し、ビルドが成功すると Firebase プロジェクトにアップロードするためのボタンが表示されます。

<img width="170" alt="firebase_button01.png" src="https://qiita-image-store.s3.amazonaws.com/0/113550/20272d6a-dce0-e5f2-fe4b-5af17dbc54b8.png">

 Firebase プロジェクトと Firebase デプロイサービスの設定が正しく行われている場合は、ビルドされたファイルが Firebase プロジェクトにアップロードされます。

<img width="170" alt="firebase_button02.png" src="https://qiita-image-store.s3.amazonaws.com/0/113550/d50b4df4-317c-b3d8-4140-7f5741f88683.png">

Firebase プロジェクトの Hosting 項目に記載されているドメインにアクセスすることで、動作確認をすることができます。


# おわりに
最近は、PWA に対応したサイトも増え、注目度も上がっています。

Googleが公開している[はじめてのプログレッシブ ウェブアプリ](https://codelabs.developers.google.com/codelabs/your-first-pwapp-ja/) のソースコードを利用することで、Monaca でも簡単に PWA アプリを作成することができますので、一度試してみてはいかがでしょうか。
App Store ConnectのスクリーンショットサイズがiPhone XS Maxにあわせて変更になりました

**Apple 公式サイトにスクリーンショットについての記事が公開されました。重要なお知らせもありますので、一番下の追記をご確認ください。**

## App Store ConnectのスクリーンショットサイズがiPhone XS Maxにあわせて変更になりました

iTunes Connect あらため App Store Connectでアプリを申請しようとして、スクリーンショットの登録でハタと手が止まってしまいました。
表題の通りなのですが、iPhone XS Maxの発表にあわせて、iPhone X系のスクリーンショットの画像サイズが5.8インチから6.5インチに変わってしまったのです。

<img width="934" alt="スクリーンショットのサイズ.png" src="https://qiita-image-store.s3.amazonaws.com/0/38924/2c768ba7-dd95-108f-d2bf-068dcc11c203.png">


ためしに5.8インチの画像を6.5インチのところに登録しようとしたら、サイズがちがうからダメですよ！　と言われてしまいました（あたりまえか）。というわけで、変更前と変更後のサイズを掲載します。

## 変更前のサイズ

こちらの記事 [iTunes Connectの審査時に必要なスクリーンショットサイズのまとめ](https://qiita.com/hideyukitone/items/4f0f155ca53a685d4378) にあるように、従来はこのようなサイズでした（iPhone Xは5.8インチです）。

|端末の向き|iPhone 5.8インチ|iPhone 5.5インチ|iPad 12.9インチ|
|:--|:--|:--|:--|
|縦|1125 × 2436|1242 × 2208|2048 × 2732|
|横|2436 × 1125|2208 × 1242|2732 × 2048|

## 変更後のサイズ

iPhone XS Maxの発表に伴い、iPhone X系の画像サイズが、5.8インチから6.5インチに変わっています。

こちらの公式サイト [スクリーンショットの仕様](https://help.apple.com/app-store-connect/#/devd274dd925) を見ましたが、まだ5.8インチのままだったので、こちらの記事 [iPhoneXS/XS Max/XR発表！歴代iPhone画面解像度早見表](https://www.dorapro.co.jp/engineerblog/?p=255) で6.5インチの画面サイズを調べてまとめたのが以下の表です。

（2018/09/17追記。アップル公式のスクリーンショットの仕様が更新されて、6.5インチについての情報も追加されました）

|端末の向き|iPhone 6.5インチ|iPhone 5.5インチ|iPad 12.9インチ|
|:--|:--|:--|:--|
|縦|1242 × 2688|1242 × 2208|2048 × 2732|
|横|2688 x 1242|2208 × 1242|2732 × 2048|

## 終わりに

新機種の発売にあわせてリリースやアップデートを計画しているかたは、スクリーンショットのサイズにご注意ください。

## 追記

Apple 公式サイトにスクリーンショットについての記事が公開されました。

[新しいデバイス用のスクリーンショットとAppプレビューのサポートを開始しました](https://itunespartner.apple.com/jp/apps/news/100002380)

こちらの記事に、重要なお知らせが記載されていたので引用します。

> ２０１９年３月以降は、ユニバーサルアプリケーションを含むiPhone向けの新規AppおよびアップデートすべてにおいてiPhone XS Max用のスクリーンショットが必須となります。これらのAppは新しいiOS 12 SDKを使用して開発し、最新のデバイスをサポートする必要もあります。

今回発売される新機種（iPhone XS、XS Max、XR）の画面サイズは、すべてアスペクト比が2:1のiPhone X系です。2019年3月以降はiPhone XS Max用のスクリーンショットが必須となることから考えても、おそらく今後はこちらの画面サイズがメインとなっていくのでしょう。

たくさんのスクリーンショットを用意するのは大変なので、今から少しずつ準備していきましょう。
RDSのIAM認証で接続失敗

# 結論

現在、MySQL 5.7.22だとうまくいきません。
[フォーラム](https://forums.aws.amazon.com/thread.jspa?messageID=862286&#862286)にありました。

下記は、大丈夫でした。

+ MySQL 5.7.21
+ MySQL 5.7.16

smallやmicroなど色々な組み合わせを試してしまいましたが、まずフォーラムを見るべきですね^^;;
「恐竜が跳ぶ」のdocker 環境構築

[前回のブログ](https://qiita.com/wanghaidong1972/items/92f22fd72620768b1fe8)で強化学習でゲームをすることを紹介したが、友達から「環境構築が面倒臭い」とコメントされたので、とりあえずDockerイメージを作ってみました。

まず　Dockerfile の全文を貼り付けます。

```Dockerfile
from consol/ubuntu-xfce-vnc
MAINTAINER authors=whd (zhangs@live.jp)

# because the base image use a non-root user we should switch to root here
USER root

# it's a bit conufusing to remove chromium here
# but it's necessary because chromium will not run under web driver but the base image pre-installed it.
RUN apt-get update && apt-get install -y git unzip \
&& apt-get remove -y chromium-browser --purge

# download miniconda(python3.6) and install
RUN wget https://repo.continuum.io/miniconda/Miniconda3-4.5.4-Linux-x86_64.sh -O ~/miniconda.sh \
&& bash ~/miniconda.sh -b -p $HOME/miniconda

# install packages we need and chrome
ENV PATH="$HOME/miniconda/bin:$PATH"
RUN echo $HOME && echo $PATH \
&& pip install opencv-python keras tensorflow hickle selenium pillow \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -   && echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list   && apt-get update -qqy   && apt-get -qqy install     ${CHROME_VERSION:-google-chrome-stable}   && rm /etc/apt/sources.list.d/google-chrome.list   && rm -rf /var/lib/apt/lists/* /var/cache/apt/*

# download source and chrome web driver . use patch here because chrome can be launched only
# with -no-sandbox option by root user. Also, the function imshow of openCV have some problems
# at docker environment.
RUN echo $HOME && echo $PATH \
&& mkdir $HOME/dino \
&& cd $HOME/dino \
&& git clone https://github.com/wanghaidong1972/dino_runner.git \
&& cd dino_runner \
&& patch dinoenv.py diffs \
&& wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip \
&& unzip chromedriver_linux64.zip

```

基本的にファイル内のコメントで説明したつもりですが、いくつかの注意点を補足します。

1. X 環境ではくても、x11vncをインストールすればVncViewで接続できるはずですが、何個か試した結果、いろんなエラーが出まして、調べるのに時間がかかりそうなので、今のBase　Imageにしました。
2. [Seleniumの本家](https://github.com/SeleniumHQ)のイメージを使ってもうまく行ったが、Docker　Composeまでもいらないのではと思って、それを使わないことにしました。
3. rootユーザーでChromeを起動する時に、--no-sandboxをつける必要です。（Patchの理由）
4. opencv のimshow 方法はDocker＋Xwindow環境ではうまく行かないようなので、コメントアウトしました。したがって、プログラムを終了するには、乱暴にChromeを閉じるか、TerminalでCtrl+C　してください。

以下手順となります。

1. build image : build -t dino_run:v1 -f Dockerfile .

2. start container: docker run -p 5901:5901 -p 6901:6901 dino_run:v1
3. connect to container : vncvieweまたはそれ同等なツールで 127.0.0.1:5901　に接続
 または　HTML5 client(like Firefox) で http://127.0.0.1:6901/vnc.html に接続。　パスワおーどは　vncpassword　です
4. Vncviewで右クリックして、Terminalを開き、 /headleass/dino/dino_runner に進み、 python runner.py　で実行させます。

でも、Docker（特にVNC経由での場合）で訓練すると、FPSが落ちるので、効果も落ちますね。この手順は普通の環境の参考として見て貰えば幸いです。
EXIN Agile Scrum Foundation を受験しました。

## はじめに
* Scrum のプロジェクトに参画して5ヶ月目に受験しました。
* それまでは、まったく Scrum に関して知識もありませんでした。
* 個人的に Scrum を実践されているまたは、これから導入しようとされている方は受験をおすすめします。
 * Scrum の知識の再学習、および定着を確認することができます。
* 私個人としては Scrum での各役割（PO、SM、開発チーム）が整理できました。
 * ウォーターフォール型（PM、PL、開発チーム）と、Scrumのメンバとの役割とがイメージつかなかったのですが、
 受験するなかで、Scrum に特化した役割なのだと理解しました。
* また模擬試験で当たり前なのですが、再認識したことがありました。
  * スクラムチームの成功・失敗の究極の責任者は開発チーム
      * 改めて自分で責任を持って対応する当事者意識がScrum チームメンバには不可欠だと感じます。
  * スプリント計画完了までの期間
      * だらだらと続けてしまわないようにタイムボックスで管理する。

## 背景
* あまり試験に関する情報がなかったので、記事の追加として記録しておきます。
 * 参考: [EXIN Agile Scrum Foundation 受験レポート](https://qiita.com/oh_rusty_nail/items/15b23ed989fa205b532c)
 * 試験に関する概要などは上記記事参照。
 * 唯一受験料が 2018/4/1~ 変更になっていました。
 * 受験料
        * 29,743円(税込)

## 受験日
* 2018/9/7(金）

## 学習概要
* 学習時間は、準備ガイドには 60 時間とありますが、そこまですれば十分だと思います。
    * 前提として Scrum プロジェクトの経験があったため
* 試験を受けるにあたり下記の資料をもとに学習しました。
    * [SCRUM BOOT CAMP THE BOOK](https://www.amazon.co.jp/dp/4798129712)
        * 読み物として読破しました。
        * まだ Scrum を実践されていない方へも漫画を通してわかりやすいためおすすめです。 
    * [スクラムガイド日本語版（2017 年 11 月）](https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.p9df#zoom=100)
        * スクラムを理解するにはこの公式ドキュメントが重要です。
    * [準備ガイド (2018 年 8 月版)](https://www.exin.com/certifications/exin-agile-scrum-foundation-exam)
        * Downloads から 日本語版を取得
        * 基本概念の一覧 に用語一覧があるので、不明点は理解しておくと良いです。
    *[模擬試験 (2018 年 4 月版)](https://www.exin.com/certifications/exin-agile-scrum-foundation-exam)
        * Downloads から 日本語版を取得

* 上記の資料を一通り学習し、模擬試験の内容はすべて正解する程度には、時間を置いて2,3回解き直しました。
    * そのなかで、単語の確認や再度不明点が整理され理解不足な部分を再度学習していきました。
Spark のテーブルの filter 条件を Map から読み込む

Spark のテーブルの filter 条件を Map から読み込む
===

## 環境

Scala 2.11.8
Spark 2.3.1

## やりたいこと

* Json の中にテーブル read の条件を書きたい。
* spark.sql を使わずに read したい

読み込んだ json の中身が、

```json
"tableName": "tableA",
"filterCondition": {
    "date": "20180101",
    "type": "A"
}
```

の場合、

```scala
val df = spark.read.table("tableA").filter($"date" === filterCondition.date && $"type" === filterCondition.type)
```

みたいなものを、動的に生成してほしい。


## 解決策

Map 型に map (ややこしい)を適用する際には、case を使う必要がある。

```scala
  def loadTable(spark: SparkSession, tableName: String, filterCondition: Map[String, String]): DataFrame = {
    if (filter.isEmpty) {
      spark.read.table(tableName)
    }
    else {
      spark.read.table(tableName).filter(filterCondition.map{case (key, value) => col(key) === lit(value)}.reduce(_ && _))
    }
  }
```

参考：https://stackoverflow.com/questions/8812338/scala-mismatch-while-mapping-map
MarkdownをRedmine用のTextile記法に変換する

標準だとTextile記法で書かなくてはならないRedmineですが、管理者権限があればMarkdown記法に変更できるらしい。

でも管理者権限を持っていないので、ドキュメント変換ツール「Pandoc」でmdファイルをtextileファイルに変換しRedmineに反映することにした。

Pandocをインストール

```
$ brew install pandoc
```

mdファイルをtextileファイルに変換して別名保存

```
$ pandoc test.md -o test.textile
```

これをRedmineに貼る。
しかしRedmineがコードブロックを処理してくれない。

textile記法だとコードブロックは

```textile
bc(html). <link href="/css/index.css" rel="stylesheet" type="text/css">
```

となるが、Redmineでは

```html
<pre><code class="html">
<link href="/css/index.css" rel="stylesheet" type="text/css">
</code></pre>
```

のようにHTMLで書かなければならないようだ。
そこで、Pandocのフィルター機能でこの部分を変換するようにする。

まず、pandoc-filterをインストール。
これでfilterをnode.jsで記述できるようになります。

```
$ npm i pandoc-filter -g
```

次にフィルターとなるファイルを用意する。

```javascript:forRedmine.js
#!/usr/bin/env node

const pandoc = require('pandoc-filter');
const RawBlock = pandoc.RawBlock;

const action = (key, value, format, meta) => {
  if (key === 'CodeBlock') {
  	[ [, lang, ], code ] = value;
    const syntax = (lang.length) ? ` class="${lang}"` : '';
	return RawBlock('html', `<pre><code${syntax}>${code}</code></pre>\n`);
  }
}

pandoc.toJSONFilter(action);
```

このファイルをフィルターとして呼び出す。

```
$ pandoc test.md -o test.textile --filter=forRedmine.js
```

成功。

ちなみにSublime Text 3で行う場合は、Package ControlでPandocプラグインをインストール。
Pandoc.sublime.settingsに以下のようなセッティングを追記。

```json
{
  "user": {
    "pandoc-path": "/usr/local/bin/pandoc",
    "transformations": {
      "Textile": {
        "new-buffer": 1,
        "scope": {
          "text.html.markdown": "markdown"
        },
        "syntax_file": "Packages/Textile/Textile.tmLanguage",
        "pandoc-arguments": [
          "--to=Textile",
          "--filter=/〜/forRedmine.js",
        ]
      },
    },
    "pandoc-format-file": ["docx", "epub", "pdf", "odt", "beamer", "textile"]
  }
}
```

これでわざわざコマンドを叩かなくても変換したものを新規ファイルとして開いてくれます。
end2end とは

#意味
「両端で」「端から端まで」という意味の英語表現

#情報通信の文脈で
通信・ネットワークの分野で、通信を行う二者、あるいは、二者間を結ぶ経路全体を意味する。
通信ネットワークやプロトコルの設計原理の一つに「エンドツーエンドの原則」(エンドツーエンド原理)と呼ばれるものがある。これは、高度な通信制御や複雑な機能を末端のシステムが担い、経路上のシステムは単純な中継・転送のみを行うというものである。

インターネットを始めとするTCP/IPネットワークはこの原理に基づいて構成されており、誤り訂正やフロー制御、再送などの機能はTCP層のシステムが、単純な送受信・転送処理をIP層のシステムがそれぞれ担当している。

#ディープラーニングの文脈で
ディープラーニングは、「end-to-endmachinelearning」と呼ばれることがあります。ここで言うend-to-endとは、「端から端まで」という意味であり、これは生データ(入力)から目的の結果(出力)を得ることを意味します。
【JavaScript】Self Objectの値を参照してプロパティ値設定したい

## やりたいこと
```js
const COLORS = {
  ERROR: '#f00',
  HOGE: this.ERROR, // Not Working
};
```

## どうやるか
オブジェクトにgetterをもたせる

```js
const COLORS = {
  ERROR: '#f00',
  get HOGE() { return this.ERROR; }, // Working!!!
};
```

定数管理のオブジェクトにどうぞ

参考元：stack overflow
> [javascript - Self-references in object literal declarations - Stack Overflow](https://stackoverflow.com/questions/4616202/self-references-in-object-literal-declarations)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103475/317ced3e-497a-8af4-9e8c-2ad8ad50e62e.png)
Android アプリ内でのクライアント証明書認証

苦戦したのでメモ。

#基礎知識

[Android アプリのセキュア設計セキュアコーディングガイド](https://www.jssec.org/dl/android_securecoding_20150601.pdf)

「5.4. HTTPS で通信する」の項を参照。オレオレ証明書を使った使用例までは載ってますが、クライアント証明書を使った使用例は載ってません。


#下準備

[クライアント証明書を要求するサイトの構築](https://qiita.com/tukiyo3/items/b5e8b3efce800b0fd269)

認証局側で、p12 形式のクライアント証明書ファイルを発行します。


#Androidアプリ側の実装

クライアント証明書ファイル（sample.p12）は、/assets/ フォルダに配置。

通信部分の実装で、ローカルに配置したクライアント証明書を読み込むメソッドを用意して…

```java
// クライアント証明書の登録
private void registerClientCert ( Context context ) throws Exception {
    KeyManagerFactory keyManagerFactory;
    final char[] PASSWORD = "".toCharArray();
    InputStream inputStream;
    try {
        // クライアント証明書ファイルの指定（/assets/ フォルダに配置）
        inputStream = context.getResources().getAssets().open( "sample.p12" );
        KeyStore keyStore = KeyStore.getInstance( "PKCS12" );
        keyStore.load( inputStream, PASSWORD );
        keyManagerFactory = KeyManagerFactory.getInstance( "X509" );
        keyManagerFactory.init( keyStore, PASSWORD );
        SSLContext sslContext = SSLContext.getInstance( "TLS" );
        sslContext.init( keyManagerFactory.getKeyManagers(), null, null );

        HttpsURLConnection.setDefaultSSLSocketFactory( sslContext.getSocketFactory() );
    } catch ( IOException e ) {
        throw new Exception( e );
    } catch ( KeyStoreException e ) {
        throw new Exception( e );
    } catch ( NoSuchAlgorithmException e ) {
        throw new Exception( e );
    }
}
```

実際の通信部分で一枚かませます。

```java
// クライアント証明書使用設定
try {
    this.registerClientCert( context );
} catch ( Exception e ) {
    e.printStackTrace();
}
```

うまくできていれば、サーバ側で受けた php では、こんな感じで確認可能。


        $_SERVER["PHP_AUTH_USER"]=> "sample"
        $_SERVER["REMOTE_USER"]=> "sample"


#小ネタ
-クライアント証明書が付いてないアクセスが来たときに、apache 側で即弾くのではなく、サーバ側アプリ（php等）でより柔軟にエラー対応したい場合、apache 側のコンフィグ設定で、SSLVerifyClient : optional に指定しておくと良い。
-Android 端末自体に、クライアント証明書を仕込むこともできるが、仕込んだ瞬間から「通信が盗み見される危険性があるよ！」的な警告メッセージがユーザに出まくるようになるので、自分自身が分かってて運用するならともかく、他人に使って貰うのはとても無理っぽい。
PhpStormで PHP language level が変更できない時の対応方法

- 環境
    - OS : Windows10 64bit
    - PhpStorm : 2018.1

# 事象：PHP language level が変更できない
[Setting] > [Languages & Frameworks] > [PHP] > [PHP language level] が非活性で変更できない

# 対応： `Synchronize IDE settings with composer.json` のチェックを外す
1. [Setting] > [Languages & Frameworks] > [PHP] > [Composer] > [Synchronize IDE settings with composer.json] のチェックを外す
1. [Apply]ボタンで反映する

# 参考
- [[PHPStorm] 使用するPHPのバージョンの設定を変更する - Qiita](https://qiita.com/qiita-kurara/items/a2f43bbff02d043f3949)
- [PhpStorm ユーザーのための IntelliJ IDEA ハンズオン のすすめ - なんたらノート第三期ベータ](http://tanakahisateru.hatenablog.jp/entry/2017/11/05/061020)