OmniAICreator/Qiita-1.07M huggingface dataset:
カテゴリカル分布は多項分布のN=1バージョン（機械学習の学習 #2）

# はじめに
数学素人が、機械学習の学習で出会ったことを記載しています。
タイトルをみて「当たり前やん」と思う方は、本記事を読む必要はないです。
今回は、自分があれっと思ったことをその順で記載しています。

# カテゴリカル分布の説明がWEBで見つからない。
二項分布とかベルヌーイ分布とかは検索してヒットするのですが、カテゴリカル分布（マルチヌーイ分布とも呼ぶそう）の情報はあまりでてきません。Wikipediaにも載っていないっぽい。確率分布は？分散は？と思ったわけです。一応、

- ベルヌーイ分布　→多値をとる版→　カテゴリカル分布

ということはわかっています。

# 多項分布っていうのがあるらしい。
多項分布というのがあって、

- ベルヌーイ分布　→多試行版→　二項分布
- 二項分布　→多値をとる版→　多項分布

の関係があることがわかりました。

# ってことは・・・
カテゴリカル分布　←１回試行版←　多項分布
ってことなので、**多項分布の様々な式（確率関数とか、分散とか）に試行回数N＝１を入れれば、自分が知りたかった式が得られます。多項分布はWikipediaにも載っている。やった！**

# Wikipediaで多項分布を調べる。
確率変数が複数出てきて、・・・んん？よくわからない。

# 確率分布の関係をきれいにまとめたサイトがありました。
[ややこしい離散分布に関するまとめ](http://machine-learning.hatenablog.com/entry/2016/03/26/211106
 "ややこしい離散分布に関するまとめ")
↑
体系的＆視覚的にまとめてあって、非常に素晴らしいです。
複数出てくる確率変数をベクトルで記載してあったので、筆者的には読みやすかったです。

尚、数式等は上記サイトやWikipediaをご参照ください。筆者が書くより確実です。

# おわりに（完全に蛇足）
機械学習の学習を始めたのはいいものの、数学の用語一つ一つに引っ掛かります。どこまで知っていれば機械学習のスタートラインに立てるのかがわからないんですよね・・・。
Vuetifyのv-tabsのコンテンツを縦横100%のサイズにする


# 環境
nuxt.js : 2.6.3
vuetify.js : 1.5.5

# 問題
Vuetifyのv-tabsを使ってタブを作ろうとすると、コンテンツ部分のサイズが親要素のサイズに対して100%にならない。
.v-window__containerにスタイルを指定しても適用されず、高さの指定ができない。

# 解決策

スタイルのセレクタの指定の仕方に工夫が必要だった。

