OmniAICreator/Qiita-1.07M huggingface dataset:
CaboChaをpython3で使えるようにする時つまったところ(Windows10)

CaboChaをPythonで使えるようにするために「[CaboCha & Python3の環境構築(Windows版)](https://qiita.com/ayuchiy/items/17a2d48116b2da7535eb)」を参考に進めていたが，(4)の最後のsetup.pyのところでつまったので解決方法の備忘録

引用元だとsetup.pyのソースコードを修正するように書いてあったが，自分の場合はうまくいかなかった．
そこで「[CaboChaをPythonで使う Windows10-64bit](https://qiita.com/zincjp/items/c268cf211dddeb79bd83)」の記事を参考にsetup.pyを修正するとうまくいった．
以下うまくいかない修正案とうまくいった修正案

```python:うまくいかなかった修正案
#!/usr/bin/env python

from distutils.core import setup,Extension,os
import string

def cmd1(str):
    return os.popen(str).readlines()[0][:-1]

def cmd2(str):
    return cmd1(str).split()

setup(name = "cabocha-python",
    # ↓下記のように直す version = cmd1("cabocha-config --version"),                
    py_modules=["CaboCha"],
    ext_modules = [
        Extension("_CaboCha",
            ["CaboCha_wrap.cxx",],
            include_dirs=[r"C:\Program Files (x86)\CaboCha\sdk"],
            library_dirs=[r"C:\Program Files (x86)\CaboCha\sdk"],
            libraries=cmd2("cabocha-config --libs-only-l"))
            ])
```

```python:うまくいった修正案
#!/usr/bin/env python

from distutils.core import setup,Extension,os
import string

def cmd1(str):
    return os.popen(str).readlines()[0][:-1]

def cmd2(str):
    return cmd1(str).split()

setup(name = "cabocha-python",
    version = "0.69",
    py_modules=["CaboCha"],
    ext_modules = [
        Extension("_CaboCha",
            ["CaboCha_wrap.cxx",],
            include_dirs=[r"C:\Program Files (x86)\CaboCha\sdk"],
            library_dirs=[r"C:\Program Files (x86)\CaboCha\sdk"],
            ##↓ここの部分を修正
            libraries=['libcabocha'])
])
```
Local by Flywheel でサイトのディレクトリをまるっと変更する手順


Local by Flywheel で一度構築したローカルサイトのディレクトリを変更する手順です。

1.新しいディレクトリに現在のサイトディレクトリをコピーする

2.
https://github.com/getflywheel/local-addon-volumes
こちらからダウンロードして下記のディレクトリに配置
/Library/Application Support/Local by Flywheel/addons 

3.Local by Flywheelを起動

4.左のメニューから「add-on」＞「Volumes」をインストール、有効にしてLocal by Flywheelを再起動

5.移動させたいサイトを選択

6.「More」＞「Volumes」に移動

7.「Host Source」の各項目を移動先のパスに変更

8.編集を終えたら「RemapVolumes」のボタンを押す

9./Users/username/Library/Application Support/Local by Flywheel/sites.json を開き、
移動前のパスを探して移動先のパスに変更

10.Local by Flywheelを再起動！



###参考
https://localwp.com/community/t/moving-a-local-site-to-a-different-path/1923
TableViewでLINEと同じ順番でよろしくと言われたときに雑に対応する

# 結論
AffineTransformを使って逆向きにすればいい

# 準備

```ReverseTableViewController.swift
import UIKit

class ReverseTableViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView! {
        didSet {
            self.tableView.rowHeight = 44
            self.tableView.delegate = self
            self.tableView.dataSource = self
        }
    }
    
    private var data: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    }
}

// MARK: - UITableViewDelegate

extension ReverseTableViewController: UITableViewDelegate {}

// MARK: - UIScrollViewDelegate

extension ReverseTableViewController: UIScrollViewDelegate {
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let bottomContentOffset = scrollView.contentSize.height - scrollView.bounds.height
        let boundary = bottomContentOffset - (100 - scrollView.contentInset.bottom)
        guard scrollView.contentOffset.y > boundary else { return }
        
        let from = data.count
        let to = from + 9
        data.append(contentsOf: (from...to).map { "\($0): cell" })
        tableView.reloadData()
    }
}

// MARK: - UITableViewDataSource

extension ReverseTableViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = data[indexPath.row]
        
        return cell
    }
}

```

下にスクロールすると追加読み込みされるTableViewを作る。

<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9186/3797cee3-3f4d-6cb0-e15d-b12ab5e46f9e.png">

# 下が先頭かつ上にスクロールすると追加読み込みされるように修正

```ReverseTableViewController.swift
...
    override func viewDidLoad() {
        super.viewDidLoad()
        /// 追加１：tableViewを逆向きに
        tableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi))
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        /// 追加２：indicatorを調整
        tableView.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: tableView.bounds.width - 8)
    }
...


// MARK: - UITableViewDataSource

extension ReverseTableViewController: UITableViewDataSource {
...    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = data[indexPath.row]
        /// 追加３：cellも逆向きに
        cell.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi))
        
        return cell
    }
}

```

<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9186/25336737-ac35-9d1b-28d9-7fff27c27d37.png">


あとはセクションヘッダをフッタにする必要がありそうですかね？
こんなのでいいのかな。。。
VPCからAPIGatewayのパブリックAPI・プライベートAPIの混在呼び出し大丈夫か！？の話

前提：API GatewayにパブリックAPIと、プライベートAPIを用意しています。
##①Lambdaから、パブリックAPIを以下のように呼び出します。
▼URLは、APIGatewayをデプロイしたときに表示されているもの
https://{restapi-id}.execute-api.{region}.amazonaws.com/{stage}
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350277/6d5f391d-fa32-39cc-6e6f-9d41baa8670d.jpeg)

##②Lambdaから、プライベートAPIの呼び出しを追加しようとし、AWSで推奨されているように、VPCエンドポイントをプライベートDNSありで作成する。（※注意書きにはいろいろ書いているよ）
▼プライベートAPIの作成とそれにアクセスするVPCエンドポイントの話
>https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-private-apis.html

そうすると、パブリックAPIへの通信経路が変わってしまう。。
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350277/0abbaa55-1a61-759b-4def-8bd7c02ededb.jpeg)

その結果、”①”のパブリックAPIへのアクセスがエラーになってしまうのです( ;∀;)
なぜなら、パブリックAPIはVPCエンドポイント経由でアクセスできないからです。。

まさに↓この話
>https://aws.amazon.com/jp/premiumsupport/knowledge-center/api-gateway-vpc-connections/

これ、私あやうくやらかしそうになりました(笑)

じゃあどうしたらいいのか？
↓このあたりの話
>https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html
>https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpce-interface.html

内部ルーティングが変わってしまう、VPCエンドポイント作成時のプライベートDNS有効化はやめてしまおう。でいいと思っています。（個人的意見）

そうすると、
下記のアクセスは常にインターネット経由（パブリックAPIへのアクセス用）
https://{restapi-id}.execute-api.{region}.amazonaws.com/{stage}
⇒例）https://01234567ab.execute-api.us-west-2.amazonaws.com/test/pets

そして、VPCエンドポイント経由は下記のアクセスで可能（プライベートAPIへのアクセス用）　※さらにヘッダーにパラメータつける必要あり
https://{public-dns-hostname}.execute-api.{region}.vpce.amazonaws.com/{stage}
⇒例）https://vpce-01234567abcdef012-01234567.execute-api.us-east-1.vpce.amazonaws.com/test/pets

これでVPCエンドポイントが設定されているVPCのリソースから、パブリックAPIとプライベートAPI、両方を呼び出すことができるようになります。

これが最適解なのかはちょっと？なのですが。。

以上です。
JavaScriptをすこーし勉強してみたので書き留める②

最低限の知識一応あるけど、復習も兼ねて書いてみることにするの巻その②

# 型変換
演算子と関数は自動的に値を正しい型に変換する
   ex)`alert` は表示するために値を文字列に変換する

- 文字列変換
    - `String(vakue)`関数も使える

