OmniAICreator/Qiita-1.07M huggingface dataset:
Docker Desktopの代わりにcolimaでdockerを動かす

# TL;DR
```
# インストール
$ brew install colima

# colima VM起動
$ colima start --cpu 8 --memory 12 --disk 100 -v /Volumes/projects:w

# colima環境でdockerを使う
$ docker -v

# dockerコマンドcolimaがマウントしたdocker.sockを利用するように切り替え
$ docker context use colima

# 動作確認
$ docker run hello-world

# colima VM終了
$ colima stop
```
# 背景
2022年1月31日からDocker Desktopが大企業での利用に関して有料化された。[記事](https://www.docker.com/blog/updating-product-subscriptions/)  
(中小企業（従業員数が250人未満、年間収益が1,000万ドル未満）、個人利用、教育および非営利のオープンソースのプロジェクトでは今まで通り無料で利用が可能)

しかし、「Docker CLI」や「Docker Compose」などのコンポーネントについても引き続き無料で提供され「Docker Desktop(Docker for Mac等)」のみが今回有料化とのこと。  
そのため、大企業勤務で無料で使い続けるためには、Docker Desktopをアンインストールした上で、別の手段を考える必要がある。  
今回は、最小限のセットアップでmacOS上にコンテナランタイムを構築することができるcolimaを用いて環境を構築する。

# 前提条件
homebrewがインストール済みであること

# インストール手順
colimaはdockerd相当の部分を担当するため、Docker CLIは別途homebrewでインストールする必要がある。
```
# Docker CLIのインストール
$ brew install docker

# colimaのインストール
$ brew install colima
```

# 使い方

## 使う前に把握するべきアーキテクチャ
docker for macは内部でHyperkitを使ってlinuxのVMを立ち上げており、dockerdをその中で動かしている。  
そのためmacのターミナルからdockerコマンド実行時には、docker for macがこのVMからホストのmacにマウントしている`docker.sock`ファイルを経由して、VM内の`dockerd`とコミュニケーションしている。
また、ホストのDiskをVMにもマウントすることで、あたかもホストのMacOS上でdockerが直接動いているようなUXを実現している。
colimaも同様にLinux VMを立ち上げ、`docker.sock`をマウントするし、デフォルトで`/Users/your-user-name`をVMの`/Users/your-user-name`にマウントする。
また、インストール後に`docker context`という機能を利用して、dockerコマンドがdocker for macではなくcolimaがマウントした`docker.sock`を利用するように切り替えを行なう。

## 始め方
まずはcolimaでVMを用意する必要がある。
初回に指定したdiskサイズだけは後から変更ができないため、ある程度余裕を持って設定する方が良い。
その他のCPU, MemoryなどはVM再起動時に設定可能。
また、`/Users/your-user-name`以外のVolumeがマウントされないため、もしホームディレクトリ以外の場所で作業している場合には、明示的にマウントする必要あり。

defaultは以下の設定、引数をとることで設定を変更できる。
```:default値
cpu: 2
memory: 2GiB
disk: 60GiB
```

```:VM起動コマンド
$ colima start --cpu 8 --memory 12 --disk 100 -v /Volumes/projects:w
```
追加したいVolumeがなければ`-v /Volumes/projects:w`は省略可。
この時点で通常通り`docker / docker-compose`コマンドが利用できるように。

VMを終了する際は、以下のコマンドで終了できる。
```
$ colima stop
```

VM一覧は以下で確認できる。
```
$ colima list
PROFILE    STATUS     ARCH      CPUS    MEMORY    DISK
default    Stopped    x86_64    8       12GiB     100GiB
```
また、PCを再起動するとcolima VMも落ちるため、VMの再起動(`colima start ${Profile}`)が再度必要。
その他の機能についてはcolima helpないしcolima help COMMANDを参照。
BP_ThirdPersonCharacterの動きを変更する

# 概要
ThirdPersonTemplateに入っているBP_ThirdPersonCharacterのデフォルトの動きを速くて反応がいい動きに変えていこうとしたときに、どのパラメータを変更したらいいかのメモです。

## Character
- Jump Max HoldTime
    - ジャンプボタン押してる間、上昇しつづける時間です。
- Jump Max Count
    - 最大ジャンプ回数。2段ジャンプしたいときは2にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/3b09641a-4ae5-66d8-8f6e-2cb10a60b6e5.png)

## CharacterMovement
- Gravity Scale
    - ジャンプの落下速度です。値が高いほど速く落下します。
- Max Acceleration
    - 移動開始したときの加速度です。高いほどMax WalkSpeedにすぐに達します。
- Max Walk Speed
    - 移動速度の最大値です。上げるほど速くなります。
- Breaking Deceleration Walking
    - 移動をやめたときの減速です。値が大きいほどすぐに止まります。
- Jump Z Velocity
    - ジャンプ速度です。高いほど速くジャンプします。
- Air Control
    - ジャンプ中の動き制限割合です。1.0で歩行時と同じ速度で反応します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/723cc3ea-7823-87d0-14fc-81a131255e99.png)

# 自分の設定
| 変数名 | 値 |
|:-:|:-:|
| Gravity Scale  | 5.5  |
| Max Acceleration  | 50000  |
| Max Walk Speed  | 1000  |
| Braking Deceleration Walking  | 10000  |
| Jump Z Velocity  | 1600  |
| Air Control  | 1.0  |

![charactermovement.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157391/6f05d63b-478e-f6a8-4613-dda6cff4833b.gif)
PHPで5の付く日曜日を出力するプログラム

実務で3ヶ月経過したので4ヶ月前に書いたのと同じものを作ってみました
↓↓Javaで5の付く日曜日を出力するプログラム
https://qiita.com/noczz/items/aa1caccf6aebc334b0f8

今見返すと酷いコードですね…
初心者なりに前よりも良いコードを書けるように考えてみました
実務ではPHPを触っていますのでPHPで書いてみました

**プログラム要件**

* endと入力されるまで無限ループ
* Enterキーを押すと1つずつ次の5のつく日曜日の年月日が表示される

