OmniAICreator/Qiita-1.07M huggingface dataset:
Node.js at Windows10

環境設定したのでそのメモです。
複数バージョンを切り替えられたほうがいいかなーと思ったので、以下の手順で設定しました。

## nvmインストール

まず`nvm`をインストールする

Node Version Manager (nvm) for Windows
https://qiita.com/spiderx_jp/items/2ddc2f8a5a010ff78b1d
https://github.com/coreybutler/nvm-windows

インストール後

```
C:\>nvm list

No installations recognized.

C:\>nvm list available

|   CURRENT    |     LTS      |  OLD STABLE  | OLD UNSTABLE |
|--------------|--------------|--------------|--------------|
|    14.1.0    |   12.16.3    |   0.12.18    |   0.11.16    |
|    14.0.0    |   12.16.2    |   0.12.17    |   0.11.15    |
|   13.14.0    |   12.16.1    |   0.12.16    |   0.11.14    |
|   13.13.0    |   12.16.0    |   0.12.15    |   0.11.13    |
|   13.12.0    |   12.15.0    |   0.12.14    |   0.11.12    |
|   13.11.0    |   12.14.1    |   0.12.13    |   0.11.11    |
|   13.10.1    |   12.14.0    |   0.12.12    |   0.11.10    |
|   13.10.0    |   12.13.1    |   0.12.11    |    0.11.9    |
|    13.9.0    |   12.13.0    |   0.12.10    |    0.11.8    |
|    13.8.0    |   10.20.1    |    0.12.9    |    0.11.7    |
|    13.7.0    |   10.20.0    |    0.12.8    |    0.11.6    |
|    13.6.0    |   10.19.0    |    0.12.7    |    0.11.5    |
|    13.5.0    |   10.18.1    |    0.12.6    |    0.11.4    |
|    13.4.0    |   10.18.0    |    0.12.5    |    0.11.3    |
|    13.3.0    |   10.17.0    |    0.12.4    |    0.11.2    |
|    13.2.0    |   10.16.3    |    0.12.3    |    0.11.1    |
|    13.1.0    |   10.16.2    |    0.12.2    |    0.11.0    |
|    13.0.1    |   10.16.1    |    0.12.1    |    0.9.12    |
|    13.0.0    |   10.16.0    |    0.12.0    |    0.9.11    |
|   12.12.0    |   10.15.3    |   0.10.48    |    0.9.10    |

This is a partial list. For a complete list, visit https://nodejs.org/download/release

C:\>nvm arch
System Default: 64-bit.
Currently Configured: -bit.
```

## node.js インストール

```
C:\>nvm install latest
Downloading node.js version 14.1.0 (64-bit)...
Complete
Creating C:\Users\xxx\AppData\Roaming\nvm\temp

Downloading npm version 6.14.4... Complete
Installing npm v6.14.4...

Installation complete. If you want to use this version, type

nvm use 14.1.0
C:\>nvm use 14.1.0
Now using node v14.1.0 (64-bit)

C:\>node --version
v14.1.0

C:\>nvm install 12.16.3
Downloading node.js version 12.16.3 (64-bit)...
Complete
Creating C:\Users\xxx\AppData\Roaming\nvm\temp

Downloading npm version 6.14.4... Complete
Installing npm v6.14.4...

Installation complete. If you want to use this version, type

nvm use 12.16.3

C:\>nvm list

  * 14.1.0 (Currently using 64-bit executable)
    12.16.3

C:\>nvm use 12.16.3
Now using node v12.16.3 (64-bit)

C:\>node -v
v12.16.3

C:\>npm -v
6.14.4

C:\>
```

## Visual Studio Code の設定

以下参照
Visual Studio CodeとNode.jsの導入について
https://qiita.com/GRGSIBERIA/items/b8cd4a2b3635d1bb0391

## その他、参考サイト
Configuring your Windows development environment
https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules
HHKBでCapsLockを使う方法

#解決法

**「Fn」**＋**「Tab」**＝**「CapsLock」**（Macモードの場合）

