OmniAICreator/Qiita-1.07M huggingface dataset:
terraformでdocker for macとkubernetesを動かしてみる

# はじめに
最近はローカル開発環境の管理を terraform + kubernetes に移行しました。この記事で環境検証のための一番簡単な作成例です。

# 準備

* [Docker For Mac with Kubernetes](https://docs.docker.com/docker-for-mac/#kubernetes) 
* Terraform

# tf ファイルを書く

この設定には、[Alpine](https://hub.docker.com/_/alpine/)イメージの中の`nc`コマンドを使って、echo サーバーを起動する。そして [Service](https://kubernetes.io/ja/docs/concepts/services-networking/service/) 利用して外部に公開します。

```hcl:test.tf
provider "kubernetes" {
  version                  = "~> 1.10"
  host                     = "https://localhost:6443"
  config_context_auth_info = "docker-desktop"
  config_context_cluster   = "docker-desktop"
}

resource "kubernetes_pod" "echo" {
  metadata {
    name = "echo"
    labels = {
      app = "echo"
    }
  }

  spec {
    container {
      image   = "alpine:latest"
      name    = "echo"
      command = ["nc"]
      args    = ["-vlkp", "2000", "-e", "/bin/cat"]
    }
  }
}

resource "kubernetes_service" "echo" {
  metadata {
    name = "echo"
  }
  spec {
    selector = {
      app = "${kubernetes_pod.echo.metadata.0.labels.app}"
    }
    session_affinity = "ClientIP"
    port {
      port        = 2000
      target_port = 2000
    }

    type = "LoadBalancer"
  }
}
```

# 実行と検証

設定ファイルを terraform に応用しましょう。

```sh
$ terraform init
$ terraform plan
$ terraform apply
```

成功した後、kubernetes の方には pod と service は起動したことを確認しましょう。

```sh
$ kubectl get po
NAME   READY   STATUS    RESTARTS   AGE
echo   1/1     Running   0          17s
$ kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
echo         LoadBalancer   10.98.63.163   localhost     2000:30091/TCP   12s
```

サービスに接続みる。

```sh
$ nc -v localhost 2000
```

# リソースの削除

```sh
$ terraform destroy -auto-approve
kubernetes_pod.echo: Refreshing state... [id=default/echo]
kubernetes_service.echo: Refreshing state... [id=default/echo]
kubernetes_service.echo: Destroying... [id=default/echo]
kubernetes_service.echo: Destruction complete after 0s
kubernetes_pod.echo: Destroying... [id=default/echo]
kubernetes_pod.echo: Destruction complete after 3s

Destroy complete! Resources: 2 destroyed.
```
RaspberryPi4BにRe:VIEW starterのビルド環境を構築する

RaspberryPi4B(4Gb)+RaspbianDesktopな環境に Re:VIEWStarterのビルド環境を立ててみた。

RaspbianにDockerをインストールし、公式が用意しているDockerイメージをそのまま利用しようと思ったのだけど kauplan/review2.5 がうまく起動せず、ホスト環境(Raspbian)に直接環境をインストールすることにしました。

Raspbianは Debianベース、kauplan/review2.5はubuntu18.04ベースだけど、両者パッケージ管理にはaptが採用されているし、おそらく動くんじゃないかな、という軽い気持ちで試してみました。

結果、成功。

以下、[DockerHub | kauplan/review2.5](https://hub.docker.com/r/kauplan/review2.5/) の Dockerfileをほぼそのまま写経した感じです。

```
$ sudo su -

# apt-get update && \
    apt-get install -y --no-install-recommends \
      locales git-core curl ca-certificates && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen

# locale-gen en_US.UTF-8 && update-locale en_US.UTF-8

# apt-get update && \
    apt-get install -y --no-install-recommends \
      texlive-lang-japanese texlive-fonts-recommended texlive-latex-extra lmodern fonts-lmodern tex-gyre fonts-texgyre texlive-pictures \
      texlive-fonts-extra texlive-generic-recommended \
      fonts-noto fonts-noto-cjk fonts-noto-cjk-extra fonts-noto-color-emoji \
      ghostscript gsfonts zip ruby-zip ruby-nokogiri mecab ruby-mecab mecab-ipadic-utf8 poppler-data cm-super \
      graphviz gnuplot python-blockdiag python-aafigure && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# gem install -N bundler rake && \
    gem install -N combine_pdf && \
    gem install -N review -v "2.5.0" && \
    gem install -N review-peg -v "0.2.2"

# apt-get update && \
    apt-get install -y --no-install-recommends \
      gnupg && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# curl -sL https://deb.nodesource.com/setup_9.x | bash - 

# apt-get update && \
    apt-get install -y --no-install-recommends \
      nodejs && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    npm install -g yarn

# git clone https://github.com/kauplan/docker-review.git

# cd docker-review

# mkdir /usr/share/texlive/texmf-dist/fonts/map/dvipdfmx/ptex-fontmaps/noto/

# cp ./noto/* /usr/share/texlive/texmf-dist/fonts/map/dvipdfmx/ptex-fontmaps/noto/

# texhash && kanji-config-updmap-sys noto
```

これで完了。


[Re:VIEW starter](https://kauplan.org/reviewstarter/) で作った雛形プロジェクトのディレクトリに移動して ```$ review-pdfmaker config.yml``` を動かせばPDFファイルが作られます。
pythonの関数呼び出しをオブジェクトにぶち込んだら結構速くなった

上司「pythonは関数呼び出しのコストそこそこかかるから、ループ深いところは予めオブジェクトに用意しておいたあげたほうが早くなるよ」
僕「はーい(そんなに変わるわけないっしょww)」

・・・と思って試してみました。

```python:func_call_cost.py
import time
import datetime

TRIAL_NUM = 1000000

from_ts = datetime.datetime.fromtimestamp

def main():
    # unixtimeからdatetime作成する処理を100万回
    start = time.time()
    for i in range(TRIAL_NUM):
        datetime.datetime.fromtimestamp(i)
    print("time:{0}".format(time.time() - start))

    # 呼び出す関数を予めオブジェクトに用意しておく場合
    start = time.time()
    for i in range(TRIAL_NUM):
        from_ts(i)
    print("time:{0}".format(time.time() - start))


if __name__ == '__main__':
    main()
```

## 測定結果(10回平均)

|普通に呼び出し|オブジェクトに入れる|
|------------|-------------------|
|0.49sec|0.41sec|

…まじか。高々100万回のループでそこまで変わるか。
導入するのもかなりイージーだしループ処理の深いところでは積極的に使っていきたい。
最速! Unity Scroll View 作成3ステップ

いつもuGUIのScroll View使う時使い方思い出すのにちょっと時間かかるので、自分のメモ用に記事にしておきます。

例としてこんなの作ります。今回はVertical操作は消して、Horizontalのみの操作とします。
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/d8f04526-3446-8aa5-6f75-6d1498be9043.gif)

# STEP 1
[Scroll View]をCanvas下に作成。
<img width="556" alt="スクリーンショット 2019-12-26 23.54.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/26a2ef6b-b76f-c14a-be60-6abd045bba00.png">

# STEP 2
[Scroll View]->[Viewport]->[Content]に

1. Horizontal Layout Groupコンポーネントをアタッチ
2. Content Size Filterコンポーネントをアタッチ

コンポーネントの設定はご自由に
<img width="566" alt="スクリーンショット 2019-12-27 0.02.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/ad348f71-8caa-22c1-9316-a42fb4e894b6.png">


# STEP 3
1. Step2のContent下に並べるobjectを入れる。
2. objectにはLayout Elementコンポーネントをアタッチして、Preferred Widthなどを設定

<img width="570" alt="スクリーンショット 2019-12-27 0.02.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191216/a6a40fd6-0b2a-5e95-daee-5d6eef569c0d.png">


以上です。
【NVIDIA Jetson Nano ヘッドレスでインストール & SSDから起動】



## 用意した物

### 作業用のMacBook Pro



### 本体と電源

Jeston Nano Developer Kit
SUCCUL ACアダプター 5V 4A  センタープラス/出力プラグ外径 5.5mm(内径2.1mm)
ジャンパーピン (Bullet  JP02)

### 無線LAN接続

TP-Link WIFI 無線LAN 子機 11n/11g/b デュアルモード対応モデル TL-WN725N

### 起動用microSD

シリコンパワー microSD カード 128GB (class10 UHS-1)
Transcend USB 3.1 Super Speed カードリーダー  TS-RDF5K

### USB-SSDでの「起動」用

Geekworm NVIDIA Jetson Nano 用2.5インチ SATA SSD/HDD ストレージ拡張ボードT300 V1.0 
Samsung SSD 1TB 860QVO 2.5インチ内蔵型

### とりあえず買っておいたもの

Noctua NF-A4x20 5V PWM 40mm 静音 ファン 5000rpm
SainSmart IMX219 AIカメラモジュールNVIDIA Jetson Nanoボード用8MPセンサー77度FoV
BUFFALO 11n/a/g/b 300Mbps 簡単無線LAN子機 WLI-UTX-AG300/C



## 作業ではまったところ

### JetCardイメージを書き込んだmicroSDを使って起動。

（5V電源で給電。まだSSDは繋げていない。）

MacBook ProとUSBで繋げて、*http://192.168.55.1:8888 へアクセスしても...繋がらない。*
テキストがいくつか入ったドライブはマウントされるのだけど。



### 試行錯誤...

ParallelsのWindows10を起動して、見えているドライブをParallels側へマウント。
あら、Windows10からは http://192.168.55.1:8888 へ接続できた。



　この時点で、有線LANは有効になっているので、有線で繋げでarpでアドレスを見ればよかったのだ。



### Jupyter Labに接続して、無線LANを設定。

TL-WN725Nは見えているので、nmcliコマンドで設定するだけ。再起動して、無事、MacBook Porから無線LAN経由で接続できるようになった。



### いったん電源を落として、ストレージ拡張ボードT300とSSDを取り付け。

T300 に付属の電源二股ケーブル...根元の方がケーブルの径が違うから、元のACアダプターが接続できない....。
（まあ、このケーブルを使わなくてもUSB経由の給電はできるからいいか。）

電源を繋げて、無事起動...と思いきや、*無線LANが繋がらない。*



### 試行錯誤...

T300のUSBケーブルを取り外してSSDに給電しない状態にして起動するとなぜか繋がる。仕方ないので、再度、USB-microUSB経由でログインして、無線LANを確認。
　sudo nmcli device wifi connect <ssid_name> password <password>
してもだめ。暗号化に失敗...のようなメッセージ。

ドライバーを更新してみたり、wifi-powersaveの設定を変えたりしてみても症状は変わらず。



### 試行錯誤...

最初に設定したのとは別のLANに接続してみる...あら、繋がった。

　ここでも、素直に有線LANで繋げればよかったのだ。

で、いろいろ設定して....



## いよいよSSDからの起動へ。

参考にしたのはここ。
https://github.com/JetsonHacksNano/rootOnUSB

厳密にいうとSSDから起動するわけではなく、microSDからのブートするのだけど、initrdの途中でUSBドライブが見えるようにして、USBドライブ側をrootにするという方法らしい。



### 試行錯誤...

ヘッドレスで作業しているので、起動しなくなるとJetCardのイメージ書き込みからやり直し。
基本的に上記のページに書いてある手順（とビデオの内容）で問題ないのだけど、

- SSDのパーティションはext4にする必要がある。

- extlinux.confに記述するLABELは一つだけ（SSDからのブート用）にしておくこと。複数のLABELを書いても、ヘッドレスでの作業だと、どこから起動するか選択できるわけではなく、先へ進むことができないのだった。

  

後は、ファンとカメラを接続。
TL-WN725Nが時々、切れるから、有線LANの方にWLI-UTX-AG300/Cを繋げて無線化してみよう。
PMや部長レイヤーに開発現場から伝えられていれば良かったこと〜レガシーコードからの脱却より〜

# はじめに
[レガシーコードからの脱却](https://www.oreilly.co.jp/books/9784873118864/)を読んで、とてもいい本だと思ったと同時に、
20代の自身が知っておけば良かったことを記載しています。
自身の力や配慮が足りなかったことの戒めや反省です。
（あまりQiita向けではない気がしますが・・）

下記の問題で疲弊して悩んでいる方や
この記事を読んで、興味が出てきた人は、
本書を買って読んで学んで頂ければと思います。

- ソフトウェアのバグや不具合が多くて困っている
- ソフトウェアのリリース頻度が遅くて困っている
- アジャイル初めてみたけど、なんかうまく回っていない気がする

## うまくいってないことに対するインパクトについて
まず、うまくいっていないこと自体は残念ながら特殊な状況ではない（我が会社だけではない）ということです。
本書であげられている例を要約すると、2002年時点のある調査で、アメリカだけでソフトウェアの障害が600億ドル規模で失われていると記載されています。
大体今の（2019年12月1日時点で）任天堂の時価総額より高い、というとPMや部長レイヤーにも伝わる（伝わった）と思います。

## 現場と上のレイヤーとの認識の違い
開発者がソフトウェアの開発を行うときに、何に時間を費やしているか、
その理解をしてもらうことから始めるのが良いと思います。

特に、開発経験がない人たちには、現場との認識のズレが生じやすい箇所だと思います。

ここは大体本書の通り、

PM・部長レイヤー：コーディングに時間がかかる
実際の現場の結果：仕様書を読んだり、ドキュメントを書いたり、会議に出席したり、デバックに多くの時間が取られている

という状態になっている（た）ことを伝える必要があります。
まず、コーディングという機能という価値を生み出すところに、多くの時間を割くことができていない、という現状を証拠を揃えて伝える必要があります。

## なんでコーディングに時間が取れないの？
この質問に対しては『ソフトウェア開発が複雑である』という前提を理解してもらう必要があります。
『なぜ複雑なのか』については、人によって色々と答えがあると思いますが、
まず現実が複雑であり、人がその現実で無意識に行なっていることを（しばしば他の人の頭から）抜き出し・洗い出しを行い、それをコンピューターに対して、正確に伝える（コードを書く）というところにあると、いう回答が当時の自分にも刺さるでしょう。

また、ソフトウェア開発に対して、今のやり方が良くないことを本書のような例を持って、異議を伝えるべきです。

> ソフトウェア開発プラティクスに従うことは手術の前の消毒のようなもので、どのようなソフトウェアを開発していても正しく行われる必要がある。
> 従わなければ最近が患者を殺してしまうように、たった１つのバグがアプリケーションを殺してしまうかもしれない。規律が必要だ。
> p.47-p.48

### レガシーコードを放置するべきではない
本書では、レガシーコードというキーワードが頻発しますが、
ここでいうレガシーコードとは、マイケル・フェザースの[レガシーコード改善ガイド](https://www.shoeisha.co.jp/book/detail/9784798146355)を引用しつつ、

> テストのできないコードをレガシーコードと定義している
> p.6

としています。
それだと、当時の自分や上のレイヤーの人には、少し伝わりづらい可能性があるので、
『修正や拡張といった作業が難しいコード』
と言うほうが伝わりやすいかもしれないです。

機能の追加や修正といった手を加えることにより、正しく動くかを担保すると同時に、
機能の追加や修正が行われる前のソフトウェアと同様に、他の機能が正しく動くかも担保する必要があり、
その担保はテストにより担保するので、テストのできないコードを放置するべきではない、という論法です。

また、（ユニット）テストを作るためには、先にある程度優れたコードがないと、
テストができないので、コード品質も重要という点も述べた方がいいです。

> しかし、優れたユニットテストを行うには、テスト可能な優れたコードがあることが前提となる。これはレガシーコードには当てはまらない。
> したがって、コードを整理して、先にいい状態にしなければいけないことになる。これは言うは易く行うは難しだ。
> p.7

## とはいっても納期、お客様の要望いっぱいあるんだけどどうするの？
要望に関しては、本当に必要なものを精査できる立場、ないしはここまでで聞く耳を持っていただけているなら、5章をまるっと読んでもらえると、とても助かります。
本当にその機能がいるのか、それを突き詰めてもらえると、いくらか案件は消せたと思います。

## リファクタして意味があるの？
まず、すべてのコードをリファクタしたい、という要望は絶対に通らないことを理解しましょう。また、リファクタを行うことを本書のように、負債を返すことの重要さをきちんと説明できるようにすれば、リファクタを行うこと自体は受け入れてもらえるでしょう。
そして、本書のような7つの戦略に従い、行うべき対象を正しく精査し、少しずつでも負債を返すようにしていくことが大切です。

## 終わりに
以上、本書には色々と学びがあり、過去の自分に本書のようなものに出会えていれば、
もっと色々と幸せになれたかもしれません。
小ネタ：データ型で絞り込む

忘れがちなので、ネットに撒いておこうという趣旨です。

##やりたいこと
こんな感じでデータ型がばらついている列について、特定のデータ型に絞り込みたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370992/cd38a4ef-0145-f78b-0f13-e1abfcb9cb7c.png)

##コード
今のところ、コードを書かないと実現できないという理解でいます。
`ソース`は単純に前のステップのことです。

```
= Table.SelectRows( ソース,each Type.Is(Value.Type([Column1]),type record) )
```

↓絞り込めた様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370992/a5711ee5-337b-dade-9c86-5d992658d3be.png)



##参考
これに関しては、MSさんもwebサイトのreferenceにあまり書かれていないです。sharedを覗いてみてもほぼ同様。
※PDF版のreferenceはちょっと違っていたりします。
※下記をPower Queryエディタの数式バーに貼れば、sharedの解説が見れます。

Value.Type関数：`= Record.Field( #shared,"Value.Type")`

Type.Is関数：`= Record.Field( #shared,"Type.Is")`
EmbyのPWA不具合修正

自宅メディアを活用するために[Emby](https://emby.media/)を始動したが、設定に不具合があってPWAとして使えなかったので、修正メモ。@ CentOS 7
とりあえず動くようにしただけなので、仕様とか原理とかはまた今度詰める。

# 配信ファイルの場所

```bash
/opt/emby-server/system/dashboard-ui
```

# manifest.json
Chromeの開発者ツールのエラーメッセージによると、`related_applications`の要素には`url`または`id`が必須らしい。

```diff:/opt/emby-server/system/dashboard-ui/manifest.json
  "related_applications": [
    {
      "platform": "android",
-     "location": "https://play.google.com/store/apps/details?id=com.mb.android"
+     "url": "https://play.google.com/store/apps/details?id=com.mb.android"
    },
    {
      "platform": "ios",
-     "location": "https://itunes.apple.com/us/app/emby/id992180193?ls=1&mt=8"
+     "url": "https://itunes.apple.com/us/app/emby/id992180193?ls=1&mt=8"
    },
    {
      "platform": "web",
+     "id": "emby"
    }
  ],
```

# serviceworker
サービスワーカーの箇所で`does not work offline`とエラーメッセージが出ていた。
インストール時の処理として`self.addEventListener('fetch', function(event) {});`と書いてやればいいっぽい。
[参考：【PWA】「ホーム画面に追加」の「Site cannot be installed: the page does not work offline」エラー対策](https://pawafuru.com/0407)

`serviceworker.js`を見ると、`bower_components/emby-webcomponents/serviceworker/`にある`notifications.js`と`sync.js`を読み込んでいるよう。
`notifications.js`はいろいろ書いてあって面倒そうだったから、`sync.js`に追記しよう。

```diff:/opt/emby-server/system/dashboard-ui/bower_components/emby-webcomponents/serviceworker/sync.js
  self.addEventListener("sync",function(event){"use strict";event.tag});
+ self.addEventListener('fetch', function(event) {});
```

以上の修正でエラーが消え、無事PWAとして端末にインストールできた。
めでたしめでたし。
Install the latest Ansible v2.9.2 without `id_rsa.pub` , `authorized_keys`

![banner-ansible.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/6b0bd0d1-3299-3ef3-0e39-ac8c14d0d922.png)
> Install the latest [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#basics-what-will-be-installed) version 2.9.2
 > How to use without `id_rsa.pub` , `authorized_keys` 🙈

## Test environment
- Ubuntu 18.04
- Ansible 2.9.2


## Install
```bash
$ apt-get update
$ apt-get install software-properties-common
$ apt-add-repository --yes --update ppa:ansible/ansible
$ apt-get install ansible
```
```bash
$ ansible --version
ansible 2.9.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.17 (default, Nov  7 2019, 10:07:09) [GCC 7.4.0]
```

## Modify Ansible Configuration File
Modify both `/etc/ansible/ansible.cfg` and `/etc/ansible/hosts` [Ref Link](https://github.com/ansible-semaphore/semaphore/issues/309)

```bash
$ vi /etc/ansible/ansible.cfg
```
```yaml
[defaults]
host_key_checking = False
[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
control_path = /dev/shm/cp%%h-%%p-%%r
 
```
```bash
$ vi /etc/ansible/hosts
```
```yaml
[child]
182.252.133.71
182.252.133.72

[child:vars]
ansible_user=root
ansible_password=Password1!
```

## Run
Check the operation with the default [ping](https://docs.ansible.com/ansible/latest/modules/ping_module.html) command of [ad-hoc](https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html).
Once `ping` and `pong` are confirmed, you're done! 👌

```bash
$ ansible child -m ping -i /etc/ansible/hosts
```
```bash
182.252.133.72 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
182.252.133.71 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
```
DeepLearning_学習ノート_000

Google cloudの無料部分[cloud shell](https://ssh.cloud.google.com/)で[DeepLearning](http://www.d2l.ai/index.html)を勉強はじめました。

- cloud shell起動後  
  - 上の白色部分はファイル一覧やブラウザーの部分です。
  - 下の黒色の部分はシェールのコマンドウインドウズです。
![cloud shell](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/9910e52f-a035-7ade-c931-1ef9f974155c.png)


- DeepLearning tool のインストール
  - 下記のサイト[d2l.ai](http://www.d2l.ai/chapter_installation/index.html)の指示通りインストール可能ですが、一部のコマンドは変更必要である  
      - [Miniconda](https://conda.io/en/latest/miniconda.html) からLinux用のインストールファイルをダウンロードする
      - 初期化処理からJupyter notebook起動までの一連の処理を行う

```install_01.sh
# minicondaをインストール
sh Miniconda3-latest-Linux-x86_64.sh -b

#初期化処理
~/miniconda3/bin/conda init

#環境配置
conda create --name d2l -y

#学習資料をダウンロード＆解凍
mkdir d2l-en && cd d2l-en
curl https://d2l.ai/d2l-en.zip -o d2l-en.zip
unzip d2l-en.zip && rm d2l-en.zip

#環境起動
conda activate d2l
conda install python=3.7 pip -y

#mxnet & dl2lをインストール
pip install mxnet==1.6.0b20191122
pip install d2l

#Jupyter notebook を起動する
#ローカルのみ
jupyter notebook

#cloud 環境の起動方法
jupyter notebook --port 8000 --ip=0.0.0.0 --allow-root
```
- 起動後の画面  
![jupyter notebook](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/0a6c80a7-03d7-98b1-6290-8ea7f727d63e.png)
Rails modelのjoin戦略についての理解を深める１歩

こちらの記事。よく参考にしてます。
https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58

ここで言っているキャッシュとは何か？
同記事の最後の表についてなんとなくふわっとした理解でした。
特にキャッシュする・しないについて。
それについてまとめました。

## Rails modelって
そのmodelに定義されたリレーションに則ってデータを取得できます

```rb
class User < ApplicationRecord
  has_many :invoices
  ...
```
というUserモデルがあったとして

```rb
user = User.first
invoice = user.invoices
```

というふうに取得できますね
その時、invoicesはどのタイミングで取得する（SQLが発行される）かというと

```rb
user.invoices
```
としたタイミングです

## 結合してみよう
先程のmodelを使って結合してみよう

### joins

```rb
user = User.joins(:invoices).first
user.invoices
```

１行目のタイミングで

```SQL
 SELECT "users".* FROM "users" INNER JOIN "invoices" ON "invoices"."user_id" = "users"."id" ORDER BY "users"."id" ASC LIMIT $1
```

２行目で

```SQL
SELECT "invoices".* FROM "invoices" WHERE "invoices"."user_id" = $1 
```

のようなSQLが発行されました。
invoicesを検索するタイミングは変わってませんね。
なるほど、これがキャッシュされたかどうかってことか。

### preload

```rb
user = User.preload(:invoices).first
user.invoices
```

### includes

preload/eager_loadをいい感じに判断して使用してくれる

1行目の時点でinvoiceも検索しに行ってます

```SQL
  User Load (0.3ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
  Invoice Load (0.3ms)  SELECT "invoices".* FROM "invoices" WHERE "invoices"."user_id" = $1  [["user_id", 1]]
```

2行目では特にSQLは発行されていません。
キャッシュされてますね。
そして、SQLの結合は使わずに２回SELECTすることでuser.invoicesを取得してます。

### eager_load

```rb
user = User.eager_load(:invoices).first
user.invoices
```

Userｓに対してInvoicesをLEFT OUTER JOINで結合してました。
user.invoicesではキャッシュされてるので何も発行しません。

### キャッシュしないということ

joinsメソッドでは、結合先のデータを必要としないが、INNER JOINで絞り込みをしたいときに使用する。
なので、

```rb
user = User.joins(:invoices).first
user.invoices
```

のようなコードは無駄があるということ。
includesとwhereで絞り込みとキャッシュを行うべき。

## 以上
という感じ
Tensorflow2のMirroredStrategyを使って複数GPUで計算する

- 2020/6/9 デシリアライズについて追記

# 概要

非常に簡単。`tf.distribute.MirroredStrategy`のスコープ内でネットワークを構築するだけ。変更は数行ですむ。

# Keras APIを用いた実装例

ここでは簡単な例として隠れ層が１層のみからなるシンプルなネットワークを構築しています。

```python
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.optimizers import Adam


with tf.distribute.MirroredStrategy().scope():

    # このブロックでネットワークを構築する
    x = Input(32, dtype=tf.int32, name='x')
    hidden = Dense(20, activation='relu', name='hidden')(x)
    y = Dense(5, activation='sigmoid', name='y')(hidden)
    model = Model(inputs=x, outputs=y)
    model.compile(
        optimizer=Adam(lr=0.001),
        loss='binary_crossentropy',
    )

model.fit(
    x_train, y_train,
    epochs=10,
    batch_size=16,
)
```

# デシリアライズ時の注意点

シリアライズして保存されたモデルをロードする場合も、同じように`tf.distribute.MirroredStrategy`のスコープ内でモデルを構築すれば良い。

ただし一点注意が必要。公式ドキュメントには記載がないが、下記のstackoverflowの記事にあるように、おそらく`tf.keras.models.load_model()`を使うことはできない制約がある。

- [How to continue training after loading model on multiple GPUs in Tensorflow 2.0 with Keras API?](https://stackoverflow.com/questions/57376403/how-to-continue-training-after-loading-model-on-multiple-gpus-in-tensorflow-2-0)

そのため、記事の回答にあるように、`save_weight()`や`load_weight()`を使う必要がある。

```python
with tf.distribute.MirroredStrategy().scope():
    model = build_model(...)
    model.compile(...)
    model.load_weights('model.h5')
    model.compile(...)
model.fit(...)
```


# 関連

公式なドキュメントは次の通り。

- [Distributed training with Keras](https://www.tensorflow.org/tutorials/distribute/keras)
- [tf.distribute.MirroredStrategy](https://www.tensorflow.org/api_docs/python/tf/distribute/MirroredStrategy?version=nightly)

Keras APIをそのまま利用する場合はこの記事で紹介した通りだが、custom training loopを実装している場合などは、さらに考慮すべき点がいくつかある。その場合は上記のドキュメントを参照していただきたい。


`multi_gpu_model()`は2020年4月以降に廃止予定とのこと。

 - [tf.keras.utils.multi_gpu_model](https://www.tensorflow.org/api_docs/python/tf/keras/utils/multi_gpu_model)
Flutterの画面崩れの検知方法について（随時更新）

# Flutterの画面崩れの表示を検知したい
以前までの記事とは少し寄り道になりますが、Flutterの画面崩れを画像処理によって検知したいなという欲望が湧いてきました。（参考：https://yaba-blog.com/flutter-renderflex-overflowed/ ）
画面崩れの際に、ご丁寧に工事マークのような物を表示してくれているので、これをキーとして検知できないかなと考えています。
「そんなモノに需要があるのか...」「そもそもエラーを吐いているのだからそれをハンドリングすれば良いのでは...」という声も脳裏によぎりますが、ちょっと画像処理の勉強も含めて検討してみます。
（以前から書いている記事がメインワークなので、これは寄り道的に検討します）

# 工事マークの検知方法の検討
あまり深く考えずに簡単な方法を検討すると以下の２つが挙げられます。

- 方法A：素直な画像処理のプログラムを書いて、色とエッジ検出による識別
- 方法B：教師ありの深層学習(Neural Network Console)


それぞれの方法について以下の方法で評価してみました。

| 手法           |     実装工数 |        実行速度|メンテコスト|期待される正確性|
|:--------------|------------:|:------------------:|:------------------:|:------------------:|
|素直な画像処理   |       ○ |        ○        |△|△|
|深層学習　      |      ○ |       △       |△|○か✖︎|

本来なら深層学習はメンテコストが相当高いように感じますが、自分が初学者なのもあってSONYのNNCを使う予定なので、GUIならばそこまでメンテコストはかからないはずです。
実装工数に関しても、方法Aであればとっかかりの実装工数は少ないですが、正確性をあげようと思うとアルゴリズムの検討をしたり、何やかんやコストがかかると見積もっています。NNCは簡単ではありますが、やはりデータセットの準備に難があるのが気がかりです。
正確性については、方法Aはある一定の精度は出そうですが、いろいろな機種・画面パターンに対応できるのか不安。方法Bはうまく動くか全然ダメかの２択になると思っています。

## 方法A：素直な画像処理のプログラムを書いて、色とエッジ検出による識別
現段階で思いついている実装方法
前述したサイトの画像から工事マークの黄色と黒のRGB値を取得して、このサイト(https://www.peko-step.com/tool/hsvrgb.html )でHSV値に変換してみた結果がこちら
<img width="467" alt="スクリーンショット 2020-01-15 23.04.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555381/1dd16601-863e-d4b2-fe18-b9be75380505.png">
<img width="436" alt="スクリーンショット 2020-01-15 23.04.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555381/a4cc0c8b-c11a-575d-d45a-c2bb126e0afc.png">
<img width="415" alt="スクリーンショット 2020-01-15 23.31.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555381/454ca8de-6ff2-9265-3cc9-e7af7f2c3a5f.png">

これを見ると、HとSから識別するのが良さそう。HとSのANDにするのかどちらかにするのか、はたまたORにするのか。閾値は定数でいくのか...などと考えているとやはり少し面倒...

斜めになっている検出は、微分フィルタを使えばいいかなと考えている。しかし、こちらも重みやカーネル値の大きさなどをどうするかという課題は残っていますね。




## 方法B：教師ありの深層学習(Neural Network Console)
さて、こちらは実はよく分かっていません。今後調べていきますが、以下のような進行を考えています。

1. flutter driverを使ってスクリーンショットを撮りまくる
2. 端末の種類や文字サイズを切り替えてスクリーンショットを撮りまくる
3. それらの画像を元に以下の前処理を行う
    4. 表示崩れがないものを0、あるものを1としてアノテーションをする
    5. それぞれの画像はサイズが違うので、横サイズを256pxになるようにresizeする
    6. 縦サイズを256pxになるように画像を切り出していく。キリ良くならない場合は前倒して256*256は遵守する
    7. （斜めに微分フィルタをかけて二値化画像に変換する）
8. NNCにいれて学習器を作成する (https://support.dl.sony.com/docs-ja/%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%EF%BC%9Aneural-network-console%E3%81%AB%E3%82%88%E3%82%8B%E5%AD%A6%E7%BF%92%E6%B8%88%E3%81%BF%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A9/ )
9. 学習器を元に識別する

## 方法C：マッチングは使わないの？？？
確かに表示される物が「工事マーク」で統一されているので、正解データを用意して、それを探索するようにしていけば良いのでは？？？と思いますね。自分もそう思いました。
やりたくなかった理由は簡単で、`大きさの大小に影響されるのを考えるのが面倒`という考えがありました。
あとは輝度の関係などで、あまり使いたくなかったというのがあります。
とはいえ、方法Aと方法Bがどっちもダメダメだった場合はこちらも検討してみようと思います。


# 検証結果
鋭意作成中・・・
VRC上の表情アニメーションとまばたきの干渉を防ぐ

## 免責事項
本内容はVRoidモデルでしか試していません。
VRoid以外でできた/できなかったの報告ウェルカムです！

## くらげさんのBehaviour-Enabledを使う方法
- ダウンロード先
    - https://booth.pm/ja/items/1034257

## 手順
- zipを解凍して中の`Behaviour-Enabled.anim`を適当にUnityにインポート
- 生贄プレハブを作り、アニメーションコントローラーの中に`Behaviour-Enabled.anim`を追加する
- アニメーションウィンドウを開くと`Behaviour-Enabled.anim`が黄色（Missing）になっているので、選択+F2キー等から`Body/Body-expression`を`Body`にリネームしてあげる
    - ※VRoidの仕様が変更になったら <br>
 
![](https://i.imgur.com/abos8oG.png)
↓
![](https://i.imgur.com/SoIPIla.png)
- アニメーションウィンドウ上で`Body:Behaviour.Enabled`をコピーし、まばたきを止めたいアニメーションに貼り付ける
- `Body:Behaviour.Enabled`の右側のチェックボックスを外した状態で全てのフレームにコピーする
![](https://i.imgur.com/DSGyeDP.png)
<br>


～おわり～
【Vuetify】<v-spacer>を使っていて画面の横揺れが発生したら<v-container>の不足を疑おう

## はじめに
**Vuetify**を使って開発をしていて、
**「なぜか画面の横スクロールが発生するな」**
と思って調べたときの記録です。

画像でいうと右端の**余白**です。
こいつのせいでガタガタするので、**除去**します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/bdeb6191-b1f3-ba3f-118e-52121d00d45a.png)


## 環境
```yaml
OS: macOS Catalina 10.15.1
Vue: 2.6.10
vuetify: 2.1.0
```
## 結論:`<v-spacer>`には`<v-container>`が必須
そのまんまです。

何かの変更の際に、誤って`<v-container>`から`<div>`に変更してしまったようで、それから横揺れが発生していました。

### :x:`<div>`で囲われている

```vue
<template>
  <div>
    <v-row>
      <div></div>
      <v-spacer></v-spacer>
      <div></div>
    </v-row>
  </div>
</template>
```

### :o:`<v-container>`で囲われている

```vue
<template>
  <v-container>
    <v-row>
      <div></div>
      <v-spacer></v-spacer>
      <div></div>
    </v-row>
  </v-container>
</template>
```

**`<v-spacer>`は`<v-contaniner>`の横幅を基準**にして余白計算を行うので、`<div>`だと今回のようにはみ出す現象が発生するんですねー:sweat_smile:


## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [Grid system — Vuetify.js](https://vuetifyjs.com/en/components/grids#spacers)
Creating Twin Repositories

![banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/5f1e935a-29e7-74da-cac6-0deadac477bd.png)
> How to create a twins repository that includes both branch and tag. 🙍🙍

## Test environment
- [git](https://git-scm.com/) v2.17.1

## Grammar
```bash
$ git clone --mirror <org_repository>
$ cd org_repository
$ git remote -v
$ git remote set-url --push origin <new_repository>
$ git remote -v
$ git push --mirror <new_repository>
```

## Demo
- org_repository : https://github.com/sarojaba/awesome-devblog.git
- new_repository : https://github.com/leechungkyu/new-awesome-devblog.git

```bash
$ git clone https://github.com/sarojaba/awesome-devblog.git
Cloning into 'awesome-devblog'...
remote: Enumerating objects: 136, done.
remote: Counting objects: 100% (136/136), done.
remote: Compressing objects: 100% (88/88), done.
remote: Total 7219 (delta 81), reused 87 (delta 48), pack-reused 7083
Receiving objects: 100% (7219/7219), 2.59 MiB | 2.28 MiB/s, done.
Resolving deltas: 100% (4595/4595), done.
```
```bash
$ cd awesome-devblog
$ git remote -v
origin  https://github.com/sarojaba/awesome-devblog.git (fetch)
origin  https://github.com/sarojaba/awesome-devblog.git (push)
```
`https://github.com/leechungkyu/new-awesome-devblog.git` ✅ The repository must be created in advance. 

```bash
$ git remote set-url --push origin https://github.com/leechungkyu/new-awesome-devblog.git
$ git remote -v
origin  https://github.com/sarojaba/awesome-devblog.git (fetch)
origin  https://github.com/leechungkyu/new-awesome-devblog.git (push)
```
```bash
$ git push --mirror https://github.com/leechungkyu/new-awesome-devblog.git
Delta compression using up to 2 threads.
Compressing objects: 100% (2586/2586), done.
Writing objects: 100% (7219/7219), 2.59 MiB | 1.52 MiB/s, done.
Total 7219 (delta 4595), reused 7219 (delta 4595)
remote: Resolving deltas: 100% (4595/4595), done.
To https://github.com/leechungkyu/new-awesome-devblog.git
 * [new branch]      master -> master
 * [new branch]      origin/HEAD -> origin/HEAD
 * [new branch]      origin/gh-pages -> origin/gh-pages
 * [new branch]      origin/master -> origin/master
```
## 👥 Result
![git01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/9f6aefeb-e663-7bd9-97cf-8ad39eb55be7.png)
UnityでValveIndexコントローラーの指入力を取る

UnityでValveIndexコントローラーの指入力を取る方法です

# 前提条件
* SteamVRは2.0以降を使用します
* Action Setsはdefaultを使用します

# 実行環境
* Windows10
* Unity 2019.2.8f1
* SteamVR Plugin 2.5.0

#SteamVR Inputの設定
Asset StoreでSteamVRをimport後、メニューの「Window」タブから「SteamVR Input」を選択します
![SaveImage2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567642/42b0ad14-383d-00a8-bc58-c48e209283f3.png)
actions.jsonが無いみたいなことを言われるので、「Yes」を選択します
![notexit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567642/d5510089-88b5-1570-34fe-10dde95a90bd.png)
SteamVR Inputが開けたら、「Save and generate」を選択します
![saveandgene.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567642/181458ca-cd55-ad53-13bf-41eef620ea6c.png)

# スクリプトの作成

```C#:InputTest.cs
using UnityEngine;
using Valve.VR;

public class InputTest : MonoBehaviour
{
    // 指の入力
    public SteamVR_Action_Skeleton actionSkeleton;

    void Update()
    {
        Debug.Log(
            "親指：" + actionSkeleton.thumbCurl +
            "人差し指：" + actionSkeleton.indexCurl +
            "中指："+actionSkeleton.middleCurl +
            "薬指："+actionSkeleton.ringCurl +
            "小指："+actionSkeleton.pinkyCurl
            );
    }
}
```
## SteamVR_Action_Skeleton
指の入力アクションの状態を取ってくるためのクラスです

## thumbCurl～pinkyCurl
それぞれの指をどれだけ握っているか「0～1.0」のfloat値で表現されます


| パラメータ       |説明 
|:-----------------|:------------------|
| thumbCurl|親指の握りを表します<br />親指の値は少し特殊で、以下のような値が入ります<br />・スティックに指を置いた場合：約0.4<br />・タッチパッドに指を置いた場合：約0.5<br />・ボタンに指を置いた場合：約0.8|
| indexCurl|人差し指の握りを表します| 
| middleCurl|中指の握りを表します| 
| ringCurl|薬指の握りを表します| 
| pinkyCurl|小指の握りを表します|

#実行の準備
Main Cameraを削除して[CameraRig]をHierarchyに追加します
![scene.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567642/3e480da8-70e5-725b-5d19-e0c7430e741e.png)
適当にGameObjectを作成して先ほど作成したスクリプト「InputTest.cs」をアタッチします
inspectorから指の入力を取得する手を選択します
今回は左手の指入力を取得するので「\action\default\in\SkeletonLeftHand」を選択します
![ins.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567642/ff3e683d-0489-e8fb-ea99-380f3c3145fe.png)

#実行
ゲームを再生して左手のValveIndexコントローラーを握ると、デバッグログの値が変化します
![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567642/9cd4928b-8e1d-ce22-e8a7-7e0f15dadcb9.png)

#参考サイト
[Class SteamVR_Action_Skeleton](https://valvesoftware.github.io/steamvr_unity_plugin/api/Valve.VR.SteamVR_Action_Skeleton.html)
JavaScriptでinputのパスワードの黒丸のところを文字で表示させてみた！！

##はじめに
某プログラミングスクールで、メ○○リのコピーサイトを作成しました。
チームメンバーが実装していた、ボタンを押すとパスワードの黒丸を文字として表示させる
実装を今日はやっていきたいと思います！と思ったのですが、
すでに下記の参考記事で簡単に作成できました。
[パスワード表示時にマスキング有無を選択できるようにする方法](https://ajike.github.io/password-masking/)

なので、自分のメモ用で記載していきます。
ちなみにこんな感じのものを実装していきます。
![a1a64a26379e2a3036884ebbf0b4aa88.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560478/9fdc5620-b5e3-eefd-c0c7-41715242835c.gif)

##解説
1.まずパスワードを文字として表示していきます。
![](https://i.gyazo.com/95d186805d87d2d203b94367e310beb8.png)
　(1)hamlを記載していきます。(一部のみ表示しています。)

```password.html.haml
= form_for @resume do |f|
  = f.password_field :password,placeholder: '検索時に使用するパスワードを入力',class:"content_main9__form9--password",id:'password'
  %input#js-passcheck{type: "checkbox"}
  %label{for: "js-passcheck"} パスワードを表示する
```
コードはこんな感じです。

　(2)jsを記載していきます。

```password.js
$(function(){
  var password = '#password'; #haml内のid:'password'を取得して代入。
  var passcheck = '#js-passcheck'; #haml内のid:'js-passcheck'を取得して代入。

  $(passcheck).change(function(){  #チェックボックスを押した際に発火するイベントを作成
    if ($(this).prop('checked')){   #チェックボックスにチェックが入った場合発火
      $(password).attr('type','text');  #パスワードのタイプをtypeからtextへ変更することで文字表示
    }
  });
});
```
チェックボックスを押した際に発火するイベントを作成しています。
そして、チェックボックスにチェックが入った時に、
input内のtypeをpasswordからtextへと変更する形となっています。
なので、input内の文字が表示されるようです。

2.パスワードを黒丸に戻します。
![](https://i.gyazo.com/43602d197d644f3d5276e512534945ef.png)

```password.js
$(function(){
  var password = '#password'; #haml内のid:'password'を取得して代入。
  var passcheck = '#js-passcheck'; #haml内のid:'js-passcheck'を取得して代入。

  $(passcheck).change(function(){  #チェックボックスを押した際に発火するイベントを作成
    if ($(this).prop('checked')){   #チェックボックスにチェックが入った場合発火
      $(password).attr('type','text');  #パスワードのタイプをtypeからtextへ変更することで文字表示
    } else {                            #チェックボックスからチェックがなくなった際に発火
      $(password).attr('type','password');  #パスワードのタイプをpasswordへと変更
    }
  });
});
```
次に、elseの部分では、チェックボックスからチェックがなくなった時のイベントとなっています。
この文で、inputのtypeをtextからpasswordへと変更しているため、
文字が再び黒丸へと戻るようです。

##まとめ
もし間違えている理解が間違っている部分等が、ありましたらコメントをいただけると幸いです。
ログアウト、アカウント削除の実装 【初学者のReact×Railsアプリ開発 第13回】

#やったこと
* ログアウトとアカウント削除の実装
* ログアウトでは、ブラウザのLocalStorageに保存してあるtokenなどの情報を消去している。
* アカウント削除はRailsでdestroy。

#成果物
![pvd7u-2l44j.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367226/bccfba18-494a-873e-6287-88f5c1ca6f70.gif)

#実装手順（Rails）
###users_controller
* 消去するアカウントはログイン中のアカウントなので、current_userを使っている

```ruby:users_controller.rb
      def destroy
        @user = current_api_v1_user
        @user.destroy
        render json: { status: 'SUCCESS', message: 'Delete the user', data: @user}
      end
```

#実装手順（React）
###Logout.js
* ログアウトといっても、LocalStorageの情報を消去するだけ。
* localStorage.clear();

```javascript:Logout.js
class Logout extends React.Component {

  constructor(props) {
    super(props);
  }

  Logout() {
    localStorage.clear();
    window.location.href = process.env.REACT_APP_BASE_URL;
  }

  notLogout() {
    window.history.back()
  }

  render() {
    const { classes } = this.props;
    return (
      <div>
        <h3>ログアウトしますか？</h3>
        <Button variant="contained" size="large" color="secondary" className={classes.button} onClick={this.Logout}>
          する
        </Button>
        <Button variant="contained" size="large" color="primary" className={classes.button} onClick={this.notLogout}>
          しない
        </Button>
      </div>
    )

  }
}
```

###DeleteAccount.js
* HTTPのDELETEメソッドを使って消去している

```javascript:DeleteAccount.js
class Deleteaccount extends React.Component {

  constructor(props) {
    super(props);
    this.Deleteaccount = this.Deleteaccount.bind(this);
  }

  Deleteaccount() {
    const { CurrentUserReducer } = this.props;
    const auth_token = localStorage.auth_token
    const client_id = localStorage.client_id
    const uid = localStorage.uid
    axios.delete(process.env.REACT_APP_API_URL + `/api/v1/users`,
      {
        headers: {
          'access-token': auth_token,
          'client': client_id,
          'uid': uid
        }
      })
    localStorage.clear();
    window.location.href = process.env.REACT_APP_API_URL;
  }

  notDeleteaccount() {
    window.history.back()
  }

  render() {
    const { classes } = this.props;


    return (
      <div>
        <h3>アカウントを削除しますか？</h3>
        <Button variant="contained" size="large" color="secondary" className={classes.button} onClick={this.Deleteaccount}>
          する
        </Button>
        <Button variant="contained" size="large" color="primary" className={classes.button} onClick={this.notDeleteaccount}>
          しない
        </Button>
      </div>
    )

  }
}

```
javascript : 2つの配列を比較して、差分（増分,減分）を取得

 
proxy で配列の変更を検知したあとの処理で、「変更前の配列」と「変更後の配列」を比較したくなりました。

以下、2つの配列を受け取って、増分値と減分値の配列をオブジェクトで返す関数です。

**※ ttatsf 様から、より良いコードをコメント欄にて頂いております。断然、そちらの方が参考になると思います**

```javascript

// 配列の差異を取得する処理
const get_difference = ( _old_arr, _next_arr ) => {

  const additions = _next_arr.filter(
    _next => ! _old_arr.includes( _next )
  );

  const subtractions = _old_arr.filter(
    _old => ! _next_arr.includes( _old )
  );

  return {
    additions : additions,       //  増えた分
    subtractions : subtractions  //  減った分
  };
}

```

以下、関数の挙動を確かめます。

```javascript

//  要素を増やします
const arr1 = [ 1, 2, 3 ];
const arr2 = [ ...arr1, 4, 5 ];

const result1 = get_difference( arr1, arr2 );
console.log( result1.additions );      //  [ 4, 5 ]
console.log( result1.subtractions );   //  []

//  要素を増減させます
const arr3 = [ 'a', 'b', 'c', 'd' ];
const arr4 = [ 'a', 'b', 'e', 'f' ];

const result2 = get_difference( arr3, arr4 );
console.log( result2.additions );      // [ 'e', 'f' ]
console.log( result2.subtractions );   // [ 'c', 'd' ]

```

もっといい方法があったら、ぜひ教えてください。

以下、おまけです。（proxy で用いた例です）

```javascript

let obj = {
  array : [ 1, 2, 3 ]
}

let proxy = new Proxy( obj, {
  set( _obj, _prop, _next ){
    
    const old = _obj[ _prop ];
    
    if( _prop === 'array' ){
      const difference = get_difference( old, _next );
      console.log( 'additions : ' + difference.additions );
      console.log( 'subtractions : ' + difference.subtractions );
    }
    _obj[ _prop ] = _next;
    return true;
  }
} );

proxy.array = [ ...obj.array, 4, 5 ];
//  additions : 4, 5

proxy.array = [ 1, 2, 4, 6 ];
//  additions : 6
//  subtrctions 3, 5

```

(2020.1.16 追記）
　ttatsf 様よりコメントを頂きました。ありがとうございます。
　ご指摘いただきました通り、set について、返り値の記述が抜けておりました。　大変申し訳ございません。
　「return true」を加えたものに修正させていただきました。
　また、includes() を使用したものに差し替えさせていただきました。

```
Create Page/Todo Block with Notion API

![notion-banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/688ed8f7-92cb-3234-37fe-52c8ebbf3916.png)
> How to add a Page / Todo block with the [Notion](https://www.notion.so/) API call.
> I used https://github.com/jamalex/notion-py

> ☕️ Ex) Starbucks man drinks nine o'clock every morning and check.

## Ready
- [python](https://www.python.org/) v3.5 ↑
- token_v2
✅ Notion web login -> F12 -> Application -> Cookies -> token_v2
![notion00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/7fdf7603-7ca9-7955-cf5c-fd0eae231010.png)

## Start

### 1. Pre installation
```bash
$ pip install notion
```

### 2. Source code
`add_childpage.py` 

```bash
$ vi add_childpage.py
```
```python
from notion.client import NotionClient
from notion.block import TodoBlock
from notion.block import PageBlock

# login
token_v2 = 'c6c629d29504bd10272...012345678901234512345' # 준비물의 token_v2
client = NotionClient(token_v2=token_v2)

# 스벅남 페이지 URL
url = "https://www.notion.so/openwiki/d8e3e99628eb4e21a258575367ee72c5"
page = client.get_block(url)

print("Page 제목은  :", page.title)

################################
# API 호출로 PageBlock 추가
################################
print(page.children.add_new(PageBlock, title='2020.01.11'))
print(page.children.add_new(PageBlock, title='2020.01.12'))
print(page.children.add_new(PageBlock, title='2020.01.13'))
print(page.children.add_new(PageBlock, title='2020.01.14'))
print(page.children.add_new(PageBlock, title='2020.01.15'))

####################################
# PageBlock에 TodoBlock 추가
####################################
for child in page.children :
    child_page = client.get_block(child.id)
    child_page.children.add_new(TodoBlock, title="09:00 아아벤티")
```
### 3. Run
```bash
$ python ./add_childpage.py
```
### 4. Result
![notion01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/f0466742-fa0a-1f83-e544-b28eb301635e.jpeg)
![notion02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/a50a43fc-a412-5523-6fbf-1a2163c0a4e4.jpeg)
![notion03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/c2cb9d2f-0e29-38f5-1f66-04c07ba2e299.jpeg)

## Etc
- [Preview on Youtube](https://youtu.be/hdJg9rq66wY)
Goのgo-sql-driver/mysqlでMySQLとタイムゾーンがずれる

# 
go-sql-driver/mysqlを使ってMySQLにSQLを投げて、その結果をあれこれするAPIを作成していたときにちょっとはまったことのメモ。

## 問題の発覚

MySQLのタイムゾーンの確認。

```
show variables like '%time_zone%'
=>
|Variable_name|Value|
|system_time_zone|UTC|
|time_zone|SYSTEM|
```

MySQLのタイムゾーンがUTCなのにgo-sql-driver/mysqlを使ったSQLの実行結果を見るとJSTで返ってきてしまっていた。

```
MySQL: 2020-01-01 00:00:00 UTC
SQL実行結果のパース: 2020-01-01 00:00:00 JST
```

そこでmain.goに下記を書いて、Goアプリケーションでのタイムゾーンを確認。

```main.go
fmt.Println(time.Now())
=> 2020-01-15 13:46:07.4988314 +0000 UTC m=+1.180576601
```

で返ってきていた。

**Goアプリケーション内でもMySQLでもUTCなのになんでSQLの実行結果だけJSTになるんだ？？？**

## 解決
http://kenzo0107.hatenablog.com/entry/2015/08/19/165310

上記の記事を見ていて気づいたが、

```mysql.go
db, err := sql.Open("mysql", "xxxx:zzzzzzz@/dbname?parseTime=true&loc=Asia%2FTokyo")
```

としてしまっていたため、MySQLがUTCなのにGoで受け取ったときはそれにJSTのラベルをわざわざ付けてしまっていた…
そこで下記のように修正。

```mysql.go
db, err := sql.Open("mysql", "xxxx:zzzzzzz@/dbname?parseTime=true")
```

単純な理由だけど1時間位はまったのでメモ。
std::vectorに入った値をbinary形式で出力する方法メモ

cpp std::vector<float>型のコンテナに入った値をbinary形式で出力する方法
毎度探しているのでメモ

```cpp:write_vector_to_bin.cpp
bool write_binary(std::string filepath, std::vector<float>& vec){
    std::ofstream fout(filepath, std::ios::out | std::ios::binary);
    fout.write((char*)&vec[0], vec.size()*sizeof(vec[0]));
    fout.close();
    return true;
}
```

```cpp:read_bin_to_vector.cpp
bool read_binary(std::string filepath, std::vector<float>& vec){
    std::ifstream fin(filepath, std::ios::in | std::ios::binary);
    fin.read((char*)&vec[0], vec.size()*sizeof(vec[0]));
    fin.close();
    return true;
}
```
Google Cloud Functions上でログレベル付きのStackdriver Loggingを利用する

Google Cloud Functions（以下Cloud Functions）でログレベルを分けたいことあります。

よく Go (go111) で Cloud Functions を利用するのですが、標準のlogパッケージを利用しても、ログレベルを出し分けできません。

- https://cloud.google.com/functions/docs/monitoring/logging#functions-log-helloworld-go
- https://cloud.google.com/logging/docs/setup/go

上記ドキュメントを参考にすると、 Cloud Functions では以下のような書き方になります:

```go
func ExampleLogging(w http.ResponseWriter, r *http.Request) {
        ctx := context.Background()

        projectID := os.Getenv("GCP_PROJECT")

        client, err := logging.NewClient(ctx, projectID)
        if err != nil {
                log.Fatalf("Failed to create client: %v", err)
        }
        defer client.Close()

        logName := "cloudfunctions.googleapis.com%2Fcloud-functions"

        logger := client.Logger(logName).StandardLogger(logging.Info)
        logger.Println("info")
}
```

ちょっと煩雑ですね。また、logパッケージでの出力とは異なり、`execution_id` が付与されないため、functionの実行ごとのログがまとめて検索できません。

## github.com/groove-x/cloudfunctions/log を使う

この問題を解決するサポートパッケージ [github.com/groove-x/cloudfunctions/log](https://github.com/groove-x/cloudfunctions) を紹介します。

```go
package function

import (
	"fmt"
	"net/http"

	"github.com/groove-x/cloudfunctions/log"
)

func ExampleLogging(w http.ResponseWriter, r *http.Request) {
	log.WithRequest(r)

	log.Debug("debug")
	log.Info("info")
	log.Warn("warn")
	log.Error("error")
}
```

シンプルですね！

結果はこちら:
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30362/d48af0be-c366-bce5-3597-08d9d3ac16c5.png)

`log.WithRequest(r)` でリクエストの情報をloggerに覚えさせることで、 `execution_id` や、トレースに関する情報が自動的に追加されます。

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30362/c736e1ac-788b-ca43-c6da-8af6f2c7ade3.png)

以上。
プログラミング初心者です、よろしくお願いします

<h1>今日からプログラミングで学習したこと+他色々投稿していく</h1>
<p>今日からプログラミングで学習したことを淡々と投稿していきたいと思います。</p>
<p>気が向けば、他のことも書くかもしれません...</p>
<p>ひとまずデータベースとSQL、データベース設計を学びました。</p>
<p>ゲームをイメージしながらデータベースの内容を理解していきたい...と思いますが、</p>
<p>正直実際に使って覚えていけたら良いと思ってるので、</p>
<p>取り急ぎさらっと流す感じで今はやっていこうかと思います。</p>
<p>まずは定期的なアウトプットが継続できるよう頑張っていきたいです。</p>
나중에 읽을 기사, 포켓(Pocket) 소개

![banner-imagepocket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/5fda6f18-0ef5-4fcb-3362-7b0628092eab.png)
> [Pocket](https://getpocket.com/) 예전 이름은 **'Read It Later'** 였다고 합니다.
> 이름에서 유추할 수 있듯이 '나중에 꼭 읽어야겠다.' 하는 사이트를 Keep 해둘 수 있습니다.
> 북마크, 스크랩 성애자분들! 
> Pocket으로 생산성을 올려보아요~ 🚀

## 스크랩하기
### PC의 경우
[Pocket](https://app.getpocket.com) 회원 가입을 합니다. (무료) 
그리고, [크롬 Pocket 확장 프로그램](https://chrome.google.com/webstore/detail/save-to-pocket/niloccemoadcdkdjlinkgdfekeahmflj?hl=ko) 설치 합니다.
> ✅ Pocket 아이콘만 눌러주면 끝!
> `tag` 도 같이 입력해주면 좋아요.

https://app.getpocket.com/ 에 접속하면 수집한 전체 목록을 확인할 수 있습니다.
![pocket01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/5c8c868a-d0e4-f013-37f9-73075ab20b72.png)
![pocket02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/9263480c-9e2f-afe5-530c-bdfe70819c10.png)


### 모바일의 경우
PC와 동일하게 [크롬 Pocket 확장 프로그램](https://chrome.google.com/webstore/detail/save-to-pocket/niloccemoadcdkdjlinkgdfekeahmflj?hl=ko) 설치하면 됩니다.
아래 그림처럼 **공유**를 통해서 Pocket에 저장할 수도 있습니다.
![pocket03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/9f0ea067-0c44-ed48-47ae-4a305eba8f99.jpeg)
![pocket04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/1615ca4b-1cba-5505-9dde-9aa8a076df91.jpeg)

## 스크랩 확인하기
> 출퇴근시간이나 잠들기전 Pocket을 확인하는 습관을 만들어보세요!
> 어렵게 모아 놓고, 다시 들여다보지 않으면 결국 **꽝!** 입니다. 😂

👍 앱이 매우 직관적으로 되어있어 한 번 써보면 대부분의 기능을 알 수 있습니다. (긴 설명은 생략..)
👍 한글화도 잘 되어 있어요!
![pocket05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/d284ac9d-807c-0085-f325-af6d6657f010.jpeg)
![pocket06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/386a722b-07e8-cd69-4283-7be41a836ef8.jpeg)
![pocket07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144058/3ddd7006-9831-6042-a618-f7bb1b77b607.jpeg)

## 발견된 제약사항
😥 현재 웹으로 Pocket에 접속하면, `tag` 값이 보이지 않습니다.

## 참고자료
- [나중에 읽을 기사, 내 '포켓(Pocket)'에 쏙!](https://it.donga.com/14392/)
PIC16F1764 MPLAB MCC & Curiosity でPWMを試す

MplabのMCCを使って、PWMのコードを自動で作成できる。
MCCの基本的な使い方は、本家のドキュメントか、以下のURLあたりを参照ください。
http://blog.e-photographer.net/how-to-program-pics-with-mplab-x-and-mcc?lang=ja


# 手順
PWMが参照するタイマーをセットするため、Device Resourses からTimerを追加する。
どれでもよいがTMR2を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102681/e568f879-2ffb-d672-17a1-750277736aed.png)

Timer Clockと、Timer periodの設定によって、PWMの解像度が変わる。
今回はできるだけ解像度をあげるため、プリスケーラ、ポストスケーラともに１：１とした。

続いてPWM3を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102681/4b29f1b0-13dd-573d-f91d-dd8edfec520a.png)

PortAの5番にPWM3を紐付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102681/1e8bbd0d-512a-237d-77db-4b33858b320d.png)

で、mccのコード生成を実行し、mccが自動生成した、PWM3_LoadDutyValueを叩いてDutyをコントロールします。CuriosityだとPort Aの５番は、D4のLEDとつながっているため、LEDが調光されます。

```c:main.c
    uint16_t sawToothX = 0b1111111111; // 10bit
    while (1) {
        PWM3_LoadDutyValue(sawToothX);

        sawToothX -= 1;
        if(sawToothX == 0){
            sawToothX = 0b1111111111;
        }
        __delay_ms(10);
    }

```

##PWM5で試す
このマイコンだと、PWM5は、オフセットや位相なども設定できるのですが、PWM3とインターフェースが異なります。
クロックを直接指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102681/99331ce2-e49b-993a-a792-934ab5b738b7.png)

今度は、PORTAの1番にアサインします。これはLEDのD5に対応してます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102681/4546f4b5-5acc-0b74-3c1a-50e42641afbd.png)

`PWM5_DutyCycleSet` したあとに、設定を反映させるためには、`PWM5_LoadBufferSet`が必要でハマりました。（ドキュメント読めばわかるのですが。。）

```c:main.c
    uint16_t sawToothX = 0b1111111111; // 10bit
    while (1) {
        PWM3_LoadDutyValue(sawToothX);
        PWM5_DutyCycleSet(sawToothX);
        PWM5_LoadBufferSet();
        sawToothX -= 1;
        if(sawToothX == 0){
            sawToothX = 0b1111111111;
        }
        __delay_ms(10);
    }

```

これでD5とD4のLEDがPWMで明滅します。
ビルドは通るけどうまく動かないときは、このNotificationsを見ると、コンフィギュレーション上ダメな箇所があれば教えてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102681/3dcdd467-8713-cfd3-f7c0-3bea8aa62ced.png)
poetryで作ったpythonプロジェクトをVSCodeに読み込ませるとエラーになった時の対処法

# はじめに
Poetryの環境をVSCodeに読み込ませたらimportエラーになってしまいました。
その後、無事にエラーが解消されたのですが、ハマったのでメモを残します。

# 環境
Mac mojave

# なぜ起きるのか
Poetryは仮想環境を設定値に従って作成するのがデフォルトの動作です。
VSCode的にはそんなん知ったことではないので、poetryを無視して読み込もうとするもライブラリが全く見つからないという自体になり解決できないとしてエラーになります。

# それじゃどうするのか
設定変更してpoetry環境の作り直しをする必要があります。
Poetryはどんな設定でも一度作ってしまうとその環境を優先して読み込む仕様のようなので、手順を踏んで作り直さないと思った通りになりません。

## １：設定確認
まずはpoetryの設定を確認します。
ここで重要なのは`virtualenvs.in-project`です。
エラーになる人はここが`false`になっているかと思います。

この設定はpoetryでインストールしたものをどこに配置するかの設定になっており、`false`の場合は`virtualenvs.path`で設定されたフォルダに格納されます。」

``` sh
$ poetry config --list
cache-dir = "/Users/tasogarei/Library/Caches/pypoetry"
virtualenvs.create = true
virtualenvs.in-project = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/tasogarei/Library/Caches/pypoetry/virtualenvs
```

## 2：設定変更
`virtualenvs.in-project`を`true`に変更します。
この設定はpoetryでインストールする箇所をプロジェクトのルートフォルダに配置するかの設定になっており、`true`にすることでルートフォルダに配置されるようになります。

``` sh
$ poetry config virtualenvs.in-project true
```

## 3：既存の削除
poetryの仕様で一度作ってしまうと設定変更しても特に関係なく変更前のファイルを見に行きます。
よって、`virtualenvs.path`にあるフォルダを削除してあげないと変更しても意味がありません。

ということで、該当フォルダ内にある読みこみたいプロジェクトのフォルダを丸っと削除してあげてください。

## 4:poetryによるパッケージインストール
準備が整ったので、再びパッケージのインストールを実施します。
私は念の為`init`からやり直しましたが、`init`は必要ありません。

``` sh
$ poetry install
```

## 5：VSCodeで確認
`install`が完了すると`.venv`フォルダがルートに生成されます。
今後はここにパッケージが入ることになり、VSCodeはいい感じにこのフォルダを読んでくれるため（特に追加の設定はいりません）、起動したらエラーが消えているかと思います。

これにて作業完了です。
【React】Material UIのアイコンが表示されない

#問題
* ReactのMaterial-UIのiconが表示されない。

```javascript:XXX.js
import Icon from '@material-ui/core/Icon';
<Icon>add_circle</Icon>
```
![スクリーンショット 2020-01-15 22.41.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367226/e788e3d3-7507-8f5f-5700-99f34a303225.png)


#解決策
* index.htmlに下記の記述を追加

```html:index.html
<!DOCTYPE html>
<html lang="en">

<head>
 
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

</head>
```
![スクリーンショット 2020-01-15 22.41.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367226/a9bf2987-2738-2bb0-86ba-0c4bfbf1cb36.png)
表示された！


地味に悩みました。設定方法をきちんと理解していませんでした。
index.htmlはノーマークだった...