OmniAICreator/Qiita-1.07M huggingface dataset:
Access 今日のトリビア Schema.iniでフィールド名をブランケットで囲むと（）がつく

#前提条件
[ACCESS テキストファイル形式のフィールド区切り記号に、桁やテキストの区切り記号と同じ記号は使用できません](https://qiita.com/Q11Q/items/75fca550d0dcb7b2b907)
この設定を使いまわします。
なお、ファイル形式はmdbではなくaccdbとします。

```text:sch.txt
"NO","F01","F02","F03"
"01",2233333.456,"nam","1000000"
"01",2233333.456,"Bond, James ""master""","2000000"
```

ここでSchema.iniを次のように表記します。

```ini:schema.ini
[sch.txt]
ColNameHeader=True
Format=CSVDelimited
MaxScanRows=25
CharacterSet=ANSI
CurrencyThousandSymbol=, 
CurrencyDecimalSymbol=. 
DecimalSymbol=.
TextDelimeter="
NumberLeadingZeros=True
Col1=[NO] LONG
Col2=[F01] Double
Col3=[F02] Text Width 30
Col4=[F03] Currency
```

##SQL

```sql
SELECT * INTO T_CsvImport
FROM [TEXT;DATABASE=C:\hoge].sch.txt;
```

##実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/8d06f7fa-9645-7c08-8f0a-dc384c059a00.png)

なんとフィールド名に半角のカッコ（）がついていることがわかります。

##さらに
それではSchema.iniを次のように書きます。

```ini:schema.ini
[sch.txt]
ColNameHeader=True
Format=CSVDelimited
MaxScanRows=25
CharacterSet=ANSI
CurrencyThousandSymbol=, 
CurrencyDecimalSymbol=. 
DecimalSymbol=.
TextDelimeter="
NumberLeadingZeros=True
Col1="[NO]" LONG
Col2="[F01]" Double
Col3="[F02]" Text Width 30
Col4="[F03]" Currency
```

##この場合どうなるか
SQLを実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/bc64808f-0283-810c-c629-947b0f410487.png)

##同じようにフィールド名にカッコがつく
なんと二重引用符の有無に関わらずカッコがついてしまいました。