```
let value = true;
alert(typeof value); // boolean

value = String(value); // 今、値は文字列の "true"
alert(typeof value); // string
```

- 数値変換
    - 数値変換は数学的関数や表現の中で自動的に起こる
    - 明示的に value を変換するために Number(value) を使うことができる
    - 文字列が有効な数値でない場合、変換の結果は`NaN`になる 

```
alert( "6" / "2" ); // 3, 文字列は数値に変換されます

-----------------

let str = "123";
alert(typeof str); // string

let num = Number(str); // 数値の 123 になります

alert(typeof num); // number

-----------------

et age = Number("an arbitrary string instead of a number");

alert(age); // NaN, 変換失敗
```

変換ルール

| 値 | 変換後 |
|:-:|:--:|
| undefined | NaN |
| null | 0 |
| trueとfalse | 1 と 0 |
| string |最初と最後のスペースは取り除かれる。残った文字列が空の場合は結果は0。エラーの場合はNaN。 |

- Boolean変換
    - 論理演算で起こる
    - `Boolean(value)`関数を呼ぶことで手動で実行することもできる

変換ルール

| 値 | 変換後 | 備考 |
|:-:|:-:|:-:|
| 0,空文字,ull,undefined,NaN | false |直感的に'空'な値はfalseになる|
| その他 | true ||

```
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false

alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
```

⚠️注意点⚠️
ゼロの文字列 `"0"` は `true`！
他の言語では`"0"`をfalseと扱う言語もあるが、Javascriptは空文字ではない場合は全てtrue



# 演算子（基本的なところは省略。知り得る知識で他言語と差分がある箇所を書いていく。）
- 文字列連結 
    - （「+」でつなぐ）
    - 一方のオペランドが文字列の場合、他のオペランドも文字列に変換される(「+」以外は数値演算になる)
    - オペランドが数値でない場合は数値に変換(`Number(value)` と同じだが、より短い表現)

```
let s = "my" + "string";
alert(s); // mystring

----------------

alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"

----------------

// 数値の場合、何の影響もありません
let x = 1;
alert( +x ); // 1

let y = -2;
alert( +y ); // -2

// 非数値を数値に変換します
alert( +true ); // 1
alert( +"" );   // 0
```

# 比較
下記ページ参照しました
https://ja.javascript.info/comparison
（厳密比較じゃないとtrueになっちゃう理由がわかる）

-------------------
今日も今日とて疲労。おわりまる。
【Firebase App Distribution】Error: App Distribution could not find your app *** の対処法

# アプリ全てに対して、「Get started」 ボタンを押さないといけない

```
Make sure to onboard your app by pressing the "Get started" button on the App Distribution page in the Firebase console: https://console.firebase.google.com/project/_/appdistribution
```

iOS/Android全てのアプリに対して「Get started」押してなかったのが原因でした。
左上のセレクトボックスででアプリを切り替えて、全部押してあげると直りました。
全然気付かず、かなり時間浪費してしまった...かなしい

同じところでハマった人いました。やっぱりUI分かりづらいと思う...
https://github.com/firebase/firebase-tools/issues/1963#issuecomment-619524724
pythonのwordcloudを簡単に使ってみよう!

# pythonのWordCloudライブラリとは
文章中で出現頻度が高い単語を頻度に応じた大きさで図示してくれるやつ！

## wordcloud公式ドキュメント
- https://github.com/amueller/word_cloud
- http://amueller.github.io/word_cloud/

## 公式ギャラリー
- http://amueller.github.io/word_cloud/auto_examples/index.html

# 早速簡単に使ってみよう
## 環境
```bash
$ python3 -V
Python 3.7.3
```
## 仮想環境構築
```bash
$ mkdir wordcloud-sample    
$ cd wordcloud-sample 
$ python3 -m venv venv
$ source ./venv/bin/activate
```
## wordcloudインストール
```bash
$ pip install wordcloud
```

## wordcloudを実行
```python3
$ python3
Python 3.7.3 (default, Mar  6 2020, 22:34:30) 
[Clang 11.0.3 (clang-1103.0.32.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from wordcloud import WordCloud
>>> WordCloud().generate("hello world").to_image().show()
```

## 実行結果
![helloworld.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609246/f007515a-8e16-a110-ff75-721be4997225.png)

----
よかったよかった
Python - 複数条件でのif文判定挙動（順番が違うだけなのに）

#はじめに
環境については下記の通り

```txt:bash
$ python3 --version
Python 3.6.8
```

#if文の判定挙動
if文の条件式が複数ある場合、前から順番に処理されていく。
and演算子の場合は、一つでもFalseの条件式が見つかった時点で、
その後の条件式の判定は行われず、else部分の処理が行われる。

下記コードはif文の条件式の順番が違うだけだが、
処理結果に違いが出てくる。

```python:test.py
l = [0] * 3
# l = [0,0,0]

print("0 <= i < 3 を先に判定する場合")
for i in range(4):
    if 0 <= i < 3 and l[i] == 0:
        print("i = {} 成功".format(i))
    else:
        print("i = {} 失敗".format(i))

print("0 <= i < 3 を後に判定する場合")
for i in range(4):
    if l[i] == 0 and 0 <= i < 3:
        print("i = {} 成功".format(i))
    else:
        print("i = {} 失敗".format(i))
```


出力結果はこちら。

```txt:bash
$ python3 test.py 
0 <= i < 3 を先に判定する場合
i = 0 成功
i = 1 成功
i = 2 成功
i = 3 失敗

0 <= i < 3 を後に判定する場合
i = 0 成功
i = 1 成功
i = 2 成功
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    if l[i] == 0 and 0 <= i < 3:
IndexError: list index out of range
```

「0 <= i < 3 を先に判定する場合」だと、
`i = 3`の場合は1つ目の条件式である`0 <= i < 3` の判定の時点でFalseとなり、
2つ目の`l[i] == 0`の判定が行われていない。

一方、「0 <= i < 3 を後に判定する場合」だと、
`l[i] == 0`の判定が1番目に行われるため、
`i = 3`で`list index out of range`のエラーがでてしまう。

#おわり
サンプルコードは通るのに自分のコードは通らない・・・アルゴリズムは同じなのに・・・と苦悩した結果、発見した。

and演算子では1つでもFalseの条件がある時点でFalseとなるため、その後の条件式は処理されないようだ。

意外とこういう内容に触れている記事は少なかったようなのでまとめてみた。
演算子の括弧を省略しないのがリーダブルコード

# 疑問

JavaScriptで条件式を3つ並べたとき括弧を省略できる？:thinking:

```javascript:JavaScript
if (flag_a) {
  if (flag_b || flag_c) { }
}
```

をリファクタリングしたとき

```javascript:JavaScript
if (flag_a && (flag_b || flag_c)) { }
```

中の括弧を省略できるかという疑問。

# 調査

括弧を省略できるか書き出してみた。

| a    | b    | c    | a&&b&#124;&#124;c | (a&&b)&#124;&#124;c | a&&(b&#124;&#124;c) | a&#124;&#124;b&&c | (a&#124;&#124;b)&&c | a&#124;&#124;(b&&c) |
| ---- | ---- | ---- | --------- | ----------- | ----------- | --------- | ----------- | ----------- |
| 1    | 1    | 1    | 1         | 1           | 1           | 1         | 1           | 1           |
| 1    | 1    | 0    | 1         | 1           | 1           | **1**     | **0**       | **1**       |
| 1    | 0    | 1    | 1         | 1           | 1           | 1         | 1           | 1           |
| 1    | 0    | 0    | 0         | 0           | 0           | **1**     | **0**       | **1**       |
| 0    | 1    | 1    | **1**     | **1**       | **0**       | 1         | 1           | 1           |
| 0    | 1    | 0    | 0         | 0           | 0           | 0         | 0           | 0           |
| 0    | 0    | 1    | **1**     | **1**       | **0**       | 0         | 0           | 0           |
| 0    | 0    | 0    | 0         | 0           | 0           | 0         | 0           | 0           |

括弧の有無で計算結果が変わるので括弧を外せない。

||より&&のほうが優先的に計算される。

[演算子の優先順位 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)によると20個の規則がある。

