OmniAICreator/Qiita-1.07M huggingface dataset:
KT0915をArduinoで制御　FM編　DSPラジオ

#はじめに
* 電子工作の初心者としてDSPラジオに挑戦。
* 今までFM放送に絞っていましたが、AM、短波も挑戦したかったので、今回はKT0915をチョイス。とりあえず最初はFM放送から。AM、短波は後ほど。
* 本ICは裸で売っているので、モジュールつくりから始めました。
* 本ICは、マイコンなしでボリューム、ボタンなどで制御することも可能なようですが、ここではArduinoで制御しています。

#使用したもの
* KT0915(http://www.aitendo.com/product/7449)
* KT0915のデータシート。上記参照。
* Arduino Uno互換機(ELEGOO)

#モジュールについて
* DIP化。この変換基板(http://akizukidenshi.com/catalog/g/gP-13602/) を利用。裏面にGround、ジャンパーが用意してあり、便利そうなので使ってみました。
* ICのはんだ付けは少し苦労しましたが、フラックス＋ハンダ吸取線で何とかなりました。
* 空中配線　データシートのp24を参考に以下の作業を行いました。
    * ICの2, 5, 13のジャンパーをGroundにつなげています。
    * 32.768Khzの水晶。Pin7 と Pin8に接続。
    * 24pF2個。Pin7 - Pin13、Pin8 - Pin2。
    * パスコン0.1μF（SMD)。Pin5 - Pin6。パスコンはこれだけ使いました。
![KT0915_module.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/dbdaf695-3770-8b01-e72f-42fc4b11a8cb.jpeg)
![KT0915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/52d1d51c-2cff-6f87-a668-f7c6f79e54c2.jpeg)

#配線
* データシートのp24を参考に配線。Pin9(ENABLE)については、+3.3vにつないでいます。
* イヤフォンに直接出力可能です。出力コンデンサは不要。 
![KT0915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482773/8f185af1-9f68-c3ac-cb85-f8da82fc156e.jpeg)

#Slaveアドレス
* I2C Scannerによるとアドレスは"0x35"でした。

#I2C通信
* 本ICの場合、I2Cは普通のコードで読み書きできます。
* さらに、連続読出し、書き込みも可能。最初のレジスタは指定する必要がありますが、そのまま次のレジスタにアクセスできます。連続したアドレスに書き込むには便利ですが、使わなくても無問題だと思います。
* コード例は割愛。

#コード作成のポイント
* FMTUNEビット1　他のDSPモジュールと同様に、特定周波数をレジスタに書き込む場合、FMTUNEビット（03h.15)を1にする。03hは周波数を設定するレジスタでもあるので、FMTUNEビット1と合わせて書き込むことになる。
* CHANの計算は、50KHZで計算。80Mhz →　1600(640h)。
* FM受信ならば、さわるレジスタは少ない。Default値がFM放送向けになっているので。

#動作コード
* 上記のポイントを考慮して作成した、特定の周波数を書き込むシンプルなコード。3つのレジスタだけ操作すれば、後はDefaultのままでOK。
* 今回は、レジスタに書き込むのにwhile文を使ってみました。配列FM[]からレジスタ番号と書き込むデータを読みだしています。
* FM[]には、関係ありそうだけど、FMでは操作する必要のなさそうなレジスタもコメントアウトして入れてあります。AM、SWでは必要になりそうなので。

```
#include <Wire.h>

const unsigned int FM[]=
{                     
//0x02,0x0007, // 100kh, RLmute dis
0x03,0x8640, // fmtune1, 80Mhz(1600*50khz)
//0x03,0x8672, // fmtune1, 82.5Mhz
0x04,0xe080, // SoftMute dis, Mute dis
0x05,0x1800, // stereo, DE50
//0x0a,0x0100, //
//0x0c,0x0024, // 64-110mh
//0x0f,0x881f, // standby0, vol 11111
//0x16,0x0002, // FM
0xff,0xffff,
};

void setup() {
  // put your setup code here, to run once:
Wire.begin();
int i=0;
while (FM[i] !=0xff) {
Wire.beginTransmission(0x35); // slave address 0x35
Wire.write(FM[i]);      // Register i
Wire.write(highByte(FM[i+1]));      // Register i H
Wire.write(lowByte(FM[i+1]));      // Register i L
Wire.endTransmission();     //
i+=2;
delay(100);
}
}

void loop() {
  // put your main code here, to run repeatedly:
}
```

#おまけ
* 上手くモジュール化できて楽しかった。データシート通りに作ればよい、ということがわかりました。
* レジスタ操作も、データシートをちゃんと読めば何とか動作はさせられる感じになってきました。当たり前といえばそれまでですが、イヤホンから放送が聞こえてくると嬉しいものです。
【MySQL】pid not foundもしくはpermission deniedの対応方法

がっつりとハマってしまったので自分への備忘録として残します。

<h2>原因</h2>

MYSQL@5.7をインストールしてsever.start後、MYSQL@5.6をインストールして動かそうとすると、MYSQL@5.7で使おうとしていたファイルを参照するらしい。

残っているファイルを消すことが必要になる。

<h2>経緯</h2>

ことの発端はどこかのタイミングでbrew updateをしてしまったらしく、MYSQL@8系のバージョンが入ってしまっていた。

それにより、railsでアプリケーションを立ち上げようとした時にエラーが起きてしまったので、ダウングレードしたり様々なことをやった結果、「PIDファイルがないエラー」と「権限がないエラー」の無限ループにはまり込んでしまった


<h2>現象</h2>

MYSQLサーバーを起動させようとするとエラー

```
$ mysql.server start

/usr/local/Cellar/mysql@5.6/5.6.43/bin/mysqld_safe: line 138: /usr/local/var/mysql/username.local.err: Permission denied
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/username.local.pid).

```

どうやら一つは権限がない、もう一つはPIDファイルがないらしい。

とりあえず権限を付与。

```bash
$ sudo chmod 777 /usr/local/var/mysql

$ mysql.server start
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/username.local.pid).

```

権限問題は消えた。

PIDファイルを作るディレクトリに移動して、touchコマンドでpidファイルを作成。

```
$ cd /usr/local/var/mysql

$ sudo touch prkrsignMacBookPro.local.pid

$ mysql.server start
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/username.local.pid).

```

これでもダメ。
/usr/local/var/mysqlディレクトリのファイルリストを表示したが、pidファイルがなかった。

どうやら作られても消えてしまう？らしい。

そこでこの記事を発見。

https://qiita.com/furafura_nau/items/7d8f5370899df125d459

```
一度でも5.7を起動してしまうと、同じデータを使って5.6を起動すると次のようなエラーが出るようになります。

Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/ogin.local.pid).
mysqld等は動いていなかったので権限周りと思われますが、うまく解決できませんでした。
（バージョンによってディレクトリ構成が違っていたので、権限以外にも何か影響しているのかもしれません）

```

とのこと。

記事を参考に、

```bash
$ sudo rm -rf /usr/local/mysql
$ sudo rm -rf /Library/StartupItems/MYSQL
$ sudo rm -rf /Library/PreferencePanes/MySQL.prefPane
$ sudo rm -rf /Library/Receipts/mysql-.pkg
$ sudo rm -rf /usr/local/Cellar/mysql*
$ sudo rm -rf /usr/local/bin/mysql*
$ sudo rm -rf /usr/local/var/mysql*
$ sudo rm -rf /usr/local/etc/my.cnf
$ sudo rm -rf /usr/local/share/mysql*
$ sudo rm -rf /usr/local/opt/mysql*

<!--最後にver5.6をインストール。-->
<!--元々MYSQL@5.6が入っていて、アンインストールせずにそのままインストールしちゃいました。-->
$ brew install mysql@5.6
```

忘れずにPATHを通そう。

```bash
$ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
```

```bash
$ /usr/local/opt/mysql@5.6/bin/mysql.server start

Starting MySQL
. SUCCESS! 
```

これはドヤ顔。エラー解決に8時間かけたのにたまらずドヤ顔

記事を参考にMYSQLに入れることも確認しときます。いけました。

```bash
$ /usr/local/opt/mysql@5.6/bin/mysql -u root
```

とりあえず所感として。

MYSQLでエラーが出たら、原因はほぼ二つ。

「PIDがなくなっている」か「権限がない」。

touchを使ってPIDファイルを作成、もしくはchmodを使って権限の再設定をまず試してみるのがいいと思います。

それで改善しないなら潔く再インストールが多分手っ取り早いです。

再インストールの場合は上記のようにMYSQLが持ってるファイルを全部消して、MYSQL@5.6をインストール、パスの設定がいいんじゃないかなと思います。

@8だったり@5.7だったり、なかなかバージョン関係でいざこざ起きやすいようなので、初めに環境構築した時のバージョンを再インストールしなおすのがいいんじゃないかなと思います。
javascript ライブラリ写経~ヘルスケアwebサービスを自分で作る医者の日記~

使ったライブラリの写経を習慣にしようと思い

予約システムの勉強のために使ったjqueryのプラグイン

