OmniAICreator/Qiita-1.07M huggingface dataset:
シングル構成のelasticsearchでnetwork.hostを設定すると起動しない（development modeとproduction mode ）

#やりたいこと
ちょっとしたDBとしてelasticsearchをシングル構成で使いたい。
elasticsearchは別サーバのGrafanaからアクセスするので、
localhost以外からアクセスできるようにしたい。

ところが、elasticsearchの設定をしていると、起動しなくなった。
原因が分かるまでそこそこはまった話。

#elasticsearchがnetwork.hostを設定すると起動しない
いろいろ設定を試したところ、
elasticsearchをlocalhost以外からもアクセスできるようにするnetwork.hostを設定すると、起動しなくなった。

理由は公式ページにあった。
https://www.elastic.co/guide/en/elasticsearch/reference/current/system-config.html#dev-vs-prod

elasticsearchはnetwork.hostを設定すると、
development modeからproduction modeになり、安全のためにシングルのノードは起動しないようになるということらしい。

じゃあ、どうすればいいか？
これも公式に書いてあった。

#シングル構成で起動する設定
下記の設定を追記すればOK。
network.hostの設定も不要。

```/etc/elasticsearch/elasticsearch.yml
discovery.type: single-node
```

公式のリンク
https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
https://discuss.elastic.co/t/elasticsearch-5-6-installation-single-node/118549
'could not dequeue a view of kind: UICollectionElementKindCell with identifier hogeCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'[Swift]


# 概要
`CollectionView`を使ったViewControllerに遷移しようとしたら

```
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier recipesCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
```

# 

# 対策


# 参考
**・[Xcode - TableViewを表示できない｜teratail](https://teratail.com/questions/88166)**


# segueで別のやつ
VCから引っ張るんじゃなくてUIから引っ張るとめんどいことになるから気をつけて
segueはVC間で繋いで
idだけ指定して
遷移させたいタイミングで`performSegue`を書けばいい（この時idを指定する）
nodejsプロジェクトをgulpでDropboxにバックアップする

## 要約
nodejsを使った開発環境で**バージョン管理**じゃなくて**単なるバックアップ**としてソースコードを管理する方法を検討しました。

※この記事の対象読者：
nodejsのプロジェクトでタスク管理にgulpを利用している人で、バージョン管理以外でバックアップとしてソースコード管理をしたい人

**問題点**  

* node_modulesとか.gitとかdistとかを同期したくない
* 主要なクラウドサービス（Dropbox, GoogleDrive, iCloud）は特定のファイル・ディレクトリを同期から除外するための設定が若干めんどくさい、または存在しない。



**解決方法**

* gulpを利用してビルドのたびにバックアップディレクトリにソースファイルをコピーする。
* 基本的にプロジェクト全体をバックアップするが、gulpの設定で特定のディレクトリはコピーの対象から外す。


## 背景
昨日SSDが逝きました。

リモートリポジトリにはまだpushしてなかったコード達がお亡くなりになりました。
バージョン管理とバックアップは別物なんだなぁ　
　　　　　　　　　　　　　　　　　　　みつを
本当にありがとうございました。

（主にMacを使ってるので）昔はTimeMachineでバックアップを取ってたのですが、NASが壊れたのを機にそのまま放置してしました・・・。

自前でバックアップとるのはもう嫌なので、手軽にクラウドでバックアップを取る方法を調べて検討したのでメモします。

本当はもっと賢い方法があるのでしょうが、わからないので誰かご存じでしたら教えていただけると助かります・・・。

## 従来手法？

### Dropbox

**.gitignoreっ的なもので制御**
dbignoreというOSSがあるけどMacしか対応してない（多分）。
（たまにWindowsも使うんじゃ・・・T^T）
http://konolige.com/dbignore/

公式も「たくさん要望あるけどまだ作れてござらん」っておっしゃってる?
https://www.dropboxforum.com/t5/Files-folders/Exclude-specific-folder-names-with-Smart-Sync/td-p/289837

**GUIで制御**
selective syncという設定をすることで、ディレクトリを一つ一つ同期するかしないかを選択できる？らしいけど、これやるとローカルからディレクトリが消されるので開発できないorz。重たいファイルを特定のデバイスにダウンロードさせないための機能っぽい。
https://help.dropbox.com/installs-integrations/sync-uploads/selective-sync-overview


### GoogleDrive
**GUIで制御**
drop boxと同じでローカルから削除されるっぽい（未検証）
https://support.google.com/drive/forum/AAAAOxCWsTozRU34aolkdo/?hl=en&gpf=%23!topic%2Fdrive%2FzRU34aolkdo

### iCloud
**ファイル名で制御**
ファイル末尾に.nosync または.tmpをつける。
これは仮にできたとしても、やりたくないので未検証・・・
https://discussions.apple.com/thread/8137146


### OneDrive
ない

「OneDriveの思想はOneDriveの中身すべてを同期させることやぞ」
「特定のディレクトリを除外する機能を作るとしてもNot Right Nowだ」とのこと（2015年）

https://onedrive.uservoice.com/forums/262982-onedrive-archive/suggestions/6988070-use-a-file-to-ignore-exclude-files-or-folder



**従来手法のまとめ**
クロスプラットフォームで簡単に開発中のものをバックアップするような主要なクラウドサービスはない（多分。ほんとか？）。


## 提案手法
Gulp(v4)でビルドするたびにどっかにコピーする。

**下準備**
バックアップディレクトリの定義
（1人/1つの開発マシンしかないならこれをやらずにgulpfile.jsにパスをべた書きでOK。）
mac/linuxだったら単にterminalで、windowsだったらgitbashで下記を.bashrcとかに追記


※gulp
https://gulpjs.com/


```bash
EXPORT backup_directory="/backup/directory"
```

**gulpfile.jsに設定を追加**

``` javascript
var gulp = require('gulp');
var path = require("path");

gulp.task('backup:src', function () {
  return gulp.src([
    './**',                 //コピーしたいファイルのパス
    '!./node_modules/**',   //除外したいパス（先頭に!をつける）
    '!./dist/**',           //同上
    '!./.git'               //同上
  ])
 .pipe(gulp.dest(process.env.backup_directory+'/'+path.basename(__dirname)));
 //back_updirectory/projectname配下にバックアップ
});

gulp.task('default', gulp.series(
    //ほかのタスク：コンパイルとかデプロイとか
    'backup:src',
    //...
  )
);
```

**タスクを実行**

```bash
npx gulp
```


**結果**
![結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439355/8ba30ae6-bd47-0184-0111-a0cc1191addd.png)
Mac死んでるからWindowsで検証してる・・・orz



### 結論
gulpを使えば、ビルドの度に手軽にソースコードをDropboxにバックアップでき、node_modulesなどは除外できました。多分他のクラウドサービスも同じように実行できると思います。

### まとめと感想
初めてQiita記事を書いてみました。
間違いなどあれば、ご指摘いただけると助かります。

本当に簡単にソースコードバックアップできるサービスないのかな。。。

Javaとか他の開発環境には適用できないし、いっそすべての言語のプロジェクトをGulpでタスク管理するか・・・。と思ったけどそれは違う気がする。
最長増加部分列とlca

chokudai今日の一問　ABC006 D トランプ挿入ソート
言い換えるとN-最長増加部分列の長さを求めよってことだけど最長増加部分列の長さを求めるので詰まったから整理したい。
左から順番に、最後にそのカードを使った時の最大の列の長さはいくつかを計算していく。次の値は前の値を利用して最大値から計算していく
この場合のソースは以下となる

```c++

int main() {
	int N; cin >> N;
	int c[30010];
	int dp[30010];//dp[i]でaiを最後の要素とする増加部分列の最大の長さ
	int res = 0;
	for (int i = 0; i < N; ++i)cin >> c[i];
	for (int i = 0; i < N; ++i) {
		dp[i] = 1;
		for (int j = 0; j < i; ++j) {
			if (c[j] < c[i]) {
				dp[i] = max(dp[i], dp[j] + 1);
			}
		}
		res = max(res, dp[i]);
	}
	cout << N-res << endl;
	return 0;
}
```
また、dp[i] := i+1の部分列の最後の要素となる最小の値とする方法もある

```c++

int main() {
	int N; cin >> N;
	int c[30010];
	int dp[30010];//dp[i]:=i+1の部分列の最後の要素となる最小の値
	fill(dp, dp + N, INF);
	int res = 1;
	for (int i = 0; i < N; ++i)cin >> c[i];
	for (int j = 0; j < N; ++j) {
		for (int i = 0; i <= j; ++i) {
			if (i == 0 || dp[i - 1] < c[j]) {
				dp[i] = min(dp[i], c[j]);
				res = max(res, i + 1);
			}
		}
	}
	cout << N-res << endl;
	return 0;
}
```


これらだと計算が間に合わないので計算を早くするよう工夫する必要がある（c++なら普通に通ったけど)
ここまで出てきた中でk枚の部分列が作れるもののうち、最もカードの値が小さいものを持つ
このときdp配列は単調増加である。よって二分探索で値を埋めていくことができる

