OmniAICreator/Qiita-1.07M huggingface dataset:
Javaの最低限の環境構築とHello World

# はじめに
とある事情で、Hello Worldなりの最低限のコードをコマンドプロンプトでコンパイル・実行したかった事があり、備忘録としてとって置くための記事です。

# コード
```java
class hello{
	public static void main(String[] args){
		System.out.println("Hello World");
	}
}
```

# 環境確認
<kbd><kbd>Winキー</kbd> + <kbd>R</kbd></kbd> で ```[ファイル名を指定して実行]```ダイアログを表示し、<kbd>cmd</kbd>を実行。
プロンプトで、```java.exe``` と ```javac.exe``` のパスが通っているか、ついでにバージョンを確認

```
> java -version
> javac -version
```

次のようなエラーが表示されたら、パスが通っていないので、環境変数を確認する。
<kbd><kbd>Winキー</kbd> + <kbd>Pause</kbd></kbd> で <kbd>コントロール パネル\システムとセキュリティ\システム</kbd> を表示し、```[システムの詳細設定]```から。

```
'javac' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

というか通っていないからエラーなので、確かにどこかにあるはずなら、Cドライブの直下なりから探す。

```
> c:
> cd \
> dir javac.exe /s
```

あまり好ましくない方法なので、どれか見つかったら <kbd><kbd>Ctrl</kbd> + <kbd>Esc</kbd></kbd> で処理を強制終了する。
見つかった先のフォルダ内にある```javac.exe```のショートカットを作成し、任意のフォルダへ配置して実行する。

```
> javac.lnk {任意のjavaソースファイルへのフルパス}
```

![alt](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rrryutaro/20161222/20161222125611.png)

# よく使用するショートカットなど（ついでなので）
- ```[ファイル名を指定して実行]```ダイアログを表示する：<kbd><kbd>Winキー</kbd> + <kbd>R</kbd></kbd>
- <kbd>コントロール パネル\システムとセキュリティ\システム</kbd>を表示する：<kbd><kbd>Winキー</kbd> + <kbd>Pause</kbd></kbd>
- コマンドプロンプトのexe名：<kbd>cmd</kbd>
- コマンドプロンプトでウィンドウを最大化（縦長）：<kbd><kbd>Alt</kbd> + <kbd>Space</kbd></kbd> , <kbd><kbd>X</kbd></kbd>、または <kbd><kbd>Winキー</kbd></kbd> , <kbd><kbd>←</kbd></kbd> or <kbd><kbd>↑</kbd></kbd> or <kbd><kbd>→</kbd></kbd>
- コマンドプロンプトでフォルダ名の入力補完：任意のタイミングで <kbd><kbd>Tab</kbd></kbd>（押すたびに次候補表示）
- コマンドプロンプトで特定の範囲の文字列をコピー：<kbd><kbd>Alt</kbd> + <kbd>Space</kbd></kbd> , <kbd><kbd>E</kbd></kbd> , <kbd><kbd>Enter</kbd></kbd> , 範囲選択（キー操作 or マウスでドラッグ）, <kbd><kbd>Enter</kbd></kbd>
- コマンドプロンプトでクリップボードの文字列を貼付け：<kbd><kbd>Alt</kbd> + <kbd>Space</kbd></kbd> , <kbd><kbd>E</kbd></kbd> , <kbd><kbd>P</kbd></kbd>, <kbd><kbd>Enter</kbd></kbd>

# 元となっている記事
- （はてなブログ）[JavaでとにかくコンソールでHello Worldを表示させたかった](http://rrryutaro.hatenablog.com/entry/2016/12/21/102254)

以上
プレゼンしなくてもPresentation Assistantプラグインが便利な件

[JetBrains Advent Calendar 2016](http://qiita.com/advent-calendar/2016/jetbrains)の22日目です。

Presentation Assistantプラグインを使ってみて便利だったのでご紹介です。

![browse_repositories.png](https://qiita-image-store.s3.amazonaws.com/0/387/97c6e22d-a998-3dbc-46e1-90e7141ce345.png)

何か操作すると画面の下の方に操作内容とショートカットを表示してくれます。（全操作という訳ではありませんが）
マウスで操作しても表示されるので、便利なショートカットを発見したり、自分はMacとWindowsどちらも使うので、「あの操作Windowsではどうやるんだろう」って時にも便利です。

![refacotr_this.png](https://qiita-image-store.s3.amazonaws.com/0/387/5042ff68-f263-af13-7c94-1ff77f34d700.png)

プレゼンやペアプロしない人にも便利なのでオススメです。

以上、超小ネタ失礼しました。
【初心者向け】HTTPメソッドまとめ

HTTPメソッドについて

## そもそもHTTPとは
HTTPとは Hyper Text Transfer Protocol の略で、インターネットつまりはWWW（World Wide Web）上で、Webサーバーとクライアントが HTML(Hyper Text Markup Language）で書かれた文書などをやり取りするための通信手順（プロトコル）である。

【HTTPの特徴】

- ステートレス
原則として、前回の状態は非保持。一回コマンドを送ったら、それに対応する結果が返ってきてそれで終わり。ステートレスなことによりシンプルで汎用的なプログラムを実現している。 欠点としては、状態を保持できないので、複数回のやり取りを追跡出来ない。そのため、別途cookieなどの技術を組み合わせて使うことで、複数回のやり取りの追跡、例えばログイン状態の保持などを実現している。
　

## HTTPを使ったWebアクセス
HTTPでは、データを要求するHTTPリクエストとそれに応答して、要求されたデータを送り返すHTTPレスポンスの2つのやりとりを繰り返して、Webページを表示している。

- HTTP通信のやりとりの順番

1、利用者がWebブラウザにURL打ち込みアクセス。
2、Webブラウザは指定したWebサーバにHTTPリクエストを送信、Webページのデータを要求。
3、Webサーバは、Webブラウザから受信したHTTPリクエストを解析する。
4、Webサーバが、Webブラウザに要求されたデータをHTTPレスポンスとして返信。
5、Webブラウザは、受信したデータを解析してWebページとして表示。


- HTTPリクエストの構成

メッセージヘッダとメッセージボディの2つに大きくわけられる。
-メッセージヘッダ
　-リクエストライン
　　-HTTPメソッド、リクエストURI、HTTPバージョン
　-ヘッダーフィールド
-メッセージボディ

- HTTPメソッド

GETメソッド：クライアントからサーバーの情報を取得する要求をする
HEADメソッド：サーバー情報のヘッダー部分を取得する要求をする
POSTメソッド：クライアントからサーバーに情報を送る
PUTメソッド：クライアントがサーバーにファイルを保存する
DELETEメソッド：クライアントからサーバーのファイルを削除する要求をする
TRACEメソッド：リクエストをそのままレスポンスとして返す
【秘密鍵/公開鍵】コピペで出来る！鍵認証の設定方法

# 公開鍵と秘密鍵とは
ざっくりと。

## 公開鍵
サーバー側に持たせておく鍵。
作ったときには「id_rsa.pub」という名前で作成され、
基本的には「authorized_keys」という名前にリネームする。
複数の公開鍵を作る場合は、**authorized_keysに追記**していく。


## 秘密鍵
クライアント側で保有しておく鍵。
誰にも渡してはいけない。



# 鍵を作る
では、実際に鍵を作ってみる。

## 鍵を作る

WindowsだとWSL2とか使うとやりやすい。

```bash
$ ssh-keygen -t ed25519
```

ed25519の暗号に対応していない系の環境（古いOS/OpenSSLなど）は、以下のコマンドで作る。

```bash
$ ssh-keygen -t rsa -b 4096 
```

## 公開鍵をサーバに登録
scpしてもいいが、`ssh-copy-id`を使うと便利。
authorized_keysに自動で追加してくれる。

```bash
$ ssh-copy-id -i 公開鍵のパス サーバのユーザ名@サーバのIP
# 例
# ssh-copy-id -i ~/.ssh/id_rsa.pub nnahito@xxx.xxx.xxx.xxx
```

## 鍵認証でサーバにアクセスしてみる
sshコマンドでサーバに鍵認証を使って接続してみます。
鍵の作成・設定が成功していると、パスワードを求められずに接続できます。

```bash:command
$ ssh –i 鍵のパス サーバのユーザ名@サーバのIP

