OmniAICreator/Qiita-1.07M huggingface dataset:
# [備忘録]URLを叩いてから画面に表示されるまで

これまで漠然とした理解で開発をしてきたため、最低限の事は言語化できるくらいにはなりたいなと思い、完全自分用の学習備忘録として残します。

### 流れ

1. URLを解析する
2. キャッシュにIPアドレスがないかを確認する
3. DNSで対応するIPアドレスを取得する
4. IPアドレスでえWebサーバーにリクエストをする
5. ポート番号を割り当てる
6. HTTPリクエストを送信する
7. ロードバランサーでアクセスを調整する
8. HTTPレスポンスを送信する
9. レンダリングする

### 1. URLを解析する

例えば、[`https://twitter.com/login`](https://twitter.com/login?) というURLを叩く。

- `http` や `https` など。→ **プロトコル（安全に通信するためのルール）**
- `twitter.com` → **ドメイン（住所のようなもの）**
- `/login` → **パス**

**プロトコル**はパソコンとサーバーが安全に通信するためのルール。`https`の`s`は`secure`の`s` を指す。他のもので例えるならば、「サッカーする時は手を使ってはいけない。」というルールがあると同じように、webの世界にも外部と通信するときにルールがある。

- `http` : 通信内容が暗号化されていない
    - 通信が暗号化されていないため、送信内容（例: クレジットカード情報）が第三者に盗み見られたり改ざんされる可能性がある。
- `https` : 通信が暗号化されている
    - 通信が暗号化されており、送信内容（例: クレジットカード情報）が安全にサーバーへ送られるため、盗み見や改ざんのリスクがない。
    

### 2. キャッシュにIPアドレスがないかを確認する

ブラウザはまず、`キャッシュ`に`ドメイン`に対応する`IPアドレス`が保存されていないかを確認する。

`キャッシュ`に`https://twitter.com/login`のドメイン`twitter.com`に対応する`IPアドレス`が保存されているかを確認する。もしキャッシュに`IPアドレス`があれば、`DNS`への問い合わせをスキップし、それを使ってサーバーに直接リクエストを送る。

### 3. DNSで対応するIPアドレスを取得する

キャッシュにIPアドレスがない場合、ブラウザはDNSサーバーに問い合わせを行い、`ドメイン`と対応する`IPアドレス`を取得する。

### 4. IPアドレスでWebサーバーにリクエストをする

ブラウザは取得したIPアドレスを使用して、ターゲットのWebサーバー（ここではTwitter社のサーバー）に接続する。

### 5. ポート番号を割り当てる

1. **サーバーのポート番号**:
    - Twitterのサーバーは、HTTPS通信を受け付けるためにポート443を使う。
    - 通常、HTTPS通信はポート443を使うため、ブラウザはサーバーに対してポート443で接続する。
2. **ローカルポート番号**:
    - ブラウザは、ローカルマシン上で一時的に使用するポート番号を割り当てる。これを「エフェメラルポート」と呼ぶ。
    - 例えば、ブラウザが`https://twitter.com/login`にアクセスするとき、ローカルマシンのポート番号12345を割り当てて、サーバーのポート443に接続する。
3. **通信の流れ**:
    - ブラウザは、サーバー（Twitter）のIPアドレスとポート443に接続する。
    - 同時に、ローカルマシンのポート12345を使用してリクエストを送信する。
    - サーバーからのレスポンスは、ポート443を通じて送信され、ローカルマシンのポート12345に戻る。
    

### 6. HTTPリクエストを送信する

通信が確立されると、ブラウザはHTTPリクエストをサーバーに送信する。リクエストの内容は以下。

- **リクエストライン**
- **ヘッダー**
- **ボディ**

### 7. ロードバランサーでアクセスを調整する

 Twitter社が持つ複数のサーバーのうち、一つだけにアクセスが集中しないよう、それぞれのサーバーにアクセスを振り分け、負荷を分散させる。

### 8. HTTPレスポンスを送信する

サーバーはリクエストを処理し、HTTPレスポンスをブラウザに返す。レスポンスの内容は以下。

- **ステータスライン**
- **ヘッダー**
- **ボディ**

### 9. レンダリングする

ブラウザは受け取ったHTMLやCSS、JavaScriptを解析し、ページを表示する。

- ローディング

　1. HTMLファイルをダウンロード

　2. CSSファイルをダウンロード

- スクリプティング

　3. Javascriptを実行（React, Vueフレームワークなど）

- レンダリング

　4. レンダリングしたものをペインティングで画面に描画。
モダンJavaScript (モジュール・パッケージ・ビルド)

しまぶーさん モダンJavaScript講座など参考
https://youtu.be/De9PH3EAz7c


## モジュール
**コードを1ファイルにまとめ影響範囲を限定したもの**

- プログラムの**再利用**がしやすい
-  **同一命名**をファイルごと定義可能
-  機能ごとに分割など**管理が容易**になる
- 別スコープに  ```import``` ```export``` できる


```js:name.js
// nameをexport
export const name = "タナカ";
```


```js:index.js
// name.jsのnameを取り入れる
import { name } from "./name.js";

document.body.textContent = name;
```
  
```html:HTML
<!DOCTYPE html>
<html lang="js">
  <body></body>
  <!-- type="module"でモジュールと認識 -->
  <script src="./index.js" type="module">
  </script>
</html>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3230965/670a6711-1c5d-76d8-d8c7-569916b628bb.png)


### モジュールの書き方2種(ES Modules/CommonJS)
- **ESモジュール方式** ←現在の主流

エクスポート
```js:module.js
// 宣言時に export
export const foo = "foo";
export fonction hello(){conosole.log("hello")};

// またはまとめてexport
export {foo, hello};
```
インポート
```js:main.js
import {foo, hello} from "./module.js"
foo; // "foo"
bar(); // console=> "hello"
```
ESモジュールはHTMLのどこにおいても最後に評価される(**遅延評価**)ので、
```<script src="...">```でのjsファイル読み込みをどこでもできる。※head内とか

```html:HEML
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>test</title>
        <!-- ここで読み込んでも末尾まで読んでから実行 -->
        <script src="./module.js" type="modules"></script> 
    </head>
    <body></body>
</html>
```


- **Common JS方式**
 Node.jsで使われてきた方式。
 - ```module.exports``` ```exports```でエクスポート/インポート

```js:module.js
const name = "aaa";

// exports.〇〇でエクスポート
exports.name = name;
exports.add = (a, b) => a + b;
```
```js:main.js
// require("moduleのパス")で受け取り
const myModule = require("./module");

// module.〇〇で使用
console.log(myModule.name); // aaa
console.log(myModule.add(1, 2)); // 3
```
※ Nodeで実行する場合、そのままだとES形式と認識されて実行できない。

※ プロジェクト直下で```npm init -y```して```package.json```を作成し、```"type": "commonjs";```を記載する。


## パッケージ
- パッケージとは**モジュール**と**依存関係**をまとめたもの
- **npm**を使い管理する
    - モジュール間の依存関係管理
    - インストール／アンインストール

使い方
1. npmで各種パッケージをインストール
1. ```.js```にimport


```js:JS
// 例
import axios from 'axios';
import chalk from 'chalk';
```
## ビルド
- 開発したコードを実行環境が実行できるために**コンパイル**や**バンドル**すること。(再編して最適化するイメージ)
- ビルドは**モジュールバンドラ**が担う
        - vite
        - webpack
        - など

https://ics.media/entry/12140/images/160519_webpack_is__960.png
Flutter開発環境の構築について

# はじめに
Flutter入門時、環境構築する際に残していた備忘録です。

# 環境バージョン
Flutter 3.24.5
cocoapods 1.11.2
Xcode 15.2

# 環境構築
- 公式サイト[Install | Flutter](https://docs.flutter.dev/get-started/install)に遷移、platformを選択、iOSを選択します。
- 公式サイトの手順でFlutterのダウンロード・インストールを行います。
	- MacOS/iOSの場合：[Make iOS apps | Flutter](https://docs.flutter.dev/get-started/install/macos/mobile-ios)
- VSCode、VSCodeのFlutterプラグインを使用します。
	- [VSCode](https://code.visualstudio.com/docs/setup/mac)
	- [VSCodeのFlutterプラグイン](https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter)
		- VS Codeの拡張機能で「Flutter」を検索、インストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985483/2e93b06a-7993-68c3-7925-b3c70a0485cf.png)

Flutter拡張機能インストール後、下記の通知が来ていたらSDKをダウンロードします。
> Could not find a Flutter SDK. Please download, or, if already downloaded, click 'Locate SDK'.


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985483/c006fdce-67b8-2b56-2647-b5c823ce7da5.png)


下記のようなエラーが発生するなどダウンロードに失敗した場合は、[Make iOS apps | Flutter](https://docs.flutter.dev/get-started/install/macos/mobile-ios)から手動ダウンロードを行います。

> Failed to clone Flutter using Git. Please clone or download the Flutter SDK manually.

ダウンロード先は下記にしました。

```
/Users/ユーザー名/development/flutter
```

下記でパスを通します。

```
$ vim ~/.zshrc

// 以下を.zshrcに追加
export PATH=$HOME/development/flutter/bin:$PATH

$ which flutter
/Users/ユーザ名/development/flutter/bin/flutter

$ which dart
/Users/ユーザ名/development/flutter/bin/dart

% flutter --version
Flutter 3.24.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 2663184aa7 (9 weeks ago) • 2024-09-11 16:27:48 -0500
Engine • revision 36335019a8
Tools • Dart 3.5.3 • DevTools 2.37.3
```

パスが通ったら、VSCodeを再起動します。


VSCodeに下記の通知が来ていた場合、通知に従って`Run 'pub get'`を実行します。
> Some packages are missing or out of date, would you liketo get them now?
> 一部のパッケージが欠品または期限切れですが、今すぐ入手しますか？


`flutter doctor`を実行して環境が正しく構築できたか確認します。
✗の項目があった場合は確認、全てが✓になっていれば環境構築は完了になります。

```
% flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.24.3, on macOS 14.7 23H124 darwin-arm64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.95.2)
[✓] Connected device (6 available)
[✓] Network resources

