OmniAICreator/Qiita-1.07M huggingface dataset:
スクラムの基礎

# はじめに
引き続き、研修のアウトプットをしていきます。
今回は「スクラムの基礎」です。
# 学んだこと
### スクラムとは？

- アジャイル開発手法のひとつ
- 複雑なプロダクトを開発・維持のために用いられる
- 3つの会議と役割と成果物で構成されている

#### アジャイル開発とは？
計画 → 設計 → 実装 → テスト といった工程を、機能単位の小さいサイクルで繰り返す
早い段階でリリースできるものをつくり、利用者の声を受けてプロダクトの中身や計画を調整する

以前まとめた記事：URL
### 3つの会議
`スプリント計画（プランニング）`

- 週単位でおこなわれる会議
- スプリントという単位が用いられる（プランニングからレビューまで）
- 1スプリント2週間（※プロジェクトによって変わる）
- その週になにをつくるか決め、製品を完成させる

`デイリースクラム`

- 毎日おこなわれる会議
- 昨日やったこと、今日やること、進行の障害となっていること
- 全員それぞれ話し、全体で15分以内で共有する

`スプリントレビュー`

- 計画に対して結果を確認する
- レビューの後に、1週間の「つくったもの」ではなく「プロセス」や「人との関係」などの改善点を洗い出し、次のアクションにつなげるためのふりかえりがおこなわれる（スプリントレトロスペクティブ）

### 3つの役割
プロダクトオーナーとスクラムマスターは役職名ではなく、役割

`プロダクトオーナー`
何をどの順番で作るのか優先度づけする責任がある

`スクラムマスター`

- チームに対して状態を促したり、導く人
- プロダクトオーナーと開発チームが円滑なコミュニケーションがとれるようにする

`開発チーム`
実装する人。SE、プログラマー

### 3つの成果物
`プロダクトバックログ`
機能や改善要素を優先度づけして並べたリスト

`スプリントバックログ`
スプリント期間中のタスクリスト

`インクリメント`
スプリントで開発された成果物。いつでもリリースできる品質を満たしたプロダクト。

# まとめ
以前勉強したアジャイル開発の手法を深ぼりできたことで、実際に開発をおこなうときの流れがイメージしやすくなりました。今回習ったとおりではなく、スクラムを複数組んだり、プロジェクトごとにやり方は変わったりするとのことなので、実践を積む中で色んなパターンも学んでいきたいと思います。
パッケージ管理について

#WHY
最初に意味もわからずやっていた環境構築をすこし知ることができたので、またもし行う際など見直すため、

-------

#パッケージとは
プログラムや処理をまとめたもの。ライブラリと似てますが、パッケージの中にライブラリをまとめていることもある。

#パッケージ管理とは
パッケージやパッケージが持つライブラリなどの<B>依存関係</b>を考慮して<b>インストールやバージョンアップを行う管理</b>のことで、パッケージ管理ツールというもので管理することができる。（例:Homebrewなど）
ホームディレクトリで以下の記述でインストールできる。

##Homebrew
macOSの<b>パッケージ管理ツール。</b>
macOS上で動作するアプリケーションの多くがHomebrewからインストールできる。

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
Homebrewには様々なコマンドが用意されており、主にパッケージのインストールや更新、アンインストールなどを行うことができる。

|コマンド|説明|
|:--:|:--:|
|brew -v|Homebrewのバージョンを確認|
|brew install [パッケージ名]|パッケージをインストール|
|brew uninstall [パッケージ名]|パッケージをアンインストール|
|brew list|インストールしたパッケージを表示|
|brew search|インストール可能なパッケージを表示|
|brew update|インストールしたパッケージを最新へ更新|

また、Ruby on Railsでは、バージョン6以降、JavaScriptのパッケージがデフォルトで入っているため、プロジェクトの作成時に<b>Yarn</b>のインストールが必須となった。

##Yarnとは
JavaScriptのパッケージ管理ツール。
Homebrewを使ってインストールすることができる。

```
brew install yarn
```


#バージョン管理とは
変更したバージョンを記録、または依存関係を考慮して過去のバージョンや最新のバージョンに切り替えること。

<br>バージョン管理をしないと、Rubyのバージョンを最新にしたことで、Rubyのバージョンが<b>すべてPC内で共通</b>となってしまい、<b>依存関係の問題</b>が起きてしまうことがある。
そのため<b>バージョン管理ツール</b>というものを使う。

##rbenv
Rubyのバージョンを切り替えるための<b>バージョン管理ツール</b>。
複数のバージョンをダウンロードしておいて、使用するRubyのバージョンをディレクトリごとに指定することが可能になる。

rbenvもHomebrewでインストールすることができる。

```
brew install rbenv
```

また、rbenvにも使うコマンドが多数あり、おもにRubyのバージョンを更新したり、操作したりすることができる。

|コマンド|説明|
|:--:|:--:|
|rbenv -v|rbenvのバージョンを表示|
|rbenv install [バージョン]|バージョンを指定してインストール|
|rbenv uninstall [バージョン]|Rubyバージョンを指定してアンインストール|
|rbenv versions|インストールされているRubyバージョンの一覧を表示|
|rbenv global [バージョン]|すべてのディレクトリで使用するバージョンを切り替える|
|rbenv local [バージョン]|カレントディレクトリで使用するバージョンを切り替える|
|rbenv rehash|RubyやGemに関するコマンドをバージョン変更後も使用できるようにする|

------
【Python備忘録】文字列置換を学んだので記します（replace関数）

#はじめに
今回は、pythonにて文字列の操作を学んだので記録としてのこします。
基本的なことだけど意外と使えるなと感じたので書いてみることにします(^▽^)/

※メモレベルなので必要になった時にさらっと見返す感じで役立てて頂ければ幸いです。

#使用する関数（replace関数）

```sample.py
修正後の文字列=対象文字列.replace("置換前の文字列", "置換後の文字列")
```

#文法の説明
置き換えたい単語が含まれているある文章があったとして、その文章を「対象文字列」と呼ぶことにします。

今回は「対象文字列」に含まれる置換したい単語を置換する操作を行います。

先ほどのように、"置換前の文字列"、"置換後の文字列"にそれぞれ書くことで、「対象文字列」の単語を置き換えた新しい文章を「修正後の文字列」に代入することが可能です。

#実際に使ってみる
今回は

```
わたしは、人参が大好きです。
本当に人参が大好きで、大好きでたまりません。
つまり人参が大好きです。
```

という文章があったとして、
「大好き」の部分を「苦手」に置換してみます。

```sample2.py
line = """わたしは、人参が大好きです。
本当に人参が大好きで、大好きでたまりません。
つまり人参が大好きです。"""

fixed_line = line.replace("大好き", "苦手")
print(fixed_line)
```
これで実行すると、文章中の「大好き」を「苦手」に置換することができました！

#さいごに
とても便利な機能なので、繰り返しの文字修正などがあった時に使ってみたいと思いました( ｀ー´)ノ
今後も学んだことをアウトプットしていきたいな。。。

#参考
公式ドキュメント
https://docs.python.org/ja/3/library/stdtypes.html?highlight=replace#str.replace
Google Compute EngineのWindowsでファイルをローカルにコピーする方法。mac

## やりたいこと

- Google Compute EngineのWindowsで
- ファイルをローカルのMacにコピーする

## やり方

1. MacでMicrosoft Remote Desktopをインストール
2. Google Compute EngineのウェブUIから、RDPファイルをダウンロード
3. RDPファイルを開く
4. Windows上でファイルを選択してCommand + Cでコピー
5. Mac上でCommand + Vでペースト
【わたし用備忘録】React Night #1 資料・メモまとめ

# React Night #1
開催日時：2020.01.25
Reactに関するLTとフリートーク

