OmniAICreator/Qiita-1.07M huggingface dataset:
Prettier と plugin だけで Node.js のモジュール import の並び順を整える


## はじめに

- Prettier を導入しているが、ESLint が導入されていない JavaScript/TypeScript の小さなプロジェクトで `import` の並び順を揃えたいニーズがあったため、追加したライブラリと設定を記載します
- ESLint を導入することで解消も可能でしたが、 ESLint を入れる程大きなプロジェクトではないため見送りました

## 実行環境

```zsh
% sw_vers
ProductName:    macOS
ProductVersion: 12.4
BuildVersion:   21F79
% node -v
v16.7.0
% yarn -v
1.22.15
```

## import の並び順を整える

今回追加するのは trivago が開発している `prettier-plugin-sort-imports` です

https://github.com/trivago/prettier-plugin-sort-imports

### ライブラリの追加

該当のプロジェクトでは `yarn` を利用していたため以下コマンドで追加を行いました
npm を利用している場合読み替えていただけると

```zsh
yarn add --dev @trivago/prettier-plugin-sort-imports
```

### 設定の追加

ライブラリを追加するだけでデフォルトの設定が有効になります
設定を変更する場合は Prettier の設定ファイルにルールを記載していきます

プロジェクトによって設定ファイル名や形式が異なる場合もあります
必要に応じて公式ドキュメントを参照してください

https://prettier.io/docs/en/configuration.html

ちなみに私が設定したルールは以下 2 つです
※ 今回追加した設定のみ記載しています

```json:.prettierrc.json
{
  "importOrder": ["^@foo/(.*)$", "^[./]"],
  "importOrderSeparation": true
}
```

他にもルールは存在しますが追加した 2 ルールだけ説明を追加します

|        ルール名         |                           ルール説明                           |
| :---------------------: | :------------------------------------------------------------: |
|      `importOrder`      |               左から順に import 順を並び替えます               |
| `importOrderSeparation` | `importOrder` を 1 つのグループとし その前後に改行を追加します |

### Prettier を実行する

以下のようなコマンドを実行し、整形を行います

```zsh
yarn prettier --write .
```

コマンドの実行結果
Before, After 例を載せておきます

```ts:before.ts
import hoge from "./"
import foo from "@foo/baz"
import foo from "@foo/bar"
```

```ts:after.ts
import foo from "@foo/bar"
import foo from "@foo/baz"

import hoge from "./"
```

## Reference

https://github.com/trivago/prettier-plugin-sort-imports

https://prettier.io/docs/en/configuration.html
パッケージの引用リスト作成

　論文を書く際には、先行研究だけでなく、分析で使用したパッケージを引用しないといけません。その際、関数ごとに毎回citation()で調べているとキリがないです。バージョンの一覧などは以下の関数で調べられますが、引用文献リストに追加する情報としては足りません（著者名とか）。

```R
sessionInfo()
```

　そんな時に使用するのが、gratefulパッケージのscan_package関数です。以下をRunすると、packages変数の中に、指定したRmdファイル内で使用したパッケージのデータが格納されます。
```R
library(grateful)
packages <- scan_packages(path = "Rmdファイルまでのパスを指定")
```
　中身は添付の写真の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344524/298e4935-f4dc-eac7-1de2-b53df516173d.png)
　ここで格納したデータをもとに、文献リストを作成していきます。
使う関数は、purrrパッケージのmap関数になります。このmap関数はかなり便利なので、是非調べてみてください。
　以下では、citation関数を、データの中身すべてに適用し、それらをtext形式で表示させています。以下のコードをRmdファイルの最後につければ、引用パッケージリストの完成です。

```R
library(purrr)
packages$pkg %>%
  map(citation) %>%
  print(style = "text")
```
　HTMLにKnitすると以下のような出力となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344524/77020c57-e96c-a8cb-d23a-a88d74d1813c.png)

　一つ問題なのは、**著者名のアルファベット順では表示されないところです。** ここは改良が必要です。いいアイデアがあればコメント欄にお願いします！
Web3.0検証(22(最終回))-MeteorでTODO管理アプリの開発(デプロイ&公開)

##### [前回] [Web3.0検証(21)-MeteorでTODO管理アプリの開発(リグレッションテスト)](https://qiita.com/mingchun_zhao/items/5f879f2dc6e2979904e6)

## はじめに

アプリの開発とテストが終わり、いよいよデプロイと公開です。

## 基本知識

### デプロイ(deploy)とは

- Webアプリなどの実行ファイルを、Webサーバーなど実行環境に配置し、実行可能状態にする工程
- 広義のデプロイは、ソフトウェアのインストールや公開まで含む場合あり
    - 開発環境からステージング環境への反映
    - ステージング環境から本番環境への反映
- デプロイ方法
    - コールドデプロイ
        - デプロイ(配置)操作後にサーバを再起動させるデプロイ方法
    - ホットデプロイ
        - サーバーを再起動させずにデプロイしたプログラムを反映する機能
    - CI/CDによる自動で継続的なデプロイ
        - GitHub Actions
        - CircleCI

### リリース

- 製品やサービスとして公開し、ユーザーが使える状態にする工程
- デプロイ後、サービス公開前に動作確認などが必要
    - デプロイはリリース作業の一部

## Meteorアプリをデプロイ

Galaxy提供の無料デプロイサービスを利用します。

### Meteor Cloudアカウントを作成

- `cloud.meteor.com`にアクセスし、アカウント作成
- ログインすると、以下のダッシュボードが表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/7db98e07-3cf6-2f82-45fd-38e4877f41fa.png)

### デプロイする

- デプロイ前に、すべての依存関係がインストールされていることを確認
```
$ meteor npm install
```
- アプリ公開に必要なサブドメインを選択
    - Galaxy無料プランに含まれているメインドメイン`meteorapp.com`を使用
    - ドメイン(domain)名とは
        - IPネットワークにおいて、個々のコンピュータを識別し、接続先を指定するために使用される名称の一部
            - 例: `example.com`
        - ドメイン名は階層構造かつツリー構造になっている
    - サブドメインとは
        - より大きなドメインの一部であるドメイン
            - 例: `east.example.com`は`example.com`のサブドメイン

- deployコマンドを実行
※ 必ず、`my-deploy-test`部分を別のサブドメイン名に置き換えてください
```
$ cd simple-todos-react
$ meteor deploy my-deploy-test.meteorapp.com --free --mongo
```

上記作成したアカウントのメールアドレスを聞かれます。

```
You must be logged in to deploy, just enter your email address.

Email: xxxxxxxxxxxxxxxxxxxxxxx

Logging in as xxxxx.
Password:
Talking to Galaxy servers at https://us-east-1.galaxy-deploy.meteor.com
Preparing to build your app...
... ...
Preparing to upload your app...
... ... 
Waiting for deployment updates from Galaxy...
Building app image...
Deploying app...
You have successfully deployed the first version of your app.
******************************************************************************
... ...
For details, visit https://galaxy.meteor.com/app/my-deploy-test.meteorapp.com
```

- Galaxyは、アプリバンドルを含む新しいDockerイメージを構築し、コンテナをデプロイ
- Galaxyログから、Dockerイメージを構築し、デプロイしている部分確認できる

### 公開されたアプリにアクセス

- アプリにアクセス
    - `https://my-deploy-test.meteorapp.com/`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/28b86562-6a08-3f7b-46ac-b73d5853c1a9.png)

- Galaxyダッシュボードにアクセス
    - `https://galaxy.meteor.com/app/my-deploy-test.meteorapp.com`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/469b3339-f290-5458-1f61-cc360a72df51.png)

- Githubの`OAuth Apps`でURL設定を更新
    - `https://github.com/settings/developers`にアクセス
    - アプリケーションを見つけ、下記を`https://my-deploy-test.meteorapp.com`に変更
        - Homepage URL
        - Authorization callback URL

これで、Meteorアプリを、世界中の誰もがすぐ使用できるようになりました。

## おわりに

アプリのリリースまで辿り着きました。
本題の「MeteorでWeb3.0アプリ作成」は積み残しとさせていただき、
ここで、一旦本連載を終了させていただきます。
今後、別の形でWeb3.0検証を再開する予定です。

拙い文章を読んでいただき誠にありがとうございました。
pythonでcase文を書く

python3.101　リリースが2022/04くらいなので今更感はあるが、、


## 主要な変更点

- 構造的パターンマッチング(case構文)

## 構造的パターンマッチング

要するにcase構文. SQLとかではifよりこっちがメインだがpythonでは`dict`や`if ..elif`でなんとかなるだろうと言うことで今まで採用して来なかったらしい。

他の言語と同じように書ける.
```example1.py
a:int = 2
match a:
    case 1:
        print("this is 1")
    case 3:
        print("this is 3")
    case _:
        print("Other")
# Other
```

これまでは`case`を書きたければ以下のように書く必要があった.

```example2.py
# pattern1
if a == 1:
    print("this is 1")
elif a == 3:
    print("this is 3")
else:
    print("Other")

# patern2
cases = {
        1:"this is 1", 
        3:"this is 3"
        }
cases[a] if a in cases.keys() else "Others"
```

python~3.9でも同じことはできたが、caseの方が可読性が高い、と言うのが導入理由だったらしい。

ちなみにifとの組み合えわせもでき、その場合はcaseが先に評価され、その後でifが評価される。

```example3.py
sample = "hello"
match sample:
    case int(x) if sample > 0:
        print("sample is integer and greater than 0")
    case str(x) if sample == "hello":
        print("sample is string and 'hello'")
    case int(x):
        print("sample is integer")
    case str(x):
        print("sample is string")
    case _:
        print("other!")
# sample is string and 'hello'
```

ここで２番目のcaseで引っ掛かっているので４番目のcaseでは引っかからない.　またcaseでデータ型を判定したい場合には
`class(x)`のように書く。これは自作のクラスでも使用できる
`if type(sample) == `と同じ。

