OmniAICreator/Qiita-1.07M huggingface dataset:
ゲームログをもっと集計し易くしたい

昨今のゲームは長期的な運用を前提としているのものがほとんどであり、売上を伸ばすための施策を練るにはユーザーの動向を逐一把握していることがとても大事です。そのためユーザーの行動情報を出力し調べることが必要になります。

しかし、

ゲームについて分析をしたいけれども集計するためにはどういったログを出せばいいのか、何もルールをなしにログを出していくとあとあとの集計が困難になっていくことがしばしばあります。

そのためソーシャルゲームを基に考えてどんなログを出せば集計し易いかを述べていきます。
（個人の見解に基づきます）

#扱い易いログを作るための手順

###1.最優先したいフィールド
常時運用を続けるサービスでは何を集計するにしても以下の２つは必ず出力しておかなければなりません。

#####・時刻
#####・ユーザーID

###2.計算したいフィールド
次に重要なのは数値計算をして指標を見る場合の基となるログです。合計、平均、割合などを集計することがよくあるかと思いますが、個々のユーザーに紐付けて出力しましょう。

（例）
#####・アイテム所持数
#####・所持ゲーム内通貨
#####・レベル
#####・限界突破数
#####・何かしらのポイント所持数など

###3.IDになるフィールド
欲しい情報に何らかの分類がある場合に必要になります。計算したい情報毎にIDが設定してあると集計が容易になります。

（例）
#####・クエストID
#####・キャラクターID
#####・アイテムID


###4.名前になるフィールド
IDが何に対する値なのか分かるようにするため、それに対応する名目も同時必要になります。

（例）
#####・"曜日限定クエスト"
#####・"キャラクター名"
#####・"回復アイテム"

###5.セグメントになるフィールド
これは必須ではないですが、どのレベル帯のユーザーなのかなど、ユーザーの特徴をある程度分けて見る必要が頻繁に出てきます。そのための情報はログに常に紐付けておくと違いが明確にしやすくなります。

（例）
#####・ユーザーレベル
#####・月額課金額

#指標から考える扱い易いログ
基本的には上記のようにログを出せばエクセルや、SQLなどで集計することが可能になりますが、応用的な指標を作成する場合は上記のログだけでは不十分な場合があります。ありがちなケースに対応できるようにするログの作成方法を以下に追記します。

###1.モノに基づく指標
ソーシャルゲーム内のアイテム、クエスト、ステータスなどのモノの情報は頻繁に追加、アップデートされるためそれに対応できるように一意性を保持しておくことが望ましいです。しかし、一つのIDだとコンテンツが多くなるに連れて分類や意味合いを分けるのが困難になってきます。そのため一意の情報を崩さないためには何層にもIDを振り分けておくか、リストとしてログを出力すると分別がしやすく、フィルターとして差別化もしやすくなります。

（例）

```　
   ┌── アイテムID  
   ├── 種類ID
   └── レア度
```

```
カードID 
   ├── 名前
   ├── レベル
   └── スキル
         ├── スキル1     
               ├── スキル名
               └── スキルレベル
         ├── スキル２
               ├── スキル名
               └── スキルレベル
         └── スキル３
               ├── スキル名
               └── スキルレベル
```

###2.時間に基づく指標
経過日数や、効果期間、前回行動した時間などが重要になる指標を作成する場合、ログの中に現在どれぐらいの期間が経過しているか、前回実行した時間はいつなのかなどの情報を埋め込んでおくと指標作成が容易になります。

（例）

```
ユーザーID  
   ├── 前回ログイン日時
   ├── 継続ログイン日数
   └── 効果取得日数
```
td-agent3（Fluentd v1.0）でS3に「LTSV形式のログ」を保存する。2018-03-16

