OmniAICreator/Qiita-1.07M huggingface dataset:
Zabbix:監視対象サービス停止時に自動復旧させる

# やりたいこと

例えば、httpdサービスが停止した(httpdプロセス数が0個になった)場合、Zabbixでアラーム(トリガ)として検知します。
ここまでは普通ですが、
その後、そのトリガをアクションの条件として、障害発生サーバのhttpdサービスを復旧したら楽ですよね。

# やりたいことの考え

ワークアラウンドとしてまず浮かぶのは、(１回目のアラーム時)停止サービスを再度起動してみることですよね。
だったら、人間様じゃなくてZabbix君にやらせてしまいましょう。
それも再度落ちるようなら(２回連続アラームなったら)、人間様にご登場いただくと云う寸法で。

# 今回の実現環境
* ZabbixServer側：zabbix3.0
* ZabbixAgent(httpdサービス起動)側：zabbix-agent導入済みのCentOS7

# ざっくりした実現方法

1. zabbix-agent経由で、httpdサービス停止を検知
2. zabbix-serverでトリガ発報
3. トリガでアクションが発動
4. アクションで、Zabbix-agent側でshellコマンドを発行
5. shellコマンドで"systemctl start httpd.service"をsudoで実行
6. httpdサービス復旧

# 実現方法
## ZabbixSever側
### ITEM設定
名前を「httpd.service process」と設定。最初の１ワード目が、"systemctl で使用する"httpd.service"と同じ文字列であることがミソ(アクションのコマンドで使用します)。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/e1852454-e9f7-b889-eb77-a85c5da46f37.png)

### TRIGGER設定
名前を「httpdサービス停止(自動再起動処理有)」とし、日本語部分を固定フォーマットにすることがミソ(アクション設定時にこの文字列をキーワードにする)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/ee99ba4e-2c4a-7030-0c65-938d8c334c33.png)

### ACTION設定
アクション設定です。アクションの名前は何でも良いです。
アクションの条件に、３行目（トリガー名 含まれる 「サービス停止(自動再起動処理有)」）を加える。
トリガで使用した文字列「サービス停止(自動再起動処理有)」が存在すればアクションを起こすようにする。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/4eb64e7a-244d-57e8-a490-89c87fb09a18.png)

実行内容は、Zabbixエージェントで、下記のようなコマンドを実行するよう指示する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/627bd112-7b4f-75e6-f2a9-7483bccd4f97.png)
]

## ZabbixAgent側
実現方法として、Zabbix-agentをrootユーザで稼働する方法と、sudoを使用する方法がある。
今回は、既存システムに影響が少ないsudoを使用する方法を採用する。

### /etc/sudoers設定

visudoコマンドで、/etc/sudoersの最終行に追加。

```ruby:/etc/sudoers
zabbix ALL=(ALL)NOPASSWD: /usr/bin/systemctl start httpd.service, /usr/bin/systemctl start chronyd.service
```

# 実行結果
イベントログを見ていると、サービス停止後、ひとつのアクションが実行され復旧していることがわかる。
アクション内容も、設定したマクロ{ITEM.NAME}が思ったとおりに展開されていることが確認できた。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/82244/bc40a30f-637b-b684-cd9c-f0a5c9b756c6.png)

# 最後に

見ていただければわかるように、アイテム「httpd.service process」(マクロの{ITEM.NAME})のhttpd部分を別のサービス名(e.g. chronyd等々)に変更すれば汎用的に利用可能です。
また、実際の現場では、サービスは起動はOKだが、「Webシナリオ」でエラーとなる場合に、httpd/mysqldサービスの再起動を実行する等すれば、少しは使い物になると思います。

今回は例としてsystemctlコマンドでした。
が、ansibleと連携することで、Webシナリオ等のサービス障害検知時に、設定状況の差異修復を行えば良いと思う。

# 最後の最後に
もし本番でこのような仕組みを使うのであれば、メンテナンス時にZabbix機能の「メンテナンス」を使用することをおすすめします(アクションの条件にもデフォルトで入っています)。
もし使用しなければ、メンテナンス中にZabbixが勝手にサービス再開してしまいますから…（怖い怖いw)
jQueryでテーブルの行を操作する（移動・削除・追加）

jQueryを使ってテーブルの行を上下に移動したり、追加や削除を行う方法の覚書きです。サンプルのHTML部分は末尾に掲載します。

###選択した行をひとつ上へ移動

clickイベントが発生した要素からclosest()で遡ってtrオブジェクトを取得し、そのtrオブジェクト自身を、ひとつ上の要素に対してinsertBefore()で追加します。

```JS:JavaScript
$('.rowup').click(function() {
 let $row = $(this).closest("tr");
 let $row_prev = $row.prev("tr");
 if($row.prev.length) {
	 $row.insertBefore($row_prev);
 }
});
```

###選択した行をひとつ下へ移動
clickイベントが発生した要素からclosest()で遡ってtrオブジェクトを取得し、そのtrオブジェクト自身を、ひとつ下の要素に対してinsertAfter()で追加します。

```JS:JavaScript
$('.rowdown').click(function() {
 let $row = $(this).closest("tr");
 let $row_next = $row.next("tr");
 if($row_next.length) {
	 $row.insertAfter($row_next);
 }
});
```

###選択した行を削除
clickイベントが発生した要素からclosest()で遡ってtrオブジェクトを取得し、そのtrオブジェクトをremove()で削除します。

```JS:JavaScript
$('.rowdel').click(function() {
 let row = $(this).closest("tr").remove();
 $(row).remove();
});
```

###選択した行をコピーしてひとつ下に追加
clickイベントが発生した要素からclosest()で遡ってtrオブジェクトを取得し、そのtrオブジェクトをclone()で複製した上で、自身のひとつ下にinsertAfter()で追加します。もちろんclone()せずに新しいtrオブジェクトを作って追加してもいいです。その場合はイベントがセットされていないので、大元のイベントをtableにセットしてdelegateするか、別途個別にイベントセットする必要があります。

```JS:JavaScript
$('.rowins').click(function() {
 let $row = $(this).closest("tr");
 let $newRow = $row.clone(true);
 $newRow.insertAfter($row);
});
```

###ターゲットのテーブルの例

ボタンにclass属性を付けてclickイベントを割り当てています。

