OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub Actions学んでみた①

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:

**「いいね」か「ブックマーク」**
を頂けると僕のモチベーションアップになります！:thumbsup:
少しでも気に入っていただけたらよろしくお願いいたします！:thumbsup:


# 今回の目的
自分の作ったコンポーネントを確認したり検証するための技術を身に付けたい！
公式のクイックスタートを参考に進めていきます。
項目ごとに補足のみ書いて進めています。わかりづらいところの理解の手助けになれば幸いです！

# 主に参考にさせていただいた記事

https://docs.github.com/ja/actions/quickstart

# クイックスタート
## はじめに（GitHub Actionsとは）
GitHubが提供するCI/CD（継続的インテグレーション／継続的デリバリー）ツールです。これにより、リポジトリの変更に対して自動化されたワークフロー（ビルド、テスト、デプロイメントなど）を設定することができます。

## 最初のワークフローを作成する
新しいレポジトリを作成。Actionsタブからsetupを始めます。

## ワークフローの結果を表示する
ファイル作成後、実行された内容を確認しましょう。
![スクリーンショット 2024-06-14 20.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/a345f4fd-ae38-3b5e-f660-c3aae13fef43.png)

# GitHub Actionsについて
## サンプルワークフローを作成する ワークフローファイルを理解する
```yml
name: learn-github-actions
run-name: ${{ github.actor }} is learning GitHub Actions
on: [push]
jobs:
  check-bats-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install -g bats
      - run: bats -v
```

GitHub リポジトリの 「Actions」 タブに表示されるワークフロー名
```yml
name: learn-github-actions
```

ワークフロー実行中、表示されるメッセージ
```yml
run-name: ${{ github.actor }} is learning GitHub Actions
```
![スクリーンショット 2024-06-14 20.21.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/0b9bd683-2658-2d37-6517-e293cf5e7cc6.png)

ワークフローのトリガー。今回はPushがトリガーとなる。
```yml
on: [push]
```

ジョブのグループ化
```yml
jobs:
```
ジョブを定義
```yml
check-bats-version：
```

ubuntu-latest（最新版の Ubuntu Linux）で実行するように設定
```yml
runs-on: ubuntu-latest
```
すべてのステップをグループ化。入れ子になっているのはアクションかスクリプト
```yml
steps:
```
actions/checkout アクションはワークフローでリポジトリのコードを使用するときに使う。
```yml
- uses: actions/checkout@v4
```
Node.jsのバージョンを指定してインストール
```yml
- uses: actions/setup-node@v4
        with:
          node-version: '20'
```
コマンドを実行するようジョブに指示
```yml
 - run: npm install -g bats
```
batsコマンドを実行
```yml
- run: bats -v
```

# 次

https://qiita.com/mr_noppo/items/f815d6af8847500d5f00
闘魂Elixir ーー AtCoder Beginner Contest 354(B)をElixirで楽しむ

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>


# はじめに

