OmniAICreator/Qiita-1.07M huggingface dataset:
エスケープシークエンスで文字のタイプを変更する

## 目的
カラフルな出力には`\033[93m`といった特殊文字が用いられる.
それらを全て暗記するのは困難であるので，一括で表示するコードを書いた．
筆者は`alias colors='...'`と`.bash_profile`に追記することで呼び出せるようにしている．
## 環境
```bash:python
$ python
Python 3.6.4 |Anaconda custom (64-bit)| (default, Jan 16 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
## コード
```python:color.py
#!/usr/bin/env python

for i in range(110):
    print(f'\033[{i}m' + '{0:3d}'.format(i) + '\033[0m', end = ' ')
    if str(i)[-1] == '9':
        print('\n')
```
## 実行
![スクリーンショット 2018-03-09 21.51.45.png](https://qiita-image-store.s3.amazonaws.com/0/183420/0ce38897-cc65-f982-4d96-0886f7d76feb.png)

おわり．
802.11mc対応APの構築

Android P developper preview が　802.11mc / FTM / ToF / Indoor positioning with Wi-Fi RTTに対応したというこで802.11mcの評価環境について調べてみました。

自分の理解では、この機能を使うには対応したAPを用意しないと使えません。

現時点(2018-03)には、市販されているAPは対応していません。(そのうち Google Wifiが対応するような気がしますけど。)

追記：２０１９年１月ごろにGoogle Wifiが802.11mcに対応したらしいです。→→ https://speakerdeck.com/napplecomputer/wi-fi-rttniyoruwu-nei-ce-wei-apuriwozuo-rou

結論から言うと、「 Intel 8260　を搭載したLinuxマシンを使って、８０２．１１mc対応APを構築できる。」です。　（でも自分は試せてません）


手順は
https://bugzilla.kernel.org/show_bug.cgi?id=197187
のチケットのコメントとリンクに書いてありますが、まとめてみます。

# 追記
Google I/O 18 の セッション [How to get one-meter location-accuracy from Android devices (Google I/O '18)](https://www.youtube.com/watch?v=vywGgSrGODU&t=0s&list=PLOU2XLYxmsIInFRc3M44HUTQc3b_YJ4-Y&index=112) で、Google WiFiがまもなく11mc対応することが正式発表されてました。ビデオの21分ごろです。

# 802.11mc対応AP構築手順

## 準備
* Intel 8260　を搭載したLinuxマシンを２台用意する。
* https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/backport-iwlwifi.git/ からCore30リリースをダウンロード
* https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi/core_release の手順でビルドしインストール
* https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi/core_release からIntel8260 Core31 のFWをダウンロード
* hostap 2.6 をダウンロードしてビルド
* iwの最新版をダウンロード
* e nl80211.hをCore30のドライバソースコードからコピー
* https://bugzilla.kernel.org/attachment.cgi?id=258801&action=diff をiwにパッチしてビルド

## AP 操作手順
* ドライバをロード
* hostapでAPを起動

```
driver=nl80211
interface=wlan0
hw_mode=g
channel=13
wmm_enabled=1
ssid=tof_test
ftm_responder=1
ftm_initiator=1
```

* sysfsからtof responderの設定を行う

```

# cd /sys/kernel/debug/iwlwifi/0000:06:00.0/iwlmvm/netdev:wlan1
# echo channel_num=1 > tof_responder_params#
# echo bssid=bb:bb:bb:bb:bb:bb > tof_responder_params
# echo rate=1 > tof_responder_param
# echo ftm_per_burst=5 > tof_responder_params
# echo send_responder_cfg=1 > tof_responder_params
```

## STA 操作手順
* ドライバをロード
* tofリクエストを送信して、tofレスポンスを表示 ```bb:bb:bb:bb:bb:bb``` はAPのMACアドレスに置き換える。

```
# cd /sys/kernel/debug/iwlwifi/0000:06:00.0/iwlmvm/netdev:wlan1
# echo send_tof_cfg=1 > tof_enable
# echo 'num_of_ap=1' > tof_range_request
# echo 'ap=0 1 0 0 bb:bb:bb:bb:bb:bb 0 10 0 5 5 0 0 0 0 -40' > tof_range_request
# echo 'send_range_request=1' > tof_range_request
 
# cat tof_range_response
request_id = 0
status = 2
last_in_batch = 1
num_of_aps = 0
```
* iw を使ってftm requesstを送信して、レスポンスを受信。```bb:bb:bb:bb:bb:bb``` はAPのMACアドレスに置き換える。

```
# echo bb:bb:bb:bb:bb:bb bw=20 cf=2472 > /tmp/config.txt
# iw dev wlan0 ftm_request /tmp/config.txt
phy #1: FTM result! Status: 0
Target: bb:bb:bb:bb:bb:bb, status: 4, rtt: 0 psec, distance: 50 cm
```




# あとがき
* さて、これ本当に動くんでしょうかね。
* まぁ、もうちょっとしたら、お手軽に試せるようになるとは思います。
* それから、802.11mcのスペックは2017/12/31にpublishされたので、半年後の2018/06/01にget802のページから無料でダウンロードできるようになります。
ブロックチェーン基礎の基礎：ブロックチェーンのイメージを理解する

#ブロックチェーンとビットコインの関係

はじめに、ブロックチェーンとビットコインにはどういう関係があるのか説明します。

一言でいうと、**「ブロックチェーンの１つの応用例がビットコインである」**ということになります。ビットコイン以外にも、金融をはじめとして、サプライチェーン、医療、著作権管理など様々な分野でブロックチェーンの技術が使われていたり、使われようとしていたりします。

したがって、ビットコインの仕組みを理解するだけで、ブロックチェーン全体を理解することにはならないのですが、まずは、イメージがしやすいビットコインでブロックチェーンの基礎を理解し、必要性に応じて個々のブロックチェーン技術の応用例を理解していけば良いのではないでしょうか。


#ブロックチェーンのイメージ

ブロックチェーンは下図のようにブロックが鎖のように繋がった構造になっています。
後に繋がったブロックほど新しく、前のブロックほど古いブロックになります。

![blockchain_image.png](https://qiita-image-store.s3.amazonaws.com/0/208575/4de457b6-4e3e-8df2-c936-90c04b51103c.png)

トランザクションとは、ビットコインの場合**「取引履歴」**になります。
「AさんからBさんへ○BTC支払われました」というような内容が記録されています。

このように、ブロックチェーンは**取引の内容が含まれたブロックが鎖状に次々と繋がっていく構造**になっているのです。

ナンス値、ハッシュ値については次のブロック生成の節で説明します。


#新しいブロックの生成
では、この取引内容を入れていくブロックはどのように生成されるのでしょうか。無条件にブロックを生成するというわけにはいかないので、特定の条件を満たすハッシュ値を持つブロックのみを正しいブロックであるとみなすようになっているのです。この条件というのが、ビットコインの場合、**「ハッシュ値の先頭に、一定の数以上の0が並んでいる」**というものなのです。

ここで、前節にでてきたナンス値とハッシュ値の関係について説明します。ハッシュ値はナンス値からハッシュ関数というものを使って求めることができます。しかし、ハッシュ関数の性質により、このハッシュ値からナンス値を求めることは極めて難しいものとなっています。したがって、ブロックを生成するために必要な条件を満たしたハッシュ値を探すためには、ナンス値を変えていって総当りで探すしか方法がないのです。

この、条件に合ったナンス値を探す行為を**「マイニング」**と呼び、ブロック生成に一定の条件を与えるこのような仕組みのことを**「PoW(Proof of Work)」**と呼びます。

#ブロックチェーンの全体像
ブロックチェーンは**「分散型台帳」**とも呼ばれ、下図のように各ノードが同一のブロックチェーンを保持する構造になっています。ここで、ノードとは個々のコンピュータだと思ってもらって構いません。

<img src = "https://qiita-image-store.s3.amazonaws.com/0/208575/19f6d9dc-4811-c94b-6c85-82ebec4f9176.png" width=100%>

この構造の特徴は、既存の金融機関のように特定の組織が集中的に情報を管理するわけではなく、**ネットワークの参加者全員で管理**しているということです。また、**個々のノードが直接相互の情報をやり取りすることができる**という点もポイントです。

#ブロックチェーンのメリット
前節のブロックチェーンの構造を踏まえると、ブロックチェーンの主なメリットは以下のようなものになります。

- データの改ざんが困難である
- P2Pでのやり取りが可能である
- すべての取引を全ノードが確認できる


一つ目の**「データの改ざんや複製が困難」**というのは、ブロックチェーンのとあるブロックを改ざんするためには、それ以降のすべてのブロックの内容を改竄する必要があることからきています。トランザクションが格納されたブロックは、前ブロックのハッシュ値を持ってチェーン状につながっています。そのため、あるブロックを改ざんすると、後続のすべてのブロックのハッシュ値を再計算する必要があり、改ざんが困難になっているのです。

二つ目の**「P2Pでのやり取りが可能」**というのは、現行のシステムと異なり、仲介者を経由せずにカネ、モノをやり取りできるので、仲介手数料がかからないということになります。また、これまで中央集権的に管理するのに必要であった人件費や設備費などのコストも不要であるということになります。ちなみに**P2P**とはPeer to Peerの略で、個々が対等の立場で通信ができる通信方式を指します。

三つ目の**「すべての取引を全ノードが確認できる」**というのは、一部のノードがダウンしても、他のノードが情報を持っているため、全体が影響を受けることは少なく、障害に強くなるということです。さらに、サプライチェーンなどの取引の透明性が重要になってくる様々な分野にも応用できるということになります。

#ブロックチェーンの将来

ブロックチェーンの技術はビットコインをはじめとする仮想通貨だけでなく、個人間取引から公的サービスまで様々な用途に応用されています。また、それぞれが固有の課題を抱えている状況でもあります。これからのブロックチェーンがこれらの問題をどのように解決していき、進化を遂げるのかとても興味深いものがあります。
axes.revelで2次元配列を1次元配列に変換し、効率よくプロットする。

毎日、pythonと格闘しているumesakuです。「pythonで始める機械学習」のP.144に謎の一文があったのでちょっと掘り下げてみました。

###画像を愚直にプロットする

```ruby:qiita.rb
from sklearn.datasets import fetch_lfw_people
import matplotlib.pyplot as plt
%matplotlib inline
#jupyter notebookで動かす時はこの呪文が必要になります。

