OmniAICreator/Qiita-1.07M huggingface dataset:
mysqlがdockerで起動しなかった時の対処法

**今回の現象**
mysqlがdockerで起動しなかった。



#やったこと

1：dockerをcacheを使わず再起動

```
docker-compose build --no-cache
dc up -d
```

2：PCの再起動

3：docker imageを削除

```
dc down 
docker images (image idを確認)
docker rmi [image id] 
```


4：docker のrebuild

```
docker-compose build --no-cache
dc up -d
```

5：logの確認 *** ここが重要でした。

```
docker logs {コンテナ名}
```

6：volume配下を削除

```
rm -rf ./data/mysql/*
```

7：再起動

```
docker-compose build --no-cache
dc up -d
```

8：databaseの作成とmigration



**ベッタープロセス**


一番はじめにアクセスを確認

```
dc ps
```

ステータスがExitだったら

```
dc logs {こんてな名}
```


ログを確認することが大事！なんかあったらログを確認する！

#あとで調べること

```
dc down
```
```
docker-compose build --no-cache
```
```
dc up -d
```
↓参考記事
https://hacknote.jp/archives/47137/
Codesandboxがうんともすんとも言わなくなったときの対応


[Codesandbox](https://codesandbox.io/)。node.jsベースのサーバサイドコードも手軽に実行できるすごくいいサービスなのですが、大きな難点があるため実は最近あまり使わなくなっていました。

それは、

**サーバサイド系は不安定で事実上使い物にならない**

という状態だったからです。

Codesandboxの各種テンプレートでは裏でnodemonが動作しているようで、コードの変更を検知して自動的に状態を更新してくれるのですが、node.jsテンプレートとかで一定の変更を加えると全く反応してくれなくなります。

100歩譲って動かなくなるのはいいのですが、そうなってしまうとそれ以上対応するすべがなくプロジェクトを破棄して新しく作り直すしか方法がなかったのです（しかも、新しいプロジェクトもなにかの拍子に動かなくなるという・・・）。

が、解決方法が見つかったので紹介します。

手順は、下記の通りです。

* 開発ブラウザデベロッパツールを表示しApplicationストレージを削除（Clear site data）
* Codesandboxからログアウト
* 再ログインし、動かなくなったプロジェクトを再起動

こうすることで、（記述したコードにバグがなければ）正しく動くようになります。


![スクリーンショット_2021-08-18_11_42_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/927127e5-6a9c-839d-6d54-cd0077699140.png "スクリーンショット_2021-08-18_11_42_28.png")
数理計画法とは

最近、数理計画法なる学問があることを知った。
昔からあったのだろうが気になり少し調べてたら、結構役に立ちそうなので勉強を始めた。

５０代後半になり、頭がついていかないところもあるが、実践的なところを主題として記録する。

私は専門家ではないので、理論については特に記録しないし、間違った記録もあるかもしれない。

下記のツールを使用しての記録を行う。
（基本的に線形・整数）

①excel
　ゾルバ（標準機能）を使用

②matlab
　Optimize ToolBoxを使用
　Global Optimize ToolBoxを使用

③labview
　線形最適化機能を使用

④python
　PuLPを使用
VPC 「DNSホスト名」の有効化とは

開発用途でVPC外部から接続可能なDBインスタンスをVPC内に立てようとして以下のエラーがでた。（※あくまで開発用途のためパブリックアクセス可能としている。また接続元IPは特定IPに制限する）

```
Cannot create a publicly accessible DBInstance. The specified VPC does not support DNS resolution, DNS hostnames, or both. Update the VPC and then try again
```

調べると、所属するVPCの「DNSホスト名」を「有効化」すると解決できるらしい。
内容としてはドキュメントの[ここ](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html#vpc-dns-hostnames)に書いてある内容。

### プライベートDNSホスト名
 
この形式のアドレスのこと。
`ip-{private-ipv4-address}.ec2.internal`
インスタンスをVPC内に立てると常に割り当てられる。

### パブリックDNSホスト名

この形式のアドレスのこと。
`ec2-{public-ipv4-address}.compute-1.amazonaws.com`
インスタンスをVPC内に立てた時、VPCの設定で「DNSホスト名」と「DNS解決」が有効になっていると割り当てられる。

![スクリーンショット_2021-08-18_11_22_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/1644ed5d-516f-80c4-d846-707f634f6d8f.png)

### 解決方法
デフォルトでは「DNS解決」のみ有効になっていた。
![スクリーンショット_2021-08-18_11_28_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/b2625165-32db-1e34-f7f0-0d9e69aa040a.png)

追加で「DNSホスト名」を有効化。
![スクリーンショット_2021-08-18_11_29_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260824/415e1563-7fec-b2f9-ccc2-afa2f02d2f03.png)
Power Automateで作成したタスクが完了したら、Teamsメッセージに自動で返信をつける

# はじめに
指定のメールがきたのをきっかけに、新規タスク作成とTeamsへのメッセージの投稿をおこなっています。
作業を完了した際、タスクを完了にし、Teamsへのメッセージにも作業完了がわかるように返信をおこなっているのですが、これが面倒なので、タスクが完了したときに返信もしてくれるようなフローを作りました。

# フローの流れ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/895455/e73972b6-7738-1712-f2bc-17c3b3efea66.png)

## 事前準備
指定のメールがきたのをきっかけに、新規タスク作成をする際に、以下の流れでフローを作成します。
1．タスクを作成する
2．メッセージを投稿する
3．タスクの詳細の更新
　 以下のように設定します
　 ・タスクID：1で作成したタスクのID
 　・説明：2で投稿したメッセージのID
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/895455/7346b4fd-fd98-78b3-83fb-b3efb182e1d4.png)

## タスクの詳細を取得する
タスクの詳細を取得することで、事前準備で設定した「説明」部分の情報を取得します

## メッセージへの返信の投稿
「メッセージ」にタスクの「説明」を設定します。
余談ですが、「返信」部分はメンションしたいので<at></at>を使用しています。

以上で完了です。

# その他：タスクが完了したら自動でメールを返信したい！
「タスクの詳細の更新」の際に、「説明」にメールの「メッセージID」を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/895455/c0ed057d-22c8-88f5-565d-2f8e7f7cf68c.png)

「メールに返信する」アクションで、「メッセージID」にタスクの「説明」を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/895455/621ba68b-7d27-50d5-418b-901695430bf6.png)

このアクションはデフォルトが「重要度：低」なので、「詳細オプション」で重要度を確認したほうが良いです。通常の重要度が「Normal」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/895455/bcf3fd85-2add-1da0-6274-ddcc1f33719d.png)

自動送信メールだってことが相手にも伝わったほうが良いかと思い、「PowerAutomateによる自動送信メールです。」と一文いれています。
CodeDeploy - EC2デプロイのログデータの確認方法

CodeDeployで作成されたログデータを表示するには、CloudWatch or インスタンスにログインしてログファイルを確認します。今回は後者です。

デプロイ先のEC2にssh接続し以下のコマンドで確認できます。

```
tail -F /var/log/aws/codedeploy-agent/codedeploy-agent.log
```

## 参考
[公式サイト](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/deployments-view-logs.html)
osを作る その2

#概要

osを作る。
とっかかりは、setjmp

#タスク切り替え

コンテキストスイッチで実現。
コンテキストとはcpuがプログラムを実行してきた履歴のことでありcpuのレジスタの値 スタックの内容などが含まれる。
コンテキストスイッチは 実行中のスレッドの実行を中断し  そのコンテキストを保存し  他のスレッドのコンテキストを復元することによって行われる。

#setjmp/longjmp

setjmpとlongjmpは関数を跨いだジャンプを実現するための関数です。
setjmpを呼び出すとその時のスタックポインタやレジスタなどの状態を引数として渡したjmp_buf型の変数に書き出します。
longjmpでは逆に値を書き戻すことでsetjmpした時の状態に戻ることができます。


#サンプルコード


```
#include "CScheduler.h"

unsigned long systim;

void task1(void) {
	while (1)
	{
		Serial.print(systim);
		Serial.println("task-1");
		Scheduler.yield();
	}
}
void task2(void) {
	while (1)
	{
		Serial.print(systim);
		Serial.println("task-2");
		Scheduler.yield();
	}
}
void task3(void) {
	while (1)
	{
		Serial.print(systim);
		Serial.println("task-3");
		Scheduler.yield();
	}
}
ISR(TIMER1_COMPA_vect) {
	systim++;
}
void setup(void) {
	Serial.begin(9600);
	while (!Serial)
		continue;
	cli();
	TCCR1A = 0;
	TCCR1B = 0;
	TCNT1 = 0;
	OCR1A = 1999;
	TCCR1B |= (1 << WGM12);
	TCCR1B |= (1 << CS11);
	TIMSK1 |= (1 << OCIE1A);
	sei();
	Scheduler.add(task1, 256);
	Scheduler.add(task2, 128);
	Scheduler.add(task3); 
}
void loop(void) {
	Serial.println(systim);
	delay(1000);
}




```

