OmniAICreator/Qiita-1.07M huggingface dataset:
オブジェクト指向について解説！

# はじめに
- オブジェクト指向について本やネットの情報から調べて理解したことをまとめました。
- もし、書いていることに何か間違いがある場合はご指摘いただけると嬉しいです。

# オブジェクト指向とは
- 機能をオブジェクトごとにまとめて、プログラムを書いていくという考え方です。
- PHPでは、クラスという設計図をもとにインスタンス（オブジェクトとも呼ばれる）を生成していきます。


## オブジェクトとは
- データ（変数）と機能（関数）をまとめたモノ（オブジェクト）。

## クラスとは
- オブジェクトの設計図。
- テンプレート（雛形）のようなイメージ。
- クラスを元にオブジェクトを作っていきます。

### クラスの書き方
- クラスは「class クラス名」と定義する。
- クラス名は大文字で始めます。

```php
<?php
  class Products{
   //ここに処理が入ります
  }
?>
```

## オブジェクト指向のイメージ
- 現実世界の自動販売機（オブジェクト）を例に言葉のイメージを説明します。
### 現実世界の場合
<img width="1143" alt="スクリーンショット 2019-05-01 17.38.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392565/8e346bf2-3b3d-14bc-7721-f7bccf19695b.png">


- 自動販売機には次のような「データ」と「機能」があります。

### 設計図にまとめられている内容

- **「データ」**
  - 商品名
  - 金額


- **「機能」**
  - 商品を出す
  - おつりを計算する

- この設計書を元に自動販売機を作成していきます。
- 設計書があるため、設計書を元に自動販売機を量産することも可能です。

### オブジェクト指向の場合
<img width="1121" alt="スクリーンショット 2019-05-01 17.38.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392565/0df02726-1290-88af-3b66-7beffe1b02ad.png">


- オブジェクト指向の場合、現実世界の設計書のことを「クラス」と呼びます。
- データのことを「プロパティ」と呼び、機能のことを「メソッド」と呼びます。

## インスタンスとは
- クラス（設計図）をもとに実体化されたものをインスタンスと言います。（オブジェクトとも呼びます）
- インスタンスは「new　クラス名()」で生成できます。

### インスタンスの書き方

```php
<?php
class Products{

}

$product = new Products();
?>
```

## プロパティとは
- クラスが持つ変数（データ）のことです。
- クラスで定義された変数のことを「プロパティ」と言います。

### プロパティの書き方
- プロパティは「public $プロパティ名」で定義します。（publicの他にprotectedやprivateが入ります）

```php
<?php
class Products{
	public $name = "パソコン";

}

$product = new Products();
?>
```
#### プロパティの呼び出し方
- 「インスタンス->プロパティ名」で、そのインスタンスが持つプロパティを呼び出すことができます。
- クラスに定義されている値を取り出すようなイメージです。

```php
<?php

class Products{
	public $name = "パソコン";

}

$product = new Products();

echo $product->name;

```
## メソッドとは
- クラスが持つ関数のことです。
- クラスで定義された関数を「メソッド」と言います。

### メソッドの書き方
- メソッドは「public function メソッド名()」のように定義します。
- 「インスタンス->メソッド名()」でメソッドを呼び出します。

```php
<?php

class Products{
	public $name = "パソコン";
	public function sayProduct(){
		echo "商品名：" . $this->name;
	}
}

$product = new Products();
$product->sayProduct();

?>
```

## オブジェクト演算子「->」とは
- 「->」の記号のことをオブジェクト演算子と言います。
- `「インスタンス->プロパティ名」`、`「インスタンス->メソッド名()」`や`「$this->プロパティ名」`、`「$this->メソッド名()」`のように定義します。
- 右辺には左辺が持つプロパティやメソッドを指定します。そうすることで、そのクラスが持つプロパティやメソッドを呼び出すことができます。

## $thisとは
- クラス内のプロパティやメソッドを呼び出したい時に「$this」を使います。 
- 「このクラス内の」という意味になります。
- 「$this」はクラス内の定義したメソッドの中でのみ使用できます。 

### $thisの書き方

```php
<?php
class Products{
 
  public $name = "パソコン";
 
  public function sayProduct(){
    echo $this->name;
  }
}
?>
```

## コンストラクタとは
- 「__construct」を定義すると、newを用いてインスタンスが生成される度にこのメソッドが呼ばれる。 
- __constructメソッドは引数をとることができます。 
- インスタンスを生成する時に引数を与えることができ、その引数の値が__constructメソッドに渡されます。

### コンストラクタの書き方
```php
<?php

class クラス名 {
    アクセス修飾子 function __construct(引数) {
        //ここに処理が入ります
    }
}

?>
```
### コンストラクタのコード例
```php
<?php

class Products{
	public function __construct($name){
		echo $name;
	}
}

$product = new Products("パソコン");

?>
```
```php:実行結果
パソコン
```
ReduxのmiddlewareでAPI呼び出しを共通化する with TypeScript

- 追記
    - 2019年6月1日: 汎用部品化して、npmリポジトリに公開した。
        - [@ytkj/redux-axios-middleware](https://www.npmjs.com/package/@ytkj/redux-axios-middleware)
    - 2019年11月3日: セキュリティバグフィックス
    - 2020年5月1日: セキュリティバグフィックス


# 概要

REST API呼び出し周りには共通的な処理が多くある。

- ローディングスピナー表示
- `axios`によるAjaxリクエスト
- レスポンスを元に
    - 正常時：`Action`発行
    - 例外時：例外`Action`発行
- ローディングスピナー非表示

`redux`の`middleware`を定義することで、これらの処理を共通部品化する。

# 車輪の再発明？

[redux-api-middleware](https://www.npmjs.com/package/redux-api-middleware)とやりたいことはほぼ同じ。ただTypeScriptの型定義ファイルが無いことと、微妙に要件が合わないことが多かった。なのでTypeScriptで一から開発した。

# インストール

`npm i -S @ytkj/redux-axios-middleware`

# 使い方

`createStore()`するときに`raMiddleware`を組み込む。`thunkMiddleware`も忘れずに組み込む。

```typescript:store.ts
import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';

import { createRAMiddleware } from '@ytkj/redux-axios-middleware';

/* importなど省略 */

const raMiddleware = createRAMiddleware({
    actionBeforeFetch: log('ajax:start;'),  // REST API呼び出し前に発行したいAction
    actionAfterFetch: log('ajax:finish;'),  // REST API呼び出し後に発行したいAction
    actionOnFail: log('ajax:fail;'),  // REST API呼び出しが正常終了しなかった（ステータスコードが400、500番台）場合に発行したAction
    actionCreatorOnFail: handleError, // REST API呼び出しが正常終了しなかった時に呼び出したいActionCreator
    axiosClient: axios,
});

export const store = createStore(
    reducer,
    applyMiddleware(raApiMiddleware, thunkMiddleware)
)
```

あとは`ActionCreator`の中から`raAction()`を呼び出せばOK。

```typescript:foo.action.ts
import { Action } from 'redux';
import { ThunkDispatch, ThunkAction } from 'redux-thunk';
import { raAction } from '@ytkj/redux-axios-middleware';

import { State } from '../states/states';

export const FOO_ACTION: 'FOO_ACTION' = 'FOO_ACTION';

export interface FooAction extends Action<typeof FOO_ACTION> {
}

export function fooAction(
    id: number,
    value: string
): ThunkAction<Promise<raAction>, State, void, raAction> {

    let thunkAction = async(
        dispatch: ThunkDispatch<State, void, raAction>,
        getState: () => State
    ): Promise<raAction> => {

        return dispatch(raAction({
            url: `/api/foo/${id}`,
            method: 'PUT',
            requestBody: {value},
            successActionType: FOO_ACTION,  // REST API呼び出しが正常終了した場合に発行したいActionのtype。payloadとしてREST APIからのレスポンス本体が設定される
        }));
    }

    return thunkAction;
}
```

次の処理を行ってくれる。

1. `actionBeforeFetch`に指定した`Action`を`dispatch()`
2. `axios.put()`呼び出し
3. レスポンスを元に
    - 正常時：`successActionType`に指定したtypeの`Action`を`dispatch()`。この例の場合は`{type: FOO_ACTION, payload: response.data}`を`dispatch()`
    - 例外時：
        - `actionOnFail`に指定した`Action`を`dispatch()`
        - `actionCreatorOnFail`に指定した`ActionCreator`を実行（`AxiosError`オブジェクトを引数として渡す）して`dispatch()`
1. `actionAfterFetch`に指定した`Action`を`dispatch()`

その他のオプションはAPIドキュメントを参照のこと。

- npm
    - [@ytkj/redux-axios-middleware](https://www.npmjs.com/package/@ytkj/redux-axios-middleware)
- GitHub
    - https://github.com/ytkj/redux-axios-middleware
obnizでAI関係のブロックを使って人を認識する

この記事は、[obnizを中心にプログラミング教育の教材を作ったりする（1人アドベントカレンダー）](https://gw-advent.9wick.com/calendars/5)のために作成されました。[前の記事](https://qiita.com/dietposter/items/f31f1abbd959653df265)の続きになっています。

#概要
obnizはIoT・電子工作を初めて習う人に向いてます。Webを少しかじっていればHTML/CSS, JavaScriptによる「プログラム」ができますし、それに加えて「ブロックプログラム」も使えます。
「ブロックプログラム」では決められたブロックを配置していくだけで比較的簡単にプログラムができあがります（ただし「プログラム」より出来ることが多くありません）。
ここでは、AIカテゴリのブロックを用いて簡単なAIをやってみたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/d5065cb4-f6c5-f9ff-888c-38c879384596.png)

#ブロックプログラムで画像認識

##準備
あらかじめobnizはWiFi接続の設定を行い、プログラム用パソコンではobnizサイトで「ブロックプログラミング」画面を表示させておきます。[前の記事](https://qiita.com/dietposter/items/f31f1abbd959653df265)の以下を行います。

* [WiFi接続を行う](https://qiita.com/dietposter/items/f31f1abbd959653df265#wifi%E6%8E%A5%E7%B6%9A%E3%82%92%E8%A1%8C%E3%81%86)
* [obnizサイトにアクセス](https://qiita.com/dietposter/items/f31f1abbd959653df265#obniz%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9)

obnizサイトの「ブロックプログラミング」を表示させたとき、もし以前使っていた不要なブロックがあれば、すべて削除します。画面上にあるブロックをすべて削除する場合、プログラム画面を右クリックして表示されたコンテキストメニューの一番下の[〇個のブロックを削除]を選びます。削除してもよいか確認ダイアログが出たら[OK]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/31b78e26-caaa-2886-391c-be56ecf2cb7c.png)


##顔認識をさせよう
1. 以下のブロックを並べてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/8a3f5c49-2182-c4c2-701a-b077696db07c.png)
並べることができたら、画面右上の![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/eb03c1d7-582d-8871-fd92-53d363933e7a.png)ボタンをクリックして実行してみます。

2. パソコンまたはタブレットの画面上でカメラが許可されれば、以下のような画面になります。自分自身が写っていれば、「だれかいる」と表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/c492ea0a-34be-f819-1afe-ef2ae70630a8.png)
顔をカメラから写らないようにすれば「いない」と表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/81ea4b34-7248-c491-5c13-3d4ecde4907c.png)
うまくできましたでしょうか？

##画像で顔認識させる
顔の認識は、実際に人間がいなくても「顔の画像」だけで顔認識されてしまいます。以下は、iPadにプーチンの画像を表示させて写してみたものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/d7eaebab-9c1f-0305-1443-8a220c035ef8.png)
人間がいなくても、画像さえあれば「顔」として認識されてしまいます。次にバナナの画像を写してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/cac56047-17b1-774a-0618-6d4edf7b422c.png)
もちろん人ではないので、顔として認識されません。ただしAIカテゴリにある![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/3b8ce5a2-dac1-d164-5569-c3e819b51873.png)
を用いれば、バナナとして認識されるでしょう。AIによるシンプルな画像認識では、画像による「なりすまし」が可能なのです。
Dockerについて調べてみた

