OmniAICreator/Qiita-1.07M huggingface dataset:
herokuデプロイについて（初学者向け）

### 初めに

- 今回は`heroku`のデプロイについて自分が学んだことを備忘録として記載いたします。
 
素人が書いたものなので、仮に相違点があった場合、ご容赦いただけると幸いです。

それでは初めていきましょう！！

### herokuをデプロイするのに必要な準備

### 1. 以下のサイトで会員登録をする

```
https://signup.heroku.com/jp
```

### 2. クレジットカードの登録

- クレジットカードを登録しなくてもある程度herokuを使うことができるが、クレジットカードを登録するとアプリの起動可能時間が**５５０**時間から**1000**時間になるので登録することをおすすめ！！

### 登録方法

- ダッシュボード右上の忍者みたいなアイコンをクリック

- `Account Setting`をクリック

- 最初に`profile`を記入し、その後、`billing`をクリックし、`Add Credit Card`をクリック

- 住所、クレジットカードを入力する（住所は英語で記入する）


### 次にターミナルから直接Herokuアプリを作成および管理するために、Herokuコマンドラインインターフェイス（CLI）を使用する

#### その方法

- ターミナルに以下を入力する

```
brew tap heroku/brew && brew install heroku
heroku login
```

- これでメールアドレスとパスワードを入力できたらOKです！！

### 次にアプリの準備をする
- （今回はアプリがある前提で話を進めていきます）

### 自前のアプリをアップする時の注意事項

- トップページを設定していること
`routes.rb`の中に`root to 'コントローラー名/アクション名'`を設定すればOK

- DBは`PostgreSQL`になっているか確認
**`config/database.yml`**を確認し、adapterが`PostgreSQL`になっているか確認

- 公開したいアプリをGitのmasterブランチにコミット済であること
もしコミットしてない場合は、コミットする

- `Github`連携、自動デプロイを行いたい方は、`Github`にリポジトリを作り、プッシュする。

**herokuのデフォルトDBは`PostgreSQL`である。**

### デプロイの準備

- herokuでアプリを公開するには、herokuアプリを作成する必要がある。

- 以下をターミナルに入力する

```
heroku create 自分が作ったアプリ名
```
【注意事項】

- アプリ名は小文字・数字・ダッシュ（-）のみ入力可能。また、世界で誰も使用していない必要がある 

- アプリ名を指定していない場合、自動で決まる

-　ここで使用したアプリ名はURLで使用される

### herokuにデプロイする
(ここでは最も単純な方法を紹介)

- 以下をターミナルに入力

```
git push heroku master
```

- 上記が問題なく終わったら、以下をターミナルに入力する
```
heroku open
```

**ここで`We're sorry, but something went wrong`**というエラーが出たら、
次のコードをターミナルに入力したらどうだろうか。

```
heroku run rails db:migrate
```
(ちなみに自分も上記のようなエラーが出た時、こちらを入力したら、エラーがなくなった)

### （参考）自動デプロイ方法
（参照URL）
https://qiita.com/sho7650/items/ebd87c5dc2c4c7abb8f0#%E8%87%AA%E5%8B%95deploy%E3%81%A3%E3%81%A6

- herokuのダッシュボードの`deploy`をクリック

- `deployment method`のgithubのマークをクリック

- 少しすると、`Connect to GitHub`というのが出てくるので、これをクリック

- そうしたらGitHubの許可画面が出てくるので、`Authorize heroku`をクリック

**これで問題がなければ、検索画面へと移行する**

- `reponame`には自分のアプリのリポジトリ名を入力し、入力完了したら、`Search`ボタンをクリックする

- そうしたら、自分のアプリのリポジトリ名が検索欄の下に出るのでその右にある`Connect`ボタンをクリックする

**`Automatic deploys`と`Manual deproy`が表示されたら成功**

- `Automatic deploys`のところに、`Wait for CI to pass before deploy`という項目があり、そこにチェックマークを付けて、`Enable Automatic Deploys`を押すと、自動デプロイ設定が完了する

### 最後に
今回herokuのデプロイについて簡単な流れを書いたが、ミスがなければ、比較的容易にデプロイできると感じた。
ただし、`git push`することを忘れたりすると、エラーでデプロイできないなどするので、`git push heroku master`を行う際は、ちゃんと`git push`を忘れずにした方がいいと思った。
JSのグラフライブラリを今選ぶならHighchartsで決まり（2015年2月版）