#結果


```
0task-1
0task-2
0task-3
0task-1
0task-2
7task-3
16task-1
27task-2
37task-3
47task-1
58task-2
68task-3
79task-1
89task-2
99task-3
110task-1
121task-2
133task-3
144task-1
156task-2
167task-3
178task-1
190task-2
201task-3
213task-1
224task-2
236task-3

```

以上。
ArgumentErrorのエラーについて

#結論。

#### 引数が間違ってる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1789450/7f3d6dff-28de-2a7b-992c-9b47dec78547.png)

```
wrong number of arguments (given 0, expected 1)
```
given ⇒ 実際コードに書かれてる引数の数
expected ⇒ 本来あるべき引数の数

経緯は忘れました。
date_parse_from_format 日時フォーマット (ISO 8601 RSS1.0)　チェックメモ

`2021-08-11T18:19:04+09:00`
`YYYY-MM-DDThh:mm:ss+09:00`
のタイムゾーンありきのフォーマットチェックに詰まったのでメモ

以前は

```php
strptime($val, '%Y-%m-%dT%H:%M:%S%z')
```
で日時をチェックしていたがOSによって挙動が違うのでdate_parse_from_formatに書き換えることにした
APIから受け取るフォーマットが`2021-08-11T18:19:04+09:00`なので

```php
date_parse_from_format('Y-m-d\TH:i:sO', '2021-08-11T18:19:04+09:00')
```
ってやればエラーを検出せずにすむ
`Y-m-d\TH:i:s\+09:00`※一応これでも大丈夫
こういう調査って地味に時間かかるの備忘録して参考になれば～
GitとGitHubをSSHで接続する

今回はローカルリポジトリとリモートリポジトリがすでにある状態で新たにSSH　keyを生成して接続する方法をまとめてみたいと思います。

※exampleは適宜ご自身の環境に置き換えてお試し下さい。

# 新しいsshキーを作成
ローカルにて以下のコマンドを打ちます。

```generate.sh

$ cd /home/exampleuser/.ssh
$ ssh-keygen -t ed25519 -C "your_email@example.com"
Generating public/private ed25519 key pair.

```

上記コマンドのyour_email@example.comはGitHubに登録されているメールアドレスを入力して下さい。
これによりkeyにラベルをつけることが出来ます。
-t ed25519はssh keyを生成するときの暗号化方式の指定をしています。
以下対話形式で入力を求められます。

```generate2.sh

#ここでなにか入力するとkeyファイルの名前やパスを変更出来ます。
#複数のプロジェクトを管理している場合は名前でわかりやすく保存するのも良いでしょう。
Enter file in which to save the key

#ここでssh keyにパスワードを設定できます。パスワードを設定すると
#例えばgit pushを行った際にここで指定したパスワードを入力しないと
#接続できないようにセキュリティレベルを高めることが出来ます。
#macOSのキーチェーン機能を使える環境ならこのパスワードを
#キーチェーンに設定して自動で接続するというようなことも可能らしいです。※詳細は参考サイト参照
Enter passphrase

#ディレクトリを確認するとファイルが生成されているはずです。
#id_rsaというのはデフォルトでkeyにつけられる名前です。
$ ls
id_rsa #秘密鍵、厳重に管理しなければならない鍵。GitHubなどに上げてしまったら再生成する必要があります。
id_rsa.pub #公開鍵、公開しても良い鍵。次の手順でGitHubに登録をします。

```

これでローカルにssh keyのペアが作成されました。

### keyのファイル名を変更した場合はconfigファイルを作成する必要があります。
保存場所は~/.ssh/configのように拡張子なしのファイルを作成して保存します。

```~/.ssh/config

Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/id_example_rsa #ここに自分の鍵のファイル名
  User git

```


# GitHubに公開鍵を設定
１．id_rsa.pubの内容をクリップボードにコピーします。
ローカルで以下のコマンドを打つとコピーできます。

```pub.sh

$ cd /home/exampleuser/.ssh
$ pbcopy < id_rsa.pub

#pbcopyがない場合はcatコマンドなどで表示させて選択してコピーします。
$ cat id_rsa.pub

```

２．GitHubにログインした状態で[画面右上のアイコン]をクリック→[Settings]をクリックします。

３．次に表示された画面で左側にある[SSH and GPG keys]をクリックします。

４．[New SSH key] または [Add SSH key] をクリックします。

５．Titleには後で見たときにわかりやすい内容をつけます。
　　例）railstutorialfromcloud9

６．keyにクリップボードから貼り付けます。

７．[Add SSH key] をクリックします。

８．GitHub パスワードの確認を促される場合があります。
　　ここではGitHubにログインするときに使用するパスワードを入力します。

# GitHubへの接続を確認
ローカルのリポジトリ（git管理しているフォルダ。.gitなどのディレクトリがあるところ）で
以下のコマンドを打ちます。

```git.sh

$ ssh -T git@github.com
The authenticity of host 'github.com (xxxxxxxxxxx)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?

```

ここで表示されたfingerprintを確認します。
以下のページにて公開されているものと一致するかを確認して下さい。
https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints

一致していればyesと入力してreturnキーを押します。

```

Hi example! You've successfully authenticated, but GitHub does not provide shell access.

```

↑このようなメッセージが表示されたらローカルリポジトリとリモートリポジトリが接続されgit pushやgit pullなどのコマンドが機能するようになるはずです。

### エラーが表示された場合
前述のkeyを生成した際に名前を変えていればconfigファイルを設定しているかを確認してみて下さい。
また.sshディレクトリのパーミッションは700
秘密鍵のパーミッションは600に設定しないとエラーが出る場合もあります。