```php

<?php
const SPECIAL_DAYS = 5;

class BlarDateTime extends DateTime
{
    /**
     * Return Date in ISO8601 format
     *
     * @return String
     */
    public function __toString()
    {
        return $this->format('Y-m-d');
    }

    /**
     * SPECIAL_DAYSの付く日曜日を返す
     * 次の日曜日の日付にSPECIAL_DAYSが含まれていなければ再帰処理
     * @return String
     */
    public function getNextSpecialDays()
    {
        if (strpos($this->modify('next Sunday')->format('d'), SPECIAL_DAYS) == True) {
            return $this->format('Y-m-d');
        }
        return $this->getNextSpecialDays();
    }
}

echo '現在の日付から5のつく日曜日を表示します…'. PHP_EOL;
echo 'Enterキーを押すと次の日付を表示'. PHP_EOL;
echo 'endと入力するとループ終了'. PHP_EOL;

$date = new BlarDateTime();

while (true) {
    $input = trim(fgets(STDIN));
    if ($input == 'end') {
        return;
    }
    echo $date->getNextSpecialDays();
}
?>
JLCPCBで４層基板を作った

**はじめに**
KiCad6で４層基板を作ってみたので感想とその備忘録を書く
感想としては、品質の良い４層板がこんなに安くていいの…？と感じたので今後は
頑張って２層で配線を引き切るのではなく、４層を使っていきたいと思った。

JLCPCBは初めて発注する日本在住の人５４＄のクーポンを配っていて本当にお得なので是非使ってみてほしい
以下がリンク
https://jlcpcb.com/JPV

**何を作ったか**
今回作成した物は自己発振する三相交流発生基板
もっと細かく言うと、クワドラチャ発振器で９０度位相がズレた二相の正弦波で発振させ、
その２相の正弦波をopampで反転や加算を行う事で三相交流にする。
クワドラチャ発振器の定数は1kHzの発振だが、二相の信号は外部から入力可能にして任意の周波数での三層交流が出せるようにする。
(もちろんopampのスルーレートなどで制限される)
そして、三相交流の振幅はデジタルポテンションメーターで制御を行う。
肝心の何に使うかは考えていない…

**4層基板の注文方法**
Kicad6での注文方法を示す。
って言っても２層基板の時とあまり変わらない。

ガーバーの設定は以下の通り
２層の時と比べて「含めるレイヤー」に
・In1.Cu(２層目)
・In2.Cu(３層目)
を追加するだけでOK
![キャプチャjhiu.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867623/efb240cc-cbd9-1839-3ac3-a17d114ffc24.png)
ドリル設定は以下の通り
![キャプチャhgjhg.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867623/1547e918-07a1-4033-bff2-285463c5764e.png)


JLCPCBでの注文はこちらから！
https://cart.jlcpcb.com/quote
![キャプチャhhhh.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867623/26f5c308-e662-03c3-16d1-67f38aac411d.png)
注文はこんな感じ。
注目してほしいのは「Layers 4」で注文金額が８ドルの点。
２層２ドルで注文できるが、＋６ドルで４層に出来るって大きくないですか？
配線の引き回しを１時間色々悩んで引き回しては直してはを繰り返すなら
さっさと＋６ドルで４層にした方が良くないですか？

**完成！!**

![IMG_8951.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867623/0adfb902-535c-15b8-7fc4-fbc06e0cfb90.jpeg)

![IMG_9162.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867623/a083ea5f-0943-1b68-41ab-d5792dc9c6c7.jpeg)

![IMG_8953.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867623/b74361d0-c623-0521-1a79-c68c29551e6a.jpeg)

デジタルポテンションメータの制御プログラムは別記事で書きます。
【IE11】6月15日以降Inernet Explorerはどうなるのか

長年お世話になったInternet Explorer 11(以降IE)が、2022年6月15日以降サポートが終了するそうです。
各OSやオンライン/オフライン状態の違いでどのような影響が出るのか、会社の人から調査を依頼されたので調べました。
皆様のお役に立てば幸いです。なお、もし間違いなどありましたらご指摘いただきいただければと存じます。

情報はMicrosoftのテックコミュニティを引用しています。

参考：
Microsoft : Internet Explorer 11 desktop app retirement FAQ.<br>https://techcommunity.microsoft.com/t5/windows-it-pro-blog/internet-explorer-11-desktop-app-retirement-faq/ba-p/2366549 (2021/05/19)

---

# 重要なポイント

* 使えなくなるタイミングは、Windows Update(１５日以降のいずれかの更新プログラム)後
* Windows Updateが実施されない環境では、これまで通りIEが使える(はず)
* IEモードを利用すれば、まだ使える

# ざっくり要点まとめ

* Windows 11ではIEが使えない(「IEモード」は使える)
* Windows 10(21H1,21H2)で、2022年6月15日でIEのサポートが終了する
    * それ以外のWindows10のバージョンではそもそもOSのサポートも終了している
* **Windows Update累積更新プログラムの一部として更新され、無効化される**
* このWindows Updateは数カ月かけて徐々に実行される
* 「無効化される」の意味とは以下であり、実質的にIEを起動するすべがないため無効化と呼ばれる
    * IEを開こうとすると、強制的にEdgeが起動するようになる
    * iexplorer.exeを直接実行しても、Edgeが起動する
    * ただし、iexplorer.exeは「IEモード」で再利用されているため削除されるわけではない

# 無効化の範囲外とされている対象

* Microsoft EdgeのIEモード
* WebOSを含むInternet Explorerプラットフォーム
* IE11のデスクトップアプリケーション
    * windows 8.1
    * Windows 7拡張セキュリティ更新プログラム(ESU)
    * Windows 10 IoT Long Term Servicing Channel（LTSC）（すべてのバージョン）
    * Windows Server SAC/LTSC (全てのバージョン)
    * Windows 10 LTSC（全てのバージョン）

# IEモードとは

予めIEで開きたいURLを登録しておくことで、URLにアクセスした際はIEモードで閲覧できるようになる機能の様です。IEモードについては本筋から外れるので、本稿では記載しません。
よく聞かれることが、「IEモードを使えばこれまで通りIEでしか動かないページは実行できるのか」という内容ですが、IEモードではiexplorer.exeを使うことから、中で動くプログラムはIEであると予想できるため、IEで動く機能は互換性があると思われます。
ただ、描画はEdgeに依存する可能性があるので、描画崩れは発生するかもしません(確証なし)

# 結局のところ、オフラインならまだ使える？

IEが使えなくなるトリガーはWindows Updateによるものなので、オフラインであればIEはまだ使えます。
ただし、OSのサポートは終了しますので、セキュリティの観点ではお薦めはできません。
もしIEを使い続けたい場合は、上記記載の範囲外となるOSやライセンスを使用することを推奨します。
google analycs4 (ga4) の遅延読み込み

### なんとなくいけてる気がしますので、掲載してみます。

```lazy-gtag.js
var MEASUREMENT_ID="G-xxxxxxxx";

$(function() {
	setgtag();
});

function setgtag() {
	setTimeout(function() {
		var gtc = document.createElement("script");
		gtc.innerHTML='window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("js",new Date());gtag("config", MEASUREMENT_ID);';

		// 下記はデバッグモード用
		//gtc.innerHTML='window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("js",new Date());gtag("config", MEASUREMENT_ID,{"debug_mode":true});';
		document.body.appendChild(gtc);

		var gt=document.createElement("script");
		gt.src='https://www.googletagmanager.com/gtag/js?id=' + MEASUREMENT_ID;
		document.body.appendChild(gt);

	}, 2500);
}

```

### 一応デバッガーでもOKが出てます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149448/68de92df-99e9-4b1b-8eff-0c1f4fd8ba15.png)
gRPCにおけるrepeatedとstreamの使い分け

# gRPCで配列を返す方法2通り

初心者なので分かりませんでした。

gRPCでデータの配列を返したい場合の実装方法として、レスポンスのデータ型を`repeated`にする方法と、サービスの定義で応答に`stream`を使用する方法の2通りがある。

レスポンスのデータ型を`repeated`にする方法。
```proto:message.proto
message Item{
  repeated int32 item_id = 1;
}
service MyService {
  rpc ListItems() returns (Item) {}
}
```

サービス定義中で応答に`stream`を指定する方法。
```proto:message.proto
message Item{
  int32 item_id = 1;
}
service MyService {
  rpc ListItems() returns (stream Item) {}
}
```

# どっちを使うか

## `repeated`を使用すべきシチュエーション

データ量が比較的少量で、容量や応答時間が分かっている場合はこちらを使う。

- 比較的短時間でデータを返すことができる場合
- データの量が決まっている場合

サーバー側であらかじめデータを組み立ててからまとめてクライアントに側に返す。
例えば、eコマースのシステムなどで条件に一致するアイテムの一覧を返すような場合。


## `stream`を使用すべきシチュエーション

その名の通りストリーミングなので、終わりの見えないデータを流し続ける場合に使う。

- データ量が非常に大きくなる可能性がある場合
- データの生成に時間がかかる可能性がある場合

レスポンスに時間がかかる場合、`repeated`を使うと応答が終わるまでクライアントの処理はブロックされ続けることになりパフォーマンス的によろしくないし、データが大きすぎる場合はメモリが枯渇する可能性もある。
こういう場合は`stream`を使って受け取ったデータを逐次処理していくことでレスポンス性やリソース効率を上げることができる。スケールもしやすいだろう。

あとは、ログメッセージのようなものをチョロチョロ流し続ける時とかもこちらを使うべきだと思う。
sinonのuseFakeTimersはsetTimeoutと一緒に使用できない

[Sinon.JS](https://sinonjs.org/)でuseFakeTimersを使って現在時刻を変更して単体テストをしていたとき、setTimeoutがおかしくなったので調べてみました。

## 公式サイトのドキュメント 

[sinonのAPIリファレンス](https://sinonjs.org/releases/latest/fake-timers/)に説明がちゃんと書いてありました。
（なのでもうここまででこの記事は99%の内容になります。あとは蛇足です。）

APIリファレンスには以下のように書かれていました。

> Causes Sinon to replace the global setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate, process.hrtime, performance.now(when available) and Date with a custom implementation which is bound to the returned clock object.

[StackOverflowでも同じ内容の質問](https://stackoverflow.com/questions/36156940/sinon-usefaketimers-creates-a-timeout-in-before-aftereach)があり、sinonのuseFakeTimersを使っている間はsetTimeoutは使えないよ、と書かれていました。

つまり、sinonでuseFakeTimersを使っている間、setTimeoutやsetInterval等それとDateオブジェクトのカスタム実装のようなJavaScriptで時間の操作が入るような関数は正常に動作しなくなります。

## 検証

useFakeTimersを使ったときにsetTimeoutがどのような動きになるのかを検証しました。
使ったJavaScriptファイルは以下のリポジトリに格納しているので、自由に利用してください。

[nodejs-module-labo/sinon/useFakeTimers-break at main · s1r-J/nodejs-module-labo](https://github.com/s1r-J/nodejs-module-labo/tree/main/sinon/useFakeTimers-break)

まず、下のようにsinonのuseFakeTimersを呼び出し、時刻を好きな時刻にします
単体テストであれば、現在時刻ではなくテストに最適な時刻を指定して利用します。

```javascript
const sinon = require('sinon');

const now = new Date();
const timeStub = sinon.useFakeTimers(now.getTime());  // ①

console.log(`now: ${now}`);  // ②

setTimeout(() => {  // ③
  console.log(`timeout: ${new Date()}`);  // ④
}, 2000);