- [イベントページ](https://misokatsu-web.connpass.com/event/196285/)
- [Youtubeアーカイブ](https://youtu.be/W-VHz71ygkc)
- 主催：[みそカツWeb](https://misokatsu-web.connpass.com/)さん

<br>
## Redux - Normalization
登壇者：渡邉 悠真さん / 株式会社スタメン
登壇資料：https://speakerdeck.com/yun8boo/redux-normalization

<br>
## Reactエンジニアに捧ぐおすすめデザインシステム
登壇者：母利 睦人さん / 株式会社オプティマインド
登壇資料：https://speakerdeck.com/makomori/react-night-dezainsisutemu

- [Material UI](https://material-ui.com/)
- [Ant Design](https://ant.design/)
- [Primer](https://primer.style/)
- [Polaris](https://polaris.shopify.com/)
- [Carbon design system](https://www.carbondesignsystem.com/)

<br>
## 複雑化したReact hookのデバッグとその対策
登壇者：一円 真治さん / ヤフー株式会社
登壇資料：https://speakerdeck.com/1coin/fu-za-hua-sitareact-hookfalsedebatugutosofalsedui-ce

<br>
## React プロジェクトに秩序をもたらす ~Rails エンジニアによる React プロジェクトの育て方~
登壇者：上島 愛史さん / 株式会社エイチーム
登壇資料：https://speakerdeck.com/aiji42/react-night-number-1-reactpuroziekutonizhi-xu-womotarasu

UIリポジトリとロジックリポジトリを分離させる
しかし結合するまで検証ができない

モノレポ
解決方法 -> 複数のリポジトリをひとつのnpmで管理させる

- [Hygen](https://www.hygen.io/)
    - 対話形式でコンポーネントが作れる
    - [hygenで簡単につくる対話式コードジェネレータCLI](https://qiita.com/usagi-f/items/ea4ecf7ec6a6b52567e3)
    - [hygen で生成 - 対話形式の Component 雛形](https://zenn.dev/takepepe/articles/hygen-template-generator)


<br>
## ガントチャート自作した話
登壇者：山崎 遼介さん / freee株式会社
登壇資料：見つけられませんでした！🙇‍♀️ お持ちの方やここにあるよ！を教えてくださる方はコメントくださいmm

<br>
## Recoil使ってるっていう話
登壇者：めろたん / bosyu開発室
登壇資料：https://docs.google.com/presentation/d/11vlSVxo_nwS6MkLu-LgvqIIpsbWuTDsoSolzU6Wp6pw/edit#slide=id.g84674502f3_0_7

フィルターやソートが簡単にできるので、アサインされてるPJのとあるページをReactにするときにRecoil使えそう。。。。

- [Recoil](https://recoiljs.org/)
    - [waitForAll(dependencies)](https://recoiljs.org/docs/api-reference/utils/waitForAll/)


<br>
<br>
**おわり:qiitan:**
通帳レス口座で通帳の表紙を印刷する方法

プログラミングに関する知識/技術とは無関係な記事であることご容赦ください。

# はじめに

就職、転職、給与を振り込みしてもらう口座の変更など、etc……な場面で「通帳の表紙」のコピーの提出を求められるコトがありますよね。通帳レス口座を利用していたり、紙の通帳が見つからない場合にどうしたらいいのって話。

# 大手3行はネットバンキングから印刷できる

- 三菱UFJ
 - https://faq01.bk.mufg.jp/faq/show/839?site_domain=default
- 三井住友
 - https://qa.smbc.co.jp/faq/show/2761?category_id=44&site_domain=default 
- みずほ
 - https://www.faq.mizuhobank.co.jp/faq/show/5880?site_domain=default

# 三菱UFJでのイメージ

以下の画像はpdfから切り抜いたものですが、これと同様のものが取得できることを確認しました。
![スクリーンショット 2021-02-09 16.53.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129243/470d0501-bbed-6ff0-2665-7f0834155980.png)

# 最後に
大手3行以外の場合は`年金受取`+`預金通帳の写し`+`銀行名` で検索すると情報を見つけやすいようでした。
以上、役に立つコトがあるかもしれない小ネタでした。
【超シンプル備忘録】 Linuxでのパスを通す

「パス」とは、「コマンドサーチパス」の略称です。
すなわち「パスを通す」とは「**コマンドを探しにいくパス（ディレクトリー）の設定をする**」という意味になります。

パスを通すためには、環境変数`PATH`に対して、通したいパスを「:」記号区切りで指定します。
この設定には、`export`コマンドを利用します。
たとえば、現在の設定に加えて「/usr/sample」というディレクトリーにもパスを通したい場合は、次のように実行します。

```
$ export PATH=$PATH:/usr/sample
mysql 8でログインする時の注意

##前提
今回使用するバージョンは以下のものです
OS RHEL 7
mysql 8.0.23

##mysqlで初回ログインするには・・・
mysqlで初回ログインする時、パスワードはあるファイルに書いてありました。

```
# vi /var/log/mysqld.log
```

上記のファイルを開くと、以下の文章があり、その一文の末尾にある[Zh1r=l;:=X,B]がパスワードです

```
[Note] A temporary password is generated for root@localhost: Zh1r=l;:=X,B
```

入力したらログイン出来ました〜〜〜〜
ただ、今度はrootのパスワードを変更したい。
そこで以下コマンドを実施

```
ALTER USER 'root'@'localhost' identified BY 'testpassword';
```

すると、エラーが。。。

```
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
```

ポリシー要件を満たしていないらしいです。
そもそも初回段階はポリシー要件が厳しいらしいので、それをゆるくします。

```
mysql> set global validate_password.policy=LOW;
```

その後再度ALTER USERコマンドを使用すると、セット出来ました。
これで諸々の設定が出来ます。

初回ログイン時はポリシーを見直してセットするようにします

###参考文献
MySQL(5.7以降)のパスワードポリシーが厳しいので変更する。Your password does not satisfy the current policy requirementsの対処法
>https://qiita.com/isao_e_dev/items/4bf590788b79932bbeb0
next-authの基本的な使い方。（gmailのsmtpサーバーを利用）

next-authの基本的な使い方。（メールリンク方式） - Qiita
https://qiita.com/masakinihirota/items/190360bfdcc4bf2b13ac
の続き。

# 今回の目標
前回はsmtp4devというダミーSMTPサーバーツールを使用してローカル内でメールリンク方式の認証をしていましたが、今回はgmailで利用できる無料SMTPサーバーを利用してメールリンク方式の認証を行います。

gmailは無料のSMTPサーバーを提供しています。
詳しくは下記をご覧ください。

GoogleのSMTPサーバー（あまり知られていない無料サービス）の使用方法
https://thefunky-monkey.com/page/googlesmtp/



# Googleアカウント設定

![セキュリティ sketch.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/0eacab12-4f7b-05a9-fc2b-2abd997b3a71.png)

Google アカウントのセキュリティ
https://myaccount.google.com/security
このセキュリティから「安全性の低いアプリのアクセス」を選び

![有効.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/7ef42bf9-60e6-c4b7-e1e0-6e37d08f8964.png)

安全性の低いアプリのアクセス
安全性の低いアプリの許可: 有効
にします。

この設定をしないと外部アプリ（今回は next.js）からのは全てシャットアウトされます。

![セキュリティ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/b56da77c-8418-36f3-8f86-46c7092bdb6f.png)

この設定をすると「安全性の低いアプリによるアクセスが有効になりました」と確認メールが来ます。
ボタンを押すと確認を促されます。
いま自分で設定したので
「はい、心当たりがあります」を選びます。
そうすると
「本人確認が完了しました
お使いのアカウントの保護を目的としています」
と表示されます。

# next.jsアプリ
メールの設定を変更します。

.env.localファイルの下記の部分を自分のメールに変更します。
NEXTAUTH_EMAIL_SERVER=smtp://{gmailのメールアドレス}:{メールのパスワード}@smtp.gmail.com:587

```.env.local
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_TWITTER_ID=
NEXTAUTH_TWITTER_SECRET=
NEXTAUTH_GITHUB_ID=
NEXTAUTH_GITHUB_SECRET=
NEXTAUTH_GOOGLE_ID=
NEXTAUTH_GOOGLE_SECRET=
NEXTAUTH_FACEBOOK_ID=
NEXTAUTH_FACEBOOK_SECRET=
NEXTAUTH_EMAIL_SERVER=smtp://{gmailのメールアドレス}:{メールのパスワード}@smtp.gmail.com:587
NEXTAUTH_EMAIL_FROM=NextAuth <masakinihirota@gmail.com>
NEXTAUTH_DATABASE_URL=sqlite://localhost/:memory:?synchronize=true
```

.env.localファイルは.gitignoreでgitが追跡していない設定になっているはずです。
**パスワードが書かれているのでネットにアップしないよう気をつけましょう。**

![メール設定とパスワード.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/18b4a1fe-1d2d-78f6-9e86-c3a453531db2.png)

※モザイク部分はパスワードです。
以上で設定は終了です。

# アプリを立ち上げて確認
ターミナルから
`npm run dev`

http://localhost:3000/

右上のSign inボタンをクリックして
メールを入力して
Sign in with Emailボタンを押して
自分のところにメールが来たかを確認します。
メールが来たのを確認できたら
「Sign in」ボタンを押すと
サイトにログイン済みになっています。

＃比較
前回は下記のようでした。
![ローカル環境.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/c7f21216-5a64-c331-bcd8-1519b5c71404.png)
から
![ローカルネット環境 gmail2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/acb09f09-e433-33c7-6ba1-37de1446cd40.png)
といように
一部の機能をネットに切り出せました。
SIGNATE インターンコンペ　まとめ

# 初めに
こんにちは、signate名はmimishitaでやっています。先日行われた[インターンコンペ](https://signate.jp/competitions/402)に参加したので、その参加記を残そうと思います。

順位については30位で銀メダルと、あまり高いものではなかったのですが、最終サブをちゃんと選んでいればもうちょっと順位は上がっていたかもしれないです。(負け惜しみ)

また、ディスカッションに載っていた[masato8823さんのベースライン](https://signate.jp/competitions/402/discussions/lgbm-baseline-except-text-vs-include-text-lb07994-1)を大いに参考にさせていただきました。この場をお借りして御礼申し上げます。

# 作成した特徴量について

特徴量については以下のものを作成しました。

* テキスト特徴量
    * html_contentをそのままtf-idfし、TrunctedSVDで64次元に圧縮
    * html_contentからタグ情報を除いたものにtf-idfを行い、TrunctedSVDで64次元に圧縮
    * html_contentからタグ情報を除いたものにbertを行い、PCAで50次元に圧縮
    * html_contentからタグ情報を除いたものから、文字数を取得
    * htmlのタグや特徴的な表現をカウント
        * div
        * p
        * h1
        * span
        * img 
        * figure 
        * video 
        * animate 
        * figcaption 
        * polygon 
        * li 
        * bold 
        * Indicator Bar 
        * dummy.com
* goal
    * '1-1000'のようなデータ構造になっているので左の値と右の値をそれぞれ分割させる。また、二つの値の平均値を取得する
    * [-1, 24999, 49999, 79999, 99999, np.inf]でbinningする
* duration
    * [-1, 30, 45, 60, 100]でbinningする
* カテゴリ変数
    * 'category1'と'category2'を結合した'category3'を生成する
    * 各カテゴリと'country'を結合した特徴量を作成
    * binningしたgoalとdurationを結合
    * LabelEncoding
    * FrequencyEncoding
* 数値変数
    * htmlの文字数、タグのカウント、goalの平均値、durationの各変数の積と商を計算する
* 集約特徴量
    * 各カテゴリ変数(country, category1, category2, category3, binningの値)の集約特徴量を計算する。集約方法は["min", "max", "mean", "std", "count"]を使用

# モデルの作成
作成したモデルについて
* LightGBM x3(max depth=3, 5, 10)
* NN
* 上記のモデルで得られた予測値を特徴量としてLightGBMを用いて予測、閾値についてはディスカッションに載っていた最適化手法を使用。

# 感想
* 初めてしっかり参加したコンペでメダルを取れたのは非常によかった
* ベースラインをかなり参考にしてしまったので、自分でモデル作成の部分ができるようになりたい
* Trust CVの精神を持つ
* 最終的にgithubにコードを載せられる程度にはコードを整理しておく
rsyncの際、パスワード入力を省略する方法

##rsync実行時のパスワードを省略する方法

こんにちは。いろはです。
今回はrsyncコマンドを実行する時に入力が求められるパスワードを省略する方法を紹介します。
方法としては2つ考えられます。

####前提
使用する環境はRHEL7です。
同期をかけるサーバは2台を想定とし、どちらもRHELであることを想定しています。

###rsync省略方法①
rootユーザに公開鍵認証を設定してパス無しとする方法です。
下記コマンドを用いることを想定しています。
※/data2/testのデータを対象サーバへ同期したい時、sshポートを指定して持っていく

```
# rsync -e ssh -avzH /data2/test root@192.168.X.X:/data2/
```

###rsync省略方法②
rsyncデーモンを移行時に起動させ、rsyncセッションでパス無しにする方法です。

具体的な手順は以下になります。
#####①移行先サーバに/etc/rsyncd.confを作成する
以下内容を記載します。

```
use chroot=no

[test]
path=/
read only=false
write only=yes
hosts allow=*
uid=0
gid=0
secrets file=/tmp/password.txt
```

#####②移行先サーバにパスワードファイル /tmp/password.txtを作成する
rootのパスワード情報をpassword.txtに書き込みます。

```
root:password
```

#####③rsyncデーモンを起動する
以下コマンドで起動します。

```
rsync --daemon
```

#####④移行元サーバでrsyncコマンドを実行する。

```
rsync -avzh /data2/test root@192.168.XX.XX::test/data2/
```

#####！！！注意！！！
・rsyncのデーモンを起動後はkillコマンドで停止してください。



####参考リンク
rsyncオプション
>https://qiita.com/bezeklik/items/22e791df7187958d76c1
Unityで作られているゲーム　１５選を紹介

ゲームエンジンとして知られるUnityですが。　

そんなUnityで作られている代表的なゲームを紹介していきます。

# ポケモンＧＯ


これはもう、Unityの代表といえるゲームですね。　

ＡＲでカメラを通すと、現実の場所にポケモンが現れてゲットできると。

当時のモバイルゲームでは１番でしたし、　今でもヘビーユーザーが多いです。　

世界的ブームを起こしたゲームですね。

　



# ドラゴンクエストVIII 空と海と大地と呪われし姫君
このゲームのアプリ版も、　Unityで作られています。　

リメイク作品として、Unityが使われているのは珍しい感じ。　



# 　スーパーマリオラン　
スーパーマリオのアプリ版ですね。　

マリオが自動で移動してくれるので、タップするだけの簡単操作が

特徴のゲームです。　

ほんと、マリオの時代を感じますね。

ファミコンのころのマリオなんて、　鬼ゲーだったのに　

今ではタップのみ　で

できてしまうわけですから。



# 原神　
去年ブレイクしたこのゲームも、Unity作品です。　

これでまたUnityの人気も上がりましたよね。　



# カニノケンカ
これは去年でしたかね？　

話題になったインディーゲームです。　

ＴＶ番組の　有吉いいeeeeでも　やっていました。

田中というカニがカニを操作していたと話題でしたねｗｗｗ

カニ同士の格闘ゲームとはまた斬新ですよ。

しかしみんなもう飽きてしまったのか　

最近は、あまり聞かないですね。



# 　バイオハザードアンブレラコア
これはＰＳ４の作品です。　

これだけのゴリゴリ３ＤをUnityで作ったのはすごいです。　

しかも、結構前ですからね。　

こちらのゲームは、　Unity会社から技術協力を受けていたようです。

Unityでも頑張れば、　こうゆうハイスペックな作品も行けるということを　

証明した作品でしょう。


# ホロウナイト
これはインディーゲームの中でも１番有名な

ゲームなので、知らない人はいないでしょう。　

私も　もちろんプレイしています。　

地図買わないと　ダンジョンで迷うのよね。

Unityの２Ｄゲーム作品では、トップクラスの作品です。

まだやっていない人はやったほうがいいですよ。

まじで面白いし、やりごたえも十分すぎるほどあります。　

ボスも結構強い。
というか強すぎてイライラするぐらいです。


# ヒューマンフォールフラット　
これも人気のインディーゲームですね。　

ぐにゃぐにゃ人間が特徴のゲームです。　

１人でやると難しいですが、みんなでやると簡単になるのが特徴の一つです。

有吉いいeeeeの　

ヒューマンフォールフラットの回は　神回になって

それでまた、ブレイクした作品です。

神回は確か、YOUTUBEでも見れます。　



# 　Celeste
セレステも実はUnityなんです。　

こちらも人気ゲームですよね。　

２Ｄの爽快感がある死にゲーです。　

死んで復活、死んで復活を繰り返して　

山の頂上を目指していくゲームです。　

ファミコン世代が好きそうなゲームですよね。


# INSIDE
これは知っている人は知っているインディーゲームです。　

私もプレイしてみましたが　

最初はホラーゲームなのかなと思ったけど

最後はなぜか、グロゲーになります。　

グロいまま終わるので、　評価は分かれている感じです。
やれば分かりますが
なんちゅー　終わり方やねんって　ツッコミたくなるような
終わり方をするゲームです。




# カップヘッド　
こちらも有名なインディーゲームです。　

シューティングアクションゲームで　

Celesteと同じぐらい、難易度の高いゲームです。　

手書きのアニメーションが特徴になっています。　


# RIME
ライムというインディーゲームもUnityで作られています。　

ノスタルジックなゲームで、人気も高い作品です。　



# 　the　first　tree
ザ　ファーストツリー。

このゲームも、インディーゲームの中では有名作品です。　

個人開発、　たった一人で作ったゲームとして有名です。　


Unityアセットを上手くつかって仕上げているのが印象です。
個人でもやればここまで　できるんだと思えるゲームですね。



# 　Fall Guys
フォールガイズ。　

こちらも昨年ブレイクした作品ですね。

Unityはこうゆうマルチプレイヤーのゲーム構築は

あまり得意ではないと言われていましたが。

このゲームで、それが覆された感じはします。

Unityの可能性を広げた作品と言えます。

Unity のマッチメイキングと Multiplay のハイブリッドクラウドの連携

で作られていますが　

これを個人レベルでやるのは、普通に厳しいですよね。



# 　Last Day on Earth
こちらもUnityの代表作といえるゲームですね。　

このゲームのすごいところは、たった２か月弱で　

リリースまで持っていて

それでヒット作に繋げたところです。　

広告もUnityadsが使われています。








ＰＳ　

　

[Unityの寺子屋ユニコーン](https://unitymaster2.com/)

というサイトもやってますよ。
Databricksにてモデル学習してみた

## Databricks ～MLFLOWトラッキング モデル実行結果～

DatabricksのNotebookを活用して、モデル学習をしてみました。
モデル学習した結果の表示や管理等まとめていきます。

参考Notebookは公式ドキュメント記載のMLflowPythonQuickstartを使用します。


##### ・自動的にログに記録する設定

MLflowは`mlflow.<framework>.autolog()`、多くのMLフレームワークで記述されたトレーニングコードを自動的にログに記録するためのAPIを提供します。トレーニングコードを実行する前にこのAPIを呼び出して、モデル固有のメトリック、パラメーター、およびモデルアーティファクトをログに記録できます。

コード例

```
# Also autoinstruments tf.keras
import mlflow.tensorflow
mlflow.tensorflow.autolog()
```



Notebook

```
import mlflow.sklearn
mlflow.sklearn.autolog()
```

![スクリーンショット (88).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/1386ee74-b7b6-214f-dd15-f37ae1c81dbe.png)



ランダムフォレストモデルを作成し、使用して、パラメーター、メトリック、およびモデルをログに記録します

```
# Enable autolog()
# mlflow.sklearn.autolog() requires mlflow 1.11.0 or above.
mlflow.sklearn.autolog()

# With autolog() enabled, all model parameters, a model score, and the fitted model are automatically logged.  
with mlflow.start_run():
  
  # Set the model parameters. 
  n_estimators = 100
  max_depth = 6
  max_features = 3
  
  # Create and train model.
  rf = RandomForestRegressor(n_estimators = n_estimators, max_depth = max_depth, max_features = max_features)
  rf.fit(X_train, y_train)
  
  # Use the model to make predictions on the test dataset.
  predictions = rf.predict(X_test)
```



with mlflow.start_run():のコマンドを叩くと、mlflowがstartして、モデル学習が行われる

```
with mlflow.start_run():
```

![スクリーンショット (89).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/d6d84352-d301-0b53-d72a-5abfcbabbfd3.png)



実行コマンドが完了されると、Experiment Runsサイドバーに実行実験結果が格納される。


![スクリーンショット (90).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/4395e77d-d3ec-738f-911f-73d86c5f8edb.png)


サイドバーに実験結果項目の中で![スクリーンショット (91).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/5a67633f-55c2-e7b9-e57a-997472dc511a.png)こちらのボタンをクリックすると、実験結果の詳細画面に遷移します。


![Inkedスクリーンショット (92)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/cecec251-7ed9-282a-9ba5-56b13fd02a57.jpeg)



実験結果のParameters、Metrics、Tags、Artifactsが表示されている。


![スクリーンショット (93).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/9bfb8b3b-08cf-7275-7beb-8d1d007aefc9.png)




Artifacts内に表示されているMLmodel、conda.yaml、model.pklはファイルをボタンからダウンロードすることが可能。

![スクリーンショット (94).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/817530/bef51e9d-88e9-2c8c-49da-52836bf81b60.png)




参照：
https://docs.databricks.com/applications/mlflow/quick-start-python.html


以上がDatabricksにてモデル学習についてでした。

見ていただき、ありがとうございました。

株式会社メソドロジック

川名智士
ネットワーク構成図 描画調査

## Graphviz の導入

https://graphviz.org/


Mac の場合

```
$ brew install graphviz
==> Downloading https://homebrew.bintray.com/bottles-portable-ruby/portable-ruby-2.6.3_2.yosemite.bottle.tar.gz
######################################################################### 100.0%
==> Pouring portable-ruby-2.6.3_2.yosemite.bottle.tar.gz
==> Tapping homebrew/cask
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
Receiving objects:  82% (450120/548926), 213.99 MiB | 6.41 MiB/s
```

DOT言語
https://graphviz.org/doc/info/lang.html
サンプル
https://graphviz.org/gallery/
言語アトリビュートリスト
https://graphviz.org/doc/info/attrs.html
CKA・CKAD受験前の最終確認

# はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
先日、無事CKAとCKADに合格しましたが、 受験前の最終確認として忘れがちな部分をまとめておきたいと思います。

#1) 既存クラスターにノードを追加する
CKAを受ける方は、kubeadmによるクラスター操作の基本はカバーしていると思いますが、「`kubeadm init`を使わずに新たなノードを追加する方法」は抜けがちでないでしょうか。

* [ノードの追加](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#join-nodes)

#2) ETCDのリストア
リストアについて正確なやり方は公式ドキュメントに載ってないので、試験前にやり方を覚えておきましょう。

* [Restoring a cluster](https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/recovery.md#restoring-a-cluster)

#3) userの新規作成
rolebindingを使ってroleとuser/saを紐付けることはよくやりますが、「userを作る」部分はちょっと抜けがちに感じます。

* [Normal user](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user)
* [Kubernetesでユーザを作成する（X509 Client Certs編）](https://qiita.com/knqyf263/items/aefb0ff139cfb6519e27)

#4) kubectl get の出力方法
jsonpath / custom-columes / sort-byなどの出力には慣れが必要です。

* [JSONPath Support](https://kubernetes.io/docs/reference/kubectl/jsonpath/)
* [Sorting list objects](https://kubernetes.io/docs/reference/kubectl/overview/#sorting-list-objects)
* [Custom columns](https://kubernetes.io/docs/reference/kubectl/overview/#custom-columns)

#5) podとserviceのDNSレコード
クラスター内からnslookupする際など、podおよびserviceのDNSレコードが必要です。

* [ServiceとPodに対するDNS](https://kubernetes.io/ja/docs/concepts/services-networking/dns-pod-service/#%E3%82%A4%E3%83%B3%E3%83%88%E3%83%AD%E3%83%80%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)

#6) プライベートレジストリからdockerイメージを取得する
secretの特殊な使い方を覚える必要があります。

* [Docker config Secrets](https://kubernetes.io/docs/concepts/configuration/secret/#docker-config-secrets)
* [Create a Pod that uses your Secret](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret)

#7) HPAの使い方
deploymentやreplicasetのオートスケール方法です。合わせて `kubectl autoscale`コマンドも覚えておくと便利です。

* [Autoscaling on multiple metrics and custom metrics](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics)
* [kubectl autoscale](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#autoscale)

#8) カスタムスケジューラーを使う
あまり使用場面はありませんが、特定のpodをスケジューラーとして使う設定です。

* [Specify schedulers for pods](https://kubernetes.io/docs/tasks/extend-kubernetes/configure-multiple-schedulers/#specify-schedulers-for-pods)

#その他
##受験環境について
受験の環境は複数のクラスターやノードを操作することになり、少し戸惑うかもしれません。
こちらの記事で予習しておきましょう。

* [Exam Experience: Certified Kubernetes Administrator (CKA)](https://www.kubernative.net/de/17-tutorial/69-exam-experience-cka)

##基本問題のおさらい
基本問題について下記記事でチェックしておきましょう。

* [Practice Enough With These 150 Questions for the CKAD Exam](https://medium.com/bb-tutorials-and-thoughts/practice-enough-with-these-questions-for-the-ckad-exam-2f42d1228552)
expressの開発にTypeScriptを利用する


expressをTypescriptで開発する方法のメモ。
nodeをTypeScriptで利用する基本的方法は[こちら](https://qiita.com/zaburo/items/0d47b3c8588bb3f96353)をどうぞ。


## 準備

### 場所の準備

```bash
mkdir ts-express-test
cd ts-express-test
```

### 必要なモジュールのインストール（Typescript使うため）

tsc, ts-nodeをインストールして、tsconfig.jsonも生成しておきます。

```bash
npm init -y

npm install -D typescript
npm install -D @types/node
npm install -D ts-node

npx tsc --init
```

### expressのインストール

expressとtypesをインストールします。


```bash
npm install express
npm install -D @types/express
```

## 実装

色々実装です。とりあえず実装用のファイルを作成。

```bash
touch index.ts
```

index.tsに以下の記述をします。とりあえずGETだけ実装。
[ここ](https://qiita.com/zaburo/private/347b1288920741d49289)で利用したAPIを再利用。

```ts:index.ts
import express from 'express'
const app: express.Express = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))

//CROS対応（というか完全無防備：本番環境ではだめ絶対）
app.use((req: express.Request, res: express.Response, next: express.NextFunction) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "*")
    res.header("Access-Control-Allow-Headers", "*");
    next();
})

app.listen(3000, () => {
    console.log("Start on port 3000.")
})

type User = {
    id: number
    name: string
    email: string
};

const users: User[] = [
    { id: 1, name: "User1", email: "user1@test.local" },
    { id: 2, name: "User2", email: "user2@test.local" },
    { id: 3, name: "User3", email: "user3@test.local" }
]

//一覧取得
app.get('/users', (req: express.Request, res: express.Response) => {
    res.send(JSON.stringify(users))
})
```

## 実行と動作確認

では動作確認。

### 実行

expressの実行は下記の通り。

```bash
npx ts-node index.ts
```

とりあえずcurlで動作確認。

```bash
curl -s -X GET http://localhost:3000/users | python -mjson.tool

[
    {
        "email": "user1@test.local",
        "id": 1,
        "name": "User1"
    },
    {
        "email": "user2@test.local",
        "id": 2,
        "name": "User2"
    },
    {
        "email": "user3@test.local",
        "id": 3,
        "name": "User3"
    }
]
```
Next.jsをはじめる

[Next.jsチュートリアル](https://nextjs.org/learn/basics/create-nextjs-app
)に沿って進める。まず以下のコマンドを実行する。

```sh
npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn-starter/tree/master/learn-starter"
cd nextjs-blog
npm run dev
```

そしてブラウザでlocalhost:3000を開けば、最初のNext.jsアプリが起動する。

あとは、必要なだけチュートリアルを続ければよい。 -> https://nextjs.org/learn/basics/create-nextjs-app/editing-the-page

## 環境
- MacBook Pro (16-inch 2019)
- macOS Catalina 10.15.7
nodeをTypeScriptで利用する


フロントエンドはだいたいTypescriptに書くのが普通になってきたので、次はバックエンドも。

## 準備

まずは準備。

### 作業場の作成


```bash
mkdir ts-test
cd ts-test
npm init -y
```

### 必要なモジュールインストール

必要なモジュールをインストールします。ポイントはts-nodeのインストールです。
ts-nodeはjsのトランスパイルなしにtsコードを実行してくれます。

```bash
npm install -D typescript
npm install -D @types/node
npx tsc --init

npm install -D ts-node
```

> -Dは--save-devと同義。tsc --initでtsconfig.jsonも生成しておきます。

## 実装

まずファイルを作ります。

```bash
touch index.ts
```

実装します。簡単なコードです。

```ts:index.ts
const hello = (message: string): void => {
    console.log("message is " + message);
}

hello("hoge");
```

## 実行

ts-nodeで実行します。

```bash
npx ts-node index.ts

message is hoge
```

>npxは./node_modules/.bin/ts-nodeと同義です（そこになければ一時的にインストールされ実行されます）

## おまけ

### 一度jsにトランスパイルしてから実行

ts-nodeがなければ一度、tscでトランスパイルしてindex.jsを生成してから実行します。

```bash
npx tsc index.ts
node index.js

message is hoge
```
mongoコマンドでError: couldn't connect to server 127.0.0.1が出た時の話

#はじめに
Node.jsの環境構築でMongoDBを接続しようとしていた時に起こったエラーの解決方法の忘備録です。
Macでの開発です。

#エラー内容
```
% mongo
MongoDB shell version v4.4.3
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:374:17
@(connect):2:6
exception: connect failed
exiting with code 1

```

#解決方法
まず参考記事のようにbrew search <パッケージ名(フォーミュラ名)>を入力してみる。

```
brew search mongodb 
```

###結果

```
==> Formulae
mongodb/brew/libmongocrypt               mongodb/brew/mongodb-community@3.6
mongodb/brew/mongocli                    mongodb/brew/mongodb-community@4.0
mongodb/brew/mongodb-community ✔         mongodb/brew/mongodb-community@4.2 ✔
mongodb/brew/mongodb-community-shell     mongodb/brew/mongodb-database-tools ✔
mongodb/brew/mongodb-community@3.2       mongodb/brew/mongosh
mongodb/brew/mongodb-community@3.4
==> Casks
gcollazo-mongodb
mongodb-compass
mongodb-compass-isolated-edition
mongodb-compass-readonly
mongodb-realm-studio
mongodbpreferencepane
nosqlbooster-for-mongodb
homebrew/cask-versions/mongodb-compass-beta
```
ターミナル上で直前にインストールしたパッケージが__太字__(上記のコード上では__チェックマーク__がついてます)になっていた。
→ここでこのパッケージ群がちゃんとインストールされていない可能性に気づく


そして着目すべきは↓

```
homebrew/cask-versions/mongodb-compass-beta
```



どうやら`homebrew/cask-versions`のパッケージ情報を更新すれば良いみたいなので下記のコマンドを入力する。

```
brew tap homebrew/cask-versions
```


###結果

```
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
Updated 12 formulae.
==> New Casks
parsify
==> Updated Casks
Updated 4 casks.

==> Tapping homebrew/cask-versions
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask-versions'...
remote: Enumerating objects: 34, done.
remote: Counting objects: 100% (34/34), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 231898 (delta 16), reused 9 (delta 6), pack-reused 231864
Receiving objects: 100% (231898/231898), 59.59 MiB | 2.07 MiB/s, done.
Resolving deltas: 100% (159718/159718), done.
Tapped 175 casks (210 files, 66MB).
```

この後mongoコマンドを入力するとMongoDBが立ち上がり、エラー解決。



#参考
[brew installでError: No available formulaが返るとき](https://qiita.com/Feel-Physics/items/98b4aacbd6e52a2bde2e)
Django-make_user automatically when we make account


accountを作るときにuserを作りたくない→read_onlyのfieldsに作り替える

```python:serializers.py
class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'user', 'fb_token', 'ig_token']
        read_only_fields = ['user']
```
↓

```python
class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'user', 'fb_token', 'ig_token']
        read_only_fields = ['user']
```

このままだとユーザーがないのでエラーが発生してしまう。→「MelolSerializer」の定義にとびcreateをとってきてuuidをインポートして名前を自動生成する

```python
    def create(self, validated_data):
        #usernameを自動生成する
        user = User(username=str(uuid.uuid4()))
        #userを保存
        user.save()
　　　　　#accountモデルを取得
        account = Account()
　　　　　accountのuserを指定
        account.user = user
　　　　 #入力させてたfb_tokenをaccountのfb_tokenに入れる
        account.fb_token = validated_data['fb_token']
        account.ig_token = validated_data['ig_token']
        account.save()
        return account
```
[iOS] ipaファイル内のFrameworkを閲覧する

# はじめに
iOS14対応のIDFAに関して、`AppTrackingTransparency.framework`を内包した場合、トラッキングの許可を求めるダイアログは必ず出さなければならないようです。よって、このFrameworkを取り除くことにしましたが、Xocdeの`Build Phase`->`Link Binary With Libraries`にも`AppTrackingTransparency.framework`はありませんでした。
では、ipa内包の中身もみてみようということで見方は下記にまとめました。

## otoolを使用
`otool`コマンドは、実行ファイルやライブラリのオブジェクトファイルを分析し、結果を表示するコマンドです。

```
otool option FileName
```
|option  |detail  |
|--------|--------|
|-L      |指定したファイルが使用する共有ライブラリを表示する  |
|-M      |ダイナミックリンクライブラリのモジュールを表示する  |
|-f      |ユニバーサルバイナリの情報ヘッダを表示  |

## ipaファイルについて
該当の`ipa`ファイルの拡張子を`zip`にします。
zipを解凍すると`Payload`ディレクトリができますので、中身を`otool`で閲覧します

```
otool -L Payload/sample.app/sample
```

```
atsutama ~/Downloads$ otool -L Payload/sample.app/sample                  
Payload/sample.app/sample:
	/usr/lib/libc++.２.dylib (compatibility version 2.0.0, current version 910.2.0)
	/usr/lib/libsqlite３.dylib (compatibility version 10.0.0, current version 421.4.0)
	/usr/lib/libz.３.dylib (compatibility version 1.5.0, current version 2.2.31)
・・・
```

これでFramework一覧が閲覧できます。
Rubyで文字列を反転させる（reverseあり・なし）

Rubyで文字列を反転させるプログラムを書きます。


```reverse.rb
str = "123456789"
reversed_str = ""
str_size = str.length.to_i

while str_size > 0 do
  reversed_str << str[str_size - 1]
  str_size -= 1
end

puts str
puts reversed_str
```


```:実行結果
$ruby reverse.rb
123456789
987654321
```

また、Rubyの組み込みライブラリを使っても出来ます。

String#reverse
文字列を文字単位で左右逆転した文字列を返します。

```
p "foobar".reverse   # => "raboof"
p "".reverse         # => ""
```

参考：[String#reverse (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/String/i/reverse.html)
AWS EC2へsshでのログインができなくなった時の対処法

# 結論
ec2インスタンスの再起動で解決できた

# 解決までの道のり

### なんでログイン出来なくなった?

ec2内にアプリケーションをコンパイルしているときに、時間がかかりすぎて、途中でサーバーがタイムアウトになった。
↓
再度sshログインしてみる
↓
動かないままタイムアウトしてしまう。

### とりあえずデバックモードで起動してみた

-vをつけると、デバックモード

```
% ssh 自分のkey -v
```

```
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /Users/wadakazuma/.ssh/config
debug1: /Users/wadakazuma/.ssh/config line 1: Applying options for key_berlin_now_rsa
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
debug1: Connecting to hogeip port 22.
debug1: Connection established.
debug1: identity file /Users/wadakazuma/.ssh/key_berlin_now_rsa type 0
debug1: identity file /Users/wadakazuma/.ssh/key_berlin_now_rsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.1
```

なんかでた

```
kex_exchange_identification: read: Connection reset by peer
```


### 色々いじくってみた


#### ・githubはssh接続できる

```
ssh -T git@github.com
Hi kazumawada! You've successfully authenticated, but GitHub does not provide shell access.
```

#### ・ec2インスタンスを確認してみる[参考](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/TroubleshootingInstances.html#troubleshooting-retrieve-system-logs)
インスタンスのステータスチェック欄が赤くなっていた
↓
インスタンスの接続性チェックに失敗しました(1/2のチェック)
↓
[インスタンスのステータスチェック](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/monitoring-system-instance-status-check.html)
[インスタンスの復旧](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-recover.html)
↓
一旦用事があったので、2hほど離れたところ、インスタンスのステータスチェックに合格していた。(2/2)が、まだssh接続ができない。
↓
<strong>とりあえずec2インスタンスを再起動してみる
↓
sshログインできた</strong>

## まとめ

僕の場合は、ec2インスタンスの再起動で解決できたのでこれ以上深追いはしませんが、他の方法はこことかみるといいかもしれません
https://dev.classmethod.jp/articles/ope20190813-ec2-trouble/
https://dev.classmethod.jp/articles/why-ec2-statuscheck-failed/
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/monitoring-system-instance-status-check.html
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/automation-ec2rescue.html
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-recover.html
Dockerを初心者なりに分かりやすく語る①(Dockerfile/docker-composeに至るまで)

<br>
Dockerの細かな原理は詳しくわかってないですが、Dockerの機能をある程度カバーしつつ、最終的にコンテナを複数組み合わせた何かを作ってみようと思います。今回はDockerの概要・仕組みに留めておきますが、次回以降、Dockerfile・docker-composeを活用して、サーバーの分割やディレクトリ共有などを記載していきます。多分このシリーズを全部読めばDockerが何なのかわかると思います（多分）。
#目次
[1.Dockerの概要](#1-概要)
[2.仕組み](#2-仕組み)
[3.次回以降の実装について](#3-次回以降の実装について)
#1.概要
###1.1 Dockerってなに？？
Dockerを理解するにあたって、重要なのは<b>&nbsp;イメージ（image）&nbsp;</b>と<b>&nbsp;コンテナ（container）&nbsp;</b>の概念です。一言で言って仕舞えばコンテナは一つのコンピュータみたいなものです。そしてそのコンピュータはイメージという設計書に従い、<b>Docker Engine</b>によって貴方のPC上で作成されます。すなわち仮想化を意味しており、Dockerについて調べておられるならこの画像を目にしていると思います。一つ一つのコンテナはカーネルを共有しつつも、カーネル技術によって独立性が維持されます。これを「隔離された環境（isolated environment）」と言うそうです。
<div align="center">
<img width="300" alt="コンテナ画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692354/cf007b19-8667-ed18-c82a-6f8be7ff1337.jpeg"/>   
ちなみに、DockerはLinuxのカーネルをもとに作成されているので、Windows/MacOS環境下では、Linux仮想環境(Hyper-Vなど)がOSの上に敷かれることになります。
<img width="300" alt="コンテナ画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692354/e9a28aa2-e485-f7b1-b549-a5f4076857d2.jpeg"/>   
個人的な解釈ですが、イメージを実行状態にしたものがコンテナなので、javaで言えばクラスとインスタンスみたいな感じですよね。
</div>
###1.2 Dockerのうまみ
では、この<b>「コンテナによる仮想化」</b>の何が便利なのでしょうか。アパレル店員と塾講師のアルバイト経験しかない私からすれば、実際の業務にどう使うのかは存じませんが、次の三つがあるように思われます（独断）。
<ol><b><li>どのPCでもすぐに同じ実行環境が生成できる</li></b>[Docker Hub](https://hub.docker.com/)　にはたくさんのイメージが公開されています。例えば授業で「生徒全員にこれを実行して欲しい。でも環境構築がめんどくさいし、それだけで授業が終わる！！」と教授が思った時、imageをみんなに共有すれば、コンテナ上に環境を展開できます（Dockerを入れてもらう必要がありますが、、）。
<b><li>サーバ・データベースなど使い道によってコンテナを分ければ、再利用性が上がる！</li></b>一方はサーバ、他方はデータベースのようにプロセス毎にコンテナを分けることで、別のアプリケーションにプロセスを流用しやすくなります。これもオブジェクト指向って感じですね。
<b><li>（後述する）docker-compose, Dockerfileを使えば、イメージからコンテナの作成まで、何個でも一瞬でできちゃう</li></b>docker-composeでは各イメージのプロパティを記載します。ポートの割り当て、OSの設定、Dockerfileへのパスなど、、、そしてDockerfileには、作成されるベースイメージに加えてパッケージのインストール、環境変数の設定などを記載することで、これを配布さえすればまとめてイメージ・コンテナを作成できます。</ol>

全然網羅していないと思いますが、dockerってこんな感じだと思います。違ったら教えてください。

#2.仕組み
頑張って描いた下の画像が全てを語っています。
<img width="600" alt="コンテナ画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692354/44586a80-03e5-f814-b433-4588f5f0c135.jpeg"/>   
####①クライアント
ユーザはCLIを使って<b>dockerコマンド</b>を打ちます。`docker pull・・・`でイメージをダウンロードしたり、`docker build`でイメージを構築、 `docker-compose up -d`でdocker-composeの実行を制御します。
####②ホスト
ホスト(デーモン)は、クライアントからのリクエストに対し、実際にDocker Hubからイメージを持ってきたり、コンテナの管理を行います。クライアントとデーモンはリモートでも、同じPC上に同居させても大丈夫です！！
####③レジストリ
Docker Hubがそれに当たりますが、`docker run`や `docker pull`コマンドによってレジストリから必要なイメージを取り出せます。
#3.次回以降の実装について
次回以降、実際にDockerをインストールし、イメージ・コンテナの作成、docker-compose.ymlやDockerfileの記述方法について述べていきたいと思います。最終的にはSpringBootを利用したサーバと、データベースにコンテナを分けたwebアプリを作ります。
#4.参考文献
Dockerの概要：https://docs.docker.jp/get-started/overview.html#docker-architecture
Dockerとは何か？初心者にも分かりやすくメリットや仕組みを解説：https://kitsune.blog/docker-summary
[HEROKU] heroku run rails db:migrate できなかったときの対処

git push heroku masterで本番環境にデプロイ後での、データベース作成の際に生じたエラーに関する記事です。

#環境
ruby 2.6.5
rails 6.0.0
db mysql2
Github

#エラーの経緯

本番環境にデプロイ後、heroku run rails db:migrateを行うと

```terminal
rails aborted!
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

というエラーが発生。

#手順

結論としては、DATABASE＿URLが間違っていました。

以下、解決した手順を記載いたします。

１、ターミナルにて以下を実行
＊この時、Created~となればオッケーです

```terminal
heroku addons:add cleardb
```

２、次に現在のDATABASE＿URLを確認します。
＊下記のように表示されるはずです。
CLEARDB_DATABASE_URL:     mysql://[あなたのURL]

```
heroku config | grep CLEARDB_DATABASE_URL
```

3、先ほど表示させたURLを変更します
mysql →mysql2

```
heroku config:set DATABASE_URL=mysql2://[あなたのURL]
```

しかし、ここで私はエラーが発生しました。
理由としては、URLの両端にクウォーテーションマークを使用していなかったからだと思います。皆さんは忘れないようにしましょう。。

気を取り直し再度入力

```
heroku config:set DATABASE_URL='mysql2://[あなたのURL]'
```

４、変更が完了したら、本番環境にデータベースを作成しましょう。

```
heroku run rails db:migrate
```

エラーが発生しなければ完了です。

#まとめ
自分がいまどんな環境で、アプリを制作しているかをちゃんと理解していれば防げたエラーです。
同じところでつまづいた方の参考になればと思います。

#参考記事
https://qiita.com/koukidesu/items/2115a50569e6519832da
M1 Macで古いdockerイメージ使おうとしたら"no matching manifest for linux/arm64/v8"が出た時の対応

とある事情でM1 Macでcentos6を動かそうとしたらエラーになった時の対応メモ

```
docker: no matching manifest for linux/arm64/v8 in the manifest list entries.
```

# TL;DR;

対応しているplatform指定してpullしてあげる。

```
docker pull --platform linux/amd64 centos:centos6  
```

mysqlの場合

```sh
docker pull --platform linux/amd64  mysql:5.6
```

あとはいつも通りの `docker run xxx` で動く。

# 背景

- 諸事情によりcentos6のイメージを使いたかった
- 最近のはちゃんとarm64v8のイメージが公開されてるけど、古いのは放置されている。(そりゃそうだw)
- dockerには他のcpuアーキテクチャのイメージをエミュレートする機能がついている。
- 一旦それに甘える


オフィシャルイメージのmanifestはこの辺にありました。
https://github.com/docker-library/official-images/tree/master/library


# 参考

https://docs.docker.com/docker-for-mac/apple-m1/
Nest.js の使い方

次のページを参考にしました。
[Overview](https://docs.nestjs.com/cli/overview)
[Nestjsをローカルで動かしてみる](https://wp-kyoto.net/try-nestjs-in-local/)

インストール

```bash
sudo npm install -g @nestjs/cli
```

プロジェクトの作成と起動

```bash
nest new -p npm my-nest-project
cd my-nest-project
npm run start:dev
```

クライアントでアクセス

```text
$ curl http://localhost:3000
Hello World!
```

ソースを改造

```src/app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
        var str_out = 'こんにちは'
    return str_out
//    return 'Hello World!';
  }
}
```

クライアントでアクセス

```text
$ curl http://localhost:3000
こんにちは
```

GET の API を作成

```js:src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('ping')
  myCustomAPI(): {message: string} {
    return {
      message: 'Hello Everybody!'
    }
  }
}
```

クライアントでアクセス

```text
$ curl http://localhost:3000/ping
{"message":"Hello Everybody!"}
```

もう少し複雑な値を返してみます。

```js:src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('ping')
  myCustomAPI(): {message: string} {
    return {
      message: 'Hello Everybody!'
    }
  }
  
  @Get('books')
  get_books_proc(): {id: string; name: string; author: string;}[] {
  const books = [
    {id: 't101', name: '草枕', author: '夏目漱石' },
    {id: 't102',  name: '走れメロス', author: '太宰治' },
    {id: 't103', name: '千曲川のスケッチ', author: '島崎藤村' },
    {id: 't104', name: '高瀬舟', author: '森鴎外' }
]
    return books
  }
}
```

クライアントでアクセス

```text
$ curl http://localhost:3000/books | jq .
[
  {
    "id": "t101",
    "name": "草枕",
    "author": "夏目漱石"
  },
  {
    "id": "t102",
    "name": "走れメロス",
    "author": "太宰治"
  },
  {
    "id": "t103",
    "name": "千曲川のスケッチ",
    "author": "島崎藤村"
  },
  {
    "id": "t104",
    "name": "高瀬舟",
    "author": "森鴎外"
  }
]
```

次のバージョンで確認しました。

```text
$ node --version
v17.3.0
$ nest --version
7.5.4
```
単体テストコード：imageが必須であることのテストコードが通らない時の対処方法

```spec/models/item_spec.rb
it 'imageが必須であること' do
    @item.image = nil
    @item.valid?
    expect(@item.errors.full_messages).to include ("Image can't be blank")
  end

  it "登録名が必須であること" do
    @item.name  = ""
    binding.pry
    @item.valid?
    expect(@item.errors.full_messages).to include ("Name can't be blank")
  end
```
単体テストコードのimageテストでは、

```@item.image = ""```のダブルクオーテーションという概念がない。""の記述にすると、https://gyazo.com/b89f642c7e2adfd3cdab491aac65bb32
というエラーが現れる。

```@item.image = nil```nilに記述を変更すると、https://gyazo.com/a272f1b8e2c47e8e334b4c237207285a
となりテストが成功する。

結論：画像（image）が必須であること　というテストコードには””の概念がないので、nilを使用すること。
Chartkickを使って、グラフを作成してみた

## はじめに
Chartkickというgemを使うと、簡単にグラフが作れてしまうらしいので、実験的に使ってみる事に。

## 環境
Ubuntu16.04.7 LTS
Windows10 + Vegrant
Rails 5.2.4
Ruby 2.5.1

## 手順

Gemfileに２つのgemを追加します。

```Gemfile
gem 'chartkick'
gem 'groupdate'
```

```
$bundle install
```

application.jsに２つのjsを追加します。

```application.js
//= require chartkick
//= require Chart.bundle
```

適当にコントローラを作成します。show1とshow2と２つメソッドを作成したのは、それぞれ異なるグラフを表示させるためです。

```
$rails g controller asagaos index show1 show2
```

適当にモデルを作成します。（朝顔の成長記録を想定したデータを登録するため、このようなモデルにしました）

```
$rails g model asagao jyotai:string take:integer ymd:date
$rails db:migrate
```

rootを設定します。

```routes.rb
get 'asagaos/show1'
get 'asagaos/show2'
root 'asagaos#index'
```

seedにテストデータを作成します。

```seed.rb
Asagao.destroy_all

require "date"
_todate = Date.today

30.times do |n|

    _jyotai = case n 
        when 0..10 then  "種"
        when 11..20 then "葉"
        when 21..30 then "花"
    end

    _ymd = _todate + n

    Asagao.create!(
        jyotai: "#{_jyotai}",
        take: "#{n + 10 }",
        ymd: "#{_ymd}"
    )
end
```

テストデータを流します。

```
$rails db:seed
```

コントローラをこのように記述します。

```controller/asagaos_controller.rb
class AsagaosController < ApplicationController
    def index
        @asagaos = Asagao.all
    end

    def show1
    end

    def show2
    end
end
```

indexビューをこのように記述します。

```view/asagaos/index.html.erb
<h1>朝顔の成長記録</h1>

<%= link_to 'グラフ１', asagaos_show1_path %>
<%= link_to 'グラフ２', asagaos_show2_path %>
<br>

<table>
  <thead>
    <tr>
      <th>状態</th>
      <th>丈</th>
      <th>日付</th>
    </tr>
  </thead>

  <tbody>
    <% @asagaos.each do |a| %>
      <tr>
        <td><%= a.jyotai %></td>
        <td><%= a.take %></td>
        <td><%= a.ymd %></td>
      </tr>
    <% end %>
  </tbody>
</table>
```

棒グラフを表示させる記述です。

```views/asagaos/show1.html.erb
<h1>Asagaos#show1</h1>
<p>Find me in app/views/asagaos/show1.html.erb</p>

<%= link_to '一覧', root_path %>
<br>
<%= column_chart Asagao.group_by_day(:ymd).sum(:take), id: "column-chart", width: "800px", height: "500px" %>
```

円グラフを表示させる記述です。

```views/asagaos/show2.html.erb
<h1>Asagaos#show2</h1>
<p>Find me in app/views/asagaos/show2.html.erb</p>

<%= link_to '一覧', root_path %>
<br>
<%= pie_chart Asagao.group(:jyotai).count %>
```

実行します。

```
$rails s
```

index画面でテストデータを一覧表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/139b67b7-e7b4-59bc-e5d2-361dd0489ad3.png)

グラフ１を表示させると、このようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/88133d28-f73f-97a7-9b83-2bae3ccd374e.png)

グラフ２を表示させると、このようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/586b9957-3948-52e0-361b-a958cca1bdd8.png)


## 参考URL
https://techtechmedia.com/chartkick-graph-rails/
mdadmの通知設定

mdadmでraid情報をメールで受け取る方法の覚書。

[この記事](https://qiita.com/StarChun/items/e784b03c22a2b2de9802)
でpostfixを使いgmailでメールを送るよう設定しました、さらに
[この記事](https://qiita.com/StarChun/items/7c949cffd5896f336396)
でmdstatを見てエラーが発生していたらメールを通知する設定を行いました。

でもそんなイレギュラーな方法ではなくてpostfixの設定が出来ていれば普通にmdadmの管理機能でメール通知が届くので、これを使うことにしました。
一日一通とかなら許容範囲ですし、正常に動作していることも分かりますしね。

というわけで
`/etc/mdadm/mdadm.conf`

に

~~~
MAILADDR user@hoge.com
~~~
とメールの宛先を追加して

~~~shell:/etc/cron.d/raid_chk
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
10 0 * * *      root  /sbin/mdadm --monitor --scan -1 --test
~~~

というファイルをcron.dの下に追加します。
以上で設定完了、指定した時間にメールが飛んできます。
仮想マシンの目指してた未来とコンテナーの現在

# ここで書いていないこと(はじめの前に)

タイトルから、[VMWare](https://www.vmware.com/jp.html)/Hyper-V/KVMやクラウドの仮想マシンと、コンテナーの比較の記事に見えるかもしれないが、ここで書く仮想マシンはJava仮想マシン、.Net仮想マシン(CLR)を扱う。

# はじめに

現在はコンテナーのブームであることはご存知だと思う。それはコンテナー・オーケストレーションであるKubernetesの登場で決定的になった。
コンテナーが目指していたことは、他の仮想マシンでも目指していた思想と一致する部分がある。
本記事ではそういうコンテナーで実現できたものと、過去の仮想マシンとの比較を記事にする。

# コンテナーの目指しているもの

コンテナーはImmutable Infrastructureという考え方のもと、ポータビリティーのあるイメージを配布する仕組みをもつ。
このポータビリティーはコンテナが好まれる性質のひとつである。

過去の仮想マシンでもこのポータビリティーは大きな目標であったが、コンテナーほど大きなムーブメントにはならなかったように思う。
本記事ではそのあたりの歴史から、コンテナー・ブームを紐解く。

# Java仮想マシン (第一章) - 最初に商用的に成功した仮想マシン

90年代半ばにインターネットのブームの中で、Sun MicrosystemsはJava言語を発表する。
その次代は、オブジェクト指向言語のブームの真っ只中で、Java言語はオブジェクト指向言語を、しかも、当時は珍しく無料で配布を配布を始めた。

JavaはどのOSでも動くという意味合いで、Write Once, run anywhere という標語も使った。Javaでコンパイルされた中間言語は、Java仮想マシンが動作するOSであれば、どれでも稼働した。

初期(第一章)のJava仮想マシンの成功に向けた推進には、後にJavaの衰退の起因のひとつが含んでいた。それはあくまでJava言語のみでコンパイルできることに拘ったことだ。

# .Net

当時Microsoftは自社の技術に非常に拘っていて、Java言語の普及に対して、自社のソリューションを提供したいと考えていた。
そこで登場をしたのが.Netである。

.NetはCLR(Common Language Runtime)と呼ばれる仮想マシンのもとで稼働する意味では、Java仮想マシンと似ていた。
ところが、それ以外の戦略はJava仮想マシンとは別の方向を目指した。
 
- 言語は、Visual Basic .Net、C#、JScript .Net、F#など複数言語に対応させた。
- (当初は)実行環境はWindowsに限定した。

この言語の面で、ニュートラルな性質からPythonやRuby等多言語に対する.Netコンパイラも開発された。(IronPython、IronRuby)

多言語に対応する仮想マシンという意味合いでは、Java仮想マシンは、遅れている印象を与えた。

# Java仮想マシン (第二章) - 多言語への対応

Javaは.Netの登場で、多言語化に向けて舵を切る。
特に2000年代半ばから、Webの開発にRuby on Railsのブームが始まり、軽量プログラミング言語 (LL) が大きくフォーカスされた。

必要に応じて、Java仮想マシンのスペックも拡張した。

PythonやRubyに対してはJythonやJRubyが登場した。
また、Java仮想マシン独自の言語もGroovy、Scala、Kotlin、Clojure等、現れた。

Kotlinは後にスマートフォンであるAndroidの推奨開発言語になるなど、一定の成功は収めたと思われる。

# Java仮想マシン/.Net仮想マシンの現在

Java仮想マシンも.Net仮想マシンも、現在でも広く使われている。
現在のステータスとしては以下であると思われる。

- Java仮想マシンはいまだエンタープライズ・エリアやAndroideで多く使われている。
- .Net仮想マシンもWindowsでの開発ではいまだ多く使用されている。MicrosoftのCEOがナデラになって以降、Linuxへの対応にも注力しているが、十分に成功しているとは言えない。
- RubyやPython等のOSSの言語への対応に関してはいずれも開発が止まる/停滞する状態で、Java/.Netとも失敗したと言ってよい。これはRubyやPythonの言語の方向性と、こういった仮想化技術とが相容れなかったのだろうと推測する。

# コンテナーの現在

その中、コンテナーが現れた。コンテナー技術を、上記の仮想化技術と比べてみる。

- コンテナーはLinuxで動く言語であれば、言語を問わない。
- コンテナーで作成したイメージは(Linuxで、かつ、CPUが同一であれば)どの環境でも動く。
- コンテナーを仮想化技術ということもあるが、仮想マシンとは異なり、中間言語を変換しながら仮想させるのではなく、ネイティブ・バイナリーが稼働する。
- コンテナーはLinuxの技術のため、あらゆる環境(OS)で稼働する技術ではない。(Windowsコンテナーという技術もあるが、あまり使用されてないので、本記事では無視する)

最後のLiunxでのみ稼働という点は、コンテナー技術の大きな弱点のひとつではある。WindowsやMac でのコンテナー稼働も、Hypervisorでの別環境でLinuxを動かして、実現している。
また、コンテナーのイメージはネイティブで稼働する性質上、CPUを選ぶ。これまではx86-64が主流だったが、MacBookのM1等、ARMもあり、実際は、複数CPUへの対応は難しい問題でもあると思われる。

上記のような弱点もあるが、Javaや.Netが中間言語への変換を考えることを比べると、Linuxで動く言語であれば、何でも稼働することは非常な利点がある。

このようにJavaや.Netで目指していたあらゆる言語での実行環境のポータビリティーはようやくコンテナーの登場で実現したと言える。

今後のことも考えると、コンテナーにフォーカスすることは正しい選択であるだろう。










・
【Rails】Deviseメール文面の変更が反映されない時の対処法

# 結論

以下のコメントアウトを外して、「true」にする

```ruby:config/initializers/devise.rb
  # config.scoped_views = false
  config.scoped_views = true
```

# これで解決する理由

（※解決しない人は、これに当てはまっていない可能性があります。）

- Deviseにnamespaceを設定していた（devise/`users`/mailer）
- Deviseはデフォルトで「devise/mailer」以下のメール文面を見に行く
- 上記の記述を書くことで、namespaceを認識するようになる
LINEリッチメニューの開発方法

#リッチメニューとは
>「LINE公式アカウントの機能の一つ「リッチメニュー」は、トーク画面の下部に大きく表示されるメニューです。画面を大きく占有するためユーザーの注意を引きやすいほか、クリエイティブとともにリンクを設定することで予約ページやECサイトなどにユーザーを誘導することができます。」
LINE for Business(https://www.linebiz.com/jp/column/technique/20180731-01/) より引用

ざっくり言うとユーザーができる行動をテキストでやりとりするのではなくリッチメニューで
表示されているボタンを押すことで簡単に利用することできるようになるということで、どうやらbotに
導入することでより便利になりそうな予感です。
この回では、個人的なメモと他に同じようにpythonでLINE messaging APIでリッチメニューを開発したい！と
考えている方の何かヒントになればという話を書きます。

#本編
まず初めに、今回この記事を参考にリッチメニューを作成しました。
[LINE Messaging APIのリッチメニューをPythonで操作する](https://qiita.com/uezo/items/2dd9db3046ef7b28ed2e)

だいたいはこの記事通りに作成していくと問題なくリッチメニューを作成することができます。
ここから苦戦したことは、
・どのように連携させるかがわからない
・json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)が発生してしまいリッチメニューの登録を行うことができない

ということが大きく分けて2つありました。

##どのように連携させるかがわからない
参考にさせてもらった記事通りにソースコードを書き、これまで作成してきたbotのソースコードに追記して
リッチメニューが使えるようになるものだと思っていました。ですが、デプロイしてみるとHTTPリクエストを同時に実行することができないと言うことで、エラーが出てしまい、bot自体も動かなくなってしまいました。
解決策としては至極簡単で、リッチメニューを登録するためのソースコード単体で実行すると言うことでした。

##json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
エラーの内容を見るにどうやらjson形式でリクエストに渡しているものが怪しいですね。
そう思い、このエラーの内容やjsonで渡している情報など調べましたが一向に解決せず。
諦めかけた時、公式リファレンスを眺めているとなにやら参考にした記事のリクエストURLが違っていることに気がつきました。どうやら、月日が経つとリクエストURLが変わっているのかもしれません。
ということで、upload_imageメソッド内のURLを以下のように変更。

```
https://api-data.line.me/v2/bot/richmenu/%s/content
```

無事に画像を登録することができました。

特定のユーザーにリッチメニューを登録する方法はget_profileメソッドを使用して、サクッとbotにオウム返し
してもらいましょう。

```
line_bot_api.get_profile(event.source.user_id)
```

#最後に
おそらくここまでの補足と参考の記事で、つまづくことなくリッチメニューの登録ができると思います。
画像の用意などはサイズを揃えないと、いつまで経っても登録できないという点にも注意です！！
Bash: JWT のペイロード部をデコード

```bash:decode_jwt.sh
awk -F. '{print $2}' | base64 -d | jq .
```

使い方

```bash
./decode_jwt.sh < token01.txt
```

実行結果

```text
$ ./decode_jwt.sh < token01.txt
{
  "name": "Scott",
  "iss": "https://securetoken.google.com/example",
  "aud": "example",
  "auth_time": 1612656837,
  "user_id": "abcdhsI5umMnbk8bQ5ULPd6Gbd19",
  "sub": "abcdhsI5umMnbk6bQ5ULPd6Gbd19",
  "iat": 1612656839,
  "exp": 1612660439,
  "email": "aaa@example.com",
  "email_verified": false,
  "firebase": {
    "identities": {
      "email": [
        "aaa@example.com"
      ]
    },
    "sign_in_provider": "password"
  }
}
```

関連情報
[Node.js: JWT のペイロード部をデコード](https://qiita.com/ekzemplaro/items/3e2c1e9cf9189a79b27c)
[Python3: JWT のペイロード部をデコード](https://qiita.com/ekzemplaro/items/e24d6af29ddc01683417)
[Go: JWT のペイロード部をデコード](https://qiita.com/ekzemplaro/items/4c45156238cb4041d847)