OmniAICreator/Qiita-1.07M huggingface dataset:
年末なのでインフラエンジニアとして今後のキャリアパスを考えてみる。

私はこれまでインフラエンジニアとして監視オペレーターからキャリアが始まり現在ではAWSを中心に大規模サービスのインフラ改善や自動化の提案導入運用をしています。
そんな私ですがインフラエンジニアの視点で最近思うことと今後のキャリアパスなどについて考えてみました。
※あくまで個人的見解です。

ちなみに私の直近２年間の経歴です。
* 国内外コンシュマーゲームインフラ運用(DevOpsエンジニアとして関わる)
* コンシュマーゲームインフラ開発(MSPに常駐し間接的に関わる)
* 人気スマホゲームのインフラ運用改善・自動化導入(現在ココです)

とまぁ元々オンプレをメインとしてサーバの設計構築をしていたのですがゲームサービスのプロジェクトに関わるようになるのと同時にクラウドエンジニアとしてキャリアチェンジしました。

# 最近思うことその1 クラウドで置き換えられる技術を1から構築設定するのをやめる！
クラウドのフルマネージドサービスは徹底的に活用すべきだと思いました。
業務で1から構築設定して用意するのは車輪の再発明なのでサービスを素早くデリバリさせる必要がある業種では通用しないのではないのかと感じています。
(但し仕組みを知る意味での一環として構築設定するのはアリだと思います。)

# 最近思うことその2 コスト削減させるための自動化は当たり前、もっと自分がやるべきことを考える！
一時的に利用するシステムを稼働させっぱなしにして利用料金を垂れ流すなどのようなことがないように、CloudFormation・AWS CLIを使って作成と削除の自動化をさせる。QA、開発環境の準備で半日〜1日などかけずにスクリプトを一発叩くだけで環境のデリバリを素早く行うなど当たり前だと考えてます。本来自分がもっとやるべき業務に時間を割くべきだと考えています。例えばその人の立ち位置にもよりますが求職者の応募が増える仕組みを考える・採用面接の対応をする・育成に時間を割く・社外セミナー開催準備など企業によってはエンジニアが非エンジニア業務を担当することがあります。技術で貢献することもいいですがそれ以外でも企業にコミットすることを意識したいですね。

# 最近思うことその3 技術はあくまで手段！こだわりすぎも良くない！
ここ数年インフラ自動化技術は急速に発展して魅力的なミドルウェアや構成管理ツールが出てきています。本当は一つ一つ試してみたいとエンジニアとしての欲求はあるのですが全て手を出すのではなく現状の問題点や課題をクリアさせるためにどの技術を採用させるべきかあくまで手段として技術を利用するのだと思考を切り替えましょう。

# 今後のキャリアパスを勝手に予想
昨今ではフルスタックエンジニアというキャリアパスがありますがこれからは技術の垣根を越えたキャリアにももっとスポットが当てられるようになるのではと勝手に考えています。
例えば
インフラ技術 + 採用
インフラ技術 + マーケティング
インフラ技術 + 教育
インフラ技術 + ブランディング
インフラ技術 + セキュリティ運営(ISMS・Pマークなど)
インフラ技術 + サービス立ち上げ

# 最後に
技術だけ幅広く経験やスキルを磨くだけではなく他分野の業務経験・スキルは今後企業にとっても重宝されるのではないでしょうか。
個人的には業務の視野が広がり様々な視点で仕事ができるようになるのでいいことだと考えています。
**技術以外はやりたくない！**といった方も多いと思いますが今後はそんなことも言っていられない気もします。
AOJ-1130 Red and Black（幅優先、深さ優先の問題）をpythonで解いてみた

こんにちはSoheiです:smile:
今回は幅優先探索と深さ優先探索の練習問題であるAOJ-1130 Red and blackという問題を解いていきたいと思います！
#流れ
①迷路を読み込む
②@地点をqueue(stack)の中に入れる
③タイルの地点を取り出す
④近いタイルが”.”だった場合そのタイルの地点をqueue(stack)に入れる
⑤④で入れたタイルを”＄”とし、カウントを一つ増やす
⑥終わりか判定
⑦③に戻る
⑧最後にカウントを出力

#実装
##幅優先

```python:sohei.py
while 1:
	w,h = map(int, raw_input().split())
	if w == h == 0:
		break
	count = 0
	cnt = 1
	lst = [list(raw_input()) for i in range(h)]
	queue = []
	for i in range(h):
		if "@" in lst[i]:
			wNow, hNow = lst[i].index("@"),i
	queue.append([hNow, wNow])
	while 1:
		hNow,wNow = queue[0][0],queue[0][1]
		queue.pop(0)
		if hNow < h-1:
			if lst[hNow+1][wNow] == ".":
				queue.append([hNow+1,wNow])
				lst[hNow+1][wNow] = "$"
				cnt += 1
		if wNow < w-1:
			if lst[hNow][wNow+1] == ".":
				queue.append([hNow,wNow+1])
				lst[hNow][wNow+1] = "$"
				cnt += 1
		if hNow > 0:
			if lst[hNow-1][wNow] == ".":
				queue.append([hNow-1,wNow])
				lst[hNow-1][wNow] = "$"
				cnt += 1
		if wNow > 0:
			if lst[hNow][wNow-1] == ".":
				queue.append([hNow,wNow-1])
				lst[hNow][wNow-1] = "$"
				cnt += 1
		if len(queue) == 0:
			break
	print cnt
```
##深さ優先

```python:hello.py
while 1:
	w,h = map(int, raw_input().split())
	if w == h == 0:
		break
	count = 0
	cnt = 1
	lst = [list(raw_input()) for i in range(h)]
	Stack = []
	for i in range(h):
		if "@" in lst[i]:
			wNow, hNow = lst[i].index("@"),i
	Stack.append([hNow, wNow])
	while 1:
		hNow,wNow = Stack[-1][0],Stack[-1][1]
		Stack.pop(-1)
		if hNow < h-1:
			if lst[hNow+1][wNow] == ".":
				Stack.append([hNow+1,wNow])
				lst[hNow+1][wNow] = "$"
				cnt += 1
		if wNow < w-1:
			if lst[hNow][wNow+1] == ".":
				Stack.append([hNow,wNow+1])
				lst[hNow][wNow+1] = "$"
				cnt += 1
		if hNow > 0:
			if lst[hNow-1][wNow] == ".":
				Stack.append([hNow-1,wNow])
				lst[hNow-1][wNow] = "$"
				cnt += 1
		if wNow > 0:
			if lst[hNow][wNow-1] == ".":
				Stack.append([hNow,wNow-1])
				lst[hNow][wNow-1] = "$"
				cnt += 1
		if len(Stack) == 0:
			break
	print cnt
```
では実際に動かしてみたいと思います。

```
#Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
0 0
```
```
#Output
45
```
ちゃんと出力してくれました:smile:
#学んだ知識
・list内包表記について
#考察
今回の学習で、深さ優先と幅優先の違いのようなものを感じました。今の例では迷路を考えていますが、迷路の種類によっては深さ優先の方が有利な時もありますが、迷路が膨大な場合を考えると、猪突猛進な深さ優先は解を求めるのに時間がかかる場合がある。それに比べて、幅優先の解を見つける速度は、言うまでもなく速いです、ですが、深さ優先は迷路が膨大な時、まれに解にたどり着ける場合があります。例えるなら幅優先が真面目な生徒会長という感じで、深さ優先は映画の主人公の勇者といった感じでしょうか。なので実用例にも違いがあります。例えば幅優先は、マップの経路などに向いていると思います。最短距離を正確に出してくれます。深さ優先は、幅優先で地道にやっていては解が見つからないようなパズルなどに向いていると思います。
今後、アルゴリズムと関わっていく中で、この幅優先と深さ優先の使い分けに気をつけていきたいと思いました。

今回はこれで失礼します:older_man:
次回は新しいアルゴリズムに挑戦してみようかなと思っております。
それではメリークリスマス！！:santa:
openFrameworksでVJingするときに役立つものまとめ


