OmniAICreator/Qiita-1.07M huggingface dataset:
Challenge Book for Web Engineers (Webエンジニアの課題図書)

Webエンジニアが読んでおくべき課題図書を選びました。 もっと正確に書くと、今の会社で働くWebエンジニアが読むべき書籍の一覧です。 (外国のオフィスもあるのでできるだけ英語のものを選んでいます。)


## Basic

### W3C HTML5 (Web Site)

https://www.w3.org/TR/html5/
(今は html 5.1 というのも進んでいますね。)

特に次の点は注意が必要です。

* How to use each content, such as sectioning content, flow content, etc. (Sectioning Content, Flow Content 等のコンテンツ)
* Each tag meaning and its attributes (各 Tag の意味・属性)

### Test Driven Development by Example

### たのしい Ruby

### はじめての Spring Boot

これは超基礎なので、公式ドキュメント読んでわかるならそれでもいいレベルです。

### Oracle Master Bronze SQL 基礎

SQL Basic

## Medium

### Design Patterns: Elements of Reusable Object-Oriented Software

### Pattern of Enterprise Application Architecture

### Domain Driven Design


とりあえずこれだけ。
javaのpublicメソッドを抽出してみる

仕事でjavaのpublicメソッドを抽出するプログラムが必要になりそうなので、書いてみた
Java7のNewIOとJava8のStream関数を使って実装してみる

```JavaFileAnalyser.java

package triple;

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class JavaFileAnalyser {
	private static Pattern PATTERN ;
	public static void main(String args[]) throws Exception{
		PATTERN = Pattern.compile(".*public(.*)(?:\\s|\\t)(.*)\\((.*)\\).*");
		
		List<String> list = Files.newBufferedReader(
				Paths.get("C:/Java/jdk1.8.0_102/src/javax/script/AbstractScriptEngine.java"),
				Charset.forName("UTF-8"))
		.lines()
		.filter(JavaFileAnalyser::isMethod)
		.map(JavaFileAnalyser::parse)
		.collect(Collectors.toList());
		
		Files.write(Paths.get("C:/Users/****/workspace/FileOpe/result/result.txt"), 
				list, 
				Charset.forName("UTF8"),
                StandardOpenOption.CREATE);
	}
	
	public static boolean isMethod(String str){
		if(PATTERN.matcher(str).find()){
			return true;
		}
		return false;
	}
	
	public static String parse(String str){
		Matcher m = PATTERN.matcher(str); 
		if(m.find()){
			return String.format("戻り値のシグニチャ : %s メソッド名:%s 引数 :%s",m.group(1),m.group(2),m.group(3));
		}
		return "";
				
	}

}
```

```結果
戻り値のシグニチャ :  メソッド名:AbstractScriptEngine 引数 :
戻り値のシグニチャ :  	AbstractScriptEngine メソッド名: 引数 :Bindings n
戻り値のシグニチャ :  void メソッド名:setContext 引数 :ScriptContext ctxt
戻り値のシグニチャ :  ScriptContext メソッド名:getContext 引数 :
戻り値のシグニチャ :  Bindings メソッド名:getBindings 引数 :int scope
戻り値のシグニチャ :  void メソッド名:setBindings 引数 :Bindings bindings, int scope
戻り値のシグニチャ :  void メソッド名:put 引数 :String key, Object value
戻り値のシグニチャ :  Object メソッド名:get 引数 :String key
戻り値のシグニチャ :  Object メソッド名:eval 引数 :Reader reader, Bindings bindings 
戻り値のシグニチャ :  Object メソッド名:eval 引数 :String script, Bindings bindings
戻り値のシグニチャ :  Object メソッド名:eval 引数 :Reader reader
戻り値のシグニチャ :  Object メソッド名:eval 引数 :String script
```

コンストラクタの情報も取得してしまっているようだが、細かいことは気にしないことにする（おい）
Curl でPOST

# CurlでPOST

```
curl -i -s http://shichimitoucarashi.com/qiita/ -X POST -d "post_val=heymen"
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Sat, 04 Nov 2017 13:36:28 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.6.31

{"result":"SUCCESS","code":"1","post_value":"heymen"}
```

便利やね

引用
http://itpro.nikkeibp.co.jp/atcl/column/14/230520/080400003/?rt=nocnt
Qt Creatorおぼえがき

## `QSplitter`
- ユーザがリサイズできるレイアウトをつくるには`QSplitter`をつかう。複数のオブジェクト間のセパレータ（ハンドル）をドラッグしてレイアウトをリサイズできる。
- `QSplitter`に入れたいオブジェクトを選んでコンテクストメニューから「水平／垂直にスプリッタの中に並べる」（左カラムのクラスリストにはない）
Controller内のI18nで継承を含めてkeyを参照させる

ControllerでI18n使う所なんてフラッシュメッセージ位だし
あえて継承気にするまでもないって事な気もするけど、
管理画面とか基本同じメッセージなのにコントローラー毎にyml定義するの面倒くさい！
という気持ちからガッっと書いた。

```ruby:app/controllers/application_controller.rb
def translate(key, options = {})
  if key.to_s.first == "."
    defaults = _prefixes.map do |prefix|
      path = prefix.tr('/', '.')
      [:"#{path}.#{action_name}#{key}", :"#{path}#{key}"]
    end
    defaults << options[:default] if options[:default]
    options[:default] = defaults.flatten
    options[:scope] = :controller
    key = options[:default].shift
  end
  I18n.translate(key, options)
end
alias :t :translate
```

これで、例えばこんなキーを読み出す時に

```ruby:app/controllers/admin/application_controller.rb
class Admin::ApplicationController < ApplicationController
end
```

```ruby:app/controllers/admin/users_controller.rb
class Admin::UsersController < Admin::ApplicationController
  def update
    if @user.update(user_params)
      redirect_to [:admin, @user], notice: t('.success')
    else
      render :edit
    end
  end
end
```

```yaml
ja:
  controller:
    application:
      success: 6th
      update:
        success: 5th
    admin:
      application:
        success: 4th
        update:
          success: 3rd
      users:
        success: 2nd
        update:
          success: 1st
```

こんな感じの順番で参照してくれるようになる。
AWS上のUbuntuでFlask環境を構築

AWS上のUbuntu（16.04.2 LTS）に、Flask環境を構築しました。

####pipでvirtualenvをインストール

```shell-session
$ pip install --user virtualenv
Collecting virtualenv
  Downloading virtualenv-15.1.0-py2.py3-none-any.whl (1.8MB)
    100% |????????????????????????????????| 1.8MB 711kB/s
Installing collected packages: virtualenv
Successfully installed virtualenv-15.1.0
$ which virtualenv
/home/ubuntu/.local/bin/virtualenv
```

####仮想環境構築

```shell-session
$ virtualenv flask
Using base prefix '/home/ubuntu/anaconda3'
New python executable in /home/ubuntu/flask/bin/python
Installing setuptools, pip, wheel...done.
```

####アクティベート

```shell-session
$ source ./flask/bin/activate
```

####Flaskをインストール

```shell-session
(flask) ubuntu@ip-XXX:~$ pip install flask
Collecting flask
  Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
    100% |????????????????????????????????| 92kB 3.2MB/s
Collecting itsdangerous>=0.21 (from flask)
  Downloading itsdangerous-0.24.tar.gz (46kB)
    100% |????????????????????????????????| 51kB 5.1MB/s
Collecting Jinja2>=2.4 (from flask)
  Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
    100% |????????????????????????????????| 348kB 3.9MB/s
Collecting click>=2.0 (from flask)
  Downloading click-6.7-py2.py3-none-any.whl (71kB)
    100% |????????????????????????????????| 71kB 5.7MB/s
Collecting Werkzeug>=0.7 (from flask)
  Using cached Werkzeug-0.12.2-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->flask)
  Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
  Running setup.py bdist_wheel for itsdangerous ... done
  Stored in directory: /home/ubuntu/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
  Running setup.py bdist_wheel for MarkupSafe ... done
  Stored in directory: /home/ubuntu/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built itsdangerous MarkupSafe
Installing collected packages: itsdangerous, MarkupSafe, Jinja2, click, Werkzeug, flask
Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 click-6.7 flask-0.12.2 itsdangerous-0.24
```

####hello.pyを作成

```shell-session
(flask) ubuntu@ip-XXX:~/flask/code$ vi hello.py
```

```python:hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run()
```

####実行