console.log('end');  // ⑤
```

このコードではsetTimeoutを使っている（③）ため、sinon.useFakeTimersによる影響がなければ以下のようなコンソール出力が得られるはずです。
JavaScriptは非同期のため、②の実行後に⑤が実行され、そのおよそ2秒後にsetTimeoutによって④が実行されるはずです。

```
now: Fri Apr 01 2022 12:00:00 GMT+0900 (Japan Standard Time)
end
timeout: Fri Apr 01 2022 12:00:02 GMT+0900 (Japan Standard Time)
```

しかし、実際のコンソール出力は以下のように、④が実行されなくなります。
setTimeoutのような時間操作が関わるメソッドはsinon.useFakeTimersを利用している間は利用できなくなります。

```
now: Fri Apr 01 2022 12:00:00 GMT+0900 (Japan Standard Time)
end
```

ただし、先述のJavaScriptコードの②と③の間で`timeStub.restore();`を実行することでsetTimeoutを正常に動作させることができます。
restoreはsinon.useFakeTimersの利用を終了して、スタブを片付けるメソッドです。

## 結論

- sinonのuseFakeTimersを使っている間は、JavaScriptで時間の操作が入るような関数（setTimeoutやsetInterval等、Dateオブジェクトのカスタム実装）は正常に動作しない
- sinonのuseFakeTimersを使ったあとはきちんとrestoreする
    - restoreしないと他のテストケースでsetTimeoutなどが正しく動作しなくなる
.editorconfigの導入

# はじめに
チーム開発においては、各開発者がそれぞれ好きなエディタやIDEを使ってコードを書いている。そのため、一貫したコーディングスタイルを維持するのは難しいが、`.editorconfig`というファイルを`Git`などのバージョン管理システムを使ってチームで共有すれば、それが簡単になる。

https://editorconfig.org/

> The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles.

「EditorConfig」プロジェクトは、

- コーディングスタイルを定義するファイルフォーマット
- エディタが↑を読み込むためのエディタ用プラグイン

で構成されているとのこと。
`.editorconfig`の正式な仕様書はこちら↓

https://editorconfig-specification.readthedocs.io/

# 導入
導入といっても、`.editorconfig`ファイルをプロジェクトディレクトリに作成するだけ。
「EditorConfig」プラグインは開いたファイルのディレクトリとすべての親ディレクトリに`.editorconfig`という名前のファイルがあるかどうか探す。ルートファイルパスに到達するか、`root=true`と書かれた`.editorconfig`ファイルが見つかれば探索終了。より近い階層にある`.editorconfig`ファイルが読み込まれ、そこに書かれたコーディングスタイルが適用される。

`.editorconfig`は[INIフォーマット](https://ja.wikipedia.org/wiki/INI%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB)に沿って書き、セクション名は[グロブ](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AD%E3%83%96)で指定する。

```ini:.editorconfig
# EditorConfig is awesome: https://EditorConfig.org

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
```

僕の場合はこんな感じ↑
OSSへのコントリビュート体験記

憧れの初OSSコントリビュート記念で投稿します！:grinning:
ちなみに、業務経験役2年のwebエンジニアです。

### I.まとめ
動き出しからマージまで、業務後作業で5日間（8時間くらい）でした。
CSSの4行だけの変更でしたが、達成感がありました！
最終的に出したプルリクエストはこちらです↓
https://github.com/joomla/joomla-cms/pull/37695

### Ⅱ.流れ
#### 1. プロジェクトを探す。（~~半年~~、1日くらい）
↓のQiita記事を参考にさせて頂き、"good first issue"というサイトで探しました。
https://qiita.com/Naughty1029/items/cf8750f375fa99bce9bb
業務で使用しているPHPやVue.jsで探しましたが、
各プロジェクトをざっくり見て、やっぱ無理。。というのを数ヶ月おきにしつつ、
ドキュメントと雰囲気がめっちゃ親切そうな
"Joomla"というプロジェクトにチャレンジすることにしました:star:

https://github.com/joomla/joomla-cms

#### 2. 環境構築（2日）
環境構築はいつも基本コピペ状態なので、ここが不安でした。
プロジェクトのドキュメントを読むも、
環境構築については、"XAMPPやMAMP使って"としか書かれていませんでした。常識ナンダネ。
https://docs.joomla.org/Setting_up_your_workstation_for_Joomla_development
仕方なく、Google先生に聞きつつ、いくつか失敗し諦めかけつつも、
MAMPが便利すぎてローカルでプロジェクトを動かすことができました。
(というかMAMPインストール->そこでgit cloneするだけでした。。)

### 3. Joomlaをインストールする (1日）
gitは親切なドキュメントの通りにやってクリア(folk&cloneするだけ)。
またそれとは別に初期設定を行いました。
DBのユーザーとパスワードの意味がよく分からず、止まりましたが、
Joomlaの使い方を紹介するネット記事に助けられ、クリア。
https://deep-blog.jp/engineer/joomla-install-setting/

### 4. 修正！ (1日）
問題の状態：tooltipのpopoverの位置が元要素から離れている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/6736b9e6-4be8-3b9d-6c8e-8e7298e73269.png)
htmlだったので開発者ツールでソースコードの場所は割と簡単に分かりました。
Sassでビルドされていたので、決定的な場所はちょっと探しづらかったですが、
過去プルリクにほぼ同じのを発見したのもあってすんなり特定。
（というか過去プルリクを見つけた時点でサービス問題化しました:sweat_smile:）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/b57b70fe-e355-bef1-c8d8-cbea848b43d8.png)
Sassに4行足して終了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/49ca26c6-56ba-009a-9936-8f6875f6d6b9.png)


あれ、変更が反映されない。。
ビルド方法に苦戦しつつも、そのヘルプまである恵まれっぷりで解決。
https://docs.joomla.org/J4.x:SCSS_and_Sass#Where_can_you_find_the_.scss_stylesheets_and_compiler.3F

ドキドキしつつ、えいやっでプルリクを出す。
30分くらい自動テストが走って無事クリア。
リアクションあるかなーと思ったけど特にコメントなかったので寝る。
朝起きたら、"大丈夫だったよ！ありがとう！"みたいな優しいコメントが付いてて朝からめっちゃ嬉しかった:sunny:
プルリクから12時間後くらいにマージ頂いて完了。。！

### Ⅲ.結論
何度もつまづきましたが、
ドキュメントやネット情報が多いプロジェクトを選べば、
そんなに難しくなかったと思いました:grinning:
ですので、初めては、大きめにプロジェクトが良いのかもしれません。
なお、一番良かった点は、
知らない人と一緒に作ってる感やいつもと違うプロジェクトの雰囲気を味わえたことが
非常に楽しかったです！
著者トークイベントから考える「良いコード/悪いコードで学ぶ設計入門」の読み方

### こちらの著者トークイベントに参加してまいりました

https://modeling-how-to-learn.connpass.com/event/242976/

参加を踏まえて、どんな人にこの本がおすすめなのかを紹介します。
また、著者トークを踏まえたこの本の実務での使い方を紹介します。
※イベント内容はメモをとりながら視聴させていただきました。
誤解のない記載に努めましたが、
正確性に欠けた記載・著者が言っていない発言を書いてしまっている場合があります。
真に正確な内容につきましては、著者の書籍を是非お買い求めください。
（ちなみにNMRtは5/3から読み始める予定です！）
https://amzn.to/3ybPn4K

#### 【イベント参加感想】
「読んでみたい！」と強く思うようになったきっかけは
「高凝集なカプセル化とイミュータブルを合わせた設計やモデリングを重視している」こと。
それらの技術を駆使して現場でリファクタリングを行なっていることから、書籍の購入を
先倒ししました。（イベント参加前はしばらく後で買う予定でした）

#### 【対象読者】
・設計・特にアプリケーションアーキテクチャに興味がある人
（でもドメイン駆動設計やクリーンアーキテクチャは難しくて読めない！という人）
・新卒〜初級プログラマー
・中級プログラマー
・オライリー本等に「抽象論ばかりでわかりにくい！」という感想を持っている人
・オブジェクト指向を実務で使いたい人
・高凝集なカプセル化・イミュータブルな設計に興味がある人
・モデリングや技術選択について説明を受けたい人

#### 【この本で著者が実現したいこと】

１）「エンジニアリングの当たり前を変える」
現代ではLinuxやGit、DockerやAWSなどはインフラエンジニアだけでなく
フロントエンジニアもある程度触れることが当たり前になっている。
そこに「変更容易性のある技術設計」という当たり前を追加したい。
また、リファクタリング反対勢をデータや設計の観点から論破したい。

２）ドツボにはまるパターンを数多く紹介すること
「悪いコード」は主に仕様変更の時に生まれる。
「悪いコード」に対しての再現性のある対処療法を紹介する。

#### 【この本でわかること】

著者はこの本で以下の内容を提供しています。
①著者が経験した「悪いコード」を大量にサンプルとして掲載しました。
②設計の定義や理想状態がわかるように記載しました。
③上記の2つを知ることで「悪いコード」の正体がわかるようにしました。
これらがわかることによって、自分のコードが理想から外れた時に気づけるようになります。

また、中級者が初級者のコードレビューを行う際に、
「なぜあなたのコードはいけないのか？」を説明するサンプルとしての使用も考えています。
（サンプルコードを都度作成するのは時間がかかる。説明が中途半端に終わると急所が伝わらない。）

#### 【この本でわからないこと】
・DBやHTML周りの設計に関すること
これらは対象外であると著者が発言しています。
（Web/ネイティブ）アプリケーションアーキテクチャに関する本と考えて良さそうです。

・完璧な設計
いわゆる「銀の弾丸」「これさえやっとけば大丈夫」は書いていないし、たぶんどの本にも書いてありません。
設計は「時間とコストのトレードオフ」であること。
この本で学んで欲しいのは、重視する方に適した設計を選択する「技術選択」力。

#### 【各章の概要】

※メモが間に合わなかったので、覚えているところ、興味を持ったところだけ書いています。
ただイベントでも詳細な内容については触れていなかったと思います。

１、２）新人プログラマ向けの章
「設計しなければ」という意識を持たせる。
命名やメソッド設計のベースについて記載。

３）クラス設計
低凝集→高凝集なValueObjectの構築方法を記載。
ここが著者曰く「超重要」

４）不変の活用
安定動作するために不変を活用。

５）低凝集に陥りがちなパターンを紹介
対策方法を紹介。

６）分岐処理を解きほぐす
いわゆる「くそネスト」に対する批判？でしょうか（うろ覚え）
解決の鍵は「インターフェースの活用」

７）コレクションのネストを解決する
コレクション周りのロジックについて解説。

８）密結合について
単一責任の原則について説明。
責務とは何かを解説。

９）設計の健全性を損なう「悪魔」について解説

１０）名前設計について解説
ロジック構造を導き出すための名前を設計することの重要性について解説。

１１）コメント

１２）メソッド

１３）モデリング

１４）リファクタリング

#### 【オススメしたいと思ったポイント】
・プログラム入門→「この本」→「往年の設計関連の名著」
という感じにステップアップができそう。
・オブジェクト指向や設計関連の本で発売前から「１万部」売れた
つまり「設計重視」は今のトレンドでもある
・悪いコードは本当にコスパが悪い
これは私の今考えている思想です。
悪いコードのせいでAWSのインスタンスが無駄に何個も追加されたらどうなるか？
かなりAWSのコスパが悪くなってしまう。
→「良いコード」に導くマネジメント技術は今後武器になるのでは？
と思い、その答えが知りたいと思い購入しました。

GW後半から読み進めていきたいと思います！！
記事を読んでいただきありがとうございました。

こちらから「良いコード/悪いコードで学ぶ設計入門」を購入できます。
https://amzn.to/3ybPn4K
Vim コマンド　基本

## Vim
- 今日はVimについてメモ程度にコマンドを記述していこうと思う。
- 間違いなどございましたらご指摘いただけると幸いです。よろしくお願いいたします。

### ノーマルモード
Vim を起動すると、ノーマルモードから始まる。
ノーマルモードを起点に各モードに遷移することができる。
それぞれのモードで「Esc」を押すとノーマルモードに遷移。

|コマンド|動作|
|---|---|
| h |左に移動|
|j  |下に移動|
|k  |上に移動|
|gg |一番上に移動|
|G  |一番下に移動|
|x  |文字削除|
|nx  |n（数字）分削除|
|dd |１行削除|
|y  |コピー|
|u  |一つ前に戻す|
|p  |ペースト|
|yy |一行コピー|
|dd→p  |切り取り貼り付け|
|$  |行末に移動|

### コマンドラインモード
|コマンド|動作|
|---|---|
| :q |終了|
|:w  |上書き保存|
|:wq  |上書き保存して終了|
|:q!  |強制終了|
|/{文字}|{文字}の検索|
|n| 次の文字列検索へ|
|N| 前の文字列検索へ|

### 入力モード
ノーマルモードから`i`を押すと使える。

### ビジュアルモード
ノーマルモードから`v`を押すと使える。
範囲指定するときに使う。
【Pythonで作図】忙しい人のための Matplotlib【初心者向け】

# ✨Python って作図がカンタン！✨
**「Pythonで作図」**…。ネットにはたくさん記事があるけど、どれも**ややこし**くて**難しい**ですよね。
そんな方々のために、**手っ取り早く**て**分かりやすい**「Python 3分クッキング」をやっていこうと思います！


# 0. 完成目標
これを作ります。
```python:完成コード
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-100,100,0.1)
y = np.sin(x)/x
plt.plot(x,y)
plt.show()
```
**結果**
![20220430test01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648376/3bd487ad-d20b-00c3-be35-357b0dab9880.png)

では、始めます。

# 1. これをコピペ
```python:【必須】おまじない（計算と作図に必要な道具を準備しろ！という命令）
import numpy as np
import matplotlib.pyplot as plt
```

# 2. 作図したい関数を入力
## 2.1 xの範囲（定義域）を指定
$a \le x \le b$ の変域ならば、
```python:定義域の指定方法
x = np.arange(a, b, 0.1)
```
と書きます。

今回は $-100 \le x \le 100$ の範囲を描きたいので、
```python:今回の定義域
x = np.arange(-100,100,0.1)
```
としました。
> この $0.1$ は、「$0.1$ 刻みでプロットしますよ」という意味。
> 大根をぶつ切りしたければ $1$ でもいいし、もっとなめらかに切りたければ $0.01$ にして大根おろしを作ってもよい。

:::note warn
**注意**（お忙ぎの方は飛ばしてください）
`np.arange(a,b,c)` は、厳密には 初項 $a$ , 公差 $c$ の等差数列の集まりで、**末項は $b$ の手前**で終わります。
つまり、**厳密には $ a \le x < b$ の範囲で作図してる**ということ。（$a \le x \\; \\, \`\`\le" \\, b$ ではない！）
例えば $ 0 \le x \le 5 $ を $1$ ずつプロットしたいとき、`np.arange(0,5,1)` って書いちゃうとグラフがヘンになっちゃうので、`np.arange(0,6,1)` って書こうねってオハナシ。
:::

## 2.2 y = f(x) を指定
今回は、
```math
y = \frac{\sin x}{x}
```
のグラフを描こうと思います。Pythonでこのグラフは、
```python:y = f(x) の指定
y = np.sin(x)/x
```
と入力できます。

> ※ エラーが出る場合は、たぶん $x=0$ で割るな！って怒られてるんだと思います。そんな時はテストする関数を例えば $y=\sin x$ とか $y=x^2$ とかに変えてみたり、定義域に $0$ が含まれないようにしてみてください。

### 註）Pythonの演算
* [Pythonの算術演算子（四則演算、べき乗、リスト・文字列の結合など） | note.nkmk.me](https://note.nkmk.me/python-arithmetic-operator/)
* [NumPyで三角関数（sin, cos, tan, arcsin, arccos, arctan） | note.nkmk.me](https://note.nkmk.me/python-numpy-sin-con-tan/)
* [Pythonで指数関数・対数関数を計算（exp, log, log10, log2） | note.nkmk.me](https://note.nkmk.me/python-math-exp-log/)

など、ググれば多数でてきます。

# 3. おまじない再び
```python:【必須】おまじない（とっとと作図しろ！という命令）
plt.plot(x,y)
plt.show()
```
これで実行します。

**結果**
![20220430test01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648376/3bd487ad-d20b-00c3-be35-357b0dab9880.png)

やったね！♡。(⋈◍＞◡＜◍)。♡
C++14 の transparent comparator について

## あらまし
`std::map<std::string, int> table;` のようなコンテナがあったとして、`table.find("hoge")` で要素を検索した場合、std::string の一時オブジェクトが作られてしまい、無駄が生じるという問題がある。
C++14 以降ではこの問題への解決策が用意されており、`std::map<std::string, int, std::less<>> table;` とすると一時オブジェクトが作成されなくなる。
[動作例](https://godbolt.org/z/cef6dG1P7)

誰もが初見では面食らうであろうこの `std::less<>` がどのように機能するのか、また、これに対応したコンテナを自作するにはどうするのか、という話が以下になる。

## Transparent Comparator
std::less の定義を見ると以下のようになっている。
```cpp
template <class T = void>
struct less {
    constexpr bool operator()(const T& l, const T& r) const {
        return l < r;
    }
};
```
T のデフォルトパラメータが void であることから、std::less\<\> は std::less\<void\> であることがわかる。
では std::less\<void\> はどうなってるのかというと、以下のような特殊化が用意されている。

```cpp
template <>
struct less<void> {
    template <class T1, class T2>
    constexpr auto operator()(T1&& l, T2&& r) const {
        return l < r;
    }