今更ながらなんかかっこいいしVJingしたいじゃん？素人が書きます。
(後々色々追加していく予定）
##ツール

###touchOSC/ofxOsc

https://hexler.net/software/touchosc

外部機器（iPadやらiPhoneやら）でoF側にデータやシグナルを贈りたいときに使うやつ。
DJが使ってるミキサーとかフェーダー・スクラッチテーブルをモチーフとした幾つかのテンプレが用意されているので使いやすいしイカす。
OSCはofxOscを使っても十分使える。geneさんのofxTouchOsc (https://github.com/genekogan/ofxTouchOsc) も便利


## エフェクトとか
### ofxPostGlitch
定番中の定番？というイメージがある（よく使っている人を見かけます）。
それっぽくグリッチをかけてくれるので便利。
これさえあれば一気にVJing感が増す。

https://github.com/maxillacult/ofxPostGlitch



## higaさんのいい感じのフレームワーク集

Context Oritented ProgrammingっぽくかくとoFでのVJもいい感じになりそう。
使い回しがきいて臨機応変にできるところが魅力的。
どちらかというとVJ特化のコードの書き方やスタイルについてのAddon。

### ofxLayer

レイヤーを定義していろんなエフェクトを別々に記述しておいて、メインルーチンで一気に描画できる。
各レイヤーのアルファを個別に設定できる。
これが流行ればVJのOpenSourceネットワークとかができそうなぐらい汎用性がある、気がする・・・・。
https://github.com/satoruhiga/ofxLayers



### ofxGlobalContext

Context Oriented Programmingのためのフレームワーク。
全エフェクトに共有したい処理（カメラワークとかeOSCとか)の記述に使える。
https://github.com/satoruhiga/ofxGlobalContext
CSS Grid Layout Generator でレイアウト用CSSを生成する

最近作ってたものの紹介です。だいたいできたんで公開します。

https://mizchi-sandbox.github.io/grid-generator/

![](https://gyazo.com/7035c1a0f54475bf1858418c01e2f127.gif)

## これは何

ワークフローによりますが、CSS書く際に最初に決めるのは大まかなレイアウト構成だと思います。
で、最近はコンポーネント志向でReactComponentとか書いていくと、各領域が何を占めるかみたいな設計に便利なのが、CSS Grid Layout ですね。たぶんそう。

https://qiita.com/kura07/items/e633b35e33e43240d363

[これからのグリッドレイアウト 第1回 Grid Layout Moduleの概要](https://app.codegrid.net/entry/display-grid-1)

CSS Grid だと何がいいかというと、やたらプラガブルなんで、機械的に吐き出しても汚くならない点です。というわけで作りました。

レイアウト設計、毎度結構だるくて、僕みたいなあんまCSS書きたがらないエンジニアだと、GUIでポチポチやって、それっぽいCSSを吐き出してくれるといいな、なんて思ったりしていました。

ただ、自分はこれを作る過程で Grid Layout に対して結構詳しくなってしまったのはあるんですが…


## 使い方

行と列を+-のボタンで追加します。デフォルトの長さは 1fr です。 fr という単位は、固定幅を除いて、それが全体の内で占める割合です。

セル名をクリックすると編集できます。同じ名前が連結すると繋がります。要はぷよぷよです。

![](https://i.gyazo.com/4e65414653b33b211df59a70861dd70d.gif)

Cells と Panes の２つの編集モードがあります。Pane モードは結合された状態で編集できます。

![](https://i.gyazo.com/576cfa8f2b17515939b9e55d7c24196a.gif)

output は今の状態を示す css/html を出力します。こんな感じです。

```
// CSS
.container {
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: 120px 4fr 1fr;
    grid-template-rows: 60px 1fr 40px;
    grid-template-areas: 'header header header' 'left content right' 'footer footer footer';
}

.area-header {
    grid-area: header;
}

.area-left {
    grid-area: left;
}

.area-content {
    grid-area: content;
}

.area-right {
    grid-area: right;
}

.area-footer {
    grid-area: footer;
}

// HTML
<div class='container'>
  <div class='area-header'></div>
  <div class='area-left'></div>
  <div class='area-content'></div>
  <div class='area-right'></div>
  <div class='area-footer'></div>
</div>
```


React でプラガブルに編集しやすいように、 styled-components 版を用意してます。なんとなく自分が最近 styled-components 使ってて、便利に感じてたんでこれ前提のAPIを組みました。

```js
// Generated by CSS Grid Editor
import styled from 'styled-components'

export default styled.div`
width: 100%;
height: 100%;
display: grid;
grid-template-columns: 120px 4fr 1fr;
grid-template-rows: 60px 1fr 40px;
grid-template-areas: 'header header header' 'left content right' 'footer footer footer';
`

export const header = styled.div`grid-area: header`


export const left = styled.div`grid-area: left`


export const content = styled.div`grid-area: content`


export const right = styled.div`grid-area: right`


export const footer = styled.div`grid-area: footer`

```

これをコピペして、こんな感じで import して使えます。(要: npm install styled-components)

```js
import Layout, * as Area from './layouts/Layout'

export default () => {
  <Layout>
    <Area.header>
       <Header/> // children に要素を与えると展開される
    </Area.header>

    <Area.left/>
    <Area.content/>
    <Area.right/>
    <Area.footer/>
  </Layout>
}
```

CSS in JS じゃない場合は CSS Modules とかで使うだろうので、インライン化はそこまで頑張らなくてもいいかな…

## 注意点

- IE11はCSS Grid Layoutの対応が不十分なので、 postcss/autoprefixer 通す必要があります。
- panes モードで、隣接できない名前にすると表示されなくなります。これは CSS Grid Layout の仕様です。cells モードで元に戻してください。

TODO: styled-components を使う場合に autoprefixer 通す方法調べる。
玄箱proのFlashBootへの切り替え方法

シリアルコンソールからu-bootを起動し以下を入力する。
> setenv bootargs_root root=/dev/mtdblock2 rw panic=5
> setenv bootcmd 'nboot \$(default_kernel_addr) 0 \$(nand_uImage_offset);bootm \$(default_kernel_addr)'
setenv nand_boot yes
> setenv bootargs \$(bootargs_base) \$(bootargs_root) \$(buffalo_ver)
> boot
特定のDynamoDBテーブルにのみCRUD権限を付け...たかった夢の跡

[株式会社オズビジョン](http://www.oz-vision.co.jp/)の@terra_yuccoです。
現在オズビジョンのサービス運営は社員だけではなく、派遣社員、アルバイト、外部コラボレータ、その他様々な方々に支えられて成り立っています。
今回はその中で、開発の中で特定のDynamoDBのテーブルだけCRUDが必要になるケースがあり、その際にいろいろ調査をしたので、その結果をまとめました。

# 実際にやったこと
## まずIAMポリシーを作る
### やりたい操作
- SQLで言うDDLレベルの操作は不要。DMLがあればいい
    - いわゆるCRUD - Create / Read / Update / Delete
- 対象テーブルは開発環境のテーブル
    - 複数環境のテーブルが同じAWSアカウントにあり、環境区別はテーブル名で行っている (サンプルではわかりやすいようにプレフィクスtest_)

### 該当する設定項目
- DynamoDBのポリシーで該当しそうなものを探す
    - 厳密にはもっと適切なページがあると思うのですが、[API Reference](http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations_Amazon_DynamoDB.html)を参照しました。
        - ~~dynamodb:PutItem~~
        - ~~dynamodb:GetItem~~
        - ~~dynamodb:Query~~
        - ~~dynamodb:Scan~~
        - ~~dynamodb:UpdateItem~~
        - ~~dynamodb:DeleteItem~~
- この辺いろいろ探したのですが、今回コンソールからの利用を想定していたため、ListTablesとか他もいろいろ必要になり、最終的には"dynamodb:*"で開けました。

### 対象テーブルのarn
以下の場所からコピペします。
DynamoDB > Tables > 該当テーブル選択して右ペイン
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95030/b605f362-75ef-8f42-7475-8ab9168b0e2b.png)

…なのですが今回結局、テーブルを1つずつ指定はしなかったため、このままは使いませんでした。＼(^o^)／

### jsonにしてみた
#### 全部を一度Allowし、必要ないところをDeny
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "dynamodb:*"
            ],
            "Resource": [
                "arn:aws:dynamodb:ap-northeast-1:xxxxxxxxxxxx:table/production*",
                "arn:aws:dynamodb:ap-northeast-1:xxxxxxxxxxxx:table/stage*"
            ]
        }
    ]
}
```

#### 結局使わなかったやつ (validateは通る)
```json
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "dynamodb:DescribeTable",
            "dynamodb:PutItem",
            "dynamodb:GetItem",
            "dynamodb:Query",
            "dynamodb:Scan",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem"
        ],
        "Resource": [
            "arn:aws:dynamodb:ap-northeast-1:xxxxxxxxxxxx:table/test_table",
            "arn:aws:dynamodb:ap-northeast-1:xxxxxxxxxxxx:table/test_table2"
        ]
    }
}
```
### 実際にポリシーを作る
(中の人都合でこちらは12/29以降に追記します...)
### お願い
現状、この設定で特に問題は発生していないのですが
この設定だとテーブルにインデックスが作れてしまう？かもしれないという点をパートナーさんに聞かれ即答できずにいます。
AWS CLI DYNAMODB のページを見ると、インデックス作成に該当するアクションはなさそうなのですが、ここを制限するにはどうしたらいいのか…
もしご存知の方がいらっしゃいましたら、コメントいただけると幸いです！
(コンソールから該当テーブルに遷移することはでき、CRUDだけが可能！となるのが理想です)

# おわりに
ぶっちゃけ開発と本番でアカウントを分けていればこのような問題は起こらないのですが、一度同じアカウントに作ってしまうとなかなか切り分けられないので、こういう風に対処していますという共有でした。

**[オズビジョンのアドベントカレンダー](https://qiita.com/advent-calendar/2017/ozvision)**は本日でひとめぐりしていますが(この記事は12/18分ですが、書いたのは12/25ですorz)、また機会があれば、エンジニア一同、このようなチャレンジをしていきたいと思っています。ぜひ、私たちの次のチャレンジを楽しみにしていただければと思います。
それでは皆様良いお年を。
【おしまい。】
Google App Maker ー オーナーや編集者でアプリケーションを公開した場合に実行できることの違い

App Maker はオーナー以外のユーザーに編集権限を付けてあげることで `編集（Editor）` 権限の人でもアプリケーションを公開することが出来る。
その際の権限周りをまとめておく。

## TL;DR
正直このあたりはバグが多いので編集者で公開とか、App Maker のオーナーを変えるとかはしないほうが良いです。


## Owner → 自分(Owner)で公開した環境
これが基本となるパターン。
もちろんなんでも出来る。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/582d5810-5ba0-0ed5-f968-d4c7db150979.png)



## Owner → 自分(Owner)以外が公開した環境
オーナーが編集者の公開したアプリケーションを操作するパターン。
※`VIEW LOGS` は画面遷移はするけど実際には権限がなくて動かない。[^1]
[^1]: GCP プロジェクトの IAM 設定で権限を付けてあげる必要がある。権限が同期していないバグと思われる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/5f3cc6ae-b5fa-1188-465d-6f5325ceb41f.png)




## Editor → 自分(Editor)以外が公開した環境
※`VIEW LOGS` は画面遷移はするけど実際には権限がなくて動かない。[^1]

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/2c376108-97cc-009c-932d-738c9931811f.png)



## Editor → 自分(Editor)で公開した環境
`削除が出来ない`以外はオーナーの場合と一緒。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/a2e47e9b-bffc-a509-cd7f-1021f6959c57.png)


## その他
公開したユーザーが GCP プロジェクトのオーナーになる。
ただ App Maker ファイルの オーナーを変えても GCP プロジェクトのオーナーは変わらないというのがポイント。

またGCPプロジェクトのオーナーと App Maker ファイルのオーナーが違うため、編集者が公開したアプリケーションを`DELETE`しても `GCP プロジェクトが消えない`というバグがあったりする。
組み込みオブジェクトを汚さない拡張のやり方

当たり前と言えば当たり前なのですが Gem を作る時とかに使えそうなので。

# 普通に拡張すると何が問題なのか？

Ruby 自体は組み込みのライブラリに含まれるクラスも簡単に拡張できます。

```ruby
class Array
  def <<(obj)
    nil
  end
