OmniAICreator/Qiita-1.07M huggingface dataset:
Intel FPGA 開発環境構築


DE10-Liteを手に入れた。FPGAを使うには、Verilog-HDLなる言語を習得する必要があるようだが、その前に開発環境を整え、「Lチカ」を実施したので、それを記録しておく。
# 準備
## ダウンロード
### インテル® Quartus® Prime 開発ソフトウェア
[インテル® Quartus® Prime 開発ソフトウェアのダウンロード](https://www.intel.co.jp/content/www/jp/ja/products/details/fpga/development-tools/quartus-prime/resource.html)
無料の場合、ライト・エディションを選択。(Quartus-lite-22.1std.0.915-windows.tar：2023年2月24日現在)

## インストール
### Quartusのインストール
tarファイルを、圧縮解凍ソフト(7zipなど)で解凍する。
展開されたファイルから、「setup.bat」を実行してインストールする。(インストール先はデフォルトから変えない方がいいらしい)

### ドライバのインストール
Quartusのインストールが終わると、続けてUSBドライバのインストールを行うのだが、うまくUSBを認識しなかった。
[Windows 10 に USB-Blaster™ II および USB-Blaster ドライバーをインストールできないときの対処方法](https://www.macnica.co.jp/business/semiconductor/articles/intel/130529/)を参考に、[Why does the Intel® FPGA Download Cable II driver installation fail on Windows* operating system?](https://www.intel.com/content/www/us/en/support/programmable/articles/000085878.html)の内容を実施。（Windows11の環境でも有効）
- [リンク先](https://www.intel.com/content/dam/support/us/en/programmable/kdb/support/knowledge-center/tools/2021/usb-blaster-ii-update.zip)から更新されたバージョンのドライバーをダウンロード
- ダウンロードしたファイルを解凍し、「{Quartus Installation Path}\quartus\drivers\usb-blaster-ii」フォルダ内の「usb-blaster-ii.inf」と「usb-blaster-ii.cat」ファイルを置き換える。
- 「デバイス マネージャー」を起動する。
- 「USB-Blaster」を探し、「右クリック＞ドライバーの更新」を選択。「コンピューターを参照してドライバーを検索」を選び、{Quartus Installation Path}を設定し、サブフォルダーも検索するにチェックを入れ、検索を行う。

# とりあえず、Lチカ
## 新規プロジェクトの作成
「Quartus」を起動し、[File]>[New Project Wizart...]を選択。だいたいデフォルトでOK。
### Directory, Name, Top-Level Entity
プロジェクトのフォルダとその名前、Top-Level Entityを設定する。Top-Level Entityは、この後つくるVerilog HDL Fileの名前と一致させる必要がある（たぶん）。
### Family, Device & Board Settings
使うデバイスに従って設定。DE10-Liteの場合、「10M50DAF484C7G」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118796/0aec713e-ae5a-1cc6-4c3a-fe8d74c76999.png)

## Verilog HDL File の追加
[File]>[New]を選択し、[Verilog HDL FIle]を選択しOKを押す。
Verilog HDL の記法はおいおい学ぶとして、以下を記述する。
```verilog
module TopModule(input sw, output led);
	assign led=sw;
endmodule
```
[File]>[Save As...]を選択し、Top-Level Entityで設定した名前で保存する。

## ピン設定
[Processing]>[Start]>[Start Analysis & Elaboration]を選択する。（しばらく時間がかかる）
[Assignments]>[Pin Planner]を選択する。ウィンドウ下側の「Node Name」にledとswがあるので、それぞれのLocationを設定する。
- led: PIN_A8 (LEDR0)
- sw: PIN_B8 (KEY0)

## コンパイル
[Processing]>[Start Compilation]を選択する。（しばらく時間がかかる）
## プログラムの書き込み
[Tools]>[Programmer]を選択する。
ウィンドウ左上の[Hardware Setup...]を押す。
[Currently selected hardware]のドロップダウンリストから、「USB-Blaster[USB-0]」を選択する。
[Program/Configure]にチェックが入っているのを確認し、
[Start]を押すと書き込みが実施される。右上のProgressが100%になったら完了。

# まとめ
FPGA開発環境の構築と、Lチカまで実施。
今後、Verilog HDLについて学んでいく。
[css] -webkit-border-radius について

①-webkit-border-radiusとは
-webkit-border-radiusは、CSSのプロパティの一つで、要素の角を丸くするためのプロパティです。

②使い方法
-webkit-border-radiusを使うには、以下のような書き方をします。

div {
  -webkit-border-radius: 10px;
}

上記のように、-webkit-border-radiusプロパティを使うと、div要素の角を10pxの半径で丸くすることができます。

③実際試したところ
以下のようなHTMLとCSSを使って、実際に-webkit-border-radiusを試してみました。

<div class=""box"">
  <p>テスト</p>
</div>

.box {
  width: 200px;
  height: 200px;
  background-color: #ccc;
  -webkit-border-radius: 10px;
}

実行結果として、div要素の角が10pxの半径で丸くなりました。

![Something went wrong]()
参考：https://eigo-bunpou.com/each/

④終わりに
-webkit-border-radiusは、要素の角を丸くするためのプロパティです。CSSで要素をより見栄えの良いものにするために、-webkit-border-radiusを使うことができます。
blade.php内の変数の中身を知りたい


blade.php内の変数の中身を知りたいとき、LaravelにおいてControllerの中であれば
dd関数に変数を入れ込めばよかったが、blade.phpの中ではエラーが出てしまう。

## 理由
PHPコードをHTML内に記述するには、PHPコードを記述する箇所を`<? php ?>`で囲む必要があるため。

## 解決方法
`<?php dd($a) ?>`

単純にphpタグで囲むだけでした。
.NET 7 のdockerfile無しコンテナ化

.NET 7 から dockerfile を作成しなくても dotnet publish コマンドだけで docker build ができるようになりました。
と、こう聞いても dockerfile がないコンテナ化なんて、何されてるのかわからなくて気持ち悪い！って思いますね。
でも使ってみると便利すぎて困っちゃいます。

サンプルプロジェクトを作ります。

```bash
dotnet new mvc -o MvcContainer && cd MvcContainer
```

ローカルで稼働確認します。

```bash
dotnet run
```

# 使い方（基本）

事前に Microsoft.NET.Build.Containers ライブラリをプロジェクトに追加しておきます。

```powershell
dotnet add package Microsoft.NET.Build.Containers
```

あとはプロジェクトフォルダで次のコマンドを叩くだけ。

```powershell
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release
```

稼働確認します。

```powershell
docker run -p 8080:80 --rm MvcContainer:1.0.0
```

公式 docs はこちら。
https://learn.microsoft.com/ja-jp/dotnet/core/docker/publish-as-container

# カスタマイズ

何もオプションを渡さずにイメージを作成すると、既定の設定が使用されます。試しに作る分にはいいですが、実際にはカスタマイズが必要です。カスタマイズはコマンド発行時にオプションとして指定する方法と、Projectファイルにカスタマイズを記載する方法と二種類があります。

Projectファイルへの記載方法は公式 docs を参照しましょう。見れば分かる通り、そのまんま書けば良いのです。コマンドのオプションの渡し方は docs に記載がありませんが、下記のようにやれば良いです。例を2つだけ書いておきます。他の場合でも応用できると思います。

[公式doc](https://learn.microsoft.com/ja-jp/dotnet/core/docker/publish-as-container)

イメージ名を任意のものにする（既定はプロジェクト名）

```powershell
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release -p:ContainerImageName=sampleimage
```

```xml:Projectファイル
  <PropertyGroup>
    <ContainerImageName>sampleimage</ContainerImageName>
  </PropertyGroup>
```


任意のタグをつける（既定はプロジェクトの Version)

```powershell
dotnet publish --os linux --arch x64 /t:PublishContainer -c Release -p:ContainerImageTags=1.1.0
```

```xml:Projectファイル
<PropertyGroup>
    <ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>
```
QC検定　－　実験計画法

# 変動の分解

| 種別 | 説明 |
|:-:|:-:|
| 級間変動  |  因子の水準の違いによる変動 |
|  級内変動 |   因子以外の制御しなかった要因による変動 |
# 一元配置

## 分散分析表

| 要因 | 　　　　　平方和　　　　　 | 　　自由度　　 | 　不変分散　 | 　分散比　 |
|:-:|:-:|:-:|:-:|:-:|
| 因子A  | $S_A= \sum_{i=1}^{n_A} \frac{(\sum x_i)^2}{n_i} - CT$　  |  $\phi_A=n_A-1$ | $V_A=\frac{S_A}{\phi_A}$  | $F_0=\frac{V_A}{V_e}$  |
|  誤差e | $S_e=S_T-S_A$  |  $\phi_e=\phi_T-\phi_A$ | $V_e=\frac{S_e}{\phi_e}$  | ↑  |
|  全体T | $S_T=\sum x^2-CT$  |  $\phi_T=n-1$ |   |  ↑ |

※データを$x$、水準$A_i$のデータを$x_i$、水準$A_i$のデータ数を$n_i$、水準数を$n_A$、$CT=\frac{(\sum x)^2}{n}$とする


分散比を検定して因子の水準間に有意な差があるかどうか判定する。
5％有意なら、有意差あり
1％有意なら、「高度に有意差あり」　

### 各水準の95%信頼区間の推定

$$ \bar{x_i} \pm t(\phi_e,0.05) \sqrt{\frac{V_e}{n_i}} $$

### 水準間の差の検定

最小有意差$lsd = t(\phi_e,0.05) \sqrt{\frac{2V_e}{n_i}}$

|2水準の差|≧lsdなら当該の2水準間に有意差あり。

# 2元配置（繰り返しなし）

## 分散分析表

| 要因 | 　　　　　平方和　　　　　 | 　　　　自由度　　　　 | 　不変分散　 | 　分散比　 |
|:-:|:-:|:-:|:-:|:-:|
| 因子A  | $S_A= \sum_{i=1}^{n_A} \frac{(\sum x_{Ai})^2}{n_{Ai}} - CT$　  |  $\phi_A=n_A-1$ | $V_A=\frac{S_A}{\phi_A}$  | $F_{0A}=\frac{V_A}{V_e}$  |
| 因子B  | $S_A= \sum_{i=1}^{n_A} \frac{(\sum x_{Bi})^2}{n_{Bi}} - CT$　  |  $\phi_B=n_B-1$ | $V_B=\frac{S_B}{\phi_B}$  | $F_{0B}=\frac{V_B}{V_e}$  |
|  誤差e | $S_e=S_T-S_A-S_B$  |  $\phi_e=\phi_T-\phi_A-\phi_B$ | $V_e=\frac{S_e}{\phi_e}$  | ↑  |
|  全体T | $S_T=\sum x^2-CT$  |  $\phi_T=n-1$ |   |  ↑ |

※データを$x$、水準$A_i$のデータを$x_{Ai}$、水準$A_i$のデータ数を$n_{Ai}$、水準数を$n_A,n_B$、$CT=\frac{(\sum x)^2}{n}$とする

### 各水準の95%信頼区間の推定

1元配置と同じ

### 最適条件の母平均の推定

点推定： $\hat{\mu} = \bar{x_{Ai}}+ \bar{x_{Bj}} - \bar{x} $
区間推定： $ \hat{\mu} \pm t(\phi_e,0.05)\sqrt{\frac{V_e}{n_e}}$

ただし、$n_e=\frac{n_A\dot{}n_B}{1+\phi_A+\phi_B}$は有効反復係数(田口の公式)

# 2元配置（繰り返しあり）

## 分散分析表

| 要因 | 　　　　　平方和　　　　　 | 　    　自由度　　 　　 | 　不変分散　 | 　分散比　 |
|:-:|:-:|:-:|:-:|:-:|
| 因子A  | $S_A= \sum_{i=1}^{n_A} \frac{(\sum x_{Ai})^2}{n_{Ai}} - CT$　  |  $\phi_A=n_A-1$ | $V_A=\frac{S_A}{\phi_A}$  | $F_{0A}=\frac{V_A}{V_e}$  |
| 因子B  | $S_A= \sum_{i=1}^{n_A} \frac{(\sum x_{Bi})^2}{n_{Bi}} - CT$　  |  $\phi_B=n_B-1$ | $V_B=\frac{S_B}{\phi_B}$  | $F_{0B}=\frac{V_B}{V_e}$  |
| 相互作用A×B  | $S_{A \times B}= S_{AB} - S_A - S_B$　  |  $\phi_{A \times B}=\phi_A \times \phi_B$ | $V_{A \times B}=\frac{S_{A \times B}}{\phi_{A \times B}}$  | $F_{0B}=\frac{V_{A \times B}}{V_e}$  |
|  誤差e | $S_e=S_T-S_A-S_B - S_{A \times B}$  |  $\phi_e=\phi_T-\phi_A-\phi_B - \phi_{A \times B}$ | $V_e=\frac{S_e}{\phi_e}$  | ↑  |
|  全体T | $S_T=\sum x^2-CT$  |  $\phi_T=n-1$ |   |  ↑ |

※データを$x$、水準$A_i$のデータを$x_{Ai}$、水準$A_i$のデータ数を$n_{Ai}$、水準数を$n_A,n_B$、繰り返し数を$r$、$CT=\frac{(\sum x)^2}{n}$、$S_{AB}=\sum \frac{(\sum x_{AiBj})^2}{r}-CT$とする


### 最適条件の母平均の推定

点推定： $\hat{\mu} = \bar{x_{AiBj}}$
区間推定： $ \hat{\mu} \pm t(\phi_e,0.05)\sqrt{\frac{V_e}{n_e}}$

ただし、$n_e=\frac{n_A\dot{}n_B\dot{}r}{1+\phi_A+\phi_B+\phi_{A \times B}}$は有効反復係数(田口の公式)
【シェルスクリプト】配列に要素を追加する方法

## `array+=(value)`

次のように`+=`を記述することで配列に要素を追加できます。

```bash
array+=("追加したい値")
```

```terminal
$ array=("sample" "test")

$ array+=("example")

$ echo "${array[@]}"
sample test example
```

## `array[i]="value"`

また次のようにインデックスを指定して要素を追加することもできます。

```bash
array[インデックス]="追加したい値"
```

```terminal
$ array=("sample" "test")

$ array[2]="example"

$ echo "${array[@]}"
sample test example
```
「Webを支える技術」読書メモ#9 HTTPヘッダ

:::note info
本記事の内容
[Webを支える技術](https://amzn.asia/d/6TCP9kg)を読んだ際のノートのようなものです。
省略している部分もあり、書籍の内容を完全に要約するものではありません。

今回は第9章あたりの内容です。
:::

# 仕様
最初は[RFC 2616](https://www.ietf.org/rfc/rfc2616.txt)で定められたが、今は[RFC 9110](https://www.ietf.org/rfc/rfc9110.txt)で修正されている。

電子メールの仕様([RFC 822](https://www.ietf.org/rfc/rfc822.txt))のヘッダから育った。
※そのせいで生まれたバッドノウハウもある。

認証、キャッシュなどヘッダ＋メソッドやステータスコードといった組み合わせで実現できる機能もあったりする。

# よく使うヘッダ
### 日時系
Date, Expires などなど。全てGMT。

### MIMEメディアタイプ
* Content-Type（タイプ/サブタイプの形式）
    * [RFC 9110](https://www.ietf.org/rfc/rfc9110.txt) 8.3. Content-Type
* charset
    * Body内の情報よりもこちらが優先されるので注意
    * デフォルトはISO8859-1

### 言語タグ
Content-Language
* [RFC 9110](https://www.ietf.org/rfc/rfc9110.txt) 8.5. Content-Language

### コンテントネゴシエーション
* Accept
    * 処理できるメディアタイプ
    * qが大きいほうが優先
    * 対応なければ406
* Accept-Charset
* Accept-Language

### Content-Length
ボディの長さを指定して、ファイルサイズの解決をする。
静的ファイルなどのやり取りで活躍する。

:movie_camera: 動的な場合は...
チャンク転送でちょっとずつ転送する。
Tranfer-Encoding

# 認証
HTTPなのか、HTTPSなのかによってもおすすめは変わる。
HTTPSならSSL/TLSによって暗号化、認証、改ざんの検知ができるため。

### Basic
かんたんにデコードできるので、HTTP通信の場合は怖い。

### Digest
組み立て方は知ることができる。
auth-initでメッセージ全体のチェックができる。

メッセージ全体は平文なので注意:warning:
また、導入できる環境には制約がある。

### WSSE
標準じゃないので注意 :warning: 
Basic認証やDigest認証がだめな場合に検討する。

クライアント/サーバの両方がパスワードを保持する必要がある。

### OpenID
シンプルなシングルサインオン。

### OAuth
認可情報を委譲することで、Webサービス間でデータをやりとりする。

# キャッシュ
キャッシュ用ヘッダで制御とかができる。
有効期限なんかも設定できるが、有効期限1年位上は意味ないので非推奨。

条件付きGETでキャッシュが有効かどうか確認したりもできる。
If-XXXXなどを使う。

# Keep-Alive
クライアント/サーバ間のTCPコネクションを1つずつ切断していてはリクエストのたびに処理が大変なので、パイプライン化してまとめて接続し続けるためのヘッダ。
レスポンスを待たずに次のリクエストを送っちゃう。

# 標準仕様外だけどよく使われるヘッダ
### Content-Disposition
リソースのファイル名をサーバー側から指定するヘッダ。

### Slug
ファイル名のヒントをクライアント側から教えるヘッダ。
「Webを支える技術」読書メモ#8 HTTPステータスコード


:::note info
本記事の内容
[Webを支える技術](https://amzn.asia/d/6TCP9kg)を読んだ際のノートのようなものです。
省略している部分もあり、書籍の内容を完全に要約するものではありません。

今回は第8章あたりの内容です。
:::

## ざっくり仕様
[RFC 9110](https://www.ietf.org/rfc/rfc9110.txt)で定義されている。

* 1XX系 処理中「今やってるで」
* 2XX系 成功　「やったで」
* 3XX系 リダイレクト「あっちやで」
* 4XX系 クライアントエラー「やめーや」
* 5XX系 サーバーエラー「しんだわ」

という大まかな分類がある。

それぞれ1〜99まで定義されてるわけではなく、余っている番号があるので
サーバー側の実装者が独自に余っている番号を使う場合もある。
そういう場面でも上記のルールに従っていれば、知らないステータスコードでも100の位で雰囲気を掴むことができる。
（逆に言うとこれを無視した番号付けはやめましょう）

詳しくはIANAを見よう。

## よく見るコードたち
### 200系
* 200 OK
* 201 Created

### 300系
* 301 Moved Permanently
* 303 See Other
    * POSTで操作→GETで取得

### 400系
* 400 BAD Request
* 401 Unauthorized
* 404 Not Found

Bodyは好きにしてよい。
プロトコルはクライアントのAcceptヘッダ等で合わせてやる。

### 500系
* 500 Internal Server Error
    * クライアント側は未知の500系のステータスコードが返却された場合、これと同じとみなして処理するのが一般的
* 503 Service Unavailable

こちらもBodyは好きにしてよい。


---
### 余談 :coffee: エイプリルフールRFC

[RFC 2324](https://www.ietf.org/rfc/rfc2324.txt) Hyper Text Coffee Pot Control Protocol

コーヒーポットを制御するためのプロトコル。
大真面目に仕様がまとめられていて、`418 I'm a teapot` （コーヒーポットじゃないですティーポットです私）というステータスコードが定義されていたり、
拡張リクエストメソッドとして`BREW`メソッドがあったりする。

なんなら[RFC 7168]()で更新されてるらしい。

全然使う機会はなさそうだけど、今度ちょっと全文読んでみよう...:relaxed:
bladeの@includeの使い方

自分の会社のコードを読んでいてわからなかったので自分のために書いておきます。

``` 
//hello.blade.php
<div>
    <p>{{ $key }}</p>
    <p>{{ $key2 }}</p>
</div>
```

同じ階層のHello.blade.phpを読み込みたいなら
`@include('hello', ['key' => 'value','key2' => 'value2'],..)`
この一行でhello.blade.phpに値を渡し、表示させることができる。

メリットとしては、hello.blade.phpを使い回すことができるという点か。。
他にもありそうですが、今日はここまで。
また何かあれば書き足すかもしれません。
Android Studioの日本語化（M1 Mac）

Android Javaを触ってみることにし、Android Studioを触りやすいように[Pleiades](https://mergedoc.osdn.jp/)で日本語化したら立ち上がらなくなり、思いの外躓いたので備忘録として記します。
そして日本語化して学習を進めているのですが、[developers](https://developer.android.com/?hl=ja)の動画が英語なので、日本語化方しない方がわかりやすいかもしれません。
また、最初の環境設定で何を設定したらいいのかもまだわかっていないので、自分用に書き溜めていきます。

# Android Studioのインストール

[この記事](https://akira-watson.com/android/adt-mac.html)等を参考にAndroid Studioのインストールまで行いました。
この段階で、SDK 等の追加インストールで、何をインストールすべきかまだわからず、インストールをしなかったので、学習を終えた後に逆算的に追記します・・・。

# 日本語化

[この記事](https://zenn.dev/kurayasu/articles/c2d3bd2a046596)を参考に日本語化しました。

## Pleiadesでインストールしてしまった場合の対処方法

2023年2月現在、[Pleiades](https://mergedoc.osdn.jp/)での日本語化はできず、Android Studioが立ち上がらなくなりました。
アプリケーションの削除だけでは解決せず、完全削除しなければいけませんでした。

```title:ターミナルからの完全削除方法
rm -Rf /Applications/Android\ Studio.app
rm -Rf ~/Library/Preferences/AndroidStudio*
rm -Rf ~/Library/Preferences/com.google.android.*
rm -Rf ~/Library/Preferences/com.android.*
rm -Rf ~/Library/Application\ Support/AndroidStudio*
rm -Rf ~/Library/Logs/AndroidStudio*
rm -Rf ~/Library/Caches/AndroidStudio*
rm -Rf ~/.AndroidStudio*
rm -Rf ~/AndroidStudioProjects
rm -Rf ~/.gradle
rm -Rf ~/.android
rm -Rf ~/Library/Android*
```

[参考](https://www.imymac.jp/powermymac/uninstall-android-studio-mac.html)

- 立ち上がらない理由を調べる方法
アプリケーション > Android Studio.appで右クリック　> パッケージの内容を表示 を選択
![スクリーンショット 2023-02-19 20.13.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485388/59d9bd7e-fa45-6613-9c85-21d2e2069644.png)

Contents > MacOS > studio を起動
![スクリーンショット 2023-02-19 20.16.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485388/069aa578-ddd6-f17b-c673-4253e35e9609.png)

こうするとターミナルが立ち上がり、エラー内容がわかります。

# 学習教材とかのメモ

- [developers](https://developer.android.com/?hl=ja)

# GitHubとの連携

ついでにGitHubとの連携も記載します。

「GitHubでプロゼクトを共有」をクリックし、アクセストークンを発行し、設定するとOK
![スクリーンショット 2023-03-12 13.52.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485388/020ad720-7958-e1c8-8770-80ddb87e4d37.png)

コミットやプッシュも簡単
![スクリーンショット 2023-03-12 14.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485388/a563c83b-2874-34e3-466a-135674382717.png)
【初心者向け】pyenv installでエラーが出た時の対処法メモ

# 遭遇したエラー
pyenv install 3.7.5を実行したところ、以下のエラーがでた。
> Unexpected output of 'arch' on OSX

本記事ではこのエラー発生時に実施した対応について記載します。

# 環境
macOS Big Sur
ターミナル：amd64、x86_64
※共にHomebrewインストール済み


# 対応内容

エラー内容でググったところ、以下の記事がヒットしました。
https://qiita.com/tomtsutom0122/items/52487730001247fdc2c5

どうもpyenvがM1チップに対応していないことが原因で起きると記載されていました。
archコマンドでx86_64を指定してインストールコマンドを実行すればOKと書いてますが、私のMacにはx86_64のターミナルがあったので、こっちでインストールコマンドを実行しました。

【補足】
M1 Macでx86_64のターミナルを動かす手順は以下の記事が分かりやすいです。
ターミナルの設定をされてない方はこちらの記事を参照いただき、x86_64のターミナルを用意した後、下記内容を実施ください。
https://qiita.com/funatsufumiya/items/cec08f1ba3387edc2eed

## 今度は別のエラーが発生
x86_64のターミナルでインストールコマンドを実行すると、今度は以下のエラーが出ました。
> implicit declaration of function 'sendfile' is invalid in C99


このエラー対応として、以下を実施しました。
　zlib、bzipsの再インストール
　.zshrcファイルを編集

### ①zlib、bzipsの再インストール
まず、上記2パッケージの再インストールを実施しました。
```
brew reinstall zlib bzip2
```

### ②.zshrcファイルを編集
.zshrcファイルを編集し、以下を追記しました。
```.zshrc
export LDFLAGS="-L/usr/local/opt/zlib/lib -L/usr/local/opt/bzip2/lib"
export CPPFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/bzip2/include"
export CFLAGS="\
-I$(brew --prefix openssl)/include \
-I$(brew --prefix bzip2)/include \
-I$(brew --prefix readline)/include \
-I$(xcrun --show-sdk-path)/usr/include" \
export LDFLAGS="\
-L$(brew --prefix openssl)/lib \
-L$(brew --prefix readline)/lib \
-L$(brew --prefix zlib)/lib \
-L$(brew --prefix bzip2)/lib" \
```

ターミナルを再起動し、以下インストールコマンドを実行したところ、無事インストールできました。
```
pyenv install --patch 3.7.5 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)
```

# 参考資料
https://qiita.com/tomtsutom0122/items/52487730001247fdc2c5
ZIG SIM PROでSocket Errorが出た時の対処法

## 環境
* 制御PC - MacBook Air (M1, 2020) macOS Monterey
* 端末 - iPhone 14 Pro iOS 16.2

## やりたいこと
ZIG SIM PROを用いて、制御PCのTouchDesignerにNDIで映像を送信する。

## エラー
デフォルトの設定のまま、ZIG SIM PROを起動してみると...。
![IMG_6552.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361940/436c2374-a3c3-318b-4e67-944ccef8d32d.png)


あれれーー。おかしいなー。
iPadだとそのままNDIで映像送信できたのに、なんでiPhoneだとできないんだろう。

これはiOSバージョンの問題か、確かに[app storeのレビュー](https://apps.apple.com/gb/app/zig-sim-pro/id1481556614)に同じこと書いてる人いたな...。

## 解決方法
実はめちゃくちゃ簡単に解決できた。
iPhoneの「設定」→ 「ZIG SIM PRO」を見てみる。
![IMG_6551.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361940/d0ab670a-454b-950a-bc17-6c8cd576214c.png)
あれ、こんなところに<strong>「ローカルネットワーク」</strong>の設定がOFFになってる！！
![IMG_6553.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361940/e5376a3e-8a3b-35f8-681d-2be5c2ae44ea.png)
ここ変えたら、簡単に直った！！最高すぎ！！

<strong>良きNDIライフを。</strong>
ビット演算でフラグ管理【C++】

# はじめに
C++でビット演算。
すぐ忘れそうなので、メモ。

# やりたいこと
ビットをON/OFFに見立てて管理したい。
OFF(0)、ON(1)としてビットを立てたり削除したりしたい。

# 使うもの
## std::bitset
C++で数値をバイナリ形式に変換するための標準的なソリューション。
bitsetを使うと2進数⇔10進数の変換ができるし、なによりコードが見やすくなる。

#### 10進数を2進数に変換
```bitset<N>(A)```
Nはビット数を指定する。
8ビット(00001111等)で管理したい場合は8を指定する。

#### 2進数を10進数に変換
to_ulong()を使い、unsigned long型の整数に変換する。
```bitset<N>(A).to_ulong()```

# ビットを使ったフラグ管理
0番目のフラグが立っている状態は ```(1<<0)``` と表せる。
0番目と2番目と4番目のフラグが立っている状態は ```(1<<0) | (1<<2) | (1<<4)``` となる。
これを用いてフラグ管理をしていく。

## ビット bit に i 番目のフラグを立てる
```c++
bit｜= (1<<i);
```
## ビット bit に i 番目のフラグを消す
```c++
bit &= ~(1<<i);
```
## ビット bit に i 番目のフラグが立っているかどうか
```c++
if (bit & (1<<i)){
    return true;
}
```
## ビット bit に i 番目のフラグが消えているかどうか
```c++
if (!(bit & (1<<i))){
    return false;
}
```

# 実際のコード
```c++:main.cpp
#include <bitset>
#include <iostream>
using namespace std;

// 定数として宣言しておく
const uint32_t BIT_FLAG_0 (1<<0); // 0000 0001
const uint32_t BIT_FLAG_2 (1<<2); // 0000 0100
const uint32_t BIT_FLAG_4 (1<<4); // 0001 0000

int main()
{
    int32_t bit_flg = 0; 

    // 0,2,4にフラグが立ったビット
    bit_flg = BIT_FLAG_0 | BIT_FLAG_2 | BIT_FLAG_4;
    cout << "bit_flg 0,2,4:" << bitset<8>(bit_flg) << endl;

    // 2番目にフラグが立っているか確認
    if (bit_flg & BIT_FLAG_2) {
        cout << "the 2nd flag is up:" << bitset<8>(bit_flg) << endl;
    }

    // 2番目のフラグを消す
    bit_flg &= ~BIT_FLAG_2;
    cout << "bit_flg 0,4:" << bitset<8>(bit_flg) << endl;

    // 2番目にフラグが消えているか確認
    if (!(bit_flg & BIT_FLAG_2)) {
        cout << "the 2nd flag is gone:" << bitset<8>(bit_flg) << endl;
    }

    return 0;
}
```
# 実行結果
```
bit_flg 0,2,4:00010101
the 2nd flag is up:00010101
bit_flg 0,4:00010001
the 2nd flag is gone:00010001
```

# さいごに
苦手意識があっても理解できるとそんなに難しくない！
QC検定　ー　相関・回帰分析

# 相関分析

変数$x,y$の相関係数$r$を$n$組のデータから求める場合、$r$は以下のようになる
```math
r = \frac{S_{xy}}{\sqrt{S_x}\times \sqrt{S_y}}
```
ただし、
```math
\begin{align}
S_{x}&=\sum x_i^2 - \frac{(\sum x_i)^2}{n}\\
S_{y}&=\sum y_i^2 - \frac{(\sum y_i)^2}{n}\\
S_{xy}&=\sum x_i \dot{} y_i - \frac{(\sum x_i)(\sum y_i)}{n}
\end{align}
```

相関係数$r$は―1～1の範囲となり、相関の強さは以下の目安で判断する

| 範囲 | 相関の強さ |
|:-:|:-:|
| $r \geqq 0.8 $  |  強い相関 |
| $0.8 > r \geqq 0.6 $ | 相関がある  |
|  $0.6 > r \geqq 0.4 $   | 弱い相関がある  |
| $ r < 0.4 $  |  ほとんど相関がない |

# 単回帰分析（分散分析）

## 回帰モデル

変数$x$に対して、実測値$y$の母平均$E(y_i)=\mu_i$が以下の直線関係にあるとする。

$$ \mu_i = \alpha + \beta x_i $$

しかし、実際には実測値$y_i$は直線状にならず、ずれが発生する。その、残差変量を$\varepsilon_i$とすると、回帰のデータモデルは以下のようになる。

$$ \mu_i = \alpha + \beta x_i ＋ \varepsilon_i $$

$\alpha,\beta$は未知なので、推定値をそれぞれ$a,b$とすると、回帰のデータモデルは、残差を$E_i$とすると以下のようになる。

$$ y_i = a + b x_i ＋ e_i $$

残差の平方和が最小になるように、最小二乗法を用いて、$a,b$を求めると、以下のようになる。

```math
\begin{align}
a &= \bar{y} - b \bar{x}\\
b &= \frac{S_{xy}}{S_x}
\end{align}
```

実測値の変動$S_T$は、回帰による変動$S_R$と残差による変動$S_E$に分解できる。

```math
\begin{align}
S_T &= S_y\\
S_R &= \frac{(S_{xy})^2}{S_x}\\
S_E &= S_T - S_R = S_y - \frac{(S_{xy})^2}{S_x}
\end{align}
```



# 回帰分析の流れ

1. 変動$S_T,S_R,S_E$の平方和をもとめる。
1. $S_T,S_R,S_E$の自由度を求める。
1. $S_R,S_E$の不偏分散と分散比$F_0$を求める
1. 分散分析表を作る
1. 検定を行い分散分析の結果を判定する
1. 回帰係数を推定する

## 変動の平方和をもとめる。
```math
\begin{align}
S_T &= S_y\\
S_R &= \frac{(S_{xy})^2}{S_x}\\
S_E &= S_T - S_R = S_y - \frac{(S_{xy})^2}{S_x}
\end{align}
```
## 自由度を求める。

それぞれの自由度は以下の通り
```math
\begin{align}
\phi_T &= n-1\\
\phi_R &= 1\\
\phi_E &= n-2
\end{align}
```
## 不偏分散と分散比を求める

$S_R,S_E$の不偏分散と分散比$F_0$は以下の通り
```math
\begin{align}
V_R &= \frac{S_R}{\phi_R} = S_R\\
V_E &= \frac{S_E}{\phi_E} = \frac{S_E}{n-2}\\
F_0 &= \frac{V_R}{V_E}
\end{align}
```

## 分散分析表を作る

| 種別 | 　　平方和　　 | 自由度 | 不偏分散 | 分散比 |
|:-:|:-:|:-:|:-:|:-:|
| 回帰  |  $\frac{(S_{xy})^2}{S_x}$ | $1$  |  $S_R$  |$\frac{V_R}{V_E}$|
| 残差  |  $S_y - \frac{(S_{xy})^2}{S_x}$ | $n-2$  | $ \frac{S_E}{n-2} $  |↑|
| 合計  |  $S_y$ |  $n-1$  |   |↑|

## 検定を行い分散分析の結果を判定する

### 母分散の違いに関する検定を用いる場合

分散分析表で求めた分散比を用いて母分散の違いに関する検定を行い、その結果を用いて判定する。
帰無仮説が採択されたら、回帰による変動が有意となり、直線的な関係を考えることに意味があるといえる。

### 無相関の検定を用いる場合

検定統計量 $ t_0 = \frac{|r|\sqrt{n-2}}{\sqrt{1-r^2}} $ をもとめ、自由度n-2でt検定を行う。

## 回帰係数を推定する

回帰係数$a,b$の推定値は以下の通り
```math
\begin{align}
a &= \bar{y} - b \bar{x}\\
b &= \frac{S_{xy}}{S_x}
\end{align}
```
GASでスプレッドシートの別シートへのリンクを自動生成する方法

## この記事でできるようになること
- Google Spreadsheet（通称 スプレッドシート）のセルに別シートへのリンクを自動生成する
- 下記のような感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652652/a62cfe1f-4748-eaee-d88c-ab6e571bf171.png)

## 手順
1. Apps Scriptを開き、「シート名を取得する関数」と「シートへのリンクを取得する関数」をコピペして保存
1. HYPERLINK関数をセルに入力する

### 1. Apps Scriptを開き、「シート名を取得する関数」と「シートへのリンクを取得する関数」をコピペして保存
1. スプレッドシートを開く
1. `メニューバー > 拡張機能 > AppScript` を選択して、無題のプロジェクトを作成する
1. 下記をコピペして、保存する
→ GET_SHEET_NAME関数とGET_SHEET_LINK関数が利用可能になる
```js
function GET_SHEET_NAME(sheet_no) {
  return SpreadsheetApp.getActive().getSheets()[sheet_no].getSheetName();
}

function GET_SHEET_LINK(sheet_no) {
  return '#gid=' + SpreadsheetApp.getActive().getSheets()[sheet_no].getSheetId();
}
```

### 2. HYPERLINK関数をセルに入力する
1. シートの番号を確認する
    - 左からx番目のxがシート番号になる
    - xは0から始まる数字
    - なお、シートの並び順を変更するとシート番号も変化する
1. ハイパーリンクを置きたいセルに下記を入力する
    - 次の例は、左から0番目のシートを取得する場合の例
    - テキストリンクはシート名にしている（変更してもOK）

```
=HYPERLINK(GET_SHEET_LINK(0),GET_SHEET_NAME(0))
```
【備忘録】heroku更新

```ターミナル
git add -A
```

```ターミナル
git commit -m "Update application"
```

```ターミナル
git push heroku main
```

```ターミナル
heroku run rails db:migrate
```

参考記事
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39
Flutterでアダプティブ対応をする

# 概要
モニターで見る時とスマホで見る時だとデザインを変えたい
今は公式のやり方でサクッとできるのかなーと思ってたけど、実装見たら別にそんなことはなく、画面幅を取得して表示非表示を切り替えているだけだった
銀の弾丸などないのだ……

# 完成系
[GitHub](https://github.com/yuki-kamikita/adaptive_sample)

[Flutter公式のNavigationRailの動画](https://www.youtube.com/watch?v=y9xchtVTtqQ&ab_channel=Flutter)っぽい形
横幅が広い時は[NavigationRail](https://api.flutter.dev/flutter/material/NavigationRail-class.html)、狭い時は[NavigationBar](https://api.flutter.dev/flutter/material/NavigationBar-class.html)にする

![スクリーンショット 2023-02-24 21.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620387/23a8f768-36e5-c59c-df55-dcde76c649a7.png)
![スクリーンショット 2023-02-24 21.32.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620387/4af64ca8-5da8-c201-3fbe-c89690ec3a79.png)

# 実装
### 画面幅を取得する
[adaptive_breakpoints](https://pub.dev/packages/adaptive_breakpoints/)を使用します
更新はあんまりされてないしバージョンも0.だけど、Material.io公式のライブラリだからこれで大丈夫だろう

```dart
import 'package:adaptive_breakpoints/adaptive_breakpoints.dart';
import 'package:flutter/material.dart';

bool isDesktop(BuildContext context) {
    return getWindowType(context) >= AdaptiveWindowType.medium;
}
```

`getWindowType(context)`で現在の画面幅を取得

`AdaptiveWindowType`でxsmall〜xlargeの5段階のサイズが定義されてるから、お好きなサイズを指定する
ここがブレークポイント（デザインの変わる境界）になる
今回はisDesktopの値によって画面のデザインを切り替える

### 画面幅によってデザインを変える
```dart
import 'package:flutter/material.dart';

// StatefulWidgetは省略

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.title),),

      // ここで単純に表示/非表示の切り替え
      // ボトムナビゲーションバーは幅が狭い時のみ表示
      bottomNavigationBar: Visibility(
        visible: !isDesktop(context),
        child: _navigationBar(),
      ),

      body: Row(
        children: [
          // ここで単純に表示/非表示の切り替え
          // ナビゲーションレールは幅が広い時のみ表示
          Visibility(
            visible: isDesktop(context),
            child: _navigationRail()
          ),

          Expanded(child: Center(child: Text(currentDisplayType(context).name))),
        ],
      ),
    );
  }

  NavigationBar _navigationBar() {
    // 省略
  }

  NavigationRail _navigationRail() {
    // 省略
  }
}

```

# この後の展開
[adaptive_components](https://pub.dev/packages/adaptive_components)
CSSライブラリによくあるグリッド状のデザインを、画面幅を変えた時に何マス表示するか、みたいなことをするライブラリっぽい

[adaptive_navigation](https://pub.dev/packages/adaptive_navigation)
NavigationRailじゃなくてDrawerを使いたい時はこれ使うと良さそう

詳しくはここら辺読んで
[【Flutter】material.ioのadaptive系ライブラリを使用してレスポンシブなポケモン図鑑を作る](https://qiita.com/alpha2048/items/fd6d829a23ddd171065d)

# 参考文献
[codelab](https://codelabs.developers.google.com/codelabs/flutter-boring-to-beautiful?linkId=8593106&hl=ja#5)

# おまけ
これ書いてる時に見つけたけど、銀の弾丸、あるっぽい
実際に使う時が来たら見てみよう
[responsive_framework](https://pub.dev/packages/responsive_framework)
[【Flutter】responsive_frameworkを試す](https://zenn.dev/slowhand/articles/d70ebdaea55af7)
vimのよく使いそうな基本的操作についての備忘録

vimについて学習したので、基本的な操作方法について個人的によく使いそうだと感じたものを備忘録として残しておくものです。

### カーソル移動等の操作
| 操作 | キー |
| :- |:- |
| 上 |k  |
| 下 |j  |
| 左 |h  |
| 右 |l  |
| 行の先頭にジャンプ| 0  |
| 行の終端にジャンプ| $  |
| (n)行目に移動 | :(n)  |
| ファイルの先頭に移動 | gg  |
| ファイルの最後に移動 | G  |

### 編集系の操作
| 操作 | キー |
|:- |:- |
| i | インサートモード |
| a | 次の文字からインサートモード |
| x | 1文字削除 |
| dd | 1行削除 |
| dw | 単語の削除 |
| (n)dd | (n)行削除 |
| u | undo |
| Ctrl + r | redo |
| yy | 1行コピー |
| (n)yy | (n)行コピー |
| p | 下の行にペースト |
| P | 現在行にペースト |


### ファイルの保存等
| 操作 | キー |
|:- |:- |
| ファイルの保存 | :w |
| 編集終了 | :q |
| 保存しないで編集終了 | :q! |
| 保存して終了 | :wq |

### 検索と置換
| 操作 | キー |
|:- |:- |
| /(search)  | 検索 |
| n | 次の検索結果に移動 |
| N | 前の検索結果に移動 |
| :%s/(search)/(replace)/g | 一括置換 |
| :%s/(search)/(replace)/gc | 1カ所ずつ置換 |
Web Share API を使用して iOS で複数画像をカメラロールに保存する

## 要件
iOSでダウンロードボタンをクリックして `ファイル` ではなく `カメラロール` に複数画像を保存させる
下記サンプルでは `imageUrls` で定義されているものが対象
iOS以外はaタグに画像ファイル配置してダウンロードさせる

```ruby:js
document.getElementById('js-download').addEventListener('click', async () => {
  const imageUrls = [
    '/150x150.png',
    '/1200x150.png',
  ];

  if (iOS) { // iOSかの判定は別途行う
    Promise.all(imageUrls.map(imageUrl => fetch(imageUrl).then(response => response.blob())))
      .then(blobs => {
        const files = blobs.map((blob, index) => new File([blob], `image${index}.png`, {type: 'image/png'}));
        if (navigator.share) {
          navigator.share({
            files,
            title: 'タイトル',
            text: 'テキスト',
          });
        }
      });
  } else {
    imageUrls.forEach((imageUrl, index) => {
      fetch(imageUrl)
        .then(response => response.blob())
        .then(blob => {
          const file = new File([blob], `image${index}.png`, {type: 'image/png'});
          const a = document.createElement('a');
          a.href = URL.createObjectURL(file);
          a.download = file.name;
          a.click();
        });
    });
  }

});
```



### Web Share API
https://caniuse.com/web-share
【SwiftUI】強制アップデートアラートを表示させる

# はじめに
ユーザーには最新のバージョンを使って欲しいです。
ですのでAppStoreに最新バージョンがリリースされたらアプリに通知します。
よく使う機能なのでライブラリを作成しました。

作成したライブラリの使い方を紹介します。

https://github.com/SNQ-2001/AppVersionMonitorSwiftUI

# サンプルアプリ
![simulator_screenshot_6CF8E9C7-F238-466D-B211-4AD971938E03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/035c9151-0dc1-51f6-e277-a5f03a7294b6.png)

# ライブラリの導入
① 「File」を選択します
② 「Add Packages...」を選択します
![スクリーンショット 2023-02-24 21.36.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d2d37573-24f3-ecfb-6fbd-bde65ea4d815.png)

③ `https://github.com/SNQ-2001/AppVersionMonitorSwiftUI`を検索します
④ 「Up to Next Major Version」を選択します
⑤ 「Add Package」を選択します
![スクリーンショット 2023-02-24 21.39.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e49db481-dab1-de09-1326-2adfc071c323.png)

⑥ 「Add Package」を選択します
![スクリーンショット 2023-02-24 21.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/fb9a67c9-e9e9-2eba-7510-68be87dbd1b7.png)

# 実装
```swift
import SwiftUI
import AppVersionMonitorSwiftUI

struct ContentView: View {
    @State var isAlert: Bool = false
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
        }
        .alert(isPresented: $isAlert) {
            Alert(title: Text("お知らせ"), message: Text("最新バージョンがあります"), dismissButton: .default(Text("OK")) {
                // TODO: ここでAppStoreを開く
            })
        }
        .appVersionMonitor(id: 1570395606) { status in
            switch status {
            case .updateAvailable:
                isAlert = true
                print("アップデートがあります")
            case .updateUnavailable:
                print("アップデートがありません")
            case .failure(let error):
                print("エラーが発生しました: \(error)")
            }
        }
    }
}
```

# アプリIDについて
`id`でしている数字はアプリIDです。
```swift
.appVersionMonitor(id: 1570395606) { status in
```
アプリIDはAppStoreのURLで確認できます。
```url
https://apps.apple.com/jp/app/g-search/id1570395606
```
後ろについている数字が`id`です。

リリース前のアプリのアプリIDを知る方法は別記事で紹介しています。

https://qiita.com/SNQ-2001/items/df93fc0804666a8c3263

# 注意事項
アプリバージョンの指定方法は「Semantic Versioning 2.0.0」を採用しています。

例：`1.0.0` `2.1.3` `3.10.1`

「Semantic Versioning 2.0.0」以外のバージョンの指定方法は使用できません。

「Semantic Versioning 2.0.0」については、以下の記事がわかりやすかったです。

https://qiita.com/usamik26/items/c8911219b610101e69a9

# おわり
スターください！
IssueやPRもお願いします！

https://github.com/SNQ-2001/AppVersionMonitorSwiftUI
[Android][NDK]Kotlinのint配列をCに渡したいとき

## やりたいこと
- NDK使ってる
- Kotlinでintの配列作ったけど、それをCの関数に渡したい

## やること
### 1. kotlinでint配列を作る
```kotlin:MainActivity.kt
        val intArray = IntArray(10000) { 10000 - it }
```

### 2. int配列をLongにする（配列のポインタを渡せるようにするため）
   （ChatGPTより：Kotlinの配列をC言語が認識できる形式に変換するには、toLongArray()メソッドを使用して、配列の要素をLong型に変換し、そのポインタを取得することができます。）
```kotlin:MainActivity.kt
        val longArray = intArray.map { it.toLong() }.toLongArray()
```
 
### 3. Cの関数に引数としてlong配列、long配列のサイズを渡す
```kotlin:MainActivity.kt
        cBubbleSort(longArray, longArray.size.toLong())
```

第１引数にjlongArray型、第２引数にjlong型でlong配列のサイズを渡す。
（バブルソートをしているのでcBubbleSortっていう名前をつけてます）
    
### 4. CでGet<PrimitiveType>ArrayElementsを使って、配列のポインタを読み取る
```C:bubble_sort.c
    JNIEXPORT void JNICALL
    Java_......_MainActivity_cBubbleSort(JNIEnv *env, jobject javaThis,
                                         jlongArray long_array_pointer, jlong length){
    int *cLongArray = (int *) (*env)->GetLongArrayElements(env, long_array_pointer, 0);

        // ...以下好きな処理

    }
```

### 5. 処理の終わりにReleaseして配列を解放する
```C:bubble_sort.c
    (*env) ->ReleaseLongArrayElements(env, long_array_pointer, (jlong *) cLongArray, 0);
```

## 全コード
```kotlin:MainActivity.kt
    class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val intArray = IntArray(10000) { 10000 - it }
        val longArray = intArray.map { it.toLong() }.toLongArray()

        //Cの関数
        cBubbleSort(longArray, longArray.size.toLong())

      }

    private external fun cBubbleSort(longArray: LongArray, length:Long)

    companion object {
        init {
            System.loadLibrary("bubblesort")
        }
     }
  }

```

```C:bubble_sort.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>

JNIEXPORT void JNICALL
Java_...._MainActivity_cBubbleSort(JNIEnv *env, jobject javaThis,
                                   jlongArray long_array_pointer, jlong length) {
    int *cLongArray = (int *) (*env)->GetLongArrayElements(env, long_array_pointer, 0);

    int i, j, temp;
    for (i = 0; i < length; i++) {
        for (j = i + 1; j < length; j++) {
            if (cLongArray[i] > cLongArray[j]) {
                temp = cLongArray[i];
                cLongArray[i] = cLongArray[j];
                cLongArray[j] = temp;
            }
        }
    }
    (*env) ->ReleaseLongArrayElements(env, long_array_pointer, (jlong *) cLongArray, 0);
}

```





## 参考
https://developer.android.com/training/articles/perf-jni?hl=ja#primitive-arrays
https://stackoverflow.com/questions/67032412/how-can-i-import-arraymat-to-jni-from-kotlin
https://stackoverflow.com/questions/24649808/how-to-pass-byte-array-from-android-java-class-to-jni-c-ndk
http://web.mit.edu/javadev/doc/tutorial/native1.1/implementing/array.html
ChatGPTを使った日報活用

# 日報をChatGPTに通して気付きを生む方法
私は日々の業務で得た気付きをOneNoteに記載する事で、1日に１つは成長を残すという事を心がけている。
そんな中で、この試みをより意味のあるものにするべく、殴り書きのTipsをChatGPTを使い膨らませ、Qiitaの記事にしてしまおうと考えた。
例えば、こんな日報（の一部）があるとする。

※本日得たTips/工夫
- スライド作成のショートカット(PPT)
    - Shift(＋Ctrl)＋上下左右: オブジェクトの拡大・縮小
    - Altキー＋1→L,H,…でオブジェクトの整列(クイックアクセスに登録済)
- Powertoysを使ってCapslockをAltキーに変更済
- かざぐるマウス導入。マウスジェスチャ。

上記を切り取って、ChatGPTに「上記の本日学んだ事リストを膨らませて、それぞれの項目についてTipsを纏めた記事をマークダウン記法で書いて」とぶん投げて少し校正してできたのが以下の記事である。

## スライド作成のショートカット (PPT)
PowerPointでスライド作成を行う際に役立つショートカットを紹介します。

- オブジェクトの拡大・縮小：Shift (＋Ctrl) + 上下左右キー
- オブジェクトの整列：Altキー + 1 → L、H、C、Eなど
    - オブジェクトの整列をクイックアクセスツールバーに登録する必要あり
- スライド・オブジェクトのコピペ：Ctrl + D
- グループ化：Ctrl + G
- グループ解除：Ctrl + Shift + G
- 設定の表示：Alt + F + T
- フォントの拡大・縮小：Ctrl + Shift + >または<
これらのショートカットを使うことで、スライド作成をスムーズに行うことができます。

## Powertoysを使ってCapslockをAltキーに変更
キーボードのキーをカスタマイズすることで、より効率的に作業を進めることができます。CapslockをAltキーに変更する方法は以下の通りです。

Powertoysをダウンロードしてインストールする。
「Keyboard Manager」を開き、キーのリマップを設定する。
Capslockを選択し、「Alt」を入力する。
「OK」をクリックして設定を保存する。
また、以下のソフトウェアを使うことでもキーボードのキーをカスタマイズすることができます。

- KeyTweak: キーの再マップが可能なソフトウェア
- AutoHotkey: キーボードのキーを再マップすることができます。
# かざぐるマウス導入
かざぐるマウスは、手の動きでカーソルを操作することができるマウスです。以下のような使い方があります。

かざぐるマウスの設定を調整する
マウスジェスチャを使う
マウスポイントのカスタマイズ
また、以下のマウスジェスチャソフトウェアも使うことができます。

- StrokeIt
- gMote
以上のTipsを活用して、より効率的な作業を行いましょう。

# 終わりに
日々1つはスキルアップを重ねて、日進月歩キャリアアップを図っていきたい。
ChatGPTというスーパーコンテンツを相棒に、より効率的に進化していけるとよいと思った。
インデックスシグネチャのキーに型付けしたい

インデックスシグネチャ（objectみたいなやつ）のキーに型付けしたいけど、地味にやり方を忘れるのでメモ

### string or number
```typescript
type A = {
  [key: string]: string;
}
```

### 独自の型定義の場合
```typescript
type Key = "one" | "two" | "three" | "four";
type MapNumber = {
  [key in Key]: number;
}

const mapNumber: MapNumber = {
  "one": 1,
  "two": 2,
  "seven": 7 // error '"seven"' does not exist in type 'MapNumber'
}
```
【GAS】スプレッドシートとSlackの同期

# はじめに
先日インターン先でこういった依頼がありました。
「アポ管理をしているスプレッドシートで期日の2日前なってもアポ担当者が未記入の時に、slackを飛ばすコードを書いて欲しい」

普段はpythonしか書かないのでjavascript初挑戦でしたが、ChatGPTに聞きながらコードを書いていきました！

# 必要なもの
- 通知を飛ばすSlackのWebhook URL　([取得する参考記事](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)）
- 使うスプレッドシート

# やっていきます！
スプレッドシート画面の「拡張機能」→「Apps Script]からコードを書く画面に飛びます。

ここでは
- A列に企業名
- B列にアポ担当者
- C列に "2023年2月6日月曜日"などのアポの日付

が記載されているとします。（ご自身のアポシートに合わせて変更してください）

以下コード例です！
```
function sendNotification() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastRow = sheet.getLastRow();
  var today = new Date();
  var messages = [];
  
  for (var i = 2; i <= lastRow; i++) {
    var B_value = sheet.getRange("B" + i).getValue();
    var C_value = sheet.getRange("C" + i).getValue();
    
    if (B_value == "" && (new Date(C_value) - today) / (1000 * 60 * 60 * 24) <= 2) {
      var A_value = sheet.getRange("A" + i).getValue();
      var message = "A_value+"の担当が未設定です。記入をお願いします.";
      messages.push(message);
    }
  }
  
  if (messages.length > 0) {
    var slackUrl = "通知を飛ばしたいslackのurl"
    var payload = {
      "text": messages.join("\n\n")
    };
    var options = {
      "method": "post",
      "payload": JSON.stringify(payload)
    };
    UrlFetchApp.fetch(slackUrl, options);
  }
}
```
以上を画面に貼り付けて保存します。

# 毎日勝手に実行するようにする
「トリガー」→「トリガーの作成」からトリガーの追加をします

以下のように設定します
- 「実行する関数を選択」→「sendNotification」
- 「イベントのソースを選択」→「時間主導型」
- 「時間ベースのトリガーのタイプを選択」→「日付ベースのタイマー」
- 「時刻を選択」→自分は「午前９時〜１０時」

これで毎日9〜１０時にプログラムが実行されます！

試しにエディタで実行を押して通知が飛ぶか試してみてください！
Sphinx+VSCodeでプレビューを見たい！

# 環境
* Windows10
* python 3.9.7
* sphinx 4.2.0
* VSCode

# 方法
以下の拡張機能をインストールする．
* reStructuredText
* Extension Pack for reStructuredText

/.vscode/settings.jsonにこれを書く．
```json:settings.json
{
    "esbonio.sphinx.buildDir" : "${workspaceFolder}/_build/html",
    "esbonio.sphinx.confDir"  : "${workspaceFolder}",
    "esbonio.sphinx.srcDir"   : "${workspaceFolder}"
}
```

うまくいくとこんな感じになる．
![2023-02-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642842/320e4fb3-dd30-637d-f9c8-39bbe50b4c75.png)
# 備考
"Extension Pack for reStructuredText"をインストールし忘れると生のhtmlのプレビューになってしまう...

# 参考文献
https://docs.restructuredtext.net/

https://marketplace.visualstudio.com/items?itemName=lextudio.restructuredtext-pack

https://docs.restructuredtext.net/articles/configuration
FastAPIの422エラー（Unprocessable Entity）をデバッグする

# はじめに

FastAPIを利用していると、たびたび422エラーが発生することがあります。
これは主に「リクエストのデータの型が、サーバが期待しているものと異なる」場合に発生します。
デフォルト状態では、FastAPIはこの様なエラーが発生した際に、その詳細について出力しません。
そのため、なぜエラーが起きたか？を確認できず、しばしば困ったことになります。

今回はデバッグ向けに、422エラーが発生した際にログを出力するように設定しよう、というの内容です。

# 解決方針

FastAPIがリクエストのバリデーションに失敗した際のカスタム例外ハンドラを設定し、
422エラーを返す際にエラー内容を出力するようにします。

https://fastapi.tiangolo.com/ja/tutorial/handling-errors/#install-custom-exception-handlers

# 実装

例として、POSTのエンドポイントを用意します。
```python
from pydantic import BaseModel
from fastapi import FastAPI,

app = FastAPI()

class Name(BaseModel):
    name:str

@app.post("/name")
def _name(data:Name):
    return {"name":data.name}
```

このアプリケーションに`exception_handler`を登録します。
このハンドラーは、アプリケーションでエラーが発生した際に呼び出す関数を設定することができます。
今回は`RequestValidationError`が発生した際に呼び出されるように設定しました。

```python
from pydantic import BaseModel
from fastapi import FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse

app = FastAPI()

@app.exception_handler(RequestValidationError)
async def handler(request:Request, exc:RequestValidationError):
    print(exc)
    return JSONResponse(content={}, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)


class Name(BaseModel):
    name:str

@app.post("/name")
def _name(data:Name):
    return {"name":data.name}
```

そして、例えば`{"nama":"Taro"}`のような誤ったデータをPOSTしてしまうと以下のような内容が出力されます。
```
1 validation error for Request
body -> name
  field required (type=value_error.missing)
```

これでPOSTしたデータの誤りを確認することができますね。

# まとめ

今回はFastAPIの422エラーが発生した際に、その詳細を出力する方法を見てきました。
紹介した例のように、単なるデバッグ目的の場合は`print`を利用する方法でよいかとは思いますが、
しっかりログを記録したい場合は`logger`の利用を検討したほうが良いでしょう。

# 参考

[Handling Errors - FastAPI](https://fastapi.tiangolo.com/ja/tutorial/handling-errors/#install-custom-exception-handlers)
すんごい馬鹿っぽいJKの喋り方で深層学習を教えてもらった





## JKの喋り方で深層学習を教えて

![スクリーンショット 2023-02-24 20.18.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/fbc777b7-cb4b-b80d-adfe-edffae999a2a.png)

まだまだ足りない


## もっとJKらしく

![スクリーンショット 2023-02-24 20.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/c57a74ad-51b5-4185-b2ba-d374a5e20497.png)

いい感じ。でも君ならもっとできるはず

## まだまだ足りない もっとJKらしく

![スクリーンショット 2023-02-24 20.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/5603ac57-4602-0935-fa73-8d5388536d57.png)

うむ。とてもいい...最後に人押し

## 若者言葉を使って！


![スクリーンショット 2023-02-24 20.23.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/57697826-299b-ff1a-b916-7b6732f2e703.png)

なぜかヤングメンが出てきてしまった。

## 本題:すんごい馬鹿っぽいJKの喋り方で！


![スクリーンショット 2023-02-24 20.25.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/7dba792e-23e0-aa57-2d88-f30db9106316.png)

わっしょーい！
AWS CDKの "CDKToolkit" を削除(初期化)する

`cdk bootstrap` で作成される `CDKToolkit` スタックを初期化するには、以下の２手順でOKです。

1. AWS CloudFormation の `CDKToolkit` スタックに紐づいている Amazon S3 Bucket を削除する
2. `CDKToolkit` スタックを削除する

紐づいているバケットは、`CDKToolkit` 内の "リソース" で見つけることができます。

### 解説

`cdk bootstrap` では、以下のリソースが作成されます。

- AWS CloudFormation / スタック
    - `CDKTookkit`
- Amazon Systems Manager / パラメータストア
    - `/cdk-bootstrap/**`
- Amazon Elastic Container Registry(ECR) / リポジトリ
    - `cdk-**-container-assets-**`
- AWS IAM / ロール
    - `cdk-**-role-**`
- Amazon Simple Storage Service(S3) / バケット
    - `cdk-**-assets-**`

`CDKToolkit` を削除すると、 Amazon S3 バケット**以外**は削除されます。S3 バケットは別途削除しましょう。

### 再び行うには？

`cdk bootstrap` しましょう。

EoT
【VSCode】Dev Containersをコマンドで起動する方法


VSCodeのコマンドパレットから`Dev Containers: Install devcontainer CLI`を選択し実行します。

VSCodeからインストールした場合には`devcontainer open`コマンドが使用できます。

```terminal
$ devcontainer --help
devcontainer <command>

Commands:
  devcontainer open [path]          Open a dev container in VS Code
  devcontainer up                   Create and run dev container
  devcontainer set-up               Set up an existing container as a dev container
  devcontainer build [path]         Build a dev container image
  devcontainer run-user-commands    Run user commands
  devcontainer read-configuration   Read configuration
  devcontainer features             Features commands
  devcontainer templates            Templates commands
  devcontainer exec <cmd> [args..]  Execute a command on a running dev container

Options:
  --help     Show help                                                                     [boolean]
  --version  Show version number                                                           [boolean]

devcontainer@0.29.0 /Users/username/.vscode/extensions/ms-vscode-remote.remote-containers-0.275
.1
```

次のように`devcontainer open`コマンドを実行するとカレントディレクトリでDev Containerを開けます。

```terminal
devcontainer open .
```



### npmでインストールする

次のコマンドを実行することでインストールできます。

```terminal
npm install -g @devcontainers/cli
```

npmでインストールした場合には`devcontainer open`コマンドは使用できません。

```terminal
$ devcontainer --help
devcontainer <command>

Commands:
  devcontainer up                   Create and run dev container
  devcontainer build [path]         Build a dev container image
  devcontainer run-user-commands    Run user commands
  devcontainer read-configuration   Read configuration
  devcontainer features             Features commands
  devcontainer templates            Templates commands
  devcontainer exec <cmd> [args..]  Execute a command on a running dev container

Options:
  --help     Show help                                                 [boolean]
  --version  Show version number                                       [boolean]
```

しかし次のようにコマンドを実行するとDev Containerを開けます。

```terminal
code --folder-uri "vscode-remote://dev-container%2B$(printf "%s" "/path/to/host/project" | xxd -p -c 256)/path/to/devcontainer/workspaceFolder"
```

- `printf "%s" "/path/to/host/project" | xxd -p -c 256`
  ホスト側のプロジェクトルートへのパスを16進数に変換[（`xxd`コマンドについて）](https://atmarkit.itmedia.co.jp/ait/articles/1811/01/news036.html)。

上記の記述は`~/Library/Application Support/Code/User/globalStorage/storage.json`で見つけることができます。

```terminal
`grep "vscode-remote://dev-container%2B$(printf "%s" "/path/to/host/project" | xxd -p -c 256)/path/to/devcontainer/workspaceFolder" \
    "${HOME}/Library/Application Support/Code/User/globalStorage/storage.json"`
```
[vim] カーソル下のパスを開く gf

vimには「カーソル下のパスを開く」という機能がありますので紹介します。

```vim
(パスにカーソルを合わせて)
gf
リンクの場合はgx
```

ノーマルモードで使います。
この『パス』はフルパスでも相対パスでも使えます。
たとえばvimで開いたファイルに「詳しくは web.de とよくいうけれど」という文章があったとします。
web.deにカーソルを合わせてgfとキーを押せばファイルを開いてくれます。
(web.deというファイルが、カレントかホームディレクトリにあればの話です)

## 注意点
- パスの前後にスペースか改行キーが必要
- 編集中でまだ保存していない場合は開かない
- 元のファイルが見えなくなってしまう
(元のファイルへは`ctrl-o`または`ctrl-^`で戻ります)

## 私の使い方
ここからはvimのgfという便利なコマンドを使う自作リンク集を紹介します。
ウィンドウズでいえば一つのフォルダにファイルのショートカットを集めたものを想像していただければいいと思います。

私は受信したメールで、面白い表現をされていたり、参考になる表現を見かけたらコピペしてテキストファイルにまとめています。ネット上で見つけたテンプレートなども入れています。
gitやrailsなどでは最初にやっておく設定や使う上での順番、あまり使わないコマンドやオプションを、テキストにメモしています。
プログラムでは汎用性のあるルーチンや関数の説明、小技集をテキストにまとめています。
もちろんvimに関しても作っています。
これらは自作の取扱説明書やテンプレート集ということになります。
この取説たちを手軽に呼び出せるようにパスを集めたテキストファイルを用意します。

```txt:C:/himitsu/hanazono.txt
# 取扱説明書
C:/himitsu/mail_text.txt
C:/himitsu/git.txt
C:/himitsu/python.py
C:/himitsu/ruby.rb
C:/himitsu/rails.txt
C:/himitsu/vim.vim
$MYVIMRC

# 作業中
H:/projects/project32/README.md
C:/atare/takaraku.ji
C:/atare/manba.ken
I:/dethn/ote/syanai.py
I:/dethn/ote/syagai.py
```

このテキストファイルをvimから呼べるようにします。

```vimrc
nnoremap <Space>m :topleft 42vnew C:\himitsu\hanazono.txt<CR>
```

上の例ではノーマルモードのときにスペースmで、画面を分割し、42幅の新しいウィンドウに指定のファイルを開きます。
そしたら紹介したgfでリンク先を開いて参照します。


## 工夫
gfで新しいファイルを開くと、元のファイルが見えなくなってしまうので、別ウィンドウや新しいタブで開けるようにするとより便利になると思います。

作業する環境が変わるのであれば、参照するファイルはUSBメモリなど入れておくと便利だと思います。


## おしまい
度忘れしたgfというコマンドを紹介しました。
恥ずかしながら私の使っている方法も記載しました。
リンク集を開いてから目的のファイルを開くというひと手間かかるやり方ですので、目的のファイルを直接開くやり方もあると思います。(この場合はgfは必要ありませんね)
ただ私にとって、個々の取扱説明書は日々育ててきたものですので、それが並んだリンク集は煮詰まったときなど、ふと開いてしまう不思議な存在になっています。
(私にとって:smileのような存在？)
gfはシンプルですが、素晴らしい機能だと思います。便利な使い方や面白い使い方などありましたら教えてください。

ではみなさまもよいvim lifeを！
google test trouble shoot

# まず

```
sudo apt install googletest
```
を使うのが一番楽です。

# buildするときは・・・

```
$ sudo apt install build-essential git cmake libgtest-dev libstdc++-dev clang lldb lld
```

```libstdc++-dev```は```libstdc++-12-dev```でもよいかもです(環境による)


```
$ git clone https://github.com/google/googletest.git
$ cd googletest
$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install
```

# trouble

```
build$ cmake ..
-- The CXX compiler identification is GNU 11.3.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - failed
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - broken
CMake Error at /usr/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake:62 (message):
  The C++ compiler

    "/usr/bin/c++"

  is not able to compile a simple test program.
..snip..
```

```
$ sudo apt remove gcc
```

```
$ sudo apt install clang-15
```

```
$ sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-15 1
$ sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-15 1
```

```
$ cd ~/work/googletest
$ rm -rf build
$ mkdir build
$ cd build
$ cmake ..
$ make -j 4
$ sudo make install
```

のように、一度clang++に切り替えて、再度buildフォルダーを作って、cmake ..し直せばうまくいきます。
Windows上で、Atcoderのローカルテスタを使ってPythonプログラムを実行する際につまずいたことメモ


Atcoder Heuristic Contest(AHC)のローカル版テスタを使った際にちょっとつまずいたので覚書として残しておく。

## 問題

OSはWindows10を使用。Python3とRustがすでにインストールされている状態。
Atcoderのコンテストサイトからツール：「ローカル版」をダウンロード・展開し任意の場所に移す。「サンプルコード(C++,Python)」もダウンロード・展開し、先ほどの「ローカル版」の`tools`フォルダ内に`sample_submission.py`をコピー＆ペーストしておく。

サンプルコードをテストしようと思い、コマンドプロンプトへ
`cargo run --release --bin tester python3 sample_submission.py < ./in/0000.txt > out.txt`
と打って実行した。
　その結果、パーミッションエラーが返ってきた。

![スクリーンショット 2023-02-25 090824.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253018/e34548aa-2875-6226-8bca-e9bcfe3c532a.png)

> Python Your program has terminated unexpectedly
> thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 5, kind: PermissionDenied, message: "アクセスが拒否されました。" }', src\bin\tester.rs:97:22

## こうしたら動いた

`python3` を`PY` へ変える。

つまり、以下のようなコマンドにする。
`cargo run --release --bin tester PY sample_submission.py < ./in/0000.txt > out.txt`

Powershell（VSCodeのターミナル含む）上で動かす場合は、

`cat ./in/0000.txt | cargo run --release --bin tester PY sample_submission.py > out.txt`


実行するPythonのバージョンを指定したいときはフルパスを入れる。

`cargo run --release --bin tester （自分でインストールしたpython.exeのフルパス） sample_submission.py < ./in/0000.txt > out.txt`




## なぜ動いたか

「Powershellの`gcm python3`コマンドが教えてくれるフルパス」＝「普段使っているpythonの実行ファイルのフルパス」だと思いこんでいた。

設定を特に触っていない限り`python3`コマンドで呼び出されるのは、Windowsにデフォルトで入っている`python3.exe`である。`python3.exe`がいる場所はPowershell上で`gcm python3`と入れることで分かる。クリックしてみるとわかるが、この`python3.exe`、MicrosoftストアにつながるだけでPythonプログラムを動かす機能は無い。これがパーミッションエラーと返ってきていた原因のようだ。対して、`PY`というコマンドではパイソンランチャーが起動しインストールされている中から適切なバージョンが選んで実行される。

## 参考

https://qiita.com/saito_ry/items/7b449966259b7aac77bd
App Runner で Global LoadBalancer （勝手に命名）を構築！

# 背景
最近血圧が高いままの [@\_\_\_nix___](https://twitter.com/___nix___) です。

さて、AWSサービスを使っていて、冗長化されたオンプレミスサーバーにロードバランシングしたいという要件があったりしませんか？

実は現在のAWS製品のロードバランサーでは構成を複雑にしないと実現できません。

![](https://storage.googleapis.com/zenn-user-upload/b57ab0e4383e-20230224.png)

これをクリアにするためには VPC を作成して VPN を張ったり、Transit Gateway を使ったり、或いは DirectConnect を使ったり... 荷が重いですよね。

それをサクッと解消してしまおうというのが今回の Global LoadBalancer (by Terraform)です。


# 概要
今回、利用するのが App Runner です。

AWS App Runner とは？

> AWS App Runnerは、Amazon Web Services（AWS）が提供するマネージドサービスの1つで、コンテナ化されたアプリケーションを簡単かつ迅速にデプロイおよび実行することができます。
> 
> App Runnerは、DockerコンテナとAmazon Elastic Container Registry（ECR）またはDocker Hubのどちらかに格納されたコンテナイメージを使用してアプリケーションを実行します。アプリケーションのセットアップ、ロードバランシング、スケーリング、モニタリングなどの面倒なタスクをAWSが自動的に処理するため、アプリケーションのデプロイメントに必要な手順を最小限に抑えることができます。
> 
> また、App Runnerは、AWS CLI、AWS Management Console、またはAWS SDKを使用して簡単に操作できるため、DevOpsチームがコンテナ化されたアプリケーションのデプロイメントプロセスを迅速かつシンプルに設定することができます。

by ChatGPT.

さて、説明用の構成図です。

![](https://storage.googleapis.com/zenn-user-upload/7e72eb7407c5-20230224.png)

## 仕様
- フルマネージド
- ラウンドロビン（デフォルト）
- アクセスログ、エラーログは CloudWatchLogs で確認可能


# 手順
では早速構築していきましょう。
今回、GitHub に全てを上げてありますので以下のリポジトリを参照してください。
※ 但し、Docker が稼働していることが条件になっていますのでご注意ください。

## 1. リポジトリへアクセス
https://github.com/nix-tkobayashi/apprunner-global-loadbalancer

## 2. 意外に重要
画面右上の★スターをクリック

## 3. README に沿って実行
https://github.com/nix-tkobayashi/apprunner-global-loadbalancer/blob/main/README.md

以上です！

実に簡単に構築が出来てしまいました。
完全マネージドサービスなのでスケーリングも自在です！

皆様も宜しければご活用くださいませ。


# 一言
今回は Round-Robin の nginx.conf を仕込んでありますが、重みを変えたり、Least-Connected や Ip-Hash の設定にしても良いかもしれませんね。

あとは App Runner ってこんな使い方できるんだ！という発見に繋がれば幸いです。