OmniAICreator/Qiita-1.07M huggingface dataset:
Javaでゲームを作るためのSwingの基礎サンプル

#概要
自分の確認用に製作したSwingの基礎を説明したサンプルコードです。Javaでゲームを作ろうとしている初心者(=俺)に向けて、少しでも参考になればと思った次第です。

プログラム自体は赤い矩形が大きくなったり小さくなったりする、ごく単純なプログラムなのですが、
JFrame や JPanel、Event取得やThread等、おおよそゲーム製作に必要になるであろう技術を可能な限り簡潔に詰め込みました。

##BasicDrawing.java
~~~
/*
    javax.swing における 2D描画の基礎
*/

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.BorderLayout;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;

//JFrame を継承
public class BasicDrawing extends JFrame{
    public static void main(String args[]){
        BasicDrawing frame = new BasicDrawing("ゲーム画面");//引数はWindow Title
        frame.setVisible(true);
    }

    //constructor. フレームの設定関係を行う
    BasicDrawing(String title){
        setTitle(title);
        setSize(640,480);
        setLocationRelativeTo(null);//初期画面表示位置を中央に
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//CLOSEでプログラム終了

        Container CP = getContentPane();//getContentPane()はJFrameクラスに定義されている
        //CP.setLayout(null);//レイアウトマネージャを停止

        //上部の背景色を橙に設定する
        JPanel panel = new JPanel();
        panel.setBackground(Color.ORANGE);
        CP.add(panel, BorderLayout.NORTH);

        //Mainパネルの作成、フレームへのセット
        MainPanel MP = new MainPanel();
        CP.add(MP);
        //CP.remove(MP);//フレームを外す
        addKeyListener(MP);//KeyListenerをフレームにセット
        //CP.removeKeyListener(MP);//KeyListenerを外す
    }
}

class MainPanel extends JPanel implements Runnable, KeyListener{
    int x = 100, y = 100;
    boolean state = true;
    Thread t;

    MainPanel(){
        //setLayout(null);
        setBackground(Color.blue);//背景色を青に
        t = new Thread(this);//Thread instance
        t.start();//Thread Start
    }

    //Runnableによるrun() method
    public void run(){
        //無限ループでThreadが終了しないようにする
        while(true){
            //矩形の大きさを変更する
            if(x < 300 && state){
                x++;
                y++;
            }
            else if(x > 0 && !(state)){
                x--;
                y--;
            }

            try{
                t.sleep(100);//100ms毎に実施
            }catch(InterruptedException e){}

            repaint();
        }
    }

    //JComponentによるpaintComponent method
    //JPanel は JComponent を継承している
    public void paintComponent(Graphics g){
        //赤い矩形を描画する
        g.setColor(Color.red);
        g.fillRect(x, y, 20, 20);//引数は(X座標,Y座標,Width,height)
    }

    /**********************
        KeyEvent
    **********************/
    //Keyが押された場合
    public void keyPressed(KeyEvent e){
        switch(e.getKeyCode()){
            case KeyEvent.VK_SPACE:
            case KeyEvent.VK_A:
                System.out.println("KeyPressed");
                if(state)state = false;
                else state = true;
                break;
        }
    }

    //Keyが離された場合
    public void keyReleased(KeyEvent e){}

    //Keyが押された場合
    public void keyTyped(KeyEvent e){}
}
~~~
##実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/121172/5d7e3a67-bf19-a628-b221-c4b3960269c2.png)

###追記
ご指摘いただいた実行結果の画像を追加。
ソース内keyReleasedとkeyTyped関数をコメントアウトするとエラーを吐くので訂正しました。
GitHubのコンフリクト　※自分用メモ

GitHubコンフリクト(一番簡単)
1.該当のリポジトリ(issue-1とか)でgit pull origin master(develop)
2.HEADと他を削除する。’’’’ ‘’' は残す？
3.git add .
4.git commit -m “update_text"
5.git push origin issue-1
※コケたら -f OK？

reverse
コミットが綺麗になる。
http://www.karakaram.com/git-rebase-i-usage
jupyter の nbextension, nbextensions_configurator の導入コマンド

nbextensions , nbextensions_configurator のインストール

こいつをインストールします。
https://github.com/ipython-contrib/jupyter_contrib_nbextensions


##まず、nbextensions_configurator (ブラウザ上の jupyter で nbextensionの切り替え等ができる)のインストール

```shell-session
$ pip install jupyter_nbextensions_configurator
$ jupyter nbextensions_configurator enable --user
```

##nbextensionがいっぱい入ったパックをインストール

```console
$ pip install https://github.com/ipython-contrib/jupyter_contrib_nbextensions/tarball/master
$ jupyter contrib nbextension install --user
```
おわり！

nbextension すごい便利ですね！
MongoDB 3.2で設定サーバ(configサーバ)をレプリカセットで立てるメモ

MongoDB 3.2から設定サーバ(configサーバ)はレプリカセット構成になった。なので、configサーバの立て方が以前と少し違う。どこにもコマンド例がなかったため、備忘録として残しておく。


### configサーバを3台レプリカで組む

configサーバを起動するときは、`--configsvr`に加えて`--replSet (レプリカセット名)`のオプションもつけなくてはいけない

コマンド例

```
$ ./bin/mongod --configsvr --replSet rsConfig --dbpath config00 --logpath config00.log --port 30000 --fork

$ ./bin/mongod --configsvr --replSet rsConfig --dbpath config01 --logpath config01.log --port 30001 --fork

$ ./bin/mongod --configsvr --replSet rsConfig --dbpath config02 --logpath config02.log --port 30002 --fork
```

そして、この３台でクラスタを組む。どこか一台に入ってrs.initiate

コマンド例

```
mongod> rs.initiate(
   {
      _id: "rsConfig",
      version: 1,
      members: [
         { _id: 0, host : "127.0.0.1:30000" },
         { _id: 1, host : "127.0.0.1:30001" },
         { _id: 2, host : "127.0.0.1:30002" }
      ]
   }
)
```

### configサーバを3台レプリカにmongosルータから接続する

そして、mongosルータから繋ぐ場合は以下のようにレプリカセットを指定する

コマンド例

```
$ ./bin/mongos --configdb "rsConfig/127.0.0.1:30000,127.0.0.1:30001,127.0.0.1:30002"  --logpath mongos00.log --port 31000 --fork

```
React.jsで"Unknown prop"に立ち向かう

# はじめに
React.jsを使っていて、こんなことを言われたことはないだろうか

```
Warning: Unknown prop `webkitdirectory` on <input> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
```

Chromeでしか使えないプロパティにつく接頭辞"webkit"ではあるが、使えてほしい。

# tl;dr
render()では該当するattributeを書かず、componentDidMountで追加すれば良い

# ISSUEを確認してみる

