OmniAICreator/Qiita-1.07M huggingface dataset:
FTP の憂鬱

## 【序文】
エクスプローラで ftp接続すると、ftpサーバ側のファイルのタイムスタンプがずれて表示されることに今更気付いた。
少し調べてみたのでその調査メモとして残す。

## 【環境】
- 母艦（クライアント）はWindows10
- 接続先は Pi3B+

## 【現象・調査】
- **エクスプローラで ftp接続**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/b3b165cc-6f91-3675-7a65-b4295db021c2.png" width=100%>
    Pi側で撮った画面キャプチャファイルを母艦側からエクスプローラで ftp接続で確認。
ファイル名は自動で年月日時分秒が割り当てられるので、ファイル名と比べればタイムスタンプが9時間ずれていることが分かる。

- **Pi側のタイムゾーン確認**
    日本標準時 (JST) と協定世界時 (UTC)は9時間の差があり、タイムゾーン関係の問題であることは予想できる。
しかしPi側のタイムゾーンを確認するも設定に問題はない。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/35128f57-dd5b-c6a4-5731-71a55084bb18.png" width=90%>
Pi側のファイルのタイムスタンプも正常。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/40d2a99b-6d3d-0a07-5bba-43aa9683d7c8.png" width=90%>

- **エクスプローラ側の問題**
    サーバ側に問題はない以上、クライアント側の問題ということになる。
ぐーぐる先生に聞いてみたところ、バグではありません仕様です、らしい。
しかもエクスプローラからプロパティで確認するとタイムスタンプは正常に表示される謎仕様。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/f334126b-db26-04d5-99a9-8c16ddfa83d8.png" width=50%>
何だかなぁ。

    そもそもエクスプローラで ftp接続してファイルをコピー（アップロード）すると、ファイル名が日本語の場合、ファイル名が文字化けする時がある。
どうもエクスプローラの ftp 対応はイマイチな感じ。

## 【対応策】
WinSCP 等の ftp専用ツールを使えってことらしい。というか、それが普通か。
エクスプローラで ftp なんて人は殆ど居ないらしく、ぐぐってもあまり情報が出てこないんだよなぁ。

## 【余談】
そもそも Windows、Linux環境でのファイルのやり取りなら普通 Samba だよねって話もある。
しかし以前、Pi2B に USB HDD を接続し、Sambaサーバを立てて NAS運用をしていたら、ファイルシステムが壊れる現象に悩まされたことがあった。
ファイル名が極端に長い場合に発生するらしいところまでは分かったけど根本原因は不明。
そんな経緯もあり、家庭内LAN環境としては大袈裟だけど、WinSCP で ftp接続、コピーという体制に変更した。
以来問題は発生していない。
Serverless + Lambda Layer でのライブラリの共通化

## 概要

Serverless フレームワークを使用して Lambda Layer を作成し、別の Lambda から Layer にあるライブラリを利用する例です。

## serverless.yml の設定

Lambda 関数が実行されるサーバーのデフォルトのライブラリ探索パス`GEM_PATH`は`$LAMBDA_TASK_ROOT/vendor/bundle/ruby/2.5.0:/opt/ruby/gems/2.5.0`です。
一方で`bundle install --deployment`したときにインストールされるパスは`vendor/bundle/ruby/2.5.0`になります。
よって、Layer としてデプロイするフォルダを`leyers`以下の`path`で`vendor/bundle`とし、`GEM_PATH`に`/opt/ruby/2.5.0`を加えて上書きしています。