```shell
(flask) ubuntu@ip-XXX:~/flask/code$ python hello.py
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

####別のターミナルを立ち上げて、curlで確認

```shell-session
$ curl http://localhost:5000
Hello, World!
```
FOVEのキャリブレーションが動かない


FOVEログを確認

```
Inaccurate vsync times observed: Short: 70 Long: 0 Shortest: 0us Longest: 0us Avg: 0us Exp: 14285us
```

PCとFOVEのvsyncがぶつかっている？

[NVIDIAコントロールパネル] > [3D設定の管理] > [垂直同期] を `3Dアプリケーション設定を使用する`に変更する

![vsync.png](https://qiita-image-store.s3.amazonaws.com/0/136286/b2483dc3-c613-5450-ec1a-e7227275be12.png)

結果、キャリブレーションが動くようになった

> 参考
[NVIDIAのさまざまなディスプレイ垂直同期方式をもう一度整理する](https://pc.watch.impress.co.jp/docs/topic/feature/1017166.html)
Kotlin入門(2)変数

# 前回
[開発環境](https://qiita.com/pe-Daniel/items/4782565492fbc9fece03)を作りました

# 今回
変数の使い方について説明します。

# ちょっと書いてみる
**src**に新しくファイルを作って下を書いてみてください。

```kotlin
fun main(args: Array<String>) {
    val hello = "Hello World!"
    println(hello)
}
```
実行すると

```
Hello World!
```
と表示されるはずです。

# 変数・定数について
Kotlinでは変数と定数を区別します。基本的には定数で定義したほうがコンパイルされたときに最適化されます。

## 定数
```kotlin
// val 変数名 : 型 = 値
val i : Int = 10
```
型は省略できます

```kotlin
// val 変数名 = 値
val i = 10
```
もちろん数字以外も入れられます

```kotlin
val s = "hogehoge"
```

しかし、定数なだけあって書き換えをしようとするとエラーが出ます。
（コンパイルできません）

```kotlin
val i = 10
i = 20 // <- Error!
```
## 変数
基本的に定数と同じ

```kotlin
// var 変数名 : 型 = 値
var i : Int = 10
i = 20 // <- OK!
```
もちろん省略もOK

```kotlin
var i = 10
```
できるだけ定数で宣言することをおすすめします。

# 変数の出力
```kotlin
val a = 100
val b = 50

// 普通にprintln()を使って出力できます
println(a)
println(a + b)

// 文字列の途中に変数を入れることもできます
println("a + b = ${a + b}")
// ${}の中が一つの場合$だけに省略できます
println("a = $a")
```
# 次回
~~関数について書こうかなと思ってます~~
~~[次回](https://qiita.com/pe-Daniel/items/000407df1c7d5206e0ef)~~
書くの忘れてました
[if,for,whileについて](https://qiita.com/pe-Daniel/items/21f0b387454c85f5d813)
CSS3のremとemの違いについて


## CSSのフォントサイズ指定方法は次の2つ
* 絶対値: 10pxなら絶対に10px
* 相対値: 親要素のサイズによって可変

## px
* サイズを絶対値で指定

```css
html {
  font-size: 32px;
}

h1 {
  font-size: 64px; /* -> 64px; */
}

span {
  font-size: 20px; /* -> 20px; */
}
```

## em
* 親要素の`font-size`を基準に大きさを計算する

```css
html {
  font-size: 32px;
}

h1 {
  font-size: 2em; /* -> 64px; */
}

span {
  font-size: 0.5em; /* -> 32px; */
}
```

## %
* emと同じで親要素の相対値

```css
html {
  font-size: 32px;
}

h1 {
  font-size: 200%; /* -> 64px; */
}

span {
  font-size: 50%; /* -> 32px; */
}
```

* 要素が入れ込んでくると、どの親要素を基準にしているかが分かりにくくなる
* そのためCSS3で使えるようになったのが、rem

## rem (root em)
* 文書のルート要素、つまり`html`要素の`font-size`を基準にする

```css
html {
  font-size: 32px;
}

h1 {
  font-size: 2rem; /* -> 64px; */
}

span {
  font-size: 0.5rem; /* -> 16px; */
}
```

## ブラウザサポートを確認
* Can I Useで確認するとIE8以下は未対応。IE9と10は一部対応
* それ以外のブラウザは対応している

![Kobito.qvcwUf.png](https://qiita-image-store.s3.amazonaws.com/0/33823/dc811104-f8c0-b281-15b0-b96bf5d9ff9d.png "Kobito.qvcwUf.png")

## ブラウザのデフォルトサイズ
* 16px

```css
html {
  font-size: 100%; /* -> 16px; */
}
```

## pxだとなぜいけないのか
* ブラウザによって文字の大きさが変わる
* あなたはどれにする？CSSの文字サイズ指定「px、em、%」 – デザインメモ http://blog.karasuneko.com/3092/

## よくあるやり方

```css
html {
  font-size: 62.5%; /* -> 10px; */
}
```
* デフォルトの16pxの代わりに1emが10pxになるように調整

```css
body {
  font-size: 1.4em; /* -> 14px; */
}
```
* 上の設定により「px」を使用するのに似た感覚でフォントサイズを指定できるようになる
* bodyでemを使うのはChromeのバグ対応
    * Chromeでfont-sizeを相対指定したとき、フォントサイズが大きく表示されることがある - Qiita https://qiita.com/qtach1/items/2a48aa64dbcd820b7d76

```css
.page-header {
  font-size: 2rem;
 
```

* emは親のfont-sizeに相対的で入れ子の時に問題になる
[Python3]リストの扱いの基本

# リストを作りたい
###　まずは基本から
```py3:list001.py
list001 = [1, 2, 4, 8]
print(list001)
```
[1, 2, 4, 8]と表示されて、list001が作られる。

```py3:list002.py
list002 = ['a', 'b', 'c']
print(list002)
```
['a', 'b', 'c']と表示されて、list002が作られる。

####　変数から作ることもできる
```py3:list003.py
x = 10
y = 20
z = 30
list003 = [x, y ,z]
print(list003)
```
[10, 20, 30]と表示されて、list003が作られる。
####　いろいろな型が混在しても大丈夫
```py3:list004.py
list004 = [1, 2, 'a', 'b', True, False]
print(list004)
```
[1, 2, 'a', 'b', True, False]と表示されて、list004が作られる。


####　効率的な作り方
```py3:list005.py
list005 = [0]*10
print(list005)
```
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]と表示されて、list005が作られる。


```py3:list006.py
Numbers = [1, 2, 3, 4, 5]
list006 = Numbers*3
print(list006)
```
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]と表示されて、list006が作られる。

```py3:list007.py
list007 = ['abc']*3
print(list007)
```
['abc', 'abc', 'abc']と表示されて、list007が作られる。

```py3:list008.py
list008 = list(range(-5, 6))
print(list008)
```
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]と表示されて、list008が作られる。

####　偶数のリストが作りたい時
```py3:list009.py
list009 = list(range(0, 20, 2))
print(list009)
```
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]と表示されて、list009が作られる。


####　奇数のリストが作りたい時
```py3:list010.py
list010 = list(range(1, 20, 2))
print(list010)
```
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]と表示されて、list010が作られる。


####　3の倍数のリストが作りたい時
```py3:list011.py
list011 = list(range(0, 30, 3))
print(list011)
```
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]と表示されて、list011が作られる。


####　文字列をlist()に入れるとバラバラになってしまう。

```py3:list012.py
list012 = list('apple')
print(list012)
```
['a', 'p', 'p', 'l', 'e']と表示されて、list012が作られる。
【Chrome Developer Tools】実例で学ぶelementタブで出来ること～HTML編

ある日の私のQiitaマイページです。
これを使って、Chrome Developer Tools（開発者ツール）を使ってみましょう:wink:
![myPage_65.png](https://qiita-image-store.s3.amazonaws.com/0/188980/05d7a749-0b1b-8a2c-19df-aac046aa569e.png)

# この記事で学ぶこと
1. HTMLの各種要素（エレメント）・属性の内容を書き換えてシミュレーションする方法。
2. HTMLを直接修正してシミュレーションする方法。

上記２つは、Chrome Developer Toolsのelementsタブから操作します。

# elementsタブを使ってみる
## HTMLの各種要素（エレメント）・属性の内容を書き換えてみる
Contribution数（いいねの数）がさみしいので、たくさん「いいね！」がついたかのように装いましょう（笑

### １．書き換えたいHTML要素を探す
まずは、F12を叩いてdeveloper toolを起動したら、左上にある赤く囲んだこのマークをクリックします。
![03 - コピー.png](https://qiita-image-store.s3.amazonaws.com/0/188980/17d6cb68-810a-33b9-a1b5-d33ef0a4a48a.png)

そのまま、画面上で「72」を狙ってクリックすると、developer tool上で該当のHTMLにジャンプします。
![001_100.png](https://qiita-image-store.s3.amazonaws.com/0/188980/9459e00b-0514-077f-efd6-2989328571e2.png)

### ２．要素の値を書き換える
ジャンプした先のHTMLで「72」をダブルクリックして、「2117」に書き換えたら、勢いよくEnterキーを叩きましょう。
これで、Contribution数が増えました:v:
※ちなみに、[2117]は、この記事を書いていた時の時刻（24時間表記）です。暗証番号とかではありません（念のため）:sweat_smile:
![002_065.png](https://qiita-image-store.s3.amazonaws.com/0/188980/256be729-68ce-c07d-fdb2-17239c1b0929.png)

あくまでも、**読み込んだHTMLのシミュレーション** なので、Qiita側への影響はゼロです。

span要素以外にも、HTMLタグで囲まれた値なら全て、HTMLタグの属性（idやclass、aタグのhrefやimgタグのaltなど）の値も、ダブルクリックでシミュレーションできます。

## HTMLを直接修正する
もっとたくさんのQiitaタグがつけられたらいいのになぁ・・・と思ったので、これも脳内イメージで装って（＝シミュレーションして）みましょう。
「[【MySQL】コマンド一発でマイナーバージョンまで確認する](https://qiita.com/mtanabe/items/f95e1cd9b82e2f7924af)」の記事で試してみます。

### １．書き換えたいHTML要素をして「編集モード」に入る
先ほど同様、画面上でQiitaタグの「Database」をクリックしてHTMLにジャンプしたら、右クリックして「Edit as HTML」を選択します。
![003_065.png](https://qiita-image-store.s3.amazonaws.com/0/188980/653a3722-f4a2-5623-20b7-c179521a0d18.png)

### ２．HTMLを自由に編集する
HTML編集モードになったら、Qiitaタグ「Database」のa要素をコピー＆ペーストして１行追加しましょう。
で、内容は適当に「コマンド」にでもしておきましょう。
![004_065.png](https://qiita-image-store.s3.amazonaws.com/0/188980/7c890c67-73a9-f633-20af-35439ec11e95.png)

### ３．HTMLの「編集モード」から抜ける
最後に、ピンクで塗った丸の辺りをふんわりクリックして、HTMLの編集モードを解除すれば:ok:です。
:warning: enterキーを叩いても、改行文字が入力されるだけで、編集モードが解除されません。:warning:

しかし、a要素をコピー＆ペーストしたので、もともとあったQiitaタグ「Database」とつながってしまいました。
![005_100.png](https://qiita-image-store.s3.amazonaws.com/0/188980/782cf3ff-e901-655f-b844-8161ababc5c1.png)

### ４．編集したいHTMLを間違えた！
li要素から作らないとダメだったようです:cry:
なので一旦F5で画面を元に戻しましょう。
そして、再度li要素を選択して右クリック→「Edit as HTML」しましょう。
![006_085.png](https://qiita-image-store.s3.amazonaws.com/0/188980/c8351e6b-2278-6b17-e83d-91f9a1597a38.png)

そして、li要素からコピー＆ペーストします。
これでliの要素が１つ増えました:v:
![007_065.png](https://qiita-image-store.s3.amazonaws.com/0/188980/39058e74-4a3b-1f8d-7534-3b66b0abb292.png)

とりあえず、この方法を覚えておけば、削除や編集ができます:sparkles:
削除やコピーなどは、ほかの右クリックメニューからでも操作できますが、たくさん覚えるのも大変なので、まずはこの１つだけ・・・。

# 現場でどう生かせるの？
<font color="#FF0099"><b>画像処理ソフトを使わなくても値が編集できる。</b></font>

つまり・・・
:arrow_right:　ユーザーマニュアルに載せるための画面キャプチャの取得がラクに出来る。
:arrow_right:　テストの実行結果を偽装できる（やっちゃダメですよ:bangbang:）。
:arrow_right:　修正後のイメージを、デザイナーさんに依頼することなく３分で自分で作れてしまう。

# まとめ（どの操作で何を学んだか）
最初に書いた２つの事項は、どの操作が該当していたかというと・・・。

**1. HTMLの各種要素（エレメント）・属性の内容を書き換えてシミュレーションする方法。**
→【操作】Contribution数の変更
**2. HTMLを直接修正してシミュレーションする方法。**
→【操作】Qiitaタグを追加する
Golang のバイナリにバージョンを埋め込む #golang


以前の記事では、（[Golang と Line Notify を利用して API の証明書期限切れチェック](https://qiita.com/ynozue/items/d00a76e16d5a3d5a784c)）を作りましたが今回は作成したバイナリにバージョンの追加を行います。

# 概要
ざっくり調べたことややりたいことを書こうと思います。

* Golang でビルドしたバイナリはデフォルトでバージョンが埋め込まれるわけではない
 * 「main.go」などに変数を用意してビルド時などに埋め込む必要がある
 * ビルド時のオプションで変数に値を設定可能
 * 「flag」パッケージを利用して、オプションの処理を実装する必要がある
* バージョンはバージョン番号とリビジョンに分けて管理
 * バージョンは git の最新のタグを利用（v1.0.0 なイメージ）
 * リビジョンは git の最新のタグのショートリビジョンを利用（e5a4228なイメージ）

# ソースコード
```apichecker.go
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strings"
	"time"
)