[ISSUE#3468: JSX render won't allow webkitdirectory and directory to be used](https://github.com/facebook/react/issues/3468)

まさにこれ

とりあえずwhitelistに書かれたプロパティしか認めてないから、それ以外はunkonws propらしい
多くのcomponentが子要素にプロパティを渡しすぎているから、[ISSUE#140](https://github.com/facebook/react/issues/140)にあるけどしばらく修正不可らしい

でも、[ISSUE#3468](https://github.com/facebook/react/issues/3468)の中に、解決された、と参照されているPRがある。

[PR#3644: Add webkitdirectory and nwdirectory attributes for input file](https://github.com/facebook/react/pull/3644)

Merged！？とおもいきや一番下でReverted...

理由は

- たとえ本来のプロパティ名がキャメルケースでなくても、reactでは全てキャメルケースにしている
- まだ標準ではないし、むやみにサポートするべきでもない

とのこと

う〜んわかるけど使いたい！！！

# 解決策

render()では該当するattributeを書かず、componentDidMountで追加すれば良い

```js
"use strict";

import React from 'react';
import ReactDOM from 'react-dom';

export default class FileInput extends React.Component {
    componentDidMount() {
        let node = this._input;
        node.webkitdirectory = true;
        node.directory = true;
    }
    render() {
        return (
            <input type="file" ref={(c) => {this._input = c;}} {...this.props} />
        );
    }
}
```

闇の方法だけど成功😇

# おまけ

ボタンを装飾する

![スクリーンショット 2016-09-01 14.11.19.png](https://qiita-image-store.s3.amazonaws.com/0/77778/ca2d4375-f83f-576f-5f02-e477bab1801e.png)

コードは以下

```js
"use strict";

import React from 'react';
import ReactDOM from 'react-dom';

export default class FileInput extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            hover: false
        };
    }
    componentDidMount() {
        let node = ReactDOM.findDOMNode(this.refs.filesInput)
        node.webkitdirectory = true;
        node.directory = true;
    }
    onMouseEnter() {
        this.setState({hover: true});
    }

    onMouseLeave() {
        this.setState({hover: false});
    }
    render() {
        let labelStyle = {
            color: "brown",
            backgroundColor: "transparent",
            border: "solid 2px brown",
            boxSizing: "border-box",
            padding: 20,
            borderRadius: 12
        }
        let hoverLabelStyle = {
            color: "white",
            backgroundColor: "brown",
            border: "solid 2px brown",
            boxSizing: "border-box",
            padding: 20,
            borderRadius: 12
        }
        return (
            <label htmlFor="file-input" style={this.state.hover ? hoverLabelStyle : labelStyle} onMouseEnter={this.onMouseEnter.bind(this)} onMouseLeave={this.onMouseLeave.bind(this)}>
                ＋フォルダを選択
                <input type="file" id="file-input" ref="filesInput" style={{display: "none"}} {...this.props} />
            </label>
        );
    }
}
```
CentOS7をHyper-Vの仮想マシンにインストールしてインターネットに接続する

##インストールするもの
- CentOS 7.2.1511
- Tera Term 4.91

##作業環境
- Windows10 Enterprise 2015
- Hyper-Vマネージャー 10.0

##Hyper-Vの起動
1. 以下のように進む  
コントロールパネル → プログラム → Windowsの機能の有効化または無効化
<br>  
2. Hyper-Vのチェックボックスをonにする
<br>  
3. Hyper-V マネージャーを起動

##Hyper-Vマネージャーで新しい仮想マシンを登録
1. ナビゲーションウィンドウ（いちばん左の枠）からPCを選択し、右クリック<br>
新規→仮想マシン<br>
![01.png](https://qiita-image-store.s3.amazonaws.com/0/36301/0a330732-d2a8-646e-7830-60768c0f37f9.png)
<br>  
2. ウィザードに従い、設定する  
 - 仮想マシンの名前と保存場所: 任意
 - 世代: 第1世代
 - 起動メモリ: 512MB（GUIを使うなら1G以上）
 - ネットワークの構成: あとで設定するので「接続しない」
 - 仮想ハードディスクの接続: 仮想ハードディスクを作成する
 - インストールオプション: 後でオペレーティングシステムをインストールする

##CentOSをダウンロード
https://www.centos.org
Get CentOS Now へ進み、任意のISOをダウンロードする。
今回は minimal ISO にしました。

##CentOSをインストール
1. 仮想マシンを右クリック → 設定 → IDEコントローラー1
<br>  
2. 「DVDドライブ」に、先ほどダウンロードしたCentOSのISOを選択
<br>  
3. 起動
<br>  
4. 画面に従って、言語などを選択してインストールする
<br>  
5. rootパスワードを設定
<br>  
6. ユーザ、グループ、権限の設定をしたほうが良い  
（ユーザ管理についてはこちらのサイトなどを参考に…）  
https://www.server-world.info/query?os=CentOS_7&p=initial_conf<br>
https://centossrv.com/centos7-init.shtml
<br>  
7. Hyper-Vで仮想マシンを右クリックして「保存」。ネットワークの設定をしていく

##仮想マシンをインターネットに接続する
1. 仮想スイッチマネージャーをクリック<br>
![02.png](https://qiita-image-store.s3.amazonaws.com/0/36301/bd2f6bd7-929a-2e48-c514-e1030f244aee.png)
<br>  
2. 新しい仮想ネットワーク　スイッチ<br>
「内部」を選択 → 仮想スイッチの作成<br>
![03.png](https://qiita-image-store.s3.amazonaws.com/0/36301/625917c9-a91a-7da4-653f-906314875e74.png)
<br>  
3. 名前をつけて「OK」<br>
名前は任意。SwitchForCentOS など。
<br>  
4. Windowsボタン（画面の左下）を右クリックしてコントロールパネルを開き、以下のように進む<br>
![04.png](https://qiita-image-store.s3.amazonaws.com/0/36301/ae374a8a-803a-e55d-2f56-d07f5e3e02ee.png)<br>
ネットワークとインターネット→ネットワークと共有センター→アダプターの設定の変更
<br>  
5. イーサネットとブリッジ接続<br>
**！注！この作業によって一回ネットが切れます**<br>
2つを同時に選択し、右クリックして「ブリッジ接続」<br>
![05.png](https://qiita-image-store.s3.amazonaws.com/0/36301/22ec09ca-34d6-d663-29da-3762000ca184.png)
<br>  
6.　Hyper-Vマネージャーで、仮想マシンを右クリック<br>
「ネットワークアダプター」で仮想スイッチを選択。

##Teratermから仮想マシンを操作する
1.　Teratermをインストール
https://osdn.jp/projects/ttssh2/
　　
2.　Hyper-V 仮想マシンからDVDを取り出して起動する
（IDEコントローラー1の設定を最初に戻す）
起動しても画面が表示されなければ、下の方の黒い画面の部分をダブルクリック。
  
3.　rootでログインする
別のユーザでログインしていたら
`su`
戻るときは
`su -u ユーザ名`

4.　IPアドレスを調べる
`ifup eth0`
`ip addr`

5.　Tera Termを起動し、ホストに4.のIPアドレスを入力
  
6.　CentOSで設定したユーザ名とパスワードでログイン

##LAMP環境の構築
ここにLAMP環境を構築します。
http://qiita.com/como96/items/cc3682e52f1a62a84536
8/30　今日の学習内容～正規表現について学習～

###今日の学習内容
***
今日はRubyの正規表現について学習しました(-ω-)/

>**正規表現**とは、文字列の中から特定のパターンを見つけ出すための構文です。
[改訂３版基礎Ruby on Rails ](https://www.amazon.co.jp/dp/4844338153)84ページより


　
　
　
正規表現のリテラル（数字の1や文字列"hello world"のようにRubyのプログラムの中に直接 記述できる値の事。[リテラル（Ruby 2.1.0）](http://rurema.clear-code.com/2.1.0/doc/spec=2fliteral.html)）は``/``で囲って書きます。

例えば、``name = /yamada/``のように書くわけですね。
こう書かれているとき、変数``name``はRegexpクラスのオブジェクトです。
>[class Regexp(Ruby 2.2.0)](http://docs.ruby-lang.org/ja/2.2.0/class/Regexp.html)

パターンをチェックするときには**``=~``演算子**を使います。
 
``~=``にしないように気を付けてください(-ω-)/
``!=``や``<=``などと違って、**``=``が先です!**
私はpaiza.IOでテストするまで気が付きませんでした(笑)

下記のように書いてみると、

```ruby:test.rb
name = "tanakayamadasatou"
if name =~ /yamada/
   puts "yamada発見!"
end
```

実行結果↓

```
yamada発見!
```

![paiza_io_2.png](https://qiita-image-store.s3.amazonaws.com/0/137880/b3ffc7b3-ac21-0784-795a-2aec58a9362f.png)


となります。

ちなみに、``/``でなく、``%r{}``や、``%r<>``などでも同じ結果になります。

![paiza_io_3.png](https://qiita-image-store.s3.amazonaws.com/0/137880/32e24d76-de8b-6536-3371-cb725a36297f.png)

 
![paiza_io_4.png](https://qiita-image-store.s3.amazonaws.com/0/137880/4c77f733-44e2-b6da-47b3-71a522e5cd60.png)


 



###あとがき
***

今日も全然進んでないですね(笑)
次回も正規表現について学習していきたいと思います。
同時にHTML、CSS、JavaScriptも学習しているのですが、こちらもなかなか覚えられないですね(;'∀')
JavaScriptからCSSのプロパティを操作するところで四苦八苦しておりました(笑)
何かいい学習法があればいいんですが...(´-ω-`)

拙い文章ですが、ここまで読んでいただきありがとうございました(*- -)(*_ _)ペコリ

###参考にさせていただいたサイトなど
***
>[改訂３版基礎Ruby on Rails (Amazonのページ)](https://www.amazon.co.jp/dp/4844338153)
[Rubyリファレンスマニュアル　リテラル（Ruby 2.1.0）](http://rurema.clear-code.com/2.1.0/doc/spec=2fliteral.html)
[Rubyリファレンスマニュアル　class Regexp(Ruby 2.2.0)](http://docs.ruby-lang.org/ja/2.2.0/class/Regexp.html)
[paiza.IO](https://paiza.io)
RailsでRiot.jsメモ


*参考*
+ http://www2.ver1000000.com/blog/posts/25


とりあえずSPAじゃない、部分的にRiot.js使うのできた。

### 下準備
```Gemfile
source 'https://rails-assets.org' do
  gem 'rails-assets-riot'
end
```

```application.js
//= require riot
```

```
$ npm install riot -g
$ mkdir app/riot app/assets/javascripts/riot
$ riot -w app/riot app/assets/javascripts/riot
```

`riot -w` でapp/riot配下のtagファイルの変更がある度にassets配下にコンパイルされたjsファイルが書き出す。

### 呼び出し方
```xxx.html.erb
<h1>Dashboard#index</h1>
<p>Find me in app/views/dashboard/index.html.erb</p>
<%= link_to 'Items', items_path %>

<todo></todo>

<script>riot.mount('todo', { title: 'TODO Title' })</script>
```

```todo.tag
<todo>
  <h3>{ opts.title }</h3>

  <ul>
    <li each={ item, i in items }>{ item }</li>
  </ul>

  <form onsubmit={ add }>
    <input>
    <button>Add #{ items.length + 1 }</button>
  </form>

  this.items = []

  add(e) {
    var input = e.target[0]
    this.items.push(input.value)
    input.value = ''
  }
</todo>
```

でとりあえず動かすところまでいけた。
たまに思い出して使いたいAndroidStudioショートカットキー（Mac）

個人的に時々使うけどよく忘れるショートカットキーをまとめます

| | コマンド |
|:-:|:-:|
|インポート文最適化|ctrl + alt + o   |
|リネーム   |shft + F6   |
|大文字小文字入れ替え   |cmd + shift + u   |
|ブックマーク：つける   |F3   |
|ブックマーク：見る   |cmd + F3   |
|行の入れ替え   |cmd + shift + ↑or↓   |
|コードフォーマット|cmd + alt + L|
Emacsで、特定の文字の色を変更する

Emacsで、特定の文字の色を変更したいと思うことがある。
例えば以下の画面。

<img width="1273" alt="スクリーンショット 2016-08-30 22.24.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/9369d80b-56a4-263f-3592-67d48ae716a5.png">

明らかに"main"の部分だけ色が薄くて見づらい。
以下、このように特定の文字の色だけをいい感じに変更するための手順。


# 1. **当該文字のfaceを調べる**
Emacsの文字や背景の色は、「face」という名称で管理されている。
そのfaceを知るためのコマンドが、

```
M-x describe-face
```

である。
色を変えたい文字列の上にカーソルがあることを確認したうえでこのコマンドを実行する。
すると、その文字列のfaceが何かがミニバッファに表示される。
***
<img width="620" alt="スクリーンショット 2016-08-30 22.33.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/00782c36-4885-06eb-d07f-675a1f82a455.png">
***
"main"の部分のfaceは、「font-lock-function-name-face」であることが分かった。

# 2. **faceの設定を変更**
文字列のfaceが分かったので、今度はそのfaceの設定を変更する。
そのためにまず、Emacsで設定されているfaceの一覧を表示させる必要がある。
それを行うためのコマンドが、

```
M-x list-faces-display
```

である。
早速実行してみると、

<img width="1274" alt="スクリーンショット 2016-08-30 22.39.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/79e32997-f9b0-3830-5771-2771231e6c81.png">

このように新しいバッファができ、face名とそれに対応する文字の色・背景色が一覧になって表示される。
このバッファ上で先程の「font-lock-function-name-face」を検索する。

<img width="799" alt="スクリーンショット 2016-08-30 22.42.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/298d81c0-3a0a-6fd8-af2b-cf6492cffa39.png">

見つかった。
確かに現在はとても見にくい薄緑色になっている。

これを見やすい色に変更するためには、まず当該face上にカーソルがあることを確認したうえでEnter。

<img width="737" alt="スクリーンショット 2016-08-30 22.44.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/cd3ba31c-1406-d57b-bb5b-c55c613bd5d0.png">

するとそのfaceの現在の設定の詳細が表示される。
今は文字の色を変更したいので、下から2行目のForegroudの[Choose]の上にカーソルを移動させ、Enter。

<img width="1274" alt="スクリーンショット 2016-08-30 22.46.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/9922e293-8b7b-c278-aded-6680be6e9a5e.png">

すると上図の通り色の一覧が別のバッファ上に表示されて、ミニバッファ上には

```
Click on a color to select it.
```

と表示されるはず。
この色の一覧の中から自分が気に入った色を選べばよい。
試しにcyanを選択してみる。
cyanの上にカーソルを持ってきてEnter。

<img width="1274" alt="スクリーンショット 2016-08-30 22.52.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/3b83d62f-dce8-82cb-b11f-406653521b5a.png">

このように元のfaceの詳細画面に戻るので、ここで```C-x C-s```により```~/.emacs.el```を上書き保存する。

以上で完了。元の画面に戻って色を確認してみる。
***
<img width="364" alt="スクリーンショット 2016-08-30 22.55.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/88804/a07edd38-1f2b-40e5-c385-5cc111ba35f0.png">
***
"main"の部分がちゃんとcyan色になった。大成功。

この方法により、Emacs上から眼に悪い色の組み合わせを排除することが出来る。


# **参考URL**
http://futurismo.biz/archives/1322
http://kakakikikeke.blogspot.jp/2014/09/emacsface_10.html
Digdagのワークフローの中で他のワークフローを呼び出し実行する

みなさま、こんばんわ。本日の我が家の夕食はカレーでした。
今日はカレー食べたことだし、digdagのワークフロー定義するdigファイル書く

##実行環境は前回作成したもの
>5分でDigdagインストールしてワークフロー実行まで試してみる
>http://qiita.com/namihitoo/items/ba259ad5fa682ee274b6

##参考資料
* Getting started（毎度おなじみお世話になります）
 - http://www.digdag.io/index.html

##Let's Try
テスト用にdigファイルを2つ作成

```digdag_one.dig 
timezone: UTC

+step1:
  sh>: echo "step1"

+step2:
  !include : 'digdag_two.dig'

+step3:
  sh>: echo "End"
```

```digdag_two.dig 
timezone: UTC

+step_other:
  sh>: echo "step2"
```



  
  
  
localモードで実行
digファイル書いて試しに実行したい時は毎回pushしたりserver modeで起動しなくていいのね(汗

* 参考
 - http://www.digdag.io/architecture.html?highlight=server%20mode




```
[root@vagrant-centos65 digdag_test]# digdag run digdag_one.dig
2016-08-30 13:42:34 +0000: Digdag v0.8.11
2016-08-30 13:42:36 +0000 [WARN] (main): Using a new session time 2016-08-30T00:00:00+00:00.
2016-08-30 13:42:36 +0000 [INFO] (main): Using session .digdag/status/20160830T000000+0000.
2016-08-30 13:42:37 +0000 [INFO] (main): Starting a new session project id=1 workflow name=digdag_one session_time=2016-08-30T00:00:00+00:00
2016-08-30 13:42:38 +0000 [INFO] (0016@+digdag_one+step1): sh>: echo "step1"
step1
2016-08-30 13:42:38 +0000 [INFO] (0016@+digdag_one+step2+step_other): sh>: echo "step2"
step2
2016-08-30 13:42:38 +0000 [INFO] (0016@+digdag_one+step3): sh>: echo "End"
End
Success. Task state is saved at .digdag/status/20160830T000000+0000 directory.
```



ちなみに、一度ワークフロー実行すると、sessionに成功した情報が残るので、連続してlocalモードで実行すると処理がSkipされるよ

```
[root@vagrant-centos65 digdag_test]# digdag run digdag_one.dig
2016-08-30 13:45:28 +0000: Digdag v0.8.11
2016-08-30 13:45:31 +0000 [WARN] (main): Reusing the last session time 2016-08-30T00:00:00+00:00.
2016-08-30 13:45:31 +0000 [INFO] (main): Using session .digdag/status/20160830T000000+0000.
2016-08-30 13:45:31 +0000 [INFO] (main): Starting a new session project id=1 workflow name=digdag_one session_time=2016-08-30T00:00:00+00:00
2016-08-30 13:45:31 +0000 [WARN] (0016@+digdag_one+step1): Skipped
2016-08-30 13:45:31 +0000 [WARN] (0016@+digdag_one+step2+step_other): Skipped
2016-08-30 13:45:31 +0000 [WARN] (0016@+digdag_one+step3): Skipped
Success. Task state is saved at .digdag/status/20160830T000000+0000 directory.
```


`.digdag/status`の配下にymlが吐かれるみたい

```
[root@vagrant-centos65 digdag_test]# ls -lR .digdag/status/20160830T000000+0000/
.digdag/status/20160830T000000+0000/:
total 20
-rw-r--r-- 1 root root 153 Aug 30 13:45 +digdag_one+step1.yml
-rw-r--r-- 1 root root 164 Aug 30 13:45 +digdag_one+step2+step_other.yml
-rw-r--r-- 1 root root 153 Aug 30 13:45 +digdag_one+step2.yml
-rw-r--r-- 1 root root 153 Aug 30 13:45 +digdag_one+step3.yml
-rw-r--r-- 1 root root 147 Aug 30 13:45 +digdag_one.yml
```

ファイル中身はこんな感じ

```
[root@vagrant-centos65 digdag_test]# cat .digdag/status/20160830T000000+0000/+digdag_one+step1.yml 
fullName: "+digdag_one+step1"
state: "success"
result:
  subtaskConfig: {}
  exportParams: {}
  storeParams: {}
  report:
    inputs: []
    outputs: []
```

以上!
WordPressにSNSアカウントでのログイン機能を実装できる和製プラグイン「Gianism」でTwitterログイン時のユーザーIDから「@」を除去

# Gianism とは

[Gianism](https://ja.wordpress.org/plugins/gianism/)とは[高橋文樹](http://takahashifumiki.com/)さんが制作されたFacebookやTwitterなどのSNSアカウントでWordPressにユーザー登録できるようにするプラグインです。

# 各SNSアカウントから登録した際のユーザーID

Facebookから登録した際のユーザーIDは**`fb-nnnnnnnn`**、Twitterアカウントからだと**`@twitterid`**（その他は試してない）。

**ユーザーIDに@が入るのはなんとなく気持ち悪い……。**

# 解決策

```php:functions.php
// ユーザーIDから「@」を削除
function gianism_twitter_login($twitter_id){
  if(!empty($twitter_id)){
    return str_replace("@", "", $twitter_id);
  }
}
add_filter('pre_user_login', 'gianism_twitter_login');
```

上記のように`pre_user_login`を使えば、ユーザー登録時、IDがDBに登録される前にフィルターを通すことができます。

なぜかこれが全然思いつかなくて、高橋さんにプラグインの機能として実装されていないか問い合わせたところ、親切にプラグインとは全然関係ない`pre_user_login`を教えていただいて無事解決しました。
PowerShellコマンドレットのオプションをGUIを利用して指定する

# はじめに

PowerShell のコマンドレットのオプションを指定する際、
オプションをあまり覚えていない場合は、ネットで調べたり、
`Get-Help コマンド名` (Linuxでいうman)のようにヘルプを表示したり
すると思います。

別の方法として、PowerShell 3.0 から `Show-Command コマンド名`と打つことで、
オプション指定を支援するための画面が表示されるようになっています。

# 手順

たとえば、`Invoke-WebRequest` という `wget` や `curl` のようなコマンドの場合、
以下のように実行します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/f4e38534-2ffc-63bb-4c31-fa0d6b73d4a6.png)

オプション入力の画面が表示されますので、ここでは必須(*)となっている`Uri`だけ
入力して「実行」ボタンを押します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/ee185e30-9060-8c49-5f50-c610bbf6613a.png)

私の環境（Windows 10 Anniversary Update適用済み）の場合、
`Invoke-WebRequest -Uri http://qiita.com/^M` のように末尾に `^M`
がついただけで、実行まで至りませんでした。

なので、`^M`を消して実行。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124069/84fdfe2c-bed5-a474-d256-c4a909f10c67.png)

無事実行されました。


参考リンク

- [Running show-command for a cmdlet | Windows PowerShell Blog]
(https://blogs.msdn.microsoft.com/powershell/2012/04/12/running-show-command-for-a-cmdlet/)
Oracle 11gでパスワードの有効期限が迫ると、JDBCで「java.sql.SQLException: UTF8とUCS2との間の変換に失敗しました。:failUTF8Conv」

つい最近、発生した事例。
どうやら、パスワードの有効期限が近くなるとJDBCにてエラーが出てくる場合があるらしい。エラーメッセージが有効期限とは全く関連がないので、ちょっとはまりました。

# 発端

Webアプリが突然、Oracle Databaseでエラーを発生するようになった。
ログを確認すると

	java.sql.SQLException: UTF8とUCS2との間の変換に失敗しました。:failUTF8Conv

とのエラーが記録されている。
Webアプリ以外でSQLPlusなどでは正常にログインができていた。

# 原因
Oracle Databaseのログインに使用していたユーザのパスワード有効期限が間近になっていたことが原因の模様。ここで気をつけて欲しいのは「有効期限が切れたわけではなく、間近な状態」であること。

どうやら、JDBCで接続する際に「ORA-28002: パスワードは、5日以内に期限切」のメッセージが出力されるとJDBCで「java.sql.SQLException: UTF8とUCS2との間の変換に失敗しました。:failUTF8Conv」のエラーが発生する場合があるみたい。

# 対処方法
単純に、パスワードの有効期限を伸ばすか、再設定すれば解消されます。
Unityのローカル設定が飛ぶ問題

かなりハマったのメモ。
バージョンはUnity 4.6.8f1
ちょっとバージョン古いですが、最新版では起こらないかもしれません。

ある日突然Unityを起動すると**Angry Bots**が起動したことはありませんでしょうか。
まさにそんなときは危険な状態です。

![screen480x480.jpeg](https://qiita-image-store.s3.amazonaws.com/0/17192/109490ad-84a7-acee-755d-42114be8713e.jpeg)
 

例えば私の場合はたくさんプロジェクトがあるので、現在開いているものがわかるように明示的に開くプロジェクトを指定している設定をしています。→「Always Show Project Wizard」
![スクリーンショット 2016-08-30 21.56.34.png](https://qiita-image-store.s3.amazonaws.com/0/17192/17abff85-9f8a-f220-71f5-e567cad03940.png)

ある日原因不明ですが、突然このチェックが外れました。もちろん手動でチェックは絶対外していません。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/17192/2c6f6843-2b80-fd03-089b-285f93912ee7.png)

まあ、この程度なら開くプロジェクトが自動的に前回のものになるのでたいして問題ないのですが...。
しかし、AssetBundleなどを作成するビルドマシンで大事なローカルの設定が飛ぶとある日突然、成果物に問題がでることになりました。
自分のPCでAssetBundleなどを作成すると問題ないのに(設定を目視しているので間違っている場合は気づく)
ビルドPCでjenkins経由などでやると設定を確認していないのでこのような問題が起こるかもしれません。

解決策として至極当然ですが

- この設定を明示的にスクリプトなどでセットするなど
- gitなどのバージョン管理を使っているなら、その設定をローカル管理のみでなくgit管理するなど

でなんとか再発を防止しました。
UITableViewCellのidentifierをスッキリする

#追記 2016/11/20
便利なExtensionを見つけたので、最近はそれを使っています。

    extension NSObject{
        class var className: String{
            return String(describing: self)
        }
    
        var className: String{
            return type(of: self).className
        } 
    }

これを使えば

    let textFieldCell = UINib(nibName: InputTextFieldCell.className,    bundle: nil)
        self.tableView.registerNib(textFieldCell, forCellReuseIdentifier: InputTextFieldCell.className)

このように書けて、いちいち各クラスでidentiferを作る必要もなくなりました。
#動機
UITableViewCellはよく使うしサブクラスも多様するが、

```swift:tableViewでよくあるやつ
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

```
みたいに書くといまいちだし、

```swift:IDを宣言
let reuseIdentifer = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifer, forIndexPath: indexPath)

```

にしても気持ち悪かったので、スマートにやれる方法を考えた。
#class変数の計算型プロパティを使う
UITableViewCellのエクステンションで

```swift:UITableViewCellExtention.swift
extension UITableViewCell{
    class var identifer: String{ return "Cell"}
}
```

このようにして、サブクラス(仮にInputTextFieldCell)

```swift:InputTextFieldCell.swift
class InputTextFieldCell: UITableViewCell {
    override class var identifer: String{ return "InputTextFieldCell"}
(中略)
    }
```
とする。
#呼び出し側

```swift:
let cell = tableView.dequeueReusableCellWithIdentifier(UITableViewCell.identifer, forIndexPath: indexPath)
```

```swift:
let textFieldCell = UINib(nibName: InputTextFieldCell.identifer, bundle: nil)
        self.tableView.registerNib(textFieldCell, forCellReuseIdentifier: InputTextFieldCell.identifer)
```
このようになる。
#static let を使わない理由
static 変数はOverrideができないため、UITableViewCellでidentifierという名前を使ってしまうと以降使えないから。

#終わり
よかったら試してみてください。
間違いなり指摘なりあればコメントお願いします。
CentOS 7.2で /lib/modules/3.10.0-327.el7.x86_64/build がないと言われた時の話


*メロスは激怒した。必ず、かの邪智暴虐の"そのようなファイルやディレクトリはありません"を除かなければならぬと決意した。*
メモ書きです。

## エラーメッセージ:
``` bash
make -C /lib/modules/`uname -r`/build M=`pwd` V=0 modules
make: *** /lib/modules/3.10.0-327.el7.x86_64/build: そのようなファイルやディレクトリはありません.  中止.
make: *** [pt3_drv.ko] エラー 2
```
どうやらSymbolic Linkが死んでいるのが原因の様子

## 対応
```bash
sudo yum install kernel-devel-$(uname -r)
```
どこかに正しいSymblic Linkを貼るのもありましたがパスが変わってるとコピペでできなくてイケてないのでyumで突っ込んでます。

イケてないのは33MB余計に食うのも同じでは
ECMAScript6の基礎と初めてのトランスコンパイル

# 概要

ECMAScript6、JavaScriptについて学習した内容を残す。


## ECMAScript6とは？

> ECMAScript（エクマスクリプト）は、JavaScript の標準であり、Ecmaインターナショナルのもとで標準化手続きなどが行われている。2015年6月に第6版がリリースされている。

[ECMAScript - Wikipedia](https://ja.wikipedia.org/wiki/ECMAScript)


* 新しい文法や仕様・機能が追加されている。
* ECMAScript6(以下ES6)はECMAScript2015という表記をされることもある。


## JavaScript、及びブラウザとの関係性は？

* JavaScriptはECMAScriptの実装言語の一つにあたり、ECMAScriptは言語仕様となる。
* ブラウザによってはES6の仕様の対応状況はまちまち。

## トランスコンパイラとpolyfilライブラリ

ES6で記述し、それをES5のソースに変換してブラウザからでも実行できるようにするという方法がある。
それにはトランスコンパイラやpolyfilライブラリというものを使う。

### トランスコンパイラ

* ES6からES5のコードに変化するツール
* 主に新しい構文などを変換対象とする。


### polyfilライブラリ

* 実行時にES5に変換するJavaScirptライブラリ
* ES6からの新しいオブジェクトなどを古いブラウザとの互換実装のために利用

## 実際にES6のソースを変換をしてみる

トランスコンパイラは[Babel](https://babeljs.io/)を利用する

Babelはnode.jsというものを利用するのでbrewでインストールする

```
$ brew install node 
```

Babelクライアントをnpmでインストール(npmはnode.jsのパッケージ管理ツール)

```
$ npm install -g babel-cli
```

次に作業用フォルダを作る。

```
$ mkdir babel-sample
$ cd babel-sample
```

.babelrcというファイルを作る

```
{
  presets: []
}
```

package.jsonというファイルを作る。（npm initというコマンドでも作れる）


```
{
  "name": "babel-sample",
  "version": "1.0.0",
  "babel": {},
  "devDependencies": {
    "babel-preset-es2015": "^6.14.0"
  }
}
```

ES6(ES2015)プレセットをインストールする

```
$ npm install --save-dev babel-preset-es2015
```

BabelのTOPにあるES6のコードをトランスコンパイルしてみる。

```sample.es6.js

[1,2,3].map(n => n + 1);
```

babelコマンドでES6をES5にする。`-o`オプションはアウトプットするファイル

```
$ babel sample.es6.js -o sample.js
```

ES5にトラスコンパイラされたソースはこんな感じで出力される。


```sample.js
"use strict";

[1, 2, 3].map(function (n) {
  return n + 1;
});
```

以上
array_flip ならぬ、 serial_flip

```javascript
var seri_flip = 
function(seri){
	var arr=[]; 
	$.each(seri.split('&'), 
	function(i,param){
		arr.push(param.split('=')[1]+'='+param.split('=')[0]);
	}); 
	return arr.join('&');
} 
```
scanf and fgets

#この記事で話したいこと

標準入力関数の中でも、scanfとfgetsにフォーカスして、scanfの注意点, fgetsのメリットについて。



#目次
### 1.scanfの注意点
### 2.fetsのメリット
### 3.まとめ

# Target
自分
# Purpose
備忘録

#1. scanf の注意点
- scanf書式

```php
#include<stdio.h>
scanf("%d",&n);
```

変数の前に＆をつけて、アドレスを指定します。
そして、変数nを何にするかによって、変換指定文字を変更することができます。

- scanfの注意点

空白文字は文字入力の終端と判断されます。
その様子のコードを下記に。

```php

int main()
{
    scanf("%d",&n);
    printf("%d",n);
}

```
```
3 2
2
```

#2. fgetsのメリット
-fgetsの書式

```php
#include <stdio.h>
char *fgets(char *s, int n, FILE *fp);
```
第一引数は、文字配列のポインタ
第二引数は、一行の文字数。ここには\nも入るので、最大文字数ー１の文字が入ります。
第三引数は、ファイルからだけでなく標準入力からも文字列を受け取れます。
標準入力の場合は「stdin」としてください。

-メリット
一行の文字を入力することができるので、 scanfで問題だった**スペースも一文字**として含めることができます。

```php
#include<stdio.h>
#define NUM ９
int main(void)
{
  char str[NUM];
  fgets(str,NUM,stdin);
  printf("%s\n",str);
  return 0;
}
```
```
2 3459 7 8
2 3459 7 8
```

#まとめ
上記にあげた注意点をscanfを使ってフォローする方法はあるようです。
ただ私はまだプログラムに慣れていないので、簡単な方法で標準入力方法の道を見つけた、という感じです。
itamae|Centos7で、ミラーリングしたldapサーバーを構築するレシピ

#概要
CentOS7のサーバにミラーリングしたldapサーバーを構築するレシピ
#構築ネットワーク
▪️ 192.168.56.101 
 centos7-admin(管理サーバー)
 ldapサーバーとitamae実行サーバーを兼ねる構築済みが前提
　本稿でミラーリングの設定を追加する

▪️ 192.168.56.104
 centos7-adm2(管理サーバーのバックアップサーバー)
 ldapサーバー構築済みが前提
　本稿でミラーリングの設定を追加する

▪️ 192.168.56.201 centos7−ldap(ldap用VIP)
 管理サーバーの冗長運用時のVIP

# 前準備
[Centos7でldapサーバーを構築するレシピ](http://qiita.com/drafts/27bea896585474f79609)で構築した、サーバーを2台準備する

# 本編
(※ パスワードやドメインなどは目的に応じて変更すること)
本編構築は[こちらのサイト](https://fuketch.wordpress.com/2013/09/11/openldap%E3%81%AE%E6%A7%8B%E7%AF%89/)を参照した。


構築の概要としては

- syncprovモジュールのロード設定追加 (レプリケーションならプロバイダ側、ミラーなので両側に設定する)
- データベースの設定エントリの配下にプロバイダ設定用のエントリを追加 (レプリケーションならプロバイダ側、ミラーなので両側に設定する)
- お互いのldapサーバーにミラーリングの設定を追加する

となり、その構築手順をitamaeのレシピに起こした

-----
```ruby:ldap_mirror.rb
# File copy
[
    "syncprov-module.ldif",
    "syncprov.ldif",
    "#{node[:name]}.ldif",
].each {| tmp |
    template "/etc/openldap/ldif_files/#{tmp}" do
        action :create
        owner  "root"
        group  "root"
        mode   "644"
        source "files/ldap-server/mirror/#{tmp}"
    end 
}

# ldapadd
[
    "syncprov-module.ldif",
    "syncprov.ldif",
].each {| file |
    execute "#{file}" do
        action  :run
        command "/bin/ldapadd -Y EXTERNAL -H ldapi:// -f /etc/openldap/ldif_files/#{file}"
    end
}

# ldapmodify
execute "#{node[:name]}" do
    action  :run
    command "/bin/ldapmodify -Y EXTERNAL -H ldapi:// -f /etc/openldap/ldif_files/#{node[:name]}.ldif"
end
```

(管理サーバーでitamaeを実行する)
▪️ 192.168.56.101側にレシピ実行
`itamae local --node-json files/ldap-server/mirror/mirror1.json ldap_mirror.rb`

▪️ 192.168.56.104側にレシピ実行
`itamae ssh -u xxx -h 192.168.56.104 -i id_rsa_xxx --node-json files/ldap-server/mirror/mirror2.json ldap_mirror.rb`

[本稿使用した、レシピとその他必要なファイル類はgithubに上げてある](https://github.com/hirotaka-tajiri/itamae_cookbooks)
社内ハッカソンの苦悩（課題だらけ）

※メンバー間の葛藤や反省やら、様々な思いで、ここに備忘録として記す。

# 社内ハッカソンの目的（弊社の）
部内の技術底上げを図るのと、社員同士のコミュニケーション活性化を目的としている。

# 技術テーマ
「slack bot」を作成する。

　参考：[最近、Slackの「bot」が何でも出来過ぎて「カオス」状態になってる件！](http://plus.appgiga.jp/masatolan/2015/07/02/56363/)

# お題
取り扱う技術テーマが「slack」だけに様々なアイディアが生まれると想定できるため、せっかくのアイディアを殺さないよう、作るものは、５W１Hを明確して自由に作ってもらう。

# 評価ポイント
- アイディア　（奇抜、興味深い）
- ユースフル　（役立つ、応用がきく）
- テクニカル　（技術要素、工夫など）

# どんな感じでやったの？
- 開催期間は１日のみ（大勢のため、２回に分けて開催）
- 現場をベースに、１チーム４～５人で参加
- 本社
- 全員参加
- 技術テーマは１か月前からアナウンス

# 開催当日
|時刻|内容|
|:-:|:--|
|～9:00|当日の出席／欠席の確認|
|9:00～|作業場所は、自由。会議室、フロア、近くの喫茶店OK|
|お昼|自由|
|～18:00|すべてのチーム作業は、完了|
|18:15～|大きな会議室に集まり、チーム毎にプレゼンした後、みんなで投票し、結果発表！|
|20:00～|懇親会|

# 運用側の工夫
- 現場チームごとを意識したチーム造り
- コスト削減のため、開催場所は自社（事実は予約が取れなかったというのが本当）
- 全員で投票、リアルタイムで投票結果がわかるようスプレッドシートを共有
- Slackチャンネルで当日撮影した写真をUPし、臨場感を演出
- 投票は匿名性をだすため数字で管理、出席／欠席の確認するさいに数字を提示（スタックシールを利用）
- 評価点数の算出方法は

当日の合計点数は、

```math
当日の合計点数=みんなの投票した総合点
```

当日の最大点数は、

```math
当日の最大点数 =(リーダークラス当日参加人数\times 5 \times 3 ) + (一般当日参加人数\times5)
```
リーダークラスは、評価ポイントが一般参加者の×３
０～５でアイディア、ユースフル、テクニカル　の評価ポイントをそれぞれ評価する。
開催を２回に分けているため参加人数に依存しないよう、それぞれ１００点満点の総合３００点満点となるように以下の式にあてはめる。　

```math
評価点数（小数点は切捨て）=\frac{ 当日の合計点数 }{ 当日の最大点数 }\times 100
```

# 課題
##### 運営の状況
運営メンバーは社外の人間の集まりであったため、業務都合なので打ち合わせができないことがよくあり、主にslack上で会話（テキストベース）しながら進めていった。開催当日まで、後手に回ることが多く本当に辛かった。

代弁URL：[後手に回ると辛い！事を起こすなら主体的にささっと動く！](http://tabi-life.hatenablog.jp/entry/2015/02/25/210350)

- 運営側メンバー間での温度差（笑）
- タスクの明確化と、具体的なアクションが他のメンバーと共有されていない
- タスクと、他のタスクとの順序性と、タスクの期日の定義がない
- 運用のフローがなく、今までの経験則で活動している
- 開催場所の確保は、安価を前提としており、キャンセル待ちであった。いくつかフォーカスをしておき、直前のキャンセルを期待したやり方だったが、最後に破たん
- 当日まで個人で準備すべき事項について、主体的に動かない参加者に対応する運営側の曖昧なフォロー（担当範囲の境界線が曖昧だった）

# 対策

##### 心構え
運営メンバーは、バラバラの現場で外駐しているメンバーなので、あえてこそ

- 無理しない、無理させない
- やりたいことは、どんどんやる
- やれることは、どんどんやる
- お互いに感謝を忘れない
 
##### 具体策
今回の社内ハッカソンの運営を体験したことで、事前にやるタスク、直前で調整するタスクなどの抽出と優先順位を把握したので、それをもとに今後の運営を考える

- Slackの会話（テキストベース）ではなく、Skypeの電話会議を行う
- 業務フローを作成する、常に運営のステータスがメンバー間でわかるよう共有する、業務フローは[Cacoo](https://cacoo.com/lang/ja/home)を利用する
- 社内活動だからこそ、運営側の担当範囲を明確化し、主体的に動いてもらうよう参加者側に伝える
Blenderでモデルを法線方向に膨らませて法線反転する輪郭線描画をする

# Blender

* モデルを用意する
* モデルをShift＋Dで複製する
* 複製した方でEditに入り、Alt+Sで法線方向に膨らませる
* そのまま法線も逆にする
* 複製モデルに別のマテリアルをつけ、見やすいように赤単色とする
* Object ModeのMaterial表示で輪郭線の太さを確認する

# Unity

* モデルとテクスチャをインポート。シーンに配置する
* メッシュが本体用とエッジ用に分かれているのでそれぞれマテリアルを付ける
* それぞれのマテリアルには同じDiffuseテクスチャをつける
* エッジ側のマテリアルの明るさを少し暗くする

これで、青い髪の輪郭は暗い青、肌色の輪郭は暗い肌色にできる。応用として、エッジ側のメッシュを調整することでエッジの太さの抑揚をつけることができる。

![output.png](https://qiita-image-store.s3.amazonaws.com/0/12309/fc4f0133-4eb7-1473-2519-dd78edaf5563.png)
Node.js express3から4へ移行

Node.js、Express入門として参考にさせていただきました。

・ドットインストール
http://dotinstall.com/lessons/basic_expressjs

・ex Express4への移行
http://expressjs.com/ja/guide/migrating-4.html
http://chaika.hatenablog.com/entry/2015/10/08/171338
http://chaika.hatenablog.com/entry/2015/10/06/183604
pythonのpickleロード時にAttributeError: Can't get attribute 'クラス名' on <module '__main__' (built-in)>と出る場合

pythonのpickleをロードするときに

```
AttributeError: Can't get attribute 'クラス名' on <module '__main__' (built-in)>
```

と出る場合、このロード対象クラスが記述されているファイルの

```
if __name__ == "__main__":
     hogehoge
```

と記述されている部分を削除し、もう一度pickleを書き出し、読み込みを行うと動くかも。

上記部分を削除するだけだと多分動かない。
簡単に表の検索やソートができるDataTablesでデフォルトソート

便利なjsでデータを簡単に表示できるDataTablesですが、
デフォルトソートの仕方で結構迷ったのでメモ。

### 試行錯誤

```

columnDefs: [
{ targets: 0, ordering: 1 },
]

や

"order": [[0, "asc" ]]

や

"order": [[ 0, 'asc' ], [ 1, 'asc' ]]

や

"aoColumnDefs": [
      { "iDataSort": 1, "aTargets": [ 0 ] }
          ]

や

"aoColumnDefs": [
{ "asSorting": [ "desc" ], "aTargets": [1]},
]

でもダメ。。

```

下記で解決しました。。

### 解決版

```:javascript

$(document).ready(function() {
    $('#example').dataTable( {
        "aaSorting": [[ 0, "desc" ]]
    } );
} );

```

0列目を、降順に。

参考：http://legacy.datatables.net/release-datatables/examples/basic_init/table_sorting.html
証明書署名要求(CSR)を作成

#証明書署名要求(CSR)を作成

##キーチェーンから証明書アシスタントを起動

まず、キーチェーンアクセスを起動します。
次に、キーチェーンアクセスのツールバーから、
「キーチェーンアクセス」 -> 「証明書アシスタント」 -> 「証明局に証明書を要求...」 を選択

<img width="538" alt="スクリーンショット 2016-08-30 20.04.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/110085/0cbec00c-da9e-2c0e-f646-73fe771e0ac2.png">

##証明書情報
<img width="728" alt="スクリーンショット 2016-08-30 20.05.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/110085/390e794f-fb84-4749-1a09-d52fa84c65d6.png">

- ユーザーのメールアドレス: iOS Developer Programに登録したメールアドレス
- 通称: 空
- CAのメールアドレス: 空
- ディスクに保存: ✅
- 鍵ペア情報を指定： ✅


##鍵ペア情報
<img width="728" alt="スクリーンショット 2016-08-30 20.06.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/110085/ec2c1b8b-b394-6156-a77a-6d086e0b1e8e.png">

- 鍵のサイズ：　2048ビットを選択
- アルゴリズム：　RSAを選択

##設定結果
「続ける」をクリックすると、証明書要求CSRがディスク上に作成されます。

<img width="728" alt="スクリーンショット 2016-08-30 20.19.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/110085/fa86f1b5-a8e9-f82a-82bd-799826aea512.png">
サーバー上（Ubuntu16.04）で、Webブラウザを自動実行することで、Web上の特定のデータを定点観測する（１）〜Webブラウザインストール編〜

# 目的

リアルタイムに値の変わるデータがWEB上にありました。その値を定期的にチェックするプログラムを作ることになったわけですが、ページにログインする必要があったりと、スクレイピングのコードを書くのが面倒でした。その対策としてseleniumを使ってWebブラウザを操作し、スクレイピングをすることにしました。その過程を備忘録的にまとめていきます。

なお、手元のPCを使い、Webブラウザをバッチ処理で自動実行しても良かったのですが、、、普段使いの自身のPC上で、勝手にWebブラウザが立ち上げるのは邪魔だったので、レンタルサーバ上（Ubuntu16.04）で勝手に動かすようにします。

より具体的には以下のイメージになります。
（１）python経由でWebブラウザを立ち上げる　→ [Part1(本投稿)](http://qiita.com/gano/items/f46adc5dff055baf3785)で説明
（２）seleniumでWebブラウザを操作し、WEBデータを処理する　→ [Part2](http://qiita.com/gano/items/6c599c531b0e68ac6414)で説明
（３）処理したデータをmongoDBに格納する　→ [Part3](http://qiita.com/gano/items/41111c320577779999a4)で説明
（４）（１）〜（３）を実行するpyプログラムをcronで自動実行する　→ [Part3](http://qiita.com/gano/items/41111c320577779999a4)で説明
（５）値に一定の変動があった場合メールで知らせる　→ [おまけ編](http://qiita.com/gano/items/4935eadce7219eb6227d)で説明


# 環境
OS     : Ubuntu16.04 (さくらVPS）
python : python3.5
# Step1) Webブラウザの選定
初期は、Google Chromeを作業をしていたが、いくつかの点でヘッドレスブラウザであるPhantomJSが良いことが分かったため、PhantomJSを使うようになりました。
PhantomJSを選定した理由は以下の点になります。

+ Javascriptで取得しているデータもスクレイピングできる
+ Chromeと違い、PhantomJSはGUIが無いので仮想ディスプレイが不要

※もし、何かしらの事情でChromeを利用したい場合は、[こちら](http://qiita.com/gano/items/a6a474525cb0872a1afa)にChromeの話を書きましたので、ご参照ください。


# Step2) PhantomJS 2.1.1のインストール
以下の手順でPhantomJSをインストールしました。

```
$ wget -O /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
$ cd /tmp
$ bzip2 -dc /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 | tar xvf -
$ sudo mv /tmp/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/
$ phantomjs --version
> 2.1.1
```

最後の行のバージョン確認で、インストールした意図したバージョンが表示されれば完了です。

（参考URL） http://bit.ly/2bRGnYI

# Step2) Seleniumをインストールする
Web上のデータを定点観測するためにSeleniumを利用する。
Seleniumとは、WEBアプリケーションのテストツールの１つです。人がブラウザを操作する代わりにSeleniumがブラウザを操作をしてくれます。

Seleniumはプログラムコードで操作をすることができますが、要するに、Seleniumを使えばプログラムでブラウザを自由に操作できるようになります。例としては、「loginという名前のbuttonをクリックする」「useridという名前のテキストボックスにメールアドレスを自動入力する」などの操作ができます。現在開いているページのHTML文を取得することもでき、それによってスクレイピングを行ったりします。

私はpython3でseleniumを操作しました。
pip3のインストールも含め、以下の手順でseleniumをインストールします。

```
sudo apt-get install python3-setuptools
sudo easy_install3 pip
pip3 install selenium
```

# Step3) SeleniumとPhantomJSのテストプログラム
SeleniumとPhantomJSを使って、[Google](http://www.google.co.jp)のページを起動して、Googleのtitleタグの値を取得してみましょう。

```py:seleniumテストプログラム
import time
from selenium import webdriver

browser = webdriver.PhantomJS(executable_path='<path/to/phantomjs>')
browser.get("http://www.google.com")
time.sleep(3)

print(browser.title)

browser.close()
```

上記のコードは直感的に分かりやすく、seleniumが初めての方でも戸惑うことはほとんどないと思います。"Google"と出力されれば正常にプログラムが動いています。

１点だけ注意が必要なのは、4行目です。
webdriver.PhantomJS()でPhantomJSを呼ぶ時に、引数にphantomJSのパスを記述する必要があります。上記のコードにある通り、webdriver.PhantomJS(executable_path='...')という形でパスを指定してください。 パスが分からない場合は、

```
which phantomjs
```

で返ってきた値がパスなのでその場所を指定しましょう。

なお、5行目は browser.get(...)で指定したURLにGETリクエストを送っています。取得したレスポンスはbrowserの中に格納され、browser.titleで[Google](http://www.google.co.jp)のtitleタグの値を出力することができます。

seleniumやPhantomJSの起動が確認できたところで、次は実際にスクレイピングをして特定のデータを抽出したいと思います。

続きは[続編の（２）](http://qiita.com/gano/items/6c599c531b0e68ac6414)にて。
もう、jQueryはnpmで管理しようぜ


## 背景

jQueryとか、js関連のファイル、どうやって管理してますか？
公式サイトからjsファイルダウンロードして使ってますか？
それ、サーバにアップロードして使ってますか？
バージョン管理どうしてますか？
ディレクトリにバージョン番号書いて管理してますか？


**面倒くせぇ・・！**

って思いませんか？

時代は変化してます。

もう、js関連のライブラリはnpmで管理する時代になりました。
jQueryの[公式サイト](https://jquery.com/download/)でも、npmかbowerを使ってインストールしよう。という説明があります。

この流れの変化、ついてこれてますか？

・・・

私はつい先日まで、冒頭で話したファイルダウンロード形式の管理でした。
jsもhtmlファイルのbodyの最後にベタ書きでした。

それを卒業したので、備忘録的に書いておきます

## 1. nodeをインストール

と、言っても、nodeはガンガン開発されており、バージョンがすぐに上がります。
バージョン固定で入れるのも面倒なので、好きなバージョンのnodeを使える`nvm`というやつを使いましょう。

```
$ git clone https://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh
```

利用可能なバージョンを探す

```
$ nvm ls-remote
        v0.1.14
        v0.1.15
        v0.1.16
        v0.1.17
        v0.1.18
        v0.1.19
        v0.1.20
        v0.1.21
        v0.1.22
        v0.1.23
        v0.1.24
        v0.1.25
        v0.1.26
        v0.1.27
        v0.1.28
        v0.1.29
        v0.1.30
        v0.1.31
        v0.1.32
        v0.1.33
        v0.1.90
ずらぁーーー
```

`v0.12.15` をインストールしてみます。

```
$ nvm install 0.12.15
Now using node v0.12.15 (npm v2.15.1)
Creating default alias: default -> 0.12.15 (-> v0.12.15)
node -v
v0.12.15
```

完

### バージョンを切り替えるのは

`nvm use [バージョン番号]` で切り替えれます。

## 2. npmの初期化

```
$ npm init
対話形式で色々聞かれるが、とりあえず全部Enter！でOK
```

すると、同じディレクトリの中に`package.json`が出来てます。

```
{
  "name": "frontend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

さっき対話形式で答えた内容で作ってくれるみたいです。

## 3. お待ちかねのjQueryインストール

```
$ npm install jquery --save

```

今度は`node_modules`というディレクトリができているはずです。
この中に`jquery`が入ってます。

色々入ってますが、いつも使ってる`jquery`ファイルは、`node_modules/jquery/dist/`の中に入ってます。

さらに、`package.json`にはどのバージョンを入れたかという情報を勝手に書いてくれてます。

```
  "dependencies": {
    "jquery": "^3.1.0"
  }
```

この`3.1.0`の前の`^(キャレット)`は「パッチバージョンで最新のものをインストールする」という意味です。
詳しくは、以前かいた[記事](http://qiita.com/ritukiii/items/7bb73fd8e383fb350a1d)で、セマンティックバージョンについて解説しているので参考にしてみてください。

ここで、`node_modules/jquery/dist/`配下のjsファイルを使って管理できればレベル1はクリアです。

## 4. せっかくなのでnodeで書いてみよう

もう、jquery書くときに、いちいち↓のように書くのも面倒じゃないですか。

```
<script type="text/javascript" src="jQueryのパス"></script>
<script type="text/javascript" src="script.js"></script>
```

```script.js
'use strict';

var $ = require('jQuery');

$(function() {
  $('h1').css('color', 'red');
  $('h1').click(function({
    alert('hello')
  });
})
```

jsで出来なかった、`require`を実現出来てます。
但し、このままではブラウザが理解できないので、ブラウザが理解出来る形式に変換する必要があります。
それを可能にするのが`browserify`です。

### browserifyのインストール

```bash
$ npm i -D browserify
$ $(npm bin)/browserify script.js -o /var/www/html/script.js
```

`($npm bin)`で、npmのバイナリファイルが入ってるパスを返してくれます。
グローバルにインストールしない場合、いちいちパス指定してられないですしね。

これで、html側は、下記のようにするだけでOKです。

```
<script type="text/javascript" src="script.js"></script>
```

楽ちんですね。
ゲッター、セッター、attr_accessor

というわけでゲッター、セッターについて書いてみます。

##ゲッター
ゲッターとは・・・インスタンス変数の値を取得するためのメソッド

うーむ。意味わかりません。
例えば以下のクラスから@nameの値をprintしたいとして、

```
class Foo
  def initialize
    @name = 'taro'
  end
end
foo = Foo.new
p foo
=>#<Foo:0x007fc9321b28c8 @name="taro">
```
これ以上どうやればいいのか、、こんなやり方もしてみたが

```
class Foo
  def initialize(name)
    @name = name
  end
end

foo = Foo.new('taro')
foo.name
=>`<main>': undefined method `name' for #<Foo:0x007fdb330fa800 @name="taro"> (NoMethodError)
```
そりゃまぁそうだわなって感じですね。。上のコードで@nameを取り出したいのであれば、

```
class Foo
  def initialize(name)
    @name = name
  end

  def name
    p @name
  end
end

foo = Foo.new('taro')
foo.name
=> "taro"
```
のように一度メソッドで取り出してあげないといけない。


ちなみにこれはいける。

```
class Foo
  def hoge(name)
    @name = name
  end
end

foo = Foo.new
p foo.hoge('taro')
=> "taro"
```

なんでいけるかというと`initialize`メソッドがなかなか特殊

initializeについて
http://ref.xaio.jp/ruby/classes/object/initialize

>newに渡した引数は、そのままinitializeに渡されます。なお、initializeの戻り値は使われません。

つまり
`Class名.initialize`ができない。

```
class Foo
  def initialize
    @name = 'taro'
  end
end

foo = Foo.new
foo.initialize
=>`<main>': private method `initialize' called for #<Foo:0x007ff43112e800 @name="taro"> (NoMethodError)
```

initializeって普通のメソッドとは違うんですねー。（そりゃそうなんですが。ちなみに`instance_eval`を使うと取り出せたりします。）
ちょっと話が脱線しましたが、結局クラス内で定義しているインスタンス変数は

```
class Foo
  def initialize(car,name)
    @car = car
    @name = name
  end

  def name
    @name + @car
  end
end

foo = Foo.new('トラック','ほんだ')
p foo.name
```
こんな感じで　`def name`みたいにメソッドにいれてあげないといけない。
このメソッドのことをゲッターという。


##セッター
セッターは値を代入する、値を書き換えること

ゲッターの並びから見てみると

```
class Foo
  def initialize(initname)
    @name = initname
  end
  def set_name(name)
    @name = name
  end
end

foo = Foo.new('taro')
p foo.set_name('jiro')
```
`set_name` の箇所でinitializeした`initname`を
setnameに書き換えてる。
あと別の書き方もあったりする。

```
class Foo
  def initialize(initname)
    @name = initname
  end

  def name=(setname)
    @name = setname
  end
end

foo = Foo.new('taro')
p foo.name='jiro'
```
個人的には前者の方がいいかなと。


でもこれってめんどくさいな。クラス内でインスタンス変数使う場合に
毎回メソッドに定義して、あげるのとかめんどい。（initializeで全部宣言するのでもいいのかもだけど）
そんなときに使えるのが`attr_accessor`さんですね。

```
class Foo
  attr_accessor :name,:title,:contents,:text

  def initialize
    @name = 'aaa';
    @title = 'bbb';
    @contents = 'ccc';
    @text = 'ddd'
  end
end

foo = Foo.new
p foo.name
p foo.title
p foo.contents
p foo.text
=> 'aaa'
=> 'bbb'
=> 'ccc'
=> 'ddd'
```

こんな感じで、`initialize`したインスタンス変数が
ゲッターを使わなくても、クラス外で使えてしまう。
便利っすねー。


以上ー

参考
http://qiita.com/Rudiments/items/c2c5251bcf49dfd7ce7a
RubyMotion開発事例

実際にGoogle Play / App Storeに並んでいるRubyMotionで作られたアプリケーションを紹介していきます。
# Ruby Motionとは
Rubyを使用してネイティブなiOSやAndroid、OS Xアプリを開発できるツールです。
XcodeやAndroid Studioなどに縛られず、自分の好きなIDEやエディタを使用することができます。
現在、Starter/Indie/Professionalの3プランが利用でき、Starterプランは無料で提供されています。
http://www.rubymotion.com/jp/

ちなみに、rubymotionのサイトから自分の大学のメールアドレス載せて「日本の大学生なんだけど学割貰えない？」って旨のメールを送ったところ半額クーポン頂けました。学生の方は是非。

# 制作事例
## FrontBack
![rubymotion1.png](https://qiita-image-store.s3.amazonaws.com/0/96818/119900db-9172-e662-d98e-f5369cf819c9.png)
http://www.frontback.me/
Instagramのような写真投稿型SNS。
アプリ名の通り、フロントカメラとバックカメラを使って同時に投稿できます。
##Bandcamp
![rubymotion2.png](https://qiita-image-store.s3.amazonaws.com/0/96818/70e02af7-7f2d-d06d-8c87-e9d9f2f56a6d.png)
https://bandcamp.com/
アメリカ発の音楽配信サービス。
インディーズアーティストを中心とした宣伝プラットフォームを提供しています。
##Beer Judge
![スクリーンショット 2016-08-30 18.55.10.png](https://qiita-image-store.s3.amazonaws.com/0/96818/6a965041-746e-0704-cbf2-7b4a86fe71f4.png)
http://www.otgapps.io/#beer-judge
カメラを利用してビールの種類や味を識別する娯楽アプリ。
個人的にめっちゃ面白いと思ったけど有料だった。
##BaBaBear Puzzle
![スクリーンショット 2016-08-30 19.13.44.png](https://qiita-image-store.s3.amazonaws.com/0/96818/ceaf9b2a-0a58-6c55-f7e2-fd7eb77d1801.png)
https://itunes.apple.com/jp/app/bababear-puzzle/id666902536?mt=8
某ぷよぷよみたいなゲーム。
##HBFav
![スクリーンショット 2016-08-30 19.16.40.png](https://qiita-image-store.s3.amazonaws.com/0/96818/1578288a-64c6-4c6f-63a7-a07ab94b56ed.png)
http://hbfav.bloghackers.net/
こちらは日本人伊藤直也さんの開発アプリ。
はてなブックマークのお気に入りをタイムライン形式で見ることができます。
#まとめ
上記で紹介した通り色々なジャンルのアプリがRubyMotionで作られており、他にも公式で多くのアプリが紹介されています。
http://www.rubymotion.com/jp/references/app-catalog/
新しいFacebookページの表示サイズ色々（2016/08/30）

いつの間にかFacebookページのレイアウトがまた変更されていましたので、表示サイズについて色々調べてみました。（2016/08/30の状態です）

<img width="1016" alt="Screen Shot 2016-08-30 at 6.21.46 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/14384/28a03e6c-aae8-3c4e-298e-b2abcd03534d.png">

# カバー画像

## PC

表示サイズは、**828 x 315 px**で固定。細長いサイズの画像をアップロードしてもトリミング操作が入ります。（実際にはトリミングしてるわけじゃなくて、`overflow:hidden`で消してるだけっぽい）

カバー画像下部のグラデーションは無くなったようです。上に乗っかるボタンも全部排除されたみたいなので、全面を有効に使えそうですね。

## SP

表示サイズはウィンドウサイズによって異なるみたいです。`"aspectRatio":1.777`という記述があったので、**1.777:1**というサイズになるのだと思います。
以前は画像サイズによって比率も変わった気がするので、その処理は排除されたんですかね？

ちなみに旧iPhoneサイズ（またはiPhone 5SEサイズ）の320pxのウィンドウサイズの場合は、**320 x 180 px**で表示されていましたので、上の比率で合ってるのかなぁと思います。

ちなみにスマホのカバー画像のグラデーションは健在の様子。コチラもどうせなら削除して欲しかった…。

# プロフィール画像

## PC

表示サイズは、**160 x 160 px**で固定。細長いサイズの画像をアップロードしても正方形サイズにトリミング操作が入ります。（カバー画像とは異なり、コチラの画像はしっかりとトリミング処理が施されていました）

## SP

表示サイズは、**64 x 64 px**で固定。周りに2pxの白い線が入るようです。

## その他

以前は小さいサイズの画像をアップロードすると小さすぎると却下されてしまいましたが、小さいサイズをアップロードしても「この写真は小さすぎるため、プロフィール写真がぼやけてしまいます。」という警告は出つつもアップロード出来るようになったみたいです。

<img width="780" alt="Screen Shot 2016-08-30 at 5.37.59 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/14384/cd83426b-0dc9-889b-36ef-4e4f92e9dcb4.png">

# タイムライン

## PC

正方形の画像をアップロードすることで表示される、**476 x 476 px**が最大サイズ。**1pxでも縦幅を大きくすると横幅目いっぱいに表示してくれなくなるようです。**（画像自体が小さい場合は左寄せ）

横長の画像はアスペクト比維持で横幅100%にしてくれるようなので、基本的には横置きの写真をアップロードすると良さそうですね。

複数の画像を同時に投稿すると、4枚までは一度に表示、5枚以降になると4枚目の画像のボタンが「+n」という表示になるようです。

## SP

ウィンドウサイズによって異なりますが、最大サイズは**333 x 499px**っぽい？ちょっと不明です。（小さい画像の場合は中央寄せ）

縦幅の最大サイズを超えると`overflow:hidden`で隠されていました。

なので、横幅333px以下の場合は画面幅目一杯に表示してくれます。ちなみに旧iPhoneサイズ（またはiPhone 5SEサイズ）の320pxのウィンドウサイズの場合は、**縦幅最大480px**でした。

複数画像の処理は同様に4枚まで一度に表示、5枚以降になると4枚目の画像のボタンが「+n」という表示になるようです。
brew link openssl --forceができない問題


## error_msg
```
Warning: Refusing to link: openssl
Linking keg-only openssl means you may end up linking against the insecure,
deprecated system OpenSSL while using the headers from Homebrew's openssl.
Instead, pass the full include/library paths to your compiler e.g.:
  -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib
```



> http://blog.yukarien.com/tech/openssl-versionup/

上記サイトでopensslをバージョンアップした時の問題解決

どうやらopensslへのlinkは貼れなくなったらしい
> http://qiita.com/chatii0079/items/b30cf35c4ec9bdf8dd70
> brew で openssl をリンクできなくしたようで、コンパイラにパスを渡してねって言ってる
  


`set -U fish_user_paths $fish_user_paths /usr/local/opt/openssl/bin`

fisherなのでfishですが、要はpathを通せばおｋ

`which openssl`
`/usr/bin/openssl`から`/usr/local/opt/openssl/bin/`になっている。
`openssl version`
```OpenSSL 1.0.2h  3 May 2016```

1.0.2がインストールされてますね。おｋ！
VirtualDub で MP4 ファイルをコマ送り

# この文書は

VirtualDubは老舗ソフトですが、動画ファイルをコマ送りにして調べたりフィルタをかけて編集するのに今もなんだかんだ便利そうです。
セットアップ方法を備忘録として置いておきます。

# ダウンロード

- 本体（執筆時典で1.10.4）
https://sourceforge.net/projects/virtualdub/

- MP4などのファイルを読むためのプラグイン
https://sourceforge.net/projects/virtualdubffmpeginputplugin/

# 設定
プラグインフォルダをコピペする
![image](https://qiita-image-store.s3.amazonaws.com/0/111730/df592e0e-f0db-eb2e-8663-a0a272cd25ac.png)

# 動作の様子

コマ送りにはキーボードショートカットも使えるので便利ですね！

![image](https://qiita-image-store.s3.amazonaws.com/0/111730/a95b9c7e-f33b-ace2-417b-12b68034ff77.png)
EXCEL > 計算の図示

```txt:動作環境
www.mindmup.com
```

### EXCELシートの問題

- 1つのセルがどのセルを使っているか、しかわからない
- 1つの計算値を求めるため複数セルを経由する場合、関連する計算がわかりにくい
- 入力データがどの場所でどのように使われているか分かりにくい

### 案

以下のようなマインドマップを整備する。
整備の方法についてはマインドマップに記載した。

[EXCEL計算関連図_160820](https://atlas.mindmup.com/yasokada/excel_160820/index.html)

整備中でも作業を中断できるように考慮している。例として、`BB6 @ CY2`は末端ノードでありながら色がついていないので「未整理」と分かる。
末端の色なしノードが残っている限りは情報の整理が完了していないことを示す。

このマップが整備できたら、あとはコーディングと対応させていく。
どこでどう間違っているかなどの情報の指針とできる。

なお、計算値の名前(AA1やCC3など）は意図的にこのような名前にした。本来はこれらは計算項目名となる (例: 温度, 抵抗係数, など)。


実際の作業中のものとしては、以下のような感じの図になる。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/3d12c1e3-608c-993b-72e4-a3399bd28541.png)

色付けについては試行錯誤中だが、以下のようにしてもいいかもしれない。

- 他のノードで使われていない計算を持つ途中ノードはデフォルト色とする
- 末端ノードで使っている計算を持つ途中ノードには色をつける
- 色はレベルの深さで決める
  - level1: 青
  - level2: 黄
  - level3: 緑
  - ...
  - level10: オレンジ