end
```

簡単に `Array` の `<<` メソッドを壊す事ができました。これは極端な例ですが、こうした衝突があちこちで起こるのを避けたいというのが本題です。

# やり方

## 継承を使う

```ruby
class MyArray < Array
  def <<(obj)
    2.times { super(obj) }
  end
end
```

実行。

```ruby
# 普通に Array の initialize が呼べる
my_array = MyArray.new(2, "hoge")
# 上書きしたメソッドを実行してみる
my_array << 1
p my_array
```

結果。

```ruby
["hoge", "hoge", 1, 1]
```

もちろん元の Array クラスでは何ら変更は起こりません。

## class_eval を用いたメソッド実装
`class_eval` の第一引数に文字列を渡すと、その中身が直接クラス内に定義されます。

また第二引数と第三引数はスタックトレースで利用されるので、このまま書いておくとデバッグの時に便利です。

おまじないにしたくない人は公式で詳しい動作をチェックしましょう。

https://docs.ruby-lang.org/ja/latest/method/Module/i/class_eval.html

これの何が嬉しいかと言うと、人が作った拡張と名前が被った時などに衝突をコンフィグで回避できる点です。

```ruby
# このようにコンフィグで設定したメソッド名を…
METHOD_NAME = "cut".freeze

class MyArray < Array
  # class_eval で直接定義する
  class_eval <<-RUBY, __FILE__, __LINE__ +1
    def #{METHOD_NAME}(count = 2)
      self.class.new self.slice(0, count)
    end
  RUBY
end
```

実行。

```ruby
my_array = MyArray.new(10, "hoge")
p my_array
p my_array.cut
p my_array.cut(1)
```

結果。

```ruby
["hoge", "hoge", "hoge", "hoge", "hoge", "hoge", "hoge", "hoge", "hoge", "hoge"]
["hoge", "hoge"]
["hoge"]
```

この場合、テストコードなどもコンフィグに合わせて実行されるように注意する必要があります（そちらは `send` を使えば簡単にできると思います）。

### 余談
このケースでも全てのメソッド名が被る事を避ける事はできませんが、そのためにネームスペースが切られています。そこまで被ってしまうケースではどうしようもありませんが、変わった名前の Gem はその辺の被りを嫌ってネーミングしているのかもしれません。

サードパーティが自社コンテンツ向け Gem でネーミングする際にかなり一般的な名前を使っている意図など考慮すると少し面白い気がします。

# 実装の例
Kaminari はこの両方の方式を使っていました。というより、自分で Gem を作った方が良さそうな要件が発生したので Clean and Easy to Use を謳っている Kaminari の実装を参考にさせて頂きました。

## 継承を使う
https://github.com/kaminari/kaminari/blob/master/kaminari-core/lib/kaminari/models/array_extension.rb#L17

元々の配列を引数にして `new` できるようになっています。

## `class_eval` を使う
https://github.com/kaminari/kaminari/blob/master/kaminari-core/lib/kaminari/models/array_extension.rb#L41

中身の実装は意外とシンプルです。
ソースのステップ数を数える

何番煎じかわからないが。

```bash
find . -mindepth 2 -maxdepth 3 -name "*.cs" | xargs wc -l
```

```
結果例：
    165 ./Xxxxxxxx.Xxxxxxxx.Xxxxxx/Hoge.cs
     29 ./Xxxxxxxx.Xxxxxxxx.Xxxxxx/Fuga.cs
     37 ./Xxxxxxxx.Xxxxxxxx.Xxxxxx/Properties/AssemblyInfo.cs
   1404 ./Xxxxxxxx.Xxxxxxxx.Xxxxxxxxx/Foo.cs
(中略)
    188 ./Xxxxxxxx.Xxxxxxxxxxxxxxxxxx.Xxxxxxx/Baa.cs
  95012 total
```

単純に `find . -name "*.cs" | xargs wc -l` とすると、カウント不要なファイル（`./aaaa/obj/Debug/hoge_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.cs` みたいなの）までカウントしてしまう。
ので、`-mindepth` と `-maxdepth` を指定して必要っぽい場所だけを検索している。
Unityでスプライトシートを使う


例えば、こういうスプライトシートを使おうと思ってやり方を調べた。
![chara.png](https://qiita-image-store.s3.amazonaws.com/0/17747/91e9ae16-069a-b6ed-3c0d-bbf04c9ef3b3.png)

## やり方

1. 画像をAssetに入れる
2. その画像のTextureTypeをSprite(2DandUI)にする
3. SpriteModeをMultipleにする
4. PixelsPerUnitを調整（ドットバイドットに見せる用）。スプライトシート8分割だったら100/8=12.5とかにする。（たぶん）
5. [Sprite Editor] を押してスプライトエディタを起動する
6. 上部ツールバーのSliceを選び、TypeをGrid by cell sizeに
7. 1個あたりのPixelSizeを指定。上記の例では16px*16px
8. Applyを押す
9. するとこんな感じにスプライトシートが分割され、画像一つ一つが選択できるようになる。
![image](https://qiita-image-store.s3.amazonaws.com/0/17747/84039266-c1b2-631c-ee9a-b3b1599d480a.png)
10. Hierarchyでcreate>2D Object>Sprite Spriteオブジェクトを作る
11. そのインスペクタSpriteRendererのSpriteという変数にさっきの分割されたそれぞれの画像が指定できる
![image](https://qiita-image-store.s3.amazonaws.com/0/17747/d3211ea0-f085-c49a-8714-bbd3cdd39c9b.png)


さらに、分割された画像をGameビューにドラッグするとアニメーションを作ってくれたりするっぽいが、それは以下を参考に。


## 参考ページ
https://unity3d.com/jp/learn/tutorials/projects/2d-shooting-game/creating-sprites-and-sprite-animations

## 参考2 (bitmap画像のdotByDot表示)
http://yukimemo.hatenadiary.jp/entry/2014/02/16/180216
Discordをみだりに採用されると困る

## 前置き
「SlackからDiscordに移行しようぜ！」というような記事をちらほら見かけるようになったんですが、「Discordのハードユーザーとしては運用に困ります！」という記事は見ないので自分で書きました。
podcast、配信、実況や作業イプみたいな通話ベースのコミュニティにとってはDiscordはマッチしてると思うけど、それ以外だとSlackの方が良いですよ。
以下本題

## Discordって何
![image.png](https://qiita-image-store.s3.amazonaws.com/0/40490/1dd4a4f0-4fbb-9658-7e94-7f0abc726161.png)
Discordは、Slackのような仕事向けチャットツールではなく、SkypeやTeamSpeak3と同じボイスチャットアプリです。
誕生から3年弱で8700万ユーザーを抱えるまでに急成長できたのは、それが単なるボイスチャットアプリではなく、あらゆる場面に対応できる柔軟な招待フローを持ち、コミュニティとしての仕事もこなし、ユーザーにサーバーを負担させない唯一無二のアプリだったからです。

## SlackとDiscordの仕様の違い
そもそも、ツールとしての出自は全く異なるんですが、今回は仕様に的を絞ります。
Slack上ではたとえ同じidで登録したとしてもチームを跨って同一のユーザーとして扱われることはありません。
職場、OSS、趣味などの特色の異なるチームに個別のユーザーとして参加できます。
そして、複数のチーム・ユーザーをSlackアプリから一元管理できるのがミソですね。

一方で、Discordでは最初に作られた1人のユーザーが複数のチームに所属する仕様になっています。
つまり、仕事であろうが趣味であろうが同一のユーザーとして紐づけられてしまいます。
もともとゲームコミュニティでDiscordを利用している人にとって、仕事のアカウントとの統合を強制されるのはあまりにひどい仕打ちです。
チームごとにオンラインステータスを変更できたりはしないので、仕事中に「ゲームやろうぜ〜」みたいな通知が飛んできたりします。

このような仕様（もとい思想）の違いが瑣末な問題として扱われ、Slackの代替イケイケアプリとしてDiscordが流行るという時流に逆らうことはできなさそうです。が、抜け道がないわけではない。

## ゲーマーたちの生存戦略
日陰でコソコソとゲームをやってる我々は、仕事とゲームのアカウントを統合することを望んでいません。
アカウントを用途によって明示的に使い分けるためには、それぞれ異なるアカウントとしてDiscordとDiscord Canaryを立ち上げる必要があります。
[Canary for OSX - Discord](https://discordapp.com/api/download/canary?platform=osx)
[Windows Canary Download - Discord](https://discordapp.com/api/download/canary?platform=win
)
("Canary"はGoogle Chromeで使われているPublic Test Buildの名前で、将来的に実装される機能などをオープンテストするためのversion/release)

Slackでは何の気なしに出来たアカウント切り替えも、Discordでは大げさな振る舞いになってしまいますね。
PC上での運用はかわいいもので、iOS/Android上ではブラウザとアプリでアカウントを使い分けなくてはならないだなんて考えたくもありません。
生意気な外国人キッズの身ぐるみを剥いで生け捕りにした後、奴隷として働かせる野蛮なゲームをやっていることを職場の人間に知られないためには、悪手を甘んじて受け入れるしかない。
gg
Pythonのrequestsを利用してRest API(json形式)にファイルアップロードする方法

## 1. はじめに

PythonのHTTPクライアントライブラリである`requests`を利用して、json形式のデータを送受信するRest APIでファイルアップロードを行う方法について説明したいと思います。
ポイントはbase64エンコードしてバイナリデータをascii文字列として送信することです。

## 2. ソースコード

```python:jsonFileUploadDemo.py
# -*- coding: utf-8 -*-
import requests
import base64

