OmniAICreator/Qiita-1.07M huggingface dataset:
しぐじり英語　---アプリ名間違えて名付けた編---

# 始めに
"Jack the Porker"というSafari拡張機能を作成しました。
## 拡張機能の概要 
"Jack the porker"は、ポップアップページ内でカードを数えるための拡張機能です。
 この拡張機能は、カードをクリックすることにより、カードを数えることを手助けします。
一つのカードをクリックした場合、そのカードは暗くなります。
全てのカードをリフレッシュしたい場合、"Refresh"ボタンをクリックすると全てのカードが明るくなります。

## スクリーンショット 
![screenshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634761/893b57f3-ab8c-8749-fd9c-50ec9a4f760f.png)

![screenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634761/f3b73a9a-c574-3337-9d16-ee9f5e9820fb.png)

![screenshot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634761/7d5bb606-67ea-5e20-b9f8-03e6f89ad560.png)

## リンク
https://apps.apple.com/jp/app/jack-the-porker/id1617402743

# 何を間違えたか？
## "Porker"じゃなくて"Poker"だよー！
トランプゲームのポーカーのつもりだったんです。。。
Pokerですね。。。
知らないのモロバレ。。。恥ずかしい。。。

# 開発のハマりどころ
Javascriptで初めてアプリを書いてみました。
コードをGitHubに置きました。
https://github.com/Kouhei-Takagi/Jack-the-Porker

# 皆さんも英語の綴りには気を付けてください。。。
私のようなミスはしないだろうとは思いますが、アプリ名で間違えると取り返しつかないですね。。。
〜インターネットができるまで〜

参考　マスタリングTCP/IP第五版

インターネットの歴史について面白かったので自分なりにまとめてみました。

### 結論

結論から言いますと、インターネットの起源は「ARPANET」だと言われています

インターネットの始まりは1960年のアメリカ国防総省（DoD）と4つの大学が協力して開発した「ARPANET」という当時としては非常に大規模なネットワークが起源だと言われています。

一般のユーザーも取り込んで行われ、わずか3年で4つの接続から34の接続ができる形にまで発展したそうです。

当時は、今よりもパソコンが高価なものだったと思うので本当に一般のユーザーだったのか怪しいところですね...ｗ

### ARPANET誕生前の出来事

1960年代、アメリカのDoDが中心になって進められていた研究がありました。当時のアメリカでは『通信は軍事的に重要なものだ』という考えがありました。そこで、『通信経路が破壊されても、迂回経路を通して通信ができる技術』が望まれました。ここで、分散型のネットワークの考えが生まれ、この考えを実現するべく「パケット通信」の考えが生まれました。

そして、このパケット通信の考えを実現するべく開発されたのがインターネットの起源と呼ばれる「ARPANET」です。

もっと詳しくいうとパケット交換技術の実用性を試験するためのネットワークが先に構築され、その後に一般のユーザーも取り込めるまでに発達したのが「ARPANET」というネットワークです

### TCP/IPの誕生

そして、1970年代前半、ARPANETの研究グループによって「TCP/IP」というプロトコルが開発されました。

TCP/IPは「仕様書よりも先にプログラムができた」と言われるほどに「実際に通信ができるか」を重視した考えで開発が進められたと言われています。

その後、1982年ごろまでかかってTCP/IPの仕様が決定され、その1年後にはARPANETで使う唯一のプロトコルになりました。

このTCP/IPが普及したのは、「BSDUNIX」というOSの内部でTCP/IPが使われていたのが関係していると言われています。

そして、1980年代からTCP /IPによって構築される世界的なネットワークを「インターネット」と呼ぶようになりました。企業などを中心に導入が進められ、コンピュータメーカー独自のプロトコルも次第にTCP/IPに対応していったと言われています。

### そして現在へ…

1990年代になるとインターネットの商用サービスが開始され、ISPなどのプロパイダがネットワークを構築して一般の市民にも提供するようになり、「インターネット」という言葉が徐々に親しまれるようになり、今では「私たちの生活に欠かせないもの」と言っても過言では無いものへと発達しました。

その使用例は数え切れないですよね。例えば、

SNS（ツイッターやインスタ）、ゲーム（オンライン対戦など）、携帯の通信データ（いわゆるギガ）、この記事なんかもインターネットが無いと成り立たないかもしれません。

### 雑感

改めて、技術の進化するスピードが速いと思いました。だからこそ、いつになっても腐らないUNIXとかネットワークの知識は深めておきたいと思いました〜。ちなみに、昔もてはやされて今では定番の技術の一つになったものを尊敬の意を込めて「枯れた技術」というそうですよ。初めて聴いたら、誤解してしまいそうですよね…ｗ

参考　マスタリングTCP/IP第五版
javaScriptの課題の追加と踏み込んだ学習の際の書籍

また、もっと踏み込んだ学習する際に、
おすすめの書籍を聞かれることがあって、
サイ本という分厚い本があるので、
そちらをおすすめしたりしてます。

記事はこちらに移動しました