    using is_transparent = int;
};
```

std::less\<std::string\> の場合、operator() の引数はどちらも const std::string& になるため、table.find("hoge") とすると文字列リテラルは暗黙の変換により std::string の一時オブジェクトになる。
一方、std::less\<void\> はどちらの引数も任意の型を受け付けるようになっている。つまり、table.find("hoge") で std::string と const char* の文字列リテラルが直接 operator< で比較される。std::string と const char* は operator< が用意されているので、一時オブジェクトを挟むことなく比較ができるというわけだ。
この std::less\<void\> のような、どんな型でも受け付ける comparator は、transparent comparator などと呼ばれているそうだ。

## コンテナ側の対応
comparator がどんな型でも受け付けるようになったのはいいが、コンテナ側も対応しないとそれを活かせない。しかも、互換性の都合から旧来の less\<std::string\> のような場合と less\<void\> の場合両方に対応する必要がある。
less\<void\> には `using is_transparent = int;` という型定義があるが、これはコンテナ側での判別のために用意されている。例えば、std::set の lower_bound() は大雑把に以下のような実装になっている。

```cpp
template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set
{
// ...

    iterator lower_bound(const Key& k)
    {
        return std::lower_bound(begin(), end(), k, Compare());
    }

    template <class K, class C = Compare, class = typename C::is_transparent>
    iterator lower_bound(const K& k)
    {
        return std::lower_bound(begin(), end(), k, C());
    }

// ...
};
```
comparator に is_transparent が定義されている場合、下のどんな型の k でも受け付ける版 lower_bound() が選択される。そうでない場合、旧来の Key 型のみを受け付ける lower_bound() が選択される。

当然これは lower_bound() に限った話ではなくて、upper_bound(), equal_range(), find() といった検索系のメンバ関数は同じように transparent comparator 対応版が用意されている。それぞれに const 版もあるので、合計 4 つのバージョンが存在している。
後付けゆえに仕方がない冗長さだが、std::set や std::map 互換のコンテナを自分で実装する場合、同じように 4 バージョンの lower_bound() などを実装するのが望ましいだろう。

なお、**std::map の operator[] は transparent comparator に対応していない**ようなので注意が必要である。table["hoge"] の場合は依然として一時オブジェクトが生成される。

## 実装例
本記事の知見は [flat_set](https://github.com/i-saint/flat_container/blob/main/include/flat_container/flat_set.h) を実装する過程で得た。
(flat set は要素がメモリ上で連続した std::set ライクなコンテナ。sorted vector とも呼ばれる)
Excel Dictionary 入れ子の例

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104697/a0db7533-a36f-c800-0fcf-7fcad819e73b.png)
コード
```vb
Sub prog1()

     Dim i As Integer

     Dim dataNum As Integer

    
     Dim dic As Object
     Dim dKey As Variant
     Dim dicSub As Object
     Dim dKeySub As Variant

     Dim ws As Worksheet

     Set ws = ThisWorkbook.Sheets("辞書")

     ws.Cells.Clear

     Application.ScreenUpdating = False

     dataNum = 10

     For i = 1 To dataNum

        ws.Cells(i, 1).Value = Chr(Int((68 - 65 + 1) * Rnd + 65)) 'A～D
        ws.Cells(i, 2).Value = Chr(Int((67 - 65 + 1) * Rnd + 65)) & "'" 'A'～C'
        ws.Cells(i, 3).Value = Int((900 - 100 + 1) * Rnd + 100) '100～900

     Next

     Set dic = CreateObject("Scripting.Dictionary")

     For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row

       If dic.Exists(ws.Cells(i, 1).Value) = True Then
       
          Set dicSub = dic.Item(ws.Cells(i, 1).Value)

          If dicSub.Exists(ws.Cells(i, 2).Value) = True Then

             dicSub.Item(ws.Cells(i, 2).Value) = dicSub.Item(ws.Cells(i, 2).Value) + ws.Cells(i, 3).Value

          Else

             dicSub.Add ws.Cells(i, 2).Value, ws.Cells(i, 3).Value

          End If

       Else

          Set dicSub = CreateObject("Scripting.Dictionary")

          dicSub.Add ws.Cells(i, 2).Value, ws.Cells(i, 3).Value

          dic.Add ws.Cells(i, 1).Value, dicSub

       End If

     Next

     i = 1

     For Each dKey In dic

         Set dicSub = dic.Item(dKey)

         For Each dKeySub In dicSub

           ws.Cells(i, 5).Value = dKey

           ws.Cells(i, 6).Value = dKeySub

           ws.Cells(i, 7).Value = dicSub.Item(dKeySub)

           i = i + 1

         Next

     Next

     Set dic = Nothing
     Set dKey = Nothing
     Set dicSub = Nothing
     Set dKeySub = Nothing

     ws.Sort.SortFields.Clear

     ws.Sort.SortFields.Add2 Key:=Range("E1:E" & ws.Cells(Rows.Count, 5).End(xlUp).Row), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

     ws.Sort.SortFields.Add2 Key:=Range("F1:F" & ws.Cells(Rows.Count, 5).End(xlUp).Row), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

     With ws.Sort

         .SetRange Range("E1:G" & ws.Cells(Rows.Count, 5).End(xlUp).Row)

         .Header = xlGuess

         .MatchCase = False

         .Orientation = xlTopToBottom

         .SortMethod = xlPinYin

         .Apply

     End With

     Set ws = Nothing

     Application.ScreenUpdating = True