# ★ポイント1
XLSX_MIMETYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

# main
if __name__ == "__main__":

    # ★ポイント2
    uploadData = {
        'fileName': 'demo01.xlsx',
        'contentType': XLSX_MIMETYPE,
        # 'contentData': は別途設定
    }
    
    # ★ポイント3
    fileDataBinary = open('demo01.xlsx', 'rb').read()
    uploadData["contentData"] = base64.b64encode(fileDataBinary)
    
    # ★ポイント4
    url = 'http://localhost:3000/data/json/upload'
    response = requests.post(url, json=uploadData)
    
    print(response.status_code)
    print(response.content)
```

**★ポイント1**
ファイルをアップロードする場合、ファイルフォーマットをサーバに知らせるため、MIMEタイプ（コンテントタイプ）を利用するのが一般的です。
最終的には利用するRest APIの仕様に準拠することになりますが、サンプルでもMIMEタイプを利用することにします。なお、xlsxのMIMEタイプは「[2007 Office system ファイル形式の MIME タイプをサーバーで登録する](https://technet.microsoft.com/ja-jp/library/ee309278(v=office.12).aspx)」を参考にしました。

**★ポイント2**
Rest APIの入力データを定義します。今回はタイトルにもあるようにjson形式（Dict）としました。contentDataフィールドはこの後、個別に設定します。

* fileNameフィールド　：　アップロードファイルのファイル名
* contentTypeフィールド　：　アップロードファイルのMIMEタイプ
* contentDataフィールド　：　アップロードファイルのファイルデータ

**★ポイント3**
今回の記事の最大ポイントです。jsonではバイナリデータを設定できないため、base64でエンコードしたascii文字列を設定します。
base64エンコードは`base64.b64encode()`を利用することで簡単に変換できます。

**★ポイント4**
`requests`を利用してRest APIを呼び出します。json形式でHTTPリクエストを送信する場合、`json`パラメータを利用すると簡単です。
`requests`の説明については以下の記事を参照ください。

* [Pythonでマイクロサービス（概要編）](https://qiita.com/5zm/items/d5375a4ad95fd67b8960#332-requests%E3%81%AB%E3%82%88%E3%82%8Bhttp%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AE%E9%80%81%E4%BF%A1)

## 3. さいごに

今回は`requests`でjson形式のRest APIでファイルアップロードを行う方法について説明しました。
この方法では、クライアント側ではファイルのバイナリデータをbase64でエンコードし、サーバ側では受信したデータをbase64でエンコードするオーバヘッド（余分な処理）が発生します。
ファイルのデータサイズが大きい場合は`multipart/form-data`によるFormを利用したファイルアップロードを検討した方がいいでしょう。
次回は`requests`を利用した`multipart/form-data`によるファイルアップロードについて説明したいと思います。
ラズパイでkeras その3

#概要
ラズパイでkeras使って、gymのPong-v0やってるけど、全然学習が進まない。
乱数では、勝てないので、勝ったデータが積み上がらない。
くやしいので、自分でやってみたら、真剣に勝てなかった話。

#写真

![](https://camo.qiitausercontent.com/e6d34b92f13e18bd2c3c451e36c064f9c8091aa7/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f31383130342f36316264393039632d323930662d326462342d613437392d3866346336363364343335362e706e67)

#自分でキー入力するサンプルコード
aキー　下
dキー　上

```
import gym
import pygame
from pygame.locals import HWSURFACE, DOUBLEBUF, RESIZABLE, VIDEORESIZE

def display_arr(screen, arr, video_size, transpose):
	arr_min, arr_max = arr.min(), arr.max()
	arr = 255.0 * (arr - arr_min) / (arr_max - arr_min)
	pyg_img = pygame.surfarray.make_surface(arr.swapaxes(0, 1) if transpose else arr)
	pyg_img = pygame.transform.scale(pyg_img, video_size)
	screen.blit(pyg_img, (0, 0))

def play(env, transpose = True, fps = 30, zoom = None, callback = None, keys_to_action = None):
	obs_s = env.observation_space
	keys_to_action = env.unwrapped.get_keys_to_action()
	relevant_keys = set(sum(map(list, keys_to_action.keys()), []))
	video_size = env.observation_space.shape[1], env.observation_space.shape[0]
	pressed_keys = []
	running = True
	env_done = True
	screen = pygame.display.set_mode(video_size)
	clock = pygame.time.Clock()
	while running:
		if env_done:
			env_done = False
			obs = env.reset()
		else:
			action = keys_to_action[tuple(sorted(pressed_keys))]
			prev_obs = obs
			obs, rew, env_done, info = env.step(action)
		if obs is not None:
			display_arr(screen, obs, transpose = transpose, video_size = video_size)
		for event in pygame.event.get():
			if event.type == pygame.KEYDOWN:
				if event.key in relevant_keys:
					pressed_keys.append(event.key)
				elif event.key == 27:
					running = False
			elif event.type == pygame.KEYUP:
				if event.key in relevant_keys:
					pressed_keys.remove(event.key)
			elif event.type == pygame.QUIT:
				running = False
		pygame.display.flip()
		clock.tick(fps)
	pygame.quit()

if __name__ == '__main__':
    env = gym.make("Pong-v0")
    play(env, zoom = 1, fps = 10)
    