# 参考サイト
[新しい SSH キーを生成　|　本家](https://docs.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
[GitHub アカウントへの新しい SSH キーの追加 | 本家](https://docs.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
[SSH 接続をテストする |　本家]
(https://docs.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh/testing-your-ssh-connection)
【C言語】エスケープシーケンス　チートシート

# エスケープシーケンスとは
>エスケープシーケンス (escape sequence) とは、コンピュータシステムにおいて、通常の文字列では表せない特殊な文字や機能を、規定された特別な文字の並びにより表したもの。

https://ja.wikipedia.org/wiki/%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9

例えば、 `printf("\n");`と書くと `\n`という文字列を出力するのではなく改行文字が出力されますね。
このように、出力することで画面を操作できる文字コードをエスケープシーケンスと呼びます。
他にもたくさんのエスケープシーケンスがあるので、知っている範囲でご紹介します。

# 特殊文字

| 文字コード | 意味　|
| -----|--------------- |
| \a | ベル文字（アラート） |
| \b | １文字分戻る |
| \f | ページ送り（クリア） |
| \n | 改行、復帰
| \r | 同じ行の先頭に戻る
| \t | 水平タブ
| \v | 垂直タブ


- `\f`と`\v`はプリンタ出力用で、コンソール上では横方向の位置そのままで次の行に移動する場合が多いようです。
- `\b`や`\r`でカーソルの位置を戻してもそれまでの出力は消えていない点には注意する必要があります。

### サンプルコード

``` C
#include <stdio.h>

int main()
{
//カーソルを行の先頭に戻す
	printf("aaaaaaaaa\rXX\n");

//カーソルを２文字分戻す
	printf("aaa\b\bX\n");
	return (0);
}
```
```
$ ./a.out
XXaaaaaaa
aXa
```


# 画面制御

| 文字コード　| 意味 |
| -------|----- |
| `\033[0J` | カーソル位置から画面右下まで消去 |	
| `\033[1J` | 画面左上からカーソル位置まで消去	|
| `\033[2J` | 画面クリア|
| `\033[0K` | カーソル位置から同じ行の右側消去	
| `\033[1K` | カーソル位置から同じ行の左側消去
| `\033[2K` | カーソルのある１行の消去	
| `\033[nA` | カーソルをn行上へ移動	
| `\033[nB` | カーソルをn行下へ移動	
| `\033[nC` | カーソルをn桁右へ移動	右端で停止
| `\033[nD` | カーソルをn桁左へ移動	左端で停止
| `\033[r;nH` | カーソルをr行、n桁目へ移動

###サンプルコード

``` C
#include <stdio.h>

int main()
{
//カーソルを行の先頭に戻して右側の出力を削除
	printf("aaaaaaaaa\r\033[0KXX\n");

//カーソルを２文字分戻してその行の出力を削除
	printf("aaa\b\b\033[2KX\n");
	return (0);
}
```

```
$ ./a.out
XX
 X
```

``` C
#include <stdio.h>

int main()
{
//画面をクリアしてカーソルを1行目1桁目に移動
	printf("\033[2J\033[1;1H");
	return (0);
}
```

# 文字制御

### 文字修飾

|文字コード　 | 意味 |
|-------- | -----|
| `\033[1m` | ハイライト(太字)	
| `\033[4m` |  下線	
| `\033[5m` | 点滅	
| `\033[7m` | 文字色と背景色を入れ替える 
| `\033[0m` | デフォルトに戻す

自分の環境（MacOS, iTerm2）では点滅はうまく動作しませんでした。


### 文字色

| 文字コード | 意味 |
| ------  | ---- |
| `\033[30m` | 黒 |
| `\033[31m` | 赤 |
| `\033[32m` | 緑
| `\033[33m` | 黄色
| `\033[34m` | 青
| `\033[35m` | マゼンダ
| `\033[36m` | シアン
| `\033[37m` | 白
| `\033[39m` | デフォルトに戻す 

### 背景色
| 文字コード　| 意味 |
|------- | ---- |
| `\033[40m` | 黒
| `\033[41m` | 赤
| `\033[42m` | 緑
| `\033[43m` | 黄
| `\033[44m` | 青
| `\033[45m` | マゼンダ
| `\033[46m` | シアン
| `\033[47m` | 灰
| `\033[49m` | デフォルトに戻す

- 色を変化させた後はデフォルトに戻すのを忘れないようにしましょう。
- ~~出力結果の画像を貼るのが面倒だったので~~サンプルコードはありません。

# まとめ
エスケープシーケンスの動作は環境に依存する場合が多いので、その点は注意してください。
エスケープシーケンスを使ってイケてるテストを書きたいですね。

## 参考文献
以下のサイトを参考にしました

https://www.mm2d.net/main/legacy/c/c-06.html

https://dev.grapecity.co.jp/support/powernews/column/clang/047/page02.htm
Python JSON


https://docs.python.org/3/library/json.html

| 関数 | 結果 |
|---|---|
| json.dumps(obj)     | 辞書型 -> 文字列(JSON) |
| json.loads(s)       | 文字列(JSON) -> 辞書型 |
| json.dump(obj, fp)  | 辞書型 -> ファイル(JSON) |
| json.load(fp)       | ファイル(JSON) -> 辞書型 |

```python:sample.py
import json

# 辞書型 -> 文字列(JSON)
def dict2json_str(json_dict):
    json_str = json.dumps(json_dict)
    print('dict2json_str -> ', type(json_str))
    return json_str

# 文字列(JSON) -> 辞書型
def json_str2dict(json_str):
    json_dict = json.loads(json_str)
    print('json_str2dict -> ', type(json_dict))
    return json_dict

# 辞書型 -> ファイル(JSON)
def dict2json_file(json_dict, filename):
    with open(filename, 'w') as f:
        json.dump(json_dict, f)
    print('dict2json_file -> ', filename)

# ファイル(JSON) -> 辞書型
def json_file2dict(filename):
    with open(filename, 'r') as f:
        json_dict = json.load(f)
    print('json_file2dict -> ', type(json_dict))
    return json_dict


json_file = 'sample.json'
sample_dict = {'title': 'json test'}
json_str = dict2json_str(sample_dict)       # 辞書型         -> 文字列(JSON)
json_dict = json_str2dict(json_str)         # 文字列(JSON)   -> 辞書型
dict2json_file(json_dict, json_file)        # 辞書型         -> ファイル(JSON)
result_dict = json_file2dict(json_file)     # ファイル(JSON) -> 辞書型
print(json_file, ' -> ', result_dict)
```

実行結果

```
dict2json_str ->  <class 'str'>
json_str2dict ->  <class 'dict'>
dict2json_file ->  sample.json
json_file2dict ->  <class 'dict'>
sample.json  ->  {'title': 'json test'}
```
osを作る

#概要

osを作る。
構想編

#実装したい機能

- 複数のタスクを同時、実行する。
- ハードを抽象化して、共通インターフェースを提供する。


#複数のタスクを同時、実行する。

CPUは一般的に1コアで1つのアプリケーションしか動作させることができません。
osがあれば、CPUのコア数より多くのアプリケーションを起動し、まるで同時に動いているかのように感じることができます。
これは、OSがCPUの時間を細かい単位に分割し、各アプリケーションを切り替えつつ実行するよう調整しているからなのです。これを実装します。

#ハードを抽象化して、共通インターフェースを提供する。

ファイルを書き込む場合、その対象は、ファイルシステムかもしれませんし、シリアルかもしれません。
osがあれば、アプリケーションは書き込み先のファイルをfopenしてwriteするだけで、書き込み先のデバイスが一体何なのかを気にせず書き込むことができます。これを実装します。

#対象ハード

arduino

#kernelの構造

kernelが、起動し、システムタスクを起動し、ユーザーアプリケーションのシェルを起動する。いわゆる、マイクロカーネルを実装する。

#システムコール

|システムコール|機能|
|:--|:--|
YIELD			|プロセス管理|
GETPID			|プロセス管理|
IRQEN			|割り込み管理|
IRQDIS			|割り込み管理|
CREATETASK		|プロセス管理|
ALLOCATESTACK		|プロセス管理|
SETUPTASK		|プロセス管理|
STARTTASK		|プロセス管理|
STOPTASK		|プロセス管理|
DELETETASK		|プロセス管理|
EXITTASK		|プロセス管理|
MALLOC			|メモリ管理|
FREE			|メモリ管理|
SEND			|プロセス間通信|
SENDREC			|プロセス間通信|
RECEIVE			|プロセス間通信|
WAITEVENT		|プロセス間通信|


以上。
Oracle データベースの RAWTOHEX と同じ出力結果を PostgreSQL で得る

# やりたいこと
Oracle データベースの RAWTOHEX と同じ出力結果を PostgreSQL で得たい。

# Oracle の出力例
- Live SQL を使用
    - https://livesql.oracle.com/
- `select RAWTOHEX('あいうえお') from dual`
    - 出力結果: `E38182E38184E38186E38188E3818A`

# PostgreSQL での対応
- `select upper(encode(convert_to('あいうえお', 'UTF8'), 'hex'))`
    - 出力結果: `E38182E38184E38186E38188E3818A`
- 元になる Oracle の環境によって文字コードを切り替える
    - `convert_to('あいうえお', 'SJIS')` など
- バージョンは 10.16 で確認
全角空白などをVSCODEで検出する

## jQueryでidを取得する方法

jQueryでHTMLタグ内のid属性(属性は英語でattribute)を取得するには、

```javascript
attr('id');
```
をつけてあげます。
おそらく、**attr**が**attribute**のことかな。

なので「WEB画面でクリックしたもののidを取得したい」という時は、

```javascript
$('div').click(function() {

let getId = $(this).attr('id');

console.log(getId);//id1

});
```

#### 参考サイト

https://1-notes.com/get-id-and-class-name/

で、今回は、

```javascript
$('#taglist').find('.btn').click(function() {

    //クリックしたボタンのid取得
    var thisid = $(this).attr('id');
    console.log(thisid);
```

で、クリックしたボタンのidを取得しようと思ったのですが、どうもできません。
調べてみると、

```html
<input class="btn btn-danger mb-1" type="button" value="無視"　id="kyoudoutyuui-1">
```

Qitaですと赤破線で表示されていますが「id=」の前に**全角スペース**が入っています。
これ、あるあるなんですよね〜。

----
### 予防策
とりあえず日本語ユーザのエンジニア向けにこんなのがあるみたいです。

https://scominc.co.jp/blog/2020/06/vscode.html

さっそく入れてみます。

VSCODEの拡張機能で、zenkakuを検索し、インストールし、VSCODEを再起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221026/5ea56437-5829-53a0-6103-c596e20fedff.png)
全角部分がグレー化されています。これをつぶしていけばいいわけですね。

自分の場合、年に3回くらい（自分で書いたコードだとチェックが甘くなるのでみつけられないんです）こういうことがあるのですが、この拡張機能を入れることでタイムロスが減りそうです。

これで、無事動くようになりました。
Pythonでエラーなく落ちる(Pillowのバージョン変更で対応)

## 状態の概要
VSCodeでF5で実行してみて、エラーも何も出ずに終了してしまう問題。自分はPyAutoGUIで起きました。



## 解決策
自分の場合はPillow==8.3.1が悪さをしているみたいなので、バージョンを少し戻してみればOK。

```shell
pip install Pillow==8.3
```


## 解決にいたるまで
コメントを入れながらデバッグしていると、`import`のところで問題が起きてるっぽい。深く追ってみると、Pillowの中でエラーが起きている...

```Python
# import先のimport先の...と追っていくときに便利なコード
print(f'##{__file__}################################')
```

追っていくと、原因の箇所は以下のようなコードになっている模様。
`from . import _imagingft as core`のところでダメになる。
ImportErrorにも引っかからないし、`except Exception as e:`の中で`traceback.print_exc()`をしても引っかかってくれない。

```Python:ImageFont.py(47-50行目、問題の箇所)
try:
    from . import _imagingft as core
except ImportError:
    core = _imagingft_not_installed()
```

_imagingftはバイナリファイルらしく、VSCodeで開けなかった。
8.3.1と8.3.0ではコードが変わらないので、_imagingftのファイル内の変更が影響してるんだろうな...
[iOS15] [未解決]「アップデートの必要があります AppをこのバージョンのiOSで動作させるには、デベロッパによるアップデートが必要です」で自作アプリがインストールできない時

# とりあえず、検証結果

- **Xcode10.xでビルドしたアプリは動かない！**
- Xcode11は未検証です。AppCenterでビルドしてみればいいけど、そのためのコード変更がめんどくさいのでやってません。
- 一部僕のところで発生したアプリでは、Swift3を使ったライブラリをリンクしてあるので、それも問題かも。（だからXcode10から離脱できなかった）


**ありがとう iOS15! やっとXcode10を捨てられるよ！！**

# 20190819 追記　修正
どうやら、Xcodeのバージョンというよりも、**Development Target**の問題っぽい。
少なくともiOS11 / watchOS3 の設定ではNGでした。@ Xcode12.5.1
何が正解なんだ？？
iOS13 watchOS6 の設定にしたところインストールまで出来ました。

どちらにせよ、Xcode10じゃダメってことで。わーい。さようならXcode10

#さらに追記修正 Xcode 12.4 はNGでした
Microsoft Azure AppCenterでXcode 12.4でビルドしたところ、Development Targetを上げてもダメでした。Xcode 12.5.1 はOK。**Xcodeは最新に！**

なんだけど、AppCenterではまだXcode12.4までしか選択できない、、、

#さらに追記　もしかしてEnterpriseアプリだけ？
実は、この現象、iOS側が解消されても、watchOSがインストールできないという
状態が今でも続いています。もちろん、Xcode13でビルドする分にはインストールできるのですが。

設定やDevelopmentTargetの変更など一通り確認し、新規プロジェクトでも試してみましたが、Enterpriseのアーカイブipaはwatchにインストールできず。
ただし、ストアアプリは動いているので、どうも、enterpriseに特化した話かもしれない。

以前に似たような現象があったようなのでメモを残しておく
https://developer.apple.com/forums/thread/110638
Docker Desktop for Windows が突然起動しなくなった 

# やったこと
## Task Manager を確認する
Docker Desktop に関係するプロセスは下記の通り。

- Docker Desktop
- Docker Desktop Backend
- docker.exe
- com.docker.proxy.exe
- Docker.Service

このうち、Docker.Service のみ起動していた。
Docker Desktop のショートカットをクリックすると、一時的に Docker Desktop 等のプロセスも表示されるが、しばらくすると消えてしまう。

## Log を確認する
AppData\Local\Docker の中に log がある。log.txt が最新のログなので、その内容を確認してみる。
これを見ると AppData\Roaming\Docker\settings.json のロードに失敗している。確認すると空ファイルになっているので、何かの拍子に設定ファイルの中身だけが消えてしまった模様。

## キャッシュフォルダを削除する
AppData\Roaming\Docker を別の場所に移動して Docker Desktop を起動すると、起動に成功した。

# そのほかの問題の場合
公式サイトにトラブルシューティングもあるので、こちらを参考にしよう。
https://docs.docker.jp/docker-for-windows/troubleshoot.html
ただし私の環境にはターミナル診断アプリ com.docker.diagnose は無かった。なぜだろう。
超簡単！Mock API開発：json-serverを試す


今更ながらjson-serverを試します。

## 準備

node.jsが必要な以外は特にありません。
作業場作って（どこでもいいです）、json-serverをインストール。

```bash
cd
mkdir mock-api
cd mock-api

npm install -D json-server"
```

## API定義（実装）

### 定義ファイル生成

jsonなら名前とかは何でもいい。

```bash
touch api.json
```

### サンプルデータを実装

基準となるデータを入れる。

```json:api.json
{
  "users": [
    {
      "id": 1,
      "name": "hoge",
      "age": 11
    },
    {
      "id": 2,
      "name": "foo",
      "age": 22
    }
  ]
}
```

### 実行

これでREST APIサーバが起動します。

```bash
npx json-server api.json
```

つまり、

* GET（取得）
* POST（登録）
* PUT（更新）
* DELETE（削除）

ができます。

## 試してみる

curlでサクッと試してみます。

### 取得

すべてを取得。

```bash
curl -X GET http://localhost:3000/users
```

1つだけ取得。

```bash
curl -X GET http://localhost:3000/users/1
```

### 登録

```bash
curl -X POST -d "name=bar&age=33"  http://localhost:3000/users
```

>登録されたかは全てを取得してみるといいでしょう。インメモリに貯まるようです。

### 更新

```bash
curl -X PUT -d "name=bar&age=44" http://localhost:3000/users/3
```

### 削除

```bash
curl -X DELETE http://localhost:3000/users/3
```

すばらしい！！
GitHub Branch Source pluginでSSHでCheckOutする方法

セキュリティを向上するため、2021/08/13にGithubからPassword認証が廃止されました。

https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/

この変更に伴ってGitHub Branch Source pluginを以下の方法でPAT(Personal Access Token)を使っていると403が返答されるようになりました。

> Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.

https://newbedev.com/how-to-use-github-personal-access-token-in-jenkins


Jobのログを見るとGithubApiは問題なくアクセスできていますが、check out時に403が返答されてしまっているようです。なので、以下の設定を行いSSHを使ってCheckOutを行うようにすれば、この問題を回避することができます。

[Branch Sources] -> [Github] -> [Behaviours] -> [Checkout over SSH]

![スクリーンショット 2021-08-17 19.58.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2135/dbaeec68-708f-7636-0845-967e4138b89a.png)

ちなみにURLでPATを指定してCredentialを空にするという手もあるようですが、GitHub Branch Source pluginはGithubApiからブランチのURLを取得しているようで、この方法を使うことはできませんでした。。。簡単なJobであればこちらを使うのも良いのかなと思います。

```
https://<access token>@github.com/<userName>/<repository>.git
```

# 参考

https://stackoverflow.com/questions/61105368/how-to-use-github-personal-access-token-in-jenkins
Thymeleafの日付比較

#Thymeleafの日付比較が賢い！
と感動したので、簡潔ですが投稿させていただきます。

#コード例
ControllerからModelに値を渡し、Thymeleafで表示する例です。

```java:○○Controller.java
...

@GetMapping("/index")
public String index(Model model) {
 model.addattribute("today", "2021-8-18");
 model.addattribute("tomorrow", "2021-8-19");
 return "index.html";

...
```

```html:index.html
...

<div th:if="${today gt tomorrow}">falseなので表示されない</div>
<div th:if="${today lt tomorrow}">trueなので表示される</div>

...
```
比較演算子で「＞」とか使いたくなりますが、
Thymeleafでは以下のように書き換える必要があります。

| Javaの演算子 | Thymeleafの演算子 |
|:-:|:-:|
|>|gt|
|<|lt|
|>=|ge|
|<=|le|
|!|not|
|==|eq|
|!=|neq|

(参考にさせていただきました！ありがとうございます！)
[Thymeleafのif文で使う比較演算子の使い方](https://qiita.com/narikei/items/c4780d6bb69902380136)

###感動ポイント
String型でModelに渡しているのに、Thymeleafが日付として前後比較してくれる。賢い。

#以上！
お読みいただきありがとうございましたm(_ _)m
【Django】特定のレコードをコピー・更新して、新規登録したい

## 目的
Pinterestのようにユーザー毎にフォルダを作成できて、ファイルをアップロードして他ユーザーと共有し、他ユーザーがアップしたファイルを自分のフォルダにも保存できるようなサービスを開発しています。
上記を実現するために、掲題のような処理を書いてみました、

## ソース
```python
# 1.コピー
# コピー元のレコードを取得
fileObj = file.objects.filter(id=id)
# querysetをdictに変換
fileJson = list(fileObj.values())[0]
# 2.更新
fileJson.pop('user_id')
fileJson.pop('folder_id')
fileJson.user = user
fileJson.folder = folder
# 3.新規登録
serializer = FileSerializer(data=fileJson)

if serializer.is_valid():
   # エラー処理
   Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializer.save()
return Response(status=status.HTTP_201_CREATED)
```

## 補足
### コピー
- 一番時間がかかってしまったところ
- `queryset json 変換`とかで検索すると、下記のようなコードが出てくるが求めていたものと違っていた

```python
# serializerで返ってくるやん
json_encode = serializers.serialize('json', WorkList, ensure_ascii=False)
# 文字列で返ってくるやん
json_encode  = json.dumps(list(WorkList), cls=DjangoJSONEncoder)
```

### 更新
- `models.ForeignKey`でユーザーテーブルなど外部参照している場合は、参照先のデータが入れ子になって取得される。新規登録時はIDのみでいいので、取得したデータを削除して入れ直している。

### 新規登録
- あとは、通常のレコード作成と同様にSerializerでバリデーションをかけてsaveして終わり


## 追記
- こんな感じでも実現できた

### ソース
```python
# 更新するデータのみのシリアライザーを用意
serializer = FileCopySerializer(data=request.data)
# バリデーション
if serializer.is_valid():
   # エラー処理
   Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# コピー元のレコードを取得
fileObj = file.objects.filter(id=serializer.validated_data.get('id'))
# 更新
# idをNoneにすることで新規登録できる
fileObj.id = None
fileObj.user = serializer.validated_data.get('user')
fileObj.folder = serializer.validated_data.get('folder')
# modelに新規登録のインスタンスメソッドを定義して呼び出し
fileObj.save()
return Response(status=status.HTTP_201_CREATED)
```

- コピー用のSerializerを用意したり、modelに新規登録のインスタンスメソッドを用意したりと、こちらの方がコード量が多い
- 前半に紹介したコードだと、serializerで更新対象外なデータのバリデーションも行っているので、わずかながらこちらの方が処理が早いかも
javascriptでselectの値を取得する方法

javascriptでselectで選ばれた値を取得する方法

```html
<select name="num" id="select-num"> <!-- selectにidを設置　-->
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
</select>  
```

```javascript
const Num = document.getElementById('select-num') 

Num.onchange = function(){　        /* onchangeでselectが変更されるたびに値を取得しています */

  alert(this.value);
}
```
Create New Users and Allow a User to Delete Accountsの追加の説明

[Trailhead関係　個別の課題別](https://qiita.com/Keiji_otsubo/items/56eb7a90bb72138ece1f)

[このトレイルヘッド](https://trailhead.salesforce.com/en/content/learn/projects/protect-your-data-in-salesforce/create-new-users-and-delete-accounts)は少々説明が足らないと思いました。
私も？になってしまいました。

このステップ6。　Editってないよ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8760cc77-a165-1804-ead1-b94c25cda3e8.png)


Editボタンを出すためには数ステップありますよね。

![profile_edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9813d180-71a7-77a3-b0a7-6275b4935769.png)

+ [Very Frustrated With Create New Users and Allow a User to Delete Accounts](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BrPNOSA3)

初めは、Admin権限がないかと思ったし、そういえばそんな回答を見た。でも答えはうやむやになってた記憶があります。
拡張ユーザプロファイルがどうだとかで...


# Salesforce ライセンスがない

+ [Missing 'Salesforce - Platform' Permission Set License](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UrBBB)

:::note
It seems like they are in order, they're grouped by User Licenses and Permission Set Licenses, then each list is sorted alphabetically.

Please scroll up.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/89e2247a-1b15-5eb4-39c5-c302bd3525f1.png)

:::

# ユーザ作成時にSalesforce ライセンスがない

+ [I currently doing a module and it requires me to make 4 users with this license and I only have 3 available. ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UvA78)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/47f9f63d-c57b-b1eb-46dc-005a91337eb8.png)

:::note
It says to disable

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/383839d9-3bca-08d4-5938-4896dac3413b.png)
:::
GitHubでパスワード認証廃止による認証エラーが出た件

2021/8/13からGitHubにてパスワード認証が廃止されました。（トークン認証）
自分のローカル環境やGitアカウントはトークン認証に切り替えていたものの、Linux環境において以前のパスワード認証のままにしていたためGitコマンド実行でエラーが出るようになりました。

## 現象
gitコマンドを叩くと以下エラーが発生しました。

```
$ git pull
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: unable to access 'https://github.com/xxx/REPO.git/': The requested URL returned error: 403

```

## 解決方法
トークンは既に取得済みなのでトークン認証用のURLを設定します。
**トークンが未取得の場合はGitHubの設定ページより以下手順でトークンを払い出してください。**

-------------
**(1)プロフィール写真をクリックしてから、設定をクリックします。**
**(2)Developer settingsをクリックします。**
**(3)Personal access tokensをクリックし、名前や有効期限などを指定して新しいトークンを生成します。**
**(4)Generate new tokenをクリックし正常に生成されたら、トークンをコピーします。**

-----

トークンが取得済みの場合、エラーが発生したGitリポジトリを開き、次のコマンドを実行して現在のOriginを削除します。

```
$ git remote remove origin
```

トークン認証用のOriginURLを追加します。

```
$ git remote add origin https://<トークン>@github.com/<ユーザ>/<リポジトリ>.git
```

これでGitコマンドが利用可能になると思います。
※上記コマンドでなくても直接.git/configでoriginのurlを書き替えてもOKです。
Lambdaを定期的に実行する

## 前提
定期的に実行したいLambdaが作成されていること。

## 手順
1. 定期実行用のCloudWatch Events のルールを作成する
1. 1.のイベントをLambdaに紐づける

### 定期実行用のCloudWatch Events のルールを作成する

Amazon CloudWatch Events とは

ざっくり言うと、AWSの各種リソースを監視して、設定したルールに該当した時にイベントを発火させるサービス。

>Amazon CloudWatch Events では、Amazon Web Services (AWS) リソースの変更を記述した、システムイベントのほぼリアルタイムのストリーミングを配信します。すぐに設定できる簡単なルールを使用して、ルールに一致したイベントを 1 つ以上のターゲット関数またはストリームに振り分けることができます。CloudWatch Events が発生すると、運用上の変更が認識されます。CloudWatch Events は、オペレーションの変更に応答し、必要に応じて、応答メッセージを環境に送り、機能をアクティブ化し、変更を行い、状態情報を収集することによって、是正措置を実行します。

>Concepts
イベント – イベントは、AWS 環境の変化を示します。AWS リソースは、その状態が変わったときにイベントを生成できます。例えば、Amazon EC2 は EC2 インスタンスの状態が保留中から実行中に変わったときにイベントを生成し、Amazon EC2 Auto Scaling はインスタンスを起動または終了したときにイベントを生成します。API コールを行うと、AWS CloudTrail がイベントを発行します。カスタムアプリケーションレベルのイベントを生成し、CloudWatch Events に発行することができます。定期的に生成される予定されたイベントをセットアップすることもできます。イベントを生成するサービスの一覧や、各サービスのサンプルイベントについては、「サポートされているサービスからの CloudWatch Events イベントの例」を参照してください。
ルール – ルールは、一致した受信イベントを検出し、処理のためにターゲットに振り分けます。1 つのルールで、複数のターゲットを振り分けることができ、それらのすべてが並列に処理されます。ルールは特定の順序で処理されません。これにより、組織のさまざまな部署が目的のイベントを検索して処理できます。ルールは、特定の部分のみ渡したり、定数で上書きしたりすることにより、ターゲットに送信される JSON をカスタマイズできます。
ターゲット – ターゲットはイベントを処理します。ターゲットには、Amazon EC2 インスタンス、AWS Lambda 関数、Kinesis ストリーム、Amazon ECS タスク、Step Functions ステートマシン、Amazon SNS トピック、Amazon SQS キュー、組み込みターゲットを含めることができます。ターゲットは、JSON 形式のイベントを受け取ります。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html


利用するには、下記設定が必要です。

・CloudWatch コンソール (https://console.aws.amazon.com/cloudwatch/) を開く
　「ルールの作成」 > 「スケジュール」で任意の実行頻度を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/c59c1e5a-9f4d-fd93-9d2e-1c0ee2b510b1.png)


### 1.のイベントをLambdaに紐づける
　「ターゲットの追加」 > 「Lambda関数」で定期実行したいLambdaを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/0d5fc31f-63d7-2177-0afc-26b8b60c79dd.png)
 

 　以上で、定期実行の設定が完了。
 　「関数の概要」ページから、トリガーに「EventBridge (CloudWatch Events)」が追加されてることを確認できる。