people = fetch_lfw_people(min_faces_per_person=20, resize=0.7)

# 先に名前のリストをとっておく
names = []
for t in people.target:
    names.append(people.target_names[t])

# 名前を短くしたいので写真は別の変数名にする
images = people.images

# テキストでは2行5列。ちょっと楽をして2行3列に写真を並べた。
fix, axis = plt.subplots(2, 3, figsize=(15, 8), subplot_kw={'xticks':[], 'yticks':[]}) 

# サブプロットの画像表示メソッドがimshow
# サブプロットのタイトルに名前表示。setを忘れずに
axis[0, 0].imshow(images[0]) 
axis[0, 0].set_title(names[0]) 
axis[0, 1].imshow(images[1])
axis[0, 1].set_title(names[1])
axis[0, 2].imshow(images[2])
axis[0, 2].set_title(names[2])
axis[1, 0].imshow(images[3])
axis[1, 0].set_title(names[3])
axis[1, 1].imshow(images[4])
axis[1, 1].set_title(names[4])
axis[1, 2].imshow(images[5])
axis[1, 2].set_title(names[5])
plt.show()
```

上記のコードでは一つずつに対して写真と名前をセットしているが、サブプロットの数が増えてくると、どんどんどんどん大変。100枚とか、もー無理（汗）。

<b>ループで効率よく処理したいんだけど、axis が 2 次元配列で、names/images が 1 次元配列だから単純なループにしたらエラーになっちゃう。私では到底処理できない（いやいや簡単にできるよという方、ぜひ教えてください！）</b>

だから、<b>axisをaxis.revel()</b>で一次元配列にする。
そうすれば、names/images/axis が一つのループで書けるようになる。

###テキスト通り書いてみた
P.144です。ちょっとaxis1 = axis.ravel()でアレンジしています。

```ruby:qiita.rb
fix, axis = plt.subplots(2, 3, figsize=(15, 8), subplot_kw={'xticks':[], 'yticks':[]}) 

#axisを1 次元配列にする
axis1 = axis.ravel() 

# これで一つのループで書ける
for name, image, ax in zip(names, images, axis1): 
    ax.imshow(image,cmap='Greys_r')
    ax.set_title(name)

plt.show()
```

###アウトプット

どちらもアウトプットは同じです。なぜか黄緑色になっちゃいますけど（涙
axes.revelは覚えておこう！

※以前axesとaxisは違うとご指摘頂きました。調べても良く理解できませんでした。なので、今回両方試行したのですがどちらも同じ結果になりました。また、見て頂けてご指摘頂けたら嬉しいです！

<img width="576" alt="LFW.png" src="https://qiita-image-store.s3.amazonaws.com/0/241427/01c5cfe5-4e16-ed31-b571-61974f0ebc7a.png">

追、@skotaroさんのアドバイスで、ax.imshow(image, cmap='Greys_r')とすると白黒写真のようになりました！cmapとはカラーマップ、_rはreverseの略で'Grey'だけだと白黒写真の反転バージョン、ということのようです！
Android airアプリ内でcontenteditable="true"のdivをフォーカスした時に、入力エリアがキーボードにかぶる

今回の環境は
lrabel blade + vue.js です。
[Android の WebView にキーボードが被る問題](http://sea-mountain.hatenablog.jp/entry/2013/09/24/001338
)
こちらの記事にあるような状況になってしまったので、html、css、jsにて対応しました。

##入力エリアの上にキーボード被る問題
LINEのようなチャットシステム内で、

```css
position :fixed;
bottom   :0;
width    :100%;
heidht   :100px;
```
上記プロパティを当てた入力エリアをタップした際、
キーボードが入力エリアコンポーネントの上に被ってしまい、何を入力しているのかわからない現象に陥りました。


入力エリアでは[絵文字](https://www.emojione.com/)を使えるようにしていたため、`div`を使用していました。

```html
<template>
    <div>
        〜〜省略〜〜
        <div contenteditable="true" id="emoji_editor" class="emoji-editor-content"></div>
       　　〜〜省略〜〜
    </div>
<template>
```

##解決策
被る事を回避させることができませんでしたので、`emoji-editor`をタップした際にclassをふって、無理やりcssにて高さを出す仕組みを用意しました。(:cssを使えない状況でした)

```html
<template>
    <div>   
        <div class="emoji-editor-wrap is_android-app"> //入力部分クリックでis_android-appを付与
            〜〜省略〜〜
            <div contenteditable="true" id="emoji_editor" class="emoji-editor__content"></div>
       　    　〜〜省略〜〜
        </div>
    </div>
<template>
```

```css
.emoji-editor-wrap.is_android-app{
    height:400px;
}
```

そして、`settimeout` を使用してフォーカスを当てました。

```js
$(document).on('touchend', (e) => {
    if (!$(e.target).closest('.emoji-editor__content').length) {
        setTimeout(() => {
            messageFooter.removeClass('is_android-app');
            emojiEditorContent.blur();
        }, 200);
    } else {
        messageFooter.addClass('is_android-app');
        setTimeout(() => {
            emojiEditorContent.focus();
        }, 200);
    }
});
```

`settimeout`を使用しないと、フォーカスがあたりませんでした。
(`settimeout`を０にすると、挙動がおかしくなったので200にしました。)

こちらを参考にしました[jquery - Set focus on div contenteditable element - Stack Overflow](https://stackoverflow.com/questions/2388164/set-focus-on-div-contenteditable-element)
資料作りのためのmatplotlib入門(1) 1次元図

# この記事のターゲット
* 理論シミュレーションとかで出てきたデータをグラフ化する方法を探している人
* 今までgnuplotを使っていたけどPythonにも興味がある人
* でも何からやればいいのかよくわからない人
* というか「matplotlib、いろんな流儀ありすぎィ！」って混乱してる人

目次

1. 1次元図（この記事）
1. 2次元contour図 https://qiita.com/Bluepost59/items/a0869aee34db3f450162


# 想定しているデータ形式
配列を扱える言語は多い。fortranでもCでも多次元配列は普通に使えるが、出力する場合は、例えば次のようなコードで出すことが多いと思う。

```fortran
do i=1,Nx
   write(UNITNUM,*) i,a(i)
end do
```
このコードを実行すると、次のような形でデータが並ぶことになる。

```
1 0.000E00
2 0.628E00
...
10 0.810E01
```

# matplotlibのインポート
Pythonでグラフを書くときは、次のライブラリを使う。

* NumPy<br>行列を扱うためのライブラリ
* matplotlib<br>グラフを書くライブラリ
* matplotlib.pyplot<br>matplotlibのインターフェースのようなもの

おのおのの詳細についてはもっとググってもらうとして、この三つがあればグラフは書ける。
普通にローカルのPCにインストールする場合、GUIが使えるが、たとえばリモートのスパコン上のデータを可視化したりするときは必ずしもGUIが使えるとは限らない。そのときは画像に出力する設定（gnuplotのset term pngcairoのような感じ）をしなければならないが、ここにつまづくポイントがある。
まず、NumPyとmatplotlibをインストールする。次にmatplotlib.pyplotをインストールする前に、matplotlibをpngで出力するように設定する。具体的には次のようになる。

```python
import numpy as np
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
```
この順番を間違えるとエラーが出る。

# データの読み込みと整列
データの読み込みはnumpyのloadtxt関数で行う。これはNumpy配列を返す関数で、以下のように記述する。

```python
mydata = np.loadtxt('mydata.txt')
```
このときmydataの中身は

```
[[1,0.0000],
[2,0.628],
...,
10,0.810]]
```

とNx行2列行列となる。
一方、matplotlibで描画に用いるplotメソッドは、次のようになる。

```python
myax.plot(x,y)
```

このxが横軸、yが縦軸の数値リストであり、ともに同じ次元を持つ1次元リストでなければならない。つまりnp.loadtxtで読み込んだmydataからx,yに整列する必要がある。ただし今回は「mydataの1列目」と「mydataの2列目」とするだけでよいので、次のように指定するだけでグラフにできる。

```python
myax.plot(mydata[:,0],mydata[:,1])
```

#サンプルコード
https://gist.github.com/Bluepost59/133efb85f3f50a16fd2e823074879c28

```python
import numpy as np
import matplotlib as mpl
matplotlib.use('Agg')
import matplotlib.pyplot as plt

mydata = np.loadtxt('mydata.txt')

