OmniAICreator/Qiita-1.07M huggingface dataset:
【WSL2】データ領域（vhdx）を圧縮する

## 概要
WSL2（Windows Subsystem for Linux 2）を使って開発をしていると、Windows上でLinuxのファイルシステムを管理するvhdxファイルが肥大化していきます。放っておくと40GBとか超えちゃう上に、内部のファイルを掃除しても自動で縮小してくれないので、定期的にダイエット操作をしましょう。

Dockerリソースの削除を伴うので、場合により環境建て直しになっても困らないような、暇なときにやりましょう。

## あらかじめDocker絡みのダイエットを行う
[【Docker】いろいろpruneしてストレージを掃除する](https://qiita.com/Shimooo_mutenka/items/0404143a958ea27600f3)にしたがって、Dockerリソースの削除を実行しておきます。

## WSLを停止する
管理者として実行したPowershellで`wsl --shutdown`を実行します。

## vhdxファイルの在処を確認する
ユーザー毎のフォルダ配下、Appdata内にあるようです。手元のPCでは`C:\Users\<username>\AppData\Local\Docker\wsl\data`でした。Appdataフォルダはエクスプローラで隠しファイルを表示するよう設定していないと見えないので、適宜設定してください。

## diskpartで圧縮
Powershellで`diskpart`を実行して、diskpartのプロンプトを開きます。

diskpartで、以下の通り実行します。vdisk云々は、Windowsの仮想ディスク（vhd/vhdx）をローカルシステムにマウントして操作できるコマンドです。
```bash
select vdisk file="C:\Users\<username>\AppData\Local\Docker\wsl\dataext4.vhdx" # 実際にファイルがあるところに読み換えてね
attach vdisk readonly
compact vdisk # 圧縮が走る
detach vdisk
exit
```

ここまで実行したら、vhdxファイルが圧縮されているはず。今回、手順を記録しながら実施した結果、vhdxファイルのサイズは43GB→11GBになりました。
React19でuseを使うとAn unsupported type was passed to use(): async functionエラーが出る

# はじめに

React19を使い始めてエラーがでたのでまとめておきます

# 問題

以下のようなコードを書いたところエラーになりました。

```tsx
async function fetchManageBook() {
  const response = await fetch("http://localhost:8080/books");
  const data = (await response.json()) as BookManageJson[];

  return data.map((book) => {
    return new BookManage(book.id, book.name, book.status);
  });
}

function App() {
  const books = use(fetchManageBook());

}
```

```
async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.
```

# 解決方法

Promiseを返すということはできているのですが、肝心なのはReactはクライアントコンポーネントということです。

クライアントコンポーネント内では`async関数`は`useEffect`の中で実行しないと再レンダリングや複数コンポーネントでの実行などで何度も実行されてしまい「コンポーネントの実行は予測可能で一貫性のある結果を返す」という原則を守れなくなってしまいます。

簡単に言うとuseはレンダリングフェーズで作成されるPromiseに対応していません。

```tsx
async function fetchManageBook() {
  const response = await fetch("http://localhost:8080/books");
  const data = (await response.json()) as BookManageJson[];

  return data.map((book) => {
    return new BookManage(book.id, book.name, book.status);
  });
}

const fetchManageBookPromise = fetchManageBook();

function App() {
  const books = use(fetchManageBookPromise);

}
```

このように1度だけPromise関数を作成して実行すれば動くようになりました。

# おわりに

すこしReactの考え方が理解できた気がします。

# 参考

https://dev.to/onthecodenow/como-consumir-una-api-con-react-19-use-suspense-2hda
【WSL2】Ubuntuディストリビューションのユーザーがsudoできるようにする

## 概要
Linuxでは、セキュリティ上の理由からrootユーザーでの直接的な操作を避け、sudoコマンドを使用して必要な時だけ管理者権限で実行することが推奨されています。

ところが、WSL2のUbuntu 22.04環境では、ユーザーがsudo権限を持っていない場合があります。これにより、パッケージのインストールや重要なシステム設定の変更など、管理者権限の必要な操作ができなくなります。

ここでは事例として、ubuntuユーザーにsudo権限を付与する手順を記載します。ユーザー名はお手元の環境に応じて適宜読み替えてください。

注：以下2つのアプローチでも解消できますが、今回はとりあえず今のWSL2環境やユーザー構成を維持して解決する手順として記載します。
1. WSL2インストール時にrootパスワードを設定
1. 新規管理者ユーザーの作成

## 背景
WSL2で以下のコマンドをubuntuユーザーにて実行したら、以下権限エラーが出て、パッケージをインストールできませんでした。
```bash
sudo apt-get install keychain # WSL2へのパッケージの追加を試みた
# sudo 権限が無いらしい。
# ubuntu is not in the sudoers file. This incident will be reported.
```

### sudo できるようにする手順
WSL2の再起動を伴うので、作業途中のものは保存するなど、お片付けをしておきましょう。

#### PowerShellからWSLのubuntuユーザーに権限を与える
##### 管理者として実行したPowerShellからWSL2のrootシェルを起動する
Windows側の操作で、PowerShellを管理者として実行し、以下の通りコマンド実行します。rootユーザーにパスワードを設定していないと、WSL2の中からではrootとしてサインインできません。なので、PowerShell側から`wsl -u root`をやっています。
```powershell
# rootユーザーとしてWSL2にサインイン
# 規定のWSL2ディストリビューション以外にサインインする場合は、ディストリビューションを指定する引数が必要
wsl -u root
# Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.146.1-microsoft-standard-WSL2 x86_64) 
# と表示されれば成功
```

##### WSLのrootシェルで、ubuntuユーザーをsudoグループのメンバーとして追加する
PowerShell上でWSL2へログインした状態になるので、以下のコマンドを実行します。

```bash
# WSLのrootシェル上で実行
usermod -aG sudo ubuntu
exit  # rootシェルを終了 logout と表示されるはず
```

##### WSL2を再起動する
```powershell
# PowerShell上で実行
wsl --shutdown
```

#### sudoを使ってコマンド実行する
WSL2へ再度サインインします。通らなかった以下のsudoコマンドが、再度ubuntuユーザーで実行すると通るようになっています。
```bash
# 管理者として実行したい任意のコマンドで読み替えてください
sudo apt-get install keychain
```

#### （もし発生してれば）Docker Desktopの設定を復旧してマシン再起動する
今回の実行内容に直接関連があるか不明ですが、手元の環境ではDocker DesktopにおけるWSL2ディストリビューションの設定が無効になっていました。これを復帰させないとWSL2でDockerが利用できないので、再度Ubuntuを有効にして、PC再起動を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906608/cae1330d-145d-3067-88b4-3a4c6f5521e9.png)
Genesisをubuntu24.04で動かす手順

# はじめに

しゅんです
新年明けましておめでとうございます。2025年、皆さまどうぞよろしくお願いします。  
去年の年末から巷で話題になっている「Genesis」を、Ubuntu 24.04で動かしてみました。結果としてはスムーズにインストール成功。GPUもご機嫌でした。せっかくなので、その手順をざっくり共有します。

## GPUスペック
- RTX 3080 VRAM 8GB

他のプロジェクトでも「お正月休みを返してくれ！」とGPUが叫ぶくらい酷使してみたけど、なんとか動いたので安心です。（自分も休みが欲しい）

## 本題の手順

### 1. 作業ディレクトリを作る
```
mkdir Gensis
cd Genesis
```
スペルミスではなく、オリジナリティを演出してみました（ウソです）。

### 2. 仮想環境を作成＆入る
```
python3 -m vemv .venv
source .venv/bin/activate
```
Ubuntu 24.04ではシステム全体に`pip`を入れにくくなっているので、仮想環境をフル活用。  
何度もPyTorchやら何やらをインストールする必要があるのは年始早々ちょっと面倒ですが、そこは根性で乗り切りましょう。

### 3. CUDAのインストール確認
CUDAインストール方法はここでは省略。インストールできたかどうかは以下で要チェック。  
```
python3
```
```python
import torch

def check_gpu_status():
    if torch.cuda.is_available():
        print("GPU is available!")
        print(f"Number of GPUs available: {torch.cuda.device_count()}")
        print(f"Current GPU: {torch.cuda.get_device_name(torch.cuda.current_device())}")
    else:
        print("GPU is not available.")

if __name__ == "__main__":
    check_gpu_status()
```
「GPU is available!」が出たら安心してお年玉を使い切りましょう。（自分はないけど）

### 4. Genesis-worldのインストール
```
pip install genesis-world
```
あれこれと依存関係で警告が出るかもしれませんが、今年の運勢が良ければ問題なしです。

