OmniAICreator/Qiita-1.07M huggingface dataset:
【高専ロボコン】SEKAI_WORLD～本当に良くないコメント～

## はじめに
この記事では、2024ロボコンに制御班として参加し、作成したプログラムの中の終わってるコメントを紹介していきます。
プログラムをよく書く人も、あまり書かない人も楽しんで見ていただいたら幸いです。

良いコメントの書き方は自分で調べたらたくさん出てくると思うので、ここでは**これだけは違う！** というコメントを、実際に使用したプログラムをもとに紹介していきます。

悪い例を紹介しているのはあまりないと思うので、是非とも反面教師にして、悪いコメントを書かないようにしてください！


## 自己紹介
鳥羽商船高専　情報機械システム工学科
4年次以降の選択科目では情報・電気・機械のうち情報系の科目を選択しています。

ロボコンでの担当は、加工(1～2年生)→制御(3～4年生)です。


## SEKAI_WORLD関数
![スクリーンショット (231).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925039/a82707ef-2d49-e7cf-e5ab-37a8d79a9749.png)
皆さんこれを見てどう思いましたか？**絶望**ですよね！
コメントを見ても何をする関数なのかが全く分かりません...
なので以下の様に修正しました。
![スクリーンショット (234).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925039/07284d78-f509-b5b2-1b25-8040b45e68f8.png)
正直良いとは言い切れませんが、SEKAI_WORLDに比べたらかなりマシにはなっていると思います。
あくまで個人の意見ですが、コメントには**何をする(している)** かを書きましょう。
関数は、やりたいことを英語で翻訳し、その結果をそのまま関数名にするのがいいのかなと思っています。
そうすることでより読みやすいプログラムになると思います。


## 終わりに
まず、最後まで読んでいただき、本当にありがとうございます。
どうでしたか？
おそらく「誰がこんなコメント書くねん（笑）」と思った方がほとんどだと思います...
ですが、皆さんのプログラムの中にも第三者視点で見た際に、「?」となるようなコメントがあるかもしれません。
一度見直すという意味も込めて、次からコメントを書く際は、第三者に理解しやすくすることを念頭に置いてコメントを書きましょう！


## おまけ
この記事を書き終わった後に見直していたら、あまりにも短かったのでおまけとしてArduinoのプログラム名も載せておきます。
![スクリーンショット (232).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925039/27d60acc-0cc8-e202-373e-ee7c05091790.png)
とても分かりづらくて見るに堪えない...
ここも個人の意見ですが、ファイル名は**使用したもの(○○センサーなど)_行ったこと** で作成すると後から見直したときに分かりやすいです。
Sequence Makerで開始セルを固定する「#START」コマンドについて

## はじめに
Sequence MakerはExcelから測定器を制御可能にするアドインです。Sequence Makerは様々なシーケンスを自由に組むことができますが、Sequence Maker専用コマンドを組み合わせるとより複雑な処理を行うことができます。この記事ではシーケンスを開始するセルを固定する「#START」コマンドについて解説していきます。なお、Sequence Makerについての詳細は以下の記事を参照ください。

https://qiita.com/sequencemaker/items/8e6a370ab0a793a06a3b

:::note warn
***お断り***
本記事の内容はSequence Maker開発元の公式見解ではなく、あくまでも個人が趣味の範囲内で執筆しているものです。記事の内容について開発元へ問い合わせることはお控えください。ご質問・要望などは各記事のコメント欄へお願いいたします。
:::

## 「#START」コマンド
| 専用コマンド | 機能 |
|:-|:-|
| #START	 | 「コマンド送受信」ボタンを押した際に#STARTと書かれたセルから開始します。<br>セルの選択状態に関わらず、常に同じセルから開始したい時に使用します。|

（https://sequencemaker.hioki.com/manual/ja/#command　より引用）

「#START」コマンドは、マニュアルにあるように、「コマンド送受信」ボタンを押した際にシーケンスを開始するセルを指定するコマンドです。Sequence Makerでは、通常選択しているセルからシーケンスを開始しますが、常に同じセルから開始したい場合に使用します。

## 使い方
開始したいセルに「#START」と書くだけです。こんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/09e213cb-91ae-cc78-5381-49d6cee4d5b5.png)

この例では、C3に「#START」が書かれているので、どのセルを選択していても、「コマンド送受信」を押したときには、必ずC3からスタートします。

::: note warn
「#START」はExcelのワークシート上に1つだけ書くようにしましょう。複数書いてあると、予期しないセルからスタートする恐れがあります。試してみた感じでは、A1のセルから横方向に「#START」を検索しているようです。

:::

## まとめ
今回は開始セルを固定する「#START」コマンドについて解説しました。定型業務などで、常に同じセルから開始したい場合には便利な機能です。なお、デバッグ時などに一時的に無効にしたい場合は「##START」のようにしておけば動作しません。
Jupyter Lab にVegaでグラフを表示する その２