myfig = plt.figure()
myax = myfig.add_subplot(1,1,1)

myax.plot(mydata[:,0],mydata[:,1])

myfig.savefig('mydata.png')
myfig.clf()
```
ここでfigureとaxesについて触れておく。figureとaxesはmatplotlibのオブジェクトで、figureが画像全体で、axesは各グラフに対応する。イメージとしてはfigureという台紙にグラフに対応するaxesを貼り付けていくような感じである。pltに直接メソッドを作用させていくやり方もあるが、このサンプルコードのようにfigureオブジェクトとaxesオブジェクトを定義するやり方もあり、後者の方が複数枚並置する場合などに拡張しやすい。
AWSで高価なインスタンスの落とし忘れをなくす

# 結論

```shell-session
(local--dayo)$ ssh (対象サーバー)
(server-dayo)$ crontab -e
# 次の内容を追加
0,5,10,15,20,25,30,35,40,45,50,55 * * * * curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"shinde nai yo!:\\n `vmstat`\"}" https://hooks.slack.com/services/$YOUR_API_KEY
```

タイトルはやや釣りでした。すみません。AWSである必要はありません。
とても原始的だけど、とても効果があると思いました。
ちょっと重めの処理を走らせているので、ついでにvmstatでメモリの推移とか色々見ています。
~~ansibleで入れたzabbixでやれとか言わないで~~

# その他の方法

- 適当なIAMを使って、一定時間特定のプロセスが生きていなかったらころす
- billing alarmとかをつかう

エバンジェリストの方によると、
http://yoshidashingo.hatenablog.com/entry/2014/09/04/100548

個人的には、機械的に殺すとやっぱり万一の時にイラっとするので、適切なアラートを飛ばすぐらいでよいのかなと
オフラインリアルタイムどう書く F10 の実装例

問題 : http://nabetani.sakura.ne.jp/hena/ordf10updown/
実装リンク集 : https://qiita.com/Nabetani/items/dae474bc17827f9b1537

実装戦略は、概ね2つある。

ひとつは、マス目を埋めていく作戦。マス目が埋まれば上下左右の隣は簡単にわかる。
難点は計算量が多くなることだけど、今回のテストデータは最大でも7000弱なので、マス目を埋めても間に合う。

そんな実装を、ruby で。

```ruby:ruby2.5
def solve( src )
  upperbound = (src+5)*2 # 根拠薄弱な計算
  pos=0+0i
  phase=0
  map={}
  target=nil
  (1..upperbound).each do |n|
    map[pos]=n
    target=pos if n==src
    case phase
    when 0
      pos+=1
      phase=1
    when 1
      pos+=1i
      phase=2 if pos.real==pos.imag
    when 2
      pos-=1
      phase=3 if pos.real==0
    when 3
      pos+=1i
      phase=4
    when 4
      pos+=1
      phase=5 if pos.real==pos.imag
    when 5
      pos-=1i
      phase=0 if pos.imag==0
    end
  end
  [target-1,target+1, target-1i, target+1i ].map{ |pos|
    map[pos] || "-"
  }.join(",")
end

DATA.map do |line|
  num, src, expected = line.split( /\s+/ )
  actual = solve( src.to_i )
  okay = expected == actual
  p [ ( okay ? "ok" : "**NG**" ), num, src, actual, expected ]
  okay
end.all?.yield_self{ |x| puts( x ? "everything is okay" : "SOMETING WRONG" ) }

__END__
0 10  9,25,-,11
1 1 -,2,-,4
2 2 1,9,-,3
3 4 -,3,1,5
33  6772  6771,6773,6677,7009
```

下→左→上→右→下→左 で、一周期。各移動を `phase` の 0〜5 に割り当ててみた。
どこまでやるかは不真面目に計算していて、ゴールの二倍ちょっと回せばいいんじゃないかといういい加減な実装になっている。

平面なので複素数を使って。
実装をミスって、下方向が実部、右方向が虚部になっている。単なるミスなんで、他意はない。

続いて別の実装。

数値から場所、場所から数値に変換できればいいというもの。
マス目の数値がどう並んでいるか、構造を理解する必要があるので算数が嫌いだと苦しいかもしれないけど、計算量がすごく少ないし、不安も少ないので仕事ならこちら一択。

そんな実装を、python で。

```python3:python3
import math

def num_at(x,y):
  if x<0 or y<0:
    return None
  layer = max(x,y)
  offset = None
  if layer % 2 == 0:
    offset = y if y<x else layer*2-x
  else:
    offset = x if x<y else layer*2-y
  return layer**2 + offset + 1

def pos_for( num ):
  layer = math.floor(math.sqrt(num-1))
  offset = num-1-layer**2
  r = [ offset, layer] if offset<layer else [ layer, layer*2-offset ]
  if layer % 2 ==0:
    r.reverse()
  return r

def impl( src ):
  x,y = pos_for( src )
  return [
    num_at(x,y-1),
    num_at(x,y+1),
    num_at(x-1,y),
    num_at(x+1,y)
  ]

def solve( src ):
  return ",".join( [ str(x) if x else  "-" for x in impl( int(src) ) ] )

def test( num, src, expected ):
  actual = solve( src )
  okay = actual==expected
  print( ( "ok" if okay else "**NG**" ), num, src, actual, expected )