参考：[AWS公式 ライブラリの依存関係をレイヤーに含める](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html#configuration-layers-path)

また、Serverless での Lambda Layer の詳しい設定は[こちら](https://serverless.com/framework/docs/providers/aws/guide/layers/)にのっています。

```yaml:serverless.yml
service: lambda-layers

provider:
  name: aws
  region: ap-northeast-1
  stage: ${opt:stage, 'dev'}
  runtime: ruby2.5
  environment:
    GEM_PATH: $LAMBDA_TASK_ROOT/vendor/bundle/ruby/2.5.0:/opt/ruby/gems/2.5.0:/opt/ruby/2.5.0

package:
  individually: true

functions:
  helloFunc:
    handler: hello.handler
    events:
      - http:
          path: hello
          method: get
    package:
      include:
        - hello.rb
    layers:
      - { Ref: TestLambdaLayer }

layers:
  test:
    path: vendor/bundle
    name: test-${self:provider.stage}
    compatibleRuntimes:
      - ruby2.5
```

## レイヤーとして使うライブラリのインストール

今回は例として[Hashids](https://github.com/peterhellberg/hashids.rb)というライブラリを使用しました。

```:Gemfile
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
gem 'hashids'
```

デプロイに必要のためプロジェクトフォルダへインストールします。

```bash
bundle
bundle install --deployment
```

## レイヤーを使用する Lambda 関数の作成

```ruby:hello.rb
require 'hashids'

def handler(event:, context:)
  hashids = Hashids.new('this is my salt')
  hash = hashids.encode(12_345)

  { statusCode: 200, body: hash }
end
```


## デプロイ & テスト

```bash
sls deploy
```

デプロイが完了すれば、`sls invoke`でテストができます。以下のような結果が返れば成功です。

```bash
sls invoke -f helloFunc
{
    "statusCode": 200,
    "body": "NkK9"
}
```
PytorchのDatasetをDataLoaderで並列に読み込みたいときのエラー（Windows）

#まえがき

Pytorchの嬉しいところは，HDDからデータをメモリに並列に読み込む仕組みが標準で実装されているところだと思う（Kerasでは自前で作成する必要があってだるい）．
実現のためには，`torch.utils.data.Dataset`と`torch.utils.data.Dataloader`を使用する．それらを使用する際に一か所つまづいた．

実行環境は以下．

* OS: Windows10 (64bit, 1903)
* pytorch: 1.1

# TL; DR
Windowsで明示的・暗黙的に並列処理するときには，並列処理する対象のクラスを別のファイルに定義すること．
つまり，`DataLoader`のインスタンス化と`Dataset`クラスの定義を同じ`.py`で行ってはいけない．

# 詳細に


以下のように書くと，`Broken Pipe`だのなんだのよくわからんエクセプションが吐かれて泣きたくなる．
（ちなみにこのコードは切ったり貼ったり名前変えたりしたので，正確ではないです．）

```python:main.py

if __name__ == '__main__':
  ... do something

  import numpy as np

  class MyDataset(torch.utils.data.Dataset):
    def __init__(self, csv_path):
      data = np.loadtxt(csv_path, delimiter="\t")

      self.vector = data[:, 0:9]
      self.target = data[:, 10]

    def __len__(self):
      return len(self.target)

    def __getitem__(self, idx):
      return ( self.vector[idx], self.target[idx] )

  train_loader = torch.utils.data.DataLoader(
    MyDataset(path),
    batch_size=batch_size,
    shuffle=True,
    num_workers=7,
    pin_memory=True
  )

```

動作させるためには，`MyDataset`の定義を別のファイルに移動させればよい．

```python:mydataset.py
import numpy as np

class MyDataset(torch.utils.data.Dataset):
  def __init__(self, csv_path):
    data = np.loadtxt(csv_path, delimiter="\t")

    self.vector = data[:, 0:9]
    self.target = data[:, 10]

  def __len__(self):
    return len(self.target)

  def __getitem__(self, idx):
    return ( self.vector[idx], self.target[idx] )
```


```python:main.py

if __name__ == '__main__':
  ... do something

  train_loader = torch.utils.data.DataLoader(
    MyDataset(path),
    batch_size=batch_size,
    shuffle=True,
    num_workers=7,
    pin_memory=True
  )

```

# あとがき
たぶんLinuxマシンでは直面しない問題なので，細部でフラストレーション感じたくなければUbuntuとか使っとくのがいいんだと思います．
僕はWindows大正義だと思っているのでもう少し苦しもうと思います．
PostgreSQLでロックを解除する方法

## ロックの確認方法

様々なサイトで以下の方法でロックされているpidを探す記事がほとんどだった。

```sql
SELECT l.pid,l.granted,d.datname,l.locktype,relation,relation::regclass,transactionid,l.mode
    FROM pg_locks l  LEFT JOIN pg_database d ON l.database = d.oid
    WHERE  l.pid != pg_backend_pid()
    ORDER BY l.pid;
```

```sql
select * from pg_stat_activity;
```

## ロックの解除方法

```sql
SELECT pg_cancel_backend(プロセスID)
```

プロセスIDには以下を指定

```sql
pg_stat_activity.procid
```

```
pg_locks.pid
```

これでも、プロセスが消えない場合は以下で解決。

```sql
SELECT pg_terminate_backend(プロセスID)
```



# 参考サイト

https://www.compiere-distribution-lab.net/2015/06/18/postgresql-0007-%E3%83%AD%E3%83%83%E3%82%AF-lock-%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95%E3%81%A8%E3%83%87%E3%83%83%E3%83%88%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E8%A7%A3%E9%99%A4/

https://cloudpack.media/1454

https://www.compiere-distribution-lab.net/2015/06/18/postgresql-0007-%E3%83%AD%E3%83%83%E3%82%AF-lock-%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95%E3%81%A8%E3%83%87%E3%83%83%E3%83%88%E3%83%AD%E3%83%83%E3%82%AF%E3%81%AE%E8%A7%A3%E9%99%A4/
Cloud Foundry の cf target コマンドで org (組織) や space (スペース) を切り替える

## 概要
- cf target, cf orgs, cf spaces コマンドで org や space を切り替える
  
## space (スペース) を切り替える

cf spaces コマンドで org 内の space 一覧を表示。

```
$ cf spaces
user@example.com として組織 first-org 内のスペースを取得しています...

名前
foo-space
bar-space
```

cf target -s で使用する space に切り替えることができる。

```
$ cf target -s bar-space
API エンドポイント   https://api.example.com
API バージョン:      2.55.0
ユーザー:            user@.example.com
組織:                first-org
スペース:            bar-space
```

## org (組織) を切り替える

cf orgs コマンドで利用可能な org 一覧を表示。

```
$ cf orgs
user@example.com として組織を取得しています...

名前
first-org
second-org
```

cf target -o で使用する org に切り替えることができる。

```
$ cf target -o second-org
API エンドポイント   https://api.example.com
API バージョン:      2.55.0
ユーザー:            user@example.com
組織:                second-org
スペースがターゲットになっていません、'cf target -s SPACE' を使用してください
```

org と space を同時に指定することも可能。

```
$ cf target -o second-org -s bar-space
API エンドポイント   https://api.example.com
API バージョン:      2.55.0
ユーザー:            user@example.com
組織:                second-org
スペース:            bar-space
```

## 参考資料 (cf target コマンドのリファレンスガイド)

[target \- Cloud Foundry CLI Reference Guide](https://cli.cloudfoundry.org/ja-JP/cf/target.html)

> 名前
> target - ターゲットにされた組織またはスペースを設定または表示します
> 
> 使用法
> cf target [-o ORG] [-s SPACE]
おっπの日が過ぎていたので。

気がついたらおっぱいの日が過ぎていたので、

ガウス＝ルジャンドルのアルゴリズム - Wikipedia
https://ja.wikipedia.org/wiki/%E3%82%AC%E3%82%A6%E3%82%B9%EF%BC%9D%E3%83%AB%E3%82%B8%E3%83%A3%E3%83%B3%E3%83%89%E3%83%AB%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0

↑これでπを計算してみる。

まずは普通に。

```javascript
const c = (a, b, t)=>(a+b)*(a+b)/(4*t);
const pi = ()=>{
  let [a,b,t,p] = [1,1/Math.sqrt(2),1/4,1];
  let pi0 = c(a,b,t);
  while(1) {
    const [ a1, b1 ] = [ (a+b)/2, Math.sqrt(a*b) ];
    [ a, b, t ] = [ a1, b1, t-p*Math.pow(a-a1, 2) ];
    p*=2;
    const pi1 = c(a, b, t);
    if( pi0 === pi1 ) return pi0;
    pi0 = pi1;
  }
};
```

実行してみると、

(1)2.914213562373095
(2)3.1405792505221686
(3)3.141592646213543
(4)3.141592653589794

※Math.PI:
3.141592653589793

という具合にものの数回で近似値までたどりついてしまったので、再帰してみる。

```javascript
const c=(a,b,t)=>(a+b)*(a+b)/(4*t);
const pi = (a=1,b=1/Math.sqrt(2),t=1/4,p=1,pi0=c(a,b,t))=>{
    const [a1,b1]=[(a+b)/2, Math.sqrt(a*b)];
    const pi1 = c(a1, b1, t-=p*Math.pow(a-a1,2));
    return (pi0 == pi1) ? pi0 : pi(a1,b1,t,p*2,pi1);
};
```

頑張ればワンライナーで行けそう。

```javascript
const pi = (c=(a,b,t)=>(a+b)*(a+b)/(4*t),a=1,b=1/Math.sqrt(2),t=1/4,p=1,pi0=c(a,b,t))=>((a1=(a+b)/2, b1=Math.sqrt(a*b), pi1=c(a1,b1,t-=p*Math.pow(a-a1,2)))=>(pi0==pi1)?pi0:pi(c,a1,b1,t,p*2,pi1))();
```

頑張った。
MATLABで競艇の解析を始めよう（とりあえずデータの取得まで）

# 競艇の解析をやってみよう。
競艇って６艇しかいないし、データは無料で大量にあるし、夏は涼しそうだし、うまくいけば儲かるし（失敗したら損するし・・・）、競馬とか競輪よりも解析にちょうどいい題材な気がする。
あとは MATLAB を使えばデータの統計解析とか可視化とか、いろんな学習まで全部できちゃいそうな気がするので、勉強ついでにやってみよう。

おっと、競艇って古い呼び方ですね。今はボートレースですね。


# まずはダウンロード
まずはデータを取得しないと始まらないので、ボートレースのサイトから力技で取ってこよう。

2019年8月1日だとすると、出走表がここにあって、
http://www1.mbrace.or.jp/od2/B/201908/b190801.lzh

結果がここにあるみたい。
http://www1.mbrace.or.jp/od2/K/201908/k190801.lzh

MATLABで取る場合、こんな感じでブラウザー頼りの web コマンドを実行すればいいですね。

```matlab

url = "http://www1.mbrace.or.jp/od2/K/201908/k190801.lzh";
web(url,'-browser')
```

あとは、ルールは /B/YYYYmm/bYYmmDD.lzh なので、既に同じファイルがあったら if exist --- で飛ばしたりしてループさせてしまおう。とりあえず３日分くらい。

```matlab
since = "20190801";
to = "20190803";
for ix = datenum(since,'yyyymmdd'):datenum(to,'yyyymmdd')
    if exist(['K',datestr(ix,'yymmdd'),'.TXT']) ~= 2
        url = "http://www1.mbrace.or.jp/od2/K/"+datestr(ix,'yyyymm')+"/k"+datestr(ix,'yymmdd')+".lzh";
        web(url,'-browser')
    end
    if exist(['B',datestr(ix,'yymmdd'),'.TXT']) ~= 2
        url = "http://www1.mbrace.or.jp/od2/B/"+datestr(ix,'yyyymm')+"/b"+datestr(ix,'yymmdd')+".lzh";
        web(url,'-browser')
    end
end
```

ブラウザーがピカピカするけど大丈夫そう！


# LZH を展開しよう

次の悩みは lzh っていう拡張子ですが、MATLABだとデフォルトで展開できない圧縮形式なので、Lhaplus とかインストールしておきましょう。デフォルトだと C:\Program Files (x86)\Lhaplus\Lhaplus.exe にインストールされるので、dos コマンドで実行しよう。

ウィンドウズの downloads フォルダーに入ってれば以下のコマンドで解凍して、適当な作業フォルダーにコピー。（例えば C:\work\boat ）

```matlab
%% ダウンロードしたもの(lzh)を C:\work\boat に展開
dl = [getenv('USERPROFILE'),'\Downloads\'];
for ix = datenum(since,'yyyymmdd'):datenum(to,'yyyymmdd')
    if exist(['K',datestr(ix,'yymmdd'),'.TXT']) ~= 2
        zipname = ['k',datestr(ix,'yymmdd'),'.lzh'];
        dos(['"C:\Program Files (x86)\Lhaplus\Lhaplus.exe" /o:C:\work\boat ',dl,zipname,' &']);
    end
    if exist(['B',datestr(ix,'yymmdd'),'.TXT']) ~= 2
        zipname = ['b',datestr(ix,'yymmdd'),'.lzh'];
        dos(['"C:\Program Files (x86)\Lhaplus\Lhaplus.exe" /o:C:\work\boat ',dl,zipname,' &']);
    end
end
```

LZH の展開のたびに確認ウィンドウとか音とかが出る場合、出ないように Lhaplus の設定をしておくといいですね。うまくいったら数ヶ月分くらいダウンロードしてみよう。


# とりあえずデータの取得までできました。
続きに興味のある人がいたら「いいね」で教えてね。（いいね中毒）

→　[２番目の記事](https://qiita.com/teruqii/items/9aede1165e7428d3f89c)
→　[３番目の記事](https://qiita.com/teruqii/items/14bdffe71ef9ff061e55)
→　[４番目の記事](https://qiita.com/teruqii/items/986d4fba96544960f367)

を書いたよ。
C言語で1次元配列を2次元風に使いたいときの#defineマクロ＠追記あり

例えばx*yのサイズの2次元配列を扱いたいが事情があって1次元配列で扱わないと行けないシーンがあるとする（例えば特定のメモリ配列方向にのみ値を入れたいがデーター構造は2次元である場合やCUDAみたいな積極的に多次元配列をサポートしていないデバイスが存在する場合など）


割と知られてる手法だと思うんですが調べても出てこなかった（調べ方が悪いだけだと思う）ので



###追記
マクロ変数を括弧でくくるべきと言う話があったので訂正

```C
test[i*x+j] = hoge(i,j)
```

みたいな若干めんどくさい
ならばこうしてはどうだろうか

```C

#define test(i,j) test[(i)*x+(j)]
```

これならば若干記法はfortranの配列じみた書き方になり微妙ですがデーター構造の表現は2次元配列になりますね。

N次元配列とかにももちろん応用できるとは思います。

実装例としては


```C
#define size_x 3
#define size_y 4
#define  test( i,j )  test[size_y*(i)+(j)]

#include<stdio.h>
#include<stdlib.h>


int main (){

int  *test;

test =(int*)malloc(sizeof(int)*size_x*size_y);

for (int i=0;i < size_x;i++){
	 for(int j=0;j < size_y;j++){
	  test(i,j)=i*size_y+j;
	}
}

for (int i=0;i < size_x;i++){
         for(int j=0;j < size_y;j++){
        printf("%d ",test(i,j));
        }
        printf("\n");
}

free(test);


return 0;
}
```

output

```
0 1 2 3 
4 5 6 7 
8 9 10 11 
```

こんな感じになるのでしょうか

割と知られてる手法だと思うんですが調べても出てこなかった（調べ方が悪いだけだと思う）ので

なんでこの記事を書いたかと言うとこの書き方を毎回忘れそうになるのと今度これを使ってN次元配列で書かれたコードを全部直してあげようみたいなムーブをすることになったからです。

なんかご提案ご意見ございましたらお気軽にコメントください。


@8月22日追記
1次元配列のメモリ構造で多次元配列を実現する方法として#defineマクロを使用せずtypedefで実現する方法のほうが良いという指摘があったのでこちらも掲載します。


```c

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int size_x = 3;
    int size_y = 4;
    typedef int Array[size_x][size_y];
    Array* test = malloc(sizeof(int) * size_x * size_y);

    for (int i = 0; i < size_x; i++) {
        for ( int j = 0; j < size_y; j++) {
            (*test)[i][j] = i * size_y + j;
        }
    }

    for (int i = 0; i < size_x; i++) {
        for (int j = 0; j < size_y; j++) {
            printf("%d ", (*test)[i][j]);
        }
        printf("\n");
    }

    free(test);
}
```
Vue-cliのsourcemapをprodcutionでoffにしたいメモ

# productionは `vue-cli-service build` を使う
`vue-cli-service build` のdefault modeは`production` なのでつけてもつけなくてもどっちでもいい(ただし `NODE_ENV` は書き換えないように)

## Ref
- https://cli.vuejs.org/guide/mode-and-env.html
- https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build

# `vue.config.js` に `productionSourceMap` を追加する
下記のような設定を追加する。

```js
module.exports = {
    productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
}
```

`VUE_CLI_SERVICE_CONFIG_PATH='$(pwd)/vue.config.prod.js'` のように環境変数をつかって、configを切り替えるようなことはしてはいけない

## Ref
- https://cli.vuejs.org/guide/webpack.html#simple-configuration
- https://cli.vuejs.org/config/#productionsourcemap
docker-composeでPostgreSQL/MySQL起動時に初期データを敷きこむ


## 概要

dockerで立ち上げたPostgreSQLやMySQLに初期データを敷きこんでおきたいことはよくあるはず。
身の回りで意外と知らない人が多かったので記事として残しておきます。

## DockerでDB起動時にデータを敷きこむ

**PostgreSQLの場合**

`docker-compose.yml`内の`db:/docker-entrypoint-initdb.d`がポイントです。

ここではローカルのdbディレクトリの中に初期化したいファイルを置いておきます。
対応しているファイルは以下です。

- `*.sql`
- `*.sql.gz`
- `*.sh`

```docker-compose.yml
version: '3.1'

services: 
  pg:
    image: postgres:latest
    ports: 
      - "15432:5432"
    environment: 
      POSTGRES_PASSWORD: example1
      POSTGRES_USER: example1
      POSTGRES_DB: mydb1
    volumes:
      - ./db:/docker-entrypoint-initdb.d
```

**（参考）MySQLの場合**

`docker`の`db:/docker-entrypoint-initdb.d`を定義して

ここではローカルのdbディレクトリの中に初期化したいファイルを置いておきます。

対応しているファイルはPostgreSQLと同様に、以下です。

- `*.sql`
- `*.sql.gz`
- `*.sh`


```docker-compose.yml
version: '3.1'

services: 
  mysql:
    image: mysql:8.0.17
    ports: 
      - "13306:3306"
    environment: 
      MYSQL_ROOT_PASSWORD: example2
      MYSQL_USER: example2
      MYSQL_DATABASE: mydb2
    volumes:
      - ./db:/docker-entrypoint-initdb.d
```

参考ここまで。
以降はPostgreSQLを使った手順になっています。


さて、`./db`ディレクトリに`sql`ファイルを作成します。
このsqlファイルに初期化して敷き込みたいデータを書いておきます。

**`db/init.sql`**

```db/init.sql
set client_encoding = 'UTF8';

create table users (
  id serial primary key,
  name varchar not null,
  age integer not null
);

insert into users(name, age) values 
  ('ichigo.chocomint', 99),
  ('banana.chocomint', 98),
  ('pinapple.chocomint', 97)
;
```

docker-composeを起動します。

```
docker-compse up
```

## データが入っているか確認する

なんでもよいのですが、TypeScriptで書いてみました。

```index.ts
import { Client } from 'pg';

type DatabaseSetting = {
  host: string;
  port: number;
  user: string;
  password: string;
  database: string;
};

class Postgres {
  static async getClient(setting: DatabaseSetting) {
    const { host, port, user, password, database } = setting;
    const client = new Client({
      host,
      port,
      user,
      password,
      database
    });
    await client.connect();
    return client;
  }
}

async function pgSampleQuery(client: Client) {
  return client.query('select * from users');
}

async function main() {
  const pgClient = await Postgres.getClient({
    host: 'localhost',
    port: 15432,
    user: 'example1',
    password: 'example1',
    database: 'mydb1'
  });

  const result = await pgSampleQuery(pgClient);
  console.log(result.rows);
}

// execute
main();
```

結果が以下の通りになっているのでOKでした。

```
[ { id: 1, name: 'ichigo.chocomint', age: 99 },
  { id: 2, name: 'banana.chocomint', age: 98 },
  { id: 3, name: 'pinapple.chocomint', age: 97 } ]
```

おわり。
【C#】排他制御の話

C#だけに限った話ではないけど
余程小さなシステムでもない限り
マルチスレッドを大なり小なり使う機会は多い。

C#は割と手軽にスレッド処理を行えるので登場機会は多い。（と思う）
そうなるとよく問題になるのが排他制御。

データを複数スレッドから同時に操作するとすぐ落ちるし、
タイミングに依存することが多いので
バグ発見が遅れたりします。

この間も現地試験フェーズでうっかりバグが出てしまい、対応した時に使ったクラスが
『ReaderWriterLockSlim』。

特定のクラスが保持する定義データの変更と参照がぶつかって例外。
本来であれば設計段階でしっかり落としておくべきなんだろうけど
終盤ということもあり、影響範囲も考慮したかったので、
シンプルにlock制御しようかと思ったんだけど
データ参照の頻度が高いので何でもかんでも排他すると
GUIでの操作にも影響が出そうだったので調べていて発見。

lockと違い、読み取りロックと書き込みロックを持つので
参照同士は排他されないのがポイント。

```C#:排他制御例
class DataManager
{
	// データ読み書き排他用
	ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();

	/// <summary>
	/// データリスト
	/// </summary>
	private List<int> listData = new List<int>();


	~DataManager()
	{
		// しっかり破棄する
		rwlock.Dispose();
	}

    /// <summary>
    /// リストを参照する処理
    /// </summary>
    private IEnumerable<int> ListData
	{
		get
		{
			try
			{
				// 読み込みロック取得
				rwlock.EnterReadLock();
				return listData.ToList();
			}
			finally
			{
				// 読み込みロック解放
				if(rwlock.IsReadLockHeld)
					rwlock.ExitReadLock();
			}
		}
	}
	
	/// <summary>
	/// リストにデータを入れる処理
	/// </summary>
	/// <returns></returns>
	public void LoadMaster()
    {
		try
		{
			// 書き込みロック取得
			_rwlock.EnterWriteLock();

			// データを取得するような処理
			listData = new List<int>{ 0, 1, 2 };
		}
		finally
		{
			// 書き込みロック解放
			if(_rwlock.IsWriteLockHeld)
				_rwlock.ExitWriteLock();
		}
    }
}
```

ポイントとしては以下。

1. ReaderWriterLockSlimはIDisposableを持つので破棄必須
- ロック取得後に例外が発生すると解放されずにデッドロックする
- ロックを解放する前にさらに取得すると例外が発生する(これは当たり前か)

1はReaderWriterLockSlimがインターフェース持ってるんだからそりゃそうだろ、と言われれば
それまでですが、C#のメモリ管理は勝手にやってくれるし、いいだろ…と
C++とかよりもその辺の意識が薄い人もいるので念のため。
＃過去の自分がそうでした。ダメですね。

2は発生するとヤバいので必ずTry-Finallyで括って確実に解放しましょう。
ロック解放時は念のため、IsReadLockHeld/IsWriteLockHeldで
ロックを保持しているか確認しておくと安心。
＃ロック未保持で解放すると例外

3は普通はまぁやらないと思いますが、ロック取得後に関数をコールして
その関数内でもロック取得、とかやると起きがちです。
排他すべき範囲をしっかり考えて使えば問題ないと思います。
＃要はちゃんと設計しろってことですね…

C#の排他制御も色んな方法があって
パフォーマンス等それぞれ異なるのでケースバイケースで採用していきたいですね。
Rasapberry Piのログインを鍵認証方式にする

#概要
Raspberry Piのsshログインを鍵認証方式へ変更した時の備忘録です。
鍵認証には公開鍵のRSAを使用しました。

動作環境は次のとおりです。
・母艦OS：Windows10
・デバイス：Raspberry Pi 3B
・デバイスOS：Rasbian　jessie

以下、手順です。

#手順
###流れ
１．TeraTerm（sshクライアント）で公開鍵と秘密鍵を生成
２．公開鍵をRaspberry Pi(sshサーバ)に送る
３．Raspberry Piのsshに鍵認証を設定する

##１．鍵生成
[設定]→[SSH鍵生成]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/dbc31716-ab19-0605-79f7-c7fe1983826f.png)

生成する鍵の設定ができます。
今回はビット数を"_4096_"にしました。
初期値の"_2048_"で生成してもOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/ad77886c-083d-d1bf-350f-20df995b5683.png)

鍵の生成後
パスフレーズとコメントを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/7639e9da-f3b6-d67d-2800-671e545ab2be.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/59359e94-b169-a1cd-e582-c2ed38ab0c01.png)

その後、公開鍵と秘密鍵を保存します。
これから生成したファイルを扱うので、わかりやすいパスがいいですね。

次の２つのファイルが生成されます。

```
id_rsa
id_rsa.pub
```

SSFTPやSambaなどを利用して、公開鍵ファイル（id_rsa.pub）をRaspberry Piのhome/pi/に送信しておきます。

その後、Raspberry Piにログインして次のコマンドを流します。

```
mkdir .ssh
cat id_rsa.pub >> .ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
rm id_rsa.pub
```

次はsshの設定をして、鍵認証を有効にします。
設定ファイルを、次のコマンドで開きます。

```
sudo nano /etc/ssh/sshd_config 
```

以下の設定を行いました。

```
port 22　 --> ssh接続ポート
PermitRootLogin no　 --> root権限でのログインを無効
RSAAuthentication    yes  --> RSA認証を有効
PubkeyAuthentication yes  --> 公開鍵認証を有効
AuthorizedKeysFile   %h/.ssh/authorized_keys 
  -->公開鍵登録ファイルのパスと名前を指定
PasswordAuthentication no  --> パスワード認証を無効
```

設定を終えたら、sshのサービスを次のコマンドでリスタートします。

```
sudo /etc/init.d/ssh restart
```

リスタートに成功すると、次のメッセージが出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/5020a58a-f210-bade-520e-28f866e81ba0.png)

#２．sshログイン
それではTeraTermを起動してログインしてみます。
ユーザ名を入力して接続しようとすると。鍵を使うように促されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/738b0b71-6782-3dea-0e43-2175eddc5467.png)

ここで、秘密鍵ファイル（id_rsa）を選択し、鍵生成時のパスフレーズを入力するとログインできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/900e89ea-d99a-b2ab-c65a-ad3b09a6ad1a.png)

ログインできました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/9a74ee59-bb1e-d13d-b253-0de127cd2209.png)