以前に [Jupyter Lab にVegaでグラフを表示す](https://qiita.com/ihgs/items/21d1c396846cca996db7) を記載しましたが、その時はVega-Altairを使っていました。しかし、Altairでは[vega-lite specを利用したグラフは描画できる](https://altair-viz.github.io/user_guide/internals.html#converting-vega-lite-to-altair)が、Vega specは利用できないため、複雑なグラフを描画できないとう課題がありました。

今回は、Altairを使わずにJupyter Lab上でVega specのグラフを表示する方法です。


IPython.display モジュールに、MIME type `application/vnd.vega.v5+json` を指定し、Vega specを渡すことでVegaグラフを描画できます。

```python
import json
from IPython.display import display

vg_spec={
#   省略
}

display({
    "application/vnd.vega.v5+json": vg_spec
}, raw=True)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/fff265d0-3e44-837d-225c-7f3b599940b9.png)

<details><summary>vg_spec</summary>

```python
vg_spec={
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "background": "white",
  "padding": 5,
  "width": 300,
  "height": 100,
  "style": "cell",
  "data": [
    {
      "name": "table",
      "values": [
        {"a": "A", "b": 1},
        {"a": "B", "b": 3},
        {"a": "C", "b": 2},
        {"a": "C", "b": 7},
        {"a": "C", "b": 4},
        {"a": "D", "b": 1},
        {"a": "D", "b": 2},
        {"a": "D", "b": 6},
        {"a": "E", "b": 8},
        {"a": "E", "b": 4},
        {"a": "E", "b": 7},
        {"a": "F", "b": 2},
        {"a": "F", "b": 5}
       ],
      "transform": [
        {
          "type": "aggregate",
          "groupby": ["a"],
          "ops": ["average"],
          "fields": ["b"],
          "as": ["average_b"]
        }
      ]
    }
  ],
  "marks": [
    {
      "name": "marks",
      "type": "rect",
      "style": ["bar"],
      "from": {"data": "table"},
      "encode": {
        "update": {
         
          "x": {"scale": "x", "field": "average_b"},
          "x2": {"scale": "x", "value": 0},
          "y": {"scale": "y", "field": "a"},
          "height": {"signal": "max(0.25, bandwidth('y'))"}
        }
      }
    }
  ],
  "scales": [
    {
      "name": "x",
      "type": "linear",
      "domain": {"data": "table", "field": "average_b"},
      "range": "width",
      "nice": True,
      "zero": True
    },
    {
      "name": "y",
      "type": "band",
      "domain": {"data": "table", "field": "a", "sort": True},
      "range": "height",
      "paddingInner": 0.1,
      "paddingOuter": 0.05
    }
  ],
  "axes": [
    {
      "scale": "x",
      "orient": "bottom",
      "grid": True,
      "title": "カテゴリごとの平均値",
      "labelFlush": True,
      "labelOverlap": True,
      "tickCount": {"signal": "ceil(width/40)"},
      "zindex": 0
    },
    {
      "scale": "y",
      "orient": "left",
      "grid": False,
      "title": "カテゴリ",
      "zindex": 0
    }
  ]
}
```
</details>


ちなみに、`xxs.vl.json` というファイル名でVega specファイルを保存し開き直すと、特に何もせず Vega グラフが表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/ab410210-2a2e-5053-93a5-722b2ff09e9e.png)
ファンクションインデックスの作成失敗

### **背景**
業務でファンクションインデックスを作成しようとした際、特定の環境で失敗する事象に遭遇しました。  
成功する環境と失敗する環境を比較した結果、**Oracleのバージョンの違い**が原因であることが判明しました。

### **問題の詳細**
古いバージョンのOracleでは、特定の条件下でファンクションインデックス作成時に失敗するバグが存在していたようです。一方、新しいバージョンではこの問題が修正されており、正常に動作しました。

### 解決方法
- **環境の比較**: 成功する環境と失敗する環境を詳細に比較。
  - Oracleのバージョン情報を確認し、古いバージョンに問題があると特定。
- **バージョンアップ**: 新しいOracleバージョンにアップグレードすることで問題を解決。

### 学び・気づき
今回の経験から、以下のことを学びました：
1. 同じSQLでも、環境（特にデータベースのバージョン）によって挙動が異なる場合がある。
2. 問題発生時は、環境間の詳細な比較が重要。
3. 公式ドキュメントやリリースノートで、バージョンごとの変更点を確認することが解決の近道となる。

### まとめ
ファンクションインデックスの作成失敗は、初めて遭遇した事象で非常に苦戦しましたが、環境の違いに着目することで解決に至りました。同様の問題に直面した方の参考になれば幸いです。
はじめてアドベントカレンダーを作成してみた

<!-- はじめてアドベントカレンダーを作成してみた -->

## 🐣 はじめに 🐣

こんにちは。人生もエンジニアも修行中、ひよこ饅頭ことひよこです。  
これまでアドベントカレンダーに参加したことすらない私が、いきなりカレンダーを作成してみたお話です。

私は普段、LLM を中心にコーディング中心の仕事をしていますが、研究にも興味を持っています。  でも仕事に追われると、どうしてもじっくり勉強する時間が確保できなくなりますよね。特に納期やバグが**ぐるぐるばたばた**しているときは、「研究関連の論文を読む暇なんてあるか！」と、私もよく思います。  

そのときの私の頭の中を覗いてみると、こんな思考が巡っています。

- 大事なのは**動くもの**とその**前評判**のみ  
- **動くもの**のための勉強は必須（コーディング、Huggingface、AWS、ABCI…）  
- **前評判**は疑わない。だって、頭のいい誰かが考えた手法を大規模な実験で検証したんでしょ？ X でもバズってたし
- ここに**なぜ**が入り込む余地なんてない。それよりも寝たい！

たぶん、これはある程度正しいと思います。  
細かい数式がわかっても評価につながるわけではありません。  
「拡散モデルの逆過程でうまいことサンプリングするっていうけど、分布もわからないのに一体どうやって？」なんて悩むより、Stable Diffusion を動かして画像を量産する方が、ずっと優先度が高い局面は確かにあります。

でも、だからこそ言いたいのです。

**論文を読もう！**

---

## なぜ論文を読むの？

この世界にいると、こんなことを痛感することが多くなりました。

- 1 次情報が大事。とにかく最後は 1 次情報に行き着く  
- 数式は定期的に眺めていないと、脳が拒絶を始める  
- 賢い人に出会うと、意味もなく凹む  
- 効率化や楽をする方法ばかりに労力を注いでいて本当にいいの？

実はこれらを一気に解決する方法があったのです。それが**論文を読むという行為**です。

これまでも一人でちまちまと論文を読んでいましたが、私の場合それだとどうしてもサボり癖が顔を出してしまいます。  
そんなとき、Qiita の**アドベントカレンダー**を知り、「これはいい！」と自分でカレンダー作成までしてしまいました。それがこれです。

[AI・機械学習関連論文](https://qiita.com/advent-calendar/2024/aiml)

今はとにかく毎日一つは何かの記事（論文紹介や実装に役立つ話題や数学知識など）を書くことを目標に頑張っている最中です。

> 🐣 毎日記事を上げるのは思っていた以上にしんどいですが…

このアドベントカレンダーでは以下の内容で記事を募集しています。  
もしよかったら、なにか記事を投稿してみませんか？ 次のような内容を募集中です。

> ## 🐣 ひよこの脱出計画、始動！ 🐣  
>
> 今回は以下のトピックを中心に記事を集めたいと思います。  
>
> - 最新の AI・機械学習論文のまとめと考察  
> - 理論と実装を結ぶコード例  
> - 論文を読解する際のコツやツールの紹介  

論文なんて敷居が高い！ 自分にはそんなもの必要ない！ そんな人にこそ参加して欲しいと思います。「この論文のここがやっぱりわからない」という内容でも歓迎です。  
**素人質問で恐縮ですが**
なんて人も、
**本当にこれ学校で習ってないの？**
なんて人も、
**英語じゃないと論文読んだとは言いませんけど**
 なんて人もいません。  

どんな形でもいいから論文に触れてみてください。きっとそこには今までにない気付きや発見があるはずです。

---

## 🐣 おわりに 🐣

ということで、ここ「はじめてのアドベントカレンダー」にはじめてアドベントカレンダーを作成した 🐣 が投稿させてもらいました。  
よろしければ、またぜひ [AI・機械学習関連論文](https://qiita.com/advent-calendar/2024/aiml) の方でお会いしましょう！
そろそろBunを使ってみる

# はじめに

Bun のメジャーバージョンが 2023年にリリースされ、1年以上が経過しました。
タイトルの通り、そろそろ使ってみたいな、ということで入門してみます。

# Bunとは？

[Bun](https://bun.sh/) は、JavaScript/TypeScript/Node.jsプロジェクト向けのランタイムです。Node.js の置き換えとして注目されており、2023年にメジャーバージョンがリリースされました。

以前は Deno が人気でしたが、着々と勢力を伸ばし、State Of Javascript 2023 では、Deno を抜き、Node.js に次ぐ注目度となっています。
2024年の結果が楽しみですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/e4f0116c-e713-1898-e116-1a535da82e5b.png)

https://2023.stateofjs.com/en-US/other-tools/#runtimes

## 特徴

- 高パフォーマンス: Zigというプログラミング言語で書かれており、JavaScriptやTypeScriptの実行速度が非常に高速
- オールインワン: パッケージマネージャー、バンドラー、トランスパイラーなどの機能を一つのツールで提供
- Node.js 互換性: 多くのNode.jsモジュールをサポート (この辺りはまだ弱い部分もあるようですが、日々対応中とのこと)
  
あと、アイコンがめちゃくちゃ可愛いので応援したくなりますね。

https://github.com/oven-sh/bun

速度とオールインワンの部分が際立っていますね。
公式のベンチマークによれば、React の SSR が Node.js の4倍以上と驚異的な結果になっています。（ただし、利用状況や条件によるため、参考程度に）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/aee88bf4-4b95-1c95-656d-5e5294e858e8.png)
*ReactのSSRにおけるBunとNode.jsのパフォーマンス比較（公式ベンチマークより）*


# 環境構築

では、早速試していきます。

## 前提環境
- MacOS（M2）
 
※ 基本自身の環境ベースで記載しますので、環境差分は適宜読み替えて下さい

## 手順

### インストール

1. 公式サイトのインストールコマンドを実行
    ```bash
    curl -fsSL https://bun.sh/install | bash
    ```
1. Terminalを再起動するか以下のコマンドを実行し、Pathを反映する
    ```bash
    source ~/.zshrc
    ```
1. 確認
    ```bash
    bun --version
    # 1.1.38 のようにバージョンが出ればOK
    ```

### Hello World を実行してみる

公式の [QuickStart](https://bun.sh/docs/quickstart) に沿って進めていきます。

1. プロジェクトフォルダを作成
    ```bash
    mkdir bun-sample && cd bun-sample
    ```
1. プロジェクトの初期化
    ```bash
    bun init
    # 全てデフォルトを選択
    ```
1. `index.ts` を以下のように修正
    ```typescript
    const server = Bun.serve({
        port: 3000,
        fetch(req) {
            return new Response("Hello Bun World!");
        },
    })
    
    console.log(`Listening on http://localhost:${server.port} ...`);
    ```
1. サーバーを起動
    ```
    bun run index.ts
    ```
1. ブラウザで `http://localhost:3000` にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/a68fd16c-a981-a1dc-de9f-201dac39b5a9.png)

無事に起動しました！

# 最後に

まだ、`Hello World!` しただけですが、`Node.js` と比べてとてもお手軽な印象を受けました。

今後さらに触りながら、色々試してみたいと思います！
git rebase -i の exec って何だ？ #Git

コミット整理などをするときに```git rebase -i```を打つと出てくるこの説明画面↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519892/263b56d5-342d-e1e9-fb03-80efece85efe.png)
多用する```pick```,```squash```をはじめほとんどのコマンドは説明を読めば使い方が大体理解できますが、```exec```だけ何に使うのかよく分かりません。ということで活用法を考えてみました。
その他のコマンドについて適当なページをリンクしようと思ったらいい記事が見つからなかったので[末尾](#付録-その他のコマンドについて)へ。

## 何が出来るのか
英語で説明されている通り、```exec```以降のシェルコマンドを実行できます。複数のコマンドを実行したい場合は```;```で実行できる模様。当然パイプも使えます。コミットとコミットの間の**新たな行**に記載するという発想が```pick```や```squash```ばかり使ってた私の頭にはなかったため、試しに書いてみても動かない、長らく意味不明なコマンドとなっていました。
```
pick abc123 hoge
exec ここに何かシェルコマンドを記載
squash def456 fuga
pick ghi789 piyo
...
```

## 活用法① ２つ以上前のコミットに入れたい変更がある
参考記事：[git-rebaseのexecを使ってstashした内容を履歴に埋め込む](https://qiita.com/yuku_t/items/fed530acb97385ecbeee)
例えば以下のような状況を考えてみましょう。コーディング中、だいぶ前に編集したファイルで誤字を発見してしまった場合。
```
$ git log --oneline
abc123 hoge //ここで編集したファイルに誤字発見！
def456 fuga
ghi789 piyo
```
直前の編集であればとりあえずコミットしておいて後で```squash```すれば事足りますが、直したいコミットが２つ以上前の場合はそう単純ではありません。ここで```exec```が真価を発揮します。

①とりあえず追加の修正をstash
```
git stash [必要に応じてコマンドオプション]
```
②git rebaseの画面で```exec```を埋め込んでstashを適用！
```
pick abc123 hoge
exec git stash pop; git commit -a --amend -C HEAD
squash def456 fuga
pick ghi789 piyo
```
え？editで直接編集すればいいじゃんって？**１行で処理するのがカッコいい**んだよ。
なお、後続の```git commit```のオプションについて、```-a```は```git add```を省略するためのオプション、```--amend```は直前のコミットの編集、```-C HEAD```は直前のコミットメッセージを再利用するためのオプションとなっています。

## 活用法②　テストがいつ動かなくなったのか調べたい
実装完了後、テストを回してみたら既存のテストが動かなくなったという経験は皆さんあるはず。そんなとき```exec```を使えばいつテストが動かなくなったのか調べることができます。
```
pick abc123 hoge
exec npm test
squash def456 fuga
exec npm test
pick ghi789 piyo
```
例えばこんな感じ。ついでに**コミット整理もできて一石二鳥**ですね。途中でテストが失敗した場合はその時点でリベースも中断されるので、問題が起きた時点のコミットを修正して```git rebase --continue```で再開しましょう。

## 付録-その他のコマンドについて

### コミットの行に書くもの
|コマンド  |内容  |
|---|---|
|p, pick |コミットをそのまま適用する |
|r, reword |コミットをそのまま適用するが、コミットメッセージを編集する |
|e, edit |コミットを適用した状態でエディターを開き、コミット内容を編集する<br>(変更を行った場合そのコミットが上書きされる) |
|s, squash |コミットを直前のコミットに統合し、コミットメッセージを編集する |
|f, fixup |コミットを直前のコミットに統合し、コミットメッセージは編集しない<br>(直前のコミットメッセージが利用される)|
|d, drop |コミットを削除する（行削除でも同様の挙動） |
|m, merge |コミットを利用して特定の\<label\>の位置でマージコミットを作成する |

### 新たな行に書くもの
|コマンド  |内容  |
|---|---|
|b, break |リベース操作を中断してエディターを開く |
|l, label |現在のHEAD位置に特定の\<label\>で名前を付ける |
|p, pick |特定の\<label\>の位置まで操作を巻き戻す |
SQLの実行順序とエイリアス

もしかしたら当たり前なのかもしれないが、自分は不思議に感じたのでメモ。

## SQLの実行順序
(私が認識している)SQLの実行順序はこの通り。
```python:SQLの実行順序
FROM句
↓
JOIN句
↓
WHERE句
↓
GROUP BY句
↓
HAVING句
↓
SELECT句
↓
ORDER BY句
↓
LIMIT句
```

## 実行順序とエイリアス
となると、SELECT文でエイリアスを使った場合に、group by句でそのエイリアスは使えないのでは？と思っていました。しかし、（少なくともBigQueryでは）group by句でもエイリアスが使えるようです。GPT君に聞いた所、ユーザーフレンドリーな設計として取り入れられているDBが多いとのこと。

## BigQueryのサンプルを使った確認
### 使用するテーブル
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402779/02c76d5b-4579-3487-4a3a-3aa8266ed404.png", width=80%>

### group byでエイリアスを使わない場合
```sql:エイリアス未使用
select
  product_category as category,
  round(avg(cost), 2) as avg_cost
from
  `sql-book-440810.sample.products`
group by
  product_category
```
#### 結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402779/e3c55414-650e-0980-9bbd-5bc2694c6252.png", width=60%>

### group byでエイリアスを使う場合
```sql:エイリアス使用
select
  product_category as category,
  round(avg(cost), 2) as avg_cost
from
  `sql-book-440810.sample.products`
group by
  category
```
#### 結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402779/caf9a4df-f564-4fef-554c-15a0275e194f.png", width=60%>

### 比較結果
同じだね☆
UiPath_辞書型のValueにタプル型を設定して値を取得してみる

## はじめに

①この記事は、UiPath アドベントカレンダーの8日目の記事です！
皆様、ぜひ書いてみましょう！

https://qiita.com/advent-calendar/2024/uipath

②使用したUiPathはCommunity版、Versionは2024.10.7です。


## 辞書型でできるかな？
昔から辞書型はよく使用されてきましたが、辞書型とタプル型を組み合わせて使ってみるとどんな感じになるのでしょうか。

## やってみましょう
以下の都道府県や市町村が記載されたExcelファイルを用意しました。都道府県に合わせて、市町村名や町名を取得できるようにしたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/3870f17b-dfce-c6c4-24df-be804e314090.png)
日本の住所のパターンは以下のような感じです。
①都道府県+区名+町名以降(東京23区)
②都道府県+市名+区名+町名以降(大阪市や福岡市など)
③都道府県+市名+町名以降
④都道府県+郡名+町村名+町名以降
都道府県を設定することでうまく必要な値を抽出することは可能でしょうか。

## 実装イメージ
基本は
①辞書型の初期値設定
②今回使用するファイル(Book1.xlsx)の読込
③辞書型に価を設定
④値をメッセージボックスに抽出
になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/366763ca-3e40-d13a-fc7b-a3816b03fa30.png)