test( 0, "10", "9,25,-,11" )
test( 1, "1", "-,2,-,4" )
test( 33, "6772", "6771,6773,6677,7009" )
```

何度も書いているんだけど、いまだに慣れないのは `iftrue if cond else iffalse`。
あと。
上記で `r.reverse()` しているけど、`reversed(r)` を return した方がきれいだと思う。上記を書いた時点では、`reversed` の存在を知らなかった。

出題者としては、上記2つが主な戦略だと思う。
マス目を埋める方の埋め方がいろいろあると思うけどね。
エンジニアの二年目病とその予防法④

こんばんは。10分で生産的なミーティングができるWebサービス「[minmeeting](https://minmeeting.jp/)」を開発している伊勢川です。

<a title="minmeeting - 10分で生産的なミーティングができる会議ツール" href="https://minmeeting.jp/" target="_blank"><img width="100px" src="https://qiita-image-store.s3.amazonaws.com/0/199506/32e65577-a5bb-2c3b-4d30-4690c3c5ce0f.png" /></a>

3月に突入し、もうすぐ新人エンジニアの皆さんも二年目の先輩エンジニアになることでしょう。そこで、余計なお世話ですが、<B>二年目エンジニアが陥りがちな症状と予防法</B>を何回かの連載で紹介しています。

昨日は気が利く頑張りやさんがなりやすい症例を紹介しましたが、本日は一年目にそれなりに優秀だったせいか（または、手がつけられなかったのか）<B>先輩から放置されていた人がなりやすい</B>症状をご紹介します。

# 放置プレイ依存症
せっかく後輩がついたのに、その後輩が活躍できるような教育もせずに、今年の新人はイマイチだなどと愚痴っている先輩社員を目にしたことがないでしょうか。ぜひそんな人にはならないでください。
<B>自分が新人のときに放置されていたからといって、そういうもんだと思い込まない方がよいです</B>。よほど優秀で自分で道を切り拓きたいという人でない限り、放置した方がよいことは特にありません。<B>負の連鎖は自分で断ち切りましょう</B>。

## 症例
自分が新人のときは放置されていたから、今年の新人も放置しておこうという考え方に陥ってしまう。

新人に仕事を頼んだ際に、自分が思っていた以上に時間がかかってしまい、プロジェクトを遅延させてしまう。遅延の原因は、新人のスキル不足だと考え、次から自分でやることで問題を回避しようとする。

新人を手厚く指導をしたが半年経ってもなかなか独り立ちしてくれない。自主的に勉強しようという姿勢もなく、会社に居る時間に言われたことだけ消化しようとする新人に苛立ち、こいつはもうダメだと見限ってしまう。

## 予防法
プログラミングができれば自分は仕事ができると思ったら大間違いです。<B>教育はエンジニアの重要な仕事</B>の1つだと認識してください。

自分が新しい道を切り拓くことができるエンジニアであったとしても、ずっとひとりでやっているとスケールアウトもスピードアップもできません。<B>新しい道を切り拓いたら、そのノウハウを誰かに伝えて仲間を増やし、自分はさらに先に進まなければなりません</B>。

<B>ソフトウェアは放っておいたら死</B>んでしまいます。メンテナンスを続けたとしても、同じところでとどまり続けると腐ってしまいます。<B>立ち止まったら終わり</B>です。<B>前に進むためには教育して仲間を増やすのも重要な手段</B>の一つです。

また、<B>人に仕事を頼む時は、自分ができると思った時間の2倍〜3倍かかる</B>と思っておけばちょうどよいでしょう。2年目くらいのときはタスクの全体像を把握していなかったり、リスクの積み方や係数の経験則がないため、<B>見積もりが甘くなりがちだから</B>です。また、要件の伝達の仕方もこなれていないため、一回でスムーズにタスクが終わる可能性は低いです。よって、自分の<B>見積もりの3倍以内で完了したら、頼んだ相手は優秀</B>だと思った方がよいでしょう。

最後に、<B>半年くらいうだつが上がらないからと言って、大事な後輩を見限るのは時期尚早</B>です。サラリーマンの場合、エンジニア人生は40年くらいあります。最初の2〜3年の成績が悪かったからといって、40年ずっとそうだという訳ではありません。<B>5年目〜10年目くらいでようやく花開く人も</B>います。私も昔、できの悪い後輩を3年目くらいでとっくに見限っていましたが、私の先輩が根気強く指導を続けた結果、5年目を過ぎた頃にほんとに頼れるエンジニアになっていたのを目の当たりにして、自分は間違っていたと気付かされたことがあります。ぜひ読者の皆様は私と同じ間違いを犯さないようにしてください。

# バックナンバー
1. [エンジニアの二年目病とその予防法①　Google依存症](https://qiita.com/Akira-Isegawa/items/220dcbd9a1639099a325)
1. [エンジニアの二年目病とその予防法②　すぐできる・なんでもできる病](https://qiita.com/Akira-Isegawa/items/d62eea7a7804ecc5fb2e)
1. [エンジニアの二年目病とその予防法③　雑用ホイホイ症候群](https://qiita.com/Akira-Isegawa/items/d6e181c354278bc0ab87)
Windows10のIISへwebアプリを配置するために必要な機能の有効化

# 概要
Windows10 64bitのIIS（バージョン10.0.16299.15）にASP.NET webアプリケーションを配置した。
Windows7 32bitのIIS（バージョン7.5.7600.16385）では同じ手順でサービスが動いたのに、動いてくれない。
調査した結果、Windows機能の有効化にて項目を追加することが必要と分かった。
# 詳細
Visual Studio（Community 2017）でwebデプロイパッケージを発行し、Windows10のIISにwebサイトを追加してパッケージのインポートを行った。
Visual Studio上でデバッグを行ったところ、クライアント側のConnected Servicesでエラー405が返ってくる。（「リモートサーバーから予期しない応答が返されました：（405）Method Not Allowed。）
全く同じ手順をWindows7のIISで行うと、サービスはちゃんと動くのだが。。。

![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/fa9a6e72-c4b6-bb60-3c3a-80f286bc4d73.png)

ブラウザでアクセスすると、ディレクトリまでは開ける。

![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/a5061f7c-3c3e-7b44-65aa-ae8876de26bf.png)

しかし、その先のサービス名を指定すると404エラーとなる。

![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/f2539157-7100-0f8c-8e9f-0e6e64254077.png)

いろいろ調査を続けて、たどり着いたのがこちらの情報。
http://surferonwww.info/BlogEngine/post/2017/02/05/wcf-servce-hosted-by-aspnet-returns-http-404-17-error.aspx
有意義な情報をありがとうございました。

Windowsの機能の有効化において、IIS（インターネットインフォメーションサービス）の各項目に加え、「.NET Framework 4.7 Advanced Services」-「WCFサービス」-「HTTPアクティブ化」にチェックONが必要だった。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/05743c03-61ac-196f-0129-15a3859e4121.png)

前述の情報では「.NET Framework 4.7 Advanced Services」のところが「.NET Framework 4.6 Advanced Services」となっており、.NET のバージョンによって変わる模様。
機能を有効化した後、サービスが動くようになった。
Rails 1,backdropの使い方備忘録  2,z-indexとスタック文脈の概念

#状況
仕事で振られたタスクの処理。
↓↓↓
Railsアプリケーションでヘッダーにドロップダウン機能（dropdown）が動いているときに
他のリンクをクリックするとそのページに飛んでしまう（ロゴを押せばトップページに、フォーム画面だったとしたらボタンが押せてしまう等）ので防ぐ
言い換えればドロップダウンしてでてきた部分以外触る事が出来ず、
一度クリック動作をしてドロップダウンが引っ込んでから他をいじれるようにする。



http://black-flag.net/jquery/20110526-3128.html
参考↑
上の記事の様にリンク個別での処理ではなく、今回はbootstrapsを使っていて、
navbarタグを用いたヘッダーだったので

http://www.wivern.com/bootstrap/javascript.html#modals-events
参考↑

>モバイル・デバイスでは、開いているドロップダウンは、正しい iOS サポートの必要から、メニューの外側をタップしたときにドロップダウンを閉じるためにタップ領域として .dropdown-backdrop を追加します。このことは、モバイルでは開いているドロップダウンから異なるドロップダウン・メニューに切り替えるには、余分にタップが必要であることを意味します。



こちらを参考にJsでコードを記述した。
Jsはprogate流し見しただけで自己判断でいじるのはほぼほぼ初の試み。

#ソースコード
ヘッダーの変更だったので共通ファイルを一ついじれば他に適応するので楽だなぁ


```rb:application.html.erb
<script type="text/javascript">
	$(function(){
		$('dropdown').on('show.bs.dropdown',function(event){
		 $("dropdown-backdrop").show();
	});
		$('dropdown').on('hidden.bs.dropdown',function(event){
		 $("dropdown-backdrop").css("display" , "none");
	});	
	});
</script>
.
.

<% if current_member%>
<li class="nav-item dropdown">

 <div class="dropdown-backdrop" style="display:none;"></div>
</li>
.
.

```

他に検索中みたのはこのbackdropは標準装備されてるのでしょうか？
dropdownをクラスに与えて使う事になる時に勝手に生成されるのでしょうか？ないのでしょうか？

よくわかりませんでした。
今回は無かったので自分で記述。

```rb:/application.scss

.dropdown-backdrop{
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 990;}