```c++

int main() {
	int N; cin >> N;
	int c[30010];
	for (int i = 0; i < N; ++i)cin >> c[i];
	int dp[30010];//dp[i]:=i+1の部分列の最後の要素となる最小の値
	fill(dp, dp + N, INF);
	for (int i = 0; i < N; ++i) {
		*lower_bound(dp, dp + N, c[i]) = c[i];
	}
	cout << N - (lower_bound(dp, dp + N, INF) - dp) << endl;
	return 0;
}
```
こんなかんじで

abc134 eでは単調減少部分列の最大長を求める。(dilworthの定理よりDAGの最小パス被膜＝DAGの最大反鎖)

pastのl問題でlcaを求めるのに帰着する。
lca:2頂点が共通して持つ最近祖先
蟻本写経した

```c++

//前処理　dfsなどによってすべての頂点について根からの距離と親を求めるダブリングなどによって
//2^k先の祖先を求める
//クエリuとvの深い方の頂点を変更してxまでの距離が同じ点u1,v1にする
//条件C(d):u1とv1からd遡った点は共通祖先かを満たす最小のdを二分探索で見つける
//u1またはv1からd先の祖先が最近共通祖先xとなる
Graph G;;//グラフの隣接リスト表現
int root;
int parent[20][150010];//親を2^k回辿って到達する頂点（根を通り過ぎるなら-1)
int depth[150010];//根からの深さ
void dfs(int v, int p, int d) {
	parent[0][v] = p;
	depth[v] = d;
	for (int i = 0; i < G[v].size(); ++i) {
		if (G[v][i] != p)dfs(G[v][i], v, d + 1);
	}
}
void init(int V) {
	dfs(root, -1, 0);
	//parentを初期化する
	for (int k = 0; k + 1 < 20; ++k) {
		for (int v = 0; v < V; ++v) {
			if (parent[k][v] < 0)parent[k + 1][v] = -1;
			else parent[k + 1][v] = parent[k][parent[k][v]];
		}
	}
}
//uとvのLCAを求める
int lca(int u, int v) {
	if (depth[u] > depth[v])swap(u, v);
	for (int k = 0; k < 20; ++k) {
		if ((depth[v] - depth[u]) >> k & 1) {
			v = parent[k][v];
		}
	}
	if (u == v)return u;
	//二分探索でLCAを求める
	for (int k = 19; k >= 0; --k) {
		if (parent[k][u] != parent[k][v]) {
			u = parent[k][u];
			v = parent[k][v];
		}
	}
	return parent[0][u];
}
int main() {
	int n, q;
	cin >> n;
	G.resize(n);
	REP(i, n) {
		int par; cin >> par;
		if (par != -1) {
			par--;
			G[i].push_back(par);
			G[par].push_back(i);
		}
		else {
			root = i;
		}
	}
	init(n);
	cin >> q;
	REP(i, q) {
		int a, b; cin >> a >> b;
		a--, b--;
		if (b == lca(a, b))cout << "Yes" << endl;
		else cout << "No" << endl;
	}
	return 0;
}
```
鍵の扱い間違ってる説

「sshのログイン、パスワードなの？鍵のほうが楽だし、セキュリティ的にも良いんだよ。」
・・・たしかにそうかも知れない。しかし、秘密鍵をメールで送ったり、Backlogのファイルにあげるなどの運用をしてないでしょうか？
他にも、チームの開発者同士で鍵を共通にしていたり、他案件で同じ鍵を利用していたりしませんでしょうか？
この運用方法は基本間違ってると言いたい！

# 公開鍵と秘密鍵
公開鍵と秘密鍵はペアで作成することができます。
公開鍵からは秘密鍵を作成することができません。
逆に、秘密鍵からは公開鍵を作成することができます。

## 公開鍵
閉めることしかできない鍵と言われたりします。
この鍵は、不特定多数に渡しても、閉めることしかできない＋公開鍵から秘密鍵は作れないので、
セキュリティ上問題ありません。

## 秘密鍵
開けることしかできない鍵と言われたりします。
この鍵は、基本的に複製したり、他の人に渡すことをしてはいけません。
セキュリティリスクが高まります。

# sshログインの仕組み
sshでログインする方法は、パスワードでのログインと鍵によるログインがあります。
鍵のほうがセキュリティが高いと言われていますが、それは正しい鍵の使いをしている場合に言えます。
冒頭のように秘密鍵を複製して色んな人で使いまわしていたり、外部にメールで送信している場合、パスワードとセキュリティレベルはかわらないです。
パスワードのほうがメールで送信する時に気を使う文化がある分ましといえます。

鍵でのログインをざっくり説明すると、まず鍵以外のログイン方法で、サーバに入り、鍵でログインできる設定に変更します。
変更したら、ログインしたいユーザのホームディレクトリの下に `.ssh` ディレクトリをつくります。
ディレクトリをつくったら `.ssh/authorized_keys` というファイルをつくります。
このファイルに公開鍵の文字列を書き込みます。
`.ssh` を `700` 、 `.ssh/authrized_keys` を `600` にパーミッションを設定します。
（パーミッションがおかしいとログインできません）
この設定ができたら、`.ssh/authorized_keys` に記述した公開鍵のペアの秘密鍵でログインすることができます。
`.ssh/authorized_keys` には公開鍵を改行区切りで複数記述することができます。
※ 複数記述できるのがポイント

# 正しい運用方法
## 家に例える
サーバを家に例えます。
秘密鍵は家の鍵、公開鍵は家の鍵穴付きのドアと言えます。
この鍵穴は中から開けることができなくて、オートロックであるものをイメージしてください。
秘密鍵を複製して複数人で使うのは、家の鍵の合鍵を作って渡すイメージです。

普通の家だと合鍵を作る発想が一般的ですよね。
この発想があるので間違った運用をしてしまう人が多いんだと思います。

## 間違った運用
メールで鍵を送信するのは、合鍵を郵便で送るイメージです。
この配布方法だと、悪意ある第三者に途中で合鍵を見られて型をとられて同じ鍵を作られる恐れがあります。
Backlogに鍵をアップロードするのは、パスワードロック付きのロッカーに鍵を入れておくみたいなイメージでしょうか。
この方法だと、パスワードがばれてしまうと、鍵を盗られてしまいます。
違うサーバで同じ鍵でログインできるようにするのは、違う家に同じ鍵穴のドアを設置しているイメージです。怖いですね。
そもそも合鍵を作る行為自体、紛失のリスクが高まります。
また、複数人に同じ鍵を配布しているので、誰が家に入ったのかわからなくなってしまい良くないです。
悪意ある人が家に侵入したと思われて、今後の侵入を防ぎたい場合、鍵の作り直しとドアの付替が発生します。
そうすると、悪意のない正しい人まで全員家に入れなくなってしまいます。

## じゃあどうするの？
合鍵をつくらなければ良いんです。
sshの正しい運用方法は、家に入りたい人がいたら、その人自身で新しい秘密鍵と公開鍵、つまり、家の鍵と家の鍵穴付きのドアを作ってもらいます。
つぎに家の持ち主（サーバ管理者）に家の鍵穴付きのドア（公開鍵）を渡して、家に設置してもらいます。
設置してもらったら、自分の鍵で家に入ることができます。
この方法だと、秘密鍵の合鍵をつくったり、秘密鍵をネット上にさらす必要がなくなります。
家の鍵穴付きのドアは第三者に見られても全く問題ありません。
勝手に複製されて、どこかの家に取り付けられたとしても、自分以外鍵を持っていないので自分以外は入れません。
これによってセキュリティが向上します。
この方法でもユーザが勝手に合鍵をつくって第三者に渡してしまうリスクはあるので、不正ログインを完全に防ぐことはできません。
ただ発覚後は、不正にログインされているドアのみ取り外せば、ほかのユーザまでログインできなくなってしまうことはありません。

鍵と家の発想だと、違う鍵穴のドアを複数設置する発想がないので、この運用方法を知らないという人が多いのかもしれません。

## 邪道
秘密鍵を厳重に扱い、極力ネットワーク経由の配布をせずに共有する方法があります。
これだと第三者に鍵を見られるリスクは少ないので大丈夫だと思います。
合鍵を信頼できる人に手渡しするイメージです。

# 最後に
公開鍵と秘密鍵の扱いについて書きました。
これを知った上で、あえて利便性を考えて、邪道な方法で鍵共通にする。
なにかあればサーバ管理者が責任取るというなら運用上問題ないかと思います。
とりあえず、鍵だったら最強！安心！って思うのだけはやめましょう。
正規表現

パターンの記述方法

/ /で囲む必要がある
[a-z] 角括弧内で囲まれた文字のいずれか１個にマッチ
\d 数字にマッチ
{n,m} 直前の文字数が少なくともn回からm回の間でのマッチ
. どの1文字にもマッチ
+ 直前の文字の１回以上の繰り返しのマッチ

メールアドレスのドメインを取得する方法

```
  mail = www@gmail.com
  mail.match(/@+./)
  =>#<MatchData "@gmail.com">
```
logstashでMultiple Pipelinesを使わずにコンフィグを分割し、サービス起動する方法

#やりたいこと
logstashで様々なファイルをelasticsearchに取り込む仕組みを作るにあたって、
可読性のためにコンフィグファイルを分割したい。