```

以上。
R Studioの開発版を試したい

この記事は[RStudio Advent Calendar 2017](https://qiita.com/advent-calendar/2017/rstudio)の…24日が空いていたので埋めようと思った，即席の記事です。

## RStudioの開発とリリース

RStudioはGitHub上のリポジトリで開発が進められています。正式版(安定版)は，みなさんご存知の[RStudioの公式サイトよりリンクに従えばすぐに到達](https://www.rstudio.com/products/rstudio/download/)できます。なお2017/12/25 19:36時点での正式版は**v1.1.383**です。

一方で，RStudioの開発は非常に早く，あっという間に次々と新機能やバグフィックスが行われております。これらは開発版で，主に2つのパターンで入手可能です:

- Preview版としてリリースされたもの
    - ある程度まとまった更新で区切り，Previewしてもらうために公開したもの
    - 不定期で公開される
    - ここである程度まとまったら正式版へとリリースされる
- Daily Build版として置かれているもの
    - 1日の成果で区切り，設置したもの
    - ほぼ毎日更新して公開される
    - RStudioのデベロッパー向け

というわけで，この記事ではこれらを紹介します。

## RStudio Preview版

### Preview版とは

ある程度の更新がまとまったらリリースするもので，「これからRStudioはどんな感じになるのかな?」というのに興味津々，というか**試してみんなに広めてドヤ顔キメたい方**にオススメです。なお，2017/12/25 19:45時点でのPreview版は**v1.1.402**です。

また**Preview版にはリリースノートが存在**しますので，必ず一読してください。

### Preview版の入手方法

Preview版は，RStudioのサイト内に(こそっと)準備してあります。URLは以下の通りです:

https://www.rstudio.com/products/rstudio/download/preview/

![2943520098.png](https://qiita-image-store.s3.amazonaws.com/0/35118/a889bc47-61ac-ec24-41e8-f6c486b9c6bd.png)

行き着くのが面倒な場合，通常のダウンロードページのURLに"/preview/"を追加すればOKです。もしくは[rstudio preview]でググれば一発です。

画面を下の方にスクロールしてもらえれば，デスクトップ版とサーバー版で，各プラットフォーム用のイメージが設置してあります。適宜DLしてインストールすればすぐに使えます。簡単ですね。

### 注意事項

これはあくまで開発版であり，**本番環境として使用するには相当のリスクがある**ことを意識していてください[^1]。ある程度動作は大丈夫だとは思いますが…。できれば仮想環境にてテストすることを強くススメます。

[^1]: とはいえ私はよく果敢に突っ込むことが多く，そこまで致命的なことになったことはあまりないです。とはいえ流石に怖いので，通常仮想環境を準備してそこに立てるようにしています。

## RStudio Daily build版

### Daily build版とは

その名の通り，「その日の進捗を組み込んでbuildしたもの」となります。そのためほぼ毎日更新され，設置場所[^2]に蓄積されていきます。これは日々RStudioの開発に携わっている人向けのものになります。2017/12/25 20:05時点で最新版は**v1.2.218**です。なんとv1.2なんですよみなさん。先日v1.1がリリースされたのにもうここまで来ているんですね。

なお，Daily build版にはリリースノートはありません。そりゃそうですよね。どんな内容がcommitされたかは，[GitHub上のrstudioリポジトリにあるcommitログ](https://github.com/rstudio/rstudio/commits/master)をチェックしてください。

[^2]: 2017/12/25現在，実はRStudioのイメージはAWS S3上の決まった場所に蓄積されています。なのでwgetなどで取得する場合，version numberを変更するだけで簡単に指定できます。これは正式版・Preview版・Daily Build版関係ないです。まあversion numberで特定していますしね。

### Daily build版の入手方法

現在，きれいにまとめられている(多分自動生成)ページがあります:

https://dailies.rstudio.com/

![389283.png](https://qiita-image-store.s3.amazonaws.com/0/35118/854abf53-5e1f-4a30-169a-e6cb7d8862e2.png)

URLは短いですが，憶えてられない方は[rstudio daily build]でググれば一発です。

各種プラットフォーム向けの最新版は画面の一番上にありますし，ちょっと前のを探りたい場合はすぐ下のところから各種プラットフォームへ進んでもらえればOKです。あとはダウンロードして入れればOKです。簡単ですね。

### 注意事項

基本Preview版と同じく開発版となりますので，**通常利用は避けたほうがいいでしょう**。うまく動かないことなんでザラです。**あなたのRStudio愛が試されます**[^3]。

## さいごに

ちょっと気になる方は，まずはPreview版からチャレンジしてみるといいかと思います。そして新機能を見つけてたらSNSやブログで流してドヤ顔キメてみましょう。でもくれぐれも開発版なので，仕様変更とかザラにあります。ドヤ顔する際はご注意ください。

**Enjoy!**

[^3]: 私はGitHubでrstudioのリポジトリをチェックしていますが，気になる機能がmergeされたら試してみるようにしています。開発側ではないのでそこまで深く踏み込まず，Preview版までにとどめています。
JDLAのディープラーニング G検定を受けてみた

この記事は、[〇〇勉強してみた Advent Calendar 2017](https://qiita.com/advent-calendar/2017/study)
の記事として投稿しました。

#JDLAのディープラーニング G検定とは
日本ディープラーニング協会が実施しているディープラーニングの検定
G（ジェネラリスト）検定は、「ディープラーニングを事業に活かすための知識を有しているかを検定する」とのこと
http://www.jdla.org/business/certificate/#education

#受験の理由
[『ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装』](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585/ref=cm_cr_arp_d_product_top?ie=UTF8)
を読んでみたものの、、、サッパリ分からない。。。
どこからどうやって勉強して行けばいいのかもサッパリ分からなかったので、体系立ってDeep Learningが知れるかなと思い、受験してみた。

#試験内容
2017/12/16（第1回）の内容

##**人工知能の開発の歴史**
・人工知能の定義
・AIブームの変遷（第一次、第二次、第三次）
・トイプロブレム、フレーム問題、弱いAI、強いAI、シンボルグラウンディング問題、フレーム問題、チューリングテスト、エキスパートシステムの問題点
・身体性

##**機械学習**
・重回帰分析、主成分分析、SVM
・ニューラルネットワーク（バイアス、重み）
・学習の工夫（正規化、標準化、無相関化、白色化）
・学習の工夫（過学習とドロップアウト、ハイパーパラメータ）
・CNN、RNNの特徴
・音声処理の手順

##**人工知能に関する動向**
・シンギュラリティに対する著名人の態度
・企業（NVIDIA、Google、IBMのwatson）
・自動運転の開発状況や各レベルの意味
・法規制の状況

人工知能の歴史や動向に関しては、JDLAの推薦図書から出題されていた。
重回帰分析、主成分分析、SVMは推薦図書にはない内容だった。

#受験前後の違い
###受験前
[『ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装』](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585/ref=cm_cr_arp_d_product_top?ie=UTF8)
をざっと読んだだけ
⇒　疑問が膨らむばかりで全く理解できなかった…
・人工知能、機械学習、ディープラーニングって何が違うの？
・何で入力値の総和が物の特徴を表せるの？
・活性化関数って何で必要なの？
・誤差を微分？？？？はぁ？？
・そもそも微分やら積分やらlogやら…スッカリ忘却の彼方なんですけど…

###勉強方法
推薦図書３冊をざっと読んで、シラバスをもとにまとめていく（3週間 10時間くらい？）

###受験後
・歴史、概要が分かった
・人工知能、機械学習、ディープラーニングの違いが分かった
・DeepLearningの概要？が理解できた
-「特徴表現をコンピューターが自らつくりだす」という点がDeepLearningのすごいところなんだと理解できた
- 神経細胞のニューロンが学習によってシナプスの結合強度を変化させることを模して、活性化関数を使っていることがわかった
- CNNは人間の視覚野に関する神経細胞を模しているモデルだということがわかった
- DeepLearningでは、定義したモデルに対して、期待値と実測値との誤差を小さくするようにパラメータを調整してくということが分かった

#感想
・数学の復習からやるべきなのか、何からはじめたらいいのかサッパリ分からなかった中、機械学習とは何ぞや？というのをざっくり把握できたのはよかったかなと思う。
・何をどう調べればいいか分からなかった中、シラバスを道しるべに進めていけたのはよかった。
・ただ、、、「ざっくり分かった」レベルになるのに受験料￥12,960円は高かったかな。。。
・ざっくり概要を掴めたので、次は何かライブラリを使って動かしてみようかな。

#2017/12/26追記：結果
不合格でした。ざっくり分かったレベルでの合格は難しかった模様。

受験者数と、合格者数は以下だったようです。
思ったよりも受験者数少ない。。。

>総受験者数　1,448名
>合格者数　　　823名
MongoDBでコレクションのすべてのフィールドを出力するやり方


MongoDBでmongoexportを使ってcsvとして出力する場合、


```
mongoexport -d dbname -c collectionA -out files.csv --csv --fields field1,filed2, field3
```
のようにフィールド名を指定しなければなりません。

ドキュメント内のフィールドは固定ではありませんが、CSVのフィールドは固定されているためです。

もしフィールドが沢山あり、そのすべてを出力したい場合どうすればいいのか。


```outputCsv.sh
IFS=$IFS;
IFS=",";

dbname="dbname";
user="admin";
password="admin";

keys=`mongo -u $user -p $password  $dbname --eval "rs.slaveOk();var keys = []; for(var key in db.collectionA.findOne()) { keys.push(key); }; keys;" --quiet`;
mongoexport -u $user -p $password --db $dbname --collection collectionA  --fields "$keys" --csv --out file.csv;

IFS=$OIFS;
```

このスクリプトを実行すれば、すべてのフィールドが出力されます。


## 参考
* https://stackoverflow.com/questions/8949335/mongo-export-all-fields-data-from-collection-without-specifying-fields
弁護士会員番号から，当該弁護士の情報を取得する（WebAPI版）

弁護士は，それぞれ固有の「弁護士登録番号」を持っています。
弁護士の所属事務所や事務所住所・電話番号等の情報は，日弁連の「弁護士検索」を通じて入手することができますが，トップページから適切な遷移を経て検索しなければ取得できません。
そこで，会員番号からそれらの情報にアクセスするAPIを作ってみます。
なお，節度を持ったアクセスに留めた方が無難かと思います。

# 使ったライブラリ
+ Flask
+ requests
+ BeatifulSoup4

# 手順
検索のトップページにアクセスし，セッションごとに設定されるトークンを取得します。
その上で，詳細検索URLにそのトークンを含むリクエストをポストして，検索結果のHTMLを得ます。
あとはそのHTMLを解析して，データの形にします。

```python3
from flask import Flask, jsonify, abort, make_response
import requests
from bs4 import BeautifulSoup

app = Flask(__name__)

URL_top = "https://www.nichibenren.jp/member_general/lawyerandcorpsearchselect/corpInfoSearchInput/changeBarSearch/"
URL_search_detail = "https://www.nichibenren.jp/member_general/lawyer/lawyerSearchResultsList/showMembersDetailedInfo"

