OmniAICreator/Qiita-1.07M huggingface dataset:
PuTTYgenを利用した秘密鍵の変換

## はじめに
PuTTYgenを利用した秘密鍵の変換についてまとめてみました。

SSHやSFTPで公開鍵認証を使ったログインを行う時に、ペアとなる秘密鍵を使いますが、
制作環境においてそのままの形式では使えず秘密鍵の変換が必要になった時などに参考になれば幸いです。

## 環境
Windows 10
PuTTYgen
　PuTTYgenは以下からダウンロードしました。
　https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

## 今回変換する秘密鍵の形式
###・pem
　~~OpenSSH形式の秘密鍵~~ OpenSSL形式の秘密鍵
　OpenSSH 7.8未満のバージョンでEd25519鍵以外の形式で「ssh-keygen」のコマンドを実行した際に
　デフォルトで作成される形式
###・~~OpenSSL形式~~ OpenSSH形式
　~~OpenSSH形式の秘密鍵~~ OpenSSH独自の形式の秘密鍵
　OpenSSH 7.8以上のバージョンでEd25519鍵以外の形式で「ssh-keygen」のコマンドを実行した際に
　デフォルトで作成される形式
###・ppk
　PuTTY形式の秘密鍵

## ppk → pem
・puttygen.exeを実行
・「Conversions」 → 「Import key」を選択
![インポートキー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/1daf9c0e-21ce-e98a-7e1d-100c01e2ef80.png)
・変換したいファイルを指定して「開く」
![選択1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/fec6cd8d-78ca-2e54-6f3b-ef7a609fe309.png)
・「Conversions」 → 「Export OpenSSH key」を選択
![pem変換.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/f11873a5-1166-886b-4835-f6a637e44ebd.png)
・名前を付けて保存
![保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/281826cc-da8f-31f5-505e-5b74a81a5c87.png)

## ppk → OpenSSH形式
・puttygen.exeを実行
・「Conversions」 → 「Import key」を選択
・変換したいファイルを指定して「開く」
![選択1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/fec6cd8d-78ca-2e54-6f3b-ef7a609fe309.png)
・「Conversions」 → 「Export OpenSSH key(force new file format)」を選択
![おーぷんSSL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/1d741758-f16f-c9fa-a184-b7c1dc8d1440.png)
・名前を付けて保存
![保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/5c0cc952-0129-6352-4563-f1fa748f8ca5.png)

## pem → ppk
・puttygen.exeを実行
・「Conversions」 → 「Import key」を選択
・変換したいファイルを指定して「開く」
![選択2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/345ff665-e039-f086-f894-cc27150b25b6.png)
・「Save private key」を選択
![ppk変換.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/cd4bbc39-7085-795a-8e77-74e28a00f4ea.png)
・名前を付けて保存
![保存２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439739/c882878f-cb13-6c90-6764-3b8768a4fcd8.png)