[pickadate](https://github.com/amsul/pickadate.js)

を写経している。

```javascript
  //merge the default and options passed
  SETTEINGS = COMPONENT ? $.extend( true, {}, COMPONENT.defaults, OPTIONS) : OPTIONS || {},
  //merge the default classes with the settings classes
  CLASSES  = $.extend( {}, PickerConstructor.klasses(), SETTINGS.klass),

```
この部分がわからない、&.extendとは

https://qiita.com/kazu56/items/f31faa7d2505a417496f
こちらを拝見すると、プラグインの設定を追加するためのマージするためのもの

マージとは？　合体　あるいは差分を補完するものか？
gitのマージと同じなの？
概念がよくわかっていない。

https://qiita.com/sasaplus1/items/68dcae1eaae018a513e9

後日考えよう

追記
https://www.sejuku.net/blog/32035
うん、なんとかわかった。
ライブラリの理解は、本当に後日
LaravelでFirebaseを使う時のサービスアカウントファイルの保存場所に困った話

## はじめに
LaravelでFirebaseを使う時、Composerから"kreait/firebase-php"をDLして設定すると思います。
その中で、Laravelにサービスアカウントのjsonファイルを読み込ませる処理を書く必要があり、マニュアルでは以下のように記述されていました。

```
■ FirebaseServiceProvider.php

 use Kreait\Firebase\Factory;
 use Kreait\Firebase\ServiceAccount;

 $serviceAccount = ServiceAccount::fromJsonFile(__DIR__.'/google-service-account.json');

 $firebase = (new Factory)
     ->withServiceAccount($serviceAccount)
     ->asUser('my-service-worker')
     ->create();
```
引用：https://firebase-php.readthedocs.io/en/latest/authentication.html

ローカル環境で動かす分には、jsonファイルを直接読み込ませる上記方法で問題ありません。
しかし、ローカル環境以外では少し面倒です。

このjsonファイルは秘密鍵のため、GitHubに上げるわけにはいきません。
そうなると、ローカル環境以外では、このファイルだけを別の手段でアップロードする必要があります。（環境によっては、自由にファイルをアップロードができない場合もあるので非常に不便です）

そこで色々と調べた結果、PHP dotenvのバージョン3からenvファイルの変数に設定できる値をMultiline（複数行）で書けるようになった事を知ったので、さっそく試してみる事にしました。


## Multiline（複数行）で書いてみる
Firebaseのサービスアカウントのjsonファイルの内容をMultiline（複数行）で環境変数に設定します。

```
■ .env

HOGE="{
  \"type\": \"service_account\",
  \"project_id\": \"xxxxxxxxxxxxxx\",
  \"private_key_id\": \"xxxxxxxxxxxxxx\",
  \"private_key\": \"-----BEGIN PRIVATE KEY-----\\xxxxxxxxxxxxxx\\nxxxxxxxxxxxxxx\\n-----END PRIVATE KEY-----\\n\",
  \"client_email\": \"xxxxxxxxxxxxxx\",
  \"client_id\": \"xxxxxxxxxxxxxx\",
  \"auth_uri\": \"https://xxxxxxxxxxxxxx\",
  \"token_uri\": \"https://xxxxxxxxxxxxxx\",
  \"auth_provider_x509_cert_url\": \"https://xxxxxxxxxxxxxx\",
  \"client_x509_cert_url\": \"https://xxxxxxxxxxxxxx\"
}"
```
環境変数に、こんなに簡単にjsonを設定できるなんて素晴らしい・・・
注意として、```"```や```\n```は、```\"```や```\\n```にして、エスケープする必要があります。

## 環境変数に合わせてLaravelの設定を見直す
Laravelにサービスアカウントのjsonファイルを読み込ませる際、マニュアルではfromJsonFileという関数を呼んでいました。
この関数はjsonファイルを読み込ませるための関数なので、このままでは使えません。
jsonを直接読み込ませる関数、fromJsonという関数が使えそうです。

```
■ FirebaseServiceProvider.php

 use Kreait\Firebase\Factory;
 use Kreait\Firebase\ServiceAccount;

 $serviceAccount = ServiceAccount::ServiceAccount::fromJson(env('HOGE'));

 $firebase = (new Factory)
     ->withServiceAccount($serviceAccount)
     ->asUser('my-service-worker')
     ->create();
```

上記でも動きますが、Laravelはキャッシュファイルが存在すると.envファイルを読み込まないので、configファイルに設定します。

```
■ config/app.php

    'fuga' => env('HOGE'), // 追加
```

```
■ FirebaseServiceProvider.php

 use Kreait\Firebase\Factory;
 use Kreait\Firebase\ServiceAccount;

 $serviceAccount = ServiceAccount::ServiceAccount::fromJson(config('app.fuga'));

 $firebase = (new Factory)
     ->withServiceAccount($serviceAccount)
     ->asUser('my-service-worker')
     ->create();
```
とりあえずで動かすのなら、この方法がよさそうです。

## LaravelをHerokuで動かす場合
Herokuで動かす時も同様、環境変数を使うと楽です。

<img width="375" alt="heroku-env.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241956/55e038d1-25c4-a966-9501-1f4a36708f16.png">


## LaravelとPHP dotenvのバージョンについて
Laravelの5.8から、PHP dotenvのバージョン3に対応しているとのこと。
5.7まではPHP dotenvのバージョンは2なので、注意してください。
Ubuntuで色がなくなる理由と改善策

# ことの発端
***Ubuntuの色がなくなった!!?***
.bash_profileを作って設定を追加するとなぜか色が消えた。ls --color=autoを使ってlsの色は何とかしたもののユーザー名などが色がつかない。

## 原因
.bashrcが読み込まれていなかった

## 解決策
以下のサイトを参考に.bashrcを読み込むように.bash_profileを設定すること

http://blog.ruedap.com/2010/09/13/mac-bash-bashrc

簡単に説明すると、.bashrcが存在すれば読み込むという設定を.bash_profileに書けば大丈夫。

# 原因発覚から改善まで
## 原因発覚
いろいろ記事を見ると`.bash_profile` -> `.bashrc`の順番で呼び出されると書いてあったが、もしかしたら`.bash_profile`がなければ`.bashrc`を呼び出すという意味ではないかと思った。

## 原因が本当にそれなのかの確認
.bashrc以下を追加した
```echo "call bashrc"```

.bash_profile以下を追加した
```echo "call bash_profile"```

これらは`.bashrc`などが呼ばれていたらcall bashrcと表示するスクリプトになっている。
実行すると予想通りcall bash_profileとしか表示されなかった。予想通り、`.bash_profile`しか呼び出されていないことが分かった。

## 調べて解決
こんな感じで`.bash_profile`に`.bashrc`を読み込む設定を書くだけでOK!
```bash: ~/.bash_profile
if [ -r "$HOME/.bashrc" ]; then
  . "$HOME/.bashrc"
fi
```

# 補足
いろいろ調べてみると、`.bash_profile`はログインシェル(初めて起動するときや`bash --login`で`bash`を起動したときのシェル)でのみ読み込まれ、`.bashrc`は`.bash_profile`が読み込まれていないときに読み込まれる場合が多いらしい。

以下のブログの図がとても分かりやすい

https://blog1.mammb.com/entry/2019/12/01/090000

`.bash_profile`を読み込みたいけど、`.bashrc`は読み込みたくないなんて場面は多分ないので、今回みたいに`.bash_profile`から`.bashrc`をロードするのがいいと思う。逆に`.bashrc`から`.bash_profile`を読み込むのはやめたほうがいい(`.bash_profile`は一度しか読み込まないものを記述するべきなのに、`.bashrc`からロードすると何度も読み込まれてしまう)

じゃあ`.bash_profile`と`.bashrc`ってどうやって分けたらいいの？っていうと、個人的には環境変数を`.bash_profile`に書くのがいいと思っている。

環境変数はシェルを何回開いても前回の変数を引き継ぐ性質がある。
例えば、`.bashrc`に`export $PATH="$PATH:/opt/local/bin"`みたいなのを書いていたとする。この状態で`bash`、`bash`、`bash`と三回実行すると、`$PATH`のなかには`/opt/local/bin`が三つ入っていると思う。`/opt/local/bin`は一つあれば十分なので`.bash_profile`に書いておいても大丈夫ということである(実際に`.bash_profile`に書いておくと何回`bash`と入力しても`$PATH`には`/opt/local/bin`が一つだけになる)。

こんな感じで、環境変数みたいな実行しなおしても前回の状態を引き継ぐタイプのものは`.bash_profile`に書いたほうが効率的だと思う。
優れたアクセシビリティラベルを付けるには

この記事はWWDC19のセッション、[Writing Great Accessibility Labels](https://developer.apple.com/videos/play/wwdc2019/254/)を翻訳したものになります。記事中のスクショは、上記セッションのスライドを撮ったものです。

# 概要

VoiceOver や画面の読み上げ機能は、一部の人にとっては必要不可欠。これらが機能するためには要素にラベルを付ける必要がある。

# アクセシビリティラベルとは

アクセシビリティ要素を識別するための、ローカライズされた文字列を指す。アプリ内の要素にラベルを付け、コンテキストや意味を与える。コードは非常に簡単で、1行書くだけで良い。

```swift
button.accessibilityLabel = "Delete"
```

とはいえ、適切なラベルを付けるのは難しい。すべてはコンテキストによって変わる。

# コンテキストを理解する

「＋」ボタンにラベルを付けるとする。普通なら「Plus」かもしれない。ではこのような「＋」の場合はどうだろう。「Add」というラベルを付けるかもしれない。メモアプリであれば「新規メモを追加」ということが理解できる。
<img width="400" alt="スクリーンショット 2019-08-17 23.46.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/7c45dcaa-910d-db6b-6fff-a9d4c676cf00.png">
買い物の文脈では「お気に入りに追加」「カートに追加」も考えられるので、混同しないようなラベルにする必要がある。
<img width="400" alt="スクリーンショット 2019-08-17 23.50.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/45c05dd5-107f-1289-ef41-86b08c9a6f92.png">
「カートに追加」が複数ある場合は、「ピーナッツバターをカートに追加」が適切になる。
<img width="400" alt="スクリーンショット 2019-08-17 23.55.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/e738cdb3-ee3a-7bf4-ac8c-fc0ec28b031d.png">

このように、同じ記号でもコンテキストによって適切なラベルは異なる。

# ベストプラクティス

## 各要素にラベルを付ける

ラベルをつけないとボタンが複数並んでいても全部「ボタン」と読み上げてしまう。ラベルがなく、ボタン内に画像が含まれている場合はその画像名を読み上げてしまう。

## ラベルに要素タイプを含めない

VoiceOver は要素のタイプを認識しているので、ラベルにわざわざ「ボタン」や「タブ」を含める必要はない。

```swift
button.accessibilityLabel = "Add button" // x
button.accessibilityLabel = "Add" // ◯
```

## UIを変更したときはラベルも更新する

```swift
addRemoveButton.accessibilityLabel = "Add"
addRemoveButton.accessibilityLabel = "Delete"
```

## コンテキストに合ったラベルを付ける

同じアクションを示すボタンが複数ある場合は、コンテキストを追加する。

```swift
button.accessibilityLabel = "Add" // x
button.accessibilityLabel = "Add Peanut Butter" // ◯
```

不要なラベルは削除する。例えば音楽プレーヤーの場合、扱うものが曲ということは明白。

```swift
// △
prevButton.accessibilityLabel = "Previous song"
playButton.accessibilityLabel = "Play song"
nextButton.accessibilityLabel = "Next song"

// ◯
prevButton.accessibilityLabel = "Previous"
playButton.accessibilityLabel = "Play"
nextButton.accessibilityLabel = "Next"
```

## 意味のあるアニメーションにもラベルを付ける

アクティビティインジケータのようなアニメーションにラベルを加えると、VoiceOver がそれを伝えてくれる。

```swift
spinner.accessibilityLabel = "Loading..."
```

## 冗長なラベルを避ける

ラベルはできる限り簡潔に書く。コンテキストで内容が明らかな場合は省略しても良い。

```swift
button.accessibilityLabel = "Delete item from the current folder and add it to the trash" // x
button.accessibilityLabel = "Delete" // ◯
```

とはいえ長いラベルが常に悪いわけではない。クッキーモンスターのステッカーには長くて面白いラベルが付いている。ラベルは人を笑顔にすることもできる。

```swift
button.accessibilityLabel = "Me happy face eat small cookie, om nom nom"
```
Windows10 の ssh を使った AWS EC2 への接続

## Windows10 の ssh とは
Windows10 April 2018 Update より Windows10 でもデフォルトで ssh が使用できるようになりました。
これまで Tera Term などをインストールする必要があったのでデフォルトで ssh ができるようになるのはうれしいことです。

![コメント 2019-08-29 233843.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/ba76dcc3-40cb-bd16-1ab7-276c35c070f0.png)

この ssh を使って AWS の EC2 インスタンスに鍵を使ったアクセスをしてみようと思います。

## AWS EC2 に Windows の ssh からアクセスする
AWS の EC2 インスタンスを作ったときに AWS 上でキーペアを作成し、それを使ったアクセスをするときに少しハマったので情報を共有します。

### 問題
まずは適当な EC2 インスタンスを作成し、キーペアをダウンロードします。
ここでは鍵を `sample-key.pem` という名前で保存することにします。

![コメント 2019-08-30 231743.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/65ff8672-0590-2268-70dd-176071b59b5e.png)

これを使い、 `ssh -i .\sample-key.pem ubuntu@{public DNS}` で EC2 のインスタンスにアクセスしようとすると

![access_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/97eb3bf4-5bfd-6723-3614-9842546700b9.png)

**UNPROTECTED PRIVATE KEY FILE!**

と怒られてしまいました。
どうやらパーミッションのエラーのようです。
Linux では `chmod 0600 sample-key.pem` のようなコマンドでパーミッションを変更して対処すると問題なく ssh できるようになるようです。

しかし、 Windows には chmod がないので他の方法でパーミッションを指定する必要があります。

### パーミッションの変更
パーミッションの変更はコンテキストメニューのプロパティで表示されるダイアログのセキュリティタブで編集することができますが、今回はコマンドラインで変更してみます。
まず、今どのようなパーミッションが設定されているかは `icacls .\sample-key.pem` で確認することができます。

![コメント 2019-08-29 235448.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/904dcb09-4128-49a7-2d37-051fa19f0b8d.png)

以下の4つのユーザーにパーミッションが設定されていることがわかりました。
* UILTIN\Administrators:(I)(F)
* NT AUTHORITY\SYSTEM:(I)(F)
* UILTIN\Users:(I)(RX)
* NT AUTHORITY\Authenticated Users:(I)(M)

このパーミッションの設定はそれぞれの環境によって変わると思われますが今回はパーミッションを持っているユーザーが多すぎたようなので、ssh するユーザーだけにパーミッションを与えるように設定を変更します。
まず、余分なユーザーのパーミッションを削除します。
今回はすべてのユーザーに(I) がついている(親コンテナから継承されたパーミッションである)ため次のコマンドで削除を行います。
`icacls .\sample-key.pem /inheritance:r`

![コメント 2019-08-30 001802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/ad731c81-138e-ee02-4fc8-e9f58afe1a86.png)

これでパーミッションがクリアされたので ssh する ユーザーにパーミッションを設定します。
`icacls .\sample-key.pem /grant "{User Name}:(F)"`

![setting_ACE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/fa0f9e71-9da1-5be8-fc8a-9ff501606aba.png)

これで以下のように `sample-key.pem` には ssh するユーザーだけがパーミッションを持っている設定になります。
* .\sample-key.pem {PC Name}\{User name}:(F)

### ssh 接続のリトライ
パーミッションの設定ができたので再度 `ssh -i .\sample-key.pem ubuntu@{public DNS}` で EC2 に接続を試みてみると

![ssh_success.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173077/829779d5-5202-d4b7-941c-e4835f324544.png)

接続できました!
RESTfull APIって？



##そもそもRESTってなに？
参照　http://e-words.jp/w/REST.html

RESTは**「リソース」**を扱うための考え方のこと。

リソースの意味も忘れないようにメモ。
**「リソース」**→例えばアップロードした画像や、ブログの記事やWebページ全体のコンテンツであったりといった、ひとかたまりの要素・情報のことを指します。

RESTの考え方では、リソースはそれぞれ固有のURIを持っていて、
そのURIにアクセスすることで、それぞれのリソースを操作することができます。

つまり、
**・GET：リソースの取得**
**・POST：リソースの新規作成**
**・DELETE：リソースの削除**
**・PUT：リソースの更新**
などなどで何を行うか伝えるということ。

ちなみに、HTTPメソッドで表現しにくい操作には
例えばメール送信などその場合は**カスタムメソッド**を使用するらしい。
おそらく**１:sendMail**とかそんな感じになるかと思います。


##じゃあ次にAPIってそもそも何？
参照　https://data.wingarc.com/what-is-api-16084

APIとは**Application Programming Interface**を省略して呼んでいる。
上記URLにわかりやすく記載してくれているが、自分用にも少しメモ。

つまりAPIとは、
ソフトウェアやアプリケーションなどの一部を外部に向けて公開することにより、
第三者が開発したソフトウェアと機能を共有できるようにしてくれるもののこと。

##RESTじゃないAPIってどんなもの？
RESTなAPIは、リソースに対応づいてURLが決まるから、
処理にはURLは対応づかないはずなのに、ついてしまっているもの。

例えば、ユーザー情報を作成したくて、
http://api.dayo.cooom/CreateUser/1/UserMain
とかこんな感じになるのかなと・・・

これだとSQLインジェクションのリスクも高くなってしまう。
（SQLインジェクション：データベースと連動したWebアプリケーションなどに対する攻撃手法の一つ）

##RESTful APIのメリットって？

・アドレス欄に入力すればそのリソースを参照できる。
　（例）chat/と入力すればchat画面にいける。
・URLの規則のおかげで開発者が楽になる。
・データフォーマットを扱うことで、他システムとの連携が容易になる。などなど。


##実際自分でも簡単なRESTfulAPIを作成してみた

golangでネットで検索しつつ、見よう見まねで作成してみました。
![スクリーンショット 2019-08-30 23.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/6812a600-b34f-d56b-8d29-b4bbc313f6fd.png)

簡単な本のWEBページを作成して、
**/books**とURLを追加してみる。

![スクリーンショット 2019-08-30 22.45.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/a3fa4be4-1763-f9b0-e36e-4b72c71acc0b.png)
まだデータがないので何も反映はされない。
なので、簡単にデータを作成してみました。

![スクリーンショット 2019-08-30 23.57.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/7aa26dba-971b-e23a-9d65-4682bb3d601d.png)

すると、
![スクリーンショット 2019-08-30 23.10.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378334/877f5b33-57c5-c1d9-30f0-9fdd2385d3fc.png)
無事、jsonでデータがかえってきました！


ここまでくるにもかなり調べて時間をかけたりしたので、
（もっと効率よく調べる方法も身に付けたい・・！）
さらに基礎を固めて、もう少し複雑なものにも今後挑戦したいと思います！
showメソッドだけ使えてfadeInメソッドが使えない！　誰か助けて(´;ω;｀)

jQueryでshowメソッドとfadeInメソッドを使ってみたのですが、
showメソッドは使えて、fadeInメソッドは、使えないという不思議な現象が起こりました(´;ω;｀)
色々調べてみたのですが、解決せずでした、、、。

誰かわかれば教えてください:joy:
よろしくお願いします。

![アニメーション3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458009/42efd975-f2e1-44fb-9ee5-7ee08cdf5b71.gif)

上の図のように、クリックしたら、モーダルを表示したいのですが、fadeInは使えません、、、、、。



関係ありそうな部分のコードだけ掲載しておきます。

HTML

```html
  <div class="modal-wrapper" id="login-modal">
       <div id="modal">
        <h1 class="text-center">学習内容</h1>
      	<p class="text-center"><a href="">実験器具の使い方</a></p>
      	<p class="text-center"><a href="">物質・密度</a></p>
      	<p class="text-center"><a href="">状態変化・蒸留</a></p>
      	<p class="text-center"><a href="">気体の性質</a></p>
      	<p class="text-center"><a href="">水溶液・溶解度</a></p>
      	<p class="text-right"><a href="">閉じる</a></p>
       </div>
      </div>
```



CSS

```css

.modal-wrapper {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 100;
  display: none;
}

  #modal{
  	width:50%;
  	margin:250px auto 0;
  	padding:10px 20px;
  	border:2px solid #aaa;
  	background:rgb(236, 245, 242);
    border-radius: 32px;
  	z-index:2;
  }

  #modal p{
  	margin-top:1em;
    font-size:36px;
    border-bottom: solid rgb(155, 159, 149);
  }

  #modal a{
    color:rgb(52, 91, 171);
  }
```

jQuery

```js

$(function(){

  $('#modal-1').click(function(){
   $('#login-modal').show();
  });

});
```

ちなみに、以下がfadeInメソッドを使ったときのエラー文です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458009/22ab77e6-5a3e-828f-2dd0-6ffd4cf1008c.png)

何ででしょう、、、(´;ω;｀)
goleakでgoroutine leakのリスクを減らす

## このページについて

uberが手掛けている[goleak](https://github.com/uber-go/goleak)を使ってgoroutine leakを検出できるか試してみました。簡単なデモコードではしっかりエラーにしてくれたので、使ってみてもよいのかなと思います。

現在(2019-08)**α版** なのでもう少し待ってみてもいいかもしれませんが、、

## 内容

goroutine leakの起こる関数を書き、goleakを使って検出できるか試してみます。

**関数**

```go
package helper

import (
	"fmt"
	"time"
)

func Leak(sleep int) {
	fmt.Println("leak test")
	go func() {
		fmt.Println("start goroutine")
		for {
            // leak しないパターンも試す
			if sleep == 0 {
				return
			}
			time.Sleep(time.Duration(sleep) * time.Second)
		}
	}()
}
```

**テスト**

```go:leak_test.go
package helper

import "testing"

func TestLeak(t *testing.T) {
	type args struct {
		sleep int
	}
	tests := []struct {
		name string
		args args
	}{
		{
			name: "leak",
			args: args{
				sleep: 1,
			},
		},
		{
			name: "not leak",
			args: args{
				sleep: 0,
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			Leak(tt.args.sleep)
		})
	}
}

```

goleakはパッケージ全体に適用したい場合は**TestMain**から動かすと良いみたいです

```go:main_test.go
package helper

import (
	"testing"

	"go.uber.org/goleak"
)

func TestMain(m *testing.M) {
	goleak.VerifyTestMain(m)
}
```

これで準備は整いました。
テストを実行します

```bash

$ go test -v ./...
=== RUN   TestLeak
=== RUN   TestLeak/leak
leak test
start goroutine
=== RUN   TestLeak/not_leak
leak test
start goroutine
--- PASS: TestLeak (0.00s)
    --- PASS: TestLeak/leak (0.00s)
    --- PASS: TestLeak/not_leak (0.00s)
PASS
coverage: 100.0% of statements
goleak: Errors on successful test run: found unexpected goroutines:
[Goroutine 33 in state sleep, with runtime.goparkunlock on top of the stack:
goroutine 33 [sleep]:
runtime.goparkunlock(...)
	/usr/local/Cellar/go/1.12.1/libexec/src/runtime/proc.go:307
time.Sleep(0x3b9aca00)
	/usr/local/Cellar/go/1.12.1/libexec/src/runtime/time.go:105 +0x159
github.com/smith-30/ootd/helper.Leak.func1(0x1)
	/go/src/github.com/smith-30/ootd/helper/leak.go:16 +0xa0
created by github.com/smith-30/ootd/helper.Leak
	/go/src/github.com/smith-30/ootd/helper/leak.go:10 +0xa6
]
FAIL	github.com/smith-30/ootd/helper	0.457s
Error: Tests failed.
```

goroutineリークを検出してテストを落としてくれていますね!
もちろん、テストケースが `not leak` のみの場合はエラーで落ちません
goroutineをバリバリ使うデーモンや並列処理を使うAPIのメインロジックのe2eテストの際には使っていきたいと思っています。
AWS Certified Developer - Associate の取得

# 目的
- エンジニアとしての気持ちを忘れないように、少しずつAWSの勉強をしている。なんとなく勉強した成果というか証がほしいので順番に資格を取得していく。

# 勉強方法の方針
- Solution Architectは参考書がたくさんあるが、DeveloperやSysOps Administrator等は参考書がなく、どんな問題が出てどれくらいできればよいのか分からない。
- 今回は英語の勉強も兼ねて、英語の有料学習サイトの「Linux Academy」を使ってみる。他にもudemyとかいろいろあるが、たまたま最初に目に留まったため。

# Linux Academy での勉強
- 月額課金コースだと、$49/Month。年契約すると割引あり。
- 資格毎にコースが構成されており、取りたい資格のコースを好きなだけ選択可能。今回は「AWS Certified Developer - Associate Level」を受講する。AWSの他、AzureやGCPの資格取得対策コースもある。
- コースの構成としては、サービス毎(IAM, EC2, VPC等)に、1)講義のビデオ、2)ハンズオン、3)テスト　の3ステップになっており、これを順番にやっていく。
- 全部講義ビデオを見るとかなり時間がかかるので、EC2とかIAMとか、ある程度理解しているところは、講義ビデオは省略する。
- 通勤でビデオを見て、家でハンズオンやテストを実施。触ったほうが覚えるのでハンズオンはなるべく実施する。ハンズオンはサンドボックスになっているので自分のAWSアカウントを使う必要はない。