## 結果
試しに大分県、長野県の市名、福岡県の区の名前を取得してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/dc6dd179-6f08-5876-9537-583226184143.png)

## 解説
### 辞書型の設定
辞書型変数dicAddress設定時に、Key値はString,Value値をTupleで設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/67c02e6e-e4a9-c828-292b-de18c794504f.png)
タプル型ですが、今回は「都区」、「市郡名」、「区」、「町村」、「地名」の5個分必要なので「Tuple(T1,T2,T3,T4,T5)*」を設定します。
*<>で囲もうとすると消えてしまうので、()で代用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/93466f8d-730d-befd-5955-057c8225bf26.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/921a59ed-9733-9e35-0496-f3163dfacb25.png)

### タプル型設定
タプル型変数tupAddressDataを設定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/712395a9-c1a7-756c-7414-f15e67ce2d33.png)
設定は以下のようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/d1a0db95-4834-cbc4-1f38-de84413776ed.png)



### タプル型初期化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/f3d853c1-baf2-7182-9dc7-10d1eba4cdc6.png)

今回の一番最初のフローにあるタプル型の初期化の際は以下のようにします。
今回は「都区」、「市郡名」、「区」、「町村」、「地名」の5個分あるので、5つ分の列名を設定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/79004a42-d7c8-0be7-5f87-27d0897f41af.png)

### 値の算出
値は辞書型変数(Key値).タプルのアイテムItem)になります。
今回の場合、Key値は都道府県なのですがValue型はタプルなので以下のようにItemを設定していきます。Itemはそれぞれ
Item1：都区
Item2：市郡名
Item3：区
Item4：町村
Item5：地名
になるので、大分県と長野県は市郡名が欲しいのでItem2、福岡県は区が欲しいのでItem3を設定すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/3b9905e4-c55b-5578-26cd-e0028dbac29a.png)


辞書型とタプル型のイメージをすると以下のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/d4e95ad1-45eb-9628-989e-89e7c99b4599.png)

## まとめ
このタプル型を使う機会はなかなか見つからないでいたのですが、辞書型との組み合わせを使える場所を見つけたことで備忘録として記事に起こしておきたかったものです。
今後も実装に役立つものがあれば発信していきます。
最後までご覧いただきありがとうございました。
Claude 3.5を活用したQiitaマークダウン生成ガイド

Qiitaの記事を書き始めたばかりの方が最初にぶつかる壁、
それはマークダウン記法ではないでしょうか。
もちろん、NotionやSlack、Discord、WordPressなどで普段から文章を書く習慣がある人にとっては問題ありませんが、
そうでない方にとっては **「面倒な存在！」** と感じるかもしれません。

そんなマークダウンが原因でQiitaの記事作成を億劫に感じている方々のために、今回はClaude 3.5を活用してサポートしてもらう方法をご紹介します！

## Claude 3.5を使ってマークダウンを簡単に生成する方法

使い方はとても簡単で、以下の手順に従ってください。

1. **記事を準備する** まず、あなたが書いた記事を準備します。これはテキストエディタやWordなど、どんなツールでも構いません。

2. **Claude 3.5に記事を貼り付ける** 書き終えた記事をコピーして、Claude 3.5の入力欄に貼り付けます。

3. **プロンプトを入力する** 以下のプロンプトを入力してください

```
以下は私が書いた記事です。これをQiitaのマークダウン記法を使って生成してください。

*文章は変更しないでください。
*全文一気に出ない場合は分割して出力してください。
*文章が読みやすくなるよう心がけてマークダウンを考えてください。
*アーティファクトを必ず使って出力してください。
```

4. **マークダウンの生成** これでClaude 3.5があなたの記事をQiita用のマークダウンに変換してくれます。

5. **Qiitaにコピペ** 生成されたマークダウンをコピーし、Qiitaのエディタに貼り付ければ完成です！

## 実際の使用例

例えば、以下のように記事を生成できます。

### 元の記事

```
コンテナの起動 以下のコマンドを実行してコンテナを起動します。 
sudo docker-compose up -d 
起動したコンテナの動作を確認するには、
次のコマンドを実行します。
docker ps
```

### Claude 3.5で生成されたマークダウン

### コンテナの起動

以下のコマンドを実行してコンテナを起動します。

```bash
sudo docker-compose up -d
```

起動したコンテナの動作を確認するには、次のコマンドを実行します。

```bash
docker ps
```

## CatGPTでも出来るでしょ！？

「CatGPTでもできるでしょ！」という声が聞こえてきそうですが、
実際にはChatGPTではマークダウンが途中でズレてしまうことが多々あります。
特にコードブロックを挿入すると、ほぼ100％の確率でレイアウトが崩れてしまいます。

