OmniAICreator/Qiita-1.07M huggingface dataset:
【Microsoft365】Vivaインサイトのライセンスの割り当てについて

# はじめに
今回は、Microsoft365の中のニッチなサービスである**Vivaインサイト**のライセンスの割り当てについてアウトプットしたいと思います。
Microsoftの公式ドキュメントを見てもよく分からなかったため、**Vivaインサイト**を業務で扱う方に参考になればと思います。

# Vivaインサイトとは？
![スクリーンショット 2022-03-05 16.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/07a7e90d-b214-c5af-d927-ea541afd5598.png)

Vivaインサイトとは、Microsoft365内のサービスの中の一つになります。
従業員一人一人の生産性とウェルビーイングの向上を支援するモジュールになります。

※ウェルビーイングとは？
幸福で肉体的、精神的、社会的すべてにおいて満たされた状態のことを指します。

# Vivaインサイトのライセンス体系
![スクリーンショット 2022-03-05 16.29.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/53774cff-224b-6b4c-c5bc-8fe6ee0edb39.png)

使用するユーザー毎にライセンスを割り振る形になります。
1ライセンス**430円**になります。

## ライセンスの割り当て例①
以下の場合は、メンバーが**9人**のため以下となります。

```bash
430円✖️9人=3870円
```

![図-イメージ図1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/27835f21-852f-1daa-3cc7-e57344e069d7.png)

## ライセンスの割り当て例②
以下の場合は、各チームのメンバーの合計が**18人**のため以下となります。

```bash
430円✖️18人=7740円
```

![図-イメージ図2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/6f070b63-59d3-b612-b89f-7d21110efc81.png)

**Insights管理者の業務分析をしたい場合は、「全体管理者」(or Insights管理者の上司にあたる人)がInsights管理者の権限を割り振る。**

# まとめ
Vivaインサイトのライセンスの割り当て方は、以下になります。

**Insights管理者(役職者)**:ライセンスの割り当てが**不要**
**メンバー**:ライセンスの割り当てが**必須**

Vivaインサイトを業務で扱う方の参考になればと思います。

AzureADでの「Insights管理者」の割り当て方は、今度アウトプットできればと思います。