以上。
IntelliJ IDEA でインデントの設定 (Code Style) ＆ ソースコード整形 (Reformat code)

IntelliJ IDEA の Preferences → Editor → Code Style から各プログラミング言語等 (Java, HTML, JSON, Kotlin, XML, YAML など) のコードスタイルを設定できる。インデントもここで設定可能。

Preferences 左上の検索窓に 「code style」 などを入力して検索するとすぐに設定画面に移動できる。

<img width="512" alt="intellij.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139365/7ee60203-248d-30d9-c68e-5cfdbd5d9f12.png">

設定後は、エディタ画面にてショートカットキーでソースコードを整形できる。

ショートカットキーは以下。

- macOS では option + command + L
- Linux と Windows では Ctrl + Alt + L

今回の動作確認環境: IntelliJ IDEA 2018.3.3 (Community Edition)

参考資料:

- [IntelliJ IDEA DEFAULT KEYMAP](https://resources.jetbrains.com/storage/products/intellij-idea/docs/IntelliJIDEA_ReferenceCard.pdf)
- [IntelliJ 公式ショートカット一覧 PDF 日本語版 \- Qiita](https://qiita.com/cypher256/items/8ce0527a46bd7cfe43eb)
AWS Lambdaでのbundle install

#### Lambdaでアプリ作成時にgemインストールできなくてモヤモヤしたので、備忘録。

知らなかったのですが、Lambdaは実行時、ディレクトリを一つずつ実行するようです。
なので、もしそのディレクトリ直下にgemのpathがなければ、いくらbundle installしてもgemが反映されないよ、という話でした。
解決してみれば、それだけ！？という内容ですが、そこに至るまでかなり時間がかかったので、記録に残しておきます。

####bundle installする前に得ていたエラー

```
{
  "errorType": "Function\u003cNameError\u003e",
  "errorMessage": "uninitialized constant HTTParty",
  "stackTrace": [
    "/var/task/post_to_slack.rb:96:in `post_request'",
    "/var/task/post_to_slack.rb:44:in `lambda_handler'"
  ]
}
```

###gemを使用するためにしたこと

ということで、例えば hello_world というディレクトリがあったら、まずその中のGemfileにgemを追加。

そして下記コマンドでbundle installするPathを指定します。

```
$ cd hello_world
$ bundle install --path vendor/bundle
```


```