End Sub

```
Nuxt で環境変数を使用するときに気をつけること

# はじめに

※ Nuxt v2.15.8 を使用しております。

# Runtime config プロパティはキャストされる

Nuxt で環境変数を扱うには、 [env プロパティ](https://nuxtjs.org/docs/configuration-glossary/configuration-env/) と [Runtime config プロパティ](https://nuxtjs.org/docs/configuration-glossary/configuration-runtime-config/) があります。 env プロパティから Runtime config プロパティへ移行したところ環境変数がキャストされ、同値演算子（ `===` ）で比較している式が失敗するという不具合に遭遇しました。（以下のような issue も立てられています。）

https://github.com/nuxt/nuxt.js/issues/8162

## 再現
`.env` `nuxt.config.js` `pages/index.vue` の各ファイルに以下を記述します。

```text:.env
TEXT=text
NUM=123
FLAG=true
```

```javascript:nuxt.config.js
export default {
  ...
  env: {
    text: process.env.TEXT,
    num: process.env.NUM,
    flag: process.env.FLAG,
  },
  publicRuntimeConfig: {
    text: process.env.TEXT,
    num: process.env.NUM,
    flag: process.env.FLAG,
  },
}
```

```javascript:pages/index.vue
...
export default Vue.extend({
  name: 'IndexPage',
  mounted() {
    console.log('--- env プロパティ ---')
    console.log(`${process.env.text}: ${typeof process.env.text}`)
    console.log(`${process.env.num}: ${typeof process.env.num}`)
    console.log(`${process.env.flag}: ${typeof process.env.flag}`)
    console.log('--- Runtime config プロパティ ---')
    console.log(`${this.$config.text}: ${typeof this.$config.text}`)
    console.log(`${this.$config.num}: ${typeof this.$config.num}`)
    console.log(`${this.$config.flag}: ${typeof this.$config.flag}`)
  },
})
```

コンソールログを確認します。

```console
--- env プロパティ ---
text: string
123: string
true: string
--- Runtime config プロパティ ---
text: string
123: number
true: boolean
```

## 対策

※ **以下のように `.env` ファイルで値をダブルクォートで囲んだり、 `nuxt.config.js` ファイルで文字列として設定してもキャストされます。**

```text:.env
TEXT=text
# ダブルクォートで囲んでもキャストされる
NUM="123"
FLAG="true"
```

```javascript:nuxt.config.js
export default {
  ...
  publicRuntimeConfig: {
    text: process.env.TEXT,
    // テンプレートリテラルを使用しても number 型にキャストされる
    num: `${process.env.NUM}`,
    // 空文字列を足しても boolean 型にキャストされる
    flag: process.env.FLAG + '',
  },
}
```

### 対策１: 環境変数で扱う値を string 型にする

上記の再現の場合、 `FLAG=true` は改善できます。例えば `FLAG` によってノーマルモードとハードモードに分けている場合は以下のように命名を `MODE` などに変更し、 boolean 型以外の値を設定します。

```diff:.env
- FLAG=true
+ MODE=hard
```

### 対策２: コード上で環境変数を string 型にキャストする

環境変数を使用するときにテンプレートリテラルなどを使用して、 string 型にキャストします。

```javascript
if (`${this.$config.num}` === "123") {...}
```

# おわりに

`nuxt.config.js` ファイルで文字列として設定してもキャストされるのは厄介です。ですので、環境変数で扱う値を初めから string 型になるように定義することでキャストされることを未然に防ぎましょう。
AWS公式の「Infrastructure as Code 談議 2022」がすごく勉強になったのでまとめてみた

この前AWS公式のYouTubeチャンネルにて、面白そうなライブ配信がありました

https://twitter.com/awscloud_jp/status/1516325731437105152?s=20&t=gQbPjNnNZwNX8aNwrfz81A

AWSの動画コンテンツといえば、BlackBeltのようなサービス紹介の動画が真っ先に思い浮かぶ方も多いと思います。
自分もその一人ですが、この動画はプロダクトではなく「Infrastructure as Code（IaC）という概念」にフォーカスしたコンテンツです。

Twitterで学びメモを書きましたが、ちゃんと記事として学びをまとめておこうと思います。
また、動画の内容に関連した補足事項を記事の後半にまとめておきました。

https://twitter.com/hatake_book/status/1520011855015473153?s=20&t=UEsp-4fApjLvsMNC7Qtm0g

↓動画本編はこちら↓

https://youtu.be/ed35fEbpyIE

↓資料はこちら↓

https://www.slideshare.net/AmazonWebServicesJapan/infrastructure-as-code-iac-2022-251672484

# IaCをなぜ使うのか
- 純粋にIaCは楽しい、手順書作成は楽しくない
    - リリースのたびに手順書更新 or 新規作成するのは、果たして楽しいのか
- IaCのほうがリリースまでのリードタイムが短い

# 運用する上での教育はどうする？
- そもそも「教育」はIaCじゃなくても必要
    - 逆に、手順書ベースの運用なら教育はいらないのか？
- 教育云々の問題の前に、IaCなら読み込めばアーキテクチャの全体像が見える
    - 手順書は手順しかない、全体像はわからない。
    - 運用を考えてもIaCのほうがメリットがあると思う。
- チャレンジを許容する組織文化が必要

# ドキュメント管理どうやってやればいい？
- ツールによって管理方法を変える
- リリースと同時に図も更新する
    - 例えば、[draw.io](https://www.draw.io/) のXMLファイルをGitHubで管理、プルリクも同時に挙げる、など

# 引き継ぎ
- そもそも常日頃から引き継ぎできるようにしよう
    - ウォーターフォールでも、アジャイルでも、いつでも引継ぎできる状態にしておくべき
- 組織が開発と運用で分断されてるとIaCの良さを活かすのは難しい
    - 開発と運用が分断されているのは果たして正解なの？
- 逆に、手順書なら問題なく引き継ぎできるのか

# 変わることへの恐怖の克服
- とはいえ、大企業など変わることを怖がる組織ではIaCは難しいのでは。。？
- 対策として挙げられるのは「小さく慎重に始める」
    - 例えば、部分的に一連のパイプラインを作ってみる
- ただし、IaCは始め方が重要、始め方を間違えると後戻りできないので注意
    - 経験者やAWSのSAさんに頼ってしまうのもあり、外部のリソースもうまく活用しよう

# IaCのデメリット
- DBの中は手を出せない
- ロールバック失敗のリスクがある
    - ロールバックが発生した場合、スムーズにロールバックできるのか？できなかったらどうする？
    - 対策として、イミュータブルな構成にすべき

# 最後に
- 外部のリソースを有効活用すべし
- 緊急リリースや脆弱性対応を行うと、環境ごとのずれが出てしまうので、デプロイ頻度は細かくすべき
- 手順書を毎回更新するのではなく、汎用的な手順書を使い回す


# 補足
## イミュータブル・インフラストラクチャとは
- イミュータブル（immutable）は「不変」の意味。本番環境に手を加えないインフラストラクチャのことを指す
    - 本番環境を変更するときは、新しく別のインフラを構築する
    - 問題なければネットワークをパチッと切り替える
    - 切り替え後に問題があれば、ネットワークだけを切り替えることで旧環境にすぐ戻せる
    - 移行・更改の負担を減らすことができる
    - IaCでコード化することで、一元的な管理と自動化が可能になる

https://www.itmedia.co.jp/enterprise/articles/1701/23/news036.html

https://www.ibm.com/blogs/think/jp-ja/cloud-native-concept-02#immutable-infrastructure

## draw.ioとは
- ブラウザ上で無料で使える作図ツール
- AWSのアイコンを使って構成図を作成することが可能
- OneDrive、Googleトライブ、Dropbox、GitHubに描画データを保存・共有できる

https://ferret-plus.com/8408

https://www.fenet.jp/aws/column/technique/1710/

# ほかにこんな記事も書きました
IaCを考える前に、そもそもパブリッククラウドへアクセスする際の認証認可を考えなければなりません

AWSにはIAMというサービスがあり、認証認可の基盤となる縁の下の力持ち的なサービスです
そんな超重要なIAMについて、ロジックからしっかり学べる場所があるんです！

以下の記事で学んできたことをまとめているので、もしご興味があれば合わせて読んでもらえると嬉しいです

https://qiita.com/hatahatahata/items/dc25320fc8dbeeb32f13
[Python実践]argparseに挑戦！《ArgumentParser編》

# はじめに

今回はPythonの「**argparse**」の基礎と「**ArgumentParser**」の使い方について解説していこうと思います！

「**add_argument**」についてはこちらを参考にしてください。

https://chaldene.net/argparse-addargument

https://chaldene.net/argparse-parseargs

「**argparse**」コマンドライン引数を渡してくれるもので、Pythonエンジニアを目指している方は知っておいた方が良いものになります。

ぜひこの記事でマスターしていってください！

この記事はPythonの公式ドキュメントを参考にしています。

Pythonに限らず、プログラミング言語の公式ドキュメントは非常に読みにくいので、この記事でわかりやすく解説していきます。

「**argparse使ってみたい**」

「**コマンドライン引数を渡してみたい**」

「**argparseって何？**」

「**自作モジュール作ってみたい**」

このような人のお役に立てれば幸いです。

それでは早速本題に入っていきましょう！

::: note warn
「argparse」はPythonの基礎を理解していないと難しいので、Pythonの基礎を理解していない人は以下を参考に学習してください！
:::

https://chaldene.net/python-book

# 概要

まずはargparseについて説明していきましょう。

argparseは一言で言えば以下のようになります。

::: note
コマンドライン引数を渡せる。
:::

これではよくわからないですよね。

「**コマンドライン引数**」とは、以下のようにPythonファイルを呼び出す際に渡せる値のことです。

```python
python main.py --n cardene --age 30
```

少し詳しく説明すると、`--nはname`で今回は**cardene**を渡しています。

`--age`は**30**という値を渡しています。

```python
def user_profile(name, age):
    print(name)
    print(age)