Dockerは仮想化技術を使ったアプリケーションの実行環境を構築/運用するためのプラットフォーム


そもそも仮想化技術とは？
-
本番環境と同じ環境を開発環境として用意したいけど、現実的でない...
理由として、物理サーバーなどの物理的コストや開発環境のメンテナンスにかかる時間的コストが存在する。

仮想的にサーバを動かす（仮想化）ことができれば、物理的・時間的・金銭的コストを下げることができる。

さらに、仮想化ソフトウェアを使うことで仮想的にいくつものOSを動作させたり破棄したりすることができる。

3つの仮想化
- 
- ホスト型仮想化
 - ハードウェア上にベースとなるホストOSをインストールしホストOSに仮想化ソフトウェアをインストールし、仮想ソフトウェア上でゲストOSを動作させる。
 - メリット = 
 - デメリット = 仮想化を行うために必要となるホストOSのスペック
- ハイパーバイザー型仮想化
 - ハードウェア上に仮想化を専門に行う「ハイパーバイザー」を配置し、ハードウェアと仮想環境を制御する。 
 - メリット = ホストOSがなくハードウェアを直接制御するため、リソースを効率よく使用できる。
 - デメリット = 仮想環境ごとにべつのOSが動くので、仮想環境の起動にかかるオーバーヘッドの大きさ
- コンテナ型仮想化
 -  ホストOS上にコンテナをつくり、コンテナごとに必要なものを閉じ込めて個別のサーバーを使っているかのようにする。
 - メリット = 他の仮想化に比べると、軽量で高速

Dockerとは
-
- インフラ環境をコンテナとして管理し作成したコンテナのもとになる DockerImageをDockerHubを介して共有することができ、開発/テスト環境と本番環境では動かないといったリスクがさがる（移植性がある）
- さまざまな組織やシステムと連携して利用することができる（相互接続性がある）

Dockerの基本機能
-
- Dockerイメージを作る機能　
  
　Dockerイメージ = 実行環境で動くコンテナのもと
　Dockerイメージは、Dockerfileから作ったり手動で作ったりすることができる

- Dokcerコンテナを作る機能

　DockerはLinux上でコンテナ単位でサーバーを動かすことができる。
　Dockerコマンドを利用してコンテナの操作を行う。
　
- Dockerイメージを公開/共有する機能
commit コマンドの -a オプションが便利だった話

##概要
タイトルのとおり、Gitにおいて`commit`コマンドを使用する際に`-a`を付けると便利だという話をします。

##本論
早速本論に入りますが、

これまで自分は、変更済みのファイルをすべてコミットする際は

```
$ git add . 
$ git commit -m "commit message."
```

と２回コマンドを叩いていた。しかし、最近`commit`コマンドのオプションの1つである`-a`の存在を知りました。

このオプションをつけることで修正または削除したファイルを**自動でインデックスに追加してくれた上でコミット**することができます。

つまり、何が嬉しいかというと今までコミットするまでに２回コマンドを叩いていましたが、**1回コマンドを叩くだけでコミットが可能になる**ということです。

具体的には

```
$ git commit -am "commit message."
```

または

```
$ git commit -a -m "commit message."
```

のように入力することで、わざわざ`add`することなく、コミットができてしまうのです。

ただし、`-a`オプションにおいて、**新規作成されたファイルに関しては適用されない**という点には注意が必要です。

そのため、新規作成ファイルが存在する場合には`add`コマンドを使う必要があります。

##まとめ
`commit`コマンドを用いる際に`-a`オプションをつけると、`add`する必要がなくなります。
ただし新規ファイルには適用されないので、新規ファイルが存在する場合には注意が必要です。
最後までお読みいただきありがとうございました。

##参考
https://git-scm.com/docs/git-commit
Reactプロジェクト立てるときのメモ

# 概要

Reactプロジェクト立てるときのメモ

# 内容

**ルーティング**

```sh

yarn add react-router-dom
```

**CSS in JS / UIライブラリ**

```sh
yarn add styled-components semantic-ui-react semantic-ui-css
```

**Lint設定**

- airbnbの設定をベースにする
- VSCodeで保存したら修正されるようにしたい

```sh
yarn add eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y babel-eslint
```
.eslintrcを作成

```json:.eslintrc
{
  "extends": "airbnb",
  "parser": "babel-eslint",
  "globals": {
    "fetch": false,
    "window": false,
    "document": false
  },
  "rules": {
    "array-callback-return": 0,
    "react/no-unused-state": 1,
    "no-unused-vars": 0,
    "react/jsx-filename-extension": 0,
    "react/prop-types": 0,
    "max-len": 0
  }
}
```
VSCodeの拡張機能からESLintをインストール
VSCodeの設定からLintのAutoFixを有効にする

# :ok_woman: 

都度追加していく
ドルフロのイベントを考察する

#これは何？
今ドルフロで「ビンゴシステム」というイベントが開かれています。