├── README.md                   
├── event.json                  
├── hello_world                
│   ├── app.rb                 
│   ├── Gemfile
│   └── vendor
│         └── bundle   <-- 追加！
├── template.yaml           
├── Gemfile                   
└── tests                   
    └── unit
        └── test_handler.rb

```

これで、無事gemを使用することができました！
AmazonがSQL++となる新しいクエリ言語、PartiQLをオープンソースで発表

先日、AWSが、PartiQLという、新しいクエリ言語を発表しました。

忙しい人向けに[AWS Open Source Blog](https://aws.amazon.com/jp/blogs/opensource/announcing-partiql-one-query-language-for-all-your-data/)から雑に要約しますので、詳しくは原文をどうぞ。

## 背景・概要

今日、我々が扱うデータは非常に巨大になっており、それらはRDBやNoSQL DB、データレイクと、ユースケースによって様々な方法で保管されます。
例えば、時にはスキーマレスな、ドキュメント指向データベースが非常に便利です。
同時にそういった場面でもSQLやSQL関連のツールを使いたくなることもあります。
ただし今までは、RDBを使うかNoSQL DBを使うかなどで通信方法やフォーマットが異なっていました。
この問題に対して今回AWSが発表したソリューションが、PartiQLです。

PartiQLは、SQL互換性のあるクエリ言語であり、簡単で一貫性のある方法によって異なるフォーマットやサービスとデータのやり取りを行うことを可能にします。
クエリエンジンがPartiQLをサポートする限り、データがどこに、どんなフォーマットで保存されているかに関わらず、効率的なデータとのやり取りを実現します。

これによって、アプリケーションコード（クエリ）を変えることなく、異なるデータソースへとデータを移行させることができます。SQLとの後方互換性があり、さらに多値、ネスト、スキーマレスのデータの拡張機能があり、標準SQLにおけるJOINやフィルター、集計機能とシームレスに融合します。

## PartiQLのデザイン原則

* SQL compatibility（SQLと互換性があること）:
    * これまでのSQLは、これまで通り動きます
* First-class nested data（第一級のネスティング）:
    * SQLの標準機能と同じように、ネストされたデータに対して包括的かつ正確にクエリを実行できます。
* Optional schema and query stability（スキーマレスと、クエリ安定性）:
    * 事前に定義されたスキーマを必要としません。スキーマの存在を前提とするデータベースエンジンでも、スキーマレスエンジンでも、それぞれで使用できます。技術的には、データ自体が同じである限りクエリの結果は変わりません。
* Minimal extensions（最小の拡張機能）:
    * SQLに対する拡張機能は理解しやすく、効率的な実装です。これにより、様々なデータセットの組み合わせに対して直感的にフィルタ処理、結合、集計、およびウィンドウ処理が可能です。
* Format independence（フォーマットの独立性）：
    * クエリはデータフォーマットによらず、例えばJSONやCSVでも、同じように書き込まれます。
* Data store independence（データストアの独立性）：
    * 特定のデータストアによらず、多様なデータストアに適用可能です。

これまでもこの原則のうちいくつかを実装した言語はありましたが、これら全てを原則としている言語はPartiQLが初めてです。

## オープンソースであること

PartiQLはチュートリアルから仕様、実際に動作する参考実装までApache2.0のライセンスでオープンソースとして公開されます。誰でもこの、クエリランゲージの統一に参加することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54274/f97a7f40-af4e-a07e-bd4a-7d8ed26a5c92.png)

PartiQLは既にAmazon S3 SelectやAmazon Glacier Select、Amazon Redshift Spectrum、Amazon QLDB、そしてAmazonの内部システムで使われ、様々な課題を解決しました。近く、より多くのAWSのサービスでサポートされる予定です。Amazonの外部でも、Couchbase Serverがサポートする予定です。

データに関わる全てのユーザーと、全ての産業がこの動きに加わることを期待しています。

## はじめかた

PartiQLを試してみるには、まず最新版のJVMが必要です。
PartiQL REPLは[こちら](https://github.com/partiql/partiql-lang-kotlin/releases)からzipファイルでダウンロードして、 `bin` ディレクトリにある `partiql` （Windowsの場合は `partiql.bat` ）を実行すると、ターミナルが開いてREPLが実行されます。

例えば、以下のようなクエリを実行できます。

```
$ SELECT * FROM [1,2,3]
   | 