@app.route('/infoOf/<int:reg_no>', methods=['GET'])
def getIno(reg_no):
	search_requests = {
		"membership_classification":"1",
		"registration_no": reg_no, #登録番号で検索する
	}
	#検索ページのセッションを作り，トークンを取得
	s = requests.Session()
	resp = s.get(URL_top, timeout=1)
	soup = BeautifulSoup(resp.text, "html.parser")
	token = soup.find("input", attrs={"name":"org.apache.struts.taglib.html.TOKEN"}).get("value")
	search_requests["org.apache.struts.taglib.html.TOKEN"] = token
	
	#検索する。
	resp = s.post(URL_search_detail,  data=search_requests)
	soup = BeautifulSoup(resp.text, "html.parser")
	
	tbodys = soup.select("div.mainCont tbody")
	result = {}
	#表１からの情報取得
	ths = tbodys[0].find_all("th")
	tds = tbodys[0].find_all("td")
	for i in range(0, len(ths)):
		result[ths[i].string] = tds[i].string
	
	#表２からの情報取得
	for tr in tbodys[1].find_all("tr"):
		result[ tr.b.string] = tr.span.string if tr.span else tr.td.string
	
	return make_response(jsonify(result))
```

# 余談
登録番号がわからない場合，まず氏名等で検索し，検索結果から得られた登録番号から詳細検索を行うことになります。
https://www.nichibenren.jp/member_general/lawyerandcorpsearchselect/lawyerInfoSearchInput/
に，検索したい要素を含んだrequestをPOSTし，返ってきたhtmlの表から登録番号を取得します。
下記をデフォルトの値として，必要な情報だけ上書きしましょう。

```python
search_requests = {
	"org.apache.struts.taglib.html.TOKEN": "", #トークンはセッションごとに設定します。
	"__Click":0,
	"membership_classification":"1", #会員区分。
	"registration_no": "", #登録番号
	"kana_last_name":"", #氏（かな）
	"kana_first_name":"", #名（かな）
	"last_name":"", #氏
	"first_name":"", #名
	"lawyers_association":"0", #弁護士会
	"sex":2,  #性別。0=女，1=男，2=不指定
	"office_address_state":0, #都道府県
	"office_address_city":"", #市区町村
	"office_address_building_name_etc":"", #ビル名・企業・団体等
	"firm_name":"", #事務所名
	"country_of_primary_qualification_country":0, #原資格国の国名
	"view_results":0, #結果表示順の制御
	"doLawyerInfoSearch":"検索"
}
```
複数の該当がある場合は先頭20件のみ返ってくるので，うまく絞り込む必要があります。
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十四章 モデルの整合性を維持する9 別々の道

# これまでの十四章
- [第四部 戦略的設計 第一四章 モデルの整合性を維持する](https://qiita.com/YasuhiroKimesawa/items/6e8e5503a05ce9515a79)
- [境界づけられたコンテキスト](https://qiita.com/YasuhiroKimesawa/items/901ac764340275b93d61)
- [継続的な統合](https://qiita.com/YasuhiroKimesawa/items/6a58743c90c5b707c29d)
- [コンテキストマップ](https://qiita.com/YasuhiroKimesawa/items/626384c84145870ec5af)

##  
- [共有カーネル](https://qiita.com/YasuhiroKimesawa/items/7895d8c28137bd34008a) 
- [顧客/供給者の開発チーム](https://qiita.com/YasuhiroKimesawa/items/c9668a437499897fa9d5)
- [順応者](https://qiita.com/YasuhiroKimesawa/items/ab4782d5e727075e2d87)
- [腐敗防止層](https://qiita.com/YasuhiroKimesawa/items/bf22f7a970d5ee29a111)

# 別々の道
## 統合にはオーバーヘッドが存在する

これまで読んできた、共有カーネル、顧客/供給者の開発チーム、順応者、腐敗防止層の各パターンのどれを採用しても、オーバーヘッドが必ず存在し、コストはとても高いものになります。テストも重点的に必要な箇所になりますし。

なので、そもそも本当に統合が必要かどうかは見極めなければいけません。
統合による利益はとても小さいかもしれませんし、もっと簡単な方法があるかもしれません。

## 統合しない！をまずは検討する

相手のシステムの情報は本当に必要なのか？こちらにあるデータだけでOkではないのか？相手のシステム側だけでなんとかならないか？
まずは統合しないということを検討しましょう。

別々の道に進んだあとに、やっぱり必要という場面が出て来るかもしれません。
そのときには、あらためて統合のパターンを検討すればいいと思います。
ブロックチェーンとスマートコントラクトの個人まとめ

12月1日当日ぐらいいきなり走り出した[一人で「イーサリアム・スマートコントラクト」 Advent Calendar 2017 - Qiita](https://qiita.com/advent-calendar/2017/ethereum-smart-contract)　、調査メモ程度のものでもありつつ、今日無事に最終日になりました。
バラバラ書いた内容をまとめたいのと、個人の感想程度のこれからのブロックチェーンとスマートコントラクトを書きたいところです。

## 書いた内容
- 初心者として、ビットコインと比較しながら、イーサリアムを調べてみた感じでした。
  - 最初はイーサリアムの定義とブロックチェーン周り
  - その後スマートコントラクト周りになり、言語仕様からデータ保存周り
  - そして、サービスを公開する際よくある、インフラ構成・マイグレーション周り
- 振り返ってみると、まだいろいろ課題がありますが、だいたいスマートコントラクトを使うサービスを開発できるじゃないかと思います。

## ブロックチェーン業界の課題
- インターネットは地球上に１つしかないですが、ブロックチェーンは、どんどん増えています。イーサリアム以降新しく作ったブロックチェーンは、ほとんどスマートコントラクトをサポートしているプラットフォームになっています。そして、チェーンとチェーンの間はあんまりやり取りができないので、ブロックチェーン上でアプリケーションを開発しようとする時は、最初に出てくるのは、どのブロックチェーン上で開発するかを選択しないと行けないところです。
- セキュリティ面は、アプリケーション開発側と利用側両方とも課題があります
    - アプリケーション開発側に対して、ブロックチェーンの論理上、データとスマートコントラクトの処理内容は全部公開されているので、穴があるとすぐに悪用されてしまいます。
        - この辺はコミュニティの力（[OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity)とか）を活用して、みんな一緒に考えてみる手もありますが、でも世界中に公開してしまうので、まだまだ不安です。
    - アプリケーション利用側に対して、事実上は長く覚えられないプライベート鍵を漏れてしまうと、ブロックチェーンから見ると、その資産を所有しなくなってしまいます。
        - ハードウェアのウォレットや、完全オフラインのウォレットなどの解決案もありますが、一般ユーザに対してハードルが高いなど、まだ課題があります。

## これから
- 2017年は仮想通貨がいろいろ意味で盛り上がっていました。仮想通貨は第一種類のブロックチェーンアプリケーションに過ぎないですが、**ブロックチェーンが信頼できるデータベースとして使える**ということをちゃんと証明したと思われるので、来る2018年は、ブロックチェーンの次のフェーズ、スマートコントラクトが盛り上がると信じています。
- スマートコントラクトは、まだいろいろ課題がありますが、Web 1.0時代のインターネットと同様に、革命的な新しいテクノロジーであり、いろんな可能性を示しました。ただ、まだどんなことができるかをみんな模索中の段階ですので、App Store 最初出た時代と同じ感じであり、**アイデア勝負** な時期であると感じています。
- 個人的には、年末年始でイーサリアム上で何かを作りたいと思っています。2018年は、日本のスマートコントラクトコミュニティ（@amachino さんが作ったコミュニティ[Ethereum 開発者向けコミュニティを作ったよ - Qiita](https://qiita.com/amachino/items/605ff76209d7193dc92c#fnref2)がありますよ〜）を広げつつ、イーサリアム以外のパブリックチェーンと、プライベートチェーンもすこし触ってみたいと思います。

では、メリークリスマス〜〜
【Lumen】Logファイルを日付ごとで出力させる

# Log出力のための設定

LumenでLog出力を有効にするには `$app->withFacades();` のコメントアウトを解除する必要があります。
単純にLog出力させるだけならこれだけでよさそうですが、日付単位でとなると、**bootstrap\app.php**をいろいろ編集する必要があります。
  
**bootstrap\app.php**

```diff:app.php
<?php

require_once __DIR__.'/../vendor/autoload.php';

// 以下を追加する
+ use Monolog\Handler\RotatingFileHandler;
+ use Monolog\Formatter\LineFormatter;

~~~略~~~

// コメントアウトを解除
- // $app->withFacades();
+ $app->withFacades();

~~~略~~~

// 以下を追加
+ $app->configureMonologUsing(function($monolog) {
+     $handlers[] = (new RotatingFileHandler(storage_path('logs/api.log'))) 
+                     ->setFormatter(new LineFormatter(null, null, true, true));
+ 
+     $monolog->setHandlers($handlers);
+ 
+     return $monolog;
+ });