logstashのバージョンが6.0以降だと、
下記のリンクのようにMultiple Pipelinesが使えるが、
当方の環境は、5.6なのでMultiple Pipelinesを使わずにやってみた。

方法としては下記リンクに、
「これを5.xで解決しようとすると、ファイルを分けて、logstashのインスタンスを分けて実行する手立てがありました」とあるので、コンフィグを分けてサービス起動すればよいと考えた。

参考リンク：https://qiita.com/tsgkdt/items/3e7f07ca963676b37718

#考慮したポイント
上記のリンクではサービス起動の方法は書いてはいないので、下記を参考にした。

- ユニット定義ファイルについて：https://qiita.com/migo/items/21767287dba0f0ee43fd
- logstashの起動ユーザーが"logstash"なことと、アクセス権限：http://atsuizo.hatenadiary.jp/entry/2017/09/13/093018
- 複数のlogstashサービスを起動したときに、"path.data"のエラーが出る：https://www.mtioutput.com/entry/2019/02/19/180000

#ユニット定義ファイルの作成
## インストールと無効化
```
# yum install logstash
###すでに起動している場合は、下記で無効化###
# systemctl stop logstash.service 
# systemctl disable logstash.service 
```
## ユニット定義ファイル作成
###①元になるユニット定義をコピーで作成
```
# cp -p /etc/systemd/system/logstash.service /etc/systemd/system/logstash_hoge.service
```
###②path.data用のディレクトリ作成
```
# mkdir /etc/logstash/logstash_hoge
```
###ユニット定義ファイル
```
# vi /etc/systemd/system/logstash_hoge.service
```
以下を修正
- Descriptionの修正
- UserとGroupをlogstash→rootに変更
- ExecStartの末尾に「--path.data /etc/logstash/logstash_hoge」を追加

```
[Unit]
Description=logstash_hoge

[Service]
Type=simple
User=root
Group=root
# Load env vars from /etc/default/ and /etc/sysconfig/ if they exist.
# Prefixing the path with '-' makes it try to load, but if the file doesn't
# exist, it continues onward.
EnvironmentFile=-/etc/default/logstash
EnvironmentFile=-/etc/sysconfig/logstash
ExecStart=/usr/share/logstash/bin/logstash "--path.settings" "/etc/logstash" --path.data /etc/logstash/logstash_hoge
Restart=always
WorkingDirectory=/
Nice=19
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target
```

#サービス登録
```
# systemctl enable logstash_hoge.service
# systemctl start logstash_hoge.service
```
Macのコマンドラインで簡単パスワード生成 & クリップボードコピー

### はじめに
最近では大分少なくなりましたが、メールにファイルを添付してデータを送らざるをえない時が未だにあります。
そういう時、パスワード付きのZIPファイルを添付して送付していますが、パスワード付きZIPファイルの生成にランダムなパスワードが欲しくなります。

これまではWebサイトのパスワードジェネレータ等を使ってパスワード生成していましたが、ちょっとしたことですが、Webにアクセスして表示されたパスワードをコピーして...というのが地味に手間。

次の方法で、Macのコマンドラインからパスワードの生成、クリップボードへのコピーまで行うことができます。

### 導入(pwgen)
```
$ brew install pwgen
```

### 使い方
#### ▶10文字記号なしのパスワードを1つ生成
```
$ pwgen 10 1 -s
AzB9nC8gjH
```
#### ▶▶10文字記号なしのパスワードを1つ生成 → クリップボードにコピー
```
$ pwgen 10 1 -s | pbcopy
```
#### ▶▶▶10文字記号なしのパスワードを1つ生成 → クリップボードにコピー → クリップボードの内容出力
```
$ pwgen 10 1 -s | pbcopy ; pbpaste
AzB9nC8gjH
```

※ pwgen の使い方、指定可能なオプションに関しては、下記の記事で紹介されていましたのでそちらを参照してください。

### 参考にさせていただきました
https://qiita.com/speg03/items/ec404c217e417160e2d5
https://qiita.com/icedpasta1832/items/57d0d9805f04b6e79875
【HTML5】文字にふりがな・注釈をつける<ruby>,<rt>,<rp>

# この記事について
HTML5でのふりがな・注釈の付け方をさらっとまとめています。
各タグの詳細は、最下部の**「参照URL」**を参考にしてください。

# `<ruby>,<rt>`で文字にふりがな・注釈をつける

下記のソースのようにふりがなを付けたい箇所を`<ruby>`タグで囲み、
ふりがな・注釈となる箇所については`<rt>`タグで囲みます。

### ソース

```html:ruby.html
<ruby>Qiita<rt>キータ</rt></ruby>

<hr>

ペンギンが<ruby>学<rt>がく</rt>習<rt>しゅう</rt></ruby>する
```

### 実際の表示


<ruby>Qiita<rt>キータ</rt></ruby>

<hr>

ペンギンが<ruby>学<rt>がく</rt>習<rt>しゅう</rt></ruby>する

# `ruby`とは

ふりがなや注釈のことを英語で[ruby](https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%93)と言います。
日本語で「ルビをふる」という表現をすることもあります。

# `<rt>`タグについて