```


#解説
https://stackoverflow.com/questions/30925699/hide-bootstraps-dropdown-backdrop-css-only
↑参考

・view側でデフォルトとして該当のdivタグをstyleオプションにてdisplay:noneに設定してます。
・CSSにて該当のクラスを上下左右すべて 0 で設定し全体を覆うようにデザインしてます。（中身は何もないです）
・z-indexの数値はどこかのサイトにのっていた参考数値をそのまま張付けてみました。

・Jsの動きを口語にするとdropdownが表れれば、デフォルトでnoneにしているdivタグを.showで更新、dropdownがとじればサイドcssメソッドでnoneに更新してます

↓こちらに助けられました。
http://bootstrap3.cyberlab.info/javascript/dropdowns-events.html#


#あとがき
紹介すればほんの短いコードですが正解にたどり着くのに2時間かかりました。
二時間後。。。

｛悲報！｝
問題発生：フッダーのリンクが押せてしまう


#状況2

ドロップダウンしてでてきた部分以外触る事が出来ず、
一度クリック動作をしてドロップダウンが引っ込んでから他をいじれるようにする。
を目標に書いたきた

が、なぜかフッター部分だけいじれてしまう。
なんでや！！


試行錯誤しながら触っているとbackdropの数値を10000　と桁が違うほど上回るように書き換えたが反応なし。
逆にフッターnavbarのz-index数値をbackdrop（990）を下回るように書き換えると成功。

？？？？？？？？？？？？？

ますますわかんなくなりましたが結果的にアプローチは間違ってないなとおもいました。


#原因究明
デベロッパーツールなど駆使した結果発見したのが、
前述した
>今回はbootstrapsを使っていて、navbarタグを用いたヘッダーだったので

ここに謎解く肝がありました。
じつはフッターもnavbarクラスを使用していました。
両方ともbootstrapのnavbarを利用しており、それぞれ別のクラス名（例：fixed-top,fixed-bottom 等）も付随してつけてあったがそのクラスのCSS を確認してみると共通してz-indexの記述があり、同値であった。同値であったのだ。1030　!!

z-index:1030;

するとなにが起こるか。
https://app.codegrid.net/entry/z-index-1
↑参考（めちゃクちャ分かりやすかったです。全て書いてあります）

”一言であらわすとbackdropの親であるヘッダーのnavとフッターnavが同じスタックレベルにいるため”
だった。
該当のドロップダウン機能もヘッダー（navbarタグ）のなかにある（入れ子状態）なので、
dropdown-backdropのz-indexをどれだけ上げても反応なし。
逆にヘッダー側を少し下げただけでうまくいったのはフッターnavがヘッダーnavのz-index値を下回ったためであると考えられる。

#あとがき２
その後の処理はどうしたのかかいてないがヘッダフッターに共通してあった1030という数値は
bootstrapを読み込んででてくるデフォルトの数値である為、
なるべくnav側の書き換えを行いたくない。
とのことで書き換えませんでした。
これまたJsでドロップダウンが表れている時はフッターの数値を1029にするなど、なんでもできます。

最初は自分用メモだったのが進めて行くうちに何故か人向けを意識しての敬語に。
駄文です。
Jenkins1.x系に2.x系対応のプラグイン入れようとしたら、起動しなくなった。

#前説
- 今回入れようとした問題のプラグイン
https://jenkins.io/projects/blueocean/
ナウいPipelineツール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/122901/5f8c3baa-f657-b87d-98ec-ac5e24902bc9.png)

- その結果、ずっとこうなりました。一向に起動しません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/122901/f4db6753-e58a-17cd-a392-9630506f8153.png)

- 環境のJenkinsのバージョンというと1.6。古い

```bash
$  curl -v --silent http://xxx.xxx.xxx.xxx:8080 2>&1 | grep X-Jenkins:
< X-Jenkins: 1.638
```

#1. 現象
- 上記のBlueOceanプラグインを入れたところ、依存関係の関係で下記の図のプラグインもアップデータしてしまった。※本当は警告でてたら入れちゃダメ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/122901/f01440d2-ad21-a7a3-b6ef-236980349b66.png)

/var/log/jenins/jenkins.logを見ると下記のようなログが流れており色々なプラグインが入っている。

```bash:/ver/log/jenins/jenkins.log
Mar 07, 2018 7:16:29 PM hudson.model.UpdateSite$Plugin deploy
WARNING: Adding dependent install of blueocean-rest for plugin blueocean-pipeline-editor
Mar 07, 2018 7:16:29 PM hudson.model.UpdateSite$Plugin deploy
WARNING: Adding dependent install of blueocean-commons for plugin blueocean-rest
Mar 07, 2018 7:16:29 PM hudson.model.UpdateSite$Plugin deploy
WARNING: Dependent install of blueocean-commons for plugin blueocean-pipeline-editor already added, skipping
Mar 07, 2018 7:16:29 PM hudson.model.UpdateSite$Plugin deploy
WARNING: Adding dependent install of pipeline-model-definition for plugin blueocean-pipeline-editor
Mar 07, 2018 7:16:29 PM hudson.model.UpdateSite$Plugin deploy
WARNING: Adding dependent install of credentials-binding for plugin pipeline-model-definition
~中略~
```

#2.  一時対応
- とりあえず/ver/log/jenins/jenkins.logや依存関係でアップデートしたプラグインをヒントに、依存関係で入れてしまったプラグインのバージョンをひたすらGUI上から戻してみる。(ダウングレード)
(例)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/122901/da61516c-7268-2c8b-4f28-f0e442503681.png)


- 結果(ダメ)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/122901/f4db6753-e58a-17cd-a392-9630506f8153.png)

# 3. 最終対応(結果的に直ったやつ)
参考 : http://www.ringohub.com/entry/2018/01/17/145618

- jenkinsのプラグインを管理している「/var/lib/jenkins/plugin/」配下を見ると1つのpluginについて下記の3つのファイルが存在していた。普通は2個で+.bakができていた。
    - **{plugin_name}**
    - **{plugin_name}.jpi (zip)**
    - **{plugin_name}.bak (zip)**
    - →{plugin_name}.bakが一つ前のバージョンなのでこれを見るように修正します。(unzipします)


####**修正手順**
1.「/var/lib/jenkins/plugin/」の中で修正前(1日前)にアップデートしたファイルを可視化します。

```bash
$ find . -maxdepth 1 -mtime -1 | grep -v ".jpi" | grep -v ".bak"  > target.list
```
上記で引っかかったファイルアップデート対象のプラグインファイルです。


2.「1のファイルをアップデートするシェル」を用意します。

```bash:run.sh
#!/bin/sh
echo $1 >> result.log // リストが全て修正されているかカウントします。
mv $1.jpi $1.jpi.latest  // jpiを.latestとして参照をなくします。
mv $1.bak $1.jpi // bakが一個前のプラグインのバージョンのためこれを参照させます。
mv $1 $1.latest //既存の参照先ディレクトリを.latestとして参照をなくします。
unzip $1.jpi -d $1 // 4行目で.bak→.jpiをunzipで解凍します。
```

3.「run.sh」を実行します

```bash
$ cat target.list | xargs -I{} ./run.sh {}
$ wc -l result.log
// ここでtarget.listと件数が一致していたら大丈夫なはずです。
```

4.「Jenkinsを再起動します」

```bash
$ kill -9 <PID> // ps aux | grep jenkinsでPIDを確認しておく。
$ service jenkins start
# service jenkins restartでも可
```

結果 → 直りました
初心者がPHP5.4からPHP7.1へバージョンアップしてみた

## 前書き
なぜか最新のバージョンでないPHP5.4をインストールしてしまっていたので、PHP7.1をインストールし直しました。
備忘録としてここに残します。
私自身、PHPをちゃんと書きはじめて３ヶ月程度のペーペーなので、おかしい箇所がいくつかあるかもしれませんがその際はご指摘いただけると幸いです。

## 環境
CentOS 7.4.1708
Apache 2.4.6 

## 手順

### 1. epelリポジトリ、remiリポジトリをインストール
まずepel？remi？リポジトリ？って感じですが、[こちら](http://zudoh.com/archives/144)によると
>レポジトリとは動作の確認できているコンパイル済みのバイナリファイルを集めたストレージのことで、自分でわざわざソースコードの入手・コンパイルなどを行わなくても簡単に導入できます。
またソフトウェアが必要としているソフトウェアの依存性も自動的に検出して、必要な物も一緒にインストールしてくれます。

とのことです。
つまり、そのままPHPをインストールしようとするとソースコードを入手したりコンパイルをしたりしなければなりませんが、
epelやremiを使えば、そういった煩わしい手順を省いて簡単にインストールができるということですね。

ということでまず最初にインストールします。

```
$ sudo yum install epel-release
$ rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```



### 2. バージョンの確認

```
$ rpm -qa | grep php
php-cli-5.4.16-43.el7_4.x86_64
php-pdo-5.4.16-43.el7_4.x86_64
php-common-5.4.16-43.el7_4.x86_64
php-mbstring-5.4.16-43.el7_4.x86_64
php-mysqlnd-5.4.16-43.el7_4.x86_64
php-5.4.16-43.el7_4.x86_64
```

5.4.1が入っています。



### 3. 念のため設定ファイルを避難

```
$ cp /etc/php.ini /tmp
```



### 4. 古いバージョンのPHPを削除

```
$ sudo yum remove php-*
削除しました:
  php.x86_64 0:5.4.16-43.el7_4                  php-cli.x86_64 0:5.4.16-43.el7_4              
  php-common.x86_64 0:5.4.16-43.el7_4           php-mbstring.x86_64 0:5.4.16-43.el7_4         
  php-mysqlnd.x86_64 0:5.4.16-43.el7_4          php-pdo.x86_64 0:5.4.16-43.el7_4
```



### 3. PHP7.1をダウンロード

```
$ sudo yum install --disablerepo=* --enablerepo=remi,remi-php71 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt
```


よしこれで完了だ！ということで動作確認をしてみると、MysqlのPDOが使えず、could not find driverと出てしまう。
phpinfo()で確認してみると…
driverにmysqlがない！

てことでmysqlndパッケージをインストールしてみる。

```
$ sudo yum install --enablerepo=remi-php70 php-mysqlnd
```

Apache再起動。

```
$ sudo systemctl restart httpd
```

で、ようやくちゃんと動きました。
ただダウンロードするだけでなくいろいろパッケージを入れておかねばならないんですね。

## 参考

http://zudoh.com/archives/144
https://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e
https://qiita.com/toriiico/items/e2d951bc7e598d7609fb
Mixed Reality Toolkit - Unityが提供するSingtonパターンに使える機能について

# インスタンスを1つにしたいときにMRTKは2種類ある。
SingletonパターンはGoFデザインパターンの1つで、何かとよく使います。特に共通系の機能やパラメータを扱う場合によく使うテクニックの1つですが、Mixed Reality Toolkit - Unityの中にもいくつか便利なクラスが提供されています。今回はたまたまよく似た2つの部品を見つけたのでそれぞれの違いについて整理してみました。

## 今回の開発環境

* Unity 2017.2.1p2
* Windows 10 Fall Creators Update
* Mixed Reality Toolkit - unity 2017.2.1.1
* Visual Studio 2017

## MRTKで提供されるSingletonパターンに当てはまるもの

MTRKでは２つの機能が提供されています。

* Singleton<T>
* SingleInstance<T>

それぞれオブジェクトを一意に扱うための機能ですが範囲が違います。

### Singleton<T>
あるコンポーネントを一意で扱うときに継承します。このクラスを継承されたオブジェクトはInstanceプロパティを使ってどこからでもクラスにアクセスすることができます。なお、Singleton<T>クラスを使用するとDontDestroyOnLoad
でインスタンス化される形になります。

#### 実装例と使い方
実装方法はいたって簡単です。Unityの[Project]タブ内で[Create]-[C# script]を選択して新しいスクリプトを追加します。
次のMonoBehaviorの代わりにSingleton＜T>を継承します。Tには今回作成したクラスを設定します。

```csharp
public class Foo : Singleton<Foo>
{
  public string Bar()
  {
     return "Samples";
  }
}
```

Fooクラスを使う場合、Foo.Instanceでインスタンスにアクセスします。

```csharp
 var data = Foo.Instance.Bar();
```

#### 使用時の注意事項
この機能を利用する際には実装時にいくつか注意が必要です。

##### 1. 継承クラスでAwake/OnDestroyを利用する場合はOverrideで実装
Singleton<T>クラスはAwakeメソッドの中でオブジェクトをインスタンス化します。その後Instanceプロパティでアクセスできます。また、インスタンスが破棄されるとOnDestroyメソッドで後処理を実施します。
このため、Awake/OnDestroyを使う場合はオーバーライドで上位クラスのAwake/OnDestroyを呼び出すように実装してください。

```csharp
public class Foo : Singleton<Foo>
{

 public override void Awake()
 {
 
  base.Awake();
  //....
 }
 
 public override void OnDestroy()
 {
 
  base.OnDestroy();
  //....
 }