Vue.jsのテンプレートで&lt;style scoped&gt;のときには&gt;ではなく、Vue特有の&gt;&gt;&gt;が必要。(詳しくは[こちら](https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html#ディープセレクタ) )

```vue:テンプレート
<template>
  <v-tabs dark color="grey darken-4" show-arrows>
    <v-tabs-slider color="yellow" />
    <v-tab v-for="i in 30" :key="i" :href="'#tab-' + i"> Item {{ i }} </v-tab>
    <v-tabs-items>
      <v-tab-item
        v-for="i in 30"
        :key="i"
        :value="'tab-' + i"
        :transition="false"
        :reverse-transition="false"
      >
        <v-card
          v-action
          flat
          height="100%"
        >
          <v-card-text>サンプル</v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-tabs>
<template>

<style scoped>
.v-tabs {
  width: 100%;
  height: 100%;
}

.v-window {
  height: calc(100% - 48px); /* タブ領域の高さを引く */
}

.v-tab__items,
.v-window-item,
.v-window >>> div.v-window__container { /* ここが重要 */
  height: 100%;
}
</style>
```
プロデルでネ申Excel作成を自動化したい #2

##セル内の文字列の置換～その２
　[#1](https://qiita.com/shukvaal/items/f246aca1745059d0a9da)で作ったコードに手を入れて、ひな型から目的のxlsxファイルを出力するようにします。#1で使ったファイルをひな型とします。
![コメント 2019-04-28 231324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349242/f1d908ae-c14c-50f3-f1bd-73b794cd6c5d.png)
カレンダー形式の表で、図では日付部分が切れていますが、「//day1-3」のようなセル位置を表す記号がそれぞれ入っています。xlsxファイルを解凍して得られるsharedStrings.xmlから文字列要素を順次読み出し、それが記号だったらその内容に応じた文字列に置換して、最後にzip圧縮→出力という流れです。
##実際のコード
　ひとまず動くものをということで作ってみました。ひな型から2020年4月の予定表を出力します。

-  7-zip32.dllなどのアーカイバDLLが必要です。
- 作業フォルダtempにひな型ファイルを解凍します。
- 予定データは配列と辞書を組み合わせた構造体もどきに格納してあります。配列の探す手順が使えないので速度的に探索が不利になりますが、読みやすいのであえてこれにしました。
- 月の大小の処理はしてません。
- その他まどろっこしい部分があります（特に後半の分岐の辺り）

``` xlsx操作.rdr
ーー予定データ
見出しは、{title=「2020年4月　プレイルーム使用予定」,mon=「月」,tue=「火」,wed=「水」,thu=「木」,fri=「金」}
ーー構造体もどきを定義
予定一覧は、{
{日付=1,参加者=「渡部 石倉 伊藤」},{日付=2,参加者=「横尾 小笠原 西 横川」},{日付=3,参加者=「江原 松本 新田 千田」},
{日付=6,参加者=「富田 浅井 森山」},{日付=7,参加者=「原 中川 藤原 」},{日付=8,参加者=「片岡 柳原 福田 山口」},
{日付=9,参加者=「柴山 志村 須藤 」},{日付=10,参加者=「志村 星野 桑原 大井」},{日付=13,参加者=「原口 宮部 新垣」},
{日付=14,参加者=「平田 生田 浜崎 三村」},{日付=15,参加者=「菅井 進藤 八木 」},{日付=16,参加者=「細田 谷口 菅谷 坂口」},
{日付=17,参加者=「山野 藤井 水口 」},{日付=20,参加者=「佐竹 荻原 島津 西」},{日付=21,参加者=「水崎 竹下 大木 」},
{日付=22,参加者=「黒沢 梅田 竹下 諏訪」},{日付=23,参加者=「泉 鈴木 阪本 」},{日付=24,参加者=「志村 北野 一木 池内」},
{日付=27,参加者=「立石 川井」},{日付=28,参加者=「岡島 池上 成海 」},{日付=30,参加者=「上山 黒岩 森下 村上」}
}


臨時日付は、「2020/4/1 0:00」を日時形式化したもの
曜日一覧は、{「月曜日」,「火曜日」,「水曜日」,「木曜日」,「金曜日」,「土曜日」,「日曜日」}
臨時一覧は、曜日一覧から[臨時日付の曜日]を探したもの
曜日オフセットは、臨時一覧(1)-1

「［プログラムの位置］カレンダー原紙.xlsx」を「［プログラムの位置］\temp」へコピーする
「［プログラムの位置］\temp\カレンダー原紙.xlsx」を「［プログラムの位置］\temp\カレンダー原紙.zip」へ変更する
「［プログラムの位置］\temp\カレンダー原紙.zip」を「［プログラムの位置］\temp」へ解凍する
「［プログラムの位置］\temp\カレンダー原紙.zip」を削除する
文字列xmlは、「［プログラムの位置］temp\xl\sharedStrings.xml」をXMLとして開いたもの
文字セル一覧は、文字列xmlから「sst\si」を取得したもの
文字セル一覧を箱へそれぞれ繰り返す
	臨時一覧は、箱の要素一覧
	臨時一覧を器へそれぞれ繰り返す
		もし器の名前が「t」かつ[器の内容が「//[[]A-Za-z[]]+」という正規表現に合致する]ならば
			マッチ単語は、器の内容から「[[]A-Za-z[]]+」という正規表現で取り出したもの
			マッチ数字は、器の内容から「[[]0-9[]]+」という正規表現で取り出したもの
			もしマッチ単語(1)が「day」ならば
				臨時は、[(マッチ数字(1)-1)*7+マッチ数字(2)-曜日オフセット]
				もし臨時>0ならば
					器の内容を、臨時に変える
				そうでないなら
					器の内容を、「」に変える
				もし終わり
			他でもしマッチ単語(1)が「member」ならば
				臨時は、[(マッチ数字(1)-1)*7+マッチ数字(2)-曜日オフセット]
				該当なし=1
				[予定一覧の個数]回、値にカウントしながら繰り返す
					もし、臨時=[予定一覧(値)の「日付」]なら
						該当なし=0
						繰り返しから抜ける
					もし終わり
				繰り返し終わり
				もし該当なし=0なら
					器の内容を、予定一覧(値)の「参加者」に変える
				そうでないなら
					器の内容を、「」に変える
				もし終わり
			そうでないなら
				器の内容を、[見出しからマッチ単語(1)を得たもの]に変える
			もし終わり
		もし終わり
	繰り返し終わり
繰り返し終わり

「［プログラムの位置］temp\xl\sharedStrings.xml」に文字列xmlを保存する
「［プログラムの位置］\temp\_rels」を「［プログラムの位置］\temp\カレンダー原紙.zip」へ圧縮する
「［プログラムの位置］\temp\docProps」を「［プログラムの位置］\temp\カレンダー原紙.zip」へ圧縮する
「［プログラムの位置］\temp\xl」を「［プログラムの位置］\temp\カレンダー原紙.zip」へ圧縮する
「［プログラムの位置］\temp\[[]Content_Types[]].xml」を「［プログラムの位置］\temp\カレンダー原紙.zip」へ圧縮する
「［プログラムの位置］\temp\カレンダー原紙.zip」を「［プログラムの位置］\temp\カレンダー原紙.xlsx」へ変更する
```

ひな型ファイル(カレンダー原紙.xlsx)をコードファイルと同じフォルダに置いて実行させると、tempフォルダにひな型と同名のファイルが出力されます。
![コメント 2019-05-05 235726.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349242/dffae64f-eee8-ace7-2d88-65e1fdb4e65a.png)

うまく置換できているようです。
アンインストールに失敗して「INSTALL_FAILED_UPDATE_INCOMPATIBLE」と出てきた時の復旧方法（アプリをインストール/アンインストールできなくなった時）

![エラー画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/0e39e8ca-1b62-0aa9-0c3d-d56fbd14b3de.png)
コマンドプロンプトからアプリをインストールしようとして失敗している様子

##症状
デバッグ中にアプリをリセットしたいと思い、GooglePlayの「アンインストール」ボタンを押してアンインストールを開始しました。
しかし、「アンインストール中...」のまま画面が変わらなくなり、全く終了する気配がしなかったので一度GooglePlayを強制終了したら、今度はインストールできないという事態にハマってしまいました...
設定のアプリ一覧にも表示されず、インストールもできず、本当に困りましたが、検索したらいろいろやり方が書いてあったのでまとめてみます。

##失敗した復旧方法
**正しく復旧できた方法は下の「復旧方法」に書いています**
####１．GooglePlayから入れなおしてみる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/967af7f8-dd9e-ccf9-35be-14c4bc381980.png" width="50%">
ちょうどGooglePlayにリリースした自分のアプリだったので、アプリのページを開いて「インストール」ボタンを押してみるも...
「他のユーザーが既にこのデバイスに互換性のないバージョンをインストールしているため、このアプリケーションをインストールできません」
と表示されてインストールできませんでした。

####２．Apkファイルから直接インストールしてみる
ビルドしたApkファイルを端末に送って、開いて「インストール」ボタンを押してみるも...
「このアプリはインストールできません」
と表示されてまたもインストール失敗。

####３．コマンドプロンプトでアプリをアンインストールする
![エラー画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/0e39e8ca-1b62-0aa9-0c3d-d56fbd14b3de.png)
USBデバッグを許可したスマホをPCに接続し、「adb uninstall rabbitp.sns.notifisor（アプリのID）」とコマンドプロンプトで入力して実行してみましたが、「Exception occurred while executing:」の後に何行もエラーが返ってきました。

「adb install "C:\androidstudio-pc\Notification Sorting\Playストア用\app_v1.7.apk"（アプリのパス）」と入力してインストールも試みましたが、「adb: failed to install C:\androidstudio-pc\Notification Sorting\Playストア用\app_v1.7.apk: Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package rabbitp.sns.notifisort signatures do not match previously installed version; ignoring!]」とエラーが返ってきて出来ませんでした。

##復旧方法
![成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409628/4cfb9995-f39c-69ba-3889-4aed0f39422a.png)
１．Android Studioでアプリのプロジェクトを開く
↓
２．左のタブにある「ビルド・バリアント」（私は開発環境の言語を日本語にしています。名前はバージョンによって異なる可能性あり。）をクリックする。
↓
３．タブが開いたら、「ビルド・バリアント」を「build」から**「release」に変更する**。
↓
４．ビルドする！
↓
５．一度アプリをアンインストールしてもいいですか？的なダイアログが出たら、「OK」（ボタンに色がついている方）をクリックする。
↓
６．見事アプリのインストール成功。


直ってよかったです。
初期化しないとダメかと思いました...

##その後...
この後すぐにまた同じ状況になりましたが、今度はapkファイルを直接インストールしたらあっさり直りました。
状況によって復旧方法が異なるようです。
上に書いた復旧方法すべてを試してみることをお勧めします。
perlで正規表現 肯定先読み、否定後読みなど


## (肯|否)先読みとは

何らかの正規表現を (?= と ) もしくは (?! と ) で括ることで，括られた正規表現にマッチする文字列が直後に存在する／存在しないことを指定してマッチングを行う。

使用例としては「hoge」という文字列を含むや「hoge」のあとに「fuga」が来たらマッチさせるなどといった場合に使える

## 使用例

#### 先読み

``` perl:「hoge」がありかつその後に「fuga」がある
/hoge(?=fuga)/

# match例
#  hogefuga
# matchしない例
#  hogeefuga
```

``` perl:「hoge」を含まない
/^(?!.*hoge).*$/

# match例
#  fugafuga
# matchしない例
# fugafugahogefuga
```

``` perl:「hoge」または「fuga」を含まない
/^(?!.*(hoge|fuga)).*$/

# match例
#  foobar
# matchしない例
#  higehoge
```

``` perl:「hoge」を含むが「fuga」を含まない
/^(?=.*abc)(?!.*def).*$/

# match例
# hogehoge
# matchしない例
#  hogefuga
#  fugahoge
```

``` perl:「hoge」で始まらない
/^(?!hoge).*$/

# match例
#  fuga
# matchしない例
#  hogefuga
```

#### 後読み

肯定後読みは　（？＜＝）
否定後読みは　（？＜！）
と書いて表します。

``` perl:「fuga」が直前にある「hoge」
/(?<=fuga)hoge/

# match例
#  fugahoge
#  afugahoge
# matchしない例
#  fuga hoge

```

``` perl:「fuga」が直前にない「hoge」
/(?<!fuga)hoge/

# match例
#  fuga hoge
# matchしない例
#  fugahoge
```

#### 参考記事

[正規表現の先読み・後読みを極める！](https://abicky.net/2010/05/30/135112/)
[[コラム] 正規表現の先読み/後読みは、どう考えても名前が悪いので、呼称禁止令を出してルックと気軽に呼んでみませんか。](https://qiita.com/mochizukikotaro/items/84f3ab2740b8efbe0dc6)
【Google Test】Visual StudioでC++のユニットテストを書いてみる

# はじめに

先日[Visual Studio 2019 Loanch Event](https://connpass.com/event/122145/)に行ってきました。MicrosoftのMVPの方々がVSについていろいろ講演をしてくださり、VSや.NETについての知識が深まるとともに開発のモチベが結構上がってとてもよかったです。

そんな経緯があり、今回はVisual Studioについての記事を書いていきたいと思います。

Googleで「c++　テスト」とか検索してみると色々出てきますが、そのほとんどがmakeでプロジェクトをビルドしていました。自分はC++の開発でVSを使っているので、自分なりに方法を探ってみたところ割と簡単にできたので、備忘録的にその方法をまとめてみようと思います。

なお、今回の記事の環境は以下の通りです

- Windows 10
- Visual Studio 2019

# プロジェクトを作る

それではプロジェクトを作っていきましょう。今回はC++コンソールアプリケーションで作成したライブラリをGoogleTestで単体テストしてみる想定でやっていきますよ。

コンソールアプリでは、```main.cpp```というメインプログラムから```Library.h```というヘッダーファイルを参照しようと思います。まずはヘッダーファイルのコードから見てみましょう。

```cpp:Library.h
#pragma once

int euclid(int n, int m) {
	if (n < m) {
		int tmp = n;
		n = m;
		m = tmp;
	}
	if (m == 0)
		return m;
	return euclid(m, n % m);
}
```

実際なんでも良いのですが、ユークリッドの互除法によって2整数の最大公約数を求める関数を作りました。この関数をメインプログラムから呼び出します。

```cpp:main.cpp
#include <iostream>

#include "Library.h"

using namespace std;

int main()
{
	int n, m;

	cin >> n;
	cin >> m;

	cout << "result: " << euclid(n, m) << endl;
}
```

実行すると、こんな感じになります。

```
25
15
result: 0
```

あれ、なんか変ですね。
この互除法の関数をテストしてみましょう。

# テストを導入する

ソリューションに新しいプロジェクトを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86191/29d291b2-1a0d-b6dd-edd0-447b1cb40f5a.png)

プロジェクトの種類はGoogle Testです。
テキトーな名前で作りましょう。

ソリューションの構成は以下の通りです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86191/11aefef0-9de2-2bba-5c16-69657174a8b6.png)

プロジェクトを作ると、最初に```test.cpp```というファイルが出てくると思うので、それを編集していきます。結果的にできたコードがこちら。

```cpp:test.cpp
#include "pch.h"
#include "gtest/gtest.h"
#include "../qiita google test sample/Library.h"

TEST(EuclidTest, Reverse) {
	EXPECT_EQ(euclid(25, 15), 5);
	EXPECT_EQ(euclid(21, 56), 7);
}

TEST(EuclidTest, Minus) {
	EXPECT_EQ(euclid(-1, 3), -1);
}
```

ここでVSの```テスト```リボンからテスト設定→ビルド後にテストを実行するに設定すると
ソリューションをビルドしたときに自動でテストを検索して実行してくれます。
それではビルドしてみましょう。なお、テスト結果はテストエクスプローラを使うとわかりやすいです。
予想通り全部レッドですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86191/6021a144-5107-45d8-d75a-6210929ac270.png)

ここで、Library.hの一行が間違いだったことに気が付きました！

```diff
+		return n;
-		return m;
```

ですね。
これでビルドしなおすと、一つのケースだけグリーンになりました。
この関数では負の値が来たときは-1と返すように定義したいので、そのコードを加えましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86191/74ae3cc9-c46c-95bf-b512-d085499355f7.png)

```cpp:Library.cpp
#pragma once

int euclid(int n, int m) {
        // add
	if (n < 0 || m < 0)
		return -1;
	if (n < m) {
		int tmp = n;
		n = m;
		m = tmp;
	}
	if (m == 0)
		return n;
	return euclid(m, n % m);
}
```

すると、見事グリーンになりました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86191/a1f25cb5-1515-f5b4-ad68-407571f84d05.png)