```

こんな感じの関数があったとして、**cardene**が`name`引数に、**30**が`age`に渡されるということです。

どうでしょうか理解できたでしょうか？

このように引数が指定されることで、ユーザーごとにカスタムして使えるようにになります。

僕自身Pypiに自作モジュールをあげたことがあります。

https://pypi.org/project/comnamepy/

このモジュールもterminalでも使用することができ、その際には「コマンドライン引数」を渡す必要があります。

この記事ではその方法を学んでいきます。

「コマンドライン引数」を設定する際、結構細かく設定できるのでぜひ全てマスターしていってください！

# 基本

まずは基本的な使い方をざっくりみていきます。

理解できなくても大丈夫なのでまずはみていきましょう！

まずは`ArgumentParser`オブジェクトを作成することから始める。

```python
import argparse

parser = argparse.ArgumentParser(description='かるでねブログ用のテストコード')
```

`parser`というオブジェクトを作成しました。

ここに２つの「**コマンドライン引数**」を追加していきます。

```python
import argparse

parser = argparse.ArgumentParser(description='かるでねブログ用のテストコード')

parser.add_argument('name', type=str, nargs='+', default='cardene', help='username')
parser.add_argument('--age', '-a', nargs='+', type=int, help='user age')

args = parser.parse_args()
```

`name`と`age`という引数を追加しました。

terminalで確認してみましょう。

```python
python main.py --h

usage: main.py [-h] [--age AGE [AGE ...]] name [name ...]

かるでねブログ用のテストコード

positional arguments:
  name                  username

optional arguments:
  -h, --help            show this help message and exit
  --age AGE [AGE ...], -a AGE [AGE ...]
                        user age