## 参考
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/RunLambdaSchedule.html
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.html
lambdaでnpm moduleを使う方法

## 前提
Lambda Functionが作成されていること。
ローカル環境にnpmがインストールされていること。

## 手順

必要な作業は下記
1. 使いたいnpmライブラリをローカルにインストールしてzip化する
1. Lambda Layerを1.のzipをもとに作成し、Lambda Functionと紐づける
1. Lambda Functionのコード上からnpmライブラリを呼び出す

Lambda Layerとは
>Lambdaレイヤーは、追加のコードまたはデータを含むことができる .zip ファイルアーカイブです。レイヤーには、ライブラリ、 カスタムランタイム 、データ、または設定ファイルを含めることができます。レイヤーを使用すると、コードの共有と責任の分離を促進し、ビジネスロジックの記述をより迅速に繰り返すことができます。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html

### 使いたいnpmライブラリをローカルにインストールしてzip化する
今回はnpmライブラリ「axios」で試してみる。

・ローカルの適当な場所で下記を実行
(npmライブラリが欲しいだけなので、プロジェクト名は適当でOK)

```
npm init
```

・npmライブラリをインストール

```
npm i axios
```

プロジェクトフォルダの「node_modules」フォルダをzip化する

### Lambda Layerを1.のzipをもとに作成し、Lambda Functionと紐づける