しかし、20個も覚えてられない。

演算子の優先順位は言語によって変わるかもしれない。

たとえば、滅多にない例だが、JavaScriptでは`!0 === 1`が`false`になるが、Pythonでは`not 0 == 1`が`True`になる。

# 結論

リファクタリングしないか、`var flag_b_or_c = flag_b || flag_c`と説明変数を挟むことがリーダブルコード。

そこはリーダブルコードにしなくていいと判断したら、括弧の有無で計算結果が変わらなかったとしても、演算子の括弧を省略しないことがリーダブルコード。 :smirk_cat:
CodeforcesにおけるPythonで大量の行のreadの実行時間

<font color="red">この記事は十分に内容が精査できていないのですが、備忘録的に投稿します</font>

https://codeforces.com/contest/1334/problem/C

がreadの遅さ起因でTLEしたような気がしたので検証。

https://codeforces.com/contest/1334/customtest

で試す。

```Python
import sys
input = sys.stdin.readline # この行はreadline を使うときだけ有効にする
q = int(input())
for _ in range(q):
    n = int(input())
    for i in range(n):
        a, b = map(int, input().split())
```

# 1回の入力
```
1
1
1 1
```
を入力としてinputに食わせる

# 大きなデータの作り方
CodeForcesでは256KBまでしかファイルを食わせられないので以下のコマンドで10000個から40000個のケースを作成する。(40000以上だとfilesizeのlimitに引っかかってしまう)

尚、今回の問題では300000個のケースまであり得る。

```shell
# この例では40000回繰り返すもの。(これを10000などに変化させる)
$ echo 40000 >a.txt && for i in {1..40000}; do echo "1"; echo "0 0"; done >> a.txt
40000
1
0 0
1
0 0
...(あと39998回続く)
```

# 結果

Python, Pypyでそれぞれreadlineなしとreadlineありで実行。

|言語|input1|10000回|20000回|30000回|40000回|
|----|------|------|-----|-----|-----|
|python3|78ms|108ms|155ms|202ms|217ms|
|pypy3|124ms|280ms|421ms|560ms|655ms|
|python3,readline|93ms|93ms|124ms|109ms|155ms|
|pypy3,readline|124ms|139ms|156ms|171ms|171ms|
オーバーヘッド(=input1)を抜いたものをとして計算する

# 考察
イニシャルやバッファのせいか、回数を変えても値が変わらない結果が散見された。特に、Pyhonで20,000->30,000回で時間が短くなっているのはおかしい気がするのだが...ともあれ、おおよそ、

- readlineを使わないのは明らかに遅いことは自明
- python+readlineでは大体30ms/20,000回　⇒ 450ms/300,000回
- pypy3+readlineでは35ms/20,000回 ⇒ 525ms/300,000回

くらいに見える。ただし、これはあくまでreadのみの時間で実際は配列への格納などが発生する。

# 配列に格納して足す　加えて　出力する

特に意味のない動作だが、以下のように値を利用し、各ケースごとに表示する。

```Python
from pprint import pprint
import sys
input = sys.stdin.readline

q = int(input())
for _ in range(q):
    n = int(input())
    data = []
    datb = []
    for i in range(n):
        a, b = map(int, input().split())
        data.append(a)
        datb.append(b)
    res = 0
    for i in range(n):
        res = data[i] + datb[i]
    print(res)
```

|言語|input1|10000回|20000回|30000回|40000回|
|----|------|------|-----|-----|-----|
|pypy3,inputのみ|124ms|139ms|156ms|171ms|171ms|
|pypy3,res代入・表示|217ms|249ms|280ms|249ms|295ms|