[【プログラミング学習者向け】javaScriptを一歩、踏み込んで学習をするためのおすすめの一冊](https://manabupanda.net/study_programming/web-programming/javascript-study-step-up-books/)
Apache Commonsを使うための準備 【Eclipse遍】


# 1.はじめに
Apache Commonsを知っている方は多いとは思いますが、実際に使ったことないな～とかどうやって使えばいいかわからん!という人に使い方を教えます。

# 2.ライブラリをダウンロードとセッティング
今回はAppache Commonsの中でも有名なAppache Common Langをダウンロードします。

まず、[Appache Commonsの公式サイト](https://commons.apache.org/)に行くと以下の画面にたどり着きます。
![s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/646a5a16-2e30-e012-7583-478700f937de.png)

次に、ずらーっと書かれた~~読む気も失せる~~英語をスクロールするとライブラリのリストが出てくるのでそこから使いたいものを選択します。(今回はCommons Langを選択します)
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/0629a3a3-6b21-5f91-2eb7-f9c1cbb53c09.png)

そして、Downloadのところをクリック
![スクリーンショット (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/d70f3fce-1b5c-c54e-85b3-f6466824d0e1.png)

ここで、Binariesの下のやつをクリックしてダウンロードします。(※ライブラリのバージョンによってはJavaのバージョンに対応していないということもあるので注意)
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/c308af25-52ad-6e1b-a0ba-b758cc2ad0b3.png)

ダウンロードが完了すると、以下のようなzipファイルがあるので7zipなどで解凍をします。
![スクリーンショット (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/ea9f7058-278d-ca9e-a0fe-e1387056c635.png)


解凍したフォルダを開くとcommons-〇〇.jarがあるので、Eclipse上であらかじめ作成しておいたプロジェクトの上にドラック＆ドロップ
![スクリーンショット (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/17a310cd-65fe-14ab-46f8-e4c7aee3605b.png)

最後に、右クリックからビルドパスを通して、このようになったら準備完了です。
![スクリーンショット (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615563/5a67deec-4d18-9fbb-f9f9-16bc9567d6a8.png)


# 3.最後に
私自身もAppache Commonsを使いたいなと思って適用させる方法を調べたけれど、どこにも詳しい方法が載ってなくてわからん!ってなった人なので使いたいと思っている人の参考になればと思います。

次は、何かしらのApache Commonsライブラリを使った記事を作成したいと思います。

それでは!!!
[メモ]LINQ WhenAllの罠

WhenAllでTaskを呼ぶとキューを順次実行するのではなく同時に並行実行するため、DBの排他制御時など同時実行が不可能な処理を含む場合は注意。
当然実行順序も保証されない。

EFcore参照でawaitしている場合に以下のような例外が発生した。
```
System.InvalidOperationException: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
   at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.EnterCriticalSection()
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
```

なかなかこの情報にたどり着けなかったので個人的な備忘録を残しておく。
横着せず一件ずつ実行してしまえば解決する。
reactのaxios API接続先をdev/stage/prodの３環境で分けたい

## reactのAPI接続先をdev/stage/prodの3環境でｘ分けたい

が、意外とジャストインケースに説明してる記事がなかった。
develop/productionならbuild時に.env.xxxのファイル名を見て勝手に分けてくれるのですが、ステージングがない。

開発環境→localhost:3000がAPIサーバー
ステージング→stage.xxxx.xxxx:8000がAPIサーバー
本番環境→ xxx.xxxがAPIサーバー

という風にdev/prod以外の環境を追加するには工夫が必要でした。

## それぞれ環境の.envファイルを用意します

```
.env
.env.stage
.env.prod
```

## envファイルに接続先の設定を書きます

```
REACT_APP_NODE_ENV='production'
REACT_APP_API_BASE_URL="https://xxxxxx.xxxxxx:8000"
```

## axiosのconfigファイルを作ります

適当にbaseURLを環境変数から取得して設定します。
baseURLをnullにするとhostが0.0.0.0にされてしまうのでこういう風に分岐。

```configs/axios.js
import axios from "axios";

if (process.env.REACT_APP_NODE_ENV === "production") {
  instance = axios.create({
    baseURL: process.env.REACT_APP_API_BASE_URL,
    // 以下省略
  });
} else {
  instance = axios.create({
    // 以下省略
  });
}

export default instance;

```

もちろん、axiosを使うときは、上記のファイルを読み込むように。
```
import axios from "configs/axios";
```
するんやで。

## 最後に、dotenvで環境変数を分ける

dotenv-cliをインストールしてね。

```
yarn add -D dotenv-cli
```

### package.jsonを変更

```package.json
  "scripts": {
    "start": "react-scripts start",
    "build:stg": "dotenv -e .env.stg react-scripts build",
    "build:prod": "dotenv -e .env.prod react-scripts build",
  }
```

これで、それぞれ指定した環境のenvファイルを読み込んでくれます。

## 参考

https://dev.classmethod.jp/articles/react-dotenv-cli/
https://teratail.com/questions/202331
https://qiita.com/T_unity/items/2dfe1d7326f18b020b6d
nginxがサーバーのストレージを食いつぶす話

とある大容量ファイルを扱うWebシステムを運用していたところ
サーバーのストレージが枯渇しかけるという局面に出会ったのが今回のお話。

結論を言うと**nginx**の設定値に問題があったのですが、
原因を見つけるまでの経緯と注意点について備忘録を残しておこうと思います。

::: note info
ちなみにOSはDebian系、Webサーバーはnginx、アプリケーションはpythonです。
:::

## 発覚

大容量ファイル（数GB～数十GB）のファイルを扱うWebシステムを運用して、
利用がだいぶ増えていたある日、サーバーの物理ストレージが数GB単位で減っては増え
減っては増えを繰り返していることが分かりました。

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198205/82b98570-7393-3582-03b7-60bcdb3539a9.png)

はじめはアプリケーションに問題があると考え、
ファイルのアップロード/ダウンロードを行うコードを読み返しましたが
特に直接ストレージに干渉するような処理は見受けられず。
ただ、検証環境でも再現はするのでまずはdf,duコマンドで確認しました。

すると全体のストレージ空き容量と実際に見えるサイズが異なる状態であったので
lsofコマンドでプロセスが開いているファイルを見たところ
```
$ sudo lsof / | sort -k7 -nr | head -1
nginx ** app ** ** **,* 1055604736 ** /var/lib/nginx/proxy/**** (deleted)
```
きっちりnginxが1GB使っていることが確認できました。

## 対処

アプリケーションの作り上、アップロードは数MBのチャンクでデータを扱っていたため
今回GB単位でストレージを消費するのはダウンロードだけでした。

ということで、ドキュメントを読み漁っていたところ原因は
nginxのバッファリングであったということが分かりました。

[Module ngx_http_proxy_module＞proxy_buffering](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering)
[NGINX リバースプロキシ＞バッファの設定](http://mogile.web.fc2.com/nginx/admin-guide/reverse-proxy.html)

localhost内でアプリケーションをプロキシしていたので
そのレスポンスをnginxがバッファしていたということになります。

ただし、nginxの一時ファイルは1GBまでの制限があるので、今回は恩恵を受けられない。
ということで該当パターンのみ設定をOFFにしました。

以下、ドキュメントより設定例
```
location /some/path/ {
    proxy_buffering off;
    proxy_pass http://localhost:8000;
}
```

::: note
ちなみにバッファがONになっていることでアプリケーション稼働は最適化されるなど
メリットも多いので制限をかけるかどうかは一考の余地があります。
:::

上記設定後、テストしたところストレージを食いつぶすような動きはなくなりました。

## 余談

今回はダウンロードが主な問題になりましたが、
アプリケーションの作り次第ではアップロードで大容量ファイルを扱う際も
同じ問題にぶつかることがあると思います。
その際は、**proxy_request_buffering**を設定してあげればいいようです。

[Module ngx_http_proxy_module＞proxy_request_buffering](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering)
AWS Session Manager経由のSSH接続でAWSのprofileを指定するには・・

## Session Managerを使ってEC2に直接SSHする

https://www.karakaram.com/aws-session-manager-tunneling-support-for-ssh/

使っているAWSアカウントが一つなら問題ないのですが

## AWSのprofileが複数あるのですが。。。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-profiles.html

案件Aと案件BでAWSアカウントが違うってよくありますよね。
そういうときはAWSのPROFILEを分けてアカウントを管理します。

## で、こんな風にしたいじゃないですか

```
ssh -i ./ssh-key.pem ec2-user@i-0xxxxxxxxxxxxx --profile HOGEHOGE
```

が、今の所できないようです

https://www.shigemk2.com/entry/2020/03/13/202311

AWS_PROFILEをexportせよ、と。

https://stackoverflow.com/questions/63893323/how-can-i-use-ssh-with-aws-ssm-sessions-and-multi-profiles

```
$ export AWS_PROFILE=HOGEHOGE
$ ssh i-12345
```

あー、これ絶対期間が空いたら忘れるやつだ。
ということでこの記事で忘備録しておくことにしました。
オブジェクト指向とは

オブジェクト指向について整理したいと思ったのでアウトプットします。

# オブジェクト指向とは？
A.「ある役割を持ったモノ」ごとにクラス（プログラム全体の設計図）を分割し、モノとモノとの関係性を定義していくことでシステムを作り上げようとするシステム構成の考え方のこと。

# そもそもオブジェクトとは何なのか？
(わかりやすい記事があったので自分なりに解説)
A.ざっくりでいうと「モノ」
プログラミング視点で考えてみる。
例えばケータイでいうと、
**オブジェクト：ケータイ**
**クラス：スマートフォン**
**インスタンス：iPhoneやAndroid**
こんな感じで考えるとわかりやすいと思った。

# オブジェクト指向のメリット
①効率よくプログラムを設計・開発できる
例、サイト制作などで色違いのボタンを5つ作るとします。
オブジェクト指向を使用しない場合は5つ全てにプログラムを実装しなければならない。
しかしオブジェクト指向を使用すれば1つのボタンの「モノ」として作成し設定してしまえば、
色を変えたり、文字を変えたりするだけで済む。

②不具合の原因を特定しやすくなる
オブジェクト指向でないコードだとどこで何がどのようなエラーが起こっているのか、
探すのが困難である。
しかしオブジェクト指向のコードで記述していれば「モノ、データ」と「操作、処理」で分かれた形で記述されているのでどこでエラーが起こったのかわかりやすい。

③プログラムの仕様が変わっても簡単に対応できる
先ほどの①のボタンの例でいうとボタン部分を全て大きくしたい時に、オブジェクト指向でないと全てのボタンを修正しなければならない。税金なども改正されることが多いのでオブジェクト指向であれば１部分を変更することで全てに適用されるので急な仕様変更に対応できる。

# オブジェクト指向のデメリット
・データと処理をひとまとめにした「継承」という仕組みによってどこのコードが実行されているのかわかりにくい。
・設計の工程に時間がかかる。
・実際再利用するとなった場合、非常に難易度が高い。

# オブジェクト指向の代表的なプログラミング言語
・Ruby
・Python
・C++

# 感じたこと
改めて文字に起こすことでオブジェクト指向の理解を深めることができた。
ただ単にコードを記述するのではなくオブジェクト指向のメリットを理解した上でコーディングしていきたいと思った。
基本的なことだが非常に重要なことだと思うので復習を繰り返し行い、完璧にインプットしたい。
【Unity】Addressableを使用しているAndroid向けビルドにPlayAssetDeliveryを導入する。

# 概要

最近はWeb開発(Nuxt.js)メインで仕事をしています、中村と申します。

UnityでiOSとAndroid両対応のアプリを短期で作らないといけない機会があったのですが、
AddressableとPlayAssetDelivery(以下PAD)の連携についてあまり参考記事がなかったので書いていきます。

# 開発環境
macOS Monterey バージョン12.3
Unity 2020.3.27f1
Addressable 1.18.19

# UnityのAndroid向け出力の罠
GooglePlayConsoleには150mbのアップロード制限があり、
アプリ本体と画像などのアセットを分割してPADを使用する必要があります。

ここで僕は
「.aabの容量を150mb以下に抑えないといけないんか...せや！
RemoteLoadPathにCDNのURLをいれてAssetBundleロードしてくればいいやん！」

と思ったのですが、これが罠でした。

通常であればこの方法を取る場合、AddressableのLoadPath等設定をRemote用にしなくてはいけません。

ですが、
Googleが用意してくれたPADなるシステムは、
そこにアップしたAssetPack(AssetBundle等を詰めたダウンロード用のデータパック)を
デバイスに任意のタイミングでダウンロードしてくれます。

このAssetPack内のAssetBundleをAddressableで読むにはどうやら**LoadPathはLocalのままで良い**んですね。
([Unity公式のAddressableサンプル](https://github.com/Unity-Technologies/Addressables-Sample)のPADの説明で注意してくださいってありますね...)

また、Unityでビルドしたaabが150mb以上であっても、
展開して確認できる**アプリ本体が150mb以下であればアップロードできます。**

理解すれば簡単かもしれませんが、Unity初心者の僕はこのあたりで
ちんぷんかんぷんになり、時間を溶かしてしまいました。

# 解決策
AddressableのAssetBundleの通常ビルドをPAD用ビルドに変更することで解決します。

### PAD用のビルドスクリプトの追加
Addressableの**Build**->**New Build**ではデフォルトでは**Default Build Script**しかありません。
PAD用のビルドを追加するために以下の手順を踏みます。

①.[Unity公式のAddressableサンプル内Assets](https://github.com/Unity-Technologies/Addressables-Sample/tree/master/Advanced/Play%20Asset%20Delivery/Assets)にある**PlayAssetDelivery**フォルダを
ダウンロードをします。

②.①で取得したフォルダを丸ごとプロジェクトに放り込みます。

③.プロジェクトのAddressableAssetSettingsをインスペクタで固定して、
先ほど放り込んだPlayAssetDeliveryフォルダのDataフォルダ内にある
・`BuildScriptPlayAssetDelivery`を`Build and Play Mode Scripts`の＋を押して追加
・`Asset Pack Content`を`Asset Group Templates`の＋を押して追加
・`PlayAssetDeliveryInitializationSettings`を`Initialization Objects`の＋を押して追加

これをすると、Addressableの**Build**->**New Build**に**Play Asset Delivery**が追加されているはずです。

### Addressable Groupsの設定
ビルドを実行する前に、プロジェクトのAddressableAssetGroupにPAD用のスキーマを設定しておきましょう。

**Window** -> **Asset Management** -> **Addressables** -> **Groups**で表示される
グループ群のインスペクタにあるAdd Schemaボタンを押して、Play Asset Deliveryスキーマを追加します。

AssetPackのダウンロード形式の設定は `InstallTimeContent(InstallTime)` がデフォルトですが、
既存のAddressableの読み込み設計を変えたくない場合はいじらなくてもいいと思います。
(InstallTime以外は別途読み込みのロジックを書く必要あり)

ついでに、**Content Packing & Loading** -> **Advanced Options** -> **Asset Bundle Provider**を
`AssetBundle Provider`から`Play Asset Delivery Provider`に変更するのを忘れないでください。

### ビルドの実行
これらを設定できたら、Addressableから**Build**-> **New Build** -> **Play Asset Delivery**から
AssetPackをビルドしておきましょう。
ここからはいつものような感覚で使ってもらえばいいと思います。


### さいごに
aabをビルドして、150mbを超えていてもGooglePlayConsoleにアップできると思います。

これでPAD AssetPackとAddressableを併用する準備ができたので、
展開して、アプリ本体の容量確認して150mb以下になるように調整したり、`OnDemand`で必要な時にダウンロードしたりなんやかんや。

`InstallTime`以外のダウンロード形式だとそれ用のGoogle公式パッケージが必要なのですが、
その辺は今回のプロジェクトでは使わなかったので書いていません。

あとはPlay Consoleの内部テスト等で実機デバッグして色々試してみてください。
Go＋CodeCommitで任意の名称のライブラリを作成・利用する方法

# 目的
Goでモジュールを作成する際には`go mod init`で任意の名称を指定することができます。
しかし AWS CodeCommit を利用時にはCodeCommitのホスト名（`git-codecommit.${AWS_REGION}.amazonaws.com`）を使用する必要があります。
そこでCodeCommitを利用しつつ任意の名称でGoのライブラリを作成する方法を調査したのでそのやり方をまとめます。
# 経緯
こんな感じです。
- プロジェクトではCodeCommitを使わないといけない
- ~~モジュール名にCodeCommitのホスト名が含まれると、別リージョンにリストアした際にクライアント側からアクセスが出来なくなる~~
    - 所感にも記載しましたが、Gitのホスト名を置換する機能を使うと解決です
- モジュール名にCodeCommitのホスト名が含まれることに気持ち悪さを感じている
- Goでライブラリを作成しないといけなくなった！！！

絶対に達成しないといけないわけではなく完全に好みですね。
# やり方
今回実現するのに、Gitのホスト名を置換してくれる機能を利用します。
## ライブラリ側
特に気にせず好きなモジュール名にして構いませんが、ライブラリ名（mylibrary.git）だけはCodeCommitのリポジトリ名と一致させます。
```cmd
$ go mod init hoge.example.com/mylibrary.git
```
## クライアント側の事前準備
### Gitの設定
Gitの設定にホスト名を置換するための設定を追加します。
設定のスコープは好みで構いませんが、特に理由が無ければ`global`で良いかと思います。
```cmd
$ git config --global --add url."https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/mylibrary.git".insteadOf "https://hoge.example.com/mylibrary.git"
```
プロジェクトでホスト名を統一したほうが管理しやすいので、私は以下のようにしています。
```cmd
$ git config --global --add url."https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/".insteadOf "https://hoge.example.com/"
```
### Goの設定
Goの設定にホスト名を置換するための設定を追加しました。
```cmd
go env -w GOPRIVATE="git-codecommit.*.amazonaws.com,hoge.example.com,direct"
```
## クライアント側のソースコード
特に難しいことは無く、単純にimportすればOKです。
```go:main.go
import (
	"hoge.example.com/mylibrary.git"
)

func main() {
	mylibrary.Fuga()
}
```
# 所感
当初はモジュール名にリージョン情報が含まれていると、リポジトリのバックアップ/リストア時にクライアントから参照できなくなることを懸念していました。
ですが、Gitのホスト名を置換する機能を使うと問題なく解決できるとわかったので、最終的には好みの問題ですね。
開発メンバ全員に設定してもらうひと手間はありますが、名前が分かりやすくなるので個人的には任意の名称を設定する方が好みです。
# 参考
https://qiita.com/neruneruo/items/fdbb9bbe02861223c215

https://kakakakakku.hatenablog.com/entry/2020/03/27/093150
Apple IDのはまりどころ

以下はApple Supportに電話で確認しました。(2022/4/5)

### Apple IDの2ファクタ認証を解除する方法は？

ありません。

現在新規で作成したApple IDは2ファクタ認証が強制されます。

昔に作ったApple IDで、まだ2ファクタ認証をOFFのままにしているなどの場合のみ、2ファクタ認証が有効化されていない場合があるようです。

### 一度削除をしたApple IDをもう一度復活させたい

できません。

一度Apple IDに登録したメールアドレスでもう一度新しいApple IDを作成することもできないようです。

### Apple IDの削除申請をしたが、やはり取り消したい。

Apple Supportに電話すると可能です。ただ7日以上経つと完全に削除されるそうです。7日以内でも絶対大丈夫とは限らないので早めに電話してください。

https://support.apple.com/ja-jp/HT201232
MinMaxScalerの注意点

データ正規化とは、最小値０、最大値１にすること。下記コードのように行う。注意点は、訓練データとテストデータで違うコードを使用すること。

from sklearn.preprocessing import MinMaxScaler

sc=MinMaxScaler()

train_sc=sc.fit_transform(train)
test_sc=sc.transform(test)

訓練データにはfit_transformを使用する
テストデータにはtransformを使用する
現場でよく使うSQLまとめ ver2

# SQL実行環境
-  PostgreSQL 9.4
- A5:SQL

# NULL値控えるために使っていたCOALESCE()。実は
```SQL
-- 今まで使ってた感じ　
-- A = NULLかどうかわからない値
SELECT COALESCE(A,0); 
-- 結果：前の値がNULLだったら０をもらう, NULLではないのであればそのまま

--　実はこういう意味だった。
--　'A','B','C'は全部NULLではないとしたら
SELECT COALESCE('A','B','C');  --結果は'A'
SELECT COALESCE(NULL,'B','C');  --結果は'B'
SELECT COALESCE(NULL,'B',NULL); -- 結果は'B'
```
前からNULLか調べてNULLだったら、次の値を調べる。NULLではない物が出るまで続くらしい。
NULLかも知らない複数の値の中で、どある順番でNULLではないものが取りたい時使ってみる。

参考：https://qiita.com/ren0826jam/items/b442bb9120a4671f90b8

# IN / NOT IN

```SQL
select *
from m_kaihi -- 会費テーブル 
where nyukin_kubun = 12 OR nyukin_kubun = 4 -- 入金区分
where nyukin_kubun IN (12, 4)
```
上と下のWHERE句は同じ意味。下の方を使いたい。とってもシンプルです。
NOT INも覚えたいです。

参考：https://qiita.com/ren0826jam/items/b442bb9120a4671f90b8

# UNION
テーブルたちを結合する
```SQL
SELECT
   A
   , B
   , C
FROM table1
UNION
SELECT
   A
   , B
   , C
FROM table2
UNION
SELECT
   A
   , B
   , C
FROM table3
```
※注意点：UNION と UNION ALL の違い
UNION と UNION ALL の違いは、重複行の扱いです。
UNION は、重複行を除外します。UNION ALL は重複行も全部含みます。

参考：https://pontz-rw.hatenablog.jp/entry/2019/10/13/000000
# WITH句
```SQL
WITH T3 AS (
        SELECT
            id
            , bula
        FROM
            some_table        
)
, T4 AS (
        SELECT
            ST.id
            , bulabula
        FROM
            some_table ST
        LEFT JOIN T3 
            ON ST.id = T3.id
        WHERE
            ST.id = 1111 AND T3.bula = 0  -- WITH句中でT3を参照できる
)
SELECT
 *
FROM
    sometable T1
LEFT JOIN sometable T2 
    ON T2.id= T1.id
LEFT JOIN T3        -- JOINの後()中にSELECT文を書かなくて済む
    ON T3.id= T1.id
LEFT JOIN T4
    ON T4.id= T1.id
```
WITH句を教えられた後からは副問い合わせはほぼWITH句で書いています。
今までは JOIN の後( )中に書くのが当たり前だと思ったが、WITH句は読みやすいし書くのもシンプルです。副問い合わせのSELECT文の中にまたSELECT文を書こうとすると、わけわかんないですね。。
WITH句は中にSELECT文以外の物も書けるらしいがまだ次調べよう！

# SQLを書く順番
あんまり意識してないが、下のとおりやってみる！
SELECT → FROM → JOIN（まず必要なテーブルを全部くっつける感じ） → WHERE → GROUP BY → HAVING → ORDER BYの順でSQL文を書く

参考：https://qiita.com/ren0826jam/items/b442bb9120a4671f90b8

# SQLを高速化するコツ・テクニック
① SQLで暗黙の型変換は回避するよう考慮する
　where句のカラム型をチェック！
② キーワードは大文字
SQLのキーワードはすべて大文字で書く！
③ IndexがかかってるカラムをWHERE句で指定した方が検索が早いらしい!
④ 行数を数えるときは「COUNT(カラム)」を使う。
　カラムはインデックスが設定されているのを使う事で処理が速くなる！

参考：https://style.potepan.com/articles/26070.html#SQL
【Blue Prism】グローバルマウスクリックで「右クリック」を行うには？

# はじめに
Blue Prism (ブループリズム)で右クリックをしたい！と思ったことはありませんか？
リンクを新しいウィンドウで開きたいときなど、右クリックの操作が出来るとより幅広い操作が出来るようになります。
この記事ではグローバルマウスクリックとグローバルキー送信を用いた右クリックメニューの選択方法を解説します。

# グローバルマウスクリックを用いた右クリック
```フォーカス → グローバルマウスクリック(right)```

例として「新しいウィンドウで開く」を選択します。
![スクリーンショット 2022-04-05 144542.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524779/48c669d8-0890-4071-6a6e-d1546f8eb752.png)

1. まずはアプリケーションモデラーの<strong>「UIオートメーションモード」</strong> でボタンを識別します。

2. 次に操作ステージを作り、プロパティからクリックしたい箇所に対し<strong>「フォーカス」「グローバルマウスクリック（中央）」「グローバルキー送信」</strong>のアクションを追加します。
![rightclick.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524779/610f54ce-6cd8-e541-f620-9241b86b4521.png)
3. 「グローバルマウスクリック（中央）」の「マウスボタン」に<strong>"right"</strong>、「グローバルキー送信」の「テキスト」に<strong>"{DOWN}{DOWN}{ENTER}"</strong>を入力します。（２回下矢印キーを押しEnterを押す操作）
これでリンクを新しいウィンドウで開くことが出来ます。

# +α「Shift＋F10キー」を用いた右クリック
```フォーカス → グローバルキー送信(+{F10})```
```メニュー選択例：フォーカス → グローバルキー送信(+{F10}{DOWN}{DOWN}{ENTER})```

右クリックのWindowsのショートカットは<strong>「Shift＋F10キー」</strong>なので、右クリックの操作を行わずに「グローバルキー送信」で<strong>"+{F10}{DOWN}{DOWN}{ENTER}"</strong>を入力しても同様の操作を行うことが可能です。

グローバルキー送信でのキーの変換は以下の通りになります。
（ページ下部に参考公式リンクあり）
| key | SHIFT | CTRL | ALT |
|:-:|:-:|:-:|:-:|
| code  | +  |  ^ | %  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524779/984d3f20-5c87-7dd5-93ff-7fdce7f5272e.png)

# +α 右クリックメニュー内のショートカット
しばしば右クリックメニュー内に「Ctrl+R」「Ctrl+S」といったショートカットで選択出来るものがあります。このようなものはショートカットを入力することで実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524779/7bfadb02-26a1-ade3-e15a-22f1cfef1726.png)
### 右クリックメニュー内のショートカットを利用するには
1. <strong>「フォーカス」と「グローバルキー送信」</strong>のアクションを追加し、
2. テキストにショートカットを入力します。（Ctrl+Sは"^s"）
これだけで右クリックメニュー内のショートカットを利用することが出来ます。
:::note warn
メニューを開いてしまうとショートカットに反応しなくなってしまいます。
フォーカス状態でショートカットを入力してください。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524779/74422ad1-bdd6-9219-df3d-187917faab38.png)
# まとめ
いかがでしょうか？
右クリックはグローバルマウスクリックとショートカットを利用することで操作できます。
また、右クリック内メニューのショートカットを利用する際はフォーカスとグローバルキー送信を組み合わせることで利用できます。

[参考リンク：グローバルキー送信の記述方法](https://portal.blueprism.com/system/files/2018-02/Guide%20to%20Send%20Keys%20and%20Send%20Key%20Events.pdf)
【macOS 12.3.1 intelchip】python環境構築まとめ

# 備忘録です.
python環境がごちゃごちゃしてたので、色々消して以下にまとめた.(2022.4.5)
環境：MacBookPro macOS 12.3.1(intelchip)

# 要約
Homebrew + pyenvでpythonバージョン管理 + venvでプロジェクトごとにパッケージ管理

## 1.Homebrewインストール
ここからインストール

https://brew.sh/

## 2.pyenvインストール＋環境設定
pyenvのインストール
```zsh:zsh
$ brew install pyenv
```
PATHを通す.
この３行目がないと、Macにデフォルトで入ってるPythonが呼び出されうまくいかなかった.
これらの意味は後程調べて記載予定.
```:~/.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
```
~/.zshrcは”ホームディレクトリ下”にあるzshシェルのログインコマンドを記載している.
iterm2を再起動か、以下のコマンド実行
```zsh:zsh
source ~/.zshrc
```

## pythonのインストール
```zsh:zsh
pyenv install -l
```
まずはインストールできるバージョン確認.
```zsh:zsh
pyenv install 3.10.1
```
この時、バージョンによっては、以下のエラーが出てインストールできず、、謎.
```zsh:zsh
checking for --with-cxx-main=<compiler>... no
checking for clang++... no
configure:

  By default, distutils will build C++ extension modules with "clang++".
  If this is not intended, then set CXX on the configure command line.

checking for the platform triplet based on compiler characteristics... darwin
configure: error: internal configure error for the platform triplet, please file a bug report
:...skipping...
BUILD FAILED (OS X 12.3.1 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/s3/dnk78f2s5pzg502lv6dhblkw0000gn/T/python-build.20220405163529.14330
Results logged to /var/folders/s3/dnk78f2s5pzg502lv6dhblkw0000gn/T/python-build.20220405163529.14330.log
```
とりあえず、インストールできたら、グローバルに設定.そして確認.
```zsh:zsh
pyenv global 3.10.1
pyenv versions
  system
* 3.10.1 (set by /Users/takasukaoru/.pyenv/version)
  3.9.11
```
無事3.10.1が設定されていることを確認.
一応,pyenvのpythonがpath通ってることも確認.(システムデフォルトではなくなっているはず)
```zsh:zsh
python -V
Python 3.10.1
```
OK.

## 3.venvで仮想環境構築
以下はvscodeのzshターミナルで実行.
プロジェクトフォルダ下で、以下を実行.
```zsh:zsh
python -m venv .venv
```
.venvは仮想環境名なので、任意.
カレントディレクトリ名の前に(.venv)と表示されればOK.
```zsh:zsh
(.venv) 
[takasukaoru@＊＊＊＊＊:~/python_project/****][master]
$ 
```
表示されていない場合、以下のコマンドを実行して、venv仮想環境に入る.
```zsh:zsh
source .venv/bin/activate
```
ここで、pipインストールすることで、ローカル環境を汚さずにパッケージインストール可能.
仮想環境から抜け出るときは,deactivateのみでOK.
```zsh:zsh
deactivate
```
また入る時は、
```zsh:zsh
source .venv/bin/activate
```
自己復帰（再実行）可能なBotのサンプル


日頃RPAのロボットを利用していて、「また止まった」とか、「最初からやり直しか～！」ということはないでしょうか。
そもそも止まってほしくない。というのはあるのですが、RPAのロボットが扱う対象のシステムの動作が不安定だったりして、
毎回同じように動かない。みたいな事があると、いくら作りこんでも月に1回は止まってしまう。などあるかもしれません。

今回は、そういった場合に取れる対策の一つして、「エラーが発生した際にはロボットを再実行し、作業途中の箇所から処理を継続させる。」というようなサンプルBotを作ってみました。


# サンプルBotの概要

氏名と電話番号が入ったリストを読み込み、市外局番から都道府県を調べて出力用シートに記入する。

### 使用するファイル
* デモ用ダミーデータ.xlsx - 氏名や電話番号等の個人情報が記入されたExcelシート
* 市外局番一覧.xlsx - 市外局番とそれに対応する都道府県+αが入っているExcelシート
* Output.xlsx - 出力用シート。デモ用ダミーデータを丸々コピーしたファイル。

### ダウンロード用URL
Google　Driveにアップロードしておきました。
上記ファイルとサンプルBot（zip形式)が含まれます。
サンプルBotはAutomation 360 v.23 (Build 11513)で作られています。
https://drive.google.com/file/d/1_zdFlv-6jzuAIjs7REKlhBiL0e2e4OhF/view?usp=sharing

### Botの処理の流れ
1. デモ用ダミーデータ.xlsxをコピーし、出力用シートを作成する。
1. 市外局番一覧を開き、データテーブル変数に格納する
1. 出力用シートを開き、都道府県を記入する列の先頭行にラベル（タイトル）を記入する。
1. 出力用シートを再度開き、1行づつ読み込む（ループ処理）
    1. 都道府県の欄が未記入の場合のみ以下を実行
    1. 電話番号から市外局番を抜き出す
    1. 抜き出した市外局番を元に、データテーブルに格納しておいた「市外局番一覧」をサーチして都道府県を調べる。
    1. 都道府県を出力用シートに記入する。

# Botのスクリーンショット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490870/7846c0a3-2caa-bc4c-df32-146fdd830edd.png)

# Botの自己復帰（再実行）ができるための条件
今回作ったBotは、作業を行った結果を一行づつ記録していくような仕組みになっています。
そのため、出力用シートの該当行にすでにデータがあるかどうかをチェックし、すでに記入済みの場合は処理をスキップする。としておくと、
途中で実行が停止してしまった場合にも、再度実行するだけで途中から記入してくれるような動きをします。

実際のケースではさらに、Botが動くための環境をリセットするような処理もBotの処理の先頭にいれておく必要となることが多いかと思います。
また、今回のように処理結果がファイルに残らないような場合は、「ファイルに記録」アクションなどでログファイルを作り、どこまで作業したか記録するようにしておき、実行時にまずそちらを読み取り、どこまで作業が完了しているかロボットが判断できるようにしておきます。

# その他補足、注意事項


# テスト用データの作成に使用したサイト
市外局番一覧
[総務省｜電気通信番号制度｜市外局番の一覧](https://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/shigai_list.html)

ダミーの個人情報
[個人情報テストデータジェネレーター](https://testdata.userlocal.jp/)
ソフトウェアテスト技法ドリル要約

ソフトテストウェア技法ドリルがJSTQBより親しみやすく実務的だったので、内容をまとめておきます。

## 点に注意を向ける

数字一つをとってみても整数、小数、自然数、負の数、数字以外といったように、
「間」「対称」「類推」「外側」を考える癖をつけることで怪しい箇所を推測する。

### 意地悪条件
ソフトウェアの入力可能範囲を超えた異常な値など、
絶対入力しないような値を考える。

### 人間の習性
ソフトウェアのバグ発生メカニズムは、「人間の習性」によるものが大半である。
→言語学、認知心理学、哲学などの力を借りる必要がある。

### 過去の経験
多くのバグ票を読みながら「どうしてそのようなバグを作り込んでしまったのだろう」と考えることでトレーニングする。
ただ、経験があるがゆえに見逃す場合もあるので注意。


## 線を意識する

### 同値分割と境界値分析
入力可能性がある値をグループ分けして代表値だけをテストすることで「網羅」するテストができる。
境界値付近に関係するバグは非常に多いため、必ず線で視覚的に分かるように図示することが重要。

### 異常値は他の異常値を隠す
プログラムの処理順番の関係上、正常値は複数組み合わせを同時に検証できるが、
異常値は一つずつしか検証できない。

## 面で逃さない

ドメイン分析テスト
下記の概念をもとに図に起こすことが重要。
マトリクスを作成し、着目した変数以外はinにしておけば着目した変数を確実に評価できる。
on   着目している境界値
off  onポイントに隣接している境界値
in   ドメインの内側の値（on/off以外）
out  ドメインの外側の値（on/off以外）


デシジョンテーブル
if文やswitch文は全てデシジョンテーブルにできる。
デシジョンテーブルを圧縮する場合には処理順が重要になるため、注意が必要。

原因結果グラフ
論理関係を目に見える形で表現したもの。
CEGTestにて原因結果グラフをデシジョンテーブルに変換することができる。

## 立体で捉える

直行表
機能と機能の間に関連がないことを「直交している」と言う。


## 時間を網羅する

### 状態遷移テスト


## 多次元の品質

### シナリオテスト
線・面・立体・時空全てを組み合わせ、人の行動に基づいてシナリオを作成する。
狭く深くシナリオを書くことが重要。


参考書籍：「ソフトウェアテスト技法ドリル　テスト設計の考え方と実際」秋山 浩一 (著) 日科技連出版社
https://www.qbook.jp/book/20200619_937.html
Homebrewをインストールする。

## 目的
Mac用のパッケージ管理ツール。Windowsのようにホームページへ行ってダウンロードするのではなく、homebrewを使用することで、パッケージのダウンロード/インストールを一括で実施してくれる。
また、homebrewのコマンドでインストールしたツール、パッケージはコマンド一つで一括バージョンの更新を行える。
->cronを使用すれば、定期的にバージョンの更新が可能。

## brewのインストール
terminalで以下を入力する。

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

## 使用例
terminalで以下を入力する。

- homebrew自体のバージョンの更新とbrewのリモートリポジトリをfetchしてくる
```
brew update
```

- ツールのインストール(pyenv のインストール)
```
brew install pyenv
```

- ツールを一括でバージョンアップする
```
brew upgrade
```

- パッケージをインストールする(VS　codeをインストール)
```
brew install visual-studio-code --cask
```
Jenkins ジョブのビルドスクリプト内のシェルスクリプトのエラーが検出されない時の対処方法

## はじめに

Jenkins のビルドスクリプトでシェルスクリプトを実行する行があり、
そのシェルスクリプト内で実行しているコマンドがエラーとなっても、
Jenkins 自体にエラーが検出されない時の対処方法について紹介します。

お忙しい方のために結論だけ先に書いてしまいます:

下記の `set` コマンドを Jenkins のビルドスクリプトとシェルスクリプトの冒頭に追加すれば ok です。

```sh
set -eu
```

以下、この対処方法についての詳細を書いておきます。

## 対処方法 `set -eu` の追加について

### ビルドスクリプトの冒頭に追加

Jenkins の Job のコンソールログを読んで、
`/bin/bash /tmp/jenkins?????.sh` のオプションに　`-e` がなければ
Jenkins のビルドスクリプト (Job の execute shell の Commands) の成功/失敗は
最後のコマンドの終了ステータスによって決まってしまいます。

例えば、ビルドスクリプトが

```sh
#!/bin/bash
./hogehoge/src/run.sh
echor $?
echo $?
```

だった時 `-e` オプションがないとジョブの結果は "成功" となります。

ビルドスクリプトの途中に明らかにエラーとなるコマンドがあったとしても、
最後のコマンドは成功するので最終的な終了ステータスは 0 となり、
ジョブの結果は "成功" となってしまうようです。

これだと、ビルドスクリプトのエラーが正しく検出されないので、
`set -eu` コマンドをビルドスクリプトの冒頭に記載します。

```sh
#!/bin/bash
set -eu # 追加
./hogehoge/src/run.sh
echor $? # ここで失敗する
echo $?
```

そうすれば、ビルドスクリプトの途中でエラーとなった時 (終了ステータスが 0 以外の時)、
ジョブの結果が正しく "失敗" となります。

なので、とりあえずシェルスクリプトの冒頭には `set -eu` コマンドを書いておくと良いかと思います。
See https://qiita.com/youcune/items/fcfb4ad3d7c1edf9dc96

### ビルドスクリプト内のシェルスクリプトに追加

続いて、ビルドスクリプト内のシェルスクリプトの冒頭にも `set -eu` コマンドを追加してください。

これをしないと、ビルドスクリプト内のシェルスクリプトの終了ステータスが、
シェルスクリプトの最後のコマンドの終了ステータスで決定してしまいます。

要は、次のようなシェルスクリプトで

```sh:ビルドスクリプト内で実行するシェルスクリプト
git clone http://github.com/git/user/hogehoge.git
python hogehoge/src/run.py # 成功 or 失敗
echo $? # 成功
```

で python スクリプトがエラーになったとしても、その次の `echo $?` コマンドが成功するので、
最終的な終了ステータスが 0 となるので、ジョブの結果は "成功" となります。

これだと python スクリプトの結果を無視しているので、ジョブの成功/失敗を正しく検出できないです。

なので、`set -eu` コマンドをシェルスクリプトの冒頭に追加します。

```sh:ビルドスクリプト内で実行するシェルスクリプト
set -eu # 追加
git clone hogehoge
python hogehoge/src/run.py # 失敗するとシェルスクリプトも失敗する
echo $? # 実行されない
```

これで python スクリプトが失敗したときにジョブが失敗となります。
(もちろんジョブのビルドスクリプトの冒頭に `set -eu` を記載していることが前提ですが)

これで、ビルドスクリプト内のシェルスクリプトが途中で失敗した場合でも、
正しくジョブが失敗と検出されるようになります。

## まとめ

最後にまとめますと、とにかく、Jenkins でシェルスクリプト (コマンド実行) する時は、
`set -eu` コマンドを冒頭に記載してください。

そうすれば、スクリプトのどこか途中でエラーとなったとき、
Jenkins のジョブの結果が正しく "失敗" と表示されるようになります。

この `set -eu` コマンドをシェルスクリプトの冒頭に記載することは、
Jenkins 関連の話で閉じる内容ではないと思います。

シェルスクリプトを書くときに `#!/bin/bash` を書くのと同じように、
`set -eu` も合わせて書いておいた方が良いかと思います。

これにてこの記事はおしまいです。

お疲れ様でした。
CakePHP4のI18nでpoの代わりにymlを使う

## 環境

PHP 
CakePHP 4.3.6

## 目的

[国際化と地域化](https://book.cakephp.org/4/ja/core-libraries/internationalization-and-localization.html) が目的。
CakePHP4のデフォルトでは.poファイルを使うわけですが、個人的には見づらい。
というわけで.yml(.yaml)ファイルを使用したい。

## 準備

[国際化と地域化](https://book.cakephp.org/4/ja/core-libraries/internationalization-and-localization.html) にもあるように、```YamlFileParser```を作ればいい。

```php:\src\I18n\Parser\YamlFileParser.php
namespace App\I18n\Parser;

class YamlFileParser
{
    public function parse($file)
    {
        return yaml_parse_file($file);
    }
}
```

これ以上は特に何も書いていませんが･･･読み込む必要はありそうなので以下を追記。

```\config\bootstrap.php
if (I18n::getLocale() == 'ja_JP') {
	I18n::setTranslator('default', new Loader('default', 'ja_JP', 'yaml'), 'ja_JP');
} else {
	I18n::setTranslator('default', new Loader('default', 'en_US', 'yaml'), 'en_US');
}
```

ymlファイルは通常通り設定します。

```yml:\resources\locales\ja_JP\default.yaml
key1:
  key2:
    key3: value
```

これで```__('key1.key2.key3')```という風にすればとれる･･･と思っていたのですが･･･。
```yaml_parse_file```の戻り値は配列です。上記の例であれば以下のようになります。

```php
['key1' => ['key2' => ['key3' => 'value']]]
```

実際どこで何をやっているのか？ までは追えていないのですが、
```__('key1')```で値がとれてしまう。なぜなのか。

## 対策

ymlファイルの階層をなくして書き直す･･･のは馬鹿らしいし見づらいので組み替える。
配列をキーでつなげなおしてあげればいいかなと思ったので以下の処理を追加

```php:\src\I18n\Parser\YamlFileParser.php
namespace App\I18n\Parser;

class YamlFileParser
{
	public function parse($file)
	{
		return $this->convert(yaml_parse_file($file));
	}

	protected function convert($data)
	{
		$new_data = [];
		foreach ($data as $key1 => $val1) {
			if (!is_array($val1)) {
				$new_data[$key1] = $val1;
			} else {
				$val1 = $this->convert($val1);
				foreach ($val1 as $key2 => $val2) {
					$new_data[$key1.'.'.$key2] = $val2;
				}
			}
		}
		return $new_data;
	}
}
```

もっといい方法があるような気はする。
LambdaでBasic認証掛けようとしたらLambda@Edgeが無い時

東京リージョン（ap-northeast-1）だとアクションのプルダウンメニューにLambda@Edgeが表示されない
バージニア北部（us-east-1）で組み込むこと

![スクリーンショット 2022-04-05 17.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23195/20d085d6-8004-dc76-3fff-a5ce404f46e0.png)
Lambda Node ランタイム v12 → v14 update 備忘録

# はじめに
Lambda Node ランタイム v12が2022/04でサポートが終わるため、v14に更新しないといけないProjectが存在していました。
その際の手順として備忘録を残したいと思います。
ただ、本記事ではv14へ上げるというよりは、ランタイムのバージョンを上げる際にどういうことをやったのかを記載したいと思います。

# 環境
- ローカル環境端末
  - macOS Big Sur
  - AWS SAM CLI　
  - Docker
- Lambda　ソース環境
  - AWS SAM で構築を実施
  - ApiGateway & Lambda(TypeScript)を構築
  - TypeScriptのためwebpackで実行ソースを作成(トランスコンパイル)している
  - 利用しているnodeModules群はすべて最新のVersionに更新済み

# 手順
私の環境での対応としては以下の流れで実施しました。
1. AWS SAM Template.yamlでNodeRuntimeのVersionを更新
2. AWSアカウントにデプロイを実施
3. AWSアカウントにデプロイした環境がLambdaFunctionを呼び出せるか確認
4. Node.js v14の変更点を公式ドキュメントで確認
5. 必要があればソースの修正を実施
6. 単体テストを実施して正常に動作しているか確認

## 1.　AWS SAM Template.yamlでNodeRuntimeのVersionを更新
私のTemplate.yamlではグローバル設定でVersionを設定しているため、その部分を修正することで
Template.yamlで管理しているLambda関数すべてのVersionを更新することが可能。
以下が修正した内容です。
```diff:Template.yaml
Globals:
  Function:
    Timeout: 30
-    Runtime: nodejs12.x
+    Runtime: nodejs14.x
  Api:
    OpenApiVersion: '3.0.2'
```
## 2.　AWSアカウントにデプロイを実施
デプロイはAWS SAM  CLIを利用している。
ちなみにAWS CLIのProfileにデプロイするAWSアカウントは設定済みです。
以下のコマンド実行でデプロイ実施。
```
$ sam deploy sam deploy --profile <自身が設定しているプロファイル名> --template-file <Template.yamlのパス>
```
デプロイ後、各Lambda FunctionをAWSコンソール画面で確認して以下のように指定したVersionに変更できていれば完了。
![Lambda　Rantime コンソール確認](https://storage.googleapis.com/zenn-user-upload/051b6ca6c442-20220405.png)

## 3. AWSアカウントにデプロイした環境のLambdaFunctionを呼び出せるか確認
確認方法はなんでもいいと思います。
方法としては以下
・AWSのLambdaコンソール画面にあるテストで確認
・APIを呼び出して想定通りにレスポンスが帰ってくるか確認
　　※APIを呼び出せるツールなど確認
・実際にStaging環境のサービスを動かして確認
などなど

## 4. Node.js v14の変更点を公式ドキュメントで確認
以下Git Hubの該当Versionの更新内容を確認
https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md#14.0.0
※今回はv12→v14ということで、v13の内容も確認しました。

## 5. 必要があればコードの修正を実施
4の手順で確認した変更点の内容で、私のProjectのLambdaFunctionには該当する内容はありませんでした。
そのため、修正作業はありませんでした。
もし、ここで修正内容箇所があれば修正します。

## 6. 単体テストを実施して正常に動作しているか確認
Staging環境のAWSに本Projectをデプロイして単体テストを実施しました。
私のLambdaFunctionはJest等でユニットテスト対応していなかった為、API確認ツール等で単体テストを実施しました。
ここで、正常に動かない部分があれば都度修正するフローになります。
私のProjectでは問題なく動作していることを確認できたので、修正作業はありませんでした。
問題ないことを確認できれば本番環境へデプロイを実施します。

# 最後に
AWS SAM Template.yamlで構築を実装していた為、Versionを上げる作業自体は簡単でした。
もし、手作業でAWSコンソール上で管理している場合、Lambda Functionが多いと一つ一つ設定を変更しないといけないので、、、Infrastructure as Codeに感謝です。
また、今回は手作業で確認するところ(単体テスト)があった為、確認作業で時間が取られました。
Jest等でユニットテストを実装していれば短縮できたのかなと思います。
ただ、Jest等を実装している場合では開発環境(ローカル端末)のNode.jsバージョンによってJest等の確認も必要になると思います。
とは言いつつJest等でのユニットテストは作業効率化の面でも重要なので今後実装する予定です。

もっと良い方法や他に確認するところが有るよ等あればコメントしていただけると幸いです。
DesignOpsとは？なぜ重要なのかを考察してみる

ワークフロントの「2019 State of Work Survey」によると、アメリカの労働者は1日のうち60％を自分の中核的な責任ではない仕事に費やしていることが報告されました（会議、メール、管理業務など）。企業が成長するにつれ、デザイナーは同じ課題に直面します。つまり、デザインに関係のない他の作業をしなければならないのです。そこで、デザイナーが本来の仕事であるデザインに集中できるように、副次的なタスクを処理するのがDesignOpsです。この記事では、DesignOpsマネージャーが何をするのか、なぜDesignOpsが重要なのかを説明します。

『DesignOpsとはなんですか? 』
DesignOpsとは、デザインの価値と影響を大規模に拡大するために、プロセス、チーム、技術を最適化することです。通常、デザインプロセスの設計、計画、管理を役割とするチームが、デザインチーム内のオペレーション、ビジネスプロセス、リソース配分、調達を担当します。DesignOpsの最終目標は、デザインチームの効率を高め、デザインアウトプットの品質を向上させることです。

『なぜDesignOpsが重要なのか?』
DesignOpsの重要性を理解するためには、まずデザインチームが直面している課題に目を向けることが重要です：
・膨大な仕事量
・スピードが求められる
・デザインツールの不足
・ループから外される　など

『DesignOpsの役割とは？』
DesignOpsマネジメントの主な役割は、デザインチームの時間を守り、障害や妨害がなく仕事に集中できるようにすることです。ここでは、この役割が日々どのように行われているかをご紹介します：

・オペレーションマネージメント
この役割は、デザインチームの長期的な目標は何か、そしてそれをどのように達成するか、明確なデザインロードマップを作成することです。また、デザインチームの人数を評価し、スキルギャップを特定するのもこの役割です。

・デザインプロセス
デザインチームが必要とするツールをマッピングし、デザインシステムを構築することで、プロセスを計画・管理します。また、デザインチームが組織内の他のチームとどのように協力すべきか、そのフレームワークを作成します。

・プロジェクト管理
デザインワークフローを担当し、プロジェクトの割り当てとスケジュールの設定を行います。DesignOpsチームは、デザインプロジェクトの進捗状況を確認するために、毎日スタンドアップミーティングを行います。また、デザインスプリントの企画・運営も行います。

・コミュニケーション戦略の策定
DesignOpsマネージャーは、デザインチームと組織内の他のメンバーとの連絡役を務めます。デザインの重要性を説き、チームミーティングの議題を設定します。また、デザインチームが必要とするすべてのファイルやリソースを保管し、簡単に取り出せるようなシステムを構築します。

・新入社員のオンボーディング
新しいスタッフのオリエンテーション、トレーニングを行い、デザインチームに適合するようにします。新しいデザインスタッフを採用することも彼らの任務のひとつです。

・デザインチームの文化の構築
DesignOpsチームは、デザインチームの専門性を高めるためのワークショップやトレーニングを企画します。また、チーム内のデザイナーを専門的かつ精神的にサポートし、デザインチームのコミュニティ意識を醸成するためのチームビルディング活動を行っています。

・予算配分と管理
Opsデザインは、デザインチームの運営にどれだけのコストがかかるかを設定し、そのコストを正当化します。予算が承認されると、デザインチーム内でどのように配分されるかを担当します。

・法務
法務チームと協力して、ユーザーテスト時に使用するNDAや参加者リリースフォームを作成します。

・調達プロセスの管理
調達部門と連携し、デザインチームが購入を決定する方法を合理化します。

・ITとセキュリティ
デザインチームの技術ロードマップを作成し、IT部門と協力してデザインツールの互換性とセキュリティを確保する。

・『ソリューションは？』
ワイヤフレーム、モックアップ、プロトタイプなどを包摂するオールインワン・デザインツールを活用し、合理的で生産的なチーム、ワークフローを作っていきましょう。
【備忘録】PHP継承について

## 継承とは
あるクラスで定義したプロパティやメソッドを、他のクラスに引き継ぐこと。

継承されるクラスを「親クラス（スーパークラス）」、継承するクラスを「子クラス（サブクラス）」と言う。

## 継承の方法
```
class 子クラス名 extends 親クラス { }
```

## サンプルコード
```
<?php

class Human {
  protected $name;

  // 初期化処理
  public function __construct($name) {
    $this->name = $name;
  }

  //名前を返す
  public function getName() {
    return $this->name;
  }

  // 名前を表示する
  public function introduce() {
    echo $this->getName();
  }
}

  // オブジェクトを生成・初期化
  $human = new Human("tanaka");
  

  // メソッドの実行
  $human->introduce();


  // 継承されたBuchoクラス
  class Bucho extends Human {
  }

  $bucho = new Bucho("sato");
  echo "<br>";
  $bucho->introduce();

```

## 実行結果
```
tanaka
sato
```
rclone の使い方

rclone を Google Drive で使ってみました。

Ubuntu 21.10 へのインストール方法

```bash
sudo apt install rclone
```

環境の設定

```bash
rclone config
```

設定が完了すると次のファイルが出来ます。

```text:$HOME/.config/rclone/rclone.conf
[remote]
type = drive
scope = drive.readonly
token = {"access_token":"ya29.A0ARrdaM_***********","token_type":"Bearer","refresh_token":"1//0eFN-5ZRtAZ9vCgYIARAAGA4SNwF-************","expiry":"2022-04-05T17:14:53.301800089+09:00"}
```

## 使い方 ##

ファイルの表示

```bash
rclone ls remote:/
```

フォルダーの表示

```bash
rclone lsd remote:/
```
本日のRuby基礎練習問題(22/4/5)

# 問題
以下の要件を満たすbubble_sortメソッドを実装しましょう。
要素が数値である配列を受け取り、数値の小さい順に並べ替えること
小さい順に並べ替えた結果を出力すること
**↓雛形**
```ruby.rb
def bubble_sort(data)
  # 配列の数を数える処理を記述
  length = 

  # for文を2つ使用する
  # 先頭から隣の数同士の大きさを比べる
  # 先頭側の要素の方が大きい場合は、配列の位置を隣同士で交換する
end

# 呼び出し例
number = [1,23,4,6,12,45,79]
bubble_sort(number)
puts number
```
出力例
1
4
6
12
23
45
79

**ヒント**
・for文を使う
・for文の入れ子を使う
・「隣同士の大きさを比較し、もし先頭側の文字の方が大きい場合は位置を交換する」という処理をする
・配列内の要素の入れ替えを行う
方法：array[a], array[b] = array[b], array[a]

# 私の回答
```ruby.rb
def bubble_sort(data)
  length = data.length 
  for a in 0..6
   for b in 1..

  # 時間制限のため回答できず！！！
end

# 呼び出し例
number = [1,23,4,6,12,45,79]
bubble_sort(number)
puts number
```
# 模範回答
```ruby.rb
def bubble_sort(data)
  length = data.length 
  for i in 0..(length-1) 
    for j in 1.. (length-i-1) 
      if data[j-1] > data[j] 
        data[j-1],data[j] = data[j],data[j-1] 
      end
    end
  end
end

number =  [1,23,4,6,12,45,79]

bubble_sort(number)

puts number
```
# 模範解説
まずは、コード全体の流れを簡単に説明します。
1〜10行目でbubble_sortメソッドを定義しています。ここでは仮引数をdataとしています。
12行目で要素の数が7個の配列numberを定義しています。
14行目でnumberを本引数として、bubble_sortメソッド呼び出しています。
16行目では、bubble_sortメソッドを実行した結果、要素の順番が変わった配列numberの値を出力しています。

次に、1〜10行目で定義したbubble_sortメソッドの中身を詳しく解説します。
2行目で、配列dataの要素の数をカウントし、その結果を変数lengthに代入しています。今回は7です。

3行目の親のfor文では、配列dataの要素の数だけ処理が繰り返されるように設定しています。
変数iには、配列の要素の位置番号が順に代入されます。配列の要素は先頭を0番目とカウントするので「length(配列の要素の数)-1」となっていることに注意です。

4行目の子のfor文では、親のfor文の処理回数に関連して、処理が繰り返されるように設定しています。

親のfor文が1回目の時は、変数jに1から6までの数字が順に代入されていきます。(length-i-1)が、7(配列の数)-0(変数i)-1 = 6となるからです。
親のfor文が2回目の時は、変数jに1から5までの数字が順に代入されていきます。(length-i-1)が、7(配列の数)-1(変数i)-1 = 5となるからです。

繰り返し処理の内容について説明します。
5行目では、配列の先頭から順に隣同士の数の大きさを比較しています。if文は「隣同士の数を比べて、前の数の方が大きければ」という条件になっています。
6行目では、if文の条件に当てはまった場合のみ、配列の位置を交換しています。

これらの処理を配列内のすべての数を比較し終えるまで繰り返すと、配列内の数を小さい順に並べ替えることができます。
# 感じたこと
for文の理解が浅すぎて知識不足が目立った。
でもRubyではeach文があるので、そこまで重要性は高くなさそう。
他言語では使用すると思うので復習はしていく。

またfor文の変数名がiやjに指定されていることに疑問を持ったため調べたら。
インデックス(Index)の「i」でした。
世界最初の高級言語であるFORTRANに由来しており、数学チックな考えからi,j,kなどがよく使われるとのこと。
特に決まりはないと思うが、理由がない限りループカウンタではi,j,kあたりを使用していきたい。

アドバイスやご指摘等ございまいたらぜひお願いします！！

以上
Azure DevOpsのAzure PipelinesでDockerのイメージPullにmirror.gcr.ioを使う方法

# 概要

既報の通り[Docker HubはイメージのPullのrate limit](https://docs.docker.com/docker-hub/download-rate-limit/)を開始しており、Azure PipelinesでDockerイメージをビルドする際にもこの影響を受けるようになる。
※ AzureのIPアドレスからのDocker Hubへのアクセスは2022年6月30日まではrate limitが適用されていないようであるためこの課題に気づきづらいが、その日時を過ぎるとrate limitされるようになる。

GCPはDocker Hubのよくアクセスされるイメージをmirror.gcr.ioでミラーしており、そこからイメージをPullすることでrate limitを回避できるようになるので、Azure Pipelinesでその設定をする方法を紹介する。


# Azure Pipelinesでmirror.gcr.ioを使うようにする設定方法

設定方法は[GCPサイトのPulling cached Docker Hub images](https://cloud.google.com/container-registry/docs/using-dockerhub-mirroring?hl=ja)に書かれているとおりで、Dockerデーモンの設定ファイル`/etc/docker/daemon.json`に対して`"registry-mirrors": ["https://mirror.gcr.io"]`を追加し、Dockerデーモンを再起動すればよい。

Azure Pipelines エージェント(ビルドを実行するエージェント)がUbuntuの場合、Azure PipelinesでDockerタスクを実行するより前のステップで以下のコードを入れれば良い。

```yaml
steps:
  - script: |
      cat /etc/docker/daemon.json | jq --arg mirror "https://mirror.gcr.io" '. + {"registry-mirrors": [$mirror]}' | sudo tee /etc/docker/daemon.json
      sudo systemctl restart docker
    displayName: update Docker settings to use mirror.gcr.io

```
.to_datetimeを使用して、 値をdatetime型の秒単位に変形させる方法

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1863223/15b00ab4-0562-c3b0-22ab-e050d3ae96d3.png)

[code]
train_df['step']=pd.to_datetime(train_df['step'],format='%S').dt.time

train_df.set_index('step',inplace=True)


train_df
Amazon ECS Execで"The execute command failed due to an internal error. Try again later."と言われた時の対応

ECS Execを実行する時に以下のエラーが発生するときがある

```
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


An error occurred (TargetNotConnectedException) when calling the ExecuteCommand operation: The execute command failed due to an internal error. Try again later.
```

## まずやるべきこと : Amazon ECS Exec Checkerを使おう

以下からgit cloneしてきましょう
https://github.com/aws-containers/amazon-ecs-exec-checker

使い方などは割と簡単なので割愛します

## Amazon ECS Exec Checkerで出てくる3パターン

### 1.ECSのタスクロールにSSM関連の権限が不足している

以下を参考にして、タスクロールを修正してみてください。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html

### 2.「読み取り専用ルートファイルシステム(Read-Only Root Filesystem)」にチェックが入っている

「タスク定義の新しいリビジョンの作成」→　「コンテナの定義」より、以下の画像のチェックを外してください。

![Screenshot from 2022-04-05 15-29-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293892/1ecf88d4-8f07-4532-a570-8263a1b040d7.png)

### 3.コンテナの定義の環境変数の中にAWS_ACCESS_KEY(AWS_ACCESS_KEY_ID) / AWS_SECRET_ACCESS_KEYが入っている


自分もココでハマりました。どうしても活用しないといけない場合は別の環境変数名に変更して見て下さい。


### 4.VPCエンドポイントの設定

該当のFargateがprivateサブネット上にある場合、ssmmessageへのVPCエンドポイントが設定されていること。ただ、Fargateからインターネットに繋がるような環境であれば、別段設定は不要です。
VPCエンドポイントは、基本的には同じVPC、同じサブネット上に作成していなければなりません。

### 5.ネットワーク(セキュリティグループ)の設定

ECS Fargateが立ち上がっているセキュリティグループと、VPCエンドポイントで設定したセキュリティグループのポートの443番が空いている必要があったはずです。
ハマりポイントとしては、VPCエンドポイントとECS側のセキュリティグループを同じにした場合。
同一セキュリティグループとはいえど、自分自身からのアクセスのインバウンドルールも追加する必要があります。
Yamaha RTX830で、OCN法人向けIPoE接続のVPNリモート接続設定をする(OCNバーチャルコネクトサービス)

## PPPoEからIPoEへ移行しよう

2018年から、PPPoEのボトルネックを解消する方式として登場したIPoE。
最早、PPPoEを使う理由はなく、さっさと、IPoEへ切り替えた方が良いです。
ネットワーク技術者を中心として、PPPoEからIPoEへの回線切り替えを進めてる人が多いですね。

PPPoEとIPoEは何が違うのか、下記に記載した総務省の資料に出てる図が分かりやすいです。

![2022-04-05_22h14_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61234/8a7205bb-f3c2-89e9-80b0-b0d02347218c.png)

NTE(Network Termination Equipment:ネットワーク終端装置・網終端装置とも呼ばれる)をISP毎に設置しなければならず、それが局舎のスペースの都合とかいろいろあって、簡単には増設できないことで、長い間、ISP業者とNTT東日本・西日本の間で揉めてました。

IPoEは、NTEが無くなり、ISP事業者は、VNE(Virtual Network Enabler)が提供するIPv6インターネットを提供するためのネットワーク設備等をローミングサービスとして利用して、ユーザにインターネット接続を提供します。

IPoEの背景などは、総務省のこちらの資料を見ると分かりやすいです。

[NGNのISP接続（PPPoEとIPoE）に関する当面の方向性](https://www.soumu.go.jp/main_content/000532520.pdf)

NTTコミュニケーションズの法人向けIPoEで固定IPが1つ貰えるOCN 光「フレッツ」IPoE（IPv6） 

https://www.kotei-ip.com/ipoe/

で、VPN接続する設定について、ヤマハさんのサポートを頂いたので共有です。
RTX830のUIでは、OCNバーチャルコネクトサービスと表示されていて、なんじゃこりゃ？ってなって、NTTコミュニケーションズさんの営業さんも、「え？」みたいになって、調べてもらったら、OCNバーチャルコネクトサービスは、ISP向けの名称だそう。

https://www.ntt.com/business/services/network/internet-connect/ocn-business/option/v-access-ipoe.html

現在、RTX830が品薄で、NTTコミュニケーションズさんはレンタルは中止しています。
だから、RTX830を使いたい場合は、購入となります。

個人向けサービスも、もちろんありますから、ご自宅の回線もさっさとIPoEに乗り換えた方がいいです。

https://www.ntt.com/personal/services/internet/hikari/ipv4overipv6.html

## 設定

既に、

- 最新版Firmwareへのアップグレード
- IPoEの設定
- VPNリモート接続の接続方式やアカウント設定

は済んでいる前提です。


### 「詳細設定」→「NAT」→「NATディスクリプターの一覧」の20000のところの「設定」のボタンを押す。
![2022-04-05_15h08_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61234/048563cb-7d36-46ca-f552-879d670afea4.png)

### 「静的IPマスカレードの設定」に、以下のように入力する。

192.168.100.xはRTX830のデフォルトのネットワークアドレスで、192.168.100.1はRTX830のデフォルトのホストアドレス。
適宜、ご自身で設定されたアドレスに置き換えてください。
(うちの場合は、今回は、192.168.11.x)

- 識別番号：1　内側アドレス：192.168.100.1　プロトコル：udp　ポート番号：500,4500
- 識別番号：2　内側アドレス：192.168.100.1　プロトコル：esp　ポート番号：空欄

![2022-04-05_15h10_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61234/2d9cd618-4b97-8830-ef81-e609a1de57f9.png)

### VPN接続でWebGUIにもアクセスできるように「管理」→「各種サーバの設定」で、「GUIへのアクセス許可」を「すべて許可する」にする

![2022-04-05_15h13_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61234/9e7fbd81-3ba2-269e-2b84-c172def4dd94.png)

## 参考: PPPoEからIPoEに変更した際のレイテンシの散布図

IPoEに移行することで、PPPの軛から解放されて、レイテンシが安定・高速、スループットも大幅上昇の世界へ。

![2022-03-27_12h18_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61234/9976072e-0970-c453-5858-c72acf29f7cb.png)
Solidity + Geth コマンドでコントラクトをデプロイ

#目次
[1.はじめに](#1-はじめに)
[2.前提条件（環境面）](#2-前提条件（環境面）)
[3.ソースのビルド](#3-ソースのビルド)
[4.Gethネットワークにデプロイ](#4-Gethネットワークにデプロイ)

# 1. はじめに
文字列を格納するコントラクトを作りたいと思ったが、Gasが多くかかるため注意が必要。と言われつつも、やってみたい。
Remixを使ってコントラクトを実行すると、Gasがinifinityと言われ、実行できない。Gethコマンドベースで実行すると動くっぽい。
参考にした書籍にも、RemixはGasの取り回しがいまいちなので、文字列を格納するサンプルはコマンドで実行していた。（数年前の書籍なのでバージョンは古いはずだが）

* 参考書籍
https://www.amazon.co.jp/gp/product/B07416W2PY/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1

コマンドで実行するにあたり、わざわざKindleを起動するのが面倒なので、備忘録として残しておく。

# 2. 前提条件（環境面）
* Windows 10
* Geth 1.10.17-stable
* Solc 0.8.13

# 3. ソースのビルド

__①ソースを任意の場所に格納__

__②solcコマンドでソースをコンパイル__
なぜか出力先(-o)にソースを同じフォルダを指定するとうまくいかなかった。これでバイナルファイル(.bin)が作成される。
```
> solc-windows -o .\bin --bin --optimize [.solファイル名]
```
__③コントラクトのABIを取得する__
ABIが表示されるだけなので、ファイルに書き込む。
```
> solc-windows --abi [.solファイル名] > [.abiファイル名]
```
# 4. Gethネットワークにデプロイ
__④gethコマンドによりネットワークに接続する。__
※ネットワーク内のアカウントはロック解除されている前提

__⑤コントラクトを登録__
ABIの内容は[]で囲う。
```
> mycontractContract = web3.eth.contract([ABIの内容]);
```
__⑥コンストラクタ?を実行して登録__
dataにはバイナリコードの内容に「0x」を付けて記載する。
```
> mycontract = myContract.new({from: eth.accounts[0], data:'0x.....', gas:3000000})
```
__⑦マイニングを開始__
```
> miner.start(1)
```
__⑧コントラクトがブロックチェーンに登録されることを確認__
```
> mycontract
{
 abi: [{
   ....
 }],
 address: "0x..." ←　コントラクトアドレス
   ....
}
```
__⑨コントラクトにアクセスするための変数を定義__
```
> contractObj = eth.contract(contract.abi).at(contract.address)
```
__⑩コントラクトのメソッド（データ登録）を実行__
```
> contractObj.[メソッド名].SendTransaction([引数1],[引数2],...,{from:eth.accounts[0]})
"0x..." ←　トランザクションアドレス
```
__⑪トランザクションがマイニングされたかを確認__
```
> eth.getTransaction([トランザクションアドレス])
```
__⑫値の参照メソッドを実行__
```
> contractObj.[メソッド名].call([引数1], {from:eth.accounts[0]})
```
__⑬再度デプロイしたコントラクトにアクセスする場合__
```
> contractObj = eth.contract([ABIの内容]).at([コントラクトアドレス])
```
numpyのインストール

Raspberry Pi 3B+にPythonのnumpyのインストールで戸惑ったのでメモに残します。

```
$ pip3 install numpy --upgrade
```

を実行したら、

```Running setup.py bdist_wheel for numpy ...```

が終わらなくなった。
見た感じはフリーズしたような状態に・・・。
しかし、このまま10分程度待ったら正常に終了しました。
短気な自分はフリーズしたのかと思い、何度もやり直してしまった。
皆様も気をつけて。
スマートコントラクトセキュリティ講座〜オーバーフロー&アンダーフロー編〜

スマートコントラクトの開発は言わずもがな、バグが命取りです。億単位のハッキング事例がたくさんありますよね。
本講座では、絶対に学ぶべき脆弱性をご紹介します。

今回取り上げるのはオーバーフローとアンダーフローについて。これはプログラム書く人なら大体みんな知っている話だと思いますが。
事例としてはhttps://medium.com/@ebanisadr/how-800k-evaporated-from-the-powh-coin-ponzi-scheme-overnight-1b025c33b530 が挙げられます。（ある種のジョークで？）金融詐欺をしようとしたみたいだけど、作者がオーバーフロー、アンダーフローをみたことがなくて866ETHやっちまったらしいです。怖いですね。

## オーバーフロー&アンダーフロー
例えばuint8は0以上255以下の数値を扱える型です。uint8 x = 0の時、xから1を引くとどうなるのでしょうか。-1になるのではなく、255になります。これが、アンダーフローです。
オーバーフローは逆に255に1をたして0になってしまうものです。

コード例: https://solidity-by-example.org/hacks/overflow/
increaseLockTime関数を利用してLockTimeをオーバーフローさせてロックを無力化。結局いつでも引き出せてしまう、ということだと思います。

## 対策方法
* オーバーフロー&アンダーフローを意識して、if文等を入れることで事前に防ぐ（当たり前）
* safeMathを使う。これはSolidityの計算演算にオーバーフローのチェックを入れてくれる。
* Solidityの0.8以上のバージョンを使う。ありがたいことに0.8以降デフォルトでオーバーフロー、アンダーフローが発生したらリバートさせてくれるようになったらしい。
【AWS】EBS縮退作業メモ

# 状況
EC2: amazonlinux2
縮退前EBS: gp2 100GB
縮退後EBS: gp3 30GB

# 作業時間目安
EBSスナップショット作成: 30秒~60秒/GB
EBS同期(rsync): 2~3分/GB

# 手順
##### 1. スナップショット作成
「アクション->イメージとテンプレート->イメージを作成」から縮退対象のインスタンスのAMIとEBSスナップショットを取得
取得後に復元しボリュームとして利用可能な状態に
※この時「再起動をしない」チェックはONにしない。再起動を行わないとスナップショット内のデータが壊れる可能性あり(AWS非推奨
![Untitled Diagram-Page-2 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298813/2e05d039-2a71-c41f-88eb-bd137f861f20.jpeg)

##### 2. 新規インスタンスと同時に縮退後のEBSを作成
縮退対象EC2と同じAMI・AZでEC2インスタンスを作成(「コミュニティAMI」でAMIIDで検索して一致するものを指定)し、ストレージを縮退後のサイズに指定
作成が完了後、インスタンスを停止し、EBSをデタッチしてからインスタンスを削除
これで縮退後のEBSが完成

![Untitled Diagram-Page-2 (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298813/e9f38dc5-fce3-0140-c1bb-76f09fc5095a.jpeg)

##### 3. 縮退対象インスタンスに同期用のEBSと、縮退後のEBSをアタッチする
縮退対象インスタンスに計3つのボリュームがアタッチされている状態に

![Untitled Diagram-Page-1 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298813/d5446101-ed34-3921-9830-b0774b238ce8.jpeg)

##### 4. 同期用EBSと縮退後EBSを同期
MOUNTPOINTに「/」と表示されているものがルートボリュームなので、それ以外をマウントし同期作業を行う

```
[ec2-user@ip-10-0-0-162 ~]$ lsblk
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   100G  0 disk
├─nvme0n1p1   259:1    0   100G  0 part /
└─nvme0n1p128 259:2    0   1M    0 part
nvme1n1       259:3    0   100G  0 disk
├─nvme1n1p1   259:4    0   100G  0 part
└─nvme1n1p128 259:5    0   1M    0 part
nvme2n1       259:6    0   30G   0 disk
├─nvme2n1p1   259:7    0   30G   0 part
└─nvme2n1p128 259:8    0   1M    0 part

[ec2-user@ip-10-0-0-162 ~]$ sudo mkdir /mnt/new /mnt/old
[ec2-user@ip-10-0-0-162 ~]$ sudo mount -o nouuid /dev/nvme2n1p1 /mnt/new
[ec2-user@ip-10-0-0-162 ~]$ sudo mount -o nouuid /dev/nvme1n1p1 /mnt/old

[ec2-user@ip-10-0-0-162 ~]$ lsblk
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
nvme0n1       259:0    0   100G  0 disk
├─nvme0n1p1   259:1    0   100G  0 part /
└─nvme0n1p128 259:2    0   1M    0 part
nvme1n1       259:3    0   100G  0 disk
├─nvme1n1p1   259:4    0   100G  0 part /mnt/old
└─nvme1n1p128 259:5    0   1M    0 part
nvme2n1       259:6    0   30G   0 disk
├─nvme2n1p1   259:7    0   30G   0 part /mnt/new
└─nvme2n1p128 259:8    0   1M    0 part

[ec2-user@ip-10-0-0-162 ~]$ sudo rsync -ax --delete /mnt/old/ /mnt/new/

[ec2-user@ip-10-0-0-162 ~]$ sudo umount /mnt/new
[ec2-user@ip-10-0-0-162 ~]$ sudo umount /mnt/old
```

##### 5. 不要になったEBSをデタッチしてルートボリュームを再設定
縮退対象EC2を停止したのち、全てのEBSを一度デタッチし、縮退後EBSをルートボリュームとしてアタッチする
このとき、デバイス名は縮退対象EC2のルートデバイスと同じにする必要がある

![Untitled Diagram-Page-1 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298813/82f3c7cd-65e5-079b-5614-a6b5eac9e162.jpeg)

##### 6. 不要になったEBSを削除
お片付けして作業終了