![スクリーンショット 2024-12-08 21.22.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841127/2f8b1eb4-256e-f9a4-cc45-b79d7fb3de0f.png)

上記のように生成されますが、実際にコピペすると以下のようになってしまいます。

1. コンテナの起動 以下のコマンドを実行してコンテナを起動します。
GPTの生成したマークダウンをコピペ
bash コードをコピーする sudo docker-compose up -d 起動したコンテナの動作を確認するには、次のコマンドを実行します。
bash コードをコピーする docker ps 4. Nextcloudの初期設定 ブラウザで以下のURLにアクセスします。
arduino コードをコピーする http://[サーバーのIPアドレス]:8080 Nextcloudの初期設定画面が表示されるので、以下の情報を入力してください。
データベースのユーザー名: nextclouduser データベースのパスワード: nextcloudpassword データベース名: nextcloud データベースホスト: db 入力後、「インストール完了」をクリックすればセットアップ完了です！

```yaml
このように、マークダウンが正しく反映されず、読みづらくなってしまいます。
```

## Claude 3.5の優れた点

一方で、Claude 3.5では以下のようにアーティファクト（artifact）を使用して正確にマークダウンを生成できます。

![スクリーンショット 2024-12-08 21.51.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841127/9aee47c7-e805-a838-9358-c54a79bec4a5.png)

出力の右下にある「コピー」ボタンを押すと、記事全文を一括でコピペでき、
マークダウンが正確に適用されます。
これは非常に便利で、時間の節約にもなります。

## まとめ

現在、複数のLLM（大規模言語モデル）を活用することが主流となりつつあります。
例えば、マークダウン記法に関してはClaude 3.5が最も適している一方で、
長文の生成や他の用途ではGeminiやChatGPT（特にo1）が優れています。
これからのスタンダードは、用途に応じて最適なAIを使い分けることになるのか、
あるいは一つのAIが覇権を握るのか、非常に興味深いところです。

とにかく、マークダウンで簡単にコピペしたい場合はClaude 3.5を強くおすすめします！
なお、ChatGPTを使ってマークダウンを正確に出力する方法も最近見つけましたが、
それはまた別のお話で。

→ **To Be Continued！**
LangChain入門：概念と主要コンポーネントの理解


この記事ではLangChainの基本概念、主要なコンポーネント、そして実際に使用するシーンなどについて解説します。
LangChainを初めて触れる方や、その使用シーンについて知りたい方に向けて、概念的な解説に留め、技術のベースをまとめます。

## LangChainとは？
LangChainはLarge Language Model(LLM)を活用するアプリケーションの開発を効率化するためのフレームワークです。LLMの能力を最大限引き出すために、モデル、プロンプトテンプレート、チェーン、エージェントなどの主要なコンポーネントを組み合わせて柔軟に開発できることが特徴です。

### LangChainの強みと価値
LangChainの強みや価値は以下の点にあります。
* **複雑なワークフローを簡潔に構築**
  * 複数のプロンプトやモデルの呼び出しを繋ぎ合わせるチェーンによって複雑なタスクを効率よく設計できる
* **柔軟なプロンプト設計**
  * プロンプトテンプレートを使用して、動的かつ再利用可能なプロンプトを設計できる
* **外部ツールとの統合**
  * エージェントを活用することで、APIやデータベースなどと連携可能
* **スケーラビリティと拡張性**
  * トレーシング機能やメモリ管理を活用することで、規模が拡大しても管理しやすい設計が可能

## LangChainの基本概念
LangChainはLLMを中心に据えた開発をシンプルかつ拡張性のある形で実現することを目的としています。具体的な活用シーンとしては以下のような例が挙げられます。
* ユーザからの入力に応じた動的なプロンプト生成
* チャットボットや対話型AIの構築
* 外部データソース(データベースやAPI)との連携

LangChainでは、LLMの能力を最大限引き出すために、いくつかの重要なコンポーネントが設計されています。それぞれの役割を理解することで、どのように課題を解決するかが見えてきます。


## LangChainの主要コンポーネント
LangChainの主要なコンポーネントを理解することで、LangChainの全体像を把握することができます。
### 1. LLM
LangChainの核となる要素です。OpenAIのGPT、 Anthropic Claude、Azure OpenAIなどの商用プラットフォームをはじめ、Hugging Face、LLaMAなどのオープンソースモデルなども使用可能です。これにより、自然言語の生成、質問応答、要約といった機能を実現します。

### 2. モデル
LLMを特定のタスクに適応化させる為の抽象化レイヤーです。モデルを選択する際に、速度や精度といったトレードオフを考慮しやすくなります。

### 3. プロンプトテンプレート
プロンプトテンプレートは、**ユーザの入力を特定のフォーマットに整形してLLMに渡す仕組み**です。これにより、LLMの応答精度やパフォーマンスを最大化できます。

### 4. チェーン(Chain)
チェーンとは**複数のプロンプトやモデル呼び出しを組み合わせて、一連の処理を自動化する仕組み**です。データの流れを構造化して制御できるため、単一のタスクではなく、複雑なプロセスを効率的に処理できます。

### 5. エージェント(Agent)
エージェントは、**外部ツールやAPIを呼び出しながら、タスクを動的に処理する仕組み**です。タスクの内容や状況に応じて、次にどのアクションを取るべきかを判断し、適切なツールを選択して実行します。あらかじめ定義されたフローに従うチェーンとは異なり、**状況に応じてリアルタイムで次のアクションを判断**します。 データベース検索、ウェブ検索、翻訳などのツールを呼び出してLLMだけでは対応できないタスクの処理をすることも可能です。

### 6. メモリー(Memory)
会話履歴やコンテキストを保持する為の仕組みです。これにより、長期的な会話の一貫性を維持することが可能となります。

### チェーンとエージェントの違い
チェーンはあらかじめ定義された手順に従って効率的にタスクを処理する一方、エージェントは外部ツールを呼び出しながら動的に判断し、柔軟に対応します。用途や目的に応じて適切に選択する必要があります。

| 特徴       | チェーン（Chain）                   | エージェント（Agent）                    |
|------------|-------------------------------------|------------------------------------------|
| 処理の流れ | あらかじめ定義されたステップに従う   | タスクに応じてリアルタイムで判断         |
| 柔軟性     | 固定されたフローで効率的に処理       | 動的なタスク処理やツール呼び出しに対応   |
| 用途       | 一連のステップを効率的に処理         | 外部ツールやAPIを活用した複雑なタスクに対応 |
| 例         | 文書解析、データ処理フローの自動化   | 計算、ウェブ検索、データベース参照       |


## まとめ
LangChainは、LLMの能力を最大限引き出すための強力なフレームワークです。主要なコンポーネント(LLM、モデル、プロンプトテンプレート、チェーン、エージェント)を理解し、これらを組み合わせることで、自然言語処理の性能を大きく引き上げることができます。

特に、プロンプトテンプレートやチェーンを活用すれば、複雑なワークフローをシンプルに構築できる点が大きな魅力です。これにより、開発効率と応答精度を両立したアプリケーションを設計できます。

LangChainの各コンポーネントを活用することで、開発効率を大幅に向上させることができます。まずはシンプルなプロンプトテンプレートやチェーンを試し、自分のユースケースに合わせたカスタマイズを進めてみてください。
【初心者必見】SQLのWHERE句を使いこなそう：よくあるエラーと解決策

SQLを利用するにあたって切っても切れない関係にあるのが**WHERE句**です。
データベースから特定の条件でデータを取得するために使う非常に重要な構文ですが、初心者がよく躓くポインドでもあります。

この記事では、WHERE句の基本的な使い方から、**よくあるエラーとその解決策**を解説します。
エラーを解消し、効率的にデータを操作できるようになりましょう。

# WHERE句とは？
WHERE句は、SQL文で条件を指定してデータを絞り込むために使用します。
SELECT文やUPDATE文、DELETE文などに指定され、処理対象となる行を絞り込むことができます。﻿
一般化した書き方と具体例を用いて確認しましょう。
```sql:基本構文
SELECT 項目１, 項目２
FROM テーブル名
WHERE 条件;
```
具体例として従業員の年齢が30歳以上いるデータを取得する場合を考えてみましょう。
```sql:例
SELECT *
FROM employees
WHERE age >= 30;
```
※``SELECT *``ですべてのデータを取得することが出来ます。
次に初心者が陥りやすいWHERE句での誤った使い方とその解決策を確認してみましょう。

# WHERE句でよくあるエラーと解決策
### １．数値型のカラムに文字列を指定するミス
よくあるミスですが、数値型にも関わらず文字列の値を指定する**データの不一致**が原因でこのエラーが起きます。
```sql:エラー例
SELECT 項目１, 項目２
FROM テーブル名
WHERE age = "30";  '←ダブルクオーテーションで文字列として扱ってしまっている'
```
解決策として数値型のカラムにはダブルク、シングルのクオーテーションの使用は避けるようにしましょう。

