OmniAICreator/Qiita-1.07M huggingface dataset:
Target Board for RX65N で電子ペーパーにサンプル画像を表示させる

今回の内容
---
Target Board for RX65Nを用いてwaveshareの5.83inch e-Paperにサンプル画像を表示しました。
サンプルコードに手を加えず、そのまま表示させることが出来ました。

![2020-05-06 17-11-53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624954/79be03b6-d651-3c92-ff0e-4b6bf2125066.jpeg)

このe-Paperは秋葉の千石電商さんのセール品で、書き換え速度は遅いものの4000円でこの大きさというのに惹かれました。

参考にさせて頂いた情報
---
waveshare社のWebページに情報がまとまっていましたので、こちらを参考にしました。
https://www.waveshare.com/wiki/5.83inch_e-Paper_HAT#Arduino_UNO

e-Paperの動作確認の流れは下記の通りでした。

1. Raspberry Pi 3で文字表示ができることを確認
2. Arduino UNO R3でサンプルコードを適用するも、5.83インチではファイルサイズがメモリサイズを超えてしまい実行不可
3. RX65NのTarget BoardでGR-ROSE相当のArduino実行環境を立ち上げ、Arduino用のサンプルコードを実行

サンプルコード
---
waveshare社がGithubに登録されているファイル群をIDE for GRでリードします。
https://github.com/waveshare/e-Paper/tree/master/Arduino/epd5in83

コンパイルすると_setup(),_loop()関数の定義が無いというエラーが発生しました。

こちらの対処法は下記の情報により解決しました。
http://blog.livedoor.jp/hardyboy/archives/8360845.html

.inoファイルとディレクトリ名を.cppとは異なる名前に変更しました。(epd5in83.ino->epd5in83test.ino,ディレクトリ名も同)

![e-ink_GR-ROSE_サンプルコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624954/46f2d86a-359c-0d87-0781-528ae730118f.png)

コンパイルが通るのが確認できましたので、Target Boardのリセットスイッチを押してRX65NがD:ドライブとして認識されたのを確認してから書き込みます。

![e-ink_GR-ROSE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624954/1aa40a68-2e3c-5b51-ff9f-176891dc47dc.png)

書き込み後、正常に書き込みが行われて冒頭の写真のような画面表示ができました。
サンプルコードの関数を見ていくとこれならどうにか自分でも書き換えて弄ることが出来そうかなと思いました。

感想
---
やはりArduinoでプロトタイピングできると全然違いますね。周辺回路はまず動作を確認してからコーディングするのが精神衛生上良いです。
Python3にPyOpenGLセットアップ

##PyOpenGLセットアップ
ややてこずりました。
pip install で普通に入ったとみせかけて実は動かないというトラップがありました。

###環境など
作業時期　2020年5月
Win10
Python3.8