# その他

個人的には条件分の xが違和感ちょっとあった。条件を柔軟に指定できて便利そうなんだけどね。。
また、caseは予約語だけど普通に変数としても使用できてしまうっぽいので注意。
Laravel9からEloquentのアクセサでキャッシュが使えるようになった

Laravel9からEloquentのアクセサ／ミューテタでキャッシュが使えるようになったので試してみました。

## 検証バージョン
PHP8.1.6
Laravel9.16.0

## キャッシュの指定方法
アクセサを定義する時に`shouldCache`メソッドを呼んで指定します。
※Laravel9からアクセサ/ミューテタの記法が変わりました
```php:User.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'email',
        'sei',
        'mei',
    ];
    
    /**
     * フルネームを取得するAttribute
     * @return Attribute
     */
    public function fullName(): Attribute
    {
        // Attribute生成時にshouldCacheメソッドを呼ぶ
        return Attribute::make(
            get: function ($value, $attributes) {
                // 起動されたことを表すためにログを埋め込み
                \Log::info('get fullName start');
                return $attributes['sei'] . ' ' . $attributes['mei'];;
            },
        )->shouldCache();
    }
}

```

## 試してみる

| id | sei | mei |
|:-----------:|:------------:|:------------:|
| 1       | 山田       |一郎         |

上記のようなデータがある場合に、フルネームを取得した後にキャッシュが効いているか試してみます。

```php:SampleController.php
class SampleController extends Controller
{
    public function index()
    {
        $user = User::find(1);
        \Log::info($user->fullName);

        // アクセサにかかわるプロパティを変更してもキャッシュが効いていてアクセサの値は変わらない
        $user->sei = '鈴木';
        \Log::info($user->fullName);

        return;
    }
}
```

埋め込んだログは下記のように表示され、キャッシュされていることがわかります。
```laravel.log
local.INFO: get fullName start  
local.INFO: 山田 一郎  
local.INFO: 山田 一郎  
```

## キャッシュが使えるようになって何が嬉しいか
計算量が多い、かつアクセサ呼ばれる回数が多い場合にキャッシュすることで1度呼んだら後は値を参照するだけなので処理速度の改善に繋がると思います。

## 注意点
アクセサは最初に取得した値を保持し続けるため、DB更新やプロパティが変更された際に値の矛盾が生じるので使い所は考える必要があります。

## まとめ
計算量が多いアクセサを実装するシーンは少ないと思いますが、上手く使うと処理速度改善に繋がると思うので使うチャンスがある場合はぜひ使ってみてください！
HTTPのKeep-Aliveと同時接続数について

自分用のメモなので端折り書きです。すみません。

# Webサーバにおけるkeepaliveとは

> * TCP/IPだと1度のリクエストとレスポンスごとにTCPコネクション貼り直す
※データを転送する前にはコネクションを確立するというプロセスがある。いきなりリクエストを投げつけて受け取るわけではない。
> * 勿体無いので一回貼ったコネクションは使いまわそう -> keepalive
> 具体的に言うと、一つのページの中で画像とかの素材を読み込んで… みたいなので細かくリクエストが発生する場合とか効きそう、という想定があるらしい
> * コネクション張っている = リクエストを待ち受ける以外何もしていないスレッドやプロセスがある、ということなのでコネクションをずっと維持していればいいと言うものでもない
> * 1回通信を実行した後(=1回分レスポンスを返してから)、どの程度サーバが待ち受けているか、であって、1回分のレスポンスにかけてよい最大時間ではない
> 引用元： https://woshidan.hatenadiary.jp/entry/2017/08/21/222904

どうやってコネクションを貼り続けているかというと、なんか定期的に信号を送り合って途切れないようにしているっぽい。
keepAliveにすることで通信の効率化（スピード向上）が期待される。

# 同時接続数とは