これも同様におかしな結果になった。(10000 - 30000回readが時間が変わらないか同じ。

# C++と比較

|言語|input1|10000回|20000回|30000回|40000回|
|----|------|------|-----|-----|-----|
|pypy3,res代入・表示|217ms|249ms|280ms|249ms|295ms|
|c++,res代入・表示|15ms|46ms|93ms|124ms|155ms|



```c++
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
#define lint long long
void solve(){
    int n;
    cin >> n;
    vector<lint> data;
    vector<lint> datb;
    lint a, b;
    REP(i, n){
        cin >> a >> b;
        data.push_back(a);
        datb.push_back(b);
    }
    int res = 0;
    REP(i, n){
        res = data[i] + datb[i];
    }
    cout << res << endl;
}

int main() {
    int q;
    cin >> q;
    REP(i, q) solve();
}
```
Pythonで毎日AtCoder #54

### はじめに
[前回](https://qiita.com/taxfree_python/items/0ca8821f180292978305)
今日は一問だけです。

### #54
[問題](https://atcoder.jp/contests/keyence2019/tasks/keyence2019_b)

**考えたこと**
文字列の操作に関する問題は苦手なので、この問題にしました。前に一度解いたのですが、逃げていたので解きます。
$S$の長さが十分に小さいので、切り分ける点を全探索します。一つの点でのみ、切り分けることに注意。

```python
s = input()

flag = False
n = len(s)
for i in range(n):
    for j in range(i,n):
        if 'keyence' == s[:i] +s[j:]:
            flag = True

if flag:
    print('YES')
else:
    print('NO')
```

### まとめ
今日のABCで茶色になりたい。今日のABCがんばりましょう! ではまた。
WSLを２に更新する

気がついたら使えるようになってた**WSL（Windows Subsystem for Linux）**を2に更新しました。
忘れてた・・・
WSL1は私はプレビュー時にインストールしてそのままなので今はやり方違うと思うのでそこは省略させてください。



#WSL1と2の違い
WSL2は仮想マシンを使い、Linuxカーネルが動作するLinux環境です。
Windows上でLinuxが動いています。
それに対してWSL1はLinux実行環境をLinuxカーネルではなく、LXCore と呼ばれる「サブシステム」が作り出しています。
つまりWSL1はLinuxぽいサブシステムを作ってそれがLinuxぽい動きをしているだけです。
それはそれですごいんですけどねｗ
Linuxが動いているわけではないです。
![wi-wsl2_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/4563e157-e381-8009-74d6-0bdd0fe1ea5d.png)

#WSLの特徴
##実行速度が早い
LinuxカーネルをWindows上で実行することはこれまでもできました。
ただ実行速度が遅かったです。
（VMware、Hyper-V）
WSLで素早くLinuxぽいことができるようになり、2で正式にLinuxを高速で使えるようになりました。

##これまで正しく動作できなかったアプリケーションが動くようになる
コンテナシステムやユーザーファイルシステムが使えるようになりました。
みんなの目的はDockerですよね。
WindowsのHOME EditionではDockerは使えません。（Proでは使える）
そのためWSLが発表されたときはDocker使える！！？って期待されたけど使えませんでした。
上記の通りWSL1はLinuxぽい動きをするサブシステムを動かしているのでそこにコンテナ置けなかったです。
じゃあDocker使えると何がいいの？って話はまた別の話になるので省略

参考
https://www.atmarkit.co.jp/ait/articles/1906/14/news019.html

#アップデート方法
##環境
ThinkPad X1 Carbon 2017
OS：Windows10 home

##CPUの仮想化を有効にする。
BIOSのSecurityタブから仮想化を有効にします。
どうでもいいけどWindows10から？高速スタートアップとかのためOS起動時にFキー連打しなくなったよね。
久しぶりにBIOS出そうとして連打してしまうｗ
高速スタートアップとかがデフォだと有効になっていてデュアルブートとかもできなくなっています。
おっさんは注意が必要です。
https://support.lenovo.com/jp/ja/solutions/ht500006

##WSL2 Linux カーネルの更新
下記のサイトに従い、Linux カーネル更新プログラムをインストールします。
https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

##Windows PowerShellで更新
```
PS C:\Users\XXX\VSCode> wsl -l -v　#現在のバージョンを確認
  NAME          STATE           VERSION
* Legacy        Stopped         1
  kali-linux    Stopped         1
  Ubuntu        Stopped         1
PS C:\Users\XXX\VSCode> wsl --set-version Ubuntu 2
変換中です。この処理には数分かかることがあります...
WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください
PS C:\Users\XXX\VSCode> wsl --set-version Ubuntu 2
変換中です。この処理には数分かかることがあります...
WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
変換が完了しました。
PS C:\Users\XXX\VSCode> wsl -l -v
  NAME          STATE           VERSION
* Legacy        Stopped         1
  kali-linux    Stopped         1
  Ubuntu        Stopped         2
```
Ubuntuのバージョンが1→2になったことが確認できました。
WSLはご覧の通り１も２も共存することができます。
どのディストリビューションをどっちで使うか後で少し考えます。
それとDockerも入れてみようかね・・・
C#エンジニアが初めてpythonを学習して感じた違い

どうも、[筋トレ臨床工学エンジニアken](https://twitter.com/ce_fitness_note)です。

Qiitaで初めての投稿です。

僕は普段はC#を使って医療システムの開発業務を行っています。
機械学習の方にも力を入れていこうと思い、pythonの学習を始めました。

学習といってもProgateのpythonコースを一回りやったほどですが、C#と記述の仕方など異なるところについて簡単にまとめます。

C#、C＋＋、VBあたりを普段使っていて、これからpythonを学習したいという人は、この両者の違いを予め知っておくと学習が捗るかと思います。


## コードから見るC#とpythonの簡単な違い

### 文の終わりのセミコロンいらない
```C#:C#
Console.WriteLine("Hello C#");  //ステートメントの末尾には必ずセミコロン
```
```python:python
print("Hello python")
```

**ステートメントの末尾のセミコロンがpythonの場合は不要です。**
普段C#のようなセミコロンが必要な言語を使っているとまずここが慣れませんでした。


### 変数は型指定不要

```C#:C#
string[] animals = {"dog","cat"};   //変数は全て型を指定
```
```python:python
animals = ["dog","cat"]
```
**pythonは「動的型付け言語」であり、変数宣言時にデータ型を指定する必要がありません。**

*C#のような静的型付け言語でもvarキーワードを使うことで実際に入るデータの型を推論してくれる（型推論）ことができますが、コードを読む際にデータ型が明示されてないのは少し難しく感じます。*

コードを書く際は楽そうだなという感じもします。

**ちなみにpythonは関数の戻り値、引数にも型指定しません。**


### 中かっこが不要、インデントの有無がコードに影響する

```C#:C#
foreach(string animal in animals)
  {
    Console.WriteLine(animal);
  }
```

```python:python
for animal in animals:
    print(animal)
```

コードの中では配列の中身を出力する処理
（C#ではforeach,pythonではforの部分）を見てもらうとわかると思うのですが、
**pythonは条件式後の処理を：（コロン）とインデントで区別しています。**
if文などの場合も同様です。

インデントの有無が動作に影響するのも面白いですね。
これだと誰が書いても見やすいように書けます。


### リストの要素は型を問わず入れられる

```C#:C#
string[] animals = {"dog","cat"};   //変数は全て型を指定
```
```python:python
animals = ["dog","cat",1,2]
```

リストとはC#でいう配列のことです。
**一つのリストの要素に文字列、数値型などなんでも混ぜて入れられるのも、C#にはない特徴です。**

*C#にもArrayListというコレクションがあり、そちらは要素の型を問わず入れることができます。ただし、取り出す際はキャスト（型変換）が必要です。*

ちなみにpythonでは配列の中身を取り出す処理をforと記述します。
C#のfor文とは処理が異なります。
この辺がややこしいかもしれません。

## まとめ
以上、pythonの学習を初めて感じた他言語（C#）との違いを簡単にまとめました。
ここまでのコードの違いをまとめて比べると以下のようになります。
出力は同じになります。

```C#:C#
using System;   //名前空間の指定

namespace test  //名前空間の宣言
{
    public class Hello //クラスの宣言
    {
        public static void Main() //メソッド
        {
        
            Console.WriteLine("Hello C#");  //ステートメントの末尾には必ずセミコロン
        
            string[] animals = {"dog","cat"};   //変数は全て型を指定
        
            foreach(string animal in animals)
            {
                Console.WriteLine(animal);
            }
        }
    }
}
```

```:出力結果
Hello C#
dog
cat
```

pythonの場合

```python:python
print("Hello python")

animals = ["dog","cat"]

for animal in animals:
    print(animal)

```

```:出力結果
Hello python
dog
cat
```



コードを見てわかるように、C#は変数の型指定など、細かく記述するためコードが長くなりがちです。
反面、pythonは非常にすっきりしています。

pythonのみならず、動的型付け言語は記述もシンプルに書けるので、高速で開発するのに向いているのかなと感じました。

今後はpythonを用いた簡単なデータ分析などにも取り組んでいこうと思います。
読んでいただきありがとうございました。

[個人のブログ](https://ce-fitness-note.com/)もやっておりますので、良ければそちらもよろしくお願いします。
Pythonでファイルをランダムサンプリングしたい

# やること
1. ファイルを100個つくる
2. 指定した拡張子のファイルパスを取得
3. ランダムに10個選び、別ディレクトリにコピー

# ディレクトリ構成
```sh
.
├── input
│   └── _sampled
└── src
    └── random_sampling.py
```

# コード
※ 全て標準ライブラリなのでインストール不要

```python:random_smpling.py
from pprint import pprint
import os
from pathlib import Path
import random
import shutil


class FileControler(object):
    def make_file(self, output_dir, file_name, content='') -> None:
        """ ファイル作成 """
        # 出力先ディレクトリがなければ作成
        os.makedirs(output_dir, exist_ok=True)
        # 出力先ディレクトリとファイル名を結合
        file_path = os.path.join(output_dir, file_name)
        # ファイル作成
        with open(file_path, mode='w') as f:
            # 初期値では空ファイル 作成
            f.write(content)

    def get_files_path(self, input_dir, pattern):
        """ ファイルパスの取得 """
        # ディレクトリを指定しパスオブジェクトを生成
        path_obj = Path(input_dir)
        # glob形式でファイルをマッチ
        files_path = path_obj.glob(pattern)
        # 文字列として扱うためposix変換
        files_path_posix = [file_path.as_posix() for file_path in files_path]
        return files_path_posix

    def random_sampling(self, files_path, sampl_num, output_dir, fix_seed=True) -> None:
        """ ランダムサンプリング """
        # 毎回同じファイルをサンプリングする場合はシード値を固定する
        if fix_seed is True:
            random.seed(0)
        # ファイル群のパスとサンプル数を指定
        files_path_sampled = random.sample(files_path, sampl_num)
        # 出力先ディレクトリがなければ作成
        os.makedirs(output_dir, exist_ok=True)
        # コピー
        for file_path in files_path_sampled:
            shutil.copy(file_path, output_dir)

```


# 実行
## インスタンス作成
```py
file_controler = FileControler()
```
## ディレクトリ
`input/`の中にファイルを１００個つくる
`input/_sampled`の中へサンプリングしたファイルをコピー

```py
all_files_dir = '../input'
sampled_dir = '../input/_sampled'
```

## まずは100ファイル作る
`.py`, `.txt`のファイルをそれぞれ50個づつ

```py
for i in range(1, 51):
    file_controler.make_file(all_files_dir, f'file{i}.py')
    file_controler.make_file(all_files_dir, f'file{i}.txt')
```

## .pyファイルのパスだけ取得
```py
from pprint import pprint


pattern = '*.py'
files_path = file_controler.get_files_path(all_files_dir, pattern)

pprint(files_path)
# ['../input/file8.py',
#  '../input/file28.py',
#  '../input/file38.py',
#  ...
#  '../input/file25.py',
#  '../input/file35.py',
#  '../input/file50.py']
#

print(len(files_path))
# 50
```

# 10ファイル分ランダムサンプリング
```py
sample_num = 10
file_controler.random_sampling(files_path, sample_num, sampled_dir)
```

# 確認
```sh:ターミナル
ls input/_sampled

file10.py file23.py file3.py  file35.py file36.py file37.py file38.py file4.py  file41.py file43.py
```
深層学習とかでのPython(bash,Windows10)エラー「bash: /c/Users/XYZZZ/AppData/Local/Microsoft/WindowsApps/python3: Permission denied」への対処

#目的
ワタシ自身は、**bash**とか、言葉はよく目にするが、全然、理解していません。
普段Windowsで作業しているが、深層学習とかで提示されている環境とかの都合で、bashに触れることもある。
そこで、以下のエラーに出会った。

**解決策が衝撃的、かつ、ググるだけでは、この解決策にたどり着かないことも多いと想像**したので、記事にする。
（衝撃的といっても、そのような仕込みになっているだけなんだろうが。。。仕組みは理解していません。）

エラーの内容は、以下。

```

$ python3 classify_image.py \
> --model models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
> --labels models/inat_bird_labels.txt \
> --input images/parrot.jpg
bash: /c/Users/XYZZZ/AppData/Local/Microsoft/WindowsApps/python3: Permission denied
```

肝心なエラー部分のみ抜粋すると、以下。

```
bash: /c/Users/XYZZZ/AppData/Local/Microsoft/WindowsApps/python3: Permission denied
```


#エラー対策

StackExchangeの

How to fix “Permission Denied” in Git Bash in Windows 10?
https://superuser.com/questions/1532831/how-to-fix-permission-denied-in-git-bash-in-windows-10

の回答のとおりにすると、解決した。
（すみません、仕組み、理解していません。）

解決策は、

**python3 --> PY**

にするとのこと。

エラーがなくなって実行した結果。これは、Google Coral TPU関連の深層学習です。

```
$ PY classify_image.py \
--labels models/inat_bird_labels.txt \
> --model models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
> --labels models/inat_bird_labels.txt \
> --input images/parrot.jpg
----INFERENCE TIME----
Note: The first inference on Edge TPU is slow because it includes loading the model into Edge TPU memory.
19.7ms
4.7ms
5.0ms
4.7ms
10.4ms
-------RESULTS--------
Ara macao (Scarlet Macaw): 0.77734

```

この記事に直接関係あるのは、先頭の２文字（「**PY**」）だけ。。。

ちなみに、
これらは、**MINGW64**上で動かしています。（これ自体も、ほとんど、理解していません。）

#まとめ
なかなか、いろんなことを知らないと、エラーが自己解決できなくて、ぐぐることが多い。ちょっと、いやになる作業ですが、、、いろんなことに詳しくないと、自力のエラー対処は、難しいですね。。。:candy:
コメントなどあれば、お願いします。
Arduinoことはじめその２

# Arduinoことはじめその２

前回に引き続きArduino入門

## プロジェクトの作り方
Arduinoはプロジェクトファイルなど面倒な外部ファイルはないので、楽でいい。

### フォルダ作成
ファイルを保存するためのフォルダを作る。
スケッチと同名である必要があるので、スケッチの名前を考えておこう。

他にも色々作るだろうからライブラリ的なフォルダを作ってその下に作ると楽。

### スケッチの作成
Arduinoではメインとなるソースをスケッチと呼ぶ。
先ほど作ったフォルダの中に保存する。

スケッチを作るためにわざわざArduinoIDEを立ち上げるのも面倒なので、適当なテキストを作って拡張子を`.ino`に変えてしまおう。


### サンプル
例えばこんな感じ

```text
├Mydocument
  └ProjectLibrary
    ├dentaku
    │ └dentaku.ino
    ├keybord
    │ └keybord.ino
    └IoTdentaku
      └IoTdentaku.ino
```

## プロジェクトの設定

### フォルダを開く
プロジェクトごとの設定を変更するには、VScodeでフォルダを開く必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/1d0eb383-43d0-379e-771e-464c8c5cb585.png)
ここからフォルダを開くを選択する。
対象のフォルダを選んだらVScodeで開くことができた。

フォルダを開くとこんな感じでフォルダの中身が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/6a10b2aa-ad9d-f16e-60f0-66ae3df05cb4.png)

この状態で設定を進めていくと、`.vscode`というフォルダに設定内容が保存されていく。
勝手にできたフォルダだからといって消しちゃダメ。

### 設定
さっき作った`.ino`が一覧に表示されていると思うのでダブルクリックで開く。
そうすると右下のステータスバーがArduinoモードに変更される。(SSは設定済みの様子)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/66ef50a0-8377-e0ea-e192-60bf3e0f8c53.png)

そうしたら、下記箇所は自分の環境に合わせて設定をしよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/d04680ac-d432-b3ee-cec9-148fa4ab23f2.png)

①については自分の持っているArduinoに合わせて設定。
もし、自分の持っているArduinoが表示されない場合はボード一覧の更新が必要かもしれない。
更新の手順は後述する。

②についてはArduinoが接続されている仮想COMポートを選択する。
どこに接続されているかは、「Winキー＋X⇒デバイスマネージャ」で確認しよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/ff425f04-97c8-a8d2-8cf8-1bdc1009c591.png)