### ２．NULL値を扱うミス
NULLは「変数やデータが何も含まれていない状態」のことを表します。
それを踏まえてエラー例のような使い方をしていないか確認してみましょう。
```sql:エラー例
SELECT *
FROM employees
WHERE department = NULL;  
```
SQLでは、``=``でNULLを比較することが出来ません。
そのためNULL値と比較する場合は、``IS NULL``もしくは``IS NOT NULL``を使用します。
```sql:正しい使い方
SELECT *
FROM employees
WHERE department IS NULL;  
```
### ３．ANDとORの条件を混ぜたミス
データの絞り込む条件が複数ある場合、``AND``や``OR``があるのはご存じだと思います。
しかし、この``AND``や``OR``には算数でいう加減乗除のようにルールがあるので、理解していないとほしいデータを取得できない可能性があります。
優先順位は結論こうです。
**NOT＞AND＞OR**
二つのSQLを見てみましょう。
```sql:例①
SELECT * 
FROM employees  
WHERE age > 30 OR position = 'Manager' AND department = 'Sales';
```
```sql:例②
SELECT * 
FROM employees  
WHERE (age > 30 OR position = 'Manager') AND department = 'Sales';
```
優先順位の考え方により例①と例②で取得するデータが違うことが分かりますか？
例②のように優先順位を明確にするために、**条件を括弧でグループ化**しましょう。

### ４．ワイルドカード（LIKE）の使い方ミス
```sql:エラー例
SELECT * 
FROM employees  
WHERE name LIKE '*Smith';
```
さてどこが間違いか分かりますか？
SQLではワイルドカードを使用するときは``*``ではなく``%``を使います。
これを踏まえて正しい使い方を確認してみましょう。
```sql:正しい例
SELECT * 
FROM employees  
WHERE name LIKE '%Smith';
```
### ５．日付データのフォーマットミス
```sql:エラー例
SELECT * 
FROM employees  
WHERE hire_date = '2024-12-05'; 'フォーマットが不適切
```
使用するRDBMS（MySQL、PostgreSQLなど）によって日付データのフォーマットが異なる場合がありますのでしっかり確認しましょう。
MySQLでは問題なかったけど、PostgreSQLでは無理だったというような事象が起きかねません。
解決策として、使っているRDBMSの日付フォーマットを確認する、または明示的に日付型として指定しましょう。
* **MySQLの場合**
```sql:
SELECT *
FROM employees  
WHERE hire_date = DATE('2024-12-05');
```

* **PostgreSQLの場合**
```sql:
SELECT * 
FROM employees  
WHERE hire_date = '2024-12-05'::DATE;
```

# ３．実務でよく使うWHERE句テクニック
### ①INで複数条件を指定する
```sql:
SELECT * 
FROM employees  
WHERE department IN ('Sales', 'Marketing', 'HR');
```
この条件では所属部署が「営業」、「マーケティング」、「人事」の社員を取得するSQLです。

### ②BETWEENで範囲を指定する
```sql:
SELECT * 
FROM employees  
WHERE age BETWEEN 30 AND 40;
```
この条件では年齢が30歳以上40歳以下の社員を取得するSQLです。
``BETWEEN``はその数字を含むことに注意して使用しましょう。
### ③NOTで条件を除外する
```sql:
SELECT * 
FROM employees  
WHERE NOT department = 'HR';
```
この条件では人事以外の社員を所得するSQLです。

# ４．まとめ
WHERE句はSQLの中でも非常に重要な部分であり、正しく使えば効率的にデータを操作できます。
しかし、条件指定のミスやデータ型の不一致でエラーが発生することもしばしばあります。

**エラーを防ぐポイント**
* データ型（数値、文字列、日付）を正しく指定する
* NULL値にはIS NULLまたはIS NOT NULLを使用する
* 条件をグループ化して優先順位を明確にする
* ワイルドカードやフォーマットはRDBMSに合わせて使用する

これを意識することでエラーをある程度回避できると思うので、ぜひ参考にしてください。
以上です。
「転職」キャリアは二刀流！エンジニア＆中国語の欲張りな転職ストーリー


![Firefly 未来がひらけた女の子の後ろ姿 アニメ 55233.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636287/2e78ee8f-e7b8-5093-7b0f-9d123b31c20d.jpeg)


## よくばりで頑固な性格
エンジニアとしてキャリアを築きながら、大学で行っていた中国語も忘れたくない——この二刀流でキャリアを築けないかそんな欲張りな挑戦を本気でやってみた話です。

## 初めての転職活動：華麗なる失敗の巻
営業職にいた私が「エンジニア＋中国語」を目指して、転職に挑戦したのがスタート。もちろん、頭の中では「言語もプログラミングもできるんだから！なんだかんだ誰か拾ってくれるさ」と思ってました。…甘かった。

なぜなら、当時のスキルは、ちょっとコードが読めるレベル。書類を出しても出しても、企業からはなんの反応もなく…返事があっても「次の選考には進めません」という定型文。未経験にありがちな壁にぶち当たりました。「やっぱり営業からエンジニアなんて無理だよね」と弱音を吐きながらも、一応転職活動を終了しましたが、その敗北感がじわじわと尾を引いてましたね。

## 打開策：ポートフォリオを全力でつくる
そこで諦めなかったのが、頑固なところです。
この1年間本気で仕事終わりにポートフォリオ作成やkaggleに打ち込むことができ、1回目の転職活動で妥協して転職しなくて良かったと思いました。


## 二度目の転職活動：再度「エンジニア×中国語」を前面に出す作戦
この二度目の転職では、「今度こそ！」とデータサイエンティスト部門とIT部門に集中して応募を開始。ターゲットを絞り込み、応募書類にエンジニアとしてのスキルと中国語のレベルを書きまくりました。「今度こそ、自分にピッタリなポジションに出会えるはず！」と信じて応募し続けましたが、返ってきたのは…なんとデータサイエンティスト部門とIT部門じゃない別の部署からの電話。

「え、なんで？」と思ったものの話を聞くと、「業務改善のためにエンジニア的なスキルが必要で、中国語もできる人材を探していた」とのこと。まさに“エンジニア×中国語”という自分の武器がピッタリとはまる条件がそこにあったのです！ここで「これは転職で掴むべきチャンスだ！」と直感し、その部署への転職を決意しました。

## 転職活動を通して一番の学び

「無理だと思っても、考えを止めない。現状でいいやと思わない。期限を決める。」ということです。企業がどこでどんな人材を探しているかはわからない。だからこそ、「エンジニア×中国語」という少しユニークな組み合わせでも、挑戦してみる価値はあるのだと実感しました。これからも転職は“挑戦”の場だと考え、さらに学び続けたいと思います。

特にエンジニアの世界では、「やってみたもん勝ち」の精神が意外と大事だったりするのかも。これを読んで「自分も挑戦してみたい！」と思ってくれた方がいたら嬉しいです！


:::note info
私の次の目標は
・kaggleでGrandmasterになる
・kaggleを強みにデータ分析の仕事がしたい
・給料上げたい
・中国語ビジネスレベルになる
:::
aqua.yaml を CLI で楽に作成する

# はじめに
記事を見てくださりありがとうございます。
@HayatoHanaoka と申します。
`aqua.yaml` 作成する際に、とてつもなく便利なコマンドがあったのでメモがてら記事にして残します。
一瞬で作成できてめっちゃ便利なので、皆さんもぜひ使ってみてください！

# aqua.yamlの初期ファイルの作成
```
aqua init
```
コマンド実行で出来上がるファイルの内容

```aqua.yaml
---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
- type: standard
  ref: v4.269.0  # renovate: depName=aquaproj/aqua-registry
packages:
```

# 任意のパッケージを `aqua.yaml` に追加する
```
aqua g -i
```
上記コマンドを実行すると、どのパッケージを追加するかを選ぶ画面が出ます。
そこで任意のパッケージを選択してください。
出来上がるファイル（skaffoldを選択した場合）
```diff_yaml
 ---
# aqua - Declarative CLI Version Manager
# https://aquaproj.github.io/
# checksum:
#   enabled: true
#   require_checksum: true
#   supported_envs:
#   - all
registries:
 - type: standard
  ref: v4.269.0 # renovate: depName=aquaproj/aqua-registry
packages:
+ - name: GoogleContainerTools/skaffold@v2.13.2
```
【Unity】ラムダ式をやっと使い始めた