# おわりに

今回はC++で単体テストを行うという内容でした。
自分自身テストに詳しくないので、これを機にちょっと勉強してみようと思います。
最後までご覧いただきありがとうございました。
わたしのメンタリング・ポリシー

所属組織内での公式/非公式限らず、メンタリングやそれに近いことをするときの、私の考えやとっている行動を明記しました。

## ！！基本指針！！
互いの認識を伝え合いましょう。
具体的か抽象的か、悩みか提案か相談か、意見か反論か、どんなことについても上記がすべての基本です。
完璧ではない人間同士、なんの配慮もなければ時には大きな摩擦に発展してしまうような、ちょっとした認識齟齬は起こりえます。
というか表面的には見えていないだけで、日常茶飯事です。

**カイゼンを進めながら一緒にモノ・コトを作っていく**ために、共に刺激を与え合う関係を築いていきましょう。

## スローガン
### 暗黙より、形式
対話しよう!

### 意識より、行動
観測可能にしよう!

### タスク内容より、達成状態の調整
やろうことしていること、やったことへの意見出しではなく、どうなっていたら良いのかのチェック項目など、どういう成果を望むのか、到達点や評価軸を調整しよう！（※注１）

### 個別の判断より、リズムに乗れる仕組み
判断には脳のリソースを大きく消費します。手順化したり、できる限り仕組みに乗っけられる工夫を考えましょう！
ただし、これが困難な場合も少なくない（不定形の業務が多かったり、そもそもその仕事が一過性のものか継続的なものかの判断は、事前に完璧に予測するのが難しい）ので、考え込み過ぎないように




## 上記のために私があなたたちに実施すること
スローガンをもとにしたメンターからメンティへの具体的な働きかけについて記載します。

* 私はあなたたちへの理解、状況に関する理解が不足しています。それらを埋めるため、教えてください。
* 以下のような問いかけをします
    * 何に詰まっていますか？なぜ困っていますか？
    * 詰まっている/困っている原因は思いつきますか？
    * 別の方法はありますか？
    * お手本になりそうな人、情報を探すあてはありますか？
* **”問題対我々”**になるように、文字にしたり図示したり、あるいはそれらを求めたりします。
 * 文字化や図示による問題の外部化は、とても重要です。100%自分の考えが表現できるとは限りません（というかほとんどそうです）が、ともに解決するために互いに助言しあえるようにしましょう。
 * 会話だけでは、言葉の意味の取違いも発生しやすいですが、それを防ぐ効果もあります。
    

## 私がやらないこと

* 代わりに答えを提示する
    * メンティの答えを導き出す手伝いをするのがメンターです。
    * 例としての案は提示できます。ただし、それも不要であれば教えて下さい。
* 説き伏せよう、説得しようとする
    * 問題にあたっている側、問題解決を支援する側、という構造上でのやりとりを続けていると、陥りやすい状況なので、メンティとメンターとしての関係性にお互いが慣れていないと、ついやってしまいがちで特に注意が必要です。
    * もちろん、法に触れたり、あまりにも社会通念上ふさわしくない場合は上記の限りではありません。

## お願い事項

* 「何か説得しようとしてない？」、と感じたらそう言ってください。
    * 説得や成果へのプレッシャーを与えることはメンターの役目（注2）ではありません。内面的な支援は、意図して成果を確認することが難しいです。内面ではなく、行動として具体的なアクションを出す事に、お互いフォーカスしていきましょう。
* 忙しそうで声をかけづらい時が必ずあります。その時にあったやり方で、問題を抱え込んでしまう時間を少なく工夫をしましょう。
    * 「遠慮なく聞く」は、お互いの事情を知れば知るほど難しくなるケースがあります。
    * いつ、どれくらい時間が欲しいか、どれくらいなら可能かを伝え合いましょう。
    * もしお互いに可能なら、簡単に要件（どんなことをやっていて、何をやりたいか、けれどここに躓いている、という状況）を教えて下さい。
    * 同じ仕事を分担している場合、上記の限りではないです。遠慮せずに、勇気を持って話かけて下さい。**勇気大事**。
    * また、考えずに済むように、定期的なMTGの時間をあらかじめ設けておく、という方法もあります。（スクラム開発のデイリー・ミーティングやスプリント・プランニングなどが参考になりそうです）
* 変化を可視化できるように、KPTなどを使って共有し、次のアクションに活かしましょう。
    * 忙しくなってくると、いろいろな状況によって実施されにくくなってしまいますが、改善を継続する上で重要な活動なので、今のうちにできるだけ体になじませられるよう、色々工夫してみましょう。