ルーに関してはざっとこんな感じ
①特定任務達成でカードが1枚もらえる
②カードには1~36のランダムな数字が書かれている
③そのカードの数字のマスを開けることができる
④すでにあけてあるマスの数字がもう一度当たった場合は何も起こらない[^1]
[^1]: 確定解読に関しては今回は触れません
![](https://www.4gamer.net/games/405/G040593/20190411086/TN/003.jpg)

重複がなければ36枚でコンプリートですが、たいていは重複があるので更なる枚数が必要です。
ということで、コンプリートするまでの枚数の期待値を調べることにしました。

#方法①：大量にシュミレーションする

```python
import random
cell_num=36
result={}
for i in range(1,cell_num+1):#初期化
    result[i]=[]

def Run():
    already=[]
    counter=0
    while True:
        counter+=1
        r=random.randrange(1,cell_num+1)
        if r not in already:
            already.append(r)
            result[len(already)].append(counter)
            if len(already)==cell_num:#この時点で全部埋まってたら
                break

size=1000
for i in range(size):#1000回やって平均をとる
    Run()
    
for i,counts in result.items():
    print(i,sum(result[i])/size)
```
##結果
```
1 1.0　　←1マス目は絶対1回で開く
2 2.033　←2マス開けるのに必要なカードの期待値
3 3.081　←3マス開けるのに(ry
4 4.151
5 5.292
6 6.447
7 7.633
8 8.875
9 10.164
10 11.478
11 12.884
12 14.307
13 15.803
14 17.313
15 18.956
16 20.588
17 22.441
18 24.258
19 26.198
20 28.314
21 30.593
22 32.975
23 35.489
24 38.422
25 41.437
26 44.626
27 48.263
28 52.451
29 56.993
30 62.149
31 68.149
32 75.408
33 83.906
34 96.066
35 114.263
36 150.705
```

#方法②：確率の計算をする
例えば、36マス中20マスが埋まっている状態を考えると、
1回で開く確率は(16/36)
2回目で開く確率は、(20/36)×(16/36)←1回目に重複する確率×2回目に当たる確率
3回目で開く確率は、(20/36)×(20/36)×(16/36)

といった感じで計算して、それらの確率×回数　の平均が期待値となります。

```python
import random
cell_num=36

def Solve(num):
    if num==1:
        return 1.0
    else:
        out=0
        all_fail_prob=1
        i=1
        while(True):
            out+=all_fail_prob*(1-(num-1)/cell_num)*i
            all_fail_prob*=(num-1)/cell_num
            i+=1
            if all_fail_prob<0.0001:#確率が0.01%をした回った時点で終了
                return out

        
start=time.time()
count=0
for i in range(1,37):
    count+=Solve(i)
    print(i,count)



```

##結果
```
1 1.0　　　　　　　　　　←1マス目は1回で開く
2 2.0284850823045266　　←2マス開けるのに必要なカードの枚数の期待値
3 3.0872604214296597　　←3マス開けるのに(ry
4 4.1779240016765735
5 5.3028202742637465
6 6.463792170353223
7 7.663637849365569
8 8.904625783402167
9 10.190118329977318
10 11.522943037008568
11 12.90722576477284
12 14.346508476931167
13 15.8459750216652
14 17.410756336838382
15 19.046199369676764
16 20.759649541919302
17 22.558829777868826
18 24.452701778909887
19 26.451725216409887
20 28.56819680788394
21 30.81669400234482
22 33.21544623832343
23 35.78501202648405
24 38.55229318830238
25 41.5499764638119
26 44.82046996685763
27 48.41787176930729
28 52.41508421449354
29 56.91128492201391
30 62.04973003709878
31 68.04451050819073
32 75.23799758337739
33 84.22999125499628
34 96.21834209653234
35 114.20120836563238
36 150.16496409399065
```

#まとめ
36マス全部開けるのに150枚もいるのかよ！！　みたいな
ガチャガチャ全種類集めるには・・みたいな計算に応用できるかもしれません。
gooの時刻情報正規化APIを使う

# 概要
* rubyで[gooの時刻情報正規化API](https://labs.goo.ne.jp/api/jp/time-normalization)を使う

# 目的
文書から和暦、西暦を含めた日付を標準化して抽出する。

# 手順
* gooでapiキーを取得します。Githubのアカウントが必要なので取得します
https://labs.goo.ne.jp/jp/apiregister/

* httpclient gemをインストールします

* 下記のclassを読み込みます。 `APP_ID` はご自分のIDに置き換えてください。

```goo_chrono.rb
require 'httpclient'
require 'json'

# gooの時刻情報正規化APIを使うためclass
# https://labs.goo.ne.jp/api/jp/time-normalization

class GooChrono
  REQUEST_URL = 'https://labs.goo.ne.jp/api/chrono'
  APP_ID = ENV['GOO_API_KEY'] # YOUR GOO API KEY

  attr_reader :response, :sentence

  def initialize(attr = {})
    @request_id = attr[:request_id] || nil
    @sentence = tr_sentence(attr[:sentence])
    @doc_time = doc_time(attr[:doc_time])
  end

  def post
    client = HTTPClient.new
    content = params.to_json
    res = client.post_content(REQUEST_URL, content, 'Content-Type' => 'application/json')
    @response = JSON.parse(res)
  end

  def first_date_time
    raise StandardError, '先にpostしてください' unless @response.present?
    return nil if @response['datetime_list'].first.nil?
    Time.zone.parse(@response['datetime_list'].first[1])
  end

  private

  def params
    hs = { app_id: APP_ID,
           sentence: @sentence,
           doc_time: @doc_time.strftime("%Y-%m-%dT%H:%M:%S") } # "%Y-%m-%dT%H:%M:%S"
    hs.merge(request_id: @request_id) if @request_id.present?
    hs
  end

  def doc_time(str)
    if str.present?
      Time.parse(str)
    else
      Time.now
    end
  end

  # 2019.01.01 などを2019/01/01 に変換しないと認識しなかったので。適宜前処理。
  def tr_sentence(str)
    str = str.gsub(/(　| )/, '')
    str = str.gsub(/(\t|\n)/, '')
    str = str.tr('０-９ａ-ｚＡ-Ｚ', '0-9a-zA-Z')
    str = str.gsub(/(\.|・)/, '/')
    str = str.gsub(/(-|ー)/, '/')
    str.strip
  end
end
```

# 試す

```irb
pry(main)> goo_chrono = GooChrono.new(sentence: '平成30年11月2日')
=> #<GooChrono:0x00005630896fe1f8 @doc_time=Wed, 01 May 2019 07:56:41 UTC +00:00, @request_id=nil, @sentence="平成30年11月2日">
pry(main)> goo_chrono.post
=> {"request_id"=>"labs.goo.ne.jp\t1556697406\t0", "doc_time"=>"2019-05-01T07:56:41", "datetime_list"=>[["平成30年11月2日", "2018-11-02"]]}
pry(main)> goo_chrono.first_date_time 
=> Fri, 02 Nov 2018 00:00:00 UTC +00:00
```

以上
Cisco Passlogicのワンタイムパスワードを自動抽出

VPN接続するときにCisco AnyConnectを使っているところは多いだろう。
ものによっては48桁の番号から自分で手作業でワンタイムパスワードを生成しなければならない。
正直めんどくさい。
ということで、passlogicのサイトから番号を抽出してきて、自分の並び順に自動で並び替えることをpythonでやってみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395136/ad7e5a14-82b9-bdaf-fe1a-0e61cd631f16.png)
※[画像はここから転載](https://www.dsol.co.jp/solution_2.html)

実際のコード

    # coding: UTF-8
    import requests
    import urllib.request, urllib.error
    from bs4 import BeautifulSoup
    import lxml.html
    import numpy as np

    # アクセスするURL
    r = urllib.request.urlopen("URL")
    data = r.read().decode('utf-8')

    soup = BeautifulSoup(data, 'html.parser')
    #tdタグの部分だけa2に全部いれる
    a2 = soup.find_all('td')

    result =  []
    bs = np.array([])
    count = 0

    for e in a2 :
        if count < (passlogicの取得MAX件数):
            result.append(e.getText())
            count += 1
    else:
        arr = np.array(result)
        #自分で持っているpasslogicの並び
        bs = (arr[?],arr[?],arr[?],arr[?],arr[?],arr[?],arr[?],arr[?])
        print(np.char.strip(bs))

pythonすごい便利...

##参考
https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406
https://qiita.com/Azunyan1111/items/b161b998790b1db2ff7a
他いくつかあったのですが...あとで記載します。
Rubyを使っていたJava初心者がSpringの学習でつまづいたこと、解決の為にしたこと

**20190508更新**
#Springを始めよう
私はずっとRubyを使ってきたのですが、Javaを使うことになり、そのためのトレーニングをすることになりました。
そこで初めてSpringを使ったのですが、今までRubyとRailsを使って開発をしていたのでつまるところがあり、できればこれを共有したいと今回書くことにしたわけです。
レベル感でいうと、本当にJavaの基礎について、Webの基礎についての本を読んで少し手を動かした程度です。

#何に詰まったか
何に詰まったかというと、MVCの形がRailsと違った為に、どのような形で実装すればいいかわからなくなったこと。
これはSpringをやってから気づいたんですが、RailsのMVCってかなり簡単に実装できるように作られているんだなぁと感じました。
まさにMVCそれぞれ、ModelとView、Controllerがそれぞれ三つだけに別れているので、何を書いていけばいいかが割と簡単にわかる。すごく楽ですね。
一方、SpringはMVCの実現がやや違う形になります。
Controller、Service、Entity、Repositoryに別れると。
Controllerの役割についてはRailsとそれほど変わらないのでわかりましたが、それ以外は何？どんなことを書いていけばいいんじゃ？となったわけです。

#何を実装するか知る旅に出よう
ここから大いなる旅が始まりました。
どうやらRepositoryはDBとのやりとりをするとはわかったものの、Serviceも割と近くね？Entityって何？となっていきました。
とにかくここがわからないと、作ったとて、学びにならない！ととにかく色々調べます。
ここで難しかったのはそれぞれの役割が割と抽象的に表現されていたこと。
例えばServiceはビジネスロジックを実装するとか。いやわかりにくい。
そのビジネスロジックってそもそもなんなんですかということに。
そうこうしていくうちに、自分の知りたいことの乗っているサイトに出会いました。
[Spring bootでweb 基本編](https://www.slideshare.net/navekazu/spring-bootweb)
Slide Shareのもので、とにかくわかりやすいです。
ここでようやく自分なりに答えが出ました。自分の勉強のため、一応ここに書いておきます。

|各名称|役割|
|:----------------|:------------------|
|Controller|コントローラー。ブラウザ、そしてServiceとやりとり。|
|Service|DBに対して何をしたいかを書いた部分。保存だったり、更新だったり、具体的なことを書いていくところ。|
|Repository|Serviceから処理要求をもらって、DBとの直接のやりとりをする。抽象化して使う。データ取得、更新など。|
|Entity|データの入れ物。保管するための箱みたいなもの。|

自分の中ではまとまっていますが、結構わかりにくいかもしれないです。
注釈を入れていくと、RepositoryはServiceの処理の実現のための抽象的なものだと解釈すればいいでしょう。
Service行うことを実装するためのものです。
で、EntityはDBとやりとりするのに値を保存する必要があるので、その時に使う箱。
数字を入れたりだとか。そういった役割をします。
ここでは自分にわかりやすいように書いていますが、もしわからない時は、先ほどのリンクできっちり見てみるといいかもしれません。

#終わりに
先ほどのサイトのおかげで、結構Springでの役者の役割がわかりました。
結構行き詰まる人もいそうだというのが私の感想です。
Googe SpreadSheet で修正箇所をSlackに通知する

めちゃくちゃ面倒だったのでメモ。そしてオススメはしない。

## 処理の流れ

- ユーザがSpreadSheetのセルを編集する
- 編集をトリガーにGASが起動
- 編集内容を読み取って、その内容をSlack通知

## ハマりポイント

- onEditとかけば編集時トリガーになるが、トリガーメニューから改めてonEditにトリガーを設定しないと権限が弱すぎる
-  UrlFetchApp.fetch を使うためにはoauthScopesに設定必要

## ソース

xxxxのところは、適宜書き換えてください。

``` javascript:コード.gs
function onEdit(e)
{
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  
  var mes_array = [];
  row_name = sheet.getRange(e.range.getRow(),1).getDisplayValue();
  col_name = sheet.getRange(1, e.range.getColumnIndex()).getDisplayValue();
  mes_array.push(e.user.getEmail());
  mes_array.push(row_name);
  mes_array.push(col_name);
  mes_array.push(e.range.getDisplayValue());
  Logger.log(mes_array)
  send_mes(mes_array.join("\n"));
}

function send_mes(mes) {
    var payload = {
        "text": mes, 
        "channel": "#xxxx",    // 投稿先チャンネル名を入力！
    };
    var options = {
        "method": "POST",
        "payload": JSON.stringify(payload)
    };
    // Webhook URL
    var url = "https://hooks.slack.com/services/xxxxx";
    var response = UrlFetchApp.fetch(url, options);
    var content = response.getContentText("UTF-8");
}

```

```appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "urlFetchWhitelist": ["https://hooks.slack.com/"],
  "oauthScopes": ["https://www.googleapis.com/auth/script.scriptapp","https://www.googleapis.com/auth/script.external_request"]
}
```

さらにGUIからトリガーの設定が必要となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/b1663115-870e-9d31-34ab-77b4f02e4fc0.png)


デフォルトではオーナーが「自分のみ」になってるところを、「オーナー：全員」にしないと、他の人の編集がトリガーにならないみたい。

### ちょっとした気遣い

セルの変数した値だけがきても、どこを直したかがわからないので、編集したセルから一番左のセルの値と、一番上のセルの値も一緒に表示している。多くのばあいは行のIDとカラム名がはいるはず。

あと、getValueではなくgetDisplayValueを使うのもコツ。セルの値ではなくセルの書式設定が適用されたあとの値を取得している。日付型とか自前でフォーマットしないでもいい。
Raspberry Pi Zero WHにカメラを接続し撮影する方法

# カメラをラズパイに接続
今回接続するカメラはこちらです。
https://www.amazon.co.jp/dp/B07CQKJ86C

このように接続します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/1756164d-689b-71e2-6e2a-c2b9c6a3dbbf.png)

Raspberry Pi Zeroの場合は最初からカメラに接続されている白いケーブルでは無く、写真の金色のケーブルを使う必要があります。

# ラズパイ側の操作
### ラズパイの設定画面を表示
SSHで接続語に以下のコマンドを実行すると、設定画面が表示されます。

```
sudo raspi-config
```

### Interfacing Optionsを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/52ea84f9-7aa5-0721-1ac9-502da5bfb300.png)

### P1 Cameraを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/ffd08a90-6e56-1441-3c9b-fb6ffc1afee2.png)

### YESを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/d8414107-453c-66ef-533a-3b7ce4ed8072.png)

### OKを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/ee729e0a-8975-fc46-873c-b188aaa5f8ca.png)

### Finishを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/362f93a0-0a58-cb94-cca8-d59036f1546c.png)

### Yesを選択（再起動します）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/094920a5-9c88-a937-6107-2f46d2667b70.png)

# 静止画の撮影する
以下のコマンドを実行すると撮影できます。
撮影時にはカメラ横のLEDが赤く点灯します。

```
raspistill -o test.jpg
```

# 動画の撮影をする
以下のコマンドを実行すると撮影できます。
静止画と同様、撮影時にはカメラ横のLEDが赤く点灯します。
最後の`10000`は何ミリ秒撮影するかという指定です。以下では10秒間撮影します。

```
raspivid -o video.h264 -t 10000
```

# タイムラプスの撮影をする
以下を参考にするとタイムラプスの撮影が可能だそうです。
https://www.raspberrypi.org/documentation/usage/camera/raspicam/timelapse.md

# 参考URL
Camera Module
https://www.raspberrypi.org/documentation/usage/camera/README.md
LINQで結合

リスト型のモデルクラス同士を結合する方法

``` C#.cs
var result =  ArrayBaseClass.Join(
                        ArrayJoinedClass
                        , b => (b.AAA,b.BBB,b.CCC,b.DDD)
                        , s => (s.AAA,s.BBB,s.CCC,s.DDD)
                        ,(s,b) => 
                            new resultClass()
                            {
                                XXX = s.XXX
                                YYY = b.YYY});
```
Linux においてマウスホイールを早くする

Linux においてマウスホイールの１ラッチが一行に相当するため、 Windows になれているとスクロールが遅く感じます。imwheel を使って１ラッチ、二行に変更する手順を紹介します。

Debian GNU/Linux 9 の場合の手順です。Debian GUN/Linux 10 の場合は、Xorg が Wayland になったため、imwheel で設定しても効果がないようです。

1. imwheel をインストールする
---------------------------

~~~
$ sudo apt-get install imwheel
~~~

2. .imwheel を作成する
---------------------

ホームディレクトリに次の内容の .imwheel を作成します。

~~~
"google-chrome"
None,      Up,   Button4, 3
None,      Down, Button5, 3
Control_L, Up,   Control_L|Button4
Control_L, Down, Control_L|Button5
Shift_L,   Up,   Shift_L|Button4
Shift_L,   Down,   Shift_L|Button5

"Mail"
None,      Up,   Button4, 3
None,      Down, Button5, 3
Control_L, Up,   Control_L|Button4
Control_L, Down, Control_L|Button5
Shift_L,   Up,   Shift_L|Button4
Shift_L,   Down,   Shift_L|Button5
~~~

この内容だと、google chromeとThunderbirdの画面を選択して、マウスホイールを回したときのスクロールが二倍になります。なお、.imwheelに記述するアプリケーションの名前は `xprop WM_CLASS | grep -o '"[^"]*"' | head -n 1` コマンドで調べられます。

Control_LやShift_Lから始まる行を記載すると、CtrlキーやShiftキーを押した状態でマウスホイールを動貸した場合の動作が、今までどおりとなります。記載しないと、CtrlキーやShiftキーを押さない場合の動作と同じになります。

/usr/bin/imwheel -k -b "4 5" を実行すると、設定が反映されます。4 と 5 がマウスホイールを表しており、マウスホイールの信号のみ操作することを意味しています。

3. ログイン時に設定されるようにする
-------------------------------
/etc/X11/imwheel/startup.conf を編集し、次の設定を行います。

* IMWHEEL_START=1 と設定する
* IMWHEEL_BOTTUN="4 5" と設定する

以下は、/etc/X11/imwheel/startup.conf の例:

~~~
IMWHEEL_START=1
#IMWHEEL_PARAMS='-b "4 5"'
IMWHEEL_BOTTUN="4 5"
~~~

/etc/X11/Xsession.d/60imwheel_start-imwheel を編集し、imwheelの起動コマンドを `/usr/bin/imwheel -k -b "${IMWHEEL_BOTTUN}" "${IMWHEEL_PARAMS}"` とします。

以下は、/etc/X11/Xsession.d/60imwheel_start-imwheel の例:

~~~
# Starts the imwheel process.
. /etc/X11/imwheel/startup.conf
if [ "$IMWHEEL_START" = "1" ]; then
#	/usr/bin/imwheel -k "${IMWHEEL_PARAMS}"
	/usr/bin/imwheel -k -b "${IMWHEEL_BOTTUN}" "${IMWHEEL_PARAMS}"
fi
~~~
コンピュータ構成要素　〜まとめ〜No.2

# パイプライン処理　ハザード

パイプライン処理は基本的に命令の依存関係により命令の読み込みを待機したり、途中までの処理を無駄にしたりと並列処理効率が低下してしまうことがある

- 構造ハザード
複数の命令によるハードウェア資源(演算器やメモリなど)の競合によって発生するハザード。主にメモリアクセスの競合が発生した場合に発生する。

- 制御ハザード(分岐ハザード)
命令の先読みを行っている処理中の分岐命令や割込み処理が原因で発生するハザード。次に実行すべき命令が判明するまでパイプラインへの読込みを停止したり、先読みした処理が無駄になることで処理効率が悪くなってしまう状態。

- データハザード
処理するデータの依存関係が原因で発生するハザード。後続の命令が直前の命令の実行結果を利用する場合などに発生する。

## 性能評価指標

- Dhrystone(ドライストーン)
整数演算性能のベンチマーク

- FLOPS(フロップス)
1秒間に浮動小数点数演算を何回できるかという能力を表した指標

- MIPS
1秒間に何百万(10^6)個の命令が実行できるかを表した指標です

- SPECint
整数演算能力を評価するベンチマーク また、SPECには浮動小数点演算能力を評価する「SPECfp」というベンチマーク

# 処理速度演算

問題:ベクトル演算速度だけが現在利用しているコンピュータの6倍のコンピュータを導入する。処理の60%がベクトル演算で残りが非ベクトル演算とし，その他の条件は何も変わらないとすると，処理速度は約何倍になるか

解答：導入予定のコンピュータでは全体の60%の部分を6倍の速度で演算でき、残りの40％を通常の速度で演算するため、
0.6×1／6＋0.4＝0.5
もとの処理速度を"1"とした場合"0.5"の処理時間で同量の処理ができることがわかります。
"1"掛かっていた処理を"0.5"で完了できるようになるので、処理速度は現状の2倍になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337110/af5193a6-1f0c-588c-a78f-85f968871eb1.png)