# はじめに
この記事は[Hamster Output Advent Calendar 2024](https://qiita.com/advent-calendar/2024/game_hamster)の9日目の記事です！

本記事では、やっとラムダ式を使いだしました！というだけの内容です！！

# ラムダ式に関して調べた
**ラムダ式は無名関数を書くことができる機能!**

ソースコードにすると下のような感じです。どこかで見たことあると思ったけど、思い出してみるとDOTweenとかUniRxとかを使っている時に、いっぱい処理書きたい！見たいな時に何となくやっていたような...

```C# : 書き方
// ()　←　これは引き数を書く場所
() => 
{
   // ここに何か処理を書く
};


```

実際にソースコードにして見るとこんな感じ。書き方が不思議だけど、何となく使い方は分かった気がする。

```C#
public class Test : MonoBehaviour
{
    private Action logAction;

    void Start()
    {
        logAction = () =>
        {
            Debug.Log("Hello, World!");
            Debug.Log("Goodbye, World!");
        };

        logAction();
    }
}
```

処理が1行だけならさらにコンパクトに書けます。
```C#
public class Test : MonoBehaviour
{
    private Action logAction;

    void Start()
    {
        logAction = () => Debug.Log("Hello, World!");
        logAction();
    }
}
```

Linqを使う場合、ラムダ式で記述する前提になっているらしく、ラムダ式を触る場合、一緒に勉強しても良さそうです。(今度やろうかな)

# 実際に使った

今作っているゲームで、VContainerの依存解決が終わったら完了通知を送るRegisterBuildCallback辺りで使ってます。VContainer周りの使い方が正しいか正しくないかはさておき、現状では登録したクラスの初期化処理を行う用途で使っていますが、これから使う場面は結構増えるかも知れないです。

```C#
public class InputDetectionLifetimeScope : LifetimeScope
{
    protected override void Configure(IContainerBuilder builder)
    {
        builder.Register<InputDetectionModel>(Lifetime.Singleton);
        builder.RegisterComponent(GetComponent<PlayerInput>());
        builder.RegisterComponent(GetComponent<InputDetectionView>());
        var presenter = GetComponent<InputDetectionPresenter>();
        builder.RegisterComponent(presenter);

        // 登録が完了したら初期化処理を呼び出す
        builder.RegisterBuildCallback(container => presenter.Initialize());
    }
}
```

# まとめ
**ラムダ式は無名関数を作れる便利機能**。メソッドを変に作らなくても良くなるし、ソースコードがスッキリする。便利な分、書き方が少し特殊で、慣れていない内は戸惑いそう。

もっと詳細な内容はまた今度調べます！
Reactを勉強し直す 〜 v17 〜

# はじめに
自分の知識がReact16で止まっていたので再勉強していきます。React16の内容は以下。

https://qiita.com/mattsu_mocha/items/0e08566eaefd47782bfa

https://qiita.com/mattsu_mocha/items/f0203be25ea6dbb1ca91

次はReact17。

# React 17について
React17では新機能追加は **“なし”**。

代わりに、アプリケーション内で複数のReactバージョンを安定して動作させる「**段階的アップグレード**」が可能になった。

これによって、アップグレード時にメンテナンスされていなくて複数のReactバージョンを混在させた結果、うまく動かないという問題を解消できるようになった。

※ ただし、基本的には一気にアップグレードするのがベストな選択肢と公式ブログには記載されている。

以下以外の変更点はこちらを参照。

https://ja.legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#other-breaking-changes

## イベントデリゲーションの変更
段階的アップグレードを可能にするため、イベントデリゲーションの変更が入った。

**イベントデリゲーション**とは、イベントリスナーを共通の親要素に設定し、子要素で発生するイベントを親要素でキャプチャして処理する手法である。

```html
<ul id="parent">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
```

```javascript
// liタグの数が増減してもイベントリスナーを新たに追加したりする必要はない
document.getElementById('parent').addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') {
    console.log('Clicked item:', event.target.textContent);
  }
});
```

React17以前はイベントリスナーがdocumentに登録されていたため、同じページに複数のReactが存在し、それぞれが同じ種類のイベント（例えば、クリックイベント）をリッスンしている場合、イベントが伝播して競合するケースがあった。

しかし、React17ではReactのルートコンテナにバインドされるため、競合する可能性が減少した。以下はReact公式ブログから引用した画像。

![react_17_delegation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733722/fa1cd0c6-7231-0e2d-f5c0-0b0e0f5b4881.png)

# 参考

https://ja.legacy.reactjs.org/blog/2020/10/20/react-v17.html

https://qiita.com/irico/items/1129cf233562a668670a#%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%AE%E9%9A%9B%E6%B0%97%E3%82%92%E3%81%A4%E3%81%91%E3%82%8B%E3%81%93%E3%81%A8

https://zenn.dev/yuu104/articles/js-react-event-delegation
FESSのインストール

<!--
2024/12/8
-->
[Windows][FESS]

## 準備（ファイルの入手）
* FESSのダウンロード
* opensearchのダウンロード
* JDKのダウンロード
## プラグインのインストール（オンライン）
* プラグインの入手
バージョンを合わせること
    ```powershell
    $OPENSEARCH_HOME\bin\opensearch-plugin install org.codelibs.opensearch:opensearch-analysis-fess:2.18.0
    $OPENSEARCH_HOME\bin\opensearch-plugin install org.codelibs.opensearch:opensearch-analysis-extension:2.18.0
    $OPENSEARCH_HOME\bin\opensearch-plugin install org.codelibs.opensearch:opensearch-minhash:2.18.0
    $OPENSEARCH_HOME\bin\opensearch-plugin install org.codelibs.opensearch:opensearch-configsync:2.18.0
    ```
* おすすめプラグイン
    ```powershell
    $OPENSEARCH_HOME\bin\opensearch-plugin install ingest-attachment
    $OPENSEARCH_HOME\bin\opensearch-plugin install analysis-kuromoji
    ```
## プラグインのインストール（オンライン）
* プラグインのダウンロード
[analysis-fess](https://repo1.maven.org/maven2/org/codelibs/opensearch/opensearch-analysis-fess/2.18.0/opensearch-analysis-fess-2.18.0.zip)
[analysis-extension](https://repo1.maven.org/maven2/org/codelibs/opensearch/opensearch-analysis-extension/2.18.0/opensearch-analysis-extension-2.18.0.zip)
[minhash](https://repo1.maven.org/maven2/org/codelibs/opensearch/opensearch-minhash/2.18.0/opensearch-minhash-2.18.0.zip)
[configsync](https://repo1.maven.org/maven2/org/codelibs/opensearch/opensearch-configsync/2.18.0/opensearch-configsync-2.18.0.zip)
* おすすめプラグインのダウンロード
[ingest-attachment](https://artifacts.opensearch.org/releases/plugins/ingest-attachment/2.18.0/ingest-attachment-2.18.0.zip)
[analysis-kuromoji](https://artifacts.opensearch.org/releases/plugins/analysis-kuromoji/2.18.0/analysis-kuromoji-2.18.0.zip)
* インストール
    ```powershell
    $OPENSEARCH_HOME\bin\opensearch-plugin install file:///C:/path/to/downloaded/plugin.zip
    ```

## 設定ファイルの編集
* Pathの区切りは￥マーク
ファイルに追記
パス末尾のスラッシュが必要だそう
    ```$OPENSEARCH_HOME/config/opensearch.yml 
    configsync.config_path: C:\opensearch-2.18.0\data\config\
    plugins.security.disabled: true
    ```
* Pathの区切りはスラッシュ
コメントアウトして、パスを記入
パス末尾のスラッシュが必要だそう
    ```$FESS_HOME/bin/fess.in.bat
    REM External opensearch cluster
    set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.search_engine.http_address=http://localhost:9200
    set FESS_JAVA_OPTS=%FESS_JAVA_OPTS% -Dfess.dictionary.path=C:/opensearch-2.18.0/data/config/
    ```
## 起動
* Opensearch.exeから起動
    ```powershell
    \opensearch-2.18.0\bin> .\opensearch.bat
    ```
* FESSの起動
    ```powershell
    \fess-14.18.0\bin> .\fess.bat
    ```
## インストール
* Opensearch.exeからインストール
    ```powershell
    \opensearch-2.18.0> .\opensearch-windows-install.bat
    ```
* FESSのインストール
    ```powershell
    \fess-14.18.0\bin> .\service.bat install
    \fess-14.18.0\bin> .\service.bat start
    ```
## ローカルファイルの検索準備
1. 管理者でログイン
2. 管理 -> クローラ -> ファイルシステム -> 新規追加
3. パスの入力
```file:/C:/Users/hogehoge/Desktop```
4. スケジュールから実行
## 停止
* FESSから止めること
## 参考サイト
https://fess.codelibs.org/ja/14.18/install/install.html

https://www.tdi.co.jp/miso/open-source-fess-search

https://note.com/umino_shachi/n/ndf62be6e7f86

https://github.com/orgs/codelibs/repositories?type=all&q=opensearch

* 以上です。
WPFのTextBoxの末尾が見切れる

# 僕だけ？
僕だけの仕打ちなのか分かりませんが、WPFのTextBox(1行)に範囲外に行くまで文字を打ち込んで矢印キーで追っかけていっても、末尾が見切れる(つまりカーソルが末尾に来ない)んですよね

# とりあえずの解決策
何故か分かりませんが、HorizontalScrollBarプロパティをAutoがVisibleにすると問題なく動作するので、その状態でテンプレートの方をいじります

TextBoxに紐づけるStyle(仮にTextBoxStyle1とします)と、その内部のScrollViewerに紐づけるStyle(ScrollViewerStyle1とします)を作成
テンプレートの編集からコピーしてやってください

TextBoxStyle1の内部から以下のScrollViewerタグを探し出してScrollViewerStyle1に紐づけます

```xml
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
                   これ →    <ScrollViewer Style="{DynamicResource ScrollViewerStyle1}" x:Name="PART_ContentHost"  Focusable="false" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden"/>
                        </Border>
```

次にScrollViewerStyle1のScrollBarにVisibility=Hiddenとします

```xml
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ScrollViewer}">
                        <Grid x:Name="Grid" Background="{TemplateBinding Background}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="10*"/>
                                <RowDefinition Height="1*"/>
                            </Grid.RowDefinitions>
                            <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
                            <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanHorizontallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" CanVerticallyScroll="False" Grid.Column="0" Content="{TemplateBinding Content}" CanContentScroll="{TemplateBinding CanContentScroll}" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
                            <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
               ここ →       <ScrollBar x:Name="PART_HorizontalScrollBar" Visibility="Hidden" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0"  Minimum="0" Orientation="Horizontal" Grid.Row="1" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
```

あとは該当のTextBoxにTextBoxStyle1を紐づければ何とかなります
【AWS re:Invent】EKSがさらに進化！Auto ModeでKubernetesクラスター管理を簡素化

## この記事で伝えたいこと（ポイント）

AWS re:Invent 2024 で、Amazon Elastic Kubernetes Service (EKS) に **EKS Auto Mode** が導入されました！この新機能により、Kubernetes の運用負荷を大幅に軽減し、開発者はアプリケーション開発に集中できます。

## はじめに

この記事では、Amazon EKS の新機能である **EKS Auto Mode** について解説します。EKS Auto Mode を使用することで、Kubernetes クラスターの管理を簡素化し、運用コストを削減できます。

## サービスの説明

Amazon EKS は、マネージド型の Kubernetes サービスです。Kubernetes クラスターの作成、管理、スケーリングを AWS が代行してくれるため、ユーザーは Kubernetes の運用に煩わされることなく、アプリケーションの開発に集中できます。

EKS Auto Mode は、EKS の新機能であり、Kubernetes クラスターの管理をさらに自動化するものです。Auto Mode では、AWS がコントロールプレーンの管理に加えて、ノードの管理も自動的に行います。これにより、ユーザーはノードの OS や Kubernetes バージョンのアップグレード、セキュリティパッチの適用などを気にする必要がなくなります。

### 補足：コントロールプレーン

Kubernetes クラスターの制御を行うコンポーネント群です。API サーバー、スケジューラー、コントローラーマネージャーなどが含まれます。EKS では、コントロールプレーンは AWS によって管理されます。

### 補足：ノード

Kubernetes クラスターを構成するワーカーマシンです。アプリケーションのコンテナが実行されます。EKS Auto Mode では、ノードの管理も AWS が自動的に行います。

## どんな時に利用できるか

EKS Auto Mode は、以下のようなユースケースで特に役立ちます。

* **Kubernetes の運用負荷を軽減したい**：ノードの管理を AWS に任せることで、運用負荷を大幅に軽減できます。
* **運用コストを削減したい**：ノードの管理を自動化することで、運用コストを削減できます。
* **アプリケーション開発に集中したい**：Kubernetes の運用に煩わされることなく、アプリケーション開発に集中できます。
* **セキュリティを強化したい**：AWS がセキュリティパッチの適用などを自動的に行うため、セキュリティを強化できます。

## どのリージョンで利用できるか

EKS自動モードは、AWS GovCloud (米国)と中国リージョンを除く、すべてのAWSリージョンで利用可能です。

Kubernetes 1.29以降で動作するEKSクラスターにおいて利用でき、初期費用や契約は不要です。
料金は、通常のEC2コストに加えて、コンピューティングリソースの管理費用が発生します。

## まとめ

Amazon EKS Auto Mode は、Kubernetes クラスターの管理を自動化し、運用負荷とコストを削減する画期的な機能です。EKS Auto Mode を使用することで、開発者はアプリケーション開発に集中し、ビジネス価値の創造に貢献できます。

## 参考文献

* [Amazon EKS が Auto Mode を発表](https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-eks-auto-mode/)
* [新しい Amazon EKS Auto Mode で Kubernetes クラスター管理を合理化](https://aws.amazon.com/jp/blogs/aws/streamline-kubernetes-cluster-management-with-new-amazon-eks-auto-mode/)

## おわり
【WordPress】カスタムHTMLを分割して表示する方法

WordPressを使っていると、
管理画面のエディターで書いたカスタムHTMLの内容を分割して、
それぞれ違うセクションに表示したい時がありました。

![スクリーンショット 2024-12-08 21.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/0e7c3a27-c029-acf5-01fb-99d1f2106339.png)



「```the_content()```は全部まとめて表示しちゃうから無理やんか。」

と思い込んでいたのですが

```get_the_content()```を使えばできることがわかりました。

思い込みはいけませんね。

## 方法

### 1.管理画面
まず、適当な投稿を作成し、カスタムHTMLを埋め込みましょう。

![スクリーンショット 2024-12-08 19.52.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/7b6d6ed6-6d6d-99e8-e1a2-2230f79c4104.png)

<br>

そして、コメントアウトで目印を残して、表示したい内容を分割します。

![スクリーンショット 2024-12-08 20.10.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/f553defc-9022-0714-bb45-b27cae7b64c6.png)


忘れずに保存しておきましょう。

<br>

### 2.php

まず、```get_the_content()```で投稿の生データを取得しましょう。

```index.php
$content = get_the_content();
```

<br>

次に、```preg_split()```でコメントアウトの目印を元にデータを分割しましょう。

```index.php
$content_parts = preg_split(
 '/<!--こっちだよ-->|<!--そっちじゃないよ、こっちだよ-->/', $content
 );
```
それぞれの目印の内容（😎と⭐️）が、配列の[1]と[2]に格納されます。

<br>

最後に、```$content_parts```に入れた内容をHTMLに埋め込みます。


```index.php
<!-- 「こっちだよ」の内容 -->
<section>
  <?php echo $content_parts[1]; ?>
</section>

<!-- 間に入れたいセクション -->
<section class="middle-section">
  <h2>間に入れたいセクション</h2>
</section>

<!-- 「そっちじゃないよ、こっちだよ」の内容 -->
<section>
  <?php echo $content_parts[2]; ?>
</section>
```

<br>

これで、カスタムHTMLの内容を分割して表示することができました。

![スクリーンショット 2024-12-08 21.19.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/20e26e5b-0bb3-ad6c-1d71-d53f2738a261.png)

<br>

全体のコード

```index.php
<?php
$content = get_the_content();

$content_parts = preg_split('/<!--こっちだよ-->|<!--そっちじゃないよ、こっちだよ-->/', $content);
?>


<!-- 「こっちだよ」の内容 -->
<section>
  <?php echo $content_parts[1]; ?>
</section>

<!-- 間に入れたいセクション -->
<section class="middle-section">
  <h2>間に入れたいセクション</h2>
</section>

<!-- 「そっちじゃないよ、こっちだよ」の内容 -->
<section>
  <?php echo $content_parts[2]; ?>
</section>

```

<br>

これが可能ということは、WordPressの投稿記事に書いた内容は、php側でいくらでも加工して表示できるということでしょうね。
タスクをこなすだけでなく、きちんとWordPressの仕組みを学ぶ必要があるなぁと感じた瞬間でした。

## 補足

### 配列の番号が[0]ではなく[1]からになっている点について
配列の番号が[1]と[2]になっているのは、[0]には空が入っていて、今回欲しい内容ではないからです。

```
Array
(
    [0] => ""
    [1] => "<p>😎</p>"
    [2] => "<p>⭐️</p>"
)
```

なぜ[0]が空になるかというと、```preg_split()```が最初に指定した目印が見つかる**前の内容を[0]に格納する**からです。

もし管理画面のカスタムHTMLで、最初のコメントアウトの前に何か書いた場合は、その内容が[0]に格納されます。

![スクリーンショット 2024-12-08 21.17.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/7af04e09-73b1-d11e-2a7a-9dd1722df9bc.png)



```
Array
(
    [0] => "ここは配列の[0]に格納される"
    [1] => "<p>😎</p>"
    [2] => "<p>⭐️</p>"
)
```
<br>

### the_content()とget_the_content()の違いについて
- ```the_content() ```
そのままHTML出力を行い、WordPressのフィルター（ショートコード展開や自動段落挿入）を適用します。そのため、投稿コンテンツを直接画面に表示したい場合に使います。

<br>

- ```get_the_content()```
「生のデータ」を取得するだけで出力しません。
そのため、分割して加工するには ```get_the_content()``` が適しています。
ただし、WordPressのフィルターが機能しないので、もしショートコードを使う場合は```apply_filters()```を使いましょう。

# 参考

https://school.t-spirits.com/wordpress-func/get_the_content/
2024年、毎月SoftwareDesign輪読＆座談会をやってきた振り返りなど

# はじめに

2024年9月2日に60回目(5年目)を向かえました。

https://softwaredesign.connpass.com/

毎月、月初の月曜日(祝日の場合は翌週の月曜日)に開催していますが、2024年11月は私の業務都合(出張)で月初の火曜日に開催したため、参加者にご迷惑おかけしました。(ｽﾐﾏｾﾝ

今年も執筆者(杉金さん、浦さん、ありがとうございました！)に参加してもらったり、参加者のオフィス(クラスメソッドさん、KINTOテクノロジーズさん、リクルートさん、サイバーソリューションズさん、ありがとうございました！)をお借りすることができ、楽しい思い出ができました。


# 過去の資料(2024年)

基本的に資料はすべて公開しています。
2024年の資料はこちらです。

https://connpass.com/event/304394/

https://connpass.com/event/307871/

https://connpass.com/event/309841/

https://connpass.com/event/313468/

https://connpass.com/event/315897/

https://connpass.com/event/319133/

https://connpass.com/event/321272/

https://connpass.com/event/324680/

https://connpass.com/event/327455/

https://connpass.com/event/329992/

https://connpass.com/event/334106/

https://connpass.com/event/336516/


# アドベントカレンダー

2023年に思いつきで始めましたが、2024年も引き続き開催しています。

https://qiita.com/advent-calendar/2023/softwaredesign

https://qiita.com/advent-calendar/2024/softwaredesign


# ふりかえり

個人的に思い出深いのは、SoftwareDesignを出版している技術評論社さんから商業本(<A HREF="https://gihyo.jp/book/2024/978-4-297-14592-7">図解即戦力 ITインフラのしくみと技術がこれ1冊でしっかりわかる教科書</A>(2024年11月9日発行))を出すことができたことです。
SoftwareDesignには寄稿したことがありませんでしたが、輪読＆座談会以外で商業本という形で貢献できてよかったです。

(2024年11月14日に編集者(鷹見氏、酒井氏)と執筆者(鶴長氏、山本氏、山根氏、北崎)で打ち上げをした時にサインした本)

![IMG_8307.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/bc9c1398-1b86-96dd-d101-3b5331c73279.jpeg)


# さいごに(来年に向けて)

次回は来年(2025年)、1月6日(月)に開催する予定です。
仕事初めの方も多く、新年会もあるかと思いますが、少しでも興味を持っていただけた方は、ぜひ参加してください！来年(2025年)も一緒に楽しく学びましょう！

https://softwaredesign.connpass.com/event/339202/

### 追伸(2024年12月18日)

年間購読を契約しました。

https://x.com/Zakkiea/status/1869165033130971408
re:Invent2024で気になるアップデートまとめ

こんにちは。

こちらは「Qiita Japan AWS Top Engineers Advent Calendar 2024」の12/8のブログになります。

AWS NEWSブログに載っているre:Invent2024の記事の中から個人的に気になったアップデートまとめになります。

https://aws.amazon.com/jp/blogs/aws/](https://aws.amazon.com/jp/blogs/aws/

## １. 新モデル「Amazon Nova」発表

https://aws.amazon.com/jp/blogs/aws/introducing-amazon-nova-frontier-intelligence-and-industry-leading-price-performance/

Amazon Bedrockで使えるモデルシリーズ「Amazon Nova」が発表されました。テキスト生成にMicro,Lite,Pro,Premier（現在利用不可）。画像生成にCanvas、ビデオ生成でReelがあります。

Amazon Nova ProとCloaude 3.5 Sonnetで簡単に比較してみましたが、生成までの時間が約2～3倍速かったです。明確に日本語対応と案内されていませんが、日本語も問題ないように見えました。

Amazon Bedrockでおそらく初めてのビデオ生成モデルになる「Amazon Nova Reel」も使ってみましたが、現在は最大6秒の動画を生成可能です。使用にあたっては動画ファイルの出力先としてS3バケットを指定する必要があります。

Reelで動画生成を試してみました。

https://x.com/i/status/1864011335350292544

## ２. Amazon Q Developerの運用調査機能

https://aws.amazon.com/jp/blogs/aws/investigate-and-remediate-operational-issues-with-amazon-q-developer/

Amazon Qに関していくつものアップデートがありましたが、こちらの機能はDevOpsの観点で開発で複雑になったシステムの運用改善に使えるのではないかと期待しています。機能開発とAWSのアップデートが重なって運用が複雑化する中で、専任の運用担当者がいるなら良いですが、工数の都合などで専任の担当者がいない場合に代わりに調査と改善提案をしてくれるのはありがたいです。この機能はAWSコンソールではAmazon Qの中ではなく、Cloud Watchに内包されているみたいですね。

https://x.com/stand_arrow/status/1864015486687842564

## ３. Amazon Q Developerエージェントでドキュメント生成、コードレビュー、ユニットテスト生成（プレビュー）

https://aws.amazon.com/jp/blogs/aws/new-amazon-q-developer-agent-capabilities-include-generating-documentation-code-reviews-and-unit-tests/

Amazon Q Developerの機能強化の認識です。以前から類似の事はできたと思いますが、コードから一括で複数のドキュメントを作成したり、ユニットテストのコードを自動で生成してテストエラーを自己デバックまでできるようです。開発者にとって強力なツールになりそうですが、一方で仕事が減る懸念もありますね。。。

## ４． AWS Bedrock Intelligent Prompt Routing（プレビュー）

https://aws.amazon.com/jp/blogs/aws/reduce-costs-and-latency-with-amazon-bedrock-intelligent-prompt-routing-and-prompt-caching-preview/

入力されたプロンプトに対して、最適なパフォーマンスを出すモデルを予測するしてくれる機能が発表されました。現状はClaudeモデルファミリーとLIamaモデルファミリーが対象です。どのモデルが良いか検証したいときに、当機能を使うのもモデルの選定方法の一つになりそうですね。Amazon Novaモデルファミリーも使えるようになってほしいです。

## ５．AWS Bedrock Knowledge Basesが構造化データをサポート

https://aws.amazon.com/jp/blogs/aws/new-amazon-bedrock-capabilities-enhance-data-processing-and-retrieval/

こちらのブログの一機能として発表されていますが構造化データをサポートしました。データストアにはAmazon Redshiftに保存されているデータが対象になっています。自然言語を適切なSQLクエリに自動生成してデータを取得してくれます。プロンプトでSQLクエリを生成する処理を開発する、RAGのためにRedshiftにあるデータをベクターデータベースにするといった開発やデータ整備が環境によっては不要になるので、今までより簡単にRAGを構築することができるようになるんじゃないでしょうか。

# 最後に

以上、まとめてみました。生成AI関連のアップデートばかりになりました。SageMakerやAmazon Q Businessのアップデートもありましたが、詳しくないためアップデートで何が良くなったのか分かり切っておらず外しました。勉強が必要ですね。

何かの参考になれば幸いです。
JSで作ったCLIツールをTS化する

プロもくチャットアドベントカレンダー9日目です!

https://qiita.com/advent-calendar/2024/puromoku

---

アドカレの6日目にJSでツールを作ったのですが、いい機会なのでTS化してみようと思います

https://qiita.com/babu-ch/items/5ee4e8f3342be123b1ea

# TypeScript

まずはtypescriptインストール
トライスパイルするのがめんどくらいのでts-nodeもいれます

https://qiita.com/mangano-ito/items/75e65071c9c482ddc335

```sh
npm i typescript ts-node
npx tsc --init
```

これでもう適当なtsファイル作って実行できます
```sh
npx ts-node main.ts
```

ついでに実行時の引数バリデーションのため、zodを入れました

```sh
npm i zod
```

このように定義して、違う値の場合エラーを発生してくれます

inferを使えば定義したschemaの型を使えるのアツい

```js
const schema = z.object({
  waitMs: z.number().positive(),
  pageToken: z.string(),
  maxPage: z.number().min(0),
  output: z.string().regex(/.+\.csv$/),
  fields: z.string().regex(/^(\w+:[\w.]+,?)+$/),
})

export type Config = {channelId:string; options:z.infer<typeof schema>}
```

・PR
https://github.com/babu-ch/youtube_csv/pull/1


# ついでにテストも導入

vitestを使います

```sh
npm i vitest
```

テストできるようにするため、結構書き換えました

最初テストしにくいコードだったんやなぁと実感

・PR 
https://github.com/babu-ch/youtube_csv/pull/2

・こまったとこ

vitestのmockを複数回設定すると最後に設定した値になる

`vi.hoisted`を使用することで解決した

https://github.com/vitest-dev/vitest/discussions/4124

```js
const channelApi = vi.hoisted(() => vi.fn())
const playlistApi = vi.hoisted(() => vi.fn())
vi.mock('googleapis', () => ({
  google: {
    youtube: () => {
      return {
        playlistItems: {
          list: playlistApi
        },
        channels: {
          list: channelApi
        }
      }
    }
  }
}))

// こんな感じでモックの値を設定
channelApi.mockReturnValue({ data: { items: [{contentDetails:{relatedPlaylists:{uploads:"playlistId"}}}] } })

```


# おわり

最初からTSでもよかったかもしれない

でも記事かけたのでよかったかもしれない
【技育CAMP2024】ハッカソン Vol.18に参加してみて

# ハッカソンに参加した理由
企業ではチーム開発が基本ということをよく耳にしますが、私は個人で開発することが多くチーム開発の経験が多くありません。
そのため、チーム開発で気をつけるべきことや新しい刺激を受けるため、初めて技育ハッカソンに参加しました。

### チームの作成物(未完成)
https://github.com/Kou-python/202412_supporterz_hackathon

- 目的
    - 関係値が浅い人とカラオケへ行った時に何を歌うかを相手に合わせて提案してくれるアプリ
- 機能
    - アプリ内でその場にいる人でグループを作成する
    - グループメンバーそれぞれの曲の履歴を共有する
    - どんな曲が欲しいか検索の欄に打ち込む
        - 例)盛り上がる
    - 曲をランキング形式で表示する

### ためになったこと
- チーム開発を経験できた
- gitの連携をすることができた
- SpotifyAPIを知れた
- 他のチームの作品から自分にはないようなアイディアをもらうことができた

### 反省点
- spotifyapiのログイン認証とアクセストークンを実装できなかったのが悔しい
- サーバー知識が全然足りないことがわかったので勉強する
- もっと細かく目標や現状報告をするべきだった
    - 誰が何をどこまで行なっているか把握しきれなかった
    - 口だけでなく、notionなどを使用して管理する

# 感想
ハッカソンを通じて、アイデアを議論し、仲間と協力しながら実際に形にしていく過程は、自分の創作意欲が大きく刺激されました。改めて「ものを作る楽しさ」を実感しました。今回のアプリのアイディアはとてもいいものだと思うので、現在作成している「入道雲サーチアプリ」の完成後、カラオケ向けのアプリを作成しようと思いました