・AWS Lambda の左ペイン上の「レイヤー」>「レイヤーの作成」を押下
![スクリーンショット 2021-08-17 182721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/06cf68d7-0a65-1f73-fd4e-6f5aee508b11.png)


　　適当なレイヤー名を付けて、zip化した「node_modules」をアップロードする。
　　ランタイムはzip化したパッケージに合わせる。今回で言うと「Node.js」を選択する。

・「Lambda」から関数を選択し、「関数の概要」ページに移動
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/25130b02-8afb-1db4-1017-fa6a889c5a3b.png)

 　 画面下の「レイヤー」>「レイヤーの追加」 > 「カスタムレイヤー」でさっき作ったレイヤを選択し「追加」を押下

### Lambda Functionのコード上からnpmライブラリを呼び出す

↓こんな感じでライブラリを利用できる。

```
const axios = require('/opt/node_modules/axios');
```

パスは下記参照
>レイヤーを作成するときは、そのすべてのコンテンツを .zip ファイルアーカイブにバンドルする必要があります。.zip ファイルアーカイブは、Amazon Simple Storage Service（Amazon S3）またはローカルマシンからレイヤーにアップロードします。Lambdaは、関数の実行環境を設定するときに、レイヤーの内容を /opt ディレクトリに抽出します。