# 参考
[従業員エクスペリエンスを高めるソリューション「Microsoft Viva」](https://bp-platinum.com/platinum/view/files/sps/trend/tr20210608-1/)
[Microsoft Viva インサイト](https://www.microsoft.com/ja-jp/microsoft-viva/buy-insights?activetab=pivot%3aoverviewtab)
[ライセンスの割り当ての概要](https://docs.microsoft.com/ja-jp/viva/insights/setup/assign-licenses-to-population)
React環境構築とLinter・Formatter設定

# React 環境構築と Linter・Formatter 設定
特にLinter・Formatterの設定に苦労したので、同じところで躓かないよう備忘録として残す。
## [このページを参照した](https://qiita.com/ro-komatsuna/items/271eb2c8f430e3dd99ae)

### ○ まずはじめに

- npm：Node Package を管理(manage)するコマンド
  npm は Node.js のデフォルトのパッケージ管理ツールです。npm コマンドを利用することでインターネット上のリポジトリから Node パッケージをインストールしたり、パッケージのバージョン管理をする
- npx：Node Package を実行(execute)するコマンド
  npx は Node.js のパッケージランナーツールです。バージョン 5.2 からデフォルトでインストールされるようになりました。npx コマンドを利用することで Node パッケージをより手軽に実行可能にする

### ○React をインストール

- rtd0131がプロジェクト名
- 「npx create-react-app rtd0131」を実行  
  →「npm start」で React アイコン表示

### ○Linter の設定

- 「npx eslint —init」を実行 linter として ESlint をインストール  
  → 以下の通り質問に回答した

1. How would you like to use ESLint?  
   : To check syntax, find problems, and enforce code style
2. What type of modules does your project use?  
   :JavaScript modules(import/export)
3. Which framework does your project use?  
   :React
4. Does your project use TypeScript?  
   :No
5. Where does your code run?
   :Browser
6. How would you like to define a style for your project?  
   :Use a popular style guide  
   :Airbnb
7. What format do you want your config file to be in?  
   :JSON
8. Would you like to install them now with npm?  
   :Yes

- 「npx eslint」を実行
- 「./node_modules/.bin/eslint src/App.js」を実行
- エラーが出る
- エラー解決のために「package.json」内の eslintConfig 内の記載を削除
- 「eslintrc.json」内の「rules」に”react/jsx-filename-extension”:[“error”,{“extensions”:[“.js”,”jsx”]}]を記載
- 「./node_modules/.bin/eslint —fix src/App.test.js」を実行  
  →'React' must be in scope when using JSX とエラー
- 「.eslintrc.js」の「rules」に以下を記載  
  →”react/react-in-jsx-scope”:”off”
- 再度「./node_modules/.bin/eslint —fix src/App.test.js」を実行  
  → エラーはでなかった
- 「package.json」の scripts に ESLint の実行を追加  
  →「”lint”:”eslint —ext .jsx,.js src/“」

### ○Formatter の設定

- 「npm install —save-dev —save-exact prettier」を実行  
  → エラーが出てインストールできていない(package.json にも記載されていない)
- package.json 内の「,」のつけ忘れがあった
- 「npm i -D prettier」を実行
  npm i（省略せずに記述すると npm install）はインストールの命令、-D はインストール先を devDependencies にするための指定
- 「echo {}> .prettierrc.json」で Prettier の設定ファイル  .prettierrc.json（空）を用意
- 「touch .prettierignore」で Prettier の除外ディレクトリやファイルを指定するように, .prettierignoreも追加
- ESLintを入れている関係で, ESLint と Prettier で競合するルールがあるので, ESLint 側に設定を追加
- 「npm install —save-dev eslint-config-prettier」で、eslint-config-prettier は, ESLint と Prettier で競合するルールを, ESLint 上でオフにするために使う
- .eslintrc.json  内の  extends  末尾に prettier を追加
  公式のコメント通り, Eslint の何の Plugin を使っているかによって, 必要な Prettier の記載を追加。"prettier"  は基本として入れて"prettier/react"  も入れます。
- ESLint の各種ルール（airbnb  とかの）を, prettier  系で上書きして競合ルールをオフにするため, 末尾にいれる必要がある感じです。（後に書かれたもので手前の設定を上書きます）
- プロジェクト下に「.vscode」を作成、中身は「setting.json」（VSCode の設定を記述するファイル）
- VSCode の設定：設定からワークスペースの設定をいじると自動的に.vscode 内の setting.json に設定が記載される
電気錠をHomeassistantに接続する

もう稼働させてから2年以上立っていますが
自分でも設置の仕方を忘れてしまったので
備忘録を兼ねてまとめてみます。

当初は新築する前から賃貸アパートにて
サーボモーターをNFCカードで制御させる玄関鍵システムを
構築していました、新築するのでせっかくなら納得する
オートメーションシステムにしたいといろいろ考えましたが
安いのは電池式の電気錠でnfcカード等で開閉するタイプ。
このタイプだとhomeassistantやHomeBridgeで制御できないため
100v接続の電気錠タイプにしました。
機器を選んだときはホームオートメーションに接続できるかわからないで
設置しましたその後研究し成功したものを紹介します。

<dl>
  <h1><dt>使用したもの</dt></h1>
<dd>LIXIL QDN-112 ドアホンコントローラー</dd>
  <dd>Panasonic ドアホン VL-MWH705</dd>
 <dd><a href="https://www2.panasonic.biz/scvb/a2A/opnItemDetail?item_cd=EK3850W&item_no=EK3850W&contents_view_flg=1&close_flg=1&b_cd=301&vcata_flg=1">EK3850W</a>　　</dd>
<dd><a href="https://www.amazon.co.jp/dp/B0116IZ9FK/ref=cm_sw_em_r_mt_dp_3C1DSKS2J4CXY6HPBH36?_encoding=UTF8&psc=1">5Vリレー</a>　</dd>
<dd><a href="https://www2.panasonic.biz/scvb/a2A/opnItemDetail?use_obligation=scva&contents_view_flg=1&catalog_view_flg=1&item_cd=CZ-TA2&item_no=CZ-TA2&b_cd=301&hinban_kbn=1&s_hinban_key=CZ-TA2&s_end_flg=1&vcata_flg=1">CZ-TA2</a></dd>
<dd>ラズパイ4</dd>

</dl>

玄関脇にドアホンコトーローラ、CZ-TA2
リビングにドアホン本体、操作ボタン、ラズパイ
玄関脇のコントローラー設置場所から空配管してもらっておき
のちに自分で配線しました。
リビング、玄関脇はLANケーブル1本で、
操作ボタン、CZ-TA2の接続の２カ所をまかないました。

操作ボタンはリビングから開閉確認操作させるため。
CZ-TA2はドアホン本体から開閉確認操作させるため。
リレーはHomeassistantにより外部や別スイッチ、スクリプトで
開閉確認操作するために設定しました。
最終的にドア外取っ手にNFCタグシールを一枚貼り付け
それをiPhoneで読み取り解錠という使い方にしています。

肝はリレーを挟んで
瞬時にオン・オフさせると開閉することを発見し
それをスクリプトで再生させてあとは必要なオートメーションに組み込んで
使用しています。

その後はエコキュートの自動お湯はりくらい制御させたいのですが
流石にそれはうまく行かず諦めております。
どなたかうまく行った方はお教えいただきたいと思います。

<h1><dt>接続図</dt></h1>


![Untitled Diagram-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776484/bda72bab-f7dd-858f-ad28-c0df9dfd847f.jpeg)

<h1><dt>homeassistnat</dt></h1>
<dd>rip_gpioを利用</dd>

```configuration.yaml
binary_sensor:
  - platform: rpi_gpio
#    invert_logic: true
    ports:
      21: 玄関鍵センサー
      23: PIR HC-SR501
```

<dd>script</dd>

```automations.yaml
alias: 玄関鍵
sequence:
  - entity_id: switch.genkan
    service: switch.turn_on
  - delay:
      milliseconds: 200
  - data: {}
    entity_id: switch.genkan
    service: switch.turn_off
  - data:
      message: 玄関鍵を開閉しました。
      title: おれの家
    service: notify.mobile_app_oreno_iphone
mode: single
```
![ドアホン本体、ラズパイ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/776484/e8a692d1-f281-cc53-ff5d-25531449143b.jpeg)
Windows 10 標準機能で操作の様子を動画で録画できる

ゲームバーという動画キャプチャ機能がある。
`Win + g` で起動する。

- 録画: `Win + alt + r`
- 画面キャプチャ: `Win + alt + PrtSc`

同じく標準アプリの「フォト」で編集も可能。
エビデンスを残すのに良さそうです。


## 参考

https://www.pasoble.jp/windows/10/screen-capture.html

https://www.pasoble.jp/windows/10/douga-hensyuu.html
Docker で立ち上げたCentOSでyumが使えない（使えなかった話）　（初心者用）

# 個人の備忘録（初心者）

## 経緯
### とりあえず、Dockerの学習もかねてコンテナ内でCentOSを動かしてTomcatを動かしたかった

## やったこと
#### 1.コンテナ起動
`
docker run -it centos /bin/bash
`
ローカルにcentosのイメージがなければDocker.hubからlatest(最新版)のイメージをpullしてきて
起動する。バッシュを起動してコンテナ内に入る。

#### 2.コンテナ内でsshをインストールしようとするとエラーになった

`yum -y install openssh-server`
* エラー 
`Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist`

* エラーで調べたら英語のサイトで解決策が見つかった
Google翻訳
`
CentOS Linux 8は、2021年12月31日に保守終了（EOL）に達しました。
～中略～
ミラーをvault.centos.orgに変更して、永続的にアーカイブする必要があります。
`
urlをvault.centos.orgに変更しないといけないらしい

* 以下のコマンドを実施
```
#yumのリポジトリがあるディレクトリに移動
cd /etc/yum.repos.d/
#なんか置換する
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
#なんか置換する２
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
```
### 3.yumが実行できた
:::note info
* Complete!
:::
WinMerge 非水平的比較


水平的比較とおなじくらい当たり前の機能だと思うが、初めて気が付いたので。

こんなフォルダ構成があるときに、Winmergeでold と newのフォルダ比較をする。

フォルダ old
* texta1.txt
* texta2.txt
* texta3.txt

フォルダ new
* texta1.txt
* texta2.txt
* texta3.txt

こんな比較結果が

![diffB30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/5b0165cd-cc78-ede3-674f-b7070a439ae1.png)


ハイライトされているところをダブルクリックすると比較（水平比較）


![diffB44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/29b837e6-89b2-30d1-a1f0-1b842203f9a1.png)


全行ハイライトして右クリック


![diffB59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/0faf344b-7d9a-fe10-6807-100b6d3e59b9.png)


非水平的に比較する＞非水平的に比較する。

次のダイアログが開く 。ん？

![diffB76.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/f968a4b3-4ac0-4999-87f4-79a35066a44a.png)


oldフォルダと、newフォルダの6個のファイルから3個まで選択して、比較ができる。

たとえば、左側3個選ぶと、

![diffB91.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/7ea2d99a-ab87-ca19-ace1-70a1ab51eef7.png)


Oldフォルダの3ファイルを比較することができる

![diffB98.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/adc90782-8666-cedc-530b-fa2e2c7ca458.png)


だたし、4行以上選択したらだめ
Oracle Linux 8にDockerCEをAnsibleでセットアップする

# はじめに

Docker開発環境をOracle Linuxで整えたかった。手順は[こちら](https://techviewleo.com/install-docker-ce-on-oracle-linux/)の記事で紹介されていたが、せっかくなのでAnsibleでやってみることにした。

# 環境

インフラ：Oracle Cloud Infrastructure
Ansible実行インスタンス：Oracle-Linux-Cloud-Developer-8.4-2021.08.27
セットアップするインスタンス：Oracle-Linux-8.4-2021.07.27

# 事前準備

- 上記２つのインスタンスを作成していること。
- Ansible実行インスタンスにセットアップするインスタンスのSSH秘密鍵をコピーしていること。
- SSH秘密鍵のパーミッションを600に変更していること。

# 手順

1. Ansible実行インスタンスにopcユーザーでログイン

1. 作業用ディレクトリ作成

   ```bash:
   mkdir ansible-exec
   cd ansible-exec
   ```

1. 次の内容でinventory.iniを作成

   ```ini:inventory.ini
   [dev_server]
   #セットアップするインスタンスのパブリックIP
   XXX.XXX.XXX.XXX
   
   [dev_server:vars]
   ansible_user=opc
   #セットアップするインスタンスのSSH秘密鍵のフルパス
   ansible_ssh_private_key_file=/home/opc/.ssh/XXXXXXX.key
   ```

1. 次の内容でdev_playbook.ymlを作成

   ```yml:dev_playbook.yml
   ---
   - hosts: dev_server
     user: opc
     become: yes
     tasks:

     - name: set timezone
       timezone:
         name: Asia/Tokyo

     - name: add yum repo
       command:
         cmd: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
         creates: /etc/yum.repos.d/docker-ce.repo

     - name: install docker
       dnf:
         name: ['docker-ce','docker-ce-cli','containerd.io']
         state: latest

     - name: docker service start/enable
       systemd:
         name: docker
         state: started
         enabled: yes

     - name: add opc user to the docker group
       user:
         name: opc
         groups: docker
         append: yes

     - name: download docker-compose
       become: no
       shell: creates=/home/opc/docker-compose-linux-x86_64 curl -s https://api.github.com/repos/docker/compose/releases/latest|grep browser_download_url|grep docker-compose-linux-x86_64|cut -d '"' -f 4|wget -qi -
       args:
         warn: false

     - name: change parm
       file:
         path: /home/opc/docker-compose-linux-x86_64
         mode: 0775

     - name: copy binary file
       shell: creates=/usr/local/bin/docker-compose cp -a /home/opc/docker-compose-linux-x86_64 /usr/local/bin/docker-compose
   ```

   - yumのrepository追加はモジュールが存在するがそれを使うとなぜかうまくいかなかったのでcommandで実行している
   - commandやshellのcreatesはこのファイルが存在しているときはスキップしてくれる

1. 次のコマンドで実行

   ```bash:
   ansible-playbook -i inventory.ini dev_playbook.yml
   ```

1. 設定内容について、インスタンスに接続し確かめる

   ```bash:
   ssh -i /home/opc/.ssh/XXXXXXX.key opc@XXX.XXX.XXX.XXX
   newgrp docker
   docker pull hello-world
   docker run -rm --name hello-world docker.io/library/hello-world:latest #dockerインストール・起動状態の正常性確認
   docker-compose version #docker composeのインストール確認
   ```

# 参考

インストール手順はこちらの記事そのままです。

- [Installing Docker CE on Oracle Linux 8](https://techviewleo.com/install-docker-ce-on-oracle-linux/)
- [Installing Docker Compose on Oracle Linux 8](https://techviewleo.com/install-docker-compose-on-oracle-linux/)
Eclipseでローカル変数の参照、宣言箇所を確認する

ひとの書いたコード読んでいて、ローカル変数多くてわからない！たすけてEclipseもん！ってなった。

対象の変数にカーソルを合わせた状態で
* 宣言箇所 `Ctrl+G`
* 参照箇所  `Ctrl+Shift+G`

を行うことでビューが開いて結果が表示されます。

さらに「次へ(`Ctrl+,`)」「前へ(`Ctrl+.`)」で移動もできます。
決まったら`Enter`でそこにジャンプ。

なおローカル変数だけでなく、他クラス含めたメンバーなどにも使えるようす。
そういうときは`Ctrl+Alt+H`使っちゃうけどどう違うんだろう。
[python3]　コンソールをクリアする

今回はPythonでコンソールをクリアする方法を説明します。
```md
環境
・Python3.10 64bit
・Windows11
```
# 基本的な書き方
```python
import os
os.system('cls')
```
[import os]の部分でosモジュールをインポートしています。
[os.system('cls')]の部分でコンソールをクリアしています。
<strong>
注意
Linux、Macの場合は[os.system('cls')]を[os.system('clear')]に置き換えてください。
</strong>
# コード例
最後に、コード例を紹介します。
```python
import os
import time

for i in range(10):
    print(i)
    time.sleep(1)
    os.system('cls')
```
上のコードは、コンソールのクリアを利用した１から１０まで数えてくれるプログラムです。

>(できればLGTMお願いします。)
Windowsにおける仮想デスクトップのTips

自分用にメモ。複数タスクの管理に非常に便利。

ctrl + Windows + D　 : 仮想デスクトップの作成

ctrl + Windows + ←→ : 仮想デスクトップの移動

ctrl + Windows + F4　 : 仮想デスクトップの削除
Rust環境構築: Visual C++ Build Toolsを使わずにCygwinのC++環境を使う

通常, WindowsにRustをインストールすると, Visual C++ Build Toolsのインストールを求められる. 
C++環境をCygwinで既に持っているユーザーは, Visual C++ Build Toolsをインストールしたくない. 
ここではその回避方法を示す. 

# 前提
`gcc-core`, `gcc-g++`, `gdb`, `make`は既にCygwinで導入済みとする. 
私のCygwinインストールメモは[こちら](https://qiita.com/birdwatcher/items/891ebe41a5e80d080171#c%E9%96%A2%E9%80%A3). 

# Rustの環境構築
## ダウンロード
通常のインストーラーの場所ではなく, [こちら](https://forge.rust-lang.org/infra/other-installation-methods.html)から`x86_64-pc-windows-gnu`の`rustup-init.exe`をダウンロードする. 
![installer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/12d85ad8-af5a-9c62-6d25-de6cba5a3a76.png)

## インストール
インストーラーの実行
![install1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/fa319a6e-1a47-ed97-ffca-3a3193452c11.png)
C++のビルドツールが必要と言われますが, 既にCygwinで持っているためそのまま進めます. 

インストールオプションが出るため, 修正する必要があります. 
(インストーラーでgnuを選んだのに**デフォルトでmsvcになっているという罠**があります)
![install2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/9290b56c-9c62-711e-35f4-2087afefe374.png)
2のCustomize installationを選んで, 
>Default host triple? [x86_64-pc-windows-msvc]

と聞かれるので, `x86_64-pc-windows-gnu`と入力します. 
その他の設定はそのままでOKです. 

## 実行
![run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294661/0cf163ed-7622-6589-4dd6-e3cffb6e8fea.png)

1. `cargo new helloworld`
2. `cd helloworld`
3. `cargo run`

で動作確認します. 
無事, 動かすことができました.
yarnでbootstrap5をインストールする。

yarnでbootstrapをインストールする機会があったので、記録がてらに投稿致します。

CDNでも用意されています。

```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
```

ビルドツールにて```$ yarn add bootstrap```でインストール可能。
```
/node_modules
 └bootstrap/scss/bootstrap/scss
/src/scss/main.scss
```
こういったディレクトリ構造の場合scss配下にあるscssファイルで```node_modules```の```bootstrap.scss```を```@import```してあげれば直ぐにbootstrapが使えるようになります。
```scss :main.scss
@import "../../node_modules/bootstrap/scss/bootstrap.scss";
```

以上です。
Harbor の Https 設定

# Harbor Server の https 設定
Harbor は http でも設定できますが、helm などのコンポーネントと連携するならば、https で建てた方が便利です。
ラボ環境なので、CA がなくて、Self Signed Cert を使います。
設定方法は [Harbor docs](https://goharbor.io/docs/1.10/install-config/configure-https/) を参照します。

まずは Harbor Server で CA 証明書を作成します。

```bash
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
 -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
 -key ca.key \
 -out ca.crt
```

そして、Server 用の key を作成し、Sign Request を作成します。

```bash
openssl genrsa -out yourdomain.com.key 4096
openssl req -sha512 -new \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
    -key yourdomain.com.key \
    -out yourdomain.com.csr
```

Harbor Https Host の証明書は x509 v3 を準拠する必要があるので、x509 v3 extension file を作成します。
DNS.1/.2/.3 に Subject Alternative Name (SAN) を入れます。

```bash
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=yourdomain.com
DNS.2=yourdomain
DNS.3=hostname
EOF
```

x509 v3 extension file と ca 証明書を持って、server の証明書をサインします。

```bash
openssl x509 -req -sha512 -days 3650 \
    -extfile v3.ext \
    -CA ca.crt -CAkey ca.key -CAcreateserial \
    -in yourdomain.com.csr \
    -out yourdomain.com.crt
```

作られた証明書とkey を証明書フォルダー（harbor.yml に記載するパス）に移動します。

```bash
cp yourdomain.com.crt /data/cert/
cp yourdomain.com.key /data/cert/
```

Docker 用として、証明書を PEM フォーマットに変換し、/etc/docker/certs.d/yourdomain.com に入れます。
もし/etc/docker/certs.d/yourdomain.com が存在しないなら、手動で作成します。

```bash
openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert
cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
cp ca.crt /etc/docker/certs.d/yourdomain.com/
```

最後に、docker と harbor を再起動し、設定を反映させます。

```bash
systemctl restart docker

# harbor の再起動には harbor.yml および docker-compose.yml が必要なので、harbor/ フォルダに移動してから実施
./prepare
docker-compose down -v
docker-compose up -d
```

# Harbor Client 側の設定

Harbor Server 側が設定完了しましたが、Self-signed Cert なので、Client 側にも CA 証明書をいれなければいけないです。
Client にアクセスし、/etc/docker/certs.d/yourdomain.com/ を作成し、ca.crt を server からコピーしてきます。

# Harbor の Https Server にアクセスしてみる

設定後、Https をアクセスしてみます

```bash
curl -k https://yourdomain.com

docker login https://yourdomain.com
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /home/administrator/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
```
Chromeの開発者ツールで画面サイズを変更すると、Swiperがスライドできなくバグについて

### この記事に書いてあること

JavaScriptのスライダープラグインであるSwiperのバグについて
SP時にスワイプできなくなる事象が発生したのでメモ書き

https://swiperjs.com/

### 具体的には

・Chromeの開発者ツールでブラウザを開く
・まずPCでロードする
・その開発者ツールのままでSPに画面サイズ変更する
・SPでスワイプできない

### 発生条件
IE11対応しているv4.5.1くらいを使用する場合に発生するようです


### issueも既にありました。

https://github.com/nolimits4web/swiper/issues/3229

### 対応方法
バージョンを最新のものにしましょう（グッバイIE）
Rubyでargvを使う方法

## argvとは
``argv``とは、argument vectorの略で「引数の配列」を意味する。
コマンドライン(ターミナル)からスクリプトを実行する時に、スクリプトに引数を渡すために利用する。

``argv``は、コマンドライン引数を取得するための仕組みとしてRubyだけではなくて、使い方はそれぞれの言語で違うが、C言語やPython、その他様々な言語にも存在する。

## argvの使い方
``ruby``では、``ARGV``という配列オブジェクトから、Rubyスクリプト実行時に渡された引数が参照できる。
スクリプト実行時に以下のように引数を渡すことで使用できる。
```
$ ruby スクリプトファイル名 1番目の引数 2番目の引数 3番目の引数...
```
この場合は、``ARGV[0]``には1番目の引数が、``ARGV[2]``には3番目の引数が設定されている。

## 実際の使用例
以下のようなファイルがあったとする。

```hoge.rb
p "Hello, #{ARGV[0]}"
```
この「hoge.rb」に引数を渡して実行してみる。
```.ターミナル
$ ruby hoge.rb World!

=> "Hello, World!"
```

違う例も見てみる。
今度は2つの引数を足し算して出力するスクリプトを作成し実行してみる。
```hogehoge.rb
p ARGV[0] + ARGV[1]
```
```
$ ruby hogehoge.rb 1 2

=> "12"
```
出力結果は “12” となった。
引数として渡した``1``と``2``が足し算されずにくっついた。

この結果から分かるように、**``argv``では渡された引数は全て文字列になる。**

引数の文字列を``to_iメソッド``を使って整数に変換するよう修正。
```hogehoge.rb
p ARGV[0].to_i + ARGV[1].to_i
```
```
$ ruby hogehoge.rb 1 2

=> "3"
```

## 参考記事
[Rubyでargvを使う方法【初心者向け】](https://techacademy.jp/magazine/18730)
VScode LaravelのBladeファイルだけtab押下時のスペースを半角スペース2個に設定する

## 概要

- VScodeにてLaravelのBladeファイルだけtab押下時のスペースを半角スペース2個に設定する

## 方法

1. VScodeを開く
1. 「cmd」 + 「Shift」 + 「p」を同時に押下する。
1. 開いたコマンド入力ウインドウに下記を入力してEnterを押下する。

    ```
    Preferences: Configure language specific settings
    ```

1. 「Blade」をクリックする。

    ![settings_json_—_line_crm_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7d4d2249-9fdc-c848-6645-6ce7fdb33fe2.png)

1. settings.jsonが自動で開き、Blade用の設定記載用フィールドが用意されているので下記を入力する。

    ```settings.json
    "editor.tabSize": 2
    ```

1. 入力後は下記の様になる。

    ![settings_json_—_line_crm_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/186622dc-bb03-f8ce-e289-8f66e070ba39.png)

1. 保存などはしなくてもすぐに設定が反映される。
SRE とは

## 勉強前イメージ

概念とかそんな感じ？

## 調査

### SRE とは

Site Reliability Engineering の略で、Googleが提唱するシステム運用の方法論です。
昨今のソフトウェア開発は以前よりスピード感や柔軟性が求められています。
その為、以前のウォーターフォール型の開発では開発が難しいこともありSREなどが提唱されました。
SREとは開発スピードや柔軟性だけでなく、サービスの品質を向上するための開発手法になります。

SREとはシステム管理や運用に対するもので、サービスの信頼性を向上させるため
システムの自動化を行い、作業を減らすことを重視しています。

### SREの指標

- [SLI](https://qiita.com/miyuki_samitani/items/6ae165657b1047fd36ea)

Service Level Indicator の略で、サービスの品質を測る指標で
ユーザに提供するサービスから計測される値を定義したものになります。

- [SLO](https://qiita.com/miyuki_samitani/items/6ae165657b1047fd36ea)

Service Level Objective の略で、サービスレベルの目標値になります。
SLIで測定されるサービスレベルの目標値がSLOになります。

- [SLA](https://qiita.com/miyuki_samitani/items/6ae165657b1047fd36ea)

Service Level Agreement の略で、サービスレベルについてお客様との合意したものになります。

### SREとDevOpsとの違い

開発と運用を組み合わせたものとして、 [DevOps](https://qiita.com/miyuki_samitani/items/aa997d59074872a71859) と同様に捉えられるかと思いますが
以下のような違いがあります。

- DevOps → 開発チームと運用チームを1つにし、協力し合うことで `迅速で柔軟に開発を進め` 、サービスの提供を行う抽象的な概念
- SRE → インフラ整備や自動化を通じて `サービスの信頼性を高める`

## 勉強後イメージ

要するに、サービスの信頼性を高めるにはどう開発していったらいいか ってことなのかね？
よく聞くけど正直ちゃんとわかってなかった部分があったので調べられてよかった。

## 参考

- [トレンドとなっているSRE（Site Reliability Engineering）とは？従来のDevOpsと何が違う？](https://www.resm.jp/faq/answer42/)
- [SREとは？ DevOpsとの違い](https://pfs.nifcloud.com/navi/tech/sre.htm)
Heroku の postdeploy が動作しない原因

# 一言でわかる結論
**[`postdeploy` はアプリの作成後に一度だけ実行される！](https://devcenter.heroku.com/ja/articles/github-integration-review-apps#:~:text=postdeploy%20%E3%81%AF%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E4%BD%9C%E6%88%90%E5%BE%8C%E3%81%AB%E4%B8%80%E5%BA%A6%E3%81%A0%E3%81%91%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%82%8B)**

これですべてを理解した場合は、これより先は読まなくても大丈夫。




# 原因と理由
Heroku では、リポジトリルートに `app.json` というファイルを作成し、その中にいろいろ記述することで Heroku 上でのデプロイ方法を指定することができる。

その中に `postdeploy` というものがある。これを利用することにより、Heroku 上でアプリがデプロイされたときに任意のコマンドを実行することができる。

```json:app.json
{
  // 省略
  "scripts": {
    "postdeploy": "RAILS_ENV=production bundle exec rails db:create && RAILS_ENV=production bundle exec rails db:migrate && RAILS_ENV=production bundle exec rails assets:precompile"
  }
  // 省略
}
```

上記の例では、Rails アプリケーションで、データベースを新規作成し、マイグレーションを実行し、アセットのプリコンパイルを実行している。

このようにアプリケーションのデプロイ後に任意のコマンドを実行できる便利な仕組みなのだが、いくら `app.json` を書き直しても動作しない。

その理由は、**`postdeploy` はアプリの作成後に一度だけしか実行されないからである**。つまり、一度デプロイされてから `app.json` を書き換えても、その内容は反映されないということ。

変更を反映させたい場合は、アプリを作成し直す必要がある。Review apps を利用している場合は、[一度 PR をクローズして再オープンすることでアプリを再作成することができる](https://devcenter.heroku.com/ja/articles/github-integration-review-apps#:~:text=%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%20postdeploy%E2%80%8B%20%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%86%8D%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%80%81%E3%83%97%E3%83%AB%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%BA%E3%81%97%E3%81%A6%E5%86%8D%E5%BA%A6%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%81%99%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%E3%81%9D%E3%81%86%E3%81%99%E3%82%8B%E3%81%A8%E3%80%81Heroku%20%E3%81%AB%E3%82%88%E3%81%A3%E3%81%A6%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%82%A2%E3%83%97%E3%83%AA%E3%81%8C%E7%A0%B4%E6%A3%84%E3%81%95%E3%82%8C%E3%80%81%E5%86%8D%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)。




# 余談
ちなみに、`https://dashboard.heroku.com/apps/<APP_NAME>/app-json` にアクセスすると、`Output` というセクションに JSON ファイルがある。

この画面にある JSON は、`app.json` に似て非なるものであるようだ。

| Heroku 画面の `Output` |
| --- |
| ![](https://raw.githubusercontent.com/noraworld/developers-blog-media-ja/master/heroku-postdeploy-runs-only-once/Screen%20Shot%202022-03-10%20at%2020.11.55.png) |

| `app.json` |
| --- |
| ![](https://raw.githubusercontent.com/noraworld/developers-blog-media-ja/master/heroku-postdeploy-runs-only-once/Screen%20Shot%202022-03-10%20at%2020.13.06.png) |

この画面上の JSON の `"scripts"` の中身が空 (`{}`) になっていたとしても、`app.json` で正しく記述されており、かつ、アプリの初回作成時であれば、`"scripts"` (`"postdeploy"`) の中身が正しく実行されるはずだ。







# 参考サイト
* [レビューアプリ (新しいバージョン)](https://devcenter.heroku.com/ja/articles/github-integration-review-apps)
laravel9で、AzureAppServiceだとasset関数でhttpsから取得出来ない。

# 内容
laravel9で、AzureAppServiceだとasset関数でhttpsから取得出来ない。

# 対策
```app\Http\Middleware\TrustProxies.php
class TrustProxies extends Middleware
{
   protected $proxies = '*';
}
```

# 参考
https://qiita.com/yamato_sorariku/items/8f3f481d88e807793ad5
Kotlin KoansでKotlin入門　第６回：Nullable types

# はじめに
公式の問題集[「Kotlin Koans」](https://play.kotlinlang.org/koans/overview)を解きながらKotlinを学習します。

過去記事はこちら
- [第０回：Kotlin Koansについて](https://qiita.com/kosuke1/items/41d192af63485bfc8cb8)
- [第１回：Simple Functions](https://qiita.com/kosuke1/items/5862a3ece96082a62e67)
- [第２回：Named arguments](https://qiita.com/kosuke1/items/2af11262852ee41b5da7)
- [第３回：Default arguments](https://qiita.com/kosuke1/items/16cb8ac780df58dc8054)
- [第４回：Triple-quoted strings](https://qiita.com/kosuke1/items/52cfeed2c49b0252d40e)
- [第５回：String templates](https://qiita.com/kosuke1/items/0221bbbc5bc70847be6f)

# 問題
[Nullable types](https://play.kotlinlang.org/koans/Introduction/Nullable%20types/Task.kt)

Kotlinの[NULLセーフティとセーフコール](https://kotlinlang.org/docs/null-safety.html)について学び、以下のJavaコードを1つのif式しか持たないように書き直します。

```Java
public void sendMessageToClient(
    @Nullable Client client,
    @Nullable String message,
    @NotNull Mailer mailer
) {
    if (client == null || message == null) return;

    PersonalInfo personalInfo = client.getPersonalInfo();
    if (personalInfo == null) return;

    String email = personalInfo.getEmail();
    if (email == null) return;

    mailer.sendMessage(email, message);
}
```


修正前のコードです。
```Kotlin
fun sendMessageToClient(
        client: Client?, message: String?, mailer: Mailer
) {
    TODO()
}

class Client(val personalInfo: PersonalInfo?)
class PersonalInfo(val email: String?)
interface Mailer {
    fun sendMessage(email: String, message: String)
}
```

# 問題のポイント
Kotlinではnullを許容する型としない型が存在します。
```Kotlin
  // nullを許容しない型宣言(Non-Null)
  var non_null: String = ""

  // nullを許容する型宣言(Nullable)
  var nullable: String? = null
```

nullableな変数にアクセスする場合、?つなぎでアクセスします。?なしではコンパイルエラーになります。
JavaではNullPointerExceptionを人力で防いでいたのをKotlinではコンパイラーが教えてくれる感じですね。
実行時にnullでない時に、?つなぎの右側がそのまま実行され、nullの時は何もしない動作になります。
```Kotlin
val length = nullable?.length
```

# 解答例
```Kotlin
fun sendMessageToClient(
        client: Client?, message: String?, mailer: Mailer
) {
    val email = client?.personalInfo?.email
    if (email != null && message != null) { 
    	mailer.sendMessage(email, message)
    }
}

class Client(val personalInfo: PersonalInfo?)
class PersonalInfo(val email: String?)
interface Mailer {
    fun sendMessage(email: String, message: String)
}
```

だんだん記述量が多くなるにつれて、コード補完してくれないブラウザ上でコードを書くのがつらくなってきました😅
TailwindCSS系のdaisyUI CSSコンポーネントライブラリを選定するために調査したデータ

人気度はGithubスター数が半年でどのくらい伸びたかを調査しました。
項目「増加％」でソート

|名前|2021年8月26日|調査時点での最終更新|2022年3月10日|調査時点での最終更新|増加％ |
|:----|:----|:----|:----|:----|:----|
|[daisyUI](https://daisyui.com/)|4.5k stars|2021年8月22日|9.3k stars|2022年3月10日|51.61%|
|[Headless UI](https://headlessui.dev/)|10.5k stars|2021年7月29日|13.7k stars |2022年3月10日|23.36%|
|[Chakra UI](https://chakra-ui.com/)|20.1k stars|2021年8月9日|24.5k stars |2022年3月9日|17.96%|
|[Material UI](https://mui.com/)|70.5k stars|2021年7月30日|76.3k stars |2022年3月10日|7.60%|
|[Ant Design](https://ant.design/)|73.9k stars|2021年8月16日|78.6k stars |2022年3月10日|5.98%|
|[Grommet](https://v2.grommet.io/)|7.4k stars|2021年7月28日|7.8k stars |2022年3月10日|5.13%|
|Rebass|7.4k stars|2019年8月28日|7.7k stars |2021年8月4日|3.90%|
|React-Bootstrap|19.8k stars|2021年6月4日|20.5k stars |2022年3月4日|3.41%|
|MUI|4.4k stars|2020年6月2日|4.5k stars |2020年6月2日|2.22%|
|reactstrap|10.1k stars|2021年1月20日|10.3k stars |2022年3月4日|1.94%|
|React Toolbox|8.7k stars|2018年6月2日|8.7k stars |2019年5月30日|0.00%|
|Belle|2.5k stars|2017年10月10日|2.5k stars |2018年6月3日|0.00%|

***※daisyUIはTailwindCSSをベースにしたコンポーネント集です。***
Djangoテンプレートでのcolor値の表示方法について

Djangoテンプレートでのcolor値をテキストではなく、カラーピッカーで表示したい場合、formのクラスで対象のfieldにwidgets = {'sample_color': TextInput(attrs={'type': 'color'})}を設定すると、テンプレートでは、カラーの値ではなく、カラーピッカーで表示されます。
これをしなければ、modelでカラー値は文字列で表示されます。

```model.py
class SampleData(models.Model):
    ＃値は文字列で格納
    fore_color = models.CharField(max_length=7,null="true") 
```

```forms.py
class SampleDataForm(ModelForm):
  class Meta:
    model = RSC_SCADULE_ITEM
    fields = ('sample_color')
    #下記を追加すすると、テンプレートでカラーパレットで表示される。
    widgets = {
               'sample_color': TextInput(attrs={'type': 'color'})
              }
```

カラーの入力項目がカラーピッカーで表示される。
```sample.html
～　略　～
{{ form.as_p }}
{% csrf_token %}
<div class="form-group row">
  <div class="offset-md-3 col-md-9">
     <button type="submit" class="btn btn-primary">送信</button>
  </div>
</div>
```
運用・保守プロジェクトから開発プロジェクトへの道のり①

現在、開発のプロジェクトに参画している私がどのようにして開発のプロジェクトに参画することが出来たのか紹介させていただきます。 

実務未経験の駆け出しエンジニアさんにとって、少しでも参考になれば嬉しいです。 
***
 

## どうしてエンジニアになったのか 
 

まず初めに簡単な自己紹介をさせていただきます。私は高校を卒業後、ITとは全く関係がない金属の加工をする工場に就職しました。その頃の私は「IT系の仕事は頭の悪い私にはできない」と決めつけていました。そんな私がITに興味を持ったきっかけは、工場勤務4年目の時に副業目的で始めたブログです。 

なぜブログがきっかけでITに興味を持ったかと言うと、当時ワードプレスというCMSでブログサイトを立ち上げ、その時に知ったのがHTMLとCSSです。普段私たちが見ているWEBサイトの裏側はこんなにもたくさんのコードが書いてあり、それの組み合わせによってWEBサイトが出来上がる事を知り、自分でコードを書き自分のWEBサイトをカスタマイズすることが、とても楽しく好きでした。
「もしかしたら自分はIT系の仕事が向いているのかも！」と思いました。
そこからは勢いで転職しました（笑） 
 

## 最初のプロジェクトについて 


初めて参画したプロジェクトは、公衆無線LANシステムの運用・保守でした。最初から開発の現場には行けると思っていなかったので、「この現場で働きつつ修行するぞ！」というのが当初の私の思いでした。 

ヘルプデスクのような仕事は今までしたことがなかったので、電話応対などの業務で5か月程度は余裕もなく辛かったのをよく覚えています。 
そこから業務に慣れて余裕ができ、休日や空いた時間で少しずつプログラミングの自己学習を行うようにしました。 

私はフロントエンドに興味があったので、HTML、CSSを習得した次はJavaScriptでスライドショーや簡単なアニメーションを作れるようになりたいと思い、 JavaScriptの学習を始めました。 
 

### 初めての挫折 


初めて JavaScriptのコードを見たときの感想は「なんだこれ、、、全然わからん。」と自分には理解できるのか？と不安に駆られました。おそらくこの辺で初めての挫折をしたと思います。 
 
工場の作業員から転職して私はプログラミングの参考書やネットの情報を頼りに、ずっと独学でやってきました。正直教えてくれる先生がいないのはとても辛いです。 

- やりたいことはあるけど、どうやったら実装できるのかわからない 
- どうあがいてもエラーが多発する 
- そもそも勉強することが多すぎて何を勉強すればいいかわからない 

独学だと何が正解で何が不正解かもわからないんですよね。。。 

ここで数週間プログラミング学習をしない休憩期間を設けました。
nodeのバージョンdefaultめんどくさい

# nodeのバージョンめんどくさい問題

Localの開発環境の nodeのバージョンめんどい
Local開発環境でPCを再起動するなどでdefault設定のバージョンで起動する。
nvmのデフォルトのバージョンの設定方法をサクっとぐぐると
```bash
nvm alias default v*.*.*
```
みたいなのが出てくる
この指定方法でデフォルトを設定をしてるとマイナーアップデートするたびにデフォルト設定を変更するの面倒
```bash
$ nvm ls
->     v14.18.3
       v14.19.0
        v16.8.0
       v16.13.2
       v16.14.0
default -> v14.18.3   # <- バージョンで指定していると、マイナーアップデートしても デフォルトのバージョンが固定されたまま
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.14.0) (default)
stable -> 16.14 (-> v16.14.0) (default)
lts/* -> lts/gallium (-> v16.14.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.10 (-> N/A)
lts/fermium -> v14.19.0 (-> N/A)
lts/gallium -> v16.14.0
```


nvmでdefault設定する

```bash
$ nvm alias default lts/fermium
default -> lts/fermium (-> v14.19.0)
```
こうしておけば、良い


例えば14のマイナーアップしてもdefaultの設定をいちいち変更することがない
```bash
$ nvm install lts/fermium
Downloading and installing node v14.19.0...
Local cache found: ${NVM_DIR}/.cache/bin/node-v14.19.0-linux-x64/node-v14.19.0-linux-x64.tar.xz
Checksums match! Using existing downloaded archive ${NVM_DIR}/.cache/bin/node-v14.19.0-linux-x64/node-v14.19.0-linux-x64.tar.xz
Now using node v14.19.0 (npm v6.14.16)
```

確認
```bash
$ nvm ls
       v14.18.3
->     v14.19.0
        v16.8.0
       v16.13.2
       v16.14.0
default -> lts/fermium (-> v14.19.0)
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v16.14.0) (default)
stable -> 16.14 (-> v16.14.0) (default)
lts/* -> lts/gallium (-> v16.14.0)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.10 (-> N/A)
lts/fermium -> v14.19.0
lts/gallium -> v16.14.0
```
streamlitで作成したアプリをデプロイするまで

Streamlitでアプリを作成し、Herokuにデプロイする方法を備忘録も兼ねて記載する。

gitのダウンロードとHrokuCLIをPCにダウンロードしておく

手元のターミナルにて
```
heroku login
```
を入力してHerokuにログインする。
次に

```
heroku create -a アプリケーションの名前
```
を入力する。
名前の重複などがあると作成ができない。
また名前はアルファベット小文字と数字、ハイフンくらいしか使えない（はず...）
次にGitの初期化を行う。

```
git init
```

次にリモートレポジトリに登録する。
```
git remote add heroku https://git.heroku.com/アプリケーションの名前.git
```

```
git add .
```

コミットメッセージを追加
```
git commit -m 'メモを適当に'
```

heroku側にpushする。
```
git push heroku master
```

以上でアプリをデプロイすることができます。
以降アプリを変更した後は
```
git add
```

```
git commit -m 'メモを適当に'
```

```
git push heroku master
```

で変更することができます。
医学生がAtCoderで青色になった話【色変記事】

はじめまして、rinmaoと申します。

先日AtCoderにて青色になり、そこそこ安全域に入ったので、初の色変記事を書かせていただきました。
青色を目指す人に限らず幅広い方を対象に書いたつもりなので、誰かの参考になれば幸いです。

![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1211836/704d7e3d-d6be-b58f-9420-a11b261b5a8d.png)


# 自己紹介
* 医学部生
* プログラミング歴は約5年
* 競プロではPythonを使用

当然と言えば当然ですが、やはり競プロをやっている方は理工学系の人が多いので、医学系の人でもプレイヤーが増えれば良いなと密かに思っています。

# 青色になるまで
## 灰〜緑
運が良かったこともあり、割と短期間で緑まで到達しました。
ただ、2019年当時は今よりもレートを上げやすかったと思います。
実際自分は緑に上がった当時、累積和や二分探索やDPといった初歩的なアルゴリズムすら全く知らなかったです。（今なら茶色にいけるかどうかってレベルでしょうか）

緑になってからは、競プロに関するいろんな記事を読み漁りました。
なによりアルゴリズムに関する知識がゼロだったので、出会うもの全てが新鮮で面白かったです。
この頃蟻本を購入しました。（途中で諦めて、今でも積読してしまっています）

## 水色
この期間が非常に長かったです。
実に1年以上停滞していました。
なんとなく実力が飽和してしまった感じがしました。
今考えるとただ単純に精進不足だったと思います。

やったりやらなかったりする時期をいろいろ経て、何とかレートも上がってきました。
苦手なアルゴリズムが無くなるよう、なるべく幅広くやっていきました。
後述もしていますが、よくするミスなどは書き出して再発が無いよう心がけました。
1500を上回ってからは、青色を仕留めようと、最近のABCの青色問題を埋め切ることに専念しました。

その成果もあってか、なんとか入青することができました。


# Ratingを上げるために
## 精進
天才でもない限り、レートを上げるにはひたすら精進するしかないでしょう。

自分が精進に使った問題は
* ABC
* 典型90問

がメインです。
ABCは126回以降の青色以下を埋めました。
典型90問は★6までやりましたが、入青という点ではオーバーワークだったかもしれません。
1回目で分からなかった問題はメモっておいて、たまに解き直すようにしました。

ARCはちらほらって感じですかね。
蟻本は初期のころに半分くらいやりました。
AtCoder以外のコンテストサイトも多くあると思いますが、自分はめんどくさく全くやってないです。

自分の色より2個以上上の難易度の問題を解きまくってる人などをたまに見かけますが、個人的には遠回りな気がします。
それよりも自分にあったレベルの問題を早解きできる方が良いと思います。
もちろん高難易度の問題を一発解ければレート一気に上がると思いますが、分散が大きく安定しにくいのではないでしょうか。
恥ずかしながら、自分はいまだに黄色難易度のAC数は10問もありません。

## コンテストへの参加
ABCには出来るだけ参加するようにしました。
「最近は精進してないから参加しない」はなるべくしないようにしました。

ARCは結構避けていました。
クセがある問題が多く、問題自体は面白くて好きなのですが、なんせパフォーマンスが安定しません。
正直青になった今でも安定する気が全くしません。
賛否両論あると思いますが、水・青色になるまでARCは全く出ないのもありじゃないでしょうか。

AGCはおそらく1,2回しか出たことがないと思います。

## コンテスト後の反省
コンテストの結果が芳しくなかった時、その原因を追求することは非常に重要です。

原因が、凡ミス・時間配分ミス・誤提出・通信エラーといったようなものであっても、それを言い訳にするのはしないようにしています。
そういうのも全て込みで実力だと思うので。
どんなミスであれ、一度起こったのであれば、再度起こりうるので、その対策に集中すべきです。

例えば、「D問題で泥沼にハマってしまいE問題を見れなかったけど、コンテスト後にE問題をみたら瞬殺できた。」というようなことは往々にしてあります。
そう言うこと自体は問題はないですが、この状態でE問題を解ける実力を持っているからOKと流してしまうことはあまり良くないです。
現実としてコンテストのパフォーマンスを最大化する行動ができていないので、次に同じ失敗をしないように考えなければならないです。

自分はよくするミスはメモにまとめていて、コンテスト中に行き詰まった時などに見るようにしています。

## 言語の選択
コンテストにおいてはPythonしか使わずにきましたし、今後もPythonメインでいくつもりです。
シンプルに書けるので、遅いことにさえ目をつぶれば、メリットも大きいと思います。
それでも重めのDPなどはPythonだと相当上手く処理しないといけないってこともあるので、速い言語も使いこなせる様になりたいな…と思ったりもしています。

# これから
入青するまでは青色に到達すれば十分と思っていましたが、いざ入青すると、黄色を目指したい欲が出てきてしまいました(笑)
Twitterを見ていると強者ばかりで、自分がまだまだだと実感させられます。
ただ正直、今後競プロに割ける時間も少なくなりそうなので、これが最初で最後の色変記事になってしまいそうです。
マラソン系に関しては初心者なので、もしやるならそっち重視かなぁと思っています。

ここまで読んでくださりありがとうございました。
LIKEをbindしようとしたら二度怒られた。

# LIKE検索をPHPからしたい。
bindなんたら～でLIKEを書いたら怒られた。
```php:おこられた書き方.php
$sql = "select * from table where hoge like %:value% ";
$stmt  = $pdo->prepare($sql);
$stmt->bindValue(":value", $value, PDO::PARAM_STR);
```
# え、これも違うのか。
文字列扱いだからクォーテーションがいる！とか思った。
```php:こりてない書き方.php
$sql = "select * from table where hoge like '%:value%' ";
$stmt  = $pdo->prepare($sql);
$stmt->bindValue(":value", $value, PDO::PARAM_STR);
```
# %も変数に入れてください🤬
すみませんでした。。。
```php:ごめんね.php
$sql = "select * from table where hoge like :value ";
$stmt  = $pdo->prepare($sql);
$value = '%'. $value .'%'; // => ここで"%"をつける。
$stmt->bindValue(":value", $value, PDO::PARAM_STR);
```
探すのに手間取ったのでメモ。

## 参考
- http://none.3rin.net/php/php%20pdo%20prepare%E3%81%A7like%EF%BC%88%E9%83%A8%E5%88%86%E4%B8%80%E8%87%B4%EF%BC%89
Jetson Xavier NX, No CameraでMIPI カメラ動作しない時のメモ

# SDカードイメージで作ったJetson Xavier nxでMIPIカメラが使えない。

・他の方々の手順を参考にしながら、色々回り道したのでメモとして残します。

#目次
[1.カメラ無いと言われる](#1-カメラ無いと言われる)
[2.原因は？](#2-原因は？)
[3.修復作業(ミス含む)](#3修復作業(ミス含む))
[4.内容は](#4-内容は)
[5.おわりに](#5-おわりに)

# 1. カメラ無いと言われる
 
【環境】
1．Jetson Xavier nx　JetPack 4.4、4.5、4.6と使いまわし
2．4.4ではSDK Manager使ってましたが、4.5,4.6公式にSDイメージがあるので、
　使いまわしていました。

【エラー画面の一部】

```
nvgstcapture
#(略)
・・・No cameras available

```
・ ls /dev/ を叩いてもしっかりとvideo0はいるのですが、何度やっても駄目です。
・Jetson Nanoではこんなことはありませんでした。

# 2. 原因は？
- Google先生に聞きました
    - するとあっさり該当する解決法が出てきました。
　> @akira-sasaki(株式会社GClue) さんの記事     

https://qiita.com/akira-sasaki/items/49c422583bde0bde164b
  
> 記事によりますと
>> "Jetson NX XavierをJetPack4.6を焼いたSDカードから起動すると、bootromのUpdateがおこなわれる。"
>> "その状態で、JetPack4.5.1のSDカードを起動すると、カメラ周りが起動しなくなる場合がある。"
> まさにその通りの操作をしていますね・・・
> 
> > 改善方法は”SDKManagerからJetPack 4.5.1をインストールする事で復活する。”とあります。


# 3. 修復作業(ミス含む)

-  メインPC(Ubuntu20.04)に早速SDK Managerインストール
・  [NVIDIA SDKmanager(公式)](https://developer.nvidia.com/nvidia-sdk-manager "SDKmanager")
　・ インストールはあっさり完了し、いざ起動！
　、→ TARGET OPERATION SYSTEMが薄暗くなって、次へ進めず。

- @hama6767　さんの記事を発見、

https://qiita.com/hama6767/items/2351cf1f7f57bddd9f2a

・ こちらの記事では/etc/os-releaseをいじることで選択可能との説明があります。
 →今度はメニューを進める事ができる様になりました。

- エラー頻発
  - リカバリーモードで起動していますが、何度やってもOSイメージ書き込みで止まります。
  -  StackOverflow等々みて回りますが、根本的な解決には至らず。
  - 最終的に参考になったのはこちらの えびかずきさんの記事でした。

https://ebi-works.com/jetson-recovery/


まとめの項をみると

:::note warn
最後にもう一度言っておきますが、仮想環境のUbuntuだと失敗しますのでお気をつけください。
:::

**・・・そういえば、このPC Anacondaだった**

- 急遽 すっぴんのUbuntu18.04作成

- 今時はSSDが主流ですが、手持ちがなかったので以下を使用しました。
    - 当年16歳(推定）のSamsungのHDD”SP2504(250GB)”
        - 10年ぶりの使用
        - 背に腹は変えられず
    - UbuntuはUSBからごく普通にインストール
- 無事、インストールSDKmanagerのインストールまでこぎつけました。

# 4. 復活へ

- さすがHDD、それも年代物です。
    - SSDで3,40分といわれるところ、2時間近く要しました。
        - 懸案のJetson OSイメージエラーは発生しませんでした。
        - 途中、転送に手間取ったのかSDKmanagerから「やりなおす？」と聞かれました。

- 何とかJetson OS起動までこぎつけてGstreamer関連のツールをインストール
    - JetPackでは基本ファイルはデフォルトインストールでしたね・・・ 

```
nvgstcapture

```
***おお！映像がでました！***

![nvgstcapture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/ce6eceba-8317-7440-b98d-5af22023da24.jpeg)

・映像は今回活躍したSP2504です。

# 5. おわりに

・いろいろな罠が潜んでいて皆様の情報に助けられていると思いました。
情報の陳腐化も早いですが、よく読むとヒントとなります。

・Jetson nxは初めはSDKmanagerで焼いていたのですが、
ある時期からNano中心になっており、普通にイメージ使っていました。
まさかこんな目に合うとは思っていませんでした。
初心者ブロックチェーンに挑戦する　10

# 長い長い記事を、間違えて消した

　PS. ごめんなさい、私、下書き、というフォルダがあることを知りませんでした。長い長い記事はそこに残ってました。以下の文章は「誤解」の上で書かれてます。元の原稿は確かに長すぎるので、今度は意図的に削除しました。(ﾟﾟ)(｡｡)ﾍﾟｺｯ

## 余分なことを書きすぎじゃ　という神の声かもね

　疲れている、ということだろう。右下の「Qiitaに投稿」ボタンの代わりに右上の「投稿する」を押して、全てが無になった。

- なんで自動で保存されんのね。
- せめて「保存しますか」と聞いてくれんのね。
- ちなみにnoteは聞いてくれるよ〜

　まあ、神の警告に従って、元通りの長い記事を再生する代わりに概略のみ。
　私にお片付け発作の効果を起こさせたエラーの原因は、アナコンダでもウワバミでもなくて、ただ単に、ファイルの編集が保存されてなかっただけだった。編集中のあの小さな　○　見えないって、老眼なんだから。

- 保存、run、成功

　そうか、さっきの記事が消えたと同じだな。windows 85で　ワードやエクセルの文書を何度なくしたことだろう。自動更新という機能が普及して、すっかり忘れていた。

　3-1　後半もちょっと詰まって、それを長々書いたんだけど、もういいや。うまくいったから。終わり良ければ、全てよし。

## 投稿ボタンは右下。上じゃないのよ。
SwiftUI で 画像を表示する

# 環境

- macOS Monterey 12.2.1
- Xcode Version 13.2.1 (13C100)
- 使用する画像ファイル
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208784/c3069634-c1bf-cb5c-6b32-40986f8e9af3.jpeg" width=50% height=50%>

# 目的

SwiftUI で画像を表示する

# Image クラス

- AppleDeveloper
https://developer.apple.com/documentation/swiftui/image

# シンプルに画像を表示する

```ruby:ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Image("DSCN0575")
                .resizable()
                .scaledToFit()
                .frame(width: 300, height: 300)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208784/135ef57b-7078-dfb6-9b5f-62b8f46cc936.png" width=50% height=50%>


#
Unity uGUI(UI)のCanvas上でParticleSystemでEffectを表示する．

こんにちは．
Unityでかっこいいエフェクトを気軽に付けれるParticleSystemはとても便利ですね．uGUIではなく普通のゲームオブジェクトではそのまま指定した位置にParticleが表示されますが，uGUIの要素(Image，ButtonやText)にParticleSystemをつける時の設定についての記事です．

uGUIにParticle付けてSceneViewには表示されるけど，GameViewには表示されないという問題を解決します．


### 環境
Unity 2020.3.30f1
macOS Big Sur ver 11.4
MacBook Pro (13-inch, M1, 2020)


#### 画像にParticleSystemをつける．

中心付近が透過されている画像を使いたかったので適当に変なキャラの画像を生成しました．(カワイイ．かわいい？．)

<img width="150" alt="tramaru" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/d51dfbf6-8e1f-9f6e-ad4b-94d6df9848ad.png">


CanvasのImageとしてこの画像を中心に配置します．

<img width="600" alt="tramaru" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/56cc7d4d-8d95-92af-820d-827c163d8409.png">


配置したCanvas/Imageに対してParticleSystemのコンポーネントをアタッチします．ParticleのサイズとスタートスピードをSceneViewを見ながら以下のように調整しました．

![Inspector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/06281d64-1975-dfaf-8203-b4d70d5c9b54.png)

この状態ではSceneViewではImage中心にParticleが描画されていますが，GameViewで見ると右上から降ってきてしまっています．この問題を解決するために設定を行いいます．

![original.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/6d2f281b-dbb4-3ec1-2ad5-22dac28f712f.gif)


### Canvasの設定

Canvasの設定を以下のように変更します．
- RenderMode : Screen Space - Overlay
↓
- RenderMode : Screen Space - Camera
MainCameraをアタッチする．
![Canvas.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/68e0ffcc-fd3d-cb28-23d7-5962b00ecf3b.png)

この状態でSceneViewとGameViewを見てみるとParticleの位置は一致したものの．サイズ感が崩れてしまいました．．.

![Lergeparticle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/d02b4555-9654-e5fc-6d6d-69d5dfb6c1cf.gif)


### ParticleSystemの設定

最後にScaleの設定を以下のように行います．

- Scaling Mode : Hierarchy

![Prticle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/6ee2e2e6-185e-e7c5-07cf-22b942ed232d.png)

以上で設定の終了です．

## 最終的な表示

SceneViewで作業した通りにGameViewで表示することができました!

![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/89c84dbc-cf8f-e39f-04ac-0bb9f30ac581.gif)

### 最後に

UnityのuGUiで描画しているボタンやテキストに対してもParticleが使えるので演出の幅が広がりそうです．
SortOrderやz座標を設定することで画像の前にParticleを表示したり調整していくと面白そうです．
Docker Desktopが起動しない Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

# Docker Desktopが起動しない問題
- Macを再起動した際に`Docker Desktop`のアイコンを押下しても立ち上がらなかった。
- ターミナルでdockerコマンドを入力するも下記エラーが表示される
`Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?`

- 同じことで悩む人がいるかもしれないので解決した時の事を簡単にまとめる。

## Docker Desktopが反応しない

Mac再起動時に`Docker Desktop`を起動するためにアイコンを押下すると
アプリが一瞬立ち上がるがすぐに落ちてしまう。

### 試した事(アクティビティモニタからDockerを終了する)
![アクティビティモニタのスクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581885/7a11ef9a-5283-ee6f-79c9-345e8cd26dc2.png)

- `アクティビティモニタ`を立ち上げる
- アクティビティモニタの右上検索欄に`Docker`と入力して検索
- Docker(応答なし)を発見
- Dockerを押下するとウィンドウが表示される為、ウィンドウ内の【終了】を押下
- 再び`Docker Desktop`のアイコンを押下すると無事に起動しました。


## まとめ

なぜこのように`Docker Desktop`が立ち上がらなかったのか
原因は分かっていませんが、同じような現象が起きた人が
この記事を見て少しでも解決の手助けになると幸いです。
AWS SAA合格体験記

北海道をこよなく愛するピーターです。
先日AWS SAAに合格しましたので体験記です。

# 僕のスペック
・文系
・プログラミングを初めて半年
・前職は営業

# 学習期間
いきなりですが、個人的に一番の反省ポイントです。というのも1週間ほど勉強したら2ヶ月放置して内容を忘れる、また勉強して放置して忘れることを繰り返してしまったからです。
いつでも受験できる学生時代は終わったので、受験するところまで計画をたてるべきでした。帰るまでが遠足です。

__*勉強したら忘れる前に受験しよう。時間がないはずはない。*__

そういうわけなので期間としては11月~3月ですが、実質の勉強時間は3週間ほどだと思われます。自分でもわかりません。

# 学習方法
Udemyとオレンジ本を使って学習しました。
[【2022年版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/share/101OzF3@fyQSGROkoF3KdSJQUGRjnvbNxtalWU9PV_5u-d-AnFUBd82tSwM_QyPZdWeqtx1usg==/)
[AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト](https://onl.la/LMLVNuN)

## Udemy
6回分のうち4回分までを解きました。1回目に不合格、2回目で合格を繰り返しました。(前述の理由で勉強した内容を忘れているので)
解説読んでフムフムを繰り返しました。

## オレンジ本
辞書的な役割をもたせて使用しました。例えば、「シャード」ってなんだっけとなったときにオレンジ本を引きました。
ちなみにシャードはElastiCasheにおいて、「1つのマスターインスタンスとリードレプリカのまとまり」のことです。(引用:オレンジ本)
「マスターインスタンス」、「リードレプリカ」ってなんだっけ・・・以下続く。

# 学習の中で工夫したこと
反射神経を鍛えました。どういうことかというと、問題文にこの単語が出てきたら答えはこれだ!と決めつけることをしていました。

**例:「NoSQL」→答えはDynamoDBだ!**

といった感じです。もちろん100%成立するわけではありません。ですが90%くらいは当たるはずです。これを何個も作りました。
もっと例を上げます。

**「FIFO」→答えはSQSだ!**
**「SSL証明書」→答えはACMだ!**
**「読み取りに障害」→答えはリードレプリカだ!**

とはいっても誰でもやっている当たり前のことです。そもそも問題文の単語からサービスを連想できなければ解けるはずはありません。
しかし、このプロセスで覚えていくんだとマイルールを設定することが重要だと思います。明文をもって方法を確立しておくと脳にも優しいはずです。

# 難しかったこと
上記の1on1だけでは合格できないことです。これまた当然で、複合的な判断をしなければ正答を選択することはできません。
1on1の覚え方は、英単語をフラッシュカード(表に英単語、裏に日本語訳を書く紙)で覚えるようなものです。
これで覚えたあとは、**フラッシュカードをどれだけ結び付けられるか**だと思います。単語同士を線で結んでいく、この作業がどれだけうまくできるかが合格の鍵だと思います。

# 終わりに
IT初心者でもなんとか合格できました。やればできる。
Laravel AmazonSNSでSMS送信

こちらの記事を参考にしています。AWSの設定は省きます。
https://codeeee.net/posts/laravel-amazon-sns-send-sms


AWSのパッケージをcomposerでインストール。
```
COMPOSER_MEMORY_LIMIT=-1 composer require aws/aws-sdk-php-laravel
```

プロバイダ追加
```php:config/app.php
'providers' => [
  //...
  Aws\Laravel\AwsServiceProvider::class,
],
```

コマンドで設定ファイルを作成
```
php artisan vendor:publish  --provider="Aws\Laravel\AwsServiceProvider"
```

以下にファイル設定が作成される
```php:config/aws.php
 'credentials' => [
        'key'    => env('AWS_ACCESS_KEY_ID', ''),
        'secret' => env('AWS_SECRET_ACCESS_KEY', ''),
    ],
    'region' => env('AWS_REGION', 'us-east-1'),
    'version' => 'latest',
    'ua_append' => [
        'L5MOD/' . AwsServiceProvider::VERSION,
    ],
```

環境設定ファイルにアクセスキーとシークレットキーを設定
```:.env
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
```

コマンドでバッチファイル作成
```
php artisan make:command SendSms
```
以下にバッチファイルが作成されるので必要なところを編集
```php:app/Console/Commands/SendSms.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;

class SendSms extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'send:sms {tel}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'sms送信';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        // パッケージ呼び出し
        $sns = App::make('aws')->createClient('sns');

        // 引数の値を取得
        $tel = $this->argument("tel");

        // メッセージ作成
        $msg = 'テスト送信';

        // 送信
        $sns->publish([
            'Message' => $msg,
            'PhoneNumber' => '+81' . mb_substr($tel, 1), // 電話番号は国際電話番号表記に変更
            'MessageAttributes' => [
                'AWS.SNS.SMS.SenderID' => [
                    'DataType' => 'String',
                    'StringValue' => 'APP_NAME' // <- 表示名
                ]
            ]
        ]);
    }
}

```

コマンドから送信する場合
```
php artisan send:sms --tel=090123456789
```

コントローラーから送信する場合
```php:
\Artisan::call('send:sms', [
    'tel' => $tel
]);
```
Javascriptで延々と非同期処理をしたい時につかう関数

# 概要
同一のURLにリクエストを送り続けるという事は中々ないのだけれど、色々あって作らなければいけなくなったので備忘録として書いておく。具体的には意図した結果が返るまで延々と非同期処理を処理を送り、なおかつレスポンスを待っている間はリクエストを投げずに待つというもの。

# ジェネレータ関数
詳細は[MDNの該当ページ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function*)を参照。ジェネレータ関数の使い方自体は[やめ太郎さんの記事](https://qiita.com/Yametaro/items/6a24631687dca63c611a)の方が分かりやすい。要するに呼び出される度に次のyieldまでの処理を行う関数なのだが、当然反復処理を使うと呼び出すたびに処理を実行する。しかもasync/awaitも使える。
while(true)にすると無限に非同期処理を実行し続けるが、今回は念のため実行回数を指定するようにし、指定した回数に達したらnullを返すようにしてある。

```typescript:request.ts
export async function* polling(request: () => Promise<any>, limit = 5) {
  if (typeof request !== "function") {
    throw new Error("callback must be a function.");
  }
  let pollingCounter = 0;
  // 実行するとwhileの中に入る。
  while (pollingCounter < limit) {
    pollingCounter++;
    console.log(pollingCounter)
    yield await request();
  }
  yield null;
}
```

# for await of で反復処理を行う。
 ~~普通のfor文~~ やforeachは非同期処理を無視する。そのため非同期処理を反復実行したいときはfor await ofを使う。(3/15追記: 普通のfor文はasyncawait対応でした。)
[MDNの該当ページ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for-await...of)曰く、

> 非同期の反復可能プロトコルを実装している非同期ジェネレーターであれば、 for await...of を使用して繰り返し処理を行うことができます。

なのでfor ofならオブジェクトや配列が入る場所にジェネレータ関数を入れることができる。

```typescript:main.ts
import { polling } from './request'

async function api(){ 
         // なんか非同期の処理
    }

const remind = async (count:number = 5): Promise<void> => {
      // ここにジェネレータ関数
      for await (let result of polling(api, count)) {
        // 試行回数を超えるとnullが返るため、ここで処理を止める
        if (result === null) {
          break;
        }
        if (result) {
          // ここでレスポンスを使った処理
          break;
        }
          // 繰り返す場合はbreakしない。
      }
    // これでジェネレータを止める
    polling.return()
    }

```

# 結局何に使ったの？
NFCを読み込むアプリのフロントエンド。
バックエンドはFastAPI+nfcpy+uvicornの構成で、リクエストするとNFCリーダーを5秒読み込み待機状態にするAPIを実装している。
試行回数を変えることで見た目上の待機時間を制御できるようにしたいので、非同期処理を直列で処理する必要があった。
アプリについては気が向いたら書きたい。

# 注意
ジェネレータ関数もfor await ofもIE非対応です。