  public string Bar()
  {
     return "Samples";
  }
}
```

##### 2.このクラスを使用する場合はStartメソッド以降で
Singleton<T>クラスはAwakeで初期化を行ってます。このため、Unityでのオブジェクトのライフサイクルを考慮すると他のコンポーネントのAwakeで呼び出した場合、Singleton<T>クラスの初期化が完了していない場合がありえます。このため、インスタンスのアクセスはStartメソッドからにした方がよいと思います。

### SingleInstance<T>
あるコンポーネントを一意で扱うときに継承します。このクラスを継承されたオブジェクトはInstanceプロパティを使ってどこからでもクラスにアクセスすることができます。Singleton<T>クラスとは異なり、こちらはDontDestroyOnLoadを使っていません。

#### 実装例と使い方
実装方法はいたって簡単です。Unityの[Project]タブ内で[Create]-[C# script]を選択して新しいスクリプトを追加します。
次のMonoBehaviorの代わりにSingleInstance＜T>を継承します。Tには今回作成したクラスを設定します。

```csharp
public class Foo : SingleInstance<Foo>
{
  public string Bar()
  {
     return "Samples";
  }
}
```

Fooクラスを使う場合、Foo.Instanceでインスタンスにアクセスします。

```csharp
 var data = Foo.Instance.Bar();
```

#### 使用時の注意事項
この機能を利用する際には実装時にいくつか注意が必要です。

##### 1. 継承クラスでOnDestroyを利用する場合はOverrideで実装
SingleInstance<T>クラスはインスタンスが破棄されるとOnDestroyメソッドで後処理を実施します。このため、OnDestroyを使う場合はオーバーライドで上位クラスのOnDestroyを呼び出すように実装してください。

```csharp
public class Foo : SingleInstance<Foo>
{
 public override void OnDestroy()
 {
 
  base.OnDestroy();
  //....
 }

  public string Bar()
  {
     return "Samples";
  }
}
```

##### 2.このクラスを使用する場合はシーン内にこのコンポーネントを複数設置してはいけない。
SingleInstance<T>クラスから一意のインスタンスを取得するにはInstanceプロパティを利用します。このInstanceプロパティは、FindObjectsOfTypeメソッドを用いてインスタンスを検索します。そして、この検索結果が１インスタンスの場合のみ値を返します。例えばFooコンポーネントを複数のGameObjectに登録し、Instanceプロパティを使用すると、正しいインスタンスが取得できないかnullとなります。
このため、SingleInstance<T>クラスはシーンの中に１つだけ設定するようにしてください。

## 両方の使い分けについて
Singletonパターンでオブジェクトを作る場合１つだけ用意するという点では同じですが、スコープの範囲がことなります。
Singleton＜T>クラスは、シーンを横断して一意にする場合に利用します。そこまで広いスコープが必要なくシーン内で一意であればよい場合はSingleInstance<T>クラスで対応します。
多重階層のハッシュをストレス無く作れるクラスを作ってみた


 {1=>{2=>{3=>"a"}}}　みたいな多重階層ハッシュを簡単に扱えるようにHashをちょっと改良したクラスを作ってみました。

```ruby:ruby

class MyHash < Hash
  def [](key)
    if has_key? key
      super
    else
      self[key] = self.class.new
    end
  end
end

```

ちょっと雑ですが、以下のようにさくっと動きます。


```irb:irb

my_hash = MyHash.new

my_hash[1][2][3] = "a"

puts my_hash
=> {1=>{2=>{3=>"a"}}}
```

ループするとこんな感じ

```ruby

my_hash = MyHash.new

data = [
  [2018, 3, 20, "◯"],
  [2018, 3, 21, "☓"],
  [2018, 3, 22, "◯"],
  [2018, 4, 20, "◯"],
  [2018, 4, 21, "◯"],
  [2018, 4, 22, "☓"],
  [2019, 4, 20, "◯"],
  [2019, 4, 21, "◯"],
  [2019, 4, 22, "☓"],
].each do |(a,b,c,d)|
  my_hash[a][b][c] = d
end

puts my_hash
=> {2018=>{3=>{20=>"◯", 21=>"☓", 22=>"◯"}, 4=>{20=>"◯", 21=>"◯", 22=>"☓"}}, 2019=>{4=>{20=>"◯", 21=>"◯", 22=>"☓"}}}
```
私のディープラーニング作業環境【Win10】


# 概要

- keras環境がある日壊れたときは再構築が必要
 - 「packages\tensorflow\contrib\rnn\python\ops_gru_ops.dll not found」みたいなエラー
- pythonのIDEにEclipse（＋PyDevプラグイン）を使いたい

# 前提（筆者の環境）
- Windows 10 Professional
- Eclipse 4.6
 - PyDev 5.6
 - Javaランタイム　　　Java 8
- Anaconda3

# 手順

### condaの古い環境削除
壊れた環境の削除とか

```
conda remove -n （削除する環境名） --all
```

### condaで仮想環境作成
※以後、「py36」という名前の環境を作成すると想定

```
conda create -n py36 python=3.6 anaconda
```

<!--
※　必要最低限のパッケージで環境構築する場合
"""
conda create -n py36 python=3.6
"""
-->

### 必要なパッケージインストール
#### GPU版
　※　CUDA, cuDNNなどは事前にインストールのこと

```
activate py36
# keras/tensorflowの場合
pip install keras tensorflow-gpu
# pytorchの場合
pip install http://download.pytorch.org/whl/cu90/torch-0.4.0-cp36-cp36m-win_amd64.whl 
pip install torchvision
# chainerの場合
pip install cupy chainer
```

<!-- conda install -c peterjc123 pytorch  -->



####CPU版

```
activate py36
# keras/tensorflowの場合
pip install keras tensorflow
# pytorchの場合
conda install -c peterjc123 pytorch 
# chainerの場合
pip install chainer
```

### Eclipseに仮想環境読み込み

1. ファイルメニュー ＞　ウィンドウ　＞　設定
1. PyDev　＞　インタープリター ＞　Python インタープリター
1. 新規　＞　インタープリター実行可能ファイルに以下を指定

```
（Anacondaインストールフォルダ）\envs\py36\pythonw.exe
```

### プロジェクトにPythonインタープリターを指定
<span style="color : gray" style="font-size:xx-small">
（プロジェクトはだいたいGitHubからCloneしたものだったり）
</span>

プロジェクトを右クリック＞プロパティー＞PyDev-Interpreter/Grammer＞使いたい環境を指定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186338/1733398b-f106-fcb3-05ea-ffe7707a037a.png)


※プロパティーにPyDevの項目がないとき
　プロジェクトを右クリック＞PyDev＞Pydevプロジェクトとして設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/186338/af5580b7-a28c-9437-cca7-e8f8516b687c.png)
PHPの対話モードでサクッとDBとの疎通確認をする

Webサーバー上でDBと疎通してるのか確認したい時ありますよね。

でも、Webサーバーにmysqlクライアントが無い事も多いですよね。

そんな時でもPHPなら対話モードを使ってサクッと確認出来ちゃいます

* 対話モード開始

```bash
$ php -a
```

* コード

```php
$db = new PDO('mysql:dbname=test;host=xxx.xxxx.xxx.xxx', 'user', 'password');
$ret = $db->query('select * from users');
$row = $ret->fetch(PDO::FETCH_ASSOC);
print_r($row);
```

いざ、アプリケーションをリリースしたらDBの接続エラーで動かない！
なんてかっこ悪い事態は未然に防ぎましょう
ターミナルやvimからgoogle翻訳を使う

# はじめに
プログラムを書いたり成果物を公開したりしていると何かと英語を書かねばならないことが多いと思います．
私自身は英語がものすごく得意と言うわけではないので自分が書いた英語が不安なときはGoogle翻訳に渡して自分が思っているような日本語にちゃんと翻訳されるかどうかというチェックをしたりします．
普段文章を書くときはほとんどVimを使っているのですがちょっとした英語のチェックのためにマウス操作を強いられるのが結構なストレスです．そこでなにか良いツールが無いかと探していたら[translate-shell](https://github.com/soimort/translate-shell/)というツールを発見したので備忘録的に個人的に便利だと思う使い方をまとめたいと思います．

# 導入
Gnu Awkさえ入っていれば導入はかんたんです．
`git clone`して`make install`するだけです．

```shell-session
$ git clone https://github.com/soimort/translate-shell
$ cd translate-shell/
$ make
$ [sudo] make install
```

# ターミナルから使う
基本的な使い方は`trans -sl=翻訳元の言語 -tl=翻訳先の言語 "翻訳したいテキスト"`のような感じです．なお対話環境で翻訳したりなど結構リッチな機能も色々備えているようですが今回は簡単にチェックするのが目的なので扱いません．

```shell-session
$ trans -sl=en -tl=ja "Peace begins with a smile."                          
Peace begins with a smile.

平和は笑顔で始まります。
(Heiwa wa egao de hajimarimasu.)

Translations of Peace begins with a smile.
[ English -> 日本語 ]

Peace begins with a smile.
    平和は笑顔で始まります