### 5. リポジトリをclone
```
git clone https://github.com/Genesis-Embodied-AI/Genesis.git
```
あとは[hEnkaさんの記事](https://qiita.com/hEnka/items/cc5fd872eb0bf7cd3abc)をそのまま参考に、好きなようにカスタムしてみてください。

## 終わりに

***なにか詰まったときは、「正月にやったことは忘れる」という格言を思い出して一呼吸。  
この記事が皆さんのGenesisライフのスタートダッシュに役立てば幸いです。by GPT***

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Ubuntu24.04 Genesis起動できた <a href="https://t.co/9NHcGvD7d4">pic.twitter.com/9NHcGvD7d4</a></p>&mdash; SYUN (@syun88AI) <a href="https://twitter.com/syun88AI/status/1874394524245746138?ref_src=twsrc%5Etfw">January 1, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 


**今年もどうぞよろしくお願いいたします。**
flaskでシンプルな掲示板を実装した

実際に動かしてみるとこんな感じ
![post.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527465/3f8e46e2-031d-4923-2dff-dfe5a54fb097.png)
## app.py
```app.py
from flask import Flask, render_template, request

app = Flask(__name__)

posts = []
    
@app.route("/", methods = ["GET", "POST"])
def index():
    if request.method == "POST":
        new_post_data = {
                "name": request.form["name"],
                "text": request.form["text"],
        }
        posts.append(new_post_data)
    return render_template("index.html", posts = posts)
app.run()
```
/はGETとPOSTを受け付ける POSTが送られた場合は連想配列new_post_dataに投稿者の名前と投稿内容を格納する その後配列postsに格納する

関数の最後はrender_templateでindex.htmlを返して配列postsを渡す

## templates/index.html
```templates/index.html
<html>
	<body>
		{% for x in posts%}
		<p>name: {{ x["name"] }}</p>
		<p>text: {{ x["text"] }}</p>
		{% endfor %}
		<form action="/" method="post">
			<input name="name" type="name">
			<br>
			<textarea name="text">
			</textarea>
			<button type="submit">
		</form>
	</body>
</html>
```
前述の渡された配列postsをfor文で描画する 名前と投稿内容を連想配列から取り出して描画している

formタグで投稿フォームを作っている buttonタグをクリックすると投稿される

## postメソッドとは(MDNより引用)

HTTP の POST メソッドは、サーバーにデータを送信します。リクエストの本文の型は Content-Type ヘッダーで示されます。

PUT と POST との違いは、 PUT がべき等であることです。一度呼び出しても複数回呼び出しても成功すれば同じ効果になる（副作用がない）のに対して、同じ POST に成功すると、複数回の注文を行うような、追加の効果が出ます。

POST リクエストは、ふつう HTML フォームを介して送信され、サーバーに変化をもたらします。この場合、<form> 要素の enctype 属性や<input> または <button> 要素の formenctype 属性に適切な文字列が指定することで、コンテンツタイプを選択することができます。
引用元: https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/POST
参考
https://www.geeksforgeeks.org/flask-http-methods-handle-get-post-requests/
!を使って真偽値を反転させる

# !を先頭につけると真偽値は反転する
```rb
irb(main):007> t1 = true
=> true
irb(main):008> f1 = false
=> false
irb(main):009> !t1
=> false
irb(main):010> !f1
=> true
```
```rb
irb(main):011> t1 && f1
=> false
irb(main):012> !(t1 && f1)
=> true
irb(main):013> (t1 && f1)
=> false
```
https://gihyo.jp/book/2017/978-4-7741-9397-7
アプリのバージョンルール - version: X.Y.Z+N の意味を理解する

## はじめに

個人アプリを開発していて、ふとバージョンの正しい付け方ってなんだっけ？となったのでメモとして残します。

ちなみに、
アプリは Flutter で開発しており、pubspec.yaml に該当のバージョンを書いてPackageInfo.fromPlatform()を使用してアプリのバージョン情報を取得してます。

```dart
showLicensePage(
  context: context,
  applicationName: packageInfo.appName,
  applicationVersion: '${packageInfo.version} (${packageInfo.buildNumber})',
);
```

それを、マイページのバージョンという項目に動的に表示されるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282990/1077656e-7cf9-4309-b764-229b6680c083.png)


## 本題

Flutterのバージョン番号は `version: X.Y.Z+N` の形式で、以下のような意味を持つ。

### セマンティックバージョニング (X.Y.Z)

- X (MAJOR)： 大きな変更をした時
- Y (MINOR)： 機能追加をした時
- Z (PATCH)： バグ修正をした時

### ビルド番号 (+N)

- 毎回のリリース時に1ずつ増やす
- ストアへの再アップロード時は必ずビルド番号を増やす必要がある（同じ番号では再アップロードできない）
- アプリの内部バージョンとして使用

### 例

```markdown
# 初回リリース
version: 1.0.0+1

# バグ修正リリース
version: 1.0.1+2

# 新機能追加
version: 1.1.0+3

# 大きな変更
version: 2.0.0+4
```

以上。
picoCTF 2022 writeup basic-file-exploit

## basic-file-exploit (Binary exploitation)

The program provided allows you to write to a file and read what you wrote from it. Try playing around with it and see if you can break it!  
The program's source code with the flag redacted can be downloaded here.  
Connect to the program with netcat:  
`$ nc saturn.picoctf.net 59093`

添付ファイル
・program-redacted.c

とりあえず、実行してみる。
```
$ nc saturn.picoctf.net 59093
Hi, welcome to my echo chamber!
Type '1' to enter a phrase into our database
Type '2' to echo a phrase in our database
Type '3' to exit the program
1
1
Please enter your data:
%x%x%x%x
%x%x%x%x
Please enter the length of your data:
8
8
Your entry number is: 1
Write successful, would you like to do anything else?
2
2
Please enter the entry number of your data:
0
0
picoCTF{M4K3_5UR3_70_CH3CK_Y0UR_1NPU75_E0394EC0}
```
フラグが出てきてしまった。

`picoCTF{M4K3_5UR3_70_CH3CK_Y0UR_1NPU75_E0394EC0}`

ちなみに、最初に選択肢1を選び、何らかの文字を入力した後、2を選んで`Please enter the entry number of your data:`のところで`0`を入力すれば、フラグが出力できる。
【PowerShell】特定のTCPポートをLISTENING状態にして占有する

 `listener.Start()`が走っている間、指定したTCPポートを占有できる。これは、特定のアプリケーションが使用する予定のポートを予め占有し、そのアプリケーションの起動時の挙動を確認するのに役立つ。
 ```powershell
 # 0.0.0.0:8080 どのネットワークインターフェースからの接続でも受け入れる
$listener = [System.Net.Sockets.TcpListener]8080 $listener.Start()
# 127.0.0.1:8080 ローカルマシン内からの接続のみを受け取る 基本的にlocalhostのポート占有を試したい場合はこっち
$listener = New-Object System.Net.Sockets.TcpListener('127.0.0.1', 8080) 
# リスニング開始
$listener.Start()

# リスニング終了
$listener.Stop()
 ```
【Linux】yt-dlp を使ってYouTubeなどの動画をダウンロードする 

# インストール for Linux

下記手順でインストールする。
```shell:
# yt-dlp のインストール
wget https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O ~/.local/bin/yt-dlp

# ファイルのパーミッション変更
chmod a+rx ~/.local/bin/yt-dlp

# ffmpeg のインストール(推奨)
sudo apt update
sudo apt install ffmpeg
```

```shell:
# アップデート
yt-dlp -U

# バージョン確認
yt-dlp --version
```
### 参考 - yt-dlp のインストール手順：

https://github.com/yt-dlp/yt-dlp/wiki/Installation

# 動画ダウンロード方法

コマンドの後ろにURLを指定するだけ。
特にオプションを指定しなければ、最高画質で保存される。

```shell:
# 動画はカレントディレクトリに保存される
yt-dlp https://www.youtube.com/watch?v=XXXXXXXXXXX
```

# yt-dlpで動画がダウンロードできるサイト

https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md
アンサンブル学習

# アンサンブル学習
アンサンブル学習(Ensemble Learning)とは、弱い機械学習モデルを組み合わせて精度の高いモデルを構成する学習手法のことで、音楽用語で二人以上が同時に演奏することを「アンサンブル」というところから名付けられているそうです。

# アンサンブル学習の種類
このアンサンブル学習には、「バギング」「ブースティング」「スタッキング」の主に３種類が存在し、それぞれの違いを説明するためには「バイアス」と「バリアンス」が重要となります。

|名前|説明|
|---|---|
|バイアス（Bias）|予測が実際の値からどれくらいズレているかを表す指標|
|分散（Variance）|予測がどれくらい変動するかを示す指標|

バイアスと分散はトレードオフの関係となっており、バイアスが高いと訓練不足によってモデルの予測精度が低くなっているとみなされ、分散が高いと過学習によって予測精度がばらついているとみなされます。そのため、両方の指標が低くなっていることが望ましいです。

### バギング
バギングとは、ブートストラップ集約法(bootstrap aggregating)の略で、ランダムに複数の学習データから選んだデータを使って学習器を作成し、学習で得た結果を全て集めて最終決定を行います。学習データの多様性などを考えながらモデルを構築するため、モデルの予測結果のバリアンスを低くすることができます。