• No issues found!
```

# flutter ライブラリのインストール
`flutter pub get`を実行します。

# デバッグについて
## コマンドライン
`flutter run`を実行、デバイスを選択します。

## VSCodeのFlutterプラグイン使用
- VSCodeのコマンドパレットから`Flutter Select Device`を実行、デバッグに使用するデバイスを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985483/cbf19ba4-5f8f-603a-cd87-c48ee60dbfb1.png)

- VSCodeのコマンドパレットから`Debug: Attach to Flutter on Device`を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985483/22a7f429-8ee0-ba95-aab2-2c118d3a95cb.png)

## その他
VSCodeの実行とデバッグからも起動いけますが、ここでは割愛します。


# おわり
Flutter拡張機能インストール後のエラー以外はスムーズにできました。
Spring bootでのログ出力のテスト

以前に書いたログ出力のテストについての別解です。

https://qiita.com/n_slender/items/2f301f0ba24f53f007d7

ログ出力そのものが仕様になっている場合、ログに出力された内容に対してassertionを書きたいです。Spring Bootではそのための、JUnit5のExtensionを用意してあります。

https://docs.spring.io/spring-boot/api/java/org/springframework/boot/test/system/OutputCaptureExtension.html

使い方は上記のjavadocに書いてあるとおりですが、標準出力とやりとりするための`CapturedOutput`が提供されているので、テストメソッドの引数などからそれを受け取れます。

```:java
@ExtendWith(OutputCaptureExtension.class)
class MyTest {

  @Test
  void testLog(CapturedOutput output) {
      // arrange
      ...

      // act
      service.apply(); // 中でログ出力している

      //assert
      assertThat(output).contains("done");
  }

}

```

test/resourceにlog4j2-test.xmlを配置すれば、テストコード実行時のloggerの設定ができます。

```:xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
	<Appenders>
		<Console name="CONSOLE" target="SYSTEM_OUT">
			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level - %msg%n" />
		</Console>
	</Appenders>
	<Loggers>
		<Root level="info">
			<AppenderRef ref="CONSOLE" />
		</Root>
	</Loggers>
</Configuration>
```

このやり方だと、loggerをdependency injectionの形にしなくてもログ出力の内容をテストできます。
FastAPIデプロイ記録

# FastAPI使いてぇ～
そう思ったことありますよね...
ということで現在作成しているゲームのバックエンドとしてFastAPIを使用しました

GitHubリポジトリ

https://github.com/KOU050223/APIFactory-backend

初めてのFastAPIということでなにもわからん！！

とりまチュートリアル

https://note.com/mz700/n/nda60fed021ff

ファイル構成はチャットGPTに聞いたやつなのでベストプラクティスなのかはわからないです
reactとかみたいにテンプレを一気に作ってくれるやつあったら楽なんだけど...

ファイル構成

```
├─.github　（デプロイ時に自動作成）
│  └─workflows
├─api-factory　（venvで作成した仮想環境）
├─app　（動作を書く部分）
│  ├─crud
│  ├─models
│  ├─routers
│  │  ├─__init__.py
│  │  ├─firstapi.py (分けて書いた処理部分)
│  │  └─__pycache__
│  ├─schemas
│  ├─__init__.py
│  ├─config.py
│  ├─database.py
│  └─main.py (お作法的なやつとルーターを追加する)
├─.gitignore
├─README.md
├─requirements.txt
└─startup.sh 
```

基本的に公式の記事を参考にしてデプロイ進めました

https://learn.microsoft.com/ja-jp/azure/app-service/quickstart-python?tabs=fastapi%2Cwindows%2Cazure-portal%2Clocal-git-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli

:::note warn
警告
Azure App Serviceの課金に注意してください。
使わない場合は削除する・落とすなどして対処してください
:::

デプロイ先

~~https://apifactory-api-g6b6gqh0gfe3apdm.japaneast-01.azurewebsites.net/~~
今は落としてます

## 詰まったところ

### スタートアップコマンド

自分のファイル構成の場合スタートアップに変更が必要でした

公式

```bash
gunicorn -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 main:app
```

今回の構成の場合

```
gunicorn -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app.main:app
```

モジュール化やらしてるせいでスタートアップコマンドに修正が必要でした

### 環境変数
今回はスタートアップコマンドの件に気づくまで環境変数がおかしいのかと思い弄ってました

最終的な環境変数

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3453576/fc01da13-26ca-7049-557f-2f660ab13a57.png)

## あとがき

公式のGitHubのプロジェクトにもあったけどstartup.shってどんな役割してるんやろうか
スタートアップコマンドで参照している感じではなさそうだし

https://qiita.com/shyamagu/items/4fca59e47ae74b1ebaff

この記事ではスタートアップコマンドに直接**startup.sh**でやってるからそんな感じで使うんかなと

最後に...

まだFastAPIちょろっとしか触ってないけどresponse見られたり実行速度早いらしかったりで便利そうな印象

このままフロントがんばるんば
社内プロキシに悩むしがないエンジニアがSSL/TLSをちゃんとわかるようになるために備忘を書く

# 目的
- 何となく証明書だのSSL/TLS通信だのに触れていて、ちゃんと仕組みがわかっているか怪しいので備忘としてアウトプット
- 社内環境がプロキシとの戦いなので、必須知識かもしれない

# 記事の概要
- サーバはどうやって証明書を手にするのか
- SSL/TLS通信の信頼性担保（SSLハンドシェイク）はどのように実現するのか

# 内容
## SSL/TLS通信の概要
- SSL/TLSはTLSハンドシェイクによる信頼性担保、および暗号化された通信路の確保を指す
- HTTPをSSL/TLSで暗号化したものがHTTPSで、SSL/TLSとHTTPSは厳密には異なる概念
- サーバ（通信を受ける側）は認証局にまともだと認められた証である証明書を持っている
- クライアント（通信を送信する側）はその証明書の内容を見て、送信先サーバがまともかどうかを検証する

## サーバはどうやって証明書を手にするのか

まずサーバは秘密鍵を作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/69f1afe2-3215-08c0-2618-8e61c15d9127.png)

その対となる公開鍵情報を含む証明書を認証局に作ってもらうための依頼書を作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/9c065942-7c0c-686a-b865-2d64fd2f78d8.png)

依頼書を認証局に送る。やがて証明書が返される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/f0e74dfd-40d0-64fd-02c9-854ca51aa94b.png)

準備OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/ba582abc-a37d-3066-56eb-9da3f1a87ce1.png)

## SSL/TLS通信はどうやって確立されるのか

まずクライアントからClient Helloという通信がサーバ向けに発せられる。これにはクライアントが対応可能な通信方式を記載している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/0bd78382-9472-ce9e-257c-0757cc33f163.png)

Client Helloを元にサーバは通信方式を決定し、Server Helloで決定された通信方式を共有する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/9ddb6aa5-6d12-43ed-daed-e598cfd66125.png)

続けてCertificateで証明書をクライアントに見せる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/ef3b2702-3661-2c0a-0821-3cf16c78a5f9.png)

クライアントはどの認証局を信じるかリストを持っていて、それを元に証明書を検証。OKだったらここでハンドシェイク成立。ハンドシェイク成立後、クライアントがランダムでセッション鍵を作る。これは後段で通信自体の暗号化で使われる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/f9de1a0b-1195-fa0e-5adc-b6e5ee5d48e5.png)

セッション鍵をサーバの公開鍵で暗号化し、サーバに送る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/f48d525c-b58c-16c0-732d-6c20cb177954.png)

サーバは秘密鍵でセッション鍵を復号。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/3ec024d6-2382-3980-1742-40e2c57f482d.png)

双方のセッション鍵を元に通信自体を暗号化できる状態になる。この状態を持って「SSL終端」。HTTPS通信などはこの暗号化された通信路で実施される（厳密にはHTTPS以外にもSSL/TLSで暗号化される）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/89ba06b2-ce6b-f2a6-18cb-a122312a64f8.png)

# Appendix
- 証明書チェーン、mTLS通信、EV-SSL証明書についても気が向いたら書くかも
GhosttyでiTerm2風のVisor(クイックターミナル)を設定する

macOSのターミナルエミュレータとして人気の高いiTerm2には、グローバルホットキーで呼び出せるVisor機能があります。今回は、新しいターミナルエミュレータであるGhosttyで、同様の機能を実現する方法をご紹介します。

## Ghosttyとは

[Ghostty](https://ghostty.org/)は、Zigで書かれていて、高速で最新の機能を備えたクロスプラットフォームのターミナルエミュレータです。Rustで書かれた[Alacritty](https://github.com/alacritty/alacritty)やC++で書かれた[kitty](https://sw.kovidgoyal.net/kitty/)と同様、モダンなアプローチでターミナルを再実装しています。

## 設定方法

Ghosttyの設定は`~/.config/ghostty/config`ファイルで管理します。以下の設定で、iterm2風のVisor表示（Ghosttyではクイックターミナルと呼びます）を実現できます：

```
font-family = Comic Mono
macos-titlebar-style = hidden
macos-non-native-fullscreen = true

# クイックターミナルの位置を画面上部に設定
quick-terminal-position = "top"

# クイックターミナルを表示するスクリーンを設定 (メインスクリーン)
quick-terminal-screen = "main"