## 参考
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html
GitHubを用いた開発の流れ

GitHubはディレクトリやファイルの変更を記録・追跡できる管理システムで、
複数人で開発をする際に役立つことを学んだ。


実際にGitHubを用いた開発の流れを、下記にまとめてみる。

①画面左上の「Current Repository」→「Add」→「Add Existing Repository」で
　ローカルリポジトリを作る。

②「Publish repository」から「Keep this code private」のチェックを外して、
　リモートリポジトリを作る。

③「Current Branch」→「New Branch」→「Create Branch」で
　　materブランチからトピックブランチを作る。
　　「Publish branch」をクリックし、リモートリポジトリにも反映する。

④ファイル編集後、commit名を記入しcommitする。

⑤変更内容を「Push origin」し、ローカルリポジトリの変更を、リモートリポジトリに反映させる。

⑥「GitHubのブラウザ」→「Repositoriesの下」→「ユーザー名/フォルダ名」で
　　リモートリポジトリの管理ページへ移動できる。

⑦「作成したブランチ名」→「作成したコミット名」で
　　コミットの変更内容が反映されているか確認できる。（緑表示が追記したレコード）

⑧「GitHub Desktop」→「Create Pull Request」から
　　「# What(どのような実装をしているのか)」「# Why(なぜこの実装が必要なのか)」を記述し、
　　「Create pull request」でプルリクエストを作る。

⑨「Merge pull request」→「Confirm merge」でマージをし、
　　そのトピックブランチが不要であれば「Delete branch」をして削除する。

⑩「GitHub Desktop」→「masterブランチ」に切り替え、「Fetch origin」→「Pull origin」で
　　リモートリポジトリの変更を、ローカルリポジトリの「masterブランチ」に反映させる。

11.「History」→「トピックブランチ」がマージされていることを確認できたらOk。
MacからX11Forwardingを利用してLinux上のGUIアプリケーションを利用する方法

IBM CloudのVPC環境およびClassic Infrastructure環境で確認。
OSはCentOS7。

```txt:OSバージョン
[root@myvpc ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
```

#1. MacにXQuartzを導入。
https://www.xquartz.org/

#2. Linux上の設定

```txt:sshd_configの確認（デフォルトのままで特に何もする必要はない）
[root@myvpc ~]# grep X11 /etc/ssh/sshd_config
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#	X11Forwarding no
```

```txt:xauthの導入。およびテスト用GUIアプリとしてxeyesを導入。
[root@myvpc ~]# yum install -y xauth
[root@myvpc ~]# yum install -y xeyes
```

#3. テスト

```txt:ssh接続時に"-X"オプションをつける
cccc@MacBook-Pro ~ % ssh -X vpcgen2
[root@myvpc ~]# echo $DISPLAY
localhost:10.0
[root@myvpc ~]# xeyes
```

これで、Mac上にxyesが起動してくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/297163a9-ae4e-39e9-15d5-b2eb6deff240.png)
Raspberry Pi 4 modelBでやったことメモ