# RISCアーキテクチャ

CPUを制御する機械語命令をできるだけ少なく単純化し、その単純化した命令を専用の論理回路(ワイヤードロジック)で処理することで高速化を目指したコンピュータの処理方式。各命令の平均実行速度を均一化されているため、パイプライン処理などに適している
- 固定命令語長
- 全ての演算が1クロックで実行される
- 演算はレジスタ‐レジスタ間演算のみ
- ワイヤードロジックで実装
- パイプライン処理に向いている
AWS SAMを使ってLambdaをデプロイする

## SAMとは
サーバーレスアプリケーションモデル（SAM）。AWSが提供するオープンソースのフレームワーク。


## インストール
[ドキュメント](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html)の通り。SAMの他にdocker for MacとAWS CLIを入れましょう。

- brew tapを追加

```
brew tap aws/tap
```

- aws-sam-cliをインストール

```
brew install aws-sam-cli
```

- 確認

```
sam --version
```

## プロジェクトを作成
```
sam init -n sample_app
```

-nオプションで名前を指定できます。未指定の場合は`sam-app`。
hello worldのサンプルが作成されます。


### 作成されるもの
```
├── README.md
├── event.json
├── hello-world
│   ├── app.js
│   ├── package.json
│   └── tests
│       └── unit
│           └── test-handler.js
└── template.yaml
```