```

長い出力が鬱陶しいときは`-brief`または`-b`をオプションに追加します．

```shell-session
$ trans -b -sl=en -tl=ja "Peace begins with a smile."
平和は笑顔で始まります。
```

ファイルを翻訳したいときは`-i ファイル名`でファイルを指定します．

```shell-session
$ trans -b -sl=en -tl=ja -i teresa.txt 
平和は笑顔で始まります。
```

なおファイルに結果を出力したければ同様に`-o ファイル名`で出力先を指定できます．また`-v`または`-view`を指定すると`less`などのページャで結果を見ることもできます．

# Vimから使う
別にこのツールに限った使い方ではないのでvimmerな方ならここまで読めばここから先は必要ないと思いますが備忘録として書いておきます．

## 編集中のファイル全体を翻訳
`:w !コマンド`でバッファの中身を任意のコマンドに流し込めます．なので今回の場合だと以下のようになります．

```vim
:w !trans -b -sl=en -tl=ja
```

これで翻訳結果が表示されエンターキーで編集に戻ります．

## 選択範囲を翻訳
Visualモードで範囲選択後`:`を押して任意のコマンドを入力すれば選択行に対して処理を実行できます．具体的には以下のような手順です．

```vim
v
...範囲を選択...
:
w !trans -b -sl=en -tl=ja
```

最終的なコマンドラインは以下のようになっているはずです．

```vim
:'<,'>w !trans -b -sl=en -tl=ja
```

いちいち打つのが面倒なので`trans -b -sl=en -tl=ja`をシェルで適当なエイリアスを設定しておくかVimのキーバインドに設定しておくと良さそうです．
UbuntuにPHP7の環境をつくる

お仕事でLaravelを使いそうなので、しれっとPHPの環境を整備したときの作業メモ。

## リポジトリ追加

```
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt update
```

## php7.2とお友達をインストール

```
sudo apt install php7.2 php7.2-common php7.2-cli php7.2-fpm php7.2-mysql php7.2-dev php7.2-mbstring php7.2-zip
```

## xdebugをインストールして設定
```
$ sudo apt-get install php-xdebug
$ sudo vim /etc/php/7.2/cli/php.ini

php.iniの最後に↓を追記
zend_extension = "/usr/lib/php/20151012/xdebug.so"
xdebug.remote_enable=on

ちょっと確認。

$ php -v
Cannot load Xdebug - it was already loaded
PHP 7.2.3-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Mar  6 2018 11:18:25) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.3-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethans
```

```
Cannot load Xdebug - it was already loaded
```
ん？　なんかいた。

```
/etc/php/7.2/mods-available/xdebug.ini
```
でもxdebug.so呼んでた。
なのでコメントアウト。



## composerインストール

```
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
$ sudo chmod +x /usr/local/bin/composer

これも確認。

$ composer -v
PHP:  syntax error, unexpected $end, expecting TC_DOLLAR_CURLY or TC_QUOTED_STRING or '"' in /etc/php/7.2/cli/php.ini on line 1917
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.6.3 2018-01-31 16:28:17

おｋ。
```
「組み込みLinuxでのGolangのススメ」を講演しました

2018年3月2日に中野サンプラザで開催された[テクニカルジャンボリー](https://elinux.org/Japan_Technical_Jamboree_64)で[「組み込みLinuxでのGolangのススメ」](https://qiita.com/tetsu_koba/items/7435ef8d0c77844d751e
)を講演しました。

スライドと動画のリンクを貼っておきます。


<iframe src="//www.slideshare.net/slideshow/embed_code/key/AiY5UwfwfhpxxK" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/tetsu.koba/linuxgolang" title="組み込みLinuxでのGolangのススメ" target="_blank">組み込みLinuxでのGolangのススメ</a> </strong> from <strong><a href="https://www.slideshare.net/tetsu.koba" target="_blank">Tetsuyuki Kobayashi</a></strong> </div>


<iframe width="560" height="315" src="https://www.youtube.com/embed/Zp_IXThjghc" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
https://www.youtube.com/watch?v=Zp_IXThjghc&feature=youtu.be


質問タイムに聴衆の方から紹介してもらった「Goならわかるシステムプログラミング」のWebの連載は[こちら](http://ascii.jp/elem/000/001/235/1235262/)
[書籍](http://amzn.to/2FzQlNF)

また、同じ著者によるこの本もGolangによる説明が多くておすすめです。
[Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術](http://amzn.to/2FteC4s)
iOS SwipeBackでButtonのtouchを阻害しない方法

```ViewController.swift
if let interactivePopGestureRecognizer = self.navigationController?.interactivePopGestureRecognizer {
    interactivePopGestureRecognizer.cancelsTouchesInView = false
    interactivePopGestureRecognizer.delaysTouchesEnded = false
    interactivePopGestureRecognizer.delaysTouchesEnded = false
}
```

対策不能と勘違いしてましたが、普通にUIGestureRecognizer取れるんですね
Xamarin.Formsでメディア再生する

Xamarinで動画再生やオーディオ再生をしたい場合、こちらのプラグインが良さそう。
[MediaManager](https://blog.xamarin.com/play-audio-and-video-with-the-mediamanager-plugin-for-xamarin/)

ただ使い方がわかりづらくはまってしまったので、備忘録を残しておきます。
#まずはプラグインを追加
NuGetで"Plugin.MediaPlayer.Forms"を追加します。
この時、PCLだけではなく、Android,iOSもお忘れなく。
<img width="821" alt="image1.png" src="https://qiita-image-store.s3.amazonaws.com/0/129520/527d60eb-b314-2306-333e-e0811d6c4c62.png">


#動画再生画面を作成
##Xaml
まずは動画を表示する画面を作成しましょう。
XamlのContentPageに下記を追加します。

```xml:XXXPage.xaml
xmlns:forms="clr-namespace:Plugin.MediaManager.Forms;assembly=Plugin.MediaManager.Forms"
```

動画の部分はこんな感じ。背景は黒にしておきました。

```xml:XXXPage.xaml
        <forms:VideoView x:Name="videoView"
                        AspectMode="AspectFit"
                        BackgroundColor="Black"
                        />
```


##コードビハインド

```c#:XXXPage.xaml.cs
using Plugin.MediaManager;
using Plugin.MediaManager.Abstractions;
.
.
    public partial class MovieAppPage : ContentPage
    {
        private IPlaybackController PlaybackController => CrossMediaManager.Current.PlaybackController;

	protected override void OnAppearing()
	{
        base.OnAppearing();

        videoView.Source = "https://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4";
        PlaybackController.Play();
	}
```

#ネイティブの設定（これを忘れると大変）
##Android
イニシャライズに

```c#:MainActivity.cs
using Plugin.MediaManager.Forms.Android;
.
.

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
            .
            .
            base.OnCreate(bundle);

            VideoViewRenderer.Init(); // << 追加

            global::Xamarin.Forms.Forms.Init(this, bundle);
            .
            .
            .
}
```

##iOS
```c#:AppDelegate.cs
using Plugin.MediaManager.Forms.iOS;
.
.
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();

            LoadApplication(new App());

            VideoViewRenderer.Init(); // << 追加

            return base.FinishedLaunching(app, options);
        }

```

これだけで、動画は再生されます。
動画のコントロールはまた後日。
Windows10タブレットでwebviewベースのアプリ&IEで表示する画面を作ったときにハマったこと

# はじめに
モバイル,タブレット端末といえば通常はiOS,Androidが用いられますが,やんごとなき事情でWindowsタブレット向けのアプリケーションを開発することになりました.  

開発メンバーのスキル等を考慮し,C#による実装ではなくWebBrowser Control & IE+Twitter Bootstrapで画面を作ることにしましたが,思わぬところで落とし穴が多数存在したため,これを共有します.

# 目次
- [WebBrowser Controlに起因する落とし穴](#WebBrowser Controlに起因する落とし穴)
- [IEに起因する落とし穴](#IEに起因する落とし穴)
- [終わりに](#終わりに)

# WebBrowser Controlに起因する落とし穴
## 全体的に動作が遅い
IEではサクサク表示されるにも関わらず,WebBrowserでは画面表示,スクロールといったアニメーションといったあらゆる動きが明らかに遅いという事象が発生しました.

### 解決策
https://social.msdn.microsoft.com/Forums/security/ja-JP/1006a1ab-b5a1-4341-87fc-56d996a062cc/c-webbrowsergpu?forum=netfxgeneralja

上記にあるように,レジストリの値を変えることでWebBrowserの動作が明らかに速くなりました.  
iOS,AndroidではwebViewにセキュリティ脆弱性があったり足りない機能がありこそすれ,ここまで遅くなるということはなかなか想定ができないと思います.iPadは偉大ですね.(?)

## HTMLコンポーネントの動きがIEと異なる
`option`のスクロール部分がタッチに反応せず,スクロールする際はかなり細いサイドバーでしか反応しないという事象でした.  
非常に操作がしづらいため,なんとか修正する必要がありました.

### 解決策
http://kkamegawa.hatenablog.jp/entry/2014/06/24/054729

WebBrowser Controlをタッチ対応にするためには,上記のレジストリ変更が必要でした.これにより,上記の問題は解消しました.

## Twitter Bootstrapのモーダルでズームが使いずらい
WebBrowser ControlでBootstrapのモーダルを表示すると,ズームしようとした箇所ではなく見当違いのところがズームされてしまうという事象でした.  
これについては解決をあきらめ,ズームをしない運用をお願いしました.

# IEに起因する落とし穴
## IEとWebBrowser Controlで論理ピクセル数が異なる
タブレット自体の論理ピクセルは`1920*1080`,WebBrowser Controlも同じ,にも関わらずIEでは`1280*720`となる事象でした.  
調べてみると,なんと**IEの拡大設定がデフォルトで150％に設定されている**ことが原因でした.  
これはタブレットの機種にも依る可能性がありますが,Windowsタブレットで表示する画面を作る際には要注意です.

そして厄介なことに, **BootstrapはIEのズーム機能をサポートしていません.**   
のちにズームが有効の場合にモーダルを表示し,これを操作すると画面に黒い線が現れるというバグを踏んだのですが,これについてはMS側もBootstrap側も一切対応する気がないという悲しい事象が起きました.  
ちなみにこれはedgeでも発生します.

https://github.com/twbs/bootstrap/issues/15677  

すでにこの150％ズームを前提にCSSを書いてしまっていた画面が本番投入されていたため,ズーム率を変えることもできません。。。  
泣く泣く,モーダル部分を別画面として作り直しました.


### 解決策
**IEではモーダルを使わない**(?)

# 終わりに
.NETでWebベースのアプリを作ると,このように様々なトラブルに遭遇します.  
こうしたトラブルを回避する,または対処するには

- マイクロソフトのプレミアムサポートを使う
- WebBrowser ControlではなくCefSharpを使う(https://github.com/cefsharp/CefSharp)  
- webベースではなく,C#で作りこむ

といった方策が有用であると感じました.
RaspberryPi 2/3をavahi-browseで検索できるようにする

RaspberryPi 2のRaspbian Stretch を使用しています。

avahi-daemonは最初から入っていたのですが、デフォルトでは設定が足りないようです。
NanoPi Neoと見比べて、以下のファイルをコピーしたらうまくいくようになりました。

```/etc/avahi/services/ssh.service
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">