### ブースティング
ブースティングとは、弱い学習器を次々に学習させて最終的に高い精度の学習器を作成します。過去の学習の誤差・誤りに注目し、その誤差を修正を次々に行うため、モデルの予測精度に対してバイアスを下げることができます。

### スタッキング
スタッキングとは、二段階以上の複数の学習器を組み合わせて高い精度の学習器を作成します。上手く利用することで、バイアスとバリアンスをバランスよく調整することができます。
Go言語(プログラミング)入門メモ①

# 変数の作り方
## 変数の宣言
変数を宣言するにはvarを使う。varのあとに変数名、変数の型と続ける。さらに初期化も行いたいときは=と代入したい値を入れる
~~~
var i int = 1
~~~
複数の変数を宣言したいときはvarのあとに()で囲って宣言を行う
~~~
var(
    i int 
    f64 float64
    s string
)
~~~

短縮変数宣言、ということもできる。変数名と値を:=でつなげることで行うことができる。ただし、この場合変数の型は自動で判別される。
~~~
xi := 1
xf := 1.2
~~~

### (注意)変数の宣言として、varを使う場合は関数の外でも宣言ができて、複数の関数から呼び出すことができるが、短縮変数宣言の場合は関数内での宣言しか行えない。

## 定数の宣言
定数の宣言はconstを使用して行うことができる。constで宣言した値はあとから変更することができないため、宣言時に初期化を同時に行う。また、基本的に関数外で宣言を行う。
~~~
const Pi = 3.14
~~~

## データ構造
### 配列
配列もvarを使って宣言する。配列名[要素数]データ型、という形で宣言する。
int型の要素を2つもつaという配列を宣言し、0番目と1番目に値を代入したい場合は以下のようにする。
~~~
var a　[2]int
[0] = 100
[1] = 200
~~~
また、宣言時に値を代入する場合は以下のように行う。
~~~
a := [2]int{100,200}
~~~
## スライス
スライスを宣言する場合も配列の宣言と大して変わらない。[]内に要素数を入れないだけ
~~~
n := []int{1,2,3,4,5}
~~~
スライス内の要素を書き換えるには、スライス名[書き換えたい要素のインデックス]で行う。
~~~
n[2] = 100
//これによりnの中身は{1,2,100,4,5}となる
~~~
## 要素を追加したいとき
スライスに要素を追加したいときはappendを使用する。
第一引数に対象のスライス、第二引数に追加したい値をいれる。また、追加したい値を,で区切って同時に追加することもできる。
~~~
append(n,100)
//nの中身は{1,2,100,4,5,100}となる。
append(n,200,300)
//nの中身は{1,2,100,4,5,200,300}となる
~~~
## make関数
make関数を使用することで要素の値が0で初期化されたスライスを作ることができる。例えば、要素数3,容量5のスライスnを作りたいときは以下のように行う。
~~~
n := make ([]int,3,5)
//nは[0,0,0]
~~~
※容量とは？
容量とは、スライスが占有する内部配列のサイズのことで、スライスの要素数が len（長さ）を超えるときに新しいメモリ割り当てが発生するのを防ぐためのもの。
容量を指定することで、スライスが拡張されるたびに新しいメモリ割り当てとコピーが発生するコストを減らすことができる。
AIに聞いたところ、一々容量を決定するようにすると具体的に以下のコストが発生する。なるほど。
スライスがその現在の容量を超えて拡張されると、新しいより大きな配列が作成され、その既存の要素が新しい配列にコピーされます。これには以下のようなコストが伴います：

新しいメモリの割り当て: 新しい配列を作成するために追加のメモリが必要です。

要素のコピー: 既存の要素を新しい配列にコピーする必要があります。これが大きなスライスの場合、コピー操作に時間がかかることがあります。

ガベージコレクション: 古い配列はもはや使用されなくなるため、ガベージコレクションが発生し、システムリソースの負荷となることがあります。

作成したスライスに要素を追加する。
~~~
append(n,0,0)
//nは[0,0,0,0,0]となる
append(n,100,200,300)
//このときnは[0,0,0,0,0,100,200,300]となる。また、容量は設定した5を超えている。このようなときは一般的に現在の容量の2倍になる。(追加する要素の数次第だが)
~~~
## Map
mapはキーとバリューの組み合わせをまとめることのできるデータ構造。
map[キーのデータ型]値のデータ型{キー1:値1,キー2:値2,…}という形で宣言できる。
~~~
m := map[string]int{"apple":100,"orange":200}
//この時点でmap mの中身は以下
map[apple:100 orange:200]
~~~
要素の書き換え方法は以下
~~~
m["orange"] = 300
//これによりmap mの中身は以下のようになる
map[apple:100 orange:300]
~~~
要素の追加方法は以下
~~~
m["banana"] = 500
//これによりmap mの中身は以下のようになる
map[apple:100 orange:300 banana:500]
~~~


## 学習に使用した教材
・『入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』M.A EduTech
https://www.udemy.com/course/golang-webgosql/?utm_medium=udemyads&utm_source=bene-msa&utm_campaign=responsive&utm_content=top-1&utm_term=general&msclkid=81e2f24a32cc185d275d953d60760226&couponCode=NEWYEARCAREERJP

・『シリコンバレー一流プログラマーが教える Goプロフェッショナル大全』酒井 潤 (著)
https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E4%B8%80%E6%B5%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B-Go%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%A4%A7%E5%85%A8-%E9%85%92%E4%BA%95-%E6%BD%A4/dp/4046070897
AWS Amplifyのビルドでシークレットを取得する方法

## 問題