## 1. 「pipで取ってきてインストール」では駄目だった
最初 `python.exe -m pip install pyopengl` で入れてみました。
　　・インストールは正常完了した。
　　・サンプルプログラム実行（[PyODE](http://pyode.sourceforge.net/) の「Tutorial 3」です。）
　　　　　　→　glutの参照でエラー。

```:glut参照エラー
PS C:\********> C:\Python380\python.exe .\tutorial3.py
Traceback (most recent call last):
  File ".\tutorial3.py", line 177, in <module>
    glutInit()
  File "C:\Python380\lib\site-packages\OpenGL\GLUT\special.py", line 333, in glutInit
    _base_glutInit( ctypes.byref(count), holder )
  File "C:\Python380\lib\site-packages\OpenGL\platform\baseplatform.py", line 423, in __call__
    raise error.NullFunctionError(
OpenGL.error.NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling
```
freeglutを入れてみたりしたが症状変化なし（freeglutは結局不要だった。）

結局このやり方はあきらめました。（ここまでにいれたものは ```pip uninstall pyopengl``` にて削除。）

## 2. WHL取得しインストールやり直し

参考になったのはこのサイト↓
http://blawat2015.no-ip.com/~mieki256/diary/201506185.html
記載のとおり
　　・https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl
　　　　　　から「PyOpenGL-3.1.5-cp38-cp38-win_amd64.whl」を取得。
　　・WHL を pip コマンドでインストール
　　　
　　        →　サンプルプログラムが正常実行できました。

ちなみにpyopenglと一緒に「PyOpenGL_accelerate」も入れるものらしいです。が、筆者はまだインストールしていません。
名称からするとGPU使うときの描画速度なんかに影響するのかも。
【msys2】msys2を導入するまでに読んだ記事まとめ

## 前書き
windowsローカルマシン上でgitコマンドを利用したくシェル環境が欲しかったのですが、仮想環境を作成してLinuxのせるまでの手間はかけたくなかった。gitbashなどの選択肢もあったが、msys2がカスタマイズも効いて使いやすいと聞いていれてみた際に読んだ記事をまとめます。半分自分が見返す目的です。
※ msys2上でvimをよく使うのでvim関連のリンクもおまけで記載

## msys2

#### 概要 + 関連ツール
[Qiita - MSYS2で快適なターミナル生活](https://qiita.com/Ted-HM/items/4f2feb9fdacb6c72083c)
[Qiita - Windowsで使えるターミナルとシェルのまとめ](https://qiita.com/Ted-HM/items/9a60f6fcf74bbd79a904)

~~~
ターミナル ： mintty
シェル ： bash
パッケージマネージャ ： pacman
端末多重接続ソフト ： tmux
Windowsパッケージ管理ソフト ： Chocolatey
~~~

#### pacman
[Qiita - pacman コマンド](https://qiita.com/MoriokaReimen/items/dbe1448ce6c0f80a6ac1)

#### tmux
[ブログ - tmuxを使い始めたので基本的な機能の使い方とかを整理してみた - 完熟トマト](http://kanjuku-tomato.blogspot.com/2014/02/tmux.html)
[Qiita - MSYS2でtmuxを使う](https://qiita.com/magichan/items/b9374e7219cbeef6e457) .tmux.conf の設定は古いので↓を参照。
[Qiita - tmux v2.1からmouse関連の設定が変わった](https://qiita.com/jyotti/items/70a3a8035d767f99f93d)

#### Chocolatey
※まだいれてないですが、先々いれたいのでメモのみ
Windowsパッケージ管理ソフトChocolateyをインストールすれば体制は万全
→ シェルスクリプトを組めばバックアップやセットアップも自動化できる
→ 設定ファイルをgithubなどに格納してインストール用スクリプトを書けば完璧

#### gcc
[Qiita - MSYS2 による gcc 開発環境の構築](https://qiita.com/spiegel-im-spiegel/items/ba4e8d2418bdfe0c8049)
[ブログ - MSYS2 による gcc 開発環境の構築 ― MSYS2 のインストールから初期化処理まで](http://text.baldanders.info/remark/2016/03/gcc-msys2-1/)

#### 設定ファイル
[Qiita - MSYS2設定ファイルを弄る](https://qiita.com/u1and0/items/b4c3217868cf8bafb085)

~~~
C:\msys64
/home/[username]
  └.bash_profile
  └.bashrc
  └.bash_aliases
  └.bash_functions
  └.inputrc
/etc
  └profile
  └fstab
~~~

説明

~~~
.bash_profile : 起動時に一度だけ読み込まれる。ログイン時に一度設定すればいいものを設定。.bashrcを読み込むように指示。
.bashrc : 起動時に一度だけ読み込まれる。bashを起動するたびに設定する必要のあるものを設定。bash_aliases .bash_function を読み込むように指示。
.bash_aliases : msys2インストール時はないので新規作成。
.bash_functions : msys2インストール時はないので新規作成。
.inputrc : キーボードショートカットを書いておくところ。
profile : 環境変数書くところ。fstab に記載したディレクトリパスのエイリアス
fstab : 環境変数書くところ。ディレクトリパスのエイリアス (win -> bash) を記述。
~~~

#### docker
[Qiita - MSYS2 + Docker for Windows](https://qiita.com/iamapen/items/201bb5e73616d76abb7b) ※ この記事通りに進めても、コマンド実行できるようにならなかった。
[ブログ - MSYS2 で DOCKER ライフ](https://naoblo.net/archives/650)

#### +α設定
[Qiita - MSYS2 +α - 構築手順・備忘録](https://qiita.com/yuukiyouki/items/a84c14240429e453428b)
[ブログ - Macっぽいキー操作でMSYS2のterminalを使うための設定](http://takemikami.com/2017/08/12/MacMSYS2terminal.html)

## vim
[Qiita - 覚えておきたい Vim コマンド 備忘録](https://qiita.com/colorrabbit/items/755cfbb0e97d48280775)
[ブログ - viの基本操作](http://www.gi.ce.t.kyoto-u.ac.jp/user/susaki/command/vi.html)

[Qiita - VimでGUIのコピー&ペーストと連携する](https://qiita.com/sei40kr/items/188c52405fcdb78a26cb)

.vimrc のパスを表示 ( vim起動中コマンドモード時 )

~~~
:echo $VIM
~~~

Vimの設定ファイルが読み込めない場合
[Qiita - Vimの設定ファイルを作る](https://qiita.com/tetsuya/items/75987487ffac42250d3b)
[Qiita - vimrcを編集したら自動で反映する](https://qiita.com/koara-local/items/52d94b8ab72d654bcd92)
AutomationAnywhere v11　TaskBotの優先順位設定と起動方法別の割込み実行の考え方

#  TaskBot実行の優先順位

AutomationAnywhereはトリガー実行できたり、ClientからもControl Roomからもスケジュール実行できたりと起動方法が沢山あるのですがそれらが競合したときにどうなるのか？について書いていきます。
Botの同一デバイスでのスケジューリング時にご参考にしていただければと思います。

####こんなときに使えるよ
#####①業務の終了時間の必要性を考慮して優先度を設定できる
例えば、「TaskBotAはTaskBotBより早い時間に終わっていなければならない」と言った要件があるときに「優先度」の設定を変えることで一方を割込みさせ、早くBot実行を終わらせることができる。
#####②予期しないBotの割込みを避ける
同じデバイスに対して複数のBot起動方法を設定することによる、意図しない割込みが発生することを防ぐことができる。
（予想していないのに、いきなりBot実行の割込みが発生したら悲しいですね）




######【Priority】
・AAE Client上でTask Botごとに設定できる
・Low, Medium, Highがあり、デフォルトはLow

Priorityの設定はAAE ClientのMain画面各Bot選択部分の下に出てきます。
(Clientからのみ設定できます。Control Roomからは設定できません。Control Room上で動かす場合はClientから設定後にControl RoomにBotのアップロードが必要。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/5abb703c-7ccc-a0e3-7ca8-bd0ddd7d7629.png)



######【Bot起動方法】
優先される順位別に書いています。

① トリガー実行　※
② AAE Clientからのスケジュール
③ Hot Keyでの実行
④ CRから即時実行
⑤ CR上でのスケジュール実行
⑥ AAE ClientのMain画面で即時実行
⑦ AAE ClientのWorkbenchから即時実行
⑧ 下記3つのオプションにてBotを実行する
・エクスプローラ上のatmxファイルをクリックしてBot実行
・デスクトップまたはその他の場所に作成されたショートカットを介してBotを実行
・コマンドプロンプトからBotを実行

※トリガー実行について　
フォルダーにファイルが作成されたとき、ウィンドウが閉じたときなどClient上でBot実行のトリガーを設定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/575f7dd4-e421-152e-1221-19188a4e363f.png)


#  Bot実行中に、「割り込み」が発生するケース
割込みなんてそんなのあるの？と私も知ったときに驚きました。

・Bot起動方法にかかわらず、実行中のBotより高PriorityのBotが実行された場合
・同Priority（優先度）において、より優先度の高い起動方法でBotが実行された場合
「割り込み」が発生すると、実行中のBotは一時停止されます。
割り込んだBotの実行が終了すると、また再開します。
割り込みが発生しないケースでは、後から実行したBotがキューに溜まり、先に起動していたBotが終了し次第順次実行されます。


つまり、【Priority】>【Bot起動方法】 の考え方です。


＜参考＞
https://apeople.automationanywhere.com/s/article/Task-Queuing-Technology


###注意
エラーメッセージのポップアップが出ている状態だと割込み実行できないのでご注意くださいませ。
Error HandlingコマンドでBotを囲んであげるとポップアップが出たままになりませんので、こちらも併せてご利用ください。

Error Handlingコマンドとは？と思った方、こちらのコマンドのことです。
他のコマンドを囲んで利用します。
オプションでエラー時のスナップショット取得やログファイルへの書き込みができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/948db521-6776-d9b5-3d5b-53fdfbcf6ece.png)
Cloud Run tutorial (python)

# 準備

+ OSはUbuntu 20.04 (64-bit)
+ GCPにテスト用のプロジェクト作っておく
+ gcloudコマンドが使える状態にする
    + 参考：[Google Cloud SDK のドキュメント](https://cloud.google.com/sdk/docs?hl=ja#deb)
+ チュートリアル用コードをクローンしておく。
    + `git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git`

# ローカルで確認

ディレクトリ移動する。
`cd python-docs-samples/run/system-package`

dockerイメージをビルドする。
`docker build --tag graphviz:python .`

コンテナを起動する。
`docker run --rm -p 9090:8080 -e PORT=8080 graphviz:python`

以下URLにアクセスし、画像が表示されることを確認する。（空白が入ってるがそのままでOK）
`https://localhost:9090/diagram.png?dot=digraph Run { rankdir=LR Code -> Build -> Deploy -> Run }`

# GCP上で確認

```
# プロジェクト
export GOOGLE_CLOUD_PROJECT=<PROJECT_ID>
# GCRにコンテナを上げる
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/graphviz
# Cloud Runにデプロイする
gcloud beta run deploy graphviz --image gcr.io/${GOOGLE_CLOUD_PROJECT}/graphviz
```

デプロイ時にどのGCPプロダクトを利用するか選択可能だが、今回はCloud Run full managedを選択する。
ログに公開されるURLが表示されるのでそれを元に以下のようなURLにアクセスし、ローカルで試したときと同様の画像が表示されることを確認する。

`https://<SERVICE_DOMAIN>/diagram.png?dot=digraph Run { rankdir=LR Code -> Build -> Deploy -> Run }`

またGCPコンソールの[Cloud Run管理画面](https://console.cloud.google.com/run?hl=ja)からデプロイされているエンドポイントを確認できる。

# 後片付け

このままだとデプロイしたアプリが動き続けてお金がかかってしまうので、削除しておく。
Cloud Run管理画面からエンドポイントの削除が可能なので消しておく。
またGCR(Google Container Registory)上にリポジトリがあるのもストレージとして課金が発生してしまう可能性があるので、気になる場合はそっちも消しておく。

# 所感

もっと複雑な環境向けかと勘違いしていたがチュートリアルではDockerfileと単一スクリプトのみの小規模なアプリでも簡単に実行、リリースが出来て便利だと感じた。
Dockerfileで自由に環境設定が可能なのでアプリを置く環境を細かめに修正したい場合や、
GCP以外でも利用する、つまりマルチクラウドを想定している場合はCloud Runで良さそうと思った。
ただGAEに慣れてるならGAE 2ndでも大体済みそうな気もしている。
pythonでCSVファイルを読み込む（ダウンロード＆CSVファイルのパース)

#１　対象データ
東京都庁がCOVID-19の感染者数データを公開しています。
このCSVデータを処理したいと思います。

東京都が公表している感染者数
[https://catalog.data.metro.tokyo.lg.jp/dataset/t000010d0000000068/resource/c2d997db-1450-43fa-8037-ebb11ec28d4c](https://catalog.data.metro.tokyo.lg.jp/dataset/t000010d0000000068/resource/c2d997db-1450-43fa-8037-ebb11ec28d4c)
(CSVファイル)
[https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv](https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv)

#２　とりあえず
公式ドキュメントにCSVファイルの読み込み方が示されています。
[https://docs.python.org/ja/3/library/csv.html](https://docs.python.org/ja/3/library/csv.html)

これを参考にして、１でダウンロードしたCSVファイルを読み込むプログラムを作成します。

```python:python
import csv
with open('130001_tokyo_covid19_patients.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    for row in reader:
        print('■'.join(row))
```

これを実行すると次のエラーメッセージが表示

```
UnicodeDecodeError: 'cp932' codec can't decode byte 0xef in position 0: illegal multibyte sequence

```

たしかcp932てS-JISみたいな意味の言葉だったよな
ということで、CSVファイルの文字コードを調べるとUTF-8でした。

対処方法は、こちらの記事を参考にしました。
[Python UTF-8のCSVファイル読み込み (UnicodeDecodeError対応)](https://qiita.com/HyunwookPark/items/ebc963f82355c837c488)

openにencoding="utf_8"を指定するとよいとのこと。

#３　完成
完成したコードはこれ

```python:python
import csv
with open('130001_tokyo_covid19_patients.csv', encoding="utf_8") as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    for row in reader:
        print('■'.join(row))
```
#４　その他
３の「row」はlistクラスでした。これから、１日ごとの集計をしたいのだけれど、
このままでは面倒そう。 pandan使った方が集計なんかは楽そうなので、pandasで作り直そうかな・・・
機械学習 過学習について

○この記事の要点
過学習を再現したのでメモ
過学習：学習データには対応できるが、未知のデータには対応できない。応用力がない感じ。

#○ソースコード(Python)：モデルの過学習と過学習の確認
```ruby:モデルの過学習と過学習の確認方法
from sklearn.datasets import load_boston
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
%matplotlib inline

# データ準備。ボストンの住宅価格
data = load_boston()
X = data.data[:, [5,]] # 説明変数として、部屋数だけを抽出
y = data.target

# 学習用データとテスト用データに分離
train_X, test_X = X[:400], X[400:]
train_y, test_y = y[:400], y[400:]

# ハイパーパラメータを変更したSVR(サポートベクトルマシン（カーネル法）)での学習
model_s = SVR(C=1.0, kernel='rbf') # 正則化パラメータが1でrbfカーネルを使用
model_s.fit(train_X, train_y)
# 学習データを利用した予測
s_pred = model_s.predict(train_X)
# テストデータを利用した予測（未知のデータに対する予測）
s_pred_t = model_s.predict(test_X)

# グラフ表示
fig, ax = plt.subplots()
ax.scatter(train_X, train_y, color='red', marker='s', label='data')
ax.plot(train_X, s_pred, color='blue', label='svr_rbf curve(train)')
ax.plot(test_X, s_pred_t, color='orange', label='svr_rbf curve(test)')
ax.legend()
plt.show()

print("○訓練データの平均二乗誤差と決定係数")
print(mean_squared_error(train_y, s_pred))
print(r2_score(train_y, s_pred))
print("○テストデータの平均二乗誤差と決定係数")
print(mean_squared_error(test_y, s_pred_t))
print(r2_score(test_y, s_pred_t))
```
結果
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628917/9e5b8a46-ec1c-a94c-1eba-7de3ba53bdd5.png)
○訓練データの平均二乗誤差と決定係数
30.330756428515905
0.6380880725968641
○テストデータの平均二乗誤差と決定係数
69.32813164021485
-1.4534559402985217

学習データの線（青）は割といい感じに線引きしているが、テストデータの線（オレンジ）は微妙。
平均二乗誤差と決定係数の値を見ても明らか。
これが過学習。

過学習を防ぐ方法には以下のようにいろいろあるが、それらの説明はまた今度。
・学習（訓練）データの数を増やす
・交差検証を行う
・ハイパーパラメーターを調整する（モデルを簡単なものにする）
・特徴量を削減する
・正則化を実施する
FirebaseのGoogleログインではまった

# はじめに
こんなことをやろうとしていた。
[JavaScript で Google ログインを使用して認証する](https://firebase.google.com/docs/auth/web/google-signin?hl=ja)

こんな風に書かれていた。

```.js
# こうして
var provider = new firebase.auth.GoogleAuthProvider();

# こう
firebase.auth().signInWithRedirect(provider);
```

だから、こんな風にした。

```.js
firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
```

動かない。以下のエラーたちが出た。

```
# これとか
Error: Cannot find the firebase namespace; be sure to include firebase-app.js before this library.

# これとか
Error in v-on handler: "TypeError: firebase.auth is not a function"

# これ
TypeError: firebase.auth is not a function
```

# 答え

こいつが不完全だった。
[Firebase を JavaScript プロジェクトに追加する](https://firebase.google.com/docs/web/setup?hl=ja#cdn-から)

```.html
<body>
  <!-- Insert these scripts at the bottom of the HTML, but before you use any Firebase services -->

  <!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
  <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js"></script>

  <!-- Add Firebase products that you want to use -->
  <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-firestore.js"></script>
</body>
```

以上。
[競技プログラミング] Python チートシート

#前書き
普段はC++で問題を解いているが，オーバーフローや気分転換時にPythonを使いたい場面があった為，
[[競技プログラミング] C++ チートシート](https://qiita.com/akidon0000/items/019c1a6bcb494f0252ea)
のPythonバージョンとして記録

#前知識
[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)

#基本知識
1 秒間で処理できる for 文ループの回数は、

```math
10^8=100,000,000 回程度
```
[計算量オーダーの求め方を総整理！ 〜 どこから log が出て来るか 〜](https://qiita.com/drken/items/872ebc3a2b5caaa4a0d0)

#テンプレート

```program.py
import itertools
import collections
import math
 
def main():

 
if __name__ == "__main__":
    main()
```

#基本
##復習

```program.py
x = 10

#割り算
print(x/3)

# 除算
print(x //3)

# 余り
print(x % 3)

#べき乗
print(3 ** 2)


```

##数値操作

```program.py

```


##文字列操作

```program.py

print("hello"+"world")
print("hello" * 3)

# result

helloworld
hellohellohello
```



##配列


```program.py

```


##セット
重複と順番を自動に整理してくれる（重複なし）

```program.py

```

##関数

```program.py

```




#入出力
##入力

```program.py
"""
入力値 >>> ABC
"""
str = input() # >>> str = "ABC"
strs = list(input()) # >>> strs = ["A","B","C"]

"""
入力値 >>> 1
"""
int = int(input()) # >>> int = 1

"""
入力値 >>> 1 2
"""
x,y = map(int,input().split()) # >>> x = 1, y = 2

"""
入力値 >>> 1 2 3 4 5 ... n
"""
lists = input().split() # >>> lists = ['1','2','3',...,'n']
lists = list(map(int,input().split())) # >>> lists = [1,2,3,4,5,...,n]

"""
入力値　>>> FTFTTFTTTFTTTTF 
"""
lists = input().split('T') 
# >>> list = ['F', 'F', '', 'F', '', '', 'F', '', '', '', 'F']

"""
入力値　>>> 3
           hoge
           foo
           bar
"""
num = int(input())
lists = [input() for i in range(n)]
# >>> num = 3
# >>> lists = ['hoge','foo','bar']

"""
入力値　>>> 1 2 2 3 1
           4 5 3 4 1 2 3 4
           2 3 5 6 0 2
"""
while True:
    try:
        lists = list(map(int,input().split())) 
        # ループ
        # 1周目　list = [1,2,2,3,1]
        # 2周目　list = [4,5,3,4,1,2,3,4]
        # 3周目　list = [2,3,5,6,0,2]
        # 4周目　エラー(out of range) よってexceptに行く。
    except:
        break;

# OR

lists = []
while True:
    try:
        lists.append(list(map(int,input().split())))
    except:
        break;
#lists = [[1, 2, 2, 3, 1], [4, 5, 3, 4, 1, 2, 3, 4], [2, 3, 5, 6, 0, 2]]


"""
入力値 >>> A B
"""

"""
入力値 >>> d1 d2 ... dN
&
入力値 >>> d1 
          d2 
          ...
          dN
"""


"""
入力値　>>> 3 4
           99 99 99
           99 0 99
           99 99 99
           99 99 99
"""


"""
入力値 >>> 10 12
          W........WW.
          .WWW.....WWW
          ....WW...WW.
          .........WW.
          .........W..
          ..W......W..
          .W.W.....WW.
          W.W.W.....W.
          .W.W......W.
          ..W.......W.
"""


"""
入力値 >>> d1 d2 .. d? （入力数が不明）
"""


```

##出力

```program.py
"""
桁数指定
"""


"""
セット全出力
"""
```
EC2のスケジュールイベント通知にタグ情報を含める

## 2020/5/4 にドキュメントに追加されていた

**Customizing scheduled event notifications**
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html#customizing_scheduled_event_notifications

※2020/5/6 時点では英語で表示する必要があります。

## マネジメントコンソールの場合
EC2 コンソール → イベント → アクション → イベント通知を管理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/413f22ee-449b-6a89-c32a-dbb3917a9657.png)

イベント通知にタグを含める を ON にして すべてのタグを含める を選択するか
含めるタグを指定して保存します。

Nameタグを含める例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/58180de7-bb21-27b3-b433-841b605d6159.png)
古い UI の方では設定できないので、ご注意ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/337fb737-0a84-c512-cdab-ea32ccb848a7.png)


## AWS CLI/SDK の場合
[RegisterInstanceEventNotificationAttributes API](https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/RegisterInstanceEventNotificationAttributes) で登録します。
CLI/SDK は最新のバージョンに更新してください。

以下は AWS CLI の例です。

### すべてのタグを含める場合
```shell-session
$ aws ec2 register-instance-event-notification-attributes \
--instance-tag-attribute IncludeAllTagsOfInstance=true
```

### 特定のタグを含める場合
```shell-session
$ aws ec2 register-instance-event-notification-attributes \
--instance-tag-attribute InstanceTagKeys=Name
```

一度すべてのタグを含めるを有効にしている(`IncludeAllTagsOfInstance=true`) 場合は
タグを指定して登録しようとするとエラーになりました。

```shell-session
$ aws ec2 register-instance-event-notification-attributes \
--instance-tag-attribute InstanceTagKeys=Name

An error occurred (CannotRegisterInstanceTagWhenIncludeAllInstanceTagIsTrue)
when calling the RegisterInstanceEventNotificationAttributes operation: None
```

一度 false に設定する必要があるようですが、実行したところ InvalidRequest で
エラーになってしまいました。不具合かもしれません (v2.0.11 で確認)。

```shell-session
$ aws ec2 register-instance-event-notification-attributes \
--instance-tag-attribute IncludeAllTagsOfInstance=false

An error occurred (InvalidRequest) when calling the RegisterInstanceEventNotificationAttributes
operation: InstanceTagKeys is empty and IncludeAllTagsOfInstance is false
```

`IncludeAllTagsOfInstance` と `InstanceTagKeys` を同時に指定してみてもダメでした。

```shell-session
$ aws ec2 register-instance-event-notification-attributes \
--instance-tag-attribute IncludeAllTagsOfInstance=false,InstanceTagKeys=Name

An error occurred (CannotRegisterInstanceTagWhenIncludeAllInstanceTagIsTrue)
when calling the RegisterInstanceEventNotificationAttributes operation: None
```

これに関しては詳細が判明したら追記します。
簡単ですが、以上です。
No route matches {:action=>"show", :controller=>"books"}, missing required keys: [:id]

本当初歩的なエラーで、少し考えたらすぐわかるようなところで、悔しい気持ちをもちつつ、
記録します。

表題エラー表記通り、redirect先で必要なidがなかったのが原因でした。

前：
def create 
    book = Book.new(book_params)
    book.save
    redirect_to user_path
end

修正後：
def create 
    book = Book.new(book_params)
    book.save
    redirect_to user_path(id: current_user)＃修正箇所
end
VirtualBoxにCentOS8を導入

<h2>ハマった点

<h6>最初の段階で仮想メモリを512MBで進めようとしましたが、インストールを始めてすぐに大量のエラーが吐かれてemergency modeに入りました。

仮想メモリを2 GBに引き上げたところ、問題なくインストールが進みました。

<h2>動機

開発環境のベース作りです。どうせ導入するなら最新版を導入しようと考え、CentOS8にしました。

<h2>環境

CPU Core i7-8700K
Memory 32 GB
Host Windows 10 Enterprize
using VirtualBox 6.1.6 r137129
Guest CentOS8-8.1.1911

<h2>ISOのダウンロード

下記が参考になりました。
https://hackers-high.com/linux/centos8-installation/
CentOS7までに存在していたMinimal ISOはなくなったのですね。7GBくらいのISOイメージをダウンロードします。

<h2>VirtualBoxに仮想マシンを作る

<h7>設定
 - LinuxのOther Linux(64-bit)
 - メモリサイズは2 GB
 - 仮想ハードディスクをVDIで作成
VDI、VHD、VMDKとありますが、下記によれば性能差はないようです。
https://www.lanches.co.jp/blog/2218
互換性の考慮も一瞬考えましたが、VirtualBoxとお付き合いすることにします。VDIで。
 - ストレージは16 GBで固定
残り時間が何度も表示されては更新されますが、これは全くアテになりませんでした。作成には数分を要しました。

<h2>仮想マシンにCentOS8をインストール

<h7>
1. ISOイメージをマウントして起動
2. Test & Install
3. 「CentOS8へようこそ」の画面が表示される（が、ワイド画面には切り替わらず不自由）
4. 言語を日本語に
5. インストール先を仮想ディスクにして
6. インストール

<h2>おしまい

何もしなくても、GNOMEデスクトップ環境が入るようです。

<h2>参考

https://qiita.com/yasushi-jp/items/01b4829a36272954719f
https://qiita.com/sigenyan/items/f47e460e154d604b2a33
https://mebee.info/2019/10/13/post-2095/
下記記事を見て仮想メモリを2 GB、仮想ハードディスクを16 GBに増強しました。
https://aw1.jp/web/virtualbox-centos8/
【Rails】登録内容確認画面を作成していた際のエラーhidden_fieldの使い方

こちらの記事を参考にしつつ、登録内容確認機能の実装をしていました。

http://rakio1234.hatenablog.com/entry/2017/01/09/234744

##エラー内容

contacts/confirmに飛ぶと以下の画面になりました。
We're sorry, but something went wrong.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/03cbda42-c1bf-d714-891b-b2386fff7652.png)


エラーコードは以下の通り。


```views/contacts/confirm.html.erb
<h1>こちらの内容でよろしいですか？</h1>
<p> email: <%= @contact.email %></p>
<p> message: <%= @contact.message %></p>

<%= form_for :contact, url: new_contacts_path do |f| %>
  <div class="form-group">
    <%= f.hidden_field :email %>
  </div>
 <div class="form-group">
   <%= f.hidden_field :message %>
 </div>
  <%= f.submit '入力画面に戻る' %>
<% end %>
<%= form_for :contact, url: contacts_path do |f| %>
  <div class="form-group">
    <%= f.hidden_field :email, 'メールアドレス' %> %>
  </div>
 <div class="form-group">
   <%= f.hidden_field :message, 'お問い合わせ内容' %>
 </div>
  <%= f.submit '送信する' %>
<% end %>
```

画像の通りエラー内容が表示されないので一つずつコードを消して試してみました。

まず、下記の部分を消します。

```
<p> email: <%= @contact.email %></p>
<p> message: <%= @contact.message %></p>
```

するとエラーが表示されず成功します。
![スクリーンショット 2020-05-06 16.39.0939.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568461/e19d62c1-f138-7767-71f9-19cb5c6aef55.png)


元に戻して、次に下記の部分を消します。

```
<%= form_for :contact, url: new_contacts_path do |f| %>

  <div class="form-group">
    <%= f.hidden_field :email %>
  </div>

 <div class="form-group">
   <%= f.hidden_field :message %>
 </div>
  <%= f.submit '入力画面に戻る' %>
<% end %>
```

するとエラーWe're sorry, but something went wrong.が表示されました。


元に戻して、次に下記の部分を消します。

```
<%= form_for :contact, url: contacts_path do |f| %>
  <div class="form-group">
    <%= f.hidden_field :email, 'メールアドレス' %> %>
  </div>
 <div class="form-group">
   <%= f.hidden_field :message, 'お問い合わせ内容' %>
 </div>
  <%= f.submit '送信する' %>
<% end %>

```

エラーWe're sorry, but something went wrong.が表示されませんでした。

結果これが怪しいということになりました。

```
<%= form_for :contact, url: contacts_path do |f| %>
  <div class="form-group">
    <%= f.hidden_field :email, 'メールアドレス' %> %>
  </div>
 <div class="form-group">
   <%= f.hidden_field :message, 'お問い合わせ内容' %>
 </div>
  <%= f.submit '送信する' %>
<% end %>
```

##原因

f.hidden_fieldに第2引数として要素を指定することはできないから。
したがって下記のようにしたところ動きました。


```
<%= form_for :contact, url: contacts_path do |f| %>
  <div class="form-group">
    <%= f.hidden_field :email %>
  </div>
 <div class="form-group">
   <%= f.hidden_field :message %>
 </div>
  <%= f.submit '送信する' %>
<% end %>
```
[C言語アルゴリズム]エンディアンネス

#C言語でエンディアン確認アルゴリズムを実装した
##学習にあたって使用した環境
* ideone.com (https://ideone.com/)
※オンライン上でプログラミング学習ができるサイト

##参考資料
C言語による最新アルゴリズム辞典 (奥村晴彦著/1991年初版 技術評論社：16ページ)

##エンディアンの概要
上位バイトと下位バイトの順序を俗にエンディアンという。
メモリの若番地が下位バイトなのがリトルエンディアン、その逆がビッグエンディアン。

![endian.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580452/75fa0576-8056-a312-dc1d-9c2bd53a4daf.png)
引用元：http://www.ertl.jp/~takayuki/readings/info/no05.html

##ソースコード
```C:endian.c
/* endianness エンディアンネス */
/* int型のエンディアンネスを調べる */

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int i = 1;
    
    if(*((char *)&i))
    {
        printf("little-endian\n");
    }
    // iをchar*にキャストして、int-1サイズ分ポインタの参照先をズラした値が≠0の場合真
    else if(*((char *)&i + (sizeof(int) - 1)))
    {
        printf("big-endian\n");
    }
    else
    {
        printf("不明\n");
    }

    return EXIT_SUCCESS;
}

```
##実行結果
リトルエンディアンであると結果が出た。

```C:result.txt(任意)
Success #stdin #stdout 0s 4380KB

little-endian
```
PythonサーバからAndroidにpush通知する

# 記事の趣旨

[前の記事](https://qiita.com/nk5jp/items/7b7c1e70bde457041bd3)でとりあえずpush通知のひな形は作れたと思うので，今度はその通知をFirebaseコンソールではなく，自分のサーバを起点として発出してみようという記事．

サーバはAWS上に立てたCentOS7を使用する．使用言語は何でも良いと思うがとりあえずPython3.7を選択．Pythonおよびpipは既にインストールされている前提とする．

## 1. 通知メッセージの送信手順

通知だけでなく，そこで送った情報をトリガとしてクライアント側に色々やらせたいところだが，まずはその辺りは抜きにして，シンプルに通知だけを送ることを目指す．

### 1.1 Firebase Admin SDKの追加

Firebase Admin SDKとは，サーバとFirebaseとの対話を仲介してくれるツールという理解で良いと思う．今回は使用言語としてPythonを選択しているので，Firebase Admin Python SDKをインストールすることになる．これを[こちら](https://firebase.google.com/docs/admin/setup?hl=ja)の手順に則って実行する．pipが入っているのなら，以下の1コマンドを実行するだけで良い．今回はバージョン4.2.0がインストールされた．

```bash
pip install firebase-admin
```

### 1.2 送信リクエストの承認

リファレンスは[こちら](https://firebase.google.com/docs/cloud-messaging/send-message?hl=ja#python)だが，注釈として「送信リクエストの承認が必要」である旨が記載されているので，先に[こちら](https://firebase.google.com/docs/cloud-messaging/auth-server?hl=ja)の手順を確認する．

いくつかのパターンが記載されているが，今回はAWSに立てたサーバからリクエストを発出するので，`Firebase プロジェクトからサービス アカウントの JSON ファイルをダウンロードする`に該当する．手順的には上記ページの[認証情報を手動で提供する](https://firebase.google.com/docs/cloud-messaging/auth-server#provide_credentials_manually)が該当する．

特に詰まるところは無いと思う，ファイルをダウンロードして環境変数をセットするだけ．今回はAdmin SDKを用いるので，「認証情報を使用してアクセス トークンを作成する」以降の手順は実施しなくて良い．

### 1.3 お試し送信

改めて[こちら](https://firebase.google.com/docs/cloud-messaging/send-message?hl=ja#python)に戻る．送信用のサンプルを流用してお試し送信を実施．コードは以下のとおり．

```python
import firebase_admin
from firebase_admin import messaging

default_app = firebase_admin.initialize_app()

# This registration token comes from the client FCM SDKs.
registration_token = 'デバイストークン'

myNotification = messaging.Notification(title='Test', body='Hello, FCM from My Phthon Server!')

# See documentation on defining a message payload.
message = messaging.Message(
    data={
        'score': '850',
        'time': '2:45',
    },
    token=registration_token,
    notification=myNotification
)

# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
```

基本的にサンプルスクリプトそのままだが，主に以下を変更している．

- 「SDKを初期化せよ」というエラーメッセージ対応のために[こちら](https://firebase.google.com/docs/admin/setup?hl=ja#python_1)の初期化処理をコピペ．
- デバイストークンを何かしらの形でサーバ側に渡す必要があるので，今回は愚直に以下で対応．
  - クライアント側にeditTextビューを用意しておき，そこにトークンを貼付しておく
  - それをコピペしてテキストファイルを作成
  - テキストファイルをサーバ側へ持ってきて，コード上の`'デバイストークン'`の部分に直書き
- サンプルのままだと何も表示されず寂しいので，notificationを追加．
  - 「インスタンスとして渡せ」と怒られるので，`myNotification`にインスタンスを代入して渡す形とした．
- `data`は今回全く使用していないが，害はない認識なのでとりあえず放置．

なお，`firebase_admin.messaging`の仕様は[こちら](https://firebase.google.com/docs/reference/admin/python/firebase_admin.messaging)にまとめられているので適宜参照すること．

このpythonスクリプトを実行したところ，ちょっと間を置いて，無事図1のようなpush通知がAndroid端末に届いた．

![notification2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494245/3fc20dd7-883c-d9ab-f346-bd63999427f8.png)
図1：サーバから発出されたPush通知

とりあえずこれで自作サーバ側からキックする処理は実装できたことになる．
React Native Debuggerで"DevTools v4 is incompatible with this version of React"のエラーが出る時の対処法

# はじめに
React Nativeで開発をしている時、今まではブラウザでデバッグしていましたが
React Native Debuggerというものがあることを知り、使ってみたらなかなか良かったのですが
導入時に(私のような)初心者だとひっかかるエラーがあったので対処法を残しておきます。

# 環境
Expo 37で開発

~~~jsx:package.json
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
~~~

React Native Debuggerのインストールコマンドは以下を実行

~~~
$ brew update && brew cask install react-native-debugger
~~~

# エラー内容
Readt Native Debuggerの左下のところに以下のエラーが発生

~~~
DevTools v4 is incompatible with this version of React
Either upgrade React or install React DevTools v3:

npm install -d react-devtools@^3
~~~
どうやら、DevTool v4とReactのバージョンが合っていないのでDevToolsのv3をインストールせよ、とのこと。

# 間違った対処法
エラーでググって出てきたそれらしい対処法を試してみる

~~~
npm uninstall -g react-devtools
npm install -g react-devtools@^3
~~~
やっていることは、今のdevtoolをアンインストールして、devtoolのv3をインストールしているので一見間違っていないように見えるが、ここでReact Native Debuggerを起動してもエラーは解消されない。

# 原因
まずは[React Native Debuggerの公式](https://github.com/jhen0409/react-native-debugger#notice-react-native-compatibility)をみると、
> To use this app you need to ensure you are using the correct version of React Native Debugger and react-native:
>
> | React Native Debugger | react-native |
> | --------------------- | ------------ |
> | >= 0.11               | >= 0.62      |
> | <= 0.10               | <= 0.61      |

react-nativeのバージョンが0.62以上の時は、React Native Debuggerは0.11以上を使い、
react-nativeのバージョンが0.61以下の時は、React Native Debuggerは0.10以下を使うとのこと。

ExpoのSDKの中にReact Nativeが入っているので、[Expo 37の記事](https://blog.expo.io/expo-sdk-37-is-now-available-dd5770f066a6)でバージョンを確認すると
> Today, we’re announcing our first release of the decade! 💐🌸 Expo SDK v37.0.0 🌸🌷 (which uses React Native 0.61 internally) is our Spring release, but also inaugurates a new, bolder approach to empowering developers.

Expo 37はReact Native 0.61を使っているので、Debuggerは0.10を使わないといけないはずです。
<br>
ここで思い出してほしい、Debuggerをインストールするこのコマンド

~~~
$ brew update && brew cask install react-native-debugger
~~~
これでは最新版のreact native debuggerをインストールしてしまうのでdebuggerとreactのバージョン違いで動かなくて当然です。

# 正しい対処法
まずは今入っているreact native dubuggerをアンインストール
(コマンドでアンインストールしないと色々残ってしまい0.10の再インストールがうまくいきません)

~~~
$ brew cask uninstall react-native-debugger
~~~

[React Native Debuggerの公式](https://github.com/jhen0409/react-native-debugger#notice-react-native-compatibility)によると、今回必要なv0.10以前のDebuggerのインストールは
以下のコマンドで実行できる

~~~
$ brew update && brew cask install https://raw.githubusercontent.com/caskroom/homebrew-cask/b6ac3795c1df9f97242481c0817b1165e3e6306a/Casks/react-native-debugger.rb
~~~

これでv0.10がインストールされ、無事エラーがなくなりました。
【Facebook】友達を外さず投稿のみ非表示にする

繋がりは維持したいけど、投稿が多い、ネガティブ投稿などで対象者の投稿を非表示にしたい場合の設定の備忘録です。

入ってくる情報が多すぎるのも考えものだわ・・・😅

<h2>方法</h2>
1.投稿記事の右上の「...」ボタンをクリック

2.○○さんのフォローをやめる

<h2>備考</h2>
対象者には通知等されません！
フォローをやめると聞くとちょっとドキっとしますけどねｗ
COVID-19チャレンジ（フェーズ3）その5

#概要

signateのCOVID-19チャレンジ（フェーズ3）やってみた。
投稿してみた。

#写真
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/9241b1aa-a1f4-a0ac-b01c-707bae7e54f4.png)


#サンプルコード


```
const sg = [1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 4, 7, 8, 14, 17, 20, 20, 20, 23, 25, 25, 25, 26, 26, 26, 28, 29, 33, 41, 53, 59, 66, 74, 84, 94, 109, 135, 147, 160, 171, 189, 214, 233, 242, 256, 274, 293, 329, 361, 417, 461, 494, 522, 581, 634, 690, 724, 787, 818, 835, 880, 921, 961, 1015, 1054, 1101, 1140, 1211, 1307, 1401, 1524, 1725, 1894, 1988, 2230, 2497, 2775, 3129, 3495, 3855, 4097, 4457, 4971, 5544, 6176, 6895, 7394, 7688, 8170, 8718, 9291, 9846, 10430, 10804, 11150, 11541, 11993, 12429, 12863, 13231, 13441, 13613, 13894, 14117, 14305, 14571, 14876, 15077, 15253, 15374, ];
var myChart;
var ctx = document.getElementById("canvas").getContext("2d");
const yy =  [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 3, 1, 6, 3, 3, 0, 0, 3, 2, 0, 0, 1, 0, 0, 2, 1, 4, 8, 12, 6, 7, 8, 10, 10, 15, 26, 12, 13, 11, 18, 25, 19, 9, 14, 18, 19, 36, 32, 56, 44, 33, 28, 59, 53, 56, 34, 63, 31, 17, 45, 41, 40, 54, 39, 47, 39, 71, 96, 94, 123, 201, 169, 94, 242, 267, 278, 354, 366, 360, 242, 360, 514, 573, 632, 719, 499, 294, 482, 548, 573, 555, 584, 374, 346, 391, 452, 436, 434, 368, 210, 172, 281, 223, 188, 266, 305, 201, 176, 121]
var pre = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,2,2,3,4,5,7,9,11,14,18,22,27,33,40,48,57,67,79,92,107,123,141,160,180,202,225,248,273,298,323,347,372,395,417,437,455,471,484,495,502,506,506,503,497,488,476,461,444,424,403,380,356,331,306,281,257,233,209,187,166,147,129,112,97,83,71,60,51,42,35,29,24,19,16,12,10,8,6,5,5];
var label = [];
var data = [];
var s = 0;
for (var i = 0; i < 131; i++)
{
	label.push(i);
	if (i < 111)
	{
		s += yy[i]; 
	}
	else
	{
		s += pre[i];
	}
	data.push(s);
}
var j = 0;
var out = document.getElementById('out');
for (i = 0; i < 131; i++)
{
	if (i > 116)
	{
		j++;
		out.value += j + "," + data[i] + "\n";
	}
}
myChart = new Chart(ctx, {
  type: 'line',
	data: {
    labels: label,
    datasets: [{
      label: "prev",
      fillColor: "rgba(151, 17, 25, 0.2)",
      strokeColor: "rgba(151, 17, 25, 1)",
      pointColor: "rgba(151, 17, 25, 1)",
      pointStrokeColor: "#fff",
      pointHighlightFill: "#fff",
      pointHighlightStroke: "rgba(151, 17, 25, 1)",
      data: data
    }, {
      label: "real",
      fillColor: "rgba(151, 187, 205, 0.2)",
      strokeColor: "rgba(151, 187, 205, 1)",
      pointColor: "rgba(151, 187, 205, 1)",
      pointStrokeColor: "#fff",
      pointHighlightFill: "#fff",
      pointHighlightStroke: "rgba(151, 187, 205, 1)",
      data: sg
    }]
  },
	options: {
		elements: {
			rectangle: {
				borderWidth: 2,
				borderColor: 'rgb(0, 255, 0)',
				borderSkipped: 'bottom'
			}
		},
		responsive: true,
		legend: {
			position: 'top',
		},
		title: {
			display: true,
			text: 'Chart.js Line Chart'
		}
	}
});

```

#成果物

https://embed.plnkr.co/plunk/u7Uh0lKNGn0AmLD8

以上。
【Linux】crontabコマンドでgit pullを定期実行しておく

crontabというコマンドを使って、定期的にPCに仕事をしてもらうようにする方法を紹介していきます。
crontabはUNIX系のコマンドでmacでつかうこともできるし、サーバ上で定期的にバッチを動かして働かせることができます。
PCに仕事をさせるのにぴったりなコマンドですね。では実際に使い方を見ていこうと思います。
今回はgit pullを自動実行して、常にローカルリポジトリを最新の状態に維持する方法を紹介していきます。

- crontabコマンドの注意
- crontabの記述
- シェルスクリプトへの記述

## crontabコマンドの注意


crontabコマンドは基本的にオプションと組み合わせて実行します。が、注意点があるので一旦manで使い方を確認


```

-l Display the current crontab on standard output.

-r Remove the current crontab.

-e Edit the current crontab using the editor specified by the VISUAL or EDITOR environment vari-
ables. The specified editor must edit the file in place; any editor that unlinks the file and
recreates it cannot be used. After you exit from the editor, the modified crontab will be
installed automatically.
```




-lをつけることで、現在の現在の状態を見れて、
-rをつけることで、crontabの削除ができて、
-eをつけることで、編集ができるようになります。

crontabはログインしているユーザごとの作成が可能です。

[ここでむちゃくちゃ注意しないといけないのが、オプション`-eと-rの違い`です。eとrはキーボードで隣の位置なので、間違えたら取り返しの付かないことになります。慣れないうちは必ずman crontabを使ってどっちだったか確認してから実行したほうがいいと思います。

## crontabへの記述

crontabにはスケジュールと実行するコマンドを書いておきます。
今回はシェルスクリプトを書いて、それを実行させていきます。

### スケジュール


分、時、日、月、曜日を指定することができます。
左からこの順番です。*だと指定なしとなり、　*/2　とすると~おきの実行となります。

```shell

 */5 * * * *
```

これだと5分おき

```shell
 0 23 * * *
```

これだと毎日23時

```shell
 * */1 * * *
```

これだと１時間おきになります。

より詳しく書いていきたい場合はこの記事とかを参考にすればいいかなと思います




クーロン(cron)をさわってみるお - Qiita






## コマンド




絶対パスを書いて上げて下さい。今回は/root以下にシェルスクリプトを書きます。

`/root/gitpull.sh
`
これをスケジュールの横に書いてあげればおけです。

```sh
*/5 * * * * /root/gitpull.sh
```

crontabのeditがおわったら、再読込のため再起動しましょう。

```sh

service crond restart
```
シェルスクリプトへの記述

ではgitpull.shを書いていきます。

```sh:gitpull.sh
cd (git pullしたいプロジェクトのディレクトリに移動)
git fetch
git reset --hard origin/master
git merge origin/master
```

とりあえず基本の型のみです。

git fetch
git reset --hard origin/master

はリモートの最新の状態をorigin/masterにもってきています。
git mergeで最新の状態をmasterに反映させることで、ローカルのファイルに変更の適用をすることができます。

つまりはgit pullをしてるだけですね

こちらも参考にしてみて下さい



[git fetchとは - Qiita](https://qiita.com/takakuda/items/2123e37733445f69f0ff)



[[社内新人向け]Gitで使ってほしくないコマンド - Qiita](https://qiita.com/zaramme/items/029d0f9b099e5f929e87)





以上です。5分おきに実行とかにしておけばgitの最新の状態が常に反映された状態になるかと。
便利ですね。
SimpleCovとRails 6のMinitest

カバレッジツール[SimpleCov](https://github.com/colszowka/simplecov) をRails 6のデフォルトのテスト（Minitest）で使ってみたところ、カバー率が0になりました。

```
Coverage report generated for RSpec to /Users/kazuto/projects/kazubon/blog-rails6-vuejs/coverage. 0 / 299 LOC (0.0%) covered.
```

Rails 6から導入された[パラレルテスト](https://edgeguides.rubyonrails.org/testing.html#parallel-testing)の影響らしく、test_helper.rbでparallelizeをコメントアウトすると、SimpleCovがカバー率を出しました。

```ruby:test/test_helper.rb
class ActiveSupport::TestCase
  include FactoryBot::Syntax::Methods

  # parallelize(workers: :number_of_processors)

  # fixtures :all
end
```

SimpleCovのGithubのIssueに、パラレルテストを使いつつカバー率を出す方法を見つけた人がいました。SimpleCov本体ではまだ対策されていないようです。

- https://github.com/colszowka/simplecov/issues/718#issuecomment-538201587

```ruby:test/test_helper.rb
class ActiveSupport::TestCase
  include FactoryBot::Syntax::Methods

  parallelize(workers: :number_of_processors)

  parallelize_setup do |worker|
    SimpleCov.command_name "#{SimpleCov.command_name}-#{worker}"
  end

  parallelize_teardown do |worker|
    SimpleCov.result
  end

  # fixtures :all
end
```

これでうまくいくのですが、MinitestなのにRspecと表示されるのがちょっと気になります。Rspecも入れているせいか。

```
Coverage report generated for RSpec, RSpec-0, RSpec-1, RSpec-2, RSpec-3 to /Users/kazuto/projects/kazubon/blog-rails6-vuejs/coverage. 187 / 210 LOC (89.05%) covered.
```
【感想】【ゼロから始めるデータ分析】ビジネスケースで学ぶPythonデータサイエンス入門

今回は、『[【ゼロから始めるデータ分析】ビジネスケースで学ぶPythonデータサイエンス入門](https://www.udemy.com/course/optworks_1/)』の学習報告を致します。
# 総評
内容　　　　　★★★☆☆
分かりやすさ　★★★★☆
オススメ度　　★★★★☆

##概要
本コースでは、データ分析について、
- 基礎分析(与えられたデータについて)
- 予測分析(未来のデータについて)
の２点をPythonを用いて学んでいきます。
事前準備としては、『[ANACONDA NAVIGATOR](https://www.python.jp/install/anaconda/index.html)』をインストールすること。
その中の『Jupyter Notebook』を用いて学習をします。事前に用意されている文言に従って作成することで、コードの学習およびデータ分析の学習を行なっていく形です。

また、予測したデータは『[SIGNATE](https://signate.jp/)』に投稿し、採点をうけることで、どのような分析手法を用いた方が良いかということを定量的に確認することができます。本コースではSIGNATE内の練習問題を解いていく形になりますが、受講終了後はCOMPETITIONを解くことで、腕試しをしたり、企業さんへのアピールになったりします。(転職を希望している方にもオススメ。。？)

## 感想
総評の通り、オススメ度は高めです(とは言っても、udemyでの初学習なので、これが基準になるのかなと思います)。学生時代に分析データについて簡単な基礎分析はやっていた(専門は地質学)ため、前半は少し退屈になってしまうところもありましたが、後半の予測分析は学生時代にやろうと思ってダメだった部分にも関連するような内容になっていたので、大変勉強になりました。
ただ、少し不満を漏らすとすれば、「Excelでできるな」というところが多く、まだPythonの強みは見えていないかなと感じております(というか、Excelってまだまだ奥深いな)。
まだ、Python学習のスタートなので、これからこのPythonの強みを見つけられるようにこれからも学習していきます。
*To be continued...*

######次回予告
次回は[【世界で21万人が受講】データサイエンティストを目指すあなたへ〜データサイエンス25時間ブートキャンプ〜](https://www.udemy.com/course/datascience365/)]について報告か...
TECH::EXPERT卒業したので、そちらの感想も書きたい(かなり幽霊部員的になってしまったが...)。
Rails I18nの紹介　flashメッセージの日本語化

##I18nとは
Internationalizationの略。
国際化という意味です。このメソッドを使用し、railsのエラーメッセージや、
自分で設定したカラムの日本語化をすることができます。
今回は、フラッシュメッセージの日本語化に苦労したので、その方法を紹介します。
まずは、表示したい日本語の設定を行っていきます。

```ja.yml
ja:
  notice:
    create: タスクを作成しました！
    update: タスクを編集しました！
    destroy: タスクを削除しました！
```


notice: noticeオプションはredirect_toメソッドで使用でき、フィードバックメッセージを渡すことができます。
先ほど設定した、「タスクを作成しました！」という文字を表示させるためには、t('notice.create')とコントローラーに記述します。

```ruby:controller.rb
  def create
    @task = Task.new(task_params)
    if @task.save
    redirect_to tasks_path, notice: t('notice.create')
    else
      render :new
    end
  end
  def update
    if @task.update(task_params)
      redirect_to tasks_path, notice: t('notice.update')
    else
      render :edit
    end
  end

  def destroy
    @task.destroy
    redirect_to tasks_path, notice: t('notice.destroy')
  end
```
noticeをビューに記述すると、フラッシュメッセージを表示することができます。

```ruby:index.html.erb
<p><%= notice %></p>
```

![94466A9B-32D4-4E34-BE9E-0262683DE1E0_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613801/11f091e7-1e61-603d-223a-0e8e7db68ffa.jpeg)

無事に日本語で表示することができました！
【Rails 】omniauth-google-oauth2を使用したgoogle認証で詰まった部分の解決策

##状況
プログラミングを勉強中です。
omniauth-google-oauth2を使用すればかなり簡単にユーザー登録における
google認証が実装できるということで、ポートフォリオに組み込んでいます。

自分自身が詰まったポイントが2点ありましたので、同じポイントでエラーが出ている方がいた場合を想定して
備忘録として残してみます。

尚、今回はローカル環境での動作確認しか行なっていません。
本番環境では　別途エラーが出る可能性もございますのでご了承ください。
また今回は、gemを使用するための事前準備としてのgoogleクライアントIDやクライアントシークレットの
取得方法については省略させていただいております。

##環境
Mac OS
Rails 5.2.4.1
ruby 2.5.3

##詰まったポイント1点目：gemを導入してもうまくいかない

google認証の動線としては、以下①、②の順番となります。
###①下の方にログインリンクが出る

<img width="1349" alt="スクリーンショット 2020-05-06 16.24.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/5cbffd2b-837c-ab05-b5c2-a29a823c6c42.png">

###②Googleのログインページに飛ぶ
<img width="1240" alt="スクリーンショット 2020-05-06 16.13.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/fca5ba89-0c18-59d6-c6d5-7844e1b114fc.png">


しかし私の場合は、google認証で使用する、**gem 'omniauth-google-oauth2'**をbundle install
したのですが、そもそも、②のgoogle認証のトップページに飛べない状況でした。
本来は上記の画像の様にリンクがログイン画面に出た後、Googleにログイン、という
ページに飛べるはずです。


##詰まったポイント1点目（解決策）：gem 'omniauth'の導入

ネットにアップいただいているgoogle認証系の記事だと、gem 'omniauth-google-oauth2'の
インストールのみで機能しているようなのですが、私の場合はうまく実装できなかったので、
**gem 'omniauth'**をbundle installしてみました。
その後、rails sでサーバーを起動しなおしました。

すると

<img width="1260" alt="スクリーンショット 2020-05-04 16.43.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565338/b2f20409-46b2-495e-3811-4b06672e5564.png">

Googleのページに接続できたものの、**エラー 400: invalid_request
Invalid parameter value for redirect_uri: Missing scheme: /users/auth/google_oauth2/callback**
と新たなエラーが出てしまいました。


##詰まったポイント２点目：エラー 400

直訳すると、「無効なリクエスト
redirect_uriの無効なパラメーター値：スキームがありません：」という意味となります。

クライアントIDが有効なのか、リダイレクト先は正しいか等色々考えてだいぶ詰まったのですが、
結論下記のやり方でなんとか対処することができました。
（根本的な原因は特定できておりません・・）

##詰まったポイント２点目（解決策）：環境変数を使用せず、直接devise.rbにクライアントID,クライアントシークレット、リダイレクトURIを書き込む。


```ruby:devise.rb

 config.omniauth :google_oauth2,'クライアントID','クライアントシークレット',
  scope: 'email',redirect_uri: "http://localhost:3000/users/auth/google_oauth2/callback"


```

ENVという表記は、環境変数を指定する際に記載するので、直接書き込む場合は不要です。
また、今回はローカル環境での実装を目的としているので、localhostのURIを指定しています。

こちらを記載して、rails s でサーバーを再起動すると、無事google認証でのユーザー登録が
成功しました！

##※※5/13追記※※
②ですが環境変数の記載が誤っておりました。

```ruby:.env

【修正前】
'ENV[GOOGLE_CLIENT_ID]'="hogehoge"
'ENV[GOOGLE_CLIENT_SECRET]'="foobar"

【修正後】
'GOOGLE_CLIENT_ID'="hogehoge"
'GOOGLE_CLIENT_SECRET'="foobar"

※"hogehoge"と"foobar"はご自身で設定した値です。
```
ENVは、環境変数を呼び出すために必要であるため、
こちらを記載してしまうと正確に環境変数を設定することができません。

上記修正することで、うまく環境変数を呼び出すことができました。

##まとめ

根本的なエラーの解決にはなっていないのですが、ひとまずローカル環境での実装という観点からすると
実装ができました。

クライアントID等をdevise.rbに直接書き込むとセキュリティ的な問題があるので、
追ってenvファイルに書き込んで、環境変数を使用して実装したいと思います。

不備があるようであれば、ご教授いただけますと幸いですm(__)m
【祝!!初投稿】プログラミングのオンライン講義を受講してみた

2020年ゴールデンウィーク
今後忘れることができない出来事・・・そうコロナによる自粛ムードです・・

なんの予定もない
このままだと、食っちゃ寝で過ぎてしまうGWになると思い自己投資を決断！

今回はこちらのオンライン講座に参加させていただきました。

[ゴールデンウィークに社会人向けのプログラミングのオンライン授業を実施。完全初心者からでもサポート可能。
](https://prtimes.jp/main/html/rd/p/000000009.000020328.html)

詳細はリンク先に記載されているので、受講してみた内容をアウトプットするための備忘録的なことをつらつらと記載していきます。

##受講の目的
上述とも重複する部分もありますが、プログラミング初心者で現在勉強中のため、
GWの期間を利用して少しでも自分の糧になるよう、受講を決意しました。

##内容
3日間という短い期間でしたが、以下の内容で進行しました。

####1日目（12:00〜18:00）
・オリエンテーション

・axiosを利用して、APIを利用するワーク
　※axiosとはブラウザやnode.js上で動くPromiseベースのHTTPクライアントです。

・LINE Notify を用いて「LINEのWEBサービスから自分に通知を受け取る機能」を
API(LINE Notify API) からやり取りして、通知させるワーク

・Discode APIを用いて、Discrodeに通知を反映させるワーク

・GitHubの使い方解説

・GitHubActionを用いて、定期的にLINE Notifyの動作を促すロジックの作成

####2日目（12:00〜18:00）
・Webの仕組み、HTML/CSSを用いて簡易サイトを作成

・[Vue.js](https://techacademy.jp/magazine/21456)でデータを読み込むWEBサイトを作成

・他のサイトの情報をAPIとして自分のサイトで扱う（スクレイピング）

####3日目（10:00〜18:00）
・2日を通して学んだ内容のアウトプット or　新型コロナウイルス感染症対策サイト への協力貢献

##3日を通して学んだこと
・APIの取得やスクレイピングを利用して必要な情報を取得する方法など、実際に手を動かして作業をすることで、具体的な動きの流れを理解することができた。

また、APIやスクレイピングを用いて必要なデータを取得することがより身近に感じられ、必要に応じて適切なデータを取得することがより身近に感じられた。

・新型コロナウイルス感染症対策サイトのOSSを用いて実際に改修等に貢献することで、OSSデータのやり取りから、作業全般まで実際に作業する流れを理解することができた。

このような取り組みがあること自体、詳しく知らず自分には程遠い話だと感じていたが、今回の講義で触れることで、多少なりともハードルが下がった。

以上2点を通して、技術的な知識に加えて技術者同士の取り組みなど、受講前と比較して可能性の視野が広がったと感じました。

##総評
本格的な勉強会に参加することは初めてでしたので、非常に良い経験となりました。
今回はオンラインでしたが、コミュニケーションツールが充実していたので、他の受講者さんとのコミュニケーションも円滑に行うことができて、とても満足でした。

当初はガッツリとコーディングなどに触れる内容と思って受講したので、その点については若干心残りなところはありますが、普段とは違うかたちでプログラミングに触れることにより、とても良い刺激になりました。
EC2に固定IPを付与する

今回はEC2に固定IPを設定する。デフォルトでは起動するたびにIPアドレスが変わってしまう。
**注意点**
固定IPを設定すると、EC2の停止中は料金が発生する。デフォルトではEC2が起動している間だけIPアドレスを使用している。しかし、固定IPを取得するとEC2が停止中もIPアドレスを使用することになる。停止中は追加料金がかかるから気をつけよう！
※後半に固定IPの解除方法を載せている。

#固定IPの設定
EC2の左側のメニューから、ElasticIPを選択。これが固定IPに相当する。新しく割り当てるので、ElasticIPアドレスの割り当てを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/25da6dfa-5559-8261-ccb9-5ba78503d370.png)
割り当てを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/1ef13494-38e5-bd79-05ae-b203cec0c8dd.png)
追加したElasticIPにチェックを入れて、ActionsのElasticIPアドレスの関連付けを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/3d235c74-ab23-c84b-cf50-56c3653c64b1.png)
インスタンス、プライベートIPアドレスを設定して、関連付けるを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/f5f94ddb-2e59-7b74-e7da-03f532978a17.png)
ブラウザで設定したElasticIPアドレスへリクエストし、テストページが返って来たら成功！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/f8aa2055-fe35-727d-75e3-d90306b51de5.png)

#固定IPの解放
EC2停止中は固定IPの料金がかかるので、ElasticIPを解放する。
ActionsのElasticIPアドレスの関連付けの解除を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/048c8f4a-9b26-afbb-7620-fd5f4c39cb27.png)
確認メッセージが出るので、関連付け解除を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/dfc10d9e-d6d8-7796-acce-9891692c2602.png)
ActionsのElasticIPアドレスの解放を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/9549f802-4cc0-d9da-025c-7afaa6e0ca72.png)
解放を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/19db66f3-6328-bba3-b259-57591ab6dc25.png)
IPアドレスの解放完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/6e2d8856-dfc1-f4fa-b4c8-cc44229bab0d.png)

#終わりに
勉強で固定IPを作成した際に、知らずに料金がかかってしまったので、EC2を停止するときはElasticIPも必ず解放しよう！
CPU速度比較

# 疑問
最近の i3 は以前の i7 より速いと聞いたが、本当ですか？

## 結論
 本当（一部に限って）

## 調査

以下の図、横軸はCPUの世代（generation）。縦軸は処理速度を表すスコア。大きい方が速い。色は種類（ i3, i5, i7, i9）。値は[このサイト](https://www.cpubenchmark.net/high_end_cpus.html)から取得したもの。
![Figure 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/a5fcaaf6-d055-300b-a94a-b0ee3bc1e4b1.png)

この図を見ると、１２世帯のi5が（スコア25000あたり）前世帯の大部分より速い。

へ～知らなかった。

![Figure 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/b839d92b-8594-270c-1c8d-a472962855c0.png)
３Dの図で見ると１２世帯は断トツ高いことが分かる




## 速度 vs 値段

スコアパフォーマンス(１ドルで購入できるスコア）でも、12 世帯 i5 がいい位置にある
![Figure 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/fe761538-eac0-a04b-5cdd-7c706984e5e9.png)


## AMD vs Intel

下図、横軸は値段、縦軸は処理速度。１００＄以上なら AMD は同値段の Intel より処理速度が速いことが分かる。
![cpu-intel-vs-amd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32912/d0a33ac5-e95d-1017-5ef7-f2a94cbec22f.png)


#### 参考
- 元データサイト（英語） https://www.cpubenchmark.net/high_end_cpus.html
- 今回使った MATLAB スクリプトは [github](https://github.com/izayoi5776/cpu_benchmark_vs_price_graph) に置いてあります。
sqlite3 dump and restore 

# dump 
```sql
sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql
```

# rails dbconsole
```
$ rails dbconsole
> .output schema.sql
> .schema
> .output dump.sql
> .dump
> .quit
$ grep -vx -f schema.sql dump.sql > data.sql
```

# restore
SQL ファイルを読み込む。

```
$ rails dbconsole
> .read data.sql
```