##参考リンク
・[id_rsa⇒pem⇔ppk 相互変換](http://www.puniokid.com/tips/linux/69/)
・[pemファイルとppkファイルの相互変換](https://ryoheihey.com/pem-ppk-2/525/#toc2)
・[【OpenSSH 7.8】秘密鍵を生成する形式が変更になった件について](https://dev.classmethod.jp/articles/openssh78_potentially_incompatible_changes/)
・[Chapter 8: SSH 認証に公開鍵を使う](https://www.ranvis.com/doc/putty/man/Chapter8.html#puttygen-conversions)
LaravelでFontAwsomeを使う方法

タイトル通り、LaravelでFontAwsomeを使う方法を２種類以下に書いていく。あくまでも自分の備忘録。

Ver７系
すでに、Laravel Mixが使える環境にある。

### CDNを使う方法
これは、他の記事を見るように。

### インストールして使う方法

プロジェクト上で、

```
npm install @fortawesome/fontawesome-free
```
を実行。

その後、グローバルに登録するために、app.jsに以下を追加。

```js:/resources/js/app.js
import '@fortawesome/fontawesome-free/js/fontawesome';
import '@fortawesome/fontawesome-free/js/solid';
import '@fortawesome/fontawesome-free/js/regular';
```

これでhtmlで使えるようになった。npm run watchやscriptタグでのapp.jsの読み込みを忘れずに。

```html:index.html
<head>
    <script src="{{ mix('js/app.js') }}" defer></script>
</head>

<body>
    <div id="app">
        <i class="fas fa-dog fa-3x"></i>
    </div>
</body>
```

わんちゃんが出現～。

以上。
オープンソースCCTVソリューション

##はじめに

こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html

###目的
![camera-712122_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/330e4326-0b71-ea92-0ffd-708408030767.jpeg)



3つの信頼できるオープンソースCCTVソリューションを紹介したいと思います。

##KERBEROS.IO
![kerberos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/e7f1f524-78ec-9185-32c9-82e2bdfce5d9.png)

**ホームページから:**
>Kerberos.ioはビデオ監視ソリューションであり、あらゆるカメラとすべてのLinuxベースのコンピューターで動作します。 完全に構成されたビデオ監視システムを、Raspberry Pi、Docker、Kubernetesクラスターなどの好みの環境に数分の間でデプロイできます。 優れたUXとスケーラビリティは、その主要な差別化要因の1つです

![Screen Shot 2020-09-28 at 15.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/dddcb5aa-c70f-a688-68d6-a60a70370db1.png)


####主な機能
- docker、kubernetes、raspberryで利用可能
- セットアップが簡単
- 良いのUXデザイン
- オンプレミスまたはクラウドの両方をサポート
- USBカメラ、 Raspberry Piカメラ、IPカメラをサポート
- 動き検出 (AI)

https://kerberos.io/

##ZoneMinder
![zm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/2a7f79dc-55d5-377a-11c6-9be27eee36f3.png)

**ホームページから:**
>ZoneMinderは、CCTVまたはセキュリティカメラのキャプチャ、分析、記録、および監視を可能にする完全な監視ソリューションを提供するアプリケーションの統合セットです。

![Screen Shot 2020-09-28 at 16.34.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/62f884ea-2163-3b4d-b1b6-4b381d985ef3.png)


####主な機能
- オブジェクトと人の検出
- BTTVカード、USBカメラ、IPカメラをサポート
- dockerで利用可能
- 動き検出 (AI)
- AWS S3 サポート

https://zoneminder.com/

##Shinobi
![shinobi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/907b3820-0164-b5e9-a46f-2a1cf2e034fb.png)

**ホームページから:**
>Shinobiはオープンソースであり、Node.jsで書かれており、本当に使いやすいです。 これは、開発者とエンドユーザーの両方にとって、CCTVとNVRの未来です。

![shinobi_633867_full.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/87bc5f7e-0e2b-fb42-9dbe-1f28ce02d2b8.jpeg)


####主な機能
- サポートされている多くのビデオフォーマット
- CPU使用率が低い
- 監視するエリアを選択できます (AI)
- 動き検出 (AI)
- dockerで利用可能

https://shinobi.video/

###情報源
https://kerberos.io/
https://www.zoneminder.com/
https://shinobi.video/
https://pixabay.com/photos/camera-spy-pigeon-surveillance-712122/
https://www.youtube.com/watch?v=517dptJhF5g
[EC2]インスタンスタイプの基本


## 勉強前のイメージ

EC2のインスタンスは大体適当に使うんだったらt2.microとかsmallとか...
あとはCPUとメモリでえいやーで決めてた

## 調査

### EC2インスタンスのネーミングポリシー

![プレゼンテーション1 - PowerPoint 2020-09-29 20.49.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/17c63048-b65f-5d69-5c2c-310c3791b95a.png)

**t3a.2xlarge** : インスタンスタイプ

- t : インスタンスファミリー
- 3 : インスタンス世代
- a : 追加機能
- 2xlarge : インスタンスサイズ

### インスタンスファミリー

特徴を持った、5つのカテゴリに分類される

- 汎用
- コンピューティング最適化
- ストレージ最適化
- メモリ最適化
- 高速コンピューティング

#### 主なインスタンスファミリーの表

| カテゴリ | ファミリー | ユースケース |
|:-:|:-:|:-:|
| 汎用 | A1, T3, T3a | 開発環境,web,マイクロサービス |
| 汎用 | M5, M5d, M5a | 小中規模のDC,キャッシュサーバ |
| コンピュー ティング 最適化 | C5, C5d, C5n | バッチ処理,動画エンコーディング |
| ストレージ 最適化 | H1 | BigData処理、分散型ファ イルシステム |
| ストレージ 最適化 | I3, I3en | NoSQLデータベース,分散型ファイルシステム |
| メモリ 最適化 | R5, R5d, R5a | ハイパフォーマンスDB,BigData処理 |
| メモリ 最適化 | X1, X1e | インメモリDB,ハイパ フォーマンスDB |
| メモリ 最適化 | Z1d | 電子設計(EDA),RDB |


### インスタンス世代

世代が進むにつれて、数字が大きくなる
世代が新しい(数字が大きい)方が高性能でコスパも高いので、基本的には最新を使うのが推奨されている。

### 追加機能


| 追加機能 | 文字列 | オプション表記 |
|:-:|:-:|:-:|
| 標準に対して内蔵ストレージ付加  |  d | C5**d**, M5**d**, R5**d**, Z1**d**, P3**d**n  |
|  標準に対し てネットワークを強化 | n  |  C5**n**, P3d**n**, I3e**n** |
|  AMDのCPUを搭載 |  a |  M5**a**, R5**a** |
| 従来よりCPU,メモリ搭載 量が異なる etc.  | e,s...  |  X1**e**, G3**s**, I3**e**n |

`P3dn` だと、内蔵ストレージが付加されネットワークも強化されたことがわかります。

### インスタンスサイズ

インスタンスサイズにより、
CPU・メモリ・ネットワークのキャパシティによって分類される。

下記の表はc5インスタンスのサイズとキャパシティになります。

| タイプ | CPU | メモリ | EBS帯域幅 | NE帯域幅 |
|:-:|:-:|:-:|:-:|:-:|
| c5.xlarge   | 4  | 8GiB   | 最大2.25Gbps | 最大10Gbps |
| c5.2xlarge  | 8  | 16GiB  | 最大2.25Gbps | 最大10Gbps |
| c5.4xlarge  | 16 | 32GiB  | 2.25Gbps     | 最大10Gbps |
| c5.9xlarge  | 36 | 72GiB  | 4.5Gbps      | 10Gbps     |
| c5.18xlarge | 72 | 144GiB | 9Gbps        | 25Gbps     |

インスタンスサイズは
nano → micro → small → midium → large → xlarge ....の順に大きくなり、
サイズが大きくなるとCPU・メモリがそれぞれ倍程度大きくなり、費用も増加する

### EC2インスタンスのネーミングポリシーおさらい

![プレゼンテーション1 - PowerPoint 2020-09-29 20.49.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/17c63048-b65f-5d69-5c2c-310c3791b95a.png)

**t3a.2xlarge** : インスタンスタイプ
- t : インスタンスファミリー : `web環境とか開発環境みたい`
- 3 : インスタンス世代 : `最近のかな？コスパ良さげ`
- a : 追加機能 : `CPUはAMD製を使ってる`
- 2xlarge : インスタンスサイズ :  `CPU:8, メモリ32GB`

## 勉強後のイメージ

それぞれ(わかってたけど)ちゃんと意味があった。
基本的に、

- ちょっと作ってみよう → t3 とか
- DCを乗っけてみよう → m5 とか
- バッチを処理しよう → c5 とかかな。

ほかはあまり使わなさそうだけど、知れてよかった。

## 参考

- [AWS初心者 入門編 EC2のインスタンスタイプが多すぎて、どれを選べばいいか分からない問題に立ち向かう](https://www.bit-drive.ne.jp/managed-cloud/column/column_22.html)
- [「Amazon EC2 インスタンスタイプ」](https://aws.amazon.com/jp/ec2/instance-types/)
- [EC2 インスタンスタイプの種類や選び方！AWS初心者向けに今一度整理](https://techblog.forgevision.com/entry/aws-ec2-instance-bgr)
- [【AWS】 EC2のインスタンスタイプを解説します。](https://www.acrovision.jp/service/aws/?p=1712)
- [Amazon EC2
インスタンスタイプの選び方ガイド](https://pages.awscloud.com/rs/112-TZM-766/images/C2-07.pdf)
PyAudio のサンプル

PyAudio のサンプルです。

録音

```py:record.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	record.py
#
#						Oct/02/2020
# ------------------------------------------------------------------
import	sys
import	pyaudio
import	wave

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
CHUNK = 1024
FORMAT = pyaudio.paInt16 # int16型
CHANNELS = 2             # ステレオ
RATE = 44100             # 441.kHz
RECORD_SECONDS = 5       # 5秒録音
WAVE_OUTPUT_FILENAME = sys.argv[1]

sys.stderr.write(WAVE_OUTPUT_FILENAME + "\n")

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

sys.stderr.write("* recording *\n")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

sys.stderr.write("* done recording *\n")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```bash
./record.py output.wav
```

再生

```py:play.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	play.py
#
#						Oct/02/2020
# ------------------------------------------------------------------
import	pyaudio
import	wave
import	sys

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
CHUNK = 1024

if len(sys.argv) < 2:
	print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
	sys.exit(-1)

sys.stderr.write(sys.argv[1] + "\n")

wf = wave.open(sys.argv[1], 'rb')

# instantiate PyAudio (1)
p = pyaudio.PyAudio()

# open stream (2)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
				channels=wf.getnchannels(),
				rate=wf.getframerate(),
				output=True)

# read data
data = wf.readframes(CHUNK)

# play stream (3)
while len(data) > 0:
	stream.write(data)
	data = wf.readframes(CHUNK)

# stop stream (4)
stream.stop_stream()
stream.close()

# close PyAudio (5)
p.terminate()
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行方法

```bash
./play.py input.wav
```

参考ページ
[PyAudio Documentation](https://people.csail.mit.edu/hubert/pyaudio/docs/)
Laravel 6.x データベース操作の種類 DBクラス・クエリビルダ・Eloquent ORM

##作業環境
Windows 10
Laravel : 6.18.35
Laravel/ui : 1.0
Laravel-mix : 5.0.1
Bootstrap : 4.0.0
MDBootstrap : 4.19.1
chart.js : 2.9.3
XAMPP
PHP : 7.4.3
Visual Studio Code

##はじめに
この記事はプログラミングをはじめたばかりの素人が、メモするのに利用しています。
内容には誤りがあるかもしれません。

Laravelを学習している中で、データベースの操作の違いがわからなくなってきたので、まとめる為に書いてます。

##操作の種類
Laravelでのデータベースの操作には、大きく分けて3つの方法がある。

①DBクラスによる操作
②クエリビルダによる操作
③Modelクラス(Eloquent ORM)による操作


##それぞれの違い

|項目|DBクラス|クエリビルダ|Eloquent ORM|
|:---|:---:|:---:|:---:|
|Modelが必要|×|×|○|
|クエリビルダが使える|×|○|○|
|SQLインジェクション対策有り|×|○※Row使用時は対策が必要|○※Row使用時は対策が必要|
|テーブルのタイムスタンプ更新|×|×|○|

DBクラスもクエリビルダもIlluminate\Support\Facades\DBクラス（ファサード）による記述方法ですが、ModelクラスはIlluminate\Database\Eloquent\Modelクラスを継承するため仕組みが異なる。

####DBクラス

```SQL
DB::SQL値(SQL文、パラメータ配列)で記述する方法でデーターべースを操作します。
```

SQL文をそのまま使用するイメージで記述できるため、SQLを理解している人にはわかりやす記述方法。

####クエリビルダ

```SQL
DB::table('テーブル名')->DBメソッド のように記述して操作します。
```

SQL文を生成するためのメソッドを、メソッドチェーンで記述することによりデーターベースを操作する。
ほぼSQL文と同じように記述できる。
SQLインジェクション対策有り。

####モデルクラス(Eloquent ORM)

```SQL
モデルクラスでは クラス名::メソッド() のように記述してクリエビルダでデータベースを操作します。
```

Eloquentを使用したデータベースの操作です。
SQLインジェクション対策有り。
Modelを使用する為、テーブルのタイムスタンプの更新が自動で行われる。
テーブルのcreated_at updated_atを更新できる。

##記述の違い
ここではデータベース上のusersテーブルから、全値を取得し$usersに代入するまでの記述の違いを比較します。


####DBクラス

```PHP
use Illuminate\Support\Facades\DB;

$users = DB::select('SELECT * FROM users');
```

####クエリビルダ

```PHP
use Illuminate\Support\Facades\DB;

$users = DB::table('users')->get();
```

####モデルクラス(Eloquent ORM)

```PHP
use App\Models\User;

$users = User::all();
```
回帰分析の複数出力モデルを作る【初級】

機械学習でやってみたくなるのが、複数の答えを出させるAIの作成です
なんとかそれっぽい感じで動いたので、備忘録ですが投稿しました

## 試行環境

| ソフトウェア | バージョン |
|:--|:-:|
| Google Colaboratory | 2020-10-01 | 

## 実装コード

### モデル

```python
def build_model():
  inputs = layers.Input(shape=(len(train_dataset.keys()),))
  x = layers.Dense(64, activation='relu')(inputs)

  a = layers.Dense(64, activation='relu')(x)
  output_a = layers.Dense(1, name='bmi')(a)

  b = layers.Dense(64, activation='relu')(x)
  output_b = layers.Dense(1, name='life_expectancy')(b)

  model = keras.Model(inputs=inputs, outputs=[output_a, output_b], name='Health')

  model.compile(
      optimizer=tf.keras.optimizers.RMSprop(0.001),
      loss_weights=[1., 0.8],
      loss=['mse', 'mse'],
      metrics=['mae', 'mse'])

  return model
```

いきなりですが、実際に試したコードが上記です
サンプルコードなどでよく使われている`keras.Sequential`などは出力が一つだけのようです
一度に複数の何かを求めたい場合は`functional API`でModelを定義しないといけないようです
例えば、ツイート内容から"リツイート"と"いいね"の数を予測するなどです

出力したい値は追加していくレイヤーの出力結果を変数に記憶しておき、それを`Keras.Model`の引数`outputs`に配列で渡すことで、いくらでも出力を増やせるようです

また、`loss`に配列で損失関数を指定することで、それぞれの出力に対して評価方法を変更できるようです

### 教師データ

| height | weight | bmi | sex | birthday | life_expectancy |
|:--|:-:|:-:|:-:|:-:|:-:|:-:|
| 161 | 121 | 47 | female | 1982-02-01 | 40 |
| 154 | 55 | 23 | female | 2005-08-09 | 72 |
| 172 | 64 | 22 | male | 1976-09-21 | 37 |

身長、体重とBMI、余命を関連づけた架空のデータを作りました
身長、体重、性別、生まれ年からBMIと余命を予測するモデルを作成します

### 訓練
```python
model.fit(train_data, [train_label_a, train_label_b], epochs=100)
```

訓練する際は、`fit`にデータと教師データを配列で渡します
辞書形式で渡すと誤差のフィードバックが上手くいかずに学習できないようです
よくある画像分析系は`tf.data.Dataset`で大きな画像データを上手に処理していますが、これも辞書型式のようなので、複数出力モデルで学習に失敗しました
しかも`tf.data.Dataset`で渡す場合データとラベルをセットした状態で渡すのでさらにチンプンカンプン orz

追記：
tf.data.Datasetでデータを渡すときは、辞書のキーとモデルの出力名を合わせることでフィードバックすることができました

```python
ds = tf.data.Dataset.from_tensor_slices((normed_train_data, {"bmi": train_labels.bmi, "life_expectancy": train_labels.life_expectancy}))
ds = ds.batch(BATCH_SIZE)

model.fit(ds, epochs=100)
```

## おまけ
書きながら動かしながら確かめたコードの全体です
Colaboratory にて公開しています

[回帰問題-BMIと余命を予測](https://colab.research.google.com/drive/1ws4KaYfPN10x9kgGhDR5uG6p2ykw4N9S?usp=sharing)

## さいごに
気張って機械学習に関して書いてみましたが、さっぱりわからないまま五里霧中です
それゆえ、記事中の語尾が"〜ようです”ばかりになっていますがご容赦ください

機械学習の精度自体は想像以上で、学習データに偏りがなければ少ないデータでもかなりの予測精度が出るようです
例外的なものや学習データに恵まれなかったようなパターンではヘンテコな数値が出たりするので、こういったものをどこまで詰めていけるかが・・・ボンジンとの差になっていくのだろうなーと感じました

## 参考
[functional APIでKerasを始めてみよう](https://keras.io/ja/getting-started/functional-api-guide/)
[活性化関数「Tanh」「Sigmoid」「ReLu」の仕組みと使い分けを数式なしで整理する／ディープラーニング](https://arakan-pgm-ai.hatenablog.com/entry/2018/11/07/090000)
[隠れ層と隠れニューロンはいくつにするべきなのか？](https://webbigdata.jp/ai/post-1491)
Insider PreviewなどなしにWSL2を使う (2020年10月ver.)

何番煎じか分からないですが、日々変化している話だと思うので記録しておきます。これは20201001時点での作業ログ。

# 事前に知っておくと良い情報

- [Windows10 バージョン1903/1909にもWSL2が来ている](https://forest.watch.impress.co.jp/docs/news/1272017.html)
  - 自分のマシンも含めて[2004がまだ届いていない人はいる](https://snow-white.cocolog-nifty.com/first/2020/09/post-6bf1ed.html)ようなので、ありがたい
- [WSL1で動かしているマシンはWSL2に変換できる](https://variable.jp/2020/06/06/wsl1からwsl2への更新/)
- WSL2ではIPアドレスが起動ごとに毎回変わる

# できたいこと
- WSL2側に開発案件のgitリポジトリを置く
- それをVSCode Remote Developmentの一機能であるremote WSLによってWin側にファイルを持つのと同じ感覚で編集する
- 開発案件がWebアプリなら、WSL2の内側で立てたWebサーバーにWin側のブラウザから簡単な方法で接続できる

# 実際にやった作業
## WSL2化まで
1. (既にWSL1のUbuntu 18.04が手元にある状態からスタート）
2. Windowsのバージョンを調べる → 1909だったが、マイナーバージョンが上記リンク先記載のものより進んでいたのでWSL2の導入が可能と判断
3. PowerShellで以下実行:

    ```
    Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart
    ```

4. [WSL2を操作しようとすると「カーネル コンポーネントの更新が必要です」と表示される](https://qiita.com/quzq/items/3de595e14426d0352fc4)ので、指示に従ってダウンロード、インストールし、とりあえず再起動。
5. WSL2をデフォルトにするためにPowerShellで以下実行
   
    ```
    wsl.exe --set-default-version 2
    ```

6. 今動いているUbuntu 18.04をWSL2に変換 (上記リンク先の手順に従って)

    ```
    wsl.exe --set-version Ubuntu-18.04 2
    ```

# VSCodeで編集、動作確認まで
## ソースを見れるようにする
1. VSCodeにRemote Development Extensionを入れる。これのサブパッケージ(?)にRemote WSLがある
1. VSCodeのremote WSLボタン(?)からUbuntu 18.04側に置いてあるリポジトリを開く
1. Vueterなど当該プロジェクトで必要なプラグインをWSLマシン側にも配置 → この時点でWindows側にソースがあるのとほとんど何も変わらない感覚で開発ができる

## 開発中のWebアプリをWin側ブラウザで見れるようにする
1. 開発中のWebアプリをWSL2側で立ち上げる (自分の場合はnuxtだったのでWSL2の端末から`npm run dev`など)。この時点で都度IPアドレスを調べればそこにWin側ブラウザでアクセスすれば接続できる
1. localhostでアクセスできるようにするために、[.wslconfigを作る](https://qiita.com/snaka/items/a8eee4cfc8f7d733e6ab)。なお設定後[wslの再起動が必要だった](https://192.jp/2020/08/23/connect-services-on-wsl-as-localhost/)。
1. 以後、`http://localhost:3000/` などでWin側ブラウザからアクセスできるようになる


# 補足
任意のGUIアプリを動かすにはWindows側にX Serverが必要になるというあたりはssh先のLinux機と変わらないようです。このあたりもそのうち改善するのではないかと期待しています。
Oracle 圧縮表に"DEFAULT"指定付きのALTER文を適用する方法

表圧縮についてはこちら
https://docs.oracle.com/cd/E57425_01/121/ADMIN/tables.htm

Oracleでは、圧縮表に対して"DEFAULT"指定のALTER文実行すると、以下のように`ORA-39726`エラーが発生する。

```
SQL> alter table SAMPLE_TABLE add SAMPLE_COL char(1) default '0';
alter table SAMPLE_TABLE add SAMPLE_COL char(1) default '0'
                                        *
行1でエラーが発生しました。:
ORA-39726: 圧縮表での列の追加/削除操作はサポートされていません
```
さすがに圧縮表をもとに戻すのも面倒なので、
ALTER文を、列追加とデフォルト値設定の二つの文に分けて実行する。

```
SQL> alter table SAMPLE_TABLE add SAMPLE_COL char(1);

表が変更されました。

SQL> alter table SAMPLE_TABLE modify SAMPLE_COL default '0';

表が変更されました。
```
[CakePHP]HTMLメール用テンプレートのHTMLを取得する方法

CakePHP3.5でプレビュー機能を作るためControllerでHTMLメール用テンプレートのHTMLデータを取得します、。
コードにするとシンプルですが実装に結構手こずったので、忘れないようにメモ。


# サンプルコード

```php:IndexController->preview()
$html = "<p>テスト</p>";
$this->viewBuilder()->setLayout("Email/html/layout_1");
$this->viewBuilder()->setTemplatePath('Email/html');
$this->viewBuilder()->setClassName(null);
$this->viewBuilder()->setName(null);
$this->set('content', $html);
$this->render('contents');
return;
```

```html:src/Template/Layout/Email/html/layout_1.ctp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title><?= $this->fetch('title') ?></title>
  <style type="text/css">
    body {
      color: rgb(35, 73, 108);
      font-size: 15px;
      padding: 10px 8%;
    }
  </style>
</head>
<body>
  <div class="container">
  	<?= $this->fetch('content') ?>
  </div>
</body>
</html>
```

```html:src/Template/Email/html/contents.ctp
<?= $content ?>
```



# 余談：生のHTMLデータを取得する方法

```php:IndexController->preview()
$content = "<p>テスト</p>";

$view = new \Cake\View\View();
$view->viewBuilder()->setLayoutPath('Email/html');
$view->viewBuilder()->setLayout('layout_1');
$view->viewBuilder()->setTemplatePath('Email/html');
$view->viewBuilder()->setTemplate('contents');
$html = $view->viewBuilder()->build(['content' => $content])->render();
```
Argparseを使ったコードを触らずに出力を変える

今回は、前回作ったモザイク自動生成プログラムを少し改良しました。
Cascade検出器って結構な種類あるので、どれを使えば良いのか、あとはdetectMultiScaleの引数はどの値が1番良いのかというところで悩むと思います。

# 実行環境
[openCVの顔検出でパラメータを指定して手っ取り早く検出精度を高める](https://qiita.com/FukuharaYohei/items/116932920c99a5b73b32)
[ArgumentParserの使い方を簡単にまとめた](https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0)

・MacOS
・python3.6(anaconda)
・opencv
・VSCode

#本来欲しかった機能
本当は、Cascadeはどの検出器を使えば良いのか、detectMultiScaleの引数はどんな値を入れれば良いのかという問題はクリアするために、**最適解を求めてくれる機能**なのかなと思っていたのですが、実は違かったみたいです。


# Argparse
argparseというのを使えば、コマンドラインで実行をする際に、**ファイル名の隣に引数の値**を自分で書き込むことによって、出力を変化させることができるということができます。

#デメリット
ただ、これを使うとプログラムを変更しなくて良いというのはメリットなのですが、結構複雑になってしまうので、面倒くさいなと思う人は別にしなくても良いのかなと思います。

# まとめ
argparseというものの存在をそもそも知らなかったので、今回知れて良かったなと思いました。
本来は最適化した値が返ってくるというものが欲しかったので、もうちょっと調べてそんなライブラリみたいなのがあったら良いなと考えています。
COCO'S朝食バイキング実施店舗一覧PDFをCSV変換

# はじめに
[COCO'S朝食バイキング実施店舗一覧PDFファイルを取得してCSVにする](https://qiita.com//dk4130523/items/b03be4a43afa606cb01b)を
参考にcamelotでPDF変換、PandasでデータクレンジングをしてCSVに変換しました

# 準備

```shell
apt install python3-tk ghostscript
pip install camelot-py[cv]
pip install pandas
```

# データクレンジング
```python
import camelot
import pandas as pd

tables = camelot.read_pdf(
    "https://www.cocos-jpn.co.jp/menu_pdf/bvshoplist.pdf",
    pages="all",
    split_text=True,
    strip_text="\n",
    line_scale=40,
)

# 列名
columns = ["".join(i) for i in zip(*(tables[0].df.head(2).values))]

dfs = [table.df.iloc[3:].set_axis(columns, axis=1) for table in tables]

# 番号振り直し
df = pd.concat(dfs).reset_index(drop=True)
df.index += 1

# 空文字を欠損に置換
df.mask(df == "", inplace=True)

# 実施日が毎日の場合、平日、土日
df["実施日"] = df["実施日"].where(df["ご利用料金"].isnull(), df["ご利用料金"])

# 毎日の店舗情報を補完
df.fillna(method="ffill", inplace=True)

# ご利用料金の列を削除
df.drop("ご利用料金", axis=1, inplace=True)

# 税込金額
adult = (
    df["大人"]
    .str.extractall("([0-9]+)")
    .unstack()
    .rename(columns={0: "大人_税抜", 1: "大人_税込"}, level=1)
)
adult.columns = adult.columns.droplevel(level=0)
df["大人"] = adult["大人_税込"].astype(int)

# 税込金額
child = (
    df["小学生以下"]
    .str.extractall("([0-9]+)")
    .unstack()
    .rename(columns={0: "小人_税抜", 1: "小人_税込"}, level=1)
)
child.columns = child.columns.droplevel(level=0)
df["小学生以下"] = child["小人_税込"].astype(int)

# 住所の列名変更
df.rename(columns={"住所字以降": "住所"}, inplace=True)

# 住所をユニコード正規化、空白除去
df["住所"] = df["住所"].str.normalize("NFKC").str.replace(" ", "")

df.to_csv("cocos.csv", encoding="utf_8_sig")
```

# 参考
[COCO'S朝食バイキング実施店舗一覧PDFファイルを取得してCSVにする](https://qiita.com//dk4130523/items/b03be4a43afa606cb01b)
PyCharm Community Edition with Anaconda plugin 2020.1.2 x64が動かなくなった...

ある日、Python書くかぁとPycharmを開くと

```
java.lang.VerifyError: Expecting a stack map frame~~~~
```

とまぁ、なんかよくわからんErrorを吐き出しやがりました、
Pycharm先生。

とりあえず以下で検索をかける。

```
Pycharm java.lang.VerifyError: Expecting a stack map frame
```
すると以下の記事がヒットしました。

`https://insilico-notebook.com/pycharm-reinstall-error/`

どうやら「pleiades-win」が悪さをしている様子。

上記のディレクトリを開き、再度セットアップすることに。

すると無事にPyCharm先生が戻ってきてくれました。

~~先生って、中には不機嫌になって職員室に引きこもるタイプいますよね...?~~

今回はこれでうまく行ったため、次回同じようなことが起きても大丈夫なようにここにメモします。

使用環境が多少違ったりする場合があるため、
同じ現象の人がこの記事を見てうまく行けばラッキー。

ダメ元でやってみましょう。人生はそんな感じなのです。
備忘録[1] windows10でインストール済みのソフト一覧を取得

#winodows10でインストール済みのソフト一覧を取得
##バッチで実行
参考文献:
http://rukifiel.net/ms-dos-001/
るきふぃえるさん、ありがとうございます！

インストール済みのソフトは以下の2か所のレジストリに保存されているらしい。。。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall]

##pythonでバッチを実行
~~~python
import subprocess as subp

#パスは実行するbatファイルを指定
exec_bat = subp.run([r'C:\\temp\\bat\\dump_list.bat'],shell=True)
~~~
WSL2での「リモートプロシージャコールに失敗しました」に対応

WSL2なubuntuを起動する際に「リモートプロシージャコールに失敗しました」とエラーが出てうまく起動できない問題ですが、2020年10月2日のWindows Insider 向け update KB4578846 にて直っているようです。

これでネットワークの
「\\wsl\Ubuntu-20.04」
にもアクセスができるようになっています。
2020/10/2 朝アウトプット

#基礎振り返り
HTMLCSS
-
-  ブロックレベル要素は横幅いっぱいで表示される四角い箱
-  インライン要素は中身のテキスト量だけ横幅が広がる

 Ruby
-  
- irbコマンドはターミナルから直接Rubyプログラムを動かせる機能を起動する
- lengthメソッドは文字列の文字数を数える
- to_sメソッドは数値を文字列に変換
- to_iメソッドは文字列を数値に変換
- 式展開は文字列のなかで#{式}
neo4jでsandbox その3

#概要

neo4jでsandboxやってみた。
covid-19のクラスター表示。
山形県のデータ投入してみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6b3dc882-eb6e-1b91-1650-87078d1c8215.png)



#サンプルコード

```
LOAD CSV WITH HEADERS FROM "https://gist.github.com/ohisama/20ff770bfda7d9dafbb1fc0e259aeb9f/raw/938b739af1e2627a66a3ee781d0c46559ca61663/covid0.csv" AS line
CREATE (:Person {id:line.id, tiku:line.tiku, tosi:line.tosi, sex:line.sex, date:line.date})

LOAD CSV WITH HEADERS FROM "https://gist.github.com/ohisama/20ff770bfda7d9dafbb1fc0e259aeb9f/raw/938b739af1e2627a66a3ee781d0c46559ca61663/covid1.csv" AS line
MATCH (a:Person {id:line.a}), (b:Person {id:line.b})
CREATE (a)-[:CONNCT]->(b)

MATCH (n)-[r]->(m)
RETURN n, r, m

```
以上。
makerfocusで購入したWIFIKit8用センサーシールド設計しました。

makerfocusで購入したWIFIKit8に温度と湿度と気圧が測定できるBME280を実装しようと計画中
![IMG-5431.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/372dbc2e-03a3-b1ad-6452-44cec604ce03.jpeg)
Amazonで購入したBME280はI2CとSPIどちらでも接続できるタイプ
![WS000052.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/87fb2289-3dd5-5f53-a5e2-4b1e11d1c5c0.jpeg)

まずは、手配線で作ってみました。
ついでに照度センサーもアナログピンに接続してみました。

![119733753_3211485138898828_1265795329978179688_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/d5be9267-3c3e-737d-b691-d4abdbada1fe.jpeg)

動作イメージ
![119948357_3211485102232165_1198163211599549247_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/0d9bc5c6-82ae-044a-97c2-9f0f9cf67e54.jpeg)



手配線はI2Cで配線しましたがOPLEもI2Cで接続されてるのでアドレスの重なりを
調べる手間を考えたらSPI接続した方がいいなと思い
どうせならどちらか選べるkicadでセンサーシールドを設計してみたので回路図と３Dビューワーの写真アップします。

回路図
![WS000050.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/44e6250e-0fe1-4136-57b9-043a115f1509.jpeg)

３Dビューワー
![WS000051.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51752/172d046d-b0ca-6919-bf05-265c778512e4.jpeg)

##工夫した点は２つ
１．I2CとSPIはショートジャンパで設定変えれるようにした
２．アナログリード用コネクタの電源ピンは
　　ESP8266は１vまでしか測定できないため
　　抵抗を分圧して１V出力できるようにしてます。
　　抵抗はチップ抵抗を実装したいところですが
　　アセンブリが簡単で手持ち部品のあるDIPタイプにしました。

##今後の予定
基板を発注して
基板来る間にプログラム制作します。
また出来ましたらこちらにアップします。


##各部品の購入サイト
WIFIKit8
https://www.makerfocus.com/products/0-91-inch-esp8266-oled-display-wifi-development-board-cp2102-support-arduino-ide?_pos=15&_sid=a6cd36349&_ss=r

BME280
https://www.amazon.co.jp/gp/product/B074KBWYX8/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1

照度センサー
https://www.amazon.co.jp/gp/product/B0179BUV92/ref=ppx_yo_dt_b_asin_title_o05_s00?ie=UTF8&psc=1
neo4jでsandbox その2

#概要

neo4jでsandboxやってみた。
練習問題、やってみた。

#このアニメの出演者を表示する。

```
MATCH (n:Anime {name:"ワイルド7"})-[r:ROLE]->(m:Actor)
RETURN n, m
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/25e49309-39fe-7360-eeac-65b837c58ab7.png)

#このアニメの出演者の他の出演作品を表示する。

```
MATCH (n:Anime {name:"ワイルド7"})-[r:ROLE]->(m:Actor)<-[d:ROLE]->(s:Anime)
RETURN n, m, s
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/edd8e647-1374-7103-13a4-c81bb42cb2fc.png)


#全てのnodeとrelashonshipを削除する。

```
MATCH (n)-[r]->(m) 
DELETE n, r, m
```

以上。
Redis の中身をチェックする方法


Redis がきちんと使われているかの確認方法

前提は Amazon Linux 2 で、PHP7.3, php-pearl-redis を使っている場合。
EC2+RDS+ElastiCache 環境。


まずは、Redis CLI をインストール。
僕の場合は、php-pearl-redis しかインストールしていなかったので、redis を EPEL からインストール。


```
$ sudo yum install redis
```

Redis にログイン。
ElastiCache の Redis インスタンスの設定は開発サーバーな小さいインスタンス。

```
$ redis-cli -h XXXX.XXXXX.XX.9999.apne1.cache.amazonaws.com
```

info keyspace を実行

```
XXXX.XXXXX.XX.9999.apne1.cache.amazonaws.com:6379 > info keyspace
# Keyspace
db0:keys=228,expires=114,avg_ttl=394907452
db2:keys=5,expires=5,avg_ttl=6607002
db3:keys=268,expires=134,avg_ttl=400919933
db4:keys=2,expires=1,avg_ttl=397361047
db5:keys=2,expires=2,avg_ttl=7178812
```

これで、どの database で key がいくつ使われているか見ることができる。
僕の場合は、ElastiCache の特定 DB のクリアを確認したかったので、これで十分だった。

以上。
wordpress add_rewrite_ruleでいろいろと試した件

ワードプレスのパーマリンク設定で、投稿記事を

https://somepage.jp/media/%postname%/

にしたところ、
カテゴリーページも

https://somepage.jp/media/category/lesson

という感じになってしまいまいました。


index.php （サイトホーム）は newsカテゴリーだけを表示し、lesson, member紹介はmediaとは異なる見え方をしようかなと思っていたので、urlとしても media配下に置きたくない思いがあります。。


# ゴール

newsカテゴリーの投稿は、メディアページとして

https://sosmepage.jp/media/%postname%/ に

レッスン紹介ページは、レッスン一覧のページとしては
https://somepage.jp/lesson

各レッスン詳細のページは
https://somepage.jp/lesson/voice


同じように講師紹介ページは、講師一覧ページとしては
https://somepage.jp/member

講師詳細ページとしては
https://somepage.jp/member/fumika

というURLで表示する

## 実現方法

新規関数(function)の中から add_rewrite_rule を呼び出し、その関数を、initイベントでフックされるようにする

```
function custom_rewrite()
{
  add_rewrite_rule('lesson/?$', 'index.php?category_name=lesson', 'top');
  add_rewrite_rule('lesson/([^/]+)/?', 'index.php?name=$matches[1]', 'top');
  add_rewrite_rule('member/?$', 'index.php?category_name=member', 'top');
  add_rewrite_rule('member/([^/]+)/?', 'index.php?name=$matches[1]', 'top');
}
add_action('init', 'custom_rewrite');
```

## はまったこと

### その1

add_rewrite_ruleを追記した場合は、設定>パーマリンクの設定 より 「変更の保存」ボタンを押して設定をリフレッシュする必要があります


### その2

最初は、https://somepage.jp/lesson を https://somepage.jp/media/category/lesson に飛ばせば良いのかなと思い

`add_rewrite_rule('lesson/?', 'media/category/lesson', 'top');`
とすればいいかなと思ったのですが、これがうまく動かない。。

## wordpressの裏側では何が起きているのか？

1. index.phpへのrewriteの場合は、.htaccessの RewriteRule についてはいじらず、index.php以降のロジックで何とかする
2. index.phpへのrewriteの場合は、.htaccessに RewriteRuleが追記される

2が曲者なのです。。

```
  add_rewrite_rule('lesson/?', 'media/category/lesson', 'bottom');
```

と記載しても
```
  add_rewrite_rule('lesson/?', 'media/category/lesson', 'top');
```

と記載しても

```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteRule ^lesson/? /media/category/lesson [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
```

となります。Lオプションがついちゃうので、 index.phpにたどり着かないのよね。。
htaccessの書き換えは、add_actionをしただけでは実施されないので、

設定 > パーマリンク設定 で何もせずに 「変更を保存」 を実行することが必要になります

逆に、外部サイトとか、別のサブディレクトリとかに飛ばしたい場合にはよさそう。。

## パーマリンクの設定

なので、add_rewrite_rule には、パーマリンクの設定で記載したURLを書いても意味がないです。。
そのため、wordpress内のカテゴリーページや記事ページを呼び出したい場合は、第二引数に index.php?を指定する必要がありました。

なので、
* 投稿idを指定する場合: index.php?page_id=1 と
* スラグを指定する場合： index.php?name=$matches[1] とか
* カテゴリ一覧を指定する場合： index.php?category_name=lesson 

とかを指定することになります
AtCoderでFortranを勉強するときに使えそうなリンク集

# はじめに
Fortranの知見は少ない上に散らばっているため、苦労することが多いです。有用なリンクをここにまとめておくことで、その苦労を少しでも解消できたら良いな。という軸で記事を書きます。皆さんの知見随時募集中です。

# AtCoderについて

プログラミングで謎解きをするオンラインゲーム(数学要素多め)(レーティングで競える)(伸ばしたコーディングスキルで研究を加速)
[公式サイト](https://atcoder.jp/?lang=ja)
[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～]
(https://qiita.com/drken/items/fd4e5e3630d0f5859067)
[(過去問精選10問のFortranでの回答例1)](https://yukiutaai.wordpress.com/2018/03/21/atcoder%e3%81%ab%e7%99%bb%e9%8c%b2%e3%81%97%e3%81%9f%e3%82%89%e8%a7%a3%e3%81%8f%e3%81%b9%e3%81%8d%e7%b2%be%e9%81%b8%e9%81%8e%e5%8e%bb%e5%95%8f10%e3%82%92fortran%e3%81%a7%e8%a7%a3%e3%81%84%e3%81%a6/)
[(過去問精選10問のFortranでの回答例2)](https://qiita.com/sage-git/items/a1f78761889812ad13f5)
[(過去問精選10問のFortranでの回答例3)](https://qiita.com/cure_honey/items/63f8e0f552b7da845598)
[参加者分布(年齢)](https://saba-kpr.hatenablog.com/entry/2020/06/04/232653)
[参加者分布(大学)](https://saba-kpr.hatenablog.com/entry/2020/01/25/193121)

# 便利なリンク集


## VSCodeで環境構築
[Fortran 使いの皆さん、エディタに Visual Stadio Code はいかがですか](https://qiita.com/tamaki_osamu/items/dcfda47c082669fa9beb)必要最低限、わかりやすい
[VSCodeでFortranのプログラムをコンパイル・デバッグするための設定](https://qiita.com/implicit_none/items/d49c9fdf51c307d22819)自分に必要な情報をうまく記事から抜き出そう

環境構築の時点から情報が少ないですね。さすがFortranです。
簡単にまとめると、

1. VSCodeを入れる(Windowsの人はちょくで入れるか、WSL環境を作っていれるか。)
1. Anaconda/minicondaを入れる
1. Anaconda/minicondaからpipでfortran-language-serverを入れる。(どこに入ったか要確認)
1. VSCode拡張で「Modern Fortran」「FORTRAN IntelliSense」を入れる
1. ファイルー>ユーザー設定ー>設定ー>fortlsで検索ー>Fortran-ls:Executable Pathに手順3で入れたfortran-language-serverのパスを入れる(ここまででシンタックスハイライト表示)
2. gfortranを入れる
3. code-runner拡張をVSCodeへ入れる
4. FortranのRun設定を書く(コンパイル&デバッグ設定)

## Fortranの基礎的な勉強

https://www.nag-j.co.jp/fortran/index.html
だいたいGoogleで`Fortran 〇〇`で調べると最上位に出てくる。90の入門的なものから2008の仕様についてまで網羅的に書いてある。例が複雑。字が小さくて見えない。

https://amanotk.github.io/fortran-resume-public/index.html
例が簡単でわかりやすい。目次の注釈にもあるように、自分の環境と照らし合わせて、必要な部分だけ読んでいこう。


http://jjoo.sakura.ne.jp/tips/f90/index.html
入門的な内容は無いが、かゆいところに手が届く感じがして良い。例がわかりやすい!。ちょっとくどい。ちょっとAtCoderやるには過剰な知識だが、ライブラリを作成するときにとてもよかったです。

https://qiita.com/jj1guj/items/43a1c876360ddf180f1f
AtCoderの問題を解くために必要な入門知識という視点で書かれている。基本中の基本を効率よく学びたい場合はおすすめ。

## Fortranの細かい話

https://www.nag-j.co.jp/nagfor/np52_manual/np52_manual_9_4.html#AUTOTOC_9_4
95までの組み込み関数を全部網羅してくれている。

https://qiita.com/implicit_none/items/ab0632357bab0f549cf2
https://qiita.com/implicit_none/items/08f894bc851c29b40b58
https://qiita.com/implicit_none/items/f582f2d4e10f2655e208
上から、「整数、不動小数」「文字列、文字配列」「配列」についての宣言方法、使用方法が細かく書かれている。AtCoderで問題を解くのに必須な知識というわけではないが、知っていると便利です。

https://qiita.com/implicit_none/items/9164c4d35d84e6e77f29
これもAtCoderやるために必須ではないが、知っていて損はない知識です。(コーディングルール)

https://qiita.com/implicit_none/items/6b5c3a65cddc6ecd8e52
スニペットについての話。とりあえず書いてある設定コピペするだけで大分便利です。

https://qiita.com/implicit_none/items/55c47407aa376277a531
AtCoderからは離れるんですが、Fortranオタクになりたい方、研究室のレガシーコードを書き換えたい方に是非オススメです。そうでない人も読んでみると面白いですよ。

https://qiita.com/septcolor/items/121dde6de28af9f74343
入出力あたりの細かい話です。
Docker for Windows：Hyper-vからWSL2への移行でMySQLのコンテナが起動しない

# 前提条件

- Hyper-vにてDocker for Windowsを稼働していた。
- 上記の環境にてMySQLのコンテナを作成。
- MySQLのデータファイルをdocker-composeのvolumesでマウント。
- MySQLのデータファイルの上記指定は変更させずに、そのままWSL2に移行。
- MySQL以外には、「PHP:7.2-apache」、「MailHog」、「phpmyadmin」のコンテナを起動。


# 現象

- MySQL以外のコンテナは正常に稼働。
- MySQLだけ以下のログを出力し、起動せず。

```sh:error.log

2020-10-01T19:41:54.887165Z 1 [ERROR] [MY-011087] [Server] Different lower_case_table_names settings for server ('2') and data dictionary ('0').

2020-10-01T19:41:54.887863Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.

2020-10-01T19:41:54.888441Z 0 [ERROR] [MY-010119] [Server] Aborting

2020-10-01T19:41:55.508831Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.21) MySQL Community Server - GPL.

```

# 対応

- MySQL用のデータフォルダを新規作成。
- docker-composeのvolumensで上記のフォルダを指定。

# 備考

- データもそのまま移行したいのだけど、それは調査中。
- とりあえず、上記で稼働はできた。
【MediaPipe】手話の数字を読み取ってみた(1~90まで)

# mediapipeで日本手話の数字を読み取ってみた
日本手話の数字を読み取ってみました。ご参考になれば幸いです。
↓youtubeで動作をご紹介
[![googleのmediapipeを使用して日本手話の数字を読み取ってみた](http://img.youtube.com/vi/mDs14yTCPsk/2.jpg)](http://www.youtube.com/watch?v=mDs14yTCPsk)

## 環境と結果概要
- mediapipe：v0.7.9(メイン機)、v0.7.10(サブ機)で動作確認
- Linux：GPUで動作確認、メイン機、Ubuntu18.04
- mac：cpuで動作確認、サブ機、Catalina10.15.7、MacBook Pro
- raspberry pi 4b：Ubuntuでやってみたが動作が遅くて断念
- windowsWSL：ライブカメラで動かせない仕様、bazelのビルドまでは問題なし
- android：動作が遅くて断念、他の方の投稿では問題なさそうなので機種によるか？
- ios：苦戦中、まだ動かせていない

## 参考にさせて頂いたページ・資料
- [【MediaPipe】投稿記事まとめ](https://dev.classmethod.jp/articles/mediapipe-yamamotohiroki-pages-matome/)
- [Simple Hand Gesture Recognition Code](https://gist.github.com/TheJLifeX/74958cc59db477a91837244ff598ef4a)
- [Google公式　※bazelやopencvのバージョン、サポートしているGPUの確認など重要](https://google.github.io/mediapipe/)

## 機能概要
- 日本手話の数字の認識：1-9、10、20、30、40、50、60、70、80、90<br>
各指を3値(open/midClose/Close)で判定、判定値の組み合わせでパターン認識
- 文字の配置：プログラム開始してからの経過時間と問題と答えを画面右上に表示
- 〇の表示：問題に対する回答が読み取った手型と一致しているときに画面に赤丸を表示

## ソースコード
[ソースコード](https://github.com/kirei7jaiann/mediapipeNumberRecognition)は検証中のもののため、動作の保証等はできかねます。ご了承の上でご使用ください。利用条件などについては[公式](https://github.com/google/mediapipe)をご覧ください。
※ソースコードは編集ファイルのみ抜粋してアップロードしています
※mediapipe本体は公式をご利用ください

## 編集内容概要
- ファイル追加：hand-gesture~が手型認識、assignment~が問題表示など
hand-gesture-recognition/BUILD
hand-gesture-recognition/hand-gesture-recognition-calculator.cc
hand-gesture-recognition/assignment-presentation-calculator.cc
<br>

- ファイル編集：hand-gesture~やassignment~用のinput_stream/output_streamを追加
※元ファイルから「handedness」を表示上の都合で削りました
mediapipe/graphs/hand_tracking/subgraphs/BUILD
mediapipe/graphs/hand_tracking/subgraphs/hand_landmark_cpu.pbtxt
mediapipe/graphs/hand_tracking/subgraphs/renderer_cpu.pbtxt
mediapipe/graphs/hand_tracking/subgraphs/hand_landmark_gpu.pbtxt
mediapipe/graphs/hand_tracking/subgraphs/renderer_gpu.pbtxt
<br>

- ファイル編集：文字や〇表示のため編集
mediapipe/calculators/util/annotation_overlay_calculator.cc
mediapipe/util/annotation_renderer.cc
mediapipe/util/annotation_renderer.h

## コマンド
CPUのビルドコマンド

```
bazel build -c opt mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu --define MEDIAPIPE_DISABLE_GPU=1
```
CPUの実行コマンド

```
GLOG_logtostderr=1 bazel-bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_cpu  --calculator_graph_config_file=mediapipe/graphs/hand_tracking/hand_tracking_desktop_live.pbtxt
```
GPUのビルドコマンド

```
bazel run --copt -DMESA_EGL_NO_X11_HEADERS --copt -DEGL_NO_X11 mediapipe/examples/desktop/hand_tracking:hand_tracking_gpu
```
GPUの実行コマンド

```
LOG_logtostderr=1 bazel-bin/mediapipe/examples/desktop/hand_tracking/hand_tracking_gpu   --calculator_graph_config_file=mediapipe/graphs/hand_tracking/hand_tracking_mobile.pbtxt
```

## 結果
mediapipeすごいです。計算カードのようなプログラムは作れそうです。

## 課題
- 日本語の表示はopencvではNGっぽいので別で実装する必要がありそうです
- 70、80、90の判定が不安定です<br>
※関節が見えない手型なのでmediapipeによる推定が不安定になります<br>
※MLなどでパターンマッチングとは別処理にしないと精度が出ないかもしれません<br>
※各手型が安定すれば12、81など、桁を区切った入力も可能になる見込みです<br>
Generative Adversarial Nets(10 June 2014)を読む

#概要

GANの論文である
https://arxiv.org/pdf/1406.2661.pdf
Generative Adversarial Nets
を読む。

#Abstractを読む

##Abstract原文
https://arxiv.org/pdf/1406.2661.pdfのアブストラクト

>
We propose a new framework for estimating generative models via an adversarial process, in which we simultaneously train two models: a generative model G that captures the data distribution, and a discriminative model D that estimates theprobabilitythatasamplecamefromthetrainingdataratherthan G. Thetraining procedure for G is to maximize the probability of D making a mistake. This framework corresponds to a minimax two-player game. In the space of arbitrary functions G and D, a unique solution exists, with G recovering the training data distribution and D equal to 1 2 everywhere. In the case where G and D are deﬁned by multilayer perceptrons, the entire system can be trained with backpropagation. There is no need for any Markov chains or unrolled approximate inference networks during either training or generation of samples. Experiments demonstrate the potential of the framework through qualitative and quantitative evaluation of the generated samples.

##Abstract Google翻訳（未加工）

>敵対的プロセスを介して生成モデルを推定するための新しいフレームワークを提案します。このフレームワークでは、データ分布をキャプチャする生成モデルGと、サンプルがGではなくトレーニングデータから得られる確率を推定する識別モデルDの2つのモデルを同時にトレーニングします。Gのトレーニング手順は、 Dが間違いを犯す確率。 このフレームワークは、ミニマックス2人用ゲームに対応しています。 任意の関数GとDの空間には、Gがトレーニングデータの分布を回復し、Dがどこでも1 2に等しいという、独自のソリューションが存在します。 GとDが多層パーセプトロンによって定義されている場合、システム全体をバックプロパゲーションでトレーニングできます。 トレーニング中またはサンプルの生成中に、マルコフ連鎖または展開された近似推論ネットワークは必要ありません。 実験は、生成されたサンプルの定性的および定量的評価を通じてフレームワークの可能性を示しています。

#今後
この論文の特徴などを追って検討します。

#まとめ
コメントなどあればお願いします。
SQLアンチパターン　フィア・オブ・ジ・アンノウン

# フィア・オブ・ジ・アンノウン

NULLを一般値として扱う。または一般値をNULLとして扱う。

## 欠けている値を区別する

データベースにはデータに値がない状況は必然的に発生する。
列の一部に値がない状態で行を挿入しないといけないような場合もある。

SQLは以下のような値を持たない列において、その値を***予約語NULL***で表現する。

* null（無）
* unknown（不明）
* inapplicable（適用不能）

SQLのテーブルとクエリでNULLを効果的に使用する方法はたくさんある。

* 行作成時点では不明な値に対してNULLを使用する
* ある行において適用可能な値がない場合にNULLを使用する（例：電気自動車のガソリンの燃料効率など）
* 無効な値が入力された場合に関数はNULLを返せる（例：DAY('2020-13-32')）
* 外部結合は一致しないテーブル列のためにNULLをプレースホルダーとして使用

## 式でNULLを扱う

以下のSQL文はバグを管理するテーブルである。
hours列にはそのバグの修正時間の見積もりが入っているものとする。

では、以下のクエリを発行した際、hours列の値がNULLだった場合はどうなるか。

```sql
SELECT hours + 10 FROM Bugs
```

hoursには値がないため結果は10が返ってくる？？
いえ、結果は***NULL***が返ってくる。
SQLの標準では文字列とNULLを連結するとNULLが返却される。

NULLは数値のゼロと同じではない。
また、長さがゼロの文字列でもない。

NULLはFALSEと同じものではないためAND、OR、NOTを用いた論理式でも注意が必要。

※OracleとSybaseで振る舞いが異なる。

## NULLを許容する列の検索

以下のクエリではBugsテーブルからbug_idが100の行を返しする。
bug_idが100以外の行、またはNULLの行は返却されない。

```sql
SELECT * FROM Bugs WHERE bug_id = 100;
```
では以下のクエリではどうでしょうか。
こちらはbug_idが100以外の行を返却する。

```sql
SELECT * FROM Bugs WHERE NOT bug_id = 100;
```

しかし、上記のクエリでもNULLが割り当てられた行を返却しない。

WHERE句の条件は式がTRUEの場合のみ該当の行を返却する。
NULLを用いた比較ではTRUE、もしくはFALSEではなく不明（unknown）を返却する。

なので以下のようにNULL、または非NULLを検索しても行を取得することはできない。

```sql
SELECT * FROM Bugs WHERE bug_detail = NULL;
```

```sql
SELECT * FROM Bugs WHERE NOT bug_detail = NULL;
```

## プリペアードステートメントでNULLを使用する

プリペアードステートメントでパラメータ化したSQLでNULLを使用することは困難。
以下のクエリにてパラメータにパラメータに整数値を使用した場合該当の結果を取得する。

しかし、パラメータにNULLを使用することができない。

```sql
SELECT * FROM Bugs WHERE assigned_to = ?;
```

## NULLの使用を避ける

NULLの扱いでクエリが複雑化することを嫌いNULLを使用しないように設計するパターンもある。
NULLの代わりに不明（unknown）や適用不能（inapplicable）を意味する値を新たに定義して格納する。

列に対しNOT NULL制約を宣言してNULLが格納されないようにし、不明（unknown）な値に対して「−1」を格納するなど。
不明（unknown）や適用不能（inapplicable）を意味する値を格納することでNULLを表現する。

しかし、格納する値によってはSUMやAVGのような計算で期待する結果が得られない場合がある。
必要に応じてWHERE句やCASE式を用いて上記の値を排除して取得する必要がある。

## アンチパターンの見つけ方

データにNULLが含まれる可能性がある場合は何かしらの問題が発生すると想定をするべき。
アプリケーションのテスト時にテストデータの設計でNULLを含むエッジケースを想定してテストを実施すべき。

## アンチパターンを用いても良い場合

NULLを用いること自体がアンチパターンというわけではない。
NULLを一般値として扱ったり一般値をNULLとして扱うことが問題となる。

# 参考文献

[SQLアンチパターン](
https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Bill-Karwin/dp/4873115892/ref=sr_1_1?adgrpid=104444684056&dchild=1&gclid=CjwKCAjw4_H6BRALEiwAvgfzqy-f83NTsyQkauo7gn6ysgAPmJvKyvuI5FaXFnxFmhVfCzCRRACsaBoCY-oQAvD_BwE&hvadid=447984765572&hvdev=c&hvlocphy=1009332&hvnetw=g&hvqmt=e&hvrand=13417269104929133208&hvtargid=kwd-335484809678&hydadcr=27264_11561110&jp-ad-ap=0&keywords=sql%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&qid=1599934568&sr=8-1&tag=googhydr-22)

![参考文献.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/b46d45ab-75ec-a620-eeb2-a422f6b1e659.jpeg)
ノンプログラミングでOK！WP plugin "web stories"を使ってみた感想メモ

## web stories for wordpressとは

https://www.vice.com/stories/japanese-curry-recipe/
まずはこちらの様に、WordPressでスライドショーを作れるplugin。
画像でも、動画でも、テキストでも直感的にスライドできるという感じです。
なお、ampにあったstoriesという機能をそのままWebでも使える様にしたものです。

使ってみた感じはWeb制作している人(PhotoshopとかXDとかFigmaとか触ってる人)なら
大体どこを押せばどうなるのかわかりやすいUIでした。

## なにも見ずに実際に作ってみた

とりあえずめっちゃ簡単でした。
あまりwebのことを良くわかってない私でも作れました

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759955/f8dc9502-a0cd-0c43-8b2a-b5a37a9132d5.png)

まずは、プラグインをインストールしたら左に「Stories」メニューが追加されました。
Add Newを押してみました

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759955/0ca0ba96-af10-be82-7385-f3f39f3991a2.png)

適当に登録されていた画像を配置。
そして、左上の「T」のアイコンがあるので、絶対テキストだと思って押してみましたらテキストが入力できました。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759955/732126a5-1097-9da2-2424-b8509b18ba71.png)

そして、テキストを編集するには、右側にいろいろな設定がありました。
言わずもがな大体何がなんだかわかりました。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759955/27d03643-8c3f-d2d4-273e-a53dca6f14ea.png)

そして、背景の画像も変えてみたり、「＋」アイコンを押してみたりしたらページが増えました。
非常に何も考えず直感的に情報を追加することができました。

![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759955/4c4626be-bac1-5f65-0b85-d5d916721296.png)

スライド時間の変更は少し迷いました。
ただ、いろいろなボタンを押したら右上「document」を押したら変更する事ができました。
ここでは投稿の設定などが行えます。

## 完成！
https://gyazo.com/8892efee7f4f4e9fd56a457a3db6307c

完成品です。
15分もあれば、クソほどお洒落なストーリーズを組み立てる事ができました。

## 所感
この技術がWordPressにムーブメントになるかはわかりませんが、
確実に「誰でも簡単に情報と気持ちを伝える」敷居は低くなってると思いました。

一番忘れてはいけないのは、
ストーリーズが何かってところですね！！
私はストーリーズを使った事がないものですから、これが凄いのかが全くわからなかったです！
zoom rest 

get user
https://marketplace.zoom.us/docs/api-reference/zoom-api/users/user

create mtg
https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingcreate


deauth
https://marketplace.zoom.us/docs/api-reference/webhook-reference/account-events/account-disassociated

https://marketplace.zoom.us/docs/api-reference/webhook-reference/app-events/app-deauthorized

webhook
https://marketplace.zoom.us/docs/api-reference/webhook-reference

エンドポイント通知
https://marketplace.zoom.us/docs/api-reference/data-compliance/data-compliance/compliance
![スクリーンショット 2020-10-01 15.51.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546786/9842242d-dbf5-3a36-2003-a7f0a420794b.png)




 this correlates to "Client ID" and "Secret"
net useのシステムエラー1219はWorkstationサービス再起動で解決

# はじめに
net useコマンドを使用していて「システム エラー 1219 同じユーザーによる、サーバーまたは共有リソースへの複数のユーザー名での複数の接続は許可されません。サーバーまたは共有リソースへの以前の接続をすべて切断してから、再試行してください。」が発生しました。

ググった解決策の「net use * /d」を実行するも、一向に解決できません。
そうなると、いつもならPC再起動をするんですが、もっといい方法がないか模索していました。

# 解決策
Workstationサービスは、Windows OSを搭載したコンピューターでのネットワーク接続をサポートするサービスです。
[第20回　ファイル共有プロトコルSMB／CIFS（その1） (1/3)](https://www.atmarkit.co.jp/ait/articles/0410/29/news103.html)

「タスクマネージャー」を起動しタブメニューの「サービス」をクリックして、サービスの画面にある「サービス管理ツールを開く」をクリックします。
サービス一覧の中の「Workstation」を右クリックし、メニューの「再起動」をクリックします。

または、次のコマンドラインでサービスを再起動することもできます。
最後の「Computer Browser」サービスは必要な人のみ行ってください。

```
net stop Workstation
net start Workstation

net start "Computer Browser"
```

# 最後に
SMB関連で検索していた時に、Workstationサービスのことを知りました。
net useの1219エラー以外でもWorkstationサービスの再起動で解決できることがあるかも知れませんね。

# 参照
https://stackoverflow.com/questions/24933661/multiple-connections-to-a-server-or-shared-resource-by-the-same-user-using-more
MacbookでUbuntuのブートUSBを作成してThinkpadにUbuntuをインストールするまで

## はじめに
Macをメインで使っていますが、そろそろLinuxも使ってみたい
てことでメルカリでThinkpad X230を購入しましたん
このマシンにUbuntuを入れようと思うのでその備忘録を残すンゴ


## 用意するもの
### ハード
- USBメモリ（２GB以上だそうな)
- Macbook(ブートUSB作成用)
- Thinkpad(Ubuntuを入れるマシン)

※実際、何でもいいｗ

### ソフト
- ディスクユーティリティ
- Etcher



## USBをフォーマット
Macbookでは「ディスクユーティリティ」というアプリでUSBメモリの初期化、再フォーマットをするそうです。
1. ディスクユーティリティを開く
2. Ubuntuのインストーラーを入れるUSBメモリを選択
3. 消去
4. 名前とフォーマットを選択（フォーマットは「MS-DOS(FAT)」だそう）
5. 完了

MS-DOS(FAT)だとwindowsでも動くそうです

参考：https://pc-karuma.net/mac-format-usb-flash-drive/

## Ubuntuファイルダウンロード
https://ubuntu.com/download/desktop
こちらでUbuntuファイルをダウンロードします
LTSであれば、安定してるはずなので良いでしょう。
今回は`Ubuntu 20.04.1 LTS`をダウンロードしました。
容量が2.6GBほどあるので、場合により長くなりそうな...

`~/Downloads/`に「ubuntu-20.04.1-desktop-amd64.iso」というファイルがあればおｋ！

## EtcherでブートUSB作成
Etcherというアプリを使うと簡単にブートUSBを作成することができるそうです。
しかもこのアプリ、クロスプラットフォームらしいです。
Macだけでなく他のOSでも使う機会がありそうですな〜

https://www.balena.io/etcher/

1. Etcherのインストール
2. Etcher起動！！！
3. Select Imageでは`Flash from file`で先程インストールした`.iso`のubuntuファイルを選択
4. Select Targetでは用意したUSBメモリを選択
5. Let's Flash!!

パスワードを聞かれたり、ポップアップが来たりしますが言われるがままにして待っていれば無事に完了するはず
これでブートUSBの完成

ブートUSBが完成すると、「このディスクはうまく読み取れません」だのどうのこうの言われますが、無視しましょう

参考：http://terufusa.blog.jp/archives/24477397.html

ちなみに、windowsでは[rufus](https://forest.watch.impress.co.jp/library/software/rufus/)というアプリを使うそうな



## コラム：ブートUSBを元の状態に戻す
ターミナルを起動

```
diskutil list
```

ブートUSBの階層を調べる


もし`/dev/disk2`にある場合は

```
diskutil unMountDisk /dev/disk2
```

```
Unmount of all volumes on disk2 was successful
```

こう表示されれば成功

```
diskutil eraseDisk FAT32 *** /dev/disk2
```

`***`には新しいUSBメモリの名前を入力
FAT32はフォーマット形式です。今回はwindowsでも使うことを考慮してFAT32にしましたが、macでしか使わないのであれば`HFS+`のフォーマット形式でもいいでしょう。

```
Finished erase on disk2
```

こう表示されれば完了です


## Ubuntuをインストール
Ubuntuを入れたいマシンの電源を落として再起動
BIOSに入る（マシンそれぞれで入り方はググる）
今回はThinkpad X230なので起動画面でF1を押すとBIOSに入れる
Secure Bootをoffにしておく
保存
作成したブートUSBを挿入して再起動
起動画面でF12を連打するとBoot Menuに入れる
作成したブートUSBを選択する
ubuntuのインストールが始まる

1. 日本語を選択し、「Ubuntuをインストール」をクリック
2. キーボードレイアウトを選択
3. 全てチェックを入れて進む
4. ディスクを削除してインストール
5. ポップアップは変更を書き込むで続ける
6. 住んでいる場所はTokyo
7. 名前、コンピュータの名前、パスワードを入力
8. インストールを進める
9. インストールが完了したら再起動
10. ブートUSBを抜いて起動を続ける


無事にUbuntuをインストールして起動が完了しました。


## 終わりに
以上で無事にUbuntuのインストールが完了しました。
意外とすんなりいった〜〜
次はUbuntuの設定とかアプリのインストールとか諸々していこうとおもう。
あざした！
Swift4行で誕生日から年齢を算出する ~今何歳だっけ？となったあなたに~

今何歳ですか？
パッとは答えられないあなたのために、生年月日から誕生日を算出するプログラムを組みました。

```Swift
var birthdate = DateComponents(year: 1994, month: 10, day: 1)
var age: Int
```

```Swift
// 年齢を算出します
let calendar = Calendar.current
let now = calendar.dateComponents([.year, .month, .day], from: Date())
let ageComponents = calendar.dateComponents([.year], from: birthdate, to: now)
age = ageComponents.year!
```


Date型からDateComponents型に変換することもできるので、誕生日をDateで管理したい場合は応用してください。
[【Swift】DateとDateComponentsの相互変換 - しめ鯖日記](https://llcc.hatenablog.com/entry/2017/08/31/230000)

----
### おまけ
誕生日を入れると自動で年齢を入れてくれるようにしたかったんですけど、initの時はdidsetが呼ばれないので諦めました。

```Swift
class Person {
    var age: Int?
    var birthdate: DateComponents {
        didSet(date){
            // 呼ばれないよ！！！
            let calendar = Calendar.current
            let now = calendar.dateComponents([.year, .month, .day], from: Date())
            let ageComponents = calendar.dateComponents([.year], from: date, to: now)
            age = ageComponents.year!
        }
    }
    init(date: DateComponents) {
        birthdate = date
    }
}

let hoge = Person(date: DateComponents(year: 1994, month: 10, day: 1))

```
[Swiftでdeinit時にメンバ変数(property)のdidSetが呼ばれない気がした – su- tech blog](https://tech-blog.sgr-ksmt.org/2017/03/09/deinit_didset/)
Android Studio 4.0.1でRクラスを確認する方法

Android開発でお馴染みの`R.java`（Rクラス）ですが、Android Studio 3.6からR.java自体は生成されず、Rクラスのバイトコードが生成される方式に変わったようです。

![スクリーンショット 2020-10-02 0.44.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/da945fd0-6247-ea5f-ca92-d4dacab1892c.png)
https://android-developers.googleblog.com/2020/02/android-studio-36.html

このことを知らず、先日Rクラスを確認しようとして困ったので、確認方法を記載したいと思います。

# 場所
`R.java` は生成されませんが、`R.txt` として生成されているようでした。

場所は

```
app/build/intermediates/runtime_symbol_list/debug/R.txt
```

にありました。 `debug` のところはビルドタイプが入ります。

Android Studioでは↓のところから参照できます。
![スクリーンショット_2020-10-02_1_01_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/0ebef57d-66d8-3355-018d-b0a81c387fb3.png)

# 内容
`R.txt` の内容としては↓のようなのがズラッと並んでいる感じでした。
![スクリーンショット 2020-10-02 1.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/4bfbfff5-4587-061f-15c3-317994b5826b.png)

```
int layout activity_select_text 0x7f0b001d
```

となっているところが

```
R.layout.activity_select_text = 0x7f0b001d
```

となるようです。数値に関しては、`R.txt` 上では `0x7f0b001d` のように16進数になっていますが、実際は10進数に変換されます。