OmniAICreator/Qiita-1.07M huggingface dataset:
CSSを学びたい！Step4

## はじめに
CSSを学びたい！！Step４です！
今回はauto-fit、minmaxを扱いレスポンシブ対応を実施していきます。

## 成果物
150px以下にならないようにレスポンシブ対応しています。
この場合、150px以下になる場合は段組みが変わります。
![step4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/7eca73c3-d28a-1f11-4dd1-98d6e69a546b.gif)

## ソースコード
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Grid Layout with auto-fit and minmax</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="card-container">
        <div class="card">カード1</div>
        <div class="card">カード2</div>
        <div class="card">カード3</div>
        <div class="card">カード4</div>
        <div class="card">カード5</div>
        <div class="card">カード6</div>
      </div>
</body>
</html>
```

```css:styles.css
.card-container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px;
    padding: 16px;
  }
  
  .card {
    background-color: #f4f4f9;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
    text-align: center;
  }
```
【Power Automate & Dataverse】検索列 (ユーザー) を利用して承認フローを作成する

# 検索列 (ユーザー) を利用して承認フローを作成する

SharePoint リストのユーザー列の場合は、列自体にメールアドレス情報を含んでいるためそのまま列の情報を使えますが、Dataverse の場合、検索列にはユーザー情報が含まれていないため **ユーザー** テーブルを参照する必要があります。

## 準備

対象の **Dataverse** テーブル承認者を設定する検索 (ユーザー) 列を作成しておきます。※ここでは『Approver』という表示名
![image-20241101221115645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/4f8a29c2-538f-8a23-7bb5-875e49f5e12c.png)


| No.  | 項目         | 設定値   |
| :--: | ------------ | -------- |
|  1   | 表示名       | Approver |
|  2   | データの種類 | 検索     |
|  3   | 関連テーブル | ユーザー |

## Power Automate で承認フローを作成する

※ここでは、例として『行が追加、変更、または削除された場合』のトリガーでフローを開始しています。

1. 『ID で行を取得する』アクションを追加します。
1. [テーブル名] に『ユーザー』テーブルを指定します。
1. [行 ID] にトリガーの列情報から、作成した列『Approver (値)』を指定します。
   ![image-20241101222730371.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/c095a3b1-639f-5c93-3252-1182fcbbe3ef.png)
1. 『開始して承認を待機』の [担当者] にメールアドレスを設定するために、『ID で行を取得する』アクションの [ユーザー名 (domainname)] を指定します。
   ![image-20241101223004027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/5fb7073e-2bae-d6b6-d761-4d9b0f4bf7b9.png)

### ポイント

『ユーザー』テーブルの [ユーザー名 (domainname)] 列には、メールアドレスが設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/fc1802b1-2d31-2917-4914-175fd02873e6.png)



# 参考

- [行が追加、変更、または削除された場合、フローをトリガーする - Power Automate | Microsoft Learn](https://learn.microsoft.com/ja-jp/power-automate/dataverse/create-update-delete-trigger?tabs=classic-designer)
CSSを学びたい！！Step3

## はじめに
CSSを学びたい！そんな思いから作るCSSの学習Step3！

## 成果物
![スクリーンショット 2024-11-01 21.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/0fcd00cd-fe98-4b8f-7e5a-5c4a8cdf6f34.png)

## ソースコード

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Grid Layout サンプル</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="grid-container">
        <div class="grid-item">1</div>
        <div class="grid-item">2</div>
        <div class="grid-item">3</div>
        <div class="grid-item">4</div>
        <div class="grid-item">5</div>
        <div class="grid-item">6</div>
    </div>
</body>
</html>
```

```css:styles.css
body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f4f4f9;
}

.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr); /* グリッドコンテナを3回繰り返す */
    gap: 16px; /* グリッドアイテム間のスペース */
    padding: 16px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.grid-item {
    background-color: #3498db; 
    color: #fff;
    padding: 16px;
    text-align: center;
    border-radius: 8px;
}
```
M1 MacにAWS-CLIをインストールする方法

# はじめに
M1 Mac に AWS-CLI をインストール方法になります。
インストールしたものの上手く実行できない方向けに、AWS-CLIを一旦アンインストールしてから、再インストールする手順になります。

# AWS-CLI をアンインストールします
```
sudo rm -rf /usr/local/aws-cli
sudo rm /usr/local/bin/aws
```

# AWS-CLI をインストールします

1. ファイルのダウンロード
ホームディレクトリにパッケージをダウンロードします。
```
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "$HOME/AWSCLIV2.pkg"
```
2. インストール実行
ダウンロードしたファイルでAWS CLIをインストールします。
```
sudo installer -pkg "$HOME/AWSCLIV2.pkg" -target /
```
3. 動作確認
正常にインストールできたかを確認。
```
aws --version
```

以上になります。
【Golang】Q-dog練習アプリケーションの開発に関する備忘録

適性検査の一つであるQ-dog練習アプリケーションを開発したので、備忘録としてその過程を記述します。フロントエンドは`TypeScript`、バックエンドでは`Golang`を使用しています。フレームワークは`Gin`と`React`です。
# Q-dogとは？
ストレスに強い人材を見抜くための適性検査であり、今回実装したのはその中の図形問題です。
図形問題では以下のように図形が二つ表示されます。その角の合計を答えるテストになっています。
△□

:::note info
今回の答えは3+4で7になります
:::

# 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787468/66c76a69-5384-0870-5a9d-ddd72d8b0169.png)

# 開発の流れ
## ディレクトリ構成
cssファイル等は省略しています。
```md:ディレクトリ構成
/
├─ backend
│  ├─ go.mod
│  ├─ go.sum
│  └─ main.go
├─ frontend
│  ├─ public
│  └─ src
│     ├─ components
│     │  ├─ common
│     │  │  └─ sideBar.tsx
│     │  └─ layout
│     │     └─ AppLayout.tsx
│     ├─ pages
│     │  ├─ Home.tsx
│     │  ├─ NoMatch.tsx
│     │  ├─ Report.tsx
│     │  └─ Training.tsx
│     ├─ theme
│     │  └─ theme.ts
│     ├─ App.tsx
│     └─ index.tsx
└─ .gitignore
```
# 環境構築の構築
settingやファイル作成を一括でしてくれるコマンド。
```md:command
npx create-react-app プロジェクト名 --template typescript
```
`/home`や`/training`のようにURLで表示するコンポーネントを変更する仕組みを作るコマンド。
```md:command
npm i react-router-dom
```
vscodeの`ES7+ React/Redux/React-Native snippets`という拡張機能をインストール。
# 開発の流れ
## コンテンツの追加
基本的には
1. `common`フォルダや`layout`フォルダの中で前ページで共通する部分の記述
2. `App.tsx`にURLを追加
3. `pages`フォルダでファイル作成→`return()`の中に表示するコンテンツ記述

という流れで行います。お好みで`pages`フォルダに各ページのcssファイル追加したり前ページ共通のcssファイルをsrc直下に置いたりしてください。

## バックエンドの実装
1. 問題と選択肢の生成
1. フロントエンドにデータを送信
1. ユーザーの回答がフロントエンドから帰ってくる
1. 正誤判定
1. 正解数の集計とフロントエンドへのデータ送信

という流れで通信しています。本アプリは10問正解すると10問分の結果が返ってくるというものなので5が必要になります。
```go:main.go
engine := gin.Default()
```
上記のコードでエンジンを生成し、`engine.GET()`や`engine.POST()`でリクエストを送信している。

:::note warn
CORSの許可を忘れないようにしましょう。`engine.USE()`で出来ます
:::

# おわりに
本アプリを作成するにあたってポテナスさんの動画を参考にしました。ありがとうございます。

https://youtube.com/playlist?list=PLBSXW-ldTw8m2LpKw8xZRc2HLfQ6_OsuN&si=0qDmanSryyEJkLdH

今後はMVCモデルでDBと連携させてレポートの部分を充実させたいと考えています。本アプリは以下のGithubにおいてあるのでよければご覧ください。

https://github.com/HinataYasukawa/Qdog
分析関数（ウィンドウ関数）ってすごい！！

# 目標
ジャンル毎に平均視聴数がトップの番組を取得したい、いわば、特定のグループ（ジャンル）毎に、上位のレコード（平均視聴数がトップの番組）を取得したい。
`ORDER BY`句と`GROUP BY` 句では限界があることに気付いたので、その学習メモをするもの。

# 結論
分析関数を使用する。
分析関数とは、集計関数と同様な動作を行毎に実行すること。`GROUP BY` 句のような同じカラム値をもつ全ての行で集計を実施する集計関数とは違い、集計作業の対象を制限することが可能。この集計対象を指定するのが`OVER`である。

```sql
ウィンドウ関数　OVER (PARTITION BY 列リスト　ORDER BY ソート用リスト)
```


## ウィンドウ関数
### RANK関数
ランキングを算出。同順位が複数出た場合は、後続の順位が飛ぶ。

### ROW_NUMBER関数
一意の連番を返す。順位がでないようにランキングを出すことができる。

### 集約関数
具体的にどんな結果が得られるのかは省略するが、全ての集約関数も、ウィンドウ関数として使うことが可能。

## PRTITION BY
`GROUP BY` 句との違いを示した概念図は以下の通り。`GROUP BY` はグループでまとめた行を表示。`PARTITON BY`は、グループ単位で行を表示。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3838211/2ba11364-04b2-f0d8-a715-5d3ec7f6440e.png">

https://itsakura.com/sql-partition-by#s1

## ORDER BY
どの列をどのような順序をつけるのか指定。`SELECT`の末尾で使う`ORDER BY`と同じで、`ASC/DESC`で昇順・降順を指定することができる。

## ウィンドウ関数はどこで使うのか
原則として、`SELECT`句のみで使える。`WHERE`句や`GROUP BY`句で使うことができない。

## 実行順序
よって、以下の構文でジャンル毎に平均視聴数がトップの番組を取得することができると思ったが、エラーが表示された。

`SELECT ジャンル、番組タイトル、RANK() OVER(PARTITION BY　ジャンル ORDER BY　平均視聴数) AS program_rank
FROM テーブル名
WHERE program_rank = 1`


```sql
SELECT    pg.genre_id, pav.program_title, RANK() OVER(PARTITION BY pg.genre_id ORDER BY pav.program_avg_view DESC) AS program_rank
FROM      programs_genres AS pg
LEFT JOIN program_avg_view AS pav
ON        pg.program_id = pav.id
WHERE     program_rank = 1;
```
エラー原因は、SQLの実行順序を考えていないためである。

SQLの実行順序は概ね以下の通り。

`FROM` → `JOIN` → `WHERE` → `GROUP BY` → `HAVING` → `SELECT` → `ORDER BY`

`WHERE program_rank= 1 `でフィルタリングをしているが、ウィンドウ関数（RANK()など）は`SELECT`の段階で計算されるため、`WHERE`句でウィンドウ関数の結果にアクセスできない。

よって、共通テーブル（CTE）を作成し、`RANK()`の結果を一時的に保存し、それに対して`WHERE`句適用する必要がある。

ちなみに、私は共通テーブルの作成はエクセルでいうピポットテーブルを何個も作成するイメージを持っている。

https://qiita.com/YamaOh/items/a836780a26eccc406d9e

# ゴール
よって、以下の構文でジャンル毎に平均視聴数がトップの番組を取得することができた。

```sql
WITH      rank_program AS (
SELECT    pg.genre_id, pav.program_title, RANK() OVER(PARTITION BY pg.genre_id ORDER BY pav.program_avg_view DESC) AS program_rank
FROM      programs_genres AS pg
LEFT JOIN program_avg_view AS pav
ON        pg.program_id = pav.id
)

SELECT    genre_id, program_title
FROM      rank_program
WHERE     program_rank = 1;
```
また、データベス設計に関する記事も作成しているため、見て頂けたら幸甚です。

https://qiita.com/poppukon4628/items/824d1133f8842b559252
Springの@Transactionalを利用するときはpropagationに注意する

spring の `@Transactional` を使用するとき、トランザクションの伝播の動きを制御する `propagation` というオプションがあります。
これの初期値は `Propagation.REQUIRED` になっているのですが、これが原因となりハマったので備忘録です。

# 何がしたかったのか？

DB の内容を処理するメソッドを書いていて、エラーが起きた際にきちんとロールバックされるのかをテストしようとしました。
テストクラスにも [@Transactional を付与することでテスト終了時に自動でロールバックされる](https://spring.pleiades.io/spring-framework/reference/testing/testcontext-framework/tx.html#testcontext-tx-enabling-transactions)ようにしていました。

テストは途中までデータの更新がされるが最終的に RuntimeException が発生する状態とし、その前後で内容が変わっていないことをもってロールバックされていることを確認しようとしました。
ざっくり以下のような形です。

```java
class SampleService {
    @Transactional
    void methodA() {
        /* DB 操作 */
    }
}

@Transactional
class SampleServiceTest {
    @Autowired
    SampleService service;
    
    @Autowired
    JdbcTemplate jt;

    @Test
    void test() {
        var before = jt.query(...);
        // 何かしらデータを弄るが途中で RuntimeException が発生
        assertThrows(service.methodA());
        var after = jt.query(...);

        // methodA の実行前後で内容が変わっていないことを確認
        assertThat(after).isEqualTo(before);
    }
}
```

この状態でテストを行うとデータの変更がされた状態になっており、methodA の前後で結果が一致しない (= この時点ではロールバックされていない) となりました。

# 原因：propagation = Propagation.REQUIRED になっているため

冒頭でも記述した通り `@Transactional` の propagation の初期値は REQUIRED です。
これは [現在のトランザクションをサポートし、存在しない場合は新しいトランザクションを作成](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html#REQUIRED) するという設定です。

つまり上記の書き方の場合、SampleService#methodA() のトランザクションは SampleServiceTest のトランザクションとなります。
そのため

methodA の中で RuntimeException が発生
→ この時点ではロールバックされない
→ テスト側では assertThrows によって methodA が例外を投げることを検証しているので期待通りということで正常に処理継続
→ `assertThat(after).isEqualTo(before);` の時点ではロールバックされていないのでテストに失敗

となっていました。

# 対応：~~REQUIRES\_NEW~~ NESTED にする or テストクラスの `@Transactional` を外す

### ~~REQUIRES\_NEW にする~~ NESTED にする

~~[REQUIRES_NEW はトランザクションが存在する場合はそれを一時停止して新しいトランザクションを作成します。](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html#REQUIRES_NEW)
処理内容によっては呼び出し元と同じトランザクションで管理したいということもあるので一概にこの対応ができるわけでは無いですが、そうで無いのであれば REQUIRES\_NEW にするのが良いと思います。
今回のメソッドはそもそも別のトランザクションが開いていても別途処理して欲しい内容でしたのでこちらで対応しました。~~

今回のようなテストを実施したいときは NESTED にすることで内側のトランザクション内でコミット / ロールバックできるようにすることが望ましいのかもしれません。
REQUIRES_NEW の場合は別のトランザクションを開くのでテスト内のトランザクションではテスト対象のメソッド内で行われたコミットの内容が反映されておらず、ロールバックされたように見えていたというだけでした。

### テストクラスの `@Transactional` を外す

処理の都合上 REQUIRED になる場合はテストクラスの `@Transactional` を外す対応になるのかなと思います。
この場合は `@BeforeEach` でテストデータを挿入して `@AfterEach` でテストデータを全て消す、などテスト後にテストデータが残らないように管理する必要があるので多少手間でしょうか。

# まとめ

`@Transactional(propagation = Proagation.REQUIRED)` が付与されたメソッドが例外を投げた時にロールバックされることをテストする際、テストクラスにも `@Transactional` を付与していたためにロールバックされませんでした。
トランザクションの伝播についての知見不足を知らされる一件でした。

# 参考

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html#propagation()

https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html

https://pppurple.hatenablog.com/entry/2017/08/30/232405
AWS Cognitoを用いてユーザー認証を実装する：Next（SSR）

こんばんは。

今日は「AWS Cognitoを用いてユーザー認証を実装する：Next（SSR）」について説明いたします。

Next.jsのApp Routerを使ったサーバーサイドレンダリング（SSR）を行う際、AWS Cognitoを用いてユーザー認証を実装することが可能です。AWS Cognitoは、アプリケーションにセキュアなユーザー認証と管理機能を提供するサービスで、ユーザー管理の手間を軽減できます。Next.jsのApp RouterとSSRを活用すれば、ユーザー情報をサーバー側で管理し、レンダリングを最適化したページを提供できます。

# 実装手順

以下の手順で、CognitoとNext.js App RouterのSSRを統合する方法を紹介します。

## AWS Cognitoの設定

まず、AWS CognitoでUser Poolを作成し、ユーザーを登録・管理できるようにします。以下が基本的な手順です。

- AWS管理コンソールにログインし、Cognitoを開く。
- 「User Pool」を作成し、認証方法やパスワードポリシーなどを設定。
- アプリクライアントを設定し、Client IDやClient Secretを取得。
- 必要に応じて、SNSやGoogleなどの外部プロバイダーと統合。

## Next.jsアプリでのCognitoの設定

次に、Next.jsのApp Routerを使用するアプリケーション内でCognitoを設定します。

### AWS AmplifyやAmazon Cognito Identity SDKを使う方法が一般的です。これらのライブラリをインストールしておくと便利です。

```terminal
npm install amazon-cognito-identity-js
```

### 環境変数として、User Pool IDやClient IDを.env.localに保存します。

```
NEXT_PUBLIC_COGNITO_USER_POOL_ID=your_user_pool_id
NEXT_PUBLIC_COGNITO_CLIENT_ID=your_client_id
```

### サーバーサイドレンダリングでの認証フローの実装

App Routerで、サーバーサイドレンダリング時にCognitoを利用してユーザー認証を行います。認証後、ユーザー情報を取得してレンダリングに利用します。

```javascript
// src/app/page.js

import { CognitoUserPool, CognitoUser } from 'amazon-cognito-identity-js';
import { cookies } from 'next/headers';

export async function getServerSideProps() {
  const token = cookies().get('token')?.value;

  if (!token) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  const userPool = new CognitoUserPool({
    UserPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID,
    ClientId: process.env.NEXT_PUBLIC_COGNITO_CLIENT_ID,
  });

  const user = new CognitoUser({ Username: token, Pool: userPool });

  return {
    props: {
      user: {
        username: user.getUsername(),
        // 他のユーザー情報
      },
    },
  };
}
```

### 認証のクライアント側実装

サーバー側の認証処理が成功した場合、トークンを取得し、クッキーやセッションストレージに保存して次回以降の認証に利用します。

```javascript
import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';

const authenticateUser = async (username, password) => {
  const userPool = new CognitoUserPool({
    UserPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID,
    ClientId: process.env.NEXT_PUBLIC_COGNITO_CLIENT_ID,
  });

  const user = new CognitoUser({ Username: username, Pool: userPool });
  const authDetails = new AuthenticationDetails({ Username: username, Password: password });

  return new Promise((resolve, reject) => {
    user.authenticateUser(authDetails, {
      onSuccess: (result) => {
        document.cookie = `token=${result.getAccessToken().getJwtToken()}; path=/`;
        resolve(result);
      },
      onFailure: (err) => {
        reject(err);
      },
    });
  });
};
```

# まとめ

1. CognitoのUser Pool設定：AWS CognitoでUser Poolを作成し、認証機能を設定。
1. Next.jsの環境変数設定：User Poolの情報を環境変数として保存。
1. SSRでの認証：App Routerを使い、getServerSidePropsやAPIルートでユーザー認証を行う。
1. クライアント側認証管理：トークンをクッキーに保存し、次回以降のリクエストで利用。

これにより、Next.jsのApp Routerを使った効率的なSSRとAWS Cognitoを用いたユーザー認証が実現します。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
HarmonAI IIIの事例から学ぶ！生成AIを活用したリポジトリデザイン

## はじめに

リポジトリデザインは、単なる見た目の装飾ではありません。それは開発効率、プロジェクトの持続可能性、そしてコミュニティとの関係性を根本から変える戦略的な取り組みです。本稿では、HarmonAI IIIの事例を通じて、最新のリポジトリデザインのベストプラクティスと、AIを活用した革新的なアプローチについて解説します。

## リポジトリデザインの歴史的背景

### 生成AI登場前のリポジトリ管理
従来のリポジトリ管理では、以下のような課題が常に存在していました：

- ドキュメンテーションの手動更新による時間的コスト
- 多言語対応における翻訳の精度と一貫性の維持
- リリースノートの作成における労力と正確性の両立
- イシュー管理における分類と優先順位付けの複雑さ

### 生成AIがもたらす変革
生成AIの登場により、これらの課題に対する革新的なソリューションが実現可能になりました：

- 自動ドキュメント生成による作業効率の向上
- 高品質な機械翻訳による迅速な多言語展開
- コミットログの自動分析によるリリースノートの生成
- AIによるイシューの自動分類と優先順位付け

## HarmonAI IIIのビジュアルデザイン

### READMEと視覚的要素
HarmonAI IIIのREADMEは、以下の要素を効果的に組み合わせています：

- センタリングされたロゴと明確なタイトル
- プロジェクトの状態を示すバッジ群
- 技術スタックを視覚的に表現するアイコン
- 整理された階層構造による情報の明確な区分け

### 視覚と機能性の調和
デザインの各要素が持つ役割：

- ヘッダー画像：プロジェクトのアイデンティティを視覚的に表現
- バッジ：プロジェクトの状態や品質指標を即座に把握可能
- セクション区分：情報の論理的な構造化を実現
- コードブロック：実装例の視認性向上

## 内部機能の自動化とIRISによるAI機能の活用

### IRISの自動リリースノート生成
IRISを活用した自動化プロセスの特徴：

- コミットメッセージの自動解析と分類
- 変更内容の重要度に基づく自動要約
- 過去のリリースとの関連性の分析
- フォーマットの一貫性維持

### AIによるイシューの自動分類と管理
イシュー管理の効率化：

- 内容に基づく自動カテゴリ分類
- 優先順位の自動判定
- 関連イシューの検出と紐付け
- 解決策の提案機能

### 多言語ドキュメント生成と翻訳
グローバル展開を支援する機能：

- 主要ドキュメントの自動翻訳
- 翻訳品質の自動チェック
- 用語の一貫性維持
- 翻訳更新の自動化

## 使用技術と依存関係の表示

HarmonAI IIIで採用されている主要技術：

- Python：コアロジックの実装
- GitHub Actions：CI/CDパイプライン
- Streamlit：インタラクティブな表示機能
- OpenAI/Gemini：AI機能の実装

各技術の選定理由と利点：

- 拡張性の確保
- コミュニティサポートの充実
- 開発効率の最適化
- メンテナンス性の向上


## ワークフローとプロジェクトの流れ

### 自動化された処理フロー
効率的な開発サイクルの実現：

1. プロジェクト初期化
2. 自動コミット生成
3. イシュー管理
4. リリースノート作成
5. ドキュメント更新

## まとめ

HarmonAI IIIが示す先進的なリポジトリデザインは、以下の点で従来の手法を大きく進化させています：

1. AI活用による自動化の徹底
2. 視覚的な情報伝達の最適化
3. 効率的なワークフローの確立
4. グローバル展開への対応

これらの要素は、今後のリポジトリデザインにおける新たな基準となることが期待されます。

## リポジトリ

https://github.com/Sunwood-ai-labs/HarmonAI_III

https://github.com/Sunwood-ai-labs/AIRA

https://github.com/Sunwood-ai-labs/IRIS
Golang入門: 初めてのGoプログラムを書こう！

はじめに
Golang（Go）は、Googleによって開発されたプログラミング言語で、シンプルで効率的な構文が特徴です。高いパフォーマンス、並行処理が得意な点から、近年のWeb開発やバックエンドシステムで人気が高まっています。今回は、Golangの基本を学び、簡単なプログラムを実際に書いていきましょう。

# 1. Golangのセットアップ
まずは、Golangを自分の環境にインストールしましょう。

### Goのインストール
公式サイトから最新版をダウンロードします。

Go公式サイト: https://golang.org/dl/
ダウンロードしてインストール。
インストール後、ターミナルで以下のコマンドを実行して、インストールが正しく行われたか確認します。

```

go version

```
### 環境設定
GolangではプロジェクトごとにGOPATHとGOROOTを設定しますが、基本的には自動設定されるので、初心者は特に気にしなくても大丈夫です。

# 2. 最初のGoプログラムを作成しよう
次に、最初のGoプログラムを書いてみましょう。

プログラムの作成
プロジェクト用のフォルダを作成し、その中にhello.goファイルを作成します。


```Diff_go
mkdir myproject
cd myproject
touch hello.go
```
### "Hello, World!"プログラム
以下のコードをhello.goファイルに書き込みます。


```Diff_go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
```
#### 解説
```package main```：このファイルが実行可能なGoプログラムであることを示します。
```import "fmt"```：標準ライブラリのfmtをインポートして、文字列の出力を可能にします。
```func main()```：Goプログラムのエントリポイントです。
#### 実行
ターミナルで以下のコマンドを実行してプログラムを動かしましょう。

```Diff_go
go run hello.go
```

Hello, World!と表示されれば成功です！

# 3. 基本構文の紹介
Golangの基本的な構文も理解しておきましょう。

### 変数と定数
```Diff_go
var x int = 10  // 変数
const y = 20    // 定数
```
### 関数
```Diff_go
func add(a int, b int) int {
    return a + b
}
```
### 条件分岐
```Diff_go
if x > y {
    fmt.Println("x is greater than y")
} else {
    fmt.Println("x is less than or equal to y")
}
```
### 繰り返し
```Diff_go
for i := 0; i < 5; i++ {
    fmt.Println(i)
}
```
# 4. Golangの特徴
##### 静的型付け：型安全が保証され、エラーが減ります。
##### 並行処理：goroutineやchannelを使って並行処理が簡単にできます。
# 5. まとめ
Golangはそのシンプルさと強力な並行処理が魅力です。今回のチュートリアルでは簡単なHello, World!プログラムを実行し、基本的な構文を学びました。ぜひ、実際にコードを書いてGolangの開発を楽しんでみてください！
pyenv+venv→poetryの移行ガイドライン

今更ですが、pyenv+venvユーザの私がpoetryへ移行した際の対応表をまとめます。

なお、poetryにはPythonのバージョンを管理する機能はないようなので、poetryはpyenvがインストールされている前提で書きます。

## 参考

- https://kosuke-space.com/python-poetry
- https://qiita.com/ksato9700/items/b893cf1db83605898d8a
- https://qiita.com/nya__str/items/be4cf7242e7fc7980e51

# インストール

## pyenv+venvのインストール

この記事を見ている人はすでに知っていると思うのでここでは省略します。

## poetryのインストール

まずは前準備としてPython3.5以降をインストールしておきます。

例えばUbuntuでは

```bash:shell
apt install -y python3.12
```

とかでOKです。
この時点ではPythonのバージョンは気にしなくて大丈夫です。

次にpoetry本体をインストールします。

```bash:shell
curl -sSL https://install.python-poetry.org | python3 -
```

最後に上でのコマンドラインへの出力の一部にある

```
Add `export PATH="*****:$PATH"` to your shell configuration file.
```

の通り、`export PATH="*****:$PATH"`を`~/.bashrc`の末尾へ追記し、`source ~/.bashrc`等で有効化すれば完了です。

```bash:shell
poetry --version
# -> Poetry (version 1.8.4)
```

# 仮想環境の作成

## pyenv+venv

```bash:shell
# 使用したいPythonバージョンのインストール
pyenv install 3.10
# プロジェクトディレクトリへ移動
cd path/to/project
# 使用したいPythonバージョンを指定
pyenv local 3.10
# 仮想環境のライブラリ等を保存する場所を作成
python -m venv .env
```

## poetry

```bash:shell
# 作成したいプロジェクトディレクトリの１つ上へ移動
cd path/to
# 'project'という名前でプロジェクトディレクトリを作成
poetry new project
# 使用したいPythonバージョンのインストール
pyenv install 3.10
```

プロジェクトディレクトリ直下の`pyproject.toml`の一部を使用したいPythonバージョンに従って以下に変更。

```:pyproject.toml
[tool.poetry.dependencies]
python = "^3.10"
```

```bash:shell
# 使用したいPythonバージョンの実行ファイルまでのパスを指定
poetry env use ~/.pyenv/versions/3.10.15/bin/python
```

# パッケージのインストール/アンインストール/インストール済み一覧表示

## pyenv+venv

```bash:shell
# プロジェクトディレクトリへ移動
cd path/to/project
# 仮想環境の有効化
source .env/bin.activate
# numpyのインストール
pip install numpy
# インストールされているパッケージ一覧の表示
pip list
# numpyのアンインストール
pip uninstall numpy
# 仮想環境の有効化解除
deactivate
```

## poetry

```bash:shell
# プロジェクトディレクトリへ移動
cd path/to/project
# numpyのインストール
poetry add numpy
# インストールされているパッケージ一覧の表示
poetry show
# numpyのアンインストール
poetry remove numpy
```

# プログラムの実行

## pyenv+venv

```bash:shell
# プロジェクトディレクトリへ移動
cd path/to/project
# 仮想環境の有効化
source .env/bin.activate
# 実行ファイルの場所を指定して実行
python src/run.py
# 仮想環境の有効化解除
deactivate
```

## poetry

```bash:shell
# プロジェクトディレクトリへ移動
cd path/to/project
# 実行ファイルの場所を指定して実行
# (poetryではプロジェクトディレクトリ下の[プロジェクト名]ディレクトリ配下に実行ファイルを置くようです。)
poetry run python project/run.py
```

または

```bash:shell
# プロジェクトディレクトリへ移動
cd path/to/project
# 仮想環境の有効化
poetry shell
# 実行ファイルの場所を指定して実行
# (poetryではプロジェクトディレクトリ下の[プロジェクト名]ディレクトリ配下に実行ファイルを置くようです。)
python project/run.py
# 仮想環境の有効化解除
exit
```

# 仮想環境の削除

## pyenv+venv

```bash:shell
# 仮想環境のライブラリ等が格納されているディレクトリを削除
rm -r path/to/project/.env
```

## poetry
```bash:shell
# プロジェクトディレクトリへ移動
cd path/to/project
# 仮想環境の名前を取得
poetry env list
# -> project-ZdgNLEiz-py3.10 (Activated)
# 上の結果をもとに仮想環境を削除
poetry env remove project-ZdgNLEiz-py3.10
```

# おわり

今のところあまりpoetryの便利さが感じられませんが、使えるようにしておけば将来参加するプロジェクトでpoetryを使っている場合に役に立つでしょう。多分。
あと、まだ気づけていないpoetryの利点も多分あるんでしょうね。
picoCTF 2024 解けなかった問題を勉強した記録

大会中、かなり粘って、何時間もかけたが解けなかったやつら。

# Mob psycho

JADX で　flag を検索しても答えが見つからなかった。
まさか、プログラムから使っていないリソースに隠すとは。
リソースに隠すのはいいけど、使えよ。と言いたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/f4bc1963-73bc-1ed6-abfe-20eadc22c4e5.png)


# No Sql Injection

はまやんはまやん氏のサイト

https://blog.hamayanhamayan.com/entry/2021/12/06/220234

に、{"id":"admin", "pw": {"$ne": "pass"}}  のような否定のクエリを投げれば真になり結果が返ってくるとあったので、入力欄２か所に
 {"$ne": "pass"}
 {"$ne": "pass"}
と入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/7e7cbed7-d5c5-e8b2-ca1f-84c2400a9e35.png)

Adminページが表示され、成功？と思ったが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/320ef359-0d9e-7057-20f9-f8eaeb1e3ece.png)

ソースを見てもフラグなし。
大会期間中は、ささってなかったのかと思い、別の方法を試したがダメ。

他の人にWriteupを見ると、トークンと書いてあったので、刺さってたと仮定して、もう一度よく探し回ってみると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/1ff2ef7d-a1f7-4d37-207d-83063010ecb5.png)

あった。ここかよ。やっぱ、刺さってたんだ。
UIKitでナビゲーションの戻るボタンをカスタマイズするときにハマった

# はじめに
タイトルの通り、UIKitでナビゲーションの戻るボタンをデフォルトと異なるアイコンに設定しようとしたときにハマったのでその内容と対応方法について残しておこうと思います。

# 困ったこと
デフォルトの戻るボタンのアイコンを以下コードで変更しようとしたが、デフォルトのボタンのまま変わらなかった。

```swift
navigationItem.backBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "chevron.backward"), style: .plain, target: self, action: #selector(tappedBackNavigationButton))
```

### デフォルトの戻るボタン
ナビゲーションバーのデフォルトの戻るボタンは以下のような`< Back`のボタンになっています。

![スクリーンショット 2024-11-01 18.54.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359094/b1e11c43-d0ac-623f-bb3d-64b2602bdc90.png)

### 期待した変更後の戻るボタン
今回は以下のような戻るボタンになることを期待しました。

![スクリーンショット 2024-11-01 21.03.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359094/f4299508-8a35-ac1d-975a-52f52f07cf19.png)

# 解決法

以下のように実装すると期待通りに変更が反映されました。

```swift
navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "chevron.backward"), style: .plain, target: self, action: #selector(tappedBackNavigationButton))
```

# 納得いかないところ
`backBarButtonItem`の公式ドキュメントを見てみると以下のように記載されています。

>When this navigation item is immediately below the top item in the stack, the navigation controller derives the Back button for the navigation bar from this navigation item. If you want to specify a custom title or image for the Back button, you can assign a custom bar button item (with your custom title or image) to this property. When you configure your bar button item, don’t assign a custom view to it; the navigation item ignores custom views in the backBarButtonItem.

日本語訳がこちら
>このナビゲーション項目がスタックの最上位項目のすぐ下にある場合、ナビゲーション コントローラーはこのナビゲーション項目からナビゲーション バーの [戻る] ボタンを派生します。 [戻る] ボタンのカスタム タイトルまたは画像を指定する場合は、カスタム バー ボタン項目 (カスタム タイトルまたは画像を含む) をこのプロパティに割り当てることができます。バーボタン項目を設定するときは、その項目にカスタムビューを割り当てないでください。ナビゲーション項目は、backBarButtonItem のカスタム ビューを無視します。

https://developer.apple.com/documentation/uikit/uinavigationitem/1624958-backbarbuttonitem

上記記載を見ると下記のようなコードは変更が適用されないが、

```swift
navigationItem.backBarButtonItem = UIBarButtonItem(customView: UIButton(type: .close))
```

下記のようなカスタムや適用されると解釈していました。
しかし、戻るボタンの変更は適用されませんでした。

```swift
navigationItem.backBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "chevron.backward"), style: .plain, target: self, action: #selector(tappedBackNavigationButton))
```
```swift
navigationItem.backButtonTitle = "Camera"
```

そうなると`backBarButtonItem`何のためにあるんやとなってしまいますが、ドキュメントには下記が記載されているのでこのプロパティで戻るボタンはカスタマイズできそうな気はしています。
> [戻る] ボタンのカスタム タイトルまたは画像を指定する場合は、カスタム バー ボタン項目 (カスタム タイトルまたは画像を含む) をこのプロパティに割り当てることができます。

ただその方法は現状自分はわからないので知っている方いたら教えてれると幸いです、、
ncコマンドでリバースシェルができなかった件

## 問題
ホスト端末のMacから仮想環境（UTM）のOSにncコマンドでシェルを奪おうとしたがうまくいかない。
## 状況
使用パソコン：Macbook Pro（M3チップ）
仮想端末を提供するアプリ：UTM
仮想端末のOS：ParrotOS（Linux）
想定：ParrotOSをncコマンドで待受状態にしてMacbookからシェルを奪取する
```bash
#ParrotOS
nc -lvp <ポート番号> -e /bin/bash
# 上記コマンドでエラーが発生する。
```
## 解決方法
通常インストールされるncはeオプションが無いらしいので代わりにncatを使う
```bash
# parrotOS側のコマンド
ncat -lvp <ポート番号> --exec /bin/bash

# macOS側のコマンド
nc <IPアドレス>　<ポート番号>

# 以降mac側で打ち込んだコマンドがparrotOSで実行され、結果がmac側に表示される。
```
## 終わりに
以前、ubunt（ホスト端末）と仮想環境のwindowsやAWSのEC2を使って問題なくncコマンドのeオプションが使用できた経験があったのでncコマンドでeオプションが使えないなんて考えがなく（ターミナルでヘルプを表示しオプションにeがないことは確認していたが、そんなわけないだろと思って無視していた）解決に時間がかかってしまった。思い込みに注意せねば…
CSSを学習したい！Step2

## はじめに
CSSを学習するStep2です！今回はCSS変数を学習したいと思います

## 成果物
![step2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/9f1c620e-f2a4-f4fd-fd9f-2e8081fc15e7.gif)

## ソースコード
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS変数のシンプルな例</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="card">
    <h2 class="title">CSS変数の例</h2>
    <p>CSS変数を使って色やスペースを管理しています。</p>
    <button class="button">クリック</button>
  </div>
</body>
</html>
```

```css:styles.css
:root {
    --primary-color: #3498db;  /* メインカラー */
    --text-color: #333;        /* 文字色 */
    --background-color: #f4f4f9; /* 背景色 */
    --padding: 16px;           /* 余白 */
    --border-radius: 8px;      /* 角丸 */
  }
  
  body {
    background-color: var(--background-color);
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    font-family: Arial, sans-serif;
  }
  
  .card {
    background-color: #fff;
    color: var(--text-color);
    padding: var(--padding);
    border-radius: var(--border-radius);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    text-align: center;
    max-width: 300px;
  }
  
  .button {
    background-color: var(--primary-color);
    color: #fff;
    padding: var(--padding);
    border: none;
    border-radius: var(--border-radius);
    cursor: pointer;
    transition: background-color 0.3s;
  }
  
  .button:hover {
    background-color: var(--background-color);
  }
  ```

  ## おわりに
  CSS変数をうまく使えるといいですね！！
【Matlab】endを使わず配列の最後の要素にアクセスする方法

# はじめに
配列の最後の要素にアクセスする際はMatlabの予約語`end`を使うのが簡単。
``` matlab:matlab
a = [0, 1, 2, 3, 4];
a(end)
% ans = 4
a(1:end-1)
% ans = 0 1 2 3
```

ただしこの`end`を変数に代入することはできない。
pythonだと負数のインデックスがあるので、変数を使った最後の要素へのアクセスが容易。
``` python:pyhon
a = [0, 1, 2, 3, 4]
a[-1]
#  4
a[0:-1]
#  0 1 2 3
b = -1
a[b]
#  4
a[0:b]
#  0 1 2 3
```


# やりたいこと
そんなに使う場面が多いわけではないが、Matlabでも配列の最後の要素に変数を使ってアクセスできるようにしたい。
可能な限り`end`を使わず、同じぐらいの手軽さでやりたい。

# ネック
変数に`end`やそれを含むものを代入できない。
``` matlab:matlab
a = [0, 1, 2, 3, 4];

% 以下いずれもエラーが出る
b = end;
c = end-1;
```



# `end`とは？
https://jp.mathworks.com/help/matlab/ref/end.html?s_tid=doc_ta

この記載の通り、
- コードブロックの終了
- 最後の配列インデックス
の二つの役割があるMatlab言語の基本的な予約語
## 1.の使い方
``` matlab:matlab
flag = true;
if flag == true
  myfunc(1)
else
  myfunc(2)
end

function output = myfunc(input)
output = 2*input;
end
```

ここで使われる`end`はどちらもコードブロックの終了を表す。

## 2.の使い方
``` matlab:matlab
a = [0, 1, 2, 3, 4];
a(end)
% ans = 4
a(1:end-1)
% ans = 0 1 2 3
```

冒頭の使い方がこちら。

つまり、一つの予約語に複数の役割があり、それぞれ使い方が全く異なっている。
コードブロックの終了は変数化の必要な状況がない（と思われる）が、配列インデックスは変数化することがよくあるため、最後の要素およびそれを含むインデックスも変数化したい。

# `end`を使わず配列の最後にアクセスする方法
## ①配列サイズを取得する関数（size,numel,length）を使う
``` matlab:matlab
a = [0, 1, 2, 3, 4];

[~,b] = size(a); % ベクトルおよび2次元配列に対するsize()の出力は[行数,列数]
% 列ベクトルの場合は[b,~] = size(a);
a(b)
% ans = 4

c = numel(a); % numel()の出力は要素数
a(1:c-1)
% ans = 0 1 2 3

d = length(a); % length()の出力は、最大の配列の次元の長さ。今回は2次元目（列）の長さ。
a(d-2:d)
% ans = 2 3 4
```

配列がベクトル（2次元配列で、一方の次元長さが1）の場合はこれらで事足りる。

2次元以上の配列でそれぞれの次元の最後の要素にアクセスする場合は`size()`を使う。
``` matlab:matlab
a = [0, 1, 2, 3, 4,
     5, 6, 7, 8, 9,
     10,11,12,13,14];

[r,c] = size(a)
% r = 3 c = 5

a(r,c)
% ans = 14

a(r-2,c-4)
% ans = 0
```

## ②ループ処理を使う
``` matlab:matlab
array = [1, 2, 3, 4, 5]; % 例としての配列
i = 1;
while true
    try
        temp = array(i);
        i = i + 1;
    catch
        lastIndex = i - 1;
        break;
    end
end
array(lastIndex)
% ans = 5
```


## ③配列の範囲を使う
``` matlab:matlab
array = [1, 2, 3, 4, 5]; % 例としての配列
array_ones = ones(size(array)); % find()は非ゼロ要素のインデックスを返すため、最後がゼロだった場合に備えた処理
indices = 1:max(1, find(array_ones, 1, 'last'));
indices_lr = fliplr(indices); % この配列の最後の要素がarrayの最後のインデックスになるが、endを使わないように左右反転
lastIndex = indices_lr(1); % 左右反転したのでindices(end)と同じ
array(lastIndex)
% ans = 5
```


# 結論
`end`ほど簡単に最後の要素にアクセスする方法は調べた限り存在しない。
`size()`や`numel()`を使うのが無難かな。
他に簡単な方法があれば是非教えてください。


内容およびコードの一部にchatGPTを使用しています。
【VSCode】GitHub Copilot Chatを使用してダイアグラムを生成する方法

GitHub Copilot Chatを使用してダイアグラムを生成するにはvscode-mermAIdという拡張機能をインストールします。

https://marketplace.visualstudio.com/items?itemName=ms-vscode.copilot-mermaid-diagram

インストールするとGitHub Copilot Chatにおいて`@mermAId`が使用可能になります。
使用すると現在のエディタの内容をもとに以下のようなシーケンス図などが作成できます。

![スクリーンショット 2024-10-31 14.59.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/88c534bf-7041-ef3b-a032-116d8bb6c97d.png)

![スクリーンショット 2024-10-31 14.51.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/8d479ad7-ac2d-96b2-76cb-5993a1f5665f.png)
Mac環境でのngrokの403 Forbidden Error

LINE bot開発で発生したエラーにめちゃくちゃ手間取ったのでメモ

## 環境
M1 Mac Sonoma 14.6.1

## エラー内容
ngrokを利用してLINE botの動作を確認しようとしたところ、下記エラーが生じた

![スクリーンショット 2024-11-01 20.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3803283/0eeb0a0e-fcb0-7279-c34f-4bb6157c72a9.png)

```:ngrok error
20:50:10.086 JST GET /static/lab/style/bootstrap-theme.min.css 403 Forbidden
```
※ ブログ書くときにたまたま開いていたJupyter labのサーバーを使ってスクショしました笑

だって、わざわざLINE botを起動させるの面倒くさいし...


## 解決方法
Macの設定のAirPlayレシーバーをoffにすることでエラーを解決できました。
[左上りんごマーク] > [システム設定] > [一般] > [AirDropとHandoff] > [AirPlayレシーバー]

## 参考
https://qiita.com/Marusoccer/items/7033c1bb9c85bf6789bd

https://stackoverflow.com/questions/70247195/flask-ngrok-access-to-subdomain-ngrok-io-was-denied-403-error

https://qiita.com/hirokun0204/items/a18427c50c90676aed95

## 余談
この方法だとjupyter labでは解決できませんでした。
もちろんLINE botは解決できました!
おそらくjupyter labのconfigでリモートアクセスをTrueにすればいけそう
(まだ試していない笑笑)

やる気出たら試します笑
今週中..今月..生きている間には..
一応、参考

https://mathshingo.chillout.jp/blog49.html

https://qiita.com/nujust/items/a396f96f9a7b7963e2f4

https://qiita.com/okdshi/items/6da004c78c471a15c0d7
CSSを学習したい！Step1

## はじめに
今年はフロントエンドのスキルアップを目標に取り組んできました！！
Reactの状態管理やコンポーネントの設計、ロジック周りの設計は理解できたのですが、最後はCSS。
これがまぁ難しいですね💦💦💦そもそもCSSに触れなさすぎて、こんな便利なCSSがあったのと作った後に教えてもらうこともありました！とにかく今年の最後はCSS！CSSと思って、アドベントカレンダーはCSSを中心に書いていきます！！頑張って25本書くぞ〜〜〜〜！！

## 成果物
![step1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/a62717dc-bd62-92fa-bbf1-41d88cdb97f7.gif)

## ソースコード

```css:step1/styles.css
:root {
    --bg-color: #f0f2f5;
    --card-bg: #ffffff;
    --card-border: #e0e0e0;
    --card-shadow: rgba(0, 0, 0, 0.1);
    --primary-color: #4a90e2;
    --text-color: #333;
    --border-radius: 10px;
    --spacing: 16px;
    --card-width: 200px;
  }
  
  *,
  *::before,
  *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
  
  body {
    font-family: Arial, sans-serif;
    background-color: var(--bg-color);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
  }
  
  .container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--card-width), 1fr));
    gap: var(--spacing);
    padding: var(--spacing);
    max-width: 1200px;
    width: 100%;
  }
  
  .card {
    background-color: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: var(--border-radius);
    box-shadow: 0 4px 8px var(--card-shadow);
    display: flex;
    align-items: center;
    justify-content: center;
    height: 150px;
    font-size: 18px;
    color: var(--text-color);
    transition: transform 0.3s, box-shadow 0.3s;
  }
  
  .card:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 16px var(--card-shadow);
  }
```

## 最後に
まず1本目です。とにかく書いて理解を深めていきます。書いているうちに理解が深まっていくので！
package.jsonとnpxについてまとめる

`package.json`の位置づけや設定可能な内容が分からなかったので調べた範囲でまとめる。
ついでに`npx`についても簡単にまとめる。

## package.jsonとは？
Node.jsのプロジェクトは公開の有無に関わらず1つのパッケージとして扱われる。
`package.json`はパッケージに関する諸々の情報が記載されているファイルである。
パッケージは、`package.json`が格納されているディレクトリがルートディレクトリとして扱われ、`npm`のコマンドは基本的にルートディレクトリで実行する必要がある。

`package.json`にはパッケージ名やパッケージの説明、ライセンス表記などパッケージの情報や、パッケージの依存関係、エイリアスやテストの定義などコマンドや実行に影響を与える情報などが含まれている。

### package.jsonの生成
`package.json`は`npm init`コマンドで生成できる。
以下は`npm init`コマンドで生成した`package.json`の例。

```json: package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "test package",
  "main": "test.js",
  "dependencies": {
    "acorn": "^8.12.1",
  },
  "devDependencies": {
    
  },
  "scripts": {
    "test": "jest"
  },
  "author": "",
  "license": "ISC"
}
```

#### `scripts`
コマンド名とそのコマンドを指定した際に実行される内容を定義できる。
ここで定義されたコマンドは`npm run <command name>`で実行可能。
`start`や`test`などいくつかのコマンド名は特別扱いされ、`npm start`や`npm test`のような形で実行可能。

### `dependencies`と`devdependencies`
`dependencies`はパッケージの実行に必要なパッケージ。
`devdependencies`は開発やテストに必要なパッケージ。
これらの追加・更新・削除は通常、`npm install <package>`コマンドを通して行う。
`devdependencies`に反映したい場合は、`npm install --save-dev <package>`とする。
`package.json`のこれらの項目を変更した場合は`npm install`コマンドで反映する必要がある。

### package-lock.jsonとは？
`npm install`した際に生成されるファイル。
依存パッケージのバージョンを固定するために使用される。

`package-lock.json`が存在する状態で`npm install`した場合はこのファイルの内容を基にパッケージのインストールを実施する。
その際、`node_modules`の削除を伴う。
`package-lock.json`の内容を優先してインストールしたい場合は、`npm ci`を使用する。
`npm ci`を使用した場合は、`package.json`との内容に矛盾があった場合、エラーとなる。

### `npx`とは？
パッケージを一時的に実行するためのコマンド。
一時的にパッケージを利用でき、使用後はパッケージが残らない。

## 参考
https://docs.npmjs.com/about-packages-and-modules

https://qiita.com/righteous/items/e5448cb2e7e11ab7d477

https://www.geeklibrary.jp/counter-attack/npx/
秋月電子で販売しているlattice FPGA（LCMXO2-256HC-4TG100C）のLチカ

# １．はじめに
秋月で買ったFPGA（MachXO2 LCMXO2-256HC-4TG100C）の書き込み時の配線や設定に関する備忘録です。

当該のFPGAの書き込みのための配線方法はいくつかネット上に情報がありますが、配線方法が人によってばらばらで、そのままだと自分の環境ではうまく動かなかったです。
自分の環境で動いたときの配線を備忘録として残します。

使用したFPGA↓
[秋月電子：MachXO2 LCMXO2-256HC-4TG100C](https://akizukidenshi.com/catalog/g/g111003/)

# ２．配線や設定
基本的には下記のサイトを参考に進めました。
>https://neurois.hatenablog.com/entry/2020/08/30/161403

ライターはこれです。
付属のマニュアルに従ってドライバーをインストールしました。
[FT2232D USBシリアル2ch変換モジュールキット EEPROM実装済](https://akizukidenshi.com/catalog/g/g116897/)

配線は秋月販売ページのものをベースとして少し手を加えています。
[参考資料（AE-FT2232を使用してFPGAにJTAGポートで書き込む為の回路）](https://akizukidenshi.com/goodsaffix/machxo2_writer.pdf)

具体的な配線の変更点などについては次の通りです。
・FT2232Dの18番ピン（VCCIOA）に3.3Vを給電する。
・FT2232DのJP2をオープンにする。
・FT2232Dの21番ピン（VCCUSB）には何も接続しない。
・FT2232Dの40番ピン（AD0）とLCMXO2-256HC-4TG100Cの91番ピン（P91_TCK）を繋ぐ線（JTAG_TCK）は2.2kΩ抵抗でプルダウンする。

lattice Diamondの「Cable and I/O Settings」の「Cable Settins」の「Cable」は「HW-USBN-2B(FTDI)」を、「Port」は「FTUSB-0」を選択しました。

# ３．おわりに
自分の備忘録としての記事なので読みにくいところがあるかと思います。
この手の配線などは環境によってうまくいく場合とそうでない場合が生じやすいものなので、同様の問題に直面した人のヒントの一つになれば幸いです。
【基本情報】通信プロトコル

# 通信プロトコル
* 異なるデバイスやPC、ソフトウェアが通信するために制定された手順
    * データ送受信のタイミングのフォーマットなど

## TCP/IP(Transmission Control Protocol)とは
* 送ったデータが相手に届いているか、その都度確認する通信
* 正確な信号を送信する通信規格を定めたもの
* エラーが起きてもクライアント側は何度もリクエストを送信し、サーバー側は正常に受け取って確実にレスポンスを返す
* TCP/IPは4つのレイヤーに分かれる

| レイヤー | 主なプロトコル | 用途 |
|:-:|:-:|:-:|
|  4層 アプリケーション層 | HTTP、FTP、SMTP等	  | メール、HP閲覧、ファイル転送  |
|  3層 トランスポート層 | TCP、UDP	  |  通信方式の選定 |
|  2層 インターネット層 | IP  | 相手先の特定  |
|  1層 ネットワークインターフェース層 | ETHERNET、WIFI、PPP  | 物理的なLANケーブルでPCを接続、ルーターの接続  |

## 代表的なプロトコル
| レイヤー | 名称 | 概要 |
|:-:|:-:|:-:|
| 1層  | ETHERNET  | 有線LANケーブルでの接続のこと/世界標準のプロトコル  |
|  1層 | WIFI（無線LAN）  |  離れた端末同士でも、通信ができる技術 |
| 1層  |  PPP(Point-to-Point Protocol) | 電話回線等を使って、1対1の通信で利用されるプロトコル  |
| 2層  | IP(Internet Protocol)  | IPアドレスを使用して、通信の相手先を特定する/論理アドレスとも呼ばれる  |
| 3層  |  TCP |  通信開始前に相手との間で仮想的な通信路を確保/データ破損を検出して、確実にデータを再送する |
|  3層 | UDP  | 通信開始前に相手との間で、事前のやりとりをしない/素早くデータを送信できる  |
|  4層 | HTTP(Hyper Text Transfer Protocol)  |  HTMLで書かれたHPの情報をやりとりするプロトコル/非暗号化 |
|  4層 | HTTPS  | HTTPを暗号化してデータで送受信する  |
|  4層 | SMTP(Simple Mail Transfer Protocol)  |  メールを送信するためのプロトコル |
| 4層  | POP(Post Office Protocol) | メールを受信するためのプロトコル/サーバからメールをダウンロードしているので、他端末でサーバーを見に行っても、そこにメールはない  |
| 4層  | IMAP(Internet Message Access Protocol) | メールを受信するためのプロトコル/メールサーバーからダウンロードせず、直接サーバー上を見に行く  |
|  4層 | FTP(File Transfer Protocol) | サーバーとクライアント間で、ファイルを送受信するためのプロトコル  |
| 4層  | SFTP | FTP通信を暗号化して送るプロトコル  |
|  4層 | DNS(Domain Name System) | ドメイン名を使用してアクセスするためのプロトコル/IPアドレスを名前解決する  |
| 4層  | DHCP(Dynamic Host Configuration Protocol) | 自動的にすべての端末に設定情報を付与する  |
PHPで三角関数を計算する(度数法、弧度法)

PHPで三角関数の正弦、余弦、正接を計算するにはsin(), cos(), tan()関数を用います。
この際に指定する角度は弧度法(ラジアン)となっています。
度数法で表現された角度をラジアンに変換するためには、deg2rad()関数を用います。

たとえば、度数法で30°の正弦、余弦、正接を表示するスクリプトは以下のようになります。

```php
$degree = 30; //度数法による角度
$radian = deg2rad($degree); //弧度法による角度
print sin($radian) . "\n"; //0.5
print cos($radian) . "\n"; //0.86602540378444
print tan($radian) . "\n"; //0.57735026918963
```

参考：
PHP: sin - Manual https://www.php.net/manual/ja/function.sin.php
PHP: cos - Manual https://www.php.net/manual/ja/function.cos.php
PHP: tan - Manual https://www.php.net/manual/ja/function.tan.php
PHP: deg2rad - Manual https://www.php.net/manual/ja/function.deg2rad.php
GCC拡張で式指向にbreakとかcontinueとか

ZigとかRustみたいに式の中で`break`とか`continue`するマクロ
```c
#define break ({ break; 0; })
#define continue ({ continue; 0; })

void test() {
  for (;;) {
    int a = break;
    // unreachable
  }
  for (int i = 0; i < 5; i++) {
    if (continue) {}
    // unreachable
  }
}
```
nullチェックみたいな使い方ができる
```c
#define break ({ break; (void *)0; })
#define continue ({ continue; (void *)0 })
#define orelse ?:

void test() {
  for (...) {
    char *p = malloc(100) orelse break;
    ...
  }
}
```
いちおう文としても書ける
```c
#define break ({ break; 0; })

void test() {
  for (;;) {
    break;
  }
}
```
`return`は括弧が必要になる(ださい)
```c
#define return(x) ({ return x; (void *)0; })
#define orelse ?:

int test() {
  char *p = malloc(100) orelse return(1);
  ...
}
```
「ソフィー・ジェルマン(Sophie Germain)」の恒等式を調べた。

・YouTubeの高校入試問題のコメントで教えてもらいました。ソフィー・ジェルマン
・別件で、以前wikipediaの内容を聞いた?見たような?

# オリジナル

"市川高校　令和4年　計算問題" を YouTube で見る。コメント様より。

https://youtu.be/US4mr-Y7O20?si=Pw-dWxGPvhJ61vqY


# 参考

https://manabitimes.jp/math/686

# wikipedia

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

https://ja.wikipedia.org/wiki/ソフィ・ジェルマン
【基本情報】MACアドレスとは

# MACアドレス(Media Access Control Address)とは
* ネットワークカード(PC/ルータ等のネットワーク機器)に付与されている番号
* 全世界でMACアドレスが重複することはない
* LANやインターネットでのイーサネット通信で利用される
* 隣の機器への通信にのみ使用される
    * 別のネットワークセグメントに繋がっている機器同士の通信には使えない
    * 同一のネットワークセグメントであれば、インターネットがなくても通信が可能
* 0~9、A~Fの16進数で構成される

## MACアドレスの形式 ex)00:10:2A:33:11:21
* 00:10:2A：前半6桁をベンダー識別子
    * ネットワーク機器のベンダー(製造会社)の固有番号
* 33:11:21：後半6桁をベンダー内管理番号
    * ベンダーが管理している番号で、機器ごとに固有の一意が割り当てられる
* `FF:FF:FF:FF:FF:FF`を指定すると、所属するネットワークの全ての機器に一斉同報送信される(ブロードキャストフレーム)
【基本情報】IPアドレスとは

# IPアドレス(Internet Protocol Address)とは
* インターネットを使用する際に、コンピューターに割り当てられた住所
* 送信先を特定するのに必要であり、他と重複するIPアドレスは存在してはいけない

## グローバル/プライベートIPアドレスについて
IPアドレスをは下記の2つに分けられる
1. グローバルIPアドレス
    * 全世界で通用するIPアドレス
    * 全世界で一意になる、重複しないIPアドレス
2. プライベートIPアドレス
    * 仲間内でのみ通用するIPアドレス
    * ローカルネットワーク内で使える、自分たちで勝手に決めて良いIPアドレス

## グローバルIP/プライベートIPの違い
* グローバルIP
    * インターネットに接続したい場合に必要で、インターネットの窓口となる
* プライベートIP
    * 基本的にルータ配下の特定のネットワーク内のデバイスに割り当てられる
    * プロバイダーから割り当てられたIPアドレスが1つでも、ルーター配下に接続している端末がインターネットに接続できているのはプライベートIPアドレスのおかげ

## IPアドレスが割り当てられる仕組み
### グローバルIPアドレス
* ICANN(別名IANA)と呼ばれる国際的な機関が管理
    * 日本ではJPNIC(一般社団法人ネットワークインフォメーションセンター)が管理している
* 上位レジストリから下位レジストリに対してIPアドレスを与える
    * ICANN -> APNIC -> JPNIC
    * 下位レジストリのプロパイダーがエンドユーザーにIPアドレスを割り当てる
### プライベートIPアドレス
* プライベートIPアドレスの範囲内で、各機器に一意の値が割り当てられる
    * グローバルIPアドレスとは異なり、組織内で重複しなければ良い

## サブネットマスク
* IPアドレスをネットワーク部とホスト部に区別するためのもの
* 10進数表記されているIPアドレスを2進数表記にして考える

### ネットワーク部
* そのIPアドレスが属しているネットワークを識別するための部分
* 日常生活で例えるなら...
    * 住んでいる都道府県/市区町村のような感じ

### ホスト部
* ネットワーク内のコンピューターを識別するための部分
* 日常生活で例えるなら...
    * 住んでいる建物名/アパート名/号室みたない感じ

### 192.168.128.10/24の場合
* 2進数にすると... 
    * 192.168.128.10 => 11000000.10101000.10000000
    * /24 => /00001010
    * よって、11000000.10101000.10000000/00001010となる
* /24の場合、左から24bitまでがインターネット部になるので、
    * 192.168.128 : ネットワーク部
    * .10 : ホスト部
Eclipseのおすすめショートカットと環境設定

# Eclipseのおすすめショートカットと環境設定

Eclipseを効率的に使いこなすためには、便利なショートカットキーや環境設定を活用することが重要です。以下に、おすすめのショートカットキーと環境設定を紹介します。

## おすすめショートカットキー

### エディタ操作

- **コード補完**: `Ctrl + Space`\:kissing_closed_eyes:

  - 入力途中のコードを補完します。
- **行の削除**: `Ctrl + D`
  - カーソルがある行を削除します。
- **行番号へ移動**: `Ctrl + L`
  - 指定した行番号に移動します。
- **行の複製**: `Ctrl + Alt + ↑` または `Ctrl + Alt + ↓`
  - 現在の行を上下に複製します。
- **行の移動**: `Alt + ↑` または `Alt + ↓`
  - 現在の行を上下に移動します。
- **整形**: `Ctrl + Shift + F`\:kissing_closed_eyes:

  - コードを自動で整形します。
- **インデント調整**: `Ctrl + I`
  - 選択したコードのインデントを調整します。
- **コメントアウト**:
  - **行コメントの切り替え**: `Ctrl + /`\:kissing_closed_eyes:
  - **ブロックコメントの追加**: `Ctrl + Shift + /`
  - **ブロックコメントの解除**: `Ctrl + Shift + \`

### コードナビゲーション

- **宣言元へ移動**: `F3`\:kissing_closed_eyes:
  - カーソルがあるシンボルの宣言元に移動します。
- **型の検索**: `Ctrl + Shift + T`
  - プロジェクト内のクラスやインターフェースを検索して開きます。
- **リソースの検索**: `Ctrl + Shift + R`
  - ファイル名でプロジェクト内のリソースを検索して開きます。
- **リファレンスの検索**: `Ctrl + Shift + G`
  - 選択したシンボルの参照箇所を検索します。

### リファクタリング

- **名前の変更**: `Alt + Shift + R`
  - 変数名やメソッド名などを一括で変更します。
- **メソッドの抽出**: `Alt + Shift + M`
  - 選択したコードを新しいメソッドとして抽出します。
- **ローカル変数の抽出**: `Alt + Shift + L`
  - 選択した式をローカル変数として抽出します。

### その他

- **インポートの整理**: `Ctrl + Shift + O`
  - 未使用のインポートを削除し、必要なインポートを追加します。
- **上書き保存**: `Ctrl + S`\:kissing_closed_eyes:
  - 現在のファイルを保存します。
- **全てのファイルを保存**: `Ctrl + Shift + S`
  - 開いている全てのファイルを保存します。


## おすすめ環境設定

### エディタ設定

- **行番号の表示**:
  - `ウィンドウ` > `設定` > `一般` > `エディター` > `テキスト・エディター` で「行番号を表示する」にチェックを入れます。
- **ホワイトスペースの表示**:
  - 同じくテキスト・エディターの設定で「ホワイトスペースの表示」にチェックを入れます。
- **自動保存の設定**:
  - `ウィンドウ` > `設定` > `一般` > `エディター` で「自動保存を有効にする」を選択し、適切な間隔を設定します。

### フォントと色

- **フォントの変更**:
  - `ウィンドウ` > `設定` > `一般` > `外観` > `色とフォント` からエディターのフォントを変更できます。
- **テーマの変更**:
  - `ウィンドウ` > `設定` > `一般` > `外観` で「テーマ」を選択し、好みのテーマを選びます。
:::note info

**補足 自動補完の設定を有効にする**

特定の文字を入力した際に自動的に補完候補が表示されるよう設定できます。

- **設定手順**:
  1. 上部メニューから「ウィンドウ」→「設定」（または「環境設定」）を選択します。
  1. 検索に「コンテンツ・アシスト」と入力します
  2. 「Java」→「エディター」→「コンテンツ・アシスト」を開きます。
  3. 「自動有効化」の項目で以下を設定します。
     - **自動有効化遅延（ミリ秒）**: 補完候補が表示されるまでの遅延時間を設定します。例えば、`200`ミリ秒など。
     - **Javaの自動有効化トリガー**: 自動補完を開始する文字を指定します。デフォルトでは`.`のみですが、`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_`を追加することで、変数名やメソッド名の入力中にも補完が有効になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576094/08f62072-21d1-029d-2806-4ff9c5ae5e4b.png)
:::
### その他の便利な設定

- **コードテンプレートの設定**:
  - `ウィンドウ` > `設定` > `Java` > `エディター` > `テンプレート` でコードのテンプレートを設定できます。
- **タブとスペースの設定**:
  - `ウィンドウ` > `設定` > `Java` > `コード・スタイル` > `インデント` で、タブ幅やスペースの設定を調整します。
- **デバッグ設定**:\:kissing_closed_eyes:
  - ブレークポイントやウォッチポイントの設定を活用して、効率的にデバッグを行います。
[AWSコスト最適化] AWSリソースの夜間停止とその運用課題について

# はじめに
こんにちは、NTTDATAのKojiです。
この度、2024 Japan AWS Jr. Championsのメンバーでブログリレーを行うことになりましたので、普段SREとして業務を行なっている中で得た知見を共有しようと思います。
内容としては、コスト最適化を目的にAWSリソース(EC2,RDS,AutoScalingGroup)の夜間停止を行おうと思っている方や、既に行なっている方向けに、その仕組みと運用する上での注意点を紹介しようと思います。


# 夜間停止の仕組みとその課題について
AWSリソースの夜間停止と聞いてまず真っ先に思いつくのがEventBridgeを利用することだと思います。
EventBridgeのEventBridge Schedulerという機能は、タスクを作成・実行・管理してくれるものなので、
- 毎日特定の時間にインスタンスを起動
- 毎日特定の時間にインスタンスを停止

は実現可能だと思います。
ただそれ自体は設定も導入も簡単なのですが、いざ運用するとなると以下のような課題が発生してくると思います。

- 各チームが日別に細かな起動・停止を行うことができない。
    - 例えばアプリチームが普段停止している試験環境を夜間でも使いたい場合を考えます。この場合、EventBridgeの設定をIaC管理していて、そのコードをインフラチームが管理する運用になっていると、アプリチームはすぐにそのコードを修正することができないです。
    - 上記によりアプリチームとインフラチーム間で作業依頼などやりとりが発生します。それにより余計なリードタイムが発生し開発スピードが低下したり、運用負荷が高まってしまったりします。
- インフラチームが突発的対応が必要になり稼働が取られてしまう。
    - シンプルに別作業の妨げになりますし、管理しているレポジトリで修正を行い設定をapplyする、アプリチームの用事が終わったら元に戻すなど一連の作業がトイル化しています。

これらの課題はアプリチームとインフラチームの境目がないような比較的小さめのプロジェクトでは、コミュニケーションコストが低いことや権限の制限が特にないなどで発生しづらいと思います。(中長期的目線で組織やプロジェクトがスケールしてくると発生する可能性は十分あると思います。)
しかし私が所属するプロジェクトではアプリチームとインフラチーム間で使用可能なリソースが権限によって分離されていることや、複数のシステムを横断的に少数のインフラチームメンバが見ていることもあり、大きな課題となっていました。




# 解決策
これらの課題を解決するためにStep FunctionsとChange Calendarを利用した新しい仕組みを導入しました。<br>AWS Systems Manager Change CalendarはカレンダーにOPENかCLOSEの予定を設定できるサービスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634057/d00c52f8-2529-01e5-c4a5-70216a822555.png)

詳しい実装は省きますが、この仕組みの概要は以下です。
- Step Functionsを用いて以下のワークフローAを作成する(Lambdaのコーディングは必要)
    - カレンダーの情報取得
    - カレンダー内のイベント確認
    - イベントで起動設定がなされている(起動時刻の範囲内)場合、カレンダー名をtagに持つリソースを起動する
    - そうでない場合、カレンダー名をtagに持つリソースを停止する。
- EventBridgeのルールでワークフローAを30分ごと(ここの時間は変えて良い)に実行するように設定する。
- Change Calendarのコンソールで`サービス名+環境名`の`hoge_dev`などとカレンダー(デフォルトcloseの設定)を作成する。
- カレンダー内でイベントを作成し、起動設定を行う。
    - 例: 9:00 - 21:00 10/15-11/15 まで等
- 起動停止を設定したいリソース(EC2,RDSなど)にカレンダー名と同じ名前のtagをつける。


この仕組みを導入することで、
- 開発環境は9:00-21:00で起動したい。
- 試験環境は普段はclose、安定性試験などで一時的に夜間、休日などにも利用したい。
といった要望も、一度リソースへのtagの設定とカレンダーの作成さえインフラチームがしてしまえば、アプリチームが柔軟かつスピーディーに対応可能となりました。
また、アプリチームとインフラチームのやり取り、コード修正などの作業が減り運用負荷軽減につなげることができました。

# ASGについて
EC2ではなくEKSなどを使っていてAutoScalingGroupでノードを管理している場合は
アプリチーム側で起動するノードの台数を調整したいなどの要望もあるかと思います。
その場合はASGのtagに以下を設定し、tagの変更でノードの起動数を変更できるようにすると良いと思います。
- DesiredCapacity
    - 停止時に設定されていた「希望する容量」の値が入ります。起動時にこのタグの値を参照、起動し自動でタグの削除が行われます。
- MinimumCapacity
    - 停止時に設定されていた「最小キャパシティ」の値が入ります。起動時にこのタグの値を参照、起動し自動でタグの削除が行われます。
- MaximumCapacity
    - 停止時に設定されていた「最大キャパシティ」の値が入ります。起動時にこのタグの値を参照、起動し自動でタグの削除が行われます。


# 終わりに
この課題を通じて、
- コスト最適化を行うことだけではなく、その後の中長期的な運用のことも考えて設計することの重要さ
- この仕組みを別プロジェクトに横展開することや、対象リソースを広げていくことで組織の全体最適に繋げることの重要さ

を学ぶことができました。<br>
同じような課題を抱えている方の参考になりましたら幸いです。

# 参考
https://qiita.com/ys1/items/21744f39676286b2c321
https://qiita.com/h_hoga/items/15da0c2632542f7d8150