```

上記の設定後は**storage\logs**以下に次のようにlogが吐き出されます。

![WS000065.JPG](https://qiita-image-store.s3.amazonaws.com/0/85815/99a7df9c-795b-37a7-0c69-6afffcdd64c6.jpeg)

  
  
もしlog名を変更する場合は**storage_pathg**の**api.log**部分を変更すればおｋ
（**[log名]-Y-m-d.log**のように吐き出されます。）
  
ちなみにLineFormatterクラスの引数のデフォルト値は以下のようにセットされるようです。
（詳しくはLineFormatterクラスのコンストラクタ参照）

```LineFormatter.php
public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false)
```

この辺の引数を渡してやれば日付部分のフォーマットを変更できそうです。


## 参考
- [Errors & Logging - Lumen - PHP Micro-Framework By Laravel](https://lumen.laravel.com/docs/5.5/errors#logging)
- [Lumenでログを出力する | Shimabox Blog](https://blog.shimabox.net/2017/02/14/output_a_log_in_lumen/)
- [lumenのログ出力制御（rotateの方法） - yasutomogのブログ](http://yasutomo.hatenablog.com/entry/2016/04/20/174409)
- [laravel - Lumen (5.1.6) daily log - Stack Overflow](https://stackoverflow.com/questions/37342418/lumen-5-1-6-daily-log)
MagicalRecordのログをオフにする

# MagicalRecordのログをオフにする方法を書いておく

何故そんなことを書くかというと、日本語でググると Cocoapods の設定でオフにする方法が出てくるから。

CocoaPodsで入れたMagicalRecordのコンソールログ出力を無効にする方法
http://tech-gym.com/2013/09/ios/1294.html

しかし、Cocoapodsで入れてない人も多いだろうし、そもそもメソッドでログをコントロールする方法がMagicalRecordのRepositryの[wiki](https://github.com/magicalpanda/MagicalRecord/wiki/Logging)に書いてある。

それによると、メソッドにenumセットしろとのこと

```
+ (void) setLoggingLevel:(MagicalRecordLoggingLevel)level;
```

具体的にはこう

```swift
// ログをオフにしたいなら
MagicalRecord.setLoggingLevel(.off)

// エラー以上のログにしたいなら
MagicalRecord.setLoggingLevel(.error)
```
Scratch1.4 を使ってみよう

Scratch 3.0 が開発中で、 Scratch 2.0 が、 Scrach SNS ( https://scratch.mit.edu/ ) で、利用されています。

Scratch 1.4 は、今でも元気に動作します。


# Scratch 1.4 

## Mac や Windows や Linux 上で　オフラインで利用できる

Scratch 1.4 は、 オフラインで利用できます。
以下から、ダウンロードできます。
https://wiki.scratch.mit.edu/wiki/Scratch_1.4

Mac、Windows、Linux　上で動作します。


## ソースコードも公開されています。

https://wiki.scratch.mit.edu/wiki/Scratch_1.4_Source_Code
Squeak/Smalltalk で書かれているそうです。
http://squeak.org/



## 機能

https://wiki.scratch.mit.edu/wiki/Scratch_1.4
https://wiki.scratch.mit.edu/wiki/Scratch_2.0

パッと見、個人的には、Scratch2.0 で、「More Blocks -> Make a Block」 より
拡張ブロックを追加できるように、なった点が大きめの違いにみえます。

※ Scrach1.4 から、 Scrach SNS ( https://scratch.mit.edu/ ) に投稿することもできます。


# 触ってみる

Scratch 2.0 と同じ感覚で使えました。

![スクリーンショット 2017-12-25 18.58.54.png](https://qiita-image-store.s3.amazonaws.com/0/54192/60fb57d4-b6da-dc93-491f-ee57bd9266f7.png)
UniRxのReactiveProperty他の配列を扱う場合の注意点

UniRxで配列を扱った時個人的に詰まったとこの解決
また、別にReactivePropertyに限った話ではないので注意。

##その１

UniRxでReactivePropertyを使うことはよくあると思う。
で、それを使って配列を扱いたいともちろん思うと思う。

```csharp:RxManager
public class RxManager : MonoBehaviour {

　　public StringReactiveProperty[] data;

}
```

 例えばこれを扱うとする。で、購読側がこんな感じ
やりたいことはdataが変更したらView　classにその変更をする通知をする

```csharp:Passenger
public class Passenger : MonoBehaviour {
	
　　　　　　　public RxManager manager;
　　　　　　　public View view;
   void Start(){
		//これは失敗する!
		for (int i = 0; i < manager.data.Length; i++) {
			manager.data[i].Subscribe (x => view.showButton (i,x));
		}

}
```
で、これは失敗する。
view.showButton (i,x)のiが
なぜか常にi = Lengthの値になるのだ

で、早速解決方法

```csharp:Passenger
public class Passenger : MonoBehaviour {
	
　　　　　　　public RxManager manager;
　　　　　　　public View view;
   void Start(){
		for (int i = 0; i < manager.data.Length; i++) {
            ////reactivepropatyで配列を扱う場合、一度変数を受ける           
            int a = i;
			manager.data[a].Subscribe (x => view.showButton (a,x));
		}

}
```

いいたいことはわかる。aもiも同じじゃないのかと。なぜ一回受けるのかと
でもまあちょっと古いC#クエリ式（Subscribe (x =>）でやる場合、こうなのだと思ってほしい。
また、補足であるがViewはこんな感じ

```csharp:View
public class View : MonoBehaviour {
		public Button[] itembtn;
		public Text[] itemtext;

		public void showButton(int num,string text){
			itemtext [num].text = text;
		}
	}
```

これでRxManagerの値を何らかの方法で変化させるだけでそれに応じたボタンのテキストも変更されるというわけ。
ItemMenu画面とかに使えると思う。


##その２ CopyTo()
を使うとストリームごとコピーしてしまう。

```csharp:ReactiveCopy
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;
using UnityEngine.UI;
public class ReactiveCopy: MonoBehaviour {
	public IntReactiveProperty[] tesint = new IntReactiveProperty[5];
	public IntReactiveProperty[] tesint2 = new IntReactiveProperty[5];


	void Start(){
		for(int i = 0;i < tesint.Length;i++){
			int a = i;
			tesint [i].Subscribe (x => tesint2[a].Value = x).AddTo (gameObject);
			tesint2 [i].Subscribe (x => Debug.Log ("s" + x));
		}
	}
	//copytoでストリームごとコピーされる。
	public void copyint(){
		tesint.CopyTo (tesint2, 0);

	}

}

```

これでcopyint関数を後から実行するとtestint[]のストリームがtestint2[]のストリームに上書きされる。
のでこのプログラムだとtestint[]の値を変更するとdebug.logが表示される。
解決法としては一回変数を受けてからなのだろうか、現在検証中。
NUnit逆引きメモ

必要に迫られたNUnit関連の逆引きメモになります。

# 例外が発生しないことを確認
```
Assert.DoesNotThrow(() => CallMymethod());
```
```
Assert.That(() => SomeMethod(actual), Throws.Nothing);
```
# log(標準出力)を確認

```
TestContext.WriteLine("test");
```

# 参考

* [logging - How can I add log messages to an NUnit test that will appear in a nant build execution? - Stack Overflow](https://stackoverflow.com/questions/13049700/how-can-i-add-log-messages-to-an-nunit-test-that-will-appear-in-a-nant-build-exe)
* [c# - NUnit: test with NO expected exception - Stack Overflow](https://stackoverflow.com/questions/9803839/nunit-test-with-no-expected-exception)
Microsoft Wordの２つの文書の差分をハイライトした文書を作成する方法

## この記事の内容
「２つの文書の差分をハイライトした文書」は論文誌の査読に対して修正稿を送る時に要求されることがあります。

この記事では、Microsoft Wordの２つの文書の差分をハイライトした文書を作成する方法を説明します。


## 方法

以下の２段階に分けて説明します。

1. 差分の変更履歴を作成する
2. マクロを動かす

### 1. 差分の変更履歴を作成する

> ※元々前回からの変更履歴があったら、2. に進んでください。


Word の 校閲 > 比較 を選ぶことで、元の文書と変更された文書の差分が変更履歴として記録された文書を作成することができます。



#### 1-1. メニューから「比較」機能を選ぶ
（英語だと Track Changes > Compare Documents...）

<img width="500" alt="Pasted_Image_12_25_17__17_48.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/a9c17f4f-edfb-9fef-16b3-39f292552925.png">


#### 1-2.  「元の文書」と「変更された文書」を選択してOKを押す

<img width="500" alt="Pasted_Image_12_25_17__17_51.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/7b536b55-b666-f444-7349-e0d18600c8b6.png">

#### 1-3. 差分が変更履歴として記録された文書が作成されるので保存する

<img width="500" alt="Pasted_Image_12_25_17__17_52.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/3dcea98f-f766-7189-4d8c-1bc21683427e.png">

### 2. マクロを動かす

#### 2-1. Visual Basic Editor を開く

<img width="500" alt="Pasted_Image_12_25_17__17_56.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/1e8dbbba-9a03-a105-95e4-24864a4f22f7.png">


#### 2-2. ハイライトしたい文書を選択する
ハイライトしたい文書を選択し、"Microsoft Word Objects" の下の "ThisDocument" を選択します

<img width="600" alt="Pasted_Image_12_25_17__17_59.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/d6a62834-82b0-1222-d6b1-c8c2b392ae5d.png">


#### 2-3. 右上のウィンドウにマクロをペーストして実行する

元の文書を保存するか聞かれるので、Yesで適当に保存。

```
Sub highlightChanged()
 
 Dim myRev As Revision
 Dim newDoc As Document
 
 ActiveDocument.TrackRevisions = False
 
 If ActiveDocument.Path <> "" Then
  If ActiveDocument.Saved = True Then
   Set newDoc = Documents.Add(Template:=ActiveDocument.FullName)
  Else
   If MsgBox("Save" & vbCr & _
        "Save?", vbYesNo, "If") = vbYes Then
    ActiveDocument.Save
    Set newDoc = Documents.Add(Template:=ActiveDocument.FullName)
   Else
    Exit Sub
   End If
  End If
 Else
  MsgBox "Please save"
  Exit Sub
 End If
 