# アニメーション時間を設定（0で即時表示）
quick-terminal-animation-duration = 0

# グローバルホットキーを設定
keybind = "global:ctrl+cmd+`=toggle_quick_terminal"
```

## 設定の解説

各設定項目について詳しく見ていきましょう：

1. `font-family = Comic Mono`
   - Comic Monoフォントを使用します。お好みのモノスペースフォントに変更可能です。

2. `macos-titlebar-style = hidden`
   - タイトルバーを非表示にして、よりミニマルな見た目を実現します。

3. `macos-non-native-fullscreen = true`
   - macOSのネイティブフルスクリーンを使用せず、より高速な切り替えを可能にします。

4. クイックターミナル関連の設定
   - `quick-terminal-position = "top"`: 画面上部からスライドダウン
   - `quick-terminal-screen = "main"`: メインスクリーンに表示
   - `quick-terminal-animation-duration = 0`: アニメーションなしで即時表示

5. `keybind = "global:ctrl+cmd+`=toggle_quick_terminal"`
   - Ctrl+Command+` でグローバルに呼び出せるように設定

## カスタマイズのポイント

この設定は以下のようにカスタマイズできます：

- `quick-terminal-position`を"bottom"に変更すると、画面下部から表示されます
- `quick-terminal-animation-duration`に値を設定すると、スライドアニメーションが有効になります
- `quick-terminal-auto-hide = true`を追加すると、フォーカスを失った時に自動的に隠れます

## まとめ

GhosttyのクイックターミナルはiTerm2のVisor機能の代替として十分な機能を提供しています。シンプルな設定で、効率的なワークフローを実現できます。開発中のプロジェクトでも、グローバルホットキーで素早くターミナルにアクセスできる環境を整えることで、生産性の向上が期待できます。
Excel で空白に見えるけど空白じゃないセルの一括消去

# これは何？
私の覚書です。
# Excel で一見空白に見えるセル
データベースとかやってる人にはおなじみのアレです。
`Null`じゃない、空白文字が入ってるという例のヤツです。
Excelでも、Worksheet関数なんかで、`=IFERROR(A1,"")`とか使うと
エラーのセルが、空白になります。
これを値コピーしたりすると、「一見空のセルだけど、空白文字が入ったセル」になります。
# ジャンプ(週刊誌じゃないよ)では消えない
毎回、間違えるので覚書です。ジャンプ機能を使って消すといつも勘違いしてしまうのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2555080/52c79cd2-c6fb-0c09-3652-7ef2a1e1c04f.png)

`Ctrl + G`で出てくるジャンプの機能の一つ、「セル選択」ボタンを押すと出てくるこのダイアログの「空白セル」でジャンプすれば消せるかなー、と思うのですが、この「空白セル」は本当の空のセルしか選択せず、「空に見える空文字が入ったセル」は選択できません。
# サクッと空白文字を消しましょう
検索を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2555080/2db58f7e-1c9d-c5d4-1e82-adbc62e04dac.png)

「検索する文字列」を空にした状態で「すべて検索」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2555080/eaf326c5-e2ef-128b-a745-a49ef28c592c.png)

「本当に空のセル」と「空に見える空文字が入ったセル」が全て見つかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2555080/f595ba88-a0d6-c141-1f7d-b6202516f8dd.png)

一番上の項目をクリック後、シフトキーを押しながら、一番下の項目をクリック。
そうする事で、「本当に空のセル」と「空に見える空文字が入ったセル」が選択されます。
この状態で、`Delete`キーを押せば、「空に見える空文字が入ったセル」が「本当に空のセル」になります。
(自分用dockerfile)Ubuntu24.04+CUDA12.5+pyenv+SSH

```dockerfile
FROM ubuntu:24.04

# aptの更新など
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y wget curl git htop vim

# .bashrcの編集
RUN sed -i 1iforce_color_prompt=yes /root/.bashrc
RUN echo alias la="'ls -lah'\n" >> /root/.bashrc

# CUDAのインストール
RUN wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb
RUN dpkg -i cuda-keyring_1.1-1_all.deb
## ↓Ubuntu23.04以降でCUDAのインストールに必要なコマンド
RUN echo "deb http://archive.ubuntu.com/ubuntu/ jammy universe" >> /etc/apt/sources.list.d/jammy.list
RUN echo "Package: *\nPin: release n=jammy\nPin-Priority: -10\n\nPackage: libtinfo5\nPin: release n=jammy\nPin-Priority: 990" >> /etc/apt/preferences.d/pin-jammy
## ↑Ubuntu23.04以降でCUDAのインストールに必要なコマンド
RUN apt-get update
RUN apt-get -y install cuda-toolkit-12-5
RUN rm cuda-keyring_1.1-1_all.deb
RUN echo "export PATH=/usr/local/cuda-12.5/bin\${PATH:+:\${PATH}}" >> /root/.bashrc
RUN echo "export LD_LIBRARY_PATH=/usr/local/cuda-12.5/lib64:\${LD_LIBRARY_PATH:+:\${LD_LIBRARY_PATH}}\n"  >> /root/.bashrc

# pyenvのインストール
RUN apt-get install -y build-essential libssl-dev libffi-dev libncurses5-dev zlib1g zlib1g-dev libreadline-dev libbz2-dev libsqlite3-dev make gcc liblzma-dev python3-tk tk-dev
RUN curl https://pyenv.run | bash
RUN echo "export PYENV_ROOT=\"\$HOME/.pyenv\""  >> /root/.bashrc
RUN echo "export PATH=\"\$PYENV_ROOT/bin:\$PATH\""  >> /root/.bashrc
RUN echo "eval \"\$(pyenv init -)\""  >> /root/.bashrc
RUN echo "eval \"\$(pyenv virtualenv-init -)\""  >> /root/.bashrc

# SSH接続のための設定
## "password"のところを任意のパスワードへ変更
RUN apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN echo '\nPermitRootLogin yes' >> /etc/ssh/sshd_config
## runしたときにSSH接続を開始
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

## コマンド
# docker build -f dockerfile -t ubuntu:24.04-cuda12.5-ssh .
# docker run -itd --gpus all --name sandbox ubuntu:24.04-cuda12.5-ssh
# docker run -itd --gpus all --name sandbox -p 10000:22 ubuntu:24.04-cuda12.5-ssh
# ssh root@127.0.0.1 -p 10000
```
年末なのでローカルブランチを整理してみた

年の瀬になると一年の振り返りや身の回りの整理をする人も多いのではないでしょうか。Git のブランチも同じく、いつの間にか **不要なブランチが増えて** しまっていることがあるかと思います。そこで今回は、不要なローカルブランチを一括で削除する方法と、そのコマンドがどう動いているのかを詳しく解説します。


## ローカルブランチ一括削除コマンド

```bash
git branch --format='%(refname:short)' \
  | grep -vE '^(master|main|develop)$' \
  | xargs git branch -d
```

## コマンド解説