Edgeについては`<rt>`タグが未対応なため、
上記のふりがなについては下記のように表示されるかもしれません。
こちらについては筆者自身で試してはおらず、
[MDNのサイト](https://developer.mozilla.org/ja/docs/Web/HTML/Element/rt)を参照しています。

Qiita キータ

<hr>

ペンギンが学 がく 習 しゅうする

# `<rp>`タグについて

今まで登場してきていませんが、`<rp>`タグというタグもあります。
こちらは、上記の`<rt>'タグが使えないEdgeでルビを表示する時に
ふりがなだとわかるような形で表示するために使用します。
具体的には下記のように使用します。

### ソース

```html:ruby.html
<ruby>Qiita<rp>(</rp><rt>キータ</rt><rp>)</rp></ruby>
```

### 実際の表示

**Edge以外の場合**

<ruby>Qiita<rt>キータ</rt></ruby>

**Edgeの場合**
&nbsp;&nbsp;※下記のように表示されるかもしれません

Qiita(キータ)



# 参照URL
- [`<ruby>`タグについて | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/ruby)
- [`<rt>`タグについて | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/rt)
- [`<rp>`タグについて | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Element/rp)
XFREEのサーバ(Mysql)にVisualStudioから接続したい。(失敗) [メモ]

##XFREEのサーバ(Mysql)にVisualStudioから接続したい。 [メモ]自分メモです。
##まえおき。
講義内でローカルのmysqlに接続する方法は習っていたが外部サーバに接続する方法が全く分からなかった。卒業研究でも必要なためメモ用にまとめる。
##開発環境
Visualstudio2017

##参考サイト
wp-config.phpに指定する「MySQL のホスト名」とは
https://www.nishi2002.com/4123.html
(ホスト名といいう単語がわからなかった。)

##実践
今回は接続の確認のみなのでopen,closeできることを確認する。
接続にはMySQL Connector/NETを使用する。
![ConnectionTest - Microsoft Visual Studio  2019_08_28 0_10_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488436/ab0d68bb-8939-9a03-00b2-15d9daf653e4.png)

```form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using System.Diagnostics;
using System.IO;

namespace ConnectionTest
{
    public partial class Form1 : Form
    {
        MySqlConnection connection = new MySqlConnection();
        MySqlCommand command = new MySqlCommand();
        public Form1()
        {
            InitializeComponent();
            connection.ConnectionString = "server = *********; user id = *************; password = ********; persistsecurityinfo = True; database = ********";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            connection.Open();
            Console.WriteLine("Open");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            connection.Close();
            Console.WriteLine("Close");
        }
    }
}

```


##結果
無理だった。タイムアウトで弾かれ調べた結果以下のものを見つけました。
[レンタルサーバーのデータベースに外部から接続できません。]https://teratail.com/questions/152035
知識不足でした。
VPS借りてやってみます。

##追記2019/09/18
使っているlocalのmysqlserverと外部にあるmysqlserverのバージョンが違う可能性があった。
自身はその後VPSを借りLinuxの中にMysqlserverを入れ、バージョンを合わせることで接続に成功した。
PostgreSQLのコンパイルやリグレッションテストにかかる時間の計測

## はじめに

8年近く使い続けていたノートPCを最近ようやく買い換えました。
せっかくなので、この新旧ノートPCで、PostgreSQLのコンパイルやリグレッションテストにかかる時間がどれぐらい違うのか確認したいと思います！

## 時間計測対象のノートPCのスペック

新旧ノートPCのスペックは以下のとおりです。
古いノートPCについては、購入から約8年間使い続けたものです。

|   | 古いノートPC | 新しいノートPC |
|---|---|---|
| モデル | MacBook Air (13-inch, Mid 2011) | MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports) |
| プロセッサ | 1.7 GHz デュアルコア Intel Core i5 (i5-2557M) | 2.4 GHz クアッドコア Intel Core i5 (i5-8279U) |
| メモリ | 4GB 1,333MHz DDR3 | 16GB 2,133MHz LPDDR3 |
| ストレージ | 128GB SSD | 512GB SSD |
| OS | macOS High Sierra バージョン10.13.6 | macOS Mojave バージョン10.14.6 |

## 時間計測の前提条件

- コンパイルやリグレッションテストの時間計測には、[PostgreSQL 11.5](https://www.postgresql.org/ftp/source/v11.5/)を利用します。
- 実行時間はtimeコマンドで計測します。
- コンパイル及びリグレッションテストのmakeコマンドでは、同時実行数(-jオプションの指定値)を1、2、4、8、10と変化させます。[^1]

[^1]: 同時実行数を12、16としたとき、リグレッションテストがサスペンド状態に陥り、makeコマンドが完了しなかったため、今回は同時実行数10の計測結果まで採用します。

## コンパイル時間の計測結果

下記コマンドの実行時間をコンパイル時間として計測します。

```bash
$ ./configure --enable-debug --enable-cassert --with-libxml --enable-tap-tests
$ make -j ?? -s install
```

計測結果は以下のとおりです。

| コマンド | 古いノートPC | 新しいノートPC |
|------------|--:|---:|
| configure  | 59.6 s | 43.0 s |
| make -j 1  | 7 m  8.2 s | 3 m 47.9 s |
| make -j 2  | 3 m 58.8 s | 2 m  7.0 s |
| make -j 4  | 3 m 19.6 s | 1 m 21.1 s |
| make -j 8  | 3 m 22.1 s | 1 m 11.9 s |
| make -j 10 | 3 m 33.8 s | 1 m 11.3 s |

## リグレッションテスト時間の計測結果

下記コマンドの実行時間をリグレッションテスト時間として計測します。

```bash
$ make -j ?? -s check-world
```

計測結果は以下のとおりです。

| コマンド | 古いノートPC | 新しいノートPC |
|------------|--:|---:|
| make -j 1  | 31 m 53.8 s | 22 m 2.1 s |
| make -j 2  | 18 m 26.1 s | 13 m 4.0 s |
| make -j 4  | 16 m 17.0 s | 7 m 36.1 s |
| make -j 8  | 14 m 18.7 s | 5 m  0.7 s |
| make -j 10 | 15 m 19.2 s | 4 m 44.8 s |

## 【付録】 tarボール解凍時間とTAGSファイル作成時間の計測結果

下記コマンドの実行時間をtarボールの解凍時間とEmacsのTAGSファイル作成時間として計測します。

```bash
$ tar jxf postgresql-11.5.tar.bz2
$ cd postgresql-11.5
$ src/tools/make_etags
```

計測結果は以下のとおりです。

| コマンド | 古いノートPC | 新しいノートPC |
|---|--:|--:|
| tar jxf | 9.0 s | 6.2 s |
| make_etags | 13.5 s | 7.4 s |
zshでURLコピペ時にバックスラッシュ補完が効くのをやめさせる

## misc.zshの特定部分をコメントアウトする

autoload,zleと書いてある部分をコメントアウトすればOK。(自分のターミナルからコピペしたのでいらない文字が混ざってます)
zshの場合、コメントアウトは半角シャープでOKです。

```zsh:~/.oh-my-zsh/lib/misc.zsh
  3 # *-magic is known buggy in some versions; disable if so
  4 if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then
  5   for d in $fpath; do
  6   ▸-if [[ -e "$d/url-quote-magic" ]]; then
  7   ▸-▸-if is-at-least 5.1; then
  8 #  ▸▸-▸-autoload -Uz bracketed-paste-magic
  9 #  ▸▸-▸-zle -N bracketed-paste bracketed-paste-magic
 10   ▸-▸-fi
 11 #  ▸▸-autoload -Uz url-quote-magic
 12 #  ▸▸-zle -N self-insert url-quote-magic
 13       break
 14   ▸-fi
 15   done
 16 fi
```

## ターミナル再起動し、URLをコピペしてバクスラが入らないことを確認

## 参考

[How to disable magic plugins · Issue #5569 · robbyrussell/oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh/issues/5569)
Github GraphQL APIでコミット数を取得する

# version
Github GraphQl API v4 (doc: https://developer.github.com/v4/)

とりあえずガイドを読むと動きがわかる: https://developer.github.com/v4/guides/
また試すときは https://developer.github.com/v4/explorer/ で実行する

# あるRepositoryに対する総コミット数の取得
```
query ($owner:String!, $name:String!, $since:GitTimestamp!, $until:GitTimestamp!) {
  repository(owner: $owner, name: $name) {
    nameWithOwner
    defaultBranchRef {
      name,
      target {
        ... on Commit {
          history(since: $since, until: $until) {
            totalCount # そのブランチに対する総コミット数
          }
        }
      }
    }
  }
}

variables {
  "owner": "username", # githubアカウント名
  "name": "project", # project名
  "since": "2019-08-01T00:00:00",
  "until": "2019-08-02T00:00:00"
}
```

Repositoryに注目するとあるブランチ（ここではデフォルトブランチ）の総コミット数を取得することができる。このときsince/untilを指定することで日付の範囲指定が可能（ISO-8601形式: https://developer.github.com/v4/scalar/gittimestamp/ ）。

# あるUserが行った総コミット数の取得
```
query ($name: String!, $from: DateTime!, $to: DateTime!) {
  user(login: $name) {
    name
    email
    contributionsCollection(from: $from, to: $to) {
      totalRepositoryContributions # コミットしたレポジトリの数
      totalCommitContributions # コミットした全レポジトリに対する総コミット数
      commitContributionsByRepository { # レポジトリ毎の情報
        repository {
          nameWithOwner
        }
        contributions {
          totalCount
        }
      }
    }
  }
}

variables {
  "name": "username", # githubアカウント名
  "from":"2019-08-01T00:00:00",
  "to":"2019-09-01T00:00:00"  
}
```

Repositoryではなくuserに注目すると、contributionsCollectionを辿ることでそのuserが行ったコミット数の情報が取得できる (https://developer.github.com/v4/object/contributionscollection/ )。

このときの日付の範囲指定はsince/untilではなくfrom/toで指定する（実は型が違うがこれもISO-8601形式: https://developer.github.com/v4/scalar/datetime/ ）。

# git shortlog的な情報は取得できない
documentを探してみたが、git shortlogで取得できるような情報（"あるrepositoryに対するuser毎のコミット数の一覧"）に対応するAPIはない模様。どうしてもcloneしたくないならコミットの一覧から自分で計算する。
【気をつけるメモ】Vuejs+Laravelで初心者が気をつけること


都度気になることがあれば更新する。

# Vuejs

## 1. $setを使わないと値が反映されない場合あり

配列やオブジェクトの変更は検知できない。これ結構ハマった。
普通に値セットしたら変更されるんじゃないの？って思ったけど、vueではそうじゃないので注意。


```
#普通に反映されないヤーツ
this.hogeObject.value = 'hoge-text'
#ちゃんと反映されるヤーツ
this.$set(this.hogeObject, 'value', 'hoge-Value')
#配列の場合の反映されるヤーツ
this.$set(this.hogeObject[index], 'value', 'hoge-Value')
```


# Laravel

## 1. キャッシュクリアしてないで反映されないヤーツ

いろんなところにキャッシュがあるので、ここクリアしないと変更されないってこともある。

```
composer dump-autoload

php artisan clear-compiled

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan config:cache
```


キーがないなら作り直す

```
php artisan key:generate
```

## 2.マイグレーションについて


上から順に実行していくやつなので、一部のマイグレーションファイルを適応する指定はできない。


- ファイル削除するとnot foundエラーになる

migrationsテーブルに残ってるので、dropしてmigrateし直せばいい。



### 3.一旦ログアウトしないと反映されない

Laravel自体を再ログインしないと修正した内容が反映されないことあり。
ただログインし直すだけでいい。


##　便利ぽいやつ1：カスタムバリデーション

バリデーション処理を自分なりにカスタムできる。




## LaravelがDBに繋がってるか確認する

データがあってることを確認すると良い。

```
DB::select('select 1');
or
DB::select('select * from `hoge`');
```


# 参考

https://cloudpack.media/41984
https://ti-tomo-knowledge.hatenablog.com/entry/2018/07/09/163051


- 良さげなサイト    

リトラボ。いい感じでまとまってる。
https://www.ritolab.com/category/PHP/Laravel
ヤクザ。名前が良い。
https://dev-yakuza.github.io/laravel/


キャッシュ系
https://qiita.com/Ping/items/10ada8d069e13d729701
カスタムバリデーション
https://qiita.com/sakuraya/items/abca057a424fa9b5a187
https://tac-blog.tech/index.php/2018/09/08/add-validation-rule/
https://qiita.com/komatzz/items/c64c83a004b7f2c63ce6
https://qiita.com/ytake/items/60c772ca52fb868a5cbd
bundle install時にnokogiriエラー(nokogiriのバージョン1.10.4)

Railsで新しいプロジェクトを作ろうと、
`bundle install —path vendor/bundle`
を実行した際に、nokogiriのインストールでエラーが発生しました。

# 環境
`$ brew --version`
Homebrew 2.1.10
Homebrew/homebrew-core (git revision ea340; last commit 2019-08-20)
`$ ruby --version`
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
`$ gem --version`
3.0.3

#エラーメッセージ
エラーメッセージの中から原因と対処法が記された部分を抜粋します。

```bash

IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxslt-1.1.33
with the following patches applied:
	- 0001-Fix-security-framework-bypass.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install
```

#対処法
Nokogiriのインストールに必要なlibxml2ライブラリというものがNokogiriの中に同梱されているのですが、これをsystem内にあるlibmxl2を利用するように設定するとうまくいくとのことです。
今回はbundleを使ってインストールするので、下記のコマンドでうまくいきました。

```bash
$ bundle config build.nokogiri --use-system-libraries
$ bundle install —path vendor/bundle
```

#まとめ
どうやら古より伝わるエラーらしく、様々な対処法がネットで報告されています。
再発率の高い厄介なエラーですね…

今回はエラーメッセージに対処法がそのまま載っていました。ググることも大事ですが、その前にエラーメッセージや公式リファレンスに目を通すことが大事ですね。
【mac】mysql8.0+Laravel5.5



mysql8.0の時はログイン認証機能がcaching_sha2_passwordになってる。
laravelでは対応してないので、mysql_native_passwordの認証方式に戻す。


```
brew install mysql
brew services start mysql
```


```
echo 'export PATH="/usr/local/opt/mysql/bin:$PATH"' >> ~/.bashrc
```


mysql_secure_installation

メモ

```
y
password
y
y
y
y
```


```
mysql -uroot -p

mysql -u default -p
```

rootは何かつけてください。
defaultのpassはsecret。



```
mysql -uroot -p
select user, host, plugin from mysql.user;

# プラグインを変更する
# caching_sha2_password から mysql_native_password に変更する

ALTER USER 'default'@'localhost' IDENTIFIED WITH mysql_native_password BY 'secret';

ALTER USER 'mysql.session'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

ALTER USER 'mysql.sys'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';


#反映
FLUSH PRIVILEGES;



exit
```


```
/usr/local/etc/my.cnf
```

変更

```
[mysqld]
default-authentication-plugin = mysql_native_password

```


```
mysql.server restart
```

データベース作る例。``をつけないと動かないこともある。


```
create database `default`;
or 
create database `default` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
```

## 照合順序

utf8mb4_unicode_ciからutf8_general_ciに変更しないと全角半角が同じものとして扱われる。


# laradock設定




```:dockerコンテナ
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=33063
DB_DATABASE=dbname
DB_USERNAME=user
DB_PASSWORD=pass
```


```:aws
DB_CONNECTION=mysql
DB_HOST=xxxxx.rds.amazonaws.com
DB_PORT=33063
DB_DATABASE=dbname
DB_USERNAME=user
DB_PASSWORD=pass
```

# 参考



mac Laravel環境構築
https://qiita.com/yoshinyan/items/38bc4e4a02a66acead91

MySQL8.0 認証方式を変更する(Laravel5)
https://qiita.com/ucan-lab/items/3ae911b7e13287a5b917
意識の整理を超簡単に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258501/460329ca-a32c-7b2a-8f21-064319a8e41f.png)

#まとめ
これを見て
単純に
①人間は死なない、ただし、死んだ、死んでないと計るとその確率が分かるだけで
でもその情報は哲学な意識の存在を計ることは出来ないことになる。人間は情報として分からない。
②死んでない本人しか分からないし、**「人間はアルゴリズムが演技したものに過ぎない」**だから、どの記憶も
本当の記憶はご存じしてないし、色んな意識がとある時には一つの意識と機能している
と整理出来る

**まとめると**
①人間は確率でしかわからないけど計る概念が哲学すぎて人間は情報として分からないもの
②人はアルゴリズムが演技したものに過ぎない

ここで言うおうとしてる答えは、**「人間はアルゴリズムが演技したものに過ぎない」**だから、
死と死んでない状態はそもそも人間に存在してないこと。**人間は機械**ということ
それ以上以下もない。
簡単にhttps化できる「あ、このテストhttps対応してないとできないテストやん！」って時に使えるものを作りました

# あ、このテストhttps対応してないとできないテストやん！って時に使えるものを作りました
コードをいじりたくない時に使ってください
このレポジトリで見てください
[https://github.com/takashiAg/https_easiest_proxy](https://github.com/takashiAg/https_easiest_proxy)

# 経緯
streamingAPIとか使用する場合、その他テストをするときにhttps対応してないとできなかったりする。
選択肢としては、

- テスト用にhttps対応コードをかく
    - 本番環境へのケースの切り分けが面倒
    - 詳しくやり方がわからない
- Apacheやnginxでリバースプロキシを設定する
    - 証明書の発行
    - httpsに対応するようapacheインストール
    - 設定ファイルの作成

が必要になるますが、面倒ですよね。

``WAN=80 LAN=3000 node proxy.js``と書けば、プロキシとして動作するものを作りました。(bash)


## installation


```
git clone https://github.com/takashiAg/https_easiest_proxy
cd https_easiest_proxy
npm install
openssl genrsa 2048 > mysslserver.key
openssl req -new -key mysslserver.key -subj "/C=JP/ST=Tokyo-to/L=Shibuya/O=Company Name/OU=IT dept./CN=Company Dept CA" > mysslserver.csr
openssl x509 -days 3650 -req -signkey mysslserver.key < mysslserver.csr > mysslserver.crt
openssl pkcs12 -export -inkey mysslserver.key -in mysslserver.crt > mysslserver.pfx
```


## start

```
node proxy.js
```

### change port

```
WAN=80 LAN=3000 node proxy.js
```
○○に似てると言われ困ったので、AIに判定させてみた

#概要

皆さんも一度は○○さん（有名人）に似てると言われたことがあるのではないでしょうか。
私も初対面の人のうち、7回に1回くらいは星○源に似ていると言われることがあります。
自分では似てないと思うのですが、毎回否定するのも面倒なので、
AzureのCustom Visionを使って、AIに定量的に判断してもらうことにしました。

#システム

##構成
・macOS Mojave
・Python 3.6.5
・Custom Vision（Azure）

##概念図
①スクレイピングで画像を集める
②集めた画像を分類する
③AzureのCustom Visionにアップし、学習させる
④自分の画像をアップし、評価を返す

![スクリーンショット 2019-08-28 0.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/f72503f9-28ba-5456-5c57-93d9d6ec7100.png)

#画像収集／スクレイピング
学習用のデータを集めることにします。
[PythonでGoogleの画像を大量スクレープする](https://qiita.com/Jixjia/items/881c03c50c6f07b0b6ab)
こちらを参考に、Pythonで画像をスクレイピング。

```
python scraping.py -s hoshinogen  -n 70
```
scraping.pyで７０枚ほど画像を集めて、複数人で写っている画像や関連性の低い画像は手動で省いていきます。
![スクリーンショット 2019-08-27 23.18.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/3e02c460-4af7-d2a4-0c34-5541f0b9178d.png)

これを繰り返し、同じような系統の顔の有名人の画像をいくつかピックアップします。
塩顔っぽい系統だと思うので、関連性の高い有名人を探します。
高橋一生さん、綾野剛さん、森山未來さん　など。

#Custom Visionを使用
[Custom Vision](https://azure.microsoft.com/ja-jp/services/cognitive-services/custom-vision-service/)

使い方はこのあたりが参考になります。
[Microsoft Custom Vision Service を使用して画像を分類する](https://docs.microsoft.com/ja-jp/learn/modules/classify-images-with-custom-vision-service/index)

##タグ付け
先ほど分類した画像とタグを紐付けて、画像をCustom Visionにアップしていきます。
![スクリーンショット 2019-08-27 23.37.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/1351741b-ec0b-6317-bcde-b58d3a121101.png)

今回は10人ほど有名人ピックアップしています。
スクレイピングした画像を精査した結果、それぞれ50枚程度になりました。

アップが終わったら、右上のボタンからトレーニングさせます。
![スクリーンショット 2019-08-28 0.03.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/00dd6490-2e6b-a469-ea20-b3410c487440.png)

##自分の画像を用意（自撮り）
いよいよ学習させたモデルから自分が似ているかどうかを判定させます。
と、その前に自分の画像を用意しましょう。

カメラデータを確認したが、自分の画像がなかったため急いで自撮りしました。

##結果判定
右上にあるQuick testから自分の画像をアップし、返ってくる評価を確認します。
![スクリーンショット 2019-08-28 0.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/6156b66b-a350-9e20-5be8-23450b31a06b.png)

ローカルファイルをアップしたときの結果がこちら。
![スクリーンショット 2019-08-27 23.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/ec9bdc29-cee8-dcf8-1a80-4025066cbe09.png)

……**星野源75.8％**になりました。

結論、比較的似ていると言えるだろうという温度感ですね。

ちなみにメガネありでやった場合も用意していたのですが、
サンプルデータが少なく高い数字が出たので、ここはもう少し学習精度上げる必要がありそうです。
![スクリーンショット 2019-08-28 0.14.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/34bdb2f2-dbfb-dc55-72de-65aef25a30bb.png)

#まとめ
Azureのサービスを使うのは2回目だが、使いやすかった。
けっこう応用もできそうで捗りそう。

以前、Google Cloud PlatformでNatural Languageを使って、
機械学習（テキスト解析）×LINE Botを作ってみたのでよろしければこちらもどうぞ
[悩める恋心を助けるためのLINE BOTを作ってみた](https://qiita.com/sksk_go/items/9741290060b2bad4abbf)

番外編
[AIに自分の顔を判定させたら失敗した話（番外編）](https://qiita.com/sksk_go/items/5035e980e16d6d182a50)
##ネクストアクション
今回作ったCustom Visionの画像認識とIoT機器を組み合わせる
Cythonでbool型のNumPyに型指定する方法

#CythonでNumPyに型指定する方法のおさらい

```python
import numpy as np
cimport numpy as np # npがかぶっているが公式によれば大丈夫。こちらは型指定用。
# from numpy cimport ndarray as ndar # np.ndarrayが長ければこう書いてもOK
cdef np.ndarray[np.int_t, ndim=2] array
```
などとする。NumPyに関しては型指定でかなり高速化されるようなのでやったほうがいいだろう。

#bool型の配列では...？
NumPyを使っていれば、`dtype=bool`で使うことも少なくないだろう。
これを型指定しようとすると、結構つまずく。公式ドキュメントで明記されてない気がするので...

思いつくような方法で

```python
cdef np.ndarray[bint, ndim=2] bool_array # bintはcythonでのbool型
cdef np.ndarray[np.bool, ndim=2] bool_array2
```
としても、コンパイルは成功するが、実行時に

```
ValueError: Item size of buffer (1 byte) does not match size of 'bint' (4 bytes)

ValueError: Does not understand character buffer dtype format string ('?')
```

などとエラーが出てしまう。

正しくは、

```python
cdef np.ndarray[np.uint8_t, cast=True, ndim=2] bool_array
# または
cdef np.ndarray[np.npy_bool, cast=True, ndim=2] bool_array
```

とする。おそらく`cast=True`で適切に型変換してくれるのだろう。

(比べてみたが、どちらでもパフォーマンスはほとんど変わらないようだ。)

##参考リンク
http://omake.accense.com/static/doc-ja/cython/src/tutorial/numpy.html
https://stackoverflow.com/questions/18058744/passing-a-numpy-pointer-dtype-np-bool-to-c
https://github.com/cython/cython/pull/2676
【truffle】ethereumによるDappsフレームワークの開発準備

前回、RailsにgemをインストールすることでEhereumネットワークと接続することができるよ。

これでDAppsが作れるよ。ということを書いたんですが・・・。

<h3>ぼくには無理でした。</h3>

RailsとEthereumを連携させるという事例はなかなかなく・・・参考にさせていただいたサイトもいくつかあるんですが僕には環境構築がうまくできませんでした・・・。

と、いうことでEthereumネットワークを用いたDAppsを作成する際に、truffleというフレームワークが多く使われているようです。

今回はこのフレームワークを使う王道方式で行こうかと思います。

<h2>truffleとは</h2>

いい匂いしそう。 ではなく、開発に必要となるコンパイルやテスト、デプロイなどを可能にするEthereumスマートコントラクト開発用フレームです。

開発環境の構築というのは、アプリケーションを作る際に常に必要な作業になるとは思うのですが、スマートコントラクト機能を持つDAppsの場合その難易度はかなり上がるんじゃないかなと思います。

というのも、スマートコントラクトとなるとgethやsolidityといった開発環境を構築していくことになるのですが、
これらの環境はまだ過渡期といってもいいような状態です。

要は、前のsolidityバージョンではこの記述でできたのに、別のsolidityバージョンではエラーがでる。なんてことが頻繁に起きます。

言語単体の話だけでなく、gethとweb3.js間のバージョンが整合性取れずに・・なんてこともあった気がします。というか原因特定に至らなかったんですがそういう雰囲気のエラーはでました。

DAppsの場合、フロントからサーバー、Ethereumネットワークまで連携的に動いていく必要があるのですが、一つ一つ構築していくとなかなか難しいです。

そこでこのtruffleをインストールすると、truffle自体が様々な機能を包括的に持っているので簡単にアプリケーション開発に望むことができます。

<h2>truffle使い方</h2>

インストール方法はネット上を探せばあるのと思うので省略させてください。

インストールしたらバージョン確認をします。最新版はv5系なのですが、安定しているらしいということでv4.1.15を使用していきます。

基本的には安定板を使用していったほうがいいと思います。本当にいろんなところでひっかかるし、ネット上にあるリファレンスが全然使えなくなったりするので・・・。

```bash
$ truffle version
Truffle v4.1.15 (core: 4.1.15)
Solidity v0.4.25 (solc-js)
```

<h2>truffleプロジェクトの作成</h2>

まずはプロジェクト用のディレクトリを作成します。

```bash
$ mkdir myapp
```

作成したディレクトリに移動してtruffleプロジェクトを新規作成します。

```bash
$ cd myapp
$ truffle init
```

作成されたtruffleプロジェクトのディレクトリ構造は下記の通りです。

```bash
$ tree
.
├── contracts
│   └── Migrations.sol
├── migrations
│   ├── 1_initial_migration.js
├── test
└── truffle.js
```

<h2>truffle developについて</h2>
truffleには、開発用ブロックチェーンとしてtruffle developが用意されています。

truffle developはトランザクション発行後に即ブロックに取り込む機能を備えています。

トランザクションの結果を即座に確認することができるため、開発の際には重宝するそうです。

gethみたいに目の前でマイニングの様子を見せてくれるわけではないみたいですね。(あれはあれで何かロマン)

<h2>truffle developの起動</h2>

```bash
$ truffle develop
```

上記コマンドを実行すると、次の内容を知らせてくれます。

・http://127.0.0.1:9545/にてtruffle developクライアントが起動
・10個のアカウントを発行
・それぞれの秘密鍵とニーモニックを表示

起動後はtruffleコンソールに切り替わります。このコンソールでは、任意のEthereumクライアントが指定されています。

<h2>デプロイ先のEthereumネットワーク設定</h2>

デプロイ先のネットワークを設定します。

ここでは、gethプライベートネットとganacheの設定を行います。

gethのインストールなんかは調べてみてください。

truffle-config.jsを開き、下記の通りに編集します。

```javascript
module.exports = {
  networks: {
      development: {
          host: '127.0.0.1',
          port: 8545,
          network_id: 15,
          gas: 4700000
      },
      ganache: {
          host: '127.0.0.1',
          port: 7545,
          network_id: '*'
      }
  }
}
```
gethプライベートネットワークのdevelopmentネットワークと、ganacheアプリケーションが提供するプライベートネットワークを指定します。

<h2>truffleコンソール</h2>

truffle-config.jsで設定したネットワークを指定して、truffleコンソールを起動します。

--networkの引数にtruffle-config.jsで指定したネットワーク名を付与して、truffle consoleコマンドを実行します。

```bash
$ truffle console --network development
truffle(develop)>
```

ちなみにネットワーク名がdevelopmentの場合は、truffle consoleだけでも起動できます。

ganacheのプライベートネットを指定する場合も操作方法は同じになります。

```bash
$ truffle console --network ganache
truffle(ganache)>
```

これでtruffleによる開発準備は完了です。


って感じです。

色々と飛ばしちゃったなぁ。ブロックチェーンの概念とかも読み深めていきたいところ。

とりあえず、しばらくは個人アプリ開発奮闘記みたいな構成で書いていこうかなと思ってます。
'git st'が遅いときの対処方法 -- Windows版 --

# TL;DR

Windows版では、gitのaliasを使っていると展開に時間がかかることがあります。
shellのaliasを使いましょう。

# 'git status'は打ちにくい

入力補完では候補が複数あって絞りきれません。

```
$ git sta
stage    stash    status
```

# aliasを使おう

`.gitconfig`のにaliasを設定します。

```{~/.gitconfig}
[alias]
    st = status
```

## なんか遅い

いざ実行してみるとなんか遅い。なんかというか、実行するたびにちょっと固まっているレベルで遅い。
gitコマンドがどのように実行されているかを確認するための``GIT_TRACE``という環境変数があるようです。今回調べていて初めて知りました。

```
$ GIT_TRACE=1 GIT_TRACE_PERFORMANCE=1 git st
21:43:46.036879 git.c:670               trace: exec: git-st
21:43:46.037550 run-command.c:643       trace: run_command: git-st
21:43:48.335997 git.c:366               trace: alias expansion: st => status
21:43:48.336520 git.c:670               trace: exec: git-status
21:43:48.336885 run-command.c:643       trace: run_command: git-status
21:43:48.356590 git.c:419               trace: built-in: git status
21:43:48.362629 read-cache.c:2256       performance: 0.003905200 s:  read cache .git/index
21:43:48.364862 read-cache.c:1574       performance: 0.000159200 s:  refresh index
21:43:48.368519 diff-lib.c:251          performance: 0.000017500 s:  diff-files
21:43:48.377368 name-hash.c:594         performance: 0.000015600 s:   initialize name hash
21:43:48.378452 dir.c:2282              performance: 0.001283200 s:  read directory
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   main.c

21:43:48.396978 trace.c:477             performance: 0.042009300 s: git command: /usr/libexec/git-core/git-status
21:43:48.399018 trace.c:477             performance: 2.366321700 s: git command: git st
```

``git st``のたびに2秒も待たされるのはつらいので、原因調査します。

## gitの問題ではない

巨大なリポジトリに対するgitの速度問題への対応策として、`git gc`などがありますが、`git status`自体が遅いわけではないので、今回は当てはまらないようです。

Windows版のgitでは、Windowsプロセスとgitとの橋渡し部分がネックになりやすいという記事を見つけました。
どうやら今回の原因もこれっぽいです。

<https://stackoverflow.com/questions/36925695/git-alias-slower-than-original-command>

# bashの関数を使う

gitのaliasを使うと遅いということで、bashにaliasを設定する方向で考えます。

普通にbashのaliasを使おうとするとスペースが使えないので、gitのaliasとは使用感が違ってきます。
その場合、bashの関数を使うことで同じ使用感でコマンドのレスポンスを向上できます。

```
func_git()
{
    if [ $1 == "st" ]; then
        command git status "${@:2}"
    else
        command git "$@"
    fi
}

alias git=func_git
```

これも今回調べて初めて使ったのですが、``"${@:<start>:<end>}"``で引数のsliceができるみたいですね。これを使えば他にも便利なaliasが作れそうですね。
[Linux] メモリのロック

## 概要

仮想メモリに比べて物理メモリは非常に量が少ない、Linuxでは不要なページをスワップアウトして必要に応じてスワップインするデマンドページングを採用している。メモリーのロックとロック解除を行うシステムコール、mlock(2)に関する記事

## mlock(2)

[torvalds/linux/mm/mlock.c](https://github.com/torvalds/linux/blob/master/mm/mlock.c)

``` c
/* mlock - メモリーのロックとロック解除を行う */
#include <sys/mman.h>

int mlock(const void *addr, size_t len);
```

mlockではaddrからlenバイト分の仮装メモリ領域を物理メモリへロックし、0を返します。

## 使用例

``` c
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>

int main(int argc, char **argv)
{
    char *c    = "AAA";
    size_t ls  = sizeof(c);

    if (!mlock(c, ls))
        fprintf(stdout, "lock pass\n");
    else
        fprintf(stderr, "lock failed(%d)\n", errno);

  return 0;
}
```

munlock(): mlock() でピン留めした状態を解除する。

## エラー

* ENOMEM

RLIMIT_MEMLOCK を持つが、制限が許可している以上のメモリーをロックしようとした。 この制限は、プロセスが特権 (CAP_IPC_LOCK) を持っている場合は適用されない。

* EPERM

呼び出し側が特権を持っていないが、 要求された操作を実行するには特権 (CAP_IPC_LOCK) が必要である。
mlock() と munlock() 用として:

## 参考リンク

* [MLOCK](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/mlock.2.html)
* [The Linux Kernel: メモリ管理](http://archive.linux.or.jp/JF/JFdocs/The-Linux-Kernel-4.html)
* [ページングおよびメモリダンプ対策](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c607.html)
Spring MVC 5からクラスWebMvcConfigurerAdapterが廃止された

Java 8からインタフェースにdefaultメソッドが定義できる新機能のおかげ、org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapterでSpring MVCを設定する必要がない、インタフェースorg.springframework.web.servlet.config.annotation.WebMvcConfigurerを実装して必要なメソッドが定義するだけでいい。
UnityでAndroidのKeystoreパスワードを自動セーブ・ロードする

# 前提
- unity 2018.4.7f1
- Android

# できること
- 一度、KeystoreとAliasのパスワードを設定してビルドすると、以降、エディター起動時に自動的に設定されるようになります。

# やりかた
- 以下のコードを、適当な`Assets/～/Editor/～`へ入れてください。

```cs:SaveKeystore.cs
using UnityEditor;
using UnityEditor.Callbacks;

public class SaveKeystore {

	private static string keystorePrefsName => PlayerSettings.Android.keystoreName;
	private static string keyaliasPrefsName => $"{PlayerSettings.Android.keystoreName}/{PlayerSettings.Android.keyaliasName}";

	[InitializeOnLoadMethod]
	private static void OnLoad () {
		if (string.IsNullOrEmpty (PlayerSettings.Android.keystorePass) && !string.IsNullOrEmpty (PlayerSettings.Android.keystoreName)) {
			PlayerSettings.Android.keystorePass = EditorPrefs.GetString (keystorePrefsName);
		}
		if (string.IsNullOrEmpty (PlayerSettings.Android.keyaliasPass)) {
			PlayerSettings.Android.keyaliasPass = EditorPrefs.GetString (keyaliasPrefsName);
		}
	}

	[PostProcessBuild]
	private static void OnBuilded (BuildTarget target, string path) {
		if (target == BuildTarget.Android) {
			if (!string.IsNullOrEmpty (PlayerSettings.Android.keystoreName) && !string.IsNullOrEmpty (PlayerSettings.Android.keystorePass)) {
				EditorPrefs.SetString (keystorePrefsName, PlayerSettings.Android.keystorePass);
			}
			if (!string.IsNullOrEmpty (PlayerSettings.Android.keyaliasName) && !string.IsNullOrEmpty (PlayerSettings.Android.keyaliasPass)) {
				EditorPrefs.SetString (keyaliasPrefsName, PlayerSettings.Android.keyaliasPass);
			}
		}
	}

}
```

# 留意事項
- KeystoreおよびAliasのパスワードが、**平文**でエディターの設定内([EditorPrefs](https://docs.unity3d.com/ja/current/ScriptReference/EditorPrefs.html))に保存されます。
    - すなわち、他のエディタ拡張からでも取得可能です。
    - 以下は、PlayerPrefsの記事ですが、EditorPrefsへ応用できると思います。
        - [簡易なセーブデータの暗号化 (PlayerPrefs)](https://qiita.com/tetr4lab/items/e57bb6486dfeb96b93f0)
- Keystoreファイルの絶対パスに依存します。プロジェクトフォルダを移動するとオートロードできなくなります。
Excel の ボタンが押せなくなった

## 俺の右往左往はどうでもよくて、結論が知りたい人
　[結論](https://qiita.com/TechnoKuRo/items/b636c24cb427d1dc35c9#%E3%81%AA%E3%81%8A%E3%81%A3%E3%81%9F)
　もしかしたら、俺の右往左往の途中で解決する人もいると思うよ

## 俺の右往左往
　ボタン押せないんですよね・・・・
　押せるボタンもあるんですけど、いくら再起動しても、そのボタンは、機能しなくなりました。５分前はちゃんと動作していたんですけどね。
　ボタンにマウスオーバーすると、テキスト選択のI型のアイコンに代わるだけ。クリックすると、ボタン選択状態になる、いわゆる「デザインモード」の動作をしちゃってる。

## ググった
引用元
https://www.sysdays.co.jp/blog/article/4/
　まずは、いちばん上に出てきたやつをやってみよう
　どうやら、キャッシュ消すといいみたい
`%USERPROFILE%\AppData\Local\Temp\Excel8.0\MSForms.exd`

　バージョンの数字は気にせず、パスをたたくと見事にそのファイルがあるじゃないか！
　Excel落として、これ思い切って消して、Excel起動すると元通り・・・

# 消してもまだダメじゃん！

## 試しに新しいボタン置いてみる
　新しいボタンは、ちゃんと押せる。でも、もともとのボタンは上のとおり。ちゃんと動くボタンと、動かないボタンがシートに同居している状態ですね。

## もっとググった
引用元
http://fanblogs.jp/iphone7/archive/50/0
どうやら、もう一つ消すファイルがあるみたい

`%USERPROFILE%\AppData\Local\Temp\Excel8.0\MSForms.exd`
`%USERPROFILE%\AppData\Local\Temp\VBE\MSForms.exd`

今度こそ　Excel落として、これ思い切って消して、Excel起動すると元通り・・・・

# まだダメじゃん！
情報元
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14139333209
これによると、Windows Update とか、関係していそう。
だけど、５分前に機能していたファイルが、OS再起動せず、Windows Update に影響されるとは考えられないのですよ。
今回は俺のケースは、これじゃない感

## 試しにもう一度マクロ登録してみる
　ひとまず、右クリック -> マクロ登録　は選択できそうなので、このボタンが担当している関数を指定しなおしてみる

# なおった！
#### 結論
　　マクロ登録しなおそう
#### 事前対策
　　ボタンに紐づく Function や Sub は覚えておこう
　　バックアップを取ろう
　　ソフトは完全性を保証してくれないことを知ろう
#### もし困ったときの心意気
　　マイクロソフトは悪くない。お前が悪いんだっ！と言われた気になろう。
　　エンジニアなら、こうなっても起き上がれるスタビライザーを用意しよう。

## Excel 便利ですよね
Excel使ってますか？
RPAだとかいろいろ便利な世の中になってきましたが、何はともあれ、普段の業務が全部RPAにできっこないんですよね。
それ、やっぱExcelで自動化が、いちばん早いんじゃないですか？
　VBAできると、ソフト組むよりも断然早く、目的地に到達できる感覚です。
　もちろん、ちゃんと設計して、やりたいこと全部RPAにやってもらえれば、できるっちゃできるでしょうけどね。
　でも、「ここがちょっと変わる」とかのリスク考えると、即効性のあるExcelVBAあたりが、ちょうどよかったりするのが、まだ今の世の中な感・・・

## CrowdworksでもVBA、GAS案件多数あり
　まぁ、それだけ民意があるってことだし、まずはExcelVBAで自動化できるとこまでやって、効果が見えたら、ちゃんとRPAみたいな、スモールスタート的なのが、いちばん賢かったりしますよね。
　最初からガチガチなアプリ組んで、「ある特定のワークフローは完全に自動化したぁ！」ってなっても、結局ちょっと違うケースが次の日には出てきて、結局そいつの面倒見る仕事が増えただけみたいな話って、あるあるなんですよ。
　皆さん。スモールスタートしませんか？

## 結論
　愚痴りつつ、自分用のメモでした。
fish シェル起動時に anyenv がエラーを吐く

ターミナル環境を zsh -> fish へ移行作業しているのですが、fish 起動時に anyenv の初期化でエラーが出るという症状が発生しました。

## 環境

- macOS 10.14.6
- 以前の環境 (zsh) で anyenv を構築済

## 結論

`ndenv` をアンインストールすることで解決しました。

```shell
anyenv uninstall ndenv
```

## やったこと

anyenv を読み込むために、 `config.fish` に次のように書きました。

```.config/fish/config.fish
set -x PATH ~$HOME/.anyenv/bin $PATH
status --is-interactive; and source (anyenv init -|psub)
```

その後、シェルを再読み込みするとエラーが発生。

```shell
$ exec fish -l
/var/folders/r8/3l845qrs2vlg1v_hzb8vpkgr0000gn/T//.psub.FB7rqmdEou (line 1): Unexpected ')' found, expecting '}'
... 略 ...

ndenv() {
  typeset command
  command="$1"
  if [ "$#" -gt 0 ]; then
    shift
  fi

  case "$command" in
  rehash|shell)
^

... 略 ...
```

調べたところ、 `ndenv` はもうメンテナンスされておらず、`nodenv` への移行が推奨されていました。

> [Deprecated] nodenv is better alternative  
> Please consider to use [`nodenv`](https://github.com/nodenv/nodenv). `ndenv` repository is not maintained actively.  
>  
> 引用元：[riywo/ndenv: node.js version manager based on rbenv](https://github.com/riywo/ndenv) 

[nodenv/nodenv: Manage multiple NodeJS versions.](https://github.com/nodenv/nodenv)

`ndenv` を消し、 `nodenv` に切り替えたところエラーが出なくなりました。

```shell
anyenv uninstall ndenv
anyenv install nodenv
```
[Unity]Tips:インスペクターにHDRモードのグラデーションを表示するには。

#普通モードとHDRモードの違い
普通モードとHDRモードの違いは、カラーの発光レベルを設定できるかどうか。
![color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/b01b0b27-16eb-5f8f-6686-3f8cc7afd972.png)

#表示方法
グラデーションをインスペクターに表示するには、

```c#:HDRgradient.cs
        [GradientUsage(true)] public Gradient color;
```
という具合に、GradientUsageというアトリビューションを記述するだけ。
ちょっとつまずいたけど、日本語での検索にヒットしなかったからメモがてらに投稿してみました、現場からは以上です。
いきなり！TDD(当方テスト初心者でいきなりTDD！) 3日目

#はじめに

前回の、[いきなり！TDD(当方テスト初心者でいきなりTDD！) 2日目](https://qiita.com/drafts/14f8f69cb0c8ea5ec400)では、

- 仮実装
- 三角測量

について学びました。今回は「明白な実装」について学びます。

#開発環境
- Xcode 10.3
- Swift
- XCTest

#作るもの

ポーカー

#明白な実装
必ずしも小さな歩幅でテストと開発を繰り返す必要はなく、確実性、自信のもてるコードがあると判断した場合には、仮実装をせずに、直接コードに落とし込む「明白な実装」を使い分けながら、TDDは進めていくのが通常です。

#実装
現在のCardオブジェクトのnotationは、3♥のように記号が後にきている事に対し、現在の初期化は、

Card(suit:, rank:)

と、suit、rankの順になっているため、この順序が一致するように修正してみます。

```Card.swift
struct Card {
    
    //順序を入れ替えた
    enum Rank: String {
        // (省略)
    }
    
    enum Suit: String {
        // (省略)
    }
    

    //順序を入れ替えた
    let rank: Rank
    let suit: Suit
    

    // (省略)
}
```

ここで、Command + U でテストを実行します。
結果はレッドになります。グリーンにするために、続けて、TDDPokerBySwiftTests.swiftも修正していきます。

```TDDPokerBySwiftTests.swift
class TDDPokerBySwiftTests: XCTestCase {

    func testInitializeCard() {
        
        var card: Card
        
        card = Card(rank: .three, suit: .heart) //順序を入れ替えた
        XCTAssertEqual(card.suit, .heart)
        XCTAssertEqual(card.rank, .three)
        
        card = Card(rank: .jack, suit: .spade) //順序を入れ替えた
        XCTAssertEqual(card.suit, .spade)
        XCTAssertEqual(card.rank, .jack)
    }
    
    func testCardNotation() {
        var card: Card

        card = Card(rank: .three, suit: .heart) //順序を入れ替えた
        XCTAssertEqual(card.notation, "3♥")
        
        card = Card(rank: .jack, suit: .spade) //順序を入れ替えた
        XCTAssertEqual(card.notation, "J♠")
    }
}
```
Card.swiftの、

let rank
let suit

の変数定義を入れ替えたことで、初期化も、

Card(rank:, suit:)

の順に変更されました。
これは、swiftのstructは、プロパティの宣言順序に応じて、初期化の引数の順序が変わります。

この機能を考慮しない場合、

```Card.swift

	let rank: Rank
    let suit: Suit

    init(rank: Rank, suit: Suit) {
        self.rank = rank
        self.suit = suit
    }

```

というように記述すべきですが、こういった機能を確実に理解しているのであれば、記述を省略することができますし、仮実装も省略して構いません。こういった考え方が「明白な実装」になります。

#不要なテストを削除する(テストのリファクタリング)

notationは初期化時に渡したrankとすいtに応じて文字列を返却するプロパティになるため、Cardの初期化が成功し、同時にrankとすいtが期待通りインスタンスに保持されることが証明できています。
よって、既存のテストケースであるtestInitializeCard()は必要ないということになり、これを削除したテストコードが、以下になります。

```TDDPokerBySwiftTests.swift
import XCTest
@testable import TDDPokerBySwift

class TDDPokerBySwiftTests: XCTestCase {
    
    func testCardNotation() {
        var card: Card

        card = Card(rank: .three, suit: .heart)
        XCTAssertEqual(card.notation, "3♥")
        
        card = Card(rank: .jack, suit: .spade)
        XCTAssertEqual(card.notation, "J♠")
    }
}
```

ToDoリストも更新しましょう。

- [x]  Cardを定義して、インスタンスを作成する
 - [x]  CardはSuitを持つ
 - [x]  CardはRankを持つ
- [x]  Cardのインスタンスから文字列表記(notation)を取得する

#終わりに
今回は、

- 明白な実装
- テストのリファクタリング

について学びました。次回から、本格的なSwiftの設計、実装を踏まえながら、引き続きTDDを学びます。

#出典

- [Swiftで書いておぼえるTDD (技術の泉シリーズ（NextPublishing）)](https://www.amazon.co.jp/dp/B07JFNVQMK/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
SourceTreeを初期化・リセットする方法

# はじめに
本日はSourceTreeがぐちゃぐちゃになってしまった方へご紹介致します。

**SourceTreeをリセットする方法・・・**
....
...
..
.
リセットするのではなく、どこが悪いのかどう直すべきかをなるべく考えるべきですが、どうしても時間がなかったりと、様々な事情があるかと思います・・・

そういう時にぜひ使用してみてください^^

ここではMacでの初期化の方法をご紹介します。
SourceTreeの公式Supportでも、Windows・Macともに初期化する方法を紹介されていますので、こちらもどうぞ。
URL：https://confluence.atlassian.com/sourcetreekb/how-to-wipe-sourcetree-preferences-412484640.html

# コマンド
ターミナルを開き、まずSourceTreeのアプリを削除します。
私は、`~/Library/ApplicationSupport`の下にSourceTreeを入れましたので、パスは下記のようになっています。おそらくほとんどの方はここになるかと思いますが、違う方は適宜SourceTreeをダウンロードしたパスを入力してください。
二番目のコマンドで初期化が完了します！

```
# SourceTreeのアプリを削除する
$ rm -rf ~/Library/Application\ Support/SourceTree/

# リセットする
$ defaults delete com.torusknot.SourceTreeNotMAS
```


# 終わりに
以上、SourceTreeを初期化・リセットする方法についてご紹介しました^^
勉強目的であれば、あまり使わない方が良いかと考えています...
しかし、本来の目的とは異なる部分でつまづくとモチベーションを保つのが難しいと思いますので、いっそのことリセットしてしまうのも一つの手です。

Progateさんは、環境構築をせずに手軽にプログラミングを楽しめるのでとてもいいです^^
私はProgateからRubyOnRailsを学んだのですが、その環境構築をいざやろうと思ったら何日かかったことか・・・
思い出したくないですね笑