# 内容
[td-agent3（Fluentd v1.0）でS3にログを保存する](https://qiita.com/abetomo/items/f7cf264525d92f1c9154) では `td-agent3`（`Fluentd v1.0`）で　`Apache` のログを、 `S3` に保存しました
今回は、「LTSV形式ログ」を保存する設定について記します

# 準備
[td-agent3（Fluentd v1.0）でS3にログを保存する](https://qiita.com/abetomo/items/f7cf264525d92f1c9154) を一通り設定した状態にする

# 設定の例
## LTSV形式のログについて
（例ということでかなりてきとーなものです）

* `/tmp/ltsv.log` に出力される
* ログのフォーマットは `datetime:%Y-%m-%d %H:%M:%S<TAB>id:数値のID`
    * 例: `datetime:2018-03-05 07:48:33<TAB>id:697`
    * `$ printf "datetime:$(date "+%Y-%m-%d %H:%M:%S")\tid:$RANDOM\n" >> /tmp/ltsv.log` で出力します

## 設定ファイル
参考: [LTSV Parser Plugin](https://docs.fluentd.org/v1.0/articles/parser_ltsv)

```conf:/etc/td-agent/td-agent.conf
# <source> の内容が本題
<source>
  @type tail
  path /tmp/ltsv.log
  tag ltsv.log
  pos_file /var/log/td-agent/ltsv-log.pos

  <parse>
    @type ltsv
  </parse>
</source>

# <match> についての詳細は割愛
<match ltsv.log>
  @type s3

  aws_key_id YOUR_AWS_KEY_ID
  aws_sec_key YOUR_AWS_SECRET_KEY
  s3_bucket YOUR_S3_BUCKET_NAME
  s3_region us-east-1
  path logs/${tag}/%Y-%m-%d/
  s3_object_key_format %{path}%{time_slice}_%{index}.%{file_extension}

  # if you want to use ${tag} or %Y/%m/%d/ like syntax in path / s3_object_key_format,
  # need to specify tag for ${tag} and time for %Y/%m/%d in <buffer> argument.

  <buffer tag,time>
    @type file
    path /var/log/td-agent/s3
    timekey 60
    timekey_wait 60
    chunk_limit_size 256m
  </buffer>
</match>
```

# 動作確認
以上の設定例で `td-agent` を起動してログ（`/var/log/td-agent/td-agent.log`）を確認します。
特に問題がなさそうであれば

```
$ while true ; do printf "datetime:$(date "+%Y-%m-%d %H:%M:%S")\tid:$RANDOM\n" >> /tmp/ltsv.log && sleep 10; done
```

などで「LTSV形式のログ」を出力して、S3にログがたまっていくか確認します。

## ログデータの確認
S3に以下のようなテキストのログがたまっていきました

```YOUR_S3_BUCKET_NAME/ltsv.log/2018-03-16/201803160439_0.gz
2018-03-16T04:39:32+00:00	ltsv.log	{"datetime":"2018-03-16 04:39:32","id":"8204"}
2018-03-16T04:39:42+00:00	ltsv.log	{"datetime":"2018-03-16 04:39:42","id":"13831"}
2018-03-16T04:39:52+00:00	ltsv.log	{"datetime":"2018-03-16 04:39:52","id":"14953"}
```

# まとめ
* 「LTSV形式のログ」を `parse` できました
* `td-agent3`（`Fluentd v1.0`）で `S3` に「LTSV形式のログ」を保存できました
Project Euler 55「Lychrel数」

# Problem 55 「Lychrel数」
47とその反転を足し合わせると, 47 + 74 = 121となり, 回文数になる.
全ての数が素早く回文数になるわけではない. 349を考えよう,

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337
349は, 3回の操作を経て回文数になる.

まだ証明はされていないが, 196のようないくつかの数字は回文数にならないと考えられている. 反転したものを足すという操作を経ても回文数にならないものをLychrel数と呼ぶ. 先のような数の理論的な性質により, またこの問題の目的のために, Lychrel数で無いと証明されていない数はLychrel数だと仮定する.
更に, 10000未満の数については，常に以下のどちらか一方が成り立つと仮定してよい.

50回未満の操作で回文数になる
まだ誰も回文数まで到達していない

実際, 10677が50回以上の操作を必要とする最初の数である: 4668731596684224866951378664 (53回の操作で28桁のこの回文数になる).
驚くべきことに, 回文数かつLychrel数であるものが存在する. 最初の数は4994である.
10000未満のLychrel数の個数を答えよ.

```python
def hoge(num, limit):
    cnt = 0
    for n in range(num):
        for _ in range(limit):
            n += int(str(n)[::-1])
            s = str(n) 
            if s == s[::-1]: break
        else:
            cnt += 1
    return cnt

print(hoge(10000, 50))
```
お尻(単語末尾)が欠けている正規表現は否定的先読み

たとえば、正常な「**Qiita**」が含まれる文中で、「**Qiit**」という文字列を検出したい。

# 結論

否定的先読みがそういう用途。

```
qiit(?!a)
```


# ぱっと思いつくもの

```
qiit(?:[^a]|$)
```

行末の場合ならいいが、行中なら余計な「`a以外の文字`」までmatchした文字列として検出される。


# 参考

* [正規表現の先読み・後読みを極める！ - あらびき日記](https://abicky.net/2010/05/30/135112/)

>否定的先読み(?!pattern)
>
次の正規表現では直後にbarがないfoo(barは含まない)に一致します．
foo(?!bar)
【PowerShell】ディレクトリ内のdatファイルの最終行を削除する

#困ったことに
・csvでほしかったデータがdatファイルできた
・なぜか最終行に半角スペースが入っているため、そのままだとPostgreSQLにインポートすることができない
・わりとたくさんファイルがある

#やりたいこと
・ディレクトリ内にあるすべてのdatファイルの最終行だけを削除したい
・datファイルからcsvファイルへ変換したい

#はじめてのPowerShell
最初はJavaでやろうとしたのだけど、機種依存文字が含まれていてどうしても文字化けしてしまうので、バッチでやることにした。しかしDOS バッチでファイルの最終行を削除することは難しそうだったので、PowerShellを使ってみることにした。シェルスクリプトは触ったことがあるけどPowerShellは初めてだったので起動から全部調べたよー。

以下、私のように初めてPowerShellを触る人へ。

※ちなみに環境はWindows7です

###1. 起動方法
Windows + RでPowerShellを検索

###2. 試しに動かしてみる
ディレクトリ内のdatファイル情報がずらーっと出てくるはず

```powershell
cd C:\work # ワークディレクトリに移動
Get-ChildItem * -include *.dat # ディレクトリ内のdatファイルを取得
```

###3. PowerShellスクリプトファイルを作る

```powershell:test.ps1
$List=Get-ChildItem * -include *.dat
foreach($file in $List) {
	$data = Get-Content $file                   #ファイルの中身を取得
	$name = $file.name -replace ".dat", ".csv"  #出力ファイル名(拡張子をcsvに置換）
	$length = $data.length -1                   #最終行番号を取得。配列のインデックスにするので-1をする
	$data[$length] = $null                      #最終行を削除
	$data | Out-File $name -Encoding default    #csv拡張子でファイル出力
}

```

###4. 実行
この時はじめてps1ファイルを実行する人は実行ポリシーにひっかかってできないはず。
詳しくはここらへんのサイトをみてね。
[WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更する](https://orebibou.com/2015/01/powershell%E3%81%A7sed%E7%9B%B8%E5%BD%93%E3%81%AE%)

```powershell
#　実行ポリシーの変更（とりあえず今回ローカルファイルを動かせればOK）
Set-ExecutionPolicy RemoteSigned
```

```powershell
# 実行
.\test.ps1
```


で、ターゲットディレクトリ内（この場合はC:\WORK）内のdatファイルはすべて最終行は削除され、拡張子が.csvになってファイル生成されましたとさ。動きとしては、ファイルから最終行を削除したっていうよりかは最終行以外をコピーしたcsvファイルを作ったっていうほうが正しいかな？実際ターゲットディレクトリ内には元のdatファイルとcsvファイルが混在してました。

他のもっとうまいやり方があるような気がするけど、今回は私の要件を満たしていたため、これでよしとします。

#参考サイト
[WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更する](https://orebibou.com/2015/01/powershell%E3%81%A7sed%E7%9B%B8%E5%BD%93%E3%81%AE%)
[PowerShellでsed相当の処理を行う](https://orebibou.com/2015/01/powershell%E3%81%A7sed%E7%9B%B8%E5%BD%93%E3%81%AE%E5%87%A6%E7%90%86%E3%82%92%E8%A1%8C%E3%81%86/)
iOS で Landscape モードのみサポートする


iOSのアプリでランドスケープモードのみをサポートする必要がありました。`Xcode`でターゲットを選び、デバイスのオリエンテーションを `Landscape Left` と `Landscape Right` に指定します。

<img width=300 src="https://qiita-image-store.s3.amazonaws.com/0/65634/1230881c-4ee5-0ba7-1cf7-86f1a3d60948.png" />

次に、`UIWindow` の root view controller この場合 `UINavigationController` のサブクラス `MyNavigationController` とかを用意して、次のメソッドをオーバーライドします。Landscape モードのみとか言いながら、シレっと、`topViewController` に `supportedInterfaceOrientations` を訊ねてそれを返します。

```MyNavigationController.swift
class MyNavigationController: UINavigationController {
	// ...
	override var shouldAutorotate: Bool {
		return true
	}
	override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
		return self.topViewController?.supportedInterfaceOrientations ?? .landscape
	}
	// ...
}
```

そして、navigation view controller の root view controller にもこんな風にメソッドをオーバーライドします。

```MyViewController.swift
class MyViewController: UIViewController {
	
	override var shouldAutorotate: Bool {
		return true
	}

	override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
		return .landscape
	}

}
```

さて、実行してみると、iPhone ではランドスケープ固定となるのですが、iPad では View が `landscape` と `portrait` に回転が起きてしまいます。Stack Overflow をちょろっと検索しても、だいたいこの辺で良いような事が書いてありました。`Application Delegate` の `func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask` を実装すればいいという書き込みがありましたが、そもそも、iPad ではそれすら呼ばれません。

諦めて公開質問を作る感じで、検証用プロジェクトを作り [GitHub](https://github.com) に公開するつもりで準備を始めました。

これがその検証用プロジェクトです。iPad では回転してしまう状態で公開されています。
https://github.com/codelynx/InterfaceOrientation-2018

ところが、これを準備している間に、答えを見つけてしまいました。どんな検索キーワードを使ったか覚えていませんが、検索キーワードで結果が大きく異なるのは少し痛いです。

[SupportedInterfaceOrientations not called in iPad] (https://stackoverflow.com/questions/35274428/supportedinterfaceorientations-not-called-in-ipad)

> If 'Requires full screen' setting from 'General' is enable, will allow the orientation delegate methods shouldAutorotate, preferredInterfaceOrientation, and supportedInterfaceOrientations to fire.

結果から言うと、`info.plist` の `Require full screen` を `on` にしておけば、ちゃんと iPad でも`supportedInterfaceOrientations` が呼ばれるようになりました。

<img width="422" alt="Screen Shot 2018-03-16 at 12.12.50 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/f89c22e8-8cc0-6423-9f6b-b4be938f1790.png">

その代わり、multitasking な機能が使えなくなると言う話もありますが、ゲームや一部アプリなど大人の事情でランドスケープ固定が望ましいアプリもあるので、それらの場合はこの方法で大丈夫のようです。

試してはいませんが、`portrait` 固定の場合でも同様かと思います。

執筆時のXcodeとSwiftのバージョンは以下の通りです。

```
Xcode Version 9.2 (9C40b)
Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2)
Target: x86_64-apple-macosx10.9
```
シェルスクリプトで実行ファイルの絶対パスを取得する

これで実行ファイルのパスが取得できる

```bash
dir=$(cd $(dirname $0); pwd)
```

順を追っていくと覚えやすい

# 1

実行ファイルのディレクトリを取得

```bash
dirname $0
```

# 2

実行ファイルのディレクトリに移動

```bash
cd '実行ファイルのディレクトリ'
```

# 3

現在位置のディレクトリを取得

```bash
pwd
```

# 評価順序

結果を見てわかる通り、1番深い`$()`の内側のコマンドから順に処理されていく
途中の`;`は単に`cd`と`pwd`を区切っているだけ

# 出力結果

例えばこのような環境下で実行した場合

```bash
$ tree
.
└─tmp
    └─ test.sh
```

```bash
$ cat tmp/test.sh
#!/bin/sh
echo $0
echo $(dirname $0)
echo $(cd $(dirname $0); pwd)
```

以下のような結果になる

```bash
$ sh tmp/test.sh
tmp/test.sh
tmp
/home/user/tmp
```

`tmp`から実行すると

```bash
$ cd tmp
$ sh test.sh
test.sh
.
/home/user/tmp
```
WebKitGTK+のリリースtarballをAsanビルドする

## 概要
WebKitの特定のバージョンに存在する脆弱性の挙動を調べるために、該当するバージョンのWebKitGTK+のリリースtarballを拾ってきてAddressSanitizerを有効にしたビルドをUbuntu上で行ったときのメモです。
WebKitGTK+ 2.19.91以降のリリースでは`ENABLE_ADDRESS_SANITIZER`フラグによって簡単にAsanビルドができるため、それより前のバージョンが本記事の対象です。

## 環境
* OS: Ubuntu 16.04（VMware 仮想マシン）
* メモリ: 4GB（ホスト: 8GB）
* ビルド対象: WebKitGTK+ 2.17.92

## 大まかな手順
* ビルドに必要な環境の準備
* AddressSanitizerを有効にする設定
* ビルド

## 手順
### 下準備
* アップデートでエラーが発生する場合は対処
    * [appstreamcliのエラー対策とアップデート](https://www.hiroom2.com/2016/05/20/ubuntu-16-04%E3%81%AEapt-update%E3%81%A7appstreamcli%E3%81%8C%E5%9B%BA%E3%81%BE%E3%82%8B/)
* 必要に応じてビルド高速化の設定を行う
    * [ビルドの高速化](https://trac.webkit.org/wiki/WebKitGTK/SpeedUpBuild)

### プログラム準備
WebKitGTK+のリリースtarballを取得・展開

```console
wget https://webkitgtk.org/releases/webkitgtk-2.17.92.tar.xz
tar -xf webkitgtk-2.17.92.tar.xz
```

依存するプログラムをインストール

```console
cd webkitgtk-2.17.92
./Tools/gtk/install-dependencies
```

cmakeして足りないプログラムをチェック

```console
cmake -DPORT=GTK -DCMAKE_BUILD_TYPE=Debug -GNinja
```

追加で使用するプログラムをインストール

```console
sudo apt install clang llvm-dev ruby-dev -y
```

パッケージでは必要なバージョンがインストールできないプログラムを取得・ビルド
今回は`Libgcrypt`およびそのビルドに必要な`Libgpg-error`をインストールした

```console
wget https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.28.tar.bz2
tar -xf libgpg-error-1.28.tar.bz2
cd libgpg-error-1.28/ && ./configure && sudo make && sudo make install && cd

wget https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.8.2.tar.bz2
tar -xf libgcrypt-1.8.2.tar.bz2
cd libgcrypt-1.8.2/ && ./configure && sudo make && sudo make install && cd
```

### AddressSanitizer有効化
* cmakeファイルを編集してAddressSanitizerをリンクさせる
    * `webkitgtk-2.17.92/Source/WebKit/PlatformGTK.cmake`内の`LDFLAGS`指定部分に`-fsanitize=address ASAN_OPTIONS=detect_leaks=0`を追記する
    * LeakSanitizerが有効だとビルド中にリークが検出されて停止してしまうためオフにしている

### ビルド
* コンパイラオプションでAddressSanitizerを有効化する。また、実験に使うMINIBROWSERのビルドをオンにする

```console
cmake -DPORT=GTK -DCMAKE_BUILD_TYPE=Debug -DENABLE_MINIBROWSER=ON -DUSE_SYSTEM_MALLOC=ON -DCMAKE_CXX_FLAGS="-g -fsanitize=address -fno-omit-frame-pointer" -GNinja
sudo ninja
sudo ninja install
```

* SYSTEM_MALLOCについてはよくわかってない

### MINIBROWSER実行時の設定
* LeakSanitizerを抑制する

```console
export ASAN_OPTIONS=detect_leaks=0
```

* スタックトレースをシンボル化する
    * `llvm-symbolizer`のパスを通せばよい

```console
export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.8/bin/llvm-symbolizer
```

* MINIBROWSER実行

```console
/usr/local/libexec/webkit2gtk-4.0/MiniBrowser
```

* 調査したい脆弱性を踏んでエラーが無事検出されたらOK
1行でWebアクセス数(req./sec.)を求める

# スクリプト
## Apache用
```shell:count_access.sh
#!/bin/sh
tail -1000 /var/log/apache2/access.log | head -1 | awk -F '[\\[\\]/:]' '{t=systime();today=mktime(strftime("%Y %m %d 00 00 00",t));tod=t-today;tod2=$5*3600+$6*60+$7;print 1000/(tod-tod2), "req/sec" }'
```
## nginx用
```shell:count_access.sh
tail -1000 /var/log/nginx/access.log | head -1 | awk '{print $4}' | awk -F '[\\[\\]:]' '{t=systime();today=mktime(strftime("%Y %m %d 00 00 00",t));tod=t-today;tod2=$3*3600+$4*60+$5;print 1000/(tod-tod2), "req/sec" }'
```

# 使い方
$ watch -n 10 ./count_access.sh

```console:出力例
Every 10.0s: ./count_access.sh                     Fri Mar 16 12:05:31 2018

165.837 req/sec
```

# やっていること
1,000件前のリクエストがいつだったかを取得し、1000÷(現在時刻との差分) を表示しているだけ。

# 制限事項
- 日付変更から1,000リクエストの間は間違った値(負の値)が出ます
- log rotateから1,000リクエストの間は間違った値(本来より小さい値)が出ます
Tinkercad > 手順 > オブジェクトを等間隔で配置する

ブラウザ動作するAutoDeskのTinkercad。

オブジェクトを等間隔で配置する機能はTinkercadにはない。

直線状に配置するには、手動で以下のようにする。
オブジェクトの高さ:20、オブジェクト間の距離:10、とした場合。

1. オブジェクトAを配置
2. オブジェクトAをdキーでdrop
    - 作業平面に下端が合う
3. ルーラーを使ってオブジェクトAのz位置を-30とする
    - 次のオブジェクトとの距離を10とする場合
4. オブジェクトBを追加する
    - オブジェクトAとオブジェクトBの距離は10である
5. オブジェクトAとオブジェクトBの水平位置を「位置合わせ」で合わせる
6. オブジェクトAとオブジェクトBをグループ化
    - グループ1と仮称する
7. グループ1のz位置を-60とする
    - 60 = (20 + 10) * 2
    - 次のオブジェクトとの距離を10とするため
8. オブジェクトCを足す
9. オブジェクトCをdキーでdrop
    - 作業平面に下端が合う
10. オブジェクトCとグループ1の水平位置を「位置合わせ」で合わせる
11. オブジェクトCとグループ1をグループ化
12. 上記の処理をN回繰り返す
    
Wordyな説明になってしまった。

格子状に配置するには途中でグループを90度回転する(天頂角方向）、など。
[Carthage] Cartfile.resolvedに変更がある時だけcopy-frameworksを実行する設定

Carthageの`copy-frameworks`は少し時間がかかる処理なので、
`Cartfile.resolved`に変更がある時にだけ実行するスクリプトをメモっておこうかと。


```sh
#! bin/sh

set -e

target_dir="${TARGET_BUILD_DIR}"
mkdir -p $target_dir

source=${SRCROOT}/Cartfile.resolved
target=${target_dir}/Cartfile.resolved

if ! diff ${source} ${target} &>/dev/null; then
/usr/local/bin/carthage copy-frameworks
fi

cp ${source} ${target}
```

<img width="816" alt="Screen Shot 2018-03-16 at 12.43.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/8358/4f09d48b-fbc3-d4cd-0061-efbf7c83d5b3.png">

スクリプトの中身は、
ビルド時にターゲットディレクトリに`Carthage.resolved`をコピーしておき、
ビルドするたびにdiffを取り、差分があればcopy-frameworksを実行する。というものです。

でも、期待した動作になるかどうかはユースケース次第なので参考までにどうぞ〜
Unix で非 ASCII 文字を含む行だけを抽出する Tips

`grep` で頑張ろうと思ったけど Perl を使ったほうが楽だった。

## 非 ASCII 文字を含む行を抽出する
``` console
$ cat FILE | perl -ne 'print if /[[:^ascii:]]/'
```

## 非 ASCII 文字を含まない (ASCII 文字のみの) 行を抽出する
``` console
$ cat FILE | perl -ne 'print unless /[[:^ascii:]]/'
```

## ASCII 文字を含む行と含まない行をそれぞれ別のファイルに出力する
``` console
$ cat FILE | perl -ne 'if (/[[:^ascii:]]/) { print STDERR } else { print STDOUT }' 1> ASCII_FILE 2> NON_ASCII_FILE
```
flexやgridって改めて便利だなと思ったこと

以下の図のようなよくあるレイアウトの場合、
これまでは`position: absolute;`を使わないと実現出来ませんでした。（あるいはjsか）

![rayout.png](https://qiita-image-store.s3.amazonaws.com/0/105520/d3679fa5-c5aa-c1c9-871d-c286407e50e8.png)

## flexで組む場合

``` html:html
<div class="wrap">
  <div class="inner">
    <div class="foo">
      <img src="test.png">
      <p>hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge</p>
    </div>
    <div class="bar">
      <p>fugafuga</p>
    </div>
  </div>
  <div class="inner">
    <div class="foo">
      <img src="test.png">
      <p>hogehoge</p>
    </div>
    <div class="bar">
      <p>fugafuga</p>
    </div>
  </div>
</div>
```

``` css:flex.css
.wrap {
  display: flex;
  word-break: break-word;
}
.inner {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 50%;
  padding: 10px;
  margin: 0 10px;
  border: 1px solid #eee;
}
.foo img {
  width: 100%;	
}
.bar {
  align-self: flex-end;
  background: #eee;
}
```

## gridの場合

※ htmlは同じなので割愛

``` css:grid.css
.wrap {
  display: grid;
  grid-template-columns: repeat(auto-fit, 50%);
  word-break: break-word;
}
.inner {
  display: grid;
  padding: 10px;
  margin: 0 10px;
  border: 1px solid #eee;
}
.foo img {
  width: 100%;
}
.bar {
  align-self: flex-end;
  justify-self: flex-end;
  background: #eee;
}
```

gridはまだそこまでガツガツ使っていないので、この方が簡潔に書ける等ありましたらコメントいただきたいです！

ちょっとしたことですが、こういうレイアウトを組む場合に少しでも考える時間が減ると良いかなと思います。
JQuery TableSorterは表を分割する夢を見るか？

備忘用。

##お試し（CodePen）
できると言えば、かなり無理やりだけどできる。

<p data-height="400" data-theme-id="0" data-slug-hash="vRKjqr" data-default-tab="result" data-user="fujisystem" data-embed-version="2" data-pen-title="TableSorter" class="codepen">See the Pen <a href="https://codepen.io/fujisystem/pen/vRKjqr/">TableSorter</a> by fujisystem (<a href="https://codepen.io/fujisystem">@fujisystem</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


## 総括・ハマりポイント
- ~~CodePenで、header背景画像（検索方法）が表示できない。ローカルでは可能。不思議。~~<br/>
  ⇒どうもCodePenが自サイト用にソース改変する影響っぽい。Class名が変わっているように見える。<br/>
　　⇒しょうがないので、Codepen用にCss修正
- CodePenの無料版では画像ファイルのアップロードができなさそうな為、base64変換してCssに組み込んだ。
- CodePenを今回初めて使ったが、AutoSaveがOnだと試行錯誤の恥ずかしい実況放送が可能だということがわかって、得をした。
Scipy lecture notes, Edition 2017.1 > a very readable language with clear non-verbose syntax

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

https://www.scipy-lectures.org/
の[PDF, 1 page per side](https://www.scipy-lectures.org/_downloads/ScipyLectures-simple.pdf)

p12
Chapter 2
The Python language
箇条書き4つ目

(太字は記事執筆者が強調)
> a very readable language **with clear non-verbose syntax**

意味が分からなかった。

https://www.merriam-webster.com/dictionary/verbose
> 1: : containing more words than necessary : wordy

必要以上に「おしゃべり(talkative)」でないということだろうか。

### 関連

- [非エンジニアのWindows派がPythonを始めるメリットをこれでもかと説明します](https://tonari-it.com/python-start/#i-2) @ いつも隣にITのお仕事
    - > とにかく、文法がシンプルで書きやすく、読みやすいというのが大きな特徴です。
既存のプロジェクトにSwiftLintを導入してみた

## 前置き

一人で対応しているiOSアプリ開発で、Swiftを書いた事がないメンバーが新しく来たため、ソースコードの統一性と品質をカバーできないかと、Swiftの静的解析ツールでよく聞くSwiftLintを試しに導入してみました。

## 対象環境

* MacBook Pro (Retina 13-inch、Early 2015) 128GB
* Mac OS Sierra
* Xcode 9.2

## 前提

[Homebrew](https://brew.sh/index_ja.html)がインストールされていること

## インストール

下記コマンドを発行

```
$ brew install swiftlint
```

インストール確認

```
$ swiftlint version
0.25.0
```

## 設定

1. Xcodeを開き、プロジェクトのSchemeからBuild Phasesを選択し、+からNew Run Script Phaseを選択する
![01_01.png](https://qiita-image-store.s3.amazonaws.com/0/25578/4b02034f-db4f-89f2-bfac-f20144873c33.png)
1. 追加したRun ScriptのType a script or drag a script file from your workspace to insert its pathに下記を設定する
   
  ```
  if which swiftlint >/dev/null; then
    swiftlint
  else
    echo "warning: SwiftLint not installed, download from 
  https://github.com/realm/SwiftLint"
  fi
  ```
![01_02.png](https://qiita-image-store.s3.amazonaws.com/0/25578/15e78654-424c-af8f-42b5-3059e0e20d74.png)

## ルールを追加

プロジェクトの.xcodeprojが配置されているディレクトリに移動し.swiftlint.ymlを追加する

```
$ cd 対象ディレクトリ
$ touch .swiftlint.yml
```
.swiftlint.ymlをエディタで開き、ルールを貼り付ける(下記は個人的に設定したもの)

```.swiftlint.yml
disabled_rules:
- trailing_whitespace
- force_cast
- line_length
- function_body_length

opt_in_rules:
- attributes
- closure_spacing
- empty_count
- explicit_init
- fatal_error_message
- first_where
- implicitly_unwrapped_optional
- missing_docs
- nimble_operator
- number_separator
- object_literal
- operator_usage_whitespace
- overridden_super_call
- private_outlet
- prohibited_super_call
- redundant_nil_coalescing
- sorted_imports
- switch_case_on_newline
- valid_docs

excluded:
- Carthage/

identifier_name:
  min_length: 2

file_length:
  warning: 600
  error: 1200
```

## 実行

設定したプロジェクトのスキーマをビルドする

## 結果

警告460件、ビルドエラー23件出て泣いた。
フォーマット系は対応が楽でしたが、implicitly_unwrapped_optionalやmultiple_closures_with_trailing_closureの対応をする際はある程度影響範囲が広かったため、対応が少し面倒でした。

## 今後

運用しつつ様子を見て、効果があるのか、また、ルール設定をどのようにした方がよいのか検討していきたい

## その他

* 既に他のスクリプトが設定されているRun ScriptにSwiftLintのスクリプトを設定してしまい10分ほど悩んだ...
* Edit SchemeのBuild -> Pre-actionsのRun ScriptにSwiftLintのスクリプトを設定してしまいしばらく悩んだ...
* .swiftlint.yml設定時にexcludedを忘れ、Carthage配下のライブラリも解析対象としてしまい、警告が999+ビルドエラーが999+出て唖然となった...

## 参考にさせて頂いた記事

* [swiftlint 最新版(0.18.1) の設定ファイル(.swiftlint.yml)のサンプル](https://qiita.com/rd0501/items/ceabe756c419ec082030)
* [SwiftLintのRules全まとめ](https://qiita.com/kagemiku/items/80e6d905dc0059c342b3)
MacOS HighSierraで bundle が失敗する

HighSierraにアップデートして以降、bundleが以下のようなエラーで失敗します。

```
-bash: /usr/local/bin/bundle: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby: bad interpreter: No such file or directory
```

原因は、HighSierraかRuby2.3がバンドルされるようになったことだそうで。なので、インストールしていたcocoapodsに到達できなくなってしまっています。ここまでわかればあとはカンタン。

```
gem install -n /usr/local/bin cocoapods
```

でcocoapodsをインストールするだけで終了です。
"IE=edge"が効かなかったときの話

Internet Explorerで互換表示設定を無効化しようとしてハマったので、メモ。

互換表示させたくないHTMLが100ファイルくらいあったので各ファイルの`<head>`タグの中に下記のコードを書いたところ、一部のファイルだけ互換表示設定が無効化されない現象に遭遇した。

~~~
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
~~~

この設定が有効でないとCSSやらJavaScriptやらが正常に動作せず、レイアウトが崩れてしまって困る。

レイアウトが崩れてしまうHTMLと正常に表示されるHTMLを比べてみたところ、前者のソースには**`<meta http-equiv="X-UA-Compatible" content="IE=edge"/>`の出現位置が後ろの方にある**という特徴があることに気づいた。

[文字エンコーディングの指定はファイルの先頭から1024バイトまでに含まれるべき](https://www.w3.org/International/questions/qa-html-encoding-declarations.ja)という話も参考にして試行錯誤して出した結論。

どうやら、**`<meta http-equiv="X-UA-Compatible" content="IE=edge"/>`はファイルの先頭から4096バイトまでに含まれるべき**であるらしい。
最後の文字の`>`が4096バイト目ならばOK。4097バイト目ならNG。

##### 今回調べた環境
Internet Explorer バージョン11.0.9600.18921


## 参考
[IE対策：互換表示させない。](https://qiita.com/rico/items/09c896290e218ed2b7c3)
[Python3]GitHubのアイコンを円形にしようとした(失敗)

# 目的
最近丸アイコンが増えてきているので，GitHubのアイコンを円形にできたらいいなと思ってやってみた．

# ソースコード

```python:Python3
from PIL import Image, ImageDraw


img = Image.new('RGB', (420, 420), color=(240, 240, 240))
draw = ImageDraw.Draw(img)
r = 211
g = 116
b = 217
ul = 40
lr = 380
draw.pieslice((ul, ul, lr, lr), start=15, end=45, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=45, end=75, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=75, end=105, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=105, end=135, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=135, end=165, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=165, end=195, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=195, end=225, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=225, end=255, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=255, end=285, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=285, end=315, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=315, end=345, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=345, end=375, fill=(r, g, b))

ul = 96
lr = 324
draw.pieslice((ul, ul, lr, lr), start=15, end=45, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=45, end=75, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=75, end=105, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=105, end=135, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=135, end=165, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=165, end=195, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=195, end=225, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=225, end=255, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=255, end=285, fill=(240, 240, 240))
draw.pieslice((ul, ul, lr, lr), start=285, end=315, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=315, end=345, fill=(r, g, b))
draw.pieslice((ul, ul, lr, lr), start=345, end=375, fill=(r, g, b))

ul = 172
lr = 248
draw.ellipse((ul, ul, lr, lr), fill=(r, g, b))
img.save('test2.png')

```

# 結果
できた画像
![test2.png](https://qiita-image-store.s3.amazonaws.com/0/237843/85e0f79c-90e5-77fa-b3ba-9a5f4dcd494c.png)

GitHubの画像
![36354250.png](https://qiita-image-store.s3.amazonaws.com/0/237843/2818adcc-d920-e185-3ea6-8a1e233faa5a.png)

致命的にダサい．以上

# 改善点
5×5から離れたほうがいいのかもしれない

# 参考
[Python, Pillowで円や四角、直線などの図形を描画 | Python / note.nkmk.me](https://note.nkmk.me/python-pillow-imagedraw/)
[初めてのPython画像処理 - Qiita](https://qiita.com/uosansatox/items/4fa34e1d8d95d8783536)
GitBucket、Knowledge、Jenkinsのフォルダパスを変える環境変数名

ボクメモ。


# GitBucket
https://github.com/gitbucket/gitbucket

名前：`GITBUCKET_HOME`
値：フォルダ名


# Knowledge
https://information-knowledge.support-project.org/ja/

名前：`KNOWLEDGE_HOME`
値：フォルダ名


# Jenkins
https://jenkins.io/

名前：`JENKINS_HOME`
値：フォルダ名


### 宣伝
個人ブログはじめました～
https://nnahito.com
さくらレンタルサーバでWordPressを常時SSL化するときの .htaccessの記述

さくらから常時SSL化のプラグインが提供されているが、有効化しようとしてエラーが出た場合。
.htaccessに以下を追記して、SSL化できた。

```
# BEGIN Force SSL for SAKURA
# RewriteしてもHTTPS環境変数を有効にする
SetEnvIf REDIRECT_HTTPS (.*) HTTPS=$1
# 常時HTTPS化(HTTPSが無効な場合リダイレクト)
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{ENV:HTTPS} !on
RewriteCond %{REQUEST_URI} !^/wp-cron.php$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# END Force SSL for SAKURA
```
postgresqlで、小数->整数のキャスト

```sql
select version(); -- "PostgreSQL 9.6.8 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18), 64-bit"

select '10.5'::integer; -- error

select '10.5'::numeric::integer; -- 11
select '10.4'::numeric::integer; -- 10
select '10.5'::double precision::integer; -- 10
select '10.4'::double precision::integer; -- 10

select 10.5::integer; -- 11
select 10.4::integer; -- 10
select 10.5::double precision::integer; -- 10
select 10.4::double precision::integer; -- 10

select cast(10.5 as integer); -- 11
select cast(10.4 as integer); -- 10
select cast(10.5::double precision as integer); -- 10
select cast(10.4::double precision as integer); -- 10
```

* 文字列 -> integerだと、errorになった。
* numeric -> integerだと、四捨五入された。
* 単に10.5とか書いてintegerにすると、numeric -> integer扱いで、四捨五入された。
* double precision -> integerにすると、切り捨てられた。
Laravelの「php artisan db:seed」で「Class ****Seeder does not exist」が発生

#起きたこと
新しいシーディングクラスを作成して、「php artisan db:seed」を実行したら「Class ****Seeders does not exist」が発生

#環境
vagrant　homesteadサーバ
PHP 7.2.2
Composer version 1.6.3
Laravel Framework 5.5.35

#原因
追加したシーディングクラスがautoloadされるクラスに定義されていなかった

#対応
以下のコマンド実行して、autoloadされるクラスに定義してあげる

```console
composer dump-autoload
```
[Unix] Find files contains string   


```sh
 find . -name *.yml -exec grep -l '\[\]' {} \;
```

### Explanation:

```sh
find . -name *.yml 
```
Find the files with extension of `yml`;

```sh
-exec ..
```
Select if the command exit code is zero value after exec.

```
grep -l 
```
Output file path inside of content.

```sh
{}
```
File path pass from `find` as a parameter of `grep`

```
\;
```
The `-exec` must end with `;`, if invoke from shell must with quote `\;`.
CentOS 7 ApacheのHTTP/2対応

# 動作確認環境
事情によりバージョンをダウングレードしました。新しいバージョンでも動作するはずです。

- 仮想環境 VMware Workstation Player 12.5.9
- OS Windows 10 Pro 64bit

# 仮想環境
- OS CentOS 7.4 (1708) minimalインストール
- メモリ 2GB
- HDD 250GB

# 前提条件
- gcc 8.1.0
- cmake 3.11.4
- MySQL 5.7.22
- OpenSSL 1.1.0.h
- Apache 2.4.33

# HTTP/2対応
共有ライブラリへパスを通す。

````
vi /etc/ld.so.conf
````

````ld.so.conf
/usr/local/lib
/usr/local/ssl/lib
````

更新する。

````
ldconfig
````

HTTP2に対応させるため、Apacheの`http.conf`の`mod_http2.so`のコメント外す。

````
vi /usr/local/apache2/conf/httpd.conf
````

````httpd.conf
LoadModule http2_module modules/mod_http2.so
````

`LoadModule`の下に追記する。

````httpd.conf
<IfModule http2_module>
    LogLevel http2:info
</IfModule>
````

Apacheを再起動し、何も表示がなければ起動が成功した。

````
systemctl restart httpd
````


# 参考
[Setting up HTTP/2 on Apache to improve web performance | Tune The Web](https://www.tunetheweb.com/performance/http2/)

---
[目次](https://qiita.com/knutpb1205/items/3ece0cab588afdb13f02)
SpringのJUnitで@Autowiredできない！

## 以下のアノテーションをつける
@RunWith(SpringRunner.class)
@SpringBootTest

```java:TestApplicationTests.java
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplicationTests {

	@Test
	public void contextLoads() {
	}

}
```
Amazon SNSのUnsubscribeのリンクを無効化する

Amazon SNSのEmailの最後についてくるUnsubscribeのリンク
メーリングリスト宛に通知するなどの使い方をしている場合、誰かがUnsubscribeすると困っちゃう、それへの対応方法

```
--
If you wish to stop receiving notifications from this topic, 
please click or visit the link below to unsubscribe:
https://sns.ap-northeast-1.amazonaws.com/unsubscribe.html?SubscriptionArn=arn:aws:sns:ap-northeast-1:999999999999:xxxxxx:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&Endpoint=user@example.com

Please do not reply directly to this email. 
If you have any questions or comments regarding this email, 
please contact us at https://aws.amazon.com/support
```

既に購読している場合は一旦解除し、再度購読要求を出す。
その時に発行されるTOKENを使い、次のAWSCLIで購読する。
`--authenticate-on-unsubscribe true`とすると、topic所有者のみ購読解除が可能となる。

aws sns confirm-subscription --token *token* --topic-arn *topic-arn* --authenticate-on-unsubscribe true
【VSTO】エクセルを開いたとき、シートがアクティブになったときのイベント処理

VSTOをはじめて作ってみたので、それのメモ

# 環境
C#

# イベント処理
```C#:ThisAddIn.cs
//(省略)
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            this.Application.WorkbookActivate += Application_Active;
            this.Application.SheetActivate += Sheet_Active;
        }
        void Application_Active(Excel.Workbook wb)
        {
            //起動時の処理を書きます～
            Excel.Worksheet activeWorksheet = ((Excel.Worksheet)Application.ActiveSheet);
            MessageBox.Show(activeWorksheet.Name, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        void Sheet_Active(object sh)
        {

            //シートアクティブの処理を書きます～
            Excel.Worksheet activeWorksheet = ((Excel.Worksheet)Application.ActiveSheet);
            MessageBox.Show(activeWorksheet.Name, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information);
                
        }
```
DataBase設計の基礎だけ

# Databaseは何のためにあるか？
Databaseはある一つの値を定めた時に他の欲しい値を取り出すためにある。
例) 商品IDという値を定めた時に商品の名前、商品の値段、商品のメーカー、商品の在庫など欲しい値を取り出せるようにするためにDatabaseは存在している。(多分)

# Databaseの基礎的な登場人物
Databaseを設計する時に出てくる単語はで特に覚えておかないといけないのは次の4つらしい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211192/b559eae8-503e-e24f-485d-d8089afbce11.png)http://it-koala.com/entity-relationship-diagram-1897


#### 1. エンティティ(意味: 実体)
クラスでいうクラス名のようなもの。値を取り出す時に投げるものの種類。それに対して情報を付け加えたいもの。上の例だと商品IDがエンティティになる。

#### 2. アトリビュート(意味: 属性)
クラスでいうメンバー変数、プロパティのようなもの。取り出される値の種類。付け加えられた情報。上の例だと商品の名前、商品のメーカー、商品の在庫などが商品IDの属性になる。

#### 3. リレーション(意味: 関係性)
結びつきのあるエンティティをリンクさせるもの。エンティティ同士の結びつき。例えば「顧客ID」というエンティティと「注文ID」というエンティティは関連している。

#### 4. カーディナリ(意味： 関係の比)
エンティティ同士の関係が何対何になるか。例えば一人の顧客に対して注文はたくさんあるので、顧客ID:注文IDは1:多になる。この時の1:多が関連の多重度である。

# Databaseの表現方法
ER図(Entity Relationship Diagram)で書きあらわす。詳しい書き方などはこちらに書いてあった。
若手プログラマー必読！５分で理解できるER図の書き方５ステップ
http://it-koala.com/entity-relationship-diagram-1897#i-6
開発費用項目

# はじめに

ざっくりクライアントに見積書（費用感？）を提示するときに、よく使わせていただいている項目7個。

## 開発費用項目

| # | 名称 | 説明 |
| :-: | --- | --- |
| 1 | 要件定義費用 |  実装すべき機能や満たすべき性能などを明確にしていく作業費用 |
| 2 | システム設計費用 | システムの設計およびデータベースの設計にかかる費用 |
| 3 | UIデザイン費用 | 画面レイアウト・ページ構成の設計にかかる費用 |
| 4 | 機能開発費用 | 機能を開発する費用 |
| 5 | テスト費用 | システムが設計通りに動作するかを確認する費用 |
| 6 | 導入費用 | システムを本番サーバー上で稼働させ、パフォーマンスがでるように設定する費用 |
| 7 | 導入支援費用 | 操作マニュアルの作成や操作説明会の実施にかかる費用 |

## 参照

『[はじめよう！ 要件定義 ～ビギナーからベテランまで](http://gihyo.jp/book/2015/978-4-7741-7228-6)』 羽生章洋 著、技術評論社（2015年4月発行）

## 個人的感想

この7項目をひとつづつしっかりできたなら、「ちゃんと動いて、使われるシステム」になると思うが、現実は得てして「納期を間に合わせるために、やっつけで作られたシステム」が出来上がってしまう。「契約締結前交渉費用」とその時間が入ってないからでしょうね。項目にないのに費用に含まれ、開発じゃないのに期間を食う。
「相談」tensorflowで画像の予測についての知恵を貸していただけませんか

私は人工知能を半年前から勉強を始めばかりですので、
ニューラルネットワークのことは少しずつ理解していますが、開発の経験がありません。
また、プログラミングはあまり得意ではなく、pythonも以前触ったことがありません。
というわけで、今の試作がなかなか順調ではなく、やり続けなくなってしまいました。
ここでニューラルネットワークに詳しい方に相談してみて、
知恵を貸していただけないかと考えています。

では、試作の内容を説明させていただきます。
tensorflowを使って、過去の天気図を学習して、
学習によりもらった特徴を使用し、
次の時点の天気状況を予測し、新しい天気図を作成する予測モデルを作りたいです。
今は天気図を二値化処理して、画像データを三つごとで訓練データに入れましたが、
（気象庁の天気図は3時間毎の過去画像がありますが、0時の画像がありません。
3時、9時、15時と21時のパターンなら、0時データがない問題を回避できると思います。）

その次でどうやって進むのは考えています。
例えば、CNNとRNNのどっちを選ぶか、あるいは、どのような形でCNNとRNNを組み合わせるか、
私の理解ではCNNは画像の分類と識別については、よい効果がありますが、
"未来"のこと、予測のことにはあまり得意ではないと思います。
逆に、RNNは時系列の予測のために生まれたものです
ですが、
株価の予測とか、エネルギー使用量の予測とかについてのサンプルをよく見つかりましたが、
どっちも一次元のことで、二次元の画像についての予測をなかなか見つかりません。
もしかして、画像の予測などはRNNの強みではないと思っています。
（もし以上ニューラルネットワークについての理解が間違いたら、笑わないでください）

ニューラルネットワークの技術は一日二日で身に着けるものではないのは十分に理解しています。
今の段階で、精度のことはともかく、
まず、予測により作成られた画像が天気図らしい予測モデルを作りたいです。
というわけで、方々の知恵を貸していただけませんか？
matplotlibでデフォルトで日本語を表示可能にする

matplotlibで日本語を表示させようとすると、デフォルト設定では``DejaVu Sans``という日本語が入っていないフォントが選択されるので、豆腐になります。

で、それを解消するときに参考にしたサイトが[これ](http://kaisk.hatenadiary.com/entry/2015/02/15/215831)なんですが、ほぼ完ぺきなんですが少しだけ情報が抜けていました。

これは、その補足です。

## 目標

少し設定をいじるだけで日本語でグラフを表示可能です。なので、目標の1つ目は

- OSにすでにある日本語を含むフォントを、matplotlibのデフォルト出力フォントにする

です。
ですが、既存のフォントが気に食わないときもあるかと思います。なので、次の目標は、

- 新しいフォント(例えば、IPAexゴシックなど)を、matplotlibのデフォルト出力フォントにする

としました。

## 環境

私が日本語にしたときは、こんな環境でした

- windows10
- python3
  - pythonは、公式のインストーラからインストール(VisualStudio経由やAnaconda経由ではない)
- matplotlib 2.1.0
  - pip経由でインストール

上記に当てはまらない人は、各種フォルダのパスが違ってきます。
記載してあるコマンドで、フォルダのパスを確かめながら進めてください。

では、次からやり方を記載していきます

## OSにすでにある日本語を含むフォントを、matplotlibのデフォルト出力フォントにする

OSにttfの形式で格納されているフォント[^1]は、すべてmatplotlibは認識しています。
そういうフォントでいいやという人は、下記のステップでmatplotlibのデフォルト出力フォントを変更できます

- matplotlibの設定ファイルの場所を探す
- matplotlibの設定ファイルをユーザー設定フォルダにコピー
- matplotlibの設定ファイルを書き換える
- フォントのキャッシュの削除

[^1]: windowsでttf形式の提供されているフォントの多くが、リコーフォントです。リコーフォントの商用使用は、追加料金がかかる可能性があるので、十分注意して使ってください。

### matplotlibrcの場所を探す

``matplotlibrc``というmatplotlibの設定ファイルを探します。

下記で調べられますし、

```python
import matplotlib as mpl
mpl.matplotlib_fname()
```

windowsなら多くの人は、

>C:\\Users\\{your_name}\\AppData\\Local\\Programs\\Python\\Python{version}\\lib\\site-packages\\matplotlib\\mpl-data\\matplotlibrc

です。

### matplotlibrcをユーザー設定ファイルを置くフォルダにコピー

``mpl.matplotlib_fname()``にある``matplotlibrc``は、もしもの時のバックアップに使いたいので、ユーザー設定ファイルを置くフォルダにコピーします。

ユーザー設定ファイルを置くフォルダは、
[公式](https://matplotlib.org/faq/troubleshooting_faq.html#locating-matplotlib-config-dir)曰く、

```python
import matplotlib as mpl
mpl.get_configdir()
```

です。なお、windowsはデフォルトで下記です。

>C:\\Users\\{your_name}\\.matplotlib\\

### matplotlibの設定ファイルを書き換える

ユーザー設定ファイル``matplotlibrc``の``font.family``という部分を書き換えます。

例えば、「Arialを使いたいなら``Arial``」と、「游明朝を使いたいなら``Yu Mincho``」と記載してください。

どんなフォントが使えて、どんな名前で使えるのかは、ユーザー設定ファイルのあるフォルダの``fontList.json``に書いてあります。

### フォントキャッシュの削除

フォントキャッシュがあるなら削除しましょう。そうしないと、キャッシングされたフォントを使うことになります。
ユーザー設定ファイルのあるフォルダにある

- ``fontList.cache
- ``fontList.py3k.cache

などを削除すればOKです(ないならないで、大丈夫です)

もしもそこにない場合は、下記コマンドでキャッシュの位置を調べてください

```python
import matplotlib as mpl
mpl.get_cachedir()
```

以上で、設定したフォントを使えるようになるはずです。
次は、matplotlibが認識していないフォントの使いかを見てみます

## 新しいフォントを、matplotlibのデフォルト出力フォントにする

今回は、「matplotlibが認識していないフォント(例えば、msGothic)などを、matplotlibのデフォルト出力フォントにする」ことを見ていきます

これは、次のステップできます

- フォントをインストールする
- フォントをmatplotlibに認識させる
- ``matplotlibrc``を書き換える

### フォントをインストールする

通常のフォントインストールと同じです。
windowsならフォントファイルをダブルクリックするだけです。

### フォントをmatplotlibに認識させる

``fontList.json``を削除してください。このファイルは、matplotlibが、matplotlibのフォントディレクトリとシステムのフォントディレクトリをスキャンして自動生成しています。なので、``fontList.json``がない状態でplotを実行して、新しくインストールしたフォントが認識された``fontList.json``が自動で生成してください。

### matplotlibrcを書き換える

``fontList.json``に新しくインストールしたフォントの設定が追加されているはずです。
そのフォント名称(``fontList.json``の``name``属性)で、``matplotlibrc``の``font.fmaliy``を書き換えてください
都道府県コード JSON版とJS版

# はじめに

都道府県コードと都道府県名の変換が必要になったとき、将来の自分もきっと「どこかにコピペできるコードはないか」って探すと思うので、あらかじめ投稿しておきます。その時もJS言語を使っているどうかわかりませんが（昔、PHPコードとSQLクエリー文で用意してましたが、捨てちゃいましたからね）。

# 都道府県コード JSON版

```json:prefectures.json
{
"prefectures": [{ "code": 1, "name": "北海道"},
    { "code": 2, "name": "青森県"},
    { "code": 3, "name": "岩手県"},
    { "code": 4, "name": "宮城県"},
    { "code": 5, "name": "秋田県"},
    { "code": 6, "name": "山形県"},
    { "code": 7, "name": "福島県"},
    { "code": 8, "name": "茨城県"},
    { "code": 9, "name": "栃木県"},
    { "code": 10, "name": "群馬県"},
    { "code": 11, "name": "埼玉県"},
    { "code": 12, "name": "千葉県"},
    { "code": 13, "name": "東京都"},
    { "code": 14, "name": "神奈川県"},
    { "code": 15, "name": "新潟県"},
    { "code": 16, "name": "富山県"},
    { "code": 17, "name": "石川県"},
    { "code": 18, "name": "福井県"},
    { "code": 19, "name": "山梨県"},
    { "code": 20, "name": "長野県"},
    { "code": 21, "name": "岐阜県"},
    { "code": 22, "name": "静岡県"},
    { "code": 23, "name": "愛知県"},
    { "code": 24, "name": "三重県"},
    { "code": 25, "name": "滋賀県"},
    { "code": 26, "name": "京都府"},
    { "code": 27, "name": "大阪府"},
    { "code": 28, "name": "兵庫県"},
    { "code": 29, "name": "奈良県"},
    { "code": 30, "name": "和歌山県"},
    { "code": 31, "name": "鳥取県"},
    { "code": 32, "name": "島根県"},
    { "code": 33, "name": "岡山県"},
    { "code": 34, "name": "広島県"},
    { "code": 35, "name": "山口県"},
    { "code": 36, "name": "徳島県"},
    { "code": 37, "name": "香川県"},
    { "code": 38, "name": "愛媛県"},
    { "code": 39, "name": "高知県"},
    { "code": 40, "name": "福岡県"},
    { "code": 41, "name": "佐賀県"},
    { "code": 42, "name": "長崎県"},
    { "code": 43, "name": "熊本県"},
    { "code": 44, "name": "大分県"},
    { "code": 45, "name": "宮崎県"},
    { "code": 46, "name": "鹿児島県"},
    { "code": 47, "name": "沖縄県"}]
}
```

## 都道府県コード JS版

```js:prefectures.js
module.exports = {
    prefectures: [
        null,
        '北海道',
        '青森県',
        '岩手県',
        '宮城県',
        '秋田県',
        '山形県',
        '福島県',
        '茨城県',
        '栃木県',
        '群馬県',
        '埼玉県',
        '千葉県',
        '東京都',
        '神奈川県',
        '新潟県',
        '富山県',
        '石川県',
        '福井県',
        '山梨県',
        '長野県',
        '岐阜県',
        '静岡県',
        '愛知県',
        '三重県',
        '滋賀県',
        '京都府',
        '大阪府',
        '兵庫県',
        '奈良県',
        '和歌山県',
        '鳥取県',
        '島根県',
        '岡山県',
        '広島県',
        '山口県',
        '徳島県',
        '香川県',
        '愛媛県',
        '高知県',
        '福岡県',
        '佐賀県',
        '長崎県',
        '熊本県',
        '大分県',
        '宮崎県',
        '鹿児島県',
        '沖縄県',
    ],
};
```
outliersパッケージのrm.outlierをもう少し使いやすく

outliersパッケージのrm.outlier関数の挙動がちょっと気に食わなかったのでググったら、同じことで悩んでいる人がいた。
[Error in data.frame with rm.outlier function](http://stackoverflow.com/questions/13685914/error-in-data-frame-with-rm-outlier-function)
何が気に食わないかというと、rm.outlier関数にdataframeを入れた場合、それぞれのcolumnから外れ値を除外したベクトルのリストが返される。このリストに含まれるベクトルの長さが一定ではないために、再びdataframeに戻すことができないため。
なので↓こうした。

```r
outlier.na <- function(df) {
  apply(df, 2, function(x) {
    x[which(x == outlier(x))] <- NA
    x
  })
}
```

```rb
> nrow(iris)
[1] 150
> nrow(na.omit(outlier.na(iris[,-5])))
[1] 144
```
回帰分析で95%予測区間を計算するかなり簡単な方法

学習用のサンプル数が多い（大体30以上あれば十分）のであれば、
予測値 ± 残差の標準偏差 * 2
とすればだいたい95%予測区間が計算できる。らしい。
どっかの本に書いてあったけどどの本か忘れました…間違ってたらごツッコミおねがいします～
link > CentOS > memtest86+ > インストールと起動方法 | GRUBメニューの表示方法 > Memtest86+は起動しない

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

Linuxにてメモリチェックをしてみる。

### 関連

[CentOS > 謎の再起動の再発 > ps -efのログ確認](https://qiita.com/7of9/items/510165dfb946a7184305)

### 参考

https://access.redhat.com/solutions/15693

### インストール

```
$ sudo yum install memtest86+
```

### 実行

> Then you will have to configure it to run on next reboot:

```
$ sudo memtest-setup
[sudo] password for y_okada: (ここでパスワード入力)
Setup complete.
```

> After reboot, the GRUB menu will list memtest. Select this item and it will start testing the memory.

再起動後にGRUBメニューでmemtestを選択する、とのこと。

実際にCentOSで上記を実行後再起動してみたが、memtest86+のGRUBメニューは表示されなかった。
そもそもGRUBメニューが表示されない。

### GRUBメニューの表示方法

以下を見つけた。
[CentOS6 をシングルモードで起動する (CentOS Tips)](https://www.ipentec.com/document/linux-centos-6x-boot-single-mode) @ Pentec
> マシンの電源投入後、下図の画面が表示されます。カウントが0になる前に任意のキーを押します。

情報感謝です。

GRUBメニューを表示したところ、Memtest86+ (5.01)の選択ができるようになった。

選択をしたところ、カーソルの点滅があるだけでMemtest86+は起動しない。

あきらめて、CD-ROM版でのMemtest86+起動にした。
ubuntuでのchshの「Password: chsh: PAM: Authentication failure」の対応

デフォルトのシェルをzshに変えようとしたら、`chsh: PAM: Authentication failure`というエラーが発生した。

```bash
$ chsh -s /bin/zsh
Password:
chsh: PAM: Authentication failure
```

検索すると英語で書かれたGitHubのissueがヒットした。どうやらuserの指定をする必要があるみたいだ。

[chsh: PAM authentication failed on Ubuntu 12.04 · Issue #1224 · robbyrussell/oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh/issues/1224#issuecomment-31623113)

```bash
$ sudo chsh $USER -s $(which zsh)
Password:
```

O K !

# 原因

[Personal Memos: CHSHコマンドで失敗して](https://takeshinho-24.blogspot.jp/2011/04/chsh.html)
1008　Perflib　サービス "BITS" (DLL "C:\Windows\System32\bitsperf.dll") の Open プロシージャに失敗しました。このサービスのパフォーマンス データは利用できません。データ セクションの最初の 4 バイト (DWORD) に、エラー コードが含まれています。

WinServ2012R2で
上記のエラーが出ていたので
グーグル先生に伺った所

https://yamahide.biz/archives_99.html

今回の”BITS”の場合は、管理者として実行したコマンドプロンプトで下記を実行すれば直ります。
cd C:\Windows\inf\BITS\0411
 lodctr bitsctrs.ini

と言われたけど
 lodctr bitsctrs.ini
が何か分からなかったけど


http://tensi-gruppe.blogspot.jp/2010/11/windowsid1008.html

管理者モードでコマンドプロンプトを起動し、
>cd c:\windows\inf\bits\タイムスタンプの一番新しいフォルダ 
（※目の前の環境だと、0411でした）
>lodctr bitsctrs.ini
　(※bitsperfの環境設定ファイルを再読み込み)
以上、


なので実行しましたっ

もう起こらない予感っ
新人エンジニア育成 〜ビギナーの成長度と、チームのコストの話〜

僕が、今のプロジェクトに入りたての頃。

とあるメンターが、僕に図を描いて説明してくれたことがあった。
チームが支払う学習コストと、ビギナーの成長度について。

# マトリクス

右ほどチームのコストが低く、上ほどビギナーの成長度が高く、良い状態。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/d2a7bfb5-6325-91ec-31e5-d0c3f78033ab.png)


# 戦略1. コスト高・成長度高

ひとつの戦い方は、チームでたくさんコストを支払って、ビギナーにいち早く成長してもらうこと。
そして、急ピッチでコストのかからないレベルまで到達してもらうことだ。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/d1917536-97f7-a952-a27e-9ff1aab99cac.png)

人間、基本的には、周りにコストをたくさんかけた方が、ぐんと成長しやすいように思う。
チームに余裕があったり、教えるノウハウがある場合は、この方法が良いかもしれない。


# 戦略2. コスト低・成長度低

チームの状況や、ビギナーの練度、そのバランスによっては、大きな学習コストをかけるのは得策ではない、という状況もある。
その時は「ビギナーが学習コストを大きく支払って、チームにコストをかけずに成長する」という戦い方がある。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/2ebbbd30-37c0-cd07-8cb3-58937a2f3207.png)

僕が今のプロジェクトにジョインしたばかりの頃、戦略1から戦略2に方針が変わった時があった。

そのときには、贅沢にも、時には丸1日をかけて、
「SQLのたった1行分、ユニークで取るか、非ユニークで取るか」ということを考えたような日もあった。

ひとつの答えが出たと思いきや、またひとつ上の答えに行き着いて、時間が経つと、さらにひとつ上の答えが見つかり、だけど最後に、プロジェクト責任者の考えはまた逆だと分かり、オセロが次々に逆になる。そんな感じ。

だけど自分の限度まで「誰にも聞かず、ひたすら考える」ということを続けたおかげで、ある程度「自分で考える習慣」というのが付いたように思う。これは本当に良い時期だった。

# まとめ

チームによって学習方針も色々だと思うが、こんなマトリクスで考えると役立つかもしれない。








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
rails5 viewでアクションによって条件分岐させたい場合

```ruby:new.html.haml
- if controller.action_name == "new" ##　newアクションの場合
   式
- else                               ##　newアクション以外の場合
   式
```

`controller.action_name`で、アクション名を参照できる。

**参考**
`controller.controller_name`で、コントローラー名を参照できる。
サーバー {ｘｘ} は、必要なタイムアウト期間内に DCOM に登録しませんでした。

が再起動時に頻発しているのですが

http://d.hatena.ne.jp/sabonight/20150706/1436147165

「このイベント ログは、コンピュータの負荷が非常に高い場合に記録されることがあります。」

だと思っておきます……
自分しか迷わないnginxのロケーション

最近業務で初めてnginxを扱ったのだが、既に公開されている会社のホームページにコンテンツを追加する作業だった。
その中でlocationについて学んだことを共有する。

- いずれか一つしか採用されない。
- 最長一致したものが採用される。
- if文の代わりにはならない。
- 似て非なるコンテキストはincludeでまとめる。
- 何が採用されたかは個別のアクセスログファイル名を指定すると分かる。

もっとあった気がするが、思い出したら追記する。

## 参考
- https://heartbeats.jp/hbblog/2012/04/nginx05.html
- http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node31.html
Swiftを触って現段階でわかったこと。


2018年2月ごろから友人が運用しているアプリの改修に携わることになった。話があったのはもう5年前だが、その当時はちょうどSwiftがで初めてObject-cとの切り替えの時期でした。ネット上にも参考になるものがなく全く何もできませんでした。
もともとWebデザイナーでUIを専門にしていましたが、HTML、CSS、JSはなんとか出来た感じでした。
以前からプログラミングには興味があり、C#でアプリを作成した経緯もあり、今回改修に挑戦して見ました。

デザイナーでJSやPHPなどを多少囓った人間からするとSwiftはなんとも奇怪に映る言語です。
そこで、この数ヶ月Swiftに触れて現時点でわかったことをまとめたいと思います。

## 対象
- OS 10.13.3
- Xcode8
- Swift 3

## わかったこと
### SwiftはAutolayoutとコードで実装ができるのが厄介
当たり前だが、これがしれば知るほど厄介に感じる。SwiftはWindowsのVisualStudioと違ってレイアウトとコードが混在している。コードでも制御でき、さらにAutolayoutでも制御できるので実装としては強い意志でどちらかを貫く姿勢が必要になってくる。
さらに、私みたいな素人だと、どうしてもAutolayoutに走りがちで、Autolayoutで全てできると先入観が生まれてしまう。しかし、よくよく実装してみるとAutolayoutでは本当に表面的なことしかできなく、実際はコードを書かないと解決しない。
さらに、見た目の話なので、コードだけで済むかというとそうもいかない。

特にデザイン上の問題などを解決するのが非常に面倒になってくる。コードで処理した方が良いのかAutolayoutで対応した方がいいのかが状況に応じて対応しなくてはいけず、状況自体が把握できな場合安易な対応になる。それが後々命取りになる。

### 画面描画のタイミングに応じた画面設定
当初、なんのこっちゃと思っていたことが、やっと今になってなんとなく理解できてきた。
Swiftは「インスタンス化された直後」「画面が表示される直前」「画面が表示された直後」「別画面に遷移する直前」でそれぞれ表示状態を分けることができる。
さらに、直前の画面状態が遷移後の画面に影響を与えることになる。それが顕著に現れるのがナビゲーション周りである。
このこととさらに先ほどのAutoLayoutとの調整で、何がどう絡んでいるのかが複雑になってくる。
さらに、改修作業が間を置いた状態で、対応する人も違うと、さらに厄介になってくる。

当初から、コードの設計を明確にして、さらに、ガイドラインなどにまとめておくと非常yにやりやすく思った。

このことは、多分、画面が多岐にわたりナビゲーションが共通化されるという前提で言語自体が設定されているような気がした。

### 厳密な記述ルールと柔軟な実装方法
Swiftのせいなのか、Xcodeのせいなのか、記述ルールが厳密に決まっているのもSwiftの特徴だ。
まだ全貌を調べていないが色々と記述への警告が表示される。

[SwiftLintのRules全まとめ](https://qiita.com/kagemiku/items/80e6d905dc0059c342b3)

例えば、1つのfunctionの中には40行までしか記述出来ないなど、通常の言語だとそこまで厳しくないが警告やエラーの元になる。

さらに、これを厄介にさせているのが、実装の方法が多岐に渡っていること。先のAutolayoutしかり、コードの記述にもいくつか方法があるようだ。
こうなってくると、修練を重ねて自分流の記述方法を編み出して行くしかなくなってくる。しかし、そこで属人性を発揮してしまうと、今後の運用で支障が出ることになる。

運用方法を考えながら、最適なコード実装を目指す必要があることがわかった。
まぁーエンジニアとしては当たり前のことなのだが、なかなか実現するのは難しい。
ニューラルネットワークをtensorflowで書いてみた例

これを分類するためのニューラルネットワークのコードです
![image.png](https://qiita-image-store.s3.amazonaws.com/0/239009/719c9c2a-ff94-ebb9-c758-dceb12f44efc.png)

```python
N = 300
X, y = datasets.make_moons(N, noise=0.3)
Y = y.reshape(N,1)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, train_size=0.8)

n_in = 2
n_out = 1
n_hidden = 3

x = tf.placeholder(tf.float32, shape=[None, n_in])
t = tf.placeholder(tf.float32, shape=[None, n_out])
keep_prob = tf.placeholder(tf.float32, shape=[])

W0 = tf.Variable(tf.truncated_normal([n_in, n_hidden], stddev = 0.01))
b0 = tf.Variable(tf.zeros([n_hidden]))
h0 = tf.nn.relu(tf.matmul(x, W0) + b0)
h0_drop = tf.nn.dropout(h0, keep_prob)

W1 = tf.Variable(tf.truncated_normal([n_hidden, n_hidden], stddev = 0.01))
b1 = tf.Variable(tf.zeros([n_hidden]))
h1 = tf.nn.relu(tf.matmul(h0_drop, W1) + b1)
h1_drop = tf.nn.dropout(h1, keep_prob)

W2 = tf.Variable(tf.truncated_normal([n_hidden, n_hidden], stddev = 0.01))
b2 = tf.Variable(tf.zeros([n_hidden]))
h2 = tf.nn.relu(tf.matmul(h1_drop, W2) + b2)
h2_drop = tf.nn.dropout(h2, keep_prob)

W3 = tf.Variable(tf.truncated_normal([n_hidden, n_out], stddev = 0.01))
b3 = tf.Variable(tf.zeros([n_out]))
y = tf.nn.softmax(tf.matmul(h2_drop, W3) + b3)

epochs = 500
batch_size = 20
n_batches = N // batch_size

cross_entropy = - tf.reduce_sum(t * tf.log(y) + (1-t) * tf.log(1-y))
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(cross_entropy)
correct_prediction = tf.equal(tf.to_float(tf.greater(y, 0.5)), t)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

for epoch in range(epochs):
    X_, Y_ = shuffle(X_train, Y_train)
    
    for i in range(n_batches):
        start = i * batch_size
        end = start + batch_size
        
        sess.run(train_step, feed_dict={
            x: X_[start:end],
            t: Y_[start:end],
            keep_prob: 0.5
        })
        
accuracy_rate = accuracy.eval(session=sess, feed_dict={
    x: X_test,
    t: Y_test,
    keep_prob: 1.0
})

print("accuracy: ", accuracy_rate)
```
**accuracy:  0.45**