##参考にしたページ
[ミズノブログ](https://blog.shogo-mizuno.me/entry/2017/02/08/100642)
[HHKB公式](https://faq.pfu.jp/faq/show/2656?category_id=256&site_domain=hhkb)
[Swift] UIStackvView inside ScrollView iOS

### 概要
scrollView内にstackViewを配置する時の制約の付け方ですが、、
必ずと言って良いほど毎回忘れてハマるのでサンプルコードを準備しました。
tableViewではカスタム出来ないデザインの画面などでよく使うケースです。（設定画面など）

ポイントはstackViewとScrollViewの「Equal Width」です。

といっても結局忘れるのでXibからviewをコピーしたほうが早いですw

### IB
<img width="1404" alt="スクリーンショット 2020-05-04 19.47.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117784/47d0e07f-6a4f-898f-140b-ba8944b26e9b.png">


### 結果
<img width="200" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-05-04 at 19.50.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117784/4c3990d6-e0f3-6b57-de58-19f54c64ee1e.png">
<img width="200" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-05-04 at 19.50.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117784/5bc3e60a-d64b-c78e-818b-a3e3404a3845.png">
<img width="200" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-05-04 at 19.50.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117784/f697cbe3-4a2a-f916-7716-6e5f69720d73.png">


### github
https://github.com/menomoto/ScrollView
ZOOMトラフィックのQOS制御

ZOOM管理者の`アカウント管理`-`アカウント設定`の中にDSCPマーキングという設定を見つけました。

RTX1200でQOS制御ができるので設定してみました。

効果のほどはわかりません。。。

#### DSCPマーキング

ネットワークトラフィックの分類を決定します。信号とメディアパケットのDSCPマーキングを有効にします。（初期設定は、56（音声）、40（ビデオ）、40（信号）です。）

これらの設定は、EXEファイルを使用してインストールされたWindowsクライアントでは有効になりません。Windowsクライアントは、MSIファイルを使用してインストールする必要があります([IT管理者用のZoomクライアントをダウンロードする](https://zoom.us/client/latest/ZoomInstallerFull.msi))。


## RTX1200の設定

http://www.rtpro.yamaha.co.jp/RT/docs/qos/diffserv_qos.html

投入した設定

```
queue lan2 type priority
speed lan2 100m
pp select 1
pppoe use lan2
queue class filter 1 dscp ip * *
queue pp class filter list 1
pp enable 1
```

雰囲気を確認するコマンド

```
show status qos all
```

## ZOOM MSI Install

https://support.zoom.us/hc/en-us/articles/201362163-Mass-Installation-and-Configuration-for-Windows

> Auto-update: Disabled by default, and will not allow users to install updates for the Zoom client. To enable (allow users to update the Zoom client), append ZoomAutoUpdate="true" to your install choice:

MSIでZOOMをインストールすると、自動アップデートが無効に設定されています。
有効にするためには、インストール時にオプション指定が必要です。

上書きインストールでは、変更されなかった雰囲気なので、アンインストール、インストールを行いました。

```
msiexec /package  ZoomInstallerFull.msi /lex zoommsi.log ZoomAutoUpdate="true"
```

## start an elevated video process to support advanced DSCP marks

インストーラオプションにも設定があったので、自動アップデートと同時に設定します。

ユーザアカウントのほうで設定があるので、しなくてもいいと思うが念のため。

```
msiexec /package  ZoomInstallerFull.msi /lex zoommsi.log ZoomAutoUpdate="true" ZConfig="EnableElevateForAdvDSCP=1"
```

### 追加情報

https://support.zoom.us/hc/en-us/articles/207368756-QoS-DSCP-Marking

WindowsのGPOの設定も必要？
シェルスクリプトのコマンド置換

#コマンド置換
シェルスクリプトを書いていると、`コマンドの出力結果をシェルスクリプト中で利用したいことがある。`
コマンド置換を使えば、**コマンドの結果を文字列として取得する**ことができる。

##利用方法
`$()`という形式で、カッコ内に実行したいコマンドを記述すると、シェルスクリプト実行時に標準出力で置き換えられる。

##例：現在の日付をYYYY-MM-DD形式で表示
```.sh
$ date '+%Y-%m-%d'
2020-05-04
```

###コマンド置換で利用する

```date.sh
#!/bin/bash

filename=$(date '+%Y-%m-%d')
touch "$filename"
```
これを実行すると、現在の日付をYYYY-MM-DD形式で表示したファイルが作成される

```
-rw-rw-r--  1 vagrant vagrant    0 May  4 10:54 2020-05-04
```
##参考
新しいLinuxの教科書
PythonでAWS-S3の署名付き(期限付き)URLを生成する

# PythonでAWS-S3の署名付き(期限付き)URLを生成する

## はじめに

`Mac環境の記事ですが、Windows環境も同じ手順になります。環境依存の部分は読み替えてお試しください。`

### 目的

この記事を最後まで読むと、次のことができるようになります。

| No.  | 概要            | キーワード                 |
| :--- | :-------------- | :------------------------- |
| 1    | 署名付きURL生成 | s3, generate_presigned_url |

### 実行環境

| 環境           | Ver.    |
| :------------- | :------ |
| macOS Catalina | 10.15.3 |
| Python         | 3.7.3   |
| boto3          | 1.11.17 |

### ソースコード

実際に実装内容やソースコードを追いながら読むとより理解が深まるかと思います。是非ご活用ください。

[GitHub](https://github.com/nsuhara/python-aws-s3-generate-presigned-url.git)

### 関連する記事

- [Boto 3 Documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html#boto-3-documentation)

## 署名付きURLの生成

```run.py
import os

import boto3

aws_access_key_id = os.getenv('AWS_ACCESS_KEY_ID', '')
aws_secret_access_key = os.getenv('AWS_SECRET_ACCESS_KEY', '')
region_name = os.getenv('REGION_NAME', '')

bucket = os.getenv('BUCKET', '')
key = os.getenv('KEY', '')
expires_in = os.getenv('EXPIRES_IN', '')  # sec / 1hour = 3600sec.


def main():
    s3 = boto3.client(
        service_name='s3',
        aws_access_key_id=aws_access_key_id,
        aws_secret_access_key=aws_secret_access_key,
        region_name=region_name
    )

    presigned_url = s3.generate_presigned_url(
        ClientMethod='get_object',
        Params={
            'Bucket': bucket,
            'Key': key
        },
        ExpiresIn=expires_in,
        HttpMethod='GET'
    )

    print('-----\n{}\n-----'.format(presigned_url))


if __name__ == '__main__':
    main()
```
XpraによるWSL2のXセッション切断問題の解決

[VcXsrvがサスペンド・レジューム後にリモートクライアントと切断される問題とその回避策](https://qiita.com/teikan/items/a91258745dd70a70c4ef)の続編です。
WSL2でも、WindowsをサスペンドしてレジュームするとVcXsrvのXクライアントのウィンドウが消えてしまいます。
[Xpra](https://xpra.org/)で一応解決したので、まとめておきます。

# WSL2でXpraをインストール

```
$ sudo apt-get install xpra
```

# WSL2でXpraサーバを起動

```
$ xpra start :100 --bind-tcp=:10000
```

# Xpraサーバ経由でXクライアントを起動

```
$ DISPLAY=:100 xterm&
```

# WindowsでXpraクライアントを起動(WSL2上のXpraサーバへ接続)
Xpraクライアントは https://xpra.org/trac/wiki/Download でダウンロードできます。

```
C:\>"\Program Files\Xpra\xpra" attach tcp://localhost:10000/ --desktop-scaling=off
```
これでXクライアントのウィンドウが出ます。
サスペンドレジュームしても消えません。

# IPアドレスを指定して接続する方法
上記のlocalhostに代えてホストのIPアドレスを指定する手もあります。

```
$ xpra start :100 --bind-tcp=0.0.0.0:10000
```
```
C:\>"\Program Files\Xpra\xpra" attach tcp://172.21.96.171:10000/ --desktop-scaling=off
```

こちらの方がWSL2のlocalhost forwardingのオーバーヘッドがない分速いような気もしますが、気のせいかもしれません。
WSL2起動のたびに変わるIPアドレスを調べる手間はあります。
vsockが動けば速そうですが、[WSL2ではうまく動かない](https://github.com/microsoft/WSL/issues/4723)ようです。

# WSL2のみで完結する方法
Windows側にクライアントをインストールしたくない場合、XpraクライアントもWSL2で動かす手もあります。
この場合はUnixドメインのソケットで十分です。

```
$ xpra start :100
$ xpra attach :100&
```
この場合、サスペンドレジュームでいったんXクライアントのウィンドウが消えますが、再度`xpra attach :100&`でXpraクライアントを起動すれば復活します。
Vim の <Plug> ってなんだ？

`<Plug> ` は、「このプラグインの関数は、外部から使ってもいいよ。このプラグインの関数は、~/.vimrc の中で nmap とかを使ってコマンドとして割り当ててもいいよ。」と、言うのを明示するために使うらしいです。

以下の記事からキッカケが掴めました。

* [【図解Vim】map と noremap](https://cocopon.me/blog/2013/10/vim-map-noremap/)


## 例えば...

### Step 1.

coc.nvim と言う Vim のプラグインをインストールしていたとします。以下のような設定を ~/.vimrc にいれると、ノーマルモードで `gd` と打つと `<Plug>(coc-definition)` に置き換えられます。ちなみに、定義ジャンプしてくれます。

```vim:~/.vimrc
nmap <silent> gd <Plug>(coc-definition)
```

* [Example vim configuration - neoclide/coc.nvim](https://github.com/neoclide/coc.nvim#example-vim-configuration)

### Step 2.

では `<Plug>(coc-definition)` と言うキーマッピングは、どこで定義されているのでしょうか？検索してみると `CocActionAsync('jumpDefinition')` と言う関数を呼び出していることがわかります。

```vim
nnoremap <Plug>(coc-definition) :<C-u>call CocActionAsync('jumpDefinition')<CR>
```

* [/plugin/coc.vim#L364 - GitHub](https://github.com/neoclide/coc.nvim/blob/d6dd56bba8992aae3ade4034f1bc8d1148c3780f/plugin/coc.vim#L364)

### Step 3.

まとめると `<silent> gd` と打つと `CocActionAsync('jumpDefinition')` が呼び出されています。

```
<silent> gd

  |
  v

<Plug>(coc-definition)

  |
  v

:<C-u>call CocActionAsync('jumpDefinition')
```

## 補足

### ◯ 公式ドキュメント

公式の説明は、以下の通りになります。これだけだと、正直厳しい...orz

```
:help <Plug>
```
```
                                                         *<Plug>*
特別なキーの名前 "<Plug>" は、内部のマッピングのために使われルことがあります、
"<Plug>" は、如何なるキーの組み合わせとも合致しません。
これはプラグインにおいて便利です |using-<Plug>|
The special key name "<Plug>" can be used for an internal mapping,
which is not to be matched with any key sequence.
This is useful in plugins |using-<Plug>|.
```

### ◯ `<C-u>` ってなんだ？

`:<C-u>call CocActionAsync('jumpDefinition')<CR>` とありました。 `:call CocActionAsync('jumpDefinition')<CR>` ではダメなのでしょうか？

Vim のコマンドラインモードにおいてカーソルの位置から先頭まで、削除してくれるそうです。

```
:help c_CTRL-U
```

```
                                                c_CTRL-U
CTRL-U  Remove all characters between the cursor position and
        the beginning of the line.  Previous versions of vim
        deleted all characters on the line.  If that is the
        preferred behavior, add the following to your .vimrc: >
                :cnoremap <C-U> <C-E><C-U>

```

例えば、範囲を選択している状態でコマンドラインモードに映ると以下のように表示されます。

```
:'<,'>
```

`<C-u>` を打つことでこれを消すことができます。

```
:
```

* [Please help understand how to use <Plug> mapping - reddit](https://www.reddit.com/r/vim/comments/78izt4/please_help_understand_how_to_use_plug_mapping/)


### ◯ なんで nmap なの？

大抵の場合 ~/.vimrc には noremap が選択されています。なんで `<Plug>` にキーマッピングする場合は noremap ではなく nmap なのでしょうか？

```vim:~/.vimrc
nmap <silent> gd <Plug>(coc-definition)
```

Reddit の方には idk, I don't know, わからんけど nmap じゃないと動かないと書かれていたのですが...

>  (idk why noremap doesn't work),
>
> * [Please help understand how to use <Plug> mapping - reddit](https://www.reddit.com/r/vim/comments/78izt4/please_help_understand_how_to_use_plug_mapping/)

以下の記事に理由が書かれていました。詳細はリンク先をご参照ください。

> noremapは「再マップしない」ので、「素のVim」のキーマッピングで `<Plug>(say_hello)` に対応するものを探してしまう。 が、そんなものは定義されているはずもなく、何も実行されない。
>
> * [【図解Vim】map と noremap](https://cocopon.me/blog/2013/10/vim-map-noremap/)

以上になります。ありがとうございました。
OSM ベクトルタイルを LDC, LLDC, SIDS とともに

これは、国連ベクトルタイルツールキット （UNVT） の新たな活動の報告です。

オープンストリートマップ・ファウンデーションの Allan Mustard (apm-wa) 議長が4月18日に発表した [Summary Report on OSMF Chair's Outreach Jan-early Apr 2020](https://www.openstreetmap.org/user/apm-wa/diary/392767) には、次の記述があります。

>One respondent noted that there is nothing to stop local chapters or others from hosting vector tiles if they wanted to, and suggested encouraging local communities and chapters to experiment with vector tiles before the OSMF settles on a solution, should it decide to do so.

ローカルのコミュニティやチャプターが**ベクトルタイルの実験をすることを奨励する**方向になっていくことが期待できます。この流れの中で UNVT は、多様な地図が最新の技術を享受できるようにする、と言う観点から、この実験を支援することができます。

国連での開発協力は、後発開発途上国（LDC）・内陸開発途上国(LLDC)・小島嶼開発途上国(SIDS)への協力を重視します。実際に、[Unite Maps Initiative/UN Mappers](https://wiki.openstreetmap.org/wiki/Unite_Maps_Initiative/UN_Mappers)は、ソマリアやコンゴ民主共和国のような国で展開しています。こういった国のデータは、現状において、分量が少ないと理解しています。分量が少ないからこそ、簡単に最新の技術に載せることができます。

ローカルのコンテキストを重視して、できる限りローカルの理解を獲得しながら、OSM を材料データとして使ってベクトルタイル協力ができないかと考えています。

ということで、試みにいくつかの国について変換をしてみました。この試みのシリーズのインデックスは、[kokoromi](https://github.com/optgeo/kokoromi) に置いています。

<img width="853" alt="Honiara, Solomon Islands" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/c35747b5-4e9e-e9ef-7218-8c5f5f3c7c67.png">

- [🇸🇧 Solomon Islands](https://optgeo.github.io/kokoromi-sb)
- [🇹🇲 Turkmenistan](https://optgeo.github.io/kokoromi-tm)
- [🇻🇺 Vanuatu](https://optgeo.github.io/kokoromi-vu)
- [🇫🇯 Fiji](https://optgeo.github.io/kokoromi-fj)
- [🇨🇭 Switzerland](https://optgeo.github.io/kokoromi-ch)
- [🇸🇴 Somalia](https://optgeo.github.io/kokoromi-so)
- [🇨🇫 Central African Republic](https://optgeo.github.io/kokoromi-cf)
- [🇨🇩 Democratic Republic of Congo](https://optgeo.github.io/kokoromi-cd)
- [🇰🇪 Kenya](https://optgeo.github.io/kokoromi-ke)
- [🇹🇴 Tonga](https://optgeo.github.io/kokoromi-to)
- [🇳🇿 New Zealand](https://optgeo.github.io/kokoromi-nz)(up to z=14 only)
- [🇦🇬🇧🇸🇧🇧🇧🇿🇨🇺🇩🇲🇩🇴🇬🇩🇬🇾🇭🇹🇯🇲🇰🇳🇱🇨🇻🇨🇸🇷🇹🇹 the Caribbean](https://optgeo.github.io/one-love)
- [🇷🇼 Rwanda](https://optgeo.github.io/kokoromi-rw)
- [🇧🇦🇷🇸🇲🇪🇽🇰🇦🇱🇲🇰 Western Balkans](https://unvt.github.io/mame)

※スイスは LDC/LLDC/SIDS ではありませんが、コンパクトでありながら非常にデータ密度が高いエリアであることが分かっていましたので、ベンチマークをかねて変換してみました。その他についても、必ずしも LDC/LLDC/SIDS にこだわっているわけではありません。

変換をするためのツールセットである [naru](https://github.com/unvt/naru) は、ベクトルタイルの生産・提供・設計・最適化の技術移転教材として完成させていきます。
MacのSourceTreeでSSH接続設定する

# RSAキーの生成
ディレクトリを移動し、sshキーを作成する

```shell
$ cd ~/.ssh && ssh-keygen -t rsa
```

質問形式で入力があるので、各項目を設定する
（今回は何も入力せずにEnterを3回押す）

```config
Enter file in which to save the key (~/.ssh/id_rsa): # キーの保存場所の設定
Enter passphrase (empty for no passphrase): # パスワードの設定
Enter same passphrase again: # パスワードの再入力
```

※うまくいかない時の最終手段は`~/.ssh`のキーとconfigを削除して手順をやり直す


# Gitのアカウント設定
1. SourceTreeの環境設定を開き、**アカウント**タブを確認する
2. [**追加...**]ボタンからアカウント情報を設定する
3. **SSHキー**欄の[**クリップボードにコピー**]ボタンをクリックする
4. 使用するGitクライアントのサイトの設定画面にある**SSH keys**欄を開く
5. [**New SSH key**]ボタンがあるのでそこで上の手順でコピーしたキーを登録する

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [SSHキー生成の仕方](https://qiita.com/oseibo/items/aee83b4bb86e6ee052f8)
- [SourceTreeでSSH設定する際に一番楽だと感じた方法（メモ）](https://qiita.com/UJinc/items/a5839c9df4ca119ae22a)
Golang 型確認


reflect.TypeOfを使う場合

```golang
package main

import (
    "fmt"
    "reflect"
    "strings"
    "time"
)

func main() {
    // 数値
    P(1)                            // int
    P(1.2)                          // float64

    // 文字列
    P("string")                     // string

    // 配列
    P([]int{0,1,2})                 // []int
    P([2]int{0,1})                  // [2]int
    P([]string{})                   // []string
    P(strings.Split("a b", " "))    // []string
    P([1]string{"1"})               // [1]string

    // マップ
    P(map[string]int{"a": 10})      // map[string]int
    P(map[int]int{1: 10})           // map[int]int
    P(map[string]string{"1": "10"}) // map[string]string

    // その他
    P(true)                         // bool
    P(nil)                          // <nil>
    P(func() {})                    // func()
    P(P)                            // func(interface {})
    P(time.Now())                   // time.Time

}

func P(t interface{}) {
    fmt.Println(reflect.TypeOf(t))
}
```

fmt.Printfを使う場合

```golang
package main

import "fmt"

func main() {
    fmt.Printf("%T\n", 1) // int
    fmt.Printf("%T\n", "string") // string
}
```

# 参考
Golangで型情報を調べる
http://y0m0r.hateblo.jp/entry/20140413/1397397593

Go言語で型を判別する関数
https://teratail.com/questions/4795
Vapor 4でModelの親子構造がある際にPOSTするためのやり方について

# はじめに

Vapor 4でリレーションしているModelの親子構造があり、子供をPOSTする際にjsonでない形式では親子構造を表現できず、どうやってリクエストするのかというのが分からなかったのでその解決方法を書いておきます。

# 前提

データベース上にすでにTodoのModelが作成されていて、その任意のTodoに紐づくCommentのModelをPOSTしてDB上に作りたいというのを例に挙げます。

- Model
    - Todo（親）
        - プロパティ
            - id
            - title
        - 子として`[Comment]`を持つ
    - Comment（子）
        - プロパティ
            - id
            - text
            - todo
                - 必ず親のTodoを持つ


## 疑問
    
- CommentをPOSTする際にTodoを指定しないといけない
    - jsonなら階層にしてPOSTすればいい
        - `{ id: "...", text: "...", todo: {id: "..."} }`
        - jsonでないならどうする？
            - jsonでないと階層構造を表現できない
            - Vapor 3では`req.formData`からPOSTされるデータを取り出せていた...?
                - Vapor 4からRequestからPOSTされたBodyをDictionaryで取り出せそうもない


# 解決案
## Contentを別途用意してそいつでデコードさせる

まずComment型にInput型を用意しContentプロパティに準拠させ、`text`と`todo_id`からオブジェクトを作れるようにします。ついでにidもランダムでいいのでPOSTさせる必要ない。

```swift
final class Comment: Model, Content {
    static let schema = "comments"

    struct Input: Content {
        let text: String
        let todoID: UUID

        private enum CodingKeys: String, CodingKey {
            case text
            case todoID = "todo_id"
        }
    }

    @ID(key: .id)
    var id: UUID?

    @Field(key: "text")
    var text: String

    // Reference to the Tooo this Comment is in.
    @Parent(key: "todo_id")
    var todo: Todo

    init() { }

    init(id: UUID? = UUID.generateRandom(), text: String, todoID: UUID) {
        self.id = id
        self.text = text
        self.$todo.id = todoID
    }
}
```

Routing側はInput型からデコードさせる。

```swift
func routes(_ app: Application) throws {

    app.post("comments") { req -> EventLoopFuture<Comment> in
        // Input型をデコード
        let commentInput = try req.content.decode(Comment.Input.self)
        // InputのインスタンスからCommentを作る
        let comment = Comment(text: commentInput.text, todoID: commentInput.todoID)
        // Commentを返す
        return comment.create(on: req.db)
            .map { comment }
    }
}
```

# 参考

https://theswiftdev.com/a-generic-crud-solution-for-vapor-4/
chaliceコマンドのデバッグ出力を行う

chalice コマンドを見てみると、デバッグオプションはちゃんとあるのに、

```bash
$ chalice --help
Usage: chalice [OPTIONS] COMMAND [ARGS]...

Options:
  --version             Show the version and exit.
  --project-dir TEXT    The project directory path (absolute or
                        relative).Defaults to CWD

  --debug / --no-debug  Print debug logs to stderr.
  --help                Show this message and exit.

Commands:
  delete
  deploy
  dev                Development and debugging commands for chalice.
  gen-policy
  generate-models    Generate a model from Chalice routes.
  generate-pipeline  Generate a cloudformation template for a starter CD...
  generate-sdk
  invoke             Invoke the deployed lambda function NAME.
  local
  logs
  new-project
  package
  url
```

以下のようにすると、怒られてしまう、、、

```bash:怒られる
$ chalice package build --debug
Usage: chalice package [OPTIONS] OUT
Try 'chalice package --help' for help.

Error: no such option: --debug
```

どうも、調べるとオプションを渡す場合はサブコマンドの前に渡す必要があるらしい。

というか、最初のをよく見ると `chalice [OPTIONS] COMMAND [ARGS]` となっており、`--debug` は `OPTIONS` の一覧なので、ここにセットしないとダメですね…。


```bash:これならOK
$ chalice --debug package build
2020-05-04 19:16:44,435 botocore.hooks [DEBUG] Changing event name from creating-client-class.iot-data to creating-client-class.iot-data-plane
2020-05-04 19:16:44,440 botocore.hooks [DEBUG] Changing event name from before-call.apigateway to before-call.api-gateway
2020-05-04 19:16:44,441 botocore.hooks [DEBUG] Changing event name from request-created.machinelearning.Predict to request-created.machine-learning.Predict
2020-05-04 19:16:44,443 botocore.hooks [DEBUG] Changing event name from before-parameter-build.autoscaling.CreateLaunchConfiguration to before-parameter-build.auto-scaling.CreateLaunchConfiguration
2020-05-04 19:16:44,443 botocore.hooks [DEBUG] Changing event name from before-parameter-build.route53 to before-parameter-build.route-53
2020-05-04 19:16:44,444 botocore.hooks [DEBUG] Changing event name from request-created.cloudsearchdomain.Search to request-created.cloudsearch-domain.Search
(後略)
```

`chalice package --stage local` のように、 `ARGS` に `--` 始まりの引数を渡すことがあったので、オプションが明確に分かれていることに気づきませんでした、というお話です。
Rails の migration で外部キー制約の設定をする (add_foreign_key, remove_foreign_key)

# はじめに
`t.references` による外部キーの設定はあまり好きでないので、この記事には記載しない。
`add_foreign_key` `remove_foreign_key`の使い方について書く。

# 前提条件
`User` と `Post` モデルが存在する。
関係は 1 対 N

# 単純にIDでやる場合
`Post` の `user_id` → `User` の `id`

```ruby
add_foreign_key :posts, :users
```

# カラム名が異なる場合
なぜか `User` が `code` なるカラムを持っていて、`Post` の `user_code` から外部キー制約を貼りたい、そんな時。

```ruby
add_foreign_key :posts, :users, column: :user_code, primary_key: :code
```

`column` で子のカラム、`primary_key` で親のカラムを指定する

# 親のレコードを消したときの挙動を変えたい (on_delete, on_update)
デフォルトだと、外部キー制約を設定した場合、子のレコードが存在していると親のレコードを削除できません。
これを `restrict` 設定といいます。
親のレコードが消えた時、子のレコードを同時に削除したい場合、`cascade`
親のレコードが消えた時、子の外部キー制約を設定したカラムを `null` にしたい場合は `nullify` に設定する必要があります。
migration から設定する方法は↓
```ruby
add_foreign_key :posts, :users, on_delete: :cascade
```

on_update といって、親レコードの該当カラムを変更した場合の挙動も設定できます。
こちらもデフォルトだと `restrict` で、更新するとエラーになります。

# 外部キー制約を削除する
## 単純パターン
```ruby
remove_foreign_key :posts, :users
```

## カラム名変えて作った場合
```ruby
remove_foreign_key :posts, column: :user_code
```
この場合、 `rails db:rollback`がコケます。
再度作り直そうにもテーブルわからんぞ〜〜〜とRailsに言われます。
安定択として、migration ファイル作成時に `up` `down`を使って明示的にrollbackの処理を書いてあげると良いでしょう

```ruby:example_migration
  def up
    remove_foreign_key :posts, column: :user_code
  end

  def down
    add_foreign_key :posts, :users, column: :user_code, primary_key: :code, on_delete: :cascade
  end
```


# おわり
これであなたも外部キーマスター(マイグレーションに限る)
AzureでVM作成しようとするとサイズ選択が行えない

## はじめに
本記事は一部以下の記事を参考にさせていただいております。
※事象はリンク先と同じに見えますが一部情報を追加させていただいております。

Azureを新規開始したらサイズの選択ができず仮想マシン(VirtualMachine)が作成できない場合の対応
https://qiita.com/gomasa/items/2d1a39faf2fc74ca7dfb

## 事象概要
Azureアカウントを2020/04/29に取得し、5/3に新規VMをデプロイしようとしたところ、
VM作成時のサイズ選択画面にて全てのサイズがグレーアウトされサイズ選択が行えない。
※無料試用版アカウントにてリージョンは西日本リージョンを使用

<img width="1210" alt="img-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246372/d57ce913-389a-7210-5c1b-aee671986807.png">

## 原因
Azureサポートに問合せを行ったところ、2020/05/03現在は昨今の社会情勢（おそらくコロナ）により全てのサブスクリプションに対して全リージョンでのデプロイをブロックしているとのことでした。

#### Azureサポートチームからの回答抜粋
> Unfortunately, all credit based subscriptions are being blocked from deploying the resources in any region because of current situation. 

また、以下のような記事も見つけました。

Microsoft Azureの需要が775％増、「優先度基準」の適用が始まる--新型コロナで
https://japan.zdnet.com/article/35151576/

## 対応策
### 1.使用するリージョンを変更する
リージョンを変更することで以下のようにサイズの指定を実施できる場合があるようです。
以下の図は米国西部2のリージョンを選択し、VM新規作成を行おうとした際のサイズ選択の画面です。

<img width="1210" alt="img-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246372/35dd0c6f-b837-c314-e580-6ae01a58d535.png">

おそらく特定リージョンの一部のVMタイプ用ホストであればリソースに空きがあり、デプロイを許可しているものと推測します。ただしこれも状況の変化によって、使用可能リージョンおよびサイズが変動すると思われます。

### 2.サポートに問合せVMデプロイを許可してもらう（※確認中）
現在Azureサポートチームに問合せを行っている最中ですが、
従量課金アカウントにアップグレードし、デプロイ情報を伝えることで
制限を解除してもらえる可能性があります。
※これについてはまだ確認中のステータスですので、確認が取れ次第更新します。

#### Azureサポートチームからの回答抜粋
> Please be informed that that free trial will have few limitations/restrications hence cannot engage Azure capacity team to enbale the region for the series. The free subscription subscription need to be upgraded to Pay-as-You-Go by following the below link.However you will still have the free credits i.e. 200 USD until the 30 days period is ended.
> Upgrade to Pay-as-you-go Link: https://docs.microsoft.com/en-us/azure/cost-management-billing/manage/upgrade-azure-subscription#upgrade-your-azure-free-account
> 
> I would request you to help us with error screenshot and help us with the VM size you are creating, also with the below details to engage our Azure capacity team and check for the possibilities.
> 
> Region to Enable:
> Deployment Model (ARM/RDFE):
> Planned VM Type:
> Planned Compute Usage in Cores:
> Planned Storage Usage in TBs (Premium if XIO Compute - DS/FS/GS):
> Additional quantity:


## (補足)事象発生の時系列
以下の時系列でVMのサイズ選択が行えずVM新規作成が行えない事象が発生している。

リージョン: 西日本

4/29(無料アカウント作成)~5/1：VM新規作成時にサイズ選択が行えず、VMデプロイ出来ない。
　　　　　　　　　　　　　　　　※厳密にはA,Dシリーズは選択可能であったがここではB2msでデプロイしようとした
5/2：VMサイズ選択が行えるようになったため、新規にB2msでVMをデプロイ。
5/3〜現在：再度新規VMデプロイ時にサイズの選択が行えなくなった。
　　　　　　Azureの[ヘルプとサポート]よりサポートリクエスト（C）を発行。
　　　　　　※この時点ではA,Dシリーズ含む全てのサイズが選択不可であった
　　　　　　※5/3に作成したVMのサイズ変更は行えるように見受けられた
　　　　　　　（実際にサイズ変更は実施していないが、サイズ選択自体は可能であった）

---
### 宣伝
弱小Twitterやってます。良かったら少し付き合ってください。
https://twitter.com/mochizuki875
ざっくりわかる自然言語処理２　〜BERT〜

# はじめに
BERTのことを調べましたが、具体的にどう使えば良いのかイメージ出来なかったため、ざっくりどんな全体像になるのか整理しました。

参考）
[BERTを用いて、日本語文章の多値分類を行う](https://qiita.com/Yuu94/items/0e5cff226bd3cc8fb08c#train%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E5%AD%A6%E7%BF%92%E6%B8%88%E3%81%BF%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AEfine-tuning)
[はじめての自然言語処理](https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part3.html)


# このページを見てわかること
* BERTをどう使えば良いかざっくりイメージ出来る
![BERT-処理概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14760/3b7053e4-8f64-c004-06fd-dedd3df3c8fa.png)
【React】GoogleMapでMarkerが複数ある時のInfoWindowの表示

## やりたいこと
GoogleMapのAPIでは、Markerをクリック等したりするとInfoWindowと呼ばれる吹き出しが表示できます。
Reactでどのように実装すればよいか検索すると、Markerが単一のときの実装例はあるのですが、複数ある場合の実装例があまりなかったので紹介します。

## 前提等
* 地図用のライブラリとして、[google-maps-react](https://github.com/fullstackreact/google-maps-react)を使います。
* ライブラリの使い方やReactの実装方式やMarkerのstateの管理は、[【React】GoogleMapで地図をドラッグして移動した後にMarkerを更新する](https://qiita.com/someone7140/items/66c6b9afd9d397d9fb58)と同様とします。
* 実装についてStackOverflowの記事[React and google-maps-react. Not displaying InfoWindow](https://stackoverflow.com/questions/57666455/react-and-google-maps-react-not-displaying-infowindow/60752452#60752452)を参考にしています。

## イメージ
複数Markerが表示されていて、Markerをクリックすると該当店舗の画像が表示されるイメージになります。
<img width="1000" alt="スクリーンショット 2020-05-04 0.51.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/4672a88e-dd3b-99ab-cc06-beca2ae19dba.png">

## サンプル
※ reducerやstoreの実装内容は割愛

``` GoogleMapComponent.js
import React, { useContext, useState } from "react";
import { GoogleApiWrapper, InfoWindow, Marker, Map } from "google-maps-react";
import { MapStore } from "../../store/MapStore";

export const GoogleMapComponent = ({ google }) => {
  const { state, dispatch } = useContext(MapStore);
  const location = state.currentLocation;
  var markerList = [];

  // InfoWindowの情報はローカルステートで管理
  const [infoWindowState, setInfoWindowState] = useState({
    markerInfo: {},
    visible: false,
  });

  // グローバルステートの情報でMarkerを作成
  state.markerList.map((m, i) => {
    return markerList.push(
      <Marker
        key={s.id}
        name={s.id}
        title={s.name}
        label={s.name}
        onClick={onMarkerClick}
        position={{ lat: m.latitude, lng: m.longitude }}
      />
    );
  });

  const onMarkerClick = (_, marker) => {
    // markerListから該当のレコードを取得
    const markerInfo = state.displayStoreList.find((m) => m.id === marker.name);
    if (markerInfo) {
      setInfoWindowState({
        activeMarker: marker,
        markerInfo: markerInfo,
        visible: true,
      });
    }
  };

  function onInfoWindowClose() {
    setInfoWindowState({
      markerInfo: {},
      visible: false,
    });
  }

  return (
    <Map
      google={google}
      zoom={15}
      center={{ lat: location.latitude, lng: location.longitude }}
      initialCenter={{ lat: location.latitude, lng: location.longitude }}
    >
      {markerList}
      <InfoWindow
        marker={infoWindowState.activeMarker}
        onClose={onInfoWindowClose}
        visible={infoWindowState.visible}
      >
        <img
          src={infoWindowState.markerInfo.image}
          alt={infoWindowState.markerInfo.name}
        />
      </InfoWindow>
    </Map>
  );
};

export default GoogleApiWrapper({
  apiKey: process.env.REACT_APP_GOOGLE_MAP_API_KEY,
})(GoogleMapComponent);

```
Reactで作成したアプリをFirebaseでホスティングする

# 概要
`create-react-app`コマンドで作ったReactアプリをFirebaseでデプロイする内容です。
想像以上に簡単にホスティングが完了しました。

流れは以下です。

1. Firebaseプロジェクトを作成
2. プロジェクトにアプリを登録
3. モジュールにFirebase SDKを追加
3. `npm run build`コマンドでビルドファイルを生成
2. `firebase.indexes.json`ファイルの作成
3. デプロイ対象のフォルダに`build`を指定
4. デプロイ

# Firebaseの設定
[Firebaseの公式ドキュメント](https://firebase.google.com/docs/web/setup)に沿って、step2まで実施します。
プロジェクト、アプリの作成が完了したので、Reactで作成されたモジュールにアプリを連携します。
以下の工程はコンソールで実施します。

# アプリの連携
## Firebase SKDの追加
以下のコマンドでfirebaseを追加します。

```
$ npm install --save firebase
```

インストールが完了したら、`src/index.js`などにFirebaseをimportします。

```typescript
import * as firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";

const firebaseConfig = {
  /* 
  ** 管理画面より、 Firebase SDK snippet の内容をペーストします。
  ** 無くてもとりあえずホスティングは可能です
  */
};

firebase.initializeApp(firebaseConfig);
```

上記の内容はホスティングするだけなら不要です。

# Firebase CLIをインストール
以下のコマンドでCLIをインストールしてください。

```
$ npm install -g firebase-tools
```

インストールが完了したら、次のコマンドでGoogleにログインします。
ブラウザが立ち上がって、ログインが促されます。

```
$ firebase login
```

>すでにログインされており、別のアカウントに切り替える必要があれば、 `logout`コマンドが利用可能です。

以下のコマンドでFirebaseを初期化します。

```
$ firebase init
...
  * You are initializing in an existing Firebase project directory

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Ent
er to confirm your choices. 
 ◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◯ Functions: Configure and deploy Cloud Functions
❯◉ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
```
方向指示キーで `Hosting: ...`を選び、スペースキーで選択します。

```
? What do you want to use as your public directory? (public) build
```
次に、ホスティング対象のディレクトリを選択します。(デフォルトでは、`public`が設定されます。)
`build`を入力して設定してください。

```
Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y
```
今回SPAなので`YES`を返します。

```
File build/index.html already exists. Overwrite?(y/N) y
```
`YES`を返します。


# ビルドファイルを作成
以下のコマンドでReactをビルドします。

```
$ npm run build
```

`/build`フォルダが生成されます。


# Firebase デプロイ
`build`ファイルが生成されたら、以下のコマンドでデプロイを実施します。

```
$ firebase deploy
...
✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/{プロジェクトID}/overview
Hosting URL: https://{プロジェクトID}.firebaseapp.com
```

正常に完了したら、ホスティングURLにアクセスします。
ホスティングURLは `アプリID.firebaseapp.com` or `アプリID.web.app`になるようです。

表示されたでしょうか？
以上でホスティング完了です。

今回ホスティングしたTODOアプリです。
https://todoapp-f93ce.web.app/

# さいごに
FirebaseホスティングにNetlifyに簡易的にアプリケーションの公開が可能になったなぁと感じます。
個人で小規模サービス公開程度なら、これらのサービスで無料公開でスタートできそうですね。

# 参考文献
- [Firebase公式ドキュメント](https://firebase.google.com/docs/web/setup?authuser=1)
- [Firebase Firebaseの初期設定〜デプロイまで](https://ajike.github.io/firebase-1/)
LINE botで注文システム作ってみました！

#LINEで注文システム作ってみた
皆さんこんにちは、たんてぃです。はじめてのQiita投稿ですが、頑張って書いていこうと思います。２年くらい前に思いついたシステムをLINE botで作ってるんですが、先に同じようなことやってる企業があって、まねされるとか思ってるような段階でもないなって思ったんでシステムの内容とコードを公開しちゃおうかと思います！

## 目次
 * 僕が作ったシステム
 * 開発手順
  * どうやって作るか調べる
  * 必要な機能の実装
  * テスト
 * 実際に作ったシステム


## 僕が作ったシステム
僕が作っているのはたまにレストランに置いてある注文用のタブレットの代わりにお客さんのスマホから注文ができるようにするシステムです。
このシステムのいいところはタブレットを店側で用意する必要がないので、<b>初期導入費用が抑えられることです。</b>
通常だと注文用のタブレットって大型のチェーン店でしか導入されていなくて、個人経営の店で注文システムが導入されているところはほとんどありません。それはレストランのような飲食店では支出が多いため設備投資に回せる資金が集まりにくく、タブレットが買えないからだと考えています。
これはシステムの概要です。
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623247/830f0673-4975-e9ac-19a1-7d0136ad501b.jpeg)
お客さんはスマホから注文をLINEで送信します。その注文を集計して厨房から注文リストを確認しながら料理を作り、お客さんに届けます。会計の際には注文リストを元にレシートを作成します。



## 開発手順

### どうやって作るか調べる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623247/3b2feb3f-173e-17cc-b573-3b28cc90fbbb.png)
作るものは決まっていましたが、LINE botを作ったことはおろかサーバーを使ったシステムを作ったこともなかったのでとりあえずLINE botの設定をググって調べてLINE公式アカウントを作成しました。
>アカウント作成の参考にしたブログ↓
[LINEのBot開発 超入門（前編） ゼロから応答ができるまで](https://qiita.com/nkjm/items/38808bbc97d6927837cd)

このままコーディングまでこのブログを参考にしながら作っちゃおうかと思ったんですが、Herokuって何？って思って調べてみたんですが、よくわかんなかったんで別の方法を探していたらGASというものを見つけました。
>こんなサイト↓
[GASを用いたサーバーレスで作るLINEbot](https://tech-blog.rakus.co.jp/entry/20191106/google-apps-script#bot%E4%BD%9C%E6%88%90)

GASはGoogle Apps Scriptの略でGoogle Spread Sheetから開いて直接コードを打ち込めばプログラムができるので環境構築とかしなくてよかったので初心者にとっては簡単だろうなと思いました。


### 必要な機能の実装
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623247/df411c19-de67-c951-21e7-f542041ba52a.png)

開発環境は整ったのでこのシステムに必要な機能を実装していきます。ちなみに僕は↑このイラストと同じ格好で作業してることが多いです。
 > - ユーザーのメッセージを受信
 > - 受信内容に合わせてSpread Sheetに入力
 > - 送信メッセージを作成
 > - メッセージを送信

必要な機能は大きく分けるとこの４つなのでこれらを含んだソースコードをネットで検索してお手本にしました。

> メッセージの受信と送信メッセージ作成のお手本にしたブログ↓
[Google Apps ScriptでLINE BOTつくったら30分で動かせた件](https://qiita.com/hakshu/items/55c2584cf82718f47464)

> Spread Sheetの操作のお手本にしたブログ↓
[【GAS】スプレッドシートの値をスクリプトから操作するぞ](https://www.pnkts.net/2019/12/03/gas-handle-spreadsheet#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF)
Spread Sheetの操作は他にもいろんなブログを見ながら作ったんですが、履歴が残ってないので１つだけ紹介してます。

> 送信メッセージ作成の参考にしたブログ↓
[JavaScriptの文字列操作（置換・連結・検索・比較など）を徹底解説！](https://www.sejuku.net/blog/21538)


僕はJavascriptは書いたことがないので、自分で考えて書き換えるというよりはネット上に転がっているコードを切り貼りしながら自分が作りたいものに必要な機能を備えていく方法を取りました。<b>自分が知らない言語で何か作りたいときはこのように、作りたいものの部品をネットに転がってるコードから取り出してきて組み合わせるのがおすすめです。</b>
実際に僕が書いたコードが見たい人は下のリンクから確認してください。↓
[実際に書いたコード](https://qiita.com/Tanthi/items/8c2affbffbc3b7d616b9)

###テスト
ある程度機能が書けたら実際にスマホを使ってテストしていきます。僕は機能の追加や変更があるたびに毎回テストしてます。テストといってもスマホから何回か入力するだけですが、これで課題抽出しながら書けるので完成度も高くなるし、次にすることを確認できるので作りやすいです。また何かを作っていると実感しやすいので、何らかの出力ができるようになればそこからはテストしながらコーディングすることをおすすめします。
テストの様子↓
<img width="375" alt="IMG_0713[1].PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623247/6204af6f-31b2-10e0-0aa7-8d6959b27e35.png">

##実際に作ったシステム
僕が作っているシステムのリンクを張り付けてます。ぜひ試して遊んでみてください。
[システムの説明書](https://peraichi.com/landing_pages/view/orderline)
[システムのLINEアカウント](https://line.me/R/ti/p/%40351esarm)
【devise】 rails g devise:install ができない、、時こそ！！


##解決法
以下を入力。９割解決します

```mac.termial
$ bundle exec spring stop
```

##原因
springというgemとdevieのgemの衝突っぽいです。
参考：http://ohara.geniusroots.com/entry/2017/03/26/145253


以上
Microsoft Learn モジュール 概観 - ソフトウェア開発にアジャイルなアプローチを選択する

# はじめに

この記事は、Microsoft Learn の下記のモジュールの中から重要と思われる内容を\(筆者が勝手に抽出して\)書き残しているものです。

- [Choose an Agile approach to software development][MSLearn]

上記のモジュールは、2020/5/4 現在、英語でのみ提供されています。日本語の内容を確認されたい方は、こちらを参照してください。※公式のものではありません

- [Azure DevOps - ソフトウェア開発にアジャイルなアプローチを選択する Part.1][MyHatena]


# アジャイルとは何か？

## アジャイルはチームが行う作業を計画するための哲学や考え方

これも勘違いする人が多いのですが、`アジャイル=ソフトウェアの開発プロセス`ではありません。チームで開発を行うための哲学や考え方に近い。つまり何を言っているかと言うと、**これがアジャイルだと定められた開発プロセスなんて存在しない** ということです。
`アジャイル開発`という言葉が世に出てもう随分と経ちますが、この言葉は、特定の正しい開発プロセスを指し示しているのではなく、新しい開発プロセスの考え方、哲学に近いものだと言うことです。

## アジャイルソフトウェア開発宣言

アジャイルが哲学や考え方である、ということを証明するものが、**Agile Manifesto** です。これは日本語で [**アジャイルソフトウェア開発宣言**][AgileManifesto] と言われています。

この Agile Manifesto は、以下のように記載がなされています。

> 私たちは、ソフトウェア開発の実践あるいは実践を手助けをする活動を通じて、よりよい開発方法を見つけだそうとしている。
> この活動を通して、私たちは以下の価値に至った。
> ・プロセスやツールよりも個人と対話を、
> ・包括的なドキュメントよりも動くソフトウェアを、
> ・契約交渉よりも顧客との協調を、
> ・計画に従うことよりも変化への対応を、
> 価値とする。すなわち、左記のことがらに価値があることを認めながらも、私たちは右記のことがらにより価値をおく。
> （引用元：アジャイルソフトウェア開発宣言）

見てわかる通り、`私たちは以下の価値に至った`と記載がされています。つまり、**宣言を出した人物たちの価値観の話しかしていない** のです。左が右より劣っていて軽視して良い、などとは一言も言っていません。

アジャイルという定められた開発プロセスはない、という認識を持っておくことが重要ですね。


# アジャイルを採用するための推奨事項

アジャイルは哲学や考え方だ、という話がありましたが、ではそれをどうやって組織に浸透させていくか、という話ですね、これは長文になるので、是非翻訳した記事の方を参照していただければと思います。

- アジャイルプラクティスを支える組織体制を作る
- アジャイル技術と実践についてチームメンバーを指導する
- チーム内およびチーム横断のコラボレーションを可能にする


# Azure Boardsとは？

やっと Azure DevOps の中身に入っていきますね。なぜここまでに時間をかけているかというのは、\(これは私個人の意見ですが\) マイクロソフト社のブランド戦略によるものが大きいと思っています。
昔と違って、今のマイクロソフトは、**ユーザーは自分たちのニーズや背景を踏まえて好きなものを使用すればいい、そのための様々なサービスをマイクロソフトは用意するので、気に入れば使ってください** というような雰囲気があります。DevOps、アジャイルを自分たちの組織に導入、定着、推進させるために、Azure DevOps がマッチするなら使ってください、という感じに見えなくもないです。

## 4つのプロセス

Azure Boards は、プロジェクトを作成する際に設定する内容によって、表示内容や活用方法が少し変わってきます。Azure DevOps では、4パターンのプロセスが選択可能です。

- Capability Maturity Model Integration (CMMI)
- Scrum
- Agile
- Basic

スクラムやアジャイル開発の経験があるチームは、それらのプロセスを選択すればいいと思います。モジュール内では、Basic を選択している通り、まだスクラムやアジャイル開発のナレッジや文化が定着していない組織では、最初は Basic を選択するのが無難だと思います。


# スプリントは2週間から4週間

ここは難しいところですね。大抵は**2週間でスプリントを切る**と良い思います。\(4週間=1ヶ月って、正直、結構長い\)

`プロダクトバックログ`に投入されているタスクの内容は、**粒度が非常にバラバラで統一されていない**ことが普通です、そのため、1スプリントで対応できる内容にするために、タスク内容を分解しなければなりません。1スプリントの期間が長ければ、その分タスクを細かく分解することが困難になり、タスク漏れやスプリントがうまくいかなかった時の影響が大きく出てしまいます。\(だって1ヶ月分の作業が無駄になったとしたら、誰もが嫌ですよね。。\)


# 演習

ここでは、実際に以下の作業を行っています。

- プロジェクトを作成する (Basic プロセスを選択)
- チームを作る・チームメンバーの追加
- ボードを作成する
- スプリントを定義する
- タスクを割り当て反復を設定する

日本語訳した記事を順に実施してもらえればと思います。
作成したワークアイテムを元に作業が進められていくわけですが、この演習を消化すれば、実業務でも Azure DevOps を使い始めるためのきっかけには十分だと思います。

# さいごに

Azure Boards は、いわゆるプロジェクト管理のサービスではありますが、ツールだけ導入してもプロジェクトは上手く進まないですよね。チームで仕事をする以上、そこには信頼関係や文化、価値観の共有が必須です。**皆に使われないツールに価値はありません**。

そのために、本モジュールでも、前半はアジャイルについての認識を共有したりする場面があったのだと思います。`DevOpsはツールではない`という言葉を覚えているでしょうか。ぜひ、この事を忘れることなく、Azure DevOps をチーム全員で使い始められるといいですね。


---

[MSLearn]:https://docs.microsoft.com/ja-jp/learn/modules/choose-an-agile-approach/
[MyHatena]:https://mappie-kochi.hatenablog.jp/entry/2020/05/03/020000

[AgileManifesto]:https://agilemanifesto.org/iso/ja/manifesto.html
【#PowerAutomate Tip's】IF関数の罠

他開発言語経験者が陥りそうな箇所だと思ったので、メモというか備忘録というか(;´Д｀)

# Power Automate の IF関数
他の開発言語と同様に「条件に合致するか否か」で処理を分岐する関数です。

[関数リファレンス if](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#if)

```
if(<expression>, <valueIfTrue>, <valueIfFalse>)
```

アクションの分岐ではなく、例えば SharePoint のリスト項目を作成する際に「Aだったら〇〇、それ以外なら××」みたいな”アクション中の動作を条件で切り替える”ための関数です。

# NGパターン1：条件における式
例えば「配列の要素（アレイの中身）が1個より多い場合」という条件で分岐したい、としましょう。C# や Java の経験があると、下記のような記載をしたくなるかと思います。

``` NG
if( 1 < length(<配列>), <Trueの処理>, <Falseの処理>)
```

はい、上記はフローでエラーになります。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/0754e732-e64b-4c89-9951-81b48874c7e7.png)

見えづらいかもしれませんが、アクションの項目が赤文字になってますよね。
参考までに、Automate で配列の要素数を取得したい場合は [length](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#length)関数 を利用します。なので、要素数を求める関数が間違っているワケではありません。

Power Automate のエラーメッセージは具体的にドコが悪いか？の詳細が解説されない場合が多いです。なので、いったいナニが何だかってなりますよね・・・。

正しくは下記のように記述します。

```
if( greater(length(<配列>),1), <Trueの処理>, <Falseの処理>)
```

記事投稿時点では、所謂「式が持つ値」による判定ができないようです。冒頭で紹介したDocsにも記載ないので”おそらく”です・・・。IF関数の条件に指定できるのは、True・Falseの2値を返却できる関数などに限定されるように見受けられますね。
なお、”ｎ以上”や”以下”に関しては [論理比較関数](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#logical-comparison-functions) を利用して記述します。

# NGパターン2：False時の式 省略
他開発言語経験者であれば同意いただけると思うのですが「条件がTrueの時だけ〇〇の処理をして、Falseの時は何もしなくてよい」という場合、Falseの処理を省略しますよね？

```
if( greater(length(<配列>),1), <Trueの処理> )
```

上記のような感じで、他の開発言語はFalseの処理を記載しなくても問題ないモノが多いです。そして、Automate も関数を上記のように記述した時点ではエラーになりません。しかし・・・。

実行時にエラーになります(;´Д｀)

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/ab10cbe3-9f65-18c3-765c-63b4eb5fb6b6.png)


エラーメッセージ抜粋はこんな感じ。

> 'テンプレート言語関数 'if' には次の 3 つのパラメーターが必要です: 最初のパラメーターとしてテストする条件、2 番目のパラメーターとして条件が true の場合に返される値、3 番目のパラメーターとして条件が false の場合に返される値。

とっても、わかりづらいですね・・・。Falseの時は何もしなくて良い場合であったとしても、ちゃんと省略せずに記載する必要があるよ、って言ってるみたいです。こちらも、公式の Docs には記載されていません。（とはいえ、False時が省略できる、とも書いてないのでグレーと言われれば・・・）

# まとめ
- Power Automate でも IF関数で条件分岐が可能
  - アクションの分岐ではない点に注意
- IF関数の条件式は「1＜比較対象」のような式を書くとエラーになる
  - 論理比較関数などを利用しましょう
- Falseの条件は省略できない
    - 実行するまでエラーにならないので注意

なお、画面イメージは「試験的な機能」をオンにしています。記事投稿時点の状況なので、今後のVerUpで変更になる可能性があります。ご留意ください。
(´ω`)。○○（あえて記載する必要もないかな、と思いつつ）

まさか、Falseの場合が省略できないなんて思いもしませんでした。当方と同じ箇所で躓く方が1名でも減りますように・・・。

それでは、皆さま、素晴らしい Power Platform Life を！
ModuleNotFoundError: No module named 'tensorflow.contrib'が出た時の対処法

#環境
python3.7.6
MacOS Mojave

#問題
以下のエラーがでる。

```
ModuleNotFoundError: No module named 'tensorflow.contrib'
```
#考えらえる理由
tensorflowのバージョンが高いことが原因の可能性が高いです。

#対処法
以下の方法でtensorflowのダウングレードができます。

```:terminal
$pip install tensorflow==1.14
```

#その他
以下のエラーの場合も同様の原因である可能性があるので、もし出てきたら上の対処法を試してみてください。

```
AttributeError: module 'tensorflow' has no attribute 'contrib' 
AttributeError: module 'tensorflow' has no attribute 'placeholder'
AttributeError: module 'tensorflow' has no attribute 'Variable'
```

#最後に
tensorflowの仕様変わりすぎじゃないですか、、、辛い。
自分の失敗が誰かのお役に立てたら幸いです。
[タスク①の解説記事]未経験からエンジニアがキャリア初期に、任されるあろう３つのタスクを出題してみる

## 前回の記事の解説

出題したタスクはこちら

https://qiita.com/morry_48/items/7dea1145d2db8bb7f570

##　タスク①画面上に表示文言を追加する
〜商品一覧ページの商品価格に「（税込）」を追記しよう〜

上記タスクにおいて、考える手順としてはMVCフレームワークにおいて、まず処理の流れを掴むこと。ただし今回のタスクに関してはデータを取得する必要もロジックを変える必要もないため、ControllerとViewのどの部分に処理が走っているか確認し、必要な部分に処理を追加する必要がある。

手がかりとなるのはURLである。

![MVC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/afd27f5e-c7f0-c3b3-f5e4-e2b5d067325f.png)

HTTPリクエストから、Controllerのどのアクションを呼び出す(FWによってはroutingを経由する)か、決めているためURLを確認する。

商品一覧ページに関しては「products/list」というpathのためproductionControllerファイルを検索する。

開いたファイル内で「products/list」というワード検索をするとfunction indexに処理が走っていることがわかる。

![ProductControllerの画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/8063be38-0a82-51e1-aa07-4f1a07741820.png)

アノテーション部分を見ると@Template("Product/list.twig")が対象のviewファイルであることが分かる。
この辺はフレームワーク事によって異なるが、viewの文言を追記するようなタスクは
URLからController→アクション→viewファイルという流れで、見た目を表示しているファイルを特定する。


次に対象の「list.twig」を検索し、対象のファイル(eccube/src/Eccube/Resource/template/default/Product/list.twig)を開くと、まずすべきことは実際にこのファイルに処理が走っているかどうかを確認する。
プログラミング初心者にありがちなミスとして、記述方法について色々悩んでいたら、そもそもその部分に処理が通っていなかった！
みたいなことがよくあるので、なにか処理を追記する際は確実に、表示出来るタグ
```
<p>TEST</p>
```
やデバックの記述をして、まずは表示確認してから実装に入るといい。

![testの画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/368a232e-0462-48eb-8ecd-2340527c155c.png)
（↑TESTという文字が表示されているので、products/listにアクセスするとlist.twigに処理が通っていることが確認出来た）
処理が走っていることを確認出来たら次は、追記すべき箇所の確認をする

該当箇所を素早く探すテクニックとしてChromeのデベロッパーツールを使う方法を知らない方は是非覚えていただきたい。

products/litsを表示している状態で、「（税込）」を表示したい料金の箇所を確認すると

![価格画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/5464bccc-2d60-6453-aefa-9cccf3d90ae9.png)

class="price02-default"

というclassで表示していることが分かる。
この「price02-default」をlist.twigファイルの中で検索してみると
![155行目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/e53e9804-59e3-9659-0f13-fc5276cb1894.png)

155行目辺りに対象の記述があることが分かる。
このendifの外に「（税込）」を追記することでタスク①は完了

![税込の追記.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378609/ab544dfe-f884-7c9f-8ae6-ca0b7d7edc7a.png)

以上、タスク①の解説となる。

大量のコードからいかに、早く正確に該当箇所を見つけるか、実務では大切になってくる。
アプリケーションの設計を掴むことや、検索の仕方を掴むことで、これぐらいのタスクはすぐにこなせることになると思います。
tiwitter開発アカウントの作成


#自分のtwitterアカウントにログインする

普通のtwitterアカウントにログインしておく


# 開発者ページにログイン

以下のページに遷移する
https://developer.twitter.com/en/apps

遷移後のページの右上にあるCreate an appをクリックして、アプリケーションを作成を開始する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/2bcc36cd-dbde-7e2b-b03b-57124d3b1ed7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/8d9d1f34-3fe5-f6fe-8a4c-eda913ff9bf5.png)

翻訳
Twitter開発者アカウントを申請してください
既存のアプリを引き続き管理できますが、新しいアプリを作成したり、TwitterプレミアムAPIを使用したりする場合は、開発者アカウントを申請してください。

開発者プラットフォームとしての私たちの最初の責任は、ユーザーに対するものです。Twitterでの会話の健全性をサポートする場所を提供することです。 プラットフォームの誤用を防止するために、開発者向けにいくつかの新しい要件を導入しました。


#利用目的アンケートへの回答

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/f6986905-fe60-5d0d-7734-7502e21db9a7.png)

# アンケートに回答する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/431d45a8-4704-962b-3506-13e4a131b754.png)

なんでもよいでの、bot作成を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/4c7cce98-7740-6f9e-b680-7dbbc9d6e02b.png)


#アプリ情報の記載

下にスクロールすると、アプリ情報が記載の記載欄がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/aac24fa5-a587-2428-e784-ffccf6fc7a65.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/ade1087b-16f9-d248-c8fa-24a3a5c51438.png)


# アプリ内容の説明

サンプルアプリを作りたい旨の文章を簡単に入力。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/da79646f-b67c-12bc-3189-6cfc1717a49d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/296cc6de-bfab-b87d-6a2a-0d95958748fe.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/ee3f4a52-ac75-da26-d4ba-ceeea2cd9e4e.png)

聞かれているのは、以下なので、2番目の項目だけyesにして、その詳細な内容を記載する。

- Twitterデータを分析する予定ですか？
- アプリはツイート、リツイート、いいね、フォロー、ダイレクトメッセージ機能を使用しますか？
- ツイッターを表示したり、ツイッター以外のツイッターのコンテンツに関するデータを集計したりする予定はありますか？
- 製品、サービス、または分析により、Twitterのコンテンツや派生情報を政府機関が利用できるようになりますか？


# 記載情報の確認

問題がなければLooks goodをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/fe1320b6-9cba-cc37-0e8b-950ddf8f4c14.png)

# 開発者契約に同意

ページ下部のチェックボックスをオンにして、Sublit Applicationをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/a8f5929e-c67a-85c5-32db-6b0a139da647.png)


# 完了画面

登録は完了。確認用のメールが送られているので、そのメールをクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/7eb01b29-98a5-70c1-fc8f-a7a6b26a27cd.png)


#メール確認の完了画面

届いているメールでconfirmを押すと以下のページに遷移して登録が完了となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222043/f1f129de-e5c2-3cf3-eee0-c5c1943efd32.png)
QGISで地理院ベクトルタイルをダウンロードするプラグインを作成しました

## GSI-VTDownloader

https://github.com/Kanahiro/GSI-VTDownloader

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/7e9b115e-5334-1e96-5d0e-5cc6492525ca.gif)
※画像は開発中のものです

## 本プラグインについて
QGIS3.14でネイティブ対応予定となっているなど普及期にあるベクタータイルですが、日本で最も価値あるデータのひとつである国土地理院の「地理院地図」も[地理院地図Vector（仮称）提供実験](https://github.com/gsi-cyberjapan/gsimaps-vector-experiment)としてベクタータイルが利用可能となっています。
[以前紹介したVectorTilesReader](https://qiita.com/Kanahiro/items/88d15b19b1f2ed4d45c1)でもベクタータイルを読み込む事はできますが、シンプルなUIで簡単にベクターデータを取得出来るように地理院タイル専用のプラグイン「GSI-VTDownloader」を作成しました。

## 動作環境
- QGIS3.10で開発
- macOS、Windowsいずれでも動作します

## プラグインのインストール
まだQGIS公式リポジトリに登載されていないので、上記GitHubリポジトリからzipファイルをダウンロードして手動インストールしてください。

## 使い方

### メインウィンドウを開く

メニューバー->Web->GSI-VTDownloaderで開く

<img width="250" alt="img01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/3d3487f8-b353-9d14-1c92-3afabd1b22e1.png">
<img width="250" alt="img02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/87274792-aa11-83a4-5630-7809fbd77c81.png">

### 対象レイヤーの選択

表示したいSouce-layerとZoomlevelをプルダウンメニューから選択する。

<img width="250" alt="img03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/8f92e709-201f-e7f2-ae61-9f7d4e8786e0.png">

### 処理を実行
「矩形範囲で実行」か「表示領域で実行」のいずれかを選べます。

#### 矩形範囲で実行
ボタンを押下するとラバーバンドモードに切り替わるので、地図上をドラッグして領域を指定してください。

#### 表示領域で実行
ボタンを押下するとダウンロード処理が開始します。
表示領域に一部分でも含まれるタイルデータをすべてダウンロードします。

<img width="250" alt="img04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/02a75061-fb19-55ff-5904-52f3ad3d7344.png">

データのダウンロード・変換が完了次第、マップにベクターレイヤーが追加されます。

### 注意点

- 対象エリアが広範囲になるほど、または、高ズームレベルになるほど、当然ながら必要なタイル数・データ量が多くなりダウンロードにも多くの時間がかかります
[D3.js] たのしいグラフ描画 - ラベル位置を工夫した円グラフ

D3.jsを使って単純な円グラフを描画します。ラベルも付けてみます。

# 元データ

元データです。
キーと値のハッシュになっています。

```json
testdata = {
  水分: 95.4,
  タンパク質: 1.0,
  脂質: 0.1,
  炭水化物: 3.0,
  灰分: 0.5
}
```

# できあがりイメージ

グラフの右側にラベルを置き、円弧と線で結んでみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/30333857-8206-861e-cb67-e74429af018e.png)


# プログラム

プログラムの一部です。

線分は `d3.lineRadical` でひきました。
lineRadicalに渡す値は、以下のように計算しました。

```javascript
  const calcLineRadical = d => {
    const firstAngle = d.midAngle;
    const firstRadius =
      (d.xOrder * 30) / Math.abs(Math.cos(Math.PI - firstAngle));
    const xpos = radius * 1.5 - d.centroidX;
    const secondAngle =
      Math.PI + Math.atan(xpos / (firstRadius * Math.cos(firstAngle)));
    const secondRadius = Math.abs(xpos / Math.sin(secondAngle));
    const fixedSecondAngle =
      secondAngle < Math.PI ? secondAngle : secondAngle - Math.PI;

    return [
      [0, 0],
      [firstAngle, firstRadius],
      [fixedSecondAngle, secondRadius]
    ];
  };
```

プログラム全体はObservableに置いています。

https://observablehq.com/@sengokyu/d3-js-basic-pie-chart-with-clear-positioning-label