# 概要
Raspberry Piで作ったものや動かしたもの、そのためにインストールしたものの簡単な説明。
たのしくあそぼう。
# 初めに用意するもの
## Raspberry OS 64bit
https://note.com/ryoma_0923/n/nb7c26336a057
## OpenJDK16
https://calorienai.com/raspberry3/
## Minecraft Server
https://sukiburo.jp/minecraft-server-by-raspberry-pi-local/
# RaspiOSのセットアップ(Headless)
## Headlessでのセットアップ
https://qiita.com/rhene/items/828858afae699c5ac0ab
## ユーザーの作成等
https://qiita.com/c60evaporator/items/ebe9c6e8a445fed859dc
## SSH鍵の再生成(再セットアップ用)
https://qiita.com/hnw/items/0eeee62ce403b8d6a23c
## raspi-config
https://qiita.com/HeRo/items/c1c30d7267faeb304538
# よくあるパッケージのインストール
## ufw
https://sukiburo.jp/raspberry-pi-firewall/#4
***
## exim4
>[wikipediaから引用](https://ja.wikipedia.org/wiki/Exim)
>Exim（いくしむ）はPhilip Hazelによって開発が始まったメール転送エージェント (MTA) の一種である。

https://qiita.com/tukiyo3/items/282fa1f6edd7578f83a2

https://www.linuxquestions.org/questions/debian-26/force-reinstall-reconfigure-of-broken-packages-in-debian-exim-%5Bsolved%5D-4175500895/
***
## その他シェルスクリプト
### mcsync
準備中
***
### mcstart
準備中
***
# 温度監視
## 温度監視スクリプト群
### coretemp.sh
https://qiita.com/FizmimiFiz/items/349da3d7c0d086d6296f

よくある温度チェックスクリプトの中身
`cat /sys/class/thermal/thermal_zone0/temp`
***
## 通知メール送信スクリプト群
### pulse.sh
https://qiita.com/FizmimiFiz/items/74054dd0008c512247b1
### mayday.sh
https://qiita.com/FizmimiFiz/items/7e11e27e06fbe43fffa4

アラートを確認したら`sudo rm pan`とかで`pan`ファイルを削除して下さい。
***
## cronを利用した定期実行
https://qiita.com/FizmimiFiz/items/2b719e1fce31adefd338
***
# microSD延命
準備中
# 筐体加工
https://qiita.com/FizmimiFiz/items/ad0c881a98b03695ee56
# はまったところ
Win32DiskImagerとか使うときにデスクトップ版Gdriveとか使ってると動かないかも。終了すれば動く。
Rasspberry Pi 4 modelBのCPU温度がやばい

#CPU温度を下げたい。
CPU温度がやばいので

https://www.amazon.co.jp/gp/product/B07FMXJ3TZ/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

https://www.amazon.co.jp/gp/product/B083TNCKM5/ref=ppx_yo_dt_b_asin_title_o05_s00?ie=UTF8&psc=1

買いました。

ファンは妙にボロボロの箱に入って届きました…倉庫の奥に眠っていたのかな。
![IMG_3817.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548777/b2ca593c-b3cf-43f7-deae-6ec44c9c8252.jpeg)

取り付け後
![E9B2t_wUUAACMyt.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548777/04a5b5b8-611e-80b2-1d81-207812db9928.jpeg)

ケースの穴はハンダゴテで焼いたりニッパーで切ったりして開けました。
以前は60℃を超えていたCPU温度が取り付け後は37℃前後で安定しました。
【GAS】clasp pushコマンド実行時に出たエラーの対処

## User has not enabled the Apps Script APIというエラー
GASをローカルで開発する際に便利なCLIであるclasp導入時に発生したエラー。
初期設定として`clasp login`が完了しているにも関わらず、`clasp push`を実行すると下記エラーメッセージが表示されて、pushに失敗する。

```
GaxiosError:User has not enabled the Apps Script API. 
Enable it by visiting   then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
```
結論、開発で使用するGoogleアカウントの設定で`Google Apps Script API`の利用をオンに設定してあげる必要があった・・・。下記のリンクから設定可能。

https://script.google.com/home/usersettings

![スクリーンショット 2021-08-18 8.27.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/56da3c0e-fb3e-cf10-6aaf-ed57bc973b73.png)

`Google Apps Script API`の利用をオンにする事で、`clasp push`が通るようになった。めでたしめでたし。

## 参考にさせて頂いた記事
・[Google Apps Script をローカル環境で快適に開発するためのテンプレートを作りました](https://qiita.com/howdy39/items/0e799a9bfc1d3bccf6e5)
【Ruby on Rails】Ransackなしで 簡単に検索機能を実装する方法


#対象者

* 　検索機能の実装を考えている方
* 　Gemなしで検索機能を実装しようとしている方


#目的

* 　検索機能を実装して投稿を表示させる

#実際の手順と実例
###1.前提
* Rails 5.2.5
* UserモデルとArticleモデルを使用します
* 検索窓はヘッダーに設置
* 投稿した記事の検索結果をViewに表示します




###2.Modelの設定

検索対象がArticleなのでArticleモデルに記述していきます。
ここが一番の肝です

````article.rb
 def self.search(search_word) #①
  Article.where(["title LIKE(?) OR body LIKE(?) OR sub_title LIKE(?)", #②
                 "%#{search_word}%", "%#{search_word}%", "%#{search_word}%"
 end
````

①search_wordを探すようにメソッドを定義しています。
　さらにselfメソッドはオブジェクトそのものを指しています。（Article）

②LIKEを使ってカラムを部分一致で検索します。カラムはtableによって変えてください。


###3.Controllerとルーティングの設定

Controllerは下記のように設定します。

````articles_controller.rb
def search
  @articles = Article.all.search(params[:keyword])
end
````

ルーティングは下記のように設定します。

```routes.rb
 get "/search" => "articles#search"
```

###4.検索窓の設置

ヘッダーに検索窓を設置していきます。

````_header.html.erb
<%= form_with url: search_path, method: :get, local: true do |f| %>
  <%= f.text_field :keyword,placeholder: "キーワードで検索", class: "search-text"%>
  <%= button_tag type: "submit", class: "btn btn-default" do %>
    <i class="fas fa-search"></i> #①
  <% end %>
<% end %>
`````
①検索ボタンをFontAwesomeで入力しています。

https://qiita.com/nao0725/items/63eb73d3851c843b68bb


###5.Viewの設定

```app/views/articles/search.html.erb
 <% if @articles.exists? %> #①
    <% @articles.each do |article| %>
     <%= artcle.title %>
     <%= artcle.sub_title %>
     <%= artcle.body %>
    <% end %>
　<% else %>
  　　<p>該当する記事は見つかりませんでした。</p>
　<% end %>

```

※わかりやすくするためにCSSは削除しました。

①でif文で記事が存在するかどうかで表示結果が変わるように設定しました。

これで実装完了です！

#参照

>[オブジェクトを理解！Rubyのselfを使う方法【初心者向け】
](https://techacadem.jp/magazine/18706)


####投稿者コメント
検索機能をさくさく実装できたので記事にしてみました。
非同期化にも挑戦したいです。

####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
Goを使ってみた

Goを使ってみた

最近はやりのGoを触ってみるべくチャレンジ

まずはGoをWindowsマシンにインストール

https://golang.org/dl/　のMicrosoft WindowsからGoをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/4a39a67e-3b30-8c49-4877-1f517ae7e3a0.png)

普通にインストール実施

適当なファイルを作成

```main.go
package main

import "fmt"

func main() {
	fmt.Printf("hellohogefuga\n")
}
```

go run コマンド実行

```cmd
>go run main.go
hellohogefuga
```

vscodeで実施

するとこんなエラーが。
```
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
exit status 1
Process exiting with code: 1
```

そのフォルダで以下実行
```
>go mod init <フォルダ名>
```

無事実行できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653035/eb44dc7f-953a-0e96-d855-d4c015b13e16.png)
Chia ; OG プロットとPP プロットを見分ける方法

#Chia Plot でOG プロットとPP プロットを見分ける方法を備忘のために残します

chia plots check -g /path/to/drive/or/plots

でチェックするとOGプロットはPool Public Key が表示される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167640/c0067e52-8876-ac78-c5c5-118946bedf37.png)
医療情報技師　情報処理編　2017

#医療情報技師試験　２０１７　情報処理編にて不明点を要約する。

##ディスプレイ
* 液晶ディスプレイ　電圧をかけるごとに分子の並び方が変わる液晶の性質を利用してバックライトの光を通したり遮断したりして画面上の各ドットの表示を制御する方法である
* LED 発光ダイオード
* プラズマ　ガラス管に封入されたガス
* 有機ELディスプレイ　画面に蒸着した有機化合物に電圧をかけて発光させる

##USB
* USB３.０　最大データ転送速度は５Gbps
* USB3.1 最大データ転送速度は１０Gbps
* USB２.０　最大データ転送速度は４８０Mbps

##DNSキャッシュポイズニング

ドメイン情報を管理するDNSサーバーになりすまし、不正なドメイン情報をキャッシュさせる方法

##無線LANのセキュリティ規格

* WPA2　無線LAN通信の暗号化方式の規格　最も最新の暗号化規格
* CHAP パスワードを暗号化して送る　（よく分からん）
* LDAP TCP/IPネットワークでディレクトリサービスにアクセスするためのプロトコルである
* SSID 無線アクセスポイントを識別するための個別の名前

##なんかよく分からん略語

* IDS （intrusion detection sysytem） 侵入検知システム　ネットワーク上を流れるパケットやホスト上のログ、ファイルなどを監視し、不正なアクセスを検知して警告するシステムである
* IKE (internet key exchange) インターネット鍵交換　暗号鍵の交換・共有を安全に行うためのプロトコルである
* UDP　（unitnterruptible power supply）　　無停電電源装置　停電時電源が途切れた際にバッテリなどで一定時間、電源を供給する装置である
* DWH（deta ware house） 業務系システムで生み出されたデータを集約して蓄積し分析するためのシステム
* EDC　（electric date capture）治療管理システム
* OLAP(online analytical processing) ビジネスインティジェンスのツールの一つ
* RDB　（relational datebase） 関係モデルに基づいたデータベースシステム
* LMS（learning management system） e-learningを構成するためのシステム
* LTO（learning tape open） 大量のデータを長期保管するために適した磁気テープ記憶装置の規格

##RASIS（信頼性評価指数）

* 信頼性　(reliability)
* 可用性　(availabitity)
* 保守性,保全性　(serviceability)
* 完全性　(integrity)
* 安全性　(security)

##情報セキュリティの３要素（CIA）
* 機密性
* 真正性
* 保存性
IPアドレスの数式

[Answersで回答する時に使う情報のまとめに戻る](https://qiita.com/Keiji_otsubo/items/9e6e0e946826133eddc7)

IPアドレスに関連する質問があったので、まとめておきます。

4番目のオクテットを取得し、/ 29を削除して、値に変換するための最終式：

```
VALUE( 
LEFT(MID(IP_Block__c, FIND(".",IP_Block__c, FIND(".", IP_Block__c, 
FIND(".", IP_Block__c)+1)+1)+1,LEN(IP_Block__c)-FIND(".", IP_Block__c, 
FIND(".", IP_Block__c, FIND(".", IP_Block__c)+1)+1)), 
(FIND("/", MID(IP_Block__c, FIND(".",IP_Block__c, FIND(".", IP_Block__c, 
FIND(".", IP_Block__c)+1)+1)+1,LEN(IP_Block__c)-FIND(".", IP_Block__c, 
FIND(".", IP_Block__c, FIND(".", IP_Block__c)+1)+1)))-1))
)
```

[I'm needing to parse the IP Address in a Formula field to get the third octet.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C6Yp9SAF)


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

```
NOT(
REGEX( ankit__IP_ADDRESS__c,
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
))
```

[Valid IP Address, VAlidation rule](https://developer.salesforce.com/forums/?id=906F00000008w2PIAQ)

# 参考資料

+ [Separate Octets Of IP Address In Excel](https://www.extendoffice.com/excel/formulas/excel-split-ip-address.html)
node.js + mysql (2021)


最近は[mysql2](https://www.npmjs.com/package/mysql2)というパッケージを利用するのがいいらしい。
特にasync/awaitを利用するときには。

## 準備

```bash
cd
mkdir mysql2-test
cd mysql2-test

npm install mysql2

touch index.js
```

## 実装

```js:index.js
const mysql = require("mysql2/promise");

(async () => {

    try {

		//内容は各自の環境に合わせて変える
        const con = await mysql.createConnection({
            host: "localhost",
            user: "root",
            password: "root",
            database: "testdb"
        });

        await con.query("drop table if exists members");
        await con.query("create table members(id int, name varchar(32))");
        await con.query("insert into members(id,name) values(?,?)", [1, "hoge"]);
        await con.query("insert into members(id,name) values(?,?)", [2, "foo"]);

        const [rows, fields] = await con.query("select * from members");
        for (const row of rows) {
            console.log(`id=${row.id}, name=${row.name}`);
        }

        await con.end();


    } catch (e) {
        console.log(e);
    }

})();
```

## 結果

```bash
node index.js

id=1, name=hoge
id=2, name=foo
```

## おまけ

### 敢えてCallback地獄で書く

```js:index.js
const mysql = require("mysql2");

const con = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: "root",
    database: "testdb"
});

con.query("drop table if exists members", (error, result, fields) => {
    if (error) throw error;
    con.query("create table members(id int, name varchar(32))", (error, result, fields) => {
        if (error) throw error;
        con.query("insert into members(id,name) values(?,?)", [1, "hoge"], (error, result, fields) => {
            if (error) throw error;
            con.query("insert into members(id,name) values(?,?)", [2, "foo"], (error, result, fields) => {
                if (error) throw error;
                con.end();
            });
        });
    });
});
```
[React]フラグメントって？なんそれ！

# フラグメントとは
コンポーネントが複数の要素を返す際に、フラグメントを使うことで、DOMに余分なノードを追加せずに子要素をまとめることができるようになります。
以下のようにすることで、まとめられます。

```react
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}
```

## フラグメントを使わない際の問題点
以下のようなコンポーネントがあったとします。その場合、無駄に<div>タグを生成することになってしまい、余分なノードを追加することになります。

```react
class Table extends React.Component {
  render() {
    return (
      <table>
        <tr>
          <Columns />
        </tr>
      </table>
    );
  }
}

class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>Hello</td>
        <td>World</td>
      </div>
    );
  }
}
```

出力結果は以下の通りです。

```react
<table>
  <tr>
    <div> { // このタグが余分 }
      <td>Hello</td>
      <td>World</td>
    </div> { // このタグが余分 }
  </tr>
</table>
```

## 解決策
以下のようにすることで、余分なノードを追加しなくても良くなります。

```react
class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>
    );
  }
}
```

出力結果は以下の通りです。

```react
<table>
  <tr>
    { // 無駄なタグが生成されていない }
    <td>Hello</td>
    <td>World</td>
  </tr>
</table>
```

### 省略記法
フラグメントの記法については省略することも可能です。

```react
class Columns extends React.Component {
  render() {
    return (
      <>
        <td>Hello</td>
        <td>World</td>
      </>
    );
  }
}
```

### keyを持たせる
明示的に宣言したフラグメントではkeyを持つことが可能です。これはコレクションをフラグメントの配列に変換するときに有用です。

```react
function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // キーがなければ警告が出る
        <React.Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}