## 参考
* [新入社員が来てメンターになれって言われたけど、どうすればいいのかという対話テクニック](https://qiita.com/hirokidaichi/items/2e8e731acfd7b6c7e02f)
* [エンジニアのためのマネジメントキャリアパス - メンターの章](https://www.amazon.co.jp/エンジニアのためのマネジメントキャリアパス-―テックリードからCTOまでマネジメントスキル向上ガイド-Camille-Fournier/dp/4873118484)



注1：恥ずかしながら、最近ようやく自分のなかでも取り組みはじめたことです。後出しジャンケン辛いな、とずっと悩んでてその場しのぎをずっとやってきてしまってたので。。。
注2：業務遂行上、説得や成果へのプレッシャーが功を奏する場面は必ずあります。なので、メンターからではなく、メンティが持っている、あるいはこれから築く関係性の中から、自分に合った良い人を見つけることをオススメします。メンターは、メンティに合った人を見つける、出会わせる、というお手伝いはできそうです。
特定用途の公開鍵を作成して使う　SSH Keys

既存の鍵ファイルがある状態でGithub用の公開鍵を作る際
既存ファイル（id_rsa id_rsa.pub）と分けて管理したかったので、その際の作成作業メモ

`既に鍵認証ファイルを作成している前提で進めます`

```zsh:移動
cd ~/.ssh
ll
```
# 鍵ファイルの作成

↓ コメントは作成する`.pub`ファイル内に記載されます。

```zsh:作成
# ssh-keygen -C コメント -f 鍵ファイルの名称
ssh-keygen -C for_github_key -f github_key
```
`passphrase`入力はご自由に

```zsh:確認
ls | grep github_key
```
```zsh:作成した鍵ファイル
github_key
github_key.pub
```
**githubに公開鍵ファイル（github_key.pub）を登録する** (※下記項に記載)

あとは、sshアクセス時にファイル指定して利用したり

```zsh:ssh
ssh -i ~/.ssh/github_key user@example.com
```
`~/.ssh/config`で指定すれば、特定アクセス時に固定ファイル使用でアクセスできる

```vim:~/.ssh/config
・

Host github
  HostName github.com
  IdentityFile ~/.ssh/github_key
```


---

# Githubに公開鍵を登録する

```zsh:公開鍵ファイルの内容を表示
cat ~/.ssh/github_key.pub
```

Githubの個人アカウント内で公開鍵ファイルの登録をする
https://github.com/settings/ssh/new

※`title`には管理しやすいようにファイル名とかを適当に入力


登録できたらコンソールからsshでアクセスできるか試す
`sshコマンドでは先ほど作成した秘密鍵を指定してアクセスする`

```zsh:sshアクセス確認
ssh -Ti ~/.ssh/github_key git@github.com
```
```zsh:アクセス成功時のメッセージ
Hi Tough_guy! You've successfully authenticated, but GitHub does not provide shell access.
```

git（ push）コマンドを利用できるように、`.ssh/config`と`.gitconfig`に追記する

```zsh:/.ssh/configの末尾に追記
echo "\nHost github\n    HostName github.com\n    IdentityFile ~/.ssh/github_key\n    User git" >> ~/.ssh/config
```
```zsh:.gitconfigの末尾に追記
echo "[url \"github:\"]\n	InsteadOf = https://github.com/\n	InsteadOf = git@github.com:" >> ~/.gitconfig
```

```vim:~/.ssh/config
・
・
・

Host github
    HostName github.com
    IdentityFile ~/.ssh/github_key
    User git
```
```vim:~/.gitconfig
[user]
.
.
.
[url "github:"]
   InsteadOf = https://github.com/
   InsteadOf = git@github.com:
```

コンソールからsshアクセスして、`successfully authenticated`メッセージが表示されれば設定成功

```zsh:sshアクセス確認
ssh -T git@github.com
```

上記が失敗する場合、`ssh-agent`に秘密鍵を登録してから再度試してみる

```zsh:
ssh-add ~/.ssh/github_key

# 確認
ssh-add -l 
```


まだリポジトリを作成してなければ、Githubで作成しとく
https://github.com/new


ここまでやれば、登録した鍵ファイルを利用した接続で`git push`が実行できるようになってるはず

# 参考
>
[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)
[Wokashi: サーバに新たなSSH公開鍵を追加する](http://mironal-memo.blogspot.com/2012/07/ssh.html)
[ssh-agentの使い方 - Qiita](https://qiita.com/isaoshimizu/items/84ac5a0b1d42b9d355cf)
[Githubからリポジトリをcloneする | ひまりさんの技術日記](https://himariweb.com/program/use-git-clone/)
[git clone 時に秘密鍵を指定する - Qiita](https://qiita.com/sonots/items/826b90b085f294f93acf)
[Git における SSH オプション指定方法あれこれ - Qiita](https://qiita.com/kyanny/items/c397370862095c305cbe)
[【Github】ローカルからリモートリポジトリのへプッシュ - Qiita](https://qiita.com/KentaKodashima/items/16a787779ffecc29e717)
[ssh - UNIX/Linuxコマンド - IT専科](http://www.itsenka.com/contents/development/unix-linux/ssh.html)
swift ボタンの角を丸くする

#ボタンを角を丸くするコード
<img width="502" alt="スクリーンショット 2019-05-05 23.43.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410295/bd49c252-434a-57a4-3ac2-9a3473ac891a.png">


##形式
UIButtonの変数名.layer.cornerRadius = 角丸の大きさ

##例

```
   @IBOutlet weak var startButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
       
        startButton.layer.cornerRadius = 10.0
        
    }
```

上のコードではstartButtonというUIButtonの角を大きさ１０にして丸くしてます。
IFTTTとGmailの連携ができなくなったのでgoogle app scriptでGmail→Lineを自作してみた

#IFTTTとGmailの連携が終了

IFTTT、3月31日からGmailのトリガーと下書き作成が利用不可に
https://japanese.engadget.com/2019/03/23/ifttt-3-31-gmail/

今日の今日まで放置してたが、しゃあないと思い自分で書いた。

#事前準備
line notifyに登録し、アクセストークンを取得する
https://notify-bot.line.me/ja/

#google app scriptを書く

~~~javascript
function line_notfication() {
    //hoge@hoge.comからのメールで題名がhogehogeで未読のものを最大50取得
    var threads = GmailApp.search('from:hoge@hoge.com is:unread subject:hogehoge', 0, 50);
    Logger.log(threads.length + "mails");
    if (threads == null || threads.length === 0) {
    return;
    } else {
        for (var i in threads) {
            var msg = threads[i].getMessages()[0];
            var msg_body = msg.getBody();

            //lineにメッセージを送る
            var accessToken = '*********'
            var options = {
                'method': 'post',
                'headers': {
                    'Authorization': 'Bearer ' + accessToken
                 },
                'payload': {
                    'message': msg_body
                 }
            };
            var response = UrlFetchApp.fetch('https://notify-api.line.me/api/notify', options);
            Logger.log(response);

            //既読にする
            threads[i].markRead();
        }
    }
}

~~~

#書いてみて

公式リファレンスが一番わかりりやすい。英語大事。
【爆速】タブを複製するための最速のショートカット

## 【爆速】タブを複製するための最速のショートカット
Chromeブラウザで、タブを複製するためのショートカットを紹介します。
command + L を押して、次にcommnad + return を押します。すると、タブが複製されます。
commnad + returnはアドレスバーにフォーカスされたときのショートカットで、アドレスバーのURLを新しいタブで開きます。

ぜひ試してみて下さい。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Python OpenCVで、複数の画像に対して画像一致を判定して、判定結果をCSVにまとめてみた

## 背景
複数の画像の中から、ある人物が写っている画像を見つけたい！
ということで、
複数の画像に対して、ある画像が一致する箇所があるかを検出して、
判定結果をCSVにまとめてみました。

## 環境
MacOS Mojave ver10.14.4
Anaconda Navigator 1.9.7
　※Anacondaのインストールは、[こちら](https://qiita.com/satoshi-iwaki/items/e431b4182e50a2918a17)を参考に
JupiterNotebook 5.4.0
OpenCV 3.4.2
※OpenCVのインストールは[以前の記事](https://qiita.com/anzanshi/items/a88df7db49f77f65fbbf)を参照ください

## 手順
#### 方針
・検索対象の画像をフォルダから読み込む
・画像の一致検索をかけ、判定結果を配列に格納
・配列をCSVに保存
#### 実装

まずは、各種ライブラリをインポート
cv2：OpenCVを使用するため
glob：フォルダ内のファイルを取得するため
os：ファイルぱすからファイル名を取得するため
ｃｓｖ：csvに保存するため

```python
import cv2
import glob
import os
import csv
```
判定結果を返す関数を設定する（１：一致あり、0：一致なし）

```python
def Push_Stamp(num):
    if 0.99 < num:
        return 1
    else:
        return 0
```
フォルダの中のファイルを取得する
今回は以下の３つのファイルが検索対象としました

```python

files =glob.glob("./ImagesFolder/temp/*") #検索画像保管フォルダパスを指定
```
![スクリーンショット 2019-05-05 23.40.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/89e269e0-400a-3612-927e-c5d7952a308b.png)


imreadで検出したい画像を読み込み

```python

template = cv2.imread('./imagesFolder/temp_template/ipou.jpeg')
```

判定結果を格納する空配列を用意する

```python

wrcsv = []
```
画像の一致判定を行って、判定結果をCSVに書き込む（繰り返し処理）

```python

for fname in files:
    # 検索対象画像の読み込み
    image = cv2.imread(fname)
    # 画像マッチング処理
    result = cv2.matchTemplate(image, template, cv2.TM_CCORR_NORMED)
    # 最も類似度が高い位置を取得する。
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result)
    # 類似度から、判定結果を求める（上で設定した式を使用）
    Judg = Push_Stamp(maxVal)
    # ファイルパスから、ファイル名と拡張子を取得
    filename, ext = os.path.splitext( os.path.basename(fname) )
    # CSVに書き込み
    wrcsv.append([filename,Judg])
```
判定結果の配列をCSVに保存

```python
with open('./imagesFolder/Output/c01.csv', "w") as f: # 文字コードをShift_JISに指定
    writer2 = csv.writer(f, lineterminator="\n") # writerオブジェクトの作成 改行記号で行を区切る
    writer2.writerows(wrcsv) # csvファイルに書き込み
```
## 実行結果
![スクリーンショット 2019-05-05 23.35.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/653faa49-775b-2bcd-f9bf-da8b9257ca9e.png)


## 終わりに
これで、一致しているかどうかをCSVでまとめて見ることができるようになりました！

## 参考
「初心者がpython Anaconda GUIで、簡単にOpenCVをインストールしてみる」
　https://qiita.com/anzanshi/items/a88df7db49f77f65fbbf
「Python OpenCVで画像の一部が一致しているか、判定結果を返してみた」
　https://qiita.com/anzanshi/items/82fc4c7a3a1f84137aef
ソフトウェア開発者としての大事な基礎まとめ[前半]

初投稿です。

僕は中小IT企業で4年間、ソフトウェア開発(デスクトップアプリ)に携わっていますが、ソフトウェア開発者として大事なことを備忘録も兼ねて、ざっくりとまとめます。

全体の目次
  1. ひとつのプログラミング言語を
  2. コードの組み立て方
  3. オブジェクト指向設計
  4. アルゴリズムとデータ構造
  5. 開発プラットフォームと関連テクノロジー
  6. フレームワーク、スタック
  7. データベースの基本的な知識
  8. ソースコントロールシステム
  9. ビルドとデプロイ
 10. テスト
 11. デバッグ

前半は、1~3まで


1. ひとつのプログラミング言語を

僕たちは常々、この世のありとあらゆるプログラミング言語を身に付けたいと思っています。
最終的には、そうあるべきだと思います。
置かれた環境で最適な言語を使用して華麗にコーディングできればめちゃくちゃかっこいいでしょう。

しかし大切なのは、最初はひとつのプログラミング言語に集中すべきだということです。
初心者プログラマの方の多くは、エンジニアとしての最初の就職先を手に入れる前に、複数のプログラミング言語を身につけてリスクヘッジしようとします。
ですが、そんなことをしても混乱するだけですし、他に学ぶべき技術スキルに注ぐエネルギーが削がれてしまいます。
それよりも、ひとつのプログラミング言語の裏表や特性を重点的に深く学ぶ方がずっといいです。そうすれば、その言語でコードを書く能力に本物の自信が得られるはずです。
自分がどんなタイプのソフトウェア開発者になりたいかできる限り具体的なイメージを持って、それを実現できる言語を深く学びましょう。

ちなみに僕は、初学ではあまり評判の良くないC/C++から始めました。
最初は本当に訳がわかりませんでした。
ですが業務でひたすらC++を触ってきましたので、C++に置いてはある程度のコーディングはできるし、知らないことは調べられるという自信(?)を付けることができました。
また、C++のような、初学者には難しめな言語に慣れたおかげか、他の言語を初めて触る時、とても快適に感じることがあります。その快適という感覚を味わえたのはよかったなと思います。
ですが、最初に学ぶのは、C/C++のような低レベルの言語ではなく、
もっと分かり易くとっつきやすい言語がいいと私は思います。そこから慣れていッタ方が絶対いいです。pythonとか。と言いつつC++大好きですがね

2. コードの組み立て方
プログラミング言語をひとつ学んだら、というよりも学んでいるうちに、コードの正しい組み立て方を知ることが必要だと思っています。
コードの組み立て方とはいったいどういうことでしょうか？
それは、コード自体が多くのことを伝えてくれるので、コメントをたくさん書かなくても理解できるような、明快で優れたコードを書くということです。
多くのソフトウェア開発者は、キャリア全体を通じてこのスキルを身につけずに終わってしまいますが、残念なことです。
残された遺産は確実に後の世代の精神を蝕みます。

主としてこれを通じてソフトウェア開発者の能力を判断する人が、たくさんいます。コードの組み立て方がよければ、ただ仕事を終わらせたというだけではなく、職人の技を感じさせるようなものになります。コードの組み立て方は、ソフトウェア開発のアート的な部分だと言えるでしょう。
みなさんやみなさんの同僚は新しいコードを書くよりも既存のコードをメンテナンスする方にかなりの時間を費やし、みなさんが書いたコードを相手に仕事をしなければならないので、そういう意味でもコードの組み立て方はきわめて重要です。
ですので、明快でわかりやすいコードの書き方は、あと付けではなく、コードを書き始めた最初の時期から一所懸命学ぶべきです。

【参考書籍】[リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック], [Code Complete 完全なプログラミングを目指して]
 
3. オブジェクト指向設計

ソフトウェア開発の世界の大部分は、オブジェクト志向設計に基づいてものを考えているので、みなさんもこの考え方を理解する必要があります。
オブジェクト指向設計とはざっくり言うと、複雑なプログラムを、クラスやオブジェクトに分解、抽象化して設計する方法です。

クラスとは、特定の役割や仕事を表す機能とデータを納めたカプセルの定義であり、
オブジェクトとは、そのクラスの定義に基づいて作られた実際のカプセルのことです。

ソフトウェア開発者は、いつも複雑さを手なずけようとして苦労しています。
オブジェクトによってものを考えると、複雑な全体を相手にするのではなく、相互作用し合う部品（コンポーネント）から複雑なシステムを定義、設計できるので、その課題の実現に近づけます。

最近では、関数型プログラミング言語が無数に作られていますが、ソフトウェア開発の世界でもっとも人気のある言語やパターンは、今でもオブジェクト指向設計や分析の影響を強く受けています。
クラスとは何か、さまざまなタイプの継承とは何か（そしてそれをいつ使うか）を理解し、ポリモーフィズム（5）とかカプセル化といった用語の意味を知ることが必要になります。

次回中盤へ
MySQLの初期パスワードのありか

MySQL5.7以降では初期パスワードが自動で生成される様になっており、以前のようにパスワードなしでMySQLに接続することができません。
初期パスワードのありかを解明するのに変に時間を使ってしまったので共有しておきます。

確認した環境(MySQLがインストールされているサーバー)

- CentOS7
- Apache 2.4
- MySQL 5.7

# 初期パスワードはログから探す
MySQLの初期パスワードは初回起動時に自動的に生成されます。
しかし、サーバーの中を探しても「これがMySQLのパスワードですよ」というようなあからさまなファイルは存在していません。

では、どこにあるのか？

じつは、MySQLのログに残っています。

MySQLを実行するmysqldというプログラムはlogを残すようになっており、そのlogの中に初期パスワードも混ざっています。

**mysqldのログファイルの場所**

```
/var/log/mysqld.log
```
このファイルをviコマンドやlessコマンドで確認すると以下の様なログがあるはずです。

```
[Note] A temporary password is generated for root@localhost: EaGapdplN0*m
```
上記の場合、':'以降の「EaGapdplN0*m」というランダムな文字列が初期パスワードです。

このパスワードを使ってMySQLにrootユーザーとしてログインすることができます！

余談ですが、ログは1行だけでなくたくさん出力されるので、「temporary paswword」などで検索するとすぐに見つかります。

# 初期パスワードはすぐに変更しておく
無事に初期パスワードでログインできたらパスワードを変更しておきましょう。
変更しないでおくと毎回「ヴァーダブダブ...」などと言いながら初期パスワードを探さなくてはいけません笑

mysqlにログインしたら、以下のコマンドでパスワードを再設定しましょう！

```:mysql
mysql> set password for root@localhost=password('ここに新しいパスワード');
```
Vue.js(トランジション)(Laravel使用)

[トランジション参考記事](https://jp.vuejs.org/v2/guide/transitions.html)・[トランジションチュートリアル](https://cr-vue.mio3io.com/guide/chapter6.html)を参考にさせていただき、進めさせていただきます。

##◆トランジション
Vue.jsでは、transitionタグで囲んで、cssでちょっと設定するだけで、移動などのcssトランジションを簡単にセットできます。

```
<style>
    .v-enter-active, .v-leave-active{
        transition: opacity 1s;
    }
    .v-enter, .v-leave-to {
        opacity: 0;
    }
</style>
<body>
    <div id="sample">
        <button @click="click">表示切替</button>
        <transition>
            <h1 v-show="show">
                Hello World!!
            </h1>
        </transition>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script>
    const vue = new Vue({
        el: '#sample',
        data:{
            show:true
        },
        methods:{
            click(){
                this.show = !this.show;
            }
        }
    })
</script>
```

<b>.v-enter-active, .v-leave-active</b>をcssで指定しておりますが、transitionタグで囲んだ範囲のDOMが挿入されるときがenterとなっており、消えるときがleaveとなっております。
enterとleaveそれぞれv-○○・v-○○-to・v-○○-activeがありますが、enterの場合で説明させていただきますと、
・v-enterは、DOMに挿入される前
・v-enter-toは、DOMに挿入された後
・v-enter-activeは、v-enterからv-enter-toまで
leaveはDOMに挿入された後から、削除されるまでで考えてほしい。
今回でいうと、v-enter-active, .v-leave-activeはDOMに挿入される前からされた後までを1秒かけて、透過度を変化させるためであり、.v-enter, .v-leave-toはDOMに挿入される前とDOMから削除された後は、透過度0と指定してます。
<b>v-</b>で始まるのはデフォルトがそうなっているためであって、transitionタグにname属性をつけることで変更できます。

##◆複数グループ化
transitionタグでは、独立したノードという決まりなのでv-forなどを使うときに困ります。そんな時はtransion-groupタグを使用して、解決できます。それでは、表示されている配列をシャッフルするときにアニメーションを働かしてみます。

```
<style>
    .fruits-list-move {
        transition: transform 1s;
    }
</style>
<body>
    <div id="sample">
        <button @click="shuffle">シャッフル</button>
        <transition-group name="fruits-list">
            <li v-for="(fruit, index) in fruitsList" :key="fruit">
                @{{ fruit }}
            </li>
        </transition-group>
    </div>
</body>
<script src=" {{ asset('js/app.js') }} "></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<script>
    const vue = new Vue({
        el: '#sample',
        data:{
            fruitsList: ['りんご', 'みかん', 'めろん', 'ぶどう']
        },
        methods:{
            shuffle(){
                this.fruitsList = _.shuffle(this.fruitsList);
            }
        }
    })
</script>
```

key属性を持つことは必須なのですが、indexを指定するとタイムラグの関係かアニメーションがうまくいきませんのでfruitsを設定させていただきました。今回は_.shuffleを使いたいため、CDNでlodash(便利関数の詰まったライブラリ)を利用させていただきます。
nameでtransition-groupを指定しましたので、それをcssで指定しています。今回使用しているのはv-move(アイテムの位置が変更されたときに働いてくれる)を使用しました。

##◆トランジションフック
transionタグにイベントフックを仕込むことで、cssのアニメーションと連動できる
[参考記事](https://jp.vuejs.org/v2/guide/transitions.html#JavaScript-%E3%83%95%E3%83%83%E3%82%AF)
複数の親オブジェクトに各々紐づく複数の子オブジェクトを一括更新するFormの作成


###当該記事の作成背景
親が単一のオブジェクト(user)に紐づく子となる複数オブジェクト(tweet)の一括更新ならわかるけど、親が複数オブジェクトの場合の一括更新処理はどうするんだ、、という点で少し詰まったので、纏めてみました。

###DB設計
User TBLに紐づくTweet TBLの全contentを一括更新する処理を実装する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324184/fda09847-6482-f586-5228-0b6340bded90.png)

###controller
```tweets_controller.rb
class TweetsController < ApplicationController
  
  # 編集ページ表示用アクション
  def edit
    @users = User.all
  end
  
  # 更新用アクション
  def update
    # idがtweetのid,itemがtweet_paramsの各tweetの中身
    tweet_params.each do |id, item|
      tweet = Tweet.find(id)
      tweet.update_attributes(item)
    end
  end
  
  # strongparameterの設定
    private
      def tweet_params
        params.permit(tweets: [:content])[:tweets]
      end
  
end

```

###view
```edit.html.erb

# エラー回避の為、全ユーザーをto_sする
<%= form_for(@users.to_s, url: tweet_path, method: :patch) do |f| %>
  
  # 各ユーザー毎の処理を記述
  <% @users.each do |user| %><br>
    <caption><%= user.name %>のtweet</caption>
    
    # ユーザーIDが同一の複数tweetをtweetsに格納
    <% tweets = Tweet.where(user_id: user.id) %>
      
      # 同一ユーザーの複数tweetsを各々tweetとして出力
      <% tweets.each do |tweet| %>
        <%= fields_for "tweets[]", tweet do |af| %><br>
          <%= af.text_field :content, class: 'form-control' %>
        <% end %>
      <% end %><br>
  <% end %>
  <%= f.submit "更新", class: "btn btn-default" %> 
    
<% end %>
      
```
###動作確認
1. edit.html.erbの表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324184/df9b296c-17f1-6b37-0efe-000a2c7af6bf.png)

2. contentの値を変更して更新ボタン押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324184/25779e86-9975-08ed-a804-a325889e51a3.png)

3. 更新結果確認


###全体を通して
form_forの引数に設定する値はto_sした複数オブジェクトで問題ない点と、結局更新するのは子オブジェクトだから、値の受け渡し先であるコントローラでの処理では、親オブジェクトの扱いを気にする必要はない点でとっても勉強になりました。
NumPyに入門 その4 統計情報の計算

Excelにあるデータ分析ツールの真似をして、
前回使用したアヤメのデータから統計情報を出力したいと思います。

[NumPyに入門 3 CSVから抽出](https://qiita.com/horitaku1124/items/5f73dc10266e7b01f1db)

```.py
>>> iris_data[:5]
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2]])
```

----


### 標準誤差

列毎に標準誤差を計算して出力します

```.py
>>> import math

>>> iris_data.std(axis = 0) / math.sqrt(iris_data.shape[0])
array([0.06738557, 0.03528462, 0.14358331, 0.06210376])
```

----

### 中央値

中央値を列毎に求めて出力します。

```.py
>>> np.median(iris_data, axis = 0)
array([5.8 , 3.  , 4.35, 1.3 ])
```

----

### 分散

分散を列毎に計算して表示します。

```.py
>>> iris_data.var(axis = 0)
array([0.68112222, 0.18675067, 3.09242489, 0.57853156])
```

-----

### 尖度(Kurtosis)

正規分布に比べて尖っている度合いを計算します。

```.py
>>> N = len(iris_data)
>>> a = N * (N + 1) / (N - 1) / (N - 2) / (N - 3)
>>> b = 3 * (N - 1) ** 2 / (N - 2) / (N - 3)
>>> c = (((iris_data - iris_data.mean(axis = 0)) ** 4) / iris_data.std(axis = 0) ** 4).sum(axis = 0)
>>> a * c - b
array([-0.51826916,  0.33592727, -1.37957167, -1.31656779])

```

-----

### 歪度(Skewness)

分布の非対称性を表す度合いを計算します。

```.py
>>> N = len(iris_data)
>>> a = N / (N - 1) / (N - 2)
>>> b = (((iris_data - iris_data.mean(axis = 0)) / iris_data.std(axis = 0)) ** 3).sum(axis = 0)
>>> a * b
array([ 0.31808651,  0.33742124, -0.27723195, -0.10605535])
```


-----
### 信頼区間(95%)

先に標準誤差を求めてから信頼区間を求めます。

```.py
>>> ste = iris_data.std(axis = 0) / math.sqrt(iris_data.shape[0])
>>> ste * 1.96
array([0.13207571, 0.06915786, 0.28142328, 0.12172337])
```
rails 子要素モデル保存, 削除

#accepts_nested_attributes_for
accepts_nested_attributes_for を使ってアソーシエーション先のモデルも含めて一発で保存する！
ついでに、simple_nested_form_for & simple_fields_for について!!

##ルーティング
```routes.rb
resources :fugas, only: %i[new create]
```

##モデル
```models/fuga.rb
has_many :hoges, dependent: :destroy
accepts_nested_attributes_for :hoges, allow_destroy: :destroy, reject_if: :all_blank
```

```models/hoge.rb
belongs_to :fuga
```

##コントローラー
```controllers/fugas_controller.rb
def new
  @fuga = Fuga.new
  @fuga.hoges.build
end

def create
  @fuga = Fuga.create(fuga_params)
end

private
def fuga_params
  params.require(:fuga).permit(:name, hoges_attributes: [:description])
end
```

ストロングパラメーターで子要素のデータ受け取りも忘れないように！


```views/fugas/_form.html.haml
= simple_nested_form_for @fuga do |f|
  = f.input :name
  #hoge_form
    = f.simple_fields_for :hoges do |h|
      = h.input :name
      = h.link_to_remove "削除"
  = f.link_to_add "追加", :hoges, data: {target: '#hoge_form'}
```


#form を作るには2パターンある
###コントローラーで予め作る

```controllers/fugas_controller.rb
def new
  @fuga.hoges.build
end
```

newアクションのタイミングでbuildするやり方

###view で1つずつ追加していく

```views/fugas/_form.html.haml
= simple_nested_form_for @fuga do |f|
  = f.input :name
  #fuga_form
    = f.simple_fields_for :hoges do |h|
      = h.input :name
      = h.link_to_remove "削除"
  = f.link_to_add "追加", :hoges, data: {target: '#fuga_form'}
```

`link_to_add`のように1つずつフォームを追加していくやり方

---

#まとめ
今回、私自身の作業でform の追加時に苦労したため、備忘録的な感じで記事にしました。
言葉で説明しても、ごちゃごちゃになりそうだったので、あまり書きませんでした。（書く知識がないだけです）

間違えてる箇所があればご指摘いただきたいです！
Python OpenCVで複数の画像が含まれている部分を、検出／表示させてみた

## 背景
ある画像の中から、複数の顔を検出したい！！
ということで、
フォルダに格納した複数の顔を読み込み、
元画像から検出して、強調表示させてみました。

## 環境
MacOS Mojave ver10.14.4
Anaconda Navigator 1.9.7
　※Anacondaのインストールは、[こちら](https://qiita.com/satoshi-iwaki/items/e431b4182e50a2918a17)を参考に
JupiterNotebook 5.4.0
OpenCV 3.4.2
※OpenCVのインストールは[以前の記事](https://qiita.com/anzanshi/items/a88df7db49f77f65fbbf)を参照ください

## 手順
#### 方針
・検索したい画像をフォルダから読み込む
・検索対象画像に対して、検索をかけ一致した部分を四角で囲んで表示させる
#### 実装

まずは、各種ライブラリをインポート
cv2：OpenCVを使用するため
glob：フォルダ内のファイルを取得するため
numpy：一致率の計算を実行するため
matopolib：グラフを表示させるため

```python
import cv2  #OpenCVをインポート
import glob
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline #JupiterNotebookに表示するため
```
フォルダの中のファイルを取得する

```python

files =glob.glob("./ImagesFolder/temp_template/*") #検索画像保管フォルダパスを指定
```
今回のフォルダの中身を確認する。
（今回は以下の母娘２人の画像ファイルを入れています）
![スクリーンショット 2019-05-05 22.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/c98368b6-c45d-79ee-d315-968b8c8aaf96.png)
temp_saki.png
![temp_saki.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/1f008c54-ec1f-2082-c691-be437ef702a9.png)
temp_saki2.png
![temp_saki2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/68b9260d-2290-5cc3-6da8-ac9eb936c851.png)


imreadを使って、検索対象の画像を読み込む

```python

image = cv2.imread('./ImagesFolder/temp/temp_moto.png')
```
![temp_moto.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/33551ca8-ffb0-ee48-b550-108cb05767f2.png)

検索したい画像分だけ、検索をかけて一致した場合に、
cv2.rectangleで四角に囲む（繰り返し処理）

```python

for fname in files:    
　　 #検索したい画像を読み込む
    template = cv2.imread(fname) 
    #検索対象画像内で画像が一致するかを検索
    result = cv2.matchTemplate(image, template, cv2.TM_CCORR_NORMED)
    # 一致部分を□で囲む
    th, tw = template.shape[:2]
    threshold = 0.99
    loc = np.where(result >= threshold)
    for pt in zip(*loc[::-1]):
        cv2.rectangle(image, pt, (pt[0] + tw, pt[1] + th), (255,0,255), 2)
```
Matpolibのimshow画像を表示させる
OpenCVで取得した画像はBGRデータ配列、Matplotlibで呼び出す場合のはRGBデータ配列なので、変換する必要があることに注意！

```python
image2 = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)　#データ配列の変換
plt.imshow(image2)
```
## 実行結果
母と娘の２人の顔が認識されているのが確認できます！
![result_temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288322/aaf6294a-2ba0-83a4-e78c-226ff09f9429.png)


## おまけ
画像を保存するには、以下を実行

```python
cv2.imwrite('./imagesFolder/temp/result_temp.png', image)
```

## 参考
「初心者がpython Anaconda GUIで、簡単にOpenCVをインストールしてみる」
　https://qiita.com/anzanshi/items/a88df7db49f77f65fbbf
「Python OpenCVで画像の一部が一致しているか、判定結果を返してみた」
　https://qiita.com/anzanshi/items/82fc4c7a3a1f84137aef
TSG CTF 2019 writeup

TSGCTF2019の解答
floretとして2人で参加
Warmupと感想入力問題(？)含めて5問解けて14位 870ptsでした

# [Forensic]Obliterated File
###### Point: 92  (90solves)

### 問題文
※ この問題は非想定な解法があり，"Obliterated File Again" で修正されました．元の問題文は以下の通りです．

TSG CTFに向けて問題を作っていたんですが，いつの間にか誤ってflagのファイルをコミットしていたことに気付いた！とにかく，Google先生にお伺いして次のようなコマンドを打ちこみました．よくわからないけどこれできっと大丈夫...？

`$ git filter-branch --index-filter "git rm -f --ignore-unmatch problem/flag" --prune-empty -- --all`
`$ git reflog expire --expire=now --all`
`$ git gc --aggressive --prune=now`
### 解法
`git log --name-status`

を実行するとflagという怪しい履歴が。。。
![ob.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181686/70d49694-3594-c31b-a8ef-f7eba0b3dbea.png)



`git reset --hard 8412`

でそのcommitまでさかのぼる
lsで確認するとflagというファイルがあるので
fileコマンドで確認すると

```
$ file flag
flag: zlib compressed data
```
zlibという形式で圧縮されているようなので
pythonで解凍する

```python
import zlib
f=open('flag',mode='rb')
zlib.decompress(f.read())
```
これでflagゲット

```
TSGCTF{$_git_update-ref_-d_refs/original/refs/heads/master}
```

# [Forensic]Obliterated File Again
###### Point: 178  (61solves)

### 問題文
さっきのコマンドには間違いがあったことに気づきました．これで今度こそ本当に，本当に大丈夫なはず......？

`$ git filter-branch --index-filter "git rm -f --ignore-unmatch *flag" --prune-empty -- --all`
`$ git reflog expire --expire=now --all`
`$ git gc --aggressive --prune=now`
### 解法
先程と同様に

`git log --name-status`

としてもflagのログを発見できない
履歴の消し方が強くなっているようだ

gitの履歴はhash値へのポインタのようなものなので
hash値のリストを見ることができればflagの情報
を確認できると考えて調べると

`git rev-list --objects --all`

で全てのobjectのhash値の一覧を見ることができると分かった
![ob2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181686/62e24678-dd50-0f61-0d15-dd3e7b193952.png)

problem/flagというhash値を

`git cat-file -t c1e3`

で調べるとblobであることが分かったので

`git cat-file -p c1e3`

で中身を見ると文字化け

前の問題と同じだろうとエスパーして

`git cat-file -p c1e3 > flag`

で中身を別ファイルに入れて、

```python
import zlib
f=open('flag',mode='rb')
zlib.decompress(f.read())
```

Obliterated Fileで使ったpythonをそのまま実行してflagゲット

```
TSGCTF{$_git_update-ref_-d_refs/original/refs/heads/master_S0rry_f0r_m4king_4_m1st4k3_0n_th1s_pr0bl3m}
```

結局想定外の解法は分からなかった。。。

# [Stego]Harekaze
###### Point: 499  (8solves)

### 問題文
Are you ready for next CTF?

次のCTFの準備はお済みですか？
### 解法
![harekaze.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181686/2fe6093c-8b66-d349-0d5f-4d704c2b72aa.jpeg)
という画像が与えられる

単純にflagになる文字列の部分の色を変えてるだけだと思い
pythonの画像処理ライブラリ使用して画像を変換

```python
import cv2
filename='harekaze.jpg'
gry=cv2.imread(filename,0)
cv2.imwrite('flag.jpg',gry)
```

見づらいけど色覚ある人なら読めるレベル
これでflagゲット
![flag.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181686/b3a50d16-422e-56e5-ac57-afdb5e70b0c4.jpeg)

一応

```
TSGCTF{UnderTheBlueSeaMermaidSwims}
```


###感想など

正直問題としてはHarekazeが一番簡単でした。
何か間違いあったら指摘お願いします。

###参考にしたサイト

https://qiita.com/nkshigeru/items/eb2b6f758c2707757738
https://docs.python.org/ja/3/library/zlib.html
https://git-scm.com/book/ja/v1/Gitの内側-メインテナンスとデータリカバリ
lint周り諸々

# 概要

あんまりlintの設定周りを自分でやってこなかったのでまとめる
あくまで自分用のメモ

# 前提条件

create-react-appで作成したproject（TypeScript）におけるlintの設定とする

# 使うやつ

- eslint
    - linter
    - 構文解析してコードの秩序を保つ
- prettier
    - code formatter
    - コード整形してコードをきれいな状態に保つ


# eslint/prettier関連の設定

## インストールコマンド

```
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser 
prettier eslint-config-prettier eslint-plugin-prettier
```

[注意] eslintはcreate-react-app(react-script)経由で入っているので、別途インストールするとbuildエラーになる（場合がある ※ react-scriptが依存しているeslintと別途入れたeslintのバージョンが異なる場合）

## 設定ファイルの作成

```json:.eslintrc
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "./tsconfig.json",
    "tsconfigRootDir": "."
  },
  "plugins": ["@typescript-eslint", "prettier"],
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended",
    "prettier/@typescript-eslint",
    "plugin:react/recommended"
  ],
  "rules": {
    "prettier/prettier": "error"
  }
}
```

```json:.prettierrc
{
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true
}
```

※ ココらへんは好みや宗教による

# VS Codeの設定

VS Codeを利用している場合は以下の設定で保存時にコード整形をすることができる

## Extensions

以下のExtensionをインストールする

- [eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
- [prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)

## settings.json

以下の設定を追加

```json:settings.json
  // 以下のファイルタイプは環境に合わせる
  "[typescript]": {
    "editor.formatOnSave": true
  },
  "[typescriptreact]": {
    "editor.formatOnSave": true
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {
        "language": "typescript",
        "autoFix": true
    },
    {
        "language": "typescriptreact",
        "autoFix": true
    }
  ],
```

# lint-staged/huskyの設定

`git commit`前に`eslint --fix`を実行して汚いコードが混入することを防ぐ

## インストール

コマンド

```
yarn add -D lint-staged husky
```

## package.jsonの設定

package.jsonに以下の設定を追加

```json:package.json
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "linters": {
      "src/**/*.{ts,tsx}": [
        "eslint --fix",
        "git add"
      ]
    }
  },
```

# まとめ（小並感）

- lintの設定あんまりやったことないけど一通りやって完全に理解した
- こういうのはフレームワークで吸収してほしいなぁ（Next.jsでどうなってるか調べてみる）
- 複数人や開発するときはやっぱりあったほうがいいね
Cloud KMS でセンシティブなデータを暗号化する

パスワードや、秘密鍵など、平文でソース管理したくないセンシティブなデータをKMSで暗号化しておくことで、Cloud Buildのビルドタスク中に復号化して利用できる。

以下、Cloud KMS で暗号化する方法を簡単に紹介する。

質問・訂正・改善・苦情・ご意見あれば、コメントにてよろしくお願いします。

## 暗号化の流れ

事前準備:

* アカウント認証・対象プロジェクトセット（[こちら参照](https://qiita.com/ideodora/items/8080409051907d281ae7)）
* APIの有効化
* keyringの作成
* keyの作成

事前準備ができたら:

* 任意のkeyを使ってファイル（またはバイナリ）を暗号化

## APIを有効化する

* Google Cloud KMS API

いつもgcpのconsole上でポチポチしてるけど、下記のようにもできるみたい。

```
# APIを探す
gcloud services list --available | grep kms

=> cloudkms.googleapis.com                               Cloud Key Management Service (KMS) API

# APIを有効化する
gcloud services enable cloudkms.googleapis.com

=> Operation "operations/acf.326e9d96-1132-40e0-986c-7e3a0917ef12" finished successfully.
```

## Keyrings を作成する

keyのグルーピングに使う模様。文字通り鍵を束ねるキーリング。
locationを指定して作成。

生成

```
gcloud kms keyrings create keyringname --location global
```

一覧表示

```
gcloud kms keyrings list --location global

=> NAME
projects/projectname/locations/global/keyRings/keyringname
```

## Key を作成する

keyring、locationを指定して作成。

生成

```
gcloud kms keys create keyname　--purpose encryption --location global --keyring default
```

必須オプション
**--purpose** {encryption | asymmetric-encription | asymmetric-signing}

* encryption = 対称鍵
* asymmetric-encription = 非対称鍵（暗号化用）
* asymmetric-signing = 非対称鍵（署名用）

一覧表示

```
gcloud kms keys list --location global --keyring keyringname

=>NAME                                                                                   PURPOSE          LABELS  PRIMARY_ID  PRIMARY_STATE
projects/projectname/locations/global/keyRings/keyringname/cryptoKeys/keyname  ENCRYPT_DECRYPT          1           ENABLED
```

## ファイルの暗号化

keyが作成できたら、そのkeyを使ってファイルの暗号化ができる。

暗号化

```
# 暗号化対象のファイルを用意
echo -n "sample text" >> sample.txt

# 暗号化
gcloud kms encrypt --location global \
  --keyring keyringname --key keyname \
  --plaintext-file sample.txt \
  --ciphertext-file sample.txt.encrypted
```

location, keyring, key, plaintext-file（暗号化する元ファイル）, ciphertext-file（暗号化したファイルの出力先） を指定して暗号化する。

```
cat sample.txt.encrypted

=> $<��~F�ڴ/jS�E�����N��*gɢR�c4TNF�L��Qao�S1emrt(�]��6���l}q�v��f�q0yQ�?i�^

# ↑正しく暗号化できている
```

## 入出力について

**plaintext-file**、 **ciphertext-file** は 『-』 を指定することで**標準入力**と**出力**につなぐことができる

```
cat sample.txt | gcloud kms encrypt --location global \
> --keyring default --key keypassword \
> --plaintext-file - \
> --ciphertext-file -

=>$<��~���)�Ɇ���,��O.�/���9NEd��b4TNFҕ0���6��F�$'���?>��u�r��*����}��9$��,&GHR
```

## で、暗号化したファイルをどう使うの？

は、別途ビルドタスクの記事をご参照ください。

* [Cloud Build で リモートサーバーにSSH 接続してデプロイするビルドタスク](https://qiita.com/ideodora/items/82768cdaa273c3dcbb85)
文字列同士のXORをとるワンライナー

#はじめに
CTFで二つの文字列同士のXORをさっと確認したくなったが、うまく動かなくて四苦八苦した。
[それを記事にした](https://qiita.com/Seigenkousya/items/a4b2d40d2ac5c7aa1ce1)のは良かったが、結局-Eオプションとかfeatureプラグマとかバージョンの話ばかりで困ったときに誰もあの記事にたどり着けないだろうと思ったのでこっちに簡潔にメモ。

#文字列同士のXORをとるワンライナー
一方の文字列を"abcd"、もう一方の文字列を"1234"とすると以下のようになる。

```
$ perl -e 'print "abcd" ^ "1234"'
$ perl -E 'say "abcd" ^. "1234"'
```
-eオプションのときの<b>文字列</b>のXOR演算子は、^
-Eオプションのときの<b>文字列</b>のXOR演算子は、^.となる。
-eと-Eでは<b>文字列</b>のビット演算子が異なる。

| 演算子 | -e | -E |
|:-:|:-:|:-:|
| and | & | &. |
| or | &#124; | &#124;. |
|  xor | ^ | ^.  |
|  not | ~ | ~. |

詳しくは前回の記事を参考されたし。
[Perlの-Eオプションとfeatureプラグマに潜む罠 - Qiita](https://qiita.com/Seigenkousya/items/a4b2d40d2ac5c7aa1ce1)
RealmSwiftを使ってみよう

RealmSwiftを使ってみたので、導入手順をまとめたいと思います。
何種類か方法はあると思いますが、今回はCocoaPodsをつかいます。

####CocoaPodsのインストール

すでにCocoaPodsをインストールしたことがある人は省略していい手順です。
ターミナルで下記を実行してください。
バージョンが表示されれば、うまく導入できています。

```コマンド
sudo gem install -n /usr/local/bin cocoapods
pod --version
```

####RealmSwiftのインストール

ターミナルでプロジェクトのフォルダーまで移動して、下記コマンドを実行します。

```コマンド
pod init
```

すると、Podfileが作られるので、開いて、下記の様に編集して下さい

```コマンド
use_frameworks!

target 'RealmExample' do
pod 'RealmSwift'　　//追加
end
```

編集し終わったら、下記コマンドでインストールします。

```コマンド
pod install
```

うまくインストールされると、下記の様にインストールしたものが分かります。

<img width="1261" alt="スクリーンショット 2019-05-03 23.41.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239560/b5061237-5dc7-94e9-7279-aba95dfd548f.png">


そして、プロジェクトのフォルダーに(プロジェクト名).xcworkspaceというファイルが作成されているはずなので、今後はこのファイルからXcodeを開き開発をすすめます。

####プロジェクトで使う

開発で使いたい場合は、下記の様にインポートすれば、使えるようになるはずです。

```○○○○.swift
import RealmSwift
```

※たまにNo such moduleというエラーがでることがあります。
大抵はクリーン&ビルドで解決するはずですが、それでも解決しない場合は下記を確認してみて下さい

Linked Frameworks and Librariesに「RealmSwift.framework、Realm.frameworks」が入っていますか？

※参考までに
いざ実行しようと思ったら、「Multiple commands produce〜」というエラーが発生しました。

下記記事を参考にして、設定を追加したのが影響を与えていました。
[[Swift] RealmSwift使ってみた](https://www.peliphilo.net/archives/1989)

Embed Frameworksに追加した「RealmSwift.framework、Realm.frameworks」を外すと上手くいきました。
ダウンロードした場合は設定が必要かもしれませんが、CocoaPodsから導入した場合は、必要な設定は行ってくれているはずなので、import文を入れれば、基本的に使えるはずです。

Firebaseを導入した時と基本的には同じ感覚でした。
CocoaPods便利ですね。
Leetcode #53: Maximum Subarray

```swift
func maxSubArray(_ nums: [Int]) -> Int {
    if nums.isEmpty {
        return 0
    }
    var answer = nums[0]
    var sum = nums[0]
    for i in 1..<nums.count {
        sum = max(nums[i], nums[i]+sum)
        answer = max(answer, sum)
    }
    return answer
}
```
Pythonを学び始める

Pythonを選んだ理由は機械学習という昨今流行りの分野で重要になる言語であると思ったので、学んでおきたいと思い選びました。

そのPythonですが、まずはProgateで学ぶことにしました。

そこで、気になった点など画像を用いて、まとめてみたいと思います。

<img width="1297" alt="スクリーンショット 2019-05-05 22.37.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276221/5abc3efd-ba62-560b-8fea-3283e3a63bbd.png">

if文の中でprintするというのがインデントがあることで非常にみやすくなっているのだなと思いました。

また、if文が終わった時に行末にコロンをつけ忘れると、改行してもインデントがなかったのですごく親切な言語だなと思いました。


<img width="1261" alt="スクリーンショット 2019-05-05 22.42.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276221/fc6a56aa-a8d1-7ada-3d18-d6091760e77e.png">

辞書についても、取り出したい値があって、それをインデックス番号を使わなくても取り出せるというのはものすごく大量の値を扱う時にすごく便利だと思いました。

このうように気づきや思ったことについて、これからもまとめていきたいと思います！
Scala入門_型

前回の環境構築編
https://qiita.com/zun_jun/items/abb74656362ef2138c41

## 型
### Scalaの型
- 今までJavaやPHPをメインにしてきましたが、Scalaでは以下の型が用意されている。
  - Any：すべての型のスーパークラス
  - AnyVal:値型のスーパータイプ
      - Byte：1バイト符号付き整数
      - Short：2バイト符号付き整数
      - Char：UnicodeのU+0000からU+FFFFまでを表す型
      - Int：4バイト符号付き整数
      - Long：8バイト符号付き整数
      - Float：4バイト浮動小数点数
      - Double:8バイト浮動小数点数
      - Boolean：真または偽の二値をとる型
      - Unit：何も返すものがないことを表す型(Javaだとvoid)
  - AnyRef：いわゆる参照型のスーパータイプ
      - StringやList、ユーザの定義したクラス
      - Null：すべての参照型のサブタイプ
  - Nothing：すべての方のサブタイプ

つらつら書きましたが、見慣れているのが
Byte、Short、Char、Int、Long、Float、Double、Boolean、Stringあたりかなと思います。
図？で書くと、
ーーーーー
Any
┣━━━━━━━━━━━━━━━━━━━━━━━━┓
AnyVal &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AnyRef
┣━━┳━━┳━┳━┳━━┳━┳━━┳━━┓　　　┣━┳━┓
Double Float Long Int Short Byte Unit Boolean Char　String List MyClass
┣━━┻━━┻━┻━┻━━┻━┻━━┻━━┛　　　┣━┻━┛
┃　　　　　　　　　　　　　　　　　　　　　　　　 Null
┣━━━━━━━━━━━━━━━━━━━━━━━━┛
Nothing
ーーーーー
こんな感じらしいです。

## 終わり
見慣れないAny、AnyVal、Unit、Nothingが出てきました。
次回は、実際に手を動かしながら基本的なことをやっていけたらなと！
今学習に使わせていただいているのが、
■実践Scala入門
https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Scala%E5%85%A5%E9%96%80-%E7%80%AC%E8%89%AF-%E5%92%8C%E5%BC%98/dp/4297101416/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=scala&qid=1557061726&s=gateway&sr=8-1
になります！
本番環境だとログインができず、詰まった点。

#portfolio作成で詰まった点。

FW:Rails　DB:Postgresql

大方の機能が実装できたので、
試しにproduction環境で動かしてみようと思い
`bin/rails server --environment production`とすると、
画面はきちんと表示されるがログイン画面から一向に切り替わらない！

`bin/rails s`だと、
ログインもできるし、投稿もできるのになぜ・・・と詰まりに詰まりまくりました。

調べつつ、自分でもどうしてログインできないのかと考えていると
production環境だとユーザー情報がない・・・？という考えになりました。

そこで productionサーバーでの初期データの投入ができないか
調べて見た所、
`seed.rb`にデータを記載し直し
本番サーバーで
`$ bin/rails db:seed RAILS_ENV=production`
としたらできました！

ひとまずこれで、本番環境ログインできない問題はクリア！

反省点としては、
ここに気づくのが遅くほとんどの時間を費やしてしまったことです。

良かった点としては、
ネットで調べまくったけれど原因が分からず
原因を自身で考えることができた点です。（とはいえ時間はかかっているので反省点のが大です！）


エラー解決できたときのすっきり感はなんとも言えないなぁ