<!--
  This file is part of avahi.
 
  avahi is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 2 of the
  License, or (at your option) any later version.

  avahi is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with avahi; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA.
-->

<!-- See avahi.service(5) for more information about this configuration file -->

<service-group>

  <name replace-wildcards="yes">%h</name>

  <service>
    <type>_ssh._tcp</type>
    <port>22</port>
  </service>

</service-group>
```

これでRaspberryPi2を再起動。
PCのLinuxからavahi-browseコマンドで見つかるようになりました。

```
$ avahi-browse -a -t |grep rasp
+   eth1 IPv6 raspberrypi                                   SSH Remote Terminal  local
+   eth1 IPv4 raspberrypi                                   SSH Remote Terminal  local
```
これで以下のようにしてsshでログインできます。

```
$ ssh pi@raspberrypi.local
```
IDCFクラウドで月300円のサーバ(仮想マシン)を作成する方法

# 条件
- IDCFクラウド環境
- OS : CentOS 6.9
- 月額 : 500円ではなく300円にする(light.S1)
- Diskを15GB(デフォルト)ではなく5GBにする

# サーバ(仮想マシン)作成
1. 仮想マシン作成
2. light.S1選択
![ダウンロード1.png](https://qiita-image-store.s3.amazonaws.com/0/231495/9e18412e-9bc5-a703-a4c4-d99547a6f0e6.png)

3. イメージ欄のISOタブを選択し、CentOS-6.9-x86_64-minimal.isoを選択
![ダウンロード2.png](https://qiita-image-store.s3.amazonaws.com/0/231495/6a98eb7b-16a8-f766-8e3c-e817eb817cbd.png)

4. ボリュームは5GBを設定
![ダウンロード3.png](https://qiita-image-store.s3.amazonaws.com/0/231495/f5dd80c1-302a-4974-dd2f-1087e6fe479c.png)

5. 300円であることを確認して作成
![ダウンロード4.png](https://qiita-image-store.s3.amazonaws.com/0/231495/d3a2c8b7-2479-6f4b-3639-32ce5a71fca5.png)

6. コンソールに接続しインストールする
[ISOインストール機能を活用してサーバーを構築する](https://www.idcf.jp/help/cloud/guide/advanced015.html)
⑦以降参照

# テンプレート化とテンプレートの公開
- 次回以降も利用できるようにする方法

### テンプレート化
- [IDCFクラウド>テンプレートの作成方法を教えてください。](https://www.faq.idcf.jp/app/answers/detail/a_id/142/c/22)
- 別リージョンでテンプレートを利用する場合は、テンプレートのエクスポート→インポートが必要

### 公開方法
- 一般向けにテンプレートを公開する方法
    - [コミュニティテンプレートへの公開方法](https://www.idcf.jp/help/cloud/guide/community_temp.html)

# 補足
- 5GBで300円/月だけでなく、3GBで260円/月も可能です。
- 他OSでは1GB 220円/月も可能です。
- この手順でルートディスクが15GB以外のLinuxサーバを作成できます。
iOS Provisioning Profileの生成時に、期限日(Expires)が1年未満の中途半端に短くなる原因と対策

# はじめに

考えるとある意味当たり前なんですが、
iOSアプリ開発時に利用するプロビジョニングプロファイルの「期限日」について、
嵌まってしまったことがあったので、そのメモです。

# 発端

プロビジョニングプロファイルを生成した際に、
通常は、期限日(Expires date)は生成日から1年後になるはずですが、
なぜか中途半端に短い日付になっていました。

何度再生成しても頑なに固定の日付となり、なんでだろうと首をかしげました。

<img width="734" alt="pp.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/9270279a-7379-6576-cb79-c78359572941.png">
[2018年3月5日ごろに生成したプロビジョニングプロファイルの期限日]


# 原因

結論として、
プロビジョニングプロファイルの期限日は、
Production Certificate の期限日が最大の日付となるようでした。

プロビジョニングプロファイル生成時に選択していた Production Certificateの期限日が
　 **2018年8月4日** で、
それゆえに、プロビジョニングプロファイルを何度再生成しても期限日が
　 **2018年8月5日** 
となっていたという状態でした。


* <img width="732" alt="pp_genrate-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/55620/ac19996d-d89f-06a5-59da-82cb8cbfe26a.png">

[プロビジョニングプロファイル生成時の、Certificateの選択]




# 対応

Production Certificate を再生成して、
新しい日付の Certificate を利用してプロビジョニングプロファイルを生成します。

```
# 例
[Certificates] → [Production] → [+] → [✅ In-House and Ad Hoc]
```

その後に、再生成したCSRを選択して、プロビジョニングプロファイルを再生成すれば、
無事期限日は1年後の日付になりました。
softmax関数を直感的に理解したい

# はじめに
最近ディープラーニングが盛り上がっていますね。その中でもディープラーニングをはじめとする機械学習に出てくるような本を読んでいるとよく出てくるsoftmax関数

```math
y_i = \frac{e^{x_i}}{\sum_{j=1}^N e^{x_j}}
```

があります。最近本を読んでいたらこいつが登場し、そろそろちゃんと理解しようと思ったのでその考察をシェアします。

# 本題
結論からいうと、softmax関数を3Dグラフにプロットするとこうなります。
（実際、この結果が見たくてググったがなかなかヒットせず）

![3d.png](https://qiita-image-store.s3.amazonaws.com/0/202772/08cb9354-713e-17e8-d64e-915dbc6b41f5.png)

これは$x_1, x_2$の値がともに$[-5, 5]$である状況で$i=2$に関するsoftmax関数

```math
y_2 = \frac{e^{x_2}}{e^{x_1} + e^{x_2}}
```
の挙動をプロットしたものになります。このグラフを観察するとわかることが2点あります。これから個別に見ていきます。

## 値域（関数の取りうる値）が0から1の間である

![zero2one.png](https://qiita-image-store.s3.amazonaws.com/0/202772/180636ea-eee3-1c11-fd8a-872eb1fd836e.png)

これがよくsoftmax関数の利点として挙げられていることです。もちろん数学的に示すことも可能です。この点ではsigmoid関数と親戚関係であることが言えます。
（実際、sigmoid関数の多クラスへの拡張という表現がされています。）
この特徴のおかげで真偽の判断を確率的なあいまい性を残した状態で扱いたいときに大変有効になります。

## maxのような挙動をしている
![likemax.png](https://qiita-image-store.s3.amazonaws.com/0/202772/2c952f61-3854-ba9e-ee78-5886926ffcd6.png)

これも重要な性質ですが、$x_1$に比べて**相対的に**$x_2$の値が大きいときに大きな値をとるようになっています。
$x_1=-5$のとき、すなわち他の値が$x_2$に対して小さいときは、$y_2$は大きな値を**取りやすく**なっています。反対に、$x_1=+5$のとき、すなわち、他の値が$x_2$に対して大きいときは、$y_2$は大きな値が**取りにくく**なっています。
言い換えれば、「自身$x_j$が他の要素$x_{k(\ne j)}$よりも目立っている確率」のような感覚でとらえることができます。

この現象を比較しやすいよう、それぞれの$x_1$の値ごとにプロットしてみます。

![each.png](https://qiita-image-store.s3.amazonaws.com/0/202772/113370a0-b4ca-76bf-80ec-afe088b34308.png)

ちなみに蛇足ですが、$x_1 = 0$のときは

```math
y_2 = \frac{e^{x_2}}{1 + e^{x_2}}
```
より、

```math
y_2 = \frac{1}{1 + e^{-x_2}}
```
となり、sigmoid関数が得られます。

この理解を直感的に多次元に拡張するならば、「softmax関数は多くの次元からなる入力のうち、自分の値が他の値たちに比べて一番目立っているならば、その値が$1$に近づく関数である」といえます。

#終わりに
いかがでしたか。
ポイントとしては、この関数が他の入力値に相対的に反応するというところでしょうか。
この記事が少しでもsoftmax関数の直感的な理解につながれば幸いです。

※余裕があれば多次元の場合での可視化についてもやってみます。


[ipython notebook - my Gist](https://gist.github.com/konabe/d4157faf64408851ed4812b968d4404e)