 newDoc.Range.HighlightColorIndex = wdNoHighlight
 
 For Each myRev In newDoc.Revisions
 
  Select Case myRev.Type
 
   Case wdRevisionInsert
    With myRev.Range
     .HighlightColorIndex = wdYellow
    End With
 
  End Select

  myRev.Accept
 
 Next
 
 Set myRev = Nothing
 Set newDoc = Nothing
 
End Sub
```

<img width="600" alt="Pasted_Image_12_25_17__18_021_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/9a59b357-8353-3bf1-41b9-6b95bbf0b486.png">


差分がハイライトされた文書が生成されます。

<img width="500" alt="Pasted_Image_12_25_17__18_39.png" src="https://qiita-image-store.s3.amazonaws.com/0/18504/d73cd24e-4958-ef67-64f5-d2352643b2c1.png">

## 注意・参考

- 実行環境: Mac OS 10.10.5 (Yosemite), Microsoft Word for Mac Version 15
- 上のマクロでは「挿入」だけがハイライトされます。`Case wdRevisionInsert`の部分を他の変更履歴のタイプ（WdRevisionType）にも適用することでいろいろできるかもしれません。
    - WdRevisionType の定数はこちらを参考にしてください https://msdn.microsoft.com/ja-jp/library/microsoft.office.interop.word.revision.type(v=office.11).aspx
- Wordの「比較」機能 https://support.office.com/ja-jp/article/-比較-オプションを使用して文書の相違点を比較します%E3%80%82-dbfc7351-4022-43a2-a0c4-54d1898702a0
Arch Linux で Swift を使う

## インストール

```bash
yay swift-bin
```

## バージョンの確認

```text
$ swift --version
Swift version 6.0.1 (swift-6.0.1-RELEASE)
Target: x86_64-unknown-linux-gnu
```

## Swift の　プログラム

```swift:hello.swift
// -----------------------------------------------------------------------
//	hello.swift
//
//					Dec/25/2017
// -----------------------------------------------------------------------
print("*** 開始 ***")
print("Hello world!")
print("これはテストです。")
print("*** 終了 ***")
// -----------------------------------------------------------------------
```

実行

```text
$ swift hello.swift
*** 開始 ***
Hello world!
これはテストです。
*** 終了 ***
```

## コンパイル

```text:Makefile
hello: hello.swift
	swiftc hello.swift
clean:
	rm -f hello
```

コンパイル

```bash
make
```

実行

```text
$ ./hello 
*** 開始 ***
Hello world!
これはテストです。
*** 終了 ***
```

import Glibc を使えるようにする

```bash
sudo mkdir /usr/include/x86_64-linux-gnu
sudo cd /usr/include/x86_64-linux-gnu
sudo ln -s /usr/include/sys .
```

確認

```text
$ swift -I /usr/lib/swift/clang/include
  1> import Glibc
  2> random()
$R0: Int = 1804289383
  3> :quit
```


関連ページ
[Package Details: swift-bin 6.0.1-1](https://aur.archlinux.org/packages/swift-bin/)
OpenCV3.4をビルドしてWindowsにインストール

以前にほぼ同じことを書いてます[^1]が，変わったことといえば
- いろいろ最新バージョン。
- VTKはPythonでは使えないのでビルドしない。（以前はムダなことをしていた1）
- WindowsではConcurrencyのほうか速い[^2]ようなので，Intel TBBは使わない。（以前はムダなことをしていた2）
- XIMEAカメラは本家の用意してくれているXiApiPythonを使う方が便利そうなのでビルドしない。（以前はムダなことをしていた3）
- 以前はビルドにPython2系が必要だったがいつの間にかPython3だけでビルドできるようになっていた。
- `stringutils.cpp`にあったウムラウト記号がUTF-8コード表記になった（Ü→\xc3\x9c）のでコードの修正が不要になった。

[^1]: [WindowsにOpenCVをビルドしてインストールする](https://qiita.com/YutaYANAGITYAYA/items/545679c9fcf010056d57)
[^2]: [OpenCVの並列化クラスParallelLoopBodyとparallel_for_](https://qiita.com/fukushima1981/items/02d6c034ca0375496b65)

# 環境
- Windows10 (64bit)
- Visual Studio 2017 Community
- Python 3.5.4
- OpenCV 3.4.0
- Eigen 3.3.4
- Qt 5.10.0

# OpenCVのビルド
### 準備
1. [Python3](https://www.python.org/downloads/)+NumPy，[Visual Studio](https://www.visualstudio.com/ja-jp/downloads/download-visual-studio-vs.aspx)，[CMake](https://cmake.org/download/)をインストール。
2. GitHubからOpenCVのソースをZipでダウンロード（[opencv](https://github.com/opencv/opencv), [opencv_contrib](https://github.com/opencv/opencv_contrib)）。それぞれ`C:\opencv\source`，`C:\opencv\opencv_contrib`に展開。
3. [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page)のlatest stable releaseをダウンロード。`C:\opencv\dev\eigen`に展開。
4. [Qt](https://www.qt.io/download-open-source/#section-2)をインストール。コンポーネントの選択ではQt>Qt 5.10.0>MSVC 2017 64-bitのみを選択しインストールする。
5. 以下のようにパスを通す。


    | 環境変数のパスを設定           |
    |:-----------------------------|
    | C:\opencv                    |
    | C:\opencv\dev\eigen          |
    | C:\Qt\5.10.0\msvc2017_64\bin |

### ビルド
1. CMakeを起動．source`C:\opencv\source`，build`C:\opencv\build`としてConfigureをクリック。
2. 以下の設定が完了するまでConfigureを何度か押して赤い項目をなくす。

    | 以下チェックを入れる        |
    |:--------------------------|
    | WITH_OPENGL               |
    | WITH_QT                   |

    | 以下チェックを外す          |
    |:--------------------------|
    | WITH_CUDA                 |
    | WITH_CUFFT                |

    | Name                      | Value                              |
    |:--------------------------|:-----------------------------------|
    | CMAKE_INSTALL_PREFIX      | `C:/opencv/install`                |
    | OPENCV_EXTRA_MODULES_PATH | `C:/opencv/opencv_contrib/modules` |



3. 赤い項目がなければGenerate→Open Projectをクリック。Visual Studioでプロジェクトを開く。
4. Visual Studioでプロジェクトが開かれたら，構成`Release`，プラットフォーム`x64`とし，”ALL_BUILD”を右クリック→ビルド。エラーがなければ”INSTALL”を右クリック→ビルド。
5. `C:\Python35\Lib\site-packages`内に「cv2.cp35-win_amd64.pyd」ができる。
6. `C:\opencv\install\bin`にパスを通す。
7. 以上。


# 注意点
CMakeを起動する前にQTのパスは通しておく。くらいです。
以前よりすごく簡単になりました。
gitのssh接続に使用する~/.ssh/configの設定について

##git cloneできなかったお話

git cloneをしようとして詰まった話です。

他のサイトを閲覧していると以下のコードで可能だと書いてあります。しかし自分の環境だと実行されずエラーを出力しました。

```
git clone [リポジトリアドレス]
```

```
# git cloneを実行
$ git clone git@github.com:kawahara-hiroyuki/kawa.vimrc.git

#以下エラー内容
Cloning into 'kawa.vimrc'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```




##~/.ssh/configの設定について
調べるとホスト名の設定が失敗している時に出るエラーの一つだそうです。
ホストの設定をしてある`~/.ssh/config`を以下のように記述していました。
またそれぞれの行の意味を下に記述します。

```
# ~/.ssh/config
Host gitgit
  User gituser
  HostName github.com
  IdentityFile ~/.ssh/test
  IdentitiesOnly yes
```

|Host|<style="color:green;">ホスト名を指定。</style>|
|---|---|
|User|gitの通信をするユーザーを指定|
|HostName|接続先の設定。FQDNを使用している。<br>[こちらを参考](https://trueman-developer.blogspot.jp/2017/01/fqdnipwindowsmaclinux.html)にgithubのIPアドレス192.30.253.112でも良い|
|IdentityFile|秘密鍵の置き場所。今回は~/.ssh/testという秘密鍵を使用している。<br>秘密鍵については[こちらを参考](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)。|
|IdentitiesOnly|使用する秘密鍵をIdentityFileだけにする。<br>デフォルトでは**no**であり、**no**だと全ての秘密鍵を試そうとする。|


##git cloneコマンドの内訳

git cloneコマンドに使う引数の設定は以下のようになっています。
コマンドでssh接続するのと似た感じでしょうか。

```
git clone [User]@[Host]:[リポジトリアドレス]
```

今回はgithubに接続しようとします。
[User]はgithubの設定に従って、`git`を使用します。（省略する場合は、`~/.ssh/config`のUserが使用されます）。
[Host]は`~/.ssh/config`にしたがって`gitgit`を使います。

##`~/.ssh/config`を考慮して再度clone

具体的には、今回は以下のコマンドが正解でした。

```
# 今回の場合のcloneするコマンド
git clone git@gitgit:kawahara-hiroyuki/kawa.vimrc.git

# ~/.ssh/configのUserをgitにしてる場合は以下でも可
git clone gitgit:kawahara-hiroyuki/kawa.vimrc.git
```