例：$ ssh -i ~/.ssh/id_rsa nnahito@xxx.xxx.xxx.xxx
```
重複したkeyを持つJSONデータをカンマ区切りvalueにまとめる

# :pencil2: 経緯
元々xmlだったデータをJSONに変換。その際にkeyの重複に気付かず:innocent:  
JSONを参照する実装をしたとき、JSON上は存在するデータが該当しなかったため、今回のバグが発覚 :imp:

# :mag: 状況
```json:duplicate_data.json
{
  "foo": "ふー",
  "bar": "ばー",
  "baz": "ばず",
  "foo": "フー",
  "bar": "バー",
  "baz": "バズ"
}
```
"ふー"を取得したい。

```js:parse.js
const data = require('./duplicate_data.json');
console.log(data);
```
読み込んで、表示してみる。

```bash:result
$ node parse.js
{ foo: 'フー', bar: 'バー', baz: 'バズ' }
```

Objectにparseされたときに、最後のkeyのvalueのみ格納されていたため、
目的のデータが取得できない。

# :bulb: 対応策

Objectとしてparseすると、上記のように最後以外のvalueが消えるので、
ファイルデータを一行ずつ読み込んで、いい感じに加工することにしました:grin:

```js:good_parse.js
const fs = require('fs');
const rs = fs.createReadStream('./duplicate_data.json');
const rl = require('readline');
const rli = rl.createInterface(rs, {});