（元記事を更新したのでこちらに退避）
（更新した[2020年9月版はこちら](https://qiita.com/grgrjnjn/items/fa39778657493008c3b6)）
.
.
.

更新記事を書きました。（2017年1月）
→ http://grgrjnjn.blogspot.jp/2017/01/jshighchartsgoogle-charts.html

.
.
.


グラフライブラリは多種多様に存在する。google trendで、highcharts、jqplot、amcharts、chart.jsなど、今選択するなら何がよいのか調べてみた。

#結論
Highchartsを採用。商用利用は有償。

###理由
圧倒的に使われている（っぽい）から。Googleトレンドでの他のライブラリとの比較。

![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F38675%2Fb261510b-7a28-c6ef-ac29-c850173ea15f.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=f71a4f4a1eb7f02d92fb6464b19ef6c7)

###Highcharts公式サイト
http://www.highcharts.com/

参考になるサイト


###商用は有償
Highcharts - Single Website License : 13,501円
Highcharts Single Developer License : 59,070円
http://www.altech-ads.com/Others/Highcharts.htm?gclid=CLOoiPif1MMCFRUGvAodPAEA0g

###デモ
http://www.highcharts.com/demo

![Highcharts_demos.png](https://qiita-image-store.s3.amazonaws.com/0/38675/71769f38-28e0-02be-8474-f8675fc674e6.png "Highcharts_demos.png")



##調査メモ

###highcharts

* ~~動作にはjQueryが必要~~（v3.0.5からはjQueryなしで利用可能）
* ベクターデータでグラフ描画できる。
* とにかく綺麗。
* オプションしだいで細部までいじれるので好き。
* Gemもあるのでとにかく便利です。lazy_high_charts このGemを使う際はController上に直接書くとControllerをかなり汚すのでHelper化してしまいましょう。
* [追記]商用に限り有料
* ptengineというアクセス解析サービスで使っていた。
* 動きが恰好よい。マップもあるしぱねぇ。
* iphone4だとちと重い。
* 商用利用不可でライセンス購入が必要。結構高い。


###jqplot

* jqueryのプラグイン
* 日本語ですごいいっぱいサンプルがあって、非常に助かる。これ凄いな。
http://alphasis.info/jquery-plugins/jqplot/

###amcharts

* MicroSoftやAmazonも使用していライブラリ。
* ここで紹介する中でも一番多機能だと思います。
* デザインもフラットできれいなのでチャート単体でも映えるので、色々なところに使えそうです。

###chart.js

* シンプルで、動きがあって、見ためはcchart.jsより好み。
* ccchartは自分のやりたいことがほぼできたので、機能的に不満はないけど、こっちがどれだけのことが出来るかチェックしてみよう。
* HTML5 canvasベースのJSライブラリ。
* フラットなグラフをかける。



#参考
http://qiita.com/hurutoriya/items/727296839a2ec638fdc4
http://www.fwoabw.info/entry/20130924/1380008062
【jQuery】$(this)について

#$(this)とは？
```sample.js
$('.btn').click(function() {
  $(this).css('color', 'pink');
});
```
イベントが発生した要素そのものをさす。

この場合、```'.btn'```をさします。

#$(this)を使う意味は？

今回の場合ですと、```'.btn'```が複数要素あるときに効果を発揮します。

例えば、
###【$(this)を使用しない場合】
・```'.btn'```：すべての要素を所得してしまう。

###【$(this)を使用する場合】
・```'.btn'```：それぞれの要素を所得する

つまり、クリックした要素それぞれを所得します。

#参考

[jQueryの$(this)の使い方(どこを指してるのか？)](https://www.flatflag.nir87.com/this-1371)
tensorflow==2.0.0でDQNを学習したらmemoryLeakが発生した

# はじめに
最近研究で使うDQNをそこそこ苦労しながら実装し、それの学習を回したところ異常な程Memoryを食っており、原因究明に1週間もかかってしまいました。
自分のような人が現れないように、簡単に記録を残していきたいと思います。

### 環境
python==3.7
Tensorflow==2.0.0
Ubuntu 18.04

## 実際に発生した現象
私が使っていたのは、研究室に設置されたDeepStationと呼ばれる学習用サーバです。
これは、GTX1080ti * 4と RAMが64GBあるので、少々無理やり動作させても変なことは起きたことがありませんでした。
実際に普通にEnd-to-Endの識別モデルの学習を行っている時には発生していませんでした。

しかし、DQNで学習を行っていた際に問題が発生しました。
今回のDQNの実装に参考にしたのは以下の記事になります。

https://qiita.com/sugulu_Ogawa_ISID/items/bc7c70e6658f204f85f9

このソースコードを実行して放置していると、三時間ぐらいで64GBのメモリをオーバーしてmemory-overでクラッシュしてしまいました。
最初は自分のソースコードに問題があると思い、一行ずつソースコードを確認していましたが特に問題が見つからず苦労していました。
もともと、Pythonはmemory-leakが起きにくいというのもあり、あまり意識したことがなかったためです。

このソースコードを見ればわかりますが、episodeが閾値を超えると毎回model.fit()を呼び出して少しずつ学習を行っています。
問題はここにありました。
以下をみてもらえれば、似たような症状が見つかります。

https://github.com/tensorflow/tensorflow/issues/33030

これをみてみると、数回model.fitやmodel.predictをしているのは大きな問題ではなく、コレを非常に多くの回数行うことでmemory-leakが発生したようです。
おそらくですが、model.fitやmodel.predictで呼び出されたmodelがreleaseされずに保持されていたんじゃないかなーと思います。

## 解決方法
基本的には、tensorflowのversionをupdateすればOKです。
私は、tenosorflow==2.3.0をインストールすることで、解決しました。

このせいで、一週間も時間を取られるとは思いませんでした。
memory leakって本当に起きるんだーって感じです。
jupyter-labで実行していると、メモリをエラーですぐに開放してくれるわけではなかったためsshでサーバにもなかなか接続できずかなり焦りました。
大きくメモリを持っていても過信せずに、pythonのメモリ使用に制限しておくと安心ですね。今は私もそうしています。
以下の記事を参考すると良いでしょう。

https://blog.imind.jp/entry/2019/08/10/022501

## 最後に
DQNで学習していても似たような情報があんまり出ていなかったので、よくわからず苦労しました。
これがみなさんの参考に慣れば幸いです。
for文で使える関数

for文で使える関数

Python では繰り返し処理を行うために for 文が使用されます。
回数を指定して繰り返すなどの処理を行いたい場合には range 関数と組み合わせる。

range()関数
0から始まり、1(デフォルト)で増減する一連の数値を返し、指定した数値の前で停止します。
range(開始, 終了, ステップ)

|使い方| 説明|
|:-:|:-:|
| 開始 | 開始位置を指定する整数。デフォルトは0です。  |
| 終了  | 終了後位置を指定する整数。  |
| ステップ  |  インクリメント、デクリメントを指定する整数。デフォルトは1である。 |

開始 開始位置を指定する整数。デフォルトは0です。
終了 終了後位置を指定する整数。
ステップ　インクリメント、デクリメントを指定する整数。デフォルトは1である。

range(開始, 終了, ステップ)

for f in renge(5)
※この場合は、開始＝「デフォルトの０」ステップ＝「デフォルトの１」が適用される。

print (f, end = ‘ ’) 

01234 
「終了」に指定した値は含まれないので４が返される。仮に５まで取得可能したい場合は、６を指定すればいいです。

range(1, 5, 2)
※この場合は１から４まで２づつ増える

range(10, 5, -2)
※この場合は10から6まで２づつ減る

print(list(range(3)))
この形にすると、リスト型で取得することができるらしいです。

ループカウンタ
恥ずかしながら、ループカウンタの意味を知らなかったので調べてきました。
ループを制御する変数で、繰り返し処理の終了条件が処理回数の場合に使用して、処理を1回行うたびに、ループカウンターを1加算し、何回処理が行われたかをカウントして制御する。
上記の意味をループカウンタと言うそうです。

Python、でループカウンタを使用したい場合はenumerate()関数を使用する。	

enumerate()

>l = [‘kokugo’, ‘suugaku’, ‘eigo’]

>for i, subject in enumerate(l):
    print(i, subject)
> 0 kokugo
> 1 suugaku
> 2 eigo

※enumerate()の第2引数を指定しない場合は０からになる

以下のように、第2引数を指定した場合は、指定した数値からループカウンタが返される。
>l = [‘kokugo’, ‘suugaku’, ‘eigo’]

>for i, subject in enumerate(l, 11):
    print(i, subject)
> 11 kokugo
> 12 suugaku
> 13 eigo

zip()
ループカウンタはzip()関数を使用して定義することも可能です

> for i , w in zip(['kokugo', 'suugaku', 'eigo'], [78, 82, 54]):
>    print(subject, number)
> kokugo 78
> suugaku 82
> eigo 54

以下のように、ループ内容を変数で定義することも可能です

> subject = ['kokugo', 'suugaku', 'eigo']
> number = [78, 82, 54]

> for i , w in zip(subject, number):
>    print(subject, number)
> kokugo 78
> suugaku 82
> eigo 54
gethでスマートコントラクトをcallするときに`Error: invalid opcode: SHR`が出てしまうときの対処

## はじめに

gethで、プライベートブロックチェーンにスマートコントラクトをデプロイしたのはいいが、実行しようとしても`.call()`、`.sendTransaction（）`で`Error: invalid opcode: SHR`が無限に出てしまい時間を割かれたので対処法。

## TL;DR

`genesis.json`を以下に変更する

```json
{
"config": {
"chainId": 9731,
"homesteadBlock": 0,
"eip150Block": 0,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"ethash": {}
},
"nonce": "0x0",
"timestamp": "0x5d5cdc87",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760",
"difficulty": "0x80000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"0000000000000000000000000000000000000000": {
  "balance": "0x1"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
```

https://ethereum.stackexchange.com/questions/74068/genesis-json-in-private-geth-network/74103#74103
GASの日付関係でちょっと困ったメモ

# 概要
日付関係の処理でちょっと止まったりしたので備忘録としてメモ。
随時更新すると思う

# getYear と getFullYear
３日後の日付を取得したくて以下のような処理を書いたら、年がうまく取得できなかったという話

```javascript
var today = new Date();
var three_days_after = new Date(today.getYear(),today.getMonth(),today.getDate()+3);
```

ログを見るとこうなってました。0120年？ GMT+0918？
> Sat Sep 19 0120 00:00:00 GMT+0918 (日本標準時)


調べたらこういうことらしい。
> 「getYear()」は2桁の年を取得する関数で「getFullYear()」が4桁の年を取得する関数です。
（参考：http://piyopiyocs.blog115.fc2.com/blog-entry-938.html）


getFullYear()に変更

```javascript
var today = new Date();
var three_days_after = new Date(today.getFullYear(),today.getMonth(),today.getDate()+3);
```
> Sat Sep 19 2020 00:00:00 GMT+0900 (日本標準時)

無事に直りました。GMT+0918のほうは調べてもよく分からんかった


# 時刻表記 HH:mm と hh:mm
HH(H) → 24時間表記（0~24）
hh → 12時間表記（0~12）

という違いがあるらしいですね。

```javascript
event_time = Utilities.formatDate(new Date(),'Asia/Tokyo','HH:mm'); //→13:00
event_time = Utilities.formatDate(new Date(),'Asia/Tokyo','H:mm'); //→13:00
event_time = Utilities.formatDate(new Date(),'Asia/Tokyo','hh:mm'); //→01:00
```

<font color="lightgray">HH/hh → 12時間表記
H → 24時間表記
っていうのも見かけたけど、実際の挙動は↑でした。。</font>
Revelコマンドを実行するがcommand not foundと表示されエラーとなる場合の解決方法

Revelのインストール時に、エラーが出てハマったことを共有します。
同じところでつまずいている初学者の方の参考になればうれしいです。
Qiitaで質問したら、即、回答していただきました。[@woxtu](https://qiita.com/woxtu)さんありがとうございました！

### 質問したこと
- [Revelコマンドを実行するがcommand not foundと表示されエラーとなる](https://qiita.com/athomegeek123/questions/7b4598e0edbc5a71168d#answer-ecbb86a8d358fcb0eb74)

## 解決したいこと
Revelフレームワーク（go get github.com/revel/revel）とコマンドラインツール（go get github.com/revel/cmd/revel）をインストールしたあとに、ターミナルで「revel XXX（newやversionなど）」を実行しても、command not foundと表示される。

### 実行環境
MacBook Pro 10.15.6
Go1.15 darwin/amd64

### 発生している問題・エラー
```terminal
zsh: command not found: revel
```

## エラーの原因はパスが通っていない
パスが通っていないので```$GOPATH/bin```を検索できず、コマンドが実行できないとのこと。
> Goのコマンドラインツールは ```$GOPATH/bin``` （GOPATH を設定していない場合は ~/go/bin）以下に配置されますが、```$GOPATH/bin``` はシステムにおけるコマンドの検索範囲にないためこちらで追加する必要があります。
https://golang.org/cmd/go/#hdr-Compile_and_install_packages_and_dependencies

## エラーの解決方法
`~/.zshrc`を編集（追記、もしくは新規作成）して、`.zshrc`を読み直す。

### エラー解決の手順
ホームディレクトリに移動（すでにホームディレクトリにいる場合は、必要ない）

```terminal
$ cd ~
```

`ls -a`コマンドで`.zshrc`の存在を確認

```terminal
$ ls -a
```

表示されたリストの中に`.zshrc`があれば、以下を実行

```terminal
$ open .zshrc
```

見当たらなければ、以下を実行

```terminal
$ touch .zshrc 
```

（デフォルトの設定なら）自動的にテキストエディタが開くので、以下を追記

```text
export PATH=$PATH:"$GOPATH/bin"

※GOPATHの設定も見当たらなければ、こちらも追記
export GOPATH=$HOME/go（デフォルトの場合）
```

`.zshrc`に追記した結果はこちら（順番入れかえました）

```text
export GOPATH=$HOME/go
export PATH=$PATH:"$GOPATH/bin"
```

編集したあとは、読み直しも忘れずに

```terminal
$ source ~/.zshrc
```

これでrevelコマンドを実行することができました！

もし、最後まで実行しても`command not found`と表示される場合は、ターミナルを終了して、再度起動して実行してみましょう。

## 参考情報
- [【zsh, bash】macでPATHを通す方法 - not found と出てしまったら](https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def)
WindowsでNode.jsを更新する

[Node.jsのバージョン管理ツール「`n`」](https://github.com/tj/n/blob/master/README.md)はWindowsには対応していません

> (Note: n is not supported natively on Windows.)

ので、Chocolateyを使いましょう

```bash
choco upgrade nodejs
```

Chocolatey経由でインストールしていなくても更新できます。
dockerで手元のイメージを誰かに渡す方法

## 前提
自分のローカルで動いているdockerのイメージをプロジェクトメンバーに共有したい、という場面。

## やり方
当然ですがweb上にイメージが落ちているのですから普通にdockerのコマンドでできます。

```
docker save コンテナ名 > my ファイル名.tar
```

これでtarファイルが生成されます。

読み込むときはこっち。

```
docker load < ファイル名.tar
```
FlutterのTextを中央揃えにする

# FlutterのTextを中央揃えにする
わからなくて最初日本語で調べていたのですがただ単に真ん中にTextをCenterを使って配置しているだけの記事が多く正しい日本語の情報にたどり着けなかったので英語で調べて出てきた正しいやり方を記述します。
#やり方
Textの引数にtextAlignというものがあるのでそこでTextAlign.centerを指定するだけです

```.dart
Center(
  child: Text(
    "この文章は\n中央揃えになっているはずです\nこんにちは",
    textAlign: TextAlign.center,
  ),
),
```
![実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135508/e6b8b600-7205-50ea-2131-2bf1198cfab9.png)

これで適切に中央揃えにすることができました。
【ポートフォリオ】ブックマーク管理アプリ【Ruby on Rails】

Railsのポートフォリオを作成したので、紹介のため記事を作成しておこうと思います。

↓動画で紹介した内容はこちら↓
<a href="https://www.youtube.com/watch?v=1xANU66z_IY" target="blank">Youtubeでのアプリ紹介</a>

↓アプリのURLはこちら↓
<a href="https://qiitapost.herokuapp.com/" target="blank">アプリのURL</a>

↓GitHubのURLはこちら↓
<a href="https://github.com/AkioShimono/qiita_post" target="blank">GitHub</a>

【アプリ開発の背景】
プログラミングの勉強をしている時、色々なサイトを見ますよね！特にQiitaは後から読むためにストックに入れることも多いと思います。
その他サイトにも有益なことが書かれているのでブクマをしますね。後から見ようと思ったらゴチャゴチャして不便でした…。（どこに何が入っているかわからない‥）

その悩みを解決するためにQiitaのストック記事と自分の投稿記事（限定共有含む）を同期させ、自分で好きなURLを追記できるアプリを作成しました。
検索機能もつけてるので、「あの記事どこだっけ‥」の状況を解決できると思います！
ホロライブの動画情報・チャンネル情報を収集するサイト「LisVir.holo」の開発メモ

## 概要
[LisVir.holo](https://lisvir.jp/)を作ろうと考えた経緯や開発環境、公開までのざっくりとした流れや公開後の話のメモ。

## なぜ作ろうと思ったのか
1. 時間がそこそこあった
1. 何か作って最近の技術に触れないと腐りそうという危機感
1. 最近VTuberにハマったので関連したものを作りたい

## 作るにあたっての検討
1. 何で作るか
仕事ではあまり触らないSPAに挑戦したい。→Node.js, express, Vue.js
DBはNoSQLに触っときたい。→MongoDB

1. 開発環境
OSは何でもよいがUbuntuを使う(遊びで触ったことがあった)。
ソース管理はGitHub(初めてちゃんと使う)

1. 公開環境
過去にさくらのレンタルサーバーでWebを公開したことがあるので今回も検討したが、折角なので従量課金のクラウド系を試したい。
→Google Cloud Platform

## ざっくり設計
1. バック
YouTube Data APIでチャンネル・スケジュールを取得しMongoDBに保存
フロントからのリクエストでMongoDBのデータを返却

1. フロント
バックへのリクエストでチャンネル・スケジュール情報を取得し画面表示

## 開発中につまったこと
1. YouTube Data APIの利用制限
執筆時点(2020年9月15日)では1日のクォータ数(Quota)が10,000となっている。
検索リクエスト(search)が1リクエストで100なので、1日100回が限界。
直近スケジュールの収集タイミングを1日3回に制限。
(動画のスケジュール動画情報を収集する対象が32チャンネルなので、それだけで9,600)
チャンネル情報取集用のリクエスト(channels)は1クォータなので制限は気にせず実行できる。
動画単体の情報収集用リクエスト(videos)も1クォータ。
クォータ数の制限を増やす申請は行い、現在対応中(後述)

1. フロントの見た目
デザイン能力の欠片もないので、見た目は誰かのテンプレートを頂戴することに。
ライセンス的に問題ないVue.jsのテンプレートの[CoPilot](https://github.com/misterGF/CoPilot)を使用。
そのテンプレート内でJavaScript Standard Styleに触れて、いつもの記法で書いていたらコンパイルがなかなか通らない。
JavaScriptでセミコロンが不要なのを知れて良かった。

## 公開に向けての作業
1. ドメイン
お名前.comで取得。
Whois情報公開代行で住所は隠したけど登録者名は非公開にならないのが、少しだけ嫌だったが仕方がない。
他のドメイン登録サービスではやってる場所もあるみたいだが、これはもうこのままでGo。

1. サーバー、SSL証明書
初のGoogle Cloud Platform。ネットで調べながら作業。
最初、Compute EngineからVMインスタンスを作ったが、
後にSSLが必要(APIの利用規約にはSSLで、とあった)となるので、これは削除。
ネットワークサービスの負荷分散からロードバランサ作成、バックエンドとしてのインスタンスグループを作った。
SSL証明書を新規に取得するほどでもなかったので、GoogleマネージドSSL証明書を使うこととして、そのためにロードバランサでうんたらかんたら。
VM(Ubuntu、東京リージョン)にアプリケーションをインストールして公開。

## 公開後の課題と展望
1. クォータ数が足りない
前述のとおり、動画情報の収集に用いる検索クエリ(search)が1回100コストかかるので、頻繁にスケジュール情報を更新できない。
そのため、YouTube APIのクォータ数の増加申請を行い、現在審査待ち
（申請に関する詳細情報は別途書く）
直近全然足りないので、スケジュール情報の収集回数を減らし、チャンネル量を増やす。
（2020/09/16時点で増やした）

1. 同系の別サイトも作りたい
ホロライブだけでなく、にじさんじ、個人勢、切り抜きチャンネルに関する情報まとめも作りたい。
そのためにはクォータ数の上限を何とか増やしたい。
※APIのプロジェクト単位でクォータ数は管理されている。1つのサイトの複数のプロジェクトのキー・クォータ数を割り当てるのは規約違反なので最悪BANされる可能性あり。少なくともクォータ数上限増加の申請はできない。


詳細な環境構築手順やGoogle Cloud Platformでの作業の詳細は別途書く。
firebase x nextjs で ReferenceError: navigator is not defined

```
> Build error occurred
ReferenceError: navigator is not defined
    at Object.areCookiesEnabled (/vercel/28f5c7d0/node_modules/@firebase/util/dist/index.node.cjs.js:650:5)
```



```
// これを
if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();
}

// こう
if (typeof window !== 'undefined' && !firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
  firebase.analytics();
}
```
AWS初心者がgithubとAWSを使用する際に気を付けたいこと

#記事を書いた動機
誤ってawsのアクセスキーとシークレットキーをgithubに挙げてしまった際、とても肝を冷やしたため。
自分はおそらく運が良かった＆awsの対応が手厚かったために被害自体はなかったのですが、他の事例を見ると**何百万という請求**が発生し得る、とんでもないミスなので多くの人が知って一人でもこういうミスをしないことと、自分のミスの戒めのためです。

#なぜ高額請求が発生するか
①awsのアクセスキーとシークレットキーをgithubに挙げてしまう
②クローラー等で、githubに挙げられているawsのキーが検知されてしまう
③勝手にキーを使われてマイニング等のためにEC2を限度いっぱいまで使われるといった流れです。

#今回助かった原因
僕が何かをした、ということではなくaws側が手厚く対策をしてくれていたからです。
githubにawsのアクセスキーとシークレットキーを挙げると、悪意のある人だけでなくawsも検知をしているみたいで、
事故が発生してから僕の場合は一時間前後でメールが届きました。

#事前にこういった事故を防ぐためにしておきたいこと

##①そもそもawsのアクセスキーとシークレットキーをどこかに書くといったことをしない
その代わりに**IAMRole**を使いましょう。
localで使う時は.envに書いて、終わったら消せばいいです。

##②githubのcommit時にアクセスキーやシークレットキーを検知するようにする
**git-secrets**というものを使います。
詳しい使い方は
[クラウド破産しないように git-secrets を使う](https://qiita.com/pottava/items/4c602c97aacf10c058f1)
[Windowsにgit-secretsをインストール](https://qiita.com/SakuraWine/items/75e9f49f7f3fe5b23937)
を参考にすればよいでしょう。
これで①で.envやほかの場所に書きっぱなしでも検知してくれます。

##③DBのパスワードとかIAMRoleでなんとかならない場合は?
awsのParameterStoreやSecretManagerを使いましょう。


①、②、③で共通することは、公開する場所にはapiKey等の大事な情報は書かないようにしようということです。
当たり前のことかもしれませんが、僕は全くといっていいほど気にも留めずgithubに挙げてしまっていました。
というのも、ローカル環境で実験しているネットの記事を元にそのままアクセスキーとシークレットキーを書いたまま、何も考えずにgithubに挙げるという考えなしの行為が原因でした。

#もしやってしまった場合は
**①rootUserのパスワードを変更する**
**②流出してしまったIAMUSERを削除**
**③全リージョンのEC2、EBS、セキュリティグループに不審な制作物が確認**
をしましょう。
実際対応されていた体験談としてはこちらが参考になります。
[初心者がAWSでミスって不正利用されて$6,000請求、泣きそうになったお話。](https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694)
[AWSが不正利用され300万円の請求が届いてから免除までの一部始終](https://qiita.com/AkiyoshiOkano/items/72002409e3be9215ae7e)
[AWSで不正利用され80000ドルの請求が来た話](https://qiita.com/koyama9876/items/add70cba3cccdb7fa995)

#おわりに
今回の事故の原因はそもそもアクセスキーとシークレットキーを何の疑問も持たずgithubに挙げてしまったことに起因するので、
IAMRoleを使うことを念頭に置いて、予防策としてgit-secretsを使えば自分から流出させてしまうような事故は防げるのではないかなと思います。
少しでも同じようなミスをして悲しいことになってしまう人が減ってくれることを祈ります...
PHPで短絡評価をうまく使って条件分岐をすっきり書く

論理演算をしっかり理解している人にとっては当たり前の内容だと思います。

PHPで複数の条件がある条件分岐を書くとき、、、

```example.php
$con_a;//条件A boolean
$con_b;//条件B boolean
if($con_a){
  if($con_b){
    //処理1
  }else{
    //処理2
  }
}else{
  //処理2
}
```

このように書くと処理2を二度記述することになります。
処理2が短い処理であればこれで良いですが、長くなるとさすがに見づらくなるのでどうにかしたいです。

ここで、PHPのリファレンスを読んでみます。
→https://www.php.net/manual/ja/language.operators.logical.php

```document.php
<?php

// --------------------
// foo() は決してコールされることはありません。これらの演算子は短絡評価を行うからです。

$a = (false && foo());
$b = (true  || foo());
$c = (false and foo());
$d = (true  or  foo());
```

短絡評価とは、
「≪左辺≫ ≪論理演算子≫ ≪右辺≫」というような、論理演算子による式（論理演算子式）があるとする。左辺（第一引数）を評価した段階で式全体の値が定まらない場合のみ右辺（第二引数）を評価する評価法。
らしいです。（wikipediaより）

つまり、条件が2つ以上ある場合、1つ目の条件で式全体の結果が確定する場合は2つ目以降は考慮しない（する必要がない）ということです。
これを踏まえて`example.php`を書き換えると、

```example.php
$con_a;//条件A boolean
$con_b;//条件B boolean
if($con_a && $con_b){
  //処理1
}else{
  //処理2
}
```

と書くことができます。

論理演算についてしっかり分かっていれば当然っちゃ当然ですが、条件が複雑になったりnot（!）がついたりするとややこしくなりますね。
laravel８系でTarget class [XXXController] does not exist. error

公式コピペ注意報発令中です。
どこもおかしくない、でもわからん原因は？
## 原因
web.phpの書き方が８系になって変わった。

参考：https://laravel.com/docs/8.x/releases

## 対処例
これまで

```Laravel:web.php
Route::get('/users', UserController@index);
```

これから

```Laravel:web.php

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
```

以上。
iOSの「ショートカット」アプリ(旧Workflow)で、無限ループさせる方法

✏️この記事について
-
ショートカットアプリを作成している際に、「無限ループ」の方法を見つけたため、そのメモを備忘録がわりに書きます

参考にしたのは[ここ](https://support.apple.com/ja-jp/guide/shortcuts/apdc11deb2c1/ios)と[ここ](https://kazesawayaka.com/gadget/797)のサイト

✨教訓👉「無限ループ」は存在します！
-
iOSのショートカットアプリ、便利で使っていたのですが、唯一**for文による無限ループが見当たらない**ことに不満を持っていました。(「参考」を参考にしてください)

🤔

でも、どうやら、ショートカットアプリで、「無限ループ」を実現する術があるようです。
>####無限ループを作成する####
「ショートカット」にはアクションのグループを永遠に繰り返すアクションは用意されていませんが、「ショートカットを実行」アクションを使用することでこの動作をエミュレートできます。「ショートカットを実行」アクションを使用すると、ショートカット内で別のショーカットを実行できます。「ショートカットを実行」アクションで内包されている同じショートカットを実行するように構成すると、ショートカットは停止するまで最初から最後まで繰り返し実行されます。

[「ショートカット」で「繰り返す」アクションを使用する - Apple サポート](https://support.apple.com/ja-jp/guide/shortcuts/apdc11deb2c1/ios)

ふむ...**「ショートカットの実行」を、ショートカット内に埋め込めばいいんですね**
![1A52E8BD-E2AB-4580-AD77-6EE2BB6FED99.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482878/0bd82e9b-3da1-ab2d-60be-8fd54f48f66e.gif)

できた...😇
ショートカットアプリの幅が広がりそうですね😭

参考
-
👇作ったレシピ
![FE46C51E-4C5D-4E7F-83FD-166E59FACAC0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482878/9035c28a-5930-d393-753e-b6d5793b35f8.jpeg)
👇「繰り返す」アクション
![B2816C80-2213-4768-9B0A-85976F5AAAA6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482878/d0f6d915-7035-d457-26ca-9f022ba27f89.jpeg)
👇➕か、➖ボタンでしか制御できない...
![97DD420D-D271-4F83-B912-C576DF34B2D6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482878/cfbe0954-1707-5f90-4781-6fdd7e0983f0.jpeg)
👇「各項目を繰り返す」アクション
![2C340DED-D88E-4788-9AB9-E5147230643B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482878/018734d1-6992-a992-110a-9268b18d8845.jpeg)
👇改行された文章の行数を数えるなど、基礎的な制御ができる
![1A75F63A-63B0-422F-83AD-964665AD3354.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482878/622bfde5-7770-8eb0-4570-4a14abbfad52.jpeg)

参考サイト様
-
[「ショートカット」で「繰り返す」アクションを使用する - Apple サポート](https://support.apple.com/ja-jp/guide/shortcuts/apdc11deb2c1/ios)

[｢if文｣と｢繰り返し｣を使ってショートカットレシピを作成する。（iOS13 ショートカット）](https://kazesawayaka.com/gadget/797)
Node.jsで16進数文字列を文字列に変換メモ


Arduinoなどのマイコンボードなどのから情報送るときにたまに使うやつです。

## Bufferでシンプルに書く

今のところこれがシンプルな感じです。 Bufferを使うのでNode.js環境のみですが

```js
const string = Buffer.from(hexStr, 'hex').toString('utf-8');
```

これでOK。

実際に書くときはこんな感じです。

```app.js
const hexStr = `48656c6c6f`; //16進数文字列
const string = Buffer.from(hexStr, 'hex').toString('utf-8');

console.log(string);
```

## その他

* もう少し丁寧に

```js
const buf = Buffer.from(hexStr, 'hex'); //16進数文字列 -> Buffer
const string = buf.toString('utf-8'); //Buffer -> 文字列
```

* バイト配列指定

```js
const buf = new Buffer.from([0x48, 0x65, 0x6c, 0x6c, 0x6f]); //48656c6c6f
const string = buf.toString('utf-8');
```

* ブラウザでも使える版

```js
const string = (new TextDecoder).decode(Uint8Array.of(0x48, 0x65, 0x6c, 0x6c, 0x6f)); //48656c6c6f
```

## ちなみに`48656c6c6f`は?

変換するとstringの値は`Hello`になります。

```
$ node app.js
Hello
```
Pandas DataFrame を .csv.gz として Amazon S3 に保存する

Pandas DataFrame を gzip 圧縮しつつ CSV ファイルとして Amazon S3 バケットに保存しようとしたときに少しハマったので備忘録。

``` python
import gzip
from io import BytesIO
import pandas as pd
import boto3

def save_to_s3(df: pd.DataFrame, bucket: str, key: str):
    """Pandas DataFrame を .csv.gz として Amazon S3 に保存する"""
    buf = BytesIO()
    with gzip.open(buf, mode="wt") as f:
        df.to_csv(f)
    s3 = boto3.client("s3")
    s3.put_object(Bucket=bucket, Key=key, Body=buf.getvalue())
```

ポイントとしては以下。

- `gzip.open` の第一引数は gzip フォーマットを表す file-like オブジェクトなので `BytesIO()` を入力する
- `pandas.DataFrame.to_csv` の出力は文字列なので、`gzip.open` の `mode` は「テキスト書き込み (`wt`)」を指定する

最初 `pandas.DataFrame.to_csv` に `compression="gzip"` を指定すれば明示的に圧縮しなくてもいけるかと思って試したが、 `to_csv` に file-like オブジェクトを入力した場合は `compression` オプションは無視されるらしく、使えなかった。
ページ遷移後はJSが読まれず、ロードするとJSが読み込まれるという不具合に直面した件

#状況
Railsを利用しフリマアプリ開発中に体験したエラーです。商品出品機能実装中、価格入力でイベント発火し出品する商品の手数料を自動計算し表示する機能を実装しました。

自動表示されることを確認後、トップページから商品出品ページのリンクに飛び商品出品機能が動作しているか確認していると、価格を入力しても手数料が表示されないという不具合を発見しました。

コードの記述等のチェックをしていると、いつの間にか手数料の自動表示機能が復活しているという現象に見舞われパニックを起こしました。

#解決の糸口
色々やっていて、いつの間にか機能が復活なんてありえないので、コードを1つずつ書き換えたりボタンを1つ押す毎に挙動がどう変化するのか試したところ、どうやら__ページ遷移した直後のページではJavaScriptが読み込まれず、リンク先に飛んだ後にもう1度ページ更新をするとJavaScriptが読み込まれている__ということが発覚しました。

```js
window.addEventListener('load',function(){
この中に手数料表示のコード
});
```
ページ読み込みが全てのJavaScriptのイベント発火に必要なので、ページを飛んだ時にはloadが読み込まれない仕様なのかと考えました。しかし、調べていくと、loadはページ遷移しただけでも読み込まれるイベントであるとのことで、ますますJSが動かないことに混乱することになりました。

#解決
結局JavaScriptのコード自体には何も問題はありませんでした。そこで、そもそもJavaScriptがどのように読み込まれているか確認をすることにしました。railsでJavaScriptを読み込む流れとしては以下のような感じです。

application.html.erbの共通のビューのheadタグの中で読み込んでいます。

```html
<head>
  <title>Furima</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <script type="text/javascript" src="https://js.pay.jp/v1/"></script>
  <%= stylesheet_link_tag 'application', media: 'all'%>
  <%= javascript_pack_tag 'application' %>　←この記述でapplication.jsを読み込んでいます。
</head>
```

app/javascript/packs/application.jsでrailsで使うJavaScriptをまとめて読み込んでいます。

```js
中略
require("@rails/ujs").start()
require("turbolinks").start()　←不具合の原因（下記で説明）
require("@rails/activestorage").start()
require("channels")
require("../fee.js")
require("../card.js")
中略
```

読み込んでいるものを1つずつ調べていくと、ようやく原因が判明しました。
__不具合の原因はturbolinksをapplication.jsで読み込んでいることでした。__turbolinksは大規模な開発等では読み込むJavaScriptが多くなるので、それを効率よく読み込めるようにする為のものみたいです。

しかし、悪い部分もあって__ページ遷移した直後にloadのイベント発火を読み込んでくれない現象を起こす__ことがあるようです。

railsではアプリを作成するとapplication.jsでturbolinksを読み込む記述が自動で記述されてしまいます。turbolinksは大規模サイトでJavaScriptがすぐ読まれるようにする為のもので個人でポートフォリオを作るような場合は不要であるので、こちらをコメントアウトして読まれなくすると、ページ遷移後にJavaScriptが起動しないという不具合を解消することができました。

大規模な開発だとデフォルトで読み込んでいるturbolinks等も別のものに書き換えたりして使うこともあるらしいです。

まだまだ初学者で間違えた知識を書いている可能性もあるので、過ちがあれば教えていただけると嬉しいです。

拙い文章であったかと思いますが、ありがとうございました。
Mac上でWindowsのプログラムを実行(Wine5)


#1 Wineのダウンロード
https://www.winehq.org
Latest Releasesの　Stable:Wine 5.0.2 (shortlog)をダウンロード

#2 tar.xzファイルを解凍

#3 インストール
ターミナルで解凍されたwine-5.0.2のフォルダをルートにする。
以下のソフトウェアをインストール

brew cask install xquartz
brew install bison flex mingw-w64 pkgconfig


ここで bison --version で最新バージョンが反映されたいることを確認。
もし反映されていない場合

/usr/local/Cellar/bisonに新しいバージョンのbisonがあるのでそこにあるバージョン名3.X.Xを確認

export PATH=/usr/local/Cellar/bison/3.X.X/bin:$PATH
でパスを通す。

bison --version
で反映を確認。

./configure --enable-win64
でコンパイル

make 
でインストール

以上
WebAPIの設計(システムアーキテクチャ)ー午後

応用情報技術者平成29年秋期 午後4

ファイル：2017h29a_ap_pm_qs.pdf

参照：
https://www.ap-siken.com/kakomon/29_aki/pm04.html

メモも簡単に記載します。
詳細の分析は、上記リンクをご参照くだいますようよろしくお願いします。


**１、表1中の下線①について，健康機器に送る必要があるユーザ情報を全て答えよ。**

〔WebAPIの設計方針〕では、HTTPリクエストヘッダ内のX-Authorizationヘッダでユーザ名とパスワードを用いる認証を全てのWebAPIで行うと説明されています。健康機器はアプリから受け取った情報を用いて"ユーザ参照"や"計測データ登録"WebAPIを呼ぶので、「ユーザ名」と「パスワード」が必要です。

後は、表１の計測　で、愛称も必要ですね。

ユーザID、パスワード、愛称　ですね。
愛称は忘れしやすいでしょう。

＜＜表１＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/85e77756-8117-d35e-d947-ff60019d5857.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/393f47f4-ddbc-41e4-6987-d9b15df947d1.png)


＜＜WebAPIの設計方針＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/7a060e0c-b88c-0c9d-fe31-3e07b74f7382.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/bcaaac54-7720-4389-6a63-6c5dda0d8848.png)


**２、本文中の下線②の認証方式を採用する際に，セキュリティ上必要となる重要な設計方針を，本文中の字句を用いて35字以内で述べよ。また，その設計方針が必要な理由を20字以内で述べよ。**

WebAPIの設計方針の②について、BASE64自体が平文で送るので、セキュリティ上で、HTTPSで送信するのは大事です。


全てのWebAPIでユーザ認証を行う（私の答え　※問題分を理解していなかった、(//∇//)）
データ漏えいを防止するため
→
WebAPIへのアクセスは，全てHTTPSを用いて行う（参考答え）
HTTPだと盗聴される危険があるから


※BASE64
マルチバイト文字やバイナリデータを印字可能な64種類の英数字のみで表されるテキストデータに変換する方式。MIMEで規定されている
認証情報はBASE64でエンコードされていますが、BASE64は暗号化方式ではないため簡単に平文に戻せます。

　
**３、体重計で利用するWebAPIの仕様について，(1)～(4)に答えよ。**
（１）、表3中のaに入れる適切なAPI名を答えよ。
（２）、表3中のb，cに入れるURIを解答群の中から選び，記号で答えよ。
（３）、表3中のd，eに入れる適切なHTTPメソッドを答えよ。
（４）、表3中のf，gに入れる適切な字句を答えよ。

fについて、"ユーザ参照"APIで、ユーザIDだけが必要ですが、既にURLに含んでいるので、リクエストボディに必要ないです。「－」でいいです。「ユーザ削除」、「計測データ参照」と同じですね。
本当はユーザID、パスワードも必要でしょう。ただ、既に、ユーザ認証は、HTTPリクエストヘッダに含んでいるので、リクエストボディに入れて送るのは必要ないでしょう。

ｇについて、「計測値種別,計測日時，計測値」が送るのは必要ですが、URLに「計測値種別」が含んでいるので、「計測日時，計測値」だけでHTTPリクエストに入れていいですね。

あらら、URLにあるものと、認証用のユーザID、パスワードを書いている方が結構いるでしょう。
それら情報を除外するのは必要ですね。

＜URL＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/82186b50-6fca-b6bd-dfa3-bc486cd27270.png)
XamarinのVisualStudio for Macで実機ビルドができなくなった時の対処の備忘録

##参考
[Xamarinで作成したiOSアプリが実機デバッグ起動できなくなった場合の対処方法](https://qiita.com/gnk263/items/e43796e96249f03fb70b)

[Visual Studio For MacでのiOS実機デバッグについて](http://devblog.whitesol.net/2017/06/visulal-studio-for-macios.html)


##対処

+ クリーンしてビルド
+ Visual Studio for Macの再起動
+ Xcodeの再起動
+ iPhoneの再起動
+ Developer CenterにてDeviceの登録
+ APP idのプロビジョニングプロファイルの作成

今回は「Visual Studio for Macの再起動」で解決。

前回は開発環境に入ってるアプリを削除したら解決したり、Macの環境はわからない。
iPhone7のデバッグの時なんかは同じエラーでiPhone側の空き容量が足りなくて２時間も悩まされた。

日本一やさしいMacの手本とか存在しないかしら。
Android StudioでのFlutter開発でfreezed用のLive Templateを準備する

# Live Template のおすすめ
Dart には data class が無いので、JSONをシリアライズ・デシリアライズしようとすると、ゴリゴリコードが必要になってきます。

そこで、[freezed](https://pub.dev/packages/freezed)を使うんですが、なかなか覚えるようなコードではないので、Live Templateを使いましょうという話です。


# Live Template の設定箇所

環境設定 `Android Studio > Preferences...` の `Editor > Live Templates` で、Flutterを選択して "➕" ボタンをクリックします。

![スクリーンショット 2020-09-16 15.16.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701574/62d3f679-ec5a-ecc7-d4fd-ae012832aba8.png)


# 設定内容

![スクリーンショット 2020-09-16 15.28.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701574/f57f6d1a-b47b-3b3b-4b6b-024314af98fa.png)


| 設定項目 | 設定内容 | 備考 |
|:-----------|:------------|:------------|
| Abbreviation       | freezed        | 補完する際に入力する文字列なので、自分でわかりやすいものを         |
| Description     | Create freezed class      | これも自分でわかりやすいものを       |
| Template text       | テンプレート文字列        | 下記(Template text)参照         |
| Edit variables       | テンプレート変数        | 下記(Variables)参照         |
| Application in         | Dart: top-level          | トップレベルでしか使わないので           |
| Expand with       | Default (Tab)       | 自分の好みの設定で       |
| Reformat according to style    | non check     | 自分の好みの設定で      |
| Shorten FQ names    | check     | 自分の好みの設定で      |


### Template text

```
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part '$FILE_NAME$.freezed.dart';
part '$FILE_NAME$.g.dart';

@freezed
abstract class $CLASS_NAME$ with _$$$CLASS_NAME$ {
  const factory $CLASS_NAME$({
    @required int id,
    @JsonKey(name: 'image_url') @required String imageUrl,
  }) = _$CLASS_NAME$;

 factory $CLASS_NAME$.fromJson(Map<String, dynamic> json) => _$$$CLASS_NAME$FromJson(json);
}
```
<font color="Red">※ 変数 `id`, `imageUrl` の宣言部分は、`@JsonKey(name: 'xxxxx')` の書き方を都度調べるのが面倒なため、複製用として入れているものです。不要な方は削除してください。</font>

### Variables

![スクリーンショット 2020-09-16 15.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/701574/ad96707b-c078-5076-5a5f-9266a1ed43d0.png)


| Name| Expression| Default value | Skip if defined |
|:-----------|:------------|:------------|:------------:|
| FILE_NAME | fileNameWithoutExtension() | fileNameWithExtension() | check | 
| CLASS_NAME | underscoresToCamelCase(String) | capitalize(underscoresToCamelCase(fileNameWithoutExtension())) | check |

これらを設定した、OK、Applyをしてください。

# 注意点
ファイル名から作成するようになっています。例えば `content_category.dart` ファイル内で、*freezed* と入力して補完すると以下のようなコードになります。

```
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'content_category.freezed.dart';
part 'content_category.g.dart';

@freezed
abstract class ContentCategory with _$ContentCategory {
  const factory ContentCategory({
    @required int id,
    @JsonKey(name: 'image_url') @required String imageUrl,
  }) = _ContentCategory;

 factory ContentCategory.fromJson(Map<String, dynamic> json) => _$ContentCategoryFromJson(json);
}
```

あとは、*build_runner* をつかってコードを生成します。詳しくは [freezed](https://pub.dev/packages/freezed) をREADMEを御覧ください。
備忘録(csv.reader とcsv.dictreaderの違い）

**pythonで自動化とかできるんでしょ～？よろしく～、って言われたので頑張る記録　その2**


記録その1（https://qiita.com/wellwell3176/items/8e9a31d1595cdde89498 ）で使った
　「csv.dictreader」が良く分からなかったので調べて、何となく分かったという話。

というか、辞書形式という言葉に問題がある気がする・・・検索性悪い・・・検索性悪くない・・・？

調べた限り、要するに、１行目に書かれた情報を「データとして扱うか」「見出しとして扱うか」の差ということらしい。
図に落とし込まないと何も分からないマンなのでポンチ絵を作ってみたが、下図であっているはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721074/b9fe7274-e561-f140-3b98-fd51b4944320.png)
　　　　　　　　　　　　　　　　　　　　　　＜図１：readerとdictreaderの差＞

CSVデータの１行目にデータではなく見出し（"No."とか、"年齢"とかそういうの）が入っているのであれば、
dictreaderの方が扱いやすそう。「年齢列の1~70行目のデータの平均値を出す」という書き方ができるはずなので。

一方、見出しが入っているCSVに対してreaderを使った場合は、「2列目の2~71行目のデータの平均値」というように、
「何列目に何の情報が格納されているか？」「1行目はデータに含まない」の2点を常に考慮しないと行けないから大変、と。

ざっくりだが、この理解で次に進もう。

とても独立記事を作るような内容ではないが、備忘録だし、一件一テーマで残しておくこととする。
[Swift]3DモデルをSCNSceneに変換する方法2つ

Swiftで3DモデルをSCNSceneに変換するにはModelIOを経由する方法とscnファイルを作成する方法の2つがあります。
片方を実装するともう片方を忘れることが多くてその度に調べることになっているので、備忘録として残しておきます。

前提条件は以下の通りです。

- Swift 5
- Xcode 11.7
- iOS 13.7

#ModelIOを経由する方法
ModelIOのMDLAssetを使い、そこからSCNSceneを読み込みます。
最初にModelIOをimportしておきましょう。注意点としては本体ではなくSceneKitの方にあるものをimportすることです。

```swift:example.swift
import SceneKit.ModelIO
```

変換したい3Dモデルはプロジェクトに追加しておきます。
階層はどこでもいいですが複数の3Dモデルを使うのであればちゃんと1つのディレクトリにまとめておく方がいいでしょう。
今回は"hoge.usdz"という3Dモデルを追加しているものとしています。
あとはBundleから3DモデルのURLを取得して、そのURLをもとにMDLAssetを作成し、作成したMDLAssetからSCNSceneに変換します。

```swift:example.swift
guard let url = Bundle.main.url(forResource: "hoge", withExtension: "usdz") else { return }
let asset = MDLAsset(url: url)
let scene = SCNScene(mdlAsset: asset)
```

URL取得時のforResourceにはファイル名を、withExtensionには拡張子を指定します。
今回はusdz形式ですがobjでもgltfでも大丈夫です。

#scnファイルを作成する方法
コードで実装せず最初からscnファイルを作成しておく方法です。
まずはModelIOを経由する方法と同じように3Dモデルをプロジェクトに追加します。
その後追加した3Dモデルを選択した状態で、Xcode上部のメニューにあるEditorから Convert to SceneKit file format (.scn)を実行します。
![pic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670074/ed74892f-32b2-08ce-0ec8-c232f99740e6.png)
するとプロジェクトに3Dモデルのファイルと同名の.scnファイルが追加されます。
例）hoge.usdz → hoge.scn
このscnファイルをSCNSceneで直接読み込みます。

```swift:example.swift
let scene = SCNScene(named: "hoge.scn")
```

どちらの方法でも難しいところはありませんが、ModelIOをimportしたりMDLAssetを作成する手間を考えると、scnファイルを作成する方法が便利ではないかと思います。
[資格取得]LinuC Level1に合格したので、勉強方法とか取ってどうだったかを書いていく

# [資格取得]LinuC Level1に合格したので、勉強方法とか取ってどうだったかを書いていく

先日、LinuC Level1を受けて、101試験、102試験両方とも無事に合格することができ、晴れてLinuC Level1を取得しました。
※ LinuCはLPICから分裂した資格で、ほとんどLPICと内容は変わらないです

## LinuCとはなにか？

Linux技術者の成長に貢献する資格です。
Level1（101, 102）、Level2（201, 202）、Level3（300, 303, 304）とレベルが別れており、それぞれで難易度が変わっていきます。
Level2以降はそれよりも下のLevelに合格する必要があるので、まずはLevel1から勉強を始めましょう。

[試験公式サイト](https://linuc.org/)
公式サイトに概要がのっております！

## LinuC Level1の内容紹介

Linuxシステムの構築・運用・管理を目的として作られたレベルの試験です。
101試験と102試験の両方に受からないとLevel1認定はされません。
ちなみに、一つの試験で約15,000円程かかるので落ちないように勉強しましょう！

Level1の勉強を行うと下記のようなことが身につきます。

- 実務で必要なLinuxの基本操作とシステム管理が行える。
- Linuxサーバー環境の構築・運用・保守をするための必要な操作とシステム管理ができる。
- Linuxディストリビューションを利用するために必要な知識がある。
- 基礎的なLinux操作について、知らないところ及び覚えないといけないところを確認し、習得できる。

試験時間は90分で問題数は60問、大体6割強取れたら合格ができると思います。
全国にあるテストセンターで受験でき、合否は問題回答後、すぐに結果が出てきます。（正直、最後の送信ボタンを押すときはビビリますｗ）

上記は一部公式サイトから抜粋しております。

## なぜ受けようと思ったのか

- インフラ障害対応時に効率よく調査や原因究明ができるようになりたかった
- 普段意味がわからず打っていたコマンド（特にオプションですが）もしっかりと覚えたかった
- 点でしか覚えていなかったことを線で結んで知識を定着させたかった
- ~~（あと、後輩が受けるということで負けたくなかったから）~~

## 勉強方法

まずは101合格を目指しました。
本を購入して一通りぱらぱら読んでみて、気になったコマンドがあれば実際にPCで打ってみました。
途中、練習問題がありますが、LinuCでは記述問題もあるので実際に打っておかないと忘れてしまう可能性が高いです・・

次に[Ping-t](https://ping-t.com/)を利用して101範囲の問題を全部金色にしました。
金色にする際に、最初の銅→銀は問題に答えてから答えをみて解説、という形ですべて銀色まで持っていき、その後銀→金は答えを見ずにすべて答えて金色にしました。
この時に、おすすめは**20問セット**にして回答したらダレなく、振り返りもすぐにできていいかなと思います。

すべて金色にしたら模擬試験を行います。
模擬試験は全部の問題からランダムで出されて60問セットとなります。
自分の場合、大体正答率80%~100%の間を行ったり来たりしておりました。
模擬試験ですが、Ping-tの場合は記述式が問題の中に入っていないので、当日の試験でいうと正答率がPing-tの正答率から10%~15%ぐらい下がるかなと思います。
したがって、**デッドラインは75%**を切ると当日の合格は怪しいかなと言う感じです・・！(あくまで個人の感想です）

102についても同様の勉強法を行いました。
102は試験問題が体感記述式が多いので、実際にLinux環境をみて勉強したほうが記述式にも対応できるかなと思います。

ちなみに、Ping-tではコマ問（コマンド問題の略かな？）というコンテンツも用意されておりますが、僕はあまり行いませんでした。
それよりも実際にLinuxマシン（僕はMacでしたが）のターミナルで実際にコマンドを打ったりして確認、ファイルの確認とかを行ったほうが身にもなって勉強にもなって一石二鳥かなと思います。

最後に、テキストは下記を購入しました
[最短突破 LinuCレベル1 合格教本 [101試験, 102試験対応] ](https://www.amazon.co.jp/%E6%9C%80%E7%9F%AD%E7%AA%81%E7%A0%B4-LinuC%E3%83%AC%E3%83%99%E3%83%AB1-%E5%90%88%E6%A0%BC%E6%95%99%E6%9C%AC-101%E8%A9%A6%E9%A8%93-102%E8%A9%A6%E9%A8%93%E5%AF%BE%E5%BF%9C/dp/4297106590/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=linuc&qid=1580377639&sr=8-1)


## 合格して役に立ったこと

普段の仕事はエンジニアマネージャーをしているので、バリバリコーディングするわけではないですが、障害対応になると別です。
緊急対応として1分1秒でも早く障害の原因から対応をするために動いていきます。
やはり調査に対してコマンドを知っているかどうかは大きく変わってくるなという印象です。

また、Linuxシステムを理解できているので、パッケージをインストールする際とかにエラーを吐き出されたときの原因調査にも役に立つことができました。

## まとめ

こういった類の資格はテストに受かるためというよりも、自分自身の身になることを主たる目的と捉えてやったほうがいいなと思います。
とはいえ、色々な事情で資格に合格しないと行けなかったり、実力確認として
その時に、本記事を参考に勉強してみると、合格かつ身になる勉強ができるかなと思います。

では、よいLinuxライフを！
Maxで和音を奏でられる（ポリフォニック）シンセサイザーを

#前の記事
[Maxでエンベロープを使ってポーーをポーンやホワーァンに](https://qiita.com/waokitsune/items/a148c65fee51e5171dc4)

#バージョン
Version 8.1.5（9359645）（64-bit windows）

#複数の音を同時に鳴らすには？
前回作ったやつは一度に一つの音しか出せない…。ドの鍵盤を押しながらミの鍵盤を押すと、ドの音が消えてミの音が流れ出す。

Q. 複数の音を鳴らせるシンセサイザーにするにはどうすりゃいいのさ？
A. **音を作る部分を別部品化** そして **MIDI鍵を押すたびに音を作る部品を呼び出す** ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/22a69a41-f64e-72c5-5269-aff328948727.png)
なんかちょっとオブジェクト指向っぽい。
音を作る部分を別部品化 = クラス
MIDI鍵を押すたびに音を作る部品を呼び出す = インスタンス
っぽいイメージ。

参考サイトさん [簡易的なポリフォニック・シンセサイザーを作る](https://numeralcreation.info/%E7%B0%A1%E6%98%93%E7%9A%84%E3%81%AA%E3%83%9D%E3%83%AA%E3%83%95%E3%82%A9%E3%83%8B%E3%83%83%E3%82%AF%E3%83%BB%E3%82%B7%E3%83%B3%E3%82%BB%E3%82%B5%E3%82%A4%E3%82%B6%E3%83%BC%E3%82%92%E4%BD%9C%E3%82%8B/)

#音を作る部分を別部品化するぞ
別部品化 = 別ファイル。
音を出す部品を『synth_cycle』、部品を呼び出す方を『root』にしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/de0994e8-d8f4-9ad0-b662-e950de355bd1.png)
synth_cycleの中をいじっていきます。
まずは **in** オブジェクトで引数を設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/6d2c7b6a-5b37-0775-164b-7e491b25d4c1.png)
buttonオブジェクトはやめて **t** オブジェクトを使ってみるぞい！
（tはtriggerの略、引数のbは『bang信号に変えろ』って意味）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ceca7ad9-36ed-213f-c212-6d49715a9f16.png)
**out~** オブジェクトで戻り値設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/29f7fec9-67da-9219-c468-c96f2b0d2bd7.png)
**thispoly~** オブジェクトでこの部品は音を出して『いるのか』『いないのか』を呼び出し元のpoly~オブジェクトに伝えることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/46b3ce35-d082-940f-7998-45d00783110a.png)
最終的にsynth_cycle君はこんな感じ。
（inとoutには何番目の引数or戻り値なのかを設定する為の引数が必要）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/835e82da-4c17-99be-f0c9-7ad79f26b0e3.png)

#部品を呼び出す側を作る
まずは部品を呼び出す **poly~** オブジェクトを追加！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bb0ee8f8-275a-c935-db2d-d14aeda63693.png)
続いて **prepend** オブジェクトを追加！
こいつの役割がまだぼんやりとしか理解できない…(´・ω・`)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a60af2ab-d613-61ef-64f5-a060c973027a.png)

最終的にはこんな感じ。無事和音が鳴らせるようになり申した(๑•᎑•๑)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/3c63928c-53ca-4826-76ac-4ceac12561a8.png)
試しにprepend無しにしてみたら『単音しか出ない状態』になった。
ということはprependは『poly~をマルチに使えるように信号を蓄えるやつ』というのが役割なのかな？
prependの理解については残課題って感じですなぁ…。

#次の記事
[MaxでMIDI鍵を弾く強さによって音の大きさが変わるポリフォニックシンセサイザーを](https://qiita.com/waokitsune/items/058fc313e8e5b40e9ecb)
RHELの開発者用サブスクリプションを取得する方法

![PostDate-2020.09.16](https://img.shields.io/badge/PostDate-2020.09.16-brightgreen)

RedHat Enterprise Linux (以下、RHEL)は有償のOSですので、サブスクリプション契約を行わないとパッケージ管理を利用できないなどの制約がかかります。ですが、単にインストールを試したり検証環境を構築したいだけであれば無償で開発者用サブスクリプションを入手することができます。

***2021/02/04 追記***
これまで開発用ライセンスは開発用として1台まで利用して良いとされていたものが、2021/2/1以降、本番環境（※本番環境がエンドユーザー先であれば、エンドユーザー側で開発者用サブスクリプションを持つ必要あり）でも16台まで利用して良いとRedHatから[アナウンス](https://www.redhat.com/en/blog/new-year-new-red-hat-enterprise-linux-programs-easier-ways-access-rhel)されました。[CentOS8のEOL問題](https://www.redhat.com/en/blog/centos-stream-building-innovative-future-enterprise-linux)に対する対応の1つと思われます。よっぽど規模の大きい組織/サービスでなければ十分そうですね。
なお、解釈違いがあるかもしれないため正しい情報は[公式FAQ](https://developers.redhat.com/articles/faqs-no-cost-red-hat-enterprise-linux)をご確認下さい。本文を参考にしたことによる如何なる損害も負いません。

## RedHatアカウントの作成
下記URLからRedHatアカウントを作成します。既に持っている人はこの作業は不要です。
画面右上のアイコンから`REGISTER`を選択し、指示に従いアカウントを作成して下さい。
https://access.redhat.com/

<img width="512" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97774/8597f843-bd0a-17e2-b297-931bb599098b.png"/>


## 開発者用サブスクリプションの発行
下記URLにRedHatアカウントでログインします。
https://developers.redhat.com/

<img width="512" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97774/210c9660-426d-e3ac-b9ee-28518daadbe4.png"/>


ログイン後に以下のURLにアクセスし、インストールイメージをダウンロードすると自動でライセンスが発行されます。
https://developers.redhat.com/products/rhel/download

<img width="512" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97774/68887d1a-1980-09d6-f4fa-6b9b05f348f2.png"/>

発行されたライセンスは以下のURLで確認できます。「Red Hat Developer Subscription」という名前の1年間有効なサブスクリプションが発行されていることが分かります。
https://access.redhat.com/management/subscriptions

<img width="512" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97774/31e171b4-4f67-8073-e877-694ef350e5b1.png"/>


以上でサブスクリプション取得が完了です。あとはRHELインストール後にサブスクリプションを紐づけることでフル機能が利用可能になります。
ストロングパラメーターを設定する際のrequireについて

動作環境
Ruby 2.6.5
Rails 6.0.3.2

ストロングパラメーターを設定する際にrequireが必要な場合と必要でない場合の違いについて、理解するのに時間がかかってしまったので投稿してみました。

##requireが必要な場合
```ruby:new.html.erb
<%= form_with model:@hoge, local: true do |f| %>
  <%= f.text_area :fuga %>
<%= f.submit "投稿する" %>
```
```ruby:hoges_controller.rb
def create
  @hoge = Hoge.create(hoge_params)
end

private
def hoge_params
  params.require(:hoge).permit(:fuga)
end
```
上記の場合、ストロングパラメーターにrequire(:hoge)が必要となります。なぜなら、投稿するをクリックした際に送信されるparamsのhogeの中にfugaが含まれているためです。
実際に、binding.pryを使ってcreateアクション内でparamsを確認すると、以下のようになります。fugaには「例」と入力しているとします。

{"authenticity_token"=>"+wXNK4Z3C0wrq4AfslPS5zl/2LSUE6BvV+23hQpkHryrsVzPb0siDIkarIsNYLK2R502fuXlqQ==", "hoge">={"fuga"=>"例"},"commit"=>"投稿する", "controller"=>"hoges", "action"=>"create"} 

##requireが必要でない場合
```ruby:new.html.erb
<%= form_with url:hoge_path, local: true do |f| %>
  <%= f.text_area :fuga %>
<%= f.submit "投稿する" %>
```
```ruby:hoges_controller.rb
def create
  @hoge = Hoge.create(hoge_params)
end

private
def hoge_params
  params.permit(:fuga)
end
```
上記の場合、ストロングパラメーターにrequireが必要ないです。なぜなら、投稿するをクリックした際に送信されるparamsの中にhogeが存在せず、直接fugaが含まれているためです。
実際に、binding.pryを使ってcreateアクション内でparamsを確認すると、以下のようになります。fugaには「例」と入力しているとします。
 

{"authenticity_token"=>"+wXNK4Z3C0wrq4AfslPS5zl/2LSUE6BvV+23hQpkHryrsVzPb0siDIkarIsNYLK2R502fuXlqQ==", "fuga"=>"例","commit"=>"投稿する", "controller"=>"hoges", "action"=>"create"} 

上記の通り、先ほどと違ってhogeが存在しないことがわかります。

##まとめ
つまり、ストロングパラメーターのrequireとは、paramsの中にある入力したもの（今回の場合はfuga）をある要素（今回の場合はhoge）から引っ張り出すために使われていることがわかりました。

雑にまとめると、form_withでmodelを指定している時はrequireが必要。指定していない時はrequireが必要でないと言えると思います。
ReactのFunctional ComponentとClass Componentの特徴

# Functional Componentの特徴

・ES6のアロー関数で記述する
・stateを持たない
(※2019.02.06に関数コンポーネントにステートを持たせられるAPIが出ている↓)
https://ja.reactjs.org/docs/hooks-state.html

・propsを引数に受け取る
・JSXをreturnする
（※主に使用されているのが、Functional Component）


# Class Componentの特徴
・Classを宣言及びReact Componentを継承
・constructorで初期化、propsを引数に受け取る
・renderメソッド内で、JSXをreturnし、引数(props)を受け取るには、thisが必要
・ライフサイクルやStateを持つことができる
（※基本、使用するのはClass Componentではなく、Functional Componentを推奨）

# Stateが肥大化した場合の管理の問題

① stateを多くの場所で使用する→Reduxのstoreで管理
② stateを特定の少数の場所で使用→Class Componentで管理

基本的には上記の軸として考えてみると良いかも。

# Functional Componentのコード例

```react

import React from 'react';

const Hoge = (props) => {
  return (
   <div>
    <h1>{props.title}</h1>
   </div>
  );
};
```

# Class Componentのコード例


```react

import React from 'react';

Class Hoge extends from React.Component{
  constructor(props){
    super(props);
  }
  render(){
    return(
      <div>
       <h1>{this.props.title}</h1>
      </div>
    );
  }
}
```

いずれも、最後に

```
export
```
を記述し、

export 例)↓

```
export default Hoge;
```

さらに、index.js側で

```
import
```

import 例)↓

```
import Hoge from './Hoge';
```


<br>
ここは違う、ここはこうした方が？
等々ございましたら、ご指摘いただけますと幸いです。
【iOS14】UNUserNotificationCenterでSwitch must be exhaustiveのwarning対応

Xcode12（GM）でビルドすると`Switch must be exhaustive`のwarningが👀
実装を確認すると、通知許可ステータスを確認するコードで吐き出されている様子

```swift
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            switch settings.authorizationStatus {
            case .authorized, .provisional:
                print("許可")
            case .denied:
                print("拒否")
            case .notDetermined:
                print("許可求む")
            @unknown default:
                fatalError()
            }
```

`UNAuthorizationStatus`のリファレンスを覗くとiOS14から新たに
`.ephemeral`
が追加されていました。
https://developer.apple.com/documentation/usernotifications/unauthorizationstatus

この子は
`The application is temporarily authorized to post notifications. Only available to app clips.`
つまり、iOS14から実装可能なApp Clipsにおいて、一時的に通知の許可を取ることができ、そのステータスということです。

App Clipsを実装している場合の実装はこちらの公式リファレンスを参考に
https://developer.apple.com/documentation/app_clips/enabling_notifications_in_app_clips

```swift
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { (settings) in {
    if settings.authorizationStatus == .ephemeral {

        // The user didn't disable notifications in the app clip card.
        // Add code for scheduling or receiving notifications here.
        return
    }
}
```
などを追加します。

App Clipsを実装していない場合は、通らない想定なので

```swift
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            switch settings.authorizationStatus {
            case .authorized, .provisional:
                print("許可")
            case .denied:
                print("拒否")
            case .notDetermined:
                print("許可求む")
            case .ephemeral:
                fatalError()// or assertionFailure()
            @unknown default:
                fatalError()
            }
```

でwarning回避できます。
リファレンスにbetaと書かれているし、`fatalError`利用したくない方は念の為
`assertionFailure`で、取得失敗の扱いで良いかと思います🙋‍♂️

ご参考までに🐣🌱
Rails - Jquery でEXCELシート情報取得

下記のソースで取得できるはず！！！
{
①include script
src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js">
src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js">
src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js">



②自分作るScript：
var ExcelToJSON = function() {
    this.parseExcel = function(file) {
      var reader = new FileReader();
      reader.onload = function(e) {
        var data = e.target.result;
        var workbook = XLSX.read(data, {
          type: 'binary'
        });
        console.log(workbook)
        $('#sheet_name').empty()
        $('.txt_sheet').empty()
        var itemHtml = ''
        workbook.Workbook.Sheets.forEach(function(sheet) {
          itemHtml = itemHtml + '<option value='+ sheet.sheetId + '>' + sheet.name + '</option>'
        })
        $('#sheet_name').html(itemHtml)
        $('.txt_sheet').html(itemHtml)
      };
      reader.onerror = function(ex) {
        console.log(ex);
      };
      reader.readAsBinaryString(file);
    };
  };

  function handleFileSelect(evt) {
    var files = evt.target.files;
    var xl2json = new ExcelToJSON();
    xl2json.parseExcel(files[0]);
    $('#template_file').val($(this).val().replace(/^.*\\/, ""));
  }

③ファイルコントロールChangeイベント追加
document.getElementById('upload_file').addEventListener('change', handleFileSelect, false);
}
※upload_file　→file_field_tag
Stripeのカード番号、Sourceに関する仕様、Tips

Stripe-PHP 7.37
###オブジェクト間の関係
Stripeのカード番号等はSourceオブジェクトで管理されており。
SourceオブジェクトはCustomer（ユーザー）オブジェクトに紐づいている

`Customer ->　Source`

ConnectでDirect Charge（Destination chargeではなく）をする場合は、CustomerがConnected Account（加盟店）に紐づくので、下記のような紐付け関係になる。

`Account ->　Customer -> Source`
`加盟店　->　ユーザー　->　カード情報`

つまり同じユーザーでも加盟店が異なる場合、Stripe上では別ユーザー扱いになる
`加盟店A -> ユーザーB ->　カード番号 C`
`加盟店B -> ユーザーB（Stripe上では上のユーザーと区別される） ->　カード番号 C `

Destination chargeで対応させるのであれば、加盟店ではなく、プラットフォーム側にユーザーが紐づくのでユーザーの情報管理に関してはシンプル。
（実装の都合に合わせてDestinationかDirectかを選択するのは本末転倒なのですが、一応）

<details><summary>蛇足</summary>ユーザーに対してカード番号の一覧を見せるような画面では、加盟店ごとにデータを取得することになるので、表示の重複を避けるのであればview等で表示の集約が必要になる</details>

###CustomerとSourceの紐付け
カード番号とソースの紐付けは二通り

`・CustomerオブジェクトのsourceをUpdate`
`・CustomerオブジェクトでcreateSource`

ソースを紐づけると
Customer->sources->dataで内容が確認できる
（紐づける前だとsources->dataは空配列）
また、Customer->default_sourceでデフォルトで使用されるソースのIDが格納されている

sourceをUpdateする場合、今まで登録してたsourceが上書きされるイメージ
createSourceは[公式ドキュメント](https://stripe.com/docs/api/sources/attach)にもあるように、createというよりattach（追加）
createSourceをしてもdefault_sourceは変わらないので注意ので手動でUpdateする必要がある