OmniAICreator/Qiita-1.07M huggingface dataset:
【スクラム】Q.スクラムはミーティングが多く、非効率ではないのか

開発チームからの質問、というか不満。
※スクラムの実務経験がない個人の私見です

# 質問内容
スクラムはミーティング（会議・打合せ）が多く、スクラムイベントだけでスプリントの20%前後を割く。
ピラミッド型（PM・開発メンバー）の体制であれば、開発メンバーは割り当てられたタスクの遂行に集中できるため、その方が生産性が高いのではないか。

# 私の回答
自信を持って回答できないので、先輩SM方のご意見を伺いたい・・・が、一旦自分なりの考えを。

### 開発は生産性が全てではない
スクラムでももちろん生産性・効率は意識しますが、生産性を最優先に考えられたフレームワークではありません。

スクラムのメリット・強みは、短いサイクルで改善・課題解決できることだったり、強い人に極端に負荷が偏るのを防ぐことだったり、スキルの平準化を目指して一人が欠けた時のリスクを抑えることだったり、いろいろあります。

生産性だけを見ればスクラムではない形の方が勝るかもしれません。

### 開発チームの仕事は開発だけではない
スクラムにはPMがいません。
かといってPMがやるべきタスク（各種管理業務、顧客折衝、チームビルディング・・・）がなくなるわけではありません。
それらタスクが各ロールに分散されるのです。
（スプリント中の）進捗や品質の管理は開発チームが、顧客折衝・要件調整などはPOが、課題管理・リスク管理などはSMが。

開発チームが開発以外にもやらないといけないのですから、当然開発自体に割ける工数は減ります。
PMは多忙になりがちで、PMがボトルネックになって作業が進まないケースがよくあるかと思いますが、スクラムではそれをPOだったり開発チームに分散されるので、PJ自体の進捗が滞るリスクが減ります。
結果的に生産性で大きく劣るということはないような気がします。

### 何よりスクラムは楽しい
ピラミッド型だと、極論、与えられたタスクをこなしていれば良いので、一開発メンバーとしては碌にコミュニケーションを取らなくても、成果を上げられるかもしれません。
黙々と職人のような働き方をしたい人はそれでもいいかも知れませんが、仲間たちとチームの成長を実感しながら目標を達成していくのって、楽しくないですか？

決して責任感なくダラダラ仕事をするわけではなく、みんながチームの目標・活動に責任を持って良いプロダクト・システムを目指して一体感を持ってやれれば、成し遂げた時の達成感もひとしおでしょう。
実務経験ないので知りませんが。
role="status"のメッセージが読み上げられない！？

## 起こったこと
HTMLの構造を変えた結果、`role="status"`内のメッセージがスクリーンリーダーに通知されなくなった。

## `role="status"`

`role="status"`を持つ要素内のコンテンツの変更がスクリーンリーダーに通知されるようにするためには、当たり前ですが
「`role="status"`を持つ要素がアクセシビリティツリー状に存在すること」
という条件があります。

これだけ見ると「？何言ってんだ」と思いますが、今回はこれに引っかかりました。

## dialog（`aria-modal="true"`）

結論からいうと、犯人はこいつでした。

dialog要素は`showModal()`メソッドで呼び出された時に`aria-modal="true"`を指定したのと同じことになり、
さらにブラウザが対応していれば`dialog`以外のコンテンツが`inert`属性で不活性化された状態と同じになります。

:::note
[`dialog`要素の説明に上記の説明が書いてあります。](https://developer.mozilla.org/ja/docs/Web/HTML/Element/dialog)
詳しく知りたい人は読んでみてください。
:::

つまり、これにより`dialog`の外側には`role="status"`を持つ要素は存在しなくなります。

`dialog`（`aria-modal="true"`）がアクティブな状態で、その外に`role="status"`を置いた状態で中のテキストを変えてもメッセージが読み上げられないということです。

もともと`aria-modal="true"`の中に置いていたスクリーンリーダーへの通知を担う責務を持つコンポーネント（`role="status"`）をbody直下に移動した関係で、読み上げられなくなってしまっていたというオチでした。

自分で体験してみたい人もいると思うので用意しておきました。
スクリーンリーダーで体験してみてください。
https://shamokit.com/examples/a11y/role-status-dialog

最初からアクセシビリティツリーを見ていれば、あるいはこの辺の理解がちゃんとできていればもう少し早く気づけたかもしれません。

同じ状況になった人のために記事として残しておきます。
【TypeScript】オブジェクトのプロパティを必須にする

`Required<T>`を使用するとオブジェクトのプロパティを必須にできます。

```ts
type User = {
  id?: number,
  name?: string,
}
 
const user: Required<User> = {
  id: 1,
};
// Property 'name' is missing in type '{ id: number; }' but required in type 'Required<User>'.
```
書く予定の暗号記事ロードマップ

# はじめに
暗号系の論文を読んだり、プログラムを書き捨てたりしたが、その結果をきちんとアウトプットしていないことに気が付いた。（ほっとくといつまでたっても記事とか書かないと思う）
アウトプットがないエンジニアに価値はないと思うので、今後はこのロードマップに従って記事やプログラムを書いていくことにする。
基本的にはcryptorechで記載されているもの。

### 記事を書く際のルール
1. 絶対に実装するプログラムはRust or C++
1. 論文の原著を見て実際に使われている実装も確認する
1. 論文のテストケースを通す
1. 記事を書いたらリンクを置き換える


# ロードマップ一覧

基本的には暗号系に携わるプログラマには必須知識ではあると思うので、別途実装するなり調べてみるなりしてもよいと思う。

- 共通鍵暗号
    - ブロック暗号
        - [AES](https://qiita.com/watason/items/a2b7a28611a4e567651f)
        - camellia
        - [Aegis](https://qiita.com/w4tson/items/cc5307582f2bbe8a4a73)
    - ストリーム暗号
        - KCipher-2
- ハッシュ関数
    - 通常のハッシュ関数
        - sha2系
        - sha3系
        - [blake2](https://qiita.com/w4tson/items/87d17cf1a6b034471464)
        - 書くかはわからないが気が向いたら書く
            - sha1
            - md5
    - パスワードハッシュ関数
        - argon2
        - bcrypto
        - pbkdf2
- メッセージ認証
    - HMAC
    - CMAC
    - CBC-MAC
- 公開鍵暗号
    - 署名
        - RSA
        - DSA
        - ECDSA
    - 鍵共有
        - DH
        - ECDH
- 秘密計算
    - 秘密分散(Multi Party Computation)
        - Oblivious Transfer
    - 準同型暗号
        - tfhe
- 疑似乱数
    - 暗号論的疑似乱数
        - salsa20　（具体的には共通鍵暗号に分類されるが大体のOSで疑似乱数の生成に使われているのでここにする）
        - [chacha20](https://zenn.dev/watason/articles/03163a9c27a5f2)　（同上）
        - [Linuxでの/dev/randomの実装方法調査](https://qiita.com/w4tson/items/0910bebeec7125d753e3)
        - Blum-Blum-Shub
- 分類外（書かないかも。。）
    - [楕円曲線上の無限遠点についての記事](https://qiita.com/watason/items/230911fee5f3fe763eb0)
    - パスワードハッシュには何が一番良いのか検証
    - MPCの計算方法解説
    - TEE

# まとめ
改めて一覧を作ると多すぎて嫌になるけど、せっかくなので頑張ってみる。
# 参照文献
https://www.cryptrec.go.jp/method.html
Yolov8 CoreMLモデルの出力が正しくない時の対処法

# Pytorchでは正しい出力なのに、変換後がおかしい

カスタムデータでトレーニングしたYolov8を変換して、previewも表示されるのに、いざSwiftから使おうとするとメチャクチャな結果が出ることがありました。

# バグ
iOS17.0
MacOS Sonoma
の時にこのバグは発生しました。
MLE5Engineというやつのバグらしい。

# 対処法

以下で正しい出力になりました。

```swift
var config = MLModelConfiguration()
config.setValue(1, forKey: "experimentalMLE5EngineUsage")
let model = try custom_yolo_coreml_model(configuration: config).model
```

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[X](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
dockerを使ったredmineの導入

# はじめに
今回はdocker-composeを使わない最もシンプルな設定でのredmineの構築について紹介します。

# redmine
redmineとは簡単に説明すると、OSS　のプロジェクト管理ツールです。dockerを使用するとかなり簡単に導入できます。
以下コマンドを実行するだけです。インストールされるredmineイメージは最新のもので、データベースにはSQLite3がインストールされます。wikiなどの機能はありません。

```
docker run -d --name some-redmine redmine
```

実行を終えたら、http://localhost:3000とブラウザに入力すればredmineにアクセスできます。

今回は以上です。

[docker hub : redmine](https://hub.docker.com/_/redmine/)
ニュートン法を実装する

ニュートン法は方程式を反復法で解くアルゴリズムです。この記事ではC++でニュートン法を実装して簡単な方程式を解くことによって平方根の値を小数で求めます。動作環境はVisual Studio Community 2022のバージョン17.7.4です。使用言語はC++20です。

# 理論
正の数$N$の平方根を$x$とすると次の式が成り立ちます。
```math
x^2 - N = 0
```
$N$の平方根を求めることは、二次関数曲線$y=x^2 - N$と直線$y=0$すなわち$x$軸の交点の$x$座標を求めることと同じになります。ここで二次関数を$y=f(x)$と表記することにします。
次に、交点に近い適当な位置$(a, f(a))$で二次関数に対する接線を引きます。この接線の方程式は以下のようになります。
```math
y = f'(x)(x - a) + f(a)
```
この接線と$x$軸の交点の$x$座標は$y=0$とすることで求められ、
```math
x=a-\frac{f(a)}{f'(a)}
```
となります。
接線と$x$軸の交点の$x$座標が求まったら、今度はこの$x$座標における二次関数の接線を引きます。そして再び接線と$x$軸の交点の$x$座標を求めます。以後、接線を引いて$x$軸との交点の$x$座標を求める計算を繰り返していきます。これを繰り返していくと$x$座標の値は、本来求めるべきだった二次関数と$x$座標の交点の$x$座標に収束していきます。イメージとしては以下の図のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/507bb267-8078-0e1d-3e01-c8644b7145bf.png)
>出典: https://note.com/aquarius2911/n/na943a1da60fd

# 実装
ニュートン法の手順が理解出来たら実装していきます。以下が平方根を求めるニュートン法のコードになります。

```C++:Newton.cpp
#include <iostream>
#include <numbers>

double h = 0.0001; //差分
int n = 10; //計算回数

double f(double x, double N)
{
	return std::pow(x, 2) - N; //二次関数を定義
}

double differentiation(double x, double a)
{
	return (f(x + h, a) - f(x - h, a)) / (2 * h); //関数fを微分する
}

//ニュートン法を実行する関数
double NewtonCalculate(double a)
{
	double x = a; //接線を引くためのx座標の初期値を設定

    //接線とx軸の交点のx座標を求める計算を繰り返す
	for (int i = 0; i < n; i++)
	{
		x = x - f(x, a) / differentiation(x, a);
	}

	return x;
}

int main()
{
	std::cout << NewtonCalculate(2) << std::endl; //2の平方根の計算結果を表示
    //1.41421
	std::cout << NewtonCalculate(3) << std::endl; //3の平方根の計算結果を表示
    //1.73205
	std::cout << NewtonCalculate(4) << std::endl; //4の平方根の計算結果を表示
    //2
	std::cout << std::numbers::sqrt2 << std::endl; //2の平方根の理論値を表示
    //1.41421
	std::cout << std::numbers::sqrt3 << std::endl; //3の平方根の理論値を表示
    //1.73205
}
```

10回の計算で正確な数値に収束しました。
他の方程式を解きたい場合は関数fの中を必要に応じて修正してください。
方程式が変われば収束するために必要な計算回数も変わると考えられるので、変数nの値も必要に応じて変更してください。
関数differentiationは微分を実行するための関数です。
微分のコードを書く場合は微分の定義式
```math
f'(x) = \lim_{h \to 0}\frac{f(x+h)-f(x-h)}{2h}
```
を使います。

# 参考
https://note.com/aquarius2911/n/na943a1da60fd
https://manabitimes.jp/math/733
http://gurigumi.s349.xrea.com/programming/diff.html
Dockerfileで.envの変数を利用する

備忘録です。
composeを一緒に利用します。

`.env`
```.env
SAMPLE_ENV="apple"
```

`docker-compose.yml`
```yml
version: "3.8"
services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
      args: # .envから利用したい環境変数名を指定
        - SAMPLE_ENV=${SAMPLE_ENV}
```


`Dockerfile`
```Dockerfile
# 環境変数の受け取り
ARG SAMPLE_ENV

# 使用
RUN echo ${SAMPLE_ENV}
```
ChatGPTを使った献立アプリを作ってみた

# はじめに
前回まではChatGPTを使ったクイズアプリを作成しました。
今回はその応用として、キーワードを入力したらそれに基づく献立を提案してくれる献立アプリを作っていきたいと思います！

クイズアプリについては以下の記事でまとめています。
https://qiita.com/shake12/items/7a33cdc1bc105be16c3b

# 事前情報
- OpenAI / ChatGPT 初心者
- 献立アプリは React + Flask で作成

# 開発環境
- macOS Sonoma 14.4
- Visual Studio Code 1.87.2
- Python 3.10.6
- Flask 2.3.2

# プロンプト準備
- [前の記事](https://qiita.com/shake12/items/ac770569db6fcc7169ad)で紹介した以下の形式で準備していく
    `model`：今回は **gpt-3.5-turbo** を使用
    `messages`：ChatGPTに投げる質問を記載する  
    - `role`：どこからの問い合わせなのかを明記する
        - **user**：人間からの問い合わせ
        - **assistant**：GPTからの返答（以前の応答を保存するのに役立つ）
        - **system**：ChatGPTに与える役を設定するために使用
    - `content`：問い合わせや返答の文章を記載する

## キーワードに対応した献立を返却するプロンプト
今回の献立を提案するアプリでは、朝食・昼食・夕食の3色についてプロンプトを用意します。

「献立を作成して」というプロンプトだと献立だけではなく材料や作り方も提案してくれたりします。
このアプリでは献立名のみ分かれば良いので「献立名のみ」という表記を加えています。

↓ 例は朝食のものになります（昼食・夕食も同様に作成）
```python:menu.py
@app.route("/breakfastMenu")
def breakfastMenu():
  openai.api_key = os.environ["OPENAI_API_KEY"]

  req = request.args
  keyword = req.get("keyword")

  BREAKFAST_MENU_PROMPT = """
  プロの料理人としての依頼です。家庭で作れる{}を使った簡単な朝食の献立を作成して"献立名のみ"を教えてください。
  """

  response = openai.ChatCompletion.create(
      model="gpt-3.5-turbo",
      messages=[
          {"role": "user", "content": BREAKFAST_MENU_PROMPT.format(keyword)},
      ],
  )

  return response.choices[0]["message"]["content"].strip()
```

### 実行結果
**■ breakfastMenu**
`/breakfastMenu`を実行した結果です。
```
http://localhost:3001/breakfastMenu?keyword=キャベツ
```
![/breakfastMenu実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/59c42eeb-9a33-0f3a-40b2-042b3c1a3152.png)

**■ lunchMenu**
`/lunchMenu`を実行した結果です。
```
ttp://localhost:3001/lunchMenu?keyword=にんじん
```
![/lunchMenu実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/03c4f15b-8ec8-872b-e8b3-5517cab80e39.png)

**■ dinnerMenu**
`/dinnerMenu`を実行した結果です。
```
http://localhost:3001/dinnerMenu?keyword=トマト
```
![/dinnerMenu実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/fcb1e951-2e4d-f9b3-0bcf-b83b2195a02f.png)

# 献立アプリの動作
「ちがう献立を表示」ボタンも設けているので献立の再検索が可能になっています！

![menuApp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/593e84a5-7c4e-5a50-796d-ad704c435492.gif)

# さいごに
前回作成したクイズアプリを応用して、ChatGPT APIを使った献立アプリも作ってみました！
3つのAPIを叩かないような上手いやり方があるかと思うので今後はそこの改善をしていきたいです。

# 参考サイト
- [ReactとPython flaskを使ってWebアプリを作りたい](https://qiita.com/Pu-of-Parari/items/f3733f0ba48e1df50667) 
- [初めてフロントエンドとバックエンドの連携（Flask+React）をやってみた時の疑問と対処法](https://qiita.com/mihonak/items/91ac9c068831c0a3bb88) 
- [React Table component - Material UI]()
AsyncNotifierの使い方を学んでます

## 前提
* Flutter勉強中です
* 間違っている可能性もあります
 ### バージョン
 ```
flutter_riverpod: ^2.4.10
freezed_annotation: ^2.4.1
json_annotation: ^4.8.1
riverpod_generator: ^2.4.0
riverpod_annotation: ^2.3.5
```

## 使ってみた
こちらはコメントを扱うViewModelです。
```dart
@riverpod
class ProblemCommentViewModel extends _$ProblemCommentViewModel {
  final commentController = TextEditingController();
  final scrollController = ScrollController();

  SecureStorageRepository get secureStorage =>
      ref.read(secureStorageRepositoryProvider);
  ProblemRepository get problemRepository =>
      ref.read(problemRepositoryProvider);
  UserRepository get userRepository => ref.read(userRepositoryProvider);

  @override
  FutureOr<List<ProblemCommentStateOfDay>?> build({
    required String problemId,
  }) async {
    // 最初に保持する値の処理
    return commentStateOfDay;
  }

  Future<void> postComment({required Problem problem}) async {
    // 処理

    // stateを取得
    final prevState = state.asData?.value;

    // stateの更新
    state = await AsyncValue.guard(() async {
      if (prevState == null) {
        return [newStateOfDay];
      }

      // リストの管理にも詰まったのでおいておきます…
      final List<ProblemCommentStateOfDay> newState = List.from(prevState);

      final lastItem = newState.last.copyWith(
        comments: [
          newComment,
          ...newState.last.comments,
        ],
      );
      return newState;
    });
  }
}
```

もっといい書き方あったら教えてください！

## 自分なりの理解
* ViewModel内のメソッドで使える
```dart
HogeRepository get hogeRepo =>
      ref.read(hogeRepositoryProvider);
```

* build()
```dart
build(引数)
```
でref.watchの時引数を渡せる

続くかもです。（24/03/29）
M1 Macbook Airにてdockerで開発環境構築した際のメモ

###  インストール方法
https://zenn.dev/imasaka0909/articles/e984e9e69c43cf

### ビルド
`docker pull` した際に、ログインを求められることを知らず。
```bash
$ docker pull python3
Using default tag: latest
Error response from daemon: pull access denied for python3, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
```

`docker login` を実行
```bash
$ docker login
Authenticating with existing credentials...
Login Succeeded
```

`docker compose up -d --build` を実行
PostgreSQLのAccessShareLockにおけるALTER文の挙動

先日、オンライン処理からAurora（PostgreSQL）に対してAccessShareLockをかけた状態で、バッチ処理からテーブルのリネームを実行しようとしてバッチ処理がアベンドする事象が発生したので、自宅PCで再現してみました。

## 前提

ターミナルを二つ立ち上げ（以下、端末A、端末Bと呼称）、それぞれでposgreSQLにpsqlでログインしていること。

※PostgreSQLの環境を構築する方法は別記事で解説しているのでご参照ください。

https://qiita.com/blue-salt/items/011558458befd5602735

## 1. 端末Aでロックをかける

```sql
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
LOCK TABLE customers IN ACCESS SHARE MODE;
```

## 2. 端末Bでロックの状態を確認

```sql
SELECT * FROM pg_stat_activity WHERE query LIKE '%customers%';
```

実行結果
```
datid | datname  | pid | leader_pid | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_start         |          xact_start           |          query_start          |         state_change          | wait_event_type | wait_event |        state        | backend_xid | backend_xmin | query_id |                             query                              |  backend_type  
-------+----------+-----+------------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+-------------------------------+-------------------------------+-------------------------------+-----------------+------------+---------------------+-------------+--------------+----------+----------------------------------------------------------------+----------------
     5 | postgres | 106 |            |       10 | postgres | psql             |             |                 |          -1 | 2024-03-29 12:30:24.877979+00 | 2024-03-29 13:32:56.536604+00 | 2024-03-29 13:32:56.536604+00 | 2024-03-29 13:32:56.536608+00 |                 |            | active              |             |          739 |          | SELECT * FROM pg_stat_activity WHERE query LIKE '%customers%'; | client backend
     5 | postgres |  76 |            |       10 | postgres | psql             |             |                 |          -1 | 2024-03-29 12:23:53.778779+00 | 2024-03-29 13:32:36.815987+00 | 2024-03-29 13:32:36.82352+00  | 2024-03-29 13:32:36.824537+00 | Client          | ClientRead | idle in transaction |             |              |          | LOCK TABLE customers IN ACCESS SHARE MODE;                     | client backend
(2 rows)
```
customersテーブルに対してロック（AccessShareLock）がかかっていることを確認


## 3. 端末Bでテーブルのリネームを実行

```sql
ALTER TABLE customers RENAME TO customers_tmp;
```
応答待ち状態になる

## 4. 端末Aでロックを開放する

```sql
COMMIT;
```

## 5. 端末Bの処理が走行してリネームが完了する

```
postgres=# ALTER TABLE customers RENAME TO customers_tmp;
ALTER TABLE
postgres=#
```

これで、PostgreSQLのAccessShareLockの挙動についての実験を再現し、結果を確認しました。
【Visual Studio】MSB8011 コンパイルエラーでリビルドできない

## 環境
- Microsoft Visual Studio Community 2022 (64 ビット) Version 17.2.3

## エラー内容
突然コンパイルエラーが出てDebugのみビルドができなくなった。
```
MSB8011 出力の登録に失敗しました。ユーザーごとのリダイレクトを有効にするか、引き上げられたアクセス許可を使用して、コマンドプロンプトからコンポーネントを登録してください。
```

## 解決(？)

プロジェクト(P) -> ...のプロパティ
構成プロパティ -> リンカー -> 全般
出力の登録を"いいえ"に変更

後でまた詳細を追記すると思われる。

## 参考
[Visual Studio 2013 で x64 COM オブジェクトがビルド時に登録されない](http://umezawa.dyndns.info/wordpress/?p=5468)
【JavaScript】日付・時間の取得方法


~~~JavaScript:
let now = new Date();
console.log(now);//→Sat Mar 23 2024 15:34:09 GMT+0900 (日本標準時)
~~~

## getFullYear()
~~~JavaScript:
let now = new Date();
let y = now.getFullYear();
console.log(y); //→2024
~~~
getFullYear() メソッドは、指定された日時の年を返します。

## getMonth() 
~~~JavaScript:
let now = new Date();
let m = now.getMonth() + 1; //※0を起点とする為
console.log(m); //→３
~~~
getMonth() メソッドは、指定された日付の「月」を表す 0 を基点とした値（すなわち 0 が年の最初の月を示す）を返します。

## getDate();
~~~JavaScript:
let now = new Date();
let d = now.getDate();
console.log(d);//→23
~~~
getDate() メソッドは、指定された日付の「日」を返します。

## getDay();
~~~JavaScript:
let now = new Date();
let dd = now.getDay();
console.log(dd);//→6　　(※土曜日のこと)
~~~
~~~JavaScript:
let now = new Date();
let dd = now.getDay();
let ddList = ["日", "月", "火", "水", "木", "金", "土"]
console.log(ddList[dd]);//→ 土     
~~~
getDay() メソッドは、指定された日付の曜日を返します。
0 は日曜日を表します。

## getHours();
~~~JavaScript:
let now = new Date();
let h = now.getHours();
console.log(h);//→  16
~~~
getHours() メソッドは、指定された日時の「時」を返します。

## getMinutes();
~~~JavaScript:
let now = new Date();
let mm = now.getMinutes();
console.log(mm);//→9
~~~
getMinutes() メソッドは、指定された日時の「分」を返します。

## getSeconds();
~~~JavaScript:
let now = new Date();
let s = now.getSeconds();
console.log(s);//→1
~~~
getSeconds() メソッドは、指定した日時の「秒」を返します。
【デザインスキルゼロでも】v0.devでサイトをリニューアルした【個人開発の救世主】

# はじめに

こんにちは、転職エントリをまとめるサイト「[転職DB](https://www.jobchangedb.com/)」を個人開発しているbani24884です。今回は、デザインスキルに自信がない筆者が、どのようにしてサイトのデザインを一新できたのか、その過程を共有したいと思います。

https://www.jobchangedb.com/

# TL;DR

- デザインに関する専門知識がほとんどない私でも、v0.devを活用することでサイトのデザインをリニューアルすることができました。
- デザイナーがいない個人開発プロジェクトにおいて、v0.devは非常に役立つツールだと実感した。

リニューアル前
![Screenshot 2024-03-22 at 13.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/a4c9049c-eaae-9330-cd1e-f49459e25269.png)

リニューアル後
![Screenshot 2024-03-22 at 13.36.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/e59c8db5-734b-41e0-7d4c-39b51d584fc2.png)



# 課題

## サイトの課題

リニューアル前のサイトは、情報をテーブルで表示するシンプルなデザインでした。当初はとにかく早くリリースすることを目標にしていたため、デザインは二の次でした。しかし、これが以下のような問題を引き起こしていました。

- ページ上の文字情報が過多で見づらい
- SEOが弱い（例えば、子ページがないため適切な階層構造になっていない）

## 開発者の課題

これらの問題を解決したいと考えていましたが、以下のような課題に直面していました。

- デザインのスキルが乏しいため、自分でデザインを行うと質が低くなりがち
- CSSが苦手で、直感的にコーディングすることが多く、しばしば理解できていない部分がある

# v0.devの活用

上述の課題を克服するため、私はVercelが提供するv0.devを利用しました。v0.devは、簡単なプロンプトから高品質なフロントエンドのコードを生成してくれるツールです。

https://v0.dev/

## プロンプト例

### メディアサイト風のカードリスト表示

メディアサイトによく見られるカードリスト表示は、次のようなプロンプトで簡単に作成できます。

```
media site card layout with text search, combo box and sort
```
![Screenshot 2024-03-29 at 22.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/59eee3b4-4b59-f0a3-0710-34c26d086235.png)


このプロンプトから、v0.devは高品質なカードリストレイアウトを生成してくれます。生成されたコードを少し修正するだけで、自分のプロジェクトに組み込むことができます。

### 左にメニューがある2カラムのレイアウト

左側にナビゲーションバーを配置した2カラムのレイアウトも、簡単なプロンプトで実現できます。例えば、以下のようなプロンプトです。

```
NavBar on the left
```

![Screenshot 2024-03-29 at 22.19.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749758/72f02437-f6a1-6ba9-2fcd-547564441eac.png)


このプロンプトを使用すると、左側にナビゲーションバー、右側にメインコンテンツを配置した2カラムレイアウトが生成されます。これも、少しのカスタマイズで自分のプロジェクトに適用できます。

これらのプロンプトを利用することで、デザインのスキルがない方でもある程度整った外観のウェブサイトを構築することが可能になります。
筆者はこれらの出力したコンポーネントを組み合わせて、サイトをリニューアルしていきました。
ただし、生成されたコードをそのまま使うだけでなく、プロジェクトの要件に合わせて適切にカスタマイズすることが重要です。v0.devはデザインの出発点を提供してくれますが、最終的には開発者自身がコードを理解し、調整を加える必要があります。

# まとめ

v0.devは、デザインスキルが乏しい個人開発者や、リソースが限られているプロジェクトにとって非常に価値のあるツールです。これにより、見た目がプロフェッショナルで使いやすいウェブサイトやアプリケーションを、大きな時間やコストをかけずに構築することが可能になります。

ただし、v0.devはあくまでもデザインの出発点を提供してくれるツールであり、生成されたコードをそのまま使うだけでは不十分です。開発者自身がコードを理解し、プロジェクトの要件に合わせて適切にカスタマイズすることが重要です。

v0.devを効果的に活用することで、私のようなデザインスキルが乏しい開発者でも、スピーディーにサイトのデザインリニューアルを行うことができました。。ぜひ、みなさんもv0.devを試してみてください。

以下のようなサイトを運営しています。応援よろしくお願いします！
転職エントリメディア 転職DB(https://www.jobchangedb.com)
Next.js×MicroCMSのテンプレート「爆速ホームページ⚡」(https://www.bakusoku-hp.com/)
【備忘録】ラズパイにwindowsからリモート接続する。

ラズパイ上でプログラミングを実施する際に、インターフェース(マウス、キーボード、ディスプレイ)を接続するのが面倒くさいので、windowsPCからリモートでアクセスできるようにする。

◇実現したいこと
　windowsPCからラズパイへリモート接続する。

◇方法
　リモートデスクトップ接続を有効にするため、RaspberryPi側にRDPサーバソフト「xrdp」をインストールする。
　下記のサイトを参考にさせていただいた。

　参考サイト：Raspberry Piにリモートデスクトップ接続する(xrdpのインストール)
　https://raspi.taneyats.com/entry/install-xrdp

◇結果
　手順通りに実施し、リモートデスクトップ接続ができた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3745465/b788e899-ebc7-c82c-fe66-f891cc85a536.png)
【JavaScript】map()メソッドについて学習してみた


## 配列に使用できる

戻り値が配列になる
配列に使用できる

```js
const data = [1, 2, 3, 4];
const result = data.map((num) => {
 return num + 1;
});

console.log(result); 
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/436ae09c-06c5-ac07-8913-db3ae7509bbb.png)


## オブジェクトには直接使用できない

戻り値が配列になる
オブジェクトには直接使用できない

```js
const data = { id: 1, age: 2, num: 3 };
const result = data.map((num) => {
 return num + 1;
});

console.log(result);
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/5984b03d-f446-b9cb-03a9-3db823e29f9a.png)

※Object.keys()メソッドを使用して、オブジェクトのキーの配列を取得し、それに対してmap()メソッドを使用してみた。


オブジェクトのキーの配列を取得

```js
const data = { id: 1, name: "Taro", age: 23, from: "Japan" };

const keys = Object.keys(data);
const result = keys.map((key) => {
    return data[key];
});

console.log(result);
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/c4958de0-8176-922e-182a-040235d11624.png)

 配列の構成を作り替えることができる

```js
const students = [
            {
                id: "0001",
                name: "AA",
                age: 20,
            },
            {
                id: "0002",
                name: "BB",
                age: 21,
            },
            {
                id: "0003",
                name: "CC",
                age: 22,
            },
];

const formatted = students.map((student) => {
 return { [student.id]: student.name };
});

console.log(formatted);
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/b4ca148d-7f2d-31fb-3f72-3cf4a8592aac.png)
【HTML,CSS】文字の色やフォントを文章の途中で変える方法

# はじめに
こんにちは! 中学2年生のWardHamamatsu67です! 今回は、HTMLのページの途中で色やフォントを変える方法について説明したいと思います。
# 方法1
1つ目の方法はCSSを使用せず、HTMLのfontタグを使用するものです。
このような感じです。
```html
    <p>明けまして<font color="red">おめでとう</font>ございます。</p>
```
赤色に指定します。
![スクリーンショット 2024-03-29 214711.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/74fd66ef-462f-d931-e522-146a916e43a5.png)
このように、「おめでとう」を赤文字にすることで強調されましたね。
結構この方法は簡単です。が、!!この方法はあまりお勧めしません。
しっかりとした理由があります。それは、、
**この方法では、色は変えられるものの、<font color="red">フォントは変えられないからなんです。</font>**
では、何の方法が良いのでしょうか? そこで次の方法を紹介します!!
# 方法2
それは、**CSSを使う方法です!!**「でしょうね」と思った方、多いと思います。多くの人がわざわざ別ファイルまで作って、面倒くさいCSSのコードを書くのには手間がかかって嫌だ、と思うかもしれません。しかし、この方法を使うと、魅力的なサイトが作れちゃったりします!!
```html
    <p>明けまして
    <span class="colorful">お</span>
    <span>め</span>
    <span>で</span>
    <span>と</span>
    <span>う</span>
    ございます。</p>
```
spanタグを使用します。
```css
    .colorful span:nth-child(6n+1){color: #ff0000};
    .colorful span:nth-child(6n+2){color: #00ff00};
    .colorful span:nth-child(6n+3){color: #0000ff};
    .colorful span:nth-child(6n+4){color: #aa0000};
    .colorful span:nth-child(6n+5){color: #00aa00};
```
![スクリーンショット 2024-03-29 221511.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/6890f7d6-488b-efc5-55a1-eae41629fbdb.png)
どうでしょう。先程のよりもカラフルで面白い記事に見えるのではないでしょうか?(まあ、カラフルにしすぎるのはよくないんですけどね...)
もちろん、フォントを変えることも可能です。(ここでは、フォントを1つに絞って絵やっていきたいと思います。)
```html
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Klee+One&family=Zen+Maru+Gothic&display=swap" rel="stylesheet">
```
HTMLでは、Google Fontsに載せてあるHTMLコード(上のやつ)を貼り付けていきます。
```css
    .colorful {
            font-family: "Klee One", cursive;
            font-weight: 400;
            font-style: normal;      
    }
```
CSSでは、Google Fontsに載せてあるCSSコード(下のやつ)を貼り付けていきます。
![スクリーンショット 2024-03-29 222434.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/d6f35d46-d358-4424-4244-cf9f6938ea7d.png)
このように。
# おわりに
以上です。コードの内容自体は簡単なのですが、長～くなってしまうので、難しく感じますが、その分、成功した時の達成感は大きいです。皆さんもぜひ、この方法を利用して、やってみてはいかがでしょうか。
この記事が良いと思った方はいいねとフォローをしてくれると嬉しいです。
スロット持ちコンポーネントをラッピングする際にスロットを継承したい（ElementPlusでel-inputをラッピングする際のprependとappendのラッピングでちょっとハマった話）


# はじめに

通常のel-inputは以下のように使いますが、

```input.vue
<el-input>
  <template #prepend>前</template>
  <template #append>後</template>
</el-input>
```

（↓のようなUIになります）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/1342eeb2-3744-8af1-749c-b6633e42d3ab.png)


入力時に値を整形するようにラッピングコンポーネントを作ろうとしたんですが、prependとappendを再利用する方法に詰まったので、解決方法を備忘録として残しておきます。

# NG例：雑にラッピングしてみた

```ng-wrapper.vue
<template>
  <el-input v-model="innerValue" @input="oninput">
    <template #prepend>
      <slot name="prepend" />
    </template>
    <template #append>
      <slot name="append" />
    </template>
  </el-input>
</template>
```

これでも、以下のようにラッピングコンポーネントにprepend・append指定したら表示されます。

```sample.vue
<Wrapper>
  <template #prepend>前</template>
  <template #append>後</template>
</Wrapper>
```


ただ、以下のように`<template #prepend>``<template #append>`を指定してなくても、el-inputのprependとappendが表示されてしまいます。

```sample.vue
<Wrapper>
</Wrapper>
```

そもそもElementPlus側がどうやって実現してんのかな～？って疑問になったので、el-inputのコードを見てみました。

```packages/components/input/src/input.vue
<template>
  <div
    v-bind="containerAttrs"
    :class="containerKls"
    :style="containerStyle"
    :role="containerRole"
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
  >
    <!-- input -->
    <template v-if="type !== 'textarea'">
      <!-- prepend slot -->
      <div v-if="$slots.prepend" :class="nsInput.be('group', 'prepend')">
        <slot name="prepend" />
      </div>

```

引用：https://github.com/element-plus/element-plus/blob/dev/packages/components/input/src/input.vue

なにやら`<div v-if="$slots.prepend"`で`<slot name="prepend" />`の表示制御している様子。
$slotsについては公式にも記載がありました。
https://ja.vuejs.org/api/component-instance.html#slots


# 解決

スロットプラグイン（`$slots`）を使うことで解決できました。  

```wrapper.vue
<template>
  <el-input v-model="innerValue" @input="oninput">
    <!-- ラッパーコンポーネントのprependが指定されていればel-inputのprependを表示 -->
    <template v-if="$slots.prepend" #prepend>
      <slot name="prepend" />
    </template>
    <!-- ラッパーコンポーネントのappendが指定されていればel-inputのappendを表示 -->
    <template v-if="$slots.append" #append>
      <slot name="append" />
    </template>
  </el-input>
</template>
<scirpt lang="ts" setup>
import { ref, watch } from 'vue';

// modelValueはv-modelで指定した値
const props = defineProps<{ modelValue: number; }>();
// v-modelで指定された値をこのコンポーネントから更新するためのイベント
const emits = defineEmits(['update:modelValue']);

// コンポーネント内部用の変数
const innerValue = ref();

// 呼び元での値の更新を反映
watch(() => props.modelValue, (v) => innerValue.value = cnv(v));

const cnv = (value) => {
  // 数値以外を削除
  return value.replace(/[^0-9]/g, '')
}

const oninput = () => {
  // ここで入力値を整形したりする
  const value = cnv(innerValue.value);
  // 入力されたら呼び元の値を更新するためのイベント発火
  emits('update:modelValue', value);
}
</setup>
```


`$slots.prepend`・`$slots.append`で以下のようにラッピングコンポーネント呼び出しにて、`<template #prepend>` `<template #append>`が指定されているか判断できます。

```sample.vue
<Wrapper>
  <!-- これを指定すると、$slots.prependにインスタンスが設定される -->
  <template #prepend>前</template>
  <!-- これを指定すると、$slots.appendにインスタンスが設定される -->
  <template #append>前</template>
</Wrapper>
```
Dockerを利用してPostgreSQLのDBを簡単に作成する方法



業務でAWSのAurora（PostgreSQL）を利用していたため、諸々の挙動確認のために自分のPCにPostgreSQLのDBを作成したいと思い、Dockerを利用してパパッと構築してみました。

## 0. 前提
- Docker desktopは既に導入済みの前提です。
- OS：macOS

## 1. PostgreSQLのイメージを取得
```terminal
    docker pull postgres    
```
Docker HubからPostgreSQLの公式イメージをダウンロードします。

## 2. **PostgreSQLのコンテナを作成**
```terminal
    docker run --name my_postgres_container -e POSTGRES_PASSWORD=password -d postgres
```
- `my_postgres_container` という名前のPostgreSQLのコンテナを作成します。
- `POSTGRES_PASSWORD` 環境変数を使用して、PostgreSQLのパスワードを設定します。

## 3. **psqlコマンドを実行して、作成したインスタンスにアクセス**
```terminal
    docker exec -it my_postgres_container psql -U postgres
```
- 対話的なターミナルセッションを開始し、PostgreSQLのインスタンスにアクセスします。

## 4. **サンプルテーブルを作成**
```sql
    CREATE TABLE customers (
        id SERIAL PRIMARY KEY,
        name VARCHAR(100),
        email VARCHAR(100),
        age INT
    );
```
- `customers` テーブルを作成します。

## 5. **サンプルデータを投入**
```sql
    INSERT INTO customers (name, email, age) VALUES
        ('John Doe', 'john@example.com', 30),
        ('Alice Smith', 'alice@example.com', 25),
        ('Bob Johnson', 'bob@example.com', 35);
```
- サンプルデータを `customers` テーブルに挿入。

## 6. **全てのデータを取得**
```sql
    SELECT * FROM customers;
```    
- `customers` テーブル内のすべてのデータを取得します。

    **実行結果**:
    ```
     id |    name     |       email       | age 
    ----+-------------+-------------------+-----
      1 | John Doe    | john@example.com  |  30
      2 | Alice Smith | alice@example.com |  25
      3 | Bob Johnson | bob@example.com   |  35
    (3 rows)
    ```

PostgreSQLベースのデータベースをDockerを使用してローカル環境に簡単に作成できました。
後は自由に操作や検証を行うことができます。
Window 365 クラウドPCのローカルIPは指定できる？

マイクロソフトの渡部です☺

お客様からよく聞かれる質問の一つに、**クラウドPCのIPアドレス**についてがあります。

ご質問をいただく背景としては、
- **"クラウドPCを条件付きアクセスの条件対象にしたい。どうやって識別する？"**
- **"特定のクラウドPCだけ会社のネットワークに通信許可をしたいがどうしたらいい"**

このあたりです。

**Window 365 クラウドPCのローカルIPは指定できるのでしょうか？**

以前に、[Windows 365を展開する ネットワークはどちらを選ぶ？](https://qiita.com/Mikiteee/items/e1f8dfcd36bbf1759ef2)で、クラウドPCが通信するネットワークの種類は2つから選ぶことができる旨を解説しましたが、それぞれの種類によって回答していきたいと思います。

# （そもそも）クラウドPCとIPアドレスについて
クラウドPCは展開時に**ローカルIPアドレスが振られます**
ローカルIPをもとにアクセス制限を実装することができます。
また、Entra ID 条件付きアクセスの条件でもローカルIPを対象にすることが可能です。

Entra IDはIPアドレスでクラウドPCを特定する以外にも、
"クラウドPC"　全体を対象にしたり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/77d90553-2c94-971d-174a-26d3b9e0f756.png)

"Microsoft Intuneに登録されているこのデバイス"　というのも条件対象にできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/7e7c5fd0-e384-4c70-bbc4-9339e582e1da.png)


# Azure ネットワーク接続　を選んだ場合
IPアドレスの指定はできませんが、Azure VNetのサブネットは指定できます。

クラウドPCは、展開時に、ネットワーク選択としてAzure のVNetを選択できます。
vNetの中のサブネットでIPアドレスのレンジを指定でき、
クラウドPC展開時には、原則としてサブネットのIPアドレスレンジの上からクラウドPCに割り当てられていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/22d8c527-3602-1ee1-f447-05e1814979c7.png)

一度割り当てられたローカルIPアドレスは、原則、再起動やシャットダウンでは解放されません。
再プロビジョニングを行うと、ローカルIPアドレスは解放されます。

したがって、
- "クラウドPCを条件付きアクセスの条件対象にしたい。どうやって識別する？
**➡クラウドPCに振られたIPアドレスで識別してください。**

また、
- "特定のクラウドPCだけ会社のネットワークに通信許可をしたいがどうしたらいい"
**➡制御したい単位ごとに、サブネットとプロビジョニングポリシーをそれぞれ準備し、展開することで、"このIPアドレスのレンジは通信許可する" という条件を設定できるでしょう**

# Microsoft ホスト型ネットワーク　を選んだ場合
IPアドレスの指定はできません。
Microsoft ホスト型ネットワークは、AzureのVNetでネットワークを設計する必要がない一方で、
ユーザーが直接ネットワークに対して設定ができないネットワークタイプになります。

クラウドPC展開時にローカルIPアドレスは振られますが、ある程度規則性が見受けられたとしても、原則ランダムな値となります。（管理者がクラウド PC に割り当てられた IP アドレス範囲やアドレス空間を制御する方法はありません。）

したがって、
- "クラウドPCを条件付きアクセスの条件対象にしたい。どうやって識別する？
**➡クラウドPCに振られたIPアドレスで識別してください。ただし、IPアドレスを判定する方法は、一度クラウドPCに入っていただき、"ipconfig"からIPアドレスを調べる必要があります**

また、
- "特定のクラウドPCだけ会社のネットワークに通信許可をしたいがどうしたらいい"
**➡上記で判定したIPアドレスを指定して、"このIPアドレスは通信許可する" という条件を設定できるでしょう**

# References
- [Windows 365 ネットワーク展開オプション](https://learn.microsoft.com/ja-jp/windows-365/enterprise/deployment-options)
【生成AIアプリ100チャレンジ】（6）会話トーク

# 公開中サイト

https://ai.nuevo.jp/talk/

# 開発環境

|              |              |
|:------------:|:------------:|
| Server       | lightSail    |
| Language     | Python3.11   |
| Framework    | Django       |
| DB           | sqlite3      |

ローカル環境ではPythonのvenvを使用。エディタはvs codeです。


# 目的
　WEB画面上でChatGPTと会話ができるアプリを作りたいと思っています。TTS(テキストを自然な音声にするAPI)とwhispar(音声をテキストにするAPI)を使った会話アプリ。
 細かい挙動の制御まではやっていないが、録音する -> 文字起こし -> 自然言語生成AI -> 朗読　という感じで実装できた。時々、音データの更新・削除にズレがでてきてしまう。こういう制御は製品化するものに対してやればいいので、今回はそこまで手を出さない。生成AIのAPIの可能性を探る、と、私自身のPYTHONスキルをアップさせるのが目的。


# コード
```python:qiita.rb
    OPENAI_API_KEY = os.environ['OPENAI_API_IMAGE_KEY']
    chat_results = ""
    if request.method == "POST":
        form = TranscribeForm(request.POST)
        if form.is_valid():
            client = OpenAI(
                api_key = OPENAI_API_KEY,
            )
            audio_file_path = settings.BASE_DIR / "uploads/talk/user.wav"
            audio_file= open(audio_file_path , "rb")
            transcription = client.audio.transcriptions.create(
                model="whisper-1",
                file=audio_file
            )
            response = client.chat.completions.create(
                model="gpt-4",
                messages=[
                    {
                        "role": "system",
                        "content": """
                        新しいひとがやってきます
                        日本語で応答してください
                        あなたは私の友人の役を演じます。
                        勉強ができなくて異性が大好き。遊んでばかりいます。
                        でも面倒見がよくて元気がいい
                        """
                    },
                    {
                        "role": "user",
                        "content": transcription.text
                    },
                ],
            )
            text_results = response.choices[0].message.content
            speech_file_path = settings.BASE_DIR / "uploads/talk/system.mp3"
            response = client.audio.speech.create(
                model="tts-1",
                voice="alloy",
                input=text_results
            )
            response.stream_to_file(speech_file_path)
            chat_results = speech_file_path
    else:
        form = TranscribeForm()

```

今回は会話目的ということで友達っぽいキャラ設定をしてみた。
なかなかユニークで面白いキャラになったと思う。キャラ付けはもっと凝りたいが、ふと英語限定にすれば、それだけで英会話アプリになるじゃんと急遽アプリを追加で作成した。英会話アプリはまじで需要があるような気がする。


# アプリ画面
![スクリーンショット 2024-03-29 22.01.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398694/001300a7-bcdc-1e6b-0943-09825c40a383.png)

写真の人物は画像生成で作りました。ChatGPT4くんです。なるべく画像も生成で用意しようとしているのですが、初期のアイコンよりプロンプトが上達しているのがわかります。

# 感想
アプリのプロンプトだけを変更した英会話アプリを速攻で作ります。
声色を変えるAPIもあるらしいので、英会話の後は女性版のトークアプリを作成してもいいかもですね。
ChatGPT同士の討論会やエヴァンゲリオンのマギシステムも作りたい。
RakutenAI-7Bは『雪国』の冒頭をどうトークナイズするのか

日本語に強い大規模言語モデル「[RakutenAI-7B](https://huggingface.co/Rakuten/RakutenAI-7B)」が3月21日に公開された。[プレスリリース](https://corp.rakuten.co.jp/news/press/2024/0321_01.html)を見てみよう。

> **2.　日本語の言語に最適化された形態素解析器により高い効率性が可能**
>　本LLMは、日本語の言語に最適化された独自の形態素解析器（注7）を使用しています。一般的に形態素解析器は自然言語で書かれている文章を適切な単位に細分化して分析することができます。楽天の形態素解析器においては、文章の分割単位であるトークンあたりの文字数が増加し、その結果、より多くの情報を単一のトークンに含めることができます。そのため、従来の形態素解析器と比較して、事前学習や推論のテキスト処理をより効率的に行えるようになりました。
> （注7）形態素解析器とは、文章をトークンと呼ばれる小さな単位に分割するプログラムのことです。トークンは、望ましい粒度に応じて、単語、部分語、または文字であることが一般的です。

「注7」の説明は、どうみても「トークナイザ」に関するものであって「形態素解析器」じゃないのだけど、どうなってるんだろう。ちょっと試してみよう。

```
>>> from transformers import AutoTokenizer
>>> tkz=AutoTokenizer.from_pretrained("Rakuten/RakutenAI-7B")
>>> print(tkz.convert_ids_to_tokens(tkz("国境の長いトンネルを抜けると雪国であった。","夜の底が白くなった。")["input_ids"]))
['
', '▁', '国境', 'の長', 'い', 'トンネ', 'ルを', '抜け', 'ると', '雪', '国', 'であった', '。', '
', '▁', '夜の', '底', 'が', '白', 'くなった', '。']
```

残念ながら、日本語トークナイザとしてはボロボロだ。特に「の長」「い」のあたりは、単語の切れ目を完全に無視していて、日本語における言語処理としては話にならない。形態素解析というものを、ちゃんと学ばずにトークナイザを作ってしまったのだろう。残念だ。
CSS設計手法の選択で考えた技術選定の重要さ

# はじめに

この記事は、CSS設計手法を選択する時の「こうしておけばよかった」という内容をまとめた記事です。

対象となるのは、CSS設計手法と呼ばれる記法でCSSを書ける状態くらいのレベルの人です。

自分と同じような後戻りや無駄に手を動かす人が同じ道を歩まなくて良いように、自分自身が同じミスをしないようにアウトプットすることが狙いです。

結論を先に言うと、技術選定がコーディング等の工数を左右してしまう点で重要である、という内容です。

# 発信者のレベル感
- HTML, CSS, 簡単なJavaScriptでWebサイトをいくつか制作
- CSS設計手法としてはBEM、FLOCSS、CSSフレームワークはBootstrapの経験がある
- JavaScriptをメインに使用した動的なチャット型アプリケーションを開発中

基本的な静的Web制作を経験し、動的な処理について学習をやり始めたレベル感です。

# 開発全体を意識してCSS設計手法を選択する
これはHTMLページが単一のチャット型アプリケーションを開発する時に感じたことです。
CSSの設計手法としてはFLOCCSを選択しました。
時間が経ってリファクタリングに着手する際、不要なコーディングや修正範囲も多いと感じたことから、当時の選択理由を振り返ることにしました。

## そもそも選択理由が合理的でなかった
- 早く手を動かして作りたい衝動のまま、合理的な判断を軽視していた
- 「どの技術を使いたいか」ではなく、「どの技術なら効果的か」の検討が不足していた
- FLOCSSを使っているにも関わらず、scssファイルは分割せずに記述→接頭辞で役割を分ける意味があまりなかった

技術選定や開発初期の設計方針によって、後工程のコーディングや、リファクタリングの工数が左右されてしまうことを実感しました。

## どういったものを作るのか、から考える
HTML単一ページのチャット型アプリケーションでは、着手前にも下記のようなことを想定できるのではと考えました。
- CSS記述量は複数ページでない分、比較的少なめ
- ピクセル単位のCSS調整の必要性は高くない
- JavaScriptによるDOM操作を行うには、クラスは少ない方が良い

上記のことから、接頭辞で分類することにより共通化を図るFLOCSSは、オーバースペックな選択ではないかと感じました。

## もっと良い方法はないかを考える

これを書いている段階で、効率的にコーディングを進めることを考えた場合、いくつか選択肢が出てきました。
- 不要なマルチスタイリングを極力なくす
- 単一HTMLページでスクラッチのCSSスタイリングを選択するなら、役割よりもブロック単位での可読性を重視してBEMを選択
- そもそもCSSフレームワークの方が良い場合

こうして、初めに思いついた内容以外にも、もっと良い方法はないか、と一度立ち止まることが遠回りのようで近道なこともあるのだと学びました。

またその当時はベストな技術選定でも、新しい技術の台頭によって、過去の開発案件のコードがレガシー化してしまうということにも繋がっているのではないかと、初学者ながら感じました。

# まとめ
設計段階での技術選定によって、後工程のコーディング、リファクタリング等の工数が左右される。


# おわりに

単純ですが、技術選定時には各技術におけるメリットデメリットを並べるなどをし、効果的な選択を行うための対策をしてみようと思います。
また技術を「知ったつもりでいる状態」であったことも要因と言えるので、「理解している状態＝人に教えられる状態」になれるようにアウトプットの習慣を作っていきます。
ITILで見る変更管理　

# はじめに

マネジメントを勉強していく中でプロジェクト中に起こる変更管理についてメモを残していきます。

## 目次

* [変更管理について](#変更管理について)
* [変更管理を行う前に](#変更管理を行う前に)

## 変更管理について

ITサービス(Webサービス等)を使うにはエンジニア達が開発して終わり...ではなくユーザーが利用できるようにするために、リリース管理を行う必要があります。また、変更を管理する変更管理という管理も必要な一つです。
管理とつくだけにリリース管理、変更管理は複数の工程で管理されています。

### 変更管理

変更管理は「システムやサービスを変更しながらITサービスの中断を抑えられるように管理する。」という内容になります。ここでの「変更」はITサービスに直接または間接的な影響を与える可能性のあるハードウェアやソフトウェアが該当します。

変更管理の例として新規画面の追加や既存画面の削除です。

機能統合による不具合影響の発生やセキュリティパッチの障害発生といったリスクを最小限にとどめるために、変更管理として制御します。

変更管理と関連性があり、重要なプロセスの展開管理、リリース管理があります。

### 展開管理

新規および変更されたハードウェア、ソフトウェア、その他コンポーネントを稼働環境に移行すること。

### リリース管理

新規および変更されたサービスを利用可能状態にすること。

展開管理は稼働環境に移行することが目的で展開管理時点ではまだ利用できません。リリース管理を行うことで展開された稼働環境を利用できるようにします。

## 変更管理を行う前に

変更管理は上記で書いたようにITサービスの中断を抑えられるように管理することが重要です。
展開管理やリリース管理から、サービスがある稼働環境に変更を加えるため不具合や障害を出さないようにするために変更管理を行う際は以下のような確認を行います。

### 変更の承認

プロジェクトの上位権限者(PMやPL)に承認をもらう。プロジェクトが大きくなるほどアプリケーション(フロントエンド)を管理するチームやサーバ、API等を管理するチーム(バックエンド)の上位者に確認を行います。

### 変更スケジュールの作成

「明日、サービスの最新版をリリースします」というようなことはなく、事前に何月何日にリリースするかのスケジュールを作成します。作成したスケジュールにより、チーム間の衝突(アプリチームとサーバチームのそれぞれの変更)やインシデント管理に役立ちます。次回のリリースにてAのインシデントとBのインシデントの修正パッチを入れるため今週は「この修正パッチにリソース(人員や時間等)ができる」といったことができます。
マルチモーダルAI紹介

# はじめに
本記事では執筆時点で知名度の高いマルチモーダルAIを紹介します。
各マルチモーダルAIの名称及び簡単な概要を書いてますが、具体的な利用方法や実装方法、利用制限といった詳細な情報は公式ページを参照いただければと思います。

# 紹介するマルチモーダルAI一覧
- GPT-4V
- Gemini
- MGIE
- LLAVA
- tsuzumi

## GPT-4Vについて
OpenAIが開発したマルチモーダルAIであり、テキストによる対話に加えて、画像データに対するテキスト応答も得ることができます。
画像内容の説明をさせることや、デザインに対する改善案の提案、画像情報からソースコード案を提案させるといった、視覚的な情報をそのまま活用できるユースケースで活用が期待できます。

- 開発元：OpenAI社（https://openai.com/）
- 日本語：可
- 入力データ種類：画像、音声、テキスト
- 出力データ種類：テキスト

## Geminiについて
Googleが開発したマルチモーダルAIであり、テキストによる対話に加えて、画像や動画に対するテキスト応答や画像生成を行うことができます。また、GmailやGoogle MapなどのGoogleサービスとの連携ができるため、各種Googleサービスの情報を活用したユースケースを実現することができます。

- 開発元：Google DeepMind（https://deepmind.google/technologies/gemini/#introduction）
- 日本語：可（画像生成では不可）
- 入力データ種類：画像、音声、テキスト、動画
- 出力データ種類：テキスト

## MGIE（MLLM-Guided Image Editing）について
AppleとUCSBの共同で開発されたマルチモーダルAIであり、画像とテキストを入力として、画像編集をすることができます。
画像の加工を専門的な知識を用いらずに、感覚的な指示で実現することができるため、クリエイティブな作業の効率化や、多くの人がクリエイティブな作業に携わることができるようになることが期待できます。

- 開発元：Apple、UCSB
　オープンソースとしてGitHubで公開（非商用）（https://github.com/apple/ml-mgie）
- 入力データ種類：画像、テキスト
- 出力データ種類：画像

## LLAVA（Large Language and Vision Assistant）について
Microsoft、ウィスコンシン大学マディソン校、コロンビア大学の研究チームが開発したマルチモーダルAIであり、画像とテキストを入力として、テキスト応答が得られます。
画像×テキストを理解するモデルとして高精度の応答が可能なことに加えて、ローカル環境で動かすことができるため、個人でAIを学習させるなど、AI研究を活性化することが期待できます。

- 開発元：Microsoft、ウィスコンシン大学マディソン校、コロンビア大学
オープンソースとしてGitHubで公開（https://github.com/haotian-liu/LLaVA）
- 日本語：可
- 入力データ種類：画像、テキスト
- 出力データ種類：テキスト
- 学習：可

## tsuzumiについて
NTTが開発した、日本語と英語に対応した軽量LLMであり、特に日本語を得意としています。
マルチモーダルとして視覚読解にも対応しており、今後もモーダル拡張を予定しています。
軽量LLMのため、オンプレミス環境やNTTグループのプライベートクラウドで利用が可能であり、企業内データ等のクローズドなデータを外部に出さずに安全に活用することができます。

- 開発元：NTT（https://www.rd.ntt/research/LLM_tsuzumi.html）
- 日本語：可
- 入力データ種類：画像、テキスト
- 出力データ種類：テキスト
- 学習：可

# さいごに
近年のAIの技術の進歩スピードはとても速く、マルチモーダルなAIの数も増えていき、私たちの生活にも浸透し始めています。
これからもその進歩は進んでいき、より多彩なAIが産まれてくることが期待されます。
マルチモーダルAIの活用例

# はじめに
マルチモーダルAIが人間のように複雑な認識や理解を行うことができるものとして期待されていますが、実際にどのような活用先があるのかという視点で本記事を書いています。

# マルチモーダルAIの活用例

## 自動車の自動運転
カメラ映像やセンサーデータを統合処理し、周囲の環境を認識することで、複雑な環境でも安全な運転を支援できるようにします。
例えば、周囲の環境認識が十分であれば、人の操作が不要な完全運転を実現することが可能になる等。

## 医療
カルテ情報や病気に関する画像データ等、医療ビッグデータを統合的に処理させることで、病気の診断や治療計画の支援を行うことが期待されます。
例えば、超音波画像と患者情報から疾病が判断できるモデルを作成することで、精密検査なし（患者への負担が少ない）でも疾病判断することが可能となる等。

## 監視
監視カメラでの情報として、画像だけではなく音声も合わせて処理することで、より詳細な状況判断が可能になることが期待されます。
例えば、人の状態と音の組み合わせで、異常な状況であるかを判断できるモデルを作成することで、異常事態を早期発見でき、事故や事件を未然に防ぐことが可能となる等。

## 生成AI
テキストに加えて画像や音声といった情報も合わせて処理することで、人の感覚的（視覚的・聴覚的）情報を言語化せずに生成指示へ含められることで、より感覚的に生成AIを利用できるようになることが期待されます。
例えば、作成したい画像の簡単なラフ画や、イメージに近い画像と作成指示を与えることで、イメージ通りの画像を生成することが容易になる等。

## 感情推定
表情と音声（声色や言葉の内容）を合わせて処理することで、より正確な感情を推定することを可能とし、コミュニケーションを支援できることが期待されます。
例えば、オンラインで営業を行った際に、お客様の状態を可視化することで、よりニーズのあった商品を提案することが可能になる等。

# さいごに
実現のためには環境や精度等で課題がある場合もありますが、マルチモーダルAIを活用することで私たちの生活は多くの恩恵を得ることができます。人間のような認識や理解をAIが実現できることということは、適用できるところは無数にあり、今後も多くのところで活用されていくことが期待されます。
マルチモーダルAIについて

# はじめに
本記事は、マルチモーダルAIとはどんなAIなのかをざっくりイメージするために、簡単な概要とどんな適用先があるのかを記載しました。

# マルチモーダルAIとは
マルチモーダルAIとは、2つ以上の異なる種類のデータを統合して処理するAIのことであり、単一の種類のデータでは導けない情報を推定することや、より正確な推論結果を得られることが期待できます。

例えば、騒いでいる集団を観測した際に、画像だけの入力では人が集まっていることしか推測できませんが、画像に加えて音声も入力として処理できることで、「騒いでいる集団」という状態を推測することができます。

このように、データ種類の組み合わせにより、複雑な課題に対応することができるため、マルチモーダルAIは様々な分野での活用が期待されています。

# シングルモーダルAIとの違い
シングルモーダルAIとは、単一の種類のデータを入力として処理するAIのことであり、画像を入力として分類結果を返す画像分類や、音声を入力として文字起こしする音声テキスト変換といった、特定のデータ種類に特化したAIです。

シングルモーダルAIとマルチモーダルAIとの違いは、入力に使用するデータ種類の数であり、マルチモーダルAIではシングルモーダルAIよりも複雑なタスクに対応が可能となり、適用範囲も広くなります。

# マルチモーダルAIの種類
マルチモーダルAIは複数のデータ種類の組み合わせであるため、組み合わせパターンは無数に存在しますが、ここではマルチモーダルAIのイメージをつかむために、利用イメージが分かりやすい数種類を紹介します。

## テキスト×画像
テキストと画像を入力とするマルチモーダルAIとしては、以下のような適用先があります。

### 画像に対する質問応答
画像に写っているものに対して質問をしたい場合、テキストしか入力を受け付けないチャットボットでは、画像の情報を人間で言語化して、質問文を作成しなくてはいけません。
マルチモーダルAIでは、入力として画像とその画像に対する質問文（テキスト）を使用することで、画像情報の言語化という手間なく、質問をすることが可能となります。

画像のような視覚的情報を質問に含めることができるため、テキスト情報のみの応答よりも、より柔軟な応答体験を得ることができます。

## 音声×画像
音声と画像を入力とするマルチモーダルAIとしては、以下のような適用先があります。

### 表情と音声から感情推定
人の感情が現れる要素として「表情」がありますが、「笑顔だけれど内心退屈している」場合や、「無表情だけれど内心楽しんでいる」といったような、表情に出さない感情というものもあります。
ここに「声」という感情が現れる別の要素も入力に含めることで、表情という画像情報だけでは読み取れるなかった感情を推定することが可能になります。

画像だけでも、音声だけでも情報が不足する感情といったものに対して、どちらの情報も活用することで、単一の情報源での推定よりも、より精度の高い推定結果を得ることができます。

## その他
画像や音声といった分かりやすいデータ種類以外にも、センサーで取得した温度や湿度、赤外線情報なども入力として組み合わされて活用されています。
組み合わせの数につきましても、例のような2つに限らず、目的に合わせて複数組み合わせてマルチモーダルAIは作成されます。

# さいごに
マルチモーダルAIは複数のデータ種類を組み合わせ、今までのシングルモーダルなAIよりも柔軟で幅広い対応が可能なAIです。
人間のように複雑な認識や理解を行うシステムが実現することで、様々な領域において革新的なソリューションが提供される可能性があり、日常生活やビジネスに革新をもたらすことが期待されます。
DTOを作るのにT4 テンプレートを使ってみたら尽く詰まってしまった話

# DTOを作るのにT4 テンプレートを使ってみたら尽く詰まってしまった話

## はじめに

モデルの情報をやりとりするために、DTOを用いる場合があります。たとえば、以下の記事のようにWeb APIでのやり取りのこともあれば、同一アプリ内でもダイアログを出す場合のときに利用することもあるかと思います。
<https://learn.microsoft.com/ja-jp/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5>

ただ、自分でDTOを用意するのも面倒そうです。そこでChatGPTにきいてみたら、T4テンプレートを使うと良いとの回答。基本的にモデルの値を送受するだけなので、T4テンプレートでリフレクションを使ってプロパティ名とタイプを取ったら簡単に作れそう！と思い取り組みました。

結果、.NET Frameworkでは一応それっぽいところまではいくものの、.NET8のように最新のフレームワークではうまくいかないことがわかりました。
[こちら](https://github.com/RdJNL/TextTemplatingCore)の拡張機能を利用すれば動くらしいのですが、素の VisualStudio ではうまく動かせないようです。
アドバイス等ありましたら教えていただけますと幸いです。

## .NET Frameworkで試す場合

- モデルを別プロジェクトに用意します（.NET Framework4.6.2で試しました）
  ```cs
  namespace ClassLibrary1
  {
    public class Book
    {
        public int Id
        {
            get;
            set;
        }
        public string Title
        {
            get;
            set;
        }
        public string AuthorName
        {
            get;
            set;
        }
        // ...
    }
  }
  ```
- 上記のモデルのプロジェクトがビルドしてできたDLLを読み込むようなT4 テンプレートを用意します
  ```
  <#@ template debug="false" hostspecific="false" language="C#" #>
  <#@ assembly name="System.Core" #>
  <#@ assembly name="$(SolutionDir)ClassLibrary1\bin\$(Configuration)\ClassLibrary1.dll" #>
  <#@ import namespace="System.Linq" #>
  <#@ import namespace="System.Text" #>
  <#@ import namespace="System.Collections.Generic" #>
  <#@ import namespace="ClassLibrary1" #>
  <#@ output extension=".cs" #>
  using System;
  
  namespace ConsoleApp2
  {
  	public class <#= nameof(Book) #>DTO
  	{
  <#
  	var properties = typeof(Book).GetProperties();
  	foreach(var property in properties)
  	{
  #>
  		public <#= property.PropertyType.Name #> <#= property.Name #> { get; set; }
  <#
  	}
  #>
  	}
  }
  ```
- 上記を保存して生成すると、以下のようなコードが生成されます（一応最低限のところまでできてます。intがInt32になっていたりしますが）。ただ、もう少し頑張ればそれっぽいところまでは行けそうな予感がします
  ```cs
  using System;
  
  namespace ConsoleApp2
  {
  	public class BookDTO
  	{
  		public Int32 Id { get; set; }
  		public String Title { get; set; }
  		public String AuthorName { get; set; }
  	}
  }
  ```

## .NET8で試したときに起きたこと

.NET Frameworkでうまくいくことはわかりましたが、本当に動かしたいのは最新バージョンです。
しかし、上記と同じようなアプローチをしてみたものの、以下のようなエラーが出てしまいました。
> 重大度レベル	コード	説明	プロジェクト	ファイル	行	抑制状態
エラー		変換をコンパイルしています: 型 'Object' は、参照されていないアセンブリに定義されています。アセンブリ 'System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' に参照を追加する必要があります。	...(省略)...TextTemplate1.tt	13	

一応回避策としてstackoverflowにも回答がありましたが、わざわざコンフィグを書き換える手法でいまいち、かつ.NET6以降ではうまく解決できないみたいです。
<https://stackoverflow.com/questions/51550265/t4-template-could-not-load-file-or-assembly-system-runtime-version-4-2-0-0>

更に回答をたどると以下の回答にたどり着き、はじめにで紹介した拡張機能のページにたどり着きました。
<https://stackoverflow.com/questions/60153842/using-net-core-assemblies-in-t4-templates/60778223#60778223>

なかなか記事も見つけられず、正式サポートはまだ先？のようです。

## おわりに

T4テンプレートのような簡単にコード生成できる仕組みがあると色々と融通が効きそうなので、最新の.NETでも動作するようになると嬉しいですね！
この件での良い解決手段を自分では見つけられず…他に良い実現方法があればぜひアドバイスいただけると幸いです。
WindowsのCrystalでファイル選択ダイアログを出す

最近、WindowsでもCrystalが使えるようになった。
Rubyを使ってWindows向けの exe ファイルを作成するのはいろいろな困難が伴うが、Crystalを使えばRubyにかなり近い書き味で、実行形式のファイルを作ることができる。

とはいえ、まだ良いGUIライブラリが存在しない。
正確に言うと、CrystalにおいてWindowsにおいて共有ライブラリを呼び出すところはまだ開発途上で、実例が少ない。

そんな時でも、`powershell.exe` を使えば、簡単なダイアログは表示できる。たとえば、ファイル選択ダイアログを表示するのは次のような感じである。

```cr
cmd = <<-CMD
powershell.exe -command
    Add-Type -AssemblyName System.Windows.Forms
    $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $openFileDialog.initialDirectory = $InitialDirectory
    $openFileDialog.filter = "All files (*.*)| *.*"
    $openFileDialog.ShowDialog() > $null
    Write-Host $openFileDialog.Filename
CMD

ps = Process.new(cmd, shell: true, output: Process::Redirect::Pipe, error: Process::Redirect::Pipe)
stdout = ps.output
content = ps.output.gets_to_end
path = Path.windows(content.strip)
p File.exists?(path)
```

はい。完全に一発芸でした。
Powerhsellではいろいろダイアログが出せるらしいです。詳しく知りたい人は[コチラ](https://gist.github.com/jonschoning/5503062)をご覧ください。この記事は以上です。
Docker を料理で例える

# Docker を料理で例える
Docker を一度で理解できなかった自分が、こう考えたら全体像が理解できたという自分なりの例えと備忘録

## Docker Image ≒ 料理レシピ

Docker イメージは、料理のレシピに相当する。レシピには、料理を作るための材料や手順が含まれているが、Docker イメージも同様に、コンテナを作成するための手順やファイルシステムのスナップショットが含まれている。

## Docker Container ≒ 調理された料理

Docker コンテナは、調理された料理に相当する。これは、イメージに基づいて作成され、実行される実行可能な状態の環境です。各コンテナは、イメージを元にして独立して動作し、特定のアプリケーションやサービスを提供する。

Docker コンテナは、基本他人と共有しない。料理で考えれば直感的で調理された料理を共有するより、レシピで共有したほうが楽に決まっている。

だから Docker イメージ を色々な人が共有している。

## Docker Compose ≒ コース料理

Docker Compose は、コース料理に相当する。複数のコンテナやサービスを組み合わせて、一連の関連する機能やサービスを提供するための設定や手順が含まれている。これにより、複数のサービスをまとめて管理することができる。

踏み込んで書くと、Docker Compose は、YAML フォーマットで記述されたコンポーズファイル（通常は `docker-compose.yml` という名前）を使用して、複数のサービスやコンテナを定義しておく。このコンポーズファイルには、各サービスの設定、依存関係、ネットワーク設定、ボリュームのマウントなどが含まれている。ならば、 `docker-compose.yml` は献立とかレシピ集に当たると言えそう。

なんで Docker Compose を作るか(一つのコンテナに複数のサービスやアプリを実行しないのか)というと、管理が複雑になるからである。一つのコンテナ(コンピュータ)で複数のサービスを運用すると、干渉が起きたり、複雑な設定になりがちだ。
コンテナは、イメージを作れば後から何回も呼び出せるのでシンプルな状態で運用しておき コンテナ同士を連携させておき トラブルシューティング などが簡単になるように運用するのが慣例となっている。

## アプリケーションの実行 ≒ 料理の実食

最終的に、アプリケーションの実行は、料理を実食することに相当する。
コンテナが起動し、(場合によっては複雑なサービスを実行するときは コンポーズから立ち上げられて) サービスが提供され、アプリケーションが利用可能になる。
IaCジェネレータを使って既存スタックをCDKで管理する

## はじめに
マネコンで試しに作ったリソースをCDKで管理しようとしたところ、最近IaCジェネレータというものリリースしていたので使ってみました。

## IaCジェネレータ

IaCジェネレータはAWSのマネージコンソールから操作できます。

![スクリーンショット 2024-03-29 20.06.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3218510/e33e5538-b7fb-4686-5828-0013a73aa136.png)

あとは任意のリソースを選択していくだけで、既存リソースのテンプレートが作成されます。

### IaCジェネレータの罠

特に何も調べずCDK用のコマンドがあったので、これをローカルで試そうと思ったんですがうまくいきませんでした。
最初は設定ファイルとかが違うのかと思ったんですが、どうやらこのコマンドはクラウドの既存リソースを参照してCDK管理下に置くものではなかったようです。

![スクリーンショット 2024-03-29 20.30.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3218510/7903f4d2-f1c0-3217-8abc-f17fed7bd266.png)


## cdk importとcdk migrateについて

`cdk import`は既存リソースをCDKのStackにインポートする機能で、
`cdk migrate`は既存のcloud formationテンプレートをCDKプロジェクトに変換する機能です。

つまり、IaCジェネレータで提案された`cdk migrate`を行ってもcloud formationがないので想定通り動かず、やりたいことをやるに`cdk import`をする必要があったわけです。


## IaCジェネレータを使ってCDKするには？

##### 1. IaCジェネレータでリソースを選んだあと、テンプレートから「スタックにインポート」をしてcloud formationのスタックを作成します。

![スクリーンショット 2024-03-29 20.46.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3218510/0b90c8e0-612d-7ca9-de73-49573ce33c82.png)

##### 2. 該当スタックを指定して`cdk migrate`を行う。
Stack-XXXXに作られたスタック名を指定して以下のコマンドを実行すると、ローカルに適切なCDK プロジェクトファイルが作られます。
`cdk migrate --stack-name Stack-XXXX --language typescript --from-stack`

あとはcdk deployすればよく、それ以降の変化をコード上で行うだけです。

## まとめ

IaCジェネレータを使うことで今までは簡単にCDKに移行することはできたと思います。
IaCジェネレータで試したのは一部のリソースのみで、VPCなども絡めた多くのリソースに対して同様のことを行うのも大変そうだったので、今後試してみたいと思います。

## 参照

https://zenn.dev/issy/articles/zenn-cfn-iac-generator-tried-it

https://qiita.com/yasomaru/items/33c8b7ebf14da8c51869