```

1行目のコマンドをterminalに入力すると以下のように出力されます。

`--h`はhelpの略で、「**コマンドライン引数**」の使い方を確認できます。

`positional arguments`は必須に引数です。

`optional arguments`はオプションの引数で、なくても問題ないものです。

コード上でどう指定するかというと、Pythonコードの`name`と`--age`の部分を見ればわかります。

`--`というのが先頭についていると**オプション引数**で、ついていないと**必須引数**となります。

早速**コマンドライン引数**を渡してみましょう！

terminalで以下のコマンドを実行してください。

```python
python main.py cardene -a 30
```

`name`に**cardene**を渡し、`age`に**30**を渡しました。

```python
Namespace(name=['cardene'], age=[30])
```

そうすると上記のように出力されました。

ここまでで基本的な使い方を確認しました！

https://chaldene.net/udemy

# 続き

これより先は以下の記事にまとめています。

https://chaldene.net/argparse-argumentparser

より詳しく**Argumentparser**について学ぶことができるので、興味がある方はぜひ！
（もちろん無料です！）
RDSからMySQLへの接続について

この記事は学習した内容をアウトプットし、更に理解を深めるための記録用投稿になります。
投稿している内容と同じ箇所で躓いている方に少しでもお力添えできれば幸いです。

今回はメンターの方に教えていただき理解が深まりました。

## 躓いていた箇所
EC2、RDSの設定が終わりMySQLに接続する際にパスワードを入力するのですが、なかなか何も表示されずしばらくの間待った末にエラーが表示される。
```
MySQL サーバーに接続できません (110)。　　#翻訳
```
```
mysql -u （マスタユーザ名） -p -h （エンドポイント）
Enter password:
ERROR 2003 (HY000): Can't connect to MySQL server on 'rds-mysql-server.
******.ap-northeast-1.rds.amazonaws.com' (110)
```
## 疑った箇所
１、一番最初に思ったのはよくある登録したパスワードを忘れてしまっているのかを疑いました。またやってしまったかと、、

２、その次に思ったのはエンドポイントの記述が間違えているのかという点でした。
データベースの接続とセキュリティでエンドポイントを確認することができますが、その記述をしっかりコピーできていないのかを疑いました。

## 試してみたこと
１、パスワードを忘れてしまっている疑いに関しては以下の記事を参考にパスワードを再度登録して試してみました。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/rese

ですが結果は変わらず、、

２、エンドポイントは再度正しくコピーをして貼り直してみましたがこちらもうまくいかず、、

## 解決方法
どれだけ足掻いても自力ではきつそう、、
結局メンター様の教えをいただくことに！

### 結論
EC2側のセキュリティグループをRDS側のインバウンドルール(セキュリティID)が許可していないため弾かれる。

例えると、、
『EC2の持つ鍵がRDSの鍵穴と一致していない状態。』

EC2の記述は触らずにインスタンスのセキュリティグループの内容を確認します。
-> RDSでのインバウンドルールの変更でソースの欄にEC2のセキュリティグループを入力。

再度試したところ『Welcome』の文字が！待ち望んでいました＾＾
```
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 55
Server version: 5.7.22-log Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 
```
やっとRDSにデータベースの作成が完了しました、、、

## 理解したこと

そもそものデータの流れを理解できていませんでした。
EC2 ==> RDSの流れでその際にEC2の持つ鍵とRDSの持つ鍵穴を一致させてあげること！

復習している時に疑問に思ったのはEC2側のセキュリティグループルールIDがどこから来ているのかがわからない点です。また調べてみます！

冒頭の躓いた点にある「なかなか何も表示されずしばらくの間待った末にエラーが表示される。」に関してはパスワード入力後何度もセキュリティーを抜けて通れるか試みてみたが結局ダメだったよというエラー。何回も試みていたことによってタイムラグが生じていた。

下記の順番も教えていただきそれを踏まえると今回は「２」をクリアできていない状態でした、、
なのでパスワードを疑っていましたがそれに関しては関係なかったようです（ ;  ; ）
```
１、mysql -u （マスタユーザ名） -p -h （エンドポイント）が合っているかチェック。
２、インバウンドルールが合っているかのチェック（鍵が合っているか）
３、入力したパスワードをチェック。
４、パスワードをチェックしてレスポンスを返す。
```
今回の質問で丁寧に教えていただきかなり理解が深まったような気がします！
今後にしっかり活かしていきたいと思います。

何か間違えている点などありましたらご指摘いただけると幸いです。
Grid layout で怖いものなし！よくあるレイアウトをコーディングしよう①

どうもお久しぶりです。maruquiです。

今回はGrid layoutについてまとめます。

横並びはもはやFlexboxを使うのが主流になっているこの頃ですが、Grid layoutでのコーディングも目立ってきました。

前職にいたときからGrid layoutは興味があったのですが、職場では全く使う機会がないまま終わっていました。

現職でいきなりGrid layoutを使う機会があり、少し戸惑いながらも勧めていくわたし。上司にコツを聞いて、ある程度習得することができました。

Flexboxでは手の届かないレイアウトを実装するときに大変便利なので、Grid layoutをイマイチ理解できない方や、自分への忘備録のために記事として残しておきます。

ただ、記事が長くなると思うので、分割してご紹介していきます。今回は、実務で実装したレイアウトに似せたものをご紹介します。

## Grid Layoutが活躍したレイアウト

![gridCording_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2519177/7113a5ce-1e89-4cc1-826b-308b1ed0de46.png)

結論から申し上げますと、PCでは左に画像、右にタイトル＋テキスト、スマホでは上からタイトル、画像、テキストの順番になるようなレイアウトで大活躍しました。

前職ではFlexboxを使って、PCとスマホでdisplay: none;で切り分ける実装をしていました。

Flexboxでの実装をコードにするとこんな感じです。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYQPWbo" data-user="codeQuina" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/codeQuina/pen/LYQPWbo">
  Untitled</a> by Takao Kawai (<a href="https://codepen.io/codeQuina">@codeQuina</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

最初はスマホ表示になっていますが、0.25xのボタンをクリックすることでPCも確認できます。

また、現職にてgap: Xpx Ypx;の存在を知ったので、gapを使う前は画像にmargin-rightで余白を指定していました。

もしFlexboxでもより洗練されたコードを記述できる方法があれば、是非知りたいです。

現状の私が知るFlexboxの実装では、どう考えてもSEO的に良いコードとはいいにくいですから。
コンテンツが重複しちゃってますし…。笑

SEO的に見て良いコードとは言いにくいですが、保守的なコードとも言いがたいです。数個くらいなら修正が発生しても直しやすいですが、大量にあると鬱陶しいし、何より他の人が修正するときに何を思われるかわかりません。笑

ということで、Grid Layoutを使ったレイアウトも見てみましょう。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="zYRYvad" data-user="codeQuina" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/codeQuina/pen/zYRYvad">
  Grid Layout</a> by Takao Kawai (<a href="https://codepen.io/codeQuina">@codeQuina</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

HTMLとSCSS(CSS)の構造がすっきりして見やすくなっています。重複コンテンツもないため、SEO的にも優しい構造だといえます。

あとは慣れてしまえばコーダーにとっても優しい…。

同じような実装ができてしまうなら、楽な方がいいのは明白です。では、Grid Layoutはどう理解して実装したらよいのか…。

それについては、次回Gridについて記事にしたときに説明していきます。

## Grid Layoutは怖くない！

ということで、Grid Layoutを理解したら、こんなときに楽だよ〜というのをご紹介させていただきました。

先ほどご紹介したレイアウトの場合、私の知る限りFlexboxだと超めんどくさいコードの書き方をしなければなりません。

しかしGrid Layoutについて理解を深めたとき、私はかなり視界が広がりました。

Flexboxについて理解ができるようになった方は、ぜひGrid Layoutについても理解していただきたいです。

近々自分の忘備録もかねて、Grid Layoutについてある程度詳しくまとめていきます。

というわけで、今日はこの辺にしておきます。最後までご覧いただきまして、ありがとうございました！

## 参考

* Grid Layoutの基本概念 - CSS MDN Web Docs
<https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout>
40代おっさんJavaScriptの即時関数を学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

### 即時関数の使い方

関数の中で使える変数や、関数を区別するために使う

```javascript
let c = (function() {

    console.log('called');
    let privateval = 0;
    let publicval = 10;

    function privateFn() {
        console.log('privateFn is called');
    }
    function publicFn() {
        console.log('publicFn is called');
    }

    return {
        publicval,
        publicFn
    };
})();

c.publicFn();

console.log(c.publicval);
```

こうするとpublicval,publicFnは関数の外で呼び出すことができますが
privateval,privateFnは呼び出せなくなり関数内でしか使えなくなります

例えば

```javascript
let c = (function() {

    console.log('called');
    let privateval = 0;
    let publicval = 10;

    function privateFn() {
        console.log('privateFn is called');
    }
    function publicFn() {
        console.log('publicFn is called' + privateval++);
    }

    return {
        publicval,
        publicFn
    };
})();

c.publicFn();
c.publicFn();
c.publicFn();
c.publicFn();
c.publicFn();

