OmniAICreator/Qiita-1.07M huggingface dataset:
[C#]int.TryParse の out 変数から学ぶ

筆者の恥ずかしい失敗談を晒すエントリです。
まずはこちらをご覧ください。


## :tea: 問題
このとき isInt と tmp がコンソールに出力する値はなんでしょう？

```C#
using System;

public class Hello
{
  public static void Main()
  {
    int tmp = 10;
    bool isInt = Int32.TryParse("six", out tmp);
    Console.WriteLine(isInt);
    Console.WriteLine(tmp);
  }
}
```

## :bulb: 正解

|変数|出力される値|
|---|---|
|isInt|false|
|tmp|0|

そんなのは当たり前だ、という賢明な諸氏は特にこの記事から得るものはないのでそっとタブを閉じてやってください。

## :warning: 誤答

で、そんなのは当たり前ではなかった筆者の~~恥晒し~~誤答はこちら。

|変数|出力される値|
|---|---|
|isInt|false|
|tmp|10|

isInt が false になるのは期待どおりですが、問題が out 変数に指定していた tmp で、こちらは 10 が出力される、と思い込んでいました。**数値に変換できない値を渡した場合であっても out に代入はされる** んですね。なので tmp に予め 10 を格納しておいても全く意味がないということです。

## :pencil: 公式

https://msdn.microsoft.com/ja-jp/library/f02979c7(v=vs.110).aspx
> 変換に失敗した場合は 0 を格納します。

しっかり書かれてました。みなさん、公式ドキュメントはよく読みましょう(ブーメラン)


## :question: ところで 0 はいつ格納されているのか

ちょっと気になったので軽くソースを見てみることにしました。
この記事を参考にさせていただきました。
https://qiita.com/Marimoiro/items/e255eecc265cd5a45025


`int` は言わずもがな `System.Int32` のエイリアスです。
なので今回見たいのは `System.Int32` クラスのドキュメントになります。さっそく見てみます。
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/types#simple-types



### *System.Int32.TryParse*
https://referencesource.microsoft.com/#mscorlib/system/int32.cs,152

実際には `Number.TryParseInt32` が実質的な処理を行っているようですね。というわけで次へ進みます。

### *System.Number.TryParseInt32*
https://referencesource.microsoft.com/#mscorlib/system/number.cs,958cb8bc00d00a94
メソッドもそうなんですが、Numberクラス自体も internal であるため、基本はプログラマーが呼び出して使うようなクラスではなさそうですね。んで、問題の out 引数への代入はメソッド開始から3行目で早々に行われていることがわかります。

```C#:mscorlib/system/number.cs,1085
result = 0
```

中の実装まで見なくてもメソッドの挙動から明らかではありますが、[out を付けた引数は参照渡しになります。](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/out-parameter-modifier)
なのでこの代入によって先ほどの問題の `tmp = 10` が書き換えられていることは間違いなさそうです。


## 追記
@albireo さんからのコメントを参考に、out引数を持つメソッドを自作して確認してみたところ、そもそもout引数に対してメソッド内で何も値を代入しないとコンパイルエラーになることがわかりました。少なくともout引数が何らかの書き換えが行われていることは確実と言えます。

```C#
void hoge(ref int refValue, out int outValue)
{
  //これはOK
  if (refValue < 0) {
    refValue = 0;
  }

  if (outValue < 0) { //後述のエラー1
    outValue = 0;
    Console.WriteLine(outValue);//これはエラーにならない
  }

  //後述のエラー2
}
```


```:VisualStudioのコンソール
エラー1
  割り当てのない out パラメーター 'outValue' の使用です。
エラー2
  out パラメーター 'outValue' はコントロールが現在のメソッドを抜ける前に
  割り当てられる必要があります。
```




これでもう同じ失敗は繰り返さないでしょうｗ
最後まで読んで下さりありがとうございました。
情報処理安全確保支援士を取得するための学習ログ　その2

# 初めに
この度、自分のスキルアップのために情報処理安全確保支援士の資格を取ることになりました。セキュリティに関する知識が乏しいため、勉強をしていくなかで普段の業務のセキュリティに関する知識を吸収することも目的としています。

# 本ブログの目的
このブログは、僕が情報処理安全確保支援士の勉強に使っている参考書[「うかる！情報処理安全確保支援士2018年版」](https://www.amazon.co.jp/情報処理教科書-情報処理安全確保支援士-2018年版-上原-孝之/dp/4798154180)の内容を自分で振り返るためのアウトプットの場にしようと思います。

# 1.2情報セキュリティの特性と基本的な考え方
情報セキュリティの主な特性として、「機密性（Confidentality）」「完全性(Integrity)」「可用性(Availability)」の三つがある。これらは英語の頭文字をとって「CIA」と呼ばれる。また、付加的な特性としたは「真正性」「責任追及性」「否認防止」「信頼性」などがある。
情報セキュリティ対策には、「抑止・抑制」「予防・防止」「検知・追跡」「回復」などの機能がある。
情報セキュリティ対策における基本的な考え方は、下記のものになる。

* 対策を行う前にリスクアセスメントを行う
* 守るべきものを認識する
* 脅威を知る
* 脆弱性を知り、対処する
* 情報セキュリティの方針、基準を明確にし、手順等を整備する
* セキュリティと利便性のバランスをとる
* インシデントの未然防止に努めつつ、発生時に備えた対処を確実に行う
* 実施した対策の有効性について、第三者によるレビューを実施する
* 最小権限の原則を徹底する
* 責務の分離の原則を徹底する
* 重要な情報を取り扱うシステムとインターネット接続環境を分離する
* フェールセーフを考慮してシステムを設計・構築する
* システムの構成や機能を単純にする
* システムや設備の重要な機能を分散化する
* 二重・三重の対策を施す（多重防御）
* 利用者等を一意に識別し、事象の追跡・検証を可能とする

# 用語解説
「用語解説」で出てきた用語を自分で調べなおしてまとめます。

## ハッシュ関数
あるデータからそのデータを要約する数列を生成する1方向の関数。

## ディジタル証明
電子身分証明のこと。認証局が発行してくれる。

## ログ
コンピュータの作業状況やサーバのアクセス状況についての記録のこと。

## タイムスタンプ
電子的な時刻証明書。いつ、どのようなことがあったかを証明してくれるもの。

## パッチ
ソフトの不具合を直すためのプログラム。

## ワンタイムパスワード方式
一定の時間ごとに変更される、使い捨てのパスワードのこと。

## ファイアウォール
内部ネットワークを、インターネットからの不正なアクセスから守るための防火壁のこと。

## IPS
サーバやネットワークの外部との通信を監視し、侵入の試みなど不正なアクセスを検知して攻撃を未然に防ぐシステム。

## Webアプリケーションファイアウォール
不正な攻撃からWebアプリケーションを防御するファイアウォールのこと。
ファイアウォールやIPSでは防げない攻撃を防ぐためのもの。

# 理解度チェックテスト
Q1.情報セキュリティの三つの特性とは何か。
Q2.最小権限の原則とは何か。
Q3.責務の分離の原則とは何か。

# 前記事の理解度チェックテストの答え
前記事は[こちら](https://qiita.com/kabachanta/items/912532d31286bee9f4e5)

A1.機密性・完全性・可溶性
A2.物理的セキュリティと論理的セキュリティ
A3.システム的セキュリティ・管理的セキュリティ・人的セキュリティ
BotkitでSlackのアプリメッセージをキャッチしたい


## 概要

SlackでBotkitを使用してbotを作るとき、ユーザーのメッセージに反応するには`ambient`だったり`mention`,`direct_message`など使うが、これらはアプリ経由やwebhook経由からのメッセージには反応しない。
つまり人間が発言したメッセージ以外はbotがキャッチしてくれない。

図で説明するとこんな感じ

![スクリーンショット 2018-08-07 0.21.40.png](https://qiita-image-store.s3.amazonaws.com/0/52227/b1bf8a7b-caae-7f26-fc54-7a0f7fe9524d.png "スクリーンショット 2018-08-07 0.21.40.png")

この`APP`が付いたメッセージをBotkitでキャッチしたい、とする。

## 方法

`controller.hears`で2番めのイベント引数に`bot_message`を渡すだけで反応してくれる

```nodejs
const Botkit = require('botkit');
const controller = Botkit.slackbot();
controller.hears([''], 'ambient, bot_message', (bot, message) => {
	//botがあれこれする箇所
});
```

ちなみに、Botkit自身が投稿したSlackメッセージには反応しない。

## 備考

ちなみに、この`bot_message`はBotkitドキュメントに見当たらず、下記Issueを見た時に偶然知った。

Any reason why bots don't hear other bots in slack? · Issue #284 · howdyai/botkit https://github.com/howdyai/botkit/issues/284

## 参考リンク

Botkit公式ドキュメント
https://botkit.ai/docs/readme-slack.html
ccat で見づらいデフォルト色 ( darkblue ) を変更する


## デフォルト色の例

```
ccat README.md
```

![image](https://user-images.githubusercontent.com/13635059/43721415-a6008fbe-99cd-11e8-8f92-b0e2139a5377.png)

## 色を変えた例

darkblue 設定の3項目を変更する。

```
ccat README.md -G Keyword="*glay*" -G Decimal="glay" -G Plaintext="glay"
```

![image](https://user-images.githubusercontent.com/13635059/43721390-98036238-99cd-11e8-8f9a-04a4736fe711.png)

## デフォルト設定

プロフィールファイルでエイリアス設定する。

```~/.zshrc
alias ccat='ccat -G Keyword="*glay*" -G Decimal="glay" -G Plaintext="glay"'
```

## 色と項目のバリエーションを確認する

```
ccat --palette
```

( なんたるコマンドオプション名の美しさや )

![image](https://user-images.githubusercontent.com/13635059/43721545-09bec61a-99ce-11e8-953c-bc1301228c00.png)

## Gist

- [ccat — Set default coloring ( unreadable darkblue to white )](https://gist.github.com/YumaInaura/e595960fabcb7ac03e8e0a7ed0fe74c0)

## Github

- [jingweno/ccat: Colorizing `cat`](https://github.com/jingweno/ccat)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
pythonのGUIアプリを.exe化

## pythonでGUI
pythonには標準ライブラリのtkinterでGUIアプリが作れます。
これを使った案件があって書いたけれども、exe化するのに手間取ったため、記録を残しておきます。

## mp3を入れる
このアプリにはアラート音としてmp3のファイルが入れてあります。
.exeにするのにpyinstallerを使いましたが、特殊なケースでもなければ、これだけで出来ます。（もちろん、tkinter等のGUIで書く必要あります）

```console
pyinstaller test.py --onefile --noconsole
```

オプションで
--onefile 一つのファイルに
--noconsole コンソールが立ち上がらないように
みたいなのもつけられます。

ただし、それだけだとmp3等のファイルを入れることが出来ません。
test.specファイルのdataの場所に追記します。

```test.spec
# -*- mode: python -*-

block_cipher = None


a = Analysis(['test.py'],
             pathex=['/Users/*****/test'],
             binaries=[],
             datas=[('./mygame/beep.mp3', 'mygame/sfx')],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='test',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=False )
app = BUNDLE(exe,
             name='test.app',
             icon=None,
             bundle_identifier=None)

```

mygame/beep.mp3と入れていたのですが、なんども作ってはパスやらファイルの場所を確認して見るとmygame/sfxの中にbeep.mp3が入っているようでした。なので、第２引数にそのように追記です。これでbeep.mp3も読み込むことが出来ました。


## seleniumのwebdriver
私の開発環境はmacなのですが、納品されて使用されるのはwindowsでした。そのため、windowsで改めて動作確認をして見た所、動作しない。。。
エラーを見ると、chromeのpathが云々と書いてあります。
そこで、[https://www.inet-solutions.jp/technology/python-selenium/](https://www.inet-solutions.jp/technology/python-selenium/)参考にさせて頂いて無事動きました。

macだとこれ↓で動くのですが、

```test.py
browser = webdriver.Chrome()
```

windowsだとchromedriverを入れる必要があるのに加え、ファイルの移動、そして↓のように、pathを指定する必要がありました。

```test.py
browser = webdriver.Chrome("c://chromedriver.exe")
```
※chromedriver.exeをcドライブ直下に置きました。

これはクライアントにも同じ場所に同じようにchromedriverを入れてもらう必要がありますね。


##　動作確認
改めてpyinstallで.exe化をして完成。
何時間も嵌ってしまいました。。。




## 参照
[pyinstaller リファレンス](https://pythonhosted.org/PyInstaller/spec-files.html)
[iNet Solutions](https://www.inet-solutions.jp/technology/python-selenium/)
ネームサーバの設定(SOA Expire 有効期限/DMARC)

ネームサーバの設定をサイト https://mxtoolbox.com を使って見直したところ問題が見つかったので修正した。以下はその時の記録である。debian stretchでbindを使用している。


#SOA (Expire 有効期限)

1209600 を指定する。規定されている範囲は以下のように長期間である。

 - RFC 1912  1209600 - 2419200 seconds (14-28 days).

#DMARC
DMARCとは、E-Mailのセキュリティ関する設定でSPFおよびDKIMの他に設定する。

##zone設定
dmarcでは\_dmarcを名前に指定するのだが、debian stretchのbindでは\_を含む名前は認められないので、 /etc/bind/named.conf.localに記載するzone設定にcheck-names ignore ;を加える。

```:/etc/bind/named.conf.local
zone "example.com" in {
  type master;
  file "/etc/bind/example.com.zone";
  check-names ignore ;
};
````

##zoneファイル設定(DMARC本体)
DMARC本体を設定する。zoneファイルに次の文を**nsレコードより下**に記述する。

```:/etc/bind/example.com.zone
_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:管理者メールアドレス; ruf=mailto:管理者メールアドレス"

```

##zoneファイル設定(SOAのSerial値)
SOAのSerial値を更新する。YYYYmmddXX(XXは通し番号)形式で指定する。

```:/etc/bind/example.com.zone
@ IN  SOA  ns.example.com. postmaster.example.com.  (
 2018080703          ; Serial
```

#bind再起動
作業が終わったらSOAのSerial値を更新後にbind再起動。

```bash:bind9の再起動
service bind9 restart
```

#参考url
rfc1912
https://www.ietf.org/rfc/rfc1912.txt
mxtoolbox.com
https://mxtoolbox.com
pythonでcsvデータを読み込む方法の整理

pythonでcsvを読み込む際どんなAPIを使っていますか？
fileオブジェクトを使う方法、標準ライブラリのcsvモジュールを使う方法、pandasのread_csv関数を使う方法がメジャーだと思います。
これらの方法はどのような問題意識から開発された機能で、どのように使い分けるべきなのでしょうか？
この記事では上記3つの機能を1. パースするか、2. コンテナオブジェクトを自動で作成するかの基準から考察します。

|                                  | パースしない     | パースする             |
|----------------------------------|------------------|------------------------|
| コンテナオブジェクトを作成しない | fileオブジェクト | csv.readerオブジェクト |
| コンテナオブジェクトを作成する   | --               | pandas.read_csv        |

# ファイルオブジェクトを利用する方法
最も素朴な方法はファイルオブジェクトのreadlineメソッドを利用する方法です。
この方法では行の終端記号はreadline側で判断してくれますが、
各行を列で分割する部分は自分で開発する必要があります。

```python
data = []
with open("myfile.csv", "r") as f:
  rows = f.readlines()
  row = rows.next() #ヘッダを飛ばしたい場合
  for row_str in rows:
    row = row_str.split(",") #文字列中の , でも分割される
  data.append(row)
```

上記の例で上手くいく場合もありますが、データ中の文字列にカンマが含まれる場合は文字列中のカンマでも分割されてしまいます。
この問題に対する一般的な対策は、あらかじめ文字列データの始まりと終わりにダブルクォーテーション"をつけておき、
ダブルクォーテーションに囲まれていないカンマで分割する方法です。
わざわざこの対策を実装するだけでも大変ですが、それに加えて文字列の中に引用符が入っている場合の対策もしなければいけません。

# csvモジュールでパース
csvモジュールでは上記のようなカンマ、引用符に対する対策を自動で実施してくれます。

```python
import csv
data = []
with open(file_name, "r") as file_obj:
  reader = csv.Reader(file_obj)
  reader.next() #ヘッダを飛ばしたい場合
  for row in reader:
    data.append(row)
```

csvモジュールを利用することで、簡単に頑健なcsv読み取り機構を構築できます。
ここでは割愛しますが、csvモジュールはcsvの様々な方言に対応できる上に、方言の自動判定をするSnifferというクラスも実装されています。

csvモジュールによってパースを自分で実装する負担がなくなりましたが、
それでもデータ構造(今回はリスト)を自分で構築したりファイルオブジェクトを作成したりといった本質的でない部分によって
8行記述することになってしまいます。

# pandasで簡単にデータフレームを作成
pandasのread_csv関数を使うとデータフレームの作成も実装する必要がなくなります。

```python
import pandas as pd
data = pd.read_csv("myfile.csv") #dataはpandasのデータフレームオブジェクト
```
IkaWidgetとmatplotlibでウデマエグラフをつくる

# やること

Splatoon 2 の対戦記録ツールである [IkaWidget](https://itunes.apple.com/jp/app/ikawidget-2/id1271025591) と可視化ツールの [matplotlib](https://matplotlib.org/) をつかって、自分のガチマッチのウデマエが時系列でわかる「ウデマエグラフ」をつくる。

# 完成イメージ

こんな感じ。そびえ立つ S+0 の壁。
~~ウデマエX？知らない子ですね~~

![udemaegraph](https://qiita-image-store.s3.amazonaws.com/0/5804/9ba9fda0-d139-3844-4adf-9b65ea2573f8.png)


# 必要なもの

* IkaWidget でエクスポートした対戦結果の json ファイル
   * 神機能ですね、作者さんに感謝です。
* matplotlib と [Jupyter Notebook](http://jupyter.org/)
   * インストールの説明とかは星の数ほどあるので省略
* イカを愛する心🦑

# コード

## おまじない

matplotlib と Jupyter Notebook を使う時に必要なやつ。

```python
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
```

## データの準備

カレントディレクトリの `data/` 以下に IkaWidget から持って来た json ファイルを格納しておく。

```python
from datetime import datetime
import glob
import json

from collections import defaultdict

data = defaultdict(list)

for file in sorted(glob.glob('data/*.json')):
    with open(file) as f:
        j = json.loads(f.read())
        # ガチマッチ以外は無視
        if not j.get('udemae'):
            continue
        # バトル番号、ルール、ウデマエ、日付を取得
        (battle_number, rule, udemae, date) = \
            j['battle_number'], j['rule']['key'], j['udemae']['number'], datetime.fromtimestamp(j['start_time'])
        # ルールごとに保存
        data[rule].append((battle_number, udemae, date))
```

## データの確認

取得できたルールとガチアサリのデータを見てみる。

```python
print(data.keys())
pd.DataFrame(data=data['clam_blitz'], columns=['number', 'udemae', 'date']).head()
```

出力は以下の通り。

![rules_datatable](https://qiita-image-store.s3.amazonaws.com/0/5804/8e15cd97-025a-ac3d-0e7b-8279159df2aa.png)

ウデマエの数字は C- を 0 として C = 1, C+ = 2, ... と増えていく。

## グラフ描画

データの準備ができたら描画。実行するとページの先頭にあったグラフが表示される。

```python
udemae_names = ['C-', 'C', 'C+', 'B-', 'B', 'B+', 'A-', 'A', 'A+', 'S', 'S+0', 'S+1']
fig, axes = plt.subplots(len(data.keys()))
fig.set_size_inches(10, 20)
for i, rule in enumerate(data.keys()):
    ax = axes[i]
    plt.sca(ax)
    plt.yticks(np.arange(len(udemae_names)), udemae_names, rotation=45)
    ax.grid()
    ax.set_title(rule)
    ax.plot('date', 'udemae', data=pd.DataFrame(data=data[rule], columns=['number', 'udemae', 'date']))

plt.show()
```

# まとめ

もっとイカ上手くなろう。
個人学習メモ#15 Arrayクラス

Arrayクラスは、配列用のクラスです。

通常は0番地から順番にデータを格納し、どんなデータ型でも格納することができる。

var array = new Array(初期サイズ);

var array = new Array(1111);

var array = ["A","B","C","123",true];

空の配列を作成
var array = [];

配列の任意の番地にアクセスする
var sample = array[0];

console.log(sample); "A"

任意の番地に書き込み
array[2] = "S";

全ての番地にアクセス
var i;
var num = array.length;
for(i=0; i<num;i++){

}

削除する場合
delete array[1];
HTML/CSS3/JSだけで(名刺|名札カード)を量産するテンプレートを作った

勉強会の時に、名札を作ることがあると思います。
参加者増えると、ひとつひとつ入力するのも大変ですよね。
というわけで、名札カードを量産できるテンプレートを作ってみました。
名刺サイズで作ったので、片面印刷だけなら、名刺テンプレートとして使えます。

![IMG_5061.jpg](https://qiita-image-store.s3.amazonaws.com/0/116223/70e5d5c4-84a2-14c8-612e-7df5366671b1.jpeg)

↑こういうのが作れます

----

## 主な仕様
* 名刺サイズ（横91mm✕縦55mm）
* A4用紙に面付可能数が10面
* デフォルトテンプレートに記載の内容
    * 名前
    * ポジション
    * メールアドレス
    * 電話番号
* テンプレートの内容とレイアウトは編集可能（CSSの知識だけでOK）

## 使い方
こちらの[codepen](https://codepen.io/kohki-shikata/pen/NBBZyV)をフォークして使ってください。

データの編集箇所は、JSの

```codepen.js
var data = [
  { 
    name: "Taro YAMADA",
    position: 'CEO/President',
    email: 't.yamada@example.com',
    phone: '06-1234-5678'
  },
  { 
    name: "Yukio MURATA",
    position: 'COO/Vice President',
    email: 'y.murata@example.com',
    phone: '06-1234-5678'
  },
  { 
    name: "Keiko YASUKAWA",
    position: 'CFO',
    email: 'k.yasukawaexample.com',
    phone: '06-1234-5678'
  },
// 以下略
```
こちらを書き換えてください。

## テンプレートデータの編集

テンプレートのマークアップは、

```codepen.html
  <div class="col">
  <div class="name">
  <h2 class="name">{{:name}}</h2>
  <p class="position">{{:position}}</p>
  </div>
  <div class="info">
  <ul class="info-list">
  <li class="list-item mail">{{:email}}</li>
  <li class="list-item tel">{{:phone}}</li>
  </ul>
  </div>
  </div>
```
を編集してください。Pug記法で書いてますが、ここの部分だけは、誰でも編集しやすいよう、HTMLで表現しています。

## 印刷とカッティングについて
### 印刷
CodepenをDebugモードで開きます。ヘッダー右上のChange View
ボタンを押すと、その中にあります。
Debugモードは、CodepenのUIが一切入らないモードです。その状態のウインドウを`Command + P`などで、印刷画面を開きます。
プレビューでは、きっちりA4縦に収まったテンプレートが見えるかと思います。
その状態で印刷ボタンを押します。決して、拡大縮小のオプションは入れないでください（等倍で出力されません）

<img width="1762" alt="スクリーンショット 2018-08-06 23.41.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/116223/653c4599-ccfc-428b-6d08-16a7aa2b26ad.png">


### カッティング
1. B4かA3程度の大きさのカッティングマットと、30cm以上の定規（できれば金尺）を用意します。
1. 青のトンボ（周囲についている線）に定規をあわせ、カットします。
1. 青が終わったら、次は赤の線に合わせてカットします。
1. 出来上がり！

**注意！ 赤から先に切ると台無しになってしまうので、くれぐれも間違えないようにしてください。** 

## 使用技術について
### テンプレートエンジン
Pugで書いてるなら、Pugでループ回したらええやん、ってなりそうですが、将来的に静的な独立したジェネレーターとして作ることもあるかと思い、テンプレートエンジンを別に使いました。

それが、[JSRender](https://www.jsviews.com/)です。

本当はhead要素内に書くのがお作法のようですが、codepenの使用上、body内にあったほうが都合が良いため、このようにしています。
今の所問題なく動いているので、多分大丈夫かと。

### jQuery
楽をするためだけに使ってます。すいません。

### Pug
トンボの線を表現するためだけに利用

### Stylus
最近、CSSはだいたいこれで書いてます。
コロンもセミコロンも要らない、でもついててもOK、なんなら波括弧ついててもついてなくてもOKという懐の深いヤツです。

### CSS3
結局の所、CSS3のおかげで色々出来た感じです。

* calc()
* display: flex

この辺のおかげで、諸々便利に作ることができました。

## 参考にした情報
* [そろそろ真面目に、HTMLで帳票を描く話をしようか - Qiita](https://qiita.com/cognitom/items/d39d5f19054c8c8fd592)
* [JavaScriptのテンプレートJsRenderとJsViewsの紹介 - Qiita](https://qiita.com/mima_ita/items/628bf36dd453cf85bf7d)

今日も、Qiitaと、Qiitaに投稿されている皆さんのおかげで楽が出来ております。

大変感謝です。
jest: SecurityError: localStorage is not available for opaque origins

jestを実行するとこんな感じのエラーが出る。

```
 ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins

      at Window.get localStorage [as localStorage] (node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
```

jest.config.jsにtestURL(任意のurl)を追記すれば解決。

```js
module.exports = {
  testURL: 'http://localhost',
}
```

現状jestのデフォルトが`about:blank`だが、待ってれば`localhost`に変わりそうな雰囲気はある。

[jest : SecurityError: localStorage is not available for opaque origins · Issue #2304 · jsdom/jsdom](https://github.com/jsdom/jsdom/issues/2304)
【jQuery】ボタンクリックしてテーブル内の値を取得したいとき

人生で初めて書くので汚いですが、許してください。
仕事でjQuery触っていてそこで詰まってしまい、解決するのに1週間。
メモ書き程度で書きます。

# \<td>で囲んだ\<select>のValue値を取得
\<td>タグで囲んだ\<select>タグの値「text」だと取得できるのですが
「text」で書くと、Value値を根こそぎ取得して持ってくる。
一意の値を取得し、Json形式で取得してストアドに投げるってのをやりたくって。

# 環境

【jQuery】
version 7.2.5
~~ごめんなさい、バージョン忘れちゃったので後日かきます。~~

【PHP】
version 3.2.1
~~ごめんなさい、これもバージョン忘れちゃったので後日かきます。~~

【サーバー】
 IISにて環境を構築

# TABLEの中にボタンを設置。ボタン設置行と同じ行にある\<select>のValueを取得

参考 : [jQueryで、ボタンをクリックすると、同じtrタグにあるtｄ要素のtextをアラート表示したい。](https://teratail.com/questions/21876)

上記、参考URLを参照してください。
回答者の方が下記の様な事を書かれていたので参考にしました。

>リファレンスによると、
>開始要素から最も近い親要素を選択します。
>引数にセレクター書式を指定した場合、マッチする最も近い親要素を返します。
>とのことですので、ボタンの親要素から、'td.name' 'tr td.name' にマッチする要素を探しますが、親にはないですよね
>親要素から、children で子要素を探すせばいいでしょう。





## 最初に書いたコード

```js
$(function(){
     $('button.setting').on("click",function(){
         $(this).children('td').eq(1).text()
     })
})
```

上記のコードだと、SelectのValue値を全部取得。
当たり前ですね。ここをVal()に変えると、なぜか値が取れない。
【8/7追記】
nameを一意の物に設定していないので取れなかった様な気がします。


## 参考URLを見て書いたコード

```js
$(function(){
     $('button.setting').on("click",function(){
         $(this).closest('tr').children('td').find("select").val()
     })
})
```

次に書いたコードだと、親要素を一度指定して、それから子へ行き
更にfind()で「select」を絞り込んでval()をやっているので取れた。

ごめんなさい、仕事メモだったので急ぎで書きましたが
後日、修正します。ご指摘などありましたらお願い致します。
JavaScriptのfetch APIでjsonをfetchしてみる。

# はじめに
電車の遅延情報を使って遊ぼうと思って、下記サイトを知った。
JavaScriptでjsonゲットして表示させようと思って調べたら、最近はfetchっての使うらしいことがわかったので、試してみた。

[鉄道遅延情報のjson](https://rti-giken.jp/fhc/api/train_tetsudo/)

# コード
HTMLはこんな感じ。
jQueryは使わない。

```html:train_delay.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Train delay!</title>
  </head>
  <body>
    Train delay!
    <script src="train_delay.js">
    </script>
  </body>
</html>
```

JavaScriptはこんな感じ。fetchして、気になる路線が載ってたらconsole.log()する。

```javascript:train_delay.js
var url_delay = "https://rti-giken.jp/fhc/api/train_tetsudo/delay.json";

fetch(url_delay)
    .then(function(response) {
        return response.json();
    })
    .then(function(myJson) {
        // console.log(myJson);                                                      
        // console.log(myJson.length);                                               
        for (var i=0; i<myJson.length; i++) {
            if(myJson[i].name == "中央線"){
                console.log("遅延しています");
                return true;
            }
        }
        console.log("遅延していません");
        return false;
    });
```

# 結果
結果はこんな感じ。全然面白みないけども。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/717ee700-7232-b366-0685-39ccf50541c9.png)

# おわりに
いまいちピンと来てないまま試してたので、時間がかかった。
なれない文法なので、不思議な感じ。最近はこんなふうに書くんかな？もっと勉強が必要そう。

# 参考

[Google Apps Scriptから色んな鉄道の遅延情報を取得する - Androidのメモとか](http://relativelayout.hatenablog.com/entry/2017/07/20/005129)

[Fetch 概説 - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch)
はじまりはディープラーニング

# 引き続き・・・
初心を忘れないようにと思い出しつつ備忘録ということで。

# はじまりはディープラーニング
機械学習の世界に入り込んだきっかけは、とあるディープラーニングの記事がきっかけだった。その内容は自分にとっては衝撃的で、その流れでいろいろ調べた後思ったことが「もっと前に気づきたかった・・・」。
エンジニアとして時代に取り残されてた感がずっしりと自分に降りてきたことを覚えてる。
仕事が忙しかったせいもあって、ショックを受けつつもその時は流していた。
（仕事で不毛な作業が続き疲れ果てていてインプットすることをまったくしていなかった自分が悪いのだが）

その後、仕事にディープラーニングを活かせないかと模索し、会社にもお伺いを立ててみたが、「そんなことは頭のいい専門家がやることで、素人のおまえが手を出すことは身の程知らず」と一蹴されてしまった。

# 独学で始める
身の程知らずと罵倒されたままでは悔しかったので、少しでも時間を作って独学でディープラーニングの勉強をすることを始めた。
まあ、自分の中で「機械学習のエンジニアスキルは今後とても重要になる」と感じており、どうしても外せないものになっていた。
いざ始めると何から手を付けてよいやら分からず、右往左往していたようなｗ

# 目指すべきもの
機械学習のエンジニアリングスキルを身に付け何を目指したいのか自問自答した。

人類補完計画・・・
いやいや、そうではなくて。

人類の進歩によって、人類が生み出した進歩に人類が取り残される可能性があると考えた時に、人工知能で人類の手助けができる可能性があると思っている。

例えば、CT画像やMRI画像やレントゲン画像を見て病気かどうか診断する。人間の目はどこまで細かな情報を見れるだろうか。
将来的にセンシング技術が究極に進むと人間の細胞単位でのスキャンが可能になるかもしれない。そこまでいかなくてもかなり細かな画像を得ることができるようになるだろう。その時に果たして人間はその詳細で膨大な情報を処理できるだろうか・・・

正直、私は人工知能に診断して欲しいと思っている・・・

大げさな言い方ではあるけど、人類の進歩が人類の幸せに繋がるために貢献できるエンジニアを目指したいと思っている。

飛び出す準備も出来てきたことだし、目指すべきことへ集中する。
MongoDBのカラム指定ﾊﾍﾝｺｳｻﾚﾃﾙﾖ


掲示板を作る時、
必要なカラムはnameとbodyだけだったので、そのように指定していたのだけれど、
いつの間にかカラム指定が全く動作しなくなっていたので修正した時の変更箇所


# nameとbodyを取りたい場合
これまでとこれから


``` js
.find( {visible: "on"}, { name:-1, body:-1})
```


``` js
.find( {visible: "on"}, { projection:{name:-1, body:-1} })
```

## わかりやすいコードもかける
以下すべて同じ結果です。

```js
.find( {visible: "on"}, { projection:{response:"出す", name:"出す"} })
```

```js
.find( {visible: "on"}, { projection:{response:"出す", name:"出さない"} })
```
```js
.find( {visible: "on"}, { projection:{response:true, name:true} })
```
```js
.find( {visible: "on"}, { projection:{response:false, name:false} })
```
判定は　!!valueだと思えばわかりやすそう

## けれど、これはダメ
出したい奴と出したくない奴を同時に記述すると動きませんでした。

```js
.find( {visible: "on"}, { projection:{response:false, name:true} })
```
Projection cannot have a mix of inclusion and exclusion.と云われ、
ドキュメントにもダメと書かれていました。
>The fields to return in the query. Object of fields to include or exclude (not both), {'a':1}

出したい奴だけか、出したくない奴だけというのがちょっと辛いかな


これらは、ここに書いています
https://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html



ｲﾂｶﾗ?ﾄｶｿﾝﾅﾉﾊｼﾘﾏｾﾝ ｼｯﾃﾙﾋﾄｵｼｴﾃﾎｼｲ

多分なんだけど、第2引数に指定できていたObjectを受け付けなくなって、
projectionでやれ！ってなったんじゃないかなぁ
Linuxにdocker-composeをインストールする

# Linuxにdocker-composeをインストールする

Dockerの複数コンテナを一括管理できるdocker-composeをインストールする。以下のようなUbuntu、lubuntuとCentOSで動作確認を行っています。[Docker公式サイト](https://docs.docker.com/compose/install/)を参考にしています。

# 環境

- Ubuntu 18.04 and lubuntu 18.04 and CentOS 7.5
- docker 18.06.1-ce、18.09.2
- docker-compose 1.22.0、1.23.2

# docker-composeのダウンロード

docker-composeの[Githubリポジトリ](https://github.com/docker/compose/releases)から現在の最新バージョンを確認する。2019年2月12日現在では最新バージョンが1.23.2なのでそれをダウンロードしてくる。違うバージョンをインストールしたい場合は1.23.2のところを変更してください。

## ダウンロード

```
~# curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
```

## 実行権の付与

/usr/local/binディレクトリにdocker-composeがダウンロード出来ているが、実行権が無いので付与します。

```
~$ ls -lh /usr/local/bin/docker-compose 
-rw-r--r--. 1 root root 12M  2月 12 21:19 /usr/local/bin/docker-compose

~# chmod +x /usr/local/bin/docker-compose

~$ ls -lh /usr/local/bin/docker-compose 
-rwxr-xr-x. 1 root root 12M  2月 12 21:19 /usr/local/bin/docker-compose
```

## バージョン確認

以下のように実行することでインストールできたことの確認とdocker-composeのバージョンの確認が出来ます。

```
~$ docker-compose  --version
docker-compose version 1.23.2, build 1110ad01
```

# docker-composeによるコンテナの起動

試しにgitlabを立ち上げてみます。[gitlab公式](https://hub.docker.com/r/gitlab/gitlab-ce/)のdockerコンテナがあるのでそれを使用します。[GitLab Docs](https://docs.gitlab.com/omnibus/docker/README.html#install-gitlab-using-docker-compose)も参考にしています。

以下のようなdocker-compose.ymlを用意します。

```
~$ vim docker-compose.yml 
version: "3"

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    restart: always
    hostname: 'gitlab.airimania.com'
    container_name: gitlab-server
    ports:
      - "80:80"
      - "2022:22"
      - "2443:443"
    volumes:
      - /srv/gitlab/data:/var/opt/gitlab
      - /srv/gitlab/logs:/var/log/gitlab
      - /srv/gitlab/config:/etc/gitlab
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.airimania.com'
    networks:
      - webnet

networks:
  webnet:
```

docker-compose upコマンドでコンテナの起動をします。

```
~$ docker-compose up -d
```

しばらく待ってから、私の環境では2,3分待ってからブラウザでアクセスするとgitlabに接続できました。

![docker_localhost.png](https://qiita-image-store.s3.amazonaws.com/0/271649/aa9a00bf-9b5f-0598-d172-375bec058155.png)

# docker-composeのアンインストール

もしdocker-composeをアンインストールする必要が出てきた場合は次のようにしてアンインストールできます。

```
~# rm /usr/local/bin/docker-compose
```
slimframework3のルーティングについてハマった備忘録

<h2>この記事について</h2>
表題の通りslimframework3をローカルの環境に導入時、ルーティングの設定にハマった際の記録。
もっと良い解決方法をご存知の方はコメント下さい。

<h2>slimframeworkのセットアップ</h2>
<ol>
<li><a href="https://qiita.com/nunulk/items/4b5c15f13ade660cafbc">こちら</a>の記事を参考にslimframework3をセットアップ</li>
<li>
セットアップする際、以下にインストール。
<blockquote><p>/ドキュメントルート/test</p></blockquote>
</li>
<li> <code>http://localhost/test/public/</code> にアクセス、起動を確認</li>
</ol>

<h2>urlを短縮する</h2>

/test/.htaccess を作成。以下の記述を追加
<pre>
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)$ public/$1
</IfModule>
</pre>

/test/public/.htaccess を以下の内容に編集
<pre>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
  RewriteRule ^(.*) - [E=BASE:%1]
  RewriteBase /test/public/
  RewriteRule ^ index.php [QSA,L]
</IfModule>
</pre>

<h2>動作を確認</h2>
<p>動作確認のため <code>http://localhost/test/</code> にアクセスするとindexページが表示される。</p>
<p>次にルートパラメータの動作確認で、<code>http://localhost/test/hogehoge</code> にアクセスすると 「Page Not Found 」と表示されてしまった</p>
<p>試しに、<code>http://localhost/test/public/hogehoge</code> にアクセスしたところ、問題なくページが表示されルートパラメータも動作を確認できた。</p>

<h2>原因を調査</h2>
<p>エラーページはApacheのものではなく、フレームワークのものが表示されている。</p>
<p>Apache側の設定でなんとかなりそうだがよくわからない為、framework側原因を調査。</p>
<p><a href='https://discourse.slimframework.com/t/slim-3-always-returns-page-not-found-solved/1704'>こちら</a>のページで以下の現在パス表示のコードが解決する手段になるかもみたいな記述を発見。
<pre>
$route = $app->getContainer()->get('request')->getUri()->getPath();
</pre>
<br>

上記コードを使用し、現在パスを表示
<p><code>http://localhost/test/public/</code> => 結果: string(1) "/"</p>
<p><code>http://localhost/test/</code> => 結果: string(1) "/test/"</p>

やはり、フレームワークのパスの解釈がそれぞれで違うのが原因でした。

<h2>対策</h2>
<p>Apache側の設定でなんとかなりそうだがやっぱりよくわからない為、framework側でなんとかする。</p>
<p>ルーティングが正しく認識していないのでルーティングを変えれば良いと思われる。</p>

ドキュメントルート/test/src/routes.php を以下の内容に修正
<pre>
$app->get('/test/[{name}]', function (Request $request, Response $response, array $args) {
</pre>

動作を確認！
【備忘録】簡単にAWSサーバにログインするためにTeratermマクロを作成する。

```
username = 'ユーザ名'
;秘密鍵ファイルのパス
keyfile = '"C:\Users\〇〇\〇〇.pem"'
;接続先ホスト
hostname = 'ホストネーム'
;パスワード
pass = ''
 
;接続コマンドの生成
msg = hostname
strconcat msg ':22 /ssh2 /auth=publickey /user='
strconcat msg username
strconcat msg ' /keyfile='
strconcat msg keyfile

;接続
connect msg
```
postgresqlでJSONBを扱う

JSONBの概要と機能を調べた際の一時的なメモ。

## JSONB

[ドキュメント](https://www.postgresql.org/docs/current/static/datatype-json.html)によると

> There are two JSON data types: json and jsonb. They accept almost identical sets of values as input. The major practical difference is one of efficiency. The json data type stores an exact copy of the input text, which processing functions must reparse on each execution; while jsonb data is stored in a decomposed binary format 

JSONは、テキストとして保存され、 `decomposed binary format`として保存されるという違いがあるようです。 (`decomposed binary format`の詳細は調べられてない。)


[Faster Operations with the JSONB Data Type in PostgreSQL](https://www.compose.com/articles/faster-operations-with-the-jsonb-data-type-in-postgresql/)ではJSONに対するJSONBの利点と欠点が以下のようにまとめられています。

### Benefit

- より効率的
- 処理の高速化
- インデックスのサポート
- よりシンプルなスキーマデザイン

### Drawbacks

- 少し入力（Insert?)が遅い
- テーブルのフットプリントが大きく、よりdisk spaceが必要
- 特定のクエリ（特にaggregation）が遅い

## テーブルの作成

```
# CREATE TABLE test (dummy_id serial NOT NULL, data jsonb);
```

## INSERT

```
# INSERT INTO test VALUES (1, '{"some_key":"some_value"}');
INSERT 0 1
```

## SELECT

### JSON Operator

[9.15. JSON Functions and Operators](https://www.postgresql.org/docs/9.4/static/functions-json.html)

### SELECT(キー要素)

```
# INSERT INTO test VALUES (1, '{"some_key":"some_value"}');
INSERT 0 1
# SELECT data->'some_key' AS some_key FROM test;
   some_key
--------------
 "some_value"
(1 row)
```

### SELECT(配列要素)

```
# INSERT INTO test VALUES (1, '["a","b","c","d","e"]');
INSERT 0 1
# SELECT data->1 FROM test;
 ?column?
----------
 "b"
(1 row)
```

## SELECT（特定の値を含むRECORDを調べる）

```
# INSERT INTO test VALUES (1, '["a","b","c"]');
INSERT 0 1
# SELECT * FROM test WHERE data ? 'a';
 dummy_id |      data
----------+-----------------
        1 | ["a", "b", "c"]
(1 row)
```

## SELECT（特定の値の全て/いずれかを含むRECORDを調べる）

```
# INSERT INTO test VALUES (1, '["a","b","c"]');
INSERT 0 1
# SELECT * FROM test WHERE data ?| array['a', 'b'];
 dummy_id |      data
----------+-----------------
        1 | ["a", "b", "c"]
(1 row)
# SELECT * FROM test WHERE data ?& array['a', 'b'];
 dummy_id |      data
----------+-----------------
        1 | ["a", "b", "c"]
(1 row)
```


## CREATE INDEX

```
The default GIN operator class for jsonb supports queries with the @>, ?, ?& and ?| operators. 
```

- 特定のJSONを含んでいるか/含まれているか
- 特定の値がキーまたは要素に含まれているか
- キーまたは要素を含んでいるか

```
# CREATE INDEX idx_some_key ON test USING gin ((data->'some_key'));
CREATE INDEX
```

json_opsとjson_path_opsがあり、デフォルトはjson_ops.

配列の中の特定の要素から検索する。

```python
select dataset_item_id, attributes from dataset_items, jsonb_array_elements(dataset_items.attributes->'classification') element WHERE element->>'label' = 'cat';
```
【Python】Selenium+Beautifulsoup4を使ってYahoo路線情報を操作する

ふと思い立ってPythonをいじったら、思いの外に面白いことができたのでメモ。
初心者向けです。

#やりたいこと
下記の操作をすべて自動で行います。
1. ブラウザ（Chrome）を立ち上げる
2. Yahoo路線情報を開く
3. 東京→新宿を入力して検索
4. 一番上に出てきた結果の出発時刻と到着時刻をターミナルに表示する
5. ブラウザを閉じる

python3系とpip, Homebrewが使える状態を前提とします。mac使っています。

#ライブラリのインストール
pipとbrewを使ってbeautifulsoup4とSelenium、ChromeDriverをインストール

```
#BeautifulSoup4とSeleniumのインストール
$ pip install beautifulsoup4
$ pip install selenium
#Selenium ChromeDriverのインストール
$ brew install chromedriver
```

#Yahoo路線情報を操作するプログラムを書く

```python:selenium-test-yahootransit.py
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from bs4 import BeautifulSoup

start = "東京" #出発駅
end = "新宿" #到着駅

print(start + "駅から" + end + "駅への直近の電車を調べます...")

#ブラウザを開く
driver = webdriver.Chrome()

#Yahoo路線情報を開く
driver.get("https://transit.yahoo.co.jp/")

#出発駅と到着駅の入力
driver.find_element_by_id("sfrom").send_keys(start)
driver.find_element_by_id("sto").send_keys(end)

#検索ボタンをクリックする
driver.find_element_by_id("searchModuleSubmit").click()

#検索結果のページのHTMLをBeautifulSoupに流し込む
soup = BeautifulSoup(driver.page_source, "html5lib")

#時間が書かれた部分をCSSセレクタで指定し、テキストを抜き出す
time = soup.select(".routeSummary li.time")[0].select("span")[0].text

#結果を表示する
print("結果:" + time + "です。")

#ブラウザを閉じる
driver.close()

```

#実際の動作
![selenium-test-yahootransit.gif](https://qiita-image-store.s3.amazonaws.com/0/86468/f65cfbff-4fe6-bf37-f026-448b7aa1239b.gif)
メモ：Qiitaの『以下の記事からリンクされています』がおかしい

ログイン状態だと『この記事は以下の記事からリンクされています』はこのように表示される。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/26088/66802954-c7f0-2a15-93e2-399d60ccd70e.png)

アコーディオンを開くとこうなる。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/26088/4fcbc38d-e01a-ff96-41e9-0ec693a97f40.png)

閉じると最初の状態に戻る。
つまり、『過去の○件を表示する』『最新の5件以外隠す』共に正しく動作している。


ログアウトしてから同じ記事を表示するとこうなっている。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/26088/2038f483-3035-df7d-2098-c99a09264588.png)

何故か古い記事が優先して表示され、『過去の○件を表示する』が下に出る。

![04.png](https://qiita-image-store.s3.amazonaws.com/0/26088/780a6cb2-6144-2171-dade-cc3bb87568a3.png)

アコーディオンを開くと全件が出力されるが、『最新の5件以外を隠す』何故か微妙に文言が異なる。

そして閉じると実際には"最古の5件が表示される"という最初の状態に戻る。
PHP触ったことない人がサクッとLaravelを始めるための手順

この記事は主に以下に当てはまる僕のような方に向け、サクッとLaravelの開発環境を構築する手順を共有する目的で書きました。

- LaravelがRuby on Railsのスター数を追い抜いたらしいので気になっている。
- けどPHPは触ったことない。
- 開発にはMacを使っている。

# 手順
ネットで調べるとbrewで最新のPHPを取得する手順は色々出てきましたが、現状(2018/8)以下のコマンドで問題なさそうです。

```
brew install php@7.2
```

で、完了したあとにターミナルを再起動するとPHPのバージョンが新しくなっています。特にパスを通したりする必要はありませんでした。

```
~ > php -v
PHP 7.2.8 (cli) (built: Jul 19 2018 12:14:25) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.8, Copyright (c) 1999-2018, by Zend Technologies
```
## composer
laravelコマンドがあまりよくないという情報を目にしたのと、大体の環境構築方法でcomposerが使われていたので、インストールにはcomposerを使っていきます。
composerもインストール方法は色々出てきますが、今は単純にbrewでいけました。最近homebrew/phpからhomebrew/coreになったらしいですね。

```
brew install composer
```

いけました。

```
~ > composer -v
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.7.0 2018-08-03 15:39:07
```

そしたらLaravelを入れましょう。プロジェクトディレクトリを作成したい場所で以下コマンドを実行します。

```
~/workspace > composer create-project --prefer-dist laravel/laravel laravel-sample
```

![スクリーンショット 2018-08-06 22.13.01.png](https://qiita-image-store.s3.amazonaws.com/0/179987/19090eaf-69fa-a166-cec1-2a58a7572700.png)

コマンドを実行したディレクトリ以下にlaravel-sampleというディレクトリが作られて、以下のような構造が出来上がります。
で、出来上がったディレクトリに移動して、開発サーバーを起動します。

```
~/workspace > cd laravel-sample
~/workspace/laravel-sample > php artisan serve
Laravel development server started: <http://127.0.0.1:8000>
```

localhost:8000にアクセスするとトップ画面が表示されました。
![laravel.png](https://qiita-image-store.s3.amazonaws.com/0/179987/d9af015b-8ceb-606b-63f0-526ebe7680db.png)

これでLaravelの開発が始められそうです。
# 終わり
閲覧いただき、ありがとうございました。
手順に誤りがあったり、よりベターな手順をご存知の方がいらっしゃいましたら、ご指摘いただけると助かります。
Flutterで import 'package:<自分のパッケージ>/ファイルパス' を使ったらハマった

Flutterでimportの入力補完で次のようなサジェストを見かけました。

```dart
import 'package:<自分のプロジェクト名>/<lib以下のディレクトリ>';
```

これなら`../`などの相対パスを使わずにプロジェクトのトップディレクトリから参照できるようにかけるので便利！と思って使ってみたらハマりました。
出力されたエラーは次のようなエラー。

```
I/flutter (31989): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (31989): The following NoSuchMethodError was thrown building Invite(dirty, state: InviteState#7df4b):
I/flutter (31989): The getter 'taskListScaffoldTitle' was called on null.
I/flutter (31989): Receiver: null
I/flutter (31989): Tried calling: taskListScaffoldTitle
```

エラーの発生する行は次のようなコードになっていました。

```dart
AppLocalization.of(context).taskListScaffoldTitle
```

AppLocalizationは[この記事](https://qiita.com/sekitaka_1214/items/99a128e2ee7463849232)で作成した多言語化ようのファイルです。
このファイルを`package:<自分のプロジェクト名>/lib/l10n/app-localization.dart`としてインポートしていました。

エラーからはこのインポート文が問題とは思わず数日悩んでいましたが、うまく動作しているファイルとの差を見比べて、このインポートが原因ぽいことがわかりました。
インポートを`import '../l10n/app-localization.dart'`と書き直すことで無事に動作するようになりました。

このインポートの書き方の何が悪いのかもよくわかりませんが、安易にサジェストの言いなりになるのも危険だなと思いました。
iPhoneをmac専用BLEマウスにしたった．

#はじめに
iPhoneを無線マウスにしてしまうアプリは[RemoteMouse](https://itunes.apple.com/jp/app/remote-mouse/id385894596?mt=8)とか[MobileMouse](https://itunes.apple.com/jp/app/mobile-mouse-remote-free/id356395556?mt=8)とかあるわけですが，たいがいWi-Fi通信方式なんですね．P2P通信が禁じられていたりするような環境（？）だと使えなくて不便だったりするので，ネットがないところでも使えるようにBluetooth Low Energyでやってしまおうと思いました．

#現在のでき
![iOSMouse.gif](https://qiita-image-store.s3.amazonaws.com/0/67153/996b4423-737e-8cdf-ac75-ada74efe28fd.gif)

なんか動きが鈍いですね．でも動きます．

#ソース
[github](https://github.com/Kyome22/iOSMouse)に公開してあります．
`iOSMouseKid`がiPhone向けの子機アプリで，`iOSMouseMother`がMac向けの親機アプリです．
macOS Mojave，iOS 12, iOS 13 beataでの動作確認済みです．

#余談
SandBoxの障壁があるためAppStoreに公開ができないのでgithubに投げました．
`CoreBluetooth`を使って通知を一方的にiPhoneからMacに投げているだけですね．
３時間くらいで作ったので雑です（汗　こっから改善していきたいですね．
ぜひ使ってみてください．コメントお待ちしています．
PowerShellでC#をファイルからコンパイル


最近のWindows(Vista以降?)だと普通はPowerShellが入っています。

PowerShellは従来のバッチファイルに比べると使いやすいです。

ただし、文法に罠が多く、大概遅くなりもにょります（経験上）。

C#と併用するのが一番ベストだと思うので、備忘録的にまとめます。

# 開発環境
* Windows 10 (1803)
* $PSVersionTable.PSVersion は5      1      17134  165

# ヒアストリングを使う方法
よく見かける方法は以下のようにヒアストリングで書く方法です。


``` run.ps1
	$src = @'
	using System;

	public static class Hello
	{
		public static void Main()
		{
				Console.WriteLine( "Hello" );
		}
	}
	'@
	Add-Type -TypeDefinition $src -Language CSharp
	[Hello]::Main()

```


C#のクラスをメモリ上に読み込むので、PowerShellから実行して好き勝手使うことができます。デバッグもしやすいです。

ただし、一度コンパイルするとメモリ上にクラスが残り続けるので、再コンパイルする時にはPowerShellを立ち上げ直す必要があります。


この方法はPowerShellで直に実行するには便利ですが、
エディタによるが大概C#の部分がシンタックスハイライトされないし、少し大きめのコードを書きたい時に気になります。
（あまりにも大きいコード書くぐらいならVisualStudio使えってなりそうだけど)

# Out-Stringで読み込む

ファイルをそのまま文字列化してやれば良いだろうという発想で。

``` hoge.cs

using System;

public static class Hello
{
	public static void Main()
	{
			Console.WriteLine( "Hello" );
	}
}

```

``` run.ps1
	$src = cat hoge.cs | Out-String
	Add-Type -TypeDefinition $src -Language CSharp
	[Hello]::Main()
```


# ファイルが複数の場合

 ***※コメント頂いた内容を元に修正しました。***

上記の開発環境の場合は

```
Add-Type .\a.cs, .\b.cs
```

だけでいけます。


## ※古い環境(Win7 PowerShell2.0以前?)で新しめのC#使いたい場合

追記：
複数ソースコードがある場合は使えなさそうです。

[ここ以下のコメント](https://qiita.com/ltzz/items/0b8e460b1488dd89976c#comment-e3b02bef92055db7c1d7)を参照ください。


原因：

~~~

Add-Typeの`-Language`と`-Path`は同時使用できない。
~~~

C#3.0以降の構文を使用している場合、拡張子から判定で古いC#としてコンパイルしようとします。C#3.0として認識させたくても上記の制約で`-Language`を指定できず詰みます。

Add-Typeでやる場合片方のコードをDLLに吐いてから

-ReferencedAssembliesでDLLを参照してexeを作ることで一応動きました。

ただ、exeにしてしまうとPowerShellからクラスが呼べるという利点がなくなってしまいます。

もうこうなるとcscを使うか、結局素直にVisualStudio使うべきなのかもしれません。

---
DirectX12 事始め デバイスの生成

今回からDirectX12の中身に触れていきます。
デバイスの生成を今回は行っていこうと思います。

まず今後作っていくクラスの`基底クラス`を定義します。

```c++:Obj.h
#include <d3d12.h>
// 解放マクロ
#define Release(X) { if ((X) != nullptr) (X)->Release(); (X) = nullptr; }
classObj
{
public:
   // コンストラクタ
   Obj() : result(S_OK) {
   }
   // デストラクタ
   virtual ~Obj() {
   }

protected:
   // 参照結果
   HRESULT result;
};
```

それではこの基底クラスを元にデバイスを使っていきたいと思います。

```c++:Device.h
#include “Obj.h”
class Device :
   public Obj
{
public:
   // コンストラクタ
   Device();
   // デストラクタ
   ~Device();

   // デバイスの取得
   ID3D12Device* Get(void) const {
      return dev;
   }
private:
   // デバイスの生成
   HRESULT Create(void);

   // デバイス
   ID3D12Device* dev;
   // 機能レベル
   D3D_FEATURE_LEVEL level;
};
```

```c++:Device.cpp
#include “Device.h”

// 機能レベルの一覧
D3D_FEATURE_LEVEL levels[] = {
   D3D_FEATURE_LEVEL_12_1,
   D3D_FEATURE_LEVEL_12_0,
   D3D_FEATURE_LEVEL_11_1,
   D3D_FEATURE_LEVEL_11_0
};

// コンストラクタ
Device::Device() : 
   dev(nullptr)
{
   Create();
}

// デストラクタ
Device::~Device()
{
   Release(dev);
}

// デバイスの生成
HRESULT Device::Create(void)
{
   //使用PCの機能レベルにあったもので作成します。
   for (auto& i : levels)
   {
      result = D3D12CreateDevice(nullptr, i, IID_PPV_ARGS(&dev));
      if (result == S_OK) 
      {
         //マッチした機能レベルを格納してます。
         level = i;
         break;
      }
   }
   return result;
}
```

これでデバイスの生成は終了です。
機能レベルを直打ちでなくどの機能レベルで作成できるのかをループで回してあげることで、
PCに依存されずに作成が可能になります。

次回はコマンド周りを作っていこうと思います。
自分へのメモ：MacへのEclipseの導入&日本語化


後からもし不具合が発生したときに見返せるように記録しておこう

####まずはダウンロード
（最初から日本語化されているものをダウンロードしたい場合はこちらからではない）
https://www.eclipse.org/downloads/
https://www.eclipse.org/downloads/packages/
下のパッケージ化されてるやつとやらをみると、
なんか選択肢がいっぱいあって、合ってそうなのが２個あるけど・・・

・Eclipse IDE for Java Developers にするか
・Eclipse IDE for Java EE Developers　が良いのか

SEとEEの違いをこちらで読んでみた
https://www.sejuku.net/blog/12902

そのうちwebアプリも作ってみたいな、と思うのでEEが良さそうなのでこちらをダウンロード。
自動的に落とされたのは最新のバージョンで、4.8 Photon　らしい
(photon=光子？）なんかまたシャレた由来があるのかな？？

####日本語化プラグインの設定方法
めんどくさそうだから英語のままで行こうかな？と思ったけどやっぱり不安なので日本語化してみることに（というかわざわざプラグインっていうものをやんなきゃいけないのか、と知った。Pleiadesってなんじゃい）
まずはPleiadesをダウンロード
http://mergedoc.osdn.jp/
設定はこちらがとても参考になった
http://tech.pjin.jp/blog/2018/07/23/tips_mac_eclipse_photon_ja_part2/


####最初から日本語化されてるEclipseをダウンロード出来るらしい
参考
http://tech.pjin.jp/blog/2018/07/10/tips_mac_eclipse_photon_ja/

別でPleiadesをダウンロードしてセットアップする手間が省けて良いけど、別でやるのに比べると動作が重くなるという記事も見ました。
どちらが良いのかは、、？？？ワカラン
（今回は結果的に勉強になったので自力でやって良かったかも。）

####雑記
記事にはほぼ関係ないけれど、先月末にAWSから警告メールが来てどうやら、Cloud9を使いすぎですよ、とのことで、無料の設定のはずだったけどな〜まあちょっと使うの控えめにしよう、オーバーしたら使用出来なく自動でなるかな？と半分放置してたら結局＄0.4の料金が発生しました(えっ0.4ドル？40セントってこと？ww)それは良いんだけど、まぁちゃんと仕組みを把握していないとダメだな、と思って調べてみたけどなんだかややこしくてちょっとうーん・・・ww大雑把な把握だけど、使った（ワークスペースにアクセスした)回数と時間とワークスペースの数が重要らしい。月単位なのかな？とにかく本当にCloud9が必要な時以外は使わないでおこう、と思い、せっかくなので以前からやらなきゃと思っていたEclipseの導入をやってみることにしました。テキストエディタはAtomってのは前から入れてたけど、ちょっとしたコードの確認に全部Cloud9使ってたからなぁ。便利だもんね。でももっとちゃんと料金体系調べないといつか痛い目に合うかも・・・!
PHPのセッションについて！

#PHPのセッション
PHPにおけるセッションについて見ていきます。

##セッションとは？
セッションとは、「webサイトにおける一連の動作の単位」を指します。
「1セッション」=「1つの連続する動作」となります。

最もわかりやすい例が「ログイン、ログアウト」の考え方です。
ページにログインしてから、ログアウトするまでの一連の動作を「セッション」といいます。
そして1つのセッションの間、IDやパスワードなどを保持し続けることができます。

まとめると以下の2つです。

・「セッション」=「ログイン～ログアウトまでの一連の動作」。
・セッションの間は、情報を保持し続けられる。

##「クッキー」と「セッション」の違い
「セッション」と似ている概念に「クッキー」と呼ばれるものがあります。
「クッキー」とは、セッションと同じく一定の期間の間情報を保存できる機能です。

しかし保存先に違いがあります。

「セッション」→サーバー側に保存
「クッキー」　→プラウザ側に保存

##セッションの使い方


・「セッション開始の合図」
　　`session_start();`

・「セッションに値を入力」
`$_SESSION['userid']="121212"`

・「セッションの値を表示」
`echo $_SESSION['userid'];`


・「実際のセッションのコード」
```
session_start();
$_SESSION['phonenumber']="090××××××××"
echo $_SESSION['phonenumber'];
```

・「セッションの値を削除」
`unset($_SESSION['userid']);`
ROS講座36 非インターネット環境でNTPをする

# 環境
この記事は以下の環境で動いています。

| 項目 | 値 |
|:-:|:-:|
| CPU | Core i5-8250U |
| Ubuntu | 16.04 |
| ROS | Kinetic |

インストールについては[ROS講座02 インストール](https://qiita.com/srs/items/e0e0a9dc3f94c2d3348e)を参照してください。
またこの記事のプログラムはgithubにアップロードされています。[ROS講座11 gitリポジトリ](https://qiita.com/srs/items/25a56a6abda41dcf396e)を参照してください。

# 概要
ROSで複数マシンを使うときに問題になるものとして時刻の問題があります。ロボットの処理では時刻に依存するものがあります。しかしROSを1つのマシンで動かしている分では時刻ずれの問題は発生しないのでこれにつて考慮されることは少ないです。
普段PCはインターネットに接続されているのでNTPによってNTPサーバーと時刻が同期されるので、複数PC間でこのような処理を行っても問題は起こりません。しかし展示会等でインターネット接続がない環境に持って行った瞬間にこの問題が顕在化します。PCのRTCでは最大で1日で1秒ほど時間がずれることもあります。
クローズな環境（＝インターネット接続がない環境）でコンピューターのうち1つをNTPサーバーとして、それにほかのPCがクライアントとして時刻同期する設定を説明します。

# 時刻ずれによる問題
一番分かりやすいところはrvizのtfの表示です。例えば2つのPC、PC-AとPC-BでROSを実行していて、Rvizを表示しているPC-AよりもPC-Bのほうが1秒時計が遅れているとします。PC-Bがtfでjointを動かしたとすると、rviz上では1秒遅れて表示されます。

# 非NTPでの時刻ずれ
PCの時刻は電源が入っている時はCPUのカウンターが時間をナノ秒単位で管理しています。これをシステムクロックと呼びます。しかしPCの電源を切っている時はこのカウンターは使えません。実はPCに電源が供給されていなくても（デスクトップPCで電源を抜いていても、ノートPCでバッテリーが抜けていても）マザーボードのバックアップ電池（という名のただのコイン電池）によってRTCというユニットは動いています。RTCには32.768kHz(=$2^{15}$Hz)の水晶発振子を持っていてこれで常に時間を数えています。これをハードウェアクロックと呼びます。
しかしこの水晶発振子も完全には正確ではなくずれがあります。一般的には20ppm$(=20\times10^{-6})$程度です。1日は86,400秒なので1日で約1.6秒ずれることとなります。これだけずれればロボットの制御はできません。

# NTPの仕組み
NTPクライアントがNTPサーバーに問い合わせるとサーバーが時刻を返すという仕組みです。

## stratum
世の中には原子時計のようにはるかに正確な時計がありますが、値段や扱いの問題でもちろんすべてのPCに乗せることはできないので一部のサーバーにのみ正確な時計を載せます。このサーバーをstratum0と呼びます。ほかのPCはこのサーバーに時刻を問い合わせることで時刻を合わせることができます。stratum0に問い合わせて時刻を合わせたPCをstratum1と呼びます。すべてのPCがstratum0のサーバーに問い合わせるのは現実的でないので、stratum1に問い合わせるPCもいます。stratum1に問い合わせて時刻を合わせたPCをstratum2と呼びます。NTPではこのようにツリー構造で多くのPCが時間を合わせます。大体のPCはstratum4や5になりますが、それで十分な時刻の精度を持ちます。Ubuntuなら標準で`ntp.ubuntu.com`というインターネット上のサーバーに問い合わせます。そのためにインターネット接続がないと時間同期をすることができなくなります。

## stepとslewモード
NTPサーバーから返ってくる時刻に即座に合わせる方式をstepモードといいます。しかしこの方法だとPCの時刻が不連続になってしまってシステムに問題が起きることがあります。NTPの時刻にで徐々に合わせます方式をslewモードと呼びます。大体のPCの設定ではこの方式で時刻を合わせます。

## NTPとその実装
古くはNTPDがありましたが、今はchronyが主流です。

# chronyの設定
Ubuntu16.04だとchronyは標準でインストールされています。

```shell:chronyのインストール
sudo apt-get install chrony
```

非インターネット環境で使うためにはchronyの設定を変更する必要があります。

```shell:chronyの設定ファイルの編集
sudo vim /etc/chrony/chrony.conf 
```

## サーバー側設定
上記のファイルに以下の2行を書き加えます（場所は問いません）。

```
local stratum 10
allow 192.168/16
```

* 1行目は上位のNTPサーバーが無くても、このPC自体がNTPサーバーとしてふるまうための設定です。
* 2行目はクライアント接続の許可設定です。この書き方だと`192.168.0.0~192.168.255.255`からのNTPのリクエストに対して応答します。

## クライアント側設定
この設定を書くことで自動的に設定したNTPサーバーにアクセスして時刻合わせをします。

```
server 192.168.2.102 minpoll 0 maxpoll 5
makestep 10 3
```

* 1行目は問い合わせるNTPサーバーの設定です。`192.168.2.102`にNTPの問い合わせをしに行きます。後ろのオプションは何回かNTPの問い合わせをして時刻合わせの精度を上げるための設定です。
* 2行目は時刻ずれが10秒以上の時はstepモードで時間合わせを行うという設定です。

# 参考
[NTPの仕組み](https://ja.wikipedia.org/wiki/Network_Time_Protocol)
[NTPDとchronyの違い](https://dan-project.blog.so-net.ne.jp/2016-05-13)
[クロック用発信子のデータシート](http://ww1.microchip.com/downloads/jp/AppNotes/01155A_JP.pdf)

# 目次ページへのリンク
[ROS講座の目次へのリンク](https://qiita.com/srs/items/5f44440afea0eb616b4a)
機械学習を独学で始めています。

# とにかくアウトプットしてみる
50歳近いおっさんが、去年からディープラーニングに興味を持ち始め、それがきっかけで機械学習を独学で勉強してきた。
実際どのくらいの力量があるのか分からず、迷走しているのかもしれず・・・

毎日何かしらのインプットをするようにしたく、そうせざるを得ない状況にさらに追い込むため、アウトプットをしていく。
まずは、Qiitaの使い方から勉強し、GitHubもついでにと。

# 自分のものとするためにアウトプット
インプットしたものを自分のものとするために、アウトプットは効果的な手法の一つと思う。
備忘録にもなるし、本当に自分が理解したのかを確認するにも役立つ。

# いままでやってきたこと
実際問題として最初は、勉強を始めるにあたって何から手を付けた方が良いか皆目見当がつかなかった。
同じような思いをしている人も多いと思うので、参考になるか分からないが、やってきたことをざっくり時系列に書き出してみる。

**・ネットを検索し、ディープラーニングの勉強を始める。（2017年夏ごろ）**
**・無料の講習会を探しては参加しまくって、とっかかりを探す。**
**・ディープラーニング学習用にGPUが乗ったゲーミングPCを購入。**
**・ChainerやNeural Network Console(SONY)でチュートリアル的にいろいろ試す。**
**・2017年12月　JDLAのG検定を受験。合格。（JDLA Deep Learning for GENERAL 2017）**
**・ディープラーニングを含む機械学習そのものから勉強した方が良さそうだと思う。**
**・Udemyの教材で機械学習やPythonの勉強を行う。**
**・やっぱり数学はやっておいた方が良さそうなので、必要そうな数学を勉強する。**
　**（微分積分、線形代数、確率統計など）**
**・AIエンジニアだけでなくデータサイエンティストの領域にも足を突っ込む必要がありそうだと思う。**
**・Kaggleへの挑戦開始した！**
**・独学した内容を振り返りつつ自分なりの理解でまとめようとQiitaで発信開始！（2018年08月）**

JDLAのG検定受験のための勉強は、人工知能に関する知識を浅く広く勉強するためにとても役に立ったと思う。技術的なことの前にまずはここから始めるのは良いかと思う。
講習会や勉強会などもかなり役にたった。無料なものも多く、とてもありがたかった。特にハンズオンは実際自分で動かしながら学べるのでお勧め。
自分の経験から、ハンズオンを経てから技術書に入ると、とっつきやすいのではないかと。

# 勉強を始めたときに購入した書籍
勉強を始めたばかりの時に買った書籍。**★印の3冊はJDLAのG検定の勉強用として購入**したもの。
★[AI白書 2017 （独立行政法人情報処理推進機構　AI白書編集委員会）](https://amzn.to/2KE6zDU)
★[人工知能は人間を超えるか ディープラーニングの先にあるもの](https://amzn.to/2vvRsHJ)
★[深層学習](https://amzn.to/2nm8V0H)
・[ゼロから作るDeep Learning Pythonで学ぶディープラーニングの理論と実装](https://amzn.to/2vtU6hc)
・[Pythonではじめる機械学習 scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎](https://amzn.to/2M8sbhm)
・[Chainerによる実践深層学習](https://amzn.to/2ORHM2x)

# 継続は力なり
とうことで、これからどんどんアウトプットするために、インプットも怠らず行う。
グローバル変数を使ったGo言語のテクニック

# Goでランダム関数を使う時にグローバル変数に入れる事でスタブテストがしやすくなる
# 以下の事に困ってる人に役に立つ内容になっている
・ランダムな値のスタブのテストが出来ない。
・日付を扱ったスタブのテストが出来ない
・引数に上記のような値を入れて解決してるが微妙だと思ってる人

# 結論
※結論から先に記載しておく。そこに行きついた背景などは下に書いておく。
ランダム関数をグローバル変数に入れて、使用する箇所で呼び出せばよい。
こんな感じ↓

```go
// hoge.go
// グローバル変数に関数をぶち込む
var getRandNum = func(num uint) uint {
	rand.Seed(time.Now().UnixNano())
	return uint(rand.Intn(int(num)) + 1)
}

func hoge() string {
	var num uint = 7
	randNum := getRandNum(num)
	if randNum%2 == 0 {
		return "偶数"
	}
	if randNum%2 == 1 {
		return "奇数"
	}
	return "異常"
}
```


```go
//hoge_test.go
func TestName(t *testing.T) {
	type testSet struct {
		num      uint
		expected string
	}

	testCase := []testSet{
		{13, "奇数"},
		{20, "偶数"},
		{15, "奇数"},
	}

	for _, test := range testCase {
		// グローバル変数に定数値を挿入
		getRandNum = func(num uint) uint { return test.num }
		actual := hoge()
		if actual != test.expected {
			t.Errorf("got %v\nwant %v", actual, test.expected)
		}
	}
}

```


# 困ったこと
こんな感じのソースコードを書いていて、いざテストを書こうとしたときに書けなかった。

```go
func hoge() string {
	var num uint = 7
	
	rand.Seed(time.Now().UnixNano())
	randNum := uint(rand.Intn(int(num)) + 1)
	
	if randNum%2 == 0 {
		return "偶数"
	}
	if randNum%2 == 1 {
		return "奇数"
	}
	return "異常"
}

```

理由は、ランダムな値をスタブすることが出来なかった。
解決策は他にもあった。
例えばこんな感じに引数にランダム値を取らせル方法

```go
func hoge() string {
	var num uint = 7
	
	rand.Seed(time.Now().UnixNano())
	randNum := uint(rand.Intn(int(num)) + 1)
	
	return huga(randNum)
}

func huga(num uint) string {

	if num%2 == 0 {
		return "偶数"
	}
	if num%2 == 1 {
		return "奇数"
	}
	return "異常"
}
```
これが一般的な解決策にも思えるが、これだと呼び出し側がランダムな値を渡すことを知ってしまうし、
他のケースだと引数が多い場合もあると思う。
なのでスマートじゃない。ってことでグローバル変数を使って処理を書いた。
※ グローバル変数を小文字スタートで定義したらパッケージ内からしかさせないので、外にそんなに影響がないと思ってる。