- template.yaml
AWSリソースの定義ファイル。LambdaやAPI Gateway等の定義を記述します。

- hello_world/
Lambdaのコードが入っているディレクトリ。

- event.json
Lambda関数にわたすイベントデータを含むjsonファイル。

## デプロイまでの流れ
### ビルド
Lambda関数をビルドします。

```
sam build
```

### ローカルテスト
dockerコンテナを起動しローカル環境でLambda関数をテストします。

```
sam local invoke -e event.json
```

### パッケージング

```
sam package --s3-bucket sam-test --output-template-file packaged.yaml
```

### デプロイ
デプロイするとCloudformationを利用して各リソースが作成されます。

```
sam deploy --template-file packaged.yaml --stack-name sam-test --capabilities CAPABILITY_IAM
```

![CloudFormation_-_スタック_sam-test-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234559/2f834855-b630-cf44-edbd-7cf67f35d1ff.png)

## 参考
[AWS サーバーレスアプリケーションモデル (AWS SAM) の使用 - AWS Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/serverless_app.html)
[Installing the AWS SAM CLI on macOS - AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html)
[brew tapとは - Qiita](https://qiita.com/saa/items/85ed5e914d424fbf9fd6)
NVIDIA Jetson Nano 開発者キットで TF-TRT を利用した物体検出を試す

![screenshot_s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384208/4e77f3d8-3b58-2cc0-96f3-488a44c5d953.png)

# TF-TRT
[NVIDIA Jetson Nano 開発者キットで TensorRT サンプル・プログラムを試す](https://qiita.com/tsutof/items/f81d3900fa77d954ef39) で [TensorRT](https://developer.nvidia.com/tensorrt) を Jetson Nano で利用する方法について紹介させていただきましたが、TensorRT を利用する方法はもう一つ存在します。TensorRT は [TensorFlow](https://www.tensorflow.org/) に統合されていますので TensorFlow から TensorRT の機能を利用することができます。この仕組みは TF-TRT と呼ばれ、TensorRT 対応のニューラルネットワーク層は TensorRT で最適化され、そうでない層は TensorFlow でそのまま処理されます。ニューラルネットワーク・モデルを TensorRT 向けにすべて変換する方法に比べると多少パフォーマンスは劣りますが簡単に利用できるのが利点です。

# TensorFlow/TensorRT Models on Jetson

TF-TRT を利用した物体認識と物体検出のサンプルが [NVIDIA-AI-IOT/tf_trt_models](https://github.com/NVIDIA-AI-IOT/tf_trt_models) で公開され、それぞれ Jupyter ノートブック上で試すことができます。ここでは物体検出の Jupyter ノートブック [tf_trt_models/examples/detection/detection.ipynb](https://github.com/NVIDIA-AI-IOT/tf_trt_models/blob/master/examples/detection/detection.ipynb) を試してみましょう。

まず、[Setup](https://github.com/NVIDIA-AI-IOT/tf_trt_models#setup) で説明されているとおりに必要なモジュールをインストールします。Python3 で試す場合、ステップ２にインストールしているモジュール **python-pip** と **python-matplotlib** はそれぞれ **python3-pip** と **python3-matplotlib** に変更が必要です。

Setup で説明されているモジュールに加え、Jupyter のインストールも必要です。

~~~
$ sudo pip3 install jupyter
~~~

また、TensorFlow で学習済みのモデルに対して TensorRT による最適化をかける過程で多くのメモリを必要とします。以下のとおりスワップ領域を割り当ててこの問題を乗り切ります。[^1]

[^1]: [このページ](https://github.com/NVIDIA-AI-IOT/jetbot/wiki/Create-SD-Card-Image-From-Scratch) を参考にしました。

```
$ sudo fallocate -l 4G /var/swapfile
$ sudo chmod 600 /var/swapfile
$ sudo mkswap /var/swapfile
$ sudo swapon /var/swapfile
$ sudo bash -c 'echo "/var/swapfile swap swap defaults 0 0" >> /etc/fstab'
```

インストールが完了したら Jupyter Notebook を起動します。

~~~
$ jupyter notebook
~~~

ウェブブラウザが自動的に起動します。

![Screenshot from 2019-05-01 13-57-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384208/92cb17ab-17a5-e0d3-db91-af2a588cab8c.png)

examples -> detection と移動して **detection.ipynb** をクリックします。
後は Jupyter ノートブック内の Python スクリプトを順に実行することで TF-TRT の仕組みを学ぶことができます。ここで行われる処理は以下のとおりです。

1. TensorFlow で学習済みのモデルからフローズン・グラフ [^2] を生成
2. フローズン・グラフを TensorRT で最適化
3. 最適化された TensorFlow グラフを TensorFlow にロード
4. 推論（物体検出）を実行

[^2]: モデル内の変数がすべて定数に変換された状態をフローズンと呼ぶらしいですが、私の勉強不足で詳細は分かりません。

# カメラ画像から物体検出

上記 **detection.ipynb** Jupyter ノートブックの実行中に TensorRT で最適化された TensorFlow グラフ（モデル）が **tf_trt_models/examples/detection/data/ssd_inception_v2_coco_trt.pb** ファイルとして保存されますが、このモデルを使ってカメラ画像のほぼリアルタイム物体検出を試してみました。

コードを [tsutof/tf-trt-ssd](https://github.com/tsutof/tf-trt-ssd) で公開中です。

モデル読み込みに時間がかかるため起動に３分程待つ必要があります。

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384208/ef7c31e2-92cf-5ce3-4e44-21fbd0290052.png)

以上です。
個人サービスUIの改善　Bootstrap入門2日後のBefore/After

## 概要
### ミッション
- [自作サービス](http://www.shin-o.net/lat_long_converter/)（緯度経度の単位を変換するだけのサイト）のUIをマトモにする

### この記事で書くこと
- CSSを1行も書いたことがない初心者がBootstrapでどうUIを改善できたかの結果（実働2日）

つまり、これからBootstrapを使ってみようと思っている人に対する費用対効果の紹介。

### この記事で書かないこと
- Bootstrapに関する技術的詳細

### 筆者のスキル
- Javascript: 2ヶ月ほど前に以下のサイトを作るため、素のjsを少し勉強。素人レベル。
- CSS: HTMLの見た目に関するDSLということは知っているが自分で書いたことはない。
- VueとかTypescriptとかWebpackとかBabelとか色々: 未だに何がなんだか分かっていない。

筆者は普段は組み込みソフトウェアの仕事をしており、Web系は初心者です。

### 作ったもの
**Before**

緯度経度の単位を変換する計算サイトです。下部の"Oops!"は本当はGoogle Mapが表示されます。
![latlon_old.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187660/22ba44f6-de54-938d-ecdc-379f755b3e4f.png)

**After**

Bootstrapでお化粧後。
アイコン類は[FontAwesome](https://fontawesome.com)。実際の動作ページは[こちら](http://www.shin-o.net/lat_long_converter)。
![latlon_new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187660/7e370b11-9433-44bc-1faa-3a5e2da374f0.png)

## モチベーション
[過去の投稿](https://qiita.com/shino_312/items/78fe6b4275840179c960)にも記載したのですが、この緯度経度の変換サイトを作成した動機は半分は自分の本業用です。

この類のサイトは既に色々ありますが、以下の条件を満たすものが意外とありませんでした。
- よく使用される全ての単位（十進数/度分/度分秒/NMEA）を網羅
- いちいち「変換」ボタンを押す必要がない
- 該当位置を地図で確認可能

ちょうどその時、自分でWebサービスを作る勉強をしてみたいと思い、題材としてこれを選びました。

## UI作成に関する悩み
- フロントエンドは色々ありすぎてよく分からないが、調べているうちに色々あることがわかってきた
  + ReactとかVueといったやつはやっぱり大変そう
  + 単に見た目(CSS)をそれっぽくするだけならBootstrapを使いこなせればマシになりそう

**→　GWで集中的にBootstrapやってみる**

## 買った本
[Bootstrap4 ファーストガイド](https://www.amazon.co.jp/Bootstrap4ファーストガイド―CSS設計の手間を大幅に削減-相澤-裕介/dp/487783432X)

グリッドシステムって何？から説明されており初心者には良かったです。
1日喫茶店に居座って7割くらい読めました。
以下3つだけ理解してしまえば、とりあえず色々遊べるようになります。

- グリッドシステムの概要
- `<header></header>`でBootstrapをCDNで読み込む
- Bootstrapのclass属性を設定すれば、実際に変化が見える　→　あとは色々試す

## 結果
上記Before/After写真が全てですが、実際にBootstrapを使ってみて以下印象。

- 使い方は本当に簡単。（追求すれば色々あると思うが、ちょっと変化を起こすだけなら、**学習コストは1日**）
- レスポンシブデザイン（画面サイズによって適応的にレイアウトを変える）が簡単にできるのは少し感動。
- Bootstrap自体はCDNで読み込めるため、ややこしいインストールなども不要。

![latlon_small_new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187660/414c54a6-0d92-9e37-5e9d-d07a47af935c.png)

Webページが作れるということは、人に自分の考えや作品を見せる場所を作ることができるということです。
簡単にWebページをお洒落にできるのでどんな種類のエンジニアでも覚える価値があると感じました。

P.S. もっとこうした方がいいよ、というご意見歓迎です。
Raspberry Pi Zero WHの画面に、Macからリモート接続する方法

# VNCのインストール
インストールしたOSによっては最初から`vncserver`がインストールされているかもしれませんが、Macからだと利用できません。
そのため以下コマンドで`tightvncserver`をインストールする必要があります。

```
sudo apt-get install tightvncserver
```

# VNC起動
以下コマンドで起動します。

```
tightvncserver
```

初回起動時のみVNC接続時のパスワードを設定するように要求されます。なおパスワードは8文字以下しか設定できません。

# VNC接続
**Finder -> 移動 -> サーバへ接続** を選択します。
次に`vnc://IPアドレス:5901`と入力して接続を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/58fa7cc4-2d75-f6e4-c75e-13db614e1879.png)

# 接続完了
以下のようにラズパイの画面が表示されたら成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/b403081f-38d2-cc5a-6d36-6a02c9fcb530.png)

なぜか初回は接続できませんでしたが、ラズパイを再起動（`sudo reboot`）したのち、VNCを起動して接続したら、無事に接続できました。

# もしラズパイにディスプレイを接続していて、そのディスプレイと同じ画面をVNCで表示したい場合
x11vncをインストールして使用すればOKです。

## インストール
```
sudo apt-get install x11vnc
```

## パスワード設定
```
x11vnc -storepasswd
```

## 起動
```
x11vnc -usepw -forever
```

## Macから接続
**Finder -> 移動 -> サーバへ接続** を選択します。
次に`vnc://IPアドレス:5900`と入力して接続を押します。

これでラズパイのディスプレイと同じものがVNCでも表示されます。
キーボードもディスプレイも無しでMacbookのみでRaspberry Piに接続する

#はじめに
今回はキーボードもディスプレイも無し、MacbookのみでRaspberry Piに接続する方法を説明します。Raspberry Piのセットアップするだけでわざわざキーボードやディスプレイを購入するのは手間がかかりまうすよね。以下の方法を使えば、最小の準備でRaspberry Piのセットアップができます。

#開発環境
クライアントOS:macOS Mojave(10.14.4)
ホストOS:Raspbian

#準備したもの
・MacBook
・Raspberry Pi3 Model B（本体） 
・microSDカード（16GB）※4GB以上であれば問題ないかと思います
・USB SDカードリーダー
・microUSBケーブル
・USB ACアダプタ(出力2.1A)※出力2.5A以上が望ましいようです
・WiFi環境

#手順
###1.Raspberry PiにSSH接続する準備
microSDのルートであるbootにsshという名前の空ファイルを作ってSSH接続を有効にします。
microSDを以下の写真のように、MacBookで読み込み、ターミナルより以下のコマンドを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259323/18d6ec38-a687-23ac-cefe-8f4fa3cd51b4.png)

```php:macOS
$ touch /Volumes/boot/ssh
```
###2.Raspberry PiをWiFiに接続する準備
Raspberry Piと無線で通信するために、microSDのルートであるbootにWi-Fiの設定用のファイルを以下のコマンドで作成します。

```php:macOS
$ touch /Volumes/boot/wpa_supplicant.conf
```
接続するWi-FiのSSIDがhoge、パスワードがpiyoのとき、下記のようなプログラムを上記で作成したファイルに書き込みます。

```php:wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="hoge"
    psk="piyo"
}
```
###3.MacBook（クライアント）よりRaspberry PiにSSH接続する
以下のようにmicroSDとmicroUSBケーブルをRaspberry Piに接続し、MacBookのターミナルより以下のコマンドを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259323/44aa4b11-a4ef-32c9-272b-e52bb4e92f24.png)

```php:macOS
$ ssh pi@raspberrypi.local
```
パスワードの入力が要求されるので、 raspberry(初期パスワード)と入力すると、下記のように表示されます。

```php:Raspbian
pi@raspberrypi:~ $
```

無事、キーボードやディスプレイ、LANケーブル無しでRaspberry Piに接続することができましたね。

#参考記事
[macしかない状況でRaspberry Piに接続してみた](https://qiita.com/murs13/items/81757bf8bc74b6b76cdf)
PHPでnamespaceを除いたクラス名を取得する

# 取得方法

下記のような変換を行います。

`Somenamespace\named_class_B` => `named_class_B`

`explode()`と`end()`を利用すると取得できます。

```php
<?php
$class_parts = explode('\\', \Somenamespace\named_class_B::class);
echo end($class_parts) . PHP_EOL; // named_class_B
```

# 目的
Laravelでクラス名を列挙して利用したかったです。
その際にクラス名からDBのテーブル名への変換、エンドポイントの設定などを配列を使って行いたかったのですが、クラス名から文字列への変換に手間取りました。
文字列で`named_class_B`使えば良いのですが、それだとIDEの静的解析から漏れてしまうため、Typoなどを検出できませんでした。

そのためできれば `Somenamespace\named_class_B::class` といった静的解析ができるように記述したかったです。

# サンプル

```php:Class_A.php
<?php

Class Class_A {
	public function sample_method() {

	}
}
```

```php:Named_class_B.php
<?php

namespace Somenamespace;

class Named_class_B {
	public function sample_method() {

	}
}
```

```php:I_named_class_C.php
<?php
namespace Somenamespace;

Interface I_named_class_C {
	public function sample_method();
}
```

```php:main.php
<?php

require 'Class_A.php';
require 'Named_class_B.php';
require 'I_named_class_C.php';

new Class_A();
new \Somenamespace\Named_class_B();

// ネームスペースなし
echo Class_A::class . PHP_EOL; // Class_A

// ネームスペースあり
echo \Somenamespace\Named_class_B::class . PHP_EOL; // Somenamespace\\Somenamespace\Named_class_B
echo basename(\Somenamespace\Named_class_B::class) . PHP_EOL; // Somenamespace\\Somenamespace\Named_class_B
// new すれば取れる
echo get_class(new \Somenamespace\Named_class_B()) . PHP_EOL; // \Somenamespace\Named_class_B

// echo get_class(I_named_class_C::class); // Interfaceの場合にnewできない。


// これが解決方法
// @see https://stackoverflow.com/questions/49358575/get-class-name-minus-namespace-without-using-reflection
$class_parts = explode('\\', \Somenamespace\Named_class_B::class);
echo end($class_parts) . PHP_EOL; // named_class_B

$class_parts = explode('\\', \Somenamespace\I_named_class_C::class);
echo end($class_parts) . PHP_EOL; // I_named_class_C
```

コードはここからです。
[php - Get class name minus namespace without using Reflection - Stack Overflow](https://stackoverflow.com/questions/49358575/get-class-name-minus-namespace-without-using-reflection "php - Get class name minus namespace without using Reflection - Stack Overflow")

[`get_class()`](https://www.php.net/manual/en/function.get-class.php)も良かったのですが、インスタンスを作らなければ取れませんでした。

`::class`のようなものがあれば良いのですが見つかりませんでした。
`Interface`の場合でも動く`explode('\\')`ですね。

せめてワンライナーで書きたいのですが、explode->end()が参照渡しなので一旦変数に取っています。うーん良い方法無いかな。
【Vue/TypeScript】vue-svg-loaderのbuildエラーを解決

Nuxtでsvgを使いたくてvue-svg-loaderを導入するもVSCodeのVeturと
buildエラーが出て解決に困ったので明記します。

表題のエラー解決方法を今すぐ知りたい方はこちら
https://qiita.com/kawa64372358/items/aa327ea55f7df0d510bc#解決方法

## vue-svg-loaderの導入
vue-svg-loader：https://www.npmjs.com/package/vue-svg-loader

これを導入するとSVGファイルをVueコンポーネントとして使用できます。
SVGをインライン化しているのでスタイルを設定できたり、SSRでも問題なく利用できます。

```bash
$ yarn add -D vue-svg-loader
```

nuxt.configに下記を追記
Vue CLIの場合は記述が変わるので[basic-configuration](https://www.npmjs.com/package/vue-svg-loader#basic-configuration)を確認してください

```nuxt.config.ts
  build: {
    extend(config: any, ctx: any) {
        // svg
        const svgRule = config.module.rules.find((rule: any) => rule.test.test('.svg'));

        svgRule.test = /\.(png|jpe?g|gif|webp)$/;

        config.module.rules.push({
          test: /\.svg$/,
          loader: 'vue-svg-loader'
        });
       }
```

実際にsvgを読み込みたいcomponentに下記を追記

```GlobalNavigatioon.vue
<template>
  <ThreeLinesIcon />
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import ThreeLinesIcon from '~/assets/svg/icons/ThreeLinesIcon.svg';

@Component({
  components: {
    ThreeLinesIcon
  }
})
export default class GlobalNavigation extends Vue {}
</script>
```

## "Cannot find module" with TypeScript [Vetur]
ブラウザにはsvgが通常表示されるも、下記ビルドエラーが発生

`Cannot find module '~/assets/svg/icons/ThreeLinesIcon.svg'.`
<img width="804" alt="スクリーンショット 2019-04-30 19.55.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239038/460e884a-8bc0-31b6-19c7-3e87d17f235e.png">

Veturにもエラーが出ています
<img width="562" alt="スクリーンショット 2019-04-30 21.06.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239038/70eb3817-1b0a-13a9-0921-2ac26e640669.png">

同じような問題がvuejs/veturのissuesにありました
[Cannot find module 'xxxx' #762](https://github.com/vuejs/vetur/issues/762)

```tsconfig.json
{
"compilerOptions": {
  "baseUrl": ".",
  "paths": {
    "@/*": [
      "src/*"
    ]
  }
}
```
自分の場合は、すでにcompilerOptionsでpathsを書いていたので関係なさそう・・

## 解決方法

vue-svg-loaderのissuesに解決方法が書いてありました
["Cannot find module" with Typescript #37](https://github.com/visualfanatic/vue-svg-loader/issues/37)

vue-svg-loaderのdocumentationにも書いてありました
https://vue-svg-loader.js.org/faq.html#how-to-use-this-loader-with-typescript
>If you want to use this loader in a project that is written in TypeScript, you will get the "Cannot find module" error. To fix that you need to provide a type definition which is needed by TypeScript to know how to handle SVG components.

assetsのsvgを格納しているディレクトリに下記のような型ファイルを追加してあげればいいみたい

```index.d.ts
declare module '*.svg' {
  const content: any;
  export default content;
}
```

無事解決しました。これでbuildも通ります！

## 参考
Cannot find module '~/components/Card.vue'. Vetur
https://qiita.com/kanzume/items/2ff1be119d7e64089d30
firebaseとfirebase-adminを一緒に使っているとfirebase側のメソッド呼び出しがエラーになる

## エラー内容
CloudFunctionsを実行した際、firebase側のメソッドを呼び出した際に下記のエラーが出ていた
```TypeError: firebase.auth is not a function```

## 実行環境
```package.json
  "dependencies": {
    "firebase": "^5.11.0",
    "firebase-admin": "^6.5.1",
  }
```

注)そもそも併用しているのはCloudFunctions側でメールパスワードをauthに登録しようとしたところ、firebase-adminにcreateUserWithEmailAndPasswordが無かったため

## 原因
firebaseとfirebase-adminは共有のモジュールを使っているが、その依存関係がおかしくなると起こるらしい。
firebase⇒firebase-adminの順にinstallするのが正しいとのこと。
https://github.com/firebase/firebase-js-sdk/issues/752

## 解決法
自分の場合、下記で解決

1. 配下のnode_modulesディレクトリ、package-lock.jsonを削除
2. 下記コマンドを実施

```
npm install firebase --save
npm install firebase-admin --save
```
JSONデータのDataframeでの処理方法

JSONデータをPandas Dataframeで処理する際の方法をまとめました。

目的
JSON形式で株価のデータを提供してもらったので、分析時にdataframeに入れて処理するために使用

例で用いるデータは加工済み

```python
prices = [{'Date' : '2019/04/08', 'Open':1081.0, 'High': 1013.0, 'Low': 1071.0, 'Close': 1007.0},
          {'Date': '2019/04/09', 'Open': 1000.0, 'High': 1000.0, 'Low': 1033.0, 'Close': 1076.0}]
```

pricesに上記のように株価のデータ入れる。

上記データを一瞬でデータフレームに入れたいと思ったので、ちょっと調べてみたところ、
pd.io.json.json_normalize()で処理できることが判明。

```python
df = pd.io.json.json_normalize(prices)
```

これで処理すると、Date〜Closeをカラム名として、インデックスがついたデータが出力される。

JSONの処理をする際には使ってみたい。

JSONのデータ加工はTableauに入れて処理したりしているが、やはりPythonでやってしまった方が圧倒的に早い。
gitのコミットメッセージの頭に付けるプレフィックス一覧

# 概要

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">gitのコミットメッセージの頭に付けるプレフィックス、結局これに落ち着く(デスクの前に貼ってる) <a href="https://t.co/MXQJ4oge1v">pic.twitter.com/MXQJ4oge1v</a></p>&mdash; スゥ……… (@ITF_sudame) <a href="https://twitter.com/ITF_sudame/status/1102194158746382341?ref_src=twsrc%5Etfw">March 3, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


上記のツイートの画像の内容の転記です。許可とかないので怒られたら消します。自分がめっちゃこのツイートを何度も開いて確認してて面倒だったので転機させていただいてます :pray: 

# 内容

|        |        |    
|:-----------------|:------------------|
| fix | バグ修正 |
| hotfix | クリティカルなバグ修正 |
| add | 新機能・ファイル追加 |
| update |  バグではない機能修正 |
| change | 仕様変更 |
| clean | リファクタリングなどのコード整理 |
| disable | 機能無効化 |
| remove | 削除(ファイル) |
| upgrade | バージョンアップ |
| revert | 変更取り消し |
素人が一週間で人狼ゲームを作ってみた話。(Laravel)

ネットに転がっていた簡単なチュートリアルを参考に、[記事投稿サイト](https://amusing-haiku.herokuapp.com/ "俳句大喜利")を作成したことしかない素人がネットを頼りに[人狼ゲーム](https://werewolfis.herokuapp.com/ "werewolfis")を作ってみた話です。
# 背景
何かもっと「作った！！」と言えるようなサイトを作ってみたいと思っていたとき、友達と一緒にスマホアプリの人狼ゲームをやっていたが、課金をしないと役職が増えないことに不満を持ったことがきっかけで作成しました。
# 設計
まあ何はともあれ、まずは設計しないと後々大変なことになると思ったので、設計をしようとしたが、umlとかをやろうとすると設計だけで力が尽きそうな予感がしたので、適当にゲームの流れを書いて、終了。(1時間経過)
# 作成

## ゲーム開始前の設定作成
- 人数を決めさせ、役職を決めさせ、ルールを決めさせる。

ここは簡単にできるだろうと思っていたが、すぐにそれが誤りだったと知る。
ユーザの入力に応じて入力欄を増やさないといけなかったり、役職の数が人数と等しくなるようにしなくてはいけなかったり。
ほぼjavascriptの知識がなかったので、適当に基本的な構文と簡単なDOM操作方法だけ抑えて作成。
綺麗さを犠牲に何とか作成。(1日目終了)

## 夜
- プレイヤー一人一人に順番に回していき、それぞれ夜のアクションを行わせる。

ここに来た時には簡単なjavascriptならかけるようになっていたため、思っていたより早く作成が完了。(2日目終了)

## 朝
- 投票を行わせ、一人の犠牲者を出す。

意外とここも早く作成することが出来た。(3日目終了)

## ルールを適用する
- 初夜殺し、初夜占い、連続ガードを選択できるようにする。

設定画面は作っていたが、適用出来るようにしていなかったことが判明。
色々直さなくてはいけないところが出てきたので、直した。(5日目終了)

## 役職を増やす
- 人狼、市民、多重人格、占い師しかいなかったので、追加。

本来の目的を忘れていた。よく覚えていないが、いたるところを直さなくてはいけなくなったのを覚えている。(6日目終了)

## 決選投票を出来るようにする
- 同率一位になったらランダムにしていたが、それだと面白くないということで決選投票を作成。

(7日目終了)

## バグを取り除く
- 友達にやらせてみたら、他のデバイスのプレイヤーを持ってきてしまう時があったので直す。

原因がすぐに見つかったため意外と早く治せた。(+1時間30分)

# 終えてみて
最初の設計のほとんどが変更をたどることになった。
なぜあんなにも設計を丁寧にさせようとしているのかが分かった。

# 使い方
アカウントがないとゲームを開始できないようにしてあるので、もし使う方が居たら右上の[Register]タブからアカウントを作成してください。
アカウントが作成出来たら、トップページの[New Game]からゲームを開始できます。
使い方としては一つの端末で複数人で端末を回しながらゲームをしてください。
役職にある[狼男]ですが、勝手に自作した役職ですので気にしないでください。そのうち各役職の説明も表示できるようにすると思います。
Jetson Nano上でStyleGANを使って無限に人物画像生成するデモを行う方法



# Jetson NanoでStyleGANを動かす
　Jetson Nano上でStyleGANが動かないというコメントをみたので「そんなわきゃないだろ」と思い早速試して見ました。試してみたコードは以下のものです。

[stylegan(on GitHub)](https://github.com/NVlabs/stylegan)

## Jetson Nanoセットアップ
　以下記事を参考にセットアップをして下さい。

[Jetson Nano関係のTIPSまとめ](https://qiita.com/karaage0703/items/b14c249aa33112669ee4)

　「Swapファイルの設定」の項目で6GBのSwapファイルを確保するのを忘れないで下さい（これをやらないと途中で死にます）。


## StyleGANテスト
　ターミナルで以下コマンド実行すると、学習済みのモデルから人物画像が生成されます。クローンするリポジトリは、最初に紹介したNVIDIAオリジナルのものでもよいのですが、この後のデモプログラム実行の関係で、私がフォークしたものを使用しています。

```sh
$ git clone https://github.com/karaage0703/stylegan
$ cd stylegan
$ python3 pretrained_example.py
```

　以下のような陽気なおっさん画像が生成されます。これ、教師画像ではなくて、人工知能が生成した人物画像です。
![D5cnmnGUIAEZqw9.jpg-large.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/50c8042a-0b7e-da68-2675-76ff5a2b48f1.jpeg)


## StyleGANリアルタイム生成デモ
　そのまま以下コマンド実行すると、次々に人物画像が生成されるデモができます。

```sh
$ python3 generate_demo.py
```

　デモの様子は、以下リンク先参照下さい。

[Style GANのリアルタイムデモ動画(on instagram)](https://www.instagram.com/karaage/p/Bw6NXj9gW_B/?igshid=179vh622tmmdx)

　デモプログラムは、基本的にサンプルプログラムを少し改造しただけです。詳細はソースコードを参照下さい。

## プログラムがうまく動かない場合
　モデルがうまくダウンロードできていない場合があるようです。その場合は、ブラウザで以下のアドレスから、直接ファイルをダウンロードして、styleganディレクトリの下に直接置いてから、プログラムを実行してください。

https://drive.google.com/uc?id=1MEGjdvVpUsu1jB4zrXZN7Y4kBBOzizDQ


# 参考リンク
[A Style-Based Generator Architecture for Generative Adversarial Networks を読んだ](https://qiita.com/d-ogawa/items/d645509e3ccedc989680)

# 関連記事
[Jetson Nano関係のTIPSまとめ](https://qiita.com/karaage0703/items/b14c249aa33112669ee4)
Jetson Nano関係の情報はこちらにまとめています

# 変更履歴
- 2021/03/01 プログラムがうまく動かない場合の対処を追記
モザイク図とヒートマップを合わせた図を作成する


## 成果物

![mosaic_heatmap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295829/2ce3d798-26ef-8702-0d03-cd9d2e09824f.png)


## コード

- https://github.com/suaaa7/samplecode-for-qiita/blob/master/mosaic_heatmap/mosaic_plot_and_heatmap.ipynb

```python
%matplotlib inline
import numpy as np
import scipy as sp
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import seaborn as sns

from statsmodels.graphics.mosaicplot import mosaic
from itertools import product

def normalize_for_color(value, ratio):
    return max(min(value / ratio + 0.5, 0.99), 0.01)

data = [
    ['A','a',2,-0.3],
    ['A','b',3,0.4],
    ['A','c',5,-0.7],
    ['B','a',2,0.8],
    ['B','b',2,-0.2],
    ['B','c',5,0.1]
]
columns = ['Column1', 'Column2', 'area', 'value']
df = pd.DataFrame(data=data, columns=columns)

df['tuple'] = list(zip(df.Column1, df.Column2))
df = df.set_index('tuple')
df = df.drop(['Column1', 'Column2'], axis=1)
data_dic = df.to_dict('index')

props = lambda k: {'color': cm.coolwarm(normalize_for_color(data_dic[k].get('value'), 1.0))}
labelizer = lambda k: "{0:+.02f}".format(data_dic[k].get('value'))
mosaic(df.area, title='Mosaic Plot And Heat Map', properties=props, labelizer=labelizer, gap=0.005)
plt.show()
```

## 参考
- https://www.statsmodels.org/dev/generated/statsmodels.graphics.mosaicplot.mosaic.html