![ブラウザでの表示例](https://qiita-image-store.s3.amazonaws.com/0/46062/d7f3b6e6-2792-43e9-7b42-272d219a70ff.png)

```HTML:HTML
<table border="1px">
	<thead>
		<tr>
			<th>ID</th>
			<th>名前</th>
			<th>性別</th>
			<th>上へ</th>
			<th>下へ</th>
			<th>削除</th>
			<th>追加</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>001</td>
			<td>山田太郎</td>
			<td>男</td>
			<td><button class="rowup">↑</button></td>
			<td><button class="rowdown">↓</button></td>
			<td><button class="rowdel">Del</button></td>
			<td><button class="rowins">＋</button></td>
		</tr>
		<tr>
			<td>002</td>
			<td>鈴木二郎</td>
			<td>男</td>
			<td><button class="rowup">↑</button></td>
			<td><button class="rowdown">↓</button></td>
			<td><button class="rowdel">Del</button></td>
			<td><button class="rowins">＋</button></td>
		</tr>
		<tr>
			<td>003</td>
			<td>高橋陽子</td>
			<td>女</td>
			<td><button class="rowup">↑</button></td>
			<td><button class="rowdown">↓</button></td>
			<td><button class="rowdel">Del</button></td>
			<td><button class="rowins">＋</button></td>
		</tr>
		<tr>
			<td>004</td>
			<td>山本三郎</td>
			<td>男</td>
			<td><button class="rowup">↑</button></td>
			<td><button class="rowdown">↓</button></td>
			<td><button class="rowdel">Del</button></td>
			<td><button class="rowins">＋</button></td>
		</tr>
	</tbody>
</table>
```
bootstrap-selectでJavaScriptから任意の項目を選択済みにする方法 

bootstrapの[bootstrap-selectプラグイン](https://github.com/silviomoreto/bootstrap-select)を使ってドロップダウンリストを作った場合、通常のHTMLの<option>タグのようにselected属性をセットしても選択済みにはなりません。

任意の項目を選択済みにしたい場合は、<select>のvalue属性に選択済みにしたい項目のvalue属性の値をセットした上で、selectpicker('refresh')を呼び出してリフレッシュします。

次のようにすると「BLUE」が選択済みの状態になります。selectpicker('refresh')をしないと表示に反映されない場合があります。

```html:HTML
<select name="color" class="selectpicker">
   <option value="red">RED</option>
   <option value="green">GREEN</option>
   <option value="blue">BLUE</option>
   <option value="yellow">YELLOW</option>
</select>
```
```js:JavaScript
$('select[name=color]').val("blue");
$('.selectpicker').selectpicker('refresh');
```

複数選択ができるドロップダウンリストの場合は、次のようにvalueに配列をセットします。

```html:HTML
<select name="color" class="selectpicker" multiple>
   <option value="red">RED</option>
   <option value="green">GREEN</option>
   <option value="blue">BLUE</option>
   <option value="yellow">YELLOW</option>
</select>
```
```js:JavaScript
$('select[name=color-multi]').val(["yellow","green","red"]);
$('.selectpicker').selectpicker('refresh');
```

ちなみに、展開後のDOMの状態をChromeのインスペクタで見てみたら次のような感じになっていました。
選択済みのフラグは、optionの属性としてではなく、data-original-indexというカスタムデータ属性を持ったliタグにclass属性の値としてセットされるようです。

```html:
<div class="btn-group bootstrap-select">
	<button type="button" class="btn dropdown-toggle btn-default" data-toggle="dropdown" role="button" title="BLUE">
		<span class="filter-option pull-left">BLUE</span>&nbsp;
		<span class="bs-caret"><span class="caret">
		</span></span>
	</button>
	<div class="dropdown-menu open" role="combobox">
		<ul class="dropdown-menu inner" role="listbox" aria-expanded="false">
			<li data-original-index="0"><a tabindex="0" class="" data-tokens="null" role="option" aria-disabled="false" aria-selected="false"><span class="text">RED</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
			<li data-original-index="1"><a tabindex="0" class="" data-tokens="null" role="option" aria-disabled="false" aria-selected="false"><span class="text">GREEN</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
			<li data-original-index="2" class="selected"><a tabindex="0" class="" data-tokens="null" role="option" aria-disabled="false" aria-selected="true"><span class="text">BLUE</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
			<li data-original-index="3"><a tabindex="0" class="" data-tokens="null" role="option" aria-disabled="false" aria-selected="false"><span class="text">YELLOW</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
		</ul>
	</div>
	<select name="color" class="selectpicker" data_liveedit_tagid="0x00007fbeb701cc70" tabindex="-98">
   		<option value="red" data_liveedit_tagid="0x00007fbeb701ced0">RED</option>
   		<option value="green" data_liveedit_tagid="0x00007fbeb701d260">GREEN</option>
   		<option value="blue" data_liveedit_tagid="0x00007fbeb701d5f0">BLUE</option>
   		<option value="yellow" data_liveedit_tagid="0x00007fbeb701d980">YELLOW</option>
	</select>
</div>
```
awkで小数を出力する場合に指数表現になってしまうのを解除する

awkでprint文を使って桁数の多い小数を出力すると、デフォルトでは次のように指数表現になってしまいます。

```awk:
$ echo 1234567.89 | awk '{ print $1*10 }'
1.23457e+07
```

一度変数に代入してから出力する場合でも同様です。

```awk:
$ echo 1234567.89 | awk '{ res=$1*10; print res }'
1.23457e+07
```

awkのprint文は、数値を出力する際の文字列への変換にsprintf関数を利用します。その際にどの形式を使って出力するのかはOFMTという組込変数で定義されていて、これがデフォルトでは"%.6g"となっています。すなわち、小数点以下第6位以上は指数表現の文字列にするということです。

したがって、以下のようにOFMTを"%0.6f"などに変更すれば不動小数点表現になります。OFMTに設定できる値は、sprintfに使う書式制御文字と同様です。

```awk:
$ echo 1234567.89 | awk '{ OFMT="%.6f" } { res=$1*10; print res }'
12345678.900000
```

```awk:
$ echo 1234567.89 | awk '{ res=$1*10; OFMT="%.6f"; print res }'
12345678.900000
```

ただし、$1のようなフィールド変数に直接値を代入した場合には、この変更が適用されないので注意が必要です。

```awk:
$ echo 1234567.89 | awk '{ OFMT="%.6f" } { res=$1*10; $1=res; print }'
1.23457e+07
```
Mac → Win10 RDP キーマップの修正を簡単に

#Mac→Win10リモート接続 キー配列が…
MacからWin10へのリモートデスクトップ接続で、＆（アンド）とか＊（アスタリスク）とかの場所がおかしくなってて、苦労している方も多いかと。キーマップを変えるアプリを使うなどとか色々ありますが、正直面倒です。

「英数」「かな」キーによる「IMEのオン／オフ」利用も出来ます。少ない手数で管理したいと思っている方のための決定版です。

#■ 原因
リモート接続クライアント(Mac)のキー配列が【なぜか】反映されない

#■ 選択可能な対応策（さわりだけ）
######<今回>Win10側変更（レジストリ変更、セキュリティレベル維持）
 → リモート接続時に「JIS配列キーボードを強制指定」します。
#####<参考>その他のやり方（今回説明しません）
######(A)Win10側変更（セキュリティレベルを下げる設定）
 → Win7まで使えた[Microsoft Remote Desktop Connection Client for Mac 2.1.1](https://www.microsoft.com/ja-jp/download/details.aspx?id=18140)を使えるように、Win10のセキュリティレベルをWin7レベルに下げるもの。
######(B)Mac側変更(キーマップ変更）
Karabinarというツールを使用。ただしMacOS Sierraではこのツールが使えなくなっているようです？
######(C)VNCを使う(Win10側にVNCサーバをインスト）
これも一案。RemoteDesktopのレスポンスが大きく向上した現在では、OSX用のVNCクライアントのレスポンスに物足りなさを覚えます。

#■ JIS配列キーボードを強制する
レジストリ触ります (^^;) ＊お約束の自己責任ということで
###<手順１>デフォルトのキーボードマッピングを変更
US配列時のドライバ指定 kbd101.dllをkbd106.dllに変更する

```
<場所>
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\KeyboardType Mapping\JPN\

<変更内容>
キー値"00000000" (旧)kbd101.dll　→ （新）kbd106.dll
```
#######＜考察＞
Win10側コントロールパネルで「ハードウエアキーボードレイアウト」を「日本語キーボード（106／１０９キー）」に変更できるはずですが、うまく反映されません。この為、上記のような乱暴なやり方をしています。
###<手順２>Mac側のリモート接続Appを公式β版に変更
上記＜手順１＞だけではうまく行きません。おまじないとして、クライアントappを変更する必要があります。
[Microsoft Remote Desktop for Mac (Beta)](https://rink.hockeyapp.net/apps/5e0c144289a51fca2d3bfa39ce7f2b06/)
　↑ 一見怪しげなページに飛びますが、MS公式。
<dl>
 <dt>【参考】HockeyApp - Microsoft Azure</dt>
 <dd>公式解説ページです→https://azure.microsoft.com/ja-jp/services/hockeyapp/</dd>
</dl>
#■ 最後に
　この「キー配列がずれる」件、古いクライアントApp(Microsoft Remote Desktop Connection Client for Mac 2.1.1)では、全く発生していませんでした。

　実際、MacOS SierraでもこのApp普通に動きます。この問題の原因は、Windows側のセキュリティポリシー変更により、Win8.1以降で上記Appのプロトコルでは接続できなくなったようです。なので、Windows側のセキュリティを下げればアクセスできます。

 実は、Microsoft Remote Desktop for Mac (Beta)でもちょっと前のバージョンでは、この問題解決していました。なのでわざわざこちらをインストールし直している人も多かったかと思います。なぜ、この点が改悪されたかわかりませんが相変わらずこの問題放置されたままです。
新卒エンジニアでもできる！コメントアウトで同期に差をつける裏技

#6月がやってきた
新卒の皆さんは、入社して2カ月が経ちました。
そろそろ会社に慣れてきた頃でしょうか。
会社によっては、研修期間が終了して、現場でバリバリ開発をしている人もいるかと思います。

##JavaScriptでコメントアウト

基本的な文法は以下の通りです。

```javascript
//1行コメント
```

```javascript
/*
複数行コメント
複数行コメント
*/
```


##本には載ってないコメントアウトの裏技

それでは、裏技についての説明です。

これは、私が1年目の駆け出しだった頃、SONY系のゲーム会社から転職してきた「T先輩」に教わった裏技です。

当時の私は、仕事のやり方を覚えている最中で、「先輩から学べることは何でも学んでやろう！」と意気込んでいた頃でした。

さっそく、裏技のやり方を説明したいのですが、「基本編」と「応用編」で2つの技があります。

まずは、「基本編」から解説させていただきます。

##基本編

以下のコードは、複数行コメントである「/* */」を使って、3行の処理をまとめてコメントアウトしています。

```javascript
/*/
console.log("aaa");
console.log("bbb");
console.log("ccc");
//*/
```

このコードの先頭に、「/」を追加するだけで、何とコメントが外れます！

```javascript
//*/
console.log("aaa");
console.log("bbb");
console.log("ccc");
//*/
```
はい！
Qiitaの見た目上も、コメントであるグレーから、ブラックやレッド文字色に変わっていると思います。

##応用編

続いて応用編です。こちらは、基本編ベースにして、さらに応用したコードになります。

応用編の使いどころですが、「開発環境」と「本番環境」で、**何かを切り替えたい時**に活用できます。

具体例をあげるとすれば、「APIのURL」や「DBの接続先」がありますね。

それではやり方ですが、基本編と同じです。

そうです。
先頭に「/」を付けるだけです。

今まで「Debug」が有効だったのが、

```javascript
/*  
console.log("Release");
/*/ 
console.log("Debug");
//*/
```

「/」を付けると「Release」が有効になります。

```javascript
//*  
console.log("Release");
/*/ 
console.log("Debug");
//*/
```

いや～ 便利ですね (^_^;

##JavaScript以外にも使えないの？
使えます。
「//」で1行コメント
「/* */」で複数行コメント
という言語なら他の言語でも大丈夫です。

ざっくり調べたのですが、
「C」「C++」「C#」「Java」「PHP」「Go」も同じだそうです。

paiza.ioでサクッと試せるので、確認してみるのも手です。
https://paiza.io/

ぜひ、この裏技を身に着けて、同期のライバル達に差を付けちゃいましょう！

##今後どの言語を勉強したらいいの？

最近、Web系のプログラミングスクールがいくつも登場しています。
そして、学習のしやすさから「Ruby」を勧めるケースが多いですね。

ところが、いざ就職しようとすると、Rubyを使っている会社はスタートアップ系の企業が多くて、就職先に意外と苦労する、という現実にぶち当たります。（Ruby好きだから心苦しい。。。）

SESの営業職の方は、肌感覚で分かっていることかもしれませんが、
世の中の案件を見てみると「Java」と「PHP」の案件で全体の50%を占めているそうです。

・2017年の人気プログラム言語１０選を徹底比較！気になる年収や求人、学習難易度まで
https://toiroha.jp/article/detail/32380

・フリーエンジニアナビ　言語（DB)から選ぶ
https://www.freeengineer-navi.tokyo/search/index/4

・フリーランスの仕事探し！プログラミング言語別の開発案件数を調べてみた。1位はやっぱり!?
http://notsleeeping.com/archives/2238

・言語から案件検索
https://careerups.jp/slan

今後の生存戦略として「Java」か「PHP」のどちらかは、マスターしておいた方が良いかもしれません。

そして、
**「Java」や「PHP」でも、今回の裏技は使えます！**

繰り返します。
**「Java」や「PHP」でも、今回の裏技は使えます！**
(大事なことなので、2回言いました。)

##まとめ

今回はコメントアウトを使ったお話でした。

そういえば、コメントアウトといえば、一昔前のブラウザだと
\<script\>タグが無効なケースを想定して、「<!---->」で囲んだり、「<![CDATA[]]>」で囲んだりした時期がありました (^_^;

世の中のブラウザの進化に合わせて、エンジニアのコードも進化し続けているのを感じます。

気が付けば、私がこの業界に入ってから10年以上経ちました。
あの時お世話になったT先輩は、お元気にしているでしょうか。

もしも願いが叶うなら、また一緒にお仕事をしたいです。
先輩。
MacにXcodeをインストールする

*超初心者向け

<h3>1. Macのバージョンを調べる</h3>
画面左上のAppleマーク > このMacについて > 概要
→ *OSX xxx
　バーションxxxxx*

<h3>2. 該当のXcodeをインストール</h3>
AppleのDeveloperサイトに移動
https://developer.apple.com/download/more/#

1で確認したバージョンをもとに、該当のXcodeを選択し、インストールする

<h3>3. Macの流れに身をまかせる</h3>
特に注意すべきことはなし！
インストール後に落ち着くまで動作が安定しないことがあるが、
Dockアイコン右クリック → 強制終了 → 再起動
でうまくいくことが多い。

困った時はとにかく再起動すること！
VisualStudioCodeに自動整形機能があった

Visual Studio CodeでTypeScriptを書いていて自動整形が欲しくなったので調べたら、
見つかったのでメモ

追記
2018/06/11　同じ設定項目があるのを確認
2019/03/09　いろいろ変わっていたので書き直した

1. 「ファイル」「基本設定」「設定」を開く
2. 上の検索窓からformatonで検索する
3. Format On XXXで必要なものをチェックする
![WS000938.JPG](https://qiita-image-store.s3.amazonaws.com/0/153576/2555aa35-2d93-4ba0-a928-765448a1420d.jpeg)
4. 右上の{}で設定内容を確認できる
5. コードを書く
6. 自動整形できた！
    1. コードの区切りを入力したとき(On Type)
    2. 保存したとき(On Save)
    3. 貼り付けを行ったとき(On Paste)
VirtualBox、Vagrantを使って、rbenvをinstallしたときにエラーに遭遇

#概要
VirtualBox、Vagrantを使って、rbenvをinstallしたときにエラーに遭遇したので、それの解決した時のメモ

#環境
- macOS Sierra 10.12.5
- Rails5
- Virtual Box
- Vagrant
- CentOS7

#エラー内容
仮想マシン上で必要なソフトウェアをインストールしていた時に、rbenvがインストールできなかった。

```
$ rbenv install 2.4.0
Downloading ruby-2.4.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.0.tar.bz2
error: failed to download ruby-2.4.0.tar.bz2

BUILD FAILED (CentOS Linux 7 using ruby-build 20170523-7-g2de7a29)
```

エラーログを確認してみるとcurlがどうやらおかしいらしい。

```
less /tmp/ruby-build.2017*******.****.log
curl: (35) Peer reports incompatible or unsupported protocol version.
```

#解決方法
[rbenvでrubyのインストールが出来ない:CentOS7](http://morototo.hatenablog.com/entry/2017/05/31/124436)を参考にして下記のコマンドを実行してみる。

```
$ RUBY_BUILD_CURL_OPTS=--tlsv1.2 rbenv install 2.4.0
Downloading ruby-2.4.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.0.tar.bz2
Installing ruby-2.4.0...
Installed ruby-2.4.0 to /home/vagrant/.rbenv/versions/2.4.0
```

よし、インストール完了！！！次に進みましょ！

#参考資料
[2017年版!30分で作るRuby on Rails 5開発環境 Mac編 Vagrant+CentOS7+rbenv](http://withdom.jukendou.jp/withdom-it-lab/it-skills/714)
[rbenvでrubyのインストールが出来ない:CentOS7](http://morototo.hatenablog.com/entry/2017/05/31/124436)


#キーワード
- Ruby On Rails5
- Virtual Box
- Vagrant
- CentOS7
- rbenv
TypeScriptを使うために型定義を準備する

electronを使ってみようと思っているのだが、
その準備としてnode.jsとTypeScriptの勉強をすることに。

1. バージョン管理のためにnodistをインストール
2. Node.jsのインストール
3. TypeScriptのインストール
4. 型定義の準備
5. 使ってみる

環境　windows10 CreatersUpdate

# 1. バージョン管理のためにnodistをインストール  
nodistはNode.jsのバージョン管理をするツール。
以下からダウンロードしてインストール
https://github.com/marcelklehr/nodist/releases

コマンドプロンプトから

```
nodist -v
```

を実行してバージョンが表示されればOK

# 2. Node.jsのインストール
インストールできるバージョンの確認

```
nodist dist
```

偶数バージョン（安定版）の最新バージョン（2017/06/04現在）　v6.10.3をインストールする。

```
nodist + v6.10.3
```

インストールされたバージョンの確認

```
node -v
```

# 3. TypeScriptのインストール
```
npm install -g typescript
```

これだけで終わり
"-g"はグローバルでインストールするという意味。

# 4. 型定義の準備
TypeScriptの型定義管理ツール[typings](https://github.com/typings/typings)をインストール
[TSD]()は非推奨みたい。

```
npm install -g typings
```

# 5. 使ってみる
## 5.1. 型定義をインストールする

```
typings install dt~node --global --save
```

--saveを付けておくとpackage.jsonみたいなのを作ってくれるので
別環境で動作させたいときなどに

```
typings install
```

でまとめてインストールできる

サンプル

```hello_typescript.ts
///<reference path="./typings/index.d.ts"/>
import http = require("http");
class Main
{
    constructor()
    {
        var server = http.createServer((request:http.ServerRequest, response:http.ServerResponse) => this.requestHandler(request, response));
        server.listen("8080");
    }
 
    /*
    * サーバーにリクエストがあった時に実行される関数
     */
    private requestHandler(request:http.ServerRequest, response:http.ServerResponse):void
    {
        response.end("Hello! Node.js with TypeScript");
    }
}
var main:Main = new Main();
```

## 5.2. コンパイルする

```
tsc hello_typescript.ts --module commonjs
```

と思ったらなんかいっぱいエラーが出た。
結局以下のような原因だった。

TypeScriptの1.6.2が入ってるはずなのにtsc --versionが1.0.3.0を返したら
http://kiyokura.hateblo.jp/entry/2015/10/13/224800

ということで環境変数から
C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\
を削除して再度コンパイル
error TS2688: Cannot find type definition file for 'node'.
とか出ているがとりあえずコンパイルはできたみたい。

一応解決のためにtypesをインストールすればいいのかと思ったらエラー増えたので、とりあえずアンインストールしたらエラーメッセージが出なくなったという謎。見なかったことにしておこう。

```
npm install @types/node --save
npm uninstall @types/node --save
```

## 5.3. 実行する

```
node hello_typescript.js
```

http://localhost:8080/ にアクセスして以下のように表示されたら成功

```
Hello! Node.js with TypeScript
```

追記
typesというものがあったようです
https://qiita.com/tonkotsuboy_com/items/634b0921b6170cf56813
Firefoxのヘッドレスモード

こんにちは！
PhantomJSいつまで使いますか！！
ヘッドレスモード使えるようになるのはChromeだけだと思ってませんか！！！


Firefox 55, 56からヘッドレスモードが使えるようになりました
========================================================

Google Chrome/Chromiumに比べて喧伝されていないためか、案外知っている人が少ない気がしますが…もうちょっと大騒ぎしてもいいんじゃないでしょうか！
Firefox 55からヘッドレスモードを利用可能にする主旨のバグトラッカーが、Bugzillaに掲載されています。
[Bug 1338004 - [meta] Headless browsing mode](https://bugzilla.mozilla.org/show_bug.cgi?id=1338004)
予定通り無事リリースされました！


どんな判断だ
==============

発端はそもそも9年前の「Xvfbとか使わないヘッドレスモードがあるといいなあﾁﾗｯﾁﾗｯ」なリクエストのようです。ずいぶん長い時間がかかりましたね～
[Bug 446591 - Make it possible to run Mozilla with UI "rendered" to memory](https://bugzilla.mozilla.org/show_bug.cgi?id=headless)

直近の動機としては、Firefoxに依存している [SlimerJS](https://slimerjs.org/) の中で完全なヘッドレスモードで利用したい、というような雰囲気もありますね。


Linuxが先行、WindowsとMacも対応
============================

WindowsとMacへの対応は、ちょっと遅れてFirefox 56で同時にリリースされました！
対応するのは次のチケットです。
[Bug 1355147 - Support headless mode on MacOS](https://bugzilla.mozilla.org/show_bug.cgi?id=1355147)
[Bug 1355150 - Support headless mode on Windows](https://bugzilla.mozilla.org/show_bug.cgi?id=1355150)

使い方
========

Mozillaのサイトに詳細に載っています。
https://developer.mozilla.org/ja/Firefox/Headless_mode

当初は、環境変数 `MOZ_HEADLESS` を1に設定した状態でFirefoxを起動していました。
簡単にやると次のような感じです。

```bash
$ MOZ_HEADLESS=1 /path/to/firefox
```

ただ、すぐに `-headless` フラグをつけるやり方が追加されました。こっちの方がやりやすいですね。

```bash
$ /path/to/firefox -headless
```
PHP/PythonのジェネレータをGolang/Rubyで実現

#Golang(Go)/Rubyでジェネレータを実現する
[こちら](http://qiita.com/hiroykam/items/2fea445fd2d489354c34#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3%82%BF)でPHPとPython3でのジェネレータを調べていた際に、GolangとRubyではどのように実現できるのか調査をしてみた。

##PHP、Python3、Golang、Ruby2.4でジェネレータ
`numbers.txt`を読み込み、以下の出力結果となるような簡単なジェネレータを用意した。

```numbers.txt
zero
one
two
three
four
five
```

```text:出力結果
0:zero
1:one
2:two
3:three
4:four
5:five
```

###PHPの場合
PHP5.6で検証した。`yield from`は今回は利用していないので、PHP7は選択しなかった。

```php
<?php

function my_generator($name)
{
    $file = fopen($name, "r");

    if ($file) {
        while ($line = fgets($file)) {
            yield $line;
        }
    }
    fclose($file);
}

$g = my_generator("numbers.txt");
foreach ($g as $k => $v) {
    print($k. ":". $v);
}
```

###Pythonの場合
PHPと同等な方法で実現できる。Pythonのバージョンは3.5を利用した。

```py
def my_generator(name):
    with open(name) as lines:
        for line in lines:
           yield line

g = my_generator("numbers.txt")
for k, v in enumerate(g):
    print("%s:%s" % (k, v), end="")
```

###Golangの場合
GolangにはPHPやPythonの`yield`に相当した機能がない（[参考](http://www.yunabe.jp/docs/golang_pitfall.html#goroutinegenerator-yield-)はこちら）。そのため、ゴルーチン・チャンネルまたクロージャを利用した方法で類似のことを実現した。

####ゴルーチン・チャンネルを利用した方法
`numbers.txt`の行数が膨大になることを想定するとパフォーマンス面で懸念がある。

```go
package main

import (
    "bufio"
    "fmt"
    "os"
)

func yield(fp *os.File) chan string {
    ch := make(chan string)

    go func() {
        defer close(ch)

        scanner := bufio.NewScanner(fp)
        for scanner.Scan() {
            ch <- scanner.Text()
        }
        if err := scanner.Err(); err != nil {
            panic(err)
        }
    } ()

    return ch
}

func main() {
    fp, err := os.Open("numbers.txt")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    i := 0
    for s := range(yield(fp)) {
        fmt.Printf("%d:%s\n", i, s)
        i++
    }
}
```

####クロージャを利用した方法
`sync.Mutex`で同期をとる方法もありかもしれない。

```go
package main

import (
    "bufio"
    "fmt"
    "os"
)

func yield(fp *os.File) func() (bool, string) {
    scanner := bufio.NewScanner(fp)
    return func() (bool, string) {
        t := scanner.Scan()
        if err := scanner.Err(); err != nil {
            panic(err)
        }
        return t, scanner.Text()
    }
}

func main() {
    fp, err := os.Open("numbers.txt")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    y := yield(fp)
    for i := 0;;i++ {
        t, s := y()
        if !t { break }
        fmt.Printf("%d:%s\n", i, s)
    }
}
```

###Ruby2.4の場合
Rubyにも`yield`があるが、PHP/Pythonのようなジェネレータではなくブロックを受け取る関数定義となる。PHP/Pythonのジェネレータに相当するような機能に`Enumerator`があり、下記のよう記載する。
※kts_hさんからご提案いただいたコードに修正しました。

```rb
def my_generator(name)
  return to_enum(__method__, name) unless block_given?
  IO.foreach(name) do |line|
    yield(line.chomp)
  end
end

g = my_generator('numbers.txt')
g.with_index { |l, i| p '%d:%s' % [i, l] }
```


ここでは、ブロックがあるとブロックの処理をし、ブロックがないと Enumerator を返すメソッドとして扱うことができる。
フロント書くなら確実に知っておくべきCodePenについてのメモ

# 概要

HTML/CSS/JavaScriptが書きたい？じゃあCodePenでしょ！！

ということで基本の使い方とすごいところを語ります。

# What is CodePen? :information_desk_person:

HTML/CSS/JSのコードを、ブラウザ上で編集しながら実行結果が確認できる最強ツールです。

コードを保存して公開することもできるので、ポートフォリオとしてコードを公開している人や、誰かの書いた素晴らしいコードを参考にしてコーディングを行うことができます。

# How to Start CodePen!:point_up:

### 1. Sign up ボタンを押します！
【URL】 https://codepen.io/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/c812d0e2-9bc0-46e6-d443-b76bb08255b1.png)

### 2.Free プランをクリックします！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/398a3e90-de8e-d109-fe24-fe59fea4f19a.png)

### 3.入力＆Submit！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/489aff19-a586-905d-17b1-d4f6ad95a1e9.png)

### 4.Save&Continueをクリック！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/ffeefc66-4669-8c58-d645-671a53800c82.png)

### 5.アカウント作成完了！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/154c6d1c-a960-6921-5bb4-2efe83c6b107.png)

# 他にも色々 :dancers:

## フォークする

参考になりそうなコードをフォーク(コピー)して自分のアカウントで編集することができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/26bf1211-f1b4-9569-6e6a-5cdadd558859.png)

※フォークして編集したソースコードは、プロフィール一覧の「forked」ラベルで確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/ebefdc77-bda9-ac64-d6fd-3d5fd4c90cf1.png)
新規Railsプロジェクト作成時のコマンド

#概要
bundlerを使用してプロジェクトローカルにgemをインストールする方針。
自分用メモ。

#前提条件
- rbenvでRubyインストール済み（Ver. 2.4.1)
- gem install bundlerでbundlerインストール済み

#コマンド
##### プロジェクトディレクトリ作成・移動
```
$ mkdir test_project
$ cd test_project
```

##### Gemfile作成
```
$ bundle init
```

##### Gemfile編集
```
$ vi Gemfile
```

```ruby:Gemfile
source "https://rubygems.org"
gem "rails", "5.1.1"
```

##### Railsをパスを指定してbundle install
```
$ bundle install --path vendor/bundle
```

##### Railsプロジェクト作成
```
$ bundle exec rails new . -d postgresql --skip-bundle
```
※ --skip-bundleを指定しないとrails new時にbundle installが実行され、Ruby環境にgemがインストールされてしまう。
※ -dオプション: 使用するDBMSを指定。

##### プロジェクトローカルのgemでrails server起動
```
$ bundle exec rails s
```

無事起動すれば完了。

# 備考
bundle execで純粋にプロジェクトローカルのgemだけを使用するには、
.bundle/configのBUNDLE_DISABLE_SHARED_GEMSを"true"にすること。
"false"の場合、vender/bundle配下に存在しないgemをRubyグローバルから探してくる。

```
$ vi .bundle/config
```
```ruby:.bundle/config
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_DISABLE_SHARED_GEMS: "true"  #ここを"true"
```
PHP Manual 読書会(5回目)(演算子#1)

PHPに慣れる為に週1ぐらいで更新していきます。PHP Manualを読んで実験して行きます。

前回: [PHP Manual 読書会(4回目)(定数)](http://qiita.com/amesho/items/37356172c5fe220a8b4f)

## 演算子#1

### [演算子の優先順位](http://php.net/manual/ja/language.operators.precedence.php)

気になったところは、ここですね。
> 演算子の優先順位や結合性は、あくまでも式のグループ分けだけを決めるものであり、評価順を決めるものではありません。 PHP では一般に 、式をどの順番で評価するかは決めていません。 そのため、特定の順序で式が評価されることを前提としたコードを書いてはいけません。 PHP のバージョンが変わったり前後のコードが変わったりしたときに、評価順が変わる可能性があるからです。

```php
<?php

$hoge = 1;
echo $hoge + $hoge++;
```

`++`の演算子が、他の言語のように式が評価された後に実行されるとは決められていないので上記のスクリプトは1,2のどちらを返すのかは決め られていない。ということになります。

### [代数演算子](http://php.net/manual/ja/language.operators.arithmetic.php)

`+-*/%`などのことですが、言われないと分からないのは以下ですね。

> $a を、必要に応じて int あるいは float に変換する

```php
<?php

$hoge = 1;
echo +$hoge;
```

### [比較演算子](http://php.net/manual/ja/language.operators.comparison.php)

ここだと、良く見かける`==`と`===`は何が違うのかというところが分かります。

> $a == $b 型の相互変換をした後で $a が $b に等しい時に TRUE。
> $a が $b に等しく、および同じ型である場合に TRUE 。

型変換をした上で、等しいか、型をチェックして等しいかの違いですね。
例にもでていますが、こういうケースが真になるかならないかというところが違いとなっています。

```php
<?php

var_dump( "1" == "01" );
```
Ansible で WebLogic Server を構築する〜説明編〜

# 本投稿の目的
Ansible を使った Oracle WebLogic Server の構築例を共有することが目的です。  

## 初めに

### 今回のソース
今回利用するソースは GitHub に置きました。自由にご覧ください。

+ [kyohiga0325/WLS-Playbook](https://github.com/kyohiga0325/WLS-Playbook.git)

### WebLogic Server の基礎知識
Oracle WebLogic Server (WLS) とは旧 BEA 社のアプリケーションサーバ製品であり、現在は Oracle 社より販売されております。基本的に開発目的・個人使用の目的であれば、無料での利用が可能です。  

まず、OS 上にはたくさんのプロセスがありますが、__WebLogic Server はただの Java のプログラム__なので、JVM(Java Virtual Machine) 上で動作します。  


<img src="https://qiita-image-store.s3.amazonaws.com/0/62100/072c06a0-6a96-c5ae-af47-6b3681eac274.png" width=70%>

なので、Ansible で構築する際も以下のような順番で実行するようにします。  
それぞれの項目は追って別の記事で解説します。

1. (Optional) OS のもろもろの設定  
今回は省略しますが、ネットワークの設定など、他にもいっぱい Ansible の記事があると思うので、それらをもとに設定ください。
2. Java のインストール  
WebLogic Server が動作する基盤となる Java をインストールします。  
3. WebLogic Server のインストール  
一般的には GUI を使いますが、Ansible のコマンドラインで実行するために、サイレントインストールを使います。
4. WebLogic Server Domain の構築  
WebLogic Server は基本的にドメインと呼ばれる単位で管理されるので、そのドメインの構築まで行います。
5. (Optional) アプリケーションのデプロイ

##### 参考記事
+ [「WebLogicってなんなの？」をWebLogic初心者向けに説明する](http://qiita.com/kazuma1989/items/28ea5c32de7fa789f9e9)
+ [Oracle WebLogic Serverの理解 12c (12.2.1.2.0)/4 WebLogic Serverドメイン](http://docs.oracle.com/cd/E84527_01/wls/INTRO/domains.htm#GUID-EE8E9DA0-2D95-4EF1-ADA2-4C76CB1AB3A4)
OpenShift Origin MinishiftをCentOS7にインストールしてみた

### OpenShift Origin Minishiftとは

コンテナ環境のOpenShift Originのローカル実行環境。
VM上でOpenShift Origin clusterを動作させるそう。
詳細については公式ページにて確認してください。

公式サイト　[OpenShift Origin Minishift](https://docs.openshift.org/latest/minishift/index.html)

インストール方法もサイト上で公開されているのですが、ここではCentOS7へのインストールをメモとして残しています。

- KVMのインストール

VMの環境としてKVMを使うので、まずは、KVMをインストールします。
KVMのインストール手順は既に多くの情報があるので、そちらも参考にしてください。

```
# yum -y install qemu-kvm libvirt virt-install bridge-utils virt-manager
```

ついでに起動させておきます。

```
# systemctl start  libvirtd
# systemctl enable libvirtd
```

- KVM driverのインストール

```
# curl -L https://github.com/dhiltgen/docker-machine-kvm/releases/download/v0.7.0/docker-machine-driver-kvm -o /usr/local/bin/docker-machine-driver-kvm
# chmod +x /usr/local/bin/docker-machine-driver-kvm
# usermod -a -G libvirt root
# newgrp libvirt
```

- minishiftのインストール

1. インストール先のディレクトリの作成
    インストール先は /opt とし minishift という名前のディレクトリを作成します。

    ```
    # mkdir /opt/mimishift
    ```
1. ファイルをダウンロードして展開

    今回ダウンロードしたファイルは minishift-1.0.1-linux-amd64.tgz です。
    既に/opt/minishiftディレクトリに配置してます。

    ```
    # tar zxvf minishift-1.0.1-linux-amd64.tgz
    ```

1.  PATHを通す

    minishiftはバイナリ形式で展開されるので、実行できるように /opt/minishift にPATHを通します。
    必要に応じて.bashrc等でも記載してください。

    ```
    # export PATH=$PATH:/opt/minishift
    ````

- minishiftの起動

minishiftを起動します。

```
# minishift start
```

おや？エラーが出て失敗しました。
とりあえず、今日はここまで。
原因は後日調査します。
Retrofit2でMultipartPOST


すぐ忘れるのでメモ。
間違いなどあったら是非指摘していただきたいです。

##やりたいこと
タイトルにある通り。
APIに画像を投げたいとか、そういう場合を想定してます。

##環境
- AndroidStudio 2.3.2
- buildToolVersion 25.0.2
- Retrofit2 2.2.0
- Okhttp 3.8.0
- Retrolambda 3.3.0
- RxJava2 2.0.8
- RxAndroid 2.0.1

##方法
###1.interfaceの定義
`@Body`アノテーションを付与した`RequestBoby`を定義するインタフェースの引数に含める。
以下は、`/post`へ投げる例。

```Java:api.java
@POST("/post")
Single<Response<StatusResponse>> createPost(@Body RequestBody images);
```

`@Multipart`が必要なのかと思っていたが、必要無かった。

###2.`RequestBody`の生成
`Okhttp3.RequestBody`に存在する`Builder`を使って生成する。

```Java:PostService.java
MultipartBody.Builder builder = new MultipartBody.Builder()
  .setType(MultipartBody.FORM)
  .addFormDataPart("caption", intent.getStringExtra("caption"));

for (File file : files) {
  builder.addFormDataPart("media", file.getName(), 
  // RequestBody.createが廃止されたので、file.toRequestBodyに修正
  file.toRequestBody("image/jpg".toMediaTypeOrNull(), 0, file.size)
}

RequestBody body = builder.build();
```

**2020/09/30追記**

RequestBody.createが廃止されたので、file.toRequestBodyに修正しました。
修正提案いただきました @mizukicker さん、ありがとうございました:bow:

--追記ここまで--

####`setType`
Content-Typeを指定する。Content-Typeは以下のようなもの

- multipart/form-data
- application/octet-stream
- text/plain
- image/jpeg
などなど

`RequestBody`には、次のTypeが定義されている。

|値|Content-Type|
|:----|:----|
|FORM|multipart/form-data|
|MIXED|multipart/mixed|
|ALTERNATIVE|multipart/alternative|
|DIGEST|multipart/digest|
|PARALLEL|multipart/parallel|

内部的には各値に対応する文字列を`MediaType.parse()`に渡している。

今回は上記のうち`FORM`を使っています。

####`addFormDataPart`
nameとvalueを引数に取るものと、nameとfileNameとbodyを引数に取るものがあります。

単なる文字列ならば`(name, value)`で。
画像とかのファイルならば`(name, fileName, value)`を使う。

後者では、第3引数にRequestBodyが必要。
`RequestBody.create()`などで作ってやればOK。

###3.呼び出して実行
ViewModelやRepositoryなどから、実際に呼び出す。

```Java:HogeRepository.java
//Maybe<T>を返す
return ApiClient.postApi.createPost(body)
  .compose(DebugTransformer.withSingle("createNewPost"))
  .doOnError(throwable -> {
    Log.d("debug", "error: createNewPost");
    throwable.printStackTrace();
  })
  .filter(response -> response.body() != null)
  .map(response -> response.body().status);
```

上記はRepositoryでの実装例。
実際には、ViewModelなどでsubscribeしておき、APIコールの結果を使ってViewに反映させたりする。
IMEキーボードの表示/非表示

# 表示
```java:showKeyboard
public static void showSoftboard(@Nullable final Activity activity) {
    if (activity == null) {
        Log.w("activity NULL");
        return;
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(
            Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(1, InputMethodManager.SHOW_IMPLICIT);
}
```

# 非表示
```java:hideKeyboard
public static void hideKeyboard(@Nullable final Activity activity) {
    if (activity == null) {
        Log.w("activity NULL");
        return;
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(
            Context.INPUT_METHOD_SERVICE);
    View currentFocus = activity.getCurrentFocus();
    if (currentFocus != null) {
        imm.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
    }
}
```
fmt.Print(str) v.s. fmt.Printf(str)

Go で文字列をフォーマットせずに出力する時普段は `fmt.Print` を使っています．

```go
Print("hello")
```

ですが，`fmt.Print` は引き数に `interface{}` を取るので `string` を直接第1引数に取れる `fmt.Printf` のほうが速いのでは…とふと思いました．

```go
Printf("hello")
```

というわけでベンチマークをとってみました．

```go
package main

import (
	"fmt"
	"io/ioutil"
	"testing"
)

func BenchmarkPrint(b *testing.B) {
	for i := 0; i < b.N; i++ {
		fmt.Fprint(ioutil.Discard, "hello, hello")
	}
}

func BenchmarkPrintf(b *testing.B) {
	for i := 0; i < b.N; i++ {
		fmt.Fprintf(ioutil.Discard, "hello, hello")
	}
}
```

結果：

```
BenchmarkPrint-8    	20000000	        92.4 ns/op
BenchmarkPrintf-8   	30000000	        46.8 ns/op
PASS
ok  	command-line-arguments	3.402s
```

呼び出しコストは `Print` のほうが2倍ぐらい大きいようです．では `Printf` が良いのでしょうか？もうちょっと見てみます．

大きい文字列を入力にしてみます．

```go
package main

import (
	"fmt"
	"io/ioutil"
	"strings"
	"testing"
)

var input = strings.Repeat("hello, ", 1000)

func BenchmarkPrint(b *testing.B) {
	for i := 0; i < b.N; i++ {
		fmt.Fprint(ioutil.Discard, input)
	}
}

func BenchmarkPrintf(b *testing.B) {
	for i := 0; i < b.N; i++ {
		fmt.Fprintf(ioutil.Discard, input)
	}
}
```

結果：

```
BenchmarkPrint-8    	10000000	       167 ns/op
BenchmarkPrintf-8   	  500000	      2892 ns/op
PASS
ok  	command-line-arguments	3.331s
```

今度は `Printf` のほうがかなり遅い結果になりました．`Printf` はフォーマット文字列を走査しないといけないからでしょうか？しかしフォーマット文字列の後の可変長部分は空なのでそれは不要のはずです．おかしいですね…

と思ったら，どうやら可変長部分が空でもフォーマット文字列を走査していました．それは遅い…

https://github.com/golang/go/blob/177dfba1120d2d5976bb5fb5a68bf20bb6ca9ada/src/fmt/print.go#L944

## 結論

- 小さい文字列を繰り返し print するときは `Printf` が良く，大きめの文字列を一度に print するときは `Print` が良く，それ以外の場合はどちらでも良い
- `Print` の呼び出しコストは高々2倍なので，よほどのことが無い限り当初通り `Print` を使っておけば良い
- Go はベンチマーク取りやすくて良い
pacman -S wine で，"wine"が無い・・・

# pacman -S wine では，wineをインストールできなかった．
Windows互換環境のWineをインストールをしようとしたら，
すぐにはできなかった．

 > sudo pacman -Sy wine
:: パッケージデータベースの同期中...
 core は最新です
 extra は最新です
 community は最新です
 archlinuxfr は最新です
エラー: 対象が見つかりませんでした: wine

# 対策
ここによれば，
https://bbs.archlinux.org/viewtopic.php?id=120219
 /etc/pacman.conf の
 コメントアウトされている [multitab] を，有効にすればよい，とのこと

 #[multilib]
 #Include = /etc/pacman.d/mirrorlist
 ーー＞
 [multilib]
 Include = /etc/pacman.d/mirrorlist

# できた!!
> sudo pacman -Ss wine
　　　　　：
community/python2-twine 1.8.1-2
    Collection of utilities for interacting with PyPI
community/twine 1.8.1-2
    Collection of utilities for interacting with PyPI
community/wine-mono 4.7.0-1
    Wine's built-in replacement for Microsoft's .NET Framework
community/winetricks 20170517-1
    Script to install various redistributable runtime libraries in Wine.
multilib/q4wine 1.3.5-1
    A Qt4 GUI for Wine
multilib/wine 2.9-1　★★★★★★★　あった
    A compatibility layer for running Windows programs


sudo pacman -S wine winetricks で Go!!
[備忘]numpyメモ

#はじめに

個人的なnumpyのメモ

#ランダムな値の配列を作る
### ０〜9までのランダムな値を持つ、2×2の配列を作る
```lang:python
# coding: utf-8
import numpy as np

rand_arr = np.random.randint(0, 10, (2, 2))
print(rand_arr)
# 結果
# [[3 7]
#  [2 6]]
```

#配列の合計、最大値(最小値)を取得する
第2引数にaxis=0を設定すると、各列に対する結果になる
第2引数にaxis=1を設定すると、各行に対する結果になる

```lang:python
# coding: utf-8
import numpy as np

random_arr = np.random.randint(0, 10, (2, 2))
print(random_arr)

# 結果
# [[4 8]
#  [3 1]]

arr_sum = np.sum(random_arr)
print(arr_sum)

# 結果
# 16

arr_sum_by_col = np.sum(random_arr, axis=0)
print(arr_sum_by_col)

# 結果
# [7 9]

arr_sum_by_row = np.sum(random_arr, axis=1)
print(arr_sum_by_row)

# 結果
# [12  4]

arr_max = np.max(random_arr)
print(arr_max)

# 結果
# 8

arr_max_by_col = np.max(random_arr, axis=0)
print(arr_max_by_col)

# 結果
# [4 8]

arr_max_by_row = np.max(random_arr, axis=1)
print(arr_max_by_row)

# 結果
# [8 3]
```
Vagrant

## Vagrant作業メモ
・vagrantを利用してvboxを起動するまでメモ
・vboxやDocker,EC2(AWS)といったイメージの起動・停止・破棄を制御
　→つまりコンテナやVMのそれぞれ個別で持っている制御コマンドを
　　　vagrantを利用することで同じインターフェイスでやれるものと理解

## install
公式からinstall
[vagrant insatll](https://www.vagrantup.com/docs/installation/)
[virtualbox install](https://www.virtualbox.org/wiki/Downloads)


## vagrant


```
# vagrant --help
Usage: vagrant [options] <command> [<args>]

    -v, --version                    Print the version and exit.
    -h, --help                       Print this help.

Common commands:
     box             manages boxes: installation, removal, etc.
     connect         connect to a remotely shared Vagrant environment
     destroy         stops and deletes all traces of the vagrant machine
     global-status   outputs status Vagrant environments for this user
     halt            stops the vagrant machine
     help            shows the help for a subcommand
     init            initializes a new Vagrant environment by creating a Vagrantfile
     login           log in to HashiCorp's Atlas
     package         packages a running vagrant environment into a box
     plugin          manages plugins: install, uninstall, update, etc.
     port            displays information about guest port mappings
     powershell      connects to machine via powershell remoting
     provision       provisions the vagrant machine
     push            deploys code in this environment to a configured destination
     rdp             connects to machine via RDP
     reload          restarts vagrant machine, loads new Vagrantfile configuration
     resume          resume a suspended vagrant machine
     share           share your Vagrant environment with anyone in the world
     snapshot        manages snapshots: saving, restoring, etc.
     ssh             connects to machine via SSH
     ssh-config      outputs OpenSSH valid configuration to connect to the machine
     status          outputs status of the vagrant machine
     suspend         suspends the machine
     up              starts and provisions the vagrant environment
     version         prints current and latest Vagrant version

For help on any individual command run `vagrant COMMAND -h`

Additional subcommands are available, but are either more advanced
or not commonly used. To see all subcommands, run the command
`vagrant list-commands`.
```

## 起動までの流れ

### 作業ディレクトリ
```
mkdir -p ./vagrant_work/centos6;cd ./vagrant_work/centos6
```
### Vagrant init
```
vagrant init vagrant init scalefactory/centos6
```
→実行ディレクトリに「Vagrantfile」が生成される
[Atlas Discover Vagrant Boxes](https://atlas.hashicorp.com/boxes/search?_ga=2.41127714.1481776172.1496550790-961812756.1496550790)

### 起動
実行ディレクトリに生成された「Vagrantfile」に合せて
仮想マシンが起動される

```
vagrant up
```

## 接続
```
vagrant ssh
```
新規にブランチを作成したら自動で空コミットを作成するgit hook

概要
---

以下のような状況に対応するようなgit hookがほしかったので作ってみました。

- Feature branch を作成し、すぐに　WIP 状態で Pull Request を出したい
- Pull Request 出すにはマージ先のブランチとコミット差分が必要
- なので **ブランチを切ったら自動で空コミットを作成するhookがほしい**
- なおコミットメッセージは "Creat new branch [xxx]" (xxx: 新規作成したブランチ名)とする

以下のような感じのことを自動でやりたいというイメージです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17214/6f6f2867-5a93-6e52-56ee-6e3c9fe4a3c9.png)

実装
---

gistは[こちら](https://gist.github.com/imaizume/35ed1209ec4ca29c74ec8d0617b6892c)から

```ruby:post-checkout
#!/usr/bin/env ruby

before, after, switch = ARGV
exit 0 unless before == after
exit 0 unless switch.to_i == 1

branch = `git rev-parse --abbrev-ref HEAD`
msg = "Created new branch #{branch}"
system(%(git commit --allow-empty -m "#{msg}"))
```
やっていることは単純で、以下の仕様を単純に実装しただけです。

仕様
---

今回は [post-checkout hook](https://git-scm.com/docs/githooks#_post_checkout)を使って実装します。
`post-checkout`では`git checkout`後に引数として以下の情報をうけとることができます。

1. `git checkout` 実行前のHEAD (以下 `B`)
2. `git checkout` 実行後のHEAD (以下 `A`)
3. ブランチの変更があったか (0: なし　1: あり) (以下 `S`)

今回作成したいのは**新しいブランチを作成したら自動で空コミットを1つ作成するhook**です。
したがって **`B == A　 && S == 1` であれば空コミットを作成するようにしたいと思います。**

この条件なら `git branch && git checkout` でも `git checkout -b` でも、ブランチ作成後、即座にからコミットが作成できるというわけです :thumbsup:  

問題
---

しかし、上記の条件では

- `git branch feature` 後、別のコミットをcheckoutしてから`git checkout feature`する :arrow_forward: `B!=A`のため空コミットは作られない
- 既に `git checkout feature` した状態で、masterにfast forward mergeし、かつcheckoutした後、再び`gitc checkout feature`する :arrow_forward: 既にブランチは作成済みだが `B==A` のため空コミットが作られる

いずれも、通常の使用を考えるとそのようなケースは稀だと思い、今回は対応しませんでした。
1 については、逆に空コミットを自動作成されたくない場合の回避策にもなると思います。
ただもっとよい実装があったらぜひ教えてください。

実行
---

いちおう念のため実行例を載せておきますので、ローカルでリポジトリ作って試してみてください。

```shell-session
$ git log --decorated --graph --oneline --all
* 2fcd02f - (HEAD -> master) Initial commit <imaizume>
$ git cob feature1
Switched to a new branch 'feature1'
[feature1 1c3f519] Created new branch feature1
$ git log --decorated --graph --oneline --all
* 1c3f519 - (HEAD -> feature1) Created new branch feature1 <imaizume>
* 2fcd02f - (master) Initial commit <imaizume>
```

補足
---

- Pull Requestも出すなら、そのままhookでpushまでやっても良いと思います。
- ただ自分はブランチ名をtypoすることがあるので、リモートを汚したくないということであえて入れませんでした。
- 自作の際は `chmod u+x post-checkout`するのをお忘れなく :exclamation: 
- 調べてみると意外とpost-checkout hookに関する情報って無いんですね、あまり使い所がないのかな :sweat_smile: 

参考リンク
---

- [Gitのフックの説明と挙動の検証 \- Qiita](http://qiita.com/mima_ita/items/dcaa3789022d2a9ab929#checkout%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E3%83%95%E3%83%83%E3%82%AF)
- [gitで現在のブランチ名を取得する \- すがブロ](http://sugamasao.hatenablog.com/entry/2013/11/02/174311)
When the Eclipse mentions "Unresolved import cv2"

#　Memo

As i have done in [previous](http://qiita.com/Merdane/items/655130dfd176d8ee272e) post, the opencv 3.2 works very well, but one thing bothers me, the eclipse is keeping mention "Unresolved import:: cv2", even the cv2 works well. 

At first, i thought the Eclipse PyDev configuration causes this problem, so i googled a little bit and there was no obvious solution. 
So i followed into the python3.6 side-package folder (which looks like this `C:\Users\%Username%\AppData\Local\conda\conda\envs\python36\Lib\site-packages)`, then i confirmed the cv2 binary file is right there, but i noticed it is named as `cv2.cp36-win_amd64.pyd`, so i tried rename it as `cv2.pyd` with a copy of `cv2.cp36-win_amd64.pyd`(because i am not sure if `cv2.cp36-win_amd64.pyd`is the default name for library link), and it did solve the problem, after that i tried to delete the original `cv2.cp36-win_amd64.pyd` file, it still works, happy ending.
i18nのキーを調べる方法(nestされているパターン等)

nestした場合のキーってどうなるのだろうか？ということで色々ググったりしますが、そんなことよりメソッドから探したほうが早かったです。

```ruby
class WorkForm::CastForm
  include ActiveModel::Model

  attr_accessor :name
end
```

このパターンです。

**i18n_scope**

```ruby
WorkForm::CastForm.i18n_scope
=> :activemodel
```

これで`activemodel`に書けばいいことがわかる。

**model_name**

```ruby
WorkForm::CastForm.model_name
=> #<ActiveModel::Name:0x007f86a2093c30
 @collection="work_form/cast_forms",
 @element="cast_form",
 @human="Cast form",
 @i18n_key=:"work_form/cast_form",
 @klass=WorkForm::CastForm,
 @name="WorkForm::CastForm",
 @param_key="work_form_cast_form",
 @plural="work_form_cast_forms",
 @route_key="work_form_cast_forms",
 @singular="work_form_cast_form",
 @singular_route_key="work_form_cast_form">
```

情報が列挙される。

ここで必要なのは`i18n_key`なので、こうする。

```ruby
WorkForm::CastForm.model_name.i18n_key
=> :"work_form/cast_form"
```

こう書けばいいことがわかる

**i18nのファイルの中**

```ruby
ja:
  activemodel:
    attributes:
      work_form/cast_form:
        name: "qiita"


```

```
WorkForm::CastForm.human_attribute_name("name")
=> "qiita"
```

以上です。
プログラミング言語Go読書会#11(7.3-7.5)[2017/05/31]

[Go読書会 #11](https://lancers-engineer.connpass.com/event/58457/) が[ランサーズ株式会社](https://www.lancers.co.jp/)で行われたので進捗と技術的なメモ書きを書いておきます。読書会の内容は[プログラミング言語Go](https://www.amazon.co.jp/dp/4621300253/?&_encoding=UTF8&tag=amesho-22&linkCode=ur2&linkId=7e29043d833086d36f8b64c2ed3721b2&camp=247&creative=1211)を冒頭から皆で読み進めていくというものです。

## 進捗した内容

+ 7章 インタフェース
  + 7.3 インターフェースを満足する
  + 7.4 flag.Valueによるフラグの解析
  + 7.5 インターフェース値

## 話題に上がった話


### 7.3 インターフェースを満足する

ここでは、`関数がインターフェースが要求しているすべてのメソッドの型を保持していること`を指すインターフェースを満足するということが出てきました。そのままの言葉通りでinterfaceで宣言されているメソッドと同じ型のメソッドをそのデータ型が実装しているかどうかという意味です。型がインターフェースを満足していれば、その型はインターフェースに代入可能となります。

```go
type Hoge interface {
  String() string
}

type Page struct {}

func (*p Page) say() string {
  return "Hello"
}
```

あと、ここで話題になったのは`空インターフェース`です。基本どんな型でも代入可能なのですが、これはインターフェースを満足するというルールを満たしているためです。型に対して何も要求していないのですべての値を代入することが出来ます。

### 7.5 インターフェース値

ここでは、インターフェースは`動的な型(dynamic type)`と`動的な値(dynamic value)`という2つの構成要素を持っている。動的に決まるので通常の型では起こらないようなpanicなどが起きうるので注意することが必要。あとは、インターフェースを通して呼び出すときは、コンパイル時に決まらないので型記述子から該当のメソッドを取得して、間接的に呼び出す`動的なディスパッチ`などをコンパイラが行っていうることが書かれていました。

今週は短縮だったので、短いです。

ここまで呼んだところで、時間になりました。次回は `7.5.1 警告:nilポインタを含むインターフェースはnilではない`からです。
標準SQL書式のかんたんな一覧



## 基本

```sql
select
	[{distinct|all}]{*|★ [,★]}
from
	TABLE_NAME
[where ▲]
[group by COLUMN_NAME [{asc|desc}]]
[having ▲]
[order by COLUMN_NAME [{asc|desc}]]

```
順番は変更不可！!

### 凡例
* `[A]`：オプション。Aはあってもなくてもいい
* `{A|B}`：選択。AかBのいずれか
* `θ`：比較演算。``{<|<=|=|>=|>|<>}``
* `TABLE_NAME `：表名
* `COLUMN_NAME `：列名

## ★　→　値式（列名か関数か式か定数）
関数　→　下記参照
式　→　演算式（*100とか+1とか）
定数　→　3.14とか365とか固定の値

## ▲　→　条件

下記をひとつ、またはand, or, not でつないで複数指定

* 比較： `★　θ　★`
* BETWEEN： `★　[not] between ★ and ★`
* IN： `★　[not] in (★ [,★])`
* LIKE： `COLUMN_NAME　[not] like "なんらかの文字列"`
* NULL： `COLUMN_NAME　is [not] null`

## 関数（countとか）
* 総数 count： `count([{distinct|all}] {COLUMN_NAME|*})`
* 総和　sum：`sum([{distinct|all}] COLUMN_NAME)`
* 平均値　avg：`avg([{distinct|all}] COLUMN_NAME)`
* 最大値 max：`max(COLUMN_NAME)`
* 最小値 min：`min(COLUMN_NAME)`

## サブクエリ用の記述
* 比較： `★　θ　（サブクエリ）`
* IN： `★　[not] in（サブクエリ）`
* 限定： `★　θ {all|any|some}　（サブクエリ）`
* EXISTS： `★　exists　（サブクエリ）`


## 参考文献
* 「リレーショナルデータベースの実践的基礎」速水治夫　著
Goでマルチバイナリ構成のレポジトリを作る

# 背景
下記の意図があり、1レポジトリでマルチバイナリの構成にするためのディレクトリ構造を考えていた。

* `go get`で全てのバイナリがインストール出来ること
* 共通で利用するコードが結構あるので、これをトップディレクトリに置いておきたい
* 開発時は、docker-composeで全部立ち上げたい

# ディレクトリ構成
先にディレクトリ構成を晒す。
省略しているものがあるけど、実際のものと大体同じ。

```bash
├── Gopkg.lock
├── Gopkg.toml
├── Makefile
├── entity
├── contrib
│   ├── admin-server
│   │   ├── Dockerfile
│   │   ├── main.go
│   └── api-server
│       ├── Dockerfile
│       ├── main.go
├── docker-compose.yml
├── middleware
├── repository
├── service
└── vendor
```

こんな感じで`contrib`配下にディレクトリを掘って、管理画面とAPIサーバをそれぞれ内包しています。

# 開発時のdocker-compose
開発時は管理画面とAPIサーバ、あとMongoDBと管理用のmongo-expressも立ち上げるようにしている。

```yaml:docker-compose.yml
version: '3'
services:
  api:
    build:
      context: .
      dockerfile: contrib/api-server/Dockerfile
    volumes:
      - .:/go/src/app
    ports:
      - 18080:18080
    links:
      - mongo
    environment:
      API_SERVER_STORE_URL: mongodb://mongo/example
  admin:
    build:
      context: .
      dockerfile: contrib/admin-server/Dockerfile
    volumes:
      - .:/go/src/app
    ports:
      - 19080:19080
    links:
      - mongo
    environment:
      ADMIN_SERVER_STORE_URL: mongodb://mongo/example
  mongo:
    image: mongo:3.4
    volumes:
      - store-data:/data/db
    ports:
      - 27017:27017
  mongo-admin:
    image: mongo-express:0.38
    ports:
      - 18081:8081
    links:
      - mongo
    environment:
      ME_CONFIG_MONGODB_ENABLE_ADMIN: "false"
volumes:
  store-data:
    driver: local
```

今のところこんなディレクトリ構成、docker-composeで開発は問題ない。
公開用Dockerイメージのビルドは、

```bash
$ docker build -f contrib/api-server/Dockerfile -t hoge:fuga .
$ docker build -f contrib/admin-server/Dockerfile -t hoge:fuga .
```
上記のようなコマンドを実行するタスクをMakefileに定義している。

# go getで全てのバイナリをインストールするには
本記事でのレポジトリを仮に、
**github.com/neko-neko/mutiple-binary**
だとすると

```bash
$ go get -v -u github.com/neko-neko/mutiple-binary/contrib...
```

上記コマンド実行後、$GOPATH/bin/配下に
* api-server
* admin-server
が格納される。

# 最後に
APIサーバ / 管理画面 / 共通コード(この例だと`entity`とか`repository`とか`middleware`とかのセット)ごとにレポジトリを分ければ良いじゃんって思うけど、1人で全部メンテするのは面倒くさかったのよね。