console.log(c.publicval);
```

初期化は最初に呼ばれたときにしかしないのでその後は++する形になって表させることになる

## 参考資料

<https://www.udemy.com/course/javascript-essence/>
WSL2上のUbuntu 22.04にJMESPath Terminalをインストールして使ってみる

JMESPath TerminalはJMESPathを実行するターミナルで、入力結果に対して出力結果がわかりやすく表示されるため。

JMESPathを便利に使えるターミナルになります。
こちらのターミナルで色々と構文を試してみて学習すれば、JMESPathの学習にはよいかと思います。

## 今回利用する環境

- windows 10 21H2
- WSL2 Ubuntu 22.04
- Python 3.10.4

## WSL2のUbuntu22.04にインストール

今回はWSL2上のUbuntu22.04にインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/137f39ac-3547-a6df-8ae1-58baa36f830a.png)

2022年4月現在、特に対応OSについては記載がないようですが。
Windows上では動かないようです。
（urwidがWindowsで動かないっぽい）

[Is there a JMESPath Terminal for windows 10?](https://stackoverflow.com/questions/41212649/is-there-a-jmespath-terminal-for-windows-10)

[Problem over windows platform](https://github.com/urwid/urwid/issues/152)

またUbuntu22.04へのインストールでも、下記の問題が発生していました。
issueではインストールするsetuptoolsのバージョンを制限することで回避していたので、今回そのように対応しています。

[Urwid version](https://github.com/jmespath/jmespath.terminal/issues/19)

```bash
# pipでjptermをインストールしたいのでpipをインストール
sudo apt install python3-pip

# https://github.com/jmespath/jmespath.terminal/issues/19　の対応
pip install 'setuptools<58'
pip install jmespath-terminal

# jpterm実行
jpterm 
```

jptermが起動しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/a15301ec-7614-834c-445a-b2e96394749b.png)

## jptermの操作について

JMESPath ExpressionにJMESPathを入力をすると、Input JSONに表示されたJSONを評価した結果をJMESPath Resultに表示してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/c430dc0c-8d1f-f617-50b5-544d8bde7cae.png)

## 任意のinput JSONを利用する

jptermに引数で任意のjsonファイルをINPUTファイルとして利用できます。

```bash
jpterm sample.json
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/c5a70fc0-8051-7455-7d13-07121f19eab2.png)

## jptermのキー操作

jptermを終了する場合は `CTRL-C` もしくは `F5キー`。

JMESPath Expressionをクリアする場合は、`CTRL+]`。

outputモード（後述）の切替をする場合は `CTRL-p`。

### outputモードについて

jpterm実行中に `Ctrl-p` でoutputモードを変更できます。

outputモードはjpterm終了時に標準出力にセットする値を指定します。
モードは三種類あります(expression,result,quiet）。

outputモードを切り替えるたびに、下、Status:欄にモードが表示されます

- Status: output mode set to expression <- 終了時にexpression を標準出力に渡す
- Status: output mode set to result <- 終了時にresult　を標準出力に渡す
- Status: output mode set to quiet　<- 終了時に標準出力に何も渡さない

## インストール時のエラーについて

2022年4月現在、Ubuntu 22.04に`pip install jmespath-terminal`でインストールしようとすると下記のエラーがでました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/ca9baa34-990d-3a98-21f4-e3e71b89ef92.png)

下記にissueが出ていて。

[Urwid version #19](https://github.com/jmespath/jmespath.terminal/issues/19)

setuptoolsが58以上だとuse_2to3がサポートされていないのが原因のようです。
本記事では上記を参考にしてpip install 'setuptools<58'　で58より前のバージョンをインストールして回避しています。

## 総評

JMESPathを色々と試したい場合は、入力と結果が素早く確認できてわかりやすいかと思います。
40代おっさんJavaScriptのクロージャーを学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## クロージャー

クロージャーとは
レキシカルスコープの変数を関数が使用している状態

```javascript
function fn1() {
    let b = 1;
    function fn2() {
        console.log(b);
    }
    fn2();
}
fn1();
```

このようにfn2から外側のfn1のlet bを呼び出している状態

これを使って以下の関数を作ることができる

### プライベート変数の定義

例えば

```javascript
let num = 0;

increment();
increment();
increment();

function increment() {

    num = num + 1;
    console.log(num);
}
```

これのログを見ると1,2,3となっていると思いますが

```javascript
let num = 0;

increment();
increment();
increment();

function increment() {

    num = num + 1;
    console.log(num);
}

num = 0;

increment();
```

としてしまうとnumが初期化しまいます
このようにならないように、内部で変数を持って外部からアクセスできないようにする方法をクロージャーを用いてやってみます。

```javascript
function incrementFactory() {
    let num = 0;
    function increment() {
        num = num + 1;
        console.log(num);
    }

    return increment;
}

const increment = incrementFactory();

increment();
increment();
increment();
```

このようなコードにすることによりnumは外部から操作できないことになります
const increment = incrementFactory();
が実行されたときのみにnumが初期化されます。
その後は
increment();
が呼び出されたも
return increment;
の戻り値が呼び出される仕組み

### 動的な関数の生成

例えばこのようなコードがあります

```javascript
function addNumberFactory(num) {
    function addNumber(value) {
        return num + value;
    }
    return addNumber;
}

const add5 = addNumberFactory(5);
const result = add5(10);
console.log(result);
```

これはaddNumberFactory(5);
numには5の値が渡っています
その後戻り値でaddNumberに戻るため
add5はnumに5が設定されている関数になる
add5(10)でvalueに10が渡されるため合わせてログに15が出てくることになる

このように渡される値によって生成される関数が変わってくるので動的は関数の生成と呼ぶことができる

## 参考資料

<https://www.udemy.com/course/javascript-essence/>
40代おっさんJavaScriptのスコープを学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## スコープとは

実行中のコードから値と式が参照できる範囲
JavaScriptにおけるスコープとは、変数がどの場所から参照できるのかを定義する概念

### 5種類のスコープ

#### グローバルスコープ

・プログラムのトップレベルで宣言された変数は、グローバル変数となり、プログラム全体のどこからでもアクセス可能なグローバルスコープ

・varやfunctionで値を保持するとWindowで値が保持される
これがグローバルスコープになる

#### スクリプトスコープ

一般的にはスクリプトスコープもグローバルスコープと呼ばれる
letで値を保持するとScopeで保持される
もし同じ変数があったとして、varとletに格納すると優先されるのはletである
そのためグローバルスコープとスクリプトスコープでは少し違いがある

#### 関数スコープ

```javascript
function a() {

}
```

上の関数の{}の部分を指す

関数内で宣言された変数は関数外で呼び出すとエラーになる

#### ブロックスコープ

```javascript
{

}
```

関数宣言がない{}の部分を指す

条件があり、変数を宣言する場合はlet,constを使用
varを使うとブロックが無視される
またブロック内で関数を宣言してもブロックは無視される

※if,for文の時に使用、その時にvar,関数を使うと意図としない動きになるので注意！！

#### モジュールスコープ

こちらはモジュールを勉強時に説明します

## レキシカルスコープ

レキシカルとは
語彙の、辞書（編集）の、辞書的な

プログラム的なレキシカルとは
プログラムの文脈ではソースコードのどこに何を書いているかという意味

レキシカルスコープとは
コードを書く場所によって参照できる変数が変わるスコープのこと

コードを記述した時点で決定するため「静的スコープ」ともいう

実行中のコードから見た外部スコープのこと
どのようにしてスコープを決定するかの仕様のこと

## スコープチェーン

スコープチェーンとは
スコープが複数階層で、連なっている状態

```javascript
let a = 2;
window.a = 4;
function fn1() {
    let a = 1;
    function fn2() {
        let a = 3;
        console.log(a);
    }
    fn2();
}
fn1();
```

このように複数階層になっており、また変数名が重複している場合は
内側の層から値を取ってくる
この場合は
a=3になる

特に気を付けないといけないのは

```javascript
let a = 2;
window.a = 4;
function fn1() {
    function fn2() {
        console.log(a);

        if(true) {
           var a = 3;
       }
    }
    fn2();
}
fn1();
```

外側のlet a = 2;
の値を取りたいのにvar a = 3;
同じ変数名を定義してまって値を取ると
undefinedになってしまいエラーにすらならないのでコードが実行されてしまう

## 参考資料

<https://www.udemy.com/course/javascript-essence/>
何かを自作するまでの道のりを此処に示す．

昔からアニメが好きですが，自分自身で何か作ったことはありません．
美術的なセンスも勉強も工作も苦手ですが，一度くらい自分で何かを成し遂げてみたいと思い，
Qiitaで少しずつ勉強の進捗を書けたらいいなと思い投稿してみました．

見切り発車であり，不定期であるため，勉強した事を書いて少しずつ構築できたらいいなと思います．