> 「リクエストに応答するために作成される 子プロセスの最大個数」です。
スレッドを用いるサーバではクライアントに対応できるスレッドの最大個数、スレッドを用いないサーバではクライアントに対応できる子プロセスの最大個数になります。
１つの子プロセスは１つのリクエストに応答するために働きますから、サーバーは最大(Max)MaxClients個のクライアント(Client)からのリクエストに応答するために働くことが出来るという事になります。
リクエストへの応答が終わった後、それに使われたコネクションが解除されるまでには、ある程度の時間がかかります。
また、リクエストのためのコネクションは、サーバ側で待ち列(キュー）に保持されたりします(キューにある間はコネクションはあっても、応答するための子プロセスに割り当てられていない状態になります)。
そのため、コネクションの総数がMaxClientsを超える場合があります。逆に言うとMaxClientsはコネクションの総数の上限ではないという事です。
引用元：https://teratail.com/questions/40045

keepAliveを不要に長い時間に設定している、かつclose:connectionのリクエストを行わないと、不要になったコネクションが残りっぱなしになり、同時接続数の上限に達したりするので要注意。

# 参考サイト

* HTTPキープアライブとは - IT用語辞典
https://e-words.jp/w/HTTP%E3%82%AD%E3%83%BC%E3%83%97%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96.html
STM32G031のI2Cスレーブモードで超音波距離センサーHC-SR04の値をマスターで受信する。2(小改良)



x 動作確認済み2022/6/4 14:55


目的
軽量コンパクト化
ライブラリのSTM32 MCU based boards 2.2.0化
タイムアウトの短縮化 pulseIn(in_pwm, HIGH, 24000);



仕様

1 エコー
2 VDD
3 GND
4 トリガー

8 SWD 
7 SWD 
6 SDA
5 SCL


回路図


![o_con398.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3c134ee8-5cb8-fc89-e675-ad9deaf46b1e.jpeg)



レンジ圧縮のレンジ切り替え20cmで8ビットに丸める が　わかる人


![o_con388.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6fa979cb-049b-942c-ea99-b27c44325509.jpeg)


OB GPIO


![o_con391.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b6587145-15c0-ff49-6bb5-23173fca5d20.jpeg)


2.2.0


![o_con469.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cec119fa-7066-4a4b-0050-d31ae844b5ed.jpeg)



![o_con517.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/00e32aa0-b15c-2c87-084b-929623ea7142.jpeg)



詳しくは、こちら



https://qiita.com/caa45040/items/b74c0e26e768fdf750a3


名前は、まだない


```c++




//i2c_slave_HC_SR04_031_2


#include <Arduino.h>
#include <Wire.h>


#define TRIG PA0
#define ECHO PB7


//初期化処理
void setup() {

  //GPIOの初期化
  pinMode(TRIG, OUTPUT); digitalWrite(TRIG, LOW);
  pinMode(ECHO, INPUT);

  //I2Cの初期化
  Wire.setSDA(PA12);
  Wire.setSCL(PA11);
  Wire.begin(8);// Slave ID #8
  Wire.onRequest(requestEvent);

}//setup


//メインループ
void loop() {
}//loop


//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)

int b = 200; // ((s-140)*10)+200 -> 800


void requestEvent() {

  //1つ前の値を送信
  Wire.write(b);

  // 超音波を発生させる
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  // 超音波を受け取る　測定時間
  int times = pulseIn(ECHO, HIGH, 24000);

  // 測定時間を長さに変換
  //distance = (int)(times * 0.017);
  int distance = (times * 17) / 100;

  //レンジ圧縮をして8ビット(256)に収める
  //60mm から　200mmまでは、1mm単位
  //60mm = 0 , 200mm = 140
  //200mm から　800mmまでは、1cm単位
  //200mm =140 ,  800mm = 200

  //オーバーの値を丸める
  if ( distance >= 800 ) {
    distance = 800;
  }
  if ( distance <= 60  ) {
    distance = 60 ;
  }

  // 200mmより　小さいか?
  if ( distance <= 199 ) {

    b = distance - 60;

  } else {

    b = DIV10(distance) - 20 + 140; //DIV10(x)==x/10

  }//endif

}//requestEvent


```


マスター


```c++



//i2c_master_HC_SR04_031_2


#include <Arduino.h>
#include <Wire.h>
#include <HardwareSerial.h>


//初期化
void setup()
{

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

  //I2Cの初期化
  Wire.setSDA(PA12);
  Wire.setSCL(PA11);
  Wire.begin(); //pa12 pa11

}//setup


//メインループ
void loop()
{

  int  b = 200; //読み込み値
  int  l;       //長さ

  //読み込み
  Wire.requestFrom(8, 1);

  while (Wire.available())  {   // 要求より短いデータが来る可能性あり
    b = Wire.read();            // 1バイトを受信
  }//while

  //読み込み値から長さに変換
  if ( b <= 139 ) {
    l = b + 60;
  } else {
    l = (b - 140 + 20) * 10;
  }//endif

  //表示
  Serial.print("800,");
  Serial.print(l);      //031
  Serial.print(",0");
  Serial.println();
  delay(500); // 0.5秒の待ち

}//loop



```
access2000の作法 その19

# 概要
access2000の作法、調べてみた。
sqlを発行する方法は、四つ、あるらしい。

# runsql
```
	Dim strSQL As String 
	strSQL = "Delete * From Tbl_A" 
	DoCmd.SetWarnings False
	Docmd.RunSQL strSQL 
	DoCmd.SetWarnings True

```

# dao
```
	Dim db As Dao.Database
	Dim strSQL As String 
	Set db = CurrentdDb()
	strSQL = "Delete * From Tbl_A" 
	db.Execute strSQL, dbFailOnError 
	db.Close
	Set db = Nothing 

```

# connection
```
	Dim cn As ADODB.Connection
	Dim strSQL As String 
	Set cn = CurrentProject.Connection
	strSQL ="Delete * From Tbl_A" 
	cn.Execute strSQL, dbFailOnError 
	cn.Close
	Set cn = Nothing

```

# command
```
	Dim cn As ADODB.Connection
	Dim cmd As New ADODB.Command
	Dim strSQL As String 
	Set cn = CurrentProject.Connection
	cmd.ActiveConnection = cn
	strSQL ="Delete * From Tbl_A" 
	cmd.CommandText = strSQL 
	cmd.Excute 
	cn.Close
	Set cn = Close

```

以上。
学習時におけるRailsのメリットとデメリット

# 取り扱うこと
今回はRailsのメリット・デメリットについて

僕個人としてはすごく大好きな言語
JavaScriptと同じくらい好きです

さてそんなRailsのメリットとデメリットについてご紹介

# 学習時のメリット、デメリット

## メリット

1.規則に従えばそれで動く
2.CRUDアプリを作るなら経験上一番カンタン
3.gemの存在

さて解説

### 規則に従えばそれで動く
上２つは概念的なことでした
次は実用的なこと
少し例えて見ます
逆にわかりにくかったらごめんなさい
あなたは本棚を作ろうとしています
いきなり木材と工具を渡されてもちょっと訳わかんないですよね？
でもRailsは通販で本棚購入して設計図をもとにパーツを組み立てるだけです
多言語だと設計図をまず自分で構想する必要があります
書いてて思ったのですがプラモデルだと思ってください

### CRUDアプリを作るなら経験上一番簡単
CRUDアプリってなんやねん
と思う方もおられると思います
Create,Read,Update,Deleteの頭文字を取ったもので、この機能が使えるアプリを指します
簡単に言えばメモ帳とか掲示板ですね
メモ帳だと
メモを書き込む(Create)
メモを見る(Read)
メモを編集する(Update)
メモを削除する(Delete)
こういった機能を作るのが非常に簡単
自動でやってくれる部分が多いので作業工程の３割は多言語より減ってるような気もしますがこれは人によりますねｗ

### gemの存在
これはRailsに限ったことではないのでちょっと圧倒的メリットとは行きませんがすごく便利です
例えばログイン機能を作りたいと思ったときにネットに転がっているログイン機能をもつプログラムを持ってくることができるのです
これでログイン機能は作らなくても良くなったので作業工程が大幅に減りましたね
gemとはこういう存在です

## デメリット
実は結構あります
それも学習時が一番デメリット大きいと思います
1.開発環境で躓く
2.バージョンとgemが親密関係すぎる

他にもそれなりにありますが学習時にはこの２つが大きいと感じます
解決策もあるので一緒に突破しましょう
それでは解説

### 開発環境で躓く
ローカル環境と言って自分のPCにRailsをインストールして行う方法があります
開発環境はベテランでも躓くことがあります
ここで躓いた場合初心者の方は解決が難しいです
するとプログラムをまだ一行も書いてないのに「もういいや」となってしまう方もいます
これはあまりにももったいない
そこで救世主を呼びましょう
「Cloud9」です
ブラウザ上で開発できる開発環境です
登録から１年間は無料でその後も勉強程度なら１ヶ月で２００円くらいしかかかりません
使った分だけ費用が発生します
電気代的なやつです
まぁ１年経っても１月２００円で全部そろえてくれてるからやすいですｗ
ブラウザあればいいので安いChromeBook購入して勉強できます

### バージョンとgemが親密関係すぎる
これめっちゃ重要
学習教材と必ずRailsやRubyのバージョンは揃えてください
教材がRails５を使ってて自分はRails７で行うと大変なことになります
前半戦はいいのですが後半戦でgemとかが出てきたときに詰まります
ご自身で解決できるスキルがあれば別ですが初心者のうちは無理に決まってるじゃないですか
だからここはかならず教材とバージョンを合わせるといったことが必要です
この記事を書いてる現在だとRails５以上の教材で始めましょう
４はサポート終わったので・・・。

# まとめ
デメリットについて補足します
>開発環境も組めないやつが〜
>エラーを直せるスキルがないと〜

という人はいます
まぁ言ってることは間違ってはないです
ですが初心者のうちは無理なので適当に相槌打っておいてください
何度も何度も繰り返し勉強してるうちにエラー対処はできる用になります
はじめのうちからは絶対に無理です
１０分考えてわからなかったら質問サイトとか使えばいいです
開発環境に関して言えば便利なものがあるのに使わない理由が僕にはわかりません
しっかり勉強した後に試しに組んでみたらいいと思います
簡単に環境整えようぜ！って開発されたものですから使って大丈夫です
ブラウザあればどこでも編集できますし
チームでやるなら開発環境は合わせたほうがいいですが個人開発なら好きなの使ってください
shttpdの不具合

ZRouterではshttpd(1.42)をportsもどきに入れて使えるようにしています。我が家のおうちモニター(oumon)もshttpdで動かしています。またセンサーモジュールのmruby on YABMからのデータの受け取りもshttpd経由です。

shttpdをブラウザでアクセスすると時々ハングアップしてしまいことがありました。

ハングアップした時にloginしてpsで確認するとステータスがRで実行時間が実時間で繰り上がっていくので、暴走しているようです。

portsもどきはobjディレクトリのイメージがあるディレクトリにある、portsのまた深いところでビルドされます。ソースもそこに展開されています。

buildworld,kernelはインクリメンタルビルドされますが、portsもどきは毎回クリーンビルドになります。

ソースを見るとコンパイルオプションでデバッグメッセージが出せるようなのでshttpdのportsもどきのMakefileに以下を追加してビルドします。

```
MAKE_ARGS= CFLAGS="-D_DEBUG"
```

デバッグにいちいちフルビルドしてイメージをターゲットに焼いてでは手間がかかりすぎます。

ZRouterのMakefileはターゲットにportsを指定するとportsだけをビルドするので、それでとりあえずバイナリを作ります。

出来上がったバイナリをtftpでターゲットの/tmpにコピーして実行してみます。

shttpdは幸いファイル一本なので、この方法で対応できますが、soを使っている場合は、ちょっと面倒になります。

すぐには再現しないのですが、ブラウザで何度かアクセスするとselectまわりで暴走します。どうもたくさんファイルを拾うアクセスのときにハングしやすい気がします。oumonではトップページで、html,css,jsを読み込んでいて、ほとんどここでハングします。

デバッグメッセージでselectがerrnoを9(EBADF)で返してしまう事が確認できました。

OK

```
read_stream (4 file): read 249/249/249 bytes (errno 2)
4 (null) stopped. 249 of content data, 249 now in a buffer
write_stream (4 socket): written 249/249 bytes (errno 2)
Disconnecting 4 (keep-alive)
```

NG

```
read_stream (9 file): read 249/249/249 bytes (errno 2)
9 (null) stopped. 249 of content data, 249 now in a buffer
Disconnecting 9 (keep-alive)
```

```
read_stream (9 file): read 5197/5197/5197 bytes (errno 2)
9 (null) stopped. 5197 of content data, 5197 now in a buffer
write_stream (9 socket): written -1/5197 bytes (errno 54)
9 (null) stopped. 0 of content data, 0 now in a buffer
Disconnecting 9 (keep-alive)
```

```
Assertion failed: (stream->io_class != NULL), function read_stream, file shttpd.c, line 916.
Abort trap
```

shttpdはlistenしてるファイルディスクリプタをselectしているようなのですが、なぜかエラーになることがあります。

よく分からなかったので、とりあえあずEBADFの時はexitしてプロセスを終了させて、shスクリプトのラッパーで再度起動するようにしました。

考えられる可能性

* shttpdのバグ
* FreeBSDのバグ
* FreeBSD/mipsのバグ
* FreeBSDでなんらかのリソース不足

私の勘では、アクセスが原因ではなくて、アクセスのクローズ時になんらか問題が起きて、その後selectできなくなるような気がします。httpのcloseの処理はネットの状況やブラウザの挙動によって変わってくるような気がしています。

rayからは他のにしたらって言われてます。

結構根が深そうなのと、デバッグが不自由なので、あきらめてmini_httpd使うことにしました。

おそらくファイルが1本とかのページであればとくに問題なく動くけど、jsやらcssやらたくさんファイルがあるページで問題を起こすようです。誰かデバッグしてみませんか？
HTTPの圧縮アルゴリズムについて整理する

# はじめに

- ネットワークトラフィックを削減し、Web上で高速にテキストやバイナリ等のコンテンツをやり取りすることを目的に圧縮される
- 一般的に、ApacheやnginxのようなWebサーバ側で圧縮され、Webブラウザ側で解凍される
- 圧縮アルゴリズムには複数種類あるため、それぞれのメリットやデメリットについて整理してみる

# HTTPヘッダ

- HTTPリクエスト/レスポンス上でどのように圧縮アルゴリズムの交渉がなされるのかという例示

### HTTPリクエストヘッダ

- クライアントがどの圧縮アルゴリズムを解釈できるかを指定する

```
# 圧縮アルゴリズムを１つ指定するパターン
Accept-Encoding: gzip

# 圧縮アルゴリズムを複数指定するパターン
# 優先順位の高い順で指定する
Accept-Encoding: gzip, compress, br

# 圧縮アルゴリズムを複数指定するパターン
# それぞれを品質値と呼ばれ、`;q=`の形式で記述する方式で重み付けをしている
Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1
```

### HTTPレスポンスヘッダ

- どの圧縮アルゴリズムによって圧縮されたかを指定する

```
Content-Encoding: gzip

# 複数適用されたパターン
# 適用された順に記述される
Content-Encoding: gzip, identity
```

# 圧縮アルゴリズム

- 圧縮アルゴリズムの評価軸としては、圧縮/解凍処理の高速性や圧縮率の高さ等がある
- 圧縮/解凍処理の遅さが圧縮率の低さによるボトルネックを上回らないようにすることが大切
- HTTPで一般的に使用できる圧縮アルゴリズムには以下のような種類がある

### gzip

- [GNU zip](https://www.gzip.org/)の略称でGNUプロジェクトでメンテされているzip形式の圧縮アルゴリズム
- Lempel-Ziv(LZ77)とハフマン符号を用いた圧縮アルゴリズム
- [RFC 1952](https://datatracker.ietf.org/doc/html/rfc1952)として標準化されている
- compressで使用されている圧縮アルゴリズムが特許侵害の問題を抱えていたことから開発が開始された
- compressよりも圧縮率が高いという特徴を持つ

### compress

- Lempel-Ziv-Welch(LZW)を用いた圧縮アルゴリズム
- 特許侵害の問題を抱えていることや、他に優秀な圧縮アルゴリズムが台頭してきたことからあまり使用されなくなっている

### deflate

- LZ77の改良版であるLempel–Ziv–Storer–Szymanski(LZSS)とハフマン符号を用いた圧縮アルゴリズム
- HTTP上で使用されるDeflateにはzlibヘッダが付与されている
- 一部のプログラムではzlibヘッダが付与されていない生のdeflateとして扱われる問題があるため、多少圧縮率が落ちてもgzipが採用される傾向にある

### sdch

- SDCH(Shared Dictionary Compression for HTTP)
- VCDIFF([RFC 3284](https://datatracker.ietf.org/doc/html/rfc3284))をベースにGoogleが開発した
- Google Chromeのバージョン59でサポートが打ち切られ、後述のbrへの移行が進んでいる

### br

- Brotilの略称
- 元々はWebフォントのオフライン圧縮を目的に開発されたものをGoogleが改良した
- Deflateと圧縮/解凍速度がほぼ同等のまま、20%の圧縮率の高さを実現できるとされている

### identity

- 圧縮されていないことを表す
- この値は省略されていても常に許容されるものとして扱われる

### *

- 指定可能な全ての圧縮アルゴリズムを表す
- これはクライアントが指定可能な全ての圧縮アルゴリズムを解釈できるという意味ではない
- `Accept-Encoding`ヘッダが設定されていない場合の既定値

---

- 参考
    - [Accept-Encoding - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Accept-Encoding)
    - [Content-Encoding - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Encoding)
    - [Quality values](https://developer.mozilla.org/ja/docs/Glossary/Quality_values)
    - [Hypertext Transfer Protocol (HTTP) Parameters](https://www.iana.org/assignments/http-parameters/http-parameters.xml)
Gradleコマンド・build.gradle記述方法まとめ

# 初めに
本記事はJava使用時のGradleの使用を想定しています。ご注意ください。
[Gradleコマンド](#gradleコマンド) 
[build.gradle記述方法](#buildgradle記述方法) 
# Gradleコマンド
Gradleコマンドについてです。
## プロジェクトの作成
プロジェクトの作成方法
```# プロジェクトの作成
gradle init 
```
## クリーン
クリーンの方法
```:# クリーン
gradle build 
```
## ビルド
ビルドの方法
```:# ビルド
gradle build 
```
## プログラムの実行
```:# プログラムの実行
gradle run --args="任意の引数1 任意の引数2..."
```
以下例です。
```:# 例
gradle run --args="1 1"
```
# build.gradle記述方法
build.gradleの記述方法についてです。
## Mainクラスを指定
```:# Mainクラスを指定
application {
    mainClass = 'メインクラスを指定(パッケージ込み)'
}
```
以下例です。
```:# 例
application {
    mainClass = 'app.App'
}
```

## 実行可能なjarファイルを作成する
実行可能なjarファイルを作成したい
```:#
jar {
    manifest {
        attributes 'Main-Class': 'メインクラスを指定(パッケージ込み)'
    }
} 
```
以下例です。
```:# 例
jar {
    manifest {
        attributes 'Main-Class': 'app.App'
    }
}
```

# 外部jarの追加
外部jarの追加したい
```:# 外部jarの追加
dependencies {
    implementation '任意のライブラリ'
}
```
以下例です。
```:# 例（OpenCSVの追加）
dependencies {
    implementation 'com.opencsv:opencsv:5.6'
}
```

# おまけ
## 外部jarをまとめて1つのライブラリにしたい。
Shadowと呼ばれるGradleのプラグインを使用します。

https://imperceptiblethoughts.com/shadow/introduction/

### 手順1 Shadowプラグインの追加
```:# 手順1 Shadowプラグインの追加
plugins {
    id 'application'
    // Shadowプラグインの追加
    id 'com.github.johnrengelman.shadow' version '7.1.2'
}

repositories {
    mavenCentral()
}

dependencies {
    // 追加 opencsv
    implementation 'com.opencsv:opencsv:5.6'
}

application {
    mainClass = 'app.App'
}

jar {
    manifest {
        attributes 'Main-Class': 'app.App'
    }
}
```

### 外部ライブラリをまとめてjar化するコマンド。
外部ライブラリをまとめてjar化するコマンドです。
```:外部ライブラリをまとめてjar化するコマンド
gradle shadowJar
```

# 参考

https://qiita.com/niwasawa/items/425b766578133f14d516

https://qiita.com/niwasawa/items/533385a7c718a1dc39a3
新卒エンジニアがタイピングを3週間でした話

新卒駆け出しエンジニアのCybermanです。

記者のスペック以下の通り。
・大学文系（地域活性化系）
・タイピングE＋（e-typing）　※1分間ではかったとき20文字だったかな？
・幼少期にPCつぶした遊んでた（笑）
・Word2013　Excel2013取得済
・なぜかクラウドだけ触ったことあるがNWってなに？レベル。（プログラミング不可）

# 本記事について
新卒駆け出しエンジニアがタイピングを<font color="red">**短期間**</font>でどれだけできるか記載した記事。

# 1.タイピングにチャレンジしようとしたきっかけ
タイピングはとてつもなく遅く誤字脱字も多かった。ある日社会人二年目の先輩にタイピングに関して、「タイピングが遅い」とはっきり言われたことがきっかけでタイピング練習を行い始めた。それまでは私生活や仕事に関して特段、影響がなかった。だが、その言葉が自身の弱い部分に刺さったこともあり、この際タイピングを早くしようと思い行動したのがきっかけである。

【タイピング練習前の自分】
・一分間で平均<font color="red">**20~30**</font>文字
・文字の<font color="red">**誤字脱字**</font>が多い。
・e-typingでは、<font color="red">**レベルE**</font>
※インターネットでタイピング練習E-typing co、イータイピング株式会社，https://www.e-typing.ne.jp/, (参照 2022-06-03)

# 2.具体的な内容について
学習期間は二週間程である。この二週間で行ったことはタイピングを行いながらYouTubeを見る。
具体的には、YouTubeで学習動画やアニメを見ながらタイピングサイトで学習。まず、基本的な部分を抑えるため以下を意識し行動。

・キーボード上で<font color="red">**両人差し指をFとJに置く**</font>ことを意識。
・<font color="red">**正しくローマ字を打つ**</font>こと
・<font color="red">**Enter**</font>を押す回数を少なくする
・<font color="red">**タイピング速度**</font>は気にせず
・指をしっかり<font color="red">**曲げる**</font>（理由：PやQを押せるようにするため）

これらを1.5週間意識し行動したことで、正確にキーを押せるようになった。また、キーボード上で正しい手の置き方を意識せずともできるようになった。その後、下記の項目を意識し行動。

・タイピングの<font color="red">**速さ**</font>を意識
・画面や別の部分を<font color="red">**見ずに文字を打つ**</font>こと
・様々なタイピングサイトを<font color="red">**活用**</font>すること

これらをのこりの1.5週間で意識して行った。このことにより、自分の弱点（どのキーが弱いかなど）が理解できるようになった。
それが理解できたことで集中的に改善できた。

# 4.結果と習得したことによるメリット
上記の学習期間を終えた結果として、1分間で100字以上、e-typingではランクB～Aに成長できた。また成長できたメリットとして、<font color="red">**業務の効率**</font>が上がった。また、コマンドなど打つ際にキーを覚えているので、英語が分かれば<font color="red">**画面を見ながらでも**</font>できるようになった。また、キーボード上を把握することによりshift/ctrlなどの配置が理解できるようになった。それにより以前よりも<font color="red">**ショートカットキー**</font>を利用しやすくなった。


# 5.最後に
最後に上記を踏まえ、ITエンジニアとしてタイピングを早くすることは<font color="red">**メリット**</font>しかないと感じた。また、意識のやり方次第で上達頻度は短くなり、<font color="red">**短期間**</font>で早くなるのではないかと思った。もしこの記事を見ている方がいればぜひ、タイピング練習してみてほしい.....
Linux・シェル作成コマンドメモ

# フォルダ作成
フォルダ作成時に既にフォルダが作成されている場合は無視したい
```:# 既にフォルダが作成されている場合は無視
mkdir -p フォルダ名
```
以下例です。
```:# 例
mkdir -p test
```
# 一時停止
一時停止したい
```:# 一時停止したい
read -p "Press [Enter] key to resume."
```
# キーボード入力の取得
キーボードから入力した値を変数に代入したい
```:# キーボードから入力した値を変数に代入する
echo -n "任意の文言"
read 変数
```
以下例です。
```:# 例
echo -n "好きな数字を入力してください"
read NUMBER
```
# 変数の使用
変数の使用方法です。
```:変数の使用方法
変数名=任意の値
echo $変数名
```
以下例です。
```:例
name=Tanaka
echo $name
```
# ファイルコピー
ファイルをコピーしたい
```:
cp コピー元 コピー先
```
以下例です。
```:# 例
cp ./test1/test1.txt ./test2/test2.txt 
```

# ファイル削除
ファイルを削除したい。
```:#ファイル削除
rm ファイル名
```
以下例です。
```:# 例
rm test.txt
```
# 空フォルダの削除
空フォルダを削除したい
```:#ファイル削除
rm -d フォルダ名
```
以下例です。
```:# 例
rm -d test
```

# サブフォルダ・ファイル含めて削除
サブフォルダ・ファイル含めて削除したい
```:# サブフォルダ・ファイル含めて削除
rm -r フォルダ名
```
以下例です。
```:# 例
rm -r test
```

# ファイル名を変更
ファイル名を変更したい
```:
mv 変更前 変更後
```
以下例です。
```:# 例
mv test1 test2
```

# 参考

https://sites.google.com/site/afcinbash/home/tips/pause

https://atmarkit.itmedia.co.jp/ait/articles/1606/06/news013.html#:~:text=rm%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A8%E3%81%AF%EF%BC%9F,%E3%81%AF%E8%A4%87%E6%95%B0%E6%8C%87%E5%AE%9A%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

https://uxmilk.jp/8334

https://eng-entrance.com/linux_command_cp
EC2のインスタンス接続にて、Apacheを起動する

・EC2にてインスタンスを起動→画面上部の接続を押す
・EC2 Instance Connectから接続
・Amazon Linuxのコマンドラインにて下記コマンドを入力
```
$ sudo systemctl start httpd
```
(https://www.youtube.com/watch?v=xXuAX1ctg9E&list=PLh6V6_7fbbo8gYuNbxWXuZhTmfxzYcL9A&index=2より)


EC2入門を動画にて勉強中なので、動画中を探し直さなくて良いように自分用メモ。
前回でpart5くらいまで続けて進めていたので、インスタンスを再起動したらApacheも止まることを知らずpart1から見直して探しました(・_・`)
よく考えたらxamppだって再起動後はstartを押さないと起動できないので、それと同じでしょうか。
「マイクロサービスパターン」の復習 13章 リファクタリング

## 13章 マイクロサービスのリファクタリング

- ついに最終章である13章
- モノリシックアーキテクチャをマイクロサービスアーキテクチャへとリファクタリングする方法について
- 著者の主張は、最初はモノリシックで動くものをサクッとつくってから、メンテナンス性向上のためにマイクロサービスに変えるのが良いとしています
- なので必然的に、モノリシックからマイクロサービスへのリファクタリングは必須となります。

## マイクロサービスへのリファクタリングの概要

- まず、システムを0から作り直す「ビッグバンリライト」は止めた方がいいとのこと
- これは元と同じ機能を再現するだけで数年かかってしまうのでビジネス的になりたたないから
    - 私の実体験からいってもこれは確かにその通り。ビジネス的に新たな価値を提供することができないので、会社的にも見放されてしまうかもしれません。
- ストラングラーアプリケーション
    - 元のシステムから少しずつ一部を切り出してサービス化していって、最後には全体がマイクロサービスになるというやり方。著者的にはこちらがおすすめ。
    - このやり方ならマイクロサービス化した部分は生産性が高くなるので、ビジネス的に必要な機能を取り込みやすくなります
    - 移行過程では、（生産性の低い）モノリスの部分に対する変更量がなるべく少なくなるようにするのが大事
        - そう入ってもサービスを切り出すのには、データベースリファクタリングも必要ですけど

## モノリスをマイクロサービスに移行させるための方法

3つ挙げられています

- 新機能をサービスとして実装する
- プレゼンテーションティアとバックエンドを切り離す
- モノリスから機能を抽出してサービスで置き換える

## 新機能をサービスとして実装する

- 分析的にみて、新たなサブドメインの追加になるケース
- 手順としては大体以下
    - 新たなサブドメイン用のサービスを立ち上げる
    - APIゲートウェイで、モノリスと新サービスの振り分けを行う
    - モノリスと新サービスで通信できるような仕組みを双方に入れる。これをインテグレーショングルーと呼ぶ
        - 通信がリクエスト・レスポンスなのかイベントなのか、同期なのか非同期なのかは設計次第

## プレゼンテーションティアとバックエンドを切り離す

ここは文字通りなので省略

## モノリスから機能を抽出してサービスで置き換える

ここがメインです。

- 手順
    - 分析レベルでドメインモデルを分割・抽出する
    - それに対応するようにデータベースリファクタリングする（別テーブルあるいは別データベースに分割する）
    - あとは新機能をサービスとして実装する場合と大体同じ。インテグレーショングルーも必要に応じて作成する


問題はテーブルの分割に伴って、それを参照する実装コードを全面的に書き換えるというところです。
これを緩和する手段として、OrderテーブルからDeliveryを抽出する例が説明されています。

- Orderテーブルの中で、Deliveryに関するフィールドを特定する
- Deliveryテーブルを作成する
- Deliveryテーブルへの書き込みはトリガーを使って、Orderテーブルの該当フィールドに反映する
- モノリスはOrderテーブルをread/writeするが、Delivery部分はread onlyで扱う
- Deliveryサービスは、Deliveryテーブルをread/writeする

こうするとOrderテーブル側は、修正してないので、ORマッパーなどは変更なしで済みます

これを行う上で重要な点が2つ

- 腐敗防止層
    - インテグレーショングルーによりモノリスとサービスが通信するにせよ、トリガーによるテーブルの同期にせよモノリス側の言葉（ユビキタス言語）をそのままサービス側に見せてしまったら、せっかく抽出したらサービス側が正しいドメインモデルになりません
    - なのでインテグレーショングルーには、モノリス側のユビキタス言語とサービス側のユビキタス言語を変換する層が必要になります
    - ひらたく言えば、フィールド名の変換や、値の変換などを行います
- モノリスからのイベントパブリッシュ
    - 真正面からこれをやろうとするとモノリス側の変更量が多くなってしまうので、モノリス側のテーブルのトランザクションログをテーリングしてイベントを発行するとよい。内容が低レベルになってしまっても大丈夫ならモノリス側の変更量が抑えられる

## データ整合性

- モノリスからサービスを抽出すると、当然、トランザクションによるデータ整合性の保証ができなくなります
- なのでサーガパターンによるトランザクションのシーケンスに乗り換えることになります
- 問題はサーガによるトランザクションシーケンスの先頭の方にモノリス側のトランザクションがあると、ロールバックするときにモノリス側に打ち消し用の処理を追加しなければならなくなります
- こういうときは、サービスの抽出順を変えて、なるべくモノリス側での変更を少なくするとよい
- 例えば、FTGOの例では、サーガの先頭でOrderを作成したりするので、Orderを最初にサービスとして抽出すれば、モノリス側でOrderの打ち消し処理をやらなくて済む
- 逆に例えばTicketを先にサービスにしてしまうと、Orderがモノリスに残るので、モノリス側でOrderの打ち消し処理が必須になってしまう

## 認証認可

- モノリスならセッションだけで済んでいただろうけど、サービス側はJWTなどが必要になるので、移行途中はセッション+JWTの併用にするとのこと
- この変更は、変更箇所が局所化されているので、やればできるレベルではあるでしょう。


## 感想

- 原理上、可能なのは分かるけど、どれだけ頑張ってもあまりにも修正量が多いと言わざるを得ない
- 稼働中のシステムを、このやり方でマイクロサービスに移行させるとして、途中の段階でリリースするためにいったいどれだけ膨大なテストが必要なのだろうと思う
- もともとの著者の主張である「最初はモノリスで作って、途中からマイクロサービスに移行する」は本当に正しいのか？
    - 「プロトがモノリスで、製品はマイクロサービス」ならまだ理解できる
- この主張の背景には、「マイクロサービスアーキテクチャは素早くはじめることができない」があると思うが、こういうところこそ、今後のテクノロジーの進化で改善してほしいと思う

## この本全体を通して

- いままで慣れ親しんできたモノリスとのギャップはあまりにも大きい
- トランザクションの代わりとなるサーガや、全面的なイベント発行の採用など、やればそこそこ動くであろうことは想像できる
- 一方で、不具合なくものが作れるか？不具合があったときにデバッグできるか？再現性に乏しいデータ整合性の不具合を抑え込むことができるか？など実際に製品開発で採用して大丈夫だろうかという懸念が残った
- 実装技術もさることながら、分析レベルで「粗結合であることが自然」と思えるような、すばらしいモデルが作れないと厳しいかな？
Robocode Tank Royale 盤面を動き回る

こちらの続き

https://qiita.com/JQinglong/items/7ec02a689f78abbd3324

## 動きを変える

近場をうろちょろせず、混戦は避けるために
・盤面を動き回る
・敵に衝突したらそこから離れる

止まっている敵にも、意外と弾が命中しない。
・せめて止まっている敵には確実に命中させる

これらをやっていきます。

## 盤面を動き回る

参考になるのは、Crazy ですね。

setForward(40000) で、とりあえず長距離動く「設定を」します。
set系を使うことで、複数の動作をパラレルにさせることができる、ということで、合わせて setTurnRight(90) も使用しています。set系のメソッドの説明を見ると、IBaseBot.go() を行うまでの設定が使われるということのようなので、下記のように書くと、ぐるぐる回り出します。左に角度を変えながら前に進むので、そんな感じになるわけです。

```java
            setForward(400);
            setTurnLeft(90);
            go();
```

では、左に曲がったり右に曲がったりさせようと思って、こう書いてもうまくはいきません。

```java:
            setForward(400);
            setTurnLeft(90);
            go();
            setForward(400);
            setTurnRight(90);
            go();
```

ほぼ真っ直ぐ進もうとします。左にちょっと向きを変えて進もうとしたら、すぐ次のコマンドで右に曲がれと言われるからですね。
そこで、Crazy では、回転し切るまでwaitするようです。そのための情報として、getTurnRemaining が可能ということですね。

ただ、そのまま真似しても面白くないので、基本は左回転するけど、敵を見つけたら右回転するということにしてみました。

```java:public void run()
        while (isRunning()) {
            setForward(400);
            setTurnLeft(90);
            go();

        }
```

```java:public void onScannedBot(ScannedBotEvent e)
        fire(1);
        setForward(100);
        setTurnRight(90);
        go();
```

これはなかなか面白い。そして強い。
反時計回りに円弧を描きながら敵の後ろに回り込んで、見つけたら、左右に揺れながら前に進み撃ちまくります。
めった撃ちにしてやりますw

ただ、撃って点を稼ぐので勝率は良いですが、割と早めに退場になることが多いです。
そして、混戦を避けようと思ったのに、めちゃくちゃ自分から突っ込んでいってるのが、戦いの美学的によろしくないです。

そこで、次は、敵に衝突したらそこから離れる、ヒットアンドアウェイを考えてみようと思います。
CloudFlarePagesとMicroCMSでブログを作る

# はじめに
この記事は何も考えずにCloudFlarePagesとMicroCMSを使ってブログを作る手順というか方法を**覚書**ぐらいに書いているものです。
筆者は何も考えたくない人なので間違っている可能性もあります。情報の精査は各自でお願いします。

# Nuxtでコードを書く
公式のチュートリアルに「[microCMS + NuxtでJamstackブログを作ってみよう](https://blog.microcms.io/microcms-nuxt-jamstack-blog/)」を参考にコードを書いていきます。

書いたコードはGitHubに置いておきます。プライベートリポジトリ可です。

# CloudFlarePagesでビルドする
CloudFlareのダッシュボードにログインして、Pagesに移動して、プロジェクトを作成からGitに接続をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201995/fe7989b4-ebf6-1b8e-f8fb-ce88298f1be2.png)

初めての場合GitHubの認証画面が出ると思うので、認証を済ませます。

リポジトリを選択するから先程のコードを上げたリポジトリを選びます。

ビルドコマンド、デプロイ先は先程のチュートリアルのページを参考にしていいと思います。
自分の場合ビルドコマンドは「nuxt generate」にしています。

ビルドが走ると思いますので、エラーが出ることなく走りきれば問題ありません。

プロジェクト名.pages.devになるので、長い名前でリポジトリを作成したのなら変えておくと良いです。

## ドメインを追加する
**カスタムドメインを使用する場合、DNS を Cloudflare に移行する必要があります。**

ブログのドメインがプロジェクト名.pages.devで大丈夫じゃない方はドメインを追加する必要が出てくると思います。
特に、AdSenseで広告を表示したい方、何かしらのサービスを展開していてblog.なんとか.jpとかでサイトを公開したい方とか。

ドメインの追加は「カスタムドメイン」のページから「カスタムドメインを設定」をクリックします。
入力フォームが出てくるので、ドメインを入力します。

あとは適当にポチポチします。面倒なDNSの設定も自動で追加されるはずです。

# microCMSを更新したらビルドが走るようにする。
設定からビルド&デプロイを選択します。デプロイ フックというのがあるので、追加するボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201995/d6af1cc0-cac2-fc49-d242-28c31fed0d7a.png)

デプロイフック名は適当でいいです。ブランチも特に弄っていないのであればmasterのままだと思います。
(ブランチがmainとかになってるかも。)

追加をクリックするとURLが発行されるのでこれをコピーしておきます。

次にmicroCMSに行って、APIの設定からwebhookを選択します。
追加をクリックして、Netlifyを選びます。
Webhookの名前は適当で、下のフォームに先程コピーしたURLをペーストします。

下の通知タイミング設定はお好みで設定してください。
自分の場合は以下のようにしています。

コンテンツの公開時・更新時
- [x] コンテンツ編集画面による操作
- [ ] APIによる操作
- [ ] レビューによる公開
- [x] 予約設定による操作
- [ ] コンテンツの並び替え
- [x] コンテンツIDの変更
- [x] 公開日時の変更

コンテンツの非公開時
- [x] コンテンツ編集画面による操作
- [ ] APIによる操作

公開中コンテンツの削除時
- [x] コンテンツ編集画面による操作
- [ ] APIによる操作

上記にない設定はチェックを入れていません。

これで実際に投稿してみて、ビルドが走れば設定に問題がないと思います。
あとは、実際に使ってみて、問題がなければおｋだと思います。
ノンビン塾～エンジニアとしての成長記録3～

## ノンビン塾について
そもそもノンビン塾ってなに？
→[過去の記事参照](https://qiita.com/kenny_engineer/items/fc3a45ef2c123ce49495)

## 前回の課題提出
### テーマ
　何か一つ業務をフローチャートで示す

### 回答
　某業務の対応について流れを作成してみることにした。
　　※業務内容に直結する為、ボカシ入り
![Untitled(1) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627323/eff304d3-deb3-a702-fb0d-c67909707a0d.png)
　作成自体はスムーズにできた。
　しかも、割とよくできた！とさえ思った。
　ところがだ。。
　以下フィードバックのとおり、漏れがあった。
　アドバイスを受けて、なるほど確かに。。と唸るケニー。。
　うむむむむむ。悔しい。
### フィードバック
* 分岐ができてて良い。
* 自分が担当かつ自分で回答できそうな内容に対して、
チームメンバーに回答をお願いする分岐があってもよかった
* 自分やチームで回答できそうにない内容に対して、もう少し細かく書くと良い。
* 返信待ちのステータスがあってもよかったね（解決までの流れ）

## 今回の講義
【テーマ】
　対象の年を渡すと、閏年かどうかを計算するフローチャートを書いてみよう。

　前提条件
　・４で割り切れる
　・１００で割り切れない
　・１００で割り切れるが、４００でも割り切れる

今までに閏年を計算した事がなかったので、正直かなり苦戦した。苦笑
＜苦戦したポイント＞
　「100で割り切れない」の次が「100で割り切れるが・・略」とあったので、
　このあたりのフローチャートを示せなかった。  
　そもそも「100で割り切れない」で、YESだった時の行先が分からなかった。
　答えはシンプルだった。。【YES＝閏年】だった。。笑
　oh....bloody hell... :(

![Untitled(1) (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627323/7a04b344-71e7-bf60-87d5-e7d3d5816020.png)



### 次回ノンビン塾までの課題
　130円の飲み物と160円の飲み物、この２種類しかない自動販売機で、
　飲み物を買うまでの動きをフローチャートで示す。
　※お金が入った→飲み物が出てくる　まで。
　※お金は小銭のみ！


## 感想
閏年フローチャート作成は苦戦してしまった。
今回の学び・気づきは、
* 最初は分からなくても、作成しながら理解していく（整理していく）方法で良い。
* 詰まってしまったら、どうしようもない。
実務ではすぐにヘルプを求めるべし。笑
* フローチャートはとりあえず7〜8割完成させたら、一晩寝かしてみようかな。
一晩寝かして頭をリフレッシュさせて見直すと、抜け漏れなどに気づきそう。
[AWS] [EC2] 踏み台サーバーに秘密鍵を送る方法

### 今回やりたかったこと
AWSについて勉強中です。
踏み台サーバー(パブリックサブネットに作成したEC2)に
秘密鍵（〇〇.pem）をコピーし、
バッチサーバー（プライベートサブネットに作成したEC2）にSSHで入りたい

### 前提
環境はcloud9です。
VPC内にパブリックサブネットとプライベートサブネット、EC2は既に構築してあります。

### 結論

注意：cloud9側で！
```terminal:terminal
scp -i ~/.ssh/〇〇.pem ~/.ssh/〇〇.pem ec2-user@踏み台サーバーのパブリックipアドレス:.ssh/〇〇.pem
```
上記コマンドで自分はできました。
cloud9側の秘密鍵が違うディレクトリにある場合は適宜変えてください！
scpはcp(コピー)をs(シークレット)にするコマンドです。大事なものはこのコマンドで送ります。

例↓
```terminal:terminal
scp -i ~/.ssh/test.pem ~/.ssh/test.pem ec2-user@35.77.102.64:.ssh/test.pem
```
おそらく、
最初の~/.ssh/〇〇.pemはそもそもコピーするために鍵が必要なのでcloud9側に存在している鍵を使ってる
２番目がcloud9側のどのディレクトリの何をコピーするか
3番目が指定したipアドレスを持つEC2側のどこにどんな名前で配置したいのか
だと思います。
なので3番目のみ任意の置き場・名前でもできると思います。

### おすすめです
AWSを勉強しているけど全く理解ができないって方（自分）にとてもおすすめします。
youtubeチャンネルですがこの方の説明がかなりわかりやすく、何をするための作業なのかを最初に噛み砕いて説明してくれるので理解度が違います！
再生リストのAWS入門「ELBとEC２で負荷分散をしてみよう」に今回のことも一連の流れとして載ってます。

https://www.youtube.com/channel/UCI2HUZx-Ch6oc96o7BQ9JLQ

### 最後に
とても簡単なのですが、自分は全てにおいて全く理解できていないために秘密鍵の受け渡しですら手間取ってしまいました。

しかし動画で理解を深めるのはやっぱいいですね。
文字でインプットするよりも聞くほうが遥かに理解が進み、その後に文字で読むともう少しだけ深いことが頭に入って来る気がします。

それではここまで閲覧頂きありがとうございました！
ABC075 B問題 配列不使用縛りの中で解く

2, 3日前からAtCoderのC++入門に取り組みはじめた。(b'-' )

https://atcoder.jp/contests/abc075/tasks/abc075_b

[C++入門 AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/apg4b/tasks/APG4b_m)で、
「文字列の知識があれば解けるB問題も紹介します。」と書いていた、
配列を使わない、C++入門のこのページまでに出た知識で解く縛り。。

この縛りの中で、もっと簡単な解法あったら教えてほしい。。

```
#include <bits/stdc++.h>
using namespace std;

int main() {
  int h, w;
  cin >> h >> w;
  
  string a = "";
  
  for (int i=0; i<h; i++) {
    string s;
    cin >> s;
    a = a + s;
  }
  
  for (int i=0; i<(h*w); i++) {
    int el = 0;
    int x = i%w + 1;
    int y = i/w + 1;
    
    if (i != 0 && i%w == 0) {
      cout << endl;
    }
    
    if (a.at(i) == '#') {
      cout << '#';
      continue;
    }
    
    if (x-1 > 0) {
      int p = x-1;
      int q = y;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (x+1 < w+1) {
      int p = x+1;
      int q = y;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (y-1 > 0) {
      int p = x;
      int q = y-1;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (y+1 < h+1 ) {
      int p = x;
      int q = y+1;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (x-1 > 0 && y-1 > 0 ) {
      int p = x-1;
      int q = y-1;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (x+1 < w+1 && y-1 > 0) {
      int p = x+1;
      int q = y-1;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (x-1 > 0 && y+1 < h+1 ) {
      int p = x-1;
      int q = y+1;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    if (x+1 < w+1 && y+1 < h+1 ) {
      int p = x+1;
      int q = y+1;
      if (a.at(p+ (q-1)*w -1) == '#') { el++; }
    }
    cout << el;
  }
  cout << endl;
}
```
「DPC導入の影響評価に係る調査」実施説明資料のPDF内のICDコードをCSVに変換

https://www01.prrism.com/dpc/2021/top.html

2022年度「DPC導入の影響評価に係る調査」実施説明資料をダウンロード

```
!wget https://www01.prrism.com/dpc/2022/file/setumei_20220331.pdf
```

# プログラム
```
!apt update
!apt install ghostscript
!pip install camelot-py[cv]
```

```python
import camelot
import pandas as pd

# ページ範囲
pages = "145-168"

tables = camelot.read_pdf("setumei_20220331.pdf", pages=pages, split_text=True)

dfs = [pd.DataFrame(table.data[1:], columns=table.data[0]) for table in tables]

# 結合
df = pd.concat(dfs).reset_index(drop=True)

# 列名の改行を除去
df.columns = df.columns.str.replace("\s", "", regex=True)

df

df.to_csv("result.csv", encoding="utf_8_sig", index=False)
```
【2022年版】中年から始める awk

# AWK メモ

## 基礎書式

- awk プログラム 入力ファイル
  例：```awk '$3 > 100 {print $1, "calc = ", $2 * $3, $0}' data.txt```
- プログラム = パターン {アクション}
  例：```'$3 > 100 {print $1, "calc = ", $2 * $3, $0}'```
- サンプル
  ```
  % cat << EOF > data.txt
  heredoc> a 1000 0
  heredoc> b 1000 20
  heredoc> c 1000 100
  heredoc> d 800 180
  heredoc> e 1200 0
  heredoc> f 1300 100
  heredoc> EOF
  % awk '$3 > 100 {print $1, "calc = ", $2 * $3, $0}' data.txt
  d 144000
  ```

## パターン
### BEGIN, END
  - BEGIN
    構文：```BEGIN {文}```
    例：```BEGIN {print "-----"}```
  - END
    構文：```END {文}```
    例：```END {print "-----"}```
### 式
  構文：```式 {文}```
  例：```$3 > 100 {print $1, "calc = ", $2 * $3, $0}```
  例：```$1=="c" {print $1, $2 * $3}```
### 正規表現
  構文：```/正規表現/ {文}```
  例：```/^c+/ {print $1, "calc = ", $2 * $3, $0}```
  例：```/JPN/ {print $1}``` 行全体にJPNを含む（↓と同一）
  例：```$0 ~ /JPN/ {print $1}``` 行全体にJPNを含む
  例：```$1 ~ /JPN/ {print $1}``` $1がJPNを含む
  例：```$1 !~ /JPN/ {print $1}``` $1がJPNを含まない

### 複合
  - and
    構文：```式 && 式 {文}```
    例：```$1 == "c" && $3 == 100 {print $1}```
  - or
    構文：```式 || 式 {文}```
    例：```$3 == 0 || $3 == 100 {print $1}```
### 範囲
  構文：```パターン１, パターン２ {文}```
  例：```/JPN/, /USSR/ {print $1}```JPNからUSSRまでの範囲が該当（USSRが出てこなければ最終行まで全選択

## 組込変数
  - ARGC
    コマンド行引数の数
  - ARGV
    コマンド行引数の配列
  - FILENAME
    ファイル名、新しいファイルが読まれるたびに設定される
  - FNR
    現在までに読み込んだ現在のファイルの行数、現在のファイルのレコード番号
  - FS
    列の区切り文字
  - NF
    現在のレコードの列数
  - NR
    現在までに読み込んだ行数
  - OFMT
  - OFS
  - ORS
  - RLENGTH
  - RS
    行の区切り文字、入力レコードの区切文字
  - RSTART
  - SUBSEP
## 組込算術関数
  - atan2(y, x)
  - cos(x)
  - exp(x)
  - int(x)
  - log(x)
  - rand()
  - sin(x)
  - sqrt(x)
  - srand(x)
## 組込文字列関数
  - gsub(r, s)
  - gsub(r, s, t)
  - index(s, t)
  - length(s)
  - match(s, r)
  - split(s, a)
  - split(s, a, fs)
  - sprintf(書式, 式)
  - sub(r, s)
  - sub(r, s, t)
  - substr(s, p)
  - substr(s, p, n)
## アクション
### 式
  - print 式
  - print (書式, 式)
### 制御文
  - if (式) 文
  - if (式) 文 else 文
  - while (式) 文
  - for (式; 式; 式) 文
  - for (変数 in 配列) 文
  - do 文 while (式)
  - break
  - continue
  - next
  - exit
  - exit 式
  - {文}
### 配列
  - split
  - delete
  - pop
## ユーザ定義関数
  - function 関数名(引数) {文}
## 出力
  - print
  - printf
  - close
  - system
### print文
### ファイル
### パイプ

## 入力
### 区切り
### 複行
### getline関数

## system関数

## データ変換

## データ検証

## Bndle, unbundle

## 複行
Azure function appをazure devops pipelineでデプロイする with terraform

個人用です。

## 概要
えーマジazure devops!?azure devopsは小学生までだよねー！キャハハ

小学生と言わず一生無関係でいたかった。

### 条件
以下のterraformでfunction appを作成した

```
// https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_function_app
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

resource "azurerm_storage_account" "example" {
  name                     = "linuxfunctionappsa"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_service_plan" "example" {
  name                = "example-app-service-plan"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  os_type             = "Linux"
  sku_name            = "Y1"
}

resource "azurerm_linux_function_app" "example" {
  name                = "example-linux-function-app"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  storage_account_name = azurerm_storage_account.example.name
  service_plan_id      = azurerm_service_plan.example.id

  site_config {}
}
```

これに対して、azure devops pipelineからfunction appをデプロイすると以下のようなエラーが発生した

```
2022-06-23T13:33:49.1568910Z ##[error]Error: Unable to find the storage account associated with the function app.
```

ちなみにデプロイ方法は

```
steps:
- task: AzureFunctionApp@1
  displayName: 'Azure Function App Deploy'
  inputs:
    azureSubscription: 'xxxxx'
    appType: functionAppLinux
    appName: 'func-xxxxxx'
    package: 'xxxxxx'
```

これ

### 原因

storage_account_access_keyを設定したら解消出来ました。
手動だと設定しなくてもdeploy出来たんだけどなぁ。。。
Rubygemsの基本コマンド(インストール/アンインストール/確認)

## はじめに
Ruby用のパッケージ管理システムであるRubygemsの基本コマンド(インストール/アンインストール/確認)について記事を書きます。
自宅のMacにchefを導入しようと試みる過程でgemを触っていて、パッケージの確認やインストール等をする機会があり、そこでコマンドの使い方を調べていたことが記事を書く動機になります。

## コマンド一覧

### Gemのインストール

```zsh:コマンド
gem install <対象のGem>
```

```zsh:実行例
% gem install chef
Fetching aws-eventstream-1.2.0.gem
Fetching multi_json-1.15.0.gem
Fetching uuidtools-2.2.0.gem
Fetching aws-sigv4-1.5.0.gem
Fetching little-plugger-1.1.4.gem
Fetching vault-0.17.0.gem
Fetching rubyntlm-0.6.3.gem
〜〜〜省略します〜〜〜
```

### インストール済みのGemを確認

```zsh:コマンド
gem list
```

```zsh:実行例
% gem list

*** LOCAL GEMS ***

abbrev (default: 0.1.0)
addressable (2.8.0)
aws-eventstream (1.2.0)
aws-partitions (1.600.0)
aws-sdk-core (3.131.2)
aws-sdk-kms (1.57.0)
aws-sdk-s3 (1.114.0)
aws-sdk-secretsmanager (1.64.0)
aws-sigv4 (1.5.0)
base64 (default: 0.1.1)
〜〜〜省略します〜〜〜
```

### Gemのアンインストール

```zsh:コマンド
gem uninstall <対象のGem>
```

```zsh:実行例
% gem uninstall knife
Remove executables:
	knife

in addition to the gem? [Yn]  Y
Removing knife
Successfully uninstalled knife-17.10.0
%
```

## まとめ

|  コマンド  |  内容  |
| ---- | ---- |
|   gem install <対象のGem> |  Gemのインストール  |
|  gem list |  インストールされているGem一覧を確認  |
|  gem uninstall   |  Gemのアンインストール |

## 参考情報
https://qiita.com/shimadama/items/cb3942135ef7397ed496
【Automation Anywhere】日付の形式を揃える - はじめてのAA

# 今日はこれを覚えよう！

「2022年2月1日」「2022/02/01」「1.2.2022」など、様々な形式で書かれた日付の形式を揃える方法を解説します。

日付の形式を揃える操作はRPAの中では頻出で、これができるとやれることの幅がぐっと広がります！

型という考え方に慣れない方には少し難しく感じるかもしれませんが、少しずつ理解しながらやっていきましょう！

# 日付の形式を揃える

ここでは、「1.2.2022」と書かれた日付を「20220201」という形式に揃える方法を例に手順を解説していきます。

## 作り方

日付の形式を揃えるためには、２つのステップが必要です。

1. もとの日付の文字列（1.2.2022）を、日付型の変数に入れる
1. 日付型の変数を、揃えたい形式(20220201)の文字列に変換する

以下、順を追って見ていきましょう。

### 1. もとの日付の文字列（1.2.2022）を、日付型の変数に入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/bb9c57d0-3a20-4ee8-bf0e-33cf1923c15f.png)

※１：d.M.yyyyは、最初の１桁は日（ゼロ埋めなし）で、そのあとに.が来て、次に月（ゼロ埋めなし）が来て、また.が来て、最後に4桁の西暦年が入るよ！という意味です。それ以外の形式の場合にどのように指定すればいいかは、[こちらの記事（主に後半部分）](https://qiita.com/IQ_Bocchi/items/43cafbc56cf609b7a959)を参考にしてみてください。

※２：日付型の変数を設定する、の意味がわからなくても大丈夫。④の入力欄の横にある小さなxのようなマークを押すと、変数の作成画面が起動しますが、この変数は勝手に日付型になります。

なお、「文字列」や「日付型」という言葉がピンと来ない方は、以下の記事を参考にしてみてください。

https://qiita.com/IQ_Bocchi/items/f6d6ab7ccfeb2f29641e

### 2. 日付型の変数を、揃えたい形式(20220201)の文字列に変換する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f8e73da0-fa26-72b4-7c04-e12a0ebd68eb.png)

※１：yyyyMMddは、最初の4桁は西暦年、次の2桁は月、最後の2桁は日にしてね、という意味です。これ以外の形式にしたい場合にどのように指定すればいいかは、[こちらの記事（主に後半部分）](https://qiita.com/IQ_Bocchi/items/43cafbc56cf609b7a959)を参考にしてみてください。

※２：文字列型の変数を設定する、の意味がわからなくても大丈夫。④の入力欄の横にある小さなxのようなマークを押すと、変数の作成画面が起動しますが、この変数は勝手に文字列型になります。

## 結果

上記の例で、「日付_編集後」という変数を表示すると、以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/3bc0eb71-5d2a-2ae8-e382-8fcb34666929.png)

⇩

表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/ad49c850-76b5-076b-51d2-f79dd9b30e13.png)

# 以上！

いかがでしたか？

日付の形式を揃えたり、フォーマット変換を使いこなせると、RPAでできることの幅がぐっと広がります。

この機会にぜひ日付の形式変換をマスターしてみてください！

# もっと知りたい！　学びたい！

この記事を読んで、「Automation 360 の使い方をもっと知りたい！」と思った方は、以下のシリーズをチェックしてみてください。

Automation360の基礎知識や使い方を、わかりやすくまとめたシリーズで、この記事もシリーズの１トピックとなっています。

https://qiita.com/IQ_Bocchi/items/8d28f12256037b5f9058

Automation Anywhere を使い始めたばかりの方はもちろん、これから使ってみようと思っている方や、ずっと使っているけど改めて基本を学びたい方などは、ぜひチェックしてみてください！
Protocol Buffers について調べたことを殴り書く

gRPC 使うことになったのでメモ、、

# Protocol Buffers とは

> プロトコルバッファは、構造化されたデータをシリアライズするための、言語やプラットフォームに依存しない、Googleの拡張可能なメカニズムです

> 構造化されたデータを前方互換および後方互換の方法でシリアライズするための、言語、プラットフォーム、拡張性にとらわれないメカニズムを提供します

（公式を Deepl に突っ込んでみた）

ふむ、わからん。
とりあえず読み進めてみると、、

> JSONに似ていますが、より小さく高速で、ネイティブの言語バインディングを生成することができます

まとめると、、、

- 互換性がある
- 言語間の壁がない
- JSON や XML みたいなデータの記述形式

# Protocol Buffers の構成要素

> 定義言語（.protoファイルで作成）、protoコンパイラがデータとのインタフェースとして生成するコード、言語固有のランタイムライブラリ、ファイルに書き込む（またはネットワーク接続で送信する）データのシリアライズ形式の組み合わせである。

ふむ、わからん。
1つずつみていく。

## ① .protoファイル とは

- プロトコルバッファのメッセージとサービスを定義するファイル
- .proto ファイルは、構造化されたデータを表すという点では JSON ファイルに似てる
- .proto ファイル上でコンパイラを実行すると、選択したプログラミング言語でデータを読み書きできるコードを生成することができる
- ちなみに proto2 と proto3 で書き方が違うらしい

### メッセージとは

- プロトコルバッファではやり取りするデータを「メッセージ」と呼ぶ
- こんな感じ⏬で書ける

```proto
message メッセージ型の名前 {
    型 フィールド1 = 1;
    型 フィールド2 = 2;
    型 フィールド3 = 3;
}
```

書いてみたらこんな感じ⏬

```proto
syntax = "proto3"; // これ書かないとデフォルトで proto2 になる

message Sample {
    int32 id = 1;
    string name = 2;
    bool isBool = 3;
}
```

### サービスとは

- APIの定義本体、らしい
- サービスの中にメソッド　(rpc)　を含めることができる
- ちなみに4種類ある（詳細は[こちら](https://zenn.dev/hsaki/books/golang-grpc-starting/viewer/stream)で、、）
    - 単項RPC
    - サーバーストリーミングRPC　　
    - クライアントストリーミングRPC　
    - 双方向ストリーミングRPC


こんな感じで書ける⏬

```proto
service サービス名 {
 rpc メソッド名 (引数のメッセージ型) returns （返り値のメッセージ型） {}
}
```

実際に書いてみるとこんな感じ

```proto
service Sample {
    // 単項RPC
    rpc Sample (SampleRequest) returns (SampleResponse);

    // サーバーストリーミングRPC　　「返り値の型の頭」に stream をつける
    rpc SampleServerStreamMethod (SampleRequest) returns (stream SampleResponse);

    // クライアントストリーミングRPC　「引数の型の頭」に stream をつける
    rpc SampleClientStreamMethod (stream SampleRequest) returns (SampleResponse);

    // 双方向ストリーミングRPC　　「返り値と引数の型の頭」に stream をつける
    rpc SampleBidirectionalMethod (stream SampleRequest) returns (stream SampleResponse);
}
```

## ② protoコンパイラ

- 先ほど述べた proto ファイルを、他の言語で読み込めるようにコンパイル（変換）してくれるらしい
- コンパイル後に生成されたコードが、「データとのインタフェース」としての役割を担う
- ちなみにコンパイル後に生成される言語は C / Java / PHP など色々対応してるらしい（[参考]()）

https://developers.google.com/protocol-buffers/docs/overview#cross-lang




## ③ 言語固有のランタイムライブラリ

- ランタイムライブラリとは「プログラムとかを動かすときに必要な部品のこと」
- protpcol Buffer を動かすためのライブラリが必要ということ
- ちなみに TS だと[こんなもの]()があった

https://www.npmjs.com/package/@protobuf-ts/runtime


# 参考


https://developer.amazon.com/en-US/docs/alexa/alexa-gadgets-toolkit/proto-buffer-format.html#overview

https://qiita.com/Captain_Blue/items/b7a1f4a42f48559fac0c


https://developers.google.com/protocol-buffers/docs/overview

https://qiita.com/yugui/items/160737021d25d761b353

https://qiita.com/kitauji/items/fdbd052c19dad28ab067
Pythonのlist型とtuple型のメソッド比較

## シーケンス型

list型とtuple型は、共にコンテナシーケンス型。
list型は可変、tuple型は不変。

|型|可変/不変|コンテナ/フラット|
|---|---|---|
|list|可変|コンテナ|
|tuple|不変|コンテナ|
|collections.deque|可変|コンテナ|
|str|不変|フラット|
|bytes|不変|フラット|
|array.array|可変|フラット|
|bytearray|可変|フラット|

## list型とtuple型のメソッド比較

|メソッド|説明|list型|tuple型|
|---|---|---|---|
|s[p] (s.\_\_getitem\_\_(p))|位置pにある要素を取得|●|●|
|s.index(e)|eの最初出現位置を探す|●|●|
|len(s) (s.\_\_len\_\_())|要素数|●|●|
|s.count(e)|要素eの出現回数を計算|●|●|
|e in s (s.\_\_contains\_\_(e))|e in s|●|●|
|s.\_\_iter\_\_()|イテレータの取得|●|●|
|s + s2 (s.\_\_add\_\_(s2))|連結|●|●|
|s += s2 (s.\_\_iadd\_\_(s2))|置換連結|●||
|s * n (s.\_\_mul\_\_(n))|繰り返し連結|●|●|
|s *= n (s.\_\_imul\_\_(n))|繰り返し置換連結|●||
|n * s (s.\_\_rmul\_\_(n))|逆繰り返し連結|●|●|
|s[p] = e|要素eで位置pにある既存要素を上書き|●||
|s.append(e)|最後に要素eを追加|●||
|s.extend(it)|リストに別のリスト（iterableオブジェクト）の要素を一つずつ要素として追加|●||
|s.insert(p, e)|位置pの前に要素eを挿入|●||
|s.pop([p])|最後の要素または位置pの要素を取り出す(pはオプション)|●||
|s.remove(e)|最初に出現する要素eを削除|●||
|s.\_\_delitem\_\_(p)|位置pにある要素を削除|●||
|s.clear()|全ての要素を削除|●||
|s.reverse()|順序を逆にする|●||
|s.\_\_reversed\_\_()|逆順序のイテレータの取得|●||
|s.sort([key], [reverse])|ソート（keyとreverseはオプション）|●||
|s.copy()|リストのコピー|●||
|s.\_\_getnewargs\_\_()|pickleによる最適な直列化のサポート||●|