OmniAICreator/Qiita-1.07M huggingface dataset:
python 自分メモ

# はじめに
今月よりpythonの案件に突っ込まれたので、2週間で学んだことを自分用の備忘録としてメモっておく
なお、基本的な文法も記述していくが、変数宣言とか簡単な比較演算子は対象外としてく
※ちょいちょい忘れそうなら追記します

# 基本文法
基本的なのをざっくり書いていきます。

###for文

```
for 変数名 in 繰り返し回数:
   処理
```

###if文

```
if 条件文 :
  処理
elif:
  処理
else
  処理
```

###関数定義

```
  def 関数名(self):
	処理内容
```


###デコレーター

```
# ロギングデコレータ
def logging(func):
    def wrapper(obj, *args, **kwds):
        print("{} {} {} {} args={} kwds={}".format(
            datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "INFO", func.__qualname__, "START", args, kwds))
        rtn = func(obj, *args, **kwds)
        print("{} {} {} {} return {}".format(
            datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "INFO", func.__qualname__, "END", rtn))
        return rtn
    return wrapper
 
```

### 文字列置換

文字列に変数を埋め込める
C言語や！

```
name = 'hoge'
print ('Hello, %s' % (name))

# 実行結果
Hello, hoge
```

### if __name__ == '__main__':について
上記の記述後の処理は、モジュール化して実行された場合実行されない
テストコードとかに便利!


# ライブラリ系統

### pandas

```
# DataFrameからnumpyに変更する方法
   変数名 = df.values

# 値の取り出し方

print (df) # 全件出力

print (df['カラム名']) # 指定したカラムのみ抜き出す

print (df [['カラム名','カラム名']])  #複数のカラムを抜き出す

print (df[0:3]) # 0から３行目を出力する

df[df > 0] # 0より上の要素はそのまま返し、それ以外はNaN
```

### numpy
配列同士で足し引きができる！

```
array1 = np.array([[1, 2], [3, 4]])
array2 = np.array([[10, 20], [30, 40]])
array3 = array1 + array2
print(array3)

#実行結果

[[11 22]
 [33 44]]
```

#所感

今までjavaがメインだったけど、pythonの方が好きになりそう！
構文自体はわかりやすい！

随時更新していけたらいいな〜
【Unity】UnityでFacebook用3D画像を作る