===' 
<<
  {
    '_1': 1
  },
  {
    '_1': 2
  },
  {
    '_1': 3
  }
>>
--- 
OK! (187 ms)
```

## PartiQLに参加する方法

PartiQLは上述のようにオープンソースであり、さらに仕様を拡張させ、コミュニティに浸透させていくためにissueや、プルリクエストを歓迎しています。

* PartiQLに関して、より詳しくは[こちら](https://partiql.org/)
* さらに詳しい仕様は、[こちら](https://partiql.org/assets/PartiQL-Specification.pdf)

---

実際にはまだまだこれからという感じですが、PartiQLのようなSQL++を実装するクエリ言語が広まり各クエリエンジンに搭載されることで、僕らの技術選択の幅がこれまで以上に広げやすくなると良いですね。
駆け出してもいないエンジニアとして始めたこと


<h2>自己紹介</h2>
まずは自己紹介をします。
駆け出しエンジニアになるべく独学でプログラミングをしています、名前は「肉まる」です(一応仮。（笑）)(@nikumaru2516)
いまは引きこもり求人を見ながら勉強、基本的には本やサイト見ながらもくもく書いています。

いまはJAVA,PHP,SQL,Laravelあたりを重点的に学んでいますが,ゆくゆくはRudy・Python・PHPあたりからC言語,JavaScript,CSSなどフロントで使うものも3-5年じっくり勉強していく予定。。フルスタックエンジニアになってから方向を考えたい。リーダーやマネージャーになりたい意欲はそこまで、です。。

ちなみにスクールですら未経験ながら画像作成やディレクションを制作会社で未経験で働いていたからか
未経験ながら書類選考はあまり落ちていません

東京での面接に何回か失敗してますが・・・
交通費にお金かかるのでレンタルサイクルで交通費浮かせつつUberで日銭稼ぎしてました。
(スクールで学んでいないのも,お金なさすぎて満喫やカプセルホテル宿泊が辛いので早めに正社員で転職・上京したいです)
いまは地元就職は考えていないため。

面接が一次・二次あるので上手くいった面接、ダメだった面接についても今後はまとめていきます。自分の成長のためのアウトプット、及び初心者の人に伝えたくてブログ等はじめました。

ちなみにテスターは受けていませんが面接練習としてもSESの会社　(アウトソーシング系も)うけてます。家賃補助や福利厚生が整っていれば生活は なんとかなると思ったからです。最悪お金を貯めて1-2年で転職す(ry
転職エージェントに登録はしましたが稼働は3社程度です。(また詳しく書きます)

タイトルにもあるようにエンジニアを目指す前と後で変わった取り組み含め書いています。基本的に週5程度のスパンで学んでいます。

<h2>初学者になる前に習慣にしていること</h2>
現在おこなっていることや何をしているのかを簡単にまとめてみました。
平日2h,土日4h
(動画はそれ以外隙間時間)
※習慣になるように努力していることも含みます。

<h3>ネット・本でまずは1つずつ覚えていくこと</h3>
・一応Progateで課金して8月の1ヶ月で全体サラっとこなす(予定)
・ドットインストール
・Paizaラーニング
・QiitaやSNSで駆け出しの人のアウトプットたまに見てます
＋どの言語を勉強するとき何したらいいか迷ったのでどの本を買うかを確認(本も勉強途中と勉強後に一通り読んだ後でよかったものをまとめます。)判断力がまだ鈍いので基本的にはネットですが(あてにしていないわけではないですが)信用できるまで検索もしてます。(就業中で残業が多かったり時間ない人だと難しいかもしれませんが..)


やる気出ない日はYouTubeも見ていますが今後はSchooに移行します。
他にも英語学習サイトの存在は知っていましたがアレもコレもはスペック的に難しいのでここまで。

(※ただ英語も時間かけても読めるようにはなりたい)

（聞き慣れないも単語も説明できないとわからないのと同じ。
ピカわか さんというかたのサイトも見ています。公式ではないので載せていいかわかりませんでしたが..。）

まだ取り組んでいないサイト(メモ用)：
https://codeprep.jp/
https://www.codecademy.com/learn

<h3>とりあえず作ってみないと無理だと思った</h3>
勉強で基礎をみていてもわかった？と聞かれると理解したとはわたしは、言えませんでした。(断言)有料でスクールに行ってもないしメンターもいないのでそりゃ不安だからです。
調べてもわからなければ質問サイトに投げればいいと思う。(teratailならスクショとったりエラーをコピーして質問したことはあります..;)
あとPaiza内であれば有料の人であれば質問してもいいかもしれませんね(まだしたことない)

<h3>チュートリアルをやる</h3>
勉強とかぶってしましますが..とりあえず作ってみるのは時間がかかるので頭を切り替えるために自分で調べながらする制作と休憩の動画を見るのと勉強サイトは時間を区切ってわたしはわけています。気乗りしない時や、身体が疲れている場合にとても有効です。


<h3>番外：じっくり転職活動中</h3>
面接対策は最初しました。質問を予想し答えをまとめていますが面接練習しながら試行錯誤しています。
なぜエンジニアになりたいのですか？
ここは言えないとダメだと思います。しっかりと自己紹介　なぜ退職したかITなのかなど..
勉強とはズレていますが　エラーがおこったとき原因が考えられるのに面接で原因分析しないと本当にいきたい会社の面接でこけてしまうのでおこなっています。


これは就職が決まり次第ブログに残していく予定です。

習慣にしていくのもエラーで憤ることもありますが　楽しいから初学者として学んでいます。
長くなりましたが読んでいただきありがとうございました。
Sigfox APIを使ってデバイスメッセージの詳細を取得

SigfoxクラウドAPIを利用し、デバイス情報やユーザ情報を取得する方法は、[こちら](https://qiita.com/ghibi/items/b9cb1d26ccff26a427a3)に記載していますが、ここでは、デバイスメッセージ履歴の取得に際し、Callbackステータスや受信フレーム数などを取得する方法を説明します。

#デバイスメッセージを取得するAPI
デバイスメッセージを取得する場合、`/devices/{device-id}/messages`エンドポイントを使用します。具体的には下記GETリクエストにBasic認証を付加してもらえれば結構です。
`https://api.sigfox.com/v2/devices/{device-id}/messages`
*{device-id}のところは、メッセージを取得したいデバイスのID