[AWS公式ブログ](https://aws.amazon.com/jp/blogs/news/accessing-resources-in-a-amazon-virtual-private-cloud-amazon-vpc-from-next-js-api-routes/)に記載されている以下の実装例では、 `amplify.yml` にて `$secrets` で保存したシークレットが取得できる、とされています。

```amplify.yml
version: 1

frontend:
  phases:
    preBuild:
      commands:
        - yum -y install jq
        - jq --version
        - npm ci
    build:
      commands:
        - echo $secrets | jq -r 'to_entries|map("\(.key)=\(.value)")|.[]' >> .env
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - "**/*"
  cache:
    paths:
      - node_modules/**/*

```

しかし、実際に `echo $secrets` や `env` で確認しても、中身は空です（`secrets` 変数自体は存在するようです）。

GitHubの[issue](https://github.com/aws-amplify/amplify-hosting/issues/3348)でも同様の問題が提起されており、サービスロールの権限の問題と指摘されていますが、自分はすべての権限を付与しても解決しませんでした。

なお、試した際の `aws-amplify` のバージョンは `6.11.0` です。

## 解決策

### 実装

以下のように直接 `aws ssm` コマンドを叩くと、シークレット値を取得できます。

```amplify.yml
version: 1
backend:
  # 省略
frontend:
  phases:
    build:
      commands:
        - SOME_SECRET_1=$(aws ssm get-parameter --name "/amplify/shared/${AWS_APP_ID}/SOME_SECRET_1" --with-decryption --query "Parameter.Value" --output text 2>/dev/null || aws ssm get-parameter --name "/amplify/${AWS_APP_ID}/${AWS_BRANCH}/SOME_SECRET_1" --with-decryption --query "Parameter.Value" --output text)
        - echo "SOME_SECRET_1=$SOME_SECRET_1" >> .env.production
        - SOME_SECRET_2=$(aws ssm get-parameter --name "/amplify/shared/${AWS_APP_ID}/SOME_SECRET_2" --with-decryption --query "Parameter.Value" --output text 2>/dev/null || aws ssm get-parameter --name "/amplify/${AWS_APP_ID}/${AWS_BRANCH}/SOME_SECRET_2" --with-decryption --query "Parameter.Value" --output text)
        - echo "SOME_SECRET_2=$SOME_SECRET_2" >> .env.production
        - npm run build
  # 以下省略

```

### 解説

[Amplifyドキュメント](https://docs.amplify.aws/nextjs/deploy-and-host/fullstack-branching/secrets-and-vars/)にあるように、全ブランチ共通のシークレットは `/amplify/shared/<app-id>/<secret-key>` に保存され、ブランチ固有のシークレットは `/amplify/<app-id>/<branchname>/<secret-key>` に保存されます。

上記の実装では、最初に全ブランチ共通のシークレットから取得し、なければブランチ固有のシークレットから取得するようにしています。

ここでは `build` フェーズで取得しましたが、 `prebuild` で取得したほうがいいかもしれません。

## おわりに

AWS公式ブログ通りに実装しても取得できないのは不思議です。
自分が何か勘違いしているだけかもしれないので、他に解決策があればぜひコメントで情報を共有してください。
アドベントカレンダー7日目

# 6つ目　睡眠の環境チェッカー
　6つ目は、睡眠の環境チェッカーです。

 # きっかけ
 　睡眠は生きていくためには必要不可欠であり、徹夜の場合は脳の機能が著しく低下します。だが、睡眠の質が悪い場合もストレスの耐性が下がったり、日中の怠さや倦怠感に繋がったりしてしまいます。寝ているはずなのに体が休めていない状態だと、日常生活に支障をきたしたりしてしまう可能性もあります。私もその経験があるため、眠りの質を高めるために自身で出来ることはやるようにしています。
　これを解決するためにはどうしたらいいかを考えたときに、部屋の温度や明るさ、煩さ、それぞれに反応して違う音のアラームを鳴らし、Microbitにマークを変えてそれぞれ表示をしてくれるシステムを作ろうと考えました。
　3つの項目にしたのは、それぞれ理由があります。睡眠時に温度が低すぎると、体温維持のため皮膚から熱が逃がしにくくなり、逆に高すぎると外気に熱を逃がしにくくなります。部屋が明るすぎると、快適な睡眠に必要なメラトニンの分泌が抑えられ、不眠や生活リズムが崩れてしまいます。周りが煩すぎると、中途覚醒や浅い睡眠になってしまい、これを繰り返してしまうと自律神経が乱れ体調不良の原因になってしまうからです。

# 実際に作ってみる
　今回使用したのは、microbitです。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924203/8494a02f-e7ee-d714-7e96-3967c894cfcb.png)

# プログラム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924203/d8c24d19-b493-369e-2cb9-71e8af7b40e1.png)

# 結果
　それぞれの範囲外では、きちんと写真のように変化することが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924203/2745fe20-284a-17ae-5a86-0b879fd0f83b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924203/5d396d26-f282-48a2-be56-175aefb8f151.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924203/6a6c2942-337e-e911-e686-911507e2fa7f.png)

# 反省点
　布団の中の温度と外の温度では差が生まれてしまうため、改善するには温度を測れるセンサーを取り付け、センサーを布団の中にいれ、それ以外を外に出すことで解決できるのではないかと思いました。
AWSで所望のタグの付いたリソースを探す方法

# はじめに

以前に[AWS CLIで所望のEC2インスタンスを探す方法](https://qiita.com/nkojima/items/bae2d3cc075d09501be1)という記事で`ec2 describe-instances`コマンドを紹介しましたが、これはあくまでもEC2インスタンスを検索するためのコマンドとなります。

今回はEC2に限らず、AWSアカウント内の全リソースから「所望のタグの付いたリソース」を探す方法を記事としてまとめてみました。

# 概要

* AWS CLIの`resourcegroupstaggingapi`の`get-resources`コマンドを利用します。
* AWS CLI上で複数の認証情報（プロファイル）を利用している場合、以下のいずれかの方法で利用するプロファイルを切り替えておきます。
  * 事前に`~/.aws/config`ファイル中の`default`を開いて、所望のAWSアカウントの情報に書き換える。
  * `get-resources`コマンド実行時に`-profile {configファイル中の所望のプロファイル名}`とオプションを追加して、所望のAWSアカウントを指定する。

# 実行するコマンド

* `--tag-filters`オプションを指定することで、所望のタグの付いたリソースを探すことが出来ます。
  * 「タグの値」はカンマ区切りで複数指定できるようです。
* ここでのバッククォート（`）はPowerShellの文法によるもので、AWS CLIのコマンドとは全く関係ありません。
  * 「行末にバッククォートを入れると改行文字を無視して複数行にコマンドを記述することができる」という機能を利用して、コマンドを少し見やすくしています。
  

```powershell:コマンドの基本形
aws resourcegroupstaggingapi get-resources `
--tag-filters Key={タグ名},Values={タグの値} `
```

* 以下のように`--profile`オプションを指定すれば、所望のAWSアカウントを指定した上でリソースを探すことが可能です。

```powershell:profileを指定したコマンド
aws resourcegroupstaggingapi get-resources `
--tag-filters Key={タグ名},Values={タグの値} `
--profile {configのプロファイル名}
```

* `--region`オプションを指定すれば、所望のリージョンに絞り込んだ上でリソースを探すことが可能です。

```powershell:regionを指定したコマンド
aws resourcegroupstaggingapi get-resources `
--tag-filters Key={タグ名},Values={タグの値} `
--region {リージョン名}
```

# 参考URL

* [AWS CLIで所望のEC2インスタンスを探す方法](https://qiita.com/nkojima/items/bae2d3cc075d09501be1)
* [resourcegroupstaggingapi](https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/)
  * [get-resourcesコマンド](https://docs.aws.amazon.com/cli/latest/reference/resourcegroupstaggingapi/get-resources.html)
QtのCMakeからWindouse向けのビルドまでの流れ

まず、Qtをダウンロードします。

https://www.qt.io/download-qt-installer-oss

ここからダウンロードすれば、会社名などを入力する手間がないです。
そしたらインストーラーをお好みで進めてください。

srcフォルダーを作ったらその中身にソースコードを入れてください。

次はCMakeListsです。
```C:CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

list(APPEND CMAKE_PREFIX_PATH "C:/Qt/6.8.1/mingw_64/lib/cmake")

project(Philia VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
qt_standard_project_setup()

add_subdirectory(src)

target_link_libraries(Philia PRIVATE Qt6::Widgets)

set_target_properties(Philia PROPERTIES
    WIN32_EXECUTABLE ON
    MACOSX_BUNDLE ON
)
```
まず、CMAKE_PREFIX_PATHが必要です。
```CMAKE_PREFIX_PATH```は、qtのインストール先の
```lib/cmake```です。
次にパッケージを探します。
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
```Core```は必須です。
次に```qt_standard_project_setup()```
を実行します。
最後に```target_link_libraries(Philia PRIVATE Qt6::Widgets)```を追加します。

次にbatファイルを作ります。
```bat:build_win.bat
set QT_PATH=C:/Qt/6.8.1/mingw_64
set QT_TOOL_PATH=C:/Qt/Tools
%QT_TOOL_PATH%\CMake_64\bin\cmake.exe . -G "Ninja" -B Build  "-DQT_QMAKE_EXECUTABLE:FILEPATH=%QT_PATH%/bin/qmake.exe" "-DCMAKE_PREFIX_PATH:FILEPATH=%QT_PATH%/mingw_64" "-DCMAKE_C_COMPILER:FILEPATH=C:/Qt/Tools/mingw1310_64/bin/gcc.exe" "-DCMAKE_CXX_COMPILER:FILEPATH=%QT_TOOL_PATH%/mingw1310_64/bin/g++.exe" "-DCMAKE_GENERATOR:STRING=Ninja"
cd Build
ninja
%QT_PATH%/bin/windeployqt.exe .
pause
```
こんな感じで作ります。
ここはもうコピペでも良いです。
ここの、```QT_PATH```と```QT_TOOL_PATH```は、各自のパスにすればよいです。

流れを説明すると、Qt内のcmakeをNinjaで行うようにし、Buildフォルダー内に中身を入れるようにしています。その後に、Qt独自のフラグを設定しています。
その後、Buildフォルダーに行きninjaを直接実行し、windeployqt.exeをしようしてdll類をコピーしています。

https://doc.qt.io/qt-6/windows-deployment.html
PythonをWindowsで学習するための準備

# 記載の目的
一度実施すると、忘れてしまうので、メモを残す！

# Pythonをインストールする
https://www.python.org/downloads/
下のほう

※インストール時にパスを追加するのを忘れずに！
　「Add pthon.exe to PATH」をチェック！


# Pythonがインストールされたことの確認する
```
PS C:\Users> python --version
Python 3.11.1
```

# 学習用フォルダの作成する
```
PS C:\Users> mkdir test
PS C:\Users> cd test
PS C:\Users\test> 
```


# PowerShellの実行ポリシーを設定する
```
PS C:\Users\test> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
```

# envという名前のPythonの仮想環境を作成する
```
PS C:\Users\test> python -m venv env
```

# 仮想環境を有効化する
```
PS C:\Users\test> env/Scripts/Activate.ps1
(env) PS C:\Users\test> 
```


# 以下は仮想環境envで実施
## pipを最新化する
```
(env) PS C:\Users\test> python -m pip install --upgrade pip
```

## JupyterLabをインストールする
```
(env) PS C:\Users\test> pip install jupyterlab
```


## JupyterLabを起動する
```
(env) PS C:\Users\test> jupyter lab
```
Linux コマンドラインの基本操作

カーソルを一文字後ろに戻す

```
control + b
```

カーソルを一文字前に進める

```
control + f
```

カーソルを一番前に移動する

```
control + a
```

カーソルを一番後ろに移動する

```
control + e
```

単語単位で後方にカーソルを移動する

```
Meta + b

Esc を押した後 b
```

単語単位で前方にカーソルを移動する

```
Meta + f

Esc を押した後 f
```

カーソル一の後方一文字を削除する

```
BackSpace または control + h
```

カーソル位置の一文字を削除する

```
Delete または control + d
# 文字が何も打たれていない状態で control + d をするとログアウトされてしまうので注意
```

文字を単語単位で削除する

```
control + w
```

カーソル位置から行末までを削除する

```
control + k
```

カーソル位置から行頭までを削除する

```
control + u
```

最後に削除した文字列を入力する

```
control + y
```

画面のロック

```
control + s
# ロックした状態でも打ち込んだ文字列は受け入れられている
```

画面のロック解除

```
control + q
# control + s でロック中に入力した文字列、コマンドが実行される
```

実行中のコマンドを強制終了させる

```
control + c
```

画面を消去する

```
control + l
```

コマンドの補完機能を利用する

```

# 補完候補が一つの場合
利用したいコマンドを途中まで打ち込みむ + Tab

# 補完候補が複数ある場合
利用したいコマンド + Tabを2回押すとコマンドの候補が表示される
```

ひとつ前のコマンド履歴を参照する

```
cntrol + p
```

次のコマンド履歴を参照する

```
control + n
```

履歴を遡ってインクリメンタル検索する

```
control + r

# 検索結果をそのまま利用する場合は Enter
# 検索結果を修正する場合は Escを押す
# 検索結果を破棄する場合は control + g
```
SoraのRelaxed Modeを使ってみた

# 概要
Sora（OpenAIの動画生成AI）のRelaxed Modeでは、
動画をクレジット消費なしで生成できます。
肌間では、生成速度には10秒くらいしか差がないです。

# Relaxed Modeの紹介
### 機能
クレジット消費なしで動画を生成できる機能です。
クレジットを消費しきると、Proプランでこちらに自動で移行します。
※私は、2024年の年末年始限定で、Plusにも解放されていたこちらの機能で検証しました。

### 使ってみた肌感
生成が始まるまでの待ち時間は10秒ほど長くなりました。
一方、生成が始まってから生成完了まではクレジット消費時と特に変わらず、
その他の要素（解像度や秒数など）も特に変わらずです。

### 制限
クレジット消費では同時並行して生成できますが、Relaxed Modeでは同時に1つのみです。
また、生成できる動画の解像度や長さは、プランに依存します。
- Plusだと10s・780pまで
- Proだと20s・1080pまで　　※どちらも2025年1月時点

### 通常かかるクレジット
Plusプランでは、下記のクレジットがかかります。
例えば、780pで10sの動画をモリモリ作ってたら、16本でPlusプランの上限に達します。
また、Soraではクレジット追加購入はできません。

| 解像度       | 5s           | 10s          | 15s          | 20s          |
|--------------|--------------|--------------|--------------|--------------|
| 480p square  | 20 credits   | 40 credits   | 60 credits   | 80 credits   |
| 480p         | 25 credits   | 50 credits   | 100 credits  | 150 credits  |
| 720p square  | 30 credits   | 75 credits   | 150 credits  | 225 credits  |
| 720p         | 60 credits   | 180 credits  | 360 credits  | 540 credits  |
| 1080p square | 100 credits  | 300 credits  | 650 credits  | 1000 credits |
| 1080p        | 200 credits  | 600 credits  | 1300 credits | 2000 credits |

公式サイト：https://help.openai.com/en/articles/10245774-sora-billing-credits-faq#
【React】ポートフォリオサイト作成中に発生したエラーとその対処法

## はじめに
Reactを使ってポートフォリオサイトを作成しようとしていました。
参考にした動画は[こちら](https://www.youtube.com/watch?v=_TPaTndgBfc&t=267s)。
自分の学びと経験を発信することも兼ねて、今回直面したエラーとその対処方法を共有します。

## 発生した問題
「npx create-react-app」を使ってプロジェクトを初期化しようとした際、以下のエラーが発生しました。

```
Initialized a git repository.

Installing template dependencies using npm...
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: react-bootstrap-portfolio@0.1.0
npm error Found: react@19.0.0
npm error node_modules/react
npm error   react@"^19.0.0" from the root project
npm error
npm error Could not resolve dependency:
npm error peer react@"^18.0.0" from @testing-library/react@13.4.0
npm error node_modules/@testing-library/react
npm error   @testing-library/react@"^13.0.0" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
```

### エラーの内容
このエラーは、Reactと@testing-library/reactの間の依存関係のコンフリクトにより発生しているようでした。具体的には、プロジェクトがReactのバージョン19.0.0を要求している一方で、@testing-library/reactがバージョン18.0.0を期待しているためです。

## 対応策
以下の手順で問題を解決しました。

1. エラーを修正するために、以下のコマンドを実行しました。
   ```bash
   npm install web-vitals --save
   ```

2. 再度、プロジェクトの作成を試みました。

```bash
npx create-react-app react-bootstrap-portfolio
```

すると、また別のメッセージが表示されました。

```
The directory react-bootstrap-portfolio contains files that could conflict:

  node_modules/
  package-lock.json
  package.json
  public/
  src/

Either try using a new directory name, or remove the files listed above.
```

## 結果
・「npm start」を入力し起動しなおすと、画面が無事表示されました。
・これで良いのか不安も残りますがひとまず良しとします。

![スクリーンショット 2025-01-02 15.14.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288939/34164d39-838d-5506-7510-dd46f1a777b8.png)


## まとめ
今回直面したエラーは、依存関係のバージョン衝突によるものでした。reactを勉強し始めたばかりということもあり、バージョン周りのエラーでつまづくことが多く苦しんでします。この備忘録が他の人の助けになることを祈っております。

---
SwiftDataで@Queryを条件付き取得にする

`SwiftData`で`@Query`を使用してデータを取得する際に単純な全件取得ではなく、条件付きで取得したい場合に`#Predicate`を使用します。

公式ドキュメント
[Predicate | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/predicate)
# 全件取得の場合

```swift
import SwiftData
import SwiftUI

struct DailyTask {
    let date: Date
}

struct ContentView: View {
    @Query var dailyTasks: [DailyTask]
    
    var body: some View {
        VStack {
            ....
        }
    }
}
```

# 条件付き取得

実装例として「dateが今週のもの」を取得する処理を書いてみます

## 一旦公式ドキュメント通りに書いてみる

```swift
// 公式ドキュメントの実装例
let messagePredicate = #Predicate<Message> { message in
    message.length < 100 && message.sender == "Jeremy"
}

//　dateが今週のものを取得する 
let pridicateDailyTask = #Predicate<DailyTask> { dailyTask in
    let calendar = Calendar.current
    let now = Date()
    let startOfWeek = Calendar().date(from: Calendar().dateComponents([.yearForWeekOfYear, .weekOfYear], from: now))!
    let endOfWeek = Calendar().date(byAdding: .day, value: 6, to: startOfWeek)!
    return dailyTask.date >= startOfWeek && dailyTask.date <= endOfWeek
}
```

実際に書いてみると以下のエラーが表示されビルドが通りません。

```swift
Instance member 'pridicateDailyTask' cannot be used on type 'ContentView'; did you mean to use a value of this type instead?
```

## 解決策

`static`をつけると実行できました

```swift
import SwiftData
import SwiftUI

struct DailyTask {
    let date: Date
}

struct ContentView: View {
    // staticをつける！！
    static let pridicateDailyTask = #Predicate<DailyTask> { dailyTask in
        let calendar = Calendar.current
        let now = Date()
        let startOfWeek = Calendar().date(from: Calendar().dateComponents([.yearForWeekOfYear, .weekOfYear], from: now))!
        let endOfWeek = Calendar().date(byAdding: .day, value: 6, to: startOfWeek)!
        return dailyTask.date >= startOfWeek && dailyTask.date <= endOfWeek
    }
    
    @Query(filter: pridicateDailyTask) var dailyTasks: [DailyTask]
    
    var body: some View {
        VStack {
            ....
        }
    }
}
```

## functionで書きたい場合

引数で値を受け取りたかったり、可読性の観点からFunctionで書きたい場合はこんな感じです

```swift
import SwiftData
import SwiftUI

struct DailyTask {
    let date: Date
}

struct ContentView: View {	
    @Query(filter: pridicateDailyTask()) var dailyTasks: [DailyTask]
    
    var body: some View {
        VStack {
            ....
        }
    }
    
    // staticをつける！！
    static func pridicateDailyTask() -> Predicate<DailyTask> {
      let calendar = Calendar.current
      let now = Date()
      let startOfWeek = Calendar().date(from: Calendar().dateComponents([.yearForWeekOfYear, .weekOfYear], from: now))!
      let endOfWeek = Calendar().date(byAdding: .day, value: 6, to: startOfWeek)!
      return #Predicate<DailyTask>{ dailyTask in
          dailyTask.date >= startOfWeek && dailyTask.date <= endOfWeek
      }
    }
}
```

# 最後に

不備、間違い等あればご指摘いただけると幸いです。

# 参考記事

[Swift #Predicate with function usage on the argument](https://stackoverflow.com/questions/77769330/swift-predicate-with-function-usage-on-the-argument)
#0002（2024/01/02） セッションとステート

# モチベーション
- 昨日、「ステートレスかステートフルか」という記事を書いた
- その中で、ステート（状態）について、調べるとステートとセッションは似た概念なのではないかと思った
- そのため、深堀って調べてみた

# ステートとセッション
## ステート
- ステートは抽象的な概念であり、様々な"状態"を意味している
- 具体的に言えば…
    - システム関係
        - サーバーの起動状態（起動中、停止中）
        - リソース状況（CPU稼働率）
        - フォームの入力状況（カートに入れたものの情報）
        - ユーザーのログイン状態
        - アーキテクチャの構成（2つのEC2と1つのRDSが起動中）
    - ネットワーク
        - セッション状態（接続済み、切断済み）
    - プログラム
        - 変数の値

## セッション
- クライアントのアクションを記録するための、クライアントとサーバーの繋がり
- 具体的に言えば…
    - ユーザーがウェブサイトに接続したときからサーバーから切断するまでの期間﻿
    - TCPによるコネクションが確立してから解放されるまで﻿
    - Webサイトのユーザーがログインしてからログアウトするまでの一連の行動

## 関係性
- 私が一番理解に繋がった考え方
    - セッションはステートを維持するための、一時的もしくは永続的な繋がり

## ソース
- chatgptの回答を参考
Podmanコマンド備忘録

## はじめに

Dockerと互換性があり、ルートレスでの動作も可能なコンテナツール Podman を使い始めるための超入門ガイドです。よく使う基本コマンドをまとめました。

## 目次
1. [インストール](#インストール)
2. [コンテナイメージの取得](#コンテナイメージの取得)
3. [コンテナを起動する](#コンテナを起動する)
   - [runオプション](#runオプション)
4. コンテナの操作
   - [実行中のコンテナの確認](#実行中のコンテナの確認)
   - [コンテナの停止](#コンテナの停止)
   - [コンテナの削除](#コンテナの削除)
5. イメージの操作
   - [イメージ一覧の確認](#イメージ一覧の確認)
   - [イメージの削除](#イメージの削除)
6. その他便利な操作
   - [ログ確認](#ログ確認)
   - [コンテナに入る](#コンテナに入る)
7. [自分用FAQ](#自分用faq)


## インストール
WSL2のUbuntuにインストールします。

```bash
sudo apt update
sudo apt install podman
```

## コンテナイメージの取得

```bash
podman pull <イメージ名>
```

https://hub.docker.com/

## コンテナを起動する

```bash
podman run <イメージ名>
```

### runオプション

| 引数       | 説明                     | 使用例                                       |
|------------|--------------------------|----------------------------------------------|
| `-d`       | バックグラウンド起動     | `podman run -d nginx`                        |
| `-p`       | ポートマッピング         | `podman run -p 8080:80 nginx`               |
| `--name`   | コンテナに名前を付ける   | `podman run --name my-container nginx`       |
| `-e`       | 環境変数の設定           | `podman run -e KEY=value nginx`             |
| `-v`       | ボリュームのマウント     | `podman run -v /host:/container nginx`      |


## 実行中のコンテナの確認

```bash
podman ps
```

`-a`で停止中のコンテナ含め全コンテナの確認

## コンテナの停止

```bash
podman stop <コンテナID>
```

## コンテナの削除

```bash
podman rm <コンテナID>
```

## イメージ一覧の確認

```bash
podman images
```

## イメージの削除

```bash
podman rmi <イメージID>
```

## ログ確認

実行中、停止中どちらも確認可能

```bash
podman logs <コンテナID>
```

## コンテナに入る

実行中のコンテナ内で操作するシェルを起動

```bash
podman exec -it <コンテナID> [コンテナ内パス]
```


## 自分用FAQ

### コンテナを削除したらデータは消えるか？
デフォルトではコンテナ内のデータは削除される。
`-v` オプションを使用してボリュームをマウントすることでデータを永続化可能。

### PodmanとDockerの違いは何か？
Podmanはルートレスでの動作が可能。
デーモンを使用しないためセキュリティや軽量性で優れている。
Aurora Replica Lagとは何か？

# はじめに

Aurora の特徴の一つには、プライマリインスタンスとレプリカでストレージを共有している点が挙げられます。

しかし、CloudWatch には「AuroraReplicaLag」というメトリクスが用意されています。「同じストレージを共有しているのになぜ遅延が起こるのか」という疑問が生じる人もいると思います。

実際、年末に質問があったので、調べてまとめてみました。

# AuroraReplicaLag とは何か

[AuroraReplicaLag](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.AuroraMonitoring.Metrics.html#:~:text=%E5%89%B2%E5%90%88%20(%25)-,AuroraReplicaLag,-Aurora%20%E3%83%AC%E3%83%97%E3%83%AA%E3%82%AB%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
) のドキュメントを読むと、次のように説明されています。

```
Aurora レプリカについて、プライマリインスタンスからアップデートをレプリケートする際の遅延時間。
```

Auroraのデータは共有ストレージに書き込まれます。
リードレプリカは、更新を行うプライマリインスタンスからアップデートを受信して何をしていると思いますか？  

答えはメモリー上のバッファープールの更新です。  
プライマリインスタンスからREDOログを受信して、バッファープールを更新しています。

# バッファープールとは
メモリー上のキャッシュ領域です。
しかし、ただのキャッシュではなく、キャッシュされた以降はこちらが主となります。

DBMS はデータを固定長のページ単位で管理しています。ページ内には複数の行が格納されています。

DBMS はクライアントのリクエストに応じて、ストレージからページをバッファープールに読み込みます。一度バッファープールに読み込まれたページは、それ以降はストレージにアクセスせず操作されます。これにより、同じデータに対するストレージへのリクエストが繁発しないようになるため、システム全体の性能が向上します。

# バッファープールの更新が必要な理由

なぜ、バッファープールの更新が必要なのでしょうか。
それは、バッファープールにページが存在する場合、ストレージからの再読み込みを行わないからです。

Auroraの各ノードはストレージを共有していますが、インスタンスが異なるためメモリーは独立しています。このため、各ノードのバッファープールの状態は一致していません。

Auroraでプライマリインスタンスがデータを更新した時、**もし同じページがレプリカのバッファープールにキャシュされていれば「更新前」の状態になっています。そして、このページはレプリカ側では再読み込みされません**。この状況を解決するため、プライマリインスタンスはREDOログをレプリカに送り、レプリカはバッファープールを更新する必要があります。

この過程が実行されないと、レプリカでは以下のような問題が発生する可能性があります。

- 更新前のデータをクライアント返す
- 削除済みのデータをクライアントに返す
- 新規に挿入されたデータが認識されない

いわゆるレプリケーション遅延です。

## 新規に挿入されたデータが認識されないってどういうこと？

この中で「新規に挿入されたデータが認識されない」というのは奇異に感じるかも知れません。
新規データはレプリカにはキャッシュされていないように思われるからです。
データはページ単位で管理され、ページ内には複数の行が入っていることを思い出してください。新規データの登録されたページがバッファープールに格納されている場合は、ストレージを再読み込みしません。このため、新規データはストレージに存在しても認識されません。

# まとめ

AuroraReplicaLag は、REDOログの同期遅延を監視するメトリクスです。
プライマリインスタンスとレプリカで、同じデータがバッファープールに格納されていた場合、レプリカのバッファープールが更新されないと新しいデータは参照可能になりません。

興味がわいたら[この論文](https://www.amazon.science/publications/amazon-aurora-design-considerations-for-high-throughput-cloud-native-relational-databases)を読むとことをおすすめします。Aurora に対する理解が深まりますよ。


# 参考資料
- [Amazon Aurora: Design considerations for high throughput cloud\-native relational databases \- Amazon Science](https://www.amazon.science/publications/amazon-aurora-design-considerations-for-high-throughput-cloud-native-relational-databases)
- Amazon Web Services ブログ
    - [Amazon Aurora Under the hood: クオーラムと障害](https://aws.amazon.com/jp/blogs/news/amazon-aurora-under-the-hood-quorum-and-correlated-failure/)
    - [Amazon Aurora Under the Hood: クオーラムの読み取りと状態の遷移](https://aws.amazon.com/jp/blogs/news/amazon-aurora-under-the-hood-quorum-reads-and-mutating-state/)
    - [Amazon Aurora Under the Hood: クオーラムセットを使ったコスト削減](https://aws.amazon.com/jp/blogs/news/amazon-aurora-under-the-hood-reducing-costs-using-quorum-sets/)
    - [Amazon Aurora Under the Hood: クオーラムメンバーシップ](https://aws.amazon.com/jp/blogs/news/amazon-aurora-under-the-hood-quorum-membership/)
- [01\_Amazon Aurora アーキテクチャ概要\.pdf](https://pages.awscloud.com/rs/112-TZM-766/images/01_Amazon%20Aurora%20%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3%E6%A6%82%E8%A6%81.pdf)
【ゼロからのOS自作入門】Day02

Day02を読み終えました。
難しいですね。
UEFIは、EDK Ⅱで作られているんですね。
コードは、どんなことしてそうって感じで、なんとなくしかわからないですね。
よくわからなくても、とりあえず進めていきますかー

WSLのUbuntu-18.04で実行しました。
![スクリーンショット 2025-01-02 135000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498946/f1ddea83-e9e7-990c-5f82-b06f85de7118.png)
![スクリーンショット 2025-01-02 135514.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498946/218c956a-962a-10d9-2b9d-92af6385ddfa.png)
![スクリーンショット 2025-01-02 135629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498946/13ebbf1b-d88e-b928-0c9c-e33e09b15e2f.png)
大数の法則とシミュレーション

# はじめに
コインのトスを繰り返し行った場合、表がでる確率の平均値は$1/2$に収束する。これは、二回トスをすれば必ず表は一回でるという意味ではない。一般的に、膨大な試行回数を行えた場合、ある事象の平均的な確率は一定の値に収束するはずである。これを大数の法則という。そこで、今回はコイントスに対応する試行をPythonのRandomで再現することで、表がでる平均確率は0.5に収束することを確かめる。

![確率収束1000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/216651df-41f7-0989-525d-3fa2bad1c1af.png)

# 二項分布と大数の法則
上記のような試行における分布は、試行回数を$n$とすると平均$\mu=np$、分散$\sigma^2=np(1-p)$の二項分布に従う。ただし、確率変数を$X=0,1$とする。


![二項分布反復試行回数100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/dca1d68d-3d8c-aedd-358d-2ad86fe7ad0a.png)

ここで、平均確率を以下のように定義する。

```math
P(n)=\frac{1}{n}\sum^{n}_{k=1} X_k
```


ここで、

```math
V(X)=np(1-p)
```
より、

```math
V(P(n))=\frac{1}{n^2}V(X)=\frac{p(1-p)}{n}
```

となる。また期待値は、

```math
E(P(n))=\frac{np}{n}=p
```

となる。$n \rightarrow \infty$ のとき、


```math
V(P(n))=\frac{1}{n^2}V(X)=\frac{p(1-p)}{n}\rightarrow　0
```

となる。したがって、平均確率は$p$に収束する。

# プログラム
そこで、以下のようなプログラムを作成した。

``` python coin_ave.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math
import random

#試行の繰り返し回数N
N=1000
X_ary=[]
X_sum=0
i_ary=[]

X_ideal=0.5
X_ideal_ary=[]
for i in range(N):
  
  X=random.random()
  if X>0.5:
    X=1
  else:
    X=0
  i_ary.append(i)
  X_sum=X_sum+X
  X_ary.append(X_sum/(i+1))
  X_ideal_ary.append(X_ideal)

#グラフの描画
plt.plot(i_ary,X_ary,color="red",label="実際の確率")
plt.plot(i_ary,X_ideal_ary,color="blue",label="理想の確率")
plt.legend()
plt.xlabel("試行回数")
plt.ylabel("表が出る平均確率")
plt.savefig("確率収束"+str(N)+".png")
plt.show()
```
# 結果
以下のようなグラフが出力される。

![確率収束1000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/216651df-41f7-0989-525d-3fa2bad1c1af.png)

試行回数が100以下の場合は、平均確率は$1/2$を大きく上下していた。しかし、それ以降ではそのような振動は少なくなりほぼ$1/2$となった。

# まとめ

今回は、コイントスを題材として大数の法則をシミュレーションした。結果、試行数を増やすほど平均確率は一定の値に収束するということが分かった。このような膨大な試行を扱う確率・統計の分野においては、計算機の力を借りることが望ましいといえる。

# 参考文献

https://amzn.asia/d/2rE6BFR
【GitHubActions】workflow_dispatchとcronのサンプル

### はじめに

GitHub Actionsは、ビルド、テスト、およびデプロイメント パイプラインを自動化できる継続的インテグレーションおよび継続的デリバリープラットフォームです。
基本的にGitHub上で動いてくれるので、Jenkinsなどのように自前のサーバを用意してワークフロー等を実行する必要のないところが嬉しいです（学習コスト的にも）

### ワークフローとは

GitHub Actionsのワークフローは、ソフトウェア開発ライフサイクルタスク(SDLC)を自動化するためにリポジトリにて設定するプロセス(?)です。
このワークフローを使用すると、いろんなプロジェクトをビルド、テスト、パッケージリリース、およびデプロイできます。
ワークフローの記述スタイルとしては、YAMLで書けるようになっています。

### 本記事では

本記事では、ワークフローを実行するにあたっての使用することのできるトリガー（workflow_dispatch, cron）について書いてみます。

### workflow_dispatch（手動実行が可能）をトリガーとするワークフロー

下記は、ワークフローを手動で実行する際のファイル。
URLからアクセスし、`Manual Hello Echo` を押下し、`Run Workflow` を選択して実行をするとワークフローが動作するはずです。
できなかったら、自分ので試してみてください。

```yaml
name: Manual Hello Echo

on:
  workflow_dispatch:  # 手動実行のトリガー

jobs:
  say-hello:
    runs-on: ubuntu-latest
    steps:
      - name: Echo Hello
        run: echo "hello"
```

- workflow_dispatch イベントを使用して手動実行可能に
- 単純に "hello" という文字列をecho

URL：https://github.com/yyoosshh/sandbox-githubactions/actions


### cron(定期実行)をトリガーとするワークフロー

下記は、毎時0分に echo を実行するワークフローです。

```yaml
name: Hourly Time Echo

on:
  schedule:
    - cron: '0 * * * *'  # 毎時0分に実行

jobs:
  echo-time:
    runs-on: ubuntu-latest
    steps:
      - name: Get current time
        run: echo "Current time is $(date)"
```

- schedule イベントを使用して、cron式で毎時0分に実行されるように設定
- date コマンドを使用して現在時刻を出力

### ワークフローが配置されているレポジトリ

こちらのレポジトリに上述したワークフローが配置されており、cronは定期実行されています。

URL：https://github.com/yyoosshh/sandbox-githubactions/actions/workflows/cron-workflow.yaml
Db2 ファミリー間のSQL互換性を調べたい

主題の通りです。

## The SQL reference for cross-platform development

こちらにDb2ファミリー(Db2 for i, LUW, z/OS)のSQL互換性の情報リンクがあります。

17 November 2023発行
[SQL Reference for Cross-platform Development: Version 7 (Db2 13 for z/OS, IBM i 7.5, Db2 11.5)](https://www.ibm.com/support/pages/system/files/inline-files/ibmsqlr_2023.pdf)

※古いバージョンはこちらです。
[SQL Reference for Cross-Platform Development Version 6 (Db2 for z/OS V12, i V7.3, LUW V11.0)](https://community.ibm.com/HigherLogic/System/DownloadDocumentFile.ashx?DocumentFileKey=d0d9a212-f938-8dfa-8a65-82c84b1a3864&forceDialog=0)

## Db2 for i 単体のSQLリファレンス最新版（IBM i 7.6）

IBM i 7.6＝Db2 for i 7.6 のSQLリファレンスはこちらです。
[Db2 for i SQL Reference (IBM i 7.6)](https://www.ibm.com/docs/en/ssw_ibm_i_76/pdf/rbafzpdf.pdf)

## Db2 for i のゼネラルな情報リンク(IBM docs)

[Db2 for IBM i](https://www.ibm.com/support/pages/db2-ibm-i)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/c599d08a-7a75-ee2b-8daa-acbebc52e8fc.png)


## 基本のキ Db2ファミリー

こんな感じで3系統ありまして、もともとはSQL, その他いろいろ非互換の塊でしたが最近ではだいぶ共通化されつつあります。
※下記はDB2と表記されていた時点での作成資料です、最新ではDb2 と改称されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/8726e358-84ee-e115-32c0-5929698d2ede.png)

とは言いながら共通化されているのやSQLプログラミングや相互運用管理の観点であり、それぞれの独自性＝機能面での優位性などに基づく独自性は維持されています。
下記はDb2 for i 観点の図解ですが他のファミリーとは設計思想からして一線を画していることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/50c156eb-0286-9ba4-474e-d2d35ac7a1af.png)
AWS CLIについて

## 概要
MFA有効にしたユーザーでCLIを利用し、その後MFAを無効にアクセスしようとした際ハマったので記載します。

## 本編
結論から記載するとクレデンシャルに以前利用したSTSの情報が残っていたせいで、アクセス拒否されてしまっていました。

STSを利用して、home/.aws配下にあるクレデンシャルファイルに
```
aws session token = [key]
```
を記入している場合ですがここを削除してあげないとCLIではじかれてしまいます。

## まとめ
中々ない状況だと思いますが、備忘録として残します。
プロファイル別で作れという話ですよね...
はんだ付けの時に火傷をしないためのシミュレーション

## はじめに
はんだ付けをする際、
　・はんだを持ったつもりがスズメッキ線を持っていて火傷をした。
　・加熱位置から近すぎる箇所を持って火傷をした。
という経験は誰もが持っているはずである。
安全な距離は痛い思いをして覚えていくものであるが、そうは言っても予め目安を知っておくに越したことはないと思い、温度分布のシミュレーションを行った。

## 目次
- [熱伝導率](#熱伝導率)
- [シミュレーション](#シミュレーション)
- [【参考】シミュレーション時の各種パラメータ](#【参考】シミュレーション時の各種パラメータ)

## 熱伝導率
例えば、はんだを手に持ってはんだ付けしても熱くはないが、スズメッキ線を持ってはんだ付けの動作をするとやけどをする。これは素材の熱伝導率の違いによるところが大きい。

はんだ：約 50 W/m·K
スズメッキ軟銅線：約 400 W/m·K

この値が大きいほど熱がよく伝わり、手元まで熱くなる。
![conductivity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/20cc4cf9-963c-d436-7690-96a53dc97672.png)

## シミュレーション
FreeCADというソフトを用いて熱伝導のシミュレーションを行い、その出力をParaViewというソフトで確認した。
それぞれの使い方については、余力があったら別の記事で紹介しようかな・・・

（参考）
・FreeCAD：https://www.freecad.org/index.php?lang=ja
・ParaView：https://www.paraview.org/
※FreeCADの出力をParaViewで結果を確認している時の例：
![paraview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/2daba616-c367-9795-ffaf-21c89e1d6d08.png)

以下、シミュレーションの結果を見ていく。

まずは直径0.4mmの線材について、はんだとスズメッキ線で温度分布を比較した結果は以下の通りである。
![material_comp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/1a6ef6e2-3a86-bba9-ec2c-cbc2b7a77920.png)
例えば加熱位置から100mmの所では、0.4mm径のはんだの温度は約30℃であるのに対して、同径のスズメッキ線は約90℃にもなる。はんだと間違えてスズメッキ線を持ったら火傷をするのは当たり前である。

様々な線径について同様のシミュレーションを行った結果を以下に示す。
充分な時間加熱し、熱平衡状態に至った時の温度分布である。
![all_comp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/ee72883d-ddef-dc50-349c-b463bfea355c.png)

一般的に、60℃以上の物体に数秒以上触れるとやけどすると言われているようである。
上記グラフと照らし合わせると、例えば1.2mm径のはんだは加熱位置から90mm程度、0.6mm径のはんだは60mm程度離れた位置を持てば安全なのではないかと予測できる。

## 【参考】シミュレーション時の各種パラメータ
FreeCADでシミュレーションを行う際に入力したパラメータは以下の通りである。
※本シミュレーションには不要なパラメータも含まれている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925524/c3ff09e6-8bd7-6206-5d21-ce17905eb958.png)

参考にしたサイト：
https://www.hakko.co.jp/library/qa/qakit/html/h01020.htm
https://cend.jp/heat_primer/convection_heat.html
【Web】ログ運用

# はじめに
こんにちは。アメリカで独学でエンジニアを目指している者です。現在はWeb技術について学習中で、本日は「ログ」について取り上げたいと思います。
親族が仕事で「ログが云々」とよく話しているのですが、実はサーバーだけでなくアプリケーションやシステム運用においても、ログは非常に重要な役割を果たしているようです。なお、今回ご紹介する内容のうち、教材に書かれていない部分はAIを活用して情報を補足していますので、あらかじめご了承ください。
## ログ運用の重要性

ログ（Log）は、システムやアプリケーションの動作状況やエラー情報などを記録したファイルです。
トラブルシューティングやセキュリティ対策、性能管理など、運用管理のさまざまな場面で活用されます。
適切なログ運用は、以下のようなメリットをもたらします。

* **トラブルシューティングの効率化**
不具合が発生した際、いつ、どのような処理が行われたかをログで確認できます。迅速に原因を特定し、復旧に役立てることが可能です。

* **セキュリティ対策**
不正アクセスや内部不正などを疑う場合、ログをもとに追跡調査が行えます。早期発見や証拠の保全にもつながります。

* **サービス改善・最適化**
ユーザーのアクセス状況などを分析し、ボトルネックの特定やサービス改善のアイデアを得ることができます。

## ログファイルの種類とその役割

ログファイルはシステムや用途によってさまざまな種類があり、それぞれに役割があります。代表的なログファイルの例を挙げます。

### システムログ (System Log)
OSやミドルウェアなどの動作状況を記録するログです。
  - Linuxでは「/var/log/messages」や「/var/log/syslog」が代表的です。
  - システム全体の重要なイベントを記録し、障害発生時の調査に最初に参照されることが多いです。

### アプリケーションログ (Application Log)
WebサーバやDBサーバ、その他アプリケーション自体が出力するログです。
  - アプリケーション固有のエラーや警告、デバッグ情報などを記録します。
  - 障害発生時はシステムログだけでなく、関連アプリケーションのログも合わせて調べることで原因特定の精度が高まります。

### セキュリティログ (Security Log)
認証・アクセス権限の変更、不正アクセスの試行などセキュリティに関するイベントを記録します。
  - 外部からの不正アクセスや内部の不正利用の兆候を検知する役割を担います。
  - ログインやsudoコマンドの実行履歴など、重要な操作履歴が含まれます。

### アクセスログ (Access Log)
Webサーバなどへのアクセス情報を記録するログです。
  - 通常は「何時」「どのIPアドレスから」「どのURLに」「どのようなHTTPメソッドで」「どのステータスコードで」アクセスされたかが記録されます。
  - ユーザー動向やサイトの負荷状況、セキュリティインシデントの兆候把握に役立ちます。

## ログローテーション

ログは時間の経過やアクセス数の増加に伴い、ファイルサイズが肥大化していきます。大きくなったログファイルは扱いづらく、ディスク容量を逼迫し、場合によってはシステム停止の原因となります。そのため定期的に古いログを圧縮・削除・分割する「ログローテーション」が重要です。

### ログローテーションの仕組み
* **日時やサイズでのローテーション**
一定の日数・週・月ごと、またはファイルサイズの上限を超えたタイミングで古いログを新しいファイルへ移動・圧縮し、メインのログファイルをクリア（または新規作成）する方法です。
* **ログローテーションの設定例 (Linux)**
多くのディストリビューションには「logrotate」というツールがデフォルトで搭載されています。/etc/logrotate.conf や /etc/logrotate.d/ 以下で各アプリケーションごとの設定が可能です。
```bash
/var/log/httpd/access_log {
    weekly
    rotate 4
    compress
    delaycompress
    missingok
    notifempty
    create 640 root adm
}
```
weekly: 週ごとにログローテーション
rotate 4: 世代を4つ保持
compress: 古いログファイルを圧縮
delaycompress: ローテーション直後は未圧縮で残し、次のサイクルで圧縮する
missingok: ログファイルがなくてもエラーにしない
notifempty: ログが空ファイルの場合はローテーションしない

### ローテーションにおける注意点

* **ローテーションの頻度**
アクセス頻度が高いサービスでは、1日1回ではなく数時間ごとにローテーションを行うことを検討しましょう。

* **ログの保管期間**
業務要件や法令によって保管期間が定められている場合があります。ビジネスやコンプライアンス要件を踏まえて設定する必要があります。

* **バックアップとアーカイブ**
ログは障害時の調査やセキュリティ監査に不可欠です。ローテーションされたログは定期的にバックアップをとる、あるいは集中管理サーバ（例: syslogサーバやSIEM）に転送して保管することが多いです。

## アクセスログ分析

アクセスログは、単に読み込むだけではなく、分析によってさまざまな情報を得られる重要なデータソースです。

### 分析ツールと手法

* **Web解析ツールの使用**
Google Analytics や AWStats、Matomo (旧 Piwik) などの解析ツールを用いることで、アクセス元や滞在時間、ユーザーの行動などを可視化できます。

* **ログ解析スクリプト・コマンドの活用**
grepやawk、sed、cutなどのUnix系コマンドを組み合わせて集計・フィルタリング・可視化する方法があります。シンプルな調査やカスタマイズされた集計に向いています。

* **SIEMやログ管理プラットフォーム**
Elasticsearch + Kibana (ELK Stack) や Splunk などを使って大量のアクセスログをリアルタイムで集約・分析できます。アラートの設定や可視化ダッシュボードの作成も可能です。

### 分析で得られる主な成果

* **利用状況の可視化**
どのページにアクセスが多いか、ピーク時のアクセス傾向はいつかなど、サービス運用に役立つ情報を得られます。

* **ボトルネックの特定**
特定のページの応答が遅い、ステータスコード5xxエラーが頻発しているなどの問題点を特定し、改善策を検討できます。

* **セキュリティインシデントの検知**
不正アクセスを試みるIPアドレスや攻撃パターンをいち早く検出し、防御策を講じることが可能です。


## まとめ
今回は、ログ運用の概要について大まかに理解することができました。現在はRailsの学習を進めていますが、今後ポートフォリオを作成していくにあたっても、ログの役割や重要性をある程度把握しておくことは非常に有意義だと感じています。