# 受験
- 試験結果：　合格(778点)
- 真面目に勉強したつもりだったがギリギリだった。

# 所感
- 当然のことだが、実際に触ると、意識せずとも設定項目や手順をなんとなく覚えるので、実際に触ってみるのが大切と改めて実感。Linux Academyだけに頼らず、各サービスの操作を試してみるのが必要。
- Linux Academyの講義ビデオの英語が聞き取れないことがあるが、私のような人向けに字幕が付いた（全部ではない？）のでありがたい。当然ながら講義ビデオ、ハンズオンのテキスト、テスト問題等全て英語なので、ついでに英語の勉強になった。
- Linux Academyはコンテンツ買い切りではなくサブスクリプションモデルなので、休みなくたくさんやらないと損してしまう。次はこの流れでSysOps Administrator - Associate を取得したい。
Azure Functions (C#) で ASP.NET Core っぽく DI を利用する

# 概要
Azure Functions にて .NET Core で開発する際において、DIを用いた実装方法について纏めます。
ASP.NET Core にて利用したように、Serviceインスタンスの依存関係注入がやり易い形になっています。

公式のドキュメントは、下記になります。
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-dotnet-dependency-injection

以下、記事を参考にさせていただきました。
https://blog.shibayan.jp/entry/20190520/1558340113
https://qiita.com/HiroyukiSakoh/items/e9e472a92a53da4d7568

# 環境
- Azure Functions v3
- Windows10
- Visual Studio 2019
- .NET Core 3.1

# コードサンプル
サンプルコードを Github にアップしています。
https://github.com/tYoshiyuki/azure-functions-di-sample
(※) コードサンプルを Azure Functions v3 に更新しました。

# 解説
公式の記事の通り、Microsoft.Azure.Functions.Extensions を Nuget より取得し、プロジェクトに加えます。
https://www.nuget.org/packages/Microsoft.Azure.Functions.Extensions/

Startup.cs にて DI の設定を行います。
実装例として、設定ファイルの読み込みとサービスのDI設定を行っています。

```cs:Startup.cs
[assembly: FunctionsStartup(typeof(Startup))]
namespace AzureFunctionsDiSample
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var services = builder.Services;
            var provider = services.BuildServiceProvider();
            var configuration = provider.GetRequiredService<IConfiguration>();
            
            // 設定ファイルの内容をバインドする
            services.Configure<AppSettings>(configuration.GetSection("AppSettings"));

            // サービスのDI設定を行う
            services.AddTransient<IHelloService, HelloService>();
            services.AddTransient<IApplication, Application>();
        }
    }
}
```

コードサンプルは、以下のようにクラスのレイヤー分けを行っています。

|クラス名|説明|
|:--|:--|
|EntryPoint|Azure Functions のエントリーポイント|
|Application|メインとなるアプリケーション|
|HelloService|ビジネスロジックサービス|

Azure Functions のエントリーポイントとなるクラス (EntryPoint.cs) から、
実際のアプリケーション処理を行うクラス、サービス処理を行うクラスを別レイヤーに切り出しています。
これにより、エントリーポイントとアプリケーションの依存関係を分離し、ユニットテストを実施し易い形にしています。

DIで設定したインスタンスは、コンストラクタインジェクションで受け取ります。
ASP.NET Core で利用する形と同じようなイメージになります。

```cs:EntryPoint.cs

public EntryPoint(IApplication application)
{
    _application = application;
}

[FunctionName("FunctionsDiSample")]
public IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    log.LogInformation("Function Run");

    _application.Run();

    return new OkObjectResult("Hello Functions DI Sample");
}

```

EntryPointでは Application を受け取り、また同様に Application では HelloService を受け取ります。
設定ファイルについては、IOptionsで受け取れます。

```cs:Application.cs

private readonly AppSettings _appSettings;
private readonly IHelloService _service;

public Application(ILogger<IApplication> logger, IOptions<AppSettings> optionsAccessor, IHelloService service) : base(logger)
{
    _appSettings = optionsAccessor.Value;
    _service = service;
}

```

ASP.NET Core で開発する際に意識するような クラスのレイヤー分け のノウハウが、
Azure Functionsでも生かせるようになり、今後の開発の幅が広がると思います。
FakeNews 誰でもフェイクニュースを書き込めるサイト

# フェイクニュース書き放題

###近年フェイクニュースの問題は世間を騒がす対象になっていなすが。いまだにそのいい解決方法が出てきていません。

そこで、私は誰でもフェイクニュースを書き込めるプラットフォームを作る
という解決方法を見つけ出しました。

誰でもフェイクニュースを書き込めるということでツイッターやfacebookに書き込まれる
いたずらが原因のフェイクニュースは減少させられると見込んでおります。

#登録方法
まずフェイクを投稿するにはサイトに登録しなければなりません
こちらのURLですhttp://fakebook.xsrv.jp/
下の画像の「新規登録」という項目をクリックしていただくと必要事項の
入力フォームに飛びますので、必要な物を入力してください。
<img width="375" alt="IMG_1621.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/b225801b-218a-fce0-e662-1a6d57c38684.jpeg">

ログインの場合はうえの画像を参考に新規登録の際に入力した
メールアドレスとパスワードを入力して頂ければログインできます。
**次からログインを省略のチェックボックスにチェックを入れれば
5年間ログインしなくても使い続けられます**

登録をせずに記事を読むだけなら**読むだけならこちら**をクリックしてください

#主な機能

1.フェイクニュース投稿
2.記事の検索
3.フォロー機能
4.記事に対するコメント

### １．フェイクニュース投稿
![Billy Joel - It's Still Rock and Roll to Me (Official Video) - YouTube - Google Chrome 2019_08_30 22_29_06 (2)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/fcf21d04-5864-2eb1-4a61-8fd8da1533a8.jpeg)

画像の右にあるフェイクするのボタンを押すと、記事作成フォームに飛びます。
![Billy Joel - It's Still Rock and Roll to Me (Official Video) - YouTube - Google Chrome 2019_08_30 22_37_50 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/6b9b7f27-dba9-28b2-0c57-ccd273376ceb.png)

そこでタイトル、フェイクニュースの内容、画像の選択をすればフェイクニュースは完成です。
次に確認画面にうつりそこで完了すれば最新のトレンドとして投稿が追加されます。

### ２．記事の検索
この検索窓に好きなワードを入力するとそれに関連したフェイクニュース
が読めます。
![Billy Joel - It's Still Rock and Roll to Me (Official Video) - YouTube - Google Chrome 2019_08_30 22_29_06 (3)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/770a30dd-494e-4cde-f00d-9163d907d4e7.jpeg)

### ３．フォロー機能
ユーザー名のURLをクリックしてユーザープロフィールに移動すると以下の画面が
表示されます。「フォロー＋」と書かれたボタンを押すとそのユーザーをフォロー
することができます。
![FakeNews - Google Chrome 2019_08_30 22_52_06 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/b5d2c80e-bdba-3b0d-9936-d2e22455b5ab.png)
フォローしたユーザーは、自分の名前をクリックして出てくる欄の「フォロー」という項目
をクリックすればフォローしたユーザーとフォロワーの一覧が見られます。
<img width="375" alt="IMG_1617.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/816bdea1-81a4-01d0-98a2-001d308c34db.jpeg">

上の写真の友達の投稿という項目をクリックするとフォローしたユーザーとフォロワーの投稿
が見られます。

### ４．記事に対するコメント
記事を読む画面の一番下側にコメント入力フォームがあります。
そこから自分のコメントを書き込めることができます。
<img width="375" alt="IMG_1619.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367083/60a940ca-cd37-65d3-cefd-abdc8c36dc1f.jpeg">

以上がFakeNewsの機能及び使い方の説明でした。
echo コマンド（シェルビルトイン）を試してみる

こんにちは。
dash のビルトインの echo コマンドは POSIX echo のようです（```echo -e hello``` を実行すると ```-e hello``` と出力され ```-e```オプションを持っていません）[^1]。
これに対して bash や zsh のビルトインの echo コマンドは GNU echo のようです。

[^1]: また MacOSX や BSD の /bin/echo も POSIX echo のようです。

```console
$ dash -c 'LANG=en_US.UTF-8; type echo; echo -e hello'
echo is a shell builtin
-e hello
$
$ bash -c 'LANG=en_US.UTF-8; type echo; echo -e hello'
echo is a shell builtin
hello
$ zsh -c 'LANG=en_US.UTF-8; type echo; echo -e hello'
echo is a shell builtin
hello
$ dash -c 'LANG=en_US.UTF-8; type gecho; gecho -e hello'
gecho is /usr/local/bin/gecho
hello
$
$ uname
Darwin
$ dash -c 'LANG=en_US.UTF-8; type /bin/echo; /bin/echo -e hello'
/bin/echo is /bin/echo
-e hello
```

なお ```type echo``` の出力から、それがビルトインの ```echo``` であることが確認できます。

```console
$ type echo
echo is a shell builtin
$ type -a echo
echo is a shell builtin
echo is /bin/echo
```

------------------

* ところで、何のコマンドを用いればそのシェル名を得られるのだろうか．．．？

```dash -c '何かのコマンド'```  →  ```dash```
```bash -c '何かのコマンド'```  →  ```bash```
【連載】初めてのReact Native + Expo開発環境構築入門(Windowsベース)

　この記事では、Windows 10にExpoを使ったReact Nativeの開発環境を1から構築し、サンプルアプリを作成するところまでをゴールとします。
　1つの記事ですべてカバーできないので、いくつかの記事に分けて少しずつ投稿していく連載にしていきます。
　なお、筆者はアメリカで開発業務を行っているため、選択するトレンドなどはアメリカ主体となります。

[Mac Catalina版はこちらにおまかせしました](https://kyokara.com/start-expo-mac/)

# 環境

開発環境は、2019年8月時点最新の以下のソフトウェアで構築します。

- Chrome 最新 (76.0.3809.100 (64-bit))
- Visual Studio Code 最新 (1.37.1)
- Node.js + npm 最新 (10.16.3)

※npmが最新なので、npmでのinstallは--saveを省略します。

# なぜExpo?

　モバイルアプリ開発のクロスプラットフォームには、Cordova (ionicやMonaca含む)、Xamarin、最近ではFlutterなどいくつもの選択肢がありますが、その中で以下のメリットが強いときにReact Native + Expoを使うのがよいかと思います。

- とにかく開発工数を小さくしたい。
- 業務用アプリなどで、細部にはあまりこだわらない
- Web開発の知識をなるべくそのまま応用したい。
- JavaScriptの知識をメインにして作りたい
- Reactの知識がすでにある
- デバイスに依存した機能は使わないプロジェクト、またはモックアップ用
- 実機でデバッグを簡単に実施したい
- 簡単に配布したい

　同じような条件では、Monacaが競合に入ってきます。実際私も過去にMonacaを使って開発しましたが、Reactのメリットを感じない場合はMonacaでもいいかなと思います。ただ、最近よくReactを使うから今さらjQueryはあまり積極的に使いたくないとか、データ取り扱いでやっぱりReactにメリットを感じるといった場合は、Expoサイコーでよいと思います。

　なお、React Native (=react-native-cli)じゃなくてReact Native + Expoな理由は、[この辺りの記事](https://qiita.com/kaba/items/03053d3b9ab356e00557)が参考になります。

# 記事一覧

　連載内容の予定です。途中で大幅に変更する可能性があります。

- [Expoのアカウントを作ってReact Nativeの開発環境を整える](https://qiita.com/hitotch/items/ea4de1ed408a9ca14fce)
- [React Native Expoの編集環境をVisual Studio Codeで準備する](https://qiita.com/hitotch/items/70bbf3e7a7f5f79dc265)
- [React Native + Expo + Visual Studio Code + Chrome で実機デバッグする](https://qiita.com/hitotch/items/285f6f3b1eab656908d7)
- エミュレータでデバッグする -> スキップ
- [React Native + Expo に、ルート管理ライブラリreact-navigationを導入する](https://qiita.com/hitotch/items/0ceca6eb440c06512c51)
- [React Native + Expo + react-navigationで、アプリの画面構成を作成する](https://qiita.com/hitotch/items/79533682670d4ecd2355)
- [React Native + Expo + unstated (+ react-navigation)で、簡単グローバルState管理＋ローカルデータ管理を実現する](https://qiita.com/hitotch/items/36dcc678976bd4ebe006)
- [React Native + Expo アプリに Native Base 導入で楽々画面デザイン](https://qiita.com/hitotch/items/3bba68417af561b1a4d0)
- [React Native + Expo アプリで unstatedのStateにaxiosを使って簡易テストサーバーからデータ取得](https://qiita.com/hitotch/items/f4f227a6ca3ca6c62e8e)
- [React Native + Expo アプリで QRコードを読んでJSON取得](https://qiita.com/hitotch/items/de06a44b3aa699f0f4cb)
- [React Native + Expo アプリでunstatedのデータを永続化](https://qiita.com/hitotch/items/f563ec8a60f05bb7edd8)
- [React Native + Expo アプリをPublish(公開)する：テスト配布する](https://qiita.com/hitotch/items/5f72523fc4c769e31e3a)
- [React Native + Expo アプリをDeploy(ネイティブビルド)する](https://qiita.com/hitotch/items/04637fb753482ed683ee)
ラムダ式とは

# ラムダ式とは

関数型言語由来の概念。
関数型言語とは「関数を値と同じ様に扱える」言語。

"値"というのは数値とか文字列とかリストとか。
値と同じ様に扱えるとは、

- 変数に代入できて
- 関数の引数に渡せて
- 関数の戻り値にできる

ということ。

例えば、引数に値をとり、それに10を足して返す関数

```
F(x) = x + 10
```

のような関数。
関数型言語ではこの関数を値として取り回せる。

では、上記の関数を変数に代入するにはどうすればよいか。
この「値として取り回せる関数の書き方」がラムダ式。

例えば、関数型言語のHaskellでは上記の関数は

```
 f = x -> x + 10
```

というふうに記述できる。

「【数値xを受け取り、それに10を足した値を返す関数】を、fという変数に代入した」と思って下さい。

この書き方は言語により異なるが、どれもラムダ式である。
どれも「値として取り回せる関数の書き方」を定義したものだから。
-> とか => とか細かな書き方の違いは関係ありません。

と、ここまでがラムダ式の話なのだがJavaやC＃では少々事情が異なる。

これらはクラスあっての言語なので関数はクラスの中、つまりメソッドという形でしか存在できないからです。

なので、function(C#だとFunc)インターフェイスを作り、擬似的に関数として取り回せる様にしている。

例えばJavaで

```java
Function<Integer, Integer>f = new Funciton<>(){
    public Integer apply(Integer x){
        return x + 10;
    }
}
```

の省略記法に過ぎないわけです。

単なるインスタンスなので、変数に代入できるし、引数にも戻り地にも出来る、というわけです。

以上がラムダ式の説明になります。

- 「そもそもラムダ式とはなんなのか」
- 「（関数型言語由来の概念である）ラムダ式を、オブジェクト志向言語に落とし込むには？」

がごっちゃになると一気にわけがわからなくなるので、この2つは分けて考えたほうが良いですね。
ContractCodeが特定アドレスのERC20トークンをburnするには少し工夫がいるよ、という話

# tl;dr
- コントラクト内でコード実行者のERC20を```burn（amount）```できないよ
    - ex) Aアカウントアドレスがサービスコントラクトを実行し、サービスコントラクトがERC20トークンコントラクトの```burn(amount)```を実行できない。
- ↑のburn実行時の```msg.sender```は、サービスコントトラクトのアドレスになるよ
- ```burnFrom(account, amount)```でできるけど、burnしたい量と同じ量だけ先に`approve`しておく必要があるよ


## 前提

solidity 0.5.0

# 事象

サービスコントラクト内で特定のERC20トークンをburnしようと下記のコードを実行

```solidity
function doSomethingAndBurnToken(uint256 _tokenNumber) public {
    // 〜何らかの処理〜
    ERC20Burnable(DEVaddress).burn(_tokenNumber);
}
```


すると```Error: Returned error: VM Exception while processing transaction: revert SafeMath: subtraction overflow -- Reason given: SafeMath: subtraction overflow.```で落ちた。


# 原因

そもそも勘違いしてた（というか一度ハマって調べた事あったのに覚えてなかった、、、）のが、コントラクトAからコントラクトBをコールした場合、コントラクトBにおける```msg.sender```はコントラクトAのアドレスになる。
コントラクトAを実行したアカウントアドレスではない。


# 対処

なので、特定のコントラクト内から処理実行者のERC20のburnをするには工夫がいる。
代わりに```burnFrom(account, amount)```が使える。見たまま、あるアカウントの所有するERC20をburnできる。
ただ、勝手にburnされることを防ぐため、予めそのERC20の```approve(address spender, uint256 amount)  ```を実行しておく必要がある。


approveは特定のコントラクトアドレスに自身のトークンの内、一定数を操作できるようにプールしておける機能。
なのでburnをする前にburnしたいトークン数分だけ予めapproveしておく必要がある。
approveしてれば、下記のような実装でburnが可能になる。

```solidity
// In advance, msg.sender is supposed to approve same amount DEV token as vote number.
ERC20Burnable(DEVaddress).burnFrom(msg.sender, _tokenNumber)
```



## 参考

- https://qiita.com/Kumamera/items/a81de80a56340076e254
- https://blockchain.gunosy.io/entry/token-summary-and-token-contract#approve--transferFrom--allowance
- https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol
EC2上でwebpackを実行したらNo space left on deviceと出てバンドリングできなかった

作業メモです。

ディスク容量が足りていないとのことで確認。

```
$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         488M   56K  488M    1% /dev
tmpfs            498M     0  498M    0% /dev/shm
/dev/xvda1       7.8G  7.7G     0  100% /
```

この場合ec2のコンソールからボリュームをアタッチすればいいのですが、　そんなにメモリを圧迫するようなことをした覚えがなかったので、インスタンスを再起動して再び確認。

すると使用率が48%となっており、webpackも問題なく動きました。　原因は謎です。
本ではなくレーザープリンタと転がってるPDFで勉強するとなんか捗った話

前は僕は本で勉強してましたが、最近はネットでゴロゴロ転がってるPDFを１０ページぐらいずつレーザープリンタで印刷して読むことにしてます。
その利点をまとめると以下の通り

##１０ページぐらいちまちまと印刷して読むので、達成感がある。
普通技術書って何百ページもあるので、３０ページぐらい読んでも半分も行ってないんですよね。で、挫折しちゃう。でも１０ページぐらいちまちま印刷して読めば、ちまちまと達成感があるので、なかなかに捗ります。

##ディスプレイを見てないので目とメンタルヘルスにいい
本との比較じゃないんですが、紙ってやっぱり目とメンタルヘルスにいいんですよね。ディスプレイは開発中やドキュメント作成中は見ることになるし、基本的に現代人はディスプレイ見過ぎだと思います。ウロウロ部屋の中を歩きながら読めるのもいいです。iPadじゃあ絶対に読めないです。

##金がかからない
ネットに転がってるPDFを使うし、レーザープリンタもコストは一枚３円ぐらいなので、財布にやさしいです。レーザープリンタ自体も最近安いです。でも、読み込んでるPDFで、書籍版があった場合はリスペクトを込めて買ってあげるべきだと思います。PDFを売ってる場合もあるのでそれを買う手もありますね。あと、著作権法は守りましょう。印刷したものは個人用途でしか使えないと思います。

##アクセスできる情報量が本より多い
英語のPDFが多くなるんですが、書籍よりネットに転がってるまたは売ってるPDFを印刷して読んだ方が情報の母数が多いです。英語の書籍は日本だと英国や米国から取り寄せになったりして、結構大変なんですよね。論文とかも山ほどあったりして、これはもうPDFでしか手に入らないです。

ということで、最近は本ではなくレーザープリンタで勉強してます。参考までに
JavaScript(条件分岐、オブジェクト、for文、関数の定義方法)について

コンソールに記入/表示する
JavaScriptはブラウザ上で動く言語であるため検証ツールからコンソールを開く事でコードが書く事ができる。


変数宣言の際に定義する必要がある

**let 後で置き換える事のできる変数宣言
conset　後で置き換える事ができない変数宣言**

#条件分岐の仕方
条件式は（）で囲む
処理内容は{}で囲む
複数条件の際はelse ifとする　

```js
let num = 60;

if (num % 15 == 0) {
  console.log(num + 'は3と5の倍数です');
} else if (num % 3 == 0) {
  console.log(num + 'は3の倍数です');
} else if (num % 5 == 0) {
  console.log(num + 'は5の倍数です');
} else {
  console.log(num + 'は3の倍数でも、5の倍数でもありません');
}
```

#オブジェクト
データのまとまりのこと。配列は順番での管理だが、オブジェクトはデータを名前と値をセットで管理できる。このセットをプロパティという。
作成方法には{}を使う

例１）

```js
let a = {};
```

例２）

```js
let a = {name: 'imada'};
        プロパティ名  値     
```

######値の取得、変更方法
名前を取り出したい場合

```js
let a = {name: 'imada', age: '25'};
console.log(a.name);
```

名前をtanakaに変更したい場合

```js
let a = {name: 'imada', age: '25'};
a.name = 'tanaka';
console.log(a.name);
```

#for文
繰り返し処理はfor文を使う

例

```js
num = 1
for (let i = 0; i < 100; i += 1){
   console.log(num + '回目')
   num += 1
}
```

#関数の定義方法
####function文
```js
function 関数名（引数）{
  処理内容
}
```
※注意）**引数が無くても記入しなくてはならない**

return文について
Rubyでは関数において最後の戻り値が関数の戻り値として返すがJavaScriptではreturnを明示する必要がある

#####関数の定義種類
1.関数宣言
2.関数式（無名関数）

```js
 関数宣言
function hello(){
  console.log('hello');
}

 関数式（無名関数）
let hello = function(){
    console.log('hello');
}
```
役割に大きな違いはないが、関数式にする事で代入や他の関数に渡しやすくなる
herokuへのデータベースのリセットとサンプルデータの生成

##heroku上のデータベースをリセットしたい場合
```
heroku pg:reset DATABASE
```
##リセット後
```
heroku run rails db:migrate
heroku run rails db:seed
```
結果は同じだがこちらのコードでも大丈夫↓

```
heroku run rake db:migrate
heroku run rake db:seed
```
git pushがreject（拒否）されたときの対処法

リモートにプッシュした時、次のようなエラーが返ってきた。

```
To github.com:○○○○○○/○○○○○○○
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:○○○○○○/○○○○○○'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

##状況確認
`non-fast-forward` は、下のような状況で言うと`master`ブランチのリモートとローカルの最新情報が異なっていることを示す。そのため、通常のプッシュが行えず、`reject`が表示される。

```
master    a --- b --- c --- d --- e
(リモート)
　　　　　　　　　 
master    a --- b --- c --- d --- f
(ローカル)　   　
```

##対処法１
```
$ git pull origin master　　リモートの情報をローカルに持ってくる(自動的にマージも行われる)
$ git push origin master　　最新情報が一致するため通常のプッシュが行える
```


##対処法2
```
$ git push -f origin master  　強制(force)的にプッシュする
```
PSRのクラス・定数・プロパティ・メソッドの命名規則

命名規則について、PSRを参考にしてみた。

## PSRってなに？
PHP Framework Interop Groupが策定しているPHPコーディング規約。

■wiki（PHP Standard Recommendation）
[https://en.wikipedia.org/wiki/PHP_Standard_Recommendation](https://en.wikipedia.org/wiki/PHP_Standard_Recommendation)

> PHP Standard Recommendation（PSR）は、PHP Framework Interop Groupによって公開されたPHP仕様です。 JavaのJava Specification Requestと同様に、PHPのプログラミング概念の標準化に役立ちます。目的は、コンポーネントの相互運用性を有効にし、最適なプログラミングとテストの実践のための実証済みの概念を実装するための共通の技術的基盤を提供することです。 PHP-FIGは、いくつかのPHPフレームワークの創設者によって形成されています。[1] 各PSRはメンバーによって提案され、合意されたプロセスに従って一貫して行動するために、確立されたプロトコルに従って投票されます。

PHP Framework Interop Groupのサイト[（https://www.php-fig.org/）](https://www.php-fig.org/)

## 命名規則

### 参考にしたサイト
**PHP-FIG**
[https://www.php-fig.org/psr/psr-1/](https://www.php-fig.org/psr/psr-1/)

### クラス名
**スタッドリーキャップス（StudlyCaps）**で宣言！
先頭文字と単語の区切りを大文字にする命名規則。

```php
// StudlyCaps
class ClassName
{
}
```

### 定数
**スネークケース&大文字**で宣言！
単語の区切りをアンダースコア（_）、定数名は全て大文字

```php
// StudlyCaps
class ClassName
{
    // snake_case
    const CONSTANT_NAME = 'name';
}
```

### プロパティ
> This guide intentionally avoids any recommendation regarding the use of ```$StudlyCaps```, ```$camelCase```, or ```$under_score``` property names.
Whatever naming convention is used SHOULD be applied consistently within a reasonable scope. That scope may be vendor-level, package-level, class-level, or method-level.

スタッドリーキャップス、キャメルケース、スネークケースどれ使ってもいいけど、
ベンダーレベル、パッケージレベル、クラスレベル、メソッドレベルで統一して下さいと:relaxed:

### メソッド
**ローワーキャメルケース**で宣言！
先頭文字小文字の単語の区切りを大文字にする命名規則

```php
// StudlyCaps
class ClassName
{
    // snake_case
    const CONSTANT_NAME = 'name';
    // camelCase
    public function methodName()
    {
    }
}
```
PowerApps,Flow新ライセンスプランの注意点

#Azure系コネクタがPremium？！
***※本投稿の記載は正式なアナウンスではありませんので、詳細は公式情報を参照してください。***

新ライセンスの適用であたふたしてしまいますよね。特にAzure系が標準コネクタに入らなくなると、これはかなりインパクトかなと思います。
SharePointのカスタムリストでアプリつくったり、SQLDBでアプリつくったりして、CDSのコスト負担を回避していたユーザーにとっては、現行環境どうしてくれるんだという懸念があるかなと思います。
（対象コネクタ抜粋）
- Azure Application Insights
- Azure Automation
- Azure Blob Storage
- Azure Container
- Azure Cosmos
- Azure Data Factory
- Azure Data Lake
- Azure DevOps
- Azure Event Grid
- Azure Event Grid Publish
- Azure File Storage
- Azure IoT Central
- Azure Kusto
- Azure Log Analytics
- Azure Log Analytics Data Collector
- Azure Queues
- Azure Resource Manager
- Azure SQL
- Azure SQL Data Warehouse
- Azure Table Storage

新規ユーザーのみなさま、というか10/1以降に上記のコネクターを利用する場合には確かにPremiumになりますので、有償プランの購入が必要になります。

#見落としがちなMessage Centerの文言
AdminのMessage Centerにきている通知には以下のように記載されています。
>How does this affect me?
You are receiving this message because our reporting indicates your organization is using PowerApps or Flow with Office 365 and one or more of the capabilities listed above.
Your tenant will receive a grace period before the connector reclassification goes into effect, until October 1, 2020, or the expiration of your current Office 365 subscription term, whichever is longer. In addition, apps and flows created prior to October 1, 2019 will receive an extended grace period until October 1, 2024 – during this time these qualifying apps and flows will be exempt from Premium connector licensing requirements.
>Beginning October 1, 2019 your organization will have the limits on Flow trigger frequency and number of runs removed. However, your organization will continue to maintain service limits comparable to current entitlement until October 1, 2020 or the expiration of your current Office 365 subscription term, whichever is longer.

特に重要だと思うのは、
>In addition, apps and flows created prior to October 1, 2019 will receive an extended grace period until October 1, 2024 – during this time these qualifying apps and flows will be exempt from Premium connector licensing requirements.

ここです。
既存(10/1までに作成された)のアプリやFlowであれば、猶予期間が設定されます。それが5年後の2024/10/1です。これはMicrosoftなりの既存ユーザーへの配慮なのだろうと思います。
この期間中は上記にリストされているようなPremiumコネクターを使用していても、標準プランで実行ができます。

残念ながら上記の2024/10/1が書かれている公式なドキュメント（Message Center以外）が見つけられませんでしたが、参考にしつつ、今後の発表をまっていただければと思います。
Juliaで微分


# パッケージPlotsの追加
コマンドラインでjulia起動して以下の通り

```jl
julia> Pkg.add("Plots")
```

驚くほど時間かかります。

# sin関数の微分
```jl
using Plots

# 入力xの範囲を決める
# piは円周率のπのこと
# -3.14から+3.14まで0.01刻み
# つまり-180°～180°
x = -pi:0.01:pi

# 関数f(x)の定義
# 今回はサイン関数
f(x) = sin(x)

# ⊿xを決める
# なるべく0に近い数字がいい
⊿x = 0.0001

# f(x)の微分関数df(x)
df(x) = (f(x+⊿x)-f(x))/⊿x

# グラフを描く
# xは配列なので関数の末尾に.をつける(各要素ごとに演算する)
plot(x,[f.(x), df.(x)])
```

![sin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131730/78bacb40-219b-7f8c-83d2-80bbe2a36b5b.png)

y1がf(x)
y2がdf(x)
sin(x)を微分するとcos(x)になるのでうまくいっていそうです。

# もうすこし複雑な関数をやってみる
```jl
using Plots

# 入力x
x = -pi:0.01:pi

# 関数f(x)
f(x) = sin(x) / (cos(x) + 2)

# ⊿x
⊿x = 0.0001

# f(x)の微分関数df(x)
df(x) = (f(x+⊿x)-f(x))/⊿x

# グラフを描く
plot(x,[f.(x),df.(x)])
```

さっきと違うのはf(x)の定義だけ。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131730/1b6ba256-2eb9-0027-e4d8-4ad44a091fa2.png)

なんだかそれっぽい。

# まとめ
プログラミング言語としての関数じゃなくて
数学的に関数書いていけるのってとても書きやすくていいですね。
Elm meet upに行ってきたよ 〜Elmoに導かれしElmoたち〜

※読書感想文みたいな感想と、Elmの魅力の言語化まとめです

今更ですが、 [Elm meet up](https://elm-jp.connpass.com/event/140431/)に行ってきました。
よく読んでいたElmの記事を書いている方々が登壇されていて、いつも日本人のElmライフを支えてくださりありがとうございます・・・という拝むような気持ちで聞いておりました。

そして私も、チームを代表して、仕事でElm使ってるよ〜っていう話をしてきました。
冷静なってみると、Elm3ヶ月もやってないくらいで強者揃いの中ようElmのこと語れたな？（笑）って感じですが、初心者だからこそElmに対して感じた「感動」みたいな、初々しい感情、あとは「感謝」みたいなものを、伝えることならできるかな、という思いで恐る恐る発表してきました。

[発表資料：チームでElm開発。〜TEAに導かれし者たち〜](https://speakerdeck.com/natsumisawa/timudeelmkai-fa-teanidao-karesizhe-tati)

[当日のつぶやきまとめ：議事録みたいでとても良い、追っていくと参加した気分になれる]
(https://togetter.com/li/1395821)

## meet upどうだったか
人と人が直接コミュニケーションをとることで得られる知識や刺激やモチベーションがある、ということを改めて感じました。
雰囲気が柔らかいのも良かった、つよつよ〜おらおら〜は、ちょっと怖いので。
正直コミュニティ的なのは苦手だったけど（女の子いっぱいいるのは好きだよ！）モチベーションを上げるために、殻を破って積極的に参加していかないとなぁと思いました。

つよつよの方々の「Elm対談」もとても刺激的でした。
言語についてしっかり語り合う場って、なんか初めて見たけど、良かった。
Elmをやってみて、すごいなって思ったポイント、たまに辛いなってなるポイントを代わりに綺麗に言語化してくださった感じがして、スッキリ〜した気持ちになりました。

最近Produce48（IZ*ONEが誕生した韓国のオーディション番組）を見て、「同じ目標を目指す仲間で助け合う姿は素敵だな〜日本人って実力を秘めたがる人多い気がするからな、韓国の女の子達みんないい子すぎるな」と感動したばかりで。
ElmコミュニティはこのProduce48のように、熟練者も初心者でも関係なく、助け合ってもっとよくしていこう〜という感じがする。伝わるかわかんないけど。

![izone-3003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137322/0c9905cb-d4cf-70b6-a415-647bedb9ffe2.jpeg)
かわいい。

## そうそう！Elmって、そうだよね、、！
読書感想文みたいな文はここまでで終わりにします。
発表や対談を聞いて、Elmという言語がなんで魅力的に感じたのかまとめました。

- やっぱりElmは **シンプル** な言語
- だから初心者でも初速は早い → 初心者がいるチームでも大丈夫！
- そして **TEA** があるから、腕力で書く言語
- コンパイラに導かれるままにベタベタ書いていく、 **愚直**〜〜💪💪
- これが性に合う人もいれば、もっと自由にやりたいよ〜とか、めんどくさくてムリ〜となる人もいるかも
    - ちなみにうちのチームでは、ボイラープレートが多い部分はコードを自動生成している
    - そのツール自体もabab...さんがElmで作ったよ
- 自由度低いけど、その代わり実装において **考えることがあまりない**
- それって、 **ユーザーへの価値提供の最大化** に繋がったりするよね
- 製品のイメージがあって、それをTEAに落としていく感じ
- 愚直に書き続けたら、その製品は、出来上がってるよ
- TEAに落ちれば、やることはおなじ👍

だから、いいものを早く作りたかったら、Elmはいいのかもしれないです。

## そして、何をするのか
最後に、meet upでモチベーション上がったなら、何をやるんだい？にお答えします。

#### elm-form-decoderカタカタする
[elm-form-decoder](https://package.elm-lang.org/packages/arowM/elm-form-decoder/latest/)の理解のために、[カタカタ練習する](https://github.com/miyamoen/elm-form-decoder-katakata) ことをしています。登壇されていた方が作ったライブラリであり、また別の登壇されていた方が作った練習問題ですね。ありがたいです。業務でめっちゃ複雑なform作ったのですが、form decoderのコード理解が辛くて、今あれを一人で作れと言われたらムリだし、ちゃんと理解したいのです。改めて勉強するのにちょうど良いです。

#### なんかつくる
再三言った通り作ってなんぼな言語ですね、価値あるものを作らなきゃ意味がないし、Evanさんも悲しんじゃいます。
Elmめっちゃ書けるようになるぞ〜というよりかは、ものを作るぞ〜💪という、種の、気合い、があるので、作りたいものはあるから作ろうと思ってます。
少なくとも [Elm始めてすぐ作ったクソゲー](https://goofy-fermi-86e26a.netlify.com/) は超えていきたい。
TypeScriptで型をDIしてFirestore周りの型チェックをnode/browser向け環境にそれぞれ解決する

\*[こちらの資料](https://qiita.com/sisisin/items/954cf6b3464233e2d010) で解決できなかったと記載したfirebase周りの型解決についての記事になります
こちらの資料を元にした記述があるので、目を通してもらえると理解しやすいかと思います

# なにがやりたいか

[これ](https://qiita.com/sisisin/items/954cf6b3464233e2d010#やりたいこと)

> firebaseのFirestoreへのアクセスする処理をfirebase functionsとフロントで使いまわしたい

# 何が問題か

[これ](https://qiita.com/sisisin/items/954cf6b3464233e2d010#うまく行かなかったこと)

> firestoreの型定義がブラウザ向けとfunctions向けで別物になっていて、ブラウザ向けは lib.dom.d.tsへ依存しているなど、トランスパイル時に両方を満たすうまい方法が見つけられなかった

firebaseのjs向けsdkは、ブラウザ環境で利用するための `firebase`パッケージと、node環境で利用するための `firebase-admin`パッケージがあります。
これらは共に `Firestore`クラスの定義を（何故か）それぞれ持っています
またそれらは、例えばServiceWorkerのような環境に依存する値に依存しています

つまり、いわゆるRepository層を作ってそれをfirebase functionsとフロント双方で使おうとするとTypeScriptのトランスパイル時に型検査エラーとなります

今回はこれを解決しました

# どうやったか

解決したcommit
https://github.com/sisisin-sandbox/monorepo-tsconfig/commit/ec424adc9dfff71f4450c4ce92c30d75f1c3f67f

（このリポジトリ構成については[この辺](https://qiita.com/sisisin/items/954cf6b3464233e2d010#ディレクトリ構成)参考のこと）


---

- それぞれの環境向けのtsconfigを用意
- また、それぞれの環境向けのfirebase.d.tsを用意

```ts:node向けfirebase.d.ts
// 別名にしておかないとfirebase変数を参照したときに `firebase` パッケージのものを参照してしまう
import { firestore as adminFirestore } from 'firebase-admin';

declare module 'firebase' {
  export interface MyFirestore extends adminFirestore.Firestore {}
}
```

```ts:ブラウザ向けfirebase.d.ts
import { firestore } from 'firebase';

declare module 'firebase' {
  export interface MyFirestore extends firestore.Firestore {}
}
```

- Repositoryは上記で作成した `MyFirestore`型を使って型付けする

```ts:HogeRepository.ts
import { MyFirestore } from 'firebase';

export class HogeRepository {
  constructor(private db: MyFirestore) {}
// 以下略
```

- それぞれの環境向けのtsconfigで、 `include`に上記型定義ファイルを含めるようにする


概ね以上になります

# つまりどういうこと？

何が問題だったかと言うと、型がnode/browser環境下でそれぞれ違うということなので、それぞれの環境用にトランスパイル出来るようにしつつ、型をトランスパイル時に差し替えということをやりました
つまりトランスパイル時に型についてDependency Injectionしたことになりますね！

この構成だと、front,sharedという2つのパッケージをブラウザ向けにトランスパイルしたいので `front/tsconfig.json` 及び `shared/tsconfig.browser.json`は `include` にブラウザ向けfirebase.d.tsを含めるようにして解決。
functionsも同様、といった具合です

そもそもfirebaseの型定義がuniversalを意識して書かれていればこんなことにはならないんですが、まあしょうがないということで。
あまり起こる事象ではないでしょうが、複数環境向けのリポジトリで同様の課題にあたったときに同じアプローチで解決出来ると思います

---

次回は資料のもう一つの心残り、 `functionsから shared/lib/esのimportがあったとき（またはその逆）にトランスパイルエラーにならない` をpaths使って解決する編になる気がします（やる気があれば）