##ポイント
まずなぜ角かっこで包んだかというと、
[Access 2002 以降のバージョンの Access の予約語の一覧](https://docs.microsoft.com/ja-jp/office/troubleshoot/access/reserved-words)

>予約語を含む名前を持つ既存のオブジェクトの場合は、オブジェクト名を角かっこ ([ ]) で囲み、エラーを回避できます

というのがあり、
この予約語の中に`NO`があるため、角かっこ`[]`でエラーを回避しようとしたためでした。
なお、角かっこ`[]`英語ではブランケットとも言いますが、これ自体はフィールド名に使えずエラーになるとされています。

[Access データベースで特殊文字を使用する場合のエラー メッセージ](https://docs.microsoft.com/ja-jp/office/troubleshoot/access/error-using-special-characters)
>フィールド名に角かっこ ([]) またはかっこ (()) が含まれている場合は、次のエラー メッセージが表示されます。
    入力した式には、閉じるかっこ、かっこ (])、または垂直バー (|) がありません。

次に、Schma.iniのフィールド名は二重引用符は必ずしも必要ではありません。しかし、空白があるとエラーが起きるため、二重引用符で回避しsています。



なお、accdb形式では上記の予約語は使ってもエラーになりません。これは誤解していたのですが、よく見ると、
>難易度: 低シングル ユーザー コンピューターのユーザー インターフェイスに関する知識が必要です。 この記事は、Microsoft Access データベース (.mdb) と Microsoft Access プロジェクト (.adp) に適用されます

とあります。つまり、accdbファイルではエラーにならないわけです。その代わりブランケットが勝手に変換されているという自体になっているわけです。
ここまではいいのですが、ブランケットを使っていたらエラーではなく勝手に変換しているという点が最大のポイントです。
これは予期しない動作としていいと思います。
なぜかというとフィールド名に使えない文字を使い、さらに、テキストファイルのフィールド名と一致していないからです。
本来なら一口も食べずにエラーになって当たり前のはずです。
そうした予想を裏切るので、予期しない動作といえるわけです。

なお、SChema.iniのcsv変換で下手を打つと、Accessは強制終了します。なので、このへんはあまりAccessを試すような行為はやめたほうがいいと思います。
[フィールド、コントロール、オブジェクトに名前を付けるためのガイドライン](https://support.microsoft.com/ja-jp/office/%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89-%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB-%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AB%E5%90%8D%E5%89%8D%E3%82%92%E4%BB%98%E3%81%91%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%82%AC%E3%82%A4%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3-120c27fa-7ae1-4182-9baa-dbd183179cc3)を守りましょう。
FlutterでBitriseの使うための設定方法

## 概要
- Bitriseってなに？
- Bitriseの設定
- GithubでWebhookを確認する
- Bitriseが動くかテストする

### Bitriseってなに？
モバイルに特化されたCI/CDになります。

https://www.bitrise.io/

CI/CDがわからない人は下記の記事を参考にしてください。

https://qiita.com/choco_p/items/1bd1b106daee1fbd4449

### Bitriseの設定
下記の画面で「Add new app」をタップして、ワークスペース、ブランチを指定していきます。

https://app.bitrise.io/getting-started

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/fb732bf0-3a21-924c-5ea9-2cb11a0bb94f.png" width="500">

ブランチを選び下記の画像のように同期が始まります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/16b2220d-71d6-3186-5edd-944a6af2adb8.png" width="500">

あとは流れに沿って登録を進めていきます。

### GithubでWebhookを確認する
BitriseのWebhookとGithubのリポジトリが紐付いているか確認します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/483d13a4-c6ef-0584-ea65-cdc6f973205f.png" width="500">

`Payload URL`にwebhook urlがあるか確認します、もし誤っている場合は、Bitriseの`Code`の`SETUP WEBHOOK`でurlを確認しましょう。

`Which events would you like to trigger this webhook?`のチェックボックスを`Let me select individual events.`に変更し`Pushes`と`Pull requests`になっているか確認します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/b5ea8c79-4161-b90f-b2c8-d60fd5036445.png" width="500">


### Bitriseが動くかテストする
最後は紐づけたリポジトリでpushしBitriseが動くか確認します。
下記画像のようにRunningになっていたらOKです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/90f75b65-7510-5c74-b3dd-f95d29d59fe3.png" width="500">
Django 備忘録

# はじめに
個人用のDjangoプロジェクトのセットアップ備忘録です。

##activate
```bash
$conda activate djangoenv
```

##activate確認
```bash
$conda env list
```

##プロジェクト作成
```bash
$django-admin startproject [プロジェクト名]
```

## Django プロジェクト起動
```bash
$python manage.py runserver
```

#### ポート番号指定
```bash
$python manage.py runserver8080
```

#### IPアドレス指定
```bash
$python manage.py runserver1.2.3.4:3000
```


## migration - 初期DB, テーブルの作成
```bash
$python manage.py migrate
```

## アプリケーションの作成
```bash
$python manage.py startapp [アプリケーション名]
```
アプリ作成後はsettings.jsonに登録をする
シェル学習 xargsによる一括処理

####xargsによる一括処理

xargs→コマンドに引数を渡して実行してもらう

```
1,2,3,4という名前のディレクトリを作成する
$ seq 4 | xargs mkdir

ディレクトリ1,2,3,4を削除する
$ seq 4 | xargs rmdir

1,3という名前のディレクトリを作成しておき、それぞれを2,4という名前に変更
$ mkdir 1 3
$ seq 4 | xargs -n2 mv
xargs -n個数で「入力された文字列を指定した個数ずつコマンドに渡す」

dir_1,dir_2,dir_3,dir_4という名前の4個のディレクトリを作成
$ seq 4 | xargs -I@ mkdir dir_@
@のところに、xargsが受け取った文字列を1つずつ入れる

```
コンテナレジストリをhostsで解決するときにDocker Desktopでdocker loginがタイムアウトする場合の対処方法

# 事象

Docker Hub等ではなく独自にコンテナレジストリを立ち上げており、その名前解決をhostsで行う必要があり、かつ、Docker Desktopを使用しているとき、docker loginをすると、次のようなエラーが発生する場合があります。

```
Error response from daemon: Get "https://${ホスト名}/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Error response from daemon: Get "https://${ホスト名}/v2/": dial tcp ***.***.***.***:443: i/o timeout (Client.Timeout exceeded while awaiting headers)
```

# 原因

Docker Desktopの場合、Docker Daemonが参照するhostsファイルが/etc/hostsではないためです。

OSがLinuxの場合は/etc/hostsで問題ありません。

# 対応

## Windows

WSLディストロ内の/etc/hostsではなくC:\windows\system32\drivers\etc\hostsにコンテナレジストリのアドレスとホスト名を追記してください。

## Mac

/etc/hostsではなく/private/etc/hostsにコンテナレジストリのアドレスとホスト名を追記してください。
そこのお前！　余計なuseMemo1個に含まれるオーバーヘッドは余計なdiv 0.57個分だぜ！

※効果には個人差があります。

---

# useMemoのオーバーヘッドについて

Reactの`useMemo`は、パフォーマンス最適化に使われるAPIです。コンポーネント内で計算やオブジェクトの生成を行う際に、以前の計算結果をキャッシュして使い回すことで再レンダリング時の計算を削減したり、新しいオブジェクトの生成を防ぐことができます。

`useMemo`に関しては、あくまで最適化のためのものであるから「無駄に使うべきではない」という言説がよく見られます。その理由は、`useMemo`のコストもゼロではなく、余計な使用はそれだけパフォーマンスの低下に繋がってしまうからです。

しかし、筆者は`useMemo`のコストは微々たるものであり、本当に一目見て明らかに無駄でない限りは積極的に使うべきだと思っています。

そこで、筆者は`useMemo`のオーバーヘッドがどれくらいかを調べるためのベンチマークを作成しました。この記事ではその結果を共有します。結論はタイトルにある通りです。以前にも以下の記事で同じような主張をしていたのですが、そのときはベンチマークが適当で精度が低かったのでこの記事では以前よりはちゃんとしたベンチマークを用意しました。

https://zenn.dev/uhyo/articles/usememo-time-cost

# ベンチマーク

https://react-usememo-bench.vercel.app/

ここで試すことができます。適当なコンポーネントを何度もレンダリングしてその時間を計測し、最小値・最大値・25%/50%/75%/99%パーセンタイルを表示します。計測対象としては、余計なuseMemoがない場合・余計なuseMemoがある場合に加えて、useMemoと同数の余計な`<div />`がある場合を計測してみました。

3つの設定項目があります。

- **Render Timing**: コンポーネントの初回レンダリング時の時間を計測するのか、再レンダリング時の時間を計測するのかを選択します。デフォルトでは再レンダリングになっています。どちらの結果を重視するかは場合によりますが、再レンダリング時の時間を計測する方が余計な`<div />`がある側に有利です。
- **Number of useMemo/div per rendering**: 1つのコンポーネントに何個の余計なuseMemo/divを含むかです。
- **Number of renderings**: 計測を何回行うかです。

下2つのデフォルト値は筆者のMacBook Proでちょうどいい時間（10秒強）で終わるように設定されていますので、適宜調整してください。

# ベンチマーク結果

筆者の環境での結果を共有します。（再レンダリング, M=10000, N=1000）

Time spent for one rendering (ms):

| | min | 25% |	50% | 75% | 99% | max |
| - | - | - | - | - | - | - |
| raw	| 0.00 | 0.10 |	0.10 | 0.10 | 0.30 | 0.70 |
| useMemo | 1.50 | 1.70 | 1.80 | 1.80 | 4.70 | 7.10 |
| div	| 2.70 | 3.00 |	3.10 | 3.20 | 4.20 | 6.70 |

50パーセンタイル（中央値）に注目してみましょう。**余計なuseMemoが10,000個ある場合、1.7ミリ秒程度のオーバーヘッドがある**ようです。これはMac上での結果なので、スマートフォン対象の超大規模アプリだと10ミリ秒単位の差が出るかもしれません。1個あたりだと0.00017ミリ秒くらいのオーバーヘッドと概算できますね。

さらに、驚くべきことに、**余計なdivが10,000個ある場合は3.0ミリ秒程度のオーバーヘッド**が観測されています。**useMemoの約1.76倍**です。

useMemoの方が大きな外れ値が出る傾向がありますが（何回か計測したり他の人の結果を見ても同様でした）、全体を見ればuseMemoよりもdivの方が実は高コストであることが明らかになりましたね。

# まとめ

塵も積もれば山となると言いますから、余計なuseMemoを削ってコストを削減するのは悪いことではないかもしれません。

しかし、useMemoひとつのオーバーヘッドよりもdivひとつのオーバーヘッドのほうが大きいのです。よって、**余計なuseMemoを削ることにご執心の場合はその1.7倍の情熱を余計なdivを削ることに注がなければ道理に合わない**のです。

一応述べておきますが、筆者の主張は「useMemoもdivも削れ」ではありません。「微々たるものだからどちらも気にしなくていい。しかしuseMemoを気にするのにdivを気にしないのはおかしい」というのが筆者の考えです。

なお、ベンチマークのコードはGitHubで公開していますので、手法や結果に異論がある場合はぜひコメント欄などで議論してください。

https://github.com/uhyo/react-usememo-bench

続編ができました↓

https://qiita.com/uhyo/items/5258e04aba380531455a

## Q&Aコーナー

**Q.** 積極的にuseMemoを使うべき理由が書いていない
**A.** [useCallbackについては以前の記事で書きました](https://blog.uhy.ooo/entry/2021-02-23/usecallback-custom-hooks/)。useMemoでも本質はだいたい同じです。この記事はuseMemoを積極的に使いたい人を応援する記事なので、積極的に使いたいかどうかはあなた次第です。

**Q.** 速度より消費メモリ量を見るべきでは？
**A.** ~~ウェブ開発でメモリ量を気にする人がぜんぜんいないし速度に比べて重要性が低いので速度を測りました。ただ、useMemoで外れ値が大きく出るのはGCっぽい気がする（憶測）~~
**A.** （ここに対するつっこみが多いので回答を訂正しました） 消費メモリ量の制御が重要な場面が存在することは否定しませんが、速度に比べて重要ではない場面が多いこともやはり否定できません。少なくともこの記事は後者の場合に役に立つでしょう。消費メモリ量が重要な場合は残念ですがこの記事の内容はあまり参考にならないかもしれません。

**Q.** 環境が書いていない。環境によって結果が違うのでは？
**A.** 筆者のMacBook Pro 2018上のGoogle Chrome 96です。ご指摘の通り環境によって結果が違うのは当たり前です。ただ、useMemoとdivの相対的な倍率についてはあまり変わらないのではないかと思い積極的に喧伝しています。
Dockerのコンテナ内に入る！でもなんで入れるの？

## はじめに

Docker環境を構築した際に``rails``コマンドや``php artisan``コマンドを使用したかったり、MySQLなどを操作したいときに、起動済みのコンテナに接続するケースがあると思います。

正確なコマンドをよく忘れてしまうので、メモとして残します。

## docker execコマンド
```
$ docker exec -it コンテナ名 bash
```

コンテナ名を指定するとコンテナ内部に入ることができる。

やったね！

<b>でもなんでこれでコンテナ内部に入れるの???</b>
普段無意識に使ってたから気になる。


#### 折角なので、コマンドについてもう少し調べてみた。
こちらの記事によると、```docker exec```コマンドは
<b>実行中のコンテナ環境内で、指定したコマンドを実行してくれるもの</b>とのこと。
[docker execコマンドの使い方（実例で解説）](https://www.memotansu.jp/docker/591/)

さらに以下の記事から引用させていただくと、
オプション```-it```を指定することで..........

>-iは、Keep STDIN open even if not attached
標準入力を開き続ける。

>-tは、Allocate a pseudo-TTY
疑似ttyを割りあてる。

>標準入力を開き続け、そこを操作出来るようにする。
→手元の環境で、docker内入力ができるようにする

ということになるらしい。

<b>??????????</b>
<b>擬似ttyって何???????</b>ってなった。

いまいち全容を掴むことができなかった。これ以上は話の大筋から逸れそうなので続ける。

要は```-it```オプションを指定した```docker exec```コマンドは
<b>実行中コンテナ内部でshellを起動するコマンドとなり、手元の環境でコンテナ内に入力ができるようになる</b>！ということらしい..........

ちゃんと調べよう............

引用元:[docker exec -itって実際は何をしてるの？【90日目】](https://www.nyamucoro.com/entry/2018/01/11/224932)



#### コンテナ情報出力
ちなみにコンテナ名は以下で確認できます。

```
$ docker ps -a
```


## docker-composeコマンド

以下のコマンドでは、それぞれdbとappのコンテナに入ることができます。
普段はこっちを使う方が多かった。

```
$ docker-compose exec db bash
```

```
$ docker-compose exec app bash
```

参考サイト:[docker-compose exec](https://matsuand.github.io/docs.docker.jp.onthefly/compose/reference/exec/)


### 参考記事
[Docker exec -it とは](https://hacknote.jp/archives/56621/)
[任意のDockerコンテナ上でbashを起動する](https://qwx.jp/docker-container-on-bash/)
eslint(react+typescript+airbnb)の設定

# 概要
react+typescriptの環境でeslintをairbnbのルールで導入したのでメモする

# 前提
- npmが使えること
- TypeScriptが導入されており、設定ファイルが存在すること

# パッケージの導入

```sh:shell
$ npm i -D eslint eslint-config-airbnb eslint-config-airbnb-typescript 
```

# 設定

### 1. 以下のコマンド実行

```sh:shell
　$ npx eslint --init
```

### 2. eslintの初期設定

必要に応じて設定
自分は以下のように選択した

```shell:設問
? How would you like to use ESLint? To check syntax and find problems
# eslintでどこまでを制御するかを選ぶ
# シンタックスのチェックだけを行なうか、問題のあるコードも解析するか、そしてコードスタイルを適用するのか問われてます。

? What type of modules does your project use? JavaScript modules(import/export)
# モジュールのimport/exportスタイルを問われています。 ES2015のimport/exportを使うならJavaScript modules、CommonJSのrequireを使うならCommonJSを選択

? Which framework does your project use? React
# フロントエンドのフレームワーク

? Does your project use TypeScript? Yes
# TypeScriptを利用するか？

? Where does your code run? (Press <space> to select, <a> to toggle all, <i> to invert selection)Browser
# 実行環境はブラウザかnodeか？
# フロントエンドならブラウザ

? What format do you want your config file to be in? javascript
# eslint設定ファイルの拡張子

Successfully created .eslintrc.json file in /path/to/your/project
```

### 3. 必要パッケージの自動インストール

2.の設定に応じて必要なパッケージがインストールされます

2.3.が成功すると`eslintrc.js`が作成される

### 4. `.eslintrc.js`の編集
extendsプロパティにairbnbの設定を入れる。
順番は、`airbnb`, `airbnb-typescript`の順番にしないとうまく行きません。
parseOptions.projectプロパティにTypeScriptの設定ファイルを指定する

```diff:.eslintrc.js
  extends: [
  + "airbnb",
  + "airbnb-typescript",
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "eslint-config-prettier",
  ],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 13,
    sourceType: "module",
+   project: "./tsconfig.json",
  },
```

### 5. コマンドの追記

`.src/`直下のts,tsx拡張子のみlintをかけるようにした


```json:package.json
  "scripts": {
    "lint": "eslint ./src/**/*.{tsx,ts}",
  },
```


これで`$ npm run lint`でlintをかけることができる

# 参考
https://stackoverflow.com/questions/59265981/typescript-eslint-missing-file-extension-ts-import-extensions

https://www.konosumi.net/entry/2019/09/01/165449
カフェでプログラミングしてる風（でも何もやってない）Goコード

# 概要
[こちら](https://qiita.com/3S_Laboo/items/660883a0184dabaea65b "こちら")と[こちら](https://qiita.com/YottyPG/items/e988ebacab94a8f4645f "こちら")の記事を拝見し、学び始めの言語を使うにはちょうど良さそうだと思ったので、Goで作ってみました。

# 見た目
こんな感じで、ただただ何かをダウンロードしているだけの人間になります。
数秒程度であれば周りの目を誤魔化せるはず、、、、
![go_cofe.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521898/1f1f4d8b-dbef-8306-4a35-2402921fc003.gif)

# 実装
```go
package installs

import (
	"fmt"
	"math/rand"
	"time"
)

func PrintInstall() {
    // 時刻からランダムなシード値を設定
	rand.Seed(time.Now().UnixNano())

	// #を50文字出力する
	maxCount := 50
	// #をカウントする
	currentCount := 0
	// 出力用のダミーパッケージ名
	packageList := [...]string{
		"hoge",
		"fuga",
		"coffee-code",
		"go-package",
		"sample",
		"json-parset",
		"yokozuna",
		"kakamimochi",
		"ramen",
		"mac",
	}
	// ダミーのアラートメッセージ
	alertMsg := `Warning: This package is old version!!
	You should install newer version!!`

	// パッケージのダウンロードを繰り返す
	for {
		// 0~9でランダムに生成
		randomNum := rand.Intn(10)

		// パッケージ名をランダムに出力
		fmt.Printf("go: downloading %s", packageList[randomNum])
		fmt.Println("")

		// 出力している#が50未満なら#を出力する
		for currentCount < maxCount {
			// ランダムに時間をかけているように見せるための数値を生成
			sleepRate := time.Duration(rand.Intn(50))

			fmt.Print("#")
			currentCount++

			// sleepRateが0ならsleepしない
			if sleepRate == 0 {
				continue
			}
			time.Sleep(time.Second / sleepRate)
		}

		fmt.Println(" Done!!")

		// randomNumが0ならダミーのアラートを出す
		if randomNum == 0 || randomNum == 1 || randomNum == 2 {
			fmt.Printf("%s", alertMsg)
			fmt.Println("")
		}

		// 最後に#のカウントを0に戻す
		currentCount = 0
	}
}
```

# 最後に
Goを簡単に勉強して基本的な文法だけで作れそうなものがないかと思っていたら、ちょうど良さそうな題材を拝見したので作ってしまいました。
Rust版とかも作ってみたいなぁと思っています。

# 参考
[カフェでプログラミングしてる風（でも何もやってない）Java（クソ）コード](https://qiita.com/3S_Laboo/items/660883a0184dabaea65b)
[カフェでプログラミングしてる風（でも何もやってない）Python（クソ）コード](https://qiita.com/YottyPG/items/e988ebacab94a8f4645f)
【Ruby】繰り返し処理　times文

※初心者向け
※アウトプット練習の為

開発環境
rails 6.1.4.1
ruby 2.6.5

##問題内容##
times文を使って、以下のようにターミナルに出力されるプログラムを書いてください。

**ターミナル**

```
1回目の繰り返し
2回目の繰り返し
3回目の繰り返し
4回目の繰り返し
5回目の繰り返し
6回目の繰り返し
7回目の繰り返し
8回目の繰り返し
9回目の繰り返し
10回目の繰り返し
```

##解答##
```csharp
10.times do |i|
  puts "#{i + 1}回目の繰り返し"
end
```

##解説##
times文を使えば、何度も繰り返される同じ処理をまとめることができます。今回まとめられるのは◯回目の繰り返しとターミナルに出力する部分です。

times文は繰り返したい回数.timesと記載して繰り返す数を決めます。今回は10回繰り返すので10.timesとなります。


```csharp
10.times
end

```

10.timesとendの間に、◯回目の繰り返しとターミナルに出力する処理を記述します。出力にはputsメソッドを使います。一旦そのまま◯回目の繰り返しとして処理を書いてみます。

```csharp
10.times
  puts "◯回目の繰り返し"
end
```
この◯の部分は繰り返しの回数が入ります。どうしたら繰り返しの回数を◯の部分に入れることができるでしょうか?

times文には繰り返しの中で「現在の繰り返し回数」を使うための機能があります。それが繰り返しの回数.times do |変数名|です。変数名の箇所は自由ですが、今回はiとしておきます。

```csharp
10.times do |i|
  puts "◯回目の繰り返し"
end
```

この変数iは、10.times do |i|とendの間だけで使える変数です。つまり繰り返しの処理の中でしか使えません。ではiに何が入るのかというと「現在の繰り返し回数」が入ります。プログラムなので、1回目の繰り返しではiは0になります。2回目はiは1です。3回目はiは2です。
　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2451862/de282008-6464-d039-e06f-86f216d01c04.png)
よって、1回目の繰り返しで1回目の繰り返しと出力するには、(i + 1)回目の繰り返しとすれば良いことになります。

```csharp
10.times do |i|
  puts "#{i + 1}回目の繰り返し"
end
```
composerとその他のファイル（自分用）

#Composerとは
PHPのパッケージ・ライブラリ管理ツールのこと。
PHPを用いたアプリ開発に必要なライブラリやパッケージをまとめて管理することができる。

■パッケージ管理ツールのメリット3つ
①パッケージのインストールが楽
②チーム開発でパッケージやパッケージのバージョンを統一できる
③パッケージの依存関係を考えなくていい

#composer.jsonとcomposer.lockとは
Composerがライブラリやパッケージを管理しているファイルが、composer.jsonやcomposer.lock

①composer.lockがない時（１回目のcomposer install）
composer.jsonを基にライブラリをインストールし、composer.lockを生成

②composer.lockがある時（2回目以降のcomposer install）
composer.lockを基にライブラリをインストールし


#参考
[composer.jsonとcomposer.lockの役割について分かりやすくまとめてみた](https://www.engilaboo.com/about-composer/)
docker コンテナ内の例えば .bash_profile の設定を反映して実行したい

Login を伴うのであれば、--login オプションを付ければ、反映される。

```
docker run -it something_image bash --login
```

以下のように、Login せずにコマンドだけ実行させたい場合があった。

```
docker run something_image ls -l
```

強引ではあるが、以下のように対処した。

```
docker run something_image bash -c "source /home/root/.bash_profile && ls -l"
```
メモ帳クローンをダークテーマに対応させてみる

# はじめに

メモ帳がダークテーマに対応するとの事。

https://forest.watch.impress.co.jp/docs/news/1372383.html

では、**メモ帳クローン**も対応させてみましょう。Delphi でメモ帳クローンを作る記事は次の通りです。

 - [Delphi Starter Edition でメモ帳クローンを作る (前編)](https://qiita.com/ht_deko/items/bd854e8a22cf31b636b0)
 - [Delphi Starter Edition でメモ帳クローンを作る (後編)](https://qiita.com/ht_deko/items/d5c4de7d55eebca928e2)
 - [Delphi Starter Edition でメモ帳クローンを作る - 2nd Edition -](https://qiita.com/ht_deko/items/525cd67aaba16681c3ba)
   - [[編集(E)] （1）](https://qiita.com/ht_deko/items/f2f330ebdcb3f9f49e96)
   - [[編集(E)] （2）](https://qiita.com/ht_deko/items/d40247d93533c42f4ef0)
   - [[書式(O)]](https://qiita.com/ht_deko/items/4309e5fc56419a8aa05d)
   - [[表示(V)]](https://qiita.com/ht_deko/items/774482e86c8380a08bf8)
   - [[ヘルプ(H)]](https://qiita.com/ht_deko/items/2d82538c58ed2d16b261)
   - [[ファイル(F)]](https://qiita.com/ht_deko/items/46c476859388dd566b27)
   - [その他の機能](https://qiita.com/ht_deko/items/5347de15b7856f3008fc)
 - [Delphi Starter Edition でメモ帳クローンを作る - 番外編](https://qiita.com/ht_deko/items/90b8500d0ca4fc286206)

:::note info
2022/1 現在、無償で使える Delphi は Starter Edition から、より高機能な Community Edition へと変更されています。
:::

:::note info
本記事では有償版の Delphi 11.0 Alexandria を使用しています。
:::

**See also:**

 - [Delpi Community Edition (Embarcadero)](https://www.embarcadero.com/jp/products/delphi/starter)


# やってみる

メモ帳クローンのソースコードは以下から持ってきます。

 - [https://ht-deko.com/software/notepad_clone.zip](https://ht-deko.com/software/notepad_clone.zip)

## 改変

 1. [ファイル | プロジェクトを開く...] から `notepad_clone.dproj` を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b613d499-8a73-99a9-8b1c-884afeab12eb.png)
 2. [プロジェクト | オプション] でオプションダイアログを開き、[アプリケーション | 表示] にあるカスタムスタイルで `Windows 11 Dark` (なければ `Windows 10 Dark`) にチェックを入れます。デフォルトスタイルも `Windows 11 Dark` になっている事を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/dc2b131e-10c3-2180-07a8-002bbe3fef9b.png)
 3. 〔F9〕を押してコンパイルして実行します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/325d29cf-8969-706a-4a38-089793ed171c.png)

以上です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/a248d2af-4d89-274c-0ad3-d57f1d538d16.png)
追加の VCL テーマは GetIt パッケージマネージャ ([ツール | GetIt パッケージマネージャ...]) で探すことができます。 

# おわりに
複数の VCL スタイルにチェックを入れてコンパイルすれば、実行時にスタイルを切り替える事ができます。アプリケーション実行時に、利用可能な VCL スタイルの一覧を得るには以下のように記述します。

```delphi
uses
  ..., Vcl.Themes, VCL.Styles;

var
  StyleName: string;
begin
  // 利用可能な VCL スタイルの一覧を得る
  for StyleName in TStyleManager.StyleNames do
    begin
      ...
    end;
  ...  
end;  
```

VCL スタイルをコードで変更するには以下のように記述します。


```delphi
 // VCL スタイルを "Slate Classico" に変更
  if not TStyleManager.TrySetStyle('Slate Classico') then
    begin
      // エラー処理
    end;
```

**See also:**

 - [VCL スタイルの概要 (DocWiki)](https://docwiki.embarcadero.com/RADStudio/ja/VCL_%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AE%E6%A6%82%E8%A6%81)
【Django】migration を 切り戻す方法

# Django migration を 切り戻す方法

Djangoでモデルをいじくっていると、DBがおかしくなって、migrateがいっこうに動かなくなることが多々あります
↓今回はこんなエラーでした

```
django.db.utils.OperationalError: foreign key mismatch - "〇〇" referencing "××"
```

「今日行った変更はいったん全部切り戻して、何事もなかったようにする！」の方法を紹介します

## 1. 特定のバージョン(?)にmigrateする

`$ python manage.py makemigrations` を実行すると、
model.py のある app (例として今回は main というapp とします) の、migrations ディレクトリに、migrate用のpythonファイルが自動で作成されていきます

```shell
$ python manage.py makemigrations
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, main, sessions, users
Running migrations:
  Applying main.0007_auto_20220106_2310... OK

$ ls -lA main/migrations/
合計 32
-rw-rw-r--. 1 user user  877 12月 23 22:56 0001_initial.py
-rw-rw-r--. 1 user user  621 12月 23 23:07 0002_auto_20211223_2307.py
...略...
-rw-rw-r--. 1 user user 1160  1月  6 23:10 0007_auto_20220106_2310.py
-rw-rw-r--. 1 user user    0 12月 23 22:28 __init__.py
drwxrwxr-x. 2 user user 4096  1月  6 23:10 __pycache__
```

この`XXXX_〇〇〇_×××.py`をmigrate先に指定することができますので、
まずは一番最新のまだエラーが起こってない頃のバージョン(?)にmigrateします

コマンドは
`$ python manage.py migrate app名 migrate先`
です

```
$ python manage.py migrate main 0002_auto_20211223_2307
```

`.py`は不要なので注意!

これでDBの中身は正常だったころの内容に戻ります

## 2. model.py を戻す

今日変更を行ったDBをおかしくしてしまうmodelは元に戻します
git 管理しているなら `git checkout` でいいと思います

```
$ git checkout main/models.py
```

## 3. migrationsディレクトリのファイルを消す

今日出来たDBをおかしくしてしまうmigration 関連のファイルを削除しちゃいます

```
$ rm main/migrations/XXXX_〇〇〇_×××.py
```

### 4. 再度migrate処理

元に戻せたら、もう一回

`$ python manage.py makemigrations`
`$ python manage.py migrate`

を実行します

### 5. 完了

これでひとまず切り戻しが完了します

細かいことを考えず一気に戻しちゃいたいときは参考にしてみてください

無論、DBのデータは丁寧に扱うべきなので、むやみやたらに実行するのは避けたいですね
どうしようもなくなったときに実行するのがいいと思います

自分は個人で気楽に開発してるので、
エラーで詰まる時間がもったいないと感じちゃいます (~~というかめんどくさい~~)
こういう時はすぐ切り戻したり全部ぶっ壊して一からやり直すみたいなことすぐやっちゃいます
エラー解決能力が育たないのでよくないですね
【uniqueness: scopeの使い方】ブックマーク、いいね機能実装に使える

##uniquenessとは
バリデーションの１つ。Railsで一意であることを示す。
``scope``はuniquenessのオプション。

下記は人が投稿したものに対してブックマーク（いいね）機能を入れた時のmodel例。
１投稿に対して、１人のユーザーが１ブックマーク（いいね）しかすることができないため、このようなバリデーションになる。

```models/bookmark.rb
class Bookmark < ApplicationRecord
  belongs_to :user
  belongs_to :board

  validates :user_id, uniqueness: { scope: :board_id }
end
```

もし``scope``を付与せずにいると、

```models/bookmark.rb
 validates :user_id, uniqueness: true
```

「1投稿」に対して「1ブックマーク（いいね）」しか付けることしか出来ず、**早い者勝ちで一番最初に誰かがブックマーク（いいね）をしたら、それ以上その投稿にブックマーク（いいね）が付けれなくなる。**

なのでブックマーク（いいね）機能搭載の時は``uniqueness: scope``が必須と言える。
また``uniqueness: scope``配列にして複数指定ができる。

```models/bookmark.rb
validates :user_id, uniqueness: { scope: [:group_id, :board_id] }
```

これで``board_id``, ``group_id``, ``user_id`` の全てが同じデータは1件しか作成できなくなる。

##参考記事
[【Rails】複数のカラムを使ったユニーク制約の方法【uniqueness: scope】](https://310nae.com/rails-uniqueness/)
IchigoJamでエラトステネスの篩

# 背景

こんなツイートを見つけました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">エラトステネスの篩で、32768未満の素数をリストアップする処理をさせたところ、LPC1114版では968秒ほどかかったのが、RISC-V版では202秒と、約4.8倍高速になってた。&gt; IchigoDake</p>&mdash; 荒木 宏之 (@h_araki) <a href="https://twitter.com/h_araki/status/1479024588600524800?ref_src=twsrc%5Etfw">January 6, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

エラトステネスの篩で32768未満の素数をリストアップする処理をさせたそうです。
32768個のフラグを管理するには、1個のフラグを1ビットで管理すると4096バイト使うことになります。
(1バイト＝8ビットとします)

[IchigoDake](http://dakeigai.shizentai.jp/)で使われている[LPC1114FDH28](https://www.nxp.com/part/LPC1114FDH28#/)は、
SRAM全体のサイズが4kB (4096バイト) しかなく、
エラトステネスの篩で普通に32768までの素数をリストアップするのは困難であると考えられます。
(フラグを外部のメモリやFlashに置いたり、マシン語のプログラムをFlashに置いて実行したり、
という方法が考えられ、不可能ではないでしょう)

具体的な実装は書かれていないようで、気になったので実装してみることにしました。

# 方針

32768未満の非負整数を表すビットを全部SRAMに載せようとするとメモリが足りなくなってしまうので、
メモリに収まる大きさのブロックに分割して処理します。

また、$n^2$以下の素数を求めるには、$n$以下の素数の倍数を落とす処理をすればよいことが知られています。
したがって、${181}^2=32761$、${182}^2=33124$なので、
32768未満の素数を求めるには182以下の素数を落とす処理をすればよいことがわかります。

今回は、キャラクターパターン領域を用い、1個のフラグを1 **バイト** で処理することにしました。
ブロックのサイズは256要素となります。
ビット単位ではなくバイト単位で処理することで、ビット演算をする手間を省けます。

2以外の偶数は素数ではないので、182以下の素数は高々92個であり、102要素ある配列に収まります。
そこで、ます最初のブロックは普通にエラトステネスの篩を行い、182以下の素数を配列に格納します。
次以降のブロックは、この配列に格納した素数を用いて処理します。

# 実装

```
10 ' ｴﾗﾄｽﾃﾈｽ ﾉ ﾌﾙｲ
20 POKE#700,0,0:FOR I=#702 TO #7FF:POKE I,1:NEXT
30 N=-1:FOR I=2 TO #FF
40 IF !PEEK(#700+I) GOTO 80
50 ?I;" ";
60 IF I<=182 N=N+1:[N]=I
70 IF I<16 FOR J=#700+I*I TO #7FF STEP I:POKE J,0:NEXT
80 NEXT
90 FOR K=#100 TO #7F00 STEP #100
100 FOR I=#700 TO #7FF:POKE I,1:NEXT
110 FOR I=0 TO N:P=[I]
120 FOR J=(K+P-1)/P*P-K+#700 TO #7FF STEP P:POKE J,0:NEXT
130 NEXT
140 FOR I=#700 TO #7FF
150 IF PEEK(I) ?I-#700+K;" ";
160 NEXT
170 NEXT
180 ?CHR$(10);
```

# 実行結果

IchigoDakeは持っていないので、IchigoKamuy (IchigoJam BASIC 1.4.1、`VER()=14114`)
および IchigoJam R (IchigoJam BASIC 1.5b、`VER()=15001`) で実行してみました。

その結果、32768未満の素数のリストが正しく求まりました。
答え合わせのため、[素数表](http://angelos.info.kanagawa-u.ac.jp/tgl/Appendix/Prime.html)から32768未満の素数の部分をコピーし、
以下のRecipeで各素数の間に空白1個が入る形式に変換し、さらにSHA-256を求めました。
[Find / Replace, 3 more - CyberChef](https://gchq.github.io/CyberChef/#recipe=Find_/_Replace%28%7B%27option%27:%27Regex%27,%27string%27:%27%5C%5Cs%5B1-9%5D%2B0%7B2,%7D%5C%5Cs%27%7D,%27%27,true,false,true,false%29Find_/_Replace%28%7B%27option%27:%27Regex%27,%27string%27:%27%5C%5Cs%2B%27%7D,%27%20%27,true,false,true,false%29Find_/_Replace%28%7B%27option%27:%27Regex%27,%27string%27:%27%5E%5C%5Cs%2B%27%7D,%27%27,true,false,true,false%29SHA2%28%27256%27,64,160%29)
このSHA-256 `bde5648268d480c606d7560e85d8aa685924dec7c432361972e325607327a119` を
プログラムの出力(最後の空白を除く)のSHA-256と比較し、一致することを確認しました。

実行時間は以下のようになりました。

|機種|ビデオ出力あり|ビデオ出力なし|
|---|---|---|
|IchigoKamuy|9分40秒 (580秒)|6分20秒 (380秒)|
|IchigoJam R|1分13秒 (73秒)|1分4秒 (64秒)|

IchigoJam R は IchigoKamuy に比べ、ビデオ出力ありの時は約7.9倍、
ビデオ出力なしの時は約5.9倍速い、という結果になりました。

また、ビデオ出力なしの時、冒頭で紹介したツイートで示されている秒数と比べ、
IchigoKamuy ではLPC1114版の約2.5倍、
IchigoJam R ではRISC-V版の約3.2倍速い結果になりました。

# おわりに

* IchigoJamはjig.jpの登録商標です。
* IchigoKamuyは株式会社syushuの登録商標です。
2進に変換

末尾にdのついた10進数文字列、末尾にhのついた16進数文字列、末尾にbのついた2進数文字列をbitの並びに変換するテスト

```py
def any2bin(valstr: str, is_signed: bool, bitlen: int):
    """ 2進数に変換する """
    final_char = valstr[-1]
    valstr = valstr[:-1]
    ret = ''
    if final_char == 'b':
        if len(valstr) == bitlen:
            ret = valstr
        else:
            raise Exception     # 桁数不一致
    elif final_char == 'd':
        ret = dec2bin(valstr, is_signed, bitlen)
    elif final_char == 'h':
        ret = hex2bin(valstr, is_signed, bitlen)
    else:
        raise Exception

    return ret


def dec2bin(valstr: str, is_signed: bool, bitlen: int):
    """十進数を二進数のbitが並んだ文字列に変換する"""
    val = int(valstr)
    if _range_check(val, is_signed, bitlen):
        if is_signed and val < 0:
            all_one = int('1' * bitlen, base=2)     # 1111...1b (bitlen個の1)
            ret = f'{~(all_one ^ val): b}'
        else:
            ret = f'{val:b}'.zfill(bitlen)
    else:
        raise Exception  # out of range

    return ret


def hex2bin(valstr: str, is_signed: bool, bitlen: int):
    """16進数を二進数のbitが並んだ文字列に変換する"""
    # unsignedとしてbit変換
    val = int(valstr, base=16)
    maxval = (2 ** bitlen) - 1
    if val > maxval:
        raise Exception  # out of range

    ret = f'{val:b}'.zfill(bitlen)

    return ret


def _range_check(decval: int, is_signed: bool, bitlen: int):
    """範囲をチェックする"""
    ret = True
    if is_signed:
        min_val = -1 * (2 ** (bitlen-1))
        max_val = (2 ** (bitlen - 1)) - 1
    else:
        min_val = 0
        max_val = (2 ** bitlen) - 1

    if decval > max_val:
        ret = False
    if decval < min_val:
        ret = False

    return ret
```
【Git log をリセット】Gitの履歴を全て削除したら幸せになったwwwwwwww

## Gitの履歴を全削除

Gitの履歴を全削除したいときがありました。調べてもなんか違う記事ばっかりだったので、海外から探してきて和訳してきたのでメモしときます。YouTubeのタイトルのようなタイトルにした理由は特にありません。(記事を書いている現在は仕事終わりです)

※この記事でやりたいことは、gitの「履歴」を全て削除するだけで、commitしたソースの変更分はそのまま全て残します。

## 例
- OSSをcloneしたけど、俺が作ったことにしたいからlogを全て消したい
  - logは消すけど、codeはそのまま

## 結論

チェックアウト

```
git checkout --orphan about_branch
```

追加・コミット

```
git add -A
git commit -am "initial commit"
```

ブランチを削除・現在のブランチの名前をmainに変更

```
git branch -D main
git branch -m main
```

リポジトリを強制的に更新

```
git push -f origin main
```

https://git-scm.com/docs/git-log
https://git-scm.com/docs/git-checkout
https://gist.github.com/ktx2207/3167fa69531bdd6b44f1
https://qiita.com/ykawakami/items/0d6826c529ad7c7b37dd
AWS / CircleCI / Docker を使ったアプリの完成


# プロフィール
・実務未経験の27歳
・大学院卒業 〜 現在まで約2年フリーターとして就業中
・週3, 4勤務
・プログラミングスクール卒業生

目標にしていたAWS、Docker、CircleCIの導入ができたので一旦これでポートフォリオの完成にしようと思います。インフラの勉強むずい！

# ポートフォリオについて

## 機能一覧
日々の運動習慣を記録できるアプリで、機能は大きく分けて三つあります。

1. 運動した時間や走行距離などをグラフとして描画できる機能
2. 基本的なCRUD機能を持つつぶやき投稿（つぶやきの新規作成、編集、削除、一覧表示）
3. つぶやき投稿に対するいいね機能
4. つぶやき投稿に対するコメント機能
5. フォロー・フォロワー機能

## テストユーザーの使用例
* ランニング → 走行距離・走行時間
* 筋トレ → 筋トレ部位・筋トレ時間

上記のように、ユーザーは「ランニング」と「筋トレ」に分けて運動を記録することができます。
それらのデータを使って三種類のグラフを描画します。

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/ff02a90d-78ec-f2e4-3043-26377abe2b2d.png)

## 使用した技術
* サーバーサイド言語：Ruby
* データベース：PostgreSQL
* インフラ：AWS（EC2, RDS, Internet Gateway, Route53, ELB, Certificate Manager ）, Docker&docker-compose, CircleCI
* ソース管理：Git
* フロント：HTML, CSS, JS
* テストフレームワーク：RSpec

## 使用したgem (一部抜粋)
* chart.js (グラフの描画)
* gon (RailsとJavascriptの連携)
* kaminari (ページネーション)
* rspec-rails (テスト)
* capybara (UIテスト用のフレームワーク)
* factory_bot_rails (テスト用のサンプルデータ作成)
* rubocop (コード解析)
* launchy (デバック)
* pry-rails (デバック)  

## ER図
こちらの画像は[drawio](https://app.diagrams.net/)使って作成しました。
![ER図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/da82e4f3-2946-2775-9fcc-6277839d5732.png)



## インフラ構成図
開発はdocker上で行いました。git pushするとCircleCIが起動し、RSpecとRubocopを使ったテストを実行させるように設定しています。
またAWSを導入しており、独自ドメインの取得およびhttps化まで行っています。
こちらの画像も[drawio](https://app.diagrams.net/)使って作成しました。
![インフラ構成図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1293293/e971c630-6ec8-bf7f-61d1-964cdcd8664b.png)


## 終わりに
今後は画像投稿機能やレスポンシブデザインも取り入れていきたいです。
あとはRSpecの更なる充実！
Windows10でUbuntu20.04を起動したら、0x800701bcというエラーがでた

新しくBTOで注文したPCが届いたので、ワクワクでUbuntuインストールし、起動したら0x800701bcというエラーがでました。。

### 環境
Windows10 20H2
WSL2


### エラー
``` 
Installing, this may take a few minutes... 
WslRegisterDistribution failed with error: 0x800701bc Error: 0x800701bc 
WSL 2 ???????????? ??????????????????????? https://aka.ms/wsl2kernel ?????????
```

### 原因
Linux カーネル更新プログラム パッケージをダウンロードしていなかった。

### 参考にさせていただいた記事
[https://hachimoto12.com/wsl2_error_0x800701bc.html](https://hachimoto12.com/wsl2_error_0x800701bc.html)

### 解決法
エラーにもある[https://aka.ms/wsl2kernel](https://aka.ms/wsl2kernel)へ遷移し、[x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ](https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi)をクリックしてダウンロードしてインストールする。



### 最後に

初めてのQiita投稿で、文章がおかしくて読みにくかったすみません、、！
自分の文章を書くのが苦手、Githab以外の成果物？アウトプット？がないという課題を解決するために、2022年は月に1本投稿しようと思うので今後ともよろしくお願いいたします！
2022年の抱負

# 執筆の経緯
まだまだ新米エンジニアで勉強することが大量にあるので、目標をたててコツコツやらないと迷いそう。
よっしゃ、文字に起こしてモチベーションに繋げてみよう。

# 自己紹介
本記事執筆時点(2022年1月時点)で実務経験4ヶ月目の新米エンジニア。
業務ではフロントエンド領域(Vue.js)を担当。ちなみに2系のVue.js。

# 目次
- 去年できたこと
    - フロントエンド
    - バックエンド
    - インフラ
    - その他
- 今年やりたいこと
    - フロントエンド
    - バックエンド
    - インフラ
    - その他
- おわりに
- 作成したアプリのリポジトリ

# 去年できたこと
### フロントエンド
- Vue.js & Nuxt.js
    - Vue.jsは実務で使用していたので一番知見が伸びた。
 独学だと学びにくいVueRouterのナビゲーションガード周り、ユニットテスト周りの知見を伸ばせたのが大きかった。
    - Nuxt.jsは転職用のポートフォリオで使用したレベル。今見ると本当にヒドいコード。
 それが分かるようになっただけヨシとしよう・・・。
- React.js & Next.js
    - React.jsおよびNext.jsはどちらも自己学習レベル。
 ただしエンジニアになってから周りの先輩の話とかも聞きながら学習し始めたので、Nuxt.jsとは違い、独学だけど質の良い学習ができた。
    - React.js × Laravelで簡単なCRUDアプリを作成できた。
    - Next.js × LaravelでNuxt.jsで作ったポートフォリオをリプレイス中。
    - じゃけえさんのUdemy講座及び書籍のおかげで爆速でキャッチアップできた。感謝。
- TypeScript
    - TypeScriptも実務で使用していたので、知見が伸びた。
 曖昧に理解していたUtility Types周りが分かった。

### バックエンド
- PHP & Laravel
    - 前職の有休消化で1ヶ月くらい休みがあったので、そこで一気に学習。
    - 山浦清透さんの『独学エンジニア』という学習サービスのおかげでこちらも爆速キャッチアップできた。感謝。
    - 前述のとおりReact.js or Next.jsと一緒にアプリ作成もできた。

### インフラ
- Docker
    - Dockerfileおよびdocker-compose.ymlを自作して、LaravelとMySQLの環境構築ができた。

### その他
- エンジニアになれた
    - 2020年11月23日勉強開始。本当にド素人だったので、HTMLとCSSから始めました。
 HTMLで既に躓きまくって、本当にエンジニアになれるのか不安が凄かった。
    - 2021年5月31日ポートフォリオデプロイ。
    - 2021年6月17日内定2社。(受託会社1社、自社開発1社)
    - 2021年10月1日勤務開始。
- Qiita記事執筆。
    - 数多の親切なQiita記事に助けられてきたので、自分も僅かながら力になりたく、3本記事執筆。
    - コード書いて終わりの記事ではなく、何故そう実装したかに焦点を当て、他の人に読んでもらうことが意識できた。
- 勉強会出席
    - ゆーたろーさん主催の「つながる勉強会」に出席。
    - エンジニアの醍醐味とも言える横の繋がりができて、とても楽しかった。前職の営業時代にはあり得なかった・・・。

# 今年やりたいこと
### フロントエンド
- 最優先でReact.js & Next.jsに取り組む。自己学習だとどうしても進みが遅いので、業務で使いたい。
今はVue.jsのプロジェクトにアサインされているので、まず副業でReact案件を探せたらいいなと思っている。
- Vue.jsは業務をこなしながらキャッチアップ。3系が主流になりそうなら本格的にキャッチアップするかも。
- TypeScriptは自分で学習を進めるよりも既存コードから見て盗む方向でとりあえず学習。
TypeScript単体で学習してもあんまり成果なさそうなので。
- CSSの知見が弱々しすぎるので、どこかで時間を取って基礎を身につけたい。ただマークアップ方面を伸ばしたいわけではないので、そこまで時間は割かない。
- webpackの知見が弱弱しすぎるので、こちらも基礎を身に着けたい。(babelもだけど、webpackやる中で出てきそうなので割愛)

### バックエンド
- 全体として優先度はフロントエンドより下。実務で使えそうなら優先度上げる。
- とりあえず引き続きLaravelを触っていこうと思っているが、実務で使えるか分からないし、それならフロントの足しになるNode.jsもありか・・・？

### インフラ
- 知見がなさすぎるので、基礎を身につけたい。
- 作成しているNext.js × LaravelをAWSでデプロイしたい。

### その他
- Qiita執筆と勉強会出席は引き続き行う。
- React案件の副業を探す。

# おわりに
エンジニア転職という目標は達成できたので、昨年は大成功の年になったな〜と思っている。
とは言えスタートラインに立っただけなので、もっと技術力を上げていきたい。

# 作成したアプリのリポジトリ
- 転職時のポートフォリオ
    - Nuxt.js × TypeScript × Firebase

https://github.com/chillout2san/nuxt_firebase_todoapp

- 学習用で作った簡単なCRUDアプリ
    - React.js × TypeScript × Laravel × Docker

https://github.com/chillout2san/laravel_crud

- 学習用で目下作っているCRUDアプリ(ポートフォリオのリプレイス)
    - Next.js × TypeScript × Laravel × Docker

https://github.com/chillout2san/next_laravel_todoapp
migrationファイルのadd_indexは何なのか

##add_indexとは
よくマイグレーションファイルに``add_index :~``と記述があるがいまいち何でこれを書いているのか分からなかったので、調べてみた。

``add_index:``とは特定のカラムからデータを取得する際に、``テーブルの中の特定のカラムのデータを複製し検索が行いやすいようにする``ための記述。

多くのデータを格納するテーブルの、格納される値がそれぞれ異なるようなカラム(unique制約のかかったカラムなど)の中で、``検索がよく行われるカラム
に対してadd_indexの記述を張ることで検索を簡単にしたいときに使う。``

##記入法

```
add_index :追加したいテーブル名, カラム名, 必要ならオプション名

#記入例
class CreateBookmarks < ActiveRecord::Migration[5.2]
  def change
    create_table :bookmarks do |t|
      t.references :user, foreign_key: true, null: false
      t.references :board, foreign_key: true, null: false

      t.timestamps
    end
    add_index :users, :email, unique: true ⬅️ここ
  end
end

```

indexのオプションとして以下のようなものがある。

|オプション | 説明 |
|:-:|:-:|
| :name  | インデックスの名前  |
|  :if_not_exists |  カラムがすでに存在している場合は再追加を行わないように指定 |
|  :unique | trueを指定するとユニークなインデックス  |
| :length  |  インデックスに含まれるカラムの長さ |
[▶︎その他オプションはここ](https://railsdoc.com/page/add_index)

##参考記事
[deviseの add_index :users, :email, unique: true　記述について](https://qiita.com/tech_hack_Rich/items/01662f33c9ed405fa51b)
Vuex(Store)で保存したデータがリロードすると消える

## はじめに
フロントエンドにNuxt.jsを使用し開発中、Vuexに保存した情報が
リロードすると消えてしまって少しはまったその備忘録

## 環境
macOS
Nuxt.js Rails Docker postgresql

## Storeについて
【Nuxt.jsでStoreにデータを保存するメリット】
componentsでもStoreから直接データを持ってこれる
※ Storeを使用しないとProps/emitを使用し各componentsへデータを渡さないといけない

## 対策
 [vuex-persistedstate]を導入し
Storeに保存されたデータを[LocalStorage/SessionStorage]へ保存し
リロード時にデータを照合しStoreのデータを復元する
※今回はlocalStrageに入れます

## vuex-persistedstate導入
```
root $ docker-compose run front yarn add vuex-persistedstate
```

## localStrage.js作成
```
front $ touch plugins/localStrage.js
```

```localstrage.js
import createPersistedState from 'vuex-persistedstate'

export default ({ store }) => {
  createPersistedState({})(store)
  // storage: window.sessionStorage // ←sessionStrageに保存したい場合はコメントアウトを外す
}
```

```Nuxt.config.js
 plugins: [
    { src: '~/plugins/localStorage.js', ssr: false } //追加
  ],
```

これでStoreに保存された情報がlocalStrageにも保存されるようになる。
リロード時はlocalStrage内のデータと照合しStore情報とloalStrageを同期してくれる

### 最後に
注意：個人情報など他者にデータをとられてはいけないデータは情報漏洩につながるのでlocalStrageへの保存はNG!!

お疲れ様でした
ClipyやGasMaskなどの開発ツール設定値エクスポート方法

#　目次
[1.はじめに](#1-はじめに)
[2.各開発ツール](#2-各開発ツール)
[3.参考サイト](#3-参考サイト)

#1. はじめに
パソコンの引越しが発生するため、開発で使用しているツールのバックアップ方法をまとめた。
エクスポートするツールはIntellijのようにあるが、Clipy や GasMask はエクスポートのような機能はないようなので、手動でコピーしてバックアップするしかないと思ったが、手動でバックアップより、良い方法があったのでメモ残しておく。

#2. 各開発ツール
###1. Intellij
1. File
2. Manage IDE Settings
3. Export Settings
4. Zipファイルを保存する場所を選択
5. OKボタン押下

###2. Clipy
1. Clipyを起動する
2. メニューを開く
3. 「スペニットを編集...」を選択
4. エクスポートを押下
5. xmlファイルを保存する名前と場所を選択
6. 保存を押下

###3. Gas Mask
1. Show Editor Windowを押下
2. 左側に作成しているHostsファイルを右クリック
3. 「Show In Finder」を押下
4. Finderが開く
5. Finderで開いた設定ファイルをバックアップする
6. 引越し先でバックアップしたファイルをGasMaskのフォルダに格納する

Gas Maskのフォルダ構成的には以下のようになっているので、想定しているディレクトリに配置する。


```
ライブラリ
└── Gas Mask
    ├── Combined
    ├── Local
    └── Remote
```

#3. 参考サイト
- https://www.jetbrains.com/ja-jp/idea/
- https://clipy.softonic.jp/mac
- https://github.com/2ndalpha/gasmask
- https://pleiades.io/help/idea/sharing-your-ide-settings.html#import-export-settings
tomcat とは

## 勉強前イメージ

apacheにのっかってるやつ？
正直説明できるイメージではない

## 調査

### tomcat とは

正式名称はApache Tomcatで、オープンソースになります。
Javaを使用してアプリケーションサーバを構築するためのソフトウェアです。

### そもそも・・・

Javaを使ってアプリケーションサーバを構築するには
`Javaサーブレット` と `JSP` がよく知られている技術になります。
TomcatはJavaサーブレットとJSPの公式参考実装として開発・実装されています。
TomcatはJavaサーブレットを動かす際に使用され、ページを動的にすることができます。

### Apacheとの関連性について

TomcatはTomcat単体でwebサーバとして動作します。
しかし、一般的なwebサイトは静的コンテンツが多く、
Java VMのTomcatで動作させると非効率になります。
そのため静的なコンテンツはApache、動的なコンテンツはTomcatというふうに
振り分けをApacheのTomcatコネクタというモジュールで処理することができます。

## 勉強後イメージ

Tomcat単体でwebサーバになるとは知らなかった・・・
要するにTomcatを使えばJavaのプログラムがweb上で動かせるよ！
apacheと併用したら効率的だよ！ってことかな？

## 参考

- [Tomcatとは](https://www.designet.co.jp/faq/term/?id=VG9tY2F0)
- [Tomcatを利用するメリットとデメリット｜インストールまでの4つの手順](https://www.fenet.jp/infla/column/server/tomcat%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%E3%81%A8%E3%83%87%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%EF%BD%9C%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC/)
マイグレーション

###マイグレーションとは？
データベースにどのようなテーブルを作成するのかを定義し作成する機能です。

テーブル定義とは、カラムの名前・データ型・制約などを記述します。


###マイグレーションファイル作成方法
Artisanコマンドを使用します。

```
php artisan make:migration マイグレーションファイル名
```
例）↓↓

```
php artisan make:migration create_posts_table
```

実際に作成されたコードは下記のようなコードになります。

```php:2022_01_07_000515_create_posts_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}
```
中を見るとup()メソッドとdown()メソッドがあります。
up()メソッド内にテーブルの定義を作成していきましょう。
down()メソッドには削除コードを記述していきます。(ロールバック)

###マイグレーションの実行
下記Artisanコマンドに入力によりデータベースのテーブルに反映されます。

```
php artisan migrate
```

テーブル作成は以上となります。
web3.pyでhardhat_resetを実行する方法


hardhatのethノードでは、hardhat_resetなどの特殊なコマンドが使える。web3.pyでそのコマンドを使う方法を紹介する

## hardhat用のモジュール

web3.pyはモジュールで機能を拡張できる。w3.ethなどもモジュールとして実装されている。w3.ethの実装を参考に以下のように書いたら、hardhatコマンドを使えるようになった。

```python
# license: CC0
from web3.module import Module, Method
from web3.types import RPCEndpoint

class HardhatModule(Module):

    def reset(self):
        return self._hardhat_reset()

    _hardhat_reset = Method(RPCEndpoint("hardhat_reset"))

```

## hardhat用のモジュールの使い方

w3にモジュールをattach_modulesで注入する。

```python
# license: CC0
import os
from unittest import TestCase
from web3 import Web3
from web3._utils.module import attach_modules
from src.hardhat_module import HardhatModule


class TestHardhatModuleReset(TestCase):
    def test_reset(self):
        external_modules = {
            'hardhat': (HardhatModule, )
        }
        w3 = Web3(Web3.HTTPProvider(os.getenv('WEB3_PROVIDER_URI')))
        attach_modules(w3, external_modules)

        w3.hardhat.reset()
```

## v5.25.0には含まれていないが、masterにあるexternal_modules

以下のPRでexternal_modulesが追加されて、実装詳細(from web3._utils.module import attach_modules)に依存しなくてよくなったらしい。まだ、pipの最新版(v5.25.0)には含まれていないらしい。

https://github.com/ethereum/web3.py/pull/2288
PythonでHeapを実装してみる

Heapのデータ構造を理解するためにPythonで書いてみました。

```python
class Heap:
    def __init__(self) -> None:
        self.heap = []

    def push(self, x):
        self.heap.append(x)
        i = len(self.heap) - 1
        while i > 0:
            p = (i - 1) // 2
            if self.heap[p] >= x:
                break

            self.heap[i] = self.heap[p]
            i = p
        self.heap[i] = x

    def top(self):
        if len(self.heap) != 0:
            return self.heap[0]
        else:
            return -1

    def pop(self):
        if len(self.heap) == 0:
            return
        x = self.heap.pop()
        i = 0
        while i * 2 + 1 < len(self.heap):
            child_left = i * 2 + 1
            child_right = i * 2 + 2
            if (
                child_right < len(self.heap)
                and self.heap[child_right] > self.heap[child_left]
            ):
                child_left = child_right
            if self.heap[child_left] <= x:
                break
            self.heap[i] = self.heap[child_left]
            i = child_left
        self.heap[i] = x

# 検証コード
def test_myheap():
    h = Heap()
    h.push(5)
    h.push(3)
    h.push(7)
    h.push(1)
    assert h.top() == 7
    h.pop()
    assert h.top() == 5
    h.push(11)
    assert h.top() == 11

```

## Pythonのライブラリのheapqはどんなもん？

こちら。

https://github.com/python/cpython/blob/main/Lib/heapq.py

`push()`や`pop()`をする際の木構造の構築しなおしを、`_shitup()`や`_shitdown()`とくくりだしていてスマートだなぁ。
「mac with intel chip」と「 mac with apple chip」どちらが良いのか確認する方法

#はじめに
![スクリーンショット 2022-01-06 21.23.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/e4580c52-4208-0a6a-c582-bc98a975b8c8.png)

https://developer.android.com/studio?hl=ja

Android Studioをダウンロードしようとすると、👆のような選択肢が出てきた。
はたしてこれはどっちを選ぶべきなのだろうか？

#「intel chip」と「apple chip」の違いは？
端的に言うと
**・新しいもの＝apple chip**
**・古いもの＝intel chip**

です。

>2020 年後期に発売された一部のモデルから、Apple は Mac の Intel プロセッサを Apple シリコンに移行していきます。
https://support.apple.com/ja-jp/HT211814

従来のモデルにはIntel（インテル）のCPUが使われてましたが、最新のものではApple M1チップ(通称Apple Silicon)が搭載されるようになってるようです。

**要するにCPU（のようなもの？）がintelのもから、Apple独自のチップに変わっていくと言うことです！**

#自分のMacはどっち？
`Appleメニュー＞このMacについて`
![スクリーンショット 2022-01-06 21.39.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/10437757-3fdb-bd1e-cb6c-f2e2c73cde6e.png)

![スクリーンショット 2022-01-07 22.54.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/9de7cd28-cc10-7938-e57d-7b8410c475d4.png)


**👆これはApple M1チップ(通称Apple Silicon)なので、Android Studioのダウンロード時は「 mac with apple chip」を選択しましょう。**

![macos-mojave-about-this-mac-overview-version-build.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/d5943221-bd81-523c-e76c-a3a5973decf9.jpeg)

**👆これはintelなので、Android Studioのダウンロード時は「 mac with intel chip」を選択しましょう。**
[Rails]annotate

# 概要
DBのテーブル定義をmodel、specファイルの上部にコメントで一覧として書き出してくれるgem

# 導入手順

(前提: ver.3.1.1.を導入したときの話)
gem「rspec」, 「factory_bot」を導入済み

```
# 1. Gemfileにannotateを記述
# 2. bundle installを実行
# 3. rails g annotate:installを実行
=>lib/tasks/auto_annotate_models.rakeが作成される
```

# 利用手順

```
# 対象ファイルすべてにコメントを付与
bundle exec annotate
=>以下ファイルすべてにmodelのテーブル定義がコメントとして付与される
- app/models/<model>.rb
- spec/models/<model>_spec.rb
- spec/factories/<models>.rb
```

**参考**

https://github.com/ctran/annotate_models
macOSのキーチェンに保存しているパスワードをコマンドでの表示、追加方法

macOSのキーチェンに保存しているパスワードをコマンドでの表示、追加方法

# 表示
```
security find-generic-password -a アカウント名 -s パスワード名 -w
```

# パスワードの追加

```
security add-generic-password -a アカウント名 -w パスワード -s パスワード名
```

既に保存されている場合は以下のようにエラーが出るので `-U`オプションをつける

`security: SecKeychainItemCreateFromContent (<default>): The specified item already exists in the keychain.`

```
security add-generic-password -a アカウント名 -w パスワード -s パスワード名 -U
```

もちろんキーチェーンアクセスのアプリから変更してもok
【Mac】スクリーンセーバー回避

# PCをスリープさせたくない
スクリーンセーバーの設定が制御されており、自分でコントロールできない場合にスリープさせない方法。
５分間PCを触らないとスクリーンセーバーが発動、なんて設定はよくある話。
「Shiftキーを４分ごとに押す」というプログラムが常時動いていれば問題ナッシング。

# スクリプトエディタで以下を実行

### スクリプトエディタを開く
Macのデフォルトアプリケーション、`スクリプトエディタ`を開いて
![ScreenShot 2022-01-06 20.38.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2045017/311c54bc-83d2-9b49-922d-39e6b2a911ba.jpeg)

### コードを書く
以下を書き込み、実行するだけ。

```
tell application "System Events"
	repeat
		key code 57
		delay 240
	end repeat
end tell
```

### 実行する

再生マークを押して実行中になればOK
![ScreenShot 2022-01-06 20.51.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2045017/565a18cb-1ac6-a495-b7a2-2ef5ca6d0b33.jpeg)

デスクトップにでも保存して、使いたいときに実行してください。


# 実行時にエラーが出たら

以下のエラーが出る場合は、

> System Eventsでエラーが起きました: スクリプトエディタにはキー操作の送信は許可されません。
![ScreenShot 2022-01-06 20.24.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2045017/889954cc-1699-4ae8-d323-91222282f602.jpeg)




システム環境設定で以下を設定

`システム環境設定` → `セキュリティとプライバシー` → `プライバシー` → `アクセシビリティ` → `スクリプトエディタ`
スクリプトエディタにチェックマークを入れて、再実行してみてください。
![ScreenShot 2022-01-06 20.32.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2045017/521cf75a-1942-5555-cd38-bc277663941f.jpeg)
【Rails】memberとcollectionの違い

##``member``と``collection``が使われる理由
どちらもresourcesでroutingを設定しているとき、``resourcesでは自動で生成されないactionへのroutingを設定``するときに使用するもの。

``member``,``collection``ルーティングを行うと、**新たにルーティングした**``〇〇_photo_urlヘルパー``と``〇〇_photo_pathヘルパー``も作成される。

##``member``と``collection``の違いとは
生成するroutingに、``:id``の有無で決まる。

``:id``とは 、URL内に記述されるIDのことである。

```
#rails routes

#id有
/users/:id/follow(.:format)  

#id無
/users/slide(.:format)
```

``menber``はidが**有り、**``collection``はidが**無い。**

**◆member記入例**
この場合は``user resources``に``follow action``のroutingを``member``で追加したとき、生成されたurlにuserを**識別するための:id**が自動で追加される。

```
#member記入例
resources :users do
    member do
      get :follow
    end
end

#結果
follow_user GET    /users/:id/follow(.:format)  users#follow
```

``memberルーティング``が1つだけしかない場合は、以下のようにルーティングで``:onオプション``を指定することでブロックを省略できる。

```
resources :users do
  get 'follow', on: :member
end
```


**◆collection記入例**
memberと同じように、``user resources``に``follow action``のroutingを``collection``で追加したが、``:id``は付与されない。

```
#collection記入例

resources :users do
    collection do
      get :slide
    end
end

#結果
slide_users GET    /users/slide(.:format)      users#slide
```
collectionもmember同様に``:onオプション``を使える。

```
resources :users do
  get 'slide', on: :collection
end
```

###``:onオプション``を使ってアクションを追加
また、``:onオプション``を使って、たとえば以下のように別のnewアクションを追加することもできる。

```
resources :users do
  get 'follow', on: :new
end
```

上記のようにすることで、GET + ``/users/new/follow``のようなパスが認識され、Usersコントローラのfollowアクションにルーティングされる。

##まとめ
◆ ``:id ``を**使用した**アクションの場合は``member``を使用する。
◆`` :id ``の**必要ない**アクションの場合は ``collection`` を使用する。

##参考記事
[railsのroutes.rbのmemberとcollectionの違いをわかりやすく解説してみた。〜rails初心者から中級者へ〜](https://qiita.com/hirokihello/items/fa82863ab10a3052d2ff)
[Railsガイド](https://railsguides.jp/routing.html#restful%E3%81%AA%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E3%81%95%E3%82%89%E3%81%AB%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)
【最終回】コロナ禍だから何かできることをー　自宅療養者連絡ツール　ー

#まえがき
2022年1月。

新年早々に第６波が発生しそうな予感がします。
前回の第５波のように自宅待機者がたくさん出てくるのでは？
そして、担当者の方々が緊急事態となり、労基法の適用外になるほど働くことになるのではないか
心配でなりません。

そこで、前回から作成していたLINEを使った自宅療養者管理ツールを紹介します。

前回までの目次は一番下にあります

# 更新履歴

2022/01/13　LINE内LIFFのユーザー登録時、i-phoneの端末でユーザーIDが入力できないのを修正
2022/01/16　LINEbotでユーザー登録時に登録できなかった不具合を修正
2022/01/16　ステータス完了時にＬＩＮＥでＢｏｔで利用できない事と、別途担当連絡先をリプライするように修正

#イメージ動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/huckVYRFGzE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>



#コロナ禍だから何かできることをー　自宅療養者連絡ツール　ー
[【第一回】実装イメージ図と動画](https://qiita.com/STYLE-D/items/743bbecae1c52be15505)
[【第二回】LINEからデータを取得して返すまでの流れ](https://qiita.com/STYLE-D/items/9e0addd8df44be8590b7)
[【第三回】LINEからデータベースまでの流れ](https://qiita.com/STYLE-D/items/345e9142948c00330e71)
[【第四回】データベースへの更新までの流れ](https://qiita.com/STYLE-D/items/8af17d7f94f5c351ede0)
[【第五回】ユーザー登録の仕組み-LINEbotの設定部分](https://qiita.com/STYLE-D/items/a745bd5faeb68caa1d7c)
[【第六回】ユーザー登録の仕組みLIFFで表示する画面の開発](https://qiita.com/STYLE-D/items/321038c8028eb9e9231f)
[【第七回】データベースの構造](https://qiita.com/STYLE-D/items/71085dc9a04042f33f0e)
[【第八回】WEB画面上でできる機能](https://qiita.com/STYLE-D/items/c32e9098a3948e8f32f2)
[【第九回】まとめ](https://qiita.com/STYLE-D/items/77eb6a8e61ae2201565f)