```
PhpStorm で phpunit のテストを書くときに記載する @noinspection 自分がよく利用するもの

```php
/** @noinspection NonAsciiCharacters */
/** @noinspection PhpUnhandledExceptionInspection */
/** @noinspection PhpDocMissingThrowsInspection */
/** @noinspection PhpPrivateFieldCanBeLocalVariableInspection */
/** @noinspection PhpExpressionResultUnusedInspection */
/** @noinspection PhpStaticAsDynamicMethodCallInspection */
```

## 目的

`@noinspection NonAsciiCharacters`

メソッド名に日本語を利用するため。

`@noinspection PhpUnhandledExceptionInspection`
`@noinspection PhpDocMissingThrowsInspection`

`@throws` タグはテストを書いていく中で変更が必要になることが多いため。
管理が煩雑となるため、書かない方が楽である。

`@noinspection PhpPrivateFieldCanBeLocalVariableInspection`

同様に、クラスのプロパティも必要になったり不要になったりと変更が多いため。

`@noinspection PhpExpressionResultUnusedInspection`

例外を投げられることをテストする場合、以下のようなコードを書くことがあるため。

```php
$this->expectException(HogeValidateException:class);
new Hoge('invalid param');
```

`@noinspection PhpStaticAsDynamicMethodCallInspection`

phpunit のアサーションを `$this->assertTrue()` の形で呼び出すため


`@noinspection` 一覧
[options for phpStorm @noinspection annotation](https://gist.github.com/discordier/ed4b9cba14652e7212f5)
ARMアーキテクチャ向けにDockerイメージをビルドする for ラズパイ 


# はじめに

IntelやAMDといったx86アーキテクチャ向けにしか提供されていないDockerイメージをラズパイ上で利用しようとするとエラーが発生してしまいます。
例えば、ラズパイ上で`docker run`で起動しようとすると以下のような`exec format error`が出たり、、

```shell
standard_init_linux.go:211: exec user process caused "exec format error"
```

`docker pull`を実行すると以下のような`no matching manifest`というエラーが出たりします。
試しにARM向けのイメージが提供されていないmysqlの公式イメージをpullしてみると、以下のようなエラーが発生しました。

```shell
$ docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
no matching manifest for linux/arm64/v8 in the manifest list entries
```

ラズパイに搭載されているCPUはARMアーキテクチャのものであり、当然ながらCPUのアーキテクチャが異なるイメージを動かすことはできません。
しかし、ARM向けにDockerイメージをビルドすればラズパイ上でもそのイメージが利用できるようになります。

今回は例としてオープンソースの経路検索エンジン`OSRM backend`のDockerイメージを使って解説します。
（ラズパイで経路検索サーバをたてようとしたのですがOSRM backendのイメージがARMに対応しておらず、環境構築に少し手間取ってしまったため今回の記事を書く発端となっています）

# 前提

今回検証した環境は以下の通りです。

__[ラズパイ]__
  機種: Raspberty PI 4 Model B
  メモリ: 8GB
  OS: Raspbian OS 64bit

__[作業マシン]__
  MacBook Pro: 2019
  メモリ: 16GB
  SSD: 250GB

__[Docker]__
  バージョン: 20.10.7
  (`buildx`を使うのでバージョン19.03以降のものを使用します)

なお、ラズパイ上イメージをビルドしても良いのですが、手元のMacの方が処理が速いため
今回はMac上でビルドするものとします。

# 手順

1: ORSM backendのプロジェクトを`git clone`してDockerファイルをプロジェクトフォルダ直下にコピーします。

```shell
git clone https://github.com/Project-OSRM/osrm-backend.git
cd osrm-backend/docker
cp Dockerfile ../
cd ..
```

2: ARMのCPU向けにdockerのイメージをビルドします。ここではdockerのbuildxを使います。

```
docker buildx build --platform linux/arm64/v8 --tag osrm-backend-arm64:latest  .
```

パラメータの`--platform`がポイントです。
上に書いた`no matching manifest for linux/arm64/v8 in the manifest list entries`というエラーメッセージにプラットフォーム名が表示されるのでこれと同じ文字列を指定します。
ここでは`linux/arm64/v8`を指定します。
なお、ビルドは非常に時間がかかります。自分のMacでは1時間以上かかりました。。。

3: イメージをtar形式で保存します。
以下を実行して`osrm-backend-arm64`という名前のイメージがtar形式で保存します。

```
docker save -o osrm-backend-arm64.tar osrm-backend-arm64
```

4: scpなどで作業マシンからラズパイへtar形式のイメージをコピーします。
scpのパラメータ(ポート番号、ユーザ名、ホスト名等)は適宜ご自身の環境に合わせて指定してください。
（ここでは公開鍵認証を使っています）
tarはラズパイ上の/tmpにコピーするものとします。
```
scp -P xxx -i ~/.ssh/id_rsa osrm-backend-arm64.tar yyy@aaa.bbb.ccc.ddd:/tmp
```

5: ラズパイにsshでログインしてコピーしたイメージをラズパイのdocker上にロードします。

```
cd /tmp
docker load -i osrm-backend-arm64.tar
```

以上でARMのCPUを搭載しているラズパイでもOSRM backendのイメージが利用できるようになります。

まとめ
===

今回はOSRM backendを題材に挙げましたが、他にもIntel/AMD向けのイメージしか提供されていないイメージをラズパイでも動かしたい場合は`buildx`を使うことで利用可能となります。

参考資料
===

- https://docs.docker.com/buildx/working-with-buildx/
- https://github.com/Project-OSRM/osrm-backend