##ポイントは"fields"パラメータ
デバイスメッセージを取得するAPIの説明は[Sigfox Support](https://support.sigfox.com/apidocs#operation/getDeviceMessagesListForDevice)にまとめられており、ここで、**fields**というクエリパラメータに関する説明が記載されています。
このfieldsパラメータをHTTPパラメータに追加することにより、より詳細情報を取得することが可能になります。
例えば、下記GETリクエスト（Basic認証も必要ですが）の場合
`https://api.sigfox.com/v2/devices/{device-id}/messages?fields=device(name),rinfos(cbStatus,rep)`
応答は下記のようになります。

```
{
    "data": [
       {
            "device": {
                "id": "XXXXXX",
                "name": "My_device_name"
            },
            "time": 1565081856000,
            "data": "0123456789ABCDEF",
            "rinfos": [
                {
                    "baseStation": { "id": "5859" },
                    "rssi": "-133.00",
                    "snr": "12.48",
                    "freq": 923233573,
                    "delay": 2.3450000286102295,
                    "lat": "35.0",
                    "lng": "135.0",
                    "rep": 3,
                    "cbStatus": [
                        {
                            "status": 200,
                            "cbDef": "[POST] https://api.try.iotagency.sigfox.com/api/Messages/sigfox",
                            "time": 1565081858249,
                            "attempts": 1
                        }
                    ]
                },
                ...(省略)...
            ],
            ...(省略)...
        },
```
fieldsパラメータを追加しなかったときに比べ、デバイス名フィールドの他、rinfos以下に**rep**フィールドと**cbStatus**フィールドが追加されていることがわかります。
repは各基地局で受信されたフレームの数、cbStatusはそのメッセージのCallbackステータスが確認できます。

##fieldsパラメータ
fieldsパラメータは下記の定義となっています。

|パラメータ|意味|
|:--------|:---|
|oob|Out Of Band message。デバイスから定期的に送信されているステータス確認メッセージ。詳しくは[こちら](https://support.sigfox.com/docs/out-of-band-(oob)-messages)|
|ackRequired|下り要求メッセージかどうかのフラグ|
|device(name)|デバイス名|
|rinfos(cbStatus,rep,repetitions,baseStation(name))|次表参照|
|downlinkAnswerStatus(baseStation(name))|下り応答ステータス|

|rinfos|意味|
|:-----|:---|
|cbStatus|Callbackステータス|
|rep|各基地局での受信フレーム数|
|repetitions|各フレームのRSSI、SNR等|
|baseStation(name)|受信基地局名|

**＊ただし、API権限により表示されないパラメータもあります。**

[Sigfox Japan KCCS](https://qiita.com/organizations/sigfox)
【Swift】protocol extensionしたクラスをクラス変数として使う方法

# はじめに

swiftのprotocol extensionを使う際に少々詰まったところがあったため覚え書きです。

具体的には、protocol extensionをクラスのフィールド変数として使う際、そのままでは機能しない場合があるという点をご説明します。 
オブジェクト志向の初歩的な仕様であるかもしれませんが、ご参考になれば幸いです。


### 目次
この記事は以下のような構成です。

- protocolの使い方
- protocol extensionの使い方
- protocol extensionをクラス変数として使う方法


# protocolの使い方
まずはprotocolの基本文法です。最もシンプルには以下のようになるかと思います。

``` swift
protocol MyProtocol {
    func hoge()
}

// protocolを継承したクラス
class MyClass: MyProtocol {
    func hoge() {
        print("My Class")
    }
}

let myClassInstance: MyClass = MyClass()
myClassInstance.hoge() // "My Class"
```

# protocol extensionの使い方
続いて、protocol extensionの基本です。

``` swift
protocol MyProtocol {
    func hoge()
}

// 拡張
extension MyProtocol {
    // hoge() を定義 (必要)
    func hoge() {
    }
    
    // hogehoge() を定義
    func hogehoge() {
        print("My extended Protocol")
    }
}

// extensionを継承したクラス
class MyClass: MyProtocol {
    // extension で定義済みの func hoge() は書かなくても良い。

    // hogehoge() を書き換え
    func hogehoge() {
        print("My Class")
    }
}

// protocol extensionをそのまま使う。
let MyProtocolInstance: MyProtocol = MyProtocol()
myMyProtocolInstance.hogehoge() // "My extended Protocol"

// protocol extensionを継承したクラスを使う。
let myClassInstance: MyClass = MyClass()
myClassInstance.hogehoge() // "My Class"
```

ここまでは問題ないかと思います。 

# protocol extensionを継承したクラスをクラス変数として使う方法
少しややこしいのは、上記の 「protocol extensionを継承したクラス」 をクラス変数として使う場合です。

``` swift
// 以下では注意が必要。
class Test {
    var testData: MyProtocol?

    init() {
        testData = MyClass() // 継承後のクラスに変更したつもり...
        testData.hogehoge()
    }
}

// この場合はMyProtocol型オブジェクトになり、継承先のクラスにはならない。
let testInstance: Test = Test() // "My extended Protocol" となる。
```

上記のように ```init()``` において継承先のクラスを用いたつもりが、実際は継承前の protocol extensionが使われることになることが分かります。

この原因として、クラス変数 ```testData``` の型宣言時に継承前のものを宣言していることが関係しているようです。

### protocol extensionを正しくクラス変数として使う
以下の方法で、継承先のクラスをクラス変数として使用できます。

具体的には、一旦protocol extensionを継承した 「親クラス」 に相当するものを用意し、実際に使うクラスとしてこれを継承した 「子クラス」 を用いることで正しく機能します。

``` swift
protocol MyProtocol {
    func hoge()
}

extension MyProtocol {
    // extension では hoge() のみ定義してやることにする
    func hoge() {
    }
}

// extension を継承した 「親クラス」 を用意。
class MyParentClass: MyProtocol {
    // MyProtocolで定義済みの func hoge() は書かなくても良い。

    // 新関数 hogehoge() を定義
    func hogehoge() {
        print("My Parent Class")
    }
}

// 「親クラス」 を継承した 「子クラス」
class MyChildClass: MyParentClass {
    // override を記述した上で hogehoge() を書き換え。
    override func hogehoge() {
        print("My Child Class")
    }
}


// 上記 「子クラス」 であれば、クラスフィールドで使うことができる。
class Test {
    // MyProtocol ではなく、 MyParentClass 型で指定するのが重要。
    var testData: MyParentClass?

    init() {
        testData = MyChildClass() // MyChildClass 型に変更。
        testData.hogehoge()
    }
}

// 継承後の MyChildClass を動作させられている。
let testInstance: Test = Test() // "My Child Class"
```

# 終わりに
いかがでしたでしょうか？

ご参考になれば幸いです！
改善方法やご意見などあれば、どしどしコメント下さい！
【Ethereum IDE】Remixをローカルで動かす + ローカルフォルダと同期する

#概要
Ethereum のオンラインIDE であるRemix をローカル環境で使用し、ローカルのファイルと同期する方法。

#実行環境
- Node 10.16.1
- macOS 10.14 Mojave


#手順
1. remix-ide のインストール
2. remixd のインストール
3. remixd の起動
4. http://127.0.0.1:8080 にブラウザでアクセス
5. プラグインでRemixdを有効にする

##1. remix-ide のインストール
統合開発環境であるremix-ide をグローバルにインストールする

```shell:
npm install remix-ide -g
```
##2. remixd のインストール
remixd をグローバルにインストールする

```shell:
npm install remixd -g
```
##3. remixd の起動
remixd を任意のフォルダを絶対パスで指定して起動する
ここで指定したフォルダとRemix 間で同期が取れるようになる

```shell:
remixd -s <絶対パスでフォルダを指定> --remix-ide http://127.0.0.1:8080
```
##4. http://127.0.0.1:8080 にブラウザでアクセス
IDEが自動で起動されるのでhttp://127.0.0.1:8080 にブラウザでアクセス
<img width="1440" alt="スクリーンショット 2019-08-06 18.33.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390000/aafdc535-bcbf-ad91-183a-32333c11a26c.png">

##5. プラグインでRemixdを有効にする
プラグインを選択する
<img width="1440" alt="スクリーンショット 2019-08-06 18.23.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390000/1d762993-ef0e-b7ab-fbd5-34c65fc2b77f.png">

検索窓で「remixd」と検索してActivate ボタンをおす
<img width="1440" alt="スクリーンショット 2019-08-06 18.23.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390000/37788bed-29ad-98fe-0eac-2dbf66bef25e.png">

出てきた画面のConnect ボタンをおす
<img width="508" alt="スクリーンショット 2019-08-06 18.24.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390000/8a827b3c-3221-a202-5c7a-a178299e4ea9.png">

接続に成功していれば指定したフォルダが表示される
<img width="1440" alt="スクリーンショット 2019-08-06 18.18.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390000/4353d03a-1ca5-0635-f04d-e9b4a029b167.png">

#Happy Hacking :sunglasses: !

#参考
Remix https://remix.ethereum.org
Remix documentation https://remix-ide.readthedocs.io/en/latest/index.html
Action Recognition with Trajectory-Pooled Deep-Convolutional Descriptors ざっくりまとめ

行動認識におけるTDDの概要をまとめておきます。
詳しくは[論文](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwic--bNltzjAhWYzIsBHdrlBLIQFjAAegQIARAB&url=https%3A%2F%2Farxiv.org%2Fabs%2F1505.04868&usg=AOvVaw3rlHmtEUEQSfMG6Gq7N8eY)を参照ください。
あくまで自分用なので悪しからず...
#1.TDDとはどのようなものか？
行動認識の主な手法は
1. 人の手で作られた特徴量(HOG,HOF,MBH)を用いて分類する方法
2. Deep-learningのConvolution-Netで特徴マップを求めて分類する方法
の二つがありました。
TDDはこの二つの手法を組み合わせた特徴量で、これを用いることで認識率を向上させました。

#2.モチベーション
<img width="509" alt="スクリーンショット 2019-07-30 17.33.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473056/0d45888b-88d8-9c1d-14fc-46b1412fbb70.png">

TDDが考案された背景として上記の二つの特徴量のメリットとデメリットを考えます。
###人の手で作られた特徴量(図の上)
- 時間的情報を考慮されている。
- 様々なスピードの動きに対して効果的である。
- visualに対して最適化された特徴量ではないため判別能力が下がっているかもしれない。

###Convolution-Netで得られた特徴マップ(図の下)
- 使用可能なデータセットのデータ量が少ないのに対して学習(two-stream-net)には多くのデータ量が必要であるため人の手で作られた特徴量より認識率が低かった。
- 時間情報と空間情報の違いを無視し、空間情報だけを考慮している。

以上を踏まえて、時間情報と空間情報をリンクさせた特徴量を考えたらうまくいくのではないかと考えられたわけです。

#3.TDDの計算方法
<img width="1170" alt="スクリーンショット 2019-08-06 18.26.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473056/56e17666-f024-8c7c-cda4-2c32c449736f.png">

$$D(T\_k,\widetilde{C}^{a}\_m)=\sum\_{p=1}^P\widetilde{C}^{a}\_m(\overline{(r\_m×x^{k}\_p)},\overline{(r\_m×y^{k}\_p)},z^{k}\_p)$$

$\widetilde{C}^{a}\_m$はconvolution-netで得られた特徴マップでaには空間情報か時間情報かを表す記号が入ります。また、mはm層目の特徴マップということを表しています。
$T\_k$はk個目のdense-opticalflowで$T\_k=\{(x^{k}\_1,y^{k}\_1,z^{k}\_1),(x^{k}\_2,y^{k}\_2,z^{k}\_2),\cdots,(x^{k}\_P,y^{k}\_P,z^{k}\_P)\}$のように軌跡の座標が入っています。
$\overline{(r\_m×x^{k}\_p)}$のところの$r\_m$は$\frac{1}{2^m}$が入ります。これはconvnetにおいて層が１層進むごとに特徴マップ大きさが$\frac{1}{2}$倍されているためです。
ざっくりこの式が何をしているかというとdense-opticalflowで動きの特徴点の座標を求め、特徴マップにおいてその座標の値を参照しています。

#4.実験結果
<img width="555" alt="スクリーンショット 2019-08-06 17.59.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473056/a54ce3ff-9fbb-99af-3421-3dfd271de15d.png">

認識率が上がってますね。
Vueで自分のアカウント一覧を表示させるには

## つくりたかったもの
ポートフォリオ等で使う、githubやqiitaのアイコンを並べて自分のサイトに遷移させるもの
こんなイメージ
![スクリーンショット 2019-08-06 18.19.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260353/4c6984bc-ccb3-6898-73d0-8d53a288fb5b.png)

### 環境
* vue-cli 3.0
* vuetify

## どう作ったか

一部省略はしているが、`v-btn`にて`v-for`して要素を入れていった

```Sample.vue
<template>
　<!-- 一部省略 -->
  <v-btn v-for="website in websites" :key="website" class="mx-4" fab icon>
    <a v-bind:href="website.link">
      <v-avatar size="45">
        <img v-bind:src="website.icon" alt="avatar" />
      </v-avatar>
    </a>
  </v-btn>
</template>

<script>
export default {
  data: () => ({
    websites: [
      {
        text: "Twitter",
        link: "https://twitter.com/your_account",
        icon: require("@/assets/twitter-logo.png")
      },
      {
        text: "Facebook",
        link: "https://www.facebook.com/people/your_account",
        icon: require("@/assets/facebook-logo.png")
      },
      {
        text: "Github",
        link: "https://github.com/your_account",
        icon: require("@/assets/github-logo.jpg")
      }
  ]
};
</script>
```

## 個人的にハマったところ
* `script`の`data`にて`require`を指定しないとうまく表示されなかった
    * 個人的にはtemplate部分で`src=require("website.icon")`としたかった
* リンク部分
    * `v-bind:href`を`img`や`avatar`上に置くとうまくいかなかったため`a tag`で我慢した


## ひとこと
Vuetifyってほんと便利だなー


## ロゴアイコンのリンク集
ポートフォリオでよく使うアカウント系のロゴのリンクをはっておきます

* [Twitter](https://about.twitter.com/ja/company/brand-resources.html)
* [Facebook](https://ja.facebookbrand.com/assets/%E3%80%8Cf%E3%80%8D%E3%83%AD%E3%82%B4/?audience=landing)
* [Wantedly](https://wantedlyinc.com/ja/brand_assets)
* [Github](https://github.com/logos)
* [Qiita](https://help.qiita.com/ja/articles/others-brand-guideline)
Python3系でbase64デコード

# 何でこんなが必要になったか
テスト用に作成したプログラムのconfigがパスワードを平文を書くようになっていたので、覗き見防止のためにパスワードをbase64へ変換してから張り付けるという仕様になったため…

## pythonでbase64パスワードのデコード用に作成
base64のエンコードは以下の手順を踏む

>1. 元データを2進数に変換。
2. 6ビットずつに分ける。
3. 最後が6ビットにならなかったら、6ビットになるまで0を追加
4. 変換表により変換
5. 4の倍数にならなかったら、4の倍数になるまで＝を追加

参考：https://became-free.com/base64-post-problem/

デコード時は穴埋めで使用される'='に対応にしたい

```python
import base64

def decode(passwd):
    dec = base64.urlsafe_b64decode(passwd + '-' * (-len(passwd) % 4))
    return dec.decode('utf-8')
```
MTGを減らすために心がけていること

# MTGを減らすために心がけていること
エンジニアに限った話ではありませんが、長く多量のMTGは業務改善の妨げです。
単純に時間を多く使いますし(参加者の時給合計にMTG時間をかけると大抵とんでもないことになる)、
MTGによって作業時間が細切れにされてしまうと効率が大きく下がります。

しかし、みんなそう思っている割にここの削減に真剣に取り組んでいる人は少ないように思えます。
実際に、前職ではチームを率いるリーダー格になると慢性的に朝から晩までMTGで予定を抑えられ、
まともに自分の作業が出来ないような状態になっていました。

そういう状況を避けるために個人的に色々とやっていることをまとめておこうと思います。

## 前提
この記事で言うMTGは業務上の何らかの決定を下すためのMTGです。
意見を出すためのブレインストーミングや話すこと自体に意味がある1on1は除きます。

## 準備
MTGは準備で8割以上決まります。
ろくに準備していないMTGでは、落としどころが分からないまま出席者が思い付きでしゃべるばかりで議論が拡散してしまいます。
ブレインストーミングならそれでも良いですが、決定を行うためのMTGでは絶対にNGです。

### 資料を事前に共有し論点を整理する
資料を事前に作成して共有しておくことは必須です。
MTGの目的や、議論して決定すべき内容について出席者全員が事前に理解しておかないと、その説明だけで多くの時間を使ってしまいます。
ここに関しては、状況が最も悪い人に合わせざるを得ないので、一人でも事前に読んで考えていない人がいたらMTG自体をリスケするか、その人をMTGから追放するくらいの断固たる態度で臨むべきです。

また、事前に議題を共有するだけでなく、各人の意見も共有できる形でまとめておくとさらに議論がスムーズに進みます。
おすすめはGoogleSpreadSheetで事前に論点を表形式でまとめて、出席者全員に共有しておくことです。
各論点について意見を事前に書いておいてもらうことで、もめる可能性のある重要な部分が洗い出せますし、
そもそも反対意見がほとんどない論点についてはMTGに持っていくことなくその場で決定してしまうことが出来ます。

何にせよ、出席者がその場で考えるようなのはダメです。
MTGはあくまで最小限の議論と決定の場であるべきです。

### ファシリテーターは事前に戦略を練っておく
まず、ファシリテーター(進行役)を決めておくことは必須です。
加えて、ファシリテーターは事前に資料を用意した上で前述のように各人の意見を事前に収集し、
どうMTGを進めるか事前に計画を立てておくべきです。
これは結構時間のかかる作業ですが、出席者全員の工数を減らせると考えれば安いものです。

特に、MTGを成功させるために「何を決めなければいけないのか」を明確にしたうえで
どのような時間配分でそれを達成するのかは考えておきましょう。

事前に集めた情報から揉めそうなところなどよく検討しておくことが必要です。
また、MTGを可能な限り少ない回数で終わらせるため、決めるべきことに漏れがないように検討も重ねるべきです。

## 時間は短く設定する
MTGの時間は可能な限り短く設定しましょう。30分か出来れば15分くらいまで縮めるべきです。
時間が十分にあると、話が脇道にそれることが多くなります。
出席者全員が目的に向かって全力で進まなければならないという認識を共有できるくらいの時間が良いです。

状況が許すなら、MTGをスタンディングで行うなど、出席者に早くMTGを終わらせるインセンティブを与えるのも有効です。

## まとめ
* 準備もせずにMTGを行ってはいけない
* 前提・論点・意見の共有はMTGの前に終わらせておく
* ファシリテーターは議論の終わらせ方のシナリオを練っておく
* 時間は可能な限り短く設定する
Vue.js地雷集(Tips)

## vue-propety-decorator & typescriptで二重にtype定義しなくてよくね？

vue, vue-propety-decorator, vue-class-component, class-api, typescript

```typescript
export default class MyChildComponent extends Vue {
  @Prop({ type: number/* ←これ */ }) hogeId!: number /* ←とこれ */
```

↓

```typescript
export default class MyChildComponent extends Vue {
  @Prop hogeId!: number // これでええやんけ
```

### A: ダメ。死にます。二重なのを我慢して必ず両方に定義しましょう

vueの親テンプレート上から、typescriptの型をガン無視したものを入れれちゃう

```vue:MyParentComponent.vue
<template>
    <my-child-component hogeId="abcd" />
</template>
```

エラー無しで通る。
まじかよ。

## 初期値undefinedのdataが動かない

vue, vue-propety-decorator, vue-class-component, class-api, typescript

```vue
<template>
  <div>{{post.content}}</div>
</template>

<script lang="ts">
export default class extends Vue {
  post!: Post

  created () {
    this.post = { content: "postContent" }
  }

  changePostContent() {
    this.post.content = `${this.post.content}+`
  }
}
</script>
```

- 初期値は画面に出ているみたい
- changePostContentをしても画面に反映されない
- devtoolでみてもpostがdataとして扱われていない

### A. 仕様っぽい nullを利用しよう

undefinedはだめだけどnullはいける。

```diff
export default class extends Vue {
-  post!: Post
+  post: Post | null = null

  created () {
    this.post = { content: "postContent" }
  }

  changePostContent() {
-    this.post.content = `${this.post.content}+`
+    this.post!.content = `${this.post!.content}+`
  }
}
```

- nullだと暗黙unwrap構文が使えないので、各所でforced-unwrapする必要がある
- created(すくなくともbeforeMount)までに初期化しないと死ぬ

## vuex使いたくないがprop-callback地獄にもなりたくない

vue


```vue:PostPage.vue
<template>
  <post :post="post" />
</template>

<script lang="ts">
import PostComponent from './Post.vue'

@Component({
  components: { post: PostComponent }
})
export default class extends Vue {
  post: Post | null = null

  created () {
    this.post = { content: "postContent" }
  }
}
</script>
```

```vue:Post.vue
<template>
  <div>
    <p>{{ post.content }}</p>
    <button @click="changePostContent">changePostContent</button>
  </div>
</template>

<script lang="ts">
import { Prop, Vue, Component } from "vue-property-decorator";
import { Post } from "~/src/Post";
import { PropType } from "vue";

@Component
export default class PostComponent extends Vue {
  @Prop({ type: Object as PropType<Post> }) post!: Post;

  changePostContent() {
    // 本来propを書き換えてもreactiveにはならないが、これはちゃんと画面に反映される
    // 親の方のdataで監視しているオブジェクトの中身を変更しているので
    // 親でdataの変更→propの更新→このComponentのPropの再セットが起こる(ということだと思う)
    this.post.content = `${this.post.content}+`;
  }
}
</script>

```

以下のようにすればvuexを使わずともprop-callback地獄にならない。
静的なものではなくて、ライフサイクルがある親コンポーネントと一致しているstate-storeは、こっちのほうがいいとおもう。
誰がそのstateを更新するかわからないのはvuexも同じだし。更新手続きをカプセル化してるのもvuexと同じ。
デメリットとして、redux的な思想の「storeツリーを再現したらアプリのあらゆる状態が再現できる」が満たせなくなる。
docker toolboxでホストのディレクトリがマウントできない場合の対処方法

windowsでdockerでのローカル環境構築をしているときに
C:\Users配下がうまくマウントできない現象に悩まされ
無事解決することができたのでメモとして残しておきます。

# 原因
https://github.com/boot2docker/boot2docker/releases
~/.docker/machine/cache/boot2docker.isoのVirtualBox Guest Additionsが
現在イントールしているVirtualBoxのバージョンと一致していなかった

# 解決方法1
https://github.com/boot2docker/boot2docker/releases
boot2docker.isoを現在インストールしているVirtualBoxのバージョンと一致するものをダウンロード
~/.docker/machine/cacheにコピー
docker-machine createを行う

# 解決方法2
最新のboot2docker.isoのVirtualBox Guest Additionsのバージョンに一致するVirtualBoxをインストールする
~/.docker/machine/cache/boot2docker.isoが存在する場合削除する
docker-machine createを行う
DynamoDBからすべてのレーコドを削除する

テストように実行したバッチ処理にてDynamoDBに２万件以上のレーコドができてしまった。コンソールで削除するのも時間の無駄なので簡単lambdaにて削除しました。

こんなに簡単ですね！

```python
import boto3
from botocore.exceptions import ClientError

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
table = dynamodb.Table('my_table_name')

def deleteItem(hashKey, rangeKey):
    try:
        response = table.delete_item(
            Key={
                'my_hash': hashKey,
                'my_range': rangeKey
            }
        )
    except ClientError as e:
        raise
    else:
        print("DeleteItem succeeded:")
        
def lambda_handler(event, context):
    
    pe = "my_hash, my_range" #projection fields
    
    response = table.scan(
        ProjectionExpression=pe,
        )
    for i in response['Items']:
        hashKey = i["my_hash"]
        rangeKey = i["my_range"] 
        deleteItem(hashKey,rangeKey)
    
    while 'LastEvaluatedKey' in response:
        response = table.scan(
            ProjectionExpression=pe,
            ExclusiveStartKey=response['LastEvaluatedKey']
            )
    
        for i in response['Items']:
            hashKey = i["my_hash"]
            rangeKey = i["my_range"] 
            deleteItem(hashKey,rangeKey)
    
    
    return 'Successfully complete delete all items from table.'
```
【Photoshopスクリプト】選択中のレイヤーを一括トリミングして個別エクスポートする

## はじめに
以下を実現するスクリプトを作ってみたので紹介します。

「複数選択しているレイヤーに対して、周辺の余白をトリミングして個別にpngファイルとしてエクスポートする」

例えば、レイヤー1とレイヤー2とレイヤー3を選択している状態でこのスクリプトを実行すると、
それぞれのレイヤーの**余白部分がトリミングされた状態で
レイヤー1.png、レイヤー2.png、レイヤー3.png が出力されます。**

## 環境
OSバージョン : Windows 10
Adobe Photoshop バージョン : 19.1.3 20180323.r.293 2018/03/23: 1163761  x64

## JSXスクリプト
````trim_selection_layers.jsx
if (app.documents.length > 0) { // ドキュメントが1つ以上開かれている場合のみ実行
    // 現在のドキュメント
    var doc = app.activeDocument;

    // 保存先フォルダの選択
    var saveFolder = Folder.selectDialog("トリミングイメージの保存先フォルダの選択");
    if (saveFolder != null) {       

        var copiedDoc = app.activeDocument.duplicate(); // ドキュメント複製
        selectedLayers = GetSelectedLayers();

        // 選択中の全レイヤーをいったん非表示
        for (index = 0; index < selectedLayers.length; index++) {
            selectedLayers[index].visible = false;
        }
        for (index = 0; index < selectedLayers.length; index++) {
            selectedLayers[index].visible = true;
            activeDocument
                .trim(TrimType.TOPLEFT, true, true, true, true); // トリミング対象＝左上の色
            // alert(selectedLayers[index]);
            
            // saveAsで保存
            saveAsPng(doc, saveFolder, selectedLayers[index].name + ".png");
        
            stepHistoryBack();
            selectedLayers[index].visible = false;
        }

        copiedDoc.close(SaveOptions.DONOTSAVECHANGES);
    }
}

// UNDOを実行
function stepHistoryBack() {
    var desc = new ActionDescriptor();
    var ref = new ActionReference();
    ref.putEnumerated(charIDToTypeID("HstS"), charIDToTypeID("Ordn"), charIDToTypeID("Prvs"));
    desc.putReference(charIDToTypeID("null"), ref);
    executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
};

// 選択中のレイヤーを取得(https://forums.adobe.com/thread/2281117)
function GetSelectedLayers() {
    var A = [];
    var desc11 = new ActionDescriptor();
    var ref9 = new ActionReference();
    ref9.putClass(stringIDToTypeID('layerSection'));
    desc11.putReference(charIDToTypeID('null'), ref9);
    var ref10 = new ActionReference();
    ref10.putEnumerated(charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
    desc11.putReference(charIDToTypeID('From'), ref10);
    executeAction(charIDToTypeID('Mk  '), desc11, DialogModes.NO);
    var gL = activeDocument.activeLayer.layers;
    for (var i = 0; i < gL.length; i++) {
        A.push(gL[i]);
    }
    executeAction(charIDToTypeID('undo'), undefined, DialogModes.NO);
    return A;
};


/**
 * ドキュメントをPNG画像として保存します(別名で保存相当)。
 *
 * @param {Document} doc
 * @param {Folder}   folder
 * @param {string}   name
 *
 */
function saveAsPng(doc, folder, name) {
    // フォルダが存在しない場合作成
    if (!folder.exists) {
        folder.create();
    }
    
    var file = new File(folder.fsName + "/" + name);
    // PNG保存のためのオプション
    var options = new PNGSaveOptions();
    var asCopy = true;
    // 保存
    doc.saveAs(file, options, asCopy, Extension.LOWERCASE);
}
```

## 参考URL
選択中のレイヤーを取得するJSXは下記URLを参考にしました。
https://forums.adobe.com/thread/2281117