Oculus Quest用自作アプリのスマホミラーリングができなくて記事をあさっていたら、[こんな記事](https://www.oculus.com/blog/introducing-new-features-for-3d-photos-on-facebook/?locale=ja_JP)を見つけました。
![58269699_1238655549634251_3034182755815522304_n.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/6c8a2afd-af3e-c0f2-d4c9-de01d9a5cb0c.gif)

えっ！こんなに簡単に？
ということで、ちょっと試してみました。

まずは普通にレンダリングした絵を用意します。
![testpic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/64df9f00-a6dc-c44b-1587-8fef94c79882.jpeg)

自分は[Unity Recorder](https://assetstore.unity.com/packages/essentials/unity-recorder-94079)で1フレームだけキャプチャしました。
Unity Recorderはpackage manager > preview からも手に入ります
![2019-06-15_125548.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/bc602e57-f6a9-fb89-441d-fbf50693bb03.png)


次にdepth画像を用意します
![testpic_depth.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/198e5910-ae44-d016-7fdd-4084c7b9f620.jpeg)

depth表示については[こちら](http://nn-hokuson.hatenablog.com/entry/2018/02/08/194943)からお借りしました。

風景等の距離があるものをキャプチャする場合、カメラのnear clipを大きめにするときれいに出るようです
![2019-06-15_123754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/fcb3aedf-9629-4416-7cb0-460746e09b8e.png)

画像ができたら、ファイル名を

```
test.jpg
test_depth.jpg
```

のようにします。この時、

```
test_2.jpg
test_2_depth.jpg
```

のように '_'が2つ以上入っていると変換してくれないようです。

変換結果は[こちら](https://youtu.be/TpVZpNs9XM8)
![fb3d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/da5ab7c1-1a9a-3bca-9b66-602550df8adf.gif)


うまくできました！
（・・・Oculus Questミラーリングのことを忘れてる・・・）
RustのreqwestでGetした情報のBody情報を表示する

# はじめに
RustでGetした情報を得るプログラムを書いていたのですが、reqwestの公式の通りに書いてもエラーになってしまいました。
Rustは始めたばかりで良くわからないのですが、とりあえずメモとして残しておきます。

# 環境
Rustの場合、何を残しておけば良いか分からないので、とりあえず必要そうな情報をのせておきます。

```
$ cargo -V
cargo 1.34.0 (6789d8a0a 2019-04-01)
$ rustc --version
rustc 1.34.1 (fc50f328b 2019-04-24)
$ rustup --version
rustup 1.18.3 (435397f48 2019-05-22)
```

# まずはエラーとなるケース
公式のサンプルを元に書くとこんな感じで取れそうな気がしますが、これだとエラーになります。

``` main.rs
extern crate reqwest;

fn main() {
    let res = reqwest::get("https://www.google.co.jp/")?.text();
    println!("{:?}", res);
}
```

``` sh
$ cargo run
   Compiling hello v0.1.0 (/Users/tasogarei/rust/hello)
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
 --> src/main.rs:4:15
  |
4 |     let res = reqwest::get("https://www.google.co.jp/")?.text();
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `std::ops::Try` is not implemented for `()`
  = note: required by `std::ops::Try::from_error`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `hello`.

To learn more, run the command again with --verbose.
```

いや、`Result<Response>`で返ってくるねんけど！と言いたくなりますが、なぜかエラーになります。

# エラーがでないように修正
とりあえずの解決法

``` main.rs
extern crate reqwest;

fn main() {
    let res = reqwest::get("https://www.google.co.jp/").unwrap().text();
    println!("{:?}", res);
}
```

`Result`ではあるので、とりあえずとして`unwrap()`すれば取り出せます。
ただし、`Result`はエラーが返却される可能性がある型なので、本来は`match`するなりなんなりしてきちんとエラーについても判定させるべきではあります。

今回は自分用として作成しているので、気にしないこととします。
[Swift] enumにイニシャライザを宣言すると、例えば文字列の列挙を型安全に扱える

**前提環境**

- Xcode 10.1
- Swift 4.2

---

enumのTipsです。
想定ケースとしては、APIのレスポンスで、列挙値が文字列として返却されてくる、とか。

例えば、
"company"というkeyのvalueは、

- "google"
- "apple"
- "facebook"
- "amazon"

の何れかが入っている、とします。
このコードのように、文字列リテラルで判定するのは「型安全」ではありません。

```swift
if company == "google" {
    print("google")
} else if company == "apple" {
    print("apple")
} else if company == "facebook" {
    print("facebook")
} else if company == "amazon" {
    print("amazon")    
}    
```

そこで、こんなenumの使い方のご提案。
イニシャライザがポイントになります。

```swift:playground
import Foundation

enum Company: String {
    case google
    case apple
    case facebook
    case amazon
    
    init(_ value: String) {
        guard let company = Company(rawValue: value) else {
            preconditionFailure("Company is undefined.")
        }
        self = company
    }
}

// APIのレスポンス文字列をenumに変換する想定
let company = Company("apple")

switch company {
case .google:
    print("google")
case .apple:
    print("apple")
case .facebook:
    print("facebook")
case .amazon:
    print("amazon")
}
```

**メリット**

- enumの言語仕様によって網羅性のチェックが行われますので、列挙値が増えた際に修正漏れを防げます。
- 想定外の値が入ってきた場合のチェックロジックを集約でき、防衛的プログラミングが可能です。
- Xcodeの機能にて一括リネームが可能ですので、リファクタリングしやすいです。
スクラムが「高速ウォーターフォール」ではないことを説明した資料 (DoD, 完成の定義)

# はじめに

- つい最近組織の偉い方と1 on 1 をさせていただく機会があり、そのとき表題の件を説明した内容をメモも兼ねて書き起こしたいと思います。
 - その方はしきりに「1ヶ月のウォーターフォールを何回も繰り返すのとスクラムの違いがわからない」とおっしゃっていたので、これを期に自分なりの理解を説明しようとして作ったのがきっかけです。
- なるべくエンジニアではない方にもわかりやすいように抽象的な表現も使っています。組織をアジャイルにしていこうという方などの一つの参考となれば幸いです。





# スクラム と ウォーターフォールの違い

- **スクラム と ウォーターフォールでは「品質」に対する考え方が大きく違う**

![Screenshot from 2019-06-15 11-11-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200306/d7102100-d27a-9e3a-dd76-84dae757f60f.png)

### お茶をプロダクトとした場合の例

- ウォーターフォール...
 - お茶の「美味しさ」「デザイン」を先に追求し、**「飲み物としての安全性」はその後できる限り対応する**
- スクラム... 
 - お茶の**「飲み物としての安全性」は常に担保**しつつ、「美味しさ」「デザイン」を追求する

- 誤解を恐れずにすごく極端な例でいうと、「**味はとても美味しいし、見た目の色もラベルのデザインもめちゃめちゃキャッチーだけど、毒があります。でも毒はなるべく取り除きました。**」というのがウォーターフォールで、「**飲み物として暗黙的に守られている品質や安全性はいつでも担保してあります。味とか見た目とかデザインは徐々に良くしていきます。**」というのがスクラムの考え方





# スクラムには Done と Undone という考え方がある

- 上の例のように、**技術品質を担保しつつ**毎スプリントごとに「出荷可能」なプロダクトをリリースするには、**Doneの定義 (Done + Undone)** を守り続けなければいけない。Doneの定義を満たしていないプロダクトはリリースしてはいけない。

![Screenshot from 2019-06-15 11-16-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200306/761a8f5f-1f19-0754-d651-0819319d2652.png)

- しかし現実は、各スプリントごとにすべてのDoneの定義を満たすのは不可能である。
 - よって各スプリントごとに達成できるものを**「Done」**とし、そうでないものを**「Undone」**と分ける
- 繰り返しになるが、**プロダクトをリリースするためには「Done」と「Undone」**の両方を満たす必要がある。






# リリーススプリント (炎上スプリント)

- リリースするためには、直前に「リリーススプリント」を実施し、Undone のものを実行しなければいけない。しかし**長く放置されたUndone は期限内に間に合わず炎上の原因**になる。

![Undone](https://less.works/img/framework/undone-work/xcausing-risk-and-delay.jp.png.pagespeed.ic.QXZvoiylmd.webp)
出典: https://less.works/jp/less/framework/definition-of-done.html

## Undone の扱い方
- スクラムでは**定期的(各スプリントごと)にUndoneを実行**する必要がある。Undoneは上図にあるように、放置すればするほど作業規模が曖昧になり、**予定していたリリース日に間に合わないというリスク**が大きくなる。
 - しかし、**Undoneは後半まで放置してしまいがち**である。Undone をやらずにプロダクトバックログアイテムの消化を進めていけば、**進捗していると錯覚**してしまうからである。もっというとそこには、**「早く進捗させないといけないという周りからの外圧」**があるのかもしれない
  - 定期的にUndone を実行するよう、スクラムマスターはPOと開発チームを促していく
- ウォーターフォールは工程の後半にUndoneに相当するもの実行するという点でスクラムとは大きくアプローチが異なる
*※ 余談ですが、私も様々な要因からUndone を溜め込みまくり、リリース直前になって遅延報告するという「いきなり赤信号問題」を経験しました。特にスクラムを組んで間もないことはよく起きがちなのかなと思います。*




# Undone は Done にしていかないといけない

- 世の中はいかにUndone をDone にするかでせめぎ合っている
- Undone がなくなれば、スプリントごとに品質担保されたプロダクトがリリースできる
 - 更に進化すると「リモートブランチへのPush」がリリースの単位になるかもしれない
- Undone を Done にする典型的な例は、品質課によるテストを自動化するというもの

![Screenshot from 2019-06-15 11-38-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200306/97b4233d-c6d0-5f8b-9df0-2ad736a185c1.png)



# これから考えたい課題

- 偉い方からは一定の理解を得られたかなと思いましたが、「アジャイルで開発しても、社内の連携先がアジャイルではないのでボトルネックになってしまうことが多い。開発チームが可愛そうだ。」というフィードバックをいただきました。
- 確かにそれなりに大きい組織だと、システム間がスパゲッティ状態になっており「Aシステムを使いたいのに、Aシステムが連携しているBとCシステムが不安定だから今は連携しないでほしい」みたいなことがあったりします。
- また、連携したいシステム先の工数のキャパシティが一杯で、**作ったシステムに遷移できるよう、リンクを貼ってもらう修正作業に5ヶ月待ち**という状態も発生したりしています。
- こうなるとボトルネックとなりうるシステムと連携するシステムは延々と開発できない(というかリリースできない) ことになってしまいます。
- 今現在この課題の解決案を私は持ち合わせていません。組織をアジャイルにするためには、こういった課題にアプローチしていかないといけないんだろうなあと思う今日この頃でした。
DBpediaを使って歌手の一覧を取得する

# DBPediaとは？
クエリ言語SPARQLを用いることで日本語版のWikipediaから情報を抽出できるウェブサービスです。

http://ja.dbpedia.org/

http://ja.dbpedia.org/sparql

# 今回の目標
ソニー・ミュージック・エンタテインメント・ジャパン（以下SMEJと略記）に所属している歌手の一覧を取得します。

Wikipediaからデータを取得するため、知名度の低い情報が掲載されていない可能性が高いなどの問題があります。が、今回は気にしないことにします。

# SMEJのカテゴリに存在するページを取得する
Wikipediaには「Category:SMEJのアーティスト」というページが存在することを利用し、以下のクエリを実行します。

```sparql
PREFIX dbpedia-owl:  <http://dbpedia.org/ontology/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX category-ja: <http://ja.dbpedia.org/resource/Category:>

select distinct ?artist where {
  ?artist rdf:type dbpedia-owl:Artist.
  ?artist dbpedia-owl:wikiPageWikiLink category-ja:SMEJのアーティスト.
}
```

歌手の一覧が返ってきます。この結果には「Category:SMEJのアーティスト」にある項目のみが含まれていて、下位カテゴリに属する項目は含まれていません。


# SMEJの下位カテゴリを取得する
アーティスト一覧を取得するには、「Category:SMEJのアーティスト」だけでなくその下位に存在するカテゴリに属する記事を再帰的に取得する必要があります。

```sparql
SELECT DISTINCT *
WHERE {
    ?categories skos:broader{0,10} <http://ja.dbpedia.org/resource/Category:SMEJのアーティスト> .
}
```
`skos:broader{数字, 数字}`は再帰の深さ（0から10）を指定しています。

この結果には「Category:シャ乱Qのアルバム」や「Category:ハロー!プロジェクトのコンサート」など今回は必要ない（歌手名でない）ものが含まれています。

# SMEJとその下位カテゴリに含まれるアーティスト一覧を取得する
上記の2つを組み合わせることで「Category:SMEJのアーティスト」またはその下位カテゴリに属する歌手一覧が取得できます。

```sparql
PREFIX dbpedia-owl:  <http://dbpedia.org/ontology/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX category-ja: <http://ja.dbpedia.org/resource/Category:>

select distinct * where{
    ?categories skos:broader{0,10} category-ja:SMEJのアーティスト .
    ?singer rdf:type dbpedia-owl:Artist .
    ?singer dbpedia-owl:wikiPageWikiLink ?categories .
}
```

# アーティストの名前をテキストで取得する
それぞれの歌手の名前をプレーンテキストで取得します。名前は http://ja.dbpedia.org/property/name と http://ja.dbpedia.org/property/名前 のいずれかに存在するので、FILTER式を用いてどちらの情報も拾うようにします。

```sparql
PREFIX dbpedia-owl:  <http://dbpedia.org/ontology/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX category-ja: <http://ja.dbpedia.org/resource/Category:>
PREFIX property: <http://ja.dbpedia.org/property/>

select distinct ?name where{
    ?categories skos:broader{0,10} category-ja:SMEJのアーティスト .
    ?singer rdf:type dbpedia-owl:Artist .
    ?singer dbpedia-owl:wikiPageWikiLink ?categories .
    ?singer ?filter_name ?name .
    FILTER(?filter_name = property:name || ?filter_name = property:名前)
}
```
ドラッグとポインターハンドラのコールバック順序とハマりどころ (unity)

# 前提
- Unity 2018.4.2f1
- `IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IBeginDragHandler, IDragHandler, IEndDragHandler`のコールバック

# 発生順序
1. OnPointerDown ～ ダウンした
1. OnBeginDrag ～ ダウン後、最初にポインターが動いた
1. OnDrag ～ ドラッグ開始後、さらにポインターが動いた
1. OnPointerUp ～ アップした
1. OnPointerClick ～ アップしたオブジェクトはダウンしたオブジェクトと同じだった
1. OnEndDrag ～ ドラッグが終わった

# ハマりどころ
- クリックが検出されたときは、既にポインターアップ済みです。
    - 「ダウンで情報を生成してアップで破棄」とかだと、クリックでは既に破棄されていて失敗します。
    - 「ダウンで生成」、「アップの際にダウン時のオブジェクトの上にいなければ(`!PointerEventData.hovered.Contains (PointerEventData.pointerPress)`)破棄」、「クリックで破棄」なら大丈夫のはずです。
- ドラッグ終了が検出されたときは、既にアップ&クリック済みです。
    - 上記の「ダウンで情報を生成してアップまたはクリックで破棄」だと、同様に失敗します。
    - 上記の条件に、さらに「ドラッグ中でなければ(`!PointerEventData.dragging`)」を加えて、「ドラッグ終了で破棄」することになります。
Python Pandasでpandas.io.dataをimportしたら"No module named ‘pandas.io.data’"が出た場合を解決

#pandasで簡単に株式データが取得しようとしたらエラーが
pandasで簡単に株式データが取得できるということで、'pandas.io.data'を使ってみたところ"ModuleNotFoundError"となってしまいました。
<img width="557" alt="スクリーンショット 2019-06-15 11.43.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113808/03d33f37-0a1c-826e-5208-c7471af81e38.png">
#原因はpandas.io.dataはもう使えないとのこと
検索結果によるともうpandas.ip.dataは使えないとの記事が多数ありました。'pandas_datareader'を使うようです。
#Anacondaで環境にpandas_datareaderを追加
自分の環境はAnacondaからpython3を使っていますのでAnaconda-Navidatorに助けてもらってモジュールを導入することにしました。'pandas_datareader'で検索してもモジュールが発見できず・・・
'pandas-datareader'と検索するとモジュール発見！
<img width="888" alt="スクリーンショット 2019-06-15 11.41.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113808/d6770021-8ef3-e3ac-a766-c501b837620f.png">
追加インストール
<img width="408" alt="スクリーンショット 2019-06-15 11.41.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113808/94bb631f-27a5-338e-d01c-69c9fad807df.png">
#早速pandas_datareaderをお試し
```python:pandas-datareader.py
# Yahoo.comからデータを読み込めるように
from pandas_datareader import DataReader
```
こんどはエラーありませんね。コードを書く時は'pandas_datareader'ですね。アンダースコアーにして利用します。

```python:pandas-dataget.py
# Pythonで日付と時刻を扱うためのモジュール
from datetime import datetime

# GAFAの株価をとります。
tech_list = ['GOOG','AAPL','FB','AMZN']

# 直近1年間のデータを取得。
end = datetime.now()
start = datetime(end.year - 1,end.month,end.day)

# それぞれの企業ごとに、Yahoo.comのサイトからデータを取得
for stock in tech_list:   
    # それぞれの名前でDataFrameを作ります。
    globals()[stock] = DataReader(stock,'yahoo',start,end)
# FaceBookのデータの状態を確認
FB.tail()
```
> 引用：Udemy「実績Pythonデータサイエンス」より

<img width="608" alt="スクリーンショット 2019-06-15 12.25.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113808/9f203277-c695-7140-031b-850ba3eff582.png">


実際の株価情報と比較してみましたが、だいたいあっている感じですね。
<img width="681" alt="スクリーンショット 2019-06-15 12.15.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113808/cfd74497-0a23-dfba-9e47-5acc83e09522.png">

無事第一関門クリアです。さらに株価使ったデータ解析にトライしていきます。
OCR初心者が５９重ナンプレ解読に挑戦してみた

## 59重・合体ナンプレの画像

![test_sudoku_81x57_03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428079/b6b9de80-15e0-2323-07b0-6adc42a1480c.jpeg)

## きっかけ
合体ナンプレを解くアルゴリズムを開発したが、数字を毎回入力するのが面倒くさくなってきたので自動化することにした。
59重ナンプレになると、9x9グリッドが7x5の35個あり、セルの数は２０００個ほどになってしまう。
(これを解いてしまう人は天才だと思う)

## OCRは難しい
OCRは"Optical Character Recognition"ということで画像から文字を認識してデータ化するシステムやアルゴリズムのこと。
入力値はデジタルデータだが、きちんと正規化されていないために、正確なOCRを作ることは難しい。
特に手書きの場合は、困難を極める。
この画像は１にも２にも７にも読めてしまう。
![127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428079/4cec6813-ac2f-f31f-f995-d607e586e7cd.png)

OCRに限界を感じる人もいる。
名刺を管理する株式会社SanSanは、OCRの限界を感じ、人海戦術で文字を解読している。
https://jp.sansan.com/knowledge/ocr/

## 今回の画像の制約
・写真に対応（スキャナやキャプチャももちろんOK)
・基本まっすぐに撮影してもらうが、少しの傾きはOK
・明るさは統一されてなくてもいい。
・紙が多少よれていてもいい。
・周りに関係ない画像があってもいい。
・１セル45pxは確保してもらう。
・手書きには対応しない。

## 使用したツール
・Ruby
・RMagick(ImageMagick)

## 処理の流れ
処理は大きく分けて３つになる。

①セルを認識する
②セルの中の数字を認識する
③セルの位置関係から、9x9グリッドの重なりを計算

### ①セルを認識する
最初に考えたのがセルを囲む直線を認識する方法だが、紙のよれや傾きがあり、セル数が多くなると直線でなくなるので、正しく認識できない。
そこで、１つ１つのセルを地道に認識する方法を選んだ。
セルの４つの頂点を認識し、１つのセルを認識したら上下左右にセルがないかを探索するようにした。
頂点の認識はパターンマッチングによって行った。

### ②数字を認識する
最初にtesseractを使おうとしたが、思いのほか識字率が悪く、使えない。
認識する必要があるのは０～９までの数字だけなので、自前で用意することにした。
図書館で借りた本を参考にした。

１．２極値化
２．数字を識別するたの閾値を５０種類以上用意した。
　　閾値の例、２極値化した画像のx方向、y方向の重心がどこにあるかというような値になる。
　　０の場合のx方向、y方向の重心はほぼ真ん中になり、極端に外れる場合は0でないと認識する。
３．５０種類以上の閾値をクリアしたものが残った数字となる。
　　数字が残らなかったり、複数ある場合はエラーとなる。
(セルと数字を認識後)
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428079/452d2e4d-2ac5-6212-c336-2a1b316d568f.png)


### ③セルの位置関係から、9x9グリッドの重なりを計算
セルが認識されているので、そこから、35個の9x9グリッドがどのように重なっているか計算し、正規化されたデータとする。
横幅=81、高さ=57をインプットとして、自動で正規化されたデータにしている。
(正規化されたデータの一部)
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428079/74fb50e3-464b-37f2-354d-d6e63689876d.png)


## OCRを実装してみての所感
・この値がこうだからこの画像は3だみたいな決め方をすると失敗する。
・閾値を用意する場合はかなり余裕をもった値にする。
・コントラストが小さいとエッジを抽出できないので失敗する可能性が高くなる。
・画像によれ・たわみがあるとセルの大きさが大きく変わってしまうので正しく認識できなくなる。
・今回は２極値化(モノクロ)を採用したが、元データ(グレースケールのまま)を使用した方が精度は高まるだろう。
・写真でなく、スキャナを利用すればかなり精度は高くなるはず。
・純粋な計算アルゴリズムはRubyだと遅くなるが、今回のコードをC言語で書いたら大変なことになっただろう。
・茶色っぽい紙と薄い字の組み合わせは最悪。
・数字だけでも大変だから、日本語全体で特定の閾値を用意するのには無理だ。
・５９重合体ナンプレは実物のサイズが大きいので、１つ１つのオブジェクトの画像が荒くなる。
・ パズルを解く時間（数秒)　<<<<<< OCRの時間(数百秒)
・成功のポイントは折り目やしわをなくし、明るさを均衡にして、なるべくまっすぐに撮影する！！

## 参考にした本
たまたま図書館にあった。
![51lvdK3FXnL._SX351_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428079/0bef744c-1fff-43e8-1f53-7a61afdc2b6e.jpeg)

## 合体ナンプレを自動解読するサイト
[合体ナンプレを自動解読するサイト](https://www.sentohsharyoga.com/puzzle/sudoku_multi/image/free_size)
Wi-FiのWeb認証を自動化する

公衆Wi-Fiの多くは接続時にログインを要求されます．
しかし，毎回アカウントやパスワードを入力するのが面倒なのでこれを自動的にログインできるようにします．

Linuxでの設定は以下で紹介されています:
- [【小ネタ】Web認証の自動化【Linux編】](https://qiita.com/kiida/items/c6af1e3708c5fadc1c23)

ここではmacOSにおける設定を行います．


### 1. Captive Network Assistant

macOSではウェブ認証が必要なネットワークに接続するとCaptive Network Assistantという専用のアプリが自動的に起動して認証画面が表示されます．
このアプリが起動すると他からの通信ができなくなってしまうので，以下のコマンドでこれの起動を停止します．

```
$ sudo defaults write /Library/Preferences/SystemConfiguration/com.apple.captive.control Active -boolean false
```

ちなみに以下で元の設定に戻せます:

```
$ sudo defaults delete /Library/Preferences/SystemConfiguration/com.apple.captive.control Active
```

この設定を行った後，一度再起動してWi-Fi接続時にCaptive Portalの画面が開かなくなればOKです．
ログインする際はブラウザで適当なところにアクセスすると認証画面にリダイレクトされます．

### 2. ログイン用スクリプト

ユーザー認証のページを調べるなどして以下のようなログインスクリプトを適当な場所に保存してください．

```bash
#!/bin/bash

SSID=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -I | awk '/ SSID:/ {print $2}'`

if [ "${SSID}" = "[対象Wi-FiのSSID]" ]; then
    ping -o -c 100 1.1.1.1
    curl https://example.com/login -F "user=USERNAME" -F "password=PASSWORD"
fi
```

次の手順でWi-Fiへの接続を検出した際にこのスクリプトを実行するようにするのですが，以下の方法では検出のタイミングと疎通のタイミングがうまく合わなかったので適当なところにpingを送って疎通できるまで待つようにしました．


### 3. LaunchAgents

Wi-Fi接続時にスクリプトを実行するために`~/Library/LaunchAgents/WifiAutoLogin.plist`として以下の内容を保存します．

```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>WifiAutoLogin</string>
  <key>ProgramArguments</key>
  <array>
      <string>[ログイン用スクリプトへの絶対パス]</string>
  </array>
  <key>WatchPaths</key>
  <array>
    <string>/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist</string>
  </array>
</dict>
</plist>
```

そして以下のコマンドで作成したplistをロードします．

```
$ launchctl load ~/Library/LaunchAgents/WifiAutoLogin.plist
```

これでWi-Fiに接続した際に自動でログインできるようになりました．
【console】rails c RAILS_ENV=testは廃止予定なのでrails c -e testを使う

はじめてのQiita記事投稿になります。ものっそい緊張しております。

# 概要
Railsで個人開発をしているときにRSpecを書こうとしたときの話です

FactoryBotなどの挙動をtest環境のconsoleで確認しようと思い、

```
rails c RAILS_ENV=test
```

と打ったのですが、ここでメッセージが。

```
DEPRECATION WARNING: Passing the environment's name as a regular argument is 
deprecated and will be removed in the next Rails version. Please, use the -e
option instead.
```
要は環境の名前を変数として渡すのはアレなので-eオプションを使ってね！ってこと。

# 解決策

```
rails c -e test
```

とすればWARNINGも出ない。問題解決！
【Node.jsからMySQLに接続】

以前バイト先でNode.jsを扱っていたので、忘れないようにNode.jsでMySQLに接続する方法を備忘録として残そうと思います。
今回のソースコードではローカルのDBに接続しています。
## 開発環境
- macOS Mojave バージョン10.14.4
- Node.js v11.6.0
- npm 6.8.0

## ディレクトリ構造

```
NodeTest/
├ app.js
├ mysqlConnection.js
├ package-lock.json
├ package.json
```

## モジュールのインストール
```
$npm install mysql
```
## DBを定義
```mysqlConnection.js
//mysqlモジュールを呼び出します
var mysql = require('mysql');

//DBの定義
var dbConfig = {
  host     : 'localhost', //接続先ホスト
  user     : 'root',      //ユーザー名
  password : '',          //パスワード
  database : 'test'       //DB名
};

var connection;

function handleDisconnect() {
	console.log('create mysql connection');
	connection = mysql.createConnection(dbConfig); //接続する準備

    //接続
	connection.connect(function(err) {
		if(err) {
			console.log('error when connecting to db:', err);
			setTimeout(handleDisconnect, 2000); //2秒待ってから処理
		}
	});

    //error時の処理
	connection.on('error', function(err) {
		console.log('db error', err);
		if(err.code === 'PROTOCOL_CONNECTION_LOST') {
			handleDisconnect();
		} else {
			throw err;
		}
	});

	module.exports = connection; //connectionを(他のファイルから)requireで呼び出せるようにする
}

handleDisconnect();
```

## クエリの実行,  HTTP接続
```app.js
//モジュールを読み込む
var http = require('http');
var express    = require('express');
var app        = express();
var mysql = require('mysql');

//mysqlConnection.jsで作成したconnectionを呼び出す
var connection = require('./mysqlConnection');

//サーバー作成
var server = http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'});
  res.write('Hello Ryu1!');
  res.end();
});

//クエリ作成
app.get('/', function (req, res) {
  console.log("dbの内容を取り出す");
  //クエリ文
  connection.query('select name from testTable where id = 0', function (error, results, fields) {
    if (error) throw error; //errorの場合
    res.send(results);//画面にresponseとして表示
    console.log("results: " + results[0].name); //jsonで受け取った場合の値の取得方法
  });
});

//サーバー起動。listen()メソッドを実行して3000番ポートで待ち受けする。
app.listen(3000, function () {
  console.log('listening on port 3000');
});
```

## 最後に
次回はAzureの[Azure Database for MySQL](https://azure.microsoft.com/ja-jp/services/mysql/)を試して記事にしてみたいと思います。
最後まで読んでくださってありがとうございます。
pythonのデコレーターと実用例

#はじめに
デコレーターとは何なのか、それを説明する前に、一つ簡単な問題を解決してみよう
# 問題1
```python:def.py
   def print_str():
       print("hello world")
```
> print_str関数が存在します、"hello world"を出力すると同時に、現在時間も出力してみましょう:point_up_tone1:

```python:print_1.py
   # 時間モジュールをインポート
   from datetime import datetime
   
   def print_str():
      print("hello world")
      print(datetime.now())

   print_str()

   #出力結果
   hello world
   2019-06-15 00:09:09.878962

```
関数内部に時間を出力するcodeを追加すれば、簡単に出来ます
**では、問題を少し変えてみましょう**
# 問題2

>print_str関数が存在します、"hello world"を出力する同時に現在時間も出力してみましょう。
`ただし、関数内部で時間出力のcodeを追加してはならない`:point_up:

```python:print_2.py
  
from datetime import datetime

def decorator(func):
    def wrapper():
        print(datetime.now())
        func()
    return wrapper

def print_str():
    print("hello world")

f = decorator(print_str)
f()
 
#出力結果
2019-06-15 09:28:45.585808
hello world
```
###デコレーターの定義
ここで定義された関数`decorator`がデコレーターです。
問題を踏まえて、デコレーターの定義を説明すると、
**関数の内部を変換せず、新しい機能を動的に追加することを可能にします。**

###略式呼び出し方
@マーク+関数名でデコレーターを関数に簡単に装着も可能

```python:print_3.py
def decorator(func):
    def wrapper():
        print(datetime.now())
        func()
    return wrapper

# @マーク+関数名でデコレーターを関数に簡単に装着も可能
@decorator
def print_str():
    print("hello world")

print_str()

# 出力
2019-06-15 09:39:06.419550
hello world
```
###複数パラメータ存在する関数の対応方法
```python:print_4.py
from datetime import datetime

def decorator(func):
    # 可変長引数をデコレーターにあたえ
    def wrapper(*args, **kw):
        print(datetime.now())
        func(*args, **kw)
    return wrapper

@decorator
def print_str(name, **kw):
    print("hello world" + name)
    print(kw)

print_str(" byby",a=1,b=2)

#出力
2019-06-15 10:00:03.465790
hello world byby
{'a': 1, 'b': 2}
```
##Flaskに置いてのデコレーターの実例
![Flask.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/2f2c8a4c-6a82-aa26-4b2f-0021dff40481.png)

flaskについて簡単に紹介します。
`pythonのウェブフレームワーク、現時点(2019/06/15)、githubでのstarsの数は44734、Djangoのstarsの42174よりも多いですよ`:point_up:

flaskでのデコレーターの使用例を見てみましょう、flaskが分からなくても大丈夫です、説明入ります

```python:flask.py
@api.route('/get', methods=['GET'])
def test_get_rout():
    name = request.args.get('name')
    return name, 200
# Djangoの場合はrouteファイル存在しますが
# flaskではデコレーターでルーティングを実現してます

@api.route('/psw',methods=['GET'])
@auth.login_required
def get_psw():
    psw = request.args.get('psw')
    return 'ok', 200

# 一つの関数に対して複数のデコレーターをつけることも可能
# @auth.login_requiredはこのrouteのアクセス権限を決めてます

```
flaskのルーティングのデコレータは、大量なコードによって実現されている。
もしそれを関数内で定義すると、一つの関数の中身は膨大に膨らみ、読み難いcodeになります、デコレータ使用することで、それを上手く回避できた、良いデコレータの実用例だと思います

Simple is better than complex.
複雑であるよりは平易であるほうがいい。--pythonの哲学
Sourcetree で husky が動かない場合の備忘録

`.bash_profile`で`node`のパスを追加している場合、Sourcetree からだと`.bash_profile`を読み込まないので、`node`のパスを見つけられないようです。

```shell
echo 'source ~/.bash_profile' >> ~/.huskyrc
```

これで解決しました。
【Rails】Slimを使ってみた


ProgateのRails講座ではHTMLを使ってViewを作成していたけど
「Slim」なるテンプレートエンジンを使うともっとシンプルに書けるみたいなので
ちょっと導入してみた備忘。

##Slim、便利！

例えば↓のようなコード

```HTML:sample.html
<html>
 <body>
  <h1>タイトル</h1>
  <p>Hello World</p>
 </body>
</html>
```
```Slim:sample.slim
html
 body
  h1 タイトル
  p Hello World
```

どちらがシンプルかは一目瞭然ですね。

ざっくりしたルールは以下。
・タグなし
・<%= %>　→　 =
・<% %> → -
・コメント　→　/
・id指定　→　#
・class指定　→　.

##導入方法
以下のGemが必要
・slim-rails
・html2slim

Gemfileに定義します。

```Ruby:Gemfile.erb
gem 'slim-rails'
gem 'html2slim'
```
定義したGemをインストールします。

```console
$ bundle
```
これでSlimを利用する準備が整いました。

なお、すでに「html.erb」 形式のファイルが存在している場合は
以下のコマンドで変換します。

```console
$ bundle exec erb2slim app/view --delete
```
capybara-webkitインストール時に"qmake not available"

##### このruby version のDocker image を使用 :
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]

## 問題
```
# gem install capybara-webkit
Building native extensions. This could take a while...
ERROR:  Error installing capybara-webkit:
        ERROR: Failed to build gem native extension.

    current directory: /usr/local/bundle/gems/capybara-webkit-1.15.1
/usr/local/bin/ruby -r ./siteconf20181206-95-ixbkmk.rb extconf.rb
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
            ...
Command 'qmake ' not available

extconf failed, exit code 1

Gem files will remain installed in /usr/local/bundle/gems/capybara-webkit-1.15.1 for inspection.
Results logged to /usr/local/bundle/extensions/x86_64-linux/2.5.0/capybara-webkit-1.15.1/gem_make.out
```

## 対処
### これを参照して、先にqtをインストールしておく
[Installing Qt and compiling capybara webkit](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit#debian--ubuntu)

```
sudo apt-get update
sudo apt-get install qt5-default libqt5webkit5-dev gstreamer1.0-plugins-base gstreamer1.0-tools gstreamer1.0-x
```

#### Dockerfile : 
```
RUN apt-get update
RUN \
  apt-get install -y \
  qt5-default \
  libqt5webkit5-dev \
  gstreamer1.0-plugins-base \
  gstreamer1.0-tools \
  gstreamer1.0-x
```
Cisco IOS XE 脆弱性公表 脆弱性対応OSリリース済み

Cisco IOS XEで脆弱性が公表されております。

脆弱性内容としては、外部遠隔地からの攻撃によって制御権が奪われるとのこと。
脆弱性深刻度が「High」ということで、既に脆弱性対応のOSはリリースされているため要検討です。

取り急ぎ情報共有
Android の Camera2 API  を使って 動画を撮影する

[Android の Camera2 API を使って カメラのプレビュー画面を表示する](https://qiita.com/ohwada/items/7bb65a566114066c8ced)
の続きです。

### 概要

下記の公式サンプルが公開されている。
これを例に説明する。

[Android Camera2Video Sample](https://github.com/googlesamples/android-Camera2Video)

カメラからの画像の出力先として、
写真(静止画)の場合は、ImageReaderを使用した。
動画の場合は、MediaRecorderを使用する。

### MediaRecorder

オーディオおよびビデオのキャプチャおよびエンコードをするためのクラス。

[reference : MediaRecorder](https://developer.android.com/reference/android/media/MediaRecorder.html)

使い方は、下記の記事を参考に。
注意： パラメータの設定には、順番がある。
違反すると、IllegalStateException が発生する。

[MEDIARECORDERで録画する](https://techbooster.org/android/multimedia/4265/)

下記のように MediaRecorder を生成する。

```
    Size videoSize;
    String outputFile;
    int orientation;
        MediaRecorder mediaRecorder　= new MediaRecorder();
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setOutputFile(outputFile);
        mediaRecorder.setVideoEncodingBitRate(10000000);
        mediaRecorder.setVideoFrameRate(30);
        mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setOrientationHint(orientation);
        mediaRecorder.prepare();
```

### 録画の開始

Recordボタンをクリックすると、
MediaRecorderを出力先にして、キャプチャーを要求する。

```
            previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            List<Surface> surfaces = new ArrayList<>();
            surfaces.add(previewSurface);
            previewBuilder.addTarget(previewSurface);
            Surface recorderSurface = mediaRecorder.getSurface();
            surfaces.add(recorderSurface);
            previewBuilder.addTarget(recorderSurface);
      cameraDevice.createCaptureSession(surfaces,  cameraCaptureSession.StateCallback, backgroundHandler);
```


キャプチャーを開始すると、
CameraCaptureSession.StateCallback の中で onConfigured　が呼ばれる。
それを契機に、録画を開始する。


```
CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured( CameraCaptureSession cameraCaptureSession) {
                            mediaRecorder.start();
```

### 録画の終了

Record ボタンをクリックすると、MediaRecorder を停止し、リソースを開放する。

```
        mediaRecorder.stop();
        mediaRecorder.reset();
```

### MediaRecorder の出力フォーマット

公式サンプルでは MPEG4 にしている。
下記のように１０種類ほどある。

MediaRecorder.OutputFormat.xxx


|Value|Name|Remarks|
|:------------:|:------------:|:------------:|
|0|DEFAULT| |
|1|THREE_GPP| |
|2|MPEG_4| |
|3|AMR_NB| |
|4|AMR_WB| |
|5|AAC_ADIF| |
|6|AAC_ADTS| |
|7|RTP_AVP| |
|8|MPEG_2_TS|Added in API level 26 |
|9|WEBM| |
|11|OGG|Added in API level 29|

[reference : MediaRecorder.OutputFormat](https://developer.android.com/reference/android/media/MediaRecorder.OutputFormat)

MPEG4 は、現在の主流でありこのまま何の支障もない。
しかし選択肢があると試したくなる。

PreferenceFragment を使って選択できるようにする。
![camera213_format.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/45421914-2276-a1ee-c49f-9674eb965f0b.png)

サンプルコードをgithub に公開した。
https://github.com/ohwada/Android_Samples/tree/master/Camera213
Windows10で外付けHDDの接続が切れる時の対処

#はじめに
Windows10で外付けHDDを使用しているときに、時間経過で接続が切れる時の対処です

##現象
上と同じです

**※画像無くてすみません**

##対処方法
１．[Windows 管理ツール]-[コンピューターの管理]を右クリック、[その他]-[管理者として実行]を押下
![hdd-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437338/4f16dbd6-a4c0-4732-e38c-d6664d750463.png)

２．[デバイスマネージャー]-[ユニバーサル シリアル バス コントローラー]-[USB 大容量記憶装置]を右クリック、「プロパティ]を押下
![hdd-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437338/b45d02f7-5722-7e52-bf4c-21f2308d8dfb.png)

３．[電源の管理]タブ内にある、"電力の節約のために、コンピューターでこのデバイスの電源をオフにできるようにする"のチェックを外す
![hdd-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437338/56d32ace-5b82-39eb-e354-10eeabc53bad.png)

**※[電源の管理]タブはデバイスマネージャーを管理者権限で実行しないと表示されないので気を付けてください**

#おわりに
Windows8.1からこの問題（というか仕様？）があるみたいですね

まあ、大事なデータはこまめに保存しましょう

それではまた
【AWS Summit2019】@幕張メッセに行ってきた　6/14

AWS Summit幕張の最終日に~~仕事をサボって~~行ってきました。

- 目的
  - コンテナ系の技術セッションに参加すること
  - AWSのコンテナのExpertに質問をすること
  - その他ブースをふらつく

コンテナ系の技術を学ぶため、というのが一番の目的でした。
自宅でちょこちょこ触っているだけなので、実業務ではどのように使われているのか、ベストプラクティス、アンチパターンを確認したいためです。

##コンテナとは？
自身の復習のためにさらっと。
事実上Dockerと言っていいほどデファクトスタンダードになっているため、以下コンテナはDockerと表現します。
DockerとはDockerエンジン上で立ち上がるそれぞれに完全に隔離された空間です。
よく仮想マシンとコンテナの比較が上がります。イメージで表すと以下です。
引用
><a href='https://knowledge.sakura.ad.jp/13265/'>Docker入門（第一回）～Dockerとは何か、何が良いのか～</a>
>>![VM_Container-680x387.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388313/b1045e9f-61fa-f7d6-48c0-1944c1c1ba7c.jpeg)


仮想マシンがハイパーバイザー上でゲストOSを乗せて動作しているのに対し、Dockerはエンジン上でコンテナが立ち上がります。
外から見ると両者はあまり違いはないかもしれません。（アクセス方法などに少し差があるくらいでしょうか）
よくDockerは仮想マシンに比べ高速だといわれていますが、この理由がここにあります。
仮想マシンはミドルウェアに相当するのですが、Dockerはプロセスです。
互いに隔離されたプロセスが立ち上がるだけなので非常に高速です。（というのを昨日のセッションで聞いて、あ！なるほど！と思いました。）
そしてDockerは四角で囲まれている部分を一つのイメージにして持ち運ぶことができるため、エンジンさえ入っていればどんな環境でも簡単に移行させることができます。
図にあるアプリの実行環境もイメージの内部にあるため、ホストOSも問いません。

##How to use Container?
本題のどのようにしてコンテナは利用されているか、ベストプラクティス、アンチパターンを聞いてきました。

- コンテナは1コンテナ1プロセスであること
さて、上記にある図を早速否定されました。原則、コンテナとプロセスは1:1にするのがベストプラクティスとされています。
ミドルウェアとアプリのコンテナは分離してイメージ化するのがよいでしょう。

- コンテナに向いているアプリケーションとそうではないアプリケーション
リソースさえあればイメージはどんなものでも作れます。が、Dockerを使ったほうがよいもの、そうでないものは当然あります。
以下のように切り分けるのがよいのではないか、と教えてもらいました。
・読み取り専用で実行したとき、問題なく動作させることができること
Dockerはデータを永続化させることができないため、（厳密にはホストOSにボリュームをマウントできるのでそうではないかもしれませんが、アンチパターンな気がします。）ファイルやデータの書き出しを行わないものであればDockerを利用することが検討できそうです。
※蛇足　DockerでホストOSにデータの書き出しはできますがFargateを使うと死亡します。というのもFargateは自動でスケールイン、スケールアウトを行うのでEC2が落ちたり立ち上がったりするからです。

- Dockerを使ったデプロイメント
個人的に考えているのはこのパターンかな、と。（アプリケーションサイドのパターンです）
・Gitなどにソースがコミットされたら、自動でイメージを作成、デプロイ、イメージのpush
別セッションでAWS CodePipelineを利用したCI/CDパターンが紹介されていました。
これはECRにイメージがpushされたことを契機にCI/CDが動作していました。ただ、これだとインフラサイド（ランタイムなどアプリの動作環境）とアプリケーションサイドが分離されていなくてイマイチじゃないかなぁと思いました。
課題はタグをどうするかということでしょうか。

- Dockerを使った開発
インフラ周り、アプリケーション周りが分離されている場合はこのようなパターンがベストではないかと。
![スクリーンショット 2019-06-15 11.30.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388313/d5a97a6e-e55e-defa-222e-37dc8afe7aef.png)
各開発者はローカル環境でテストを行うとき、お互いの最新資源で確認ができます。

- Dockerのイメージサイズについて
各イメージのサイズは数Mから大きくても数十Mが標準的なんだと聞きました。
Rubyの公式サイズのイメージは…うごごご
2019/07/20追記
とか書きましたけど、開発用なのである程度大きいのも普通なのかもしれません。

```shell
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
ruby                        2.6.1               99ef552a6db8        3 months ago        876MB
```

##感想
はっきり言って、完全に遊びに行った感覚でしかなかったんですが学びは多かったです。
コンテナのことに限らず、様々な業界の企業が出展していたので業界トレンドや各社のセールスポイントを聞くことができました。
また、AWSの方々や企業ブースの方々は非常に優しくまさかりが一本も飛んで来ませんでした。
ズタズタになる覚悟をしていきましたが。。。
あと、TISの方とOracleCloudの話で若干盛り上がりました。AWSのイベントなのに・・・
形態素解析器の違い（JUMAN++、Mecab）

書きかけのメモではありませすが、どなたかのお役に立てる可能性もあると思うので
投稿します。
（2018年5月当初に書いたものです、もう時代に合っていないかもしれませんが。。。）

#概要
・JUMAN++：形態素解析システム
・KNP：構文（構文、格、照応）解析システム
・PyKNP：pythonと、JUMANN++、KNPのバインド

（参考サイト）
https://deepage.net/machine_learning/2017/01/16/juman++.html
##統計的な言語モデルとは？

##JUMAN++ Ver.1.02 (xz圧縮, 600MB)のインストール
(参考)http://lotus.kuee.kyoto-u.ac.jp/nl-resource/jumanpp/jumanpp-manual-1.0.pdf
（参考）https://qiita.com/1O1/items/956f64af69ac99e62acf
```
$ wget http://lotus.kuee.kyoto-u.ac.jp/nl-resource/jumanpp/jumanpp-1.02.tar.xz&name=jumanpp-1.02.tar.xz

$ tar xJf jumanpp-1.02.tar.xz
$ cd jumanpp-1.02
$ ./configure 
```
●「./configure」で次のエラー発生。

```
configure: error: "Error: cannot find available Boost library."
```
Boostをインストールする。
開発者さんのページには次の２つが必須ライブラリとしてかいてありました。
ubuntuでは、gccは最初から入っているみたいなので、Boost C++だけ追加インストールすればいいみたいですね。（http://nlp.ist.i.kyoto-u.ac.jp/index.php?JUMAN++）
・gcc (4.9 以降)
・Boost C++ Libraries (1.57 以降)

```
$ sudo apt install libboost-dev
```

```
$ ./configure
$ make
$ sudo make install
$ jumanpp -v
JUMAN++ 1.01
```

##JUMANのインストール
・構文解析のためめKNPをインストールするには、（JUMAN++ではなく）JUMANのインストールが必要なようです。
・JUMANをインストールせずにKNPをインストールすると、「./configure」の時に 「juman.h: not found.」とエラーになってしまいます。

```
$ wget http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/juman/juman-7.01.tar.bz2
$ tar xvf juman-7.01.tar.bz2
$ cd juman-7.01
$ ./configure
$ make
$ sudo make install

```


##KNPインストール
```
$ wget http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/knp/knp-4.19.tar.bz2
$ tar xvf knp-4.19.tar.bz2
$ cd knp-4.19
$ ./configure
$ make
$ sudo make install
$ knp -v
knp 4.19

```
パスを通す。
```
$ sudo gedit /etc/ld.so.conf
```
gedit上で、下の１行を追加して、保存。
```
include /etc/ld.so.conf.d/*.conf
include /usr/local/lib
```

パスの読みなおし。
```
$ sudo ldconfig
juman -v
juman 7.01
```

##JUMANを試す
```
$ echo "外国人参政権" | juman
外国 がいこく 外国 名詞 6 普通名詞 1 * 0 * 0 "代表表記:外国/がいこく カテゴリ:場所-その他 ドメイン:政治"
人参 にんじん 人参 名詞 6 普通名詞 1 * 0 * 0 "代表表記:人参/にんじん カテゴリ:植物;人工物-食べ物 ドメイン:料理・食事"
政権 せいけん 政権 名詞 6 普通名詞 1 * 0 * 0 "代表表記:政権/せいけん 組織名末尾 カテゴリ:抽象物 ドメイン:政治"
```

##JUMAN++を試す
```
$ echo "外国人参政権" | jumanpp外国 がいこく 外国 名詞 6 普通名詞 1 * 0 * 0 "代表表記:外国/がいこく カテゴリ:場所-その他 ドメイン:政治"
人 じん 人 名詞 6 普通名詞 1 * 0 * 0 "代表表記:人/じん 漢字読み:音 カテゴリ:人"
@ 人 ひと 人 名詞 6 普通名詞 1 * 0 * 0 "代表表記:人/ひと 漢字読み:訓 カテゴリ:人"
参政 さんせい 参政 名詞 6 サ変名詞 2 * 0 * 0 "代表表記:参政/さんせい カテゴリ:抽象物 ドメイン:政治"
権 けん 権 名詞 6 普通名詞 1 * 0 * 0 "代表表記:権/けん 漢字読み:音 カテゴリ:抽象物"
```
##KNPを試す
```
$ echo "外国人参政権" | jumanpp | knp
# S-ID:1 KNP:4.19-CF1.1 DATE:2018/05/26 SCORE:-1.20047
外国─────┐　　　　　　　　　<体言>
          人─────┐　　　　　<体言><Wikipediaエントリ:外国人>
                参政─────┐　<体言>
                          権<体言><用言:判><Wikipediaエントリ:参政権><格解析結果:ガ/-;ニ/-;デ/-;カラ/-;時間/-;ノ/->
```


●●再開
https://deepage.net/machine_learning/2017/01/16/juman++.html#juman%E3%81%A8python%E3%83%90%E3%82%A4%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB


##余談
●Mecab辞書　ユーザ登録可能
（参考）
http://tech.innovation.co.jp/2017/07/28/mecab.html
経理社員がスクラム開発勉強会に参加してみた

# はじめに</h1>
経理社員として働きながら、独学でプログラミングを行なっています。
昨日、興味のあったスクラム開発についての勉強会に参加しました。
参加して学んだことと、異業種の人間として感じたことを書きたいと思います。
[スクラムマスターを知ろう in Agile Shinano]
(https://agile-shinano.connpass.com/event/132237/)

# 勉強会の概要 </h1>

### テーマ</h3>
「スクラムマスターを知ろう」
　・スクラムマスターの役割は何か？
　・スクラムマスターについて議論すべきことは何か？

### 学習形式</h3>
OST (Open Space Technology)形式での議論を行ないました。
OSTの概要をWikipediaから引用します。

>5人から2000人といった小人数から大人数にまで一堂に会して行えるのが特徴である。参加者が課題を提案してミーティングを行う仲間を募り、課題を解決するプロジェクトを創出することができる。参加者の当事者意識や自発性を喚起するとともに、参加者の主体的な発案、対話を促す。

全員が発言権を持ち、自由に議論を進めましょうという形式で行ないました。
実務で起きた話を聞いたり、「こんな開発メンバーはイヤだ」の大喜利が始まったりと色々な話が聞けるオモロな方法でした。
	
### 進行方向</h3>
全体で約100分の勉強会でした。

1. 動画の視聴（スクラムマスターについて）
[The Power of Scrum - Legendado - YouTube](https://www.youtube.com/watch?v=eNe0UEsBalA)

2. 一人ずつ、今回の勉強会で議論したい内容を提示
「ラガーシャツ着なきゃダメ？」（動画内のスクラムマスターがラガーマンの服装だった）から「スクラムマスターに求められる素質は？」まで多様でした。

3. 全員投票で議題を決定し、テーブルごとに議論する内容を設けて自由に話し合う
参加人数16名で2テーブル、各テーブル2テーマ、各テーマ40分ずつくらい。途中で別テーブルへの移動も可。

4. 各人がFun/Learn/Doneの振り返りを行ない、付箋をホワイトボードに貼る

### 議題</h3>

#### 1. 「スクラムマスターにはどんな権限があるか？」</h4>
  - 具体的な決定権は持たないのではないか？
     - プロダクトを決めるのは顧客とプロダクトオーナーであり、タスクの割り振りなど進行方法は開発チームが自律的に決めることが望ましい
     - 決まりを守らせる風紀委員的な役割であって、決まりを作る役割ではない
  - 開発メンバーがタスクに集中できる環境作り
     - 開発チームの進捗把握（デイリースクラム、要所要所でのヒアリングなど）
     - マルチタスクにならないよう他部署リーダーからの干渉から守る（マルチタスクは生産性低下をもたらすリスクが高い）
     - プロダクトオーナーと開発チームの認識齟齬を防ぐ（あるべきプロダクトデリバリーに導く）


#### 2. 「スクラムを困難にする開発メンバーがいた場合、スクラムマスターがすべきことは？」</h4>
 - 風紀委員として開発チームの自己組織化を促す
     - デイリースクラムの時間厳守、スプリントレビュー時の目的理解を求める
     - 状況に応じてコーチングの機会を設ける
 - 特定のメンバーの存在がチームの生産性低下に繋がる場合は、他プロジェクトへのリアサインを根回しする
     - あくまで最終手段


#### 3. 「スクラムマスターに求められる素質は？」</h4>
 - プロダクトの価値最大化を目的として開発チームの支援を行なうことができる
     - スプリントゴールを念頭に置き大局観を持つ
     - プロダクトオーナーや、クライアントとの折衝能力(時にはNoと言えること)
     - 技術指導やコーチングを通じて開発チームのサポート（開発メンバーの技術力が乏しい場合）
 - 不満や不安を伝えたときに建設的な話ができる
     - 話を聴いてくれる、話しかけてくれる

#### 4. 「スクラムマスターと開発チームのコミュニケーションの取り方」</h4>
 - 開発チームの不満を隠さないような雰囲気作り
     - 今後のスプリントで心配なことない？など、将来の不安の芽を摘む
 - プロダクトの内容について開発チームと合意をこまめに取る
     - デイリースクラムの遂行
 - 多様な働き方に対する理解と調整
     - 育児フレックスやフルリモートの働き方への理解、プロダクトバックログの見直し

# 異業種の人として感じたこと</h1>

### アジャイル/スクラム開発について</h3>
 - アジャイル/スクラムへの認識として、ウォーターフォール型に比べて仕様変更など変動の多い労働環境と思っていた。プロダクトオーナー、スクラムマスターとの絶え間ないコミュニケーションが無いとしんどい現場になりがちなのかな。
 - とはいえデイリースクラム以外でコミュニケーションに時間を割き過ぎれば生産性は落ちるし、そのジレンマに戸惑う事例は多そう。デイリースクラムでしか連絡を取らないという参加者もいればやたら打ち合わせの場があるという参加者もいたことから、人次第。

### エンジニアという職業について</h3>
 - エンジニアはプロダクトをどうやって作るかにフォーカスする職人気質な人が多いのかな。プロダクトを使ったビジネスのスケールとか収益化を考える経理、経営企画のほうが僕は好きかもしれない。※様々なエンジニアがいるので、人によることは承知しています
 - とはいえ、モノを作る人ってかっこいい！
 - 情報共有、ビジョン共有としてのコミュニケーションはエンジニアになっても大事。

### スクラムの考え方は異業種でも使える</h3>
 - 異業種でもスクラムの考え方、方法は通用する。
 - 決められた納期、成果物に対してタスクを細分化し、メンバーに振り分け、進捗管理するというのは現職でも行なっている。
 - 「タスクに集中できる環境作り」という視点は現職でも取り入れてみたい。他の人に仕事を割り振る際の用途（何に使う資料か）、納期（いつまでに終わればいいか）、内容（何が明確化されていればいいか）についての合意を心がけたい。それが相手の生産性を損なわないマナーであり、チームの生産性を損なわないことに繋がる。


# 参照リンク</h1>
OST(オープン・スペース・テクノロジー)
https://ja.wikipedia.org/wiki/オープン・スペース・テクノロジー

スクラムガイド
https://scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf
自信を持って言える、本当に初歩の初歩からのGoogle Colaboratoryの使いはじめ

Google Colaboratoryを使い方について記事を探して、試そうとしても、次のような違和感が。
####「あれ？なんか画面構成が少し違うけど」
たぶん、もう使い込んでいる人が、後進のために記事を作成してくれているために、画面構成が少しちがってしまってるのではないかと思います。

そこで、実際に初回利用時の画面キャプチャを取りながら、本当の使いはじめをレポートします。


#1. 本当にはじめにやったこと
###アカウント作成
Googleドライブを使う的な噂を聞いたので、新しいGoogleアカウントを作成しました。
（いま使っているgoogleアカウントの容量がいっぱいになってきたので）

#2. Google Colaboratoryの使い始め
###キャンセルボタンを押す
僕は、Google Colaboratoryのページにアクセスし、次の画像のように「キャンセル」ボタンを押しました。
https://colab.research.google.com/notebooks/welcome.ipynb#recent=true

理由は、まずは、チュートリアル的な動画を見ようとおもったかたです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193468/90109383-e58d-4a2c-b01d-4a73a6065bee.png)


#3．チュートリアル動画
###ジェイクさん（登場人物のお名前）の動画をみる
- 早く使ってみたい気持ちを抑えて、まずは動画を閲覧。3分程度の動画です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193468/c88c27a2-ab8c-67e9-8e92-0db35a5afed8.png)

####不明だった言葉
- 動画に登場するジェイクさんが使う言葉が理解できず、調べた事。
 - ランタイム

>実行時に必要な物
（「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典）
https://wa3.i-3-i.info/word13464.html


 -Markdown（マークダウン）
>文章を記述するための記法（マークアップ言語）の一つです。
https://www.asobou.co.jp/blog/bussiness/markdown


#4.Google Colaboratoryを実際に使ってみる

###- 次のコードを入力
- 
```
print("Hellow World!")
```
- 画像中赤丸部分を押すと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193468/23804bd6-4984-74f4-fc4f-f10fee20180e.png)

- 実行されて、次のような感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193468/603c1614-58d7-c4a8-443a-ace97c72feee.png)

#5. 最後に
- これで、Google Corabolatoryが使える事が確認できました。
- どんどん使ってみて、いろいろと書き足していこうと思います。

以上
WebStormとプロジェクトのprettierを連動させてエラーをエディターで表示する。

毎回忘れてググるので

Nuxt.jsでprettierを利用した際、コンソール上のprettierのエラーがWebStorm上でも表示させたい。

 prettierのドキュメントに書いてあった。WebStorm2018.1 and aboveのガイドだったので、今の自分の環境WebStorm2019.1でも同様でした。

https://prettier.io/docs/en/webstorm.html

## File WacherでPrettierを定義

Preferences / Tools / File Watchersで＋をクリック

Choose TemplateでPrettierを選択。Edit画面が開くが、大体は以下のような設定がデフォルトで入っているのでそのまま使用できます。

・Name: 適当に。わかりやすいようPrettierにした

・File Type: JavaScript（or watchしたいファイルタイプ）

・Scope: Project Files

・Program: ``$ProjectFileDir$/node_modules/.bin/prettier``

・Arguments: ``--write [other options] $FilePathRelativeToProjectRoot$``

・Output paths to refresh: ``$FilePathRelativeToProjectRoot$``


<img width="950" alt="スクリーンショット 2019-06-15 10.46.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248843/7c741d2e-bc82-9d15-3412-ae28c1e1e2c7.png">

## Prettierのパッケージを設定
Preferences / Languages ＆ Frameworks / JavaScript / Pretier
Node interpreterとPrettier　packageをそれぞれ設定。
<img width="1124" alt="スクリーンショット 2019-06-17 23.25.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248843/c3244775-8104-725a-b142-643ce7a813b3.png">


Apply 後
<img width="521" alt="スクリーンショット 2019-06-15 10.59.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248843/adbec892-fe03-d97c-70d4-6a3bd7e1c39b.png">



できた！
CodePenでWeekly Coding Challengeに参加してみた #2

以前CodePenで発見したWeekly Coding Challenge（[詳しくは前回の記事](https://qiita.com/hiromir13/items/bbe4f294302705b67d53)）

ウィークリーチャレンジなのにマンスリーチャレンジになりましたが
２題目にも挑戦してみました！

## 今回のテーマ
「Slider」

普通に作れば楽だったのですが、なぜかどうしてもクロスフェードにしたい気分だったので
JSのコントロールに苦労しました💦

### 私はこんなの作りました

遅れすぎて恥ずかしかったのでひっそりとしたおかげで
まだ全く誰にも閲覧されていないような状況ですが😂

<p class="codepen" data-height="358" data-theme-id="0" data-default-tab="js,result" data-user="hiromir13" data-slug-hash="xNPvYg" style="height: 358px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Weekly Coding Challenge #2 Cross fade Slider">
  <span>See the Pen <a href="https://codepen.io/hiromir13/pen/xNPvYg/">
  Weekly Coding Challenge #2 Cross fade Slider</a> by hiromir13 (<a href="https://codepen.io/hiromir13">@hiromir13</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 詳しくはこちら
[Weekly Coding Challenge](https://www.florin-pop.com/blog/2019/03/weekly-coding-challenge)
WSL2を使ってみる (InsiderPreview)

Win10 Pro IPにWSL2が来たので使ってみました。
WSLは、VM⇔Host 間のファイルやり取りの為のセットアップが面倒になっている身には期待したいものがあります。現状でもDocker for Winが良い線行ってますが、WSLもなかなかのもの。

試用した感想としては良い感じ。ただ、/mnt/c/へのアクセスは速度的に要注意。

# 機能を有効化
Hyper－V上にて次の環境で試しました。

* OS: Windows 10 Pro Insider Preview
* Build: 18917.1000
* WSL有効化済み

仮想マシンで試すならば、おそらくNested Hyper-Vの有効化が必要です (未確認)。
https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/user-guide/nested-virtualization

現状ではWSL2を有効化するのにいくつか作業があるようです。
https://docs.microsoft.com/en-us/windows/wsl/wsl2-install

```powershell
# 管理者権限で実行
# 「Windowsの機能の有効化または無効化」に相当。
PS> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform

# ↑を実行後に再起動すること
PS> Restart-Computer

# インストールされているディストロを表示
# 著者の環境ではubuntuを入れています。
PS> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         1

# ubuntuの動作環境をWSL2へ変換
# 別のディストロをWSL2化したい場合には"ubuntu"部分を書き換えます
PS> wsl --set-version ubuntu 2
変換中です。この処理には数分かかることがあります...
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
変換が完了しました。

# WSL1に戻す際は2の部分を1にすれば戻せます
# PS> wsl --set-version ubuntu 1
```

# 使ってみる

```powershell
# バージョンが2になっていればWSL2が有効になってます
PS> wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         2

# あとはいつもどおりの方法で起動できます
PS> ubuntu
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

$ ls /
bin   dev  home  lib    lost+found  mnt  proc  run   snap  sys  usr
boot  etc  init  lib64  media       opt  root  sbin  srv   tmp  var

$
```

# 噂の性能向上を計測
手頃なサイズのtarballを解凍してみました。

```bash
$ time tar -zxf WordPress-5.2.1.tar.gz
```

ついでに素のWindowsも

```powershell
PS> Measure-Command { tar -zxf WordPress-5.2.1.tar.gz }
```

WslFsはWSL内のファイルシステム、DrvFsはWSLから見たWindowsのファイルシステムです。
WSL2はWslFsが高速化してる一方、DrvFsは遅くなってます。9pのせい？。

| version    | WslFs  | DrvFs   |
|------------|--------|---------|
| WSL1       | 3.043s | 25.044s |
| WSL2       | 0.391s | 55.221s |
| Windows    | 41.18s | 24.223s |

# まとめ
* 有効化は「Windowsの機能有効化」と、「wsl --set-version ubuntu 2」で行う
* WSL2のファイルアクセスは確かに早くなってる (もう少し大きいファイルが良かったな)。
* /mnt/c/へのアクセスは旧版以上に重い

IOの主体をWSLかWinのどちらかに寄せたい。
VSCode Remoteにはその辺を期待してて、WindowsからWSL内のファイルへのアクセスを上手く活用し、作業時にはファイルの実体はWSL側に持たせたい感じ。ファイルアクセスの遅さに幻滅してるツイートを見かけましたが、この辺が原因かなと思った。

```powershell 
PS> explorer \\wsl$\Ubuntu
```
if文

###if
```go
func main() {
	num := 10
	if num%2 == 0 {
		fmt.Println("by 2")
	}
}
```

###if else
```go
func main() {
	num := 11
	if num%2 == 0 {
		fmt.Println("by 2")
	} else {
		fmt.Println("else")
	}
}
```

###else if
```go
func main() {
	num := 9
	if num%2 == 0 {
		fmt.Println("by 2")
	} else if num%3 == 0 {
		fmt.Println("by3")
	} else {
		fmt.Println("else")
	}
}
```

###&& ||
```go
func main() {
	x, y := 10, 10
	if x == 10 && y == 10 {
		fmt.Println("&&")
	}
}
```
```go
func main() {
	x, y := 11, 22
	if x == 10 && y == 10 {
		fmt.Println("&&")
	} else if x == 10 || y == 22 {
		fmt.Println("||")
	}
}
```

###関数を使った書き方
```go
func by2(num int) string {
	if num%2 == 0 {
		return "ok"
	} else {
		return "hoge"
	}
}

func main() {
	result := by2(10)
	if result == "ok" {
		fmt.Println("nice!")
	}
}
```
main関数内をもっと簡単に書くこともできる

```go
if result := by2(10); result =="ok"{
	fmt.Println("nice!")
}
```

ただし、この書き方だとif文の中でしか`result`を使うことができないので注意したい。
>【参考】
現役シリコンバレーエンジニアが教えるGo入門(https://www.udemy.com/share/100BhMB0obeFpbTX4=/)