portpopを入れておくと接続時にポップアップ表示されるので非常に楽。
https://github.com/tomozh/PortPop

### コンパイル＆書き込み
ここまで設定できればコンパイルと書き込みが可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/c61ef3de-a63d-9f35-fc4a-afd8c56da428.png)

①が書き込みで②がコンパイルのボタンである。
書き込み時に自動でコンパイルされるので、書き込みしたいときはコンパイル不要。
構文チェックとかメモリ使用量のチェックをしたいときにコンパイルを使う。

## ArduinoIDEを使わないといけないとき
ここまでVScodeを使った手順を紹介してきたが、どうしてもArduinoIDEを使わないといけない時が2種類ある。
それは「ボードの追加&更新」の時と、「ライブラリの追加&更新」の時。

どちらもエクスプローラーを使って直接インストールすることは可能であるが、せっかく管理の仕組みがあるのに手管理は面倒。
なので、この２つはArduinoIDEを使うことをオススメする。

### ボードの追加&更新
ツールメニューの結構深いところにある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/9b2b8a4c-465c-c3d5-400c-01d97e0afc0c.png)

公式リポジトリで管理されているボードはここから追加&更新が可能。
追加するときは一覧から選ぶか、検索する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/2e60f414-bdb1-ab3c-0232-40f02b07ec5a.png)

一覧の状態ではメニューが何も表示されていないが、マウスオーバーすると、インストールや更新などのメニューが表示される。
上記SSでは１つ目のボードにマウスオーバーしている。

### ライブラリの追加&更新
ライブラリの管理はここ
ボードマネージャと使い方は同じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558673/7c15290b-93b3-8c86-47c0-e444be19dbf8.png)


## まとめ
以上でLチカ＋αくらいの内容までは辿りつけると思う。
前回の最後にも書いたが、何が起きても驚かない大きな心で臨むこと。これが肝心。

あと、２回か３回リトライしてうまくいかない時ってどこかで勘違いとか手順間違いとかしてる可能性が大きい。
落ち着いて手順を見直すか、有識者にSOSを送るといいと思う。
pandas.DataFrameの行を間引く（ダウンサンプリング）

#### 方法

リストと同様にスライスが使えます。

```python
# 5行間隔で間引く
df[::5]
# 10行間隔で間引く
df[::10]
```

### 例

```python
In [1]: import pandas as pd

In [2]: df = pd.DataFrame()

In [3]: df['col'] = range(100)

In [4]: df
Out[4]:
    col
0     0
1     1
2     2
3     3
4     4
..  ...
95   95
96   96
97   97
98   98
99   99

[100 rows x 1 columns]

In [5]: df[::5]
Out[5]:
    col
0     0
5     5
10   10
15   15
20   20
25   25
30   30
35   35
40   40
45   45
50   50
55   55
60   60
65   65
70   70
75   75
80   80
85   85
90   90
95   95

In [6]: df[::10]
Out[6]:
    col
0     0
10   10
20   20
30   30
40   40
50   50
60   60
70   70
80   80
90   90
```
1日目

# Hello_appの作成
- rails newを使い、ディレクトリの作成をした。
 
```
rails new hello_app
```
- GemfileをTutorialの指示通りに編集し、bundle installを行った。ここでいろいろな規則が書いてあったが、さらっと読み飛ばした。