let pairsAry = [];
let pairs = [];
let l = '';
// 読み込んだファイルを一行ずつ処理
rli.on('line', (line) => {
  // 空白、改行を削除
  l = line.trim();
  // keyとvalueを含めた文字列を配列に分割
  pairs = l.split(':');
  // "や,など不要な部分を削除して配列を返す
  pairs = pairs.map((val) => { return val.replace(/\"|\,/g, '').trim(); });
  // keyとvalueが存在する配列だけ格納
  if (pairs.length === 2) pairsAry.push(pairs);
});

let resultObj = {};
// 読み込みが終了したら実行
rli.on('close', () => {
  let key, value;
  pairsAry.forEach((val) => {
    key = val[0];
    value = val[1];
    if (resultObj.hasOwnProperty(key)) {
      // すでに同じkeyが存在する場合は、カンマ区切りでvalueを追加
      resultObj[key] += ',' + value;
    } else {
      // keyが存在しない場合は、新規でvalueをセット
      resultObj[key] = value;
    }
  });
  // JSONファイルとして、書き出し
  fs.writeFile('parsed_data.json', JSON.stringify(resultObj, null, 2));
});

```

```json:parsed_data.json
{
  "foo": "ふー,フー",
  "bar": "ばー,バー",
  "baz": "ばず,バズ"
}
```
めでたしめでたし:clap:

# :notebook_with_decorative_cover: 結論
絵文字をつかうと、記事がやわらかい雰囲気になって良い感じでした:kissing_smiling_eyes:
Slackに返信ボタンをつけるChrome拡張をつくりました

Slackの仕様変更に追従することに心が折れたので公開停止しました。
ご迷惑をおかけして申し訳ありません。

---

これは[Slack Advent Calendar 2016](http://qiita.com/advent-calendar/2016/slack)の22日目の記事です。

---

Slackを使っていて、こんな不便を感じたことはありませんか？

- 特定のメッセージに対して返信したいのに、返信ボタンが無い… :sob:
- いくら補完があるとは言え、`@user-name`を打ち込むのが大変 :sob:
- 素早く引用ができない :sob:

これらの問題を解決するGoogle Chromeの拡張を開発しました :muscle: 
Chromeウェブストアに公開しているので、↓のページから誰でも簡単に導入できます :smile: 

- [Slack 返信引用ボタン(Slack Reply and Quote Button) - Chrome ウェブストア](https://chrome.google.com/webstore/detail/slack-%E8%BF%94%E4%BF%A1%E5%BC%95%E7%94%A8%E3%83%9C%E3%82%BF%E3%83%B3slack-reply/cechhipifmcinmnnjnlichjigoabokbg?hl=ja)

もし気に入っていただけたら、レビューお願いします:bow:

# 機能紹介

以下の3種類のボタンがあります。

2. Mentionボタンを使うと、返信ができます。
1. Replyボタンを使うと、引用+返信を素早くできます。
3. Quoteボタンを使うと、引用のみができます。

また、文字を選択した状態でReplay・Quoteボタンを押すと、部分引用ができます。

## 返信ボタン / Mention Button

Mentionボタンを使うと、返信ができます。

![Mentionボタンを使うと、すばやく返信できます](https://qiita-image-store.s3.amazonaws.com/0/17718/cfe0aa0d-a15a-e884-65bc-092d5511c2e1.gif)


## 返信+引用ボタン / Replay Button

Replyボタンを使うと、引用+返信をすばやくできます。

![Replyボタンを使うと、引用付きの返信をすばやくできます](https://qiita-image-store.s3.amazonaws.com/0/17718/2ccee58c-cb35-5283-72f2-187a4dbb6455.gif)

## 引用ボタン / Quote Button

Quoteボタンを使うと、引用ができます。相手に通知が飛ばしたくない場合にReplayボタンと使い分けます。

![Quoteボタンを使うと、相手に通知を飛ばさずに引用のみができます](https://qiita-image-store.s3.amazonaws.com/0/17718/34ee404a-3136-2d76-780a-4ea2eb54138d.gif)


## 部分引用

文字を選択した状態でReplay・Quoteボタンを押すと、部分引用ができます。

<!--
![文字を選択した状態でReplayやQuoteボタンを押すと、部分引用ができます](https://qiita-image-store.s3.amazonaws.com/0/17718/8e59e40b-bc53-b244-0a5c-0d9e158893ce.gif)
-->

![文字を選択した状態でReplayやQuoteボタンを押すと、部分引用ができます](https://qiita-image-store.s3.amazonaws.com/0/17718/53632798-de27-6cc7-705a-3ae455225bdb.gif)



## Tips

- Replyボタンの引用は、> による引用となります
- Replyボタンの引用は、4行以上または装飾のあるメッセージに対してはURLでの引用になります
- Quoteボタンの引用は、URLでの引用になります

# ソースコード

[GitHub](https://github.com/gam0022/slack-reply-and-quote-button)で公開しています。なんと2件もPRをいただきました！ありがたいですね:bow:

- [便利な部分引用](https://github.com/gam0022/slack-reply-and-quote-button/pull/2)を@kaneta1992さんに開発していただきました！
- [Replyボタンの動作の改善](https://github.com/gam0022/slack-reply-and-quote-button/pull/1)を[@jm-factorin](https://github.com/jm-factorin)さんに行なっていただきました！

もし拡張を気に入って頂けたら、スター :star: ください！！

# 開発時の参考情報

この拡張を開発するにあたって、以下のサイトを参考にしました。ありがとうございます:bow:

- [返信・引用機能をSlackに追加してみた その3](http://kikki.hatenablog.com/entry/2015/12/18/215911)
  - Slack 側で定義しているメッセージのHTMLを生成する JavaScript の関数（`TS.templates.builders.buildMsgHTML`）の動作を上書きするという基本方針はこちらの方法を参考にさせていただきました
- [Chrome Extension のcontent scriptでの変数隔離に対応する。](http://takuya-1st.hatenablog.jp/entry/2014/11/04/001449)
  - Chrome 拡張の JavaScript（ContentScript）はページ内の変数やイベントハンドラを上書きできないので、ここで紹介されている HTML の `<body>` タグ以下に `<script>` タグを追加してコードを実行するという方法で対処しました

# 公式サイト

- [Slackに返信・引用ボタンを追加するChrome拡張 | gam0022.net](http://gam0022.net/works/slack-reply-and-quote-button/)
Pythonでmp3の波形を描く

# はじめに
音楽の特徴を抽出するために、mp3ファイルを波形で表示したいと思いました。

# コード

```test.py
import librosa

a = librosa.load('test.mp3')
librosa.display.waveplot(a[0],sr=22050)
```

# 結果
![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/82763/27b1c35b-c5a5-26b1-306d-d87c111c54bc.png)


# 参考
下記を参考にしました。
[Urban Sound Classification with Neural Networks in Tensorflow](http://www.kdnuggets.com/2016/09/urban-sound-classification-neural-networks-tensorflow.html)

ありがとうございました。
Gebはどうして簡潔に書けるのか？ 〜Gebで学ぶmethod missing〜

# はじめに

これは[Geb Advent Calendar 2016](http://qiita.com/advent-calendar/2016/geb)の22日目の記事です。
今日はGebの内部構造の一端をご紹介します。

# Gebの簡潔表記のヒミツ

Gebといえば、下記のような簡潔な表記が可能です。

```groovy
to GebishOrgHomePage
```
今日はこれがなぜ出来るのか？　というのを解説します。

## 引数があるメソッドは、`()`を省略できる

Groovyでは、引数が1つ以上あるメソッドであれば、カッコを省略することが可能です。
なので、下記の二つのコードは等価です。

```groovy
to GebishOrgHomePage

to(GebishOrgHomePage) // カッコは省略できる
```

そうすることこれは、このテスト（あるいは上位クラスの）toメソッドの呼び出し、ということがわかります。

## 親クラスにメソッド定義されてないけど？？

はいその通り。そこでGroovyのmethod missingという機能が使われれいます。
method missingとはメソッド呼び出しの際に、呼び出しメソッドが見つからなかった時（継承がある場合はその上位クラスも含む）に、最終的に専用のメソッドが呼び出される機能です。

method missingといえばRubyですが、Groovyにもなんと備わっています！ そのものズバリ `methodMissing`というメソッドが呼び出されます。

Groovyのmethod missingについてはこちらが参考になると思います。

- http://magazine.rubyist.net/?0037-GuestTalk#l7

## method missingを覗きにいこう

というわけで、methodMissingの中に何が書いてあるかを見に行きましょう。 
この場合は、テストケースの基底クラスである(GebSpecを見に行きます)

```groovy
class GebSpec extends Specification {
    Browser _browser

    Browser getBrowser() {
        if (_browser == null) {
            _browser = createBrowser()
        }
        _browser
    }

    def methodMissing(String name, args) {
        getBrowser()."$name"(*args)
    }
}
```

そう、プライベートメソッドだと思われた処理は、`getBrowser()`によって取得されたbrowserの同名メソッドを呼び出すようになっています。[^1]

ということで下記は等価なコードとなります。

```groovy
to GebishOrgHomePage

browser.to(GebishOrgHomePage)
```

このように暗黙での処理の委譲を通して、テストケースでは省略記法で書くことができます。
ちなみに、これを繰り返してもページオブジェクトのcontentに記載されたものをメソッド呼び出しすることはできないのですが、それはAST変換という別なテクニックが使われています。
それについては別な機会にしたいと思います。

# まとめ
Gebの簡潔な記述はGroovy（のmethod missing）のおかげ！


[^1]: https://github.com/geb/geb/blob/master/module/geb-spock/src/main/groovy/geb/spock/GebSpec.groovy から一部抜粋
Mac で Ansible 使ってたら SSH エージェントフォワーディングで詰まった話

# 結論

Mac 使ってて Ansible で SSH エージェントフォワーディング効かないときは `-c ssh` オプションつけるべし
[（teratail で教えていただきました）](https://teratail.com/questions/59571)

# 困っていたこと

Mac から　Linux マシンを Ansible で構築してたんだけどどうにもこうにも SSH エージェントフォワーディングがうまくいってなくて `git clone` とかそこら辺が全くできなかった。

```
fatal: [xxx.xxx.xxx.xxx]: FAILED! => {"changed": true, "cmd": ["ssh-add", "-l"], "delta": "0:00:00.004968", "end": "2016-12-21 11:44:41.814838", "failed": true, "invocation": {"module_args": {"_raw_params": "ssh-add -l", "_uses_shell": false, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 2, "start": "2016-12-21 11:44:41.809870", "stderr": "Could not open a connection to your authentication agent.", "stdout": "", "stdout_lines": [], "warnings": []}

```

# 原因

Mac で Ansible 使ってると SSH に openssl ではなく paramiko がデフォルトで使用されるため…らしい。
なお、環境は 

- Mac OSX 10.10
- Python 2.7.10
- Ansible 2.1.1.0

# 対策

ansible.cfg に設定を書いて実行

```bash
$ cat /etc/ansible/ansible.cfg
[defaults]
transport = ssh
# ↑これで -c ssh オプションをしているのと同義

[ssh_connection]
ssh_args = -o ForwardAgent=yes
# ↑ SSH エージェントフォワーディングを有効に
```

タスク

```yaml
---
- name: test ssh-agent
  command: ssh-add -l
  become: no
```

実行結果

```bash
{"changed": true, "cmd": ["ssh-add", "-l"], "delta": "0:00:00.023313", "end": "2016-12-22 12:11:02.230611", "invocation": {"module_args": {"_raw_params": "ssh-add -l", "_uses_shell": false, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}, "module_name": "command"}, "rc": 0, "start": "2016-12-22 12:11:02.207298", "stderr": "", "stdout": "2048 hogehoge (RSA)", "stdout_lines": ["2048 fugafuga (RSA)"], "warnings": []}

```

できた :tada:
C#でSelenium2を使用してUI自動テストツールを作成した際に感じたこと

# はじめに
[C#でSelenium2を使用して主要ブラウザを動かしてみた](http://qiita.com/whoshino/items/603d92f0560276558188)から結構時間が経過してしまいました。
今回はUI自動テストツールを作成した際に感じた事を記載してみたいと思います。

# どのようなものを作成したか
独自フォーマットのテストケースを作成し、
それを元に実行させて成功時、エラー時などスクリーンショットをとる。
また、失敗した祭にメッセージをチャットで通知する。
簡単に言ってしまえばSeleniumIDEを自前で作成してような形になります。
ちなみに開発環境はVisual Studio, C#です。

# SeleniumIDEとは何が違うのか
1. 独自のフォーマットのテストケースで記載できる
2. ひとつの実行ファイルで各ブラウザに対応できる
3. チャットツールとの連携
4. 各種カスタマイズが可能

# 作成後感じたこと(今回の主題)
1. クロスブラウザには対応したがWindowsに依存してしまった
2. テストケースを完全に独自仕様にしてしまった
3. ブラウザにより微妙にSelenium2の挙動が異なる
4. UIテストに頼りがちになってしまう
5. うまく周りを巻き込まないと破綻してしまう
6. なにが原因で失敗したかの原因が特定しずらい
7. 保守するのが難しい(後回しになってしまう)
8. 確認対象のサイトのつくりに問題が...

上記についてひとつひとつ見ていきます。

## クロスブラウザには対応したがWindowsに依存してしまった
いきなり大問題。
UIテストと言われるのだからマルチプラットフォームに対応すべき。
Windowsは自動でもMacでは結局ぽちぽちしないと行けないとか、、、

Xamarinで今は対応できるのかも。。。

## テストケースを完全に独自仕様にしてしまった
HTMLをある程度知っている人なら誰でも作成できるようにしたフォーマットで作成したものの、
テストケースを作る際はブラウザでDOMを探してひとつひとつ操作を記載する必要がありとにかく作成するのが大変。
つ、つらすぎた、、、

テストケース作成時はSeleniumIDEを利用してある程度フォーマットを合わせるのをおすすめします。

## ブラウザにより微妙にSelenium2の挙動が異なる
これは仕方ないのかもしれませんが、結構細かく問題になってくる。
テストツール作成時に気を付けないと結構はまります。うまく実装すれば回避できると思います。

ググれば問題の解決方法が出てくると思うので今回は細かくは触れません。

## UIテストに頼りがちになってしまう
UIテストでなんでも解決できると思う輩が出現する。
とにかくUIテストでカバーできると思う人がいる。
違います。向き不向きがあるので何でもカバーできるわけではありません。
必ず単体テスト等も必要です。

## うまく周りを巻き込まないと破綻してしまう
これは今回のことではなくすべてのことで言えると思います。
いくら自分が頑張ったとしても周りの人にも一緒になって動いてもらわないと確実に不可能です。
行ってくれるまで忍耐強く言い続けましょう。

## なにが原因で失敗したかの原因が特定しずらい
これも何かいい方法がないか模索中。
基本問題があった際にチェックするものがテストした際のスクショになるため原因特定する際は、
スクショ確認→自動テストツールのログ確認→該当のサイトのログ確認といった手順になりなかなか解決が難しい。
結局もう一度テストケースを実行してみたらうまく実行できるとかも結構あったりしました。

ある程度の予測はできるが結局もう一度実行してみてどこで失敗したかを追っていくということになってしまい、
案外時間がかかってしまいます。

## 保守するのが難しい(後回しになってしまう)
私の知る限りテストに時間を使えないプロジェクトが一般的と言うのもわかっております。
テスト時間がとれず、頻繁に仕様が変わるようなサイトでの運用はなかなか厳しいものがあるように感じます。

## 確認対象のサイトのつくりに問題が...
これは論外の話になってしまうかもしれませんが、いち画面にIDが複数あったりそもそもの問題です。
作成した人に勉強し直してくださいと忠告しましょう。うそです。
この問題を発見できたことを良しとして修正しましょう。

# まとめ
たしかにUIテストはとても便利で、当たり前の様に運用できる状態になればとても便利です。
ただ、やはり安定運用まで持っていくのはなかなか大変かと感じました。

また、個人的に感じた事は、UIテストとして目的を細い動作等のチェックは行わずに、
対象のサイトをクローリングしキャプチャを取得して、それは毎日チェックを行いレイアウト崩れ等の発見を目的に導入するのがいいと感じました。
Pythonistaが考えるLintの重要性

## はじめに

この記事は、[Lint Advent Calendar 2016](http://qiita.com/advent-calendar/2016/lint) 21日目の記事です。

## 誰が書いても同じコード

前提として、メンテナンス性の高いコードにするために「誰が書いても同じ」ようにすることが大事だと考えています。
これに関しては昔から「幻想だ」「そんなことは大事ではない」など色々な批判がありますが、「Zen of Python」を守るPythonistaはこだわっていきたいところです。

```
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
```

## Style Guide

「誰が書いても同じコード」にするためには、チームでStyle Guideを決める必要があります。
PythonにはStyle Guideである[PEP8](https://www.python.org/dev/peps/pep-0008/)があるので、これをベースにして各々が状況に応じてカスタマイズしていくとよいです。

[Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)なども参考になります。

## コードレビュー
「Style Guide」が決まれば、それをコードレビュー時に適用できます。
ただコードレビューでは「シングルクオートに統一してください」「importの順番を整えてえてください」などに時間をかけるのではなく、もっとより本質的な議論をすべきです。

これに関してnaoyaさんがちょっと昔にブログで語っていました。
[些末なコードレビュー - naoyaのはてなダイアリー](http://d.hatena.ne.jp/naoya/20140313/1394664578)

> コードレビューに慣れないチームが、何の考えもナシにコードレビューを始めるととにかく気になったこと大小様々な指摘が行われることになる。一見、いろいろな指摘が出て議論が活発になっているように見えるが、だいたい議論が紛糾しているのは「コードのインデント幅が違う」とか「return が省略されてる。俺は return があったほうが好み」とか「その場合は字下げをした方が綺麗にみえるんでは」とか、そんな些末なことばかりである、ということが多い。必ず一度は通る道である。

> そんなことを延々議論していたって、はっきり言って何の意味もない。何の意味もない、は言い過ぎにしても、そんなところを改善したところで実質的な品質は何ひとつ上がらないわけだし、どうしても揃えたいなら lint ツールか何かで機械的にチェックすればよいことであって人間がやることではない。

> やらなければいけないのは、「その設計は拡張に対して開いていないから開くべき」とか「これではエッジケースが想定されていないからこういう不具合につながるのでは」とか「そのテストでは後日見返したときに第三者が要求仕様を解釈しづらい」とかそういう指摘である。これらはちゃんとコードを読んで、コードの構造を把握して、そこに書かれているコード以外のシステムの全体感が頭に入っていて、初めてできる指摘である。

ここで大事になのは、

+ Style GuideによるチェックなどのLintは機械がやる
+ それ以外のコードレビューは人間がやる

という分業です。
人間が使える時間は有限なので、できることは自動化していきましょう。

## Lintツール

PythonにおけるLintツール(`flake8`や`pylint`)については、以下の資料を読むと理解が深まるのでお薦めです。
[リファクタリングツールあれこれ](http://tell-k.github.io/pyconjp2014/)

ここでは普段業務で使っているものを紹介しておこうと思います。

+ [flake8](https://pypi.python.org/pypi/flake8)
+ [flake8-coding](https://pypi.python.org/pypi/flake8-coding)
+ [flake8-commas](https://pypi.python.org/pypi/flake8-commas)
+ [flake8-isort](https://pypi.python.org/pypi/flake8-isort)
+ [flake8-pep3101](https://pypi.python.org/pypi/flake8-pep3101/0.2)
+ [flake8-quotes](https://pypi.python.org/pypi/flake8-quotes/0.8.1)
+ [pep8-naming](https://pypi.python.org/pypi/pep8-naming)

## おわりに

「Zen of Python」にある

+ Readability counts.
+ There should be one-- and preferably only one --obvious way to do it.

の精神を実践していくために、Lintをうまく活用していきましょう。
【Good By エクセル】 csvをテーブルに変換するためのsqlを生成するpython script

## さよならexecel
僕はエクセルというアプリケーションが嫌いです。

1万行とかのcsvをエクセルに読みこんで、フィルターかけたり、関数をドラッグしてコピーしたりめんどくさいことみんな結構やるじゃないですか。
ロード時間なんか、日がくれんじゃねぇかってくらい時間かかる時あるし、macだとヌルヌル動かないし、そんなんでフリーズしてくれた日には、もうやる気なくして早退も辞さないわけですね。

あんなん発狂しますよ！！！

エンジニアなら、csv importからのデーター加工・抽出からのexportからのftpサーバーアップロードまで全部コマンドだけで終わらせたい！
エクセルなんて邪道 of 邪道！
信頼すべきデーターベースゥー！！！

要は、csvからcreate table文を作成して、load dataまで一括までするスクリプトさえあればもう、エクセルなんて、お別れwithout even saying goodbyですよ。
そんなpython scriptが本日のテーマどす。

## 解説
pythonにはcsv_to_tableというcsvから型を推測し、一行目のヘッダー部分をカラム名としてcreate table文作ってくれるpipがあるので、この機能に、load data文までの作成機能を加えたscriptを今回作りました。

使い方はgithubにまんま書いたのでそのまんま実行してくださいw

https://github.com/ShusukeOtani/table_stmt_generator_from_csv

```shell:gitclone
git clone https://github.com/ShusukeOtani/table_stmt_generator_from_csv
```
pipとpyenvをinstallして、python2.7.1で実行してください。


```shell:依存pipインストール
pip install -r requirements.txt
```

オプション引数には -dと-tと-pを用意してます。
-dはデータベースのタイプを判定するためのオプションです。
-d mならmysql, -d pならpostgreです。デフォルト値はmysqlです。
-tはTempテーブルにするか否かのboolです。カットした場合はpermamentテーブルにします。

-pでは主キーを指定できます。
-p idならカラムidがPKとなります。

例を書いておきます。
まずは主キーなし、permamentテーブル、mysqlならoptionはいらないので、単純にcsvのfile pathを指定してください。

```shell:exmaple1
python execute.py ./example/test.csv
```

```sql:result1
DROP TABLE IF EXISTS table_stmt_generator_from; CREATE TABLE table_stmt_generator_from (
	id smallint,
	pref text
);LOAD DATA LOCAL INFILE '/Users/200302/table_stmt_generator_from_csv/example/test.csv' INTO TABLE table_stmt_generator_from FIELDS TERMINATED BY ','  IGNORE 1 LINES;

```


postgre、tempテーブルかつ pkにidというカラムを使いたいなら、以下のoptionを加えてください。

```sql:example2
`python execute.py -d p -t -p id ./example/test.csv  
```

```sql:result2
DROP TABLE IF EXISTS test; CREATE TEMPORARY TABLE test (
	id smallint,
	pref text
, PRIMARY KEY(id));COPY test FROM '/Users/200302/table_stmt_generator_from_csv/example/test.csv' CSV HEADER;
```

## 後日談
広告の仕事の一つにフィード作成というものがあります。
CriteoやIndeedといったベンダーに対してそれぞれ最適化された案件リストのフィードを作成するわけですが、
複数のDBを見に行く場合JOINできないんですよね。
この課題解決のためにこのscriptを書きました。
実際の運用では、このscript使って下記の一連を行うapplicationにしています。

1.それぞれのDBでselect文を発行する。
2.結果をcsvとしてexportする。
3.このscriptを使ってローカルのDBにcsvをimportして、テーブルを生成する。
4.ローカルDBでJOIN して最終的なフィードデータを生成する。
5.フィードデータをftpサーバーにアップロードする。
[覚書]ServerlessフレームワークをTypeScriptで書くためのテンプレート


タイトルどおり、ServerlessフレームワークをTypeScriptで書くためのテンプレートを作って[GitHub](https://github.com/JunSuzukiJapan/sls-ts-template)にあげといたのでメモ。

# 使い方

>あらかじめAWS Lambdaの設定などはしておくこと。
>設定に関しては、[Serverless FrameworkでLINE BOTが簡単にできちゃった](http://qiita.com/narikei/items/8c6cd9e05621dcd444e5)あたりを参照のこと。

```shell:bash
$ git clone https://github.com/JunSuzukiJapan/sls-ts-template.git
$ npm install
```

としたら、src/serverless.ymlの中の

```
service: sls-ts-template
```

という行を

```
service: 自分のプロジェクト名
```

に変更しておく。

あとは、

```
$ make build
```

でビルド。

```
$ make local
```

でローカル環境でのテストを行う。

デプロイは

```
$ make deploy
```

# 参考

[Serverless+TypeScriptの開発環境を作る](http://qiita.com/shundy/items/4d14dabc3f874e1a52aa)

# 補足：npmのモジュールを実行時に読み込むためには

src/ディレクトリで、パッケージをインストールする必要があります。
（.zipで固めるときに一緒にパックする必要があるため）。

具体的には、

```
$ cd src; npm install --save パッケージ名
```
メンバ変数へのポインタを利用して型の特性を判定する

# メンバ変数へのポインタとは

まず、例として単に整数をラッピングしたクラスを考えてみます。

```cpp
class int_wrapper {
public:
  int data;
  int_wrapper(int data) : data(data) {}
};
```

このとき、 `int_wrapper::data` へのポインタ `p` は

```cpp
int int_wrapper::*p=&int_wrapper::data;
```

と書くことが出来ます。 `p` に入れられるのは `int_wrapper` クラス内の `int` 型のメンバ変数へのアドレスです。 オブジェクトではなくクラスで書いていることからわかると思いますが、 `p` が指しているのはメモリ上の具体的な場所ではなく、相対的なものです。 実質的にオフセットであると考えてよいでしょう。

参照するときはどのオブジェクトの `p` なのかとセットで書く必要があります。 以下のような要領です。

```cpp
#include <iostream>

int main(void) {
  int_wrapper foo(3);
  int int_wrapper::*p=&int_wrapper::data;
  std::cout << foo.*p << std::endl;
}
```

因みに、メンバ変数だけでなくメンバ関数でも同じような記法で扱えます。 (C++ に慣れた人であれば、メンバ変数へのポインタとメンバ関数へのポインタとは若干異なる仕組みであることは容易に想像できると思うので、ここでは触れません。)

# 存在しない型へのポインタ

メンバ変数へのポインタについては、対象となるクラスに該当する型のメンバが存在しなくても定義することが出来ます。 たとえば、上述の例では `int_wrapper` には `double` 型のメンバ変数は存在しませんが、

```cpp
double int_wrapper::*q;
```

という風に変数 `q` を作っても問題ありません。 もちろん該当するメンバ変数が存在しないのですから、キャストせずに変数 `q` へ入れられるのはヌルポインタだけですが。

# 存在しない型をどう使う？

存在しない型を指すポインタは文法の一貫性によってたまたま出来てしまったものだと思いますが、テンプレートに制約をつける用途に使えます。

以下のテンプレートは、テンプレート引数としてクラスしか渡せません。

```cpp
template<class T>
class class_wrapper {
private:
  typedef int T::*dummy;
public:
  T data;
  class_wrapper(T obj) : data(obj) {}
};
```

クラス `T` が `int` 型のメンバを持っていようがいまいが `int T::*` 型が存在することは許されますが、 `T` がクラスでなければメンバを持ち得ないのでエラーになります。

試してみましょう。

```cpp
int main(void) {
  int_wrapper foo(3);
  class_wrapper<int_wrapper> bar(foo);  // int_wrapper はクラスなので OK
  class_wrapper<int> baz(5);            // int はクラスではないので NG
  return 0;
}
```

# 過去、現代、未来の C++

この記事で紹介した技法はもはや過去のものです。 過去において機能の足りない C++ でどのように制約を表現していたかという歴史の一端を紹介したものでしかありません。

C++11 以降では `type_traits` にある `is_class` を使えば上記のような制約を表現できます。 `is_class` の方が何を表現しようとしているのか名前からわかりやすいのでより望ましい方法だと言えるでしょう。

テンプレートは様々な型に対して共通の機能を与える有用な機能ではありますが、必ずしもどんな型でも受け入れられるとは限りません。 想定した性質を持っていないのであればエラーにしたいという要求は当初からあり、どうやって__制約__を表現するのかはずっと議論されてきました。 制約を表現するための専用の機能である「コンセプト」は長く協議されながらも論争に決着が付かず、なかなか導入に至っていません。

# 制約の重要性

プログラムを書いたなら、それに対するテストを書くかもしれません。 正しい結果が得られるかどうかを確かめるのは大切なことです。

しかし一方では「動いて欲しくない場合」を想定するのも重要です。 特に汎用的なライブラリは作者が考えていたのとは全く違うような、思いもよらない使い方をされるかもしれません。 また、規模がある程度大きくなってくると自分自身でさえもそれほど信用できなくなってきます。

想定外の使われ方をしたときにコンパイルエラーになるというのはバグを抑止するためには有用です。
Talend ESB で REST/SOAP を扱う際のポイント

Talend (Open Studio利用) for ESB で REST や SOAP のサービスを構築した際に、色々と慣れるまでに苦労した点を、つらつらと記録します。

# 1. REST
## 1-1. tRESTRequest のエンドポイントには相対パス

Getting Started Guide でも Components Reference Guide でも、tRESTRequest を使ったサンプルではエンドポイントを `http://[IP/Domain]:[Port]/[ServiceName]`  のような形で指定している。
だがそうすると、Studio での実行時は問題ないが、Talend Runtime 環境に持ってゆくとデプロイに失敗する。
（trun -> list すると `Failure` と表示される。refresh してもダメ。）

ではどうするか。

エンドポイントには `/[ServiceName]` とだけ指定すればよい。
環境に応じて次のようにデプロイされる。
（ポート番号は標準設定の場合のもの。）

|実行環境|URL|
|:-----------|:------------|
|Studio|`http://localhost:8090/[ServiceName]`|
|Talend Runtime| `http://[IP/Domain]:8040/services/[ServiceName]`|


---
## 1-2. OSGIビルド時のコンテキスト切替

ビルド時に "自律実行ジョブ" が選択されていると、コンテキストスクリプトの切り替えオプションが画面に表示されるので問題ないが、"OSGIバンドル (ESB)" を選択するとこのオプションが消える。

ではどうするか。

例えばジョブ名が MyRESTService で、コンテキストに Default と Prod の２つが用意され、本番は Prod で運用したい場合には、デプロイ先サーバの "[TalendRuntimePath]/container/etc/" ディレクトリに、"MyRESTService.cfg" というテキストファイルを作成し、中に次の１行を記載すればよい。

```cfg:[TalendRuntimePath]/container/etc/MyRESTService.cfg
context = Prod
```


---
# 2. SOAP

## 2-1. tESBConsumer で SOAP ログを確認

tESBConsumer の "Log messages（ログメッセージ）" オプションをオンにすると、実際にやりとりした Outbound と Inboud のメッセージがログに出力される。
だがいつの頃から、このオプションが効かなくなった。（TOS_ESB v6.3.0 で確認。）

ではどうするか。

"File（ファイル）" -> "Edit Project Properties（プロジェクトプロパティの編集）" -> "Log4j" の順に開いて、次の設定をテンプレートに加えてやればよい。

```xml
<logger name="org.apache.cxf.services">
	<level value="INFO" />
	<appender-ref ref="CONSOLE" />
</logger>
```

参考: [source4code.info: JAX-WS - CXF logging request and response SOAP messages using Log4j](http://www.source4code.info/2015/01/jaxws-cxf-logging-request-response-soap-messages-log4j.html "source4code.info")

---
## 2-2. REST/SOAP 同居

REST と SOAP の２つの入り口を設け、内部処理は同じもの、返す値も同じものとしたい場合。
REST は普通にジョブ作成から始まり .jar ファイルが生成される。
SOAP はサービス作成から始まり .kar ファイルが生成される。
つまり一つのジョブに２つの入り口は設けられそうにない。

ではどうするか。

実際の処理は別ジョブで作成し、tRunJob で連携させればよい。
メンテナンス性も向上するし、いいことづくめ。

```
1. REST入口ジョブ：　tRESTRequest -> tFlowToIterate -> tRunJob(3.へ) -> tRESTResponse
2. SOAP入口ジョブ：　tESBProviderRequest -> tXMLMap -> tRunJob(3.へ) -> tXMLMap(WSDLに合わせる) -> tESBProviderResponse
3. 実際の処理ジョブ:　(contextで引数受け取り) -> (実際の処理やエラー処理) -> tXMLMap -> tBufferOutput
```

---
（以上）
CuratorでElasticsearchを減量

Elasticsearchが重い。
PCのメモリがしょぼい。
もうこのデータ(index)見てない。

そんなあなたへ。
#事前に準備する環境
Elasticsearch 5.0.1(5.0.0でも同様)
Python 2.7.10(2.7.6でも同様)

#やること
まずpipが入ってない方は、

```
$ curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python
```
Curatorのインストール

```
$ sudo pip install elasticsearch-curator
$ curator --version
curator, version 4.2.4
```
Elasticsearchが5.xの場合、curatorは4.x以上が必要だそうです。
#Curatorに必要なファイル
２つあります
##Configuration file
```~/.curator/curator.yml
client:
  hosts:
    - localhost
  port: 9200
  url_prefix:
  use_ssl: False
  certificate:
  client_cert:
  client_key:
  ssl_no_validate: False
  http_auth:
# if x-pack is installed, set "http_auth: elastic:changeme"
  timeout: 30
  master_only: False

logging:
  loglevel: INFO
  logfile:
  logformat: default
  blacklist: ['elasticsearch', 'urllib3']
```
##ACTION_FILE
```action_file
actions:
  1:
    action: delete_indices
    description: >-
      (custommessage)Delete indices older than 5 days (based on index name), for .monitoring-es-
      prefixed indices. Ignore the error if the filter does not result in an
      actionable list of indices (ignore_empty_list) and exit cleanly.(custom message)
    options:
      ignore_empty_list: True
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: .monitoring-es-
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 5
      exclude:
  2:
    action: close
    description: >-
      (custom message)Close indices older than 4 days (based on index name), for .monitoring-es-
      prefixed indices.(custom message)
    options:
      ignore_empty_list: True
      delete_aliases: False
      timeout_override:
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: .monitoring-es-
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m.%d'
      unit: days
      unit_count: 4
      exclude:
```
これは、４日以上前のindexをクローズして、5日以上前のindexを削除してます。
`ignore_empty_list: True`でもし該当indexが見つからない時のエラーをスルーできます。
（付けないと、2回以上連続して実行した時にエラーで止まってしまいます。）
unit_countですが、4とすると4日前のデータも削除します。indexの%dが基準のようです。

#実行
Configuration fileをデフォルトのパス（~/.curator/curator.yml）で作った場合

```
$ curator ${action_file}
```
じゃない場合

```
$ curator --config ${configuration_file} ${action_file}
```

あとはこれを気が向いた時に手動で走らせるか、ご自宅のjenkinsおじさんで日次実行させてあげてください。
※簡単なことしかしてません。もっと機能は豊富にあるので[公式ドキュメント](https://www.elastic.co/guide/en/elasticsearch/client/curator/current/)へどうぞ。
C#で任意のサイトの情報を抜き取る - ウェブスクレイピングはじめの一歩

# やりたいこと
- 任意のサイトから特定の情報を抜き出したい

[以下、2016/12/23追記]
***
ただし、こちらの記事[Jsoupで簡単ウェブスクレイピング](http://qiita.com/keigohtr/items/c8e8c0fabfb02ea2aefe)で次のように注意している通り、気をつけなくてはいけませんよね。
>注意事項：スクレイピングの可否は先方の規約に依存します。例えば、Amazonのようにスクレイピングを禁止しているサイトへのスクレイピングは禁止です。場合によっては法的な措置を取られますのでルールはちゃんと守りましょう。

<font color=red><b>すみません、自分はこちらを読むまで意識が低かったです。</b></font>
あわてて調べてみましたが、一応それらしい情報が見つけられなかったので、進めていきます。
***

# 背景
YouTubeやニコニコ動画での投稿をはじめましたが、ニコニコ動画での動画情報の編集が気に入らない。また、将来的にYouTubeやニコニコ動画の動画説明などを同期したり、テンプレートを活用するなどしたい

# 実装

ソースコード全体です。

```csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RniconicoEditor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void fileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate("http://www.nicovideo.jp/my/video");
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            System.Diagnostics.Debug.Print(e.Url.ToString());

            if (e.Url.Equals("http://www.nicovideo.jp/my/video"))
            {
                HtmlElement el = webBrowser1.Document.GetElementById("video").Children[5];
                for (int i = 1; i < el.Children.Count; i++)
                {
                    HtmlElement elm = el.Children[i].Children[1].Children[0].Children[0];
                    if (elm != null)
                    {
                        string key = elm.GetAttribute("href").Replace("http://www.nicovideo.jp/watch/", "");
                        treeView1.Nodes.Add(key, elm.InnerText).Tag = key.Replace("sm", "");
                    }
                }
            }
            else if (0 <= e.Url.ToString().IndexOf("http://www.upload.nicovideo.jp/edit?f="))
            {
                textBox1.Text = webBrowser1.Document.GetElementById("movie_title").GetAttribute("value");
                textBox2.Text = webBrowser1.Document.GetElementById("movie_detail").OuterText;
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            webBrowser1.Navigate($"http://www.upload.nicovideo.jp/edit?f={e.Node.Tag}");
        }
    }
}
```
# 元となっている記事
- （はてなブログ）[C#で任意のサイトの情報を抜き取る - ウェブスクレイピングはじめの一歩](http://rrryutaro.hatenablog.com/entry/2016/12/22/110643)

# 関連記事
- [C#でニコニコ動画の動画説明文を編集できるようにする](http://qiita.com/rrryutaro/items/adff7860531a42ba03d0)

以上
ニューラルガスを可視化してみた（2）

[前回](http://qiita.com/n-suzuki/items/3e36a22e0f0cb75257e0)投稿できなかった、デモの結果です。

デモ用のテストデータは、[こちら](http://www.brain.kyutech.ac.jp/~furukawa/data/ng.html)[^1]のページを参考に作成しました。
デモでは、入力データとして二次元の点集合を与えています。
パラメータは以下の通りです。

| パラメータ | 数値 |
|:-:|:-:|
| $N$  | 50  |
| $t_{max}$  | 300  |
| $\lambda_{ini}$  | 7.0  |
| $\lambda_{fin}$  | 0.05  |

学習過程をGIFアニメにしたものを以下に掲載します。
青い点が入力データ、赤い☆印が重みベクトルとなります。
[GitHub](https://github.com/s-naoto/Batch_Neural_Gas)には、ニューラルガスのコードに加えて、入力データを生成するモジュールも置いてあります。

[^1]: 九州工業大学 大学院 生命体工学研究科 人間知能システム工学専攻 古川研究室 (http://www.brain.kyutech.ac.jp/~furukawa/myresearch.html)

![gaussian.gif](https://qiita-image-store.s3.amazonaws.com/0/104903/a758d863-4602-9a30-d2d5-3330a911c14b.gif)

![rings.gif](https://qiita-image-store.s3.amazonaws.com/0/104903/76122245-3758-a3f3-d4c3-515c7c676c08.gif)

![rectangle.gif](https://qiita-image-store.s3.amazonaws.com/0/104903/148c0d22-fc8b-9ef2-3b34-4c648f9e2b32.gif)

![2circles.gif](https://qiita-image-store.s3.amazonaws.com/0/104903/9ed4f1c2-0157-c442-1ac4-df945b537043.gif)

重みベクトルが特徴的な動きをしながら、入力データに沿って均等に広がっている様子がわかると思います。
AmazonSNSへのサーバサイドからの端末紐付け(python+boto3)

# 課題
SNSに対しtopicに端末を紐付けたい場合、スマートフォン端末からsdkを使ってSNSに直接アクセスという事例はあるのですが、今後のこと(tokenをdynamoDB側でも管理するとかの後付け対応)を考えてサーバサイド側でやろうとしたところ意外と事例が少なかったのでまとめました。

今回push通知対象はスマートフォンなのでその前提の話になっています。
また実装はLambdaでやっていますがLambda依存にはなっていないと思います。

# 概要

```handler.py
import boto3

def lambda_handler(event, context):

    application_arn = 'arn:aws:sns:us-east-1:999999999999:notify_sample'
    topic_arn       = 'arn:aws:sns:us-east-1:999999999999:notify_sample'

    endpoint = add_endpoint(application_arn, token)
    subscribe_token(topic_arn, endpoint['EndpointArn'], is_subscribe)
```

大雑把な手順は
1. Applicationにendpointを登録する
2. TopicにendpointをSubscribeする

となります。ここで登場するApplication,TopicのARNは事前にAWS側のダッシュボードを使って登録・取得しておいてください。

# Applicationにendpointを登録する

```handler.py
def add_endpoint(application_arn, token):
    # token(boto3 doc抜粋) :
    # For example, when using APNS as the notification service, you need the device token.
    # Alternatively, when using GCM or ADM, the device token equivalent is called the registration ID.

    client = boto3.client('sns')
    endpoint = client.create_platform_endpoint(
        PlatformApplicationArn=application_arn,
        Token=token
    )

    return endpoint
```

ここは追加済みであっても呼び出します。tokenはAPNSもしくはFCM(GCM)から取得するtokenです。
create_platform_endpoint()はendpoint追加済みの場合新規追加をおこなう事なく既存のendpointの情報を返します。いずれにしてもendpoint情報が取得できるので、この情報を元にsubscribeを実施します。

> The CreatePlatformEndpoint action is idempotent, so if the requester already owns an endpoint with the same device token and attributes, that endpoint's ARN is returned without creating a new endpoint. 

# TopicにendpointをSubscribeする
ここで多少面倒な処理をしています。

subscribeは単純にsubscribe()実行すれば良いのですが、unsubscribeの場合対象端末のSubscriptionArnが必要になります。
今回は一度subscribe()を実行してSubscriptionArnを取得し、それを使ってunsubscribe()実行する、という事をやっています。

```handler.py
def subscribe_token(topic_arn, endpoint_arn, is_subscribe):

    client = boto3.client('sns')
    subscription = client.subscribe(
        TopicArn=topic_arn,
        Protocol='application',
        Endpoint=endpoint_arn
    )
    if not is_subscribe:
        client.unsubscribe(
            SubscriptionArn=subscription['SubscriptionArn']
        )

```

# 疑問点
最後のSubscriptionArnの取得方法なのですが、マニュアルを眺めてみてもこれくらいしか良さげな方法が見つかりません。
適切な方法がありましたらご指摘ください。

# 追試
実行時ちょっと釈然としないエラーが出たためboto3マニュアルを見直しコードを見直したのですが、多分以下のように書いた方が素直、だと思います。
しかし書き直してもエラーは改善しなかったので、やはりclientはlow-level clientなんだなーと思っています。

```handler.py
def add_endpoint(dry_run, application_arn, token):

    sns = boto3.resource('sns')
    platform_application = sns.PlatformApplication(application_arn)
    endpoint = platform_application.create_platform_endpoint(
        Token=token
    )
    return endpoint.arn


def subscribe_token(dry_run, topic_arn, endpoint_arn, is_subscribe):

    sns = boto3.resource('sns')
    topic = sns.Topic(topic_arn)
    subscription = topic.subscribe(
        TopicArn=topic_arn,
        Protocol='application',
        Endpoint=endpoint_arn
    )
    if not is_subscribe:
        subscription.delete()
```
PHPの例外って

PHPの例外、特に`finally`が思った通り[^ref]に動作する。
すてき。

```bash:環境情報
$ php -v
PHP 5.6.29 (cli) (built: Dec  9 2016 07:03:56)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
```

```php:さんぷるこーど
<?php
error_reporting( -1 ) ;

echo call_user_func( function ($human) {
	try{
		throw new Exception('( ﾟ∀ﾟ)') ; // (1)
	}
	catch ( \Exception $e ) {
		echo $e->getMessage() ; // (2)
		return '(ﾟ∀ﾟ )' ; // (4)
	}
	finally {
		echo $human ; // (3)
	}
}, '人') . PHP_EOL ;

//=> ( ﾟ∀ﾟ)人(ﾟ∀ﾟ )
```

## 参考と注釈

* [PHPとPythonのfinallyとexitの関係の違い - Qiita](http://qiita.com/khsk/items/4f8d4405f2f2ca2853ae)
* [例外(exceptions)](http://php.net/manual/ja/language.exceptions.php)


[^ref]:  PHP 5.5 以降では、catch ブロックの後に finally ブロックも指定できるようになりました。 finally ブロックの何かに書いたコードは、 try および catch ブロックの後で常に実行されます。例外がスローさされたかどうかには関係ありません。
oracleからjdkなどをcliで入手するためのやり方

oracleからjdkなどをcliで入手するためのコマンド。
忘れたころに必要になるのでメモ。（調べたら同様の記事がありました... ）

`wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie"  http://download.oracle.com/otn-pub/java/jdk/8u112-b15/jdk-8u112-linux-x64.rpm`

webサイトから入手するときはこの辺から
http://www.oracle.com/technetwork/java/javase/downloads/index.html

# 参考サイト

* http://www.task-notes.com/entry/20150602/1433214000
* [Linuxでjdkをwgetする方法](http://qiita.com/hajimeni/items/67d9e9b0d169bf68d1c9)
WRF > link > a typical number for the spin-up time

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
```

WRF(Weather Research and Forecasting Model)関連。

http://www2.mmm.ucar.edu/wrf/users/FAQ_files/FAQ_wrf_physics.html
の
Miscellaneous Questions > Q7
> Q7. Is there a typical number for the spin-up time or does it change from case to case?

> A7. Typically the model requires anywhere between 6-12 hours to fully spin up. It will depend on the grid distances and time steps. The finer the grid size, the more time steps you would have in a given time window, hence faster spin-up. You may calculate the kinetic energy spectra at various model times to see how the model spins up (see Skamarock, W. C., 2004: Evaluating mesoscale NWP models using kinetic energy spectra. Mon. Wea. Rev., 132, 3019-3032). You may also compute d(surface pressure)/dt to see how the values settle down in time by turning on the option diag_print. One way to shorten the spin up time is to use digital filter initialization.

意訳「Q7. spin-up timeに典型的な設定値はありますか? もしくは場合により異なりますか?」

意訳「A7. 完全にspin upするには、典型的な値として6から12時間は必要です。grid distances とtime stepsに依存します。grid sizeを詳細にする場合、より多くのタイムステップを持つことになり、spin-upは早くなります。モデルがどのようにspin upするか計算できます。d(surface pressure)/dtを計算して、値がどのように落ち着くかも見れます。その場合はdiag_printオプションをオンにしましょう。spin upを短縮する１つの方法はdigital filter initializationを使うことです。」


以下はgoogle翻訳
> 
典型的には、モデルは完全にスピンアップするために6〜12時間の間の任意の場所を必要とする。グリッドの距離と時間ステップに依存します。グリッドサイズが細かいほど、指定された時間ウィンドウでより多くの時間ステップが得られるため、スピンアップが高速になります。モデルがどのようにスピンアップするかを見るために、さまざまなモデル時間に運動エネルギースペクトルを計算することができます（Skamarock、W. C.、2004：運動エネルギースペクトルを使ったメソスケールNWPモデルの評価、Mon. Wea。Rev.、132、3019-3032）。 diag_printオプションをオンにすると、d（面圧）/ dtを計算して値が時間どおりにどのように収まるかを確認することもできます。スピンアップ時間を短縮する1つの方法は、デジタルフィルタ初期化を使用することです。
redmine-slack プラグインを使ってみたメモ

gitlab から slack への通知がとても便利なので、同じようなことを redmine でもやりたいなと思い、redmine-slack というプラグインを試してみた。

* [sciyoshi/redmine-slack: Slack notification plugin for Redmine](https://github.com/sciyoshi/redmine-slack)

## インストール方法

```
cd /your/redmine/app/
git clone https://github.com/sciyoshi/redmine-slack.git plugins/redmine_slack
bundle install
# Redmine アプリケーションを再起動
```

## 基本的な設定方法

1. Slack へ自分のユーザーでログイン
    2. チャンネルに Incoming Webhook インテグレーションを追加
    3. 発行された Webhook 用の URL をメモしておく
1. Redmine に管理権限を持つユーザーでログイン
    1. 「管理 -> プラグイン -> Redmine Slack」を開く
    2. Slack URL に上記で発行した Webhook 用の URL を入力
    3. Slack Channel に通知を送りたいチャンネルの名前を入力 (例: `#general`)
    4. 「適用」をクリック

![](https://i.gyazo.com/32c87645ba73ea6e6fe4d0132763726d.png)

ここまでやると、その Redmine の全プロジェクトでチケットに更新があったときや Wiki に更新があったときに、指定した Slack チャンネルへ通知が行われる。

![](https://i.gyazo.com/465e241afc6231fd9546e35ba7a0c400.png)

## プロジェクト毎に通知先のチャンネルを設定する

複数のチームがそれぞれ複数のプロジェクトを作成して利用しているような、中規模～大規模な利用の場合、上記のように 1 つのチャンネルにすべてのプロジェクトの更新が通知されてしまうと困る。

プロジェクト毎に通知先チャンネルを変えるには、Redmine のカスタムフィールド機能を利用して、プロジェクト毎に通知先チャンネル情報が付与できるようにする。こんな感じ。

![](https://i.gyazo.com/9059cb57b62075f147e0d9616265b161.png)

名前以外はデフォルトで大丈夫だった。上記のようにカスタムフィールドを作成すると、各プロジェクトの設定で Slack Channel という項目に通知先チャンネルを設定することができる。

![](https://i.gyazo.com/8dd9c90c8adf8938922f916c7d1af33a.png)

ちなみに、「管理 -> プラグイン -> Redmine Slack」の Slack Channel を "-" (通知しない) に設定しておくと、「デフォルトでは Slack 通知されず、プロジェクトの設定で Slack Channel を指定したときだけ通知される」という利用者にとって自然な挙動を実現することができた。

## その他

プロジェクト毎に「チケットの更新を通知するかどうか」「Wiki の更新を通知するかどうか」をカスタマイズできないのがやや不便な感じ。
2017ウェブトレンド

2016年、ミニマリストとフラットデザインがウェブの世界を支配した。
2016年もそろそろ終わりに近づき、2017年にどんなデザイントレンドがウェブの世界を支配するのが気になり、色々な記事を読むことにした。

そのトレンドに関する記事を共有したいと思います。

#1. Parallax Effects
近年、フラットデザインが最も使われたデザインであった。
一方で、2年前にGoogleがMaterial Designを紹介してから、深みがあるフラットデザインがよく使用されるように変化して来た。
そんな中、Parallax Scrollingは背景画像を前景画像よりも遅く動かすことで、深みの錯覚を作り出すデザインであることから注目されている。これは、主にコンピュータグラフィックスで使用されており、Webデザインの世界のトレンドになりつつある。
http://www.awwwards.com/websites/parallax/

#2. More Focus on Animation
GIFは、静止画の代わりにウェブサイトの中で特定の何かを目立たせるために使用されている。例えば、ベストセラーの商品を注目させるためなどである。
一方で、GIFを多用するとウェブサイトを乱雑にするだけでなく、ユーザーを混乱させることになりかねない。この問題を、cinemagraphを利用することで解決できる。
Cinemagraphは、画像とビデオのクロスオーバーで、微妙な動きがあり、ウェブサイトに人生を与えることができるのだ。 
GIF形式で提供される。
http://www.hongkiat.com/blog/cinemagraph/

#3. Big Bold Typography
近年、大きいタイポグラフィがよく使われている。以前タイポグラフィのルールは非常に厳しいものでしたが、現在ではウェブデザイナーの多くがタイポグラフィを使い自由に創造性を発揮している。
「大きく」と「太字」は必ずしもフォントの重厚さを指すとは限りません！
むしろ、「単一」で「シンプル」でありながらウェブサイト全体を包括的に捉えることが可能なステートメントに専念させることが重要である。
これらのステートメントは、一目見て明らかであり、メインメッセージを分かりやすくユーザに伝えることが可能である。

#4. Go Edgy, Use Bright Colors
ミニマリストとフラットなデザインの傾向は、しばらくの間継続し、すぐにこのトレンドが去ることはないであろう。
しかし、ウェブ世界のトレンドには、ポップなカラーが登場してくることが考えられる。
なぜなら、ミニマリズムの動きが広まった時、デザイナーは、シンプルなデザインを創ることを余儀なくされた。そんなトレンドの中、個性を活かしたデザイン作業を創造する方法を模索しているからだ。
今では、カラフルで明るい色のデザインが戻りつつある。 しかし、このトレンドがあなたのビジネスのアイデンティティと一致するかどうかを判断することが重要だ。

#5．Layouts that let the Contents Shine
ビジネスにおけるデザインの役割は、大きな変化があった。以前、デザインは開発全体のうち、後期の段階でしか考えられていなかった。
しかし最近では、デザインでコンテンツをどうやって見せるのかが重要になってきた。
世界中のデザイナーは、ユーザがコンテンツのためにウェブサイトを訪れることに気づき始めたからだ。これからは、コンテンツがもっとも分かりやすく伝わるレイアウトやデザインを考えることに注力していく必要がありそうだ。

#6. Complex Layouts
FlexboxとCSS Grid(来年3月)が登場するため、Webデザインのレイアウトは、CSSの制限を受けなくなった。
Flexboxは比較的新しい「CSS」レイアウトモジュールでありながら、機能性も優れており、驚異的なレスポンスを実現している。
これを使うことで、ページレイアウトが異なる画面サイズと異なる表示デバイスに対応しなければならないときに、要素を予測し最適化を行うことが可能だ。
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
CSS Gridはレイアウトの問題を解決するために特別に作成された最初のCSSモジュールである。
https://css-tricks.com/snippets/css/complete-guide-grid/
レスポンシブデザインでこれらの新しいレイアウト方法がどのように機能するかを理解すべきだ。
特にFlexboxとGridをどのように併用可能かを理解しなければならないだろう。

#7. More SVGs over Traditional JPG, PNG
SVGはrasterまたはpixelベースではなく、vectorで構成されている。そのため、SVGは解像度に依存せず、どのサイズのデバイスでも見た目を良くすることが可能だ。
SVGを学ぶことで、Retina-readyに向けて何か特別な準備をしなければ・・・と心配する必要はなさそうである。
また、それだけではなく SVGはHTTPリクエストが必要ない！
さらに、アニメートすることもできるのだ！

#8. More Focus on Conversation (Bots, AIs)
2016年は、ボット関連の打ち上げが急増した年だった。
また、2017年には会話インタフェースがさらに増えると想定される。現在のフォームから会話に移行することも可能だろう。
ボットやAIへのこのようなトレンドが、私たちの会話をよりよく理解できる技術を向上させることを願うばかりだ。
C#のRichTextBoxで描画処理を追加する

#やりたいこと
- 背景色を1行全体に表示されるようにしたい。

#どういうこと？
SelectionBackColorで背景色を指定した場合、選択範囲のみに背景が適用されます。
逆に、行をしていして背景色をへんこうするということができません。
Rich Text Format(RTF)的にそのような考えはないのでしょう。

#背景
ログビューワーを作成していて、特定のキーワードを見つけたら背景色を変更するようにしています。
しかしながら、文字列のある範囲しか背景色は変わらず、行全体を着色できません。

#どうするか
自分で描画処理を追加するしかありません。
RichTextBoxはListBoxやComboBoxのようにDrawItemもなくオーナードローができないということなので、WM_PAINTをフックして、RichTextBoxの描画の後に付け加える形で実現することにします。

#実装

```csharp
private const Int32 WM_PAINT = 0x000F;

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    base.WndProc(ref m);
    if (m.Msg == WM_PAINT)
    {
        using (Graphics graphic = base.CreateGraphics())
            OnPaint(new PaintEventArgs(graphic, base.ClientRectangle));
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        using (Brush brush = new SolidBrush(Color.Pink))
        {
            // 改行検索
            Regex regex = new Regex("\n");
            foreach (Match match in regex.Matches(this.Text))
            {
                Point point = this.GetPositionFromCharIndex(match.Index);
                pe.Graphics.FillRectangle(brush, point.X, point.Y, pe.ClipRectangle.Width, 18);
            }
        }
    }
```

※ちなみに、このままだとすべての改行のある行の後ろの背景色が変わりますので、背景色を変更している行のみ特定するなどの対処が必要になります

#サンプル画面
##実装前
![alt](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rrryutaro/20161221/20161221120609.png)
##実装後
![alt](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rrryutaro/20161221/20161221154240.png)

ちなみにこのサンプル画面の動作の様子は次の記事内の動画から確認できます。

- （はてなブログ）[RSkyrimLogViwer - 4 - 描画処理をさらに改造する](http://rrryutaro.hatenablog.com/entry/2016/12/21/171545)

#元となっている記事
- （はてなブログ）[C#のRichTextBoxで描画処理を追加する](http://rrryutaro.hatenablog.com/entry/2016/12/21/153543)

#参考サイト
- [ユーザー描画コントロール](https://msdn.microsoft.com/ja-jp/library/b818z6z6(v=vs.110).aspx)
- [方法 : 既存の Windows フォーム コントロールから継承する](https://msdn.microsoft.com/ja-jp/library/7h62478z(v=vs.110).aspx)
- [チュートリアル : Visual C# による Windows フォーム コントロールからの継承](https://msdn.microsoft.com/ja-jp/library/5h0k2e6x(v=vs.110).aspx)
- [OnPaint メソッドのオーバーライド](https://msdn.microsoft.com/ja-jp/library/cksxshce(v=vs.110).aspx)
- [c# - RichTextBox and UserPaint - Stack Overflow](http://stackoverflow.com/questions/5041348/richtextbox-and-userpaint)
- [c# - Drawing over RichTextBox - Stack Overflow](http://stackoverflow.com/questions/16989957/drawing-over-richtextbox)
- [テキストボックス内の改行位置について: DOBON.NETプログラミング掲示板過去ログ](http://dobon.net/vb/bbs/log3-11/6224.html)

以上
Zsh Global Aliasのあれこれ

## global alias 概要

zshにはglobal aliasあります。

通常のaliasは最初のコマンドにしか作用しないのに対し、global aliasは以降のパラメータやオプションなどにも使用できるaliasです。

```bash:.zshrc
alias -g P='-c ~/.chef/knife_prod.rb'
alias -g D='-c ~/.chef/knife_dev.rb'
```

このようなaliasを定義しておくと、

```bash
knife node list P
```

などと実行できます。

## pipeで使う

pipeと絡めたglobal aliasも便利です。

参考: oh-my-zshのplugin, common-aliases

https://github.com/robbyrussell/oh-my-zsh/blob/master/plugins/common-aliases/common-aliases.plugin.zsh


## global aliasの自動展開

コマンドを他の人に見せるときなどは、そのglobal aliasを知らない人にとって意味不明になってしまいます。
そういう観点から、以下のような設定を.zshrcに書いておくとよいでしょう。

```bash:.zshrc
# expand global aliases by space
# http://blog.patshead.com/2012/11/automatically-expaning-zsh-global-aliases---simplified.html
globalias() {
  if [[ $LBUFFER =~ ' [A-Z0-9]+$' ]]; then
    zle _expand_alias
    # zle expand-word
  fi
  zle self-insert
}

zle -N globalias

bindkey " " globalias
```
C#でRichTextBoxに書式を損なわずにテキストの追記を行う（Rtfでの追記）

# やりたいこと
- RichTextBoxにて書式変更した後にテキストを追加しても書式を損なわないようにしたい

# 背景
ログビューワーを作成していた際、特定キーワードを発見したら背景色を変更するようにしていましたが、背景色が反映されず、次のような簡易コードで確認してみました。

```csharp
richTextBox2.Text = "a";
richTextBox2.Update(); // step1

richTextBox2.Text += "b";
richTextBox2.Select(1, 1);
richTextBox2.Update(); // step2

richTextBox2.SelectionBackColor = Color.Pink;
richTextBox2.Update(); // step3

richTextBox2.Text += "c";
richTextBox2.Update(); // step4
```

step3で背景色が適用されるも、step4で背景色が消えます。
RichTexBoxはデータの実態がRich Text Format (Rtf) なので当然といえば当然なのですね。

# 実装
今回は、追記するテキストを別のRichTextBoxに貼り付けて書式変更した後、本体のRichTextBoxに貼り付ける方法にしました。

```csharp
RichTextBox rich = new RichTextBox();
rich.Text = addText;
rich.Select(0, rich.TextLength);
rich.SelectionBackColor = Color.Pink;

richTextBox2.SelectionStart = richTextBox2.TextLength;
richTextBox2.SelectedRtf = rich.Rtf;
```

# 元となっている記事
- （はてなブログ）[C#でリッチテキストのRtfの追記を行う](http://rrryutaro.hatenablog.com/entry/2016/12/21/110800)

以上