### 1. `git branch --format='%(refname:short)'`
ローカルのブランチ名を、**短縮形式**（`refs/heads/xxx` ではなく `xxx` だけ）で出力するコマンドです。  
- `%(refname:short)` は、ブランチの完全な参照名（例：`refs/heads/feature/something`）を **短縮形**（例：`feature/something`）に変換します。  
- `:short` オプションがない場合、`refs/heads/` が付いたフルネームが出力されてしまい、後続の処理で文字列が一致しないなどの問題が発生する可能性があります。
- [参照](https://inaba.hatenablog.com/entry/2018/11/03/201545)

```bash
git branch --format='%(refname:short)'
```

この時点で **ローカルブランチの一覧** を取得できます。

### 2. `grep -vE '^(master|main|develop)$'`
取得したブランチリストから **特定のブランチ名を除外** します。  
- `-v` オプションは、**マッチしない行を出力** します。  
- `-E` オプションは、**拡張正規表現** を有効にします。  
- `'^(master|main|develop)$'` は、**行の先頭から末尾まで** 完全に "master"、"main"、"develop" のいずれかに一致する行を指定します。

したがって、この正規表現でマッチする **`master`, `main`, `develop`** は出力から除外されることになります。必要に応じて、削除したくないブランチがあれば追加してください。

### 3. `xargs git branch -d`
`xargs` コマンドは、**標準入力から受け取った文字列を引数として別のコマンドに渡す** 役割を果たします。  
ここでは、フィルタリング後のブランチ名を **`git branch -d`** にまとめて渡すことで、ローカルブランチを一括削除します。

```bash
xargs git branch -d
```

- `-d` は安全な削除で、未マージのコミットがあるブランチは削除できません。エラーが表示され、削除が中断されます。  
- 未マージブランチを強制的に消したい場合は `-D` を使用しますが、十分注意しましょう。


## 実行手順まとめ

1. **削除対象でないブランチにチェックアウト**  
   ```bash
   git checkout main
   ```

2. **まとめて削除を実行**  
   ```bash
   git branch --format='%(refname:short)' \
     | grep -vE '^(master|main|develop)$' \
     | xargs git branch -d
   ```

3. **エラーが出たブランチを強制削除したい場合**  
   ```bash
   git branch --format='%(refname:short)' \
     | grep -vE '^(master|main|develop)$' \
     | xargs git branch -D
   ```

## 注意点

- **チェックアウト中のブランチは削除できません。**  
  事前に削除しないブランチへ切り替えておきましょう。
- **未マージコミットの有無を要確認**  
  `-d` だと削除できずにエラーとなり、`-D` だと強制削除されます。必要なコミットが含まれていないか慎重に判断してください。
- **後から復元する方法はあるが手間がかかる**  
  万が一間違えて削除してしまった場合、`git reflog` やローカルのログで復旧できることがありますが、気をつけるに越したことはありません。

## まとめ

- 年末は身辺整理だけでなく、**ローカルブランチの整理** もやってみませんか？
- 今年中にローカルブランチをスッキリさせて、新たな気持ちで新年を迎えましょう。

---

よいお年をお迎えください！
BashでFizzBuzzコマンドを作ってみよう

## はじめに
プログラミングの基本問題としてよく知られているFizzBuzzをbashスクリプトで実装し、さらにコマンドとして使えるようにする方法を紹介します。

ブラウザ上でLinux環境を使える[エンベーダー](https://envader.plus/)を使用しました。
シナリオによってはvimが使えないシナリオもあるので、vimが使えるシナリオを使いました。
[Linux基礎コース Part1 テキストエディタ「vim」入門](https://envader.plus/course/15/scenario/1012)

## FizzBuzzとは
1から指定した数までカウントしていき、以下のルールで出力を変更するプログラムです：
- 3の倍数のとき → "Fizz"
- 5の倍数のとき → "Buzz"
- 15の倍数のとき → "FizzBuzz"
- それ以外 → その数字をそのまま出力

## コマンド化する手順

作成したスクリプトをコマンドとして使えるようにします：

### 1. binディレクトリを作成
```bash
mkdir bin
```

### 2. fizzbuzz実行ファイルを作成
```bash
vim ~/bin/fizzbuzz  
```

以下の内容でスクリプトを作成します：
引数で数値を指定すればその数までFizzBuzzを行い、何も指定しなければデフォルトの数までFizzBuzzをするように作成します。

```bash
#!/bin/bash

# 引数が無い場合は20をデフォルト値として使用
count=${1:-20}

# 1からcountまでループ
for ((i=1; i<=$count; i++)); do
        if [ $((i%15)) -eq 0 ]; then
                echo "FizzBuzz"
        elif [ $((i%3)) -eq 0 ]; then
                echo "Fizz"
        elif [ $((i%5)) -eq 0 ]; then
                echo "Buzz"
        else
                echo $i
        fi
done
```

### コードの解説

1. シバン（`#!/bin/bash`）
   - スクリプトを実行する際に使用するインタプリタを指定
   - この場合はbashを使用することを示しています

2. 引数処理（`count=${1:-20}`）
   - `$1`: スクリプトの1番目の引数
   - `:-`: デフォルト値演算子（引数が無い場合に使用する値を指定）
   - `20`: デフォルト値

3. forループ（`for ((i=1; i<=$count; i++)); do`）
   - C言語風の構文でループを記述
   - 1から指定された数（count）まで繰り返し

4. 条件分岐
   - `$((i%15))`: 15で割った余りを計算
   - `-eq 0`: `-eq` はequal（イコール）の略。余りが0かどうかを判定
   - 同様に3の倍数、5の倍数をチェック

bashで数値計算を行う際には $(( )) を使用します。これにより、C言語風の演算が可能になります。

```bash
$((i%15))  # iを15で割った余りを計算
```

### 3. 実行権限を付与
```bash
chmod +x ~/bin/fizzbuzz
```

### 4. PATHを通す
```bash
# ~/.bashrcに以下を追記
export PATH=$PATH:~/bin

# 設定を反映
source ~/.bashrc
```

これで `fizzbuzz` コマンドとして使用できるようになります。

## 使い方

```bash
# デフォルト（20回）で実行
fizzbuzz
```
```bash
#　出力結果
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
```

引数を指定するとその数まで実行
```bash
envader@172-19-2-2:~$ fizzbuzz 30
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
```

無事にFizzBuzzが実行できました。

## おわりに
bashスクリプトでFizzBuzzを実装し、コマンド化することで、スクリプトの知識やコマンド化するまでのプロセスを理解するのに良いと思います。
この例を元に、他にも面白いコマンドを作って遊んでみてください。
【HULFT10】新機能の紹介と所感


## はじめに
この記事は [**セゾンテクノロジー Advent Calendar 2024**](https://qiita.com/advent-calendar/2024/saison-tech) 25日目の記事です。
シリーズ2は [**HULFT10**](https://www.hulft.com/software/hulft-10) のエンジニアによる投稿をお届けします。

本記事は2024/12に執筆されたものです。
最新の情報や正しい情報は公式ページをご確認ください。

また、HULFT10 for Container Services については言及しておりません。

## HULFT10 の追加機能

追加機能について、下記を参照しながらまとめました。

https://www.hulft.com/help/ja-jp/HULFT-V10/COM-NEW/Content/HULFT_NEW/FuncAdd/HULFT10_AddFunc.htm?tocpath=1.%20HULFT10%E3%81%AE%E8%BF%BD%E5%8A%A0%E6%A9%9F%E8%83%BD%7C_____0

### 共通追加機能
|機能|対象製品|
|:--:|:--:|
|Zstandard圧縮|HULFT 10.2.0|
|HULFT Smart Proxy|HULFT 10.2.0|
|HULFT API Gateway|HULFT 10.2.0|

### HULFT10 for zOS固有の追加機能
|機能|対象製品|
|:--:|:--:|
|DEFLATE圧縮|HULFT 10.2.0|

それぞれ機能とコメントを行っていきます。



## Zstandard圧縮
Zstandardと呼ばれる新規の圧縮方式が追加されました。
>「Zstandard」または「ZSTD」と呼ばれる圧縮アルゴリズムに対応した圧縮方式を追加しました。
>DEFLATE圧縮とほぼ同じ圧縮率ですが、圧縮および展開が速いことを特徴とする可逆圧縮アルゴリズムで動作します。
>また、大容量のファイル転送時、ネットワークの帯域の消費を削減でき転送時間を大幅に短縮することも可能です。
>さらに、Zstandard圧縮はDEFLATE圧縮に比べて、より高速に圧縮および展開を行います。

本件については、初期の選出や研究開発からタッチしていたこともあり、HULFT 10としてリリースできたことに喜びを感じています。
記載時点での実装対象はWindows,Linux/AIXで、惜しむべきはIBM iにて対応が行えなかったことです。
ここで終わりではなく、引き続き Challengeしていきたいです。

## HULFT Smart Proxy

https://www.hulft.com/software/hulft-10/lineup/smart-proxy

>HULFT10 Smart Proxyを経由させることで、オンプレミス環境にあるHULFTのシステム構成を変更することなく、 インターネット経由での安全なファイル集配信を実現します。

本機能を用いることで、インターネット経由の転送を行うことができるようになりました。
HULFTの新たな利用体系として、活用シーンが広がるのではないかと考えています。

![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651737/14cfb199-ae68-398e-d708-db3bee795d4b.png)


## HULFT API Gateway

https://www.hulft.com/software/hulft-10/lineup/api-gateway

>Web画面から複数HULFTの管理情報や集配信履歴を一元管理し、REST APIで外部サービスと連携することが可能です。
>接続先のプラットフォームを問わず、同一の操作方法で運用できます。

HULFT 10としては、設計Rvやテスト工程などに参加しました。
HULFTの新たな操作方法の1つとして、利用シーンが広がる結果となれば良いなと考えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651737/aa747a4d-cc26-015b-7e1f-f94d1ee5f9fd.png)


## DEFLATE圧縮(zOS)
zOSにて、DEFLATE圧縮が可能となりました。
HULFT全体としては、V8.0から実装された機能となっており、
zOSとしてはHULFT 10にて追いついた形となっています。




## おわりに
HULFT 10 の新機能についてまとめ、コメントを記載させていただきました。
これからのHULFT 10にもご期待いただければ幸いです。
SWRキャッシュの理解

## 概要

vercel出品のAPI通信ライブラリSWRの利用中に気づいたキャッシュのことをメモする

## SWRキャッシュの仕組み

- ReactのContextに保存するグローバル的参照で、キャッシュを共有している
- SWRでAPIアクセスすれば、自動的にキャッシュ機能が利用される

```tsx
<SWRProvider>{children}</SWRProvider>
```

```tsx
export const SWRProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
  return (
    <SWRConfig value={{ fetcher: fetch, revalidateOnFocus: false }}>{children}</SWRConfig>
  );
};
```

## キャッシュの動き

- SWRConfigにdedupingInterval設定があり、デフォルト値が2秒
- 2秒以内であれば、API通信せずキャッシュデータを利用
- useSWRフック経由で複数のところから同じapi通信を実行しようとしても、SWR内部のコントロールにより実は１つのapi通信しか発生しない
  - かなり良い機能
  - 色んなコンポーネントから発生するapi通信の重複排除の工数がなくなる
  - RSC（React Server Component）でnext.jsのRequest memoization機能がこれと似てる

```
dedupingInterval = 2000: この期間内での同じキーのリクエストを重複として排除します
```

## キャッシュあり場合の画面描画

SWR(Stale While Revalidation)の思想によりその場で描画される

- 古いキャッシュデータでその場にすぐ描画される
- 並行でAPI通信が走る
- API通信が終わったら、最新のレスポンスデータで再描画する

## 古いキャッシュを手動で捨てる

検索条件がSWRのキーに入る場合、細かい検索条件の変更に伴い、キャッシュMapのkeyとvalueがどんどん増えていく。valueにはサイズが大きくて、古いデータがメモリを圧迫するような気がする場合、それをクリアしたくなるかも。

- uswSWRの戻り値のmutateを使ってクリアする

```js
mutate(undefined, false);
```

## 参考記事

- [SWRキャッシュ](https://swr.vercel.app/ja/docs/advanced/cache)
G検定:重要な人名と行動のまとめ


+ アーサー・サミュエル
機械学習の定義「明示的にプログラムしなくても学習する能力をコンピュータに与える研究分野」

+ アラン・チューリング
ある機械が人工知能かどうか判定する「チューリングテスト」の考案者。
チューリングテストは、審査員(人間)に相手が機械であることを伏せて対話させ、機械と見抜けるかどうか試すテスト。

+ イアン・グッドフェロー
敵対的生成ネットワーク(GAN: Generative Adversarial Network) の考案者

+ イーロン・マスク
シンギュラリティ到来に危機感を持ち、AI研究組織「Open AI」を設立

+ ヴァーナー・ヴィンジ
著書で、シンギュラリティを「機械が人間の役に立つふりをしなくなること」と定義

+ オレン・エツィオー二
シンギュラリティーに対して「たとえば100万年後、特異点を迎える可能性はあります。けれど賢いコンピュータが世界制覇するという終末論的構想は『馬鹿げている』としか言いようがありません」と発言

+ ジェフリー・ヒントン
ImageNet データセットを画像認識の制度を競う ILSVRC というコンペティションの 2012年優勝者。本コンペでニューラルネットワーク(AlexNet)を用いて圧倒的な成績で勝ったため、ディープラーニングが一気に脚光を浴びた。

+ スティーブン・ホーキング
シンギュラリティーに対して「AIの完成は人類の終焉を意味するかもしれない」と述べた

+ ヒューゴ・デ・ガリス
シンギュラリティーは21世紀の後半に来ると予想し、その時に人工知能は人間の知能の1兆の1兆倍(10^24倍) になると主張。 

+ ヤン・ルカン
1990年代、畳み込みニューラルネットワーク(CNN：Convolutional Neural Network）」の基礎となる LeNet(5) を発明 。
敵対的生成ネットワーク(GAN: Generative Adversarial Network) に対して、「機械学習において、この10年間で最もおもしろいアイデア」と発言。

+ レイ・カーツワイル
自著「The Singularity is Near」で「シンギュラリティーは2045年に到来する」と述べる。
物理数学教科書ガイドp483(2024年3月版)「行列の固有値をsympyのソースコードと結果を教えて下さい。」をAI先生に聞きました。

・タイトル名変更予定です。
・本ガイドの目次作成予定。
　しばらく?上記の 物理数学教科書ガイド のタグでお願いします。

# 数学—物理を学び楽しむために—暫定版(2024年3月) 様
7.6.1 行列の固有値と特性方程式 468  
**PDF=p483**(=469+14) (スクショ貼り付けの省略。以下別々に実行しています。)
(本行省略)スクショ貼り付け。実行。
**上記の行列の固有値をsympyのソースコードと結果を教えて下さい。**
**上記のmathjaxのコードを教えて下さい。**

```math
A = \begin{pmatrix} a & b \\ c & d \end{pmatrix}
```

以下のページへの直接のリンクはしていません。
＞ファイルのダウンロード　通常版（12 ポイント） (pdf 8.4 MB)
＞https://www.gakushuin.ac.jp/~881791/mathbook/

# sympy実行サイト

https://live.sympy.org/

・sympyの開発環境は、ページ後半です。

# ChatGPT先生へ
>(回答抜粋)

```python
from sympy import symbols, Matrix

# 変数の定義
a, b, c, d = symbols('a b c d')

# 行列の定義
A = Matrix([[a, b], [c, d]])

# 固有値の計算
eigenvalues = A.eigenvals()

# 結果の出力
eigenvalues

# 私が、以の行を追加しました。
eigenvalues.simplify()
```
```python
{
    (a + d - sqrt((a - d)**2 + 4*b*c)) / 2: 1,
    (a + d + sqrt((a - d)**2 + 4*b*c)) / 2: 1
}
```
上記の辞書の結果を、sympyで取り出す方法を教えて下さい。
>SymPyで eigenvals() 関数を使用すると、固有値とその重複度（重根を持つ場合）が辞書として返されます。この辞書から固有値だけを取り出す方法を以下に示します。
```python
[
    (a + d - sqrt((a - d)**2 + 4*b*c)) / 2,
    (a + d + sqrt((a - d)**2 + 4*b*c)) / 2
]
```

# Gemini先生へ
未

# copilot先生へ
未

# wolframalpha先生へ
＞いい方法があれば教えて下さい。

https://www.wolframalpha.com/input?i=Matrix%28%5B%5Ba%2C+b%5D%2C+%5Bc%2C+d%5D%5D%29+%E3%81%AE%E5%9B%BA%E6%9C%89%E5%80%A4&lang=ja

https://www.wolframalpha.com/input?i=eigenvalue%28+Matrix%28%5B%5Ba%2C+b%5D%2C+%5Bc%2C+d%5D%5D%29+%29+&lang=ja

??? 結果(正方行列ではありません．固有値が定義されていません)


# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342) 　開発環境

# いつもと違うおすすめです。
#### sympyのDoc
Eigenvalues, Eigenvectors, and Diagonalization

https://docs.sympy.org/latest/tutorials/intro-tutorial/matrices.html#eigenvalues-eigenvectors-and-diagonalization

#### wikipedia

https://en.wikipedia.org/wiki/Eigenvalues_and_eigenvectors

https://ja.wikipedia.org/wiki/%E5%9B%BA%E6%9C%89%E5%80%A4%E3%81%A8%E5%9B%BA%E6%9C%89%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB

#### Qiita

https://qiita.com/tags/%e7%89%a9%e7%90%86%e3%82%92%e9%80%9a%e3%81%97%e3%81%a6%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0%e5%85%a5%e9%96%80

＞固有値・固有ベクトルの使いみち @Ken-ichi_Hironaka

https://qiita.com/kaizen_nagoya/items/a8c13888e23f9b7e57d2#%E5%9B%BA%E6%9C%89%E5%80%A4%E5%9B%BA%E6%9C%89%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E3%81%AE%E4%BD%BF%E3%81%84%E3%81%BF%E3%81%A1-ken-ichi_hironaka
Raspberry pi5をSSDインストールするときに必要なもの

# 一癖あるRaspberry Pi5のSSDインストール

RasoBerry pi5はSSDハット[^KEY]を使用して、OSプログラムの読み込みをSDカードからではなくSSDから読み込むようにすることで大幅な高速化が可能になりました。
しかし、インストールするのに必要なものを揃えていなかったりすると少々回り道が必要になります。
今回は備忘録とレビューも含めて記事を書いていきます
[^KEY]: 専用外付け回路基板
# 必要な物
## Raspberry Pi5の動作に最低限必要なもの
最低限Raspberry Pi5を動作させるには以下のものが必要になります。
* Raspverry Pi5本体
* 5.1V USB-typeC電源 3A以上
* OS書き込み用記憶媒体
* OS書き込み用記憶媒体にデータを書き込めるデバイス

USB-typeC電源はRaspberry Pi4までの電源よりも電圧が上がっているため注意が必要です。万全の状態で稼働させたい場合は専用の電源を購入しましょう。
https://www.amazon.co.jp/dp/B0CXXXDB71?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216739/573fe623-c404-b2e8-e474-3946df03bd8a.png)

OS書き込み用記憶媒体の選定ですが、これまでのRaspberryPiと同じような運用をする場合は
* microSDカード(32GB以上)
* microSDカードリーダ
で問題ありません。

SSDで運用したい場合は
* 使用するSSDハットに対応したサイズの **NVMe** のM.2 SSD(大抵の場合SATAのSSDは対応していません)
* M.2 SSDにデータを書き込める外付けSSDドライブ等のデバイス
が必要になります。

ここで注意したいのがSSDハットの対応サイズです。
M.2 SSDには今のところ以下の5サイズがあり、下にいくほどサイズが大きくなっていきます。
サイズの違いはメモリICの数だったり、保護システム用ICの有無等によるようです。
 * Type2230
 * Type2242
 * Type2260
 * Type2280
 * Type22110
 
そしてM.2 SSDはハットにネジで留めるのですが、当然ながらハットに対応するサイズ用のネジ穴が無い場合は固定できません。
ハットがサイズに対応していない場合は取り付けることができませんので注意して選定してください。

また、M.2 SSDにデータを書き込める外付けSSDドライブ等のデバイスが無い場合は、少々まわりくどい方法でmicroSDカードを使用してインストールすることになります。
https://www.youtube.com/watch?v=93oby86Nvkw
詳しくは上記リンクの動画が参考になります。
具体的にはまずmicroSDにraspberryPiのOSイメージを書き込んで起動させて、そこからSSDにraspberryPiのOSイメージを書き込んで、ブートを「microSDから」を「SSDから」に変更するという手順となります。
M.2 SSDにデータを書き込める外付けSSDドライブ等のデバイスがある場合はこの2回の書き込みを1回にすることができるのでついでに購入しておきましょう。

ただこの状態では回路基板むき出しですので、すぐに何かのデバイスに組み込んでしまうといった運用でない限り常にショートの危険性が伴います。また、Raspberry Pi5は公式が冷却ファンを推奨する程度には発熱します。安全に運用するには次にものが必要になります。

## Raspberry Pi5の安定運用に必要なもの
* Raspberry Pi5とSSDハットに対応したケース
* 冷却用ファン

ケースを導入することで、ショートの可能性を格段に下げることが可能になります。ただ、ケースはハットやファンとの相性問題があります。Raspberry Pi5自体が従来のケースとは互換性が無く、ハットや搭載SSDによってもケースとの相性があります。
そこで私はケースとSSDハットとファンがセットになった以下のセットを購入しました。
https://www.amazon.co.jp/dp/B0CXP461N3?ref=ppx_yo2ov_dt_b_fed_asin_title
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216739/dd9f58e5-5132-7a51-a9a1-6aaa7770e2ee.png)

### 利点
* M.2 NVMe SSDの2230 2242 2260 2280といったかなり大型のSSDまで対応したハットが付属しているケースのため、SSDの大きさ等による相性問題がない
* 外部のマイコン等を使用する場合はコネクタを使用してサイドの穴からケーブルを出すことで対応可能
* 予備のネジやケーブルが複数入っている
### 欠点
* サイズの問題でさらに他のハットを取り付けることができない
* ハードウェアのUARTシリアル通信のピンが埋まってしまうので、シリアル通信デバイスを使ったsshログインや直接のシリアル通信でのマイコン制御が行えない（ソフトUARTやUSBからのシリアル通信は可能）

単体でサーバー等として用いる分には問題が無いケースです。

SSDは3000円を切っていた以下の250GBのものを使用しました。
https://www.amazon.co.jp/dp/B07WDQ9GQF?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216739/bdcbd747-5031-dfff-2c0d-8a058451652a.png)

相性問題等は特になく動作しているので問題はありません。

# おわりに
以上がRaspberry Pi5にSSDを組み込む際に必要なものとなっています。
これまでのRaspberry Pi4と同じノリで調べずに買うと損をしますので注意してください。
CLI、はじめてみました (Part1)

## 本記事の目的
Command-line interface (CLI)で使えるTipsを備忘録としてまとめていきます！

## No.0001
mkdirでサブフォルダーまで一気に作成
```zsh:zsh
mkdir -p {p1,p2,p3}/{sub1,sub2,sub3}

# 以下のフォルダ階層が一気に作成可能！
# p1/
#   sub1
#   sub2
#   sub3
# p2/
#   sub1
#   sub2
#   sub3
# p3/
#   sub1
#   sub2
#   sub3
```
-p引数で親ディレクトリがなくても動作する
スペースが入ると動作しないので注意

## No.0002
フォルダ移動に疲れました、、
```zsh:zsh
cd -
```
直前まで作業していたフォルダに移動!
神業ワープ

## No.0003
上司から司令 
-> 直ちに1000ファイル作成して
-> はいぃ！？
```zsh:zsh
touch testfile{1..1000}.txt
```
testfile1, testfile2, ..., testfile1000を一瞬で作成
ドヤ顔で定時直帰ですね

## No.0004
ええと、最近使ったコマンドでいいものがあったはず、、、
```zsh:zsh
history 5

# 73 cd test
# 74 cd sub1
# 75 npx fast-cli --singleline

!75
```
番号指定して以前のコードを実行可能！

# 最後に
Tipsは便利です

:::note info
**皆さんの経験談やTipsもぜひコメントください！**
:::
オリジナルreCAPTCHAを作って共有できるウェブアプリを作った話 #個人開発

# 初めに
**※先に言っておきますがこのウェブアプリは公開しておりません。詳細は後半に**
reCAPTCHAの画像を選択する形式のやつってたびたびネタ画像が投稿されるじゃないですか。ジェネレーターみたいなのはあったのですが、それを共有できて実際に遊べる奴があれば面白いんじゃないかと思ったのが今回このウェブアプリを作ったきっかけです。意外といい感じにできたんじゃないんでしょうか,,,？
**完成品**
reCAPTCHA制作画面。パネルの数は2枚、4枚、9枚から選択できる。最大で3問作れる。
![スクリーンショット 2024-12-27 020957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926068/9aef978a-1377-2b47-de12-c076facdc6ef.png)
共有URLに飛ぶと遊べる
![スクリーンショット 2024-12-27 021155.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926068/950c5dec-0bee-a8c1-0723-dcda64294572.png)
全部正解するとメッセージが見られる
![スクリーンショット 2024-12-27 021218.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926068/2af24d71-fa82-3f7d-6963-450913a2cb93.png)
# 主な使用技術
* Flask
* Vue.js
* MySQL
* Cloudinary
ほかにはBootstrapとかcropper.jsとか使ってたりもします。
# 制作について
そんな大きなアプリじゃないので普通にFlaskとVueで基本的なところ組んでMySQlに保存するって感じでしたが、画像を保存するためにCloudinaryを初めてちゃんと触りました。すごく手軽に使えるのに加えて無料プランもストレージが25Gも用意されていてこんなあっちゃっていいの？！って思います。Cloudinary、個人開発ならめっちゃおすすめです。
> [Cloudinary](https://cloudinary.com/)
### 画像の保存
前述のとおりCloudinaryを使って画像の保存をしています。保存するまでの話ですが、まずユーザーが画像を挿入するときcropper.jsを使って画像をトリミングできるようにしています。これ結構便利だと思うんですよね。
![スクリーンショット 2024-12-27 022941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926068/528334d4-5300-e989-0e93-59ec3fc2feb0.png)
また、Cloudinaryに保存する前で画像のサイズをできるだけ小さくするためpythonライブラリのPillowで300*300に画像をカットしたのちwebp形式で保存しています。はい、そうですね。画質はすんごい落ちます。今回のアプリで画質の高い低いはそんなに関係ないっていうのと、本家reCAPTCHAの画像の画質なんていつも粗いから画質なんてちょっと落ちても大丈夫やろっ！ていうスタンスです。
しかし今回のアプリの場合デプロイしなかったのでそんなにサイズ落とす意味もなかったような気がしますね,,,。
### 共有機能
画像や正解、タイトルなどを入力した後に共有ボタンを押すと共有URLが生成されるようになっていて、それに飛ぶとそのreCAPTCHAで遊べるようになっています。
URLは「/play?t=ランダムな20文字の文字列」って感じです。全部正解すると制作者のメッセージなどが見られますが、逆に何回か失敗すると「あなたはロボットと判断されました」というメッセージが出てくるようになっています。画像以外の情報は全部MySQLに入れています。

# 頑張り点
本家のreCAPTCHAになるべく近づけるようなアニメーションとUIを目指しました。
> 色々なアイコンを提供してくれる[icooon mono](https://icooon-mono.com/)様に感謝です,,,!!

意外とcropper.jsらへんのトリミングした後の画像をやり取りが難しかったですね。トリミングしないでそのまま送信するなら簡単なんですがトリミングしたとなると、cropper.jsのキャンパスから画像をbase64でエンコードされたものが渡されるのでpython側でデコードしたのち更にpillowでの処理とcoudinaryへの保存をするためバイトストリームに変換しないといけないので手間がかかりました。画像らへんは慣れていなかったので手間取りましたね,,,。

# デプロイについて
どうせならとpythonanywhereでデプロイしようとしたんですが無料プランだと使えるAPIに制限があるらしく、cloudinaryが対象外だったため諦めました。renderはデータベースが一定期間後削除されてしまうので今回は見送りました。よってデプロイできていません！これら以外によい選択肢があれば教えてください(泣)。

# 最後に
結構思い付きの勢いで作り上げたものなんですが意外と凝ってしまって1週間半ほどかかっています(毎日一日中やってたわけではありませんが,,,。)。しかし想像以上に満足のいくものに仕上がってうれしいものがあります。特に実際に遊べるページのところでは本家に結構近い動きとUIになっているのではないでしょうか？また、本家にはない2枚パネルのreCAPTCHAが個人的に気に入っています。最大で３問用意できるので２問目までを4枚または9枚パネルで作っておいて、あと1問っ！てなった最後の問題で究極の2枚パネルってなんか熱くなりません,,,?w
私事ですが最近アイデアがストックしているのでこういうネタアプリでもどんどん作っていくかもしれません。それに対して、最近Vueを薄ーくしか理解していない気がして講座を購入したのでそっちのほうの勉強もやっていかなきゃでやりたいことが多すぎますね,,,w
ではまた次の機会に！
止まらないU-Boot

c1kのU-Bootがhit any keyにキー入力しても止まりません。loginプロンプトがでたから入力するとちゃんと出るので接続は間違いありません。どうも特定のキーのみ受け付けるようです。キーボードをがちゃがちゃやると止まる時があります。ありそうなスペース,エスケープ,コントロール+Cはだめでした。

一度止まったらオートブートを消します。そうすると起動時にU-Bootで止まります。

```
Comcerto-1000 > setenv bootcmd
Comcerto-1000 > saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Comcerto-1000 > 
DDR Training...........................................................................................Done

U-Boot 1.1.6 (Jun 21 2010 - 16:32:55) Mindspeed $Name: u-boot_4_00_4 $

DRAM:  128 MB
Comcerto Flash Subsystem Initialization
Flash: 32 MB
In:    serial
Out:   serial
Err:   serial
Reserve MSP memory
DDR Training : 
DLL_ADJ(0,1,2,3): 0x24,0x27,0x25,0x27
WR_DQS:delay0 0x8b, delay1 0x8c, delay2 0x8c, delay3 0x8d
Net:   comcerto_gemac0, comcerto_gemac1
Comcerto-1000 >
```

こうしてしまうと毎回起動時にオペレーションが必要になります。

u-bootを吸い上げて逆アセンブラして調べるなどの方法が考えられますが、NetBSDがすこぶる安定しているので、これで良しとします。

u-bootでsaveenvが出来る場合、起動やflash書き込みオペレーションを適当な名前でsetenvしておくとrunで実行できるので便利です。

他のターゲットでFlashがSPIの場合、一度外してflashromで読み出して、bootの部分だけ書いて戻すと、カーネルイメージが見つからずプロンプト落ちて止める事が出来たケースもありました。

ARecX6のu-bootも止まらなかったので、openocdでu-bootを焼直しました。

Z-LOADERはopenocdで[設定いじり](https://qiita.com/yamori813/items/d6f599cb6ca648f343d8)ました。OpenWRTをインストールすると設定してくれるようなのでそれでもいいかもしれません。
PyCaretを徹底解説！処理内容からハイパーパラメータ調整、計算効率化の工夫まで

機械学習をもっと簡単に、そして効率的に！  
Pythonの便利なライブラリ「PyCaret」を活用すれば、初心者でも手軽に機械学習モデルを構築し、高度なデータ分析が可能です。今回は、PyCaretの「処理内容」「ハイパーパラメータの調整方法」「計算効率化の工夫」を分かりやすく解説します。
※この記事は、ChatGPTの出力を基に作成しています。

---

## **1. PyCaretの処理内容**

PyCaretは、機械学習に必要な一連の作業を簡潔なコマンドで実行できます。その処理は以下のステップで進みます。

### **ステップ1: データの準備**
最初に分析対象のデータを準備します。PyCaretでは、CSVやExcelファイルの読み込みが可能で、セットアップ時にデータ型や欠損値処理も自動で行われます。

```python
import pandas as pd
from pycaret.regression import *

# データの読み込み
data = pd.read_csv('data.csv')

# PyCaretのセットアップ
setup(data, target='売上')
```

### **ステップ2: モデルの比較**
`compare_models()`を使うと、複数の機械学習モデルを比較し、最適なモデルを選定します。例えば、線形回帰やランダムフォレストなど、さまざまなアルゴリズムを一括で評価可能です。

```python
best_model = compare_models()
```

### **ステップ3: ハイパーパラメータの調整**
モデルのパフォーマンスをさらに高めるために、`tune_model()`でハイパーパラメータの自動調整を行います。詳細は後述します。

```python
tuned_model = tune_model(best_model)
```

### **ステップ4: モデルの評価と予測**
作成したモデルを評価し、新しいデータに基づいて予測を行います。

```python
# モデルの評価
evaluate_model(tuned_model)

# 予測
predictions = predict_model(tuned_model)
```

### **ステップ5: モデルの保存**
学習済みモデルを保存し、再利用することも簡単です。

```python
save_model(tuned_model, 'final_model')
```

---

## **2. PyCaretのハイパーパラメータ調整方法**

ハイパーパラメータ調整（チューニング）は、モデルの性能を最大化する重要なステップです。PyCaretでは、簡単なコマンドでこれを実現できます。

### **デフォルトの方法: ランダムサーチ**
PyCaretの`tune_model()`は、デフォルトで**ランダムサーチ**を使用します。ランダムサーチは、指定されたハイパーパラメータの範囲からランダムに値を選び、効率的に最適な設定を探します。

```python
tuned_model = tune_model(best_model)
```

### **カスタム範囲の指定: グリッドサーチ**
グリッドサーチを使いたい場合は、`custom_grid`でパラメータの範囲を指定します。これにより、全ての組み合わせを試す網羅的な探索が可能です。

```python
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 10, 15]
}

tuned_model = tune_model(best_model, custom_grid=param_grid)
```

### **高度な最適化: ベイズ最適化**
PyCaretは、追加ライブラリ（例: Optuna）を利用して**ベイズ最適化**を実行できます。ベイズ最適化は過去の試行結果を元に効率的な探索を行う手法で、複雑なパラメータ空間に適しています。

```python
setup(data, target='label', optimize=True, optimizer='optuna')
tuned_model = tune_model(best_model)
```

### **どの手法を選ぶべき？**
- ランダムサーチ: デフォルトで十分に高速かつ効果的。
- グリッドサーチ: パラメータ範囲が狭い場合に最適。
- ベイズ最適化: 高次元かつ複雑なパラメータ空間に最適。

---

## **3. PyCaretの計算効率化の工夫**

PyCaretは計算を高速化するための工夫が豊富に施されています。

### **1. 並列処理**
PyCaretは、内部で機械学習モデルのトレーニングや比較を並列化しています。多くのモデルが`n_jobs=-1`をサポートしており、すべてのCPUコアを活用して計算を高速化します。

### **2. データサンプリング**
`setup()`で`train_size`を指定すると、データセットの一部だけを使うことで計算負荷を軽減できます。

```python
setup(data, target='label', train_size=0.7)
```

### **3. GPUの活用**
GPU対応のライブラリ（LightGBMやXGBoostなど）を利用して、高速な学習を実現できます。

```python
setup(data, target='label', use_gpu=True)
```

### **4. 最適化されたライブラリの活用**
PyCaretは以下のような高速な機械学習ライブラリを活用しています：
- **LightGBM**: 大規模データに最適な勾配ブースティング。
- **XGBoost**: 並列計算が得意なブースティングアルゴリズム。
- **CatBoost**: カテゴリデータの処理に優れた高速アルゴリズム。

### **5. モデル選定プロセスの効率化**
`compare_models()`では、モデルの比較を効率化する工夫が施されています。特に、上位N個のモデルだけを探索することで計算量を削減できます。

```python
top_5_models = compare_models(n_select=5)
```

---

## **まとめ**

PyCaretは初心者でも手軽に使える強力なツールであり、以下の特徴があります：

1. **直感的な処理フロー**：データの準備からモデルの保存まで、シンプルなコマンドで完結。
2. **ハイパーパラメータの自動調整**：ランダムサーチやグリッドサーチ、ベイズ最適化に対応。
3. **計算効率化の工夫**：並列処理、GPU対応、データサンプリングなどの手法で高速化を実現。

これらの工夫により、PyCaretは効率的かつ柔軟に機械学習プロジェクトを進めることが可能です。初心者からプロフェッショナルまで、幅広いユーザーにおすすめできるツールです。ぜひ一度試してみてください！
AIハッカソン参加録【2024 最優秀賞】

# はじめに
## 開発経緯
先日、「生成AIで山梨を盛り上げよう」というテーマでYAMANASHI AIハッカソン2024が開催されました。そこで、私のグループは山梨県のコロナ後の観光業の回復に着目し、山梨県の魅力を伝えるAIエージェント、**やまなしNAVI**を開発することになりました。

## アプリの概要
- 対話形式のチャットボット（というよりは**エージェント**）
- 現在地、移動手段、季節、やりたいこと（行く、食べる、遊ぶ）などに基づき、候補となるスポットの提案をする
- ユーザーの要求に応じて、スポットについての詳細な説明をしたり、天気などのアドバイスもできる

## フロントエンド
ハッカソンでは、LINEの他にオリジナルのWEBを作成したましたが、今回はLINEのみを取り上げます。

### LINE MessegingAPI
バックエンドとLINEと連携するのに[LINE MessegingAPI](https://developers.line.biz/ja/)を使用しました。
以前、[GoogleAppScript](https://script.google.com/)を用いてLINEチャットボットを開発したことがありましたが、今回はバックエンドにDjangoを採用したことからPythonで呼び出すことになりました。

## バックエンド

### フレームワーク
豊富なライブラリを備えていて、柔軟なコーディングが...というのは建前で、一番長く使っているのがDjangoだったからです(´;ω;｀)
`Django==4.2.0`を使用しました。APIを簡単に扱うため、REST Frameworkを採用しました。(`djangorestframework==3.15.2`)

### API
使用したのは
- LINEと連携する[LINE MessegingAPI](https://script.google.com/)
- 任意の場所の画像を取得するための[GoogleMapsAPI](https://developers.google.com/maps?hl=ja)
- 生成AIのプラットフォームとして[Dify](https://docs.dify.ai/ja-jp)

## AIプラットフォーム
### 選定（時系列）
- ChatGPTのカスタムモデルである[GPTs](https://www.multifverse.com/blog-posts/custom-gpt-creation-guide)
RAGの機能を持つことから、ローカルなデータを扱うのに適していると考え採用し、回答にもそれなりの精度が得られた。が、APIを提供していないことが判明し、断念。
- [OpenAIのAssistantsAPI](https://platform.openai.com/docs/assistants/overview)
こちらはAPIを提供しており、RAGも備えていました！が、GPTs程の精度が得られず、没。
- [Dify](https://docs.dify.ai/ja-jp)
こちらはAPIも提供しており、精度もかなりよかったので採用！！

### プラットフォームの課題と工夫
LLMモデルのみによるチャットボットは情報が古かったり、ローカル情報に弱かったりしますが、Difyを採用することで**RAGによるローカル情報の補完**＆**リアルタイム検索による適時性の向上**が期待されます。



### Difyの特徴
1. ノーコードツール
ノードを線で繋いでいくことで、簡単にAIアプリが作成できるので、プログラミング経験者でなくても開発に参画できる！
2. RAG機能
RAG（[RAGとはなにか？](https://aws.amazon.com/jp/what-is/retrieval-augmented-generation/)）を用いることで、LLMに蓄積された一般的な情報だけでなく、ローカルな情報（例えば、〇〇レストランの営業時間、など）を出力に加味することができる！
3. ブラウジング機能
インターネット検索の結果から情報を補完できるから、比較的新しい情報にアクセスできて、回答の精度も向上する！今回はGoolge Search、Wikipedia、Open weather or Googleをアクション出来るようにしました
4. AIモデルが選べる
使用するモデルやバージョンを選べるから用途よって、速度や精度のトレードオフを簡単に反映できる！
5. デフォルトのフロントエンドが用意されている
モデルの作成後、簡単に挙動の確認、配布ができる！

## 技術スタック
![技術スタック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778684/817fec04-3009-88f6-ece7-91430dfba94c.png)
EC2のマイグレーション作業(AL2 →AL2023)について②

## はじめに
前回書いた記事の続きになります

https://qiita.com/tomoya0117/items/15f8571e229e56c71284
 
今回はEC2の切り替え方法についての記事になります
## 構成
切り替え前の構成
![EC2-2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/f1a66904-07d3-0d5b-69c6-aa9d4e9259c3.png)
## 前提
・AWSコンソールの操作権限があること
・新規作成したEC2にGIPがあること
・この手順はwindows環境で操作しています
## 切り替えについて
今回は以下の手順で切り替えを行いました
**・切り替え前の接続確認**
**・ALBのターゲットグループの付替え**
**・ElasticIPの付け替え**
## 切り替え前の接続確認方法
EC2を切り替える前に、作成したサーバーに接続できるかを確認します。
接続確認のために、windowsのhostsファイルに作成したサーバーを登録します。
windowsのhostsファイルは以下にあります。
**C:\Windows\System32\drivers\etc**
メモ帳を「管理者として実行」で開きます。
メモ帳の「ファイル」→「開く」を選択→「すべてのファイル」を選択してhostsファイルを開きます。
![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/d1fd4324-b384-0b7d-1470-b7841d2c53b3.png)


このファイルに、新規作成したEC2のGIPと任意のドメイン名を記載します。
ファイルを保存すると、任意のドメイン名が指定したGIPに解決されるようになります。
Chromeのシークレットモードなどを使ってアクセスすると、設定に問題がなければサーバにアクセスできるようになります。
## ALBのターゲットグループの付替え
ALBのターゲットグループの付替え方法については以下の公式サイトが参考になります。

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/target-group-register-targets.html#register-instances

ターゲットグループの付け替えは以下の手順で実施します
指定のターゲットグループに作成したEC2を登録します
１．「ターゲットの登録」→「登録したいEC2を選択」→「保留中として以下を含める」を選択します。
![スクリーンショット 2024-12-27 092838.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/e6103547-7808-2b16-a47f-dd386c1d5f2b.png)
２．ターゲットグループに追加されたことを確認したら「保留中のターゲットの登録」を押下します。
追加したEC2の状態が「実行中」となっていることを確認してから、古いEC2を選択して「登録解除」を押下します。
登録解除が完了すると、ターゲットグループの付け替えは完了となります。
## ElasticIPの付け替え
ElasticIPの付け替えについては、以下の過去に自分が作成した記事や公式のページを参考にしてください。
簡単に記載すると、既存のAL2のElasticIPの関連付けを解除し、新しいAL2023に解除したElasticIPを関連付ける作業を行います。

https://qiita.com/tomoya0117/items/66951840735897d94db5

https://repost.aws/ja/knowledge-center/ec2-move-elastic-ip

## 切り替え後の構成
上記の作業を行うと以下のような構成になります。
![EC2-3.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677761/db443713-92bc-c380-248d-b5965a65e67d.png)

## まとめ
今回は、EC2のマイグレーション作業における切り替え手順について簡単にまとめました。
実際に作業を進める際には、各手順を確認しながら進める必要があり、予想以上に時間がかかりました。
今回の作業では多くの学びを得ることができ、自分にとって非常に良い経験となりました。
Visual Studioでビルドの結果を詳細に出すには

ビルドエラー直すたびに忘れるので備忘録として残しておく。
# 手順
1. メニュー→デバッグ→オプション(モーダル表示)
1. プロジェクトおよびソリューション→ビルドして実行→MSBuildプロジェクトビルドの出力の詳細
1. 最小を詳細に変えればOK
![スクリーンショット 2024-12-27 092152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791111/f40bda47-911f-29d3-8a3f-066174c8fd5a.png)
![スクリーンショット 2024-12-27 092310.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791111/b9cf4152-2852-9cd1-846e-4498f6603597.png)

こんくらい変わる
最小
![スクリーンショット 2024-12-27 092239.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791111/f80d7a4b-6905-f0cf-01b3-627854e5f900.png)

詳細
![スクリーンショット 2024-12-27 092829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791111/21b870ee-80eb-1595-be08-79e4daaa004e.png)

どのファイルのどこまで実施し、どのファイルでエラーが起きたかまで詳細にわかるため、ビルドエラーが出て進まなくなった時用に。
出力結果がものすごい量になるため、エラーが直ったら「最小」に戻しておく。
Java開発におけるデザインパターンと設計思想の位置付け

Javaアプリケーション開発をする上で ドメイン駆動設計やらクリーンアーキテクチャやら、デザインパターンやらをよく聞きますが....
それぞれ独立した設計思想なのか? 独立していないとしたら開発においてコイツらはどういう位置付け?
というのをふと疑問に思ったので少し調べて記事にしてみました

### ざっくり理解してみる

#### デザインパターン
[参考になる記事](https://qiita.com/yu-saito-ceres/items/69adadab38cc99ad6c21#%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%81%A8%E3%81%AF)
- 概要
  - 多種プログラムで再利用可能な設計パターンのこと
  - Singleton、Factory、Observerと言われる種類がある 
- 何のために存在する?
  - ソースコードの再利用性を高め、設計を統一にすることで保守性を高める

#### ドメイン駆動設計（DDD）
- 概要
  - ビジネスの複雑な領域（ドメイン）にフォーカスし、そのドメインに基づいてソフトウェア設計を行う手法  
- 何のために存在する?
  - ビジネスロジックに焦点を当て、ドメイン知識を設計に反映することで、柔軟性や拡張性を向上させる
#### クリーンアーキテクチャ
- 概要
  - ソフトウェアの保守性、拡張性、テスト容易性を重視し、責務を分離するためのアーキテクチャパターンです。円形のレイヤー構造を持ち、中心にはドメイン、外側にはインフラやUIが配置される 
- 何のために存在する?
  - アプリケーションの層（プレゼンテーション、ドメイン、データアクセスなど）を分離し、依存関係を内側に向かわせることで、変更に強い設計を実現


### それぞれの位置付け
- デザインパターン : 実装クラス単位の再利用性を高める 
- ドメイン駆動設計 : ビジネスロジックにフォーカスしてソフトウェア設計する
- クリーンアーキテクチャ : アプリ/インフラ/ドメインを分離。アプリケーション層の依存関係を内側に向かせ、変更の依存関係を最小とし変更に強い設計を実現

つまり クリーンアーキテクチャ で ドメイン駆動設計を用いて、実装パターンはデザインパターンを用いる  

#### クリーンアーキテクチャ
アプリケーション全体の設計の枠組みや責務の分離を提供する「大枠」。

#### ドメイン駆動設計（DDD）
クリーンアーキテクチャの中核（特にドメイン層）を埋めるための「設計思想」。

#### デザインパターン
クリーンアーキテクチャやDDDを具体的に実装する際に使う「実装のテンプレート」。

今度はそれぞれをソースコードで実践していきたい
【Eclipse/STS】 消えないエラー：Class "..." is listed in the persistence.xml file, but is not annotatedの対処法

# 発生状況
プロジェクトを右クリック→構成→JPAプロジェクトに変換 を実行後、
Entityアノテーションを付与していて、persistence.xmlにもリストしているエンティティに
_Class "..." is listed in the persistence.xml file, but is not annotated_
エラーが表示される。

ビルドは問題なく成功し、動作にも影響がない。

# 環境
・STSバージョン：4.22.0.RELEASE
・JPAバージョン：2.2

# 対処法
適切にアノテーションを付与しているのにエラーが消えない原因は謎（不具合？）。
動作的には問題ないので、
ウィンドウ→設定→JPA永続化→JPA→エラー/警告→永続化単位
から、
persistence.xmlファイルにリストされているが注釈されていないクラス
の重大度レベルを「無視」に設定。

# 補足
stackoverflowには同様の事例の報告がありましたが、日本語で出てくる情報が見当たらなかったので記載しました。
参照元：<https://stackoverflow.com/questions/75597172/after-javax-persistence-jakarta-persistence-spring-boot-upgrade-error-clas>

参照元の方ではJPA2.2→3.1に切り替えた際に起きたという報告がありますが、
自分の環境ではJPA2.2でも起きているのでよく分からないです。

根本的な解決にはなっていないので、何かご存じの方がいらっしゃいましたらご教示いただきたいです。
latex workshop + tex-fmt で returned 2 って返された

# はじめに

以下の人向けです

- vscode + latex workshop環境でlatexを書いている
- フォーマッタにtex-fmtを使っている
- こういうエラーが返された

![tex-fmt returned 2 . Be cautious on the edits](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114109/9aa86950-d948-1890-176a-e446a82494aa.png)

# 解決

設定から`tex-fmt`とかで検索し，
`Latex-workshop › Formatting › Tex-fmt: Args`
の箇所を確認してください．

私の場合以下の設定になっていました．これを
![スクリーンショット 2024-12-27 085509.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114109/fb6a69e0-008a-5354-5f14-e4fa0ed0156d.png)

こうします．
![スクリーンショット 2024-12-27 085451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114109/054fa61e-e8fa-ffb5-5254-e0acf06c5767.png)

## 解説？

tex-fmtを実行する際にはいくつか引数(オプションとかどのファイルフォーマットするのとか)を渡すのですが，その引数でヘンなものを渡しているためにエラーが返されました．

![スクリーンショット 2024-12-27 084500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114109/73514d36-eb18-2c55-0c05-b2f6340755b2.png)

1. オプション`--nowrap`が`--keep`に変わったようです．[githubだと逆のissueっぽいの](https://github.com/James-Yu/LaTeX-Workshop/issues/4483)があったので，最近変わったのかも．
2. 意味も無く`%DOC%`入れてましたが，無くても.texファイルを開きながら`Alt+Shift+F`すれば.texをフォーマットしてくれました．いらないです．

`tex-fmt --help`によると以下のオプションが使えるようです．

```
Options:
  -c, --check    Check formatting, do not modify files
  -p, --print    Print to STDOUT, do not modify files
  -k, --keep     Keep lines, do not wrap <-- これ
  -v, --verbose  Show info log messages
  -q, --quiet    Hide warning messages
  -t, --trace    Show trace log messages
  -s, --stdin    Process STDIN as a single file, output formatted text to STDOUT
  -h, --help     Print help
  -V, --version  Print version
```

# おわりに

余計な行は消してくれたほうが嬉しいので，ぶっちゃけ`--keep`いらないかも．