OmniAICreator/Qiita-1.07M huggingface dataset:
AnsibleのDynamic Inventoryが使いづらいのでNode.jsとShellでできるようにした

[こちら](https://qiita.com/mjusui/items/bce4566ffdb54ba7039a)のツールの紹介になります

最近あまり名前を聞かなくなりましたが、OpenStackのような仮想マシンの自動アロケーション機能もない環境で、ExcelでKVMホストのCPU,メモリ,ディスクのリソース管理表を使ってキャパシティ管理していたことがありました(今も本当はやらないといけないんですけど、面倒くさくてやってません)

「管理表ちゃんと更新してください」と何度か言われましたが、どうしても嫌だったのでAnsibleの `Dynamic Inventory` を使って仮想マシンの自動アロケーション機能を作りました

1. KVMホストにログインしCPU,メモリ,ディスクの空き容量を取得し`host_vars`に登録する
2. 作成したい仮想マシンスペックのリストを`vars`で指定してplaybookを実行
3. KVMホストのリソースの空き状況をみて、仮想マシンに割り当てられるリソースがあれば、ホストに仮想マシンを作る

これ自体は、うまく機能したのですが `Dynamic Inventory` の仕様に合わせてJSONを生成するのが、結構ハードル高かったので(Bashでやるから……)自分なりにもっとシンプルな方法で実現できるように[こちら](https://qiita.com/mjusui/items/bce4566ffdb54ba7039a)のツールを作りました

```Dynamic.js
const Tutrial = class extends Submarine {
  query(files){
    return {
      availables: String.raw`
        df -P \
        |awk '{print $4}' \
        |grep "^[0-9]*$"
      `
    };

  }

  format(stats){
    return {
      available_max: Array.isArray(stats.availables)
        ? stats.availables.map(
            available => available * 1
          ).sort((a ,b)=>{
            return a < b
              ? -1
              : a == b
                ? 0
                : 1;
          }).reverse()[0]
        : stats.availables * 1
    };
  }

}

const Tutrials = Submarine.collect(
  host => new Tutrial({
    conn: 'ssh',
    host: host
  }),

  {
    coll: 'echo',
    str: 'server{1..5}'
  },

  {
    coll: 'ping'
  }
);

const tut = new Tutrials();


tut.current().then(
  hosts => hosts.map(
    host => host.available_max
  ).reduce((a, b)=>{
    return a + b;
  }) / 1024 / 1024
).then((available_sum)=>{
  console.log(available_sum);
});
```

このコードは何をやっているかと言うと、各サーバから`df`コマンドで取得したディスクの空き容量を足し合わせています

以下の部分で対象ホストを動的に生成しています

```Dynamic.js
...
const Tutrials = Submarine.collect(
  host => new Tutrial({
    conn: 'ssh',
    host: host
  }),

  {
    coll: 'echo',
    str: 'server{1..5}'
  },

  {
    coll: 'ping'
  }
);
...
```



1. `echo` コマンドの出力結果を対象ホストのリストとして  

```
{
  coll: 'echo',
  str: 'server{1..5}'
}
```
2. そのうち`ping`コマンドの応答があるものを対象ホストとする

```
{
  conn: 'ping',
}
```

他にも`bash`コマンドの出力結果をそのまま対象ホストとしたり`ssh`して`hostname`コマンドで取得したホスト名のうち、正規表現にマッチするものだけを対象ホストにすることもできます

[全パターン](https://gitlab.com/mjusui/submarine/tree/master/doc/en/Tutrial#7-generate-target-servers-dynamically)

`bash`コマンドがあれば`aws`コマンドと`jq`コマンドで`EC2`のリストを生成したり`/etc/hosts`を`grep`した結果をそのまま使ったりできるので、大体の要件は満たせるはず
個人でiOSアプリをリリースしました

##はじめに
初投稿です。
先日、個人開発をしていたiOSアプリをAppStoreにリリースしたので
リリースするにおいて苦労したことや、感想などをまとめていこうと思います。
##自己紹介
エンジニア歴は2年目になります。
最初はスマートフォン向けゲームアプリの開発に携わった後
企業向けのWeb系開発業務に携わり、その後モバイルアプリエンジニアとして
Androidのネイティブアプリ開発を少しかじり、浅く広く様々な
開発経験をした後、iOSアプリ開発に惹かれ現在に至ります。

iOSアプリ開発経験は独学と業務を含め1年弱です。

#リリースしたアプリ
[ドラッグストアナビ](https://apps.apple.com/jp/app/%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%E3%82%B9%E3%83%88%E3%82%A2%E3%83%8A%E3%83%93/id1464307159)というアプリをリリースしました。
位置情報を元に、周囲のドラッグストア・薬局の場所情報を検索するアプリです。

Swiftを独学で勉強し始めて初めて作ったアプリで
アプリをリリースするにあたり、機能をブラッシュアップし、リリースまで漕ぎ着きました。

**■技術構成**
Mapkit + [FoursquareAPI](https://developer.foursquare.com/)
広告表示：[Admob](https://www.google.com/intl/ja_jp/admob/index.html)
クラッシュレポート：[Firebase Crashlytics](https://firebase.google.com/docs/crashlytics?hl=ja)
<img width="414" alt="Text Above 2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436456/badbae9a-2237-6059-d14a-29f45e8c8a43.png">

##苦労したこと
とにかくリリース作業に苦戦を強いられました・・・😇
iOSアプリのリリースには、Appleによる審査があるため
元々非常にハードルが高いイメージでしたが、実際リリースをしてみると
初回は特にハードルが高いなと、身をもって実感しました。
####具体的に
**■Apple Developer Programへの加入**
苦労したことではない気がしますが・・・笑
個人でiOSアプリをリリースする上での、1つの大きな壁かなと感じています。

iOSアプリをリリースする際に[Apple Developer Program](https://developer.apple.com/jp/programs/)への加入が必須となります。
加入するにあたって、年間で約12000円の費用が発生します。
決して安い額ではありませんが、勉強代と割り切ってます。

**■スクリーンショットの提出**
AppStoreに表示されるアプリのイメージ画像の提出です。

iPhoneとiPad両方のスクリーンショットの提出が必須となっており
iPhoneにおいては、画面サイズに応じた物を用意する必要があったので地味に苦労しました・・・。
またスクリーンショットの加工に[Screenshot Designer](https://screenshotdesigner.com/)を使っています。
AppStoreでよく目にするような、スクリーンショットの加工ができるツールです。
無償版を試して非常に好感触だったので、今後も使うことを考え有償版を購入しました。

**■アプリ紹介文の文言作成**
AppStoreに表示されるアプリ紹介文の提出です。

文章力が壊滅的なので非常に苦戦を強いられました😭
またリリースしたアプリが現状多機能ではないため
何を書いたらいいのか正直困惑してしまいました・・・笑
紹介文の文言については、多くのアプリの紹介文を参考に書いてみましたが
今後も新規アプリをリリースする度に書くことになるので、要練習だなと思いました。

**■プライバシーポリシーの作成**
AppStoreに、プライバシーポリシーの記載されたページへのリンクを貼る必要があります。

アプリについてのプライバシーポリシーを作成する必要がありました。
具体的には、今回のアプリだと位置情報を使用するので
取得した位置情報を第三者に提供したり悪用することは決してない旨や
広告配信をしているので、どのサービスを利用しているのかを明記する必要がありました。

必須項目なので避けては通れず、そもそもプライバシーポリシーを作成した経験が
今までなかったので、作成するまでに非常に時間を要してしまいました。

##リリースしてみての所感
とにかく"リリース作業が大変でした"の一言に尽きます😊

ただ見返りは非常に大きく、自分が0から作ったものが
実際にAppStoreにリリースされているのを見るととても感慨深いです。
また、今回の開発からリリースするまでの一連の流れを
全て自分1人でこなしたので、すごく自信がつきました。

実際、プログラムはかけるけど個人開発をしていて
リリースするところまでちゃんと漕ぎ着ける人ってそう多くはないと思っているので
そういう意味でも、最後までやり切れた自分を高く評価したいなと思います👏

##今後について
正直やりたいことは山程あるのですが
以下、いくつか挙げてみます。

- 今回リリースしたアプリの随時アップデート
  - アプリアイコンの変更
  - 新規機能の追加
- 新規アプリの開発
- 定期的にQiitaに記事を投稿する
- 勉強会や技術カンファレンスに積極的に足を運んで知見を増やす
- 気になる技術の勉強
  - [Firebase](https://firebase.google.com/)の知見を増やす
  - [Bitrise](https://www.bitrise.io/)などのCIツールの理解

特に今回のリリースは「アプリをリリースすること」が最終目標になっていたので
今後は、更に実用性があるものをリリースしていきたいなと思ってます。

まだまだアプリエンジニアとしては駆け出しなので
どんどん引き出しを増やしていきたいなと思います！

##最後に
今回のリリースまでの一連の流れを通して
まずやってみることは非常に大事だなと改めて思いました。

リリースする前は、こんなアプリをリリースしちゃっていいのだろうかとか
レビューに低評価が沢山付いたらどうしようーとか😂
ネガティブな要因が非常に多かったのですが
そんなことはどうでもよく、まず動き出さないと何も始まらないなと思いました。

今後も、今以上にアクティブに
アプリエンジニアとして精進していこうと思います😆

非常に拙い文章だったかもしれませんが
ここまでご覧頂きありがとうございました！

**余談**
アウトプットするって難しい・・・😇😇😇
GitHub Flowとは

## git-flowとは
まず、GItHub Flowと似たものにgit-flowがあります
**git-flow**とは数あるGitのブランチ戦略の1つで、[A successful Git branching model](https://nvie.com/posts/a-successful-git-branching-model/)が基になっています。
以下はgit-flowの有名な図
![git-model@2x (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/3f44f45b-8b0c-2325-7fc5-a0b110d1b461.png)
(https://nvie.com/posts/a-successful-git-branching-model/)

`master`のメインブランチがあり、開発用の`develop`ブランチ、そして機能毎の`feature`ブランチや緊急用の`hotfix`ブランチが存在し、これらのブランチを使い分けて開発・リリースを進めていきます。

## GitHub Flowとは
**GitHub Flow**もgit-flowと同様にブランチ戦略の1つであり、その名の通りGitHubで利用されているフローです。
[GitHub Guides](https://guides.github.com/introduction/flow/)

GitHub Flowではメインの`master`ブランチと機能開発のための`feature`ブランチの2つのみのシンプルな構成になっています。
git-flowにはない特徴としては、**Pull Requestを使う**という点と、**masterブランチは常にデプロイ可能**という点があります。
(以下Pull Request=PR)

### GitHub Flowの開発の流れ
1. 開発リポジトリを、自分のアカウントへ**fork**します
2. masterブランチから、作業ブランチを切ります (ブランチの名前は自由です)
3. ローカルで開発、コミットしてForkしたブランチへPushします
4. 本家リポジトリへPRを出し、フィードバックを受けながら開発を進めます
5. レビュワーに承認されたら、本家リポジトリへマージします
6. デプロイ🎉

![Untitled Diagram (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196629/69a8f5b8-f9a6-1129-f467-21524fdc647c.png)


## forkとは
**fork**とは、あるGitリポジトリを自分のリモートリポジトリにコピーしてくることです。
**clone**が単純にローカルにリポジトリをコピーすることに対して、forkは本家のリポジトリへ貢献することが目的です。

### fork元のリポジトリの変更を取り込む方法
forkしたものをcloneすると、fork元のリポジトリがどんどん更新されてしまいます。
その場合は以下のようにしてfork元のリポジトリの変更を取り込むことができます。

```
// upstreamという名前でfork元のリモートリポジトリを登録
$ git remote add upstream fork元のリポジトリURL

// upstreamのmasterブランチの変更分をローカルに持ってくる
$ git fetch upstream master

// ローカルに持ってきたmasterの変更分をローカルのmasterに反映
$ git merge upstream/master

// もしforkして作成した自分のリポジトリに反映したい場合(originは自分のリモートリポジトリ)
$ git push origin master
```

ただ、forkしてGitHub Flowを行っている場合は、masterからfeatureブランチを切り本家のmasterにPRを出すため、origin(自分)のリモートリポジトリのmasterはあまり使わないと思います。

## Pull Requestとは
**Pull Request(PR)**とは、その名の通り「Pullして欲しいとお願いする(Request)こと」です。
git-flowのように自分でmasterブランチにマージするのではなく、**「自分のリポジトリ(origin)のfeatureブランチで開発を行ったから、featureブランチをPullして本家(upstream)のmasterブランチにマージしてもらう」**のがPull Requestになります。
**pullはfetch & mergeのこと**なので、上記の**fork元のリポジトリの変更を取り込む方法**と同様に、ローカルを本家リポジトリ(upstream)に置き換えて以下のようにイメージできます。

```
// ローカル = upstream と考えると、PRは以下のような操作

// 自分のリポジトリ(origin)で開発しているfeatureブランチの変更分を持ってくる
$ git fetch origin feature

// featureの変更分を本家リポジトリのmasterにマージ
$ git merge origin/feature
```

## GitHub Flowは何が良いの？
「色々みてきたけど、結局GitHub Flowは何がいいの？」と思うかもしれません

GitHub Flowには大きく3つのメリットがあると思います

### シンプル
git-flowがhotfixやらdevelopやらreleaseやら色々ブランチがあったのに対して、GitHub Flowはmasterブランチと開発用のブランチだけ！
シンプルで覚えやすいですね、学習コストが低いのは大切です。

### レビューしてもらえる
よく「WIP(作業中)でPRを育てる」なんて言いますが、PRを出して開発を進めるとレビュワーからのフィードバックをもらいやすく良いコードになっていきます。

### ブランチ名を気にしなくて良い
※**これはforkした時のみです**
もし同一リポジトリで作業している場合はブランチ名が被ってはいけません。
開発メンバー同士で命名規則をしっかり決めていればいいですが、それも次第に面倒になってきます。
しかしforkしたリポジトリであれば、最終的にはPullしてマージされるだけなので、どんな名前をつけようが自由です🎉
ブランチ名で悩んでいる時間はコードを書く時間に回しましょう！

ブランチ名を気にしなくてもいいので共通認識がないメンバー同士でもリポジトリに貢献できます(OSS)


## 参考
- https://nvie.com/posts/a-successful-git-branching-model/
- https://guides.github.com/introduction/flow/
MacのC++コンパイラをHomebrewで最新版にする

# はじめに
はじめまして。うまあんです。

今回はC/C++コンパイラを最新のものにします。

# インストール
Homebrewでインストールします。

```
$ brew install gcc
```

これでインストールが終わりました。
Homebrew経由入れたパッケージは/usr/local/Celler/にインストールされ、usr/local/bin/にリンクされます。
# エイリアスを探す
/usr/local/bin/からエイリアスを探し当てます。

```
$ ls /usr/local/bin | grep gcc
$ ls /usr/local/bin | grep g++
```

gcc-9とg++-9が目当てのエイリアスです。

# シンボリックリンクの作成
シンボリックリンクはOSのファイルシステムの機能の一つで、簡単に言うと特定ファイルやディレクトリを参照する別のファイルのことです。

シンボリックリンクは以下のコマンドで作成できます。

```
ln -s [シンボリックリンクを作成したいファイルのパス] [シンボリックリンクを置くフォルダのパス]
```


実際にシンボリックリンクを作成します。ついでにgccも更新しておきましょう。

```
$ ln -s /usr/local/bin/gcc-8 /usr/local/bin/gcc
$ ln -s /usr/local/bin/g++-8 /usr/local/bin/g++PATHを通す
```

# PATHを通す
~/.bash_profileに以下の記述をして、パスを通します。


```
export PATH=$PATH:/usr/local/bin
```


# コンパイラのインストールで起こる問題

Xcode CLTがインストールされていないと時間がかかるようです。

Xcode CLTを以下のコマンドでインストールします。

```
xcode-select --install
```

# 結果

```
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/9.1.0/libexec/gcc/x86_64-apple-darwin18/9.1.0/lto-wrapper
Target: x86_64-apple-darwin18
Configured with: ../configure --build=x86_64-apple-darwin18 --prefix=/usr/local/Cellar/gcc/9.1.0 --libdir=/usr/local/Cellar/gcc/9.1.0/lib/gcc/9 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-9 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 9.1.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
Thread model: posix
gcc version 9.1.0 (Homebrew GCC 9.1.0)

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/9.1.0/libexec/gcc/x86_64-apple-darwin18/9.1.0/lto-wrapper
Target: x86_64-apple-darwin18
Configured with: ../configure --build=x86_64-apple-darwin18 --prefix=/usr/local/Cellar/gcc/9.1.0 --libdir=/usr/local/Cellar/gcc/9.1.0/lib/gcc/9 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-9 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 9.1.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
Thread model: posix
gcc version 9.1.0 (Homebrew GCC 9.1.0) 

```
Arduinoでquadkeyを生成する

Arduino上でQuadKeyを使いたかったので、既存のライブラリを調査して移植した。

# QuadKeyって？

QuadKeyはMicrosoftが開発した位置情報ハッシュアルゴリズムで、Bing Mapsのタイル指定に使われている。文字列で矩形を表現することができ、先頭一致でマッチングをかけることができるため、位置情報のクラスタリングなんかに便利。

- [Tile Coordinates and Quadkeys](https://docs.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system)

類似技術として、ジオハッシュやジオヘックスなどがある。

# サンプルコード

以下はArduinoスケッチの一部。 `latlon_to_quadkey()` にGPSなどから取得した緯度経度と任意のズームレベル（町単位なら `17` くらいがおすすめ）を渡すと、QuadKey文字列を含むStringオブジェクトを返します。

手元ではちゃんと動いてそうに見えますが、にわかArduinoプログラミングなので動作は保証しません。

```c
#include <math.h>

/**
   以下を参考に実装
   https://cttr.jp/2019/04/10/post-453/
   https://github.com/buckhx/QuadKey/blob/master/quadkey/tile_system.py
*/
struct PixelXY {
  int x;
  int y;
};

struct TileXY {
  int x;
  int y;
};

double clip(double val, double minVal, double maxVal) {
  return min(max(val, minVal), maxVal);
}

String latlon_to_quadkey(double lat, double lon, int zoom_level) {
  // geo to pixel xy
  
  // normalize values
  lat = clip(lat, -85.05112878, 85.05112878);
  lon = clip(lon, -180.0, 180.0);

  double x = (lon + 180) / 360;
  double sin_lat = sin(lat * M_PI / 180);
  double y = 0.5 - log((1 + sin_lat) / (1 - sin_lat)) / (4 * M_PI);
  int map_size = 256 << zoom_level;
  int pixel_x = clip(x *  map_size + 0.5, 0, map_size - 1);
  int pixel_y = clip(y *  map_size + 0.5, 0, map_size - 1);

  PixelXY xy = {pixel_x, pixel_y};

  // pixel xy to tile xy
  TileXY tile = {xy.x / 256, xy.y / 256};

  int tile_x = tile.x;
  int tile_y = tile.y;

  String quadkey = "";
  for (int i = 0; i < zoom_level; i++) {
    int bi = zoom_level - i;
    int digit = 0;
    int mask = 1 << (bi - 1);

    if ((tile_x & mask) != 0 ) {
      digit += 1;
    }
    if ((tile_y & mask) != 0) {
      digit += 2;
    }
    quadkey += String(digit);
  }

  return quadkey;
}
```

# 例

`latlon_to_quadkey(35.677730, 139.754813, 17)` の実行結果。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29860/7947b172-ed44-cf7e-74a0-a24fdf23f9a7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29860/2f187af3-d2d4-86ba-f7c0-587f3ed837ef.png)
[※こちらのサイトで確認](http://www.townsendjennings.com/geo/#14.27/35.6769/139.7572)


# 参考

- [【C++】緯度経度からquadKey生成](https://cttr.jp/2019/04/10/post-453/)
- [QuadKey (Python2用QuadKeyライブラリ)](https://github.com/buckhx/QuadKey/)
PythonのRequestsで一つのキーに複数画像のリストを持たせて投げる

# 方法
```
{('images', open('sample1.jpg', 'rb')), ('images', open('sample2.jpg', 'rb'))}
```
として渡すと['images']に配列として入って渡される。

サンプルコードではFlaskでサーバーを立てて受け取る。

# 環境
- Python 3.7.0
- Flask 1.0.3
- requests 2.22.0  

# サンプルコード
```python:sample_request.py
import requests

file_path_list = ['sample1.jpg', 'sample2.jpg']
files = {('images', open(file, 'rb')) for file in file_path_list}
res = requests.post('http://127.0.0.1:5000/post', files=files)

print(res.status_code)
print(res.json())
```

```python:server.py
import flask
from flask import Flask, abort, jsonify, request

app = Flask(__name__)


@app.route('/post', methods=['POST'])
def post():
    if not request.files:
        abort(400)

    files = request.files.getlist('images')
    print(files)
    return jsonify({'message': 'ok'})


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

# 実行
```
$ python server.py
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 251-266-307
```

上記のように待機している状態で以下を実行。

```
$ python sample_request.py
200
{'message': 'ok'}
```

配列として渡される。

```
$ python server.py
...略
[<FileStorage: 'sample1.jpg' (None)>, <FileStorage: 'sample2.jpg' (None)>]
127.0.0.1 - - [14/Jun/2019 01:43:04] "POST /post HTTP/1.1" 200 -
```
テーブルカラムの追加方法と注意すべき点(Rails)

Railsを使って、簡易ブログをアプリを作成中に気づいたことをアウトプットしてみた。

#usersテーブルにnameというカラムをstring型で追加する手順

ターミナル上で、以下のようなコマンドを実行する。

```
$ rails g migration AddNameToUsers name:string
```

ここで注意するべき点は、大文字表記をするべき場所についてである。
Addの後ろに記述する追加カラム名(今回はName)の頭文字は、大文字表記で記述する。また、Toの後ろに記述するテーブル名の頭文字も大文字で表記する。そして、AddとTo自体も大文字表記で記述する。逆に、カラムの型は小文字表記でよい。これはおそらく、ターミナル上において記載した文字表記が、そのままマイグレーションファイルに反映されるからである。
したがって、テーブルにカラムを追加するときは、大文字表記するべき箇所と小文字表記するべき箇所を気をつけることである。

また、user_idカラムを追加したいときの記述は以下のようになる。

```
$ rails g migration AddUserIdToTweets user_id:integer
```
UserIdのように、文字を_(アンダーバー)で区切った場合、区切りの頭文字は、大文字表記にしなければならない。


そして、最後にカラムを追加したマイグレーションファイルを以下のコマンドで実行する。

```
$ db:migrate
```
**この作業を行わなければ、テーブルにカラムが追加されない。**

#おわりに
プログラムを書いていると、あまり大文字でコードを書く機会はない。強いて言えば、以下のように、コントローラのアクションメソッドにおいて、モデル名(Tweet)を記述する時くらいである。

```ruby
class TweetsController < ApplicationController

    def index
      @tweets = Tweet.all
    end
end
```

そのため、テーブルにカラムの追加する時は、個人的に注意しなければならないと感じた。

　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　以上
【GAS】sitemap.xmlをスクレイピングしてスプレッドシートにURLリストとして書き出す

sitemap.xmlをスクレイピングして、スプレッドシートに書き出しておけば、そこからBotでTwitterとかにコンテンツ投稿できたりするので、何となく便利かなーと思い作りました。

Google Apps ScriptでXMLをパースする際は、XmlServiceクラスが用意されているので、このクラスを使用して取得処理を実装します。

XmlServiceクラスに関する詳しい事はこちらの[公式リファレンス](https://developers.google.com/apps-script/reference/xml-service/)で。

#実装手順

スクリプトエディタを開きます。

<img width="983" alt="スクリーンショット 2019-06-14 1.11.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67591/937ddebb-fd91-1b0c-5daf-34d59d5f6f07.png">

以下のコードを書いて実行します。

```javascript
function getxml() {
  var sitemapUrl = "ここにsitemap.xmlのUrl";
  var xmlString = "http://www.sitemaps.org/schemas/sitemap/0.9";

  var xmlText = UrlFetchApp.fetch(sitemapUrl).getContentText();
  var document = XmlService.parse(xmlText);
  var xmlProtocol = XmlService.getNamespace(xmlString);
  var urlEntries = document.getRootElement().getChildren('url', xmlProtocol);
  
  var sheet = SpreadsheetApp.getActive().getSheetByName('シート1');
  var urlArray = [];

  for (var urlIndex= 0; urlIndex < urlEntries.length; urlIndex++) {
    if(urlIndex == 0 || urlIndex == 1){
      urlIndex = urlIndex + 1;
    }
    // シートに書き込む
    var rIndex = "A" + urlIndex;
    sheet.getRange(rIndex).setValue(urlEntries[urlIndex].getChild('loc', xmlProtocol).getText());
  }
}
```

細かく見ていきましょう。


```javascript
var xmlText = UrlFetchApp.fetch(sitemapUrl).getContentText();
var document = XmlService.parse(xmlText);
```
UrlFetchAppクラスのparseメソッドでXMLを取得して、XmlServiceのparseメソッドでXMLをパースします。

```javascript
var xmlProtocol = XmlService.getNamespace(xmlString);
var urlEntries = document.getRootElement().getChildren('url', xmlProtocol);
```

でドキュメント全体の構造を取得し、getChildren()で目的のurl要素を抽出します。

```javascript
  var sheet = SpreadsheetApp.getActive().getSheetByName('シート1');
  var urlArray = [];

  for (var urlIndex= 0; urlIndex < urlEntries.length; urlIndex++) {
    if(urlIndex == 0 || urlIndex == 1){
      urlIndex = urlIndex + 1;
    }
    // シートに書き込む
    var rIndex = "A" + urlIndex;
    sheet.getRange(rIndex).setValue(urlEntries[urlIndex].getChild('loc', xmlProtocol).getText());
  }
```

あとは取得したURLリストをシートのA列に書き出すだけです。
以下がシートに出力した結果です。

<img width="916" alt="スクリーンショット_2019-06-14_0_57_46.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67591/c54bc7d6-6b08-5c3a-d140-0597a5823fed.jpeg">

あとは、このURLリストを煮るなる焼くなり。
BotでSNSに定期投稿しても良いでしょう。

#まとめ
いかがでしたでしょうか？

Google Apps ScriptでのXMLのパースは、便利で簡単なので、やり方を覚えておくと色々な場面で応用がきくと思います。ぜひ試してみませんか。
Redmineで要否プルダウンが要のときのみ入力できる項目を表示する（否のときは表示しない）

# はじめに
[Redmine.tokyo 第16回勉強会](https://redmine.tokyo/projects/shinared/wiki/%E7%AC%AC16%E5%9B%9E%E5%8B%89%E5%BC%B7%E4%BC%9A)で、「ユーザ要望に応えるViewCustomize活用事例」の講演をしたところ、以下のようなご要望をいただきました。
> Redmine で入力フィールドが多すぎるので 要否プルダウン→要の場合のみ後続の入力欄表示みたいなことを検討中です。 view customize plugin でやってるようなので教えてください。 具体的にはコードがほしいです！

[twitterでいただいたメッセージ](https://twitter.com/netazone/status/1138603523040370688)

発表した事例のコードをそのままお渡しすることは、環境依存もあり難しいのですが、これを実現するための簡単なサンプルコードをご紹介します。

[View customizeプラグイン](https://github.com/onozaty/redmine-view-customize )を使用すれば、Redmineの表示はjavascript(jQuery)で制御することができます。(onozatyさん、いつもお世話になっております。ありがとうございます）

# 前提条件
### 環境
* Redmine 3.4.10.stable.18167
* view_customize プラグイン 2.2.0

極端なバージョン依存のコードではないので、その他のバージョンでもたぶん動作します。
### カスタムフィールドの設定
| ＩＤ| 名称 | 形式 | 備考 |
|:-----:|:---------:|:----------------:|:----------------|
| 1  | 要否 | リスト  | 選択肢は「要」「否」のいずれか（必須）|
| 2 | コメント  |  長いテキスト | （この記事でのサンプルです）項目名、形式は任意です。 |

# サンプルコード

```javascript
/*
サンプルチケット編集画面
Path pattern: .*
挿入位置：チケット入力欄の下
Type: JavaScript
*/

if ($('body').hasClass('project-sample')){

	function view_change(){											// 描画関数の定義
		if ($(':input#issue_custom_field_values_1').val() == "否" ) { 	// 要否フィールドが「否」の場合
			$(":input#issue_custom_field_values_2").parent().hide();	// コメントエリアを非表示にする
		} else {														// そうでない場合
			$(":input#issue_custom_field_values_2").parent().show();	// コメントエリアを表示にする
		}
		console.log($(this).val());	
	}

	$(':input#issue_custom_field_values_1').change(function(){			// 要否フィールドのチェンジイベントの時描画関数を実行する
		view_change();
	});

	view_change();														// 初期表示のときも描画関数を実行する
}
```

# 結果
* 要否のフィールドで「否」を選択した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138759/fd23f9d5-4ae5-b522-6bd1-052e74061429.png)

* 要否のフィールドで「要」を選択した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138759/a3c19437-422e-35d7-8835-a8cfc9d13b01.png)

# 解説
* 要否のカラムの値に応じて、コメントフィールドを表示したり非表示したりする関数(view_change)を作成しています。
* jQueryのchangeイベント発生時、および初期表示時に、上記関数を実行しています。
* 任意のカスタムクエリの入力項目は、jQueryの表現で、
`$(":input#issue_custom_field_values_2")`
のように指定すればオブジェクトを取得できます。そのオブジェクトから見て、
`parent()`
を取得すれば、ラベルも含めた\<p>タグが得られますので、それを`show()`または`hide()`で表示／非表示制御を行っています。
[xcode10]シミュレータでキーボードが表示されない・出ない場合の対処法

# 問題
シミュレータ(iPhone8のみ)でtextFieldを選択した際にキーボード(decimaPad)が表示されない
そして下記のエラーコードが表示される

```
Can't find keyplane that supports type 8 for keyboard iPhone-Portrait-decimalPad; using ----------_Portrait_iPhone-Simple-Pad_Default
```

# 解決策
`Simulator`の`Keyboard`→`Connect Hardware Keyboard`をクリックする(チェックの有無が変わらなかったので、、、、)
(`command+Shift+K`のショートカットでも可)
![シミュレータ　キーボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427937/13df28bf-9f2d-90bd-9d0d-c79c182ee28f.png)

# 参考文献
・[iOS8シミュレータでキーボードが表示されなくなった場合の対処方法](https://qiita.com/peromasamune/items/dd0c2f4e4ef2753f426c)
※この記事では`Connect Hardware Keyboard`のチェックを外せとあったのでクリックせどもチェックの有無が変わらなかったので記事を書きました(何回かクリックして試してをやったらいけると思いますw)
Unity(というかC#)で日本語をPOSTしたいとき

UnityでHttpクライアントとしてサーバー側にPOSTを送信するときは以下のようになります（公式より）

https://docs.unity3d.com/ja/2018.2/ScriptReference/WWWForm.html

```C#
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class WWWFormImage : MonoBehaviour {

    public string screenShotURL= "http://www.my-server.com/cgi-bin/screenshot.pl";

    // Use this for initialization
    void Start () {
        StartCoroutine(UploadPNG());
    }

    IEnumerator UploadPNG() {
        // We should only read the screen after all rendering is complete
        yield return new WaitForEndOfFrame();

        // Create a texture the size of the screen, RGB24 format
        int width = Screen.width;
        int height = Screen.height;
        var tex = new Texture2D( width, height, TextureFormat.RGB24, false );

        // Read screen contents into the texture
        tex.ReadPixels( new Rect(0, 0, width, height), 0, 0 );
        tex.Apply();

        // Encode texture into PNG
        byte[] bytes = tex.EncodeToPNG();
        Destroy( tex );

        // Create a Web Form
        WWWForm form = new WWWForm();
        form.AddField("frameCount", Time.frameCount.ToString());
        form.AddBinaryData("fileUpload", bytes, "screenShot.png", "image/png");

        // Upload to a cgi script
        using (var w = UnityWebRequest.Post(screenShotURL, form))
        {
            yield return w.SendWebRequest();
            if (w.isNetworkError || w.isHttpError) {
                print(w.error);
            }
            else {
                print("Finished Uploading Screenshot");
            }
        }
    }
}

```

　ちなみにこれだと基本的には日本語だとバグります。一般的なWebアプリケーションはUTF8基準なので、エンコードする必要があります。


```C#
form.AddField("frameCount", Time.frameCount.ToString(), Encoding.Unicode);
```

　AddFieldのとこの第三引数にエンコード型を放り投げるだけです。え？！フィールドごとに文字コード変えられるってマジ？！？！


## 参考
https://docs.microsoft.com/ja-jp/dotnet/api/system.text.encoding?view=netframework-4.8
https://docs.unity3d.com/ja/2018.2/ScriptReference/WWWForm.AddField.html
WSL上でVSCodeを使う

# はじめに
UdemyでDjangoを学習する際WSL上のPythonを使っていると、VSCodeのPython extentionで認識できないので、自分なりに調べてみた覚え書きです。
ちなみに、私が学習しているコースはこちら ↓
[【徹底的に解説！】Djangoの基礎をマスターして、3つのアプリを作ろう！](https://www.udemy.com/django-3app/)

## 環境
- Windows 10 Home バージョン: 1809
- Visual Studio Code バージョン: 1.35.1
- Ubuntu 18.04 LTS

# 設定
方法としては、VSCodeのinsider版からstable版で使えるようになったRemote - WSLという拡張機能を使います。
公式のページ ↓
[Developing in WSL](https://code.visualstudio.com/docs/remote/wsl#_getting-started)

## 1 . VScodeの拡張機能
[**Remote - WSL**](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)をインストールする。([Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)という拡張パックをインストールすると、Remote - WSLやRemote - SSHなどが一度にインストールできる。)

## 2. エクスプローラーでプロジェクトディレクトリを開き、アドレスバーに

```
wsl
```

と打ち込む。

## 3. WSLのターミナルが立ち上げるので、

```
code .
```

と入力するとWSL上でVSCodeが開く。

## 4. WSL上で使う拡張機能をインストールする。

たったこれだけでWSL上でVSodeが使えます。

**(追記)**バッチファイルも簡単です。
上記の2で開いたプロジェクトディレクトリ内に

```
wsl code .

exit
```

と記述したバッチファイルを作成するだけです。
`wsl`を先頭につけることでWSL上のコマンドが使えます。
[Windows と Linux の相互運用性用 Windows サブシステム](https://docs.microsoft.com/ja-jp/windows/wsl/interop)


# おわりに
私はUbuntuのPythonでflake8やautopep8が使いたかっただけですが、WSLにVSCodeをインストールしようと先人が苦しんできた問題が大きく改善されたのではないでしょうか！
~~batファイルを作っちゃえばWSLに接続したVSCodeが簡単につかえるのかなぁ？~~
pytest使ってみた

#インストール
```:
pip install pytest
```

#実装

##ディレクトリ構造
今回はこんな感じのディレクトリ構造になっています。

```:
├── main
│   └── calc.py
└── test_calc.py
```

##ソースコード
```python:calc.py
class Calc:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    
    def add(self):
        return self.a + self.b

    def dif(self):
        return self.a - self.b

    def seki(self):
        return self.a * self.b

    def shou(self):
        return self.a / self.b

    
```

```python:test_calc.py
from main.calc import Calc

def test_add_01():
    assert Calc(7,5).add() == 12

def test_dif_01():
    assert Calc(7,5).dif() == 2

def test_seki_01():
    assert Calc(7,5).seki() == 36

def test_shou_01():
    assert Calc(7,5).shou() == 2
```
それぞれのソースコードはこんな感じです。
https://qiita.com/kg1/items/4e2cae18e9bd39f014d4
こちらのサイトを参考にさせていただきました。

##実行結果
実行は```pytest```と打つだけです。
以下のような出力がされました。

![スクリーンショット 2019-06-14 0.48.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393221/b7e0e609-69fc-a669-da0e-e6af26245789.png)

sekiとshouの部分でわざと間違った計算結果を用いているので正しく動作してそうです。
実際に扱う場面などはまだわからないのでこれから勉強に励んでいきます。
競技プログラミングのA問題を1時間かけていた自分がC問題やっと自力で解けるようになってきた話

## はじめに

こんにちは、みなさん競技プログラミング生活はいかがでしょうか。ぼくは相変わらずAtCoder Beginners ContestでもA、B問題がやっとの状態です。

でも最近C問題の過去問がやっと自力で解けるようになってきたんですよね。ということでそこまでの道のりを日記的な感じで書いていきたいと思います。書いている言語はpythonです！
ガチプロのかたは。。。まあスキップしてください汗。


##1.学科同期の速すぎる成長度にびびる
去年からプログラミング学び始めた同期が春休み中にめっちゃ過去問を解き、そのおかげで急成長を遂げたという話を先週ぐらいに聞きました。
その同期が言うには、春休み中に過去問のC問題をひたすら埋めていったようです。
AtCoderの過去の問題を解くと、Atcoder Problemsというサイトで自分の成長率などを表示してくれます。めっちゃかっこいいです。以下はぼくのではなく（）、どこかのガチプロさんの画像です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/1ddee431-b082-8927-c8aa-b485748933bb.png)


結構同期が周りでもやっていて、ちょっと自分もやらねば、と思わされたのでした。

##2.C問題1日1問を目標に頑張るが。。。

ということで自分もC問題をどんどん埋めていこう！と思ったわけです。1日1問を目標にしてできるだけ自力で解こうと思いました。
しかし、ぶち当たる問題すべてが新しいものだらけでつらい。。。という状況が1週間ほど続きます。動的計画法、累積和、累積GCD、と数学Aの整数、確率あたりがもともと苦手だった自分は発狂しそうになりました（明らかに向いてない）。

やっぱ来世からやり直したほうがいいか、、、と思いつつもなんとか近くのデニーズで頭が痛くなるまで頑張ります。

自分は以下のような勉強法でC問題を解いていきました。

```
・１時間半の制限時間を自分で設定して、C問題を解いてみる。
・時間オーバーしちゃったら答えのpdfをみて、そのpdfで言っていることをpythonで実装してみる。
・それでもし余裕があったらそのpdfに書いてあることをqiitaで検索する。
を繰り返す。

```


##3.ときどき閃くようになる

と言いつつも、なんとなく傾向がわかってくるんですよね。Nがとてつもないオーダーあたりになるような問題でも、「どうせこれを簡単にO(n)で計算する方法がどっかにあるはずなんだろ？！」と反骨心が芽生えるようになりました。
2秒以内に計算しないといけないわけだから、そんな何回もfor回させるわけがない、と考えられるようになってきました。
なにも無理やりforやifを多用しなくてもいい。そうやって自分をリラックスさせることでひらめきに近づけるようになりました。これがお風呂に入っている時とか、電車に乗っている時とかにシンプルな解法をひらめくきっかけになっていったのだと思います。

##4.コードを書くより、まず考えるようになった

始めた時はpythonのsetとかtupleの違いもうろ覚えなので(おい)、コードの実験とかでめっちゃ時間をとられていました。あと入力の読み込みとかも効率のいい読み込み方法などを探すためにコンテスト中に30分ぐらいそっちに割かないといけなかったとか（向いてない x 2）。
ですがだんだん慣れてくると、その「コードを書くためのコード」の実験部分が必要なくなってくるためなのか、考えることに時間を割けるようになりました。
「実装はできるはずだから、まず手順を考えよう」みたいな。
以前はjupyter notebookで手を動かしているのが、だんだん紙のノート上で手を動かすのが増えていった気がします。
でもこれは結構重要なシフトだと思いました。自分は「自分が効率よくやっている」ことを自分に言い聞かせるためにコードを書いているくせがあった（ある）と思います。

でもこのシフトができるようになったのもpythonの使い方がだんだんわかってきたからだと思いますし。「コードのためのコードを書く」ことと「コードを書かずにまず考える」を同時にやってこそ相乗効果が見込めるのかもしれません。



##結論

自分成長していない、、、と思う時が一番つらいけど、
苦しんでもがいているのも成長の大事な部分だぞ。
冬が過ぎてこそ春が来る。ということをはしくれながら学んだ気がします。

これからもC問題できるだけ毎日解いていこうと思います。まだまだ先は長いぞ。。。
個人用アマゾンアフェリエイト資料

よく使うのに、毎回資料を探すのに無駄な時間を使っているので、まとめておく。

<a href="https://docs.aws.amazon.com/ja_jp/AWSECommerceService/latest/DG/ItemSearch.html" target="_blank">ItemSearch - Product Advertising API</a>
サーチインデックスのやつ。

<a href="https://docs.aws.amazon.com/ja_jp/AWSECommerceService/latest/DG/APPNDX_SortValuesArticle.html" target="_blank">ItemSearch Sort Values - Product Advertising API</a>
ソートに使う項目

<a href="https://docs.aws.amazon.com/ja_jp/AWSECommerceService/latest/DG/ItemSearch.html" target="_blank">ItemSearch - Product Advertising API</a>
アイテムサーチのパラメーター
python の　お勉強　１日目

Python の　お勉強１日目
１）まず　テキストのコードを　タイピング（またはカットアンドペースト）
して　同じ結果が出ることを確かめる
エディターが必要だが pythonのIDLEで問題なさそう

（カットアンドペーストでは　内容は同じでも　タブ、スペースの挿入の関係で
　エラーになることがある。）
 文字、関数、クラス、条件分岐など文法的には理解できそう。

```py:pyturtle.py
from turtle import  *

mode("standard")
shape("turtle")
pencolor("blue")                                             
pensize(25)
fd(100)#forward
lt(90)#turnleft
fd(100)
lt (90)
fd(100)
lt(90)
fd(100)
def my_squares(lengthofsquare):
    fd(lengthofsquare)＃下書きではタブが最初にあります
    rt(90)
    fd(lengthofsquare)
    rt(90)
    fd(lengthofsquare)
    rt(90)
    fd(lengthofsquare)
my_squares(110)
```
「cuDNN error: CUDNN_STATUS_MAPPING_ERROR」はオーバーフロー

#0　背景
CIFAR10で92%を出したモデルを
https://signate.jp/competitions/108
SIGNATEのコンペティションのモデルに適用させる際に出たエラーがこちら
ちなみにPytorchです。

```
    allow_unreachable=True)  # allow_unreachable flag
RuntimeError: cuDNN error: CUDNN_STATUS_MAPPING_ERROR
```

#1 よくわからないけど再インストール
失敗

#2 Pytorchのラベルの制限
「-1」を何かのラベルに利用しようとすると起こるらしい。
今回は当てはまらない

#3 気が付いた
CIFAR10は10種類クラスわけのネットワーク
SIGNATEは20種類クラス分けのネットワーク
###ネットワークの出力変えないとだめじゃないか！orz

普通よく考えてネットワーク作ると思いますが、
上記のエラーが出た場合は、出力の数とラベルの数が合っているか確認してみてください。。。
絵文字をカウントするにはマルチバイト対応の正規表現でも対応できない

👨‍👨‍👦‍👦のような合成絵文字が入ると無理っぽい。
[こちら](https://qiita.com/kyujiro/items/367fada047a6e7700a57)を見ていたら正規表現的な考え方もできるのかなと思い試したところ無理でした。

[コメント](https://qiita.com/kyujiro/items/367fada047a6e7700a57#comment-c7fea3b11dc873292a42)にあるように
each_graphemeのように実装して判定するそうです。

私が試してみたもの（合成絵文字に対応できてない）

```
$string = 'aaaああああ
👿👿👿
👿👿👿
👿👿👿👿👿

👿👿👿


';


$width = 3;
do {
$string = preg_replace('/([^\n]{' . $width. '})([^\n])/u', "$1\n$2", $string, 1, $count);
} while ($count > 0);

var_dump($string);
```

```
string(82) "aaa
あああ
あ
👿👿👿
👿👿👿
👿👿👿
👿👿

👿👿👿


"
```

あれ？違う端末でみたら一文字じゃなくて複数文字に見えるからどっちに合わせるかの問題もありそう…

[絵文字を削除](https://stackoverflow.com/questions/12807176/php-writing-a-simple-removeemoji-function)したりするのは可能
Vagrant -> Ansible -> ruby_その１（概要）

# 概要
今更ながらにVagrant+Ansibleの環境構築を初めてやってみました。
満足できる環境が出来上がるまでおおよそ１ヶ月。
せっかく苦労して書いたのに何もかも忘れていくのも寂しいので、
こちらに記述しておくことにしました。

本記事は頑張った結果の構成概要を記述したものです。
これ以降のシリーズではそれぞれの過程においての私の思いを記述していくつもりです。

本記事は連載シリーズです。全３回です。
[Vagrant -> Ansible -> ruby_その１（概要）]
[Vagrant -> Ansible -> ruby_その２（Vagrantfile）](https://qiita.com/KurokoSin/items/6e28e634aa719ac04245)
[Vagrant -> Ansible -> ruby_その３（Ansible - playbook）](https://qiita.com/KurokoSin/items/5c940ce860df5b7f5fef)


## 構成図
以下は自分の環境で構築した時の構成図です。

* 母艦(Ubuntu)にAnsibleコントロール用の仮想サーバ
* Ruby開発用の仮想サーバ

の構成になっております。

![structImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14800/70097dab-8135-903e-4843-5e9d89e5e3ed.png)

## 構成

母艦：
　　OS:Ubnutu 18.04.2 LTS
　　仮想化：KVM　(libvirt 4.0.0)
　　Vagrant 2.0.2

子１：
　　ホスト名：ansible-ontrol
　　box OS: Ubuntu 18.04.2 LTS(generic/Ubuntu1804 1.9.12)
　　Ansible: 2.8

子２：
　　ホスト名：ansible-web
　　box OS: Ubuntu 18.04.2 LTS(generic/Ubuntu1804 1.9.12)
　　ruby: 2.6.3

# 本記事でやること
子１

* IPv6 の無効化
* 時刻同期サーバの設定(同期先：NICT)

子2

* IPv6 の無効化
* 時刻同期サーバの設定(同期先：NICT)
* git インストール
* Ruby用パッケージの追加インストール(gcc,make等)
* rbenv　インストール
* ruby-build インストール


# 実行手順
```bash
$ mkdir -p /srv/vagrant && cd /srv/vagrant
$ git clone https://github.com/kurokoSin/Burgessochaeta.git .
$ vagrant up
$ vagrant ssh control
$ ansible-playbook playbook/site.yml
```

## ディレクトリ構成

```
.
├── README.md
├── Vagrantfile
├── control
│   ├── ansible_conf.sh
│   ├── expect_sendkey.expect
│   └── playbook
│       ├── ansible.cfg
│       ├── config.yml
│       ├── hosts_ansible
│       ├── roles
│       │   ├── AddPacks
│       │   │   └── tasks
│       │   │       └── main.yml
│       │   ├── Japanize
│       │   │   └── tasks
│       │   │       └── main.yml
│       │   ├── common
│       │   │   └── tasks
│       │   │       └── main.yml
│       │   ├── git
│       │   │   └── tasks
│       │   │       └── main.yml
│       │   ├── ntp
│       │   │   ├── handlers
│       │   │   │   └── main.yml
│       │   │   ├── tasks
│       │   │   │   └── main.yml
│       │   │   ├── templates
│       │   │   │   └── ntp.conf.j2
│       │   │   └── vars
│       │   │       └── main.yml
│       │   ├── rbenv
│       │   │   ├── tasks
│       │   │   │   └── main.yml
│       │   │   └── templates
│       │   │       └── rbenv_setting.sh.j2
│       │   ├── ruby
│       │   │   ├── tasks
│       │   │   │   └── main.yml
│       │   │   └── templates
│       │   │       └── rbenv_setting.sh.j2
│       │   └── ssh
│       │       ├── tasks
│       │       │   └── main.yml
│       │       └── vars
│       │           └── main.yml
│       └── site.yml
└── web
    └── pexpect_sndekey.py

```

## コード
[github にて公開](https://github.com/kurokoSin/Burgessochaeta.git) しております.
こちらを参照お願いします。
moodle導入時のエラー訂正

##moodleのサーバをたてて接続したら…
なんかエラーが出ている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400231/95c46980-26eb-7081-e3e3-28b6036c6076.png)

調べてみるとmysqlの設定にエンコードの記述を増やせばいいっぽい

##以下mysqlサーバにて作業
/etc/mysqlのディレクトリ内にあるmy.cnfを編集する

```
nano /etc/mysql/my.cnf
```
以下の記述を加える

```
[client]
default-character-set = utf8mb4

~

[mysqld]
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix

character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-character-set-client-handshake

~

[mysql]
default-character-set = utf8mb4
```
その後再起動することで設定が反映される

dockerで立てている場合なら

```
docker restart コンテナ名
```

で再起動がかけられる
Raspberry Pi 環境構築

## OSイメージダウンロード

ダウンロードURL : https://www.raspberrypi.org/downloads/
OSイメージ種類：Raspbian Stretch with desktop and recommended software
イメージファイル名：2019-04-08-raspbian-stretch-full.zip

## OSイメージ書き込み

ツール：[Etcher](https://www.balena.io/etcher/)

## SSH, WiFi事前設定

* ssh
* wpa_supplicant.conf

```bash
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="«your_SSID»"
    psk="«your_PSK»"
}
```

## Raspberry Pi起動

## IP検索

ツール：[Advanced IP Scanner](http://www.advanced-ip-scanner.com/jp/)

## Raspberry Piへssh接続

### Raspberry Pi初期設定

```bash
$ sudo apt-get update
$ sudo apt-get -y upgrade
$ sudo raspi-config
```

### IP固定

```bash
$ sudo vi /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.1.XX/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1 8.8.8.8
$ sudo reboot
```

### .bashrc修正

* bin Directory
* Editor(VI)
* Alias(ls, lr, la)

### アプリケーションインストール

* Node.js
* Enhanced Vi editor
* Golang
* Arduino IDE
* MQTT
* tmux
* Docker
* NTP
* XScreenSaver
NumPyのデータ構造 - 多次元配列を作る

前回書いた 「[NumPyでデータ作成を始める](https://qiita.com/naka-j/items/4a73c9beba45b27d5776)」 の続きのようなもの
データ作成方法にフォーカスして、色々な多次元配列の作成方法を見ていく

## 要素が全て同じの多次元配列
- 要素が全て０の１次元配列
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/294afa80-94ef-2d9c-60d8-e7fb0fa3cf57.png)
`zeros`で０が並ぶ、`ones` で１が並ぶ、なるほど
でもこれ１３とかなったらどうするんでしょう？　さーてぃーんず はないでしょ  
ちゃんとありました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/720570e9-73e1-e8fa-bb99-5736bfe669f9.png)
`full`を使えばで引数で個数と値が指定できる！！
ちなみに twos 以上はエラーになりましたw なんやねんw

- 要素が全て０の２次元配列
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/fa39174e-0ee0-b559-88ec-1e00705d8567.png)
行と列をタプルで渡せば２次元配列を作ってくれる  
同じく`full`を使ってもできる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/930fd033-af6c-08ca-7bf8-a4ae52e47620.png)

- おまけ： （100, 100, 100） の３次元配列
もう作り方はわかる
`np.full((100, 100, 100))`
さてこれをpythonのfor文で作った場合
`[[[0 for _ in range(100)] for _ in range(100)] for _ in range(100)]`
わけわからんけど、こんな感じになる  
これらの実行速度、**NumPyの方が十数倍速い**みたい
すげー

## 多次元配列の値の置き換え
`zeros_like`、`ones_like`、`full_like`を使えば、多次元配列の要素の値を全て指定した値に置き換えることができる
ただし**shapeが同じ**場合に限る！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/67de07b5-9e07-cf37-8933-4a9e1f20b63f.png)
`np.full_like((2, 3), 99, dtype=int)` で型指定もできちゃう
実際に使う場面に遭遇してみたい処理ではある

## データ作成の主なメソッド
### `arange`
pythonの range のnumpyバージョン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/52444481-d2fa-5d79-df4c-784d7a0d8595.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/999eb2e6-1b65-7b47-e26a-a954b3b0ef1b.png)
rangeと同じなので、スタートとストップ、ステップを指定して使える


### `linspace`
スタートとストップと要素の個数を指定して、配列を生成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/a5bdf4cb-8a1c-31b4-61b1-fc47083cbbbf.png)
指定した個数が入りきるようにちゃんと割って入ってくれる
これ、数学Ⅱ（？）でやった**等差数列**やね！

### `eye`
👀
`eye(n)`で 対角線上の値のみ1のn次元配列を作成（単位行列）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/621149bd-0dec-0668-a345-1597bb6559d7.png)
いや、むずいむずい
非正方行列じゃなくてもOKなんだったさ（要は雰囲気が正方形じゃないってことでしょう！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/e6246ff0-0b54-1adc-4da4-7c48cf3f8454.png)

### `diag`
対角線上の値のみ指定し、他が０の配列
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412441/6ab41bd3-b737-12f3-daf9-91d096af8608.png)
行数 ＝ 引数の要素数
つまり正方形になるってことやん？


# 感想
なんとなるデータ作るの楽で速いのは感じてきている
いつか感動爆発するんかな〜
挿入ソート

- 「最小値を決める」ことを繰り返してソートするのではなくて，**「この値が入るべき場所はどこなのかを決める」**ことを繰り返してソートする
- ほとんどデータが整列済みの時に使える
- トランプを順番に並び変えるときに自然にやる動作が挿入ソート

```go
func InsertionSort(target []int) []int {
	target = append([]int{-1}, target...)
	for i := 2; i < len(target); i++ {
		log.Printf("\t---- i = %d ----\n", i)
		sentinel := target[i]
		target[0] = sentinel
		j := i - 1
		for sentinel < target[j] {
			target[j+1] = target[j]
			log.Printf("[%d %v]\n", target[0], target[1:])
			j -= 1
		}
		target[j+1] = sentinel
		log.Printf("[%d %v]\n", target[0], target[1:])
	}
	return target[1:]
}
```

```
2019/06/13 23:44:36 Target: []int{7, 1, 4, 2, 0, 8, 5, 9, 3, 6}
2019/06/13 23:44:36     ---- i = 2 ----
2019/06/13 23:44:36 [1 [7 7 4 2 0 8 5 9 3 6]]
2019/06/13 23:44:36 [1 [1 7 4 2 0 8 5 9 3 6]]
2019/06/13 23:44:36     ---- i = 3 ----
2019/06/13 23:44:36 [4 [1 7 7 2 0 8 5 9 3 6]]
2019/06/13 23:44:36 [4 [1 4 7 2 0 8 5 9 3 6]]
2019/06/13 23:44:36     ---- i = 4 ----
2019/06/13 23:44:36 [2 [1 4 7 7 0 8 5 9 3 6]]
2019/06/13 23:44:36 [2 [1 4 4 7 0 8 5 9 3 6]]
2019/06/13 23:44:36 [2 [1 2 4 7 0 8 5 9 3 6]]
2019/06/13 23:44:36     ---- i = 5 ----
2019/06/13 23:44:36 [0 [1 2 4 7 7 8 5 9 3 6]]
2019/06/13 23:44:36 [0 [1 2 4 4 7 8 5 9 3 6]]
2019/06/13 23:44:36 [0 [1 2 2 4 7 8 5 9 3 6]]
2019/06/13 23:44:36 [0 [1 1 2 4 7 8 5 9 3 6]]
2019/06/13 23:44:36 [0 [0 1 2 4 7 8 5 9 3 6]]
2019/06/13 23:44:36     ---- i = 6 ----
2019/06/13 23:44:36 [8 [0 1 2 4 7 8 5 9 3 6]]
2019/06/13 23:44:36     ---- i = 7 ----
2019/06/13 23:44:36 [5 [0 1 2 4 7 8 8 9 3 6]]
2019/06/13 23:44:36 [5 [0 1 2 4 7 7 8 9 3 6]]
2019/06/13 23:44:36 [5 [0 1 2 4 5 7 8 9 3 6]]
2019/06/13 23:44:36     ---- i = 8 ----
2019/06/13 23:44:36 [9 [0 1 2 4 5 7 8 9 3 6]]
2019/06/13 23:44:36     ---- i = 9 ----
2019/06/13 23:44:36 [3 [0 1 2 4 5 7 8 9 9 6]]
2019/06/13 23:44:36 [3 [0 1 2 4 5 7 8 8 9 6]]
2019/06/13 23:44:36 [3 [0 1 2 4 5 7 7 8 9 6]]
2019/06/13 23:44:36 [3 [0 1 2 4 5 5 7 8 9 6]]
2019/06/13 23:44:36 [3 [0 1 2 4 4 5 7 8 9 6]]
2019/06/13 23:44:36 [3 [0 1 2 3 4 5 7 8 9 6]]
2019/06/13 23:44:36     ---- i = 10 ----
2019/06/13 23:44:36 [6 [0 1 2 3 4 5 7 8 9 9]]
2019/06/13 23:44:36 [6 [0 1 2 3 4 5 7 8 8 9]]
2019/06/13 23:44:36 [6 [0 1 2 3 4 5 7 7 8 9]]
2019/06/13 23:44:36 [6 [0 1 2 3 4 5 6 7 8 9]]
2019/06/13 23:44:36 Sorted: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

```
ILコードに触れてみる

## 概要

前にちょっと触れたILコードについて少しメモってた下書きを解放します。
なのであまり詳細にはまとまってません。完全にメモ。

また触れることがあったら追記するかも。

参考: [ILを使った動的なコード生成入門(高速リフレクション-インスタンス生成編)](https://qiita.com/yamaokunousausa/items/4061ed39ae9629823e7f)

IL逆アセンブラー

- [Ildasm.exe (IL 逆アセンブラー)](https://docs.microsoft.com/ja-jp/dotnet/framework/tools/ildasm-exe-il-disassembler)

.NET Compilerを手に入れる

- [Roslyn](http://go.microsoft.com/fwlink/?LinkID=533240)

NuGetを手に入れる

- [NuGet クライアント ツールのインストール](https://docs.microsoft.com/ja-jp/nuget/install-nuget-client-tools)


スタートメニューの検索で「dev」と打ち込むと「**Developer Command Prompt for VS2015**」みたいな感じで、開発者用のコマンドプロンプトが立ち上がります。



## 命令の種類

### 数値の指定

ldcから始まる命令を利用する。また、それに続けて型を指定する。

| 型 | 命令 | 備考 |
|:-------:|:-------:|:-----:|
| Int32  | ldc.i4  | 32bit整数 |
| Int64  | ldc.i8  | 64bit整数 |
| Float32  | ldc.r4  | 32bit浮動小数点 |
| Float64  | ldc.r8  | 64bit浮動小数点 |

なお、`-1〜8`までは定数としてのオペコードが用意されている。

| 定数 | オペコード |
|:---:|:----------:|
| -1  | ldc.i4.m1  |
| 0  | ldc.i4.0  |
| 1  | ldc.i4.1  |
| 2  | ldc.i4.2  |
| 3  | ldc.i4.3  |
| 4  | ldc.i4.4  |
| 5  | ldc.i4.5  |
| 6  | ldc.i4.6  |
| 7  | ldc.i4.7  |
| 8  | ldc.i4.8  |


### ジャンプ命令

無条件ジャンプは`br`命令を使う

```il
br target
```

`target`には通常、メソッド内のオフセット位置を4バイト整数で指定するが、ラベルを指定して実行することもできる。

ラベルの指定は以下のようにする。

```il
id:
```

ラベルを記載した次の行がターゲットとなる。

```il
.assembly extern mscorlib { }
.assembly test { }

.method static void Main() cil managed
{
    .entrypoint

    ldstr "最初のメッセージ"
    call void [mscorlib]System.Console::WriteLine(string)

    br target

    ldstr "スキップされるメッセージ"
    call void [mscorlib]System.Console::WriteLine(string)

target:
    ldstr "ターゲットメッセージ"
    call void [mscorlib]System.Console::WriteLine(string)
    ret
}
```


### 分岐命令

分岐条件には、メソッド呼び出しなどと同様にスタックに積まれた値を元に判断されます。
分岐には、値が`0`以外の場合に実行される`brtrue`命令と、`0`または`null`の場合に実行される`brfalse`命令があります。

書式は`br`命令と同様になります。

```il
brtrue target
```

この命令を実行するとスタックに積まれている値をポップしそれを評価します。
MaterialのついたGameObjectにSubItemを必ず付ける必要はない。

**※2019年06月13日当時、VCI SubItemの子供にVCI SubItemをアタッチできていましたが、
2019年7月14日時点においてVCI SubItemはVCI Objectの子供にのみVCI SubItemをアタッチできるようになりました。
（孫に付けることはできない。つまり、VCI SubItemの子供にVCI SubItemをアタッチすることはできなくなった。）**


Materialの付いたGameObject全てにSubItemを付けている方が結構いらっしゃったので、取り急ぎこれだけでも記事にします。
下記ページ参照
[VCI SubItem Component (VCISDK)](https://virtualcast.jp/wiki/doku.php?id=vci:sdk:subitem:introduction)
##VCI Sub Item
> SubItemとして使用したいobjectの数だけアタッチします。
>動く必要のないオブジェクトでVCIスクリプトによる制御も加えないのであれば、SubItemのコンポーネントは不要です

ここに記載されているVCIスクリプトによる制御は、transformに関わる制御のことであり、
transform(scale,position,rotation)に関わらないSoundやMaterialの付いたGameObjectについてはSubItemを付ける必要はありません。

例えば数値を表示する用のGameObjectだと、こうなります。
メッシュさえあればとりあえず表示されますし、UVOffsetでの変更やColorの変更もできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150633/1b4eeb69-c5de-208a-fc6b-a8eebbed0785.png)
移動させたい場合は、親にVCI SubItemを付けてそれを持つようにすると連動して動きます。
これだとFourLinksFieldにあたります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150633/0d3e7b3d-2e4d-4720-2b6e-241daf240893.png)
VCI Sub Itemはぶつかったり量が多いと重くなる原因になるので、必要なものにだけVCI Sub Itemを付けるように注意しましょう。
AB<N となる正の整数(A,B)のペアの数がO(N log N)であることの数値的確認


#動機

[AtCoder128 F問題の解説](https://img.atcoder.jp/abc128/editorial.pdf)に

```math
AB<N\text{となる}(A,B)\text{のペアの数は}O(N log N) \text{である（意訳）}
```
という記述があったのですが，直ぐには分からなかったので確認をした結果をここにまとめたいと思います．

今回計算するのは積がN未満の自然数のペアの個数ですが，積がN以下の自然数のペアの個数と考えてもほとんど変わらない結果になると思います．

#数値実験

数値的に確認するだけなら簡単なので，実際にプログラムを組んで確認してみましょう．

```python

def f1(N):
  ans = 0
  for A in range(1,N+1):
    for B in range(1,N/A+1):
      if(A*B<N):
        ans+=1
  return ans

for N in range(1, 10001):
  print("%d %d" % (N, f1(N)))
```

N=1からN=10000までのペアの数を確認しています．
この結果をプロットすると，次のようになります．
![result1](https://cl.ly/ececfea6c9a1/test1-1.png)
$f_1(N)$が$AB<N$となるペアの数です．
大体直線っぽく見えますが，ちょっと直線よりも上向きに傾いてるように見えますね．
え？見えません？

それなら縦軸を$N$で割って，対数グラフで見てみましょう．
![result2](https://cl.ly/1514da705fc0/test1-2.png)


明らかに，$N$が大きくなるに従って，$f_1(N)/N$も増えていってますね．
そして，こちらの方が，先ほどのよりも直線っぽいです．
最後に，$f\_1(N)/N log N$をプロットしてみます．

<img src="https://cl.ly/7af4d5c18670/test1-3.png" width=55%>

$N$が大きくなるにつれて，$f\_1(N)/N log N$の値が収束しているのが分かると思います．

本当に$f\_1(N) = O(N log N)$でした

#数学的なお話

数学Ⅲの積分計算ができる方は，概算で（正確には上限と下限から）示すことができます．

```math
AB<N \leftrightarrow B<N/A
```
A, Bは正の整数なので，

```math
1 \leq A \leq N
```

また，Aを固定した場合のBの範囲は

```math
1 \leq B \leq N/A
```

なので，1~Nの間でAを動かした時のN/Aの和を概算で求めたい．
これは積分を使って，

```math
  \int_1^{N} N/A ~ \text{d}A \\
= N \int_1^{N} 1/A ~ \text{d} A \\
= N \left[ \text{log} A \right]_1^{N} \\
= N \text{log} N
```

で概算できます．
ちゃんとやれば上限と下限を計算できます．
Geometric Semantic Genetic Programming(GSGP)とはなんなのか

#はじめに
本記事ではGenetic Programmingの手法の一つであるGeometic Semantic Genetic Programming(以下GSGP)についての解説をします．
Genetic Programmingを知らない人はGenetic Programmingを知ってからこの記事戻ってきてください．
また，本記事では個人の意図的・偏見的な解釈が含まれていることを了承してください．

#GSGPについて
GSGP[^1]とは2012年に発表されたGPの手法の一つです．
GSGPは，それまでのGPの手法とは違い，「**探索対象を構造から数値列へと変更**」したことによって注目を浴びました．

それまでのGPでは構造(可変長オブジェクト)を探索するためには以下の二つの手法がとられていました．

- 構造そのものを探索する
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219048/6e6e48d6-a19c-60c5-4798-c9e7ccace6b2.jpeg)

- 構造を数値列にエンコードしてから探索する
![Untitled Diagram (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219048/ea333a3d-c009-e259-e5ba-2309605f3060.jpeg)

しかし，一つ目の構造そのものの探索では，探索空間が可変的になるために効率的な探索が困難でした．
また，二つ目の構造を数値にエンコードする手法も，数値にエンコードすることによって探索空間を歪めてしまうという問題点もありました(つまり真の探索が非効率的になる)．

では，GSGPが何をしたのかというと，構造を探索することをやめたのです．
そもそも，GPの目的は目的の出力を得られる関数(構造)を探索することでした．そこでGSGPは，「**構造は何でもいいから，目的の出力だけ得られれるように探索すればよくなーい**」というようにGPの手法を大幅に変更したのです．
この目的の出力は，スカラもしくはベクトルなため，探索空間が固定的になり，探索効率が大幅に向上しました．

では，どうやって目的の出力を得る構造を求めるのでしょうか？
それには手法名にも含まれているSemanticとGeometricの意味を理解しなくてはいけません．

##Semanticとはなんなのか
Semanticとは日本語訳すると「意味の…」となります．まったく意味がわかりません（笑）
個人的な解釈になりますが，ここでいうSemanticとは構造の意味を指しているのだと思います(個人的解釈)．
構造を意味づけるものとは，すなわち構造からの出力値です．
つまりSemantic Genetic Programmingとは「構造の出力を探索するGP」と意訳することができます．

##Geometricとはなんなのか
Geometricとは日本語訳すると「幾何学的な」となります．なにが幾何学的なのでしょう？
ここでいうGeometicとは，距離関係が対称関係にあることを指しています．
つまり，2つの親(A,B)から生まれる子(C)があったときに，親同士の距離d(A,B)と，子と親の距離d(A,C),d(B,C)は次の関係にあるということです．

$$ d(A,B) = d(A,C) + d(B,C)$$ 

ある意味，内挿交叉に限定するということです．
では，どうやってGeometricでSemanticな遺伝子操作を定義するのでしょう?
以下ではその定義について話します．

##Geometric Semantic Crossover
もはやGSGPのCrossoverはCrossoverとは言わずに，「二つの個体の間の個体を生成する方法」と定義したほうがよさそうです．
子個体の生成方法は問題によって異なるのですが，例えばBoolean Expressionの場合は
![Untitled Diagram (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219048/76c426e6-4b95-1a11-20c9-28d010e5f286.jpeg)
となります．ここで，$\rm Tree_C$は子個体，$\rm Tree_A$,$\rm Tree_B$は親個体，$\rm Tree_{rand}$はランダムな木構造とします．
見てわかると思いますが，通常のGPとは大きく異なり，親個体間での部分木交換がありません．
GSGPでは，子個体の生成は，親個体+αとすることで生成するのです．

さらに，この交叉方法は常に親個体に+αされていくので，木の大きさは爆発的に大きくなっていきます．
とはいえ，木構造を保存する必要性はなく，個体の出力値だけを保存すれば子個体の生成が行えるので，メモリフローにはなりません．
この**個体の出力値だけを保存する**というのが，Semanticということです．

##Geometric Semantic Mutation
Mutationに関しては，通常のGAと同じような突然変異を行えば大丈夫です．
いま，個体は出力列(数値列)として表現されているため，適当な値を変化させればいいのです．

##Review
GSGPは木構造を探索するアルゴリズムではなく，出力値を探索するアルゴリズムです．そのため，解空間が線形になり，探索効率が大幅に上がるというメリットを持ちます．
しかし，過学習しやすいというデメリットも持ちます．当然ですが，継ぎ木のような交叉方法では，任意の出力値を吐き出す関数は複雑になってしまう場合が多いです．そのため，ノイズを含む実問題に対しては過学習するという傾向があります．

一方で，過学習してもよいという問題が存在します．それは論理回路の回帰問題などです．このような問題では入力と出力のすべてのパターンを網羅することが多いため，過学習しても問題ありません．さらに論理回路の回帰問題は，機械学習の手法を使っても解くことはできますが，論理演算子に落とし込むことが面倒です．そのような場面ではGSGPは輝くのかもしれません．

##おわりに
この記事を書いているのは2019年6月ですが，最近ではGSGPの熱も過ぎ去ったように思えます．2012年～2016年はGSGPの論文がいっぱい投稿されていますが，2019年現在は少なくなってきています．結局のところ，ノイズがある問題にはGSGPが適用しずらいことが関係しているのかなーとも思っています．

[^1]: Moraglio, Alberto, Krzysztof Krawiec, and Colin G. Johnson. "Geometric semantic genetic programming." International Conference on Parallel Problem Solving from Nature. Springer, Berlin, Heidelberg, 2012.
gitkのフォントサイズを変更する

all in oneなGUIのGitフロントエンドをあまり使いたくないのですが、コミットツリーだけはアスキーアートじゃ見づらいのでGUIで見たい。
gitに同梱されてるgitkがちょうどいいのですが、デフォルトのフォントサイズがあまりにも小さかったので調整することにしました。

# 設定ファイル

[公式サイト](https://git-scm.com/docs/gitk#_files)を見ると、

> User configuration and preferences are stored at:
>
> - `$XDG_CONFIG_HOME/git/gitk` if it exists, otherwise
> - `$HOME/.gitk` if it exists
>
> If neither of the above exist then `$XDG_CONFIG_HOME/git/gitk` is created and used by default. If `$XDG_CONFIG_HOME` is not set it defaults to `$HOME/.config` in all cases.

とあります。
つまりデフォルトでは、`$HOME/.config/git/gitk`にあるはずです。ありました。

# 設定

以下の行を編集してお好みのフォントサイズにします。

```
set mainfont {{Lucida Grande} 9}
set textfont {Monaco 9}
set uifont {{Lucida Grande} 9 bold}
```

MacBook Pro 13インチでは、

```
set mainfont {{Lucida Grande} 18}
set textfont {Monaco 15}
set uifont {{Lucida Grande} 15 bold}
```

くらいにしたらちょうどいい大きさになりました。