- rails server を別タブのターミナルで実行し、ブラウザでしっかり表示できているかの確認をした。この後、MVCについて説明が軽くされていた。この辺はProgateの開発パスでも勉強をしたが、自分で試行錯誤しながらやっていったなかで読んだほうが理解が進みそうであった。

- application_controller.rbにhelloアクションを追加し、中にhelloをhtmlで表示する指示を記述、ルートルーティングをapplication#helloを記述し、無事アプリケーションが完成した。

- 最後にソースコードをバージョン管理下に置き。herokuにデプロイし、無事どちらも実行できた。

### 演習での躓き
- [1.5.3](https://railstutorial.jp/chapters/beginning?version=5.1#sec-heroku_step_two)の演習で、2番目のアクション変更がうまくいかない。。。
[iOS]R.swiftをSPMで導入

私はiOSアプリではほとんどR.swiftを使用しています。今まではCocoapodsによる導入がほとんどでした。Xcode11からSPM(Swift Package Manager)でR.swiftを導入することが増えてきました。

## R.swiftとは？

多くの記事で書かれていますので、割愛します。
https://github.com/mac-cain13/R.swift

## R.swiftの導入方法

大きく分けて３つのパートになります。

1. rswiftコマンドのインストール
1. R.generated.swiftの生成
1. R.swift.Libraryのインストール

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

rswiftコマンドはR.generated.swiftファイルを生成するためのCLIです。インストールするためには、HomebrewとMintの２通りがあります。

- Homebrewで：簡単だが、バージョン指定が出来ない
- Mint：バージョン指定ができるが、ビルド時間がかかり、特にCI環境で影響があります。

### Homebrewでインストール

[Homebrew](https://brew.sh/index_ja)で最新版のrswiftをインストールするためには

```
$ brew install rswift
```

だけです。簡単ですね。しかし、バージョンの指定は出来ないことに注意します。


### Mintでインストール

[Mint](https://github.com/yonaskolb/Mint)でバージョンを指定してインストールするためには、

```
$ mint install mac-cain13/R.swift@5.2.2
```

です。最新版をインストールする場合は、@以降を省略します。もし、Mintfileを使用してインストールしているのであれば、"mac-cain13/R.swift"をファイルに追加します。


## R.generated.swiftの生成

次にR.generated.swiftを生成するためのスクリプトを書きます。Xcodeプロジェクト＞Targets＞[Target Name]＞Build Phase＞＋ボタンで"New Run Script"を選択します。スクリプト名は"R.swift"、場所は"Dependencies"の直後にします。

```
if which rswift >/dev/null; then
rswift generate "$SRCROOT/generated/R.generated.swift"
else
echo "warning: rswift not installed"
fi
```

また、Input Filesには`$TEMP_DIR/rswift-lastrun`、Output Filesには`$SRCROOT/generated/R.generated.swift`を指定します。R.generated.swiftの書き出し先は変更可能です。

ここまでの設定で一度ビルドすると、R.generated.swiftが生成されていることがわかります。このファイルをプロジェクトに追加します。

R.generated.swiftはgitignoreでコミットしないようにします。

## R.swift.Libraryのインストール

最後にR.generated.swiftを使うためのR.swift.LibraryをSPMで導入します。

上部メニュー＞File＞Swift Packages＞Add Package Dependencyを選択し、
`https://github.com/mac-cain13/R.swift.Library`
と入力してNextを選択します。バージョンはそのままでNextを選択します。"Rswift"と"RswiftDyamic"が選択できますが、"Rswift"を選択してFinishを押します。

もう一度ビルドを行い、"Build Succesed"となることを確認します。これで導入が完了です。
S3 → Lambda → Transcribe →  S3 で文字起こしパイプラインを作成する

##1 S3(input)##

音声用ファイルのS3バケットを作成しておく。


##2 Lambda##

`s3-get-object-python`を利用していきます。
![スクリーンショット 2020-05-02 13.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/6fde4114-89cd-0143-184d-e588590a4bc3.png)

「1 S3(input)」で作成したS3バケットを選択し、「トリガーの有効化」にチェックを入れる。
![スクリーンショット 2020-05-02 13.29.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/40e8c87a-326b-eb5f-8554-c014d5a9505d.png)


```python
import json
import urllib.parse
import boto3

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e
```

音声ファイルをS3バケットにアップロードし、CloudWatch Logsで動作していることを確認しておく。
![スクリーンショット 2020-05-02 13.45.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/660fd020-edaa-26dc-d8a7-1710da538218.png)


##3 S3(output)##

文字起こし用ののS3バケットを作成しておく。


##4 Lambda修正##

まず、実行ロールに`AmazonTranscribeFullAccess`と`AmazonS3FullAccess`を付与してあげる。
![スクリーンショット 2020-05-02 13.58.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/67ffd1bd-12a2-d15d-9c7c-fc8ef3001601.png)

※[TranscribeService](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/transcribe.html#id35)
を参考にLambda functionを編集する。

```python
import json
import urllib.parse
import boto3
import datetime

s3 = boto3.client('s3')
transcribe = boto3.client('transcribe')

def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    try:
        transcribe.start_transcription_job(
            TranscriptionJobName= datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '_Transcription',
            LanguageCode='ja-JP',
            Media={
                'MediaFileUri': 'https://s3.ap-northeast-1.amazonaws.com/' + bucket + '/' + key
            },
            OutputBucketName='naata-ouput'
        )
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e
```


#5 Transcription#

「1 S3(input)」にmp3ファイルをアップロードし、
Transcriptionの`Output data location`に出力された「3 S3(output)」で
文字起こしされているかを確認する。
reactnativeでタブメニューとナビゲーション

ここでできる

https://snack.expo.io/@ryosukehujisawa/dbe1cf?platform=android&name=Access%20the%20navigation%20prop%20from%20any%20component%20%7C%20React%20Navigation&dependencies=%40react-native-community%2Fmasked-view%400.1.7%2C%40react-navigation%2Fbottom-tabs%405.2.4%2C%40react-navigation%2Fdrawer%405.3.4%2C%40react-navigation%2Fmaterial-bottom-tabs%405.1.6%2C%40react-navigation%2Fmaterial-top-tabs%405.1.6%2C%40react-navigation%2Fnative%405.1.3%2C%40react-navigation%2Fstack%405.2.6%2Creact-native-reanimated%401.7.0%2Creact-native-safe-area-context%400.7.3%2Creact-native-screens%402.4.0&sourceUrl=https%3A%2F%2Freactnavigation.org%2Fexamples%2F5.x%2Ftab-based-navigation-stack.js
Heroku の add-on で使えるエラー監視系ツールの比較まとめ

## 始めに
今回は、サーバーのパフォーマンス監視などではなく500系エラーの監視ツールの比較です。なので、 Datadog や Mackerel 、 NewRelic などは今回対象外としています。

また、この記事は 2020年05月02日 現在の情報を元に記載しています。プラン変更などもあり得ますので、実際に使用される際はその時点でのプランの詳細をご確認ください。

## 比較対象
Sentry: https://elements.heroku.com/addons/sentry
Rollbar: https://elements.heroku.com/addons/rollbar
Airbrake: https://elements.heroku.com/addons/airbrake
Bugsnag: https://elements.heroku.com/addons/bugsnag

エラー監視系 add-on の検索結果は下記
https://elements.heroku.com/search/addons?q=Error+tracking

※ 比較対象の選定は[こちらの記事](https://qiita.com/seri_k/items/605e6f75da838ae00007#error%E7%9B%A3%E8%A6%96%E7%B3%BB)などを参考にさせていただきました。

## 情報量比較
| ツール名 | google 検索数 | Qiita 検索数 |
| --- | --- | --- |
| Sentry | 49,100,000 | 255 |
| Rollbar | 21,700,000  | 57 |
| Airbrake | 3,140,000  | 66 |
| Bugsnag | 436,000  | 59 |

## 料金プラン別できること
### 無料プラン
| ツール名 | ユーザー数 | プロジェクト数 | イベント上限/月 | ログ保管期間 |
| --- | --- | --- | --- | --- |
| Sentry | 1 | 無制限 | 5,000 | 7日間 |
| Rollbar | 無制限 | 無制限 | 3,000 | 30日間 |
| Airbrake | 1  | 1 | 2,000 | 2日間 |
| Bugsnag | 1  | - | 7,500 | 7日間 |

### 有料最安プラン
| ツール名 | 料金/月 | ユーザー数 | プロジェクト数 | イベント上限/月 | ログ保管期間 |
| --- | --- | --- | --- | --- | --- |
| Sentry | $29 | 無制限 | 無制限 | 100,000 | 90日間 |
| Rollbar | $19 | 無制限 | 無制限 | 30,000 | 180日間 |
| Airbrake | $59 | 5  | 1,000 | 100,000 | 30日間 |
| Bugsnag | $29 | 5  | - | 150,000 | 60日間 |
Vuex 概要

Vue.js用の状態管理ライブラリ`vuex`の概要をまとめる。学習目的兼備忘録。

## 導入方法

vuexのインストール

```bash
npm install --save vuex
```

vuexプラグインの`vuex-persistedstate`インストール(Webブラウザのローカルストレージ保存用)

```bash
npm install --save vuex-persistedstate
```

ストア(`store/index.js`)の定義

```javascript:store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import createdPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)

export default new Vuex.Store({
  	// プラグイン適用
    plugins: [createdPersistedState()],
    state: {
       ...
    },
    mutations: {
			...
    },
    actions: {
      ...
    }
})
```



`main.js`への記述

```javascript:main.js
import Vue from 'vue'
import App from './App.vue'
// 追加
import store from './store'
Vue.config.productionTip = false
new Vue({
	// 追加(コンポーネントから利用するため)
    store,
    router,
    render: h => h(App)
}).$mount('#app')
```



## 基本用語
### state
アプリ全体の状態を保存するオブジェクト。
取得の際には、以下のように算出プロパティ`computed`を利用する。

```javascript
// ストア
state:{
  tasks:[]
}
....
// コンポーネント
computed: {
  tasks(){
		return this.$store.state.tasks    
  }
}
```

### getters

` state` データに対する算出プロパティを定義する。各コンポーネントで利用したい場合に定義する。

```
// ストア
getters: {
    doneTasksCount: (state) => {
      return state.tasks.filter(task => task.done).length
    }
}
...
// コンポーネント
computed: {
   doneTasksCount () {
     return this.$store.getters.doneTasksCount
   }
}
```



### mutations

`state`の値を更新する。`commit`関数によって呼び出される。

```javascript
// ストア
mutations: {
     save(state, task) {
         // 追加
         state.todos.push(task);
     }
}
...
// コンポーネント
methods: {
    doAdd() {
       this.$store.commit("save",{task:this.newtask});
   }
}
```

### actions

非同期処理やAPI通信を行い、登録された`mutations`によって`state`を更新する。

```javascript
// ストア
actions: {
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
},
...
// コンポーネント
methods: {
    increment() {
       this.store.dispatch('increment');
   }
}
```



## 参考

* [Vuex とは何か？](https://vuex.vuejs.org/ja/)
* [Vuexの利用方法メモ](https://qiita.com/yoshi0518/items/6d08ee6b71e47d70e4bc)
* [Vuex の使い方を勉強してみた](https://qiita.com/nmt1119/items/27ed23e433ec54a9c950)
これからコンピュータサイエンスを学びたいです

質問です。
プログラミングの勉強と合わせてコンピュータサイエンスを学ぼうと思っていて、コンピュータシステムの理論と実装を購入したのですが、第１章からいきなりつまづいておリます。難しいのは承知でしたが、入門書というのはこれくらいのレベルなんでしょうか。
オフラインどう書く第11回問題解答

問題はこちら->http://nabetani.sakura.ne.jp/hena/ord11bitamida/

素朴にかつ手続き的に解いています。
solve/2のLは、それぞれの16進数を二進表示にし、その前後に0を加えたリストのリスト。
cha1/5の初期値をN=10,M=10,R=Z=[0,1,2,3,4,5,6,7,8]とします。
chat1のLはsolveのLの一列分、MはL内の直近の0の位置、
nth0/3でLのN番目の数を求め、1ならM,Rはそのまま、Nを1ずつ減らしてcha1を繰り返します。
0ならM>N+1の時のみRのN番目とM-1番目の値を交換し、M=Nと更新しcha1を繰り返します。
一列終わったら、foldl/4で次の列に移ります。

```Prolog

%:-initialization(start).

cha(L,Z,R):-cha1(0,L,Z,M,R),!.
cha1(10,_,Z,10,Z):-!.
cha1(N,L,Z,M,R):-
     N1 is N+1,cha1(N1,L,Z,M1,R1),(nth0(N,L,0)->(M=N,(M1>N+1->
     (M2 is M1-1,nth0(M2,R1,Y,R2),nth0(N,R2,X,R3),nth0(N,R4,Y,R3),nth0(M2,R,X,R4));
     R=R1));(M=M1,R=R1)).

tento16(L,R):-tenton(L,2,[],L1),reverse(L1,L2),L3=[0|L2],reverse(L3,R).
tenton(0,_,L,R):-length(L,N),N1 is 9-N,length(L1,N1),maplist(=(0),L1),append(L1,L,R),!.
tenton(X,B,L,RL):-X1 is X div B,R1 is X rem B,
    　　　　　　   tenton(X1,B,[R1|L],RL).

solve(L,R):-maplist(tento16,L,L1),foldl(cha,L1,[0,1,2,3,4,5,6,7,8],R).

start:-str(S),split_string(S,"\s,\n","\s",L),pre(L),!.

pre([]):-!.
pre([_,B,C|T]):-
     atomics_to_string(L,"-",B),maplist(string_concat("0x"),L,L1),
     maplist(number_chars,L2,L1),solve(L2,R1), atomics_to_string(R1,"",R),
     (R==C->Str=" pass";Str=" fail"),write(Str),write(" "),writeln(R->C),pre(T).


str("0  d6-7b-e1-9e     740631825
1       83-4c-20-10     123805476
2       fb-f7-7e-df     274056813
3       55-33-0f-ff     123456780
4       00-00-00-00     012345678
5       00-00-00-55     021436587
6       40-10-04-01     021436587
7       00-00-aa-00     103254768
8       80-20-08-02     103254768
9       ff-7e-3c-18     876543210
10      aa-55-aa-55     351708264
11      55-aa-aa-55     012345678
12      db-24-db-e7     812543670
13      00-01-00-40     021345687
14      00-00-80-00     102345678
15      01-40-00-00     021345687
16      00-00-00-02     012345768
17      00-00-02-00     012345768
18      00-14-00-00     012436578
19      00-00-01-40     021345687
20      00-80-01-00     102345687
21      c8-00-00-81     120354687
22      05-48-08-14     021435687
23      24-05-00-f0     413205687
24      40-08-14-01     021536487
25      18-c8-80-80     210534678
26      1c-88-52-00     120564738
27      ec-dc-67-62     213468705
28      0a-b6-60-e9     035162784
29      52-d6-c6-c2     120345678
30      47-e7-b0-36     231047658
31      0f-85-91-aa     108263754
32      76-b6-ed-f3     601435782
33      f5-5e-f7-3d     025847163
34      dd-e7-fb-f9     610247538
35      8f-f4-af-fd     583246017
36      bf-fb-cb-f7     105382674
37      e5-fd-ff-ff     512046378
38      ef-df-ef-fe     713205648
39      bf-7f-fd-d7     826437105
40      36-ff-df-de     814527603
41      6f-dd-ff-ff     230685147").
```
間違った名前のマイグレーションファイルを生成してしまった時

## 一つだけロールバックしたい
間違えてCというマイグレーションファイルを作ってしまい
他のは残してCだけロールバックしたい

```
 Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | xxxx_xx_xx_xxxxxx_create_xxxxx_table           | 1     |
| Yes  | xxxx_xx_xx_xxxxxx_create_xxxxxxx_xxxxxxx_table | 1     |
| Yes  | xxxxx_xx_xx_xxxxxx_create_xxxx_xxxxx_table     | 1     |
| Yes  | xxxxx_xx_xx_xxxxxx_create_xxxxxxx_table        | 1     |
| Yes  | xxxxx_xx_xx_xxxxxx_create_xxxx_table           | 2     |
| Yes  | xxxxx_xx_xx_xxxxx_c                            | 3     |
+------+------------------------------------------------+-----
```

## 解決

通常のrollbackコマンドの後ろに--stepオプションをつけると
指定した数字分だけしたからロールバック可能。


```
php artisan migrate:rollback --step=1
```

するとちゃんと一つだけロールバックできるわけだ


```
+-----+------------------------------------------------+-------+
 Ran? | Migration                                      | Batch |
+------+------------------------------------------------+-------+
| Yes  | xxxx_xx_xx_xxxxxx_create_xxxxx_table           | 1     |
| Yes  | xxxx_xx_xx_xxxxxx_create_xxxxxxx_xxxxxxx_table | 1     |
| Yes  | xxxxx_xx_xx_xxxxxx_create_xxxx_xxxxx_table     | 1     |
| Yes  | xxxxx_xx_xx_xxxxxx_create_xxxxxxx_table        | 1     |
| Yes  | xxxxx_xx_xx_xxxxxx_create_xxxx_table           | 2     |
| No   |xxxxx_xx_xx_xxxxxx_c                            | 3     |
+------+------------------------------------------------+-----
```

あとは普通にファイルを削除してしまってOK。

Railsを使ってた時に何度もお世話になったこのコマンドですが、
急にど忘れしてしまったので備忘録として残します。
dockerってなんやねん！！

#dockerについて
dockerについてわかった基本的な事を書いていきます。
頭の中の整理のためでもある。

##dockerってなんぞや
１、環境設定の手間を省ける。（dockerイメージ）
２、軽量で高速に起動、停止ができる。（dockerコンテナ）


###解説
**１、dockerイメージの解説**
作成したDockerイメージを他の人に渡して使ってもらうことで、各自の環境のバージョンずれ防止や、開発環境準備の短縮化にもつながる。新規メンバ参画時のコスト削減や、環境依存問題を減らせる。

Dockerイメージとは、環境のスナップショットで,Imageを起動することで環境を再現できる。
つまり、Dockerがなければ、他の人に作業をしてもらう際に環境のバージョンを変える手間が生じるが、開発工程からDockerを活用していくことで短縮化することができる。

**２、dockerコンテナの解説**
dockerコンテナはVM（仮想マシン）と比べるとオーバーヘッド（[無駄な処理](https://wa3.i-3-i.info/word12471.html)）が少ない。（dockerのコンテナ技術とVMが比較されている。）

![スクリーンショット 2020-05-02 13.13.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590181/f1396b17-d8df-c113-3bb9-e7ccff2ddaef.png)

よくみる図ですが、何を見たらいいのかよくわからんかった。そこで説明してみる。
左がVMで右がコンテナ、
コンテナが軽量というのは、両者比較して青丸分が少ないことを図的に認識してもらい、
具体的に異なるのは赤丸の部分で、VMはOSをいくつも立ち上げるので処理自体が重くなってしまう。


###そもそも仮想化技術とは
VMもコンテナも仮想化技術の一種である。
例え話をしましょう。Windows用アプリケーションであるWordやExcelなどのOfficeソフトは、Macではライセンスを取得しないかぎり使用できません。では、WindowsOSそのものがMacのハードウェア上で動くようにしたらどうでしょう？アプリケーションはOSと連動して動いているので、WindowsOSがMacで動くとすれば、WordやExcelを使用することができます。ユーザがあたかも複数のパソコンを保持しているかのようです。

このようなことがサーバにも起こります。通常、パソコンと同様に1つのサーバにつき1つのOSが対応しています。サーバ仮想化の技術では、1台の物理サーバ上で複数の仮想マシンを論理的に構築することによって、複数のサーバOSを作動できるような仕組みになっています。したがって、ユーザは1つのサーバ上で複数のサーバOSを使用できる、ということ。
物理的サーバを減らすことが可能になるため、コスト削減に繋がる。




**VM（仮想マシン） vs コンテナ**
○一台のVMで複数のアプリケーションがOSのリソースを共有して動作している場合において問題点
・セキュリティの問題（OSのリソースの共有による）
・特定のアプリのリソースの占有

○仮想化技術を使ってアプリケーション毎に**仮想マシン**を用意した時の問題点
・OSやアンチウィルスなどのライセンスコストUP

○**コンテナ**によりアプリレベルでアイソレーションが可能になった場合
・仮想マシン毎にOSを用意する必要がないため、オーバーヘッドが少ない。
・セキュリティがやや問題（OS共有のため複数アプリに影響を及ぼす可能性がある。)


##筆者感想
いろいろ調べてすぐに理解できなかったため、まとめようかと思ったが、あまりわかりやすいものが書けなかった。つまりまだ理解できてないということ、、
理解が深まり次第修正を加えていきたいと思う。

##参考
https://knowledge.sakura.ad.jp/13265/
https://y-ohgi.com/introduction-docker/
新米ママが育児メモのAlexaスキルを作ってみた （その1）

約2カ月半前（2020年2月）に出産し、新米ママになりました。
育児中にあったらいいなと思っていた育児メモのAlexaスキルを作ってみました。
とりあえず記録する機能だけ作成しました。今後、表示、確認機能を追加していく予定です。
出産直後で結構大変な時に、いつ何回授乳して、おむつを替えたかなどを育児日記としてつけるのは結構大変でした。
出産直後はスマートフォンをあまり使用しないほうが良いと聞いていたり、赤ちゃんのお世話をしている時は両手がふさがることが多く、音楽、ニュースを聞いたり、タイマーするのにEcho dotoを活用していて、音声操作の便利さを実感していました。
紙のノートで育児日記をつけていたのですが、これも音声操作で出来たら良いなと思っていました。
##Concept
![concept.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232585/b6b64dda-babf-4786-e172-cfce8fddba20.png)
##構成概要
構成の概要は以下のような感じです。
![arichtecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232585/c4305d9b-89e4-9576-6685-949c4d9343a1.png)

###スキル作成の手順


1. カスタムスキルを開発<br>
   初めてのスキル開発だったので以下のサイトを参考に作成<br>
[第1回: 初めてのスキル開発](https://developer.amazon.com/ja/blogs/alexa/post/31c9fd71-f34f-49fc-901f-d74f4f20e28d/alexatraining-firstskill) <br>
[第2回: カスタムスキル](https://developer.amazon.com/ja/blogs/alexa/post/93bad9f6-377f-4ada-887c-279e7346f729/alexatraining-customskill)
2. Azure Functionsを作成<br>
以下のサイトを参考にイベント情報と日時をAzure Table Storage記録するAzure Functionsを作成<br>
[Azure Functions](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-create-your-first-function-visual-studio)<br>
[Azure Functions における Azure Table Storage のバインド](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-storage-table?tabs=csharp#output)<br>
[リモートデバック](https://docs.microsoft.com/ja-jp/azure/app-service/troubleshoot-dotnet-visual-studio#remote-debugging-apps)
2. 2で作成Azure Functionsを1で作成したスキルのIntentHandler内で呼び出し<br>
Intentの数だけ繰り返す。
今回は、「授乳」、「おむつ交換」などのIntentを作成しました。
以下のサイトを参考にさせていただきました。<br>
[Node.jsの標準モジュール(https)でAPIを叩く(GETのみ)](https://qiita.com/r-yanyo/items/3ef153dac12e69a2c46c)
3. Echo dotとスマートフォンのアレクサアプリに登録<br>
以下のサイトを参考にスキルをベータ版で公開しテストができるように設定<br>
[Alexaスキルのベータテストを行う](https://developer.amazon.com/ja-JP/docs/alexa/custom-skills/skills-beta-testing-for-alexa-skills.html)

###使ってみる
さっそく使い始めています。音声で記録できるのはやっぱり便利です。まだ記録機能だけしかないのでもともとやりたかったことは出来ていないですが、、、今後、機能追加、改善をしていきたいと思います。
育児しながらのためあまり時間がとれず、進捗は遅そうですが。。。