var version = "unknown"
var revision = "unknown"

func main() {
	var endpoint = flag.String("endpoint", "", "check target Endpoint URL")
	var lineToken = flag.String("token", "", "LINE notify token")
	var showVersion = false
	flag.BoolVar(&showVersion, "v", false, "show application version")
	flag.BoolVar(&showVersion, "version", false, "show application version")
	flag.Parse()

	if showVersion {
		fmt.Println("version(", version+"."+revision, ")")
	} else {
		var apiResult = getAPI(*endpoint)
		var result = postLINE(*lineToken, apiResult)

		fmt.Printf("LINE Post result [%t]\n", result)
	}
}

func getAPI(endpoint string) string {
	if endpoint == "" {
		log.Println("not endpoint")
		return "not endpoint"
	}

	var result = ""
	resp, err := http.Get(endpoint)
	if err != nil {
		result = fmt.Sprintf("NG\n%s", err)
	} else {
		defer resp.Body.Close()
		expire := "-"
		if len(resp.TLS.PeerCertificates) > 0 {
			expireUTCTime := resp.TLS.PeerCertificates[0].NotAfter
			expireJSTTime := expireUTCTime.In(time.FixedZone("Asia/Tokyo", 9*60*60))
			expire = expireJSTTime.Format("06/01/02 15:04")
		}
		result = fmt.Sprintf("OK (expire=%s)\n%s", expire, endpoint)
	}

	return result
}

func postLINE(token string, message string) bool {
	if token == "" {
		log.Println("not token")
		return false
	} else if message == "" {
		log.Println("not text")
		return false
	}

	data := url.Values{"message": {message}}
	r, _ := http.NewRequest("POST", "https://notify-api.line.me/api/notify", strings.NewReader(data.Encode()))
	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	resp, err := http.DefaultClient.Do(r)
	if err != nil {
		log.Println(err)
		return false
	}
	defer resp.Body.Close()
	_, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println(err)
		return false
	}

	return true
}
```

# git コマンドで最新のタグとハッシュ値のショートバージョンを取得
## 最新のタグの取得
```sh
$ git describe --tags --abbrev=0
v1.0.0
```

## ハッシュ値のショートバージョンの取得
```sh
$ git rev-parse --short HEAD
e5a4228
```

# ビルド時にバージョンとリビジョンを埋め込む
**go build** 時に **ldflags** オプションを利用することで、go ファイルに定義した変数に値を設定することが可能です。

## ビルド
```sh
$ GOOS=darwin GOARCH=amd64 go build -ldflags "-X main.version=$(git describe --tags --abbrev=0) -X main.revision=$(git rev-parse --short HEAD)"
```

## バージョンチェック
```sh
$ ./apichecker -v
version( v1.0.0.e5a4228 )
```

# まとめ
コマンドラインツールは長期間利用していると、どのバージョンのバイナリで運用しているかがわからなくなるので必ずバージョンを埋め込むような癖を作らないといけないかなと思っています。
ただ、よく使うのでここらへんは標準機能として実装されるとより便利かなと思ってます。

# Appendix
* [ソースコード](https://github.com/ynozue/apichecker/tree/version)
【C#】任意個のIEnumerableをzipする

# はじめに

Pythonの `zip(a, b)` は、C#だと `a.Zip(b, Tuple.Create)` です。

Pythonの `zip(a, b, c)` は、C#にはたぶん用意されていない。なぜだ。不便だ。

# 無いなら作ろう

できた。

```c#
public static class MoreMoreEnumerable
{
    public static IEnumerable<T[]> Zip<T>(this IEnumerable<IEnumerable<T>> sources)
    {
        var enumerators = sources.Select(_ => _.GetEnumerator()).ToArray();
        while (enumerators.All(_ => _.MoveNext()))
            yield return enumerators.Select(_ => _.Current).ToArray();
    }
}
```

# 使用例

```c#
var a = new[] { 1, 2, 3 };
var b = new[] { 4, 5, 6 };
var c = new[] { 7, 8, 9 };
int[][] abc = new[] { a, b, c }.Zip().ToArray();
```
パスカルの三角形　因数分解　展開

#美しいパスカルの三角形から２項定理までをわかりやすく。
まずは、パスカルの三角形がどんなものなのかを画像で見てみましょう。
![pascal.png](https://qiita-image-store.s3.amazonaws.com/0/204488/cb24ef56-c18a-0f06-699e-6ca8bbdfc4d1.png)
画像はウィキペディアから持ってきています。
この図にはどんな意味があるでしょうか？７段目がどのように並ぶのか予想してみましょう。
簡単な解説動画
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">パスカルの三角形3<br>それぞれの文字の係数を抜き出して並べてみよう。どんな規則があるでしょうか？<br>(a+b)^0→1<br>(a+b)^1→1,1<br>(a+b)^2→1,2,1<br>(a+b)^3→1,3,3,1<br>三角形になっていますね。<br><br>この三角形をパスカルの三角形といいます。 <a href="https://t.co/76sR8yY6r3">pic.twitter.com/76sR8yY6r3</a></p>&mdash; 数学小僧 博士号 (@mathsheen) <a href="https://twitter.com/mathsheen/status/926773479856160770?ref_src=twsrc%5Etfw">November 4, 2017</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
新型MacBookProのキーの不具合の話

# はじめに
8月に購入した新型MacBookPro(15inch, 2017mid)に不具合が発生したので、修理までの経緯を残しておく。

# 故障は突然に  
今使っている筐体は15inch, 2017midである。10月中旬頃、bキーに以下のような不具合が生じるようになった。　　

- 軽くキーを押すと反応しない。
- キーを押すと二度入力される。
- キーを強く押さないと反応しない。
- キートップの右半分の反応は良いが、左半分の反応が良くない。

また、同様な症状がfキーにも現れるときがあった。

# とりあえず検索
どうやらキーボードの故障はちらほら存在し、まずは以下のような対処を推奨されるようだ。

- 掃除をする  
https://support.apple.com/ja-jp/HT205662
- NVRAM or PRAM をリセットする  
https://support.apple.com/ja-jp/HT204063
- SMCをリセットする  
https://support.apple.com/ja-jp/HT201295

対処法を全て試したところ、掃除が一番効果が現れた。一時的なもののキーボードは復活したが、一週間すると再び症状が発生した。その後は掃除してもすぐに調子が悪くなるようになった。

# 結末
結局、症状が出始めてから2週間で何をしても改善が見られなくなったため、修理することにした。修理担当の人との電話では、最近同じケースが多いらしいということ。また、Twitterなどでも同じ症状を訴える人がちらほらおり、初期不良的なものである可能性が高いと感じた。

修理までのスケジュール
- 11/1 Appleホームページから修理依頼
- 11/2 クロネコヤマトが集荷に来た。
- 11/3 修理先へ到着、同日修理が完了し、発送したとの連絡。
- 11/4 手元に帰ってくる。

こんな感じで、迅速な対応をしてもらって満足だった。保証期間内だということで無償で修理してもらった。ついでに、キーボードだけを修理してもらうと思っていたところ、新型MBPの構造のせいか、中の基盤以外の全て（キーボード、ディスプレイ、外装、バッテリーなど）を交換してもらった。ついでに、Appleのロゴが入ったクリアファイルもゲットした（？）

# おわりに
なんやかんやで、修理に出したらすぐ手に戻ってきたので、同じ状態に陥ってしまった新型MBPユーザは、上記の対処を行っても改善がみられない、またはすぐ再発するようならさっさと修理に出すことをおすすめする。保証期間内ならタダで新品待ったなしだ。（基盤を除く）

# 追記 (2018/06/26)
- なんと、Apple側からキーボードの不具合があると交換プログラムが提出された。  
[MacBook および MacBook Pro キーボード修理プログラム
](https://www.apple.com/jp/support/keyboard-service-program-for-macbook-and-macbook-pro/)
- 上記の症状にかかっている方は是非このプログラムを適用してほしい。
- ちなみに、筆者は交換した筐体のnキーに症状が現れ始めたので適用しようと思う...トホホ..
エクセルを使ってファイルを突合チェックする

先日、成果物（ここではプログラムとします）と成果物一覧を見比べてファイル有無をチェックしてほしいと言われ、エクセル関数とマクロを使用し自動化したので備忘録として残しておきます。

# したいこと
フォルダ内の成果物（.txt）と成果物一覧を突合チェックしたい。

# 方針
* Excelが使える人対象。Excel関数は IF, COUNTIF, LEFTB, LENB関数程度
* マクロは使えないけど興味ある
* マクロはあくまで補助

# エクセル側
## 1. 突合させる用のシート作成
### フォルダ側のリスト
![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/139352/7fd6e440-d471-4f7c-2f1c-e190d32ef4d7.png)

### 成果物一覧
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/139352/78330d7d-bd83-2343-8c6a-220b576be7c3.png)

## 2. 突合結果シート作成
* B2, D2はそれぞれのシートからの値が入る(=シート名!セル)
* C2はB2から.txt（4文字）を省いた値が入る（=LEFTB(セル, LENB(セル)-4)）
* E2はCOUNTIF(範囲,検索条件)を使用したチェック結果が入る。１つでもあれば１、なければ０になる。

<img width="550" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/f0f374c8-8743-08e8-9167-9dde109316e3.png">


関数を適用するとこうなる↓
<img width="426" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/78ab3a5c-ae1e-2612-9cbf-064eeba64963.png">


これでは分かりづらいので、IFを使用し０と#VALUE!が表示されないようにする。あと一覧整形。
<img width="544" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/c461fb1e-0d05-611d-48f2-1b057e6bb2d7.png">


エクセル側は完成。フォルダ内のファイル一覧取得はコマンドでもいいが、ここではマクロで一覧取得してみる

# マクロ
### 1. Alt + F11　でVisual Basic Editorを起動し、標準モジュールを作成する
<img width="950" alt="キャプチャ6.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/e668be46-8242-58e5-5881-aae0e55530a9.png">


### 2. VBAを書く、分からなければコピーでOK（サンプルはネットにころがっているので）


```vbnet
Sub test()

    '変数を定義
    Dim buf As String, ThisPath As String, cnt As Long
    
    '変数「ThisPath」にパスを格納
    ThisPath = ActiveWorkbook.Path
    
    '「Path」に存在するすべての「*.txt」をアクティブシートに書き出す。
    buf = Dir(Path & "*.txt")
    Do While buf <> ""
        cnt = cnt + 1
        Cells(cnt, 1).Value = buf
        buf = Dir()
    Loop
    
    '完了メッセージをポップアップで表示
    MsgBox "ファイル一覧を更新しました"

End Sub
```

<img width="950" alt="キャプチャ7.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/b7d1ddc0-2058-476c-1977-cc606c8b24b0.png">


### 3. 開発タブからボタンを挿入し、VBAが起動できるように紐付け
<img width="960" alt="キャプチャ9.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/ed79ee8c-8d5b-2826-47e0-f535df422739.png">


<img width="599" alt="キャプチャ10.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/139352/08afba2d-26e5-1227-4443-a92d54c49ab7.png">

完成。成果物と同じフォルダへ入れて一覧更新をすれば簡単にチェックできます。

# Excel VBAに興味を持った人へのおまけ
* [Excel VBA チートシート](https://qiita.com/uchiko/items/3d7a5ef3e2676c961ee2)
AndroidのIntentでメールしか出てこないようにする


ちょっとだけ詰まったのでメモ

## 調べていて多かったもの
```java
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"recipient@example.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
i.putExtra(Intent.EXTRA_TEXT   , "body of email");
try {
    startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
```
ソース: https://stackoverflow.com/questions/2197741/how-can-i-send-emails-from-my-android-application

ただ、これだとLINEやSlackなどが選択肢に出てしまって、自分が求めているメールを送るという目的に沿わない。

## 改善策
```java
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto","abc@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Body");
startActivity(Intent.createChooser(emailIntent, "Send email..."));
```

ソース: https://stackoverflow.com/questions/8701634/send-email-intent

これをやるとGmailなどの、mailアプリしか選択画面に表示されなくなる。
Socket.ioをサブディレクトリ(リバースプロキシ)で動かす

ローカルで動いていたスクリプトがサーバで動かなかったのでメモ。

2017/11/04 記事作成
2017/11/12 コメントを追加
## Before
```js:server.js
var http    = require('http');
var server  = http.createServer(response);
var io      = require('socket.io')(server);
// --- 処理 ---
server.listen(3000);
```

```js:client.js
const socket = io();
```

## After
```js:server.js
var http    = require('http');
var server  = http.createServer(response);
var io      = require('socket.io')(server);
// サブディレクトリのパスを指定する。
io.path('/subdir');
// --- 処理 ---
server.listen(3000);
```

```js:client.js
// pathを指定する。
const socket = io({path: '/subdir/socket.io/'});
```

## 原因
通常、Socket.ioはインスタンス生成後接続先をサーバのルートに探しに行くので、サブディレクトリで切っていると/socket.io/にアクセスできずに404を返す。
そこで、正しいパスをそれぞれに設定してあげるとうまく動く。

## 質問はお気軽に
コメント欄にどうぞ。
Twitterのほうが返信が早いです↓
[Twitter - @kznr_luk](https://twitter.com/kznr_luk)
Windows10 64BitでCCFinderXを動かす

コードクローン検出ツールと言ったらこれらしい。

#ダウンロードとインストール
## CCFinderXのダウンロードとインストール
ここからダウンロードする。http://www.ccfinder.net/ccfinderxos-j.html
ダウンロードするファイルはこれ→Win32 executable 10.2.7.4 ccfx-win32-en.zip
とりあえず適当なディレクトリに展開する。

PythonとJAVAの32Bit版が必要らしいので、落としてくる。

## JAVAのダウンロードとインストール
普通にやると64Bit環境しかインストールしてくれないので、
JAVAのインストールページ(https://java.com/ja/download/) の「すべてのJavaのダウンロード」のリンクを開いて、「Windows オフライン」と書いているのを落としてくる。
インストールする。UACとかは適当に。
## Python 2.6のダウンロードとインストール
参考ページによるとPythonのバージョンは2.6系限定らしいので、
ここから https://www.python.org/downloads/
ソースの最新版(2.6.9)はここ https://www.python.org/download/releases/2.6.9/
バイナリの最新版(2.6.6)はここ https://www.python.org/download/releases/2.6.6/
Windows x86 MSI Installer (2.6.6) (sig) と書いてあるものをダウンロードしてインストール https://www.python.org/ftp/python/2.6.6/python-2.6.6.msi

#起動バッチの変更
CCFinderX の展開先の bin/gemx.bat で起動するのだが、パスが結ばれていないので修正する。
##JAVAのパスを設定
bin/gemx.bat の先頭に以下の行を挿入して、JAVAへのパスをつないであげる。
>set PATH=C:\Program Files (x86)\Java\jre1.8.0_151\bin;%PATH%

##Pythonのパスを設定
bin/gemx.bat のPythonのパスがコメントアウトされているので有効にする。
>rem set CCFINDERX_PYTHON_INTERPRETER_PATH=C:\Python26\python.exe
の行頭のremを削除。（コメントアウトをはすず）

#起動
bin/gemx.bat を起動する。

参考ページ
「僕にそのコピペを直せというのか」https://qiita.com/mima_ita/items/fe1b3443a363e5d90a21
boto3 で CostandUsageReportService を使うときはリージョンをハードコードすること

AWS の Python 用ライブラリである boto3 を使って物作りをしていた際にハマったのでメモ．

# CostandUsageReportService とは何者
和名「AWS のコストと使用状況レポート」．

CostandUsageReportService は，ここで作られるコストレポートのエントリをいじくるためのもの

# ハマったこと
デフォルトリージョンを ap-northeast-1 などとしている環境でリージョンを指定せずに `boto3.client('cur')` とすると `describe_report_definitions()` などの呼び出し時にエンドポイントに繋がらないと怒られる．（エンドポイントが存在しないため）

``` ~/.aws/config
[default]
region = ap-northeast-1
```

``` python:sample.py
bc = boto3.client('cur')
report = bc.describe_report_definitions()

print(report)
```

``` text:実行結果
Traceback (most recent call last):
  (... snip ...)
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "https://cur.ap-northeast-1.amazonaws.com/"
```

# 直し方
クライアント作成時に `us-east-1` リージョンを指定する．

``` python:sample.py
bc = boto3.client('cur', 'us-east-1')
report = bc.describe_report_definitions()

print(report)
```

``` text:実行結果

{'ReportDefinitions': [{'ReportName': 'hogehoge', 'TimeUnit': 'DAILY', 'Format': 'textORcsv', 'Compression': 'GZIP', 'AdditionalSchemaElements': [], 'S3Bucket': 'chi9rin-cur', 'S3Prefix': '', 'S3Region': 'us-east-1', 'AdditionalArtifacts': []}], 'ResponseMetadata': {'RequestId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'content-type': 'application/x-amz-json-1.1', 'content-length': '227', 'date': 'Sat, 04 Nov 2017 10:47:20 GMT'}, 'RetryAttempts': 0}}

```

# 原因
Traceback にもあるように，`ap-northeast-1` では cur が提供されていないから．

cur については特定のリージョンに基づくものではないので，cur のクライアントを作る部分については `us-east-1` でハードコードしておいても問題はなさそう．

あと今回見つかったのは cur だけだったが，他のサービスについても同じことが言えるかもしれない．（他にリージョン無指定の IAM はクライアント作成時にリージョンを指定せずとも問題なかった）
java.nio.file.Filesでファイルを書いたり読んだり。

ふとjava.nio.file.Filesを試してみたくなったので、書いたり読んだりしてみました。
特に意味のないコードですが、せっかくなのでメモがてら晒しておきます。

doc
　https://docs.oracle.com/javase/jp/8/docs/api/java/nio/file/Files.html

```java
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class OpenFileService {

	private String dir = "src/main/resources/sample";
	private String filename = "test.txt";

	void FilesSample() {

		try {
			// ディレクトリが存在するか確認、存在しない場合は作成
			if (!Files.isDirectory(Paths.get(dir))) {
				System.out.println("ディレクトリなし");
				Files.createDirectory(Paths.get(dir));
			} else {
				System.out.println("ディレクトリあり");
			}

			// ファイルが存在するかの確認、存在しない場合は作成
			if (!Files.exists(Paths.get(dir, filename))) {
				System.out.println("ファイルなし");
				Files.createFile(Paths.get(dir, filename));
			} else {
				System.out.println("ファイルあり");
			}

			List<String> listA = new ArrayList<>();
			listA.add("あいうえお");
			listA.add("かきくけこ");
			listA.add("さしすせそ");

			// ファイルに追記書き込み
			// Files.write(Paths.get(dir, filename), listA,
			// Charset.forName("UTF-8"), StandardOpenOption.APPEND);
			// ファイルに書き込み
			Files.write(Paths.get(dir, filename), listA,
					Charset.forName("UTF-8"), StandardOpenOption.WRITE);

			// ファイルの全行読み込み。
			// 読み込み完了または例外が発生した場合、ファイルはクローズされるためクローズの記述不要。
			List<String> line = Files.readAllLines(Paths.get(dir, filename),
					Charset.forName("UTF-8"));

			// 読み込んだ文字をコンソールに出力
			for (String s : line) {
				System.out.println(String.format("Files:%s", s));
			}

			String brLine;
			try (BufferedReader br = Files.newBufferedReader(
					Paths.get(dir, filename), StandardCharsets.UTF_8)) {
				while ((brLine = br.readLine()) != null) {
					System.out.println(String.format("brLine:%s", brLine));
				}
			}
			;

			try (Stream<String> stream = Files.lines(Paths.get(dir, filename),
					StandardCharsets.UTF_8)) {
				stream.forEach(streamLine -> {
					System.out.println(String.format("Stream:%s", streamLine));
				});
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

```

もう今の時代、あの長ったらしい書き方はしなくても良くなったんですね。
ことりんにミーハーだから便乗してみる。

#:hatched_chick:ことりん
やるといいらしいので、やってみる。ミーハーだから。
学んだことをここに書いてみる。

#:hatched_chick:自分
とりより頭が悪いエンジニア。
よく分からん奴が作文書いてるだけなので、ツッコミは歓迎ですが、決して参考にはしないでください＼(^o^)／

#:hatched_chick:Kotlinとはなんぞ。
とりの仲間かなんかかと思って生きてた。
ことりんはJVM言語とかいうらしい。
JVM言語ってなんだろう？


#:hatched_chick:JVMってなんだっけ？
Javaの仮想マシン。
Javaのプログラムを動かすためにあるもの。

:point_up:参考になりました。
プログラマに優しい現実指向JVM言語 Kotlin入門：第1回　Kotlinを勧める理由 http://bit.ly/2j4PIQb

#:hatched_chick:Java仮想マシンって何？
https://ja.wikipedia.org/wiki/Java%E4%BB%AE%E6%83%B3%E3%83%9E%E3%82%B7%E3%83%B3
大好きWikipediaさんの図だと

いつも人間が書いてる.javaにJavaのコード書きます。
↓
javacコマンド打ちます。
↓
.classになりました。
↓
JVMがなんかします。:frowning:
流れはわかったけどなんかがなんだろうって。


>Java仮想マシン (JVM) のアーキテクチャ概要。ソースコードは一旦Javaバイトコードへとコンパイルされ、さらにインタプリタまたはJITコンパイラによりネイティブコードに変換されて実行される。Java APIとJVMの両者でJava実行環境 (JRE) を構成する。

:sweat_smile:説明見ても何がなんだかわからない。
アーキテクチャ？

アーキテクチャ #weblio https://www.weblio.jp/content/%e3%82%a2%e3%83%bc%e3%82%ad%e3%83%86%e3%82%af%e3%83%81%e3%83%a3
>コンピューターを機能面から見たときの構成方式。記憶装置のアドレス方式，入出力装置の構成方式などをさす。一般に，同じアーキテクチャーのコンピューターには，ソフトウエアの互換性がある。

構成？？:no_mouth:
この図の文章だとこういう仕組みになってます、ということかな？

:point_up:参考になりました。
【Java入門】JVMとは？わかりやすく解説！
https://www.sejuku.net/blog/19871
>JVMがあればJavaプログラムを解釈し、対象のOSで実行可能な形式のコードに変換して動かすことができます。

昔教わったメモも引っ張り出したところ、
「例えばwindowsとかmacとかOSなどが違っても、どんな環境でも動かせるようにするためのもの」
「OSに指示している」
「基本はOSに直接指示は出せない。（例外はあるけど）」
とそういえば教わった。
.netとかも同じでOSが違っても動く、とか。
違うOSの環境下であっても動かせるようになるものということか。

:rolling_eyes:ここら辺はもうちょい詳しく知りたいところ。

>しかし、Javaプログラムは前述したようにプログラムとOSの間にJVMを仲介させて動作します。
そのため、Javaのコンパイルは他のプログラミング言語と違い、JVMが理解できるJavaバイナリコードと呼ばれるマシン語に変換されます。
（Javaバイナリコードは、中間的なコードという意味で中間コードとも言います）

バイナリコードが0と１で表す２進数のコードのことか。

#:hatched_chick:JVM言語って？
:point_up:参考になりました
プログラマに優しい現実指向JVM言語 Kotlin入門：第1回　Kotlinを勧める理由 http://bit.ly/2j4PIQb


>Kotlinで書かれたコードはJVM（Java Virtual Machine：Java仮想マシン）で動作するJavaバイトコード（おなじみのclassファイル）へコンパイルされます。
このようなプログラミング言語をJVM言語と呼ぶことがあります。

:eyes:JavaはJVM言語じゃないの？

:point_up:参考になりました。
Jvm言語とJava、切っても切れないその関係 https://www.slideshare.net/yyyank/jvmjava-69784006
「JVMの上で実行できるプログラム言語」
いつもJavaを書くときはJVMの上では書いてないのか？

#:hatched_chick:それでことりんだと何がいいの？
:point_up:参考になりました。
【Kotlin】【Java】Kotlin Javaの比較メモ https://qiita.com/farman0629/items/f959a4ff791f26b33fc3
メリットとして両者はコードの書き方が違うみたいです。

:point_up:参考になりました
プログラマに優しい現実指向JVM言語 Kotlin入門：第1回　Kotlinを勧める理由 http://bit.ly/2j4PIQb

>Java互換

Javaとも、相性がいい模様。互換のしやすさがあるみたい。

#:hatched_chick:Kotlin以外のJVM言語はないの？

調べたら、あるらしい、あるらしい。


#:hatched_chick:それでどうすればいいの？

:point_up:参考になりました。
はじめよう、Kotlin（導入編） https://qiita.com/SYABU555/items/25b1e81a2437d6a2559f

Androidstudioからプラグイン入れるようです。


![スクリーンショット 2017-11-05 19.52.55.png](https://qiita-image-store.s3.amazonaws.com/0/148394/afbd635b-1062-0ef7-1638-434e9ac6dd02.png)
ちゃくちゃく。

![スクリーンショット 2017-11-05 19.53.58.png](https://qiita-image-store.s3.amazonaws.com/0/148394/688e194a-64e8-9271-acbf-fb1ea41e9e57.png)
ざわっ
![スクリーンショット 2017-11-05 20.03.10.png](https://qiita-image-store.s3.amazonaws.com/0/148394/c8e96e84-a4e1-ead8-a151-4f7ecaf18193.png)
拡張子がKotlinになったけど、これは・・・導入　できたのかな！？
【Debian8】タイムゾーン(Timezone)の変更

正しいのかまだ不明だが、一応動作確認はできたので忘備録としてメモ。

CentOSの場合は下記のリンクの通りでOK

「【Linux】タイムゾーン(Timezone)の変更 - Qiita」https://qiita.com/azusanakano/items/b39bd22504313884a7c3

Debianは「/etc/sysconfig/clock」の取扱が異なり、「/etc/timezone」で管理しているとのこと。

「タイムゾーンの設定方法をメモ(RHEL6, RHEL7, Ubuntu編) | Siguniang's Blog」https://siguniang.wordpress.com/2015/03/20/set-timezone/
「Changing the timezone of your Debian system」https://debian-administration.org/article/213/Changing_the_timezone_of_your_Debian_system

したがって、timezoneの値を「UTC」=> 「Tokyo」と変更して、localtimeの値も同様に変更することで時刻変更することができた。

【追記】
Debian9では下記のqiitaのエントリ通りに実施できた
多謝です。
「Debian9のタイムゾーン設定に関するメモ - Qiita」
https://qiita.com/pioka/items/e6a7a2ecdf356675d49d
TWELite-dipとarduinoを用いたシリアル通信の複数台制御

通常**Arduino UNO**の場合```rx/txピン```が1組しかないため，複数台のTWELite-dipとarduinoを用いてのシリアル通信が**できません**．そこで今回プログラムを少し工夫して，複数台制御に近い機能を実装してみます．

#実装方法
~~今回はarduinoの制御ピンを半田ごてと半田を用いて電子工作を行い，物理的に増やします~~
プログラムでポートを切り替えることで，あたかも複数台制御をしているかのように**擬似的**に実装していきます．

#宣言
それでは具体的な内容に入りましょう．
まずソース内で標準ライブラリの```SoftwareSerial```関数を利用し，通信用ピン```rx/tx```を宣言します．

```csharp
#include<SoftwareSerial.h>　　
SoftwareSerial TWE1(8, 9); // rx, tx
SoftwareSerial TWE2(10, 11); // rx, tx
```
#初期化
次に宣言したポートの**初期化**を行います．

```csharp
void setup()
{
　　TWE1.begin(9600);
　　TWE2.begin(9600);
}
```

>括弧内の数値はスピードを表しています．
この数値はシリアルモニタで数値と**同じ**にする必要があります．そうしないと文字化けやデータの不整合が起こることがあります．

#プログラム
以上で，擬似複数制御のあらかたの仕込みも終わりです．
あとはメインで処理を行うloop()内でそれぞれの処理を行う前に標準ライブラリの ”listen” 関数を使用しポートを開けば**OK**です．

```
void loop()
{
　　TWE1.liste();
　　if(TWE1.avaivable())
　　{
　　//TWE1に関する処理をここに実装
　　　TWE1.println(“TWE1 coming”);
　　}
　　TWE2.liste();
　　if(TWE2.avaivable())
　　{
　　//TWE2に関する処理をここに実装
　　　TWE2.println(“TWE2 coming”);
　　}

}
```
>この方法であればサンプルでは2台制御ですが，TWE3やTWE4というようにポートを増やすことで制御対象を増やすことが可能となります．

#プログラム全文
```csharp:example.ino
#include<SoftwareSerial.h>

SoftwareSerial TWE1(8, 9); // rx, tx
SoftwareSerial TWE2(10, 11); // rx, tx

void setup()
{
　　TWE1.begin(9600);
　　TWE2.begin(9600);
}

void loop()
{
　　TWE1.liste();
　　//TWE1に関する処理をここに実装
　　if(TWE1.avaivable())
　　{
　　　TWE1.println(“TWE1 coming”);
　　}

　　TWE2.liste();
　　//TWE2に関する処理をここに実装
　　if(TWE2.avaivable())
　　{
　　　TWE2.println(“TWE2 coming”);
　　}
　delay(2000);
}
```
メールの生データ：メーラーの改行

メモ
困った。メーラーによって改行コードの種類が違うし、CRのみ、~~LFのみ~~、CRLFとCRが混在してたりする。どこでどう判断すればいいか解らなくなってきた。

改行コードが統一されてればメーラー判断してからの正規表現を決定すればいいんだけどまさか混在してるとは思わなかった。

あとで調べないとちゃんとした処理出来ないなぁ。

ちなみにiPhoneの標準メーラーが色んな面でかなり厄介。

自分の記事リンク：[メールの生データの最初の空行](https://qiita.com/next1ka2u/items/14a2b22b18de1ae1ced5)

###メーラー毎にある改行コードを調べた結果(2017/11/04現在)

|メーラー|CR|LF|CRLF|
|:-:|:-:|:-:|:-:|
|iPhone標準メーラー|○|×|×|
|Andoroid標準メーラー|○|×|○|
|DecoMailer|○|×|○|
|Outlook2016 for PC|○|×|○|
|Gmail for WEB|○|×|×|
|Gmail for iPhone|○|×|×|

これ以外の端末は手元にないので調べようがない。**LF(\\n)**はどのメーラーでも使ってないようです。Andoroid標準メーラー、デコメーラー、Outlookは**CR(\\r)**と**CRLF(\\r\\n)**が混在してるようです。まだ詳細を調べたわけではないので**本文中に入ってる改行コードを拾ってるだけかも**しれません。**ヘッダとパートの区切り部分やパート毎の区切り部分の改行コードが統一されているようだったら**まだやりようがあるんですが。とりあえず、本文を削除してみて改行コードが統一されているかどうかを調べる必要がありそうです。
nginxを試しに動かしたメモ

# 使うもの

* Windows10
* Vagrant
* VirtualBox
* CentOS 7
* nginx

# 手順
1.VagrantとVirtualBoxインストール
2.下記Vagrantgileを準備して`vagrant up`

```
Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-7.2"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end
end
```
3.`vagrant ssh`でSSH接続
4.nginxのインストール

```
# リポジトリ追加
sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

# インストール
sudo yum -y install --enablerepo=nginx nginx
```

5.nginxの起動

```
sudo systemctl start nginx
```

6.動作確認
http://localhost:8080/ へアクセス
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117615/794c6d73-136a-0da5-f532-488472718053.png)

*設定ファイル*
`/etc/nginx/conf.d/default.conf`

*デフォルトの公開ルート*
`/usr/share/nginx/html/`

# つまづいたとこ

vagrantの起動で何故かつまづきました。

* vagrant自体は起動していそう
* ssh接続ができない

という不思議な状況だったので、VirtualBoxを開いて確認したところ、`、"仮想化支援機能(VT-x/AMD-V)を～`とエラーがでたので、下記記事を参考に解決しました。

[Windows の Vagrant で 64 bit OS が起動しないとき](https://qiita.com/rch850/items/ba254063df4a9ff15354)


# 参考にした記事

[CentOS7にnginxを導入＆初期設定まとめ](http://vdeep.net/centos7-nginx)
CIについて

![Screen Shot 2017-11-04 at 19.12.59.png](https://qiita-image-store.s3.amazonaws.com/0/208636/d3a9108c-35c8-aed2-21fc-f6ca86c8ca5d.png)

#Travis CI
有名
![Screen Shot 2017-11-04 at 18.42.21.png](https://qiita-image-store.s3.amazonaws.com/0/208636/98d834af-0efa-98bb-ad27-c3f442b94154.png)

#Circle CI
travisについで有名
1Container無料で1Container増設毎に$50/月。
お金をあまり払わずに様子見できるのはこれ？
コンテナについてー＞https://qiita.com/minodisk/items/5151e780c56ecbc4d7ee

#codeship
![Screen Shot 2017-11-04 at 19.02.56.png](https://qiita-image-store.s3.amazonaws.com/0/208636/80196c0e-4311-c9d5-5099-f7c6e0cb464f.png)
MacのChromeでBurpSuiteのSSL証明書を追加する方法

Chromeのパケットをキャプチャしてごにょりたい時に使うBurpSuiteで最初にやる設定を書いておく。

いつも忘れるのでメモしておく。設定しないままだと以下の画面が出て怒られる。

![00_chrome_error.png](https://qiita-image-store.s3.amazonaws.com/0/103672/d80bac8a-5f45-ce1b-7200-41509eb2df56.png)

## 証明書をダウンロード

BurpSuiteを起動して`127.0.0.1:8080`でプロキシを起動しておく。

Google Chromeから`http://127.0.0.1:8080/`にアクセスする。ブラウザのプロキシ設定を忘れずに。

![01_local_burp.png](https://qiita-image-store.s3.amazonaws.com/0/103672/81ed0dfe-e513-c202-c5a1-7dc49928d16f.png)

右上の「CA Certification」をクリックして証明書をダウンロードする。

## 証明書の追加

Google Chromeの設定から「証明書の管理」をクリックする。

![02_chrome_setting.png](https://qiita-image-store.s3.amazonaws.com/0/103672/857c84b7-20c8-6e3f-ab49-01b73efcad68.png)

クリックすると以下のウィンドウが表示される。

![03_mac_setting.png](https://qiita-image-store.s3.amazonaws.com/0/103672/dd47d86a-7d6f-83f4-03d9-8410f87bb3db.png)

左側にある「キーチェーン」から「ログイン」を選択する。メニューの「ファイル」->「読み込む」をクリックする。

![04_add_cert.png](https://qiita-image-store.s3.amazonaws.com/0/103672/1f32dfb6-e276-4374-ae97-5abb8865344a.png)

ファイル選択ウィンドウが出るので、先程ダウンロードした証明書を選択する。うまく追加できると「**PortSwigger CA**」という証明書が追加される。

![05_added_cert.png](https://qiita-image-store.s3.amazonaws.com/0/103672/442e7e64-3856-0cb6-3eac-797acc0bdac7.png)

このままでは信頼されていない証明書であるため、信頼された証明書に変更する。

証明書にカーソルを合わせてショートカットメニューから「**情報を見る**」を選択する。

![06_set_allow_property.png](https://qiita-image-store.s3.amazonaws.com/0/103672/5c99b078-af25-d871-2ae7-f85adcd129c9.png)

以下のウィンドウが起動する。

![07_set_trusted.png](https://qiita-image-store.s3.amazonaws.com/0/103672/660ca368-c887-b356-b5e5-57a3f069639c.png)

設定値を「信頼」->「この証明書を使用するとき」より一括で「**常に信頼**」に変更する。

![08_finish.png](https://qiita-image-store.s3.amazonaws.com/0/103672/712af733-5109-913e-3593-f31b2a48c30b.png)

証明書「PortSwigger CA」が「この証明書はこのアカウントにとって信頼されているものとして指定されています」になってアイコンが変わっていれば設定完了。

---
Copyright (c) 2017 Tomoyuki KOYAMA
Released under the MIT license
http://opensource.org/licenses/mit-license.php
FlexとBisonをVisualStudio2017で使う

#はじめに
まず、flex と bisonを ダウンロードしてインストールしてください。

そして、パスを通す（環境変数Pathに、インストール先のbinファイルのパスを追加登録する）のですが、ここで注意！

実行ファイルがディレクトリC:\Program Files\GnuWin32\binとかにおいてあると、パス名にスペースがあるとbisonを実行したいときにエラーが出るので、C:\GnuWin32\binなどに移動してからパスを通してください。

つぎに、ふつうにflexファイルとbisonファイルを用意して、コマンドラインから実行してC言語のソースを作ってみてください。これが上手く行かないと、VisualStudioにもっていっても動かないです。

コマンドは、test.l、test.y をgccだと

```
flex test.l
bison -d test.y
gcc lex.yy.c test.tab.c -o test.exe -lfl
```

この際、-lfl はライブラリのリンクです。これは、libfl.a という lex のライブラリなので、gccに入れ解く必要があります。もし gcc を使っているのなら、先ほどインストールしたflex の、デフォルトなら "C:\Program Filess(x86)\GnuWin32\lib\libfl.a" にあるライブラリを gcc の C:\MinGW\lib にコピペしてください。べつにリンクしなくてもいいです。でも、その際はyywrap関数を（ほかにもあるかもしれない）自分で定義してください(.yのファイルに)。
例

```
int  yywrap(void) { return 1; }
```

あと、コンパイラが 'yylval' が見つからないというエラーを出す場合は、#include "任意の名前.tab.h" の直後に、

```
extern YYSTYPE yylval;　
```

を入れるといいらしいです。
#VisualStudioでビルドできるようにする

flexの（拡張子が .l ）ファイルを開き、#define YY_NO_UNISTD_H と追加してください。これは、unistd.h を使わないという意味で、visualstudio にはこれがついていないようです。

そして、追加したところの下あたりに、#include \<io.h\>、#define fileno _fileno、#define isatty _isatty を追加してください。（これで、gccではコンパイルできなくなりました！）ちなみに、io.h は、isatty 関数を使うためのヘッダーです。それぞれのdefineは、関数の名前がVSでは変更になったらしいので( isatty が _isattyとか )、関数の名前を置き換えているというわけです。

#visualstudio での設定


まず、VC++の空のプロジェクトを作ってください。

そして、先ほどコンパイルしたファイル(.cとか、.lとか、.yとか)を全部まとめて入れてください。

まずライブラリをリンクします。リンカー/全般の追加のライブラリディレクトリに、先ほどの libfl.a があるフォルダを追加して、リンカー/入力の追加の依存ファイルに libfl.a を追加してください。（しなくてもいいかもしれない）

ここまで来たら、あとはこの .l , .y ファイルをC言語のソースにして(flex, bison のコマンドを使う)、vs2017に読み込ませて、（改行タイプを聞かれると思うので、windowsのにして）、vs2017でコンパイルするだけです。

#ここから先、やんなくても動きます

bison,flexコマンドを打つ作業は「ビルドイベント」の「ビルド前のイベント」の「コマンドライン」に flex test.lとか bison -d test.y （test.l, test.yの場合）を追加すれば自動化できます。バッチファイルを作って呼び出してもいいかもしれません。

そして、flexは、lex.yy.c を作る際に改行コードが visualstudio のデフォルトと違います。これを、ビルドの段階で visualstudio の改行コードに直せます。これは、powershell のコマンドで出来ます。これもバッチファイルに書き加えてもいいかもしれません
einで数式表示

# Emacs上のJupyter/IPython client Einで数式の表示

## 目標
Emacs上のJupyter/IPython clientであるEinを使って，Markdownで書かれた部分に記述されたLaTeX形式の数式をしかるべく表示する．

## いるもの
* Emacs
* LaTeX
* Jupyter/IPython
* ein
* latex-math-preview
* ein-preview-latex (https://github.com/andreasjansson/ein-preview-latex)
* git

## 手順
前提として，Emacs, LaTeX, Jupyterが使えるようになっていること．筆者はWindows 10上のEmacs 25.2.1で検証した（(https://github.com/chuntaro/NTEmacs64)）． LaTeXはTeXLive 2017, JupyterはAnaconda 4.3.27にそれぞれ同梱のものである．

1. Einをinstallする．melpaからpackage-installする．
2. latex-math-previewをinstallする． melpaからpackage-installする．
3. ein-preview-latexをinstallする．melpaには無いようなので，上記のgithub repoをcloneする．

## 使い方
einの使い方は右の記事が参考になる：[podhmo's diary EIN(Emacs IPython Notebook)を試してみる](http://pod.hatenablog.com/entry/2017/08/06/220817)
Jupyterを起動して，コンソール画面に出るログイントークンをコピーしておく．ログイントークンというのは，コンソール画面に表示される以下のURLのxxxの部分（実際にはalpha-numericな乱数列）：
```
http://localhost:8888/?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

emacs上で ```M-x ein:notebooklist-login``` して，パスワードを求められたら，上でコピーしておいた文字列をペーストする．あとは，Jupyterのノートブック一覧が現れるので，Markdownに数式（LaTeXの形式の）が含まれるノートブックを開いて確認する．

![スクリーンショット 2017-11-04 16.40.25.png](https://qiita-image-store.s3.amazonaws.com/0/211066/aa5b1a3d-b68b-1c11-a293-8a9fbd3ea2dd.png)
Pry

# 使えるpryコマンド
今まで、```next,step,exit,finish,continue```コマンド打って、変数の値や、返り値などを確認するぐらいしか使ってなったので、他に便利のコマンド、方法がないか調べてみた。

## エイリアス
案外打つのめんどくさかったりするので

```~/.pryrc
if defined?(PryByebug)
  Pry.commands.alias_command 's', 'step'
  Pry.commands.alias_command 'n', 'next'
  Pry.commands.alias_command 'f', 'finish'
  Pry.commands.alias_command 'c', 'continue'
  Pry.commands.alias_command 'w', 'whereami'
end
```

## editコマンド
```edit [method名] or [class名] or [ファイル名]```
指定したメソッドなどが、編集できる。リアルタイムでコードを編集したい場合便利かも。編集後自動でリロードされる。変更した値が読み込まれる。

``` ~/.pryrc
Pry.config.editor="subl"
# Pry.config.editor="vim"
```
このように書いとくと、editで立ち上がるエディターを自由に決められる。
sublimeの場合、編集が終わったら、ファイルを閉じないと、pryの待ち状態が続く。
また現在いるメソッドを編集しようとすると、編集してもうまく読み込みされない。
なんでだろう。。

## ループの上のpry
繰り返し処理の中にpryを仕込んだ時、
何をやってもループが抜けられない場合がある。```exit!```などで抜けられるが
スクレイパー実行時にやっちゃうと、次同期する時、めんどくさいのでやらないほうがよい。

``` !!! ```

これやると同期がリセットされて、何事もなかったかのようにpryを終了させられる。

```binding.pry unless @stop ```
で仕込んで、@stop = true とやって、exitやcontinueなどすると抜けられる。
これは、2つ以上pry仕込んだ時に、ループは抜けたいんだけど、pry自体は終わらせたくない時には使えそう。

## show-method とか whereami

```show-method メソッド名```
この行、まだ実行したくないんだけど、どういうメソッドなのか見たい時に便利。
stepとかやっちゃうと処理が進んでしまうので。
```whereami```
は、でかい配列とかをpryで出力させた場合に、今コード上のどこに居たんだっけってなるのでwheremiで周辺のコードを再出力。

## show-trace
stack-traceがたどれて、```frame 行番号```でそこにジャンプできるらしいが、
現CFO-alpha(10/13)では、できなかった。

## ```cd,ls```コマンド
いまいち使い所がまだわからない
Kotlin入門(1)開発環境

友達にKotlinを説明したくてネットを探してみてもあまりいい入門用の文がなかったので自分なりに[Kotlinのホームページ](https://kotlinlang.org/)からまとめてみました。
（ホームページの省略されたリンクが[kotl.in](http://kotl.in)ってっかっこいいですねｗ）

# 開発環境
Intellij IDEAでやるのが一番おすすめです。
他のやり方もありますが多分一番かんたんです。

インストールの仕方については他のサイトなどに色々あるので見てみてください。（気が向いたら書くかも）

# プロジェクトの作成
**Kotlin** -> **Kotlin/JVM** を選択して**Next**

![Kotlin -> Kotlin/JVM](https://qiita-image-store.s3.amazonaws.com/0/194432/2ace4ea2-2597-5845-7a6d-58850b129ccc.png)


**Project name** にプロジェクトの名前を入れて**Finish**

![set project name](https://qiita-image-store.s3.amazonaws.com/0/194432/835f76ca-89d6-244e-a38c-51dd797b0146.png)

# Hello World
定番のHello Worldから始めていきましょう
**(プロジェクト名)/src**で右クリック。
**New -> Kotlin File/Class**を選択
**Name**を**HelloWorld.kt**にしましょう

![Set File Name](https://qiita-image-store.s3.amazonaws.com/0/194432/455e1c80-3770-08ce-02d1-1aab363a6eb1.png)

## とりあえず書こう
コピペはあまりおすすめしません
めっちゃ自動補完してくれるのでそれに頼って行きましょう(今回はあまりないかも)

```kotlin
fun main(args: Array<String>){
    println("Hello World!")
}
```
※大文字小文字には気をつけてください

## とりあえず実行
編集画面を右クリックして**「Run 'HelloWorld.kt'」**をクリック

```
Hello World!
```
上のように表示されればOK!

# 次回
[変数について](https://qiita.com/pe-Daniel/items/a87ac42f76124064b4b4)
テスト駆動開発(TDD)

# TDD(テスト駆動開発)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/200131/70438680-5055-5c82-c762-ac00037cd57b.png)

最近、テスト駆動開発で有名なt_wadaさんのワークショップに参加しました。
テスト駆動開発？いまさら？と思うでしょうが、自分にとっては新しい知識だったので、まとめてみました。

## TDD(テスト駆動開発)とはなにか
[wikipediaより](https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)
> プログラム開発手法の一種で、プログラムに必要な各機能について、最初にテストを書き（これをテストファーストと言う）、そのテストが動作する必要最低限な実装をとりあえず行った後、コードを洗練させる、という短い工程を繰り返すスタイルである。

## TDD(テスト駆動開発)の何がいいか？
![image.png](https://qiita-image-store.s3.amazonaws.com/0/200131/4a5ef910-fef5-a621-785c-d93ea9219ee7.png)


目指すべきコードが、

-  **動作する** 
-  **綺麗なコード** 

であった場合。そこに到達する方法は２通りある。

1. しっかり設計してから、実装する。(赤い矢印)　→ 従来の手法
2. 汚くてもいいから実装から入り、コードを洗練させていく。(青い矢印)　

それぞれ罠がある!!!

<1の場合の罠>

- 「きれいで動かない」という状態から抜けられない。<br>
    → つまり、「きれいな設計にしたい」という欲求から抜けられない。完璧を求めてしまう。
- システム開発にはスケジュールがある。
- コードを書き始めてから、いろいろ分かり始める。<br>
   →　「ここまで設計する必要は無かった」とか「きれいな設計だけど遅すぎて使えない」とかが分かり始める。
- ソフトウェア開発は登場人物が多すぎるので、予測が立ちにくい。<br>
→　手を動かしてみて初めてわかる。

<２の場合の罠>

- 動くけど汚いシステムが出来上がる。
- 綺麗にするのは、後回し。とりあえず動いたんだからいいじゃん。という怠慢が生まれる。
- 新しい機能の追加が優先される。
- 結果、とんでもなく保守性の低いコードが出来上がる。
- 最初はまだいいが、膨れ上がると手をつけられなくなる。

##### **TDDは、黄金の回転を細かく早く回すことで、心理的な苦痛であった、綺麗なコードに直すというところを突破する(黄色矢印)** 

## 黄金の回転
![image.png](https://qiita-image-store.s3.amazonaws.com/0/200131/07f53a7d-5b70-8d80-08b4-7bf890846d31.png)


 **TDDのサイクル(黄金の回転)** 
・TDDでは、テストコードとプロダクトコードを交互に書きながら進めていく。
・TDDとは、サイクル。
・まず、「やることリスト」を作る。
・そこから１つだけ、やりたいことをピックアップする。
・そのテストコードを書く。
・テストコードを動かすと、プロダクトコードを実装してないので絶対に失敗する。（赤色になる）
・目的のコードを書く。テストを通すことを第一に考える。
・さっき書いたテストが成功する。（緑色になる）
・目標を満たす状態になったので、今度はコードの方をきれいに直すフェーズになる。それがリファクタリング。


## TDDの基本テクニック

### テストファースト 
### 仮実装(テストのテスト)

いきなり本格的なコードから入ると、テストに失敗した時にテスト自体がおかしいのか？、それとも実装したコードがおかしいのか？、判別できなくなる場合があるので、必ず仮実装をして、テストを通過させる。

### 三角測量(Triangulation)

そのテストがたまたま通過したということが起こらないように、状況によって、２つ以上の値を使用しテストを書く。
先ほどの仮実装は、この三角測量でテストに落ちるはず（想定内のエラー）なので、明白な実装へと進む。

### 明白な実装(Obvious Implementation)
仮実装で、テストのテストが済んだら、
本格的な実装に入っていく。

## 実際どう書くか？