[AtCoder Beginner Contest 354](https://atcoder.jp/contests/abc354)を[Elixir](https://elixir-lang.org/)で解いてみます。

[AtCoder](https://atcoder.jp/)を解くのが趣味で、休憩時間に解いているという若い人がいて、それってすごい意識の高い休憩時間の過ごし方だと思って、私も真似してみることにしました。


# [AtCoderをElixirでやってみる](https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01)

入力の読み取り方や解答の作り方は、別の記事にまとめています。


https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01

ご参照くださいませ。

[Elixir](https://elixir-lang.org/)で[AtCoder](https://atcoder.jp/)を楽しむためには、エントリポイントを`Main.main/0`にする必要があります。つまり`Main`モジュールを作って、その中に`main/0`関数を定義するわけです。

# [B - AtCoder Janken 2](https://atcoder.jp/contests/abc354/tasks/abc354_b)

問題はリンク先をご参照くださいませ。
私の解答を貼っておきます。


<details><summary>私の解答</summary>

_問題文を読んでいることを前提にひとこと解説をしておきます。_

並びかえには、[Enum.sort_by/3](https://hexdocs.pm/elixir/Enum.html#sort_by/3)を使えばよいでしょう。
T mod N が何者だ？　ですが、割り算の余りですので、[rem/2](https://hexdocs.pm/elixir/Kernel.html#rem/2)を使えばよいでしょう。


```elixir
defmodule Main do
  def main do
    n = IO.read(:line) |> String.trim() |> String.to_integer()
    
    list = for _i <- 1..n do
      [s, c] = IO.read(:line) |> String.trim() |> String.split(" ")
      {s, String.to_integer(c)}
    end

    solve(n, list)
    |> IO.puts()
  end
  
  def solve(n, list) do
    t = list |> Enum.map(fn {_s, c} -> c end) |> Enum.sum()
    sorted_list = list |> Enum.sort_by(fn {s, _c} -> s end)
    t_mod_n = rem(t, n)
    
    sorted_list |> Enum.at(t_mod_n) |> elem(0)
  end
end
```




</details>




---

# さいごに

[AtCoder Beginner Contest 354](https://atcoder.jp/contests/abc354)を[Elixir](https://elixir-lang.org/)で解くことを楽しみました。

あなたのお好きなプログラミング言語でお楽しみください。

---


**闘魂**とは、  **「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」** との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
**アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。**

---

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>
<b><font color="red">$\huge{１、２、３ ぁっダァー！}$</font></b>
LambdaでSESが受信したメールを一括取得する

# 導入
こんにちは。エンジニアのYamaです。

特殊なパターンですが、Amazon Simple Email Service (SES)で受信したメールをLambdaで一括処理することがあったので、備忘録的に残しておきます。

# 実装内容

今回作成したLambdaは、CloudWatch Eventsで毎日23時に実行することを想定しています。
SESの取得範囲は、前日の23時から当日の23時までのものになります。
また、SESから取得したデータの加工に関しては、割愛しています。

## Lambdaソース

```python
import boto3
from datetime import datetime, timedelta

def lambda_handler(event, context):
    # SES クライアント
    ses_client = boto3.client('ses', region_name='your-region')

    # 今日の日付を取得
    today = datetime.utcnow().date()
    end_time = datetime(today.year, today.month, today.day, 23, 0, 0)
    # 24時間前
    start_time = end_time - timedelta(hours=24)

    # SESの受信メールを一括取得する
    response = ses_client.list_receipt_rules(
        StartDate=start_time,
        EndDate=end_time
    )

    for receipt_rule in response['ReceiptRules']:
        ### 取得したメール情報を処理する ###
        print(receipt_rule)

    # 任意の処理が完了した後、レスポンス
    return {
        'statusCode': 200,
        'body': 'Get received mail info: success'
    }

```

# 最後に
案外実装は簡単でした。
SESはメール送信に利用するユースケースが多いと思うので、あまり使う機会はないかもしれませんが、もし受信メールに対してLambdaで処理を行いたい際はご参考にしていただけると幸いです。
闘魂Elixir ーー AtCoder Beginner Contest 354(A)をElixirで楽しむ

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>


# はじめに

[AtCoder Beginner Contest 354](https://atcoder.jp/contests/abc354)を[Elixir](https://elixir-lang.org/)で解いてみます。

[AtCoder](https://atcoder.jp/)を解くのが趣味で、休憩時間に解いているという若い人がいて、それってすごい意識の高い休憩時間の過ごし方だと思って、私も真似してみることにしました。


# [AtCoderをElixirでやってみる](https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01)

入力の読み取り方や解答の作り方は、別の記事にまとめています。


https://zenn.dev/torifukukaiou/articles/ac84c87736ceebf4da01

ご参照くださいませ。

[Elixir](https://elixir-lang.org/)で[AtCoder](https://atcoder.jp/)を楽しむためには、エントリポイントを`Main.main/0`にする必要があります。つまり`Main`モジュールを作って、その中に`main/0`関数を定義するわけです。

# [A - Exponential Plant](https://atcoder.jp/contests/abc354/tasks/abc354_a)

問題はリンク先をご参照くださいませ。
私の解答を貼っておきます。


<details><summary>私の解答</summary>

_問題文を読んでいることを前提にひとこと解説をしておきます。_

条件を満たした場合には計算を打ち切ってよいので、解法の骨格には、[Enum.reduce_while/3](https://hexdocs.pm/elixir/Enum.html#reduce_while/3)を使えばよいでしょう。


```elixir
defmodule Main do
  def main do
    h = IO.read(:line) |> String.trim() |> String.to_integer()

    solve(h)
    |> IO.puts()
  end
  
  def solve(h) do
    0..(10 ** 10)
    |> Enum.reduce_while(0, fn i, acc ->
      new_acc = acc + 2 ** i
      if new_acc > h, do: {:halt, i + 1}, else: {:cont, new_acc}
    end)
  end
end
```




</details>




---

# さいごに

[AtCoder Beginner Contest 354](https://atcoder.jp/contests/abc354)を[Elixir](https://elixir-lang.org/)で解くことを楽しみました。

あなたのお好きなプログラミング言語でお楽しみください。

---


**闘魂**とは、  **「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」** との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
**アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。**

---

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>
<b><font color="red">$\huge{１、２、３ ぁっダァー！}$</font></b>
M1/M2/M3 Macで外部ディスプレイにフリッカーが発生する不具合とその対処法

## 不具合の概要

M1/M2/M3 Macを外部ディスプレイに接続した際、フリッカー（ちらつき）が発生することがある。
発生条件は不明だが、暗めのグレー色の画面を表示している際に縦線が入ったようなフリッカーが発生する、という症状。フリッカーが発生したりしなかったりするので詳細な再現条件は不明。

外部ディスプレイ側の不具合かと思われたが、どうやらM1/M2/M3 Macと相性が悪いらしい（Intel Macの場合は問題が発生しない）。各ディスプレイメーカーもHPに情報を掲載している。

* EIZO: https://www.eizo.co.jp/support/compati/pc/mac/m1m2/
* BenQ: https://www.benq.com/ja-jp/knowledge-center/knowledge/how-to-fix-mac-m1-m2-external-monitor-flicker.html

しかし現時点では対症療法のような解決方法しか掲載されておらず、原因は不明とされている。

また、以下のforumでも非常に多くのユーザが嘆いていることが確認できる。

https://discussions.apple.com/thread/252106534?sortBy=best

しかし、残念ながらApple側からの対処方法などの情報は一切見つからない。

## 解決方法

最近になって民間で根本的な治療法が発見されたらしい。

https://www.reddit.com/r/mac/comments/18aadyf/will_apple_ever_fix_external_monitor_flicker_on/

情報によると、[StillColor](https://github.com/aiaf/Stillcolor) や [BetterDisplay](https://github.com/waydabber/BetterDisplay) をMacにインストールしてディザリング（dithering）をオフにすることでフリッカーを解決できる。
これだけの目的ならBetterDisplayはオーバーキル感があるのでStillColorで十分そう。

自分もStillColorをインストールしてditheringをオフにしたが、以降フリッカーは発生していない。

どうもditheringという（余計な？）ことをしてくれているおかげで外部ディスプレイとの相性が悪くフリッカーが発生してしまっていたようだ。

## 所感

M1 Macが登場してから実に4年近く問題が放置され、最近になってようやく解決方法についての情報が出てくるようになった（それも公式ではない）という状況...。公式の設定画面ではditheringはオフにできないし。そういうところですよ。
GPT4-oのAzure OpenAI APIで作るRAGシステム　~AI Challenge day 第2回参加報告を兼ねて~

# はじめに
ボンジョールノ！
2024 6/11,12にASCII、Microsoft様主催でAI Challenge day第二回というものが開催されました。
詳細は以下に書きますが、要はRAGのコンテストです。
そこで我々センシンロボティクスはASCII賞をいただきました！関わってくれた皆様、ありがとうございます！
その中で私が作った（発表では日の目を見ることがなかった）GPT-4oを使ったRAGシステムについて書きたいと思います。

# 完成品のイメージ
本ブログを読んでできることのイメージは[こちら](https://photos.app.goo.gl/MxDMkqVydNqGueXX8)です。
事前に自分の持っているPDF,powerpoint,excel等のドキュメントを登録し、画像やテキストを入力として質問をすると、答えてくれるweb appです。

# GPT-4oのAPIからの使い方のサンプル
急いでいるからさっさと作り方を教えて、という方のために、ソースコードと使い方が載ったgit hubページを共有します。
[source code](https://github.com/sensyn-robotics/microsoft-ai-challenge-day)

# AI challenge dayとは
お題は「日本の世界遺産を紹介するアシスタントを作ろう！」というテーマで、第一回とタイトルは同様ですが、中身のドキュメントは違うというものでした。詳細は以下に画像を貼りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/9e7dcf85-9dbe-990d-526a-9e2169f64d31.png
)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/5b53d9ec-c71c-17fb-a86c-96c45d4097cd.png)
（microsoft様に確認したところ、以前載せようとした資料は関係者限定のリンクだそうなので、一部のスクショのみ掲載します。）


# GPT-4oをAPIから呼び出す方法
[こちら](https://github.com/sensyn-robotics/microsoft-ai-challenge-day/blob/2f55e6db814191b3db25efb07306ab5cfabab7a9/.env.sample#L7)のように、.envファイルでモデル指定でgpt-4oを指定するだけでOKです。
　現在Azure OpenAI では、GPT-4oのAPIは[こちらのリージョン](https://microsoftapc.sharepoint.com/:b:/r/teams/AIChallengeDay611-12/Shared%20Documents/General/%E7%AC%AC%EF%BC%92%E5%9B%9E%20AI%20Challenge%20Day%20%E3%81%8A%E9%A1%8C%E5%85%AC%E9%96%8B%E7%94%A8%201.pdf?csf=1&web=1&e=RGzgpv)から使用可能です。我々はAI Challenge dayでは、EastUSを使用しました。

# おわりに
いかがでしたでしょうか？
記事作成サボりすぎでしたでしょうか？
Yes!このあたりの情報は、もう明日にでも古くなりそうなので、早く情報出したほうがいいということで、さくっと書きました！皆様いいね・コメントよろしくぅ！
HULFT10 for Container Services 拡張性構成の考え方


## 1. はじめに
こんにちは、すぎもんです:smile:

いわゆる「コンテナ版HULFT」であるHULFT10 for Container Services(以下**CS版**)を少しずつ触っております。  
CS版では従来のクライアントOSインストール版HULFT(以下**OS版**)と異なり、AWSのインフラ構成（インスタンス数、ストレージ、DB、ネットワーク等）によりファイル転送のパフォーマンス向上（同時集配信数、全体スループットの向上）が期待できます。このコンテンツでは、HULFT10の集配信性能を高めるためのAWS構成の考え方、気を付けるべきポイントなどを考えてみます。

---

## 2. OS版とCS版の拡張対応方法
### 2-1. OS版
基本的に、CPU, メモリ、ネットワークなどの増強でボトルネックを解消するアプローチです。ロードバランサー対応はされていないため、スケールアップでの対応になります。

### 2-2. CS版
ロードバランサーによる分散処理（タスク起動数を増やす）ことで全体スループットを上げるアプローチです。ロードバランサー対応のアーキテクチャとなり。スケールアウトでの対応ができます。

| OS版 | CS版 |
|---|------|
| ロードバランサー対応していない | ロードバランサー対応している |
| CPU, メモリ、ネットワークなどの増強 |タスク起動数を増やす |
| スケールアップ |スケールアウト |

---

## 3. CS版の拡張性構成のポイント

HULFT 10 for Container Servicesのスケーリングに関する詳細についてはこちらの記事を参照してください。

https://qiita.com/sugimon/items/3b88711d6c725e56ea57

管理コンテナと転送コンテナのタスク増加ケースと考慮ポイントです。

### 3-1. 管理コンテナのタスクを増やすケース
#### 3-1-1. 管理画面にアクセスが集中する
DBアクセスが多くなるため、起動数を増やして対応します。

#### 3-1-2. 少量多頻度転送が多い
こちらのケースもDBアクセスが多くなるため、起動数を増やして対応します。

### 3-2. 転送コンテナのタスクを増やすケース
#### 3-2-1. 同時多重転送が多い
転送処理を分散させるため、転送コンテナの起動数を増やして対応します。

### 3-3. その他考慮ポイント

#### 3-3-1. 転送コンテナのタスク数を増やしても効果がない
タスク数を増やしても効果がないときは、スケールアップのアプローチを考慮します。具体的には、EC2インスタンスの性能向上（CPUやメモリの増強）を検討します。

:::note info
例えば、「10GBファイルを短時間で送りたい」などのシナリオです。大きなファイルの転送では、タスク数を増やすことでの効果は見込むことができません。
:::

---

### 表：管理コンテナと転送コンテナのタスク増加ケースと考慮ポイント

| 対応方法 | ケース | 解説 |
|------------|--------|------|
| **3-1. 管理コンテナのタスクを増やす** | **3-1-1. 管理画面にアクセスが集中する** | DBアクセスが多くなるため、管理コンテナ起動数を増やして対応します。 |
| | **3-1-2. 少量多頻度転送が多い** | こちらのケースもDBアクセスが多くなるため、管理コンテナ起動数を増やして対応します。 |
| **3-2. 転送コンテナのタスクを増やす** | **3-2-1. 同時多重転送が多い** | 転送処理を分散させるため、転送コンテナの起動数を増やして対応します。 |
| **3-3. その他** | **3-3-1. 転送ファイルサイズが大きい** | 転送コンテナのタスク数を増やしても効果がないときは、スケールアップのアプローチを考慮します。具体的には、EC2インスタンスの性能向上（CPUやメモリの増強）を検討します。 |

---

## 4. おわりに
いかがでしたでしょうか。  
柔軟な拡張性は、HULFTがコンテナ対応したことで得られるメリットの一つだと思います。皆さんもHULFT 10 for Container Servicesならではのスケーリングを生かした運用を計画してみてはいかがでしょうか。

このブログでは、今後も様々なTopics記事や接続検証等、皆さんの参考になるような記事を投稿していきたいと思います！  
ここまで読んでいただきありがとうございました。それでは、また！:raised_hand:
rex0220 テーブルルックアッププラグイン 最新データの取得

[rex0220 テーブルルックアッププラグイン](https://qiita.com/rex0220/items/6a01b68adea34ab6aa35)は、ルックアップ元のテーブルをコピーするプラグインです。
ルックアップの取得ボタンクリックで、最新のテーブルデータを取得する方法を検討します。

# 概要

[rex0220 テーブルルックアッププラグイン](https://qiita.com/rex0220/items/6a01b68adea34ab6aa35)は、ルックアップの制御用コピー項目の値が変化した場合に、テーブルの更新処理を行います。

そのためルックアップ元のレコードが変更された場合に、変更されるリビジョン項目を追加して、ルックアップの制御用コピー項目として利用します。
※リビジョン項目の設定は、計算式プラグインで行います。

テーブルルックアッププラグインで制御用コピー項目に revision を指定することにより、ルックアップ取得ボタンをクリック時に最新のテーブルデータを取得できます。


![2024-06-14_20h42_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a22a4a88-120d-6acf-4c7e-7ff4b5c29981.png)

# 操作例

![2024-06-14_20h41_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e162903f-6fbf-c84a-ff6b-e0f13cfc228f.gif)

# ルックアップで参照するアプリの構成

revision 項目を追加します。
値は、計算式プラグインで $id + revision を設定します。



# ルックアップで参照するアプリの計算式プラグイン設定

revision を設定します。

![2024-06-14_20h50_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f6d5d557-f384-92d9-a27c-df5016f94196.png)

```.js
// revision SINGLE_LINE_TEXT
IF($id,$id&"-"&($revision+1))
```

# ルックアップ設定の構成

org revision 項目を追加して、ルックアップのコピー項目にします。

![2024-06-14_19h03_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/af20e173-8e26-10a3-820f-a062d49b0459.png)

# テーブルルックアッププラグインの設定

制御用コピー項目に、「org revision」を指定します。

![2024-06-14_19h05_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/b7137783-7e0c-4014-4adc-8a1ccea7e528.png)
【論文読み】MAGNN: メタパスを用いて集約するグラフ深層学習

# はじめに

元論文: [MAGNN: Metapath Aggregated Graph Neural Network for Heterogeneous Graph Embedding](https://arxiv.org/abs/2002.01680
). Fu, Xinyu and Zhang, Jiani and Meng, Ziqiao and King, Irwin. (WWW'20)

# 概要
## GNNについて
グラフデータはノードとエッジで表現されるデータ構造です．これに対して深層学習などを用いてノードを分類したり，エッジの有無を予測したりするタスクを解くのがグラフ深層学習 (GNN) です．

ほとんどのGNNで想定されてきた普通のグラフデータは，ノードがユーザでエッジがフォロー関係など，ノードとエッジがそれぞれ一つの概念を表していることが多いです．
しかし実世界のグラフやネットワークはheterogenious，すなわち異なる概念のノードが混在することが多いです．
### この論文の目的
heterogeniousなグラフにおける，ノードの埋め込み

グラフの構造的・意味的情報を低次元のノード表現に埋め込む，要するに各ノードをベクトルで表現することが目的です．

# MAGNNの主なアイデア
- ノードコンテンツの変換
- メタパス内集約
- メタパス間集約

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/f43ad161-fd92-54fc-75da-853620740a3f.png)


# a. ノードコンテンツの変換
グラフのノードの持つ特徴量は異なる特徴空間にある可能性があります．
例: 人間の情報 (性別，年齢) と食べ物の情報 (カロリー，価格) など

ノードの特徴ベクトルを同じベクトル空間に射影するため，ノードが表す概念ごとに異なる線形モデルを用いて線形変換し，同じ次元数にします．

# b. メタパス内集約

## メタパス (Meta-path) とは？
Heterogeneousなグラフにおいて，ノードとエッジの順序を示すパス (経路) です．メタパスは，異なる種類のノードとエッジが接続されている順番を表します．

メタパスの長さを一定にして，あるノードを始点とするメタパスを何本か取得することで，そのノードの近傍情報を取得できます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/b00c095c-c163-cbf0-672c-06041b25c69c.png)

## メタパス内集約
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/29869391-6167-72d4-5474-31f73df57324.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609800/e9068dc4-4324-9e72-d9ce-33d0802bea92.png)

メタパス内集約で，各メタパスに含まれるノードの構造的・意味的情報を集約し，一つのメタパスの表現とします．

始点ノードとメタパス内ノードの関係をそれぞれ埋め込みます．
その後，メタパス全体を重みをつけて集約し，一本のメタパスを一つの中間表現にします．

# c. メタパス間集約
メタパス間集約で，すべてのメタパスの埋め込みを合体します．

各メタパスの重要度をAttentionを用いて学習し，メタパスに重みをつけて合体させることで最終的なノード表現を生成します．

# さいごに
実験ではノード分類，ノードクラスタリング，エッジ予測でいい結果を出していました．

あるノードを始点とするMeta-pathを数本取ってきて埋め込み，集約することで，始点ノードの良い埋め込みが得られるようです．
[Dify]アノテーション(注釈)を入れるのは、QABotにはかなり有効なのでは？


どうも山口です。
今回は、DifyのQABotにおけるアノテーション(注釈)機能について、その有効性と使い方について書いていきたいと思います。

## アノテーション(注釈)がなぜ有効なのか？

QABotの目的は、ユーザーからの質問に対して適切で正確な回答を提供することです。
しかし、質問の内容は多岐にわたり、全てに完璧に対応するのは難しいですよね。
そこで、アノテーション機能の出番です。
Difyではアノテーションを付けることで、特定の質問に対する「標準の回答」を設定したり、「この質問には回答できません」とマークしたりすることができます。

それを利用して、実際に今までにアノテーションしていたものに対してベクトル検索を行い、アノテーションしていたものがあればそれを使うことができるのです。
イメージは以下です。︎（DifyのDocsから引用）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/482b6476-1842-eda8-edb2-fc5d7e1050df.png)
(referenced by https://docs.dify.ai/features/annotation-reply)

これにより、QABotはより正確で的確な回答を提供できるようになるんじゃないかなと思っています。
今まで正しくない回答してしまうことがLLMですが、一定アノテーションから引っ張って来れるのはハルシネーション対策としても有効です。


## 使い方
では使い方を解説します。
1. まずはチャットボットを開いて何か質問してみてください。
この時、アノテーションの良さを知るためには質問はLLMが知りようがないものにしてください。
私は以下のように質問しました。
**質問：　やまぐちは最近LLMのどんなことを勉強していますか？**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/74e8e48c-05e2-fa03-97b9-d4943c330478.png)
もちろんLLMは知らないですね。


2. 以下の画像のように「注釈を追加」をクリックしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/69d63d16-0484-ae60-877e-a332f6e6bc5d.png)
そうすると注釈を追加できます。
注釈は以下のようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/6a4d0482-e323-3d8b-0aef-d18d3246734c.png)

3. 最後に最初の質問とそれに似た質問をしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/91f7d52a-3465-0355-01eb-f071fbd82382.png)
いい感じにアノテーションした内容を使ってくれています。


## 最後に
QAbotとして使うには必須の機能になってきそうです。

Xやってるので気になる方はフォローお願いします。
https://x.com/hudebakonosoto
HULFT10  for Container Services  可用性構成の考え方

## 1. はじめに
こんにちは、すぎもんです:smile:

いわゆる「コンテナ版HULFT」であるHULFT10 for Container Services(以下**CS版**)を少しずつ触っております。  
CS版では従来のクライアントOSインストール版HULFT(以下**OS版**)と異なり、AWSのインフラ構成（インスタンス数、ストレージ、DB、ネットワーク等）により耐障害性やVup等のメンテナンス時間の縮小などが期待できます。このコンテンツでは、HULFT10の可用性を高めるためのAWS構成を考えてみます。

---

## 2. CS版とOS版の可用性を担保するアーキテクチャの違い

### 2-1. OS版（HA型クラスタを採用）
OS版では、耐障害性を確保するためにHA（High Availability）型クラスタが採用されています。これにより、障害が発生しても自動的にフェイルオーバーが行われ、ダウンタイムを最小限に抑えることが可能です。

### 2-2. CS版（負荷分散型クラスタを採用）
CS版では、負荷分散型クラスタが採用されており、スケールアウトやリソースの最適化が容易に行えます。これにより、トラフィックが増加した場合でも柔軟に対応でき、システムの安定性が向上します。

::: note info
HAと負荷分散クラスタの違いの詳細については検索でよい情報が出てきたので詳細は割愛しますがイメージは以下です。
検索キーワード：HAと負荷分散クラスタの違い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458288/9c5509ff-0d55-3f8e-15d5-b8a44c5d722f.png)

:::

---


## 3. CS版の可用性について

### 3-1. 管理情報・履歴をDB化（負荷分散化に対応させるため）
CS版では、**管理情報や履歴がデータベース化されており、複数ノードからのマルチアクセスが可能** となっています。これは、OS版ではローカルストレージ（ブロックストレージ）のみ対応していたため、負荷分散に対応できなかった点を改善しています。

### 3-2. 集配信ファイルの外部ストレージ化（EFS、S3）
CS版では、**集配信ファイルを外部ストレージ（EFSやS3）に保存することで、スケーラビリティや耐障害性を向上** させています。これにより、OS版とは異なり、ローカルストレージに依存しない柔軟な運用が可能です。

### 3-3. スケーラビリティへの対応
CS版は**スケールアウトに対応しており、転送コンテナを追加することでシステムのパフォーマンスを向上** させることができます。 これは、負荷分散に対応したアーキテクチャの副次的な効果として得られます。

---


## 4. おわりに
いかがでしたでしょうか。  
可用性・拡張性の高さはHULFTがコンテナ対応したことで得られるメリットの一つだと思います。皆さんもHULFT 10 for Container Servicesならではの可用性・拡張性への対応を計画してみてはいかがでしょうか。

このブログでは、今後も様々なTopics記事や接続検証等、皆さんの参考になるような記事を投稿していきたいと思います！  
ここまで読んでいただきありがとうございました。それでは、また！:raised_hand:
HULFT10  for Container Services EC2とFargate 実行インスタンス選択の考え方について

## 1. はじめに
こんにちは、すぎもんです:smile:

いわゆる「コンテナ版HULFT」であるHULFT10 for Container Servicesを少しずつ触っております。
HULFT10 for Container ServicesでAWS上にコンテナを利用したソフトウェアの設定を行う際にはEC2版とFargate版のいずれかを選択することができます。この記事では、それぞれの特徴と、どちらを選択すべきかの指針となる情報を考察してみます。

* * *

## 2. EC2版とFargate版の特徴

**EC2版**

- EC2版は実行エンジンのスペック（CPU、メモリ、ネットワーク等）の最適化が可能です。具体的には、アプリケーションのニーズに応じて、インスタンスの種類やサイズを自由に選択できるため、リソースの効率的な利用が可能です。これにより、高パフォーマンスが求められるワークロードに対しても柔軟に対応できます。加えて、手動によるチューニングが可能なため、特定の要件に合わせた微調整が行いやすい点が魅力。

- ストレージはEFS、S3の両方を利用できます。EFS（Elastic File System）は、スケーラブルなファイルストレージサービスであり、EC2インスタンス間でファイルを共有するのに適しています。これにより、データの一貫性や可用性を高めることができます。一方、S3（Simple Storage Service）はオブジェクトストレージサービスで、大量のデータを安価に保存するのに適しています。これらを組み合わせることで、多様なストレージニーズに対応できます。

:::note info
**EC2版特徴のまとめ**
CPU、メモリ、ネットワーク等の最適化が可能。
手動によるチューニングが可能で特定の要件に合わせた微調整が行いやすい。
ストレージはEFS、S3の両方を利用できる。
:::

* * *

**Fargate版**

- Fargateはサーバレスで、OSセキュリティパッチなどのメンテナンスが不要（オートマチック）です。サーバーレスアーキテクチャのため、インフラ管理の手間が省け、アプリケーションの開発と運用に集中できます。また、AWSが自動でセキュリティパッチを適用してくれるため、セキュリティリスクの低減にも寄与します。
- FargateはAuto Scaling機能が使えます。これにより、負荷に応じて自動的にリソースを拡張・縮小できるため、スケーラビリティとコスト効率の両立が可能です。負荷が高まったときには迅速に対応し、不要なリソースを確保することなくコストを最小限に抑えることができます。
- FargateではS3のみを利用できます。

:::note info
**Fargate版特徴のまとめ**
OSセキュリティパッチなどのメンテナンスが不要。
Auto Scaling対応。負荷に応じて自動的にリソースを拡張・縮小できる
ストレージはS3を利用できる。
:::

* * *

表にしてみました。

| 特徴                   | EC2 | Fargate |
|------------------------|-------|-----------|
| 実行エンジンのスペック | マニュアル最適化が可能。 | サーバレスで、OSセキュリティパッチ等のメンテナンスが不要。 |
| ストレージオプション  | EFS、S3の両方を利用可能。| S3のみ利用可能。 |
| スケーリング          | 手動またはスクリプトによるスケーリング。 | Auto Scaling機能が利用可能。負荷に応じて自動的にリソースを拡張・縮小。 |

* * *

## 3. EC2版とFargate版の価格の違い

AWSコスト見積ツールを使用して、EC2版とFargate版のコストを比較することができますが、一般的に、Fargateの方が単価が高い傾向にはあります。Fargateはメンテナンスフリーの付加価値・セキュリティリスクの低減を提供するため、価格差がどれだけのメリットをもたらすかを評価することになるかと想定します。

:::note info
**AWSでEC2と同程度の性能をFargateで出したい場合のコスト例**
例えば、t3.mediumインスタンスと同等のFargate設定を考えた場合、Fargateの使用料はEC2インスタンスの使用料よりも約20～30%程度高くなることがありました。
:::

* * *

##  4. EC2版とFargate版の長所

EC2版とFargate版の特徴と違いを選択の基準ごとに整理すると、以下のようになります。

**EC2を選択するケース**：
- システムを最適化したい（マニュアルチューニングが可能な状態）
- 高パフォーマンスが求められるワークロードに対応
- EFSとS3の両方を利用したい

**Fargateを選択するケース**：
- システム管理をAWSに任せたい（簡単・お任せモード）
- メンテナンスの手間を省きたい（運用負荷減）
- 自動スケーリングが必要

| 選択の基準 | EC2版を選択するケース | Fargate版を選択するケース |
|-------------|-----------------------|---------------------------|
| システムの最適化 | システムを最適化したい（マニュアルチューニングが可能な状態） | システム管理をAWSに任せたい |
| 性能重視 | 高パフォーマンスが求められるワークロードに対応 |  |
| 運用負荷軽減重視 |  | メンテナンスの手間を省きたい（運用負荷減） |
| 通信量の変化に対応 |  | 自動スケーリング対応 |
| ストレージ | EFSを利用したい |  |

システムのニーズや運用ポリシーに応じて選択するとよさそうです。EC2は柔軟性とカスタマイズ性を重視する場合に、Fargateは簡便さと運用効率を重視する場合に適しています。

昨今の傾向からすると価格が下がったことで運用費用対効果の出たFargeteが選定されることは多いようです。

* * *

## 最後に
いかがでしたでしょうか。
実行インスタンス選択も、HULFTがコンテナ対応したことで得られるメリットの一つだと思います。
皆さんもHULFT 10 for Container Servicesならではの運用負荷軽減やスケーリングを計画してみてはいかがでしょうか。

このブログでは、今後も様々なTopics記事や接続検証等、皆さんの参考になるような記事を投稿していきたいと思います！
ここまで読んでいただきありがとうございました。それでは、また！:raised_hand:
Groupのような複数のView要素を内包するカスタムViewを作る

## 概要

Groupのような複数のView要素を内包するカスタムViewのコード例です。

### コード例

```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        CustomGroup {
            Text("Hello")
            Text("World")
        }
    }
}

struct CustomGroup<Content: View>: View {
    let content: Content
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        content
    }
}

#Preview {
    ContentView()
}
```
内部クラス？ friend? っていう気の迷いメモ

## おことわり

頭悪い初心者のメモです．

## 謎の話

`class Y` と `class Z` は `class X` が使う何らかの実装として作られた．

```C++
//[X.h]
class Y;
class Z;

class X
{
    ...
private:
    Y *m_pY;
    Z *m_pZ;
};
```

この `Y` や `Z` の具体的な定義というのはどこに書くのか？
こいつらのコードが小規模ならば

```C++
//[X.cpp]
#include "X.h"

//じゃあここに書くし
class Y { ... };  //Yの定義
class Z { ... };  //Zの定義

//...以降，Xの実装
```

とかすれば，とりあえず他所からこの `Y` や `Z` を使うことはできない（…と思う）．
しかし，コード量的に割と邪魔な場合，`Y.h` と `Y.cpp` とかに分けたくなる．

```C++
//[X.cpp]
#include "X.h"

#include "Y.h"  //別のところに実装しました
#include "Z.h"

//...以降，Xの実装
```

でもそうすると，

```C++
//[どこか別のコード]
#include "Y.h"  //←ヒャッハー！ Yを使っちゃうぜ！
...
```
とかやれちゃう．何か嫌だ．

そしたら，「他所で使う想定じゃねーから」という物は「これらは `X` の実装の一部分なので」という話にしておくべきなのか？

```C++
class X
{
private:
    class Y;
    class Z;
};
```

これなら他所で `#include "Y.h"` とかしてみたところで `Y` を使おうとすればコンパイラ様がブチギレて阻止してくれる．
しかしこういうスタイル↓というのも考えられるのではあるまいか？

```C++
//「YやZを内部クラスとして定義する」だけのやつを別途用意して，
//Xはそいつの友達だということにする．
class Impls
{
    friend class X;
private:
    Impls() = delete;   //このImplsクラス自体はただの入れ物．インスタンスを作れない．
private:
    //これらはXからは使える
    class Y;
    class Z;
};
```

`Y` や `Z` を使えるやつを `friend` で登録する的な．

一番最初の状態では，`Y` と `Z` は `X` の内部クラスというわけじゃなかったのだから，こっちの方が元々のあるべき姿(?)に近い…のだろうか？

## 追記

しかし，本当にそこまでして頑なに「使わせない使えない」を達成する必要があるのかい？
例えば，`Y` や `Z` をいかにも「内部実装ですが何か？」みたいな名称の名前空間にでも突っ込んで，「他所で使う想定じゃねーから」っていう雰囲気だけ示しておけばそれで良くね？

……と，イマジナリーフレンドが脳内に直接意見してくるのであった．
エンジニアがWindowsからmacOSに移行して良かったこと / 悪かったこと

# 0 はじめに
タイトルにデカデカとエンジニアとか書きましたが，僕は情報科4年の大学生です．エンジニア名乗れるほどではありません．見栄を張りましたすみません．

これまでの学生生活ではWebやマイコン，AI，アプリ開発などいろいろやってきました．

1ヶ月ほど前にM3MacBookAirを購入し，以降メイン端末として運用しています．
MacBook移行前はDellのXPSを使ってました．これもめちゃくちゃ良いPCです．
Windowsがメインのときの開発環境はWSL2上のDocker内で作業してました．(VM on VMはどうなん？)
そんな僕がmacOSに移行して良かったことや悪かったこと，変わらずできることを逐次追記していきます．
macOS移行に悩んでる人やmacOS,Windowsアンチの皆様，参考にしてください．

なお，ゴリゴリの主観を含みます．「それWindowsでもできるやろ！」って指摘あったらぜひお願いします．みんなで両方のOSの使い勝手を良くしていきましょう！
**※この記事はmacOS贔屓です**
# 1. 良かったこと
## 1.0 英字配列が選べる
OSの話ではないですけど，どのモデルでも英字配列が選べるのは最高！
Windowsで英字配列選べるのはハイエンドしか無い(Macもハイエンドでは？という指摘は無しで)．
## 1.1 電池持ちが良い
裏でコンテナを起動させ続けても全然バッテリが減らない！
ちなみにコンテナは[Orbstack](https://qiita.com/tags/orbstack)を使って管理してます．
## 1.2 カーソル移動のショートカットが標準装備
WindowsではAutoHotKeyなどでホームポジションから移動せずにカーソル移動できるように設定していましたが，macOSは標準でできます！
## 1.3 PDFビュアーが優秀すぎる
プリインストールされたプレビューソフトはPDFの編集ができる!
- テキストの追加(テキストボックス)
- ペンによる書き込み
- ページの追加/削除
- **OCR**

そもそもWindowsにはプリインストールされたPDFビュアーがない．(良いのか悪いのか)
ビューアが標準かつ上記の機能が無料で使える．Acrobatいらない！
また，iPhoneでもできますがスキャンした紙の資料の記入欄を自動的に検出して入力フォームを作ってくれます．
「紙で配るけどオンラインで提出な！」みたいな時に便利です．
## 1.4 ディレクトリ構成が良い
UNIX系なのでWindowsのような変なディレクトリ構成じゃない．
## 1.5 インストーラを消すか聞いてくれる
僕はインストーラを消す派なので助かります．こういうちょっとした親切すごい嬉しい．
## 1.6 3本指でドラッグができる
文字列の選択やファイルの移動などができます．
クリックしながら動かさなくて良いのでめっちゃ楽です．
# 2. 悪かったこと
買う前から知ってたことも含めて
## 2.1 ウィンドウの自動分割がない
[macOS Sequoia](https://www.apple.com/jp/newsroom/2024/06/macos-sequoia-takes-productivity-and-intelligence-on-mac-to-new-heights/#:~:text=%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%E3%82%A6%E3%82%A4%E3%83%B3%E3%83%89%E3%82%A6%E3%81%AE%E3%82%BF%E3%82%A4%E3%83%AB%E8%A1%A8%E7%A4%BA%E3%81%8C%E3%81%93%E3%82%8C%E3%81%BE%E3%81%A7%E4%BB%A5%E4%B8%8A%E3%81%AB%E7%B0%A1%E5%8D%98%E3%81%A7%E3%81%99%E3%81%B0%E3%82%84%E3%81%8F,-%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AF%E3%80%81%E8%87%AA%E5%88%86)で追加
一応フリソを使っても実現はできます．
## 2.2 全画面表示にすると仮想デスクトップ扱いになる
これは好き嫌いわかれるところではあると思います．
僕は好きです．
## 2.3 Ctrl + Yができない
これ，めっちゃうざいです．
同じ機能はCmd + Shift + zです．
Windowsでも使っていたソフトをmacOSでも使用すると，バインドが被ることがあります．
# 3. 変わらずできること
## 3.1 AI動かせる
PyTorchやTensorFlowはちゃんとApple Siliconに対応済み．
PyTorchでは，
```python
tensor = torch.rand(2,2,).to('mps')
```
みたいに`.to('mps')`ってやればApple SiliconのGPUに載せられます．
## 3.2 caps lockを別キーに割り当て
いらんよね．
設定からできる．Karabiner-elementsを入れても良い．
## 3.3 クリップボード
**標準ではできません**
僕は[Paste](https://pasteapp.io/)を使ってます．
## 3.4 勝手に予測変換されなくする
macOSは勝手に変換してきます．(ライブ変換って名前)
これも好き嫌い分かれますが僕は嫌いです．
設定からオフにできます．
## 3.5 スクリーンショット
画面一部のクリップ，特定のウィンドウのみなどWindowsと同様にできます．
# 4. おわりに
Macbookに変えていつmacOS嫌いになるかな〜と思ってたけど，今んとこ大好きです．
## 4.1 MacBookの購入を検討してる人へ
MacBookを買う前に「MacはユニファイドメモリやからWindowsよりメモリが少なくても大丈夫！」みたいな言説を複数見たので，それを信じてRAM16GBで購入しましたが，結論から言うとこれは失敗でした．
メモリが足りなくなったことはまだありませんが，(ブラウザのタブを複数開く癖もあり)常時13GBくらい消費しています．
いつ足りなくなるかほんのり心配なので，お金に余裕があるならデカいのを買いましょう(当たり前)．
gemが上手く動作せず、gemの内部処理でデバッグしたい/モンキーパッチを作りたいときのやり方

gemの怪しいと思った部分をoverwriteして、binding.pryを追加すれば、追加した場所で止まってくれます。

overwriteのやり方
https://qiita.com/arakaji/items/dbf26f0b1d1c4659ef32#%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%BF%E3%81%86
Anacondaライセンスを回避するcondaコンテナの作り方

# 概要
Anacondaライセンス問題を回避する環境をコンテナで構築する方法の備忘録です。

# Anacondaの商用利用は有料です。
Pythonの環境構築をする時に必ず取り上げられるAnaconda。しかし、従業員数200名を超える組織にはライセンス料が発生します。Miniconda + conda-forge(リポジトリ)で利用すればこの問題を回避出来ます。ところが、どうやら公開されているMinicondaのコンテナイメージはデフォルトではconda-forgeを利用する様になっていないようです。よって、本記事ではこの問題を回避するコンテナの構築方法をまとめたいと思います。

* 参考

https://zenn.dev/yusuke_m/articles/6edeccc8e31caf

https://legal.anaconda.com/policies/en/?name=terms-of-service#terms-of-service

https://www.anaconda.com/pricing

https://github.com/conda-forge/conda-forge.github.io/blob/main/LICENSE

# Dockerfileの作成
Ubuntu 22.04のコンテナイメージをベースに作成します。

```dockerfile
FROM ubuntu:22.04

ARG arch="x86_64"

RUN apt-get update && apt-get upgrade -y

RUN apt-get install -y wget vim

RUN wget "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-${arch}.sh" && \
    bash Miniforge3-Linux-${arch}.sh -b
```

* 参考

https://github.com/conda-forge/miniforge#non-interactive-install

# コンテナイメージをビルドし、コンテナを起動
作成したDockerfileをビルドし、ビルドしたコンテナイメージからコンテナを起動し、コンテナにログインします。(詳細は割愛)ログイン後に、`/root`配下を見てみると、`miniforge3`というディレクトリが作成されています。この配下に格納されている`conda`の実行ファイルを実行してみましょう。以下のコマンドを試してみます。

```bash
 /root/miniforge3/bin/conda --version
conda 24.5.0
```

環境変数`PATH`に`miniforge3`ディレクトリのパスを追加すれば、`conda`コマンドだけで利用できる様になります。

# まとめ
Anacondaライセンスを回避することが出来るMiniconda + conda-forgeを利用するコンテナを作成する方法をまとめました。
Test Suiteってなに？

# 記事を書くきっかけ
Goで自動テストを作成する際に`stretchr/testify`を使用しているのですが、`suite`をよく使います。最初はライブラリ特有のものと思い`suite`について調べていたのですが、`Test suite`という言葉があったことに驚きこの記事を書こうと思いました。

# Test Suiteとは
一言でいうと、同じ種類のテストケースの集合体です。（bunch of test cases grouped for a specific purpose）
suiteの意味：組、揃(そろ)い、続きの間、スウィートルーム、

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

わかりやすくするために、user gatewayのunittestを例に説明します。
user gatewayのテストスイートがあり、その中にはCRUD操作に対応するテストケースが含まれています。具体的には、新規ユーザー作成(Create)、ユーザー情報の取得(Read)、ユーザー情報の更新(Update)、およびユーザー削除(Delete)に関するテストケースがそれぞれあります。これらのテストケースを一つのスイートにまとめることで、関連するテストを一括で管理・実行することができます。

# Test Suiteのメリット
Test Suiteを使用することで、テストの管理が容易になります。例えば、ある機能に対して多くのテストケースが存在する場合、それらを1つのTest Suiteにまとめることで、テストの実行順序や依存関係を管理しやすくなります。また、特定のTest Suiteだけを選択して実行することも可能で、効率的なテストが可能となります。

# test suiteを使用したサンプルコード
下記コードだと、`ExampleTestSuite`がテストケースをまとめるtest suiteであり、その中にある同じ目的を持ったテストケースが`TestExampleTestSuite`になります。
なので、もし`TestExampleFailureTestSuite`のようなテストケースがあると同じtest suite内に属することになりいます。
```golang
// Basic imports
import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/suite"
)

// Define the suite, and absorb the built-in basic suite
// functionality from testify - including a T() method which
// returns the current testing context
type ExampleTestSuite struct {
    suite.Suite
    VariableThatShouldStartAtFive int
}

// Make sure that VariableThatShouldStartAtFive is set to five
// before each test
func (suite *ExampleTestSuite) SetupTest() {
    suite.VariableThatShouldStartAtFive = 5
}

// All methods that begin with "Test" are run as tests within a
// suite.
func (suite *ExampleTestSuite) TestExample() {
    assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
}

// In order for 'go test' to run this suite, we need to create
// a normal test function and pass our suite to suite.Run
func TestExampleTestSuite(t *testing.T) {
    suite.Run(t, new(ExampleTestSuite))
}
```

# 参考
https://testsigma.com/blog/test-suite-vs-test-case/

https://github.com/stretchr/testify
VSCodeのRemote SSHでサーバーに接続できなかった話

## 概要
MacからVSCodeのRemote SSHでAWS EC2に接続し用とした際に接続できなかった。

Configファイルは以下のようにしていました。
```config
Host docker-demo
  HostName xxxxxxxxxxxxx (public ip addressコピペしています)
  User ubuntu
  IdentityFile ~/.ssh/xxx.pem
```

ログを見ていると以下のようなものが目に入りました。
```text:log
Load key "~.ssh/xxx.pem": bad permissions 
```
なるほど？permissions？何を付ければいいの？ということで調査開始。

## 原因 / 解決策
私の場合はpemファイルのパーミッションに問題があったようです。

公開鍵認証方式でのパーミッション指定は以下である必要があるそうです。
* ホームディレクトリのパーミッションは 755 以下であること
* .ssh ディレクトリのパーミッションは 700
* .ssh/authorized_keys のパーミッションは 600

https://lab.unicast.ne.jp/2011/12/25/%E5%85%AC%E9%96%8B%E9%8D%B5%E8%AA%8D%E8%A8%BC%E3%81%8C%E9%80%9A%E3%82%89%E3%81%AA%E3%81%84%E4%BB%B6%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/

pemファイル (xxx.pem) のパーミッションを600にしたら接続できました。
```terminal
chmod 600 xxx.pem
```

めでたしめでたし。
SSL/TLSとは？


## SSL/TLSとは
SSL (Secure Sockets Layer) / TLS (Transport Layer Security)

インターネット上でウェブブラウザとウェブサーバー間のデータの通信を暗号化し、安全に通信させるための暗号化プロトコル。主に個人情報やクレジットカード情報などの重要なデータを暗号化して通信を行う

SSL暗号化通信が行われているとアドレスバーに鍵マークがついたりURLの先頭がhttpsに変わる

## 2つの違いは？

TLSはSSLの新しいバージョンで、SSLにあった脆弱性が改善されており、現在もSSLと呼ばれているのはすでに浸透してしまっているため。TLSと呼ばれることもあるが、SSL/TLSと総称されることが多い

1999年にSSL 3.0の教訓を踏まえたTLS 1.0が誕生し、現在はTLS 1.3が最新となっている

## SSL化するには？

SSL証明書をウェブサーバーにインストールする必要があり、証明書にはサーバーにデータを暗号化および復号させる公開鍵と秘密鍵が含まれている

### SSL証明書
SSL証明書は認証局で発行する必要があり、ドメインの使用権の確認と運営者が存在しているかなどを審査される

#### SSL証明書の種類
| ドメイン認証 (DV認証) | 企業実在認証 (OV認証) | EV認証 (拡張検証) |
|--|--|--|
| ドメインの使用権のみを確認 | ドメインの使用権と運営者の法的実在確認 | ドメインの使用権、運営者の法的及び物理的実在確認 |
| 簡単に取得でき、個人利用にも適している | 一般的な企業や組織に必要な基本的な信頼性を提供 | 高い信頼性を提供し、フィッシング詐欺対策にも効果的 |
| 信頼性は最低限 | 安全性を示すための最低限のレベル | 最高レベルの安全性と信頼性を示す |
| コストは最も低い | 中程度のコスト | 高コスト |
| URLバーに鍵アイコンが表示 | URLバーに鍵アイコンが表示 | URLバーに鍵アイコンとサイト運営者の名前が緑色で表示 |

## 通信の流れ(TLS 1.3)

### 1. クライアントがサーバにSSL/TLS通信をリクエスト
- 以下が含まれている
    - クライアントが対応する暗号方式（Cipher Suites）
    - サポートするTLSバージョン
    - クライアントランダム値（ランダムなデータ）
### 2. サーバがクライアントのリクエストメッセージに応答し、サーバランダム値と選択した暗号方式を返答
- 以下が含まれている
     - サーバ証明書
         - サーバの証明書を送信し、サーバの公開鍵を提供
     - サーバ鍵交換メッセージ（KeyShare）
         - 暗号化アルゴリズムに必要な公開鍵情報
     - サーバ完成メッセージ（Server Finished）
### 3. クライアント証明書の検証:
- サーバから受け取った証明書を検証する
    - クライアントのブラウザにあらかじめインストールされている信頼のある認証局（CA）のルート証明書を使用して、サーバ証明書が本物かどうかを確認
### 4. 共有鍵（共通鍵）の計算
- クライアントとサーバが、互いに交換した鍵交換メッセージ（KeyShare）を基に共有鍵を計算する
    - この共有鍵はセッション鍵として通信の暗号化に使われる

### 5. クライアントFinishedメッセージ:
- クライアントは、自分のハンドシェイクが完了したことを示すFinishedメッセージをサーバに送信する
    - 計算された共有鍵で暗号化され、ハンドシェイクの一部として送信される

### 6. 共有鍵による暗号化通信開始:
- ハンドシェイクが完了すると、クライアントとサーバは共有鍵を使用して通信内容を暗号化する
    - 安全で信頼性の高い通信が確立され、機密情報のやり取りが安全に行われる

### 図解

```
クライアント                                  サーバ
    |        -- クライアントHello -->          |
    |        <-- サーバHello + 鍵交換情報 --   |
    |                           <-- サーバ証明書 -- |
    |                           <-- サーバFinished |
    | ------クライアントFinished メッセージ-->  |
    |                                             |
（ハンドシェイク完了、暗号化通信開始）
```

## 常時SSL化

以前は暗号化するためにリソースが多く必要だったためログインページや支払いページなど一部のページに限定してSSL化することが多かった。現在は技術が進歩しセキュリティの重要性が向上することにより、常時SSL化が推奨されるようになっている
深度推定モデル Depth Anything v2を試してみる

# Depth Anything v2とは

**Depth Anything v2**とは、2024年6月14日に発表された深度推定モデルです。

深度推定モデルとは、ざっくり言うと**奥行きを推定するモデル**です。

プロジェクトページはこちらです。

https://depth-anything-v2.github.io/

Depth Anything v2はその名前から分かる通り、Depth Anything (v1) というモデルの進化版です。

Depth Anything v1との大きな違いは、以下3点です。証拠画像も併せて載せます。画像はいずれもプロジェクトページからの抜粋です。

1. よりきめ細やかで詳細な推定が可能

    ![SS 251.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734810/18979afb-e63c-95e4-0831-5472272a6be3.jpeg)

2. ロバスト性が向上

    ![SS 252.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734810/fda1cf7d-eb10-c07a-f677-8f4388eabea0.jpeg)

3. モデルが軽量になって推論速度が向上

    ![SS 253.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734810/1e8cec0f-8f5a-f002-6667-649001b6b5eb.jpeg)

モデルのアーキテクチャや学習方法については論文を参照してください。

# モデルを動かす

私はGoogle ColabのCPU環境で動作確認しました。
そんなに大きなモデルではないので、GPUではなくCPUで動かしました。
まずは、諸々のインストールです。

```
!git clone https://github.com/DepthAnything/Depth-Anything-V2
%cd Depth-Anything-V2
!pip install -r requirements.txt
```

次に、モデルのダウンロードです。
モデルサイズは4種類ありますが、そのうち3種類が公開されています。
好きなものを選んで重みファイルをダウンロードしましょう。

- Smallモデル（公開中）
- Baseモデル（公開中）
- Largeモデル（公開中）
- Giantモデル（近日公開予定らしい（2024/6/14時点））

```
# Smallモデルの場合
!wget https://huggingface.co/depth-anything/Depth-Anything-V2-Small/resolve/main/depth_anything_v2_vits.pth

# Baseモデルの場合
!wget https://huggingface.co/depth-anything/Depth-Anything-V2-Base/resolve/main/depth_anything_v2_vitb.pth

# Largeモデルの場合
!wget https://huggingface.co/depth-anything/Depth-Anything-V2-Large/resolve/main/depth_anything_v2_vitl.pth
```

最後に、推論です。

下のコードを実行するときに、`encoder`という変数にモデルの種類を指定してください。具体的には、

- Smallモデルなら`"vits"`
- Baseモデルなら`"vitb"`
- Largeモデルなら`"vitl"`
- Giantモデルなら`"vitg"`

を指定します。

私はSmallモデルで推論してみました。

```python
import cv2
import torch

from depth_anything_v2.dpt import DepthAnythingV2

encoder = "vits" # ここにモデルの種類を指定

model_configs = {
    'vits': {'encoder': 'vits', 'features': 64, 'out_channels': [48, 96, 192, 384]},
    'vitb': {'encoder': 'vitb', 'features': 128, 'out_channels': [96, 192, 384, 768]},
    'vitl': {'encoder': 'vitl', 'features': 256, 'out_channels': [256, 512, 1024, 1024]},
    'vitg': {'encoder': 'vitg', 'features': 384, 'out_channels': [1536, 1536, 1536, 1536]}
}

model = DepthAnythingV2(**{**model_configs[encoder]})
model.load_state_dict(torch.load(f"depth_anything_v2_{encoder}.pth", map_location="cpu"))
model.eval()

raw_img = cv2.imread("画像のファイルパス")
depth = model.infer_image(raw_img)
```

深度推定の結果は`depth`にあります。
`depth`は1チャンネルの画像ですので、これを画像ファイルとして保存するなり表示するなりして結果を確認してください。

私は、以下の画像で試してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734810/0e7e75a2-2dcc-726b-98fa-02fe9bce3a3b.png)

結果はこんな感じ↓です。いい感じですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734810/6e35cc76-10a6-96d2-f296-ecf29d290b4d.png)

# 最後に

深度推定モデルについては詳しくないですが、Xで見つけたのでなんとなくDepth Anything v2を動かしてみました。

ただ、正直に言うと、個人的には深度推定モデルを使うシーンはあまりないかなと思っています笑。
学生の俺でもwebサイト作って稼ぎたい

# 学生でもwebサイト作って金稼ぎたい。(現在進行系)
こんにちは、Webサイト作ってお小遣い稼ぎしたいrkです。
プログラマーとして最近の日々を過ごしてきて、そろそろ自分でもなにか作ってお金稼ぎできたらな～ってことでwebサイト作ります。
なんの計画もなくダラダラ作ってると一生終わらないので
計画表+みんなの参考になれば、ってことで書いていこうかな。

## 以前までの取り組み
これまでは、生放送を自動で切り抜いて字幕をつける的なことをやってました(結構いい感じ)。プラスαでSNS運用的な事もやってたけどこっちはダメダメ。
最近は、超がつくほど暇な割に、動画の選定をして、動画を投稿してというのすらもかなり面倒くさくなったので、「一発でURLを入れたら動画の投稿までやってくれたら、なあ」って感じです。
今までの取り組みは以下のリンクからご覧ください：
[切り抜きAI](https://qiita.com/rikuya11212001/items/cb9c7878c2feb962503c)
[SNSアカウント運用](https://qiita.com/rikuya11212001/items/f93080ce63c77642bc2e)

### とりあえずの目標
ここらへんは完全に自分用の計画書なので読み飛ばしちゃってください。

WebページはReact × FastAPIで開発。バックエンドが重たくなるため、GCPクラウドの利用を検討中。既にURLから動画の切り抜きまでのコードは完了しており、面白い部分を切り抜くための閾値設定、切り抜いた動画をTikTokに上げる設定を自動化したいと考えています。

### 作成方法
1. GCP関係
2. front
3. backend
4. deploy

### GCP関係（過程１）
#### 参考になりそうな記事
[GCPでfront+backend](https://qiita.com/derui/items/83d853eff768c1eedff2)
[GCE + VScode開発](https://qiita.com/FukuharaYohei/items/fa2d75ad8406e497906f)
[GCEで爆速AI環境構築](https://www.tc3.co.jp/how-to-build-ai-environment-on-gcp/)
#### 進め方
Cloudの説明書見たけどちょい面倒そうなので、sshでtunnelingしてVScodeからfrontとbackend作業したらめっちゃ楽だし使いやすくね、、、？
ってことでやっていきます。
#### 1. GCPインスタンスの作成
1. GCPコンソールにログインし、Compute Engine > VMインスタンスに移動。
2. 新しいインスタンスを作成し、必要な設定を行います（GPUインスタンスを使用する場合は、適切なタイプを選択）。
ここでGPUプランを選択しようとしたら、無料プランでは使えないっぽい、、、
**注意: インスタンスを作成する際におすすめで出てくるE2はまじで使い物にならないので別のにすること。**![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624995/d3d76bf1-a292-6643-72f2-96d005d8dff6.png)

#### 2. SSH鍵の設定
1. ローカルマシンでSSH鍵を生成します（まだない場合）。
    ```bash
    ssh-keygen -t rsa -f ~/.ssh/gcp_key -C "your_email@example.com"
    ```
2. 公開鍵 (`gcp_key.pub`) をGCPインスタンスに追加します。

#### 3. VS Codeの設定
1. VS CodeにRemote - SSH拡張機能をインストールします。
2. VS Codeでコマンドパレットを開き（Ctrl+Shift+P）、`Remote-SSH: Connect to Host` を選択します。
3. SSH設定ファイルに以下のように記載します：
    ```plaintext
    Host my-gcp-instance
        HostName YOUR_INSTANCE_IP
        User YOUR_USERNAME
        IdentityFile ~/.ssh/gcp_key
    ```
4. 設定後、`my-gcp-instance`を選択して接続します。
画面の左下にSSH：my-gcp-instanceと出たら成功！

### front（過程２）
#### 進め方
React×Typescript使ってどんどん進めていこかー、ってことで。
設計的には
MainPageの一枚にとりあえずの機能として、「urlいれる欄、完成動画のダウンロード、tiktockにあげる機能、最終的に切り抜く動画時間の設定」をつける、でいい感じかな？

#### reactのsetup
[react環境構築](https://qiita.com/rspmharada7645/items/25c496aee87973bcc7a5)で大体は学べるかと
#### とりあえずのページ
適当にfront作って、npm startして、localhost上でこんな感じかな？ってのはできた。![uploading...0]()
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624995/233dd727-ce91-b890-7c95-da3ace6f7564.png)
ちゃんとGCE動いてるのに感動。

要望あれば簡単なfrontのいじり方も解説します。

#### FastAPI側
参考に:[pythonでweb apiを作ろう](https://dev.classmethod.jp/articles/try_fastapi_intro/)
localhostのurlの後ろに/docsをつけると実際のテストができるので便利
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624995/f782c6be-f914-ef84-3c93-4fa1cc352518.png)
ISO 14000　環境マネジメントシステム(SCP財団パロ)

:::note info
資格の勉強のために、数字のついたややこしい概念を復習している。
ある程度ストーリーがないと俺は数字が全然頭に入ってこないのでSCP風にしてみた。
:::


**アイテム番号:** ISO 14000
**オブジェクトクラス:** Safe

**特別収容プロトコル:** ISO 14000シリーズに定められる定義により、環境に配慮した活動を行ってください。基本的な概念や用語に関しては、ISO 14000を参照してください。
組織（企業、各種団体など）の活動・製品およびサービスによって生じる環境への影響は、持続的に改善される必要があります。

ISO 14001の第三者認証制度を利用することで、ISOに適合していることを証明する認定を受けることができます。

# 説明

ISO14000シリーズは、国際標準化機構（ISO）が定めた品質マネジメントシステムに関する一連の規格です。
必要に応じて、[ISO 9000](https://qiita.com/NUNOGAWA/items/3d6d462ca4890081c494)についても参照してください。

## ISO14000（JISQ 14000）
**目的:** 環境マネジメントシステムに関する基本概念と用語の定義を提供。大気汚染やCO2排出などの環境問題に対応して、企業が自主的に行動できるように促す。
**内容:** 環境マネジメントシステムに関する基本概念と用語の定義

## ISO 14001（JISQ 14001）
**目的:** 環境マネジメントシステムの具体的な要求事項を規定
**内容:** 組織が環境マネジメントシステムを確立し、運用するための基準。これにより、組織は認証を取得できる

# その他
細かく、ISO14004（管理策）、ISO14015（土壌汚染）、ISO14020（環境ラベル）、ISO14031（環境パフォーマンス）、ISO14040（ライフサイクルアセスメント）……。

１が認定、4が指針（管理策）であるところなどはISO 9000に似ている。

エージェント・布川：「こちらは、環境に関する規格である」ということさえ把握しておけばよさそうだ。

# 補遺
たとえば情報セキュリティマネジメント平成28年秋期 午前問30で、「情報技術セキュリティ評価のための国際標準であり，コモンクライテリア（CC）と呼ばれるものはどれか」というような問題の誤答の選択肢に出現したことがある。

[情報セキュリティマネジメント試験ドットコム](https://www.sg-siken.com/kakomon/28_aki/q30.html)

選択肢は、
- ISO 9001
- ISO 14004
- ISO/IEC 15408
- ISO/IEC 27005

だった。

試験勉強としては、概要だけ把握しておけば問題ないような気もする。また、ISO 9000（品質マネジメントシステム）の環境版として出てるので、9000より値が大きい。この流れも把握しておけば、思い出すときの補強になりそうだ。

1992年の地球サミットをきっかけとして規格の策定が始まったそうである。

# 参考
[情報セキュリティマネジメント試験ドットコム](https://www.sg-siken.com/kakomon/28_aki/q30.html)

[JSAグループ　ISO14000ファミリー規格開発情報](https://webdesk.jsa.or.jp/common/W10K0500/index/dev/iso_iso1400/)
Flutterで構築したWebアプリを、とりあえずFirebaseに乗っける

掲題の通り。
> 冗長な手順もあるかと思いますので適宜読み替えてください。

### 1. Flutterの初期化

- GitHub上でリポジトリを作成
  - 💡 Flutterがsnake_caseなので、リポジトリ名もsnake_caseにしておくとわかりやすい
- 作成したリポジトリをClone
- Cloneしたディレクトリの一つ上のフォルダに移動
  - Git BashやVSCodeのターミナルを使うと良い
- Flutterを最新化
  - `flutter upgrade`
- Flutterプロジェクトを作成する
  - `flutter create your_app_name`
- your_app_nameフォルダに移動し、実行する
  - `cd your_app_name`
  - `flutter run -d chrome`
- デフォルトのカウンタアプリが正常に起動できたら、ブラウザを閉じる
- pubspec.yamlを更新して、パッケージを取得する
  - `flutter pub get`

### 2. Firebaseプロジェクトの作成
> Firebaseコンソールで操作する。
> https://console.firebase.google.com/u/3/?hl=ja
- Firebaseのプロジェクトを新規作成する
- Firebase Authentificationの「プロバイダ」でメール/パスワードを追加する
- 「Firebase Datastore」を有効化する（データベースの作成）
- 「Hosting」を有効化する

### 3. Firebaseプロジェクトの初期化
- firebaseをインストールする
  - `npm install firebase`
- firebaseのツールをインストールする
  - `npm install firebase-tools`（`-g`は外しておく）
- firebaseのツールにログインする
  - `firebase login`
    - うまくいかない時は下記で再実行
      - `--interactive`を足す `firebase login --interactive`
      - ネットワークの接続状況を確認しつつ、`--reauth`を足す `firebase login --interactive --reauth`
- firebaseプロジェクトとして初期化する
  - `firebase init`
    - `Use an existing project`を選択し、作成したFirebaseプロジェクトを指定
    - `What do you want to use as your public directory?` ⇒ `build/web`
    - `Set up automatic builds and deploys with GitHub?` ⇒  `Y`

### 4. 自動デプロイの設定
- `firebase-hosting-pull-request.yml`および`firebase-hosting-merge.yml`を下記のように修正する

#### 修正前
```
      - run: npm ci && npm run build
```

#### 修正後
```
      - uses: subosito/flutter-action@v2
        with:
          channel: 'stable'
      - run: flutter pub get
      - run: flutter build web --release
```

### 5. FlutterとFirebaseの連携部分を調整する
> 参考：https://firebase.google.com/docs/flutter/setup?hl=ja&platform=web

- コマンドライン ツールをインストールする
  - `dart pub global activate flutterfire_cli`
- `firebase.json`を`firebase_bk.json`にリネームして、退避しておく
- `firebase.json`を作成する
  - `flutterfire configure`
    - `firebase_oprions.dart`を生成するため、`no`を入力する
    - 💡 更新されたfirebase.jsonに`build/web`の記載が残っている場合は、取っておいた`firebase_bk.json`を削除する。残っていない場合は両者の記載をくっつける
- 関連パッケージをインストールする
  - `flutter pub add cloud_firestore firebase_auth`
- `lib/main.dart`の`void main()`を下記のように調整する（importも併せて追加する）

``` dart
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'firebase_options.dart';

void main() async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}
```

### 最初のデプロイ

- アプリをビルドする
  - `flutter build web --release`
- 最初のデプロイをする
  - `firebase deploy`

> `firebase.json`のpublicに記述しているテキストが想定通り`build/web`になっていることを確認する（綴りミスに注意）
カラーユニバーサルデザイン推奨配色セットのJSON形式データ

[カラーユニバーサルデザイン推奨配色セット](https://jfly.uni-koeln.de/colorset/)

カラーユニバーサルデザイン推奨配色セットのエンジニアユニバーサルデザイン推奨書式データです。

"多様な色覚に配慮し、色で情報を伝えるためのカラーパレット" である「カラーユニバーサルデザイン推奨配色セット ver.4」は、悩まずに見やすい色使いを実現できる素敵なツールです。
しかし上記サイトのPDFは画像であり、ITエンジニアがパっと取り出して使うのには向いていません。
そこでJSON形式にして置いておくことにしました。画像からJSONへの書き出しは GPT-4o がやってくれました。すごい。

```json
{
  "AccentColors": [
    {
      "name_jp": "赤",
      "name_en": "Red",
      "rgb": [255, 75, 0]
    },
    {
      "name_jp": "黄色",
      "name_en": "Yellow",
      "rgb": [255, 241, 0]
    },
    {
      "name_jp": "緑",
      "name_en": "Green",
      "rgb": [3, 175, 122]
    },
    {
      "name_jp": "青",
      "name_en": "Blue",
      "rgb": [0, 90, 255]
    },
    {
      "name_jp": "空色",
      "name_en": "SkyBlue",
      "rgb": [77, 196, 255]
    },
    {
      "name_jp": "ピンク",
      "name_en": "Pink",
      "rgb": [255, 128, 130]
    },
    {
      "name_jp": "オレンジ",
      "name_en": "Orange",
      "rgb": [246, 170, 0]
    },
    {
      "name_jp": "紫",
      "name_en": "Purple",
      "rgb": [153, 0, 153]
    },
    {
      "name_jp": "茶色",
      "name_en": "Brown",
      "rgb": [128, 64, 0]
    }
  ],
  "BaseColors": [
    {
      "name_jp": "明るいピンク",
      "name_en": "LightPink",
      "rgb": [255, 202, 191]
    },
    {
      "name_jp": "クリーム",
      "name_en": "Cream",
      "rgb": [255, 255, 128]
    },
    {
      "name_jp": "明るい黄緑",
      "name_en": "LightYellowGreen",
      "rgb": [216, 242, 85]
    },
    {
      "name_jp": "明るい空色",
      "name_en": "LightSkyBlue",
      "rgb": [191, 228, 255]
    },
    {
      "name_jp": "ベージュ",
      "name_en": "Beige",
      "rgb": [255, 202, 128]
    },
    {
      "name_jp": "明るい緑",
      "name_en": "LightGreen",
      "rgb": [119, 217, 168]
    },
    {
      "name_jp": "明るい紫",
      "name_en": "LightPurple",
      "rgb": [201, 172, 230]
    }
  ]
}

```

できるだけ多くの人に見やすい色使いを、そしてセンスを問われてもかわせる権威ある色使いをみんなに。
jqでコマンドライン上のjsonを見やすくする

# はじめに
先日、APIレスポンスの検証をしようと思い、curlコマンドを使用する機会がありました。
レスポンスが期待通りに返ってきていることはすぐにわかったのですが、jsonの内容をコマンドライン上で見るのはかなりきつく、どうにかならないものかと思いました。
そんな時に便利なjqコマンドがあることを学んだので、記事として残しておきます。

# OpenWeatherAPIを例に
今回はOpenWeatherAPIを例にしてみます。
OpenWeatherAPIとは、ざっくり言うと天気の情報を返却してくれるAPIです。
(https://openweathermap.org/api)
実際に見た方がイメージがつきやすいと思うので、早速実践してみましょう。

# curlコマンドでAPIを叩いてみる
実際にAPIを叩いてみます。
（`appid=xxxx`の部分にはOpenWeather公式ページから取得できるAPIキーが入ります。）

```shell
curl "https://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&appid=xxxx"
```

そして返却値がこれです↓
```shell
{"coord":{"lon":139.6917,"lat":35.6895},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":29.87,"feels_like":30.42,"temp_min":27.59,"temp_max":32.03,"pressure":1007,"humidity":47},"visibility":10000,"wind":{"speed":7.72,"deg":200},"clouds":{"all":20},"dt":1718353818,"sys":{"type":2,"id":2044139,"country":"JP","sunrise":1718306694,"sunset":1718359093},"timezone":32400,"id":1850144,"name":"Tokyo","cod":200}
```

返却値、見づらいですね。

コマンドライン上だともっと見づらく、以下のようになります。
![スクリーンショット 2024-06-14 17.39.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576260/bde9929a-8665-df94-9248-948e6a459dca.png)


特に、階層構造がどうなっているのかをここから読み解くのは、まさに職人芸...

# jqを利用してみる

## まずはインストール
Homebrewを利用してインストールしました。
```shell
brew install jq
```

## 早速使ってみよう
同じようにOpenWeatherAPIを叩いてみます。
`| jq .`の部分がポイントです。
```shell
curl "https://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&appid=xxxx" | jq .
```
返却値がこれ↓
```shell
{
  "coord": {
    "lon": 139.6917,
    "lat": 35.6895
  },
  "weather": [
    {
      "id": 801,
      "main": "Clouds",
      "description": "few clouds",
      "icon": "02d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 29.21,
    "feels_like": 30.34,
    "temp_min": 27.79,
    "temp_max": 32.03,
    "pressure": 1007,
    "humidity": 53
  },
  "visibility": 10000,
  "wind": {
    "speed": 7.72,
    "deg": 200
  },
  "clouds": {
    "all": 20
  },
  "dt": 1718354119,
  "sys": {
    "type": 1,
    "id": 8063,
    "country": "JP",
    "sunrise": 1718306694,
    "sunset": 1718359093
  },
  "timezone": 32400,
  "id": 1850144,
  "name": "Tokyo",
  "cod": 200
}
```
随分見やすくなりましたね。嬉しいです。

## 他にもいろんな機能が
要素の一部を抜き出すこともできます。例えばこんなふうに書いてやると、
```shell
curl 'https://api.openweathermap.org/data/2.5/weather?q=Tokyo&units=metric&appid=xxxx'| jq '.["main"]'
```
以下のように`"main"`をキーに持つ箇所を抜き出すことができます。
```shell
{
  "temp": 29.08,
  "feels_like": 30.15,
  "temp_min": 27.79,
  "temp_max": 32.03,
  "pressure": 1007,
  "humidity": 53
}
```

# まとめ
コマンドライン操作は手軽な反面、どうしても出力が見づらくなってしまいがちです。
そんな時にjqを利用して返却値を見やすくできるのは嬉しいと思いました。

# 参考
https://openweathermap.org/api
https://jqlang.github.io/jq/manual/