OmniAICreator/Qiita-1.07M huggingface dataset:
【GPTプロンプト講座基礎編⑨】プロンプトエンジニアリングの実務応用と高度な事例

# §プロンプトエンジニアリング基礎編⑨

※本記事は執筆にあたり生成AIツールを使用している箇所があります
※プロンプトの基礎部分は生成AIで作成し、具体例や体験談を自分の視点で補完しています

こんにちは。ゆずかきです。
前回は、プロンプトエンジニアリングの実務応用や高度な応用事例をお話ししました。今回は、プロンプトエンジニアリングに取り組む中で 「よくある課題」 と、それをどう解決していくかを具体例を交えながら解説していきます。

実際にプロンプトを試してみると、「これ、どうもうまくいかないな…」って感じることが意外と多いんですよね。私も未だに苦労します。でも、失敗を乗り越えるたびに「もっと良いプロンプトが書けた！」と成長を実感できるものなんですね。

今回は、そんな「よくある課題」をいくつか取り上げてみます。

# §課題1: 曖昧なプロンプトで結果がぼんやりする

**よくあるケース**
一番多いケースが、「なんか期待した結果と違うな…」というケース。たとえば、こんなケースです。

- 私: 
「次の文章を要約してください。」
- AI: 
「以下が文章の要約です: 」

（以下に、ほぼ原文の長～い文章が出力される…）
いやいや、これ要約じゃなくてただのコピペやん！orz

**解決のヒント**
曖昧なプロンプトでは、AIが何を求められているのかを正確に理解できないことがあります。この場合、「**具体性**」を追加してプロンプトを改善するのがポイントです。
　
- 曖昧なプロンプト:
「次の文章を要約してください。」
→AIがどう回答すべきかわからず困る
　
- 改善したプロンプト:
「次の文章を100字以内で要約し、重要なキーワードを3つ挙げてください。」
→AIが回答方法の指針を得られる

　
**プロンプトに具体的な制約やフォーマットを加えることで、AIが適切な回答を返してくれる確率が大幅にアップします。**


# §課題2: 長すぎるプロンプトでAIが混乱する

**よくあるケース**
逆に、「あれも、これも」と情報を詰め込みすぎた結果、AIが混乱するパターンもあります。以前、ブログのタイトル案をお願いしたとき、こんなことがありました。

- 私: 
「次の記事のタイトルを考えてください。このブログはプロンプトエンジニアリングについてで、主に初心者向けの内容を扱い、具体的な事例や注意点を含む記事になります。また、読者はエンジニアやAIに興味のある人で…」
　
- 結果: 
AIから返ってきたのは単に「AIのプロンプトについての考察」という微妙なタイトル。なんか、欲しかったアイデアとは違う…
　
**解決のヒント**
プロンプトが長すぎると、AIが重要なポイントを見失い、平凡な出力になりがちです。この場合、プロンプトを「**分割**」するのが効果的です。

- 改善例:
「この記事の主なテーマを基にしたタイトル案を3つ考えてください。」
「次の記事のターゲット層は初心者です。初心者向けのキャッチーなタイトルにしてください。」

　
**シンプルな指示を分けて伝えることで、AIの処理能力を活かした出力を得られます。**

# §課題3: 期待と違うトーンやスタイル

**よくあるケース**
「もっとフレンドリーな文章で書いてほしい」とお願いしたのに、返ってきた文章が硬すぎてびっくりすることも。例えば…

- 私: 
「次のメールをフレンドリーなトーンで書き直してください。」
　
- AI: 
「拝啓、貴殿ますますご清栄のこととお慶び申し上げます。」
全然フレンドリーじゃない！なんなら堅苦しすぎる…。

**解決のヒント**
トーンやスタイルを調整したいときは、具体的な例を挙げるのが有効です。「こういう感じで書いてほしい」と具体例を提示することで、AIの応答を意図に近づけられます。

- 曖昧なプロンプト:
「次の文章をフレンドリーに書き直してください。」
　
- 改善したプロンプト:
「次の文章を、友達に話しかけるような口調で書き直してください。例えば、『こんにちは！今日は〇〇についてお話ししたいです。』のようなトーンです。」

　
**トーンやスタイルは抽象的になりがちなので、具体的に「どんな感じか」を例示するのがポイントです。**

# §課題4: バイアスや不正確な回答（今回の最重要項目）

**よくあるケース**
AIは学習データに基づいて回答するため、たまに偏ったり誤った情報を返すことがあります。たとえば、以前、「AIの歴史を要約してください」と依頼したところ、明らかに誤った情報が含まれていたことがありました。

**※このような「AIが嘘をつく」現象はハルシネーション（幻覚）と言います。**
　**ハルチネーションは怖い現象です。必ず工夫して避けるようにしましょう。**

**解決のヒント**
AIの回答は鵜呑みにせず、常に「根拠」を確認するクセをつけましょう。また、プロンプト内で「信頼性の高い情報を基に」と付け加えることで、より正確な回答を得られる可能性があります。
　
- 曖昧なプロンプト:
「AIの歴史を教えてください。」
　
- 改善したプロンプト:
「AIの歴史を、具体的な年号と信頼できるデータを基に要約してください。」
「**わからない場合は、ウェブ検索して正しい情報を出してください。**」
「**根拠を提示して答えてください**」
「**出典や参照元を仮定して回答してください**」

**AIの回答は補助的なものであることを忘れず、必要に応じて別途確認することが大切です。AIは万能ではないという意識は、AIと付き合うなら常に持つことが安全です。**

# §まとめ
プロンプトエンジニアリングを実践する中では、課題に直面するのは避けられません。でも、そこにこそ成長のチャンスがあります。曖昧なプロンプトを具体化したり、情報量を適切にコントロールしたりと、工夫を重ねることでAIをより効果的に使いこなせるようになります。
　
**🔑 この記事のポイントまとめ**
- **曖昧なプロンプト → 具体性を追加せよ。**
- **情報過多のプロンプト → 分割して指示を与えること。**
- **トーンやスタイルのズレ → 具体例を示して指示せよ。**
- **ハルシネーション対策（最重要！） → 根拠やステップを指定せよ。**
　

次回は、プロンプトエンジニアリングをより効率的に進めるための「デバッグのコツ」や「試行錯誤を楽しむためのアイデア」についてお話しします。プロンプトが思い通りに動かないとき、どうやって改善すれば良いのか、一緒に考えていきましょう！どうぞお楽しみに！

今回も、ご訪問ありがとうございました！
【Python】AlembicでDateTime型カラムをupdateした日時で更新する設定にする方法

# 概要
Pythonアプリで、SQLAlchemyとAlembicを利用してMySQLのDBを利用しています。
DateTime型のカラム`update_date`をレコード更新時の「現在時刻」にする方法を紹介します。

うまく認識されなかったケースもあったのでそちらも併せて記載します。

### 前提
db：mysql8.0
python：3.12
alembic：1.13.2
SQLAlchemy：2.0.3

デフォルト値を挿入時の現在時刻にする方法は以下の記事で紹介しました

https://qiita.com/Ryo-0131/items/08fc5da4ca1ef31444bf

# マイグレーションファイルに認識されなかった例
以下のようにモデルを定義したとします。

```py
class SampleTable(Base):
    __tablename__ = 'sample_table'
    id = Column(Integer, primary_key=True, autoincrement=True)
    created_at = Column(DateTime, nullable=False, server_default=func.now())
    update_date = Column(DateTime, nullable=False, server_default=func.now(), onupdate=func.now())
```

しかし、これで`alembic revision --autogenerate`を実行しても、マイグレーションファイルで「`onupdate=func.now()`」の部分が認識されませんでした。

`onupdate=func.now()`は、SQLAlchemyのモデル定義としては正しいオプションだと思うのですが、Alembicのマイグレーションファイルではこの情報を反映してくれないようです。

# マイグレーションファイルに認識された例
以下のようにモデル定義を変更しました。
SQL文の`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`をそのまま指定してあげる方法です。

```py
class SampleTable(Base):
    __tablename__ = 'sample_table'
    id = Column(Integer, primary_key=True, autoincrement=True)
    created_at = Column(DateTime, nullable=False, server_default=func.now())
    update_date = Column(DateTime, nullable=False, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
```

これで`alembic revision --autogenerate`を実行すると、マイグレーションファイルの`update_date`では、以下のようにSQLが認識されています。

```py
op.add_column('sample_table', sa.Column('update_date', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), nullable=False))
```

上記でマイグレートすると、期待通りに、レコード更新時の現在時刻が入るようになりました。

SQLAlchemyとAlembicを使う場合「上記の方法が一番好ましいのか？」はわかりませんが、これであればやりたいことは実現できました。
以上です！
米田の補題 #13圏の例　代数構造（モノイド、群）

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# 代数構造（モノイド、群）
いきなり数学的になります。いままで、圏のイメージを自然数の集合+加法にまかせてきました。まず、前提知識として、集合とはなにかです。集合はなんらかの要素（定義難しいです）からなり、どの要素も個性をもっていて、同じ要素かどうかが識別できます。そして、ある集合の要素（元とよびましょう）は、その集合に属するかどうかが判定できます。これが集合の定義ですね
自然数だけなら単なる集合ですが、ここに加法という演算をつけくわえると、代数構造をもちます。演算は、集合Mから、２つの順序ある対(A,B)を選びそれをなんらかの値Xをわりあてます。それで、演算の視点から、代数構造をみてみましょう。演算は∘で表現します。条件も　A∘B = X ∈ M　が基本です。だんだんと条件をきつくしていきます。
- マグマ　(a,b)の結果x は、集合Mに含まれる　　射でいう合成ですね。
- 半群　演算は結合則を満たしている (A∘B)∘C =  A∘(B∘C)
- モノイド　くわえて単位元Eがあります。A∘E = E∘A =A
- 群　逆元A(-1)がどの元に対しても存在する　A(-1)∘A = A∘A(-1) = E
- (以下略）

モノイドは日本語で単系といいます。自然数 + 加法は　モノイド　単系です。モノイドの中身は、圏の定義を満たしていますが、それでは射が対象間に一つしかありません。ここでは説明しませんが射は数学的に複数あったほうがいいので対象をモノイドそのものとして、一つにしてしまいます。同じ図ですがこんなかんじです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/738918c1-dd40-fabe-db3c-06531daf2df6.png)
モノイドは、対象ひとつの素朴な代数構造で圏論で好んで使われています。逆元導入して、群にしたり、いろいろ条件をつけていきます。マグマや半群も対象にすることは可能ですが、あまりに素朴で数学的には面白くないのです。よくわからないけど、そうなんだとここまでのところは鵜呑みにしてください。この図を記憶にとどめておいてもらうと鵜呑みしやすくなるでしょう。

**米田の補題川柳　図式ならモノイドすぐにおぼえるぞ**
文章ではなかなか暗記できないのですが、図式だとすぐに暗記できますね。私達が矢印をつかうのは図式だと直感的に理解でき、すぐに暗記できるからです。でもよく使うのは単純な A -> B ばかりです。少し複雑な矢印を使うと時代になってもいいのではないでしょうか？
[Rust]TypeScriptと比較してRustの文法をおさらいする②

## if文

### TypeScriptの場合
TypeScriptでは`if`を使って条件分岐を実現します。複数条件を扱う場合は`else if`や`else`を組み合わせます。

条件に従って値を導きたいときは三項演算子を使います。

```typescript
const value = 10;
if (value > 10) {
  console.log("Greater than 10");
} else if (value === 10) {
  console.log("Equal to 10");
} else {
  console.log("Less than 10");
}

let result = value > 10 ? "Greater than 10" : "10 or less";
```

### Rustの場合
Rustでも`if`を使いますが、式として値を返すことができます。

```rust
let value = 10;
if value > 10 {
    println!("Greater than 10");
} else if value == 10 {
    println!("Equal to 10");
} else {
    println!("Less than 10");
}

// 式として使用
let result = if value > 10 {
    "Greater than 10"
} else {
    "10 or less"
};
println!("{}", result);
```

## while, for文

### TypeScriptの場合
TypeScriptでは`while`や`for`を使ってループ処理を記述します。

```typescript
// whileループ
let count = 0;
while (count < 5) {
  console.log(count);
  count++;
}

// forループ
for (let i = 0; i < 5; i++) {
  console.log(i);
}
```

### Rustの場合
Rustでも`while`や`for`を使えます。特に`for`はイテレータを利用した表現が特徴的です。

```rust
// whileループ
let mut count = 0;
while count < 5 {
    println!("{}", count);
    count += 1;
}

// forループ
for i in 0..5 { // 0から4までの範囲
    println!("{}", i);
}
```

## オブジェクト指向プログラミング

### TypeScriptの場合
TypeScriptでは`class`を使ってクラスを定義し、プロパティやメソッドを記述します。

```typescript
class User {
  id: number;
  name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }

  greet(): string {
    return `Hello, ${this.name}!`;
  }
}

const user = new User(1, "Alice");
console.log(user.greet());
```

### Rustの場合
Rustでは`struct`と`impl`ブロックを組み合わせて、オブジェクト指向的なプログラミングを実現します。

```rust
struct User {
    id: u32,
    name: String,
}

impl User {
    fn new(id: u32, name: &str) -> User {
        User {
            id,
            name: String::from(name),
        }
    }

    fn greet(&self) -> String {
        format!("Hello, {}!", self.name)
    }
}

let user = User::new(1, "Alice");
println!("{}", user.greet());
```

:::note
Rustの`impl`は非常に強力で、構造体だけでなく、列挙型にも実装でき、トレイトと組み合わせることができます。
:::

## エラーハンドリング

### TypeScriptの場合

TypeScriptでは`try-catch`構文を使ってエラーハンドリングを行います。

```ts
function divide(a: number, b: number): number {
  if (b === 0) {
    throw new Error("Division by zero");
  }
  return a / b;
}

try {
  console.log(divide(10, 2)); // 5
  console.log(divide(10, 0)); // Error
} catch (error) {
  console.error(error.message);
}
```

### Rustの場合

Rustでは`Result`型を使用してエラーを表現し、安全に処理します。

```rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("Division by zero"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 2.0) {
        Ok(result) => println!("Result: {}", result),
        Err(err) => println!("Error: {}", err),
    }

    match divide(10.0, 0.0) {
        Ok(result) => println!("Result: {}", result),
        Err(err) => println!("Error: {}", err),
    }
}
```
エラー(バグ)埋め込み法の解き方

苦手な計算問題の解き方を記録しておきます！

１．問題
ソフトウェアの開発者が20個のバグを埋め込んだ。
テスト担当者が15個バグを発見し、報告した。
15個のうち、埋め込んでいたバグは5個含まれていた。
残存すると推定されるバグは何個か？ただし、埋め込んだバグの発見率とソフトウェアのバグの発見数は比例するものとする。


２．解き方
まず、テスト担当者が見つけたバグ数に対し、埋め込みバグが含まれている割合を計算する。

>ソフトウェアの開発者が20個のバグを埋め込んだ。
テスト担当者が15個バグを発見し、報告した。
15個のうち、埋め込んでいたバグは5個含まれていた。

15個のうち、埋め込みバグが5個
　→埋め込んだバグ発見率は、5/20 = 0.25　

>残存するバグは何個か？

テスト担当者が見つけたバグ数に対し、本物は10個含まれていた。
全体の推定バグ数は、 10 / 0.25 = 40　個。
【AWS SCS対策】個人的にややこしいセキュリティサービス三人組を連れてきたぞ！

# はじめに
:::note warn
タイトルでふざけておりますが、この先にネタ要素はありません。
また、今回は「AWS SCSを学び始める」方向けの記事であるため、
ある程度セキュリティサービスについて把握されている方は、
このページを閉じた方がいいかもしれません。
:::


AWS Certified Security - Specialtyを受けてきたのですが、インプットに苦しんだサービスが3つほどあるので、紹介と覚え方を記そうと思います。

**この記事では、該当サービスの「詳細な説明・使い方手順」は紹介しておりません**

サービスを詳しく知る前に「こんな感じのサービスなんだな」というイメージを持ってもらうことで、後の詳細なサービスの説明がスッと入るといいな、と願って書いた記事です。


:::note info
サービスに関する詳しい説明をお求めの方は、
「AWS BlackBelt(サービス別資料)」がおススメです。
AWS社員の方が、各サービスに応じて詳細に説明をしてくれています。「日本語」かつ「見やすい・わかりやすい」スライドを作成してくださっているので、AWS認定の対策にも活用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669759/8f6fdd94-6362-5260-799f-c0e6eb8c3630.png)
(AWS Black Belt リンク)
https://aws.amazon.com/jp/events/aws-event-resource/archive/?cards.sort-by=item.additionalFields.SortDate&cards.sort-order=desc&awsf.tech-category=*all
:::

**今回は以下の三人組についての紹介です**

**・Amazon GuardDuty**
**・Amazon Inspector**
**・Amazon Detective**



# 先に図にしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669759/45cdbaaa-8d0a-6907-a76e-481fc7640d75.png)
(事件 ＝ セキュリティインシデント)

今回は時系列で捉えれば飲み込みやすいと考えました。

「事件前」に活躍するInspectorは、事件が起きないように怪しいところを探し続け、「事件中」に活躍するGuardDutyは、脆弱性を突かれて起きた事件に対処し、「事件後」に活躍するDetectiveは、事件が起きた根本的な原因を迅速・効率的に調査します。

次の章ではAWS公式の記事を引用しつつ、一つずつ軽く説明していきます。

# それぞれの役割

### Amazon Inspector ##
>Amazon Inspector は、Amazon EC2 インスタンス、コンテナ、Lambda 関数などのワークロードを自動的に検出し、ソフトウェアの脆弱性や意図しないネットワークの露出がないかをスキャンします。
(引用元：https://aws.amazon.com/jp/inspector/?nc=sn&loc=0 )

上記の文にあるようにAmazon Inspectorは、ワークロードをスキャンすることで、ソフトウェアの脆弱性・ネットワークの露出がないかを確認してくれます。

**イメージしやすいように言うと**

**「事件が起きないように監視してくれています」**

外部からアクセスが可能な状態になっていることや、サービスやアカウントが悪用される可能性を特定し、「これ..事件起きそうじゃない..？」と教えてくれます。

### Amazon GuardDuty ###
>インテリジェントな脅威検出を使用して、AWS アカウント、ワークロード、データを保護します
(引用元：https://aws.amazon.com/jp/guardduty/)

Inspectorの説明を読んだ後だと、私がGuardDutyの何に着目するか予想できるかもしれませんが、

**そうです！　「事件が起きた」時にGuardDutyは動きます！**

事件が起こると、事前に設定しておいたEventBridgeやLambdaを用いて、問題に自動で対処してくれます。また、SNSで通知をすることも可能です。

つまり、このGuardDutyは脆弱性を特定するのではなく、「悪意を持って脆弱性を狙った攻撃を特定・対処」するのに向いています。

## Amazon Detective ##
>Amazon Detective を使用すると、セキュリティに関する検出結果や疑わしいアクティビティの根本原因を分析、調査、および迅速に特定できます。Detective は、 AWS リソースからログデータを自動的に収集します。その後、機械学習、統計分析、グラフ理論を使用して、セキュリティ調査をより迅速かつ効率的に行うのに役立つビジュアライゼーションを生成します。Detective の事前に作成されたデータの集計、要約、およびコンテキストは、考えられるセキュリティ問題の性質と範囲を迅速に分析および特定するのに役立ちます。
(引用元：https://docs.aws.amazon.com/ja_jp/detective/latest/userguide/what-is-detective.html#detective-features)

最後に紹介するDetectiveは、やはり「事件が起きた後」に活躍するサービスです。事件が起こった後は、事件が起きた原因を突き止め、再発防止に努めることが重要であり、それを迅速かつ効率的におこなうのがDetectiveの役割です。

# あとがき
今回は、個人的にややこしいセキュリティサービス三人組を連れてきました。
個人的な話になってしまうのですが、セキュリティのインプットの際、MacieやWAF、Shieldは、「こういう役割なんだな！」と(キーワード等で)認識できるのですが、今回紹介した三人組はあまりパッと役割が出てきませんでした..。


この記事が誰かの役に立つことを願います。
（AWS SCSは受かりました)
Chat Completions APIのハンズオンをやった際のメモ的なもの

# はじめに

この記事は JSL (日本システム技研) Advent Calendar 2024 - Qiita 5日目の記事です。

当社はDjango等を使用したWebアプリケーション開発を主体としていますが、LLM案件の問い合わせも多くなってきたので、「[LangChainとLangGraphによるRAG・AIエージェント［実践］入門 ](https://gihyo.jp/book/2024/978-4-297-14530-9)」という書籍を購入しました。
今回は、その中にあったハンズオンをしつつ気付いたことをメモ的に記事にしました。


## 環境：
- macOS 12.6 Apple M1 Pro
- Google Colab 

## 前準備
OpenAIのAPIキーを取得します。
こちらの説明は割愛します。

## Chat Completions APIの呼び出し

APIとのやり取り時は、`role（役割）`とそれに付随する`content(本文)`を
セットで渡します。
`role`は、`system（エージェントの事前設定？)`、`user（利用者)`、`agent（エージェント)`があるようです。

```py
import os
from openai import OpenAI
from google.colab import userdata

os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages = [
        { "role": "system", "content": "You are a helpful assistant."},
        { "role": "user", "content": "こんにちは！私はジョンと言います！"},
    ]
)
print(response)
```

レスポンスが分かり難かったので、ChatGPTからのメッセージのみを抽出してみました。

```py
#print(response)↓
print(response.choices[0].message.content)
```

```
こんにちは、ジョンさん！お会いできてうれしいです。今日はどんなことをお話ししましょうか？
```

## 会話履歴を踏まえた応答を得る

APIでは会話履歴を保存する機能は無いため、自前で履歴を渡してあげる必要があります。

```py
import os,json
from openai import OpenAI
from google.colab import userdata

os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages = [
        { "role": "system", "content": "You are a helpful assistant."},
        { "role": "user", "content": "こんにちは！私はジョンと言います！"},
        { "role": "assistant", "content": "こんにちは、ジョンさん！お会いできてうれしいです。今日はどんなことをお話ししましょうか？"},
        { "role": "user", "content": "私の名前が分かりますか？"},
    ]
)
print(response.choices[0].message.content)
```

```
はい、あなたの名前はジョンさんです。何か他にお話ししたいことや質問がありますか？
```

## JSON形式でレスポンスを得る

事前に返して欲しいJSONフォーマットを指定してあげるとJSON形式でレスポンスを得ることが出来ます。ハンズオンのものより少し入力値を変えてみました。

```py
import os,json
from openai import OpenAI
from google.colab import userdata

os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages = [
        {
            "role": "system",
            "content": '人物一覧を日本語で次のJSON形式で出力してください。\n{"people":["aaa","bbb"]}'
         },
        {
            "role": "user",
            "content": "昔々あるところにおじいさんとおばあさん、grandchildがいました。"
         },
    ],
    response_format={"type":"json_object"},
)

print(response.choices[0].message.content)
```

```
{"people":["おじいさん","おばあさん","孫"]}
```

# 感想

- Chat Completions API仕様は意外とシンプルで分かりやすかったです。
- 会話履歴は自前で管理しないと駄目ということを知りました。今後の開発時に考慮しておきたいと思います。
- Google Colabの補完機能に助けられたため、コーディングが捗りました。

- 今後は、`Function calling`を試したいです。
業務効率化×プログラミング~GASのプログラミング実践~

１.本日の気づき
・GAS最高に楽しい！！！
・
2. 難しかったこと・悩んだこと 
・function{}の中にfuntionを入れていたが、違っていたことに気づきがあった
・
3.その他、考えたこと 
・全てを上書きして貼り付けること。
function hello1() {
  Browser.msgBox("Hello World!");
}
・前回はできなかったことが今回はできたことに感激！！！
・https://gyazo.com/8c0dea32a823df742cdef67a5812c775
・https://gyazo.com/a595e701476d9d7dba9a28c20a5301f5
MBTI ？ストレングスファインダー？いや、ポケモン診断でしょ！ 性格診断と合わせて使えるワークショップ例

巷には様々な性格診断が溢れています。
企業によっては性格診断を必須とし、それをマネージャー層は評価やマネジメントに活用するという場面もあります。
モノによっては有料で診断してくれるものもあるくらい割とメジャーな人材育成の基盤になるのが性格診断です。

しかしながら、突然INFPやESTPと言われてもどう対処していけばピンと来ないこともあるでしょう。
日本人ならもっと馴染み深く、可愛くて覚えやすいキャラクターモノの診断があればいいよなぁと思いますよね。

あるんです！

それが __ポケモン自己分析！！__

https://recruit.pokemon.co.jp/pokemoncenter/special/

と、自信満々に説明しようとおもいましたが、まさかの2023/12/21にサービス終了！
早々に書くことがなくなりました。
しょうがないのでマネージャー層がチームのワークショップとして使えそうな（飲み会内のコミュニケーションとしても使える）ものを紹介したいと思います


## 価値観ワーク（Values Alignment Workshop）

チームメンバーが個々に重要視する価値観を共有し、チーム全体の「共通の価値観」を見つけるワークショップです。
こちらはオンラインで簡単にできるツールがあるので、すぐにでも実践可能です！

https://values-card.wevox.io/signin

主な流れはこんな感じ。トランプみたいに、不要な価値観を捨てていけば、手元に残った価値観が自分というやつです。

1. 価値観リスト（例: 信頼、イノベーション、スピード、安定性など）を配布
2. 各自、最も大切だと思う価値を3～5個選ぶ
3. 小グループで選んだ価値について議論し、なぜそれを選んだか説明
4. チーム全体で「共通する価値観」を選び、それをもとに行動指針を作成


## チームキャンバス（Team Canvas Workshop）

チームの目標、役割、価値観、ルールなどをキャンバス形式で整理し、チーム全体の方向性を一致させるワークショップです。Miroや物理的な付箋を使って実施します。
個人的にはリモートではなくリアルに集まって実施するほうがワイワイ感が出ておすすめです。

英語ですがMiroのチームキャンバステンプレートはあります。

https://miro.com/templates/the-team-canvas/


ステップ:
1. ホワイトボードまたはオンラインツール（MiroやMURAL）に「Team Canvas」のテンプレートを用意
2. 以下の項目を記入しながら議論:
  - チームのミッション
  - 各自の役割と責任
  - 共通の価値観
  - コミュニケーションルール
  - 潜在的な課題やリスク
3. 参加者全員が内容に合意できるまで調整

目に付く役割分担ができますが、大事なのはここに書かれていない「こぼれ球タスク」をどうするかという点です。
そういうところも拾えるようにファシリテーションする能力がマネージャーには求められますのでちょっと難易度高い気がします。

## ストーリーテリングワークショップ

各メンバーが過去の成功体験や失敗体験を共有し、それをもとにチームの価値観や学びを深めるワークショップです。
個人的にはこの内容を発展させた「Win-session（ウィンセッション）」もおすすめです。Win-sessionはOKRのフレームワークの1つですが、OKRをやっていなくてもこの儀式だけをやることでチーム全体・個人の仕事に対するモチベと成果の可視化をすることができます。
特に地味で目立たない仕事（バグをひたすら潰す人、特定の開発のしにくさ・技術的負債を解消する人、CI/CDによる自動化で効率化してる人など）の成果を別部署や上長にアピールする手段としてはかなり使えるのではないかと思います。

1.「仕事で最も誇らしかった瞬間」と「大きな挑戦だった瞬間」を事前に考えてきてもらう
2. 各自が順番にストーリーを語る（5分程度）
3. チーム全体でそれぞれの話から学んだ教訓や価値観を議論
4. 共通するテーマを見つけ、それをチーム文化に取り入れる

## コミュニケーションスタイル診断ワークショップ

チーム内でのコミュニケーションスタイルを診断し、それに応じたフィードバックや会話の仕方を学ぶワークショップです。今回のようにポケモンやMBTIなどの性格診断を事前に行ったうえでディスカッションする必要があるので、ワークショップとしては2段階構成とかにするとよいかもしれません。

1. 診断ツール（例: DISC、MBTIなど）を事前に実施
2. 診断結果を共有し、各自のコミュニケーションスタイルについて自己紹介
3. 小グループで「どのスタイルでコミュニケーションを取るとスムーズか」をディスカッション
4. チーム全体で「お互いに気を付けるポイント」をリスト化

## サイレントブレインストーミング

発言しづらいメンバーも含め、全員がアイデアを出しやすい環境を作るためのブレインストーミング形式で実施するものです。これは非同期でできるので、例えばスプリントの終わりに振り返るとか、プロジェクトの終わりに振り返るなどの区切りに向けて、いつでも気になったことを書き込めるドキュメントやボード（Notion、Miroなど）を準備しておくと良いでしょう。

1. 「解決したい課題」をホワイトボードまたはオンラインツールに記載
2. 各自、10分間で自分のアイデアをポストイットまたはデジタル付箋に書き出す
3. 集めたアイデアを分類し、優先順位を議論
4. 採用したアイデアに基づいて次のアクションを決定

後述するレトロスペクティブの部分的なワークショップという感じですね。


## プロジェクト振り返りワークショップ（Retrospective）

アジャイル開発の振り返り手法を活用し、過去のプロジェクトやスプリントの成果と課題を議論するやつです。多分やったことのある方も多いのではないかと思います。

1. ホワイトボードまたはオンラインツールで以下のカテゴリを設定:
  - よかったこと(Keep)
  - 改善が必要なこと(Problem)
  - 今後試したいこと(Try)
2. 各自の意見を付箋に書き出し、カテゴリーに貼り付ける
3. 全体で内容を共有し、優先順位をつけて具体的な改善アクションを決定

カテゴリについては上述のKPT以外にも、YWT(やったこと、わかったこと、次にやること）などもあります。
またサイレントブレインストーミングとしてカテゴリ内に意見書き出しを事前にやってもらうことで、当日のレトロスペクティブの時間を投票と議論の時間にすることができます。

## 心理的安全性ワークショップ

チーム内の心理的安全性を高めるために、相互理解や信頼構築を目的としたワークショップです。
私は取り組んだことがないので、どういう物があるかは以下の記事を参考にしてください。

https://media.unipos.me/psychological-safety-game


来年もよりよいピープルマネジメントができるよう、ワークショップにも取り組んで行きましょう。
一見良さそうで「危険」なプロダクト開発のあるある問題3選

## あるある問題
プロダクト開発の過程で起こる、上手くいってそうなのに停滞が起こる原因について3つ挙げました。

:::note
1. 全部のせマシマシ問題
1. 「いいね」と言われる問題
1. 担当者と仲が良い問題
:::

## 全部のせマシマシ問題

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/b9aad21e-a427-fd28-9790-6392aea938b8.png">

ここでは**色々な機能を盛り込んだ多機能のプロダクト**を指します。それ自体は悪いことのように見えませんが、2つの落とし穴があります。

### 1. ちゃんと考えていないかもしれない
多機能になっている背景には、ユーザーが最も解決したい課題への深堀が十分できておらず、結果的に、**何かの役に立ちそうで何の役にも立たないプロダクトになっている**可能性があります。

:::note 
#### 対策
**ユーザーのニーズを深堀する**
:::

### 2. ユーザーの学習コストが高い
機能を使いこなすためにユーザーは長い時間をかけなくてはいけません。また、もしユーザーの特定の課題を解決するために多機能になっている場合、代替案が現れるリスクを考える必要があります。

:::note 
#### 対策
- **プロダクトを分ける**ことを検討する
- **技術を見直す**
:::

## 「いいね」と言われる問題

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/d95d24f0-971b-1564-3c9a-22637aa2c0bd.png">

時間をかけてつくったプロダクトに対して「いいね」とフィードバックをもらえるのは嬉しいことですが、それではいけない場合があります。

### 1. 欲しいとまでいかない
ユーザーや協業先から「導入したい」「どうやったら手に入るのか」などといった言葉は聞けない事態に陥ってしまうことがあります。もし、「いいね」が本当に良いと言ってくれているのなら、プロダクトが解決する課題が**ユーザーにとっては実は重要ではない、あるいは緊急ではない**可能性があります。

:::note 
#### 対策
「**必要か不要か**」の情報を得る
:::

### 2. 関係的にそう言わざるを得ない
アンケートの取り方や提案先の企業との関係、担当者間の年代が離れているなど、前提となる関係性によっては「良い」と言わざるを得ない可能性があります。つまり社交辞令です。

:::note 
#### 対策
**上記 1 と同じ**
:::

## 担当者と仲が良い問題

<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/94077b58-e709-5606-ec8f-f558b2fe4f0e.png">

### ステークホルダーまで届かない
提案先の担当者、協力している大学の先生などからはフィードバックももらえるし、それに対応してプロダクトを磨いてはいます。しかし、彼らからの期待が高いにもかかわらず、中々その先に進まないことがあります。

彼らのフィードバックは有益ですが、ステークホルダーの望む視点が入っていないため収益化できるプロダクトになっていない可能性があります。

:::note 
#### 対策
「**本番稼働するなら何が必要か**」のやり取りをする
:::

## まとめ
これは私も経験したことがある失敗です。もちろん、**「いいね」と言ってもらえること**、**担当者と仲が良い**という状態は望ましいことです。
しかし、もし**上手くいってそうなのにプロダクト開発が前進していない**ということがあれば、ぜひ参考にしてみてください！
転職活動中にやっておくべきだったこと

# はじめに

アドベントカレンダーも終盤となりました。

この記事では今年転機となった転職活動において、やっておけば良かったことをかんたんにまとめてみました。
これから転職活動される方、現在している方のお役立てになれば幸いです。


# 自分で何かつくる

よく聞かれる、「入社してやりたいこと」「今後のキャリア」に対して、ペラペラ話すのは良いものの、「今何やっていることはありますか？」と返されたときに困りました。

本当にやりたいことならもう自分でやっているよね、と思うのが普通かと思います。
(私の場合は諸事情で活動中にPCの購入ができませんでした)

何でもいいので自分でもある程度やっていることをアピールできると好印象です。

私の場合は以下のようなことをやっておけば良かったと後悔しています👇

https://qiita.com/does_not_exist/items/d3432713e0cde4b7d270

# 気になる企業はすぐに選考を受けない（面接に慣れてから受けることをおすすめします）

私の場合は、オファーもらって気になった企業はカジュアル面談を受け、選考案内がきたらすぐに選考に進んでいました。
活動初期の頃は面接の準備も出来上がっていない状態でしたので、意図とズレた回答をしたり、そもそも答えられないこともしばしばありました。

せっかく気に入った企業なのに、準備不足でお祈りされるのはもったいないです。

# カジュアル面談で現場の人と期待値調整をする
活動の後半でやり始めましたが、早い段階でミスマッチを発見できるので個人的におすすめです。
可能であればカジュアル面談に現場の人も同席してもらえないか相談してみましょう。
カジュアル面談で企業側は深い質問をしてこないことが多いですが、こちらからする分には問題ないと思います。
~~私はガンガン質問していました。2、3回の面接で内定決めないといけないの時間が無さすぎます~~

# おわりに
一方的に質問すると自己中心的な印象を与えかねないので、会話ベースで自分の考えや体験をもとに質問できると自然な感じが出ると思います。
~~だから時間が足りない:sweat:~~
転職活動はチーム戦！チームメンバーと進捗共有！？

# おわりに

同じ志をもつ人と活動を行うことで多くのメリットがありましたのでかんたんにまとめておきたいと思います。


# みんなで転職サービスに登録

とある日、チームメンバーの一人からこんな提案がありました。

「実は転職ドラフトというサービスに登録したんですが、みなさんもやってみませんか？」
「野球のドラフトみたいに年収掲示ありでオファーがきますよ」


それを聞いた私や他のメンバーは興味津々でした。

「まずはレジュメ（職務経歴書）などを書いて審査に通る必要があるので頑張ってください！」

# オファーがきた会社や金額の話題で持ちきりに

「今回は年収〇〇のオファーがきました！高めでびっくりです」

「オファーきた会社、〇〇系の事業やってるんですよね、面白そうなのでカジュアル面談受けてきます！」

# しばらくするとカジュアル面談や選考内容の情報共有会に

「ここ、基本ペアプロやってて毎週ペア変えてるみたいなんですよ」

「次で最終面接なんですが、〇〇さんが受けた会社ではどんな感じの質問きました？」

「ここの技術課題結構難しくて、苦戦してるんですよね。期待値高めで見られてますかね」

「この会社こういう福利厚生あるみたいで、びっくりしました。面白いですよね」

「この間の2次面接落ちちゃいました。 合わなかったのかもしれないですね」

「内定もらいました！」

# 良かった点
- 気軽に相談できる相手がいると精神的に楽
- 自分が受けていない業界や会社の情報も知ることができる
- 自分の選考内容が特殊なのか判断できる
- 内定もらったら祝ってくれる

# 注意点
- センシティブな情報なので、無理に聞こうとはしないのが吉です


# おわりに

チームで活動していなければもしかしたら転職成功していなかったかもしれません。
メンバーに感謝です。
非エンジニアが開発オンボーディングに参加してみた -デザインクリティーク編-

こんにちは、ふるすです。
こちらの記事で弊社のオンボーディングについてまとめましたが、今日はその中の「デザインクリティーク」について体験記を書いていきます！

https://qiita.com/furusu_y/items/831ff2706b89d202cf3a

## デザインクリティークとは？

このワード自体、私にとって耳慣れないものだったのですが、「Critique：批評」という言葉のとおり、制作した課題をレビュワーに評論してもらうのかな？と考えていました。
デザインチームのアンナさんが書かれたデザインクリティークの記事はこちら。

https://qiita.com/annafuru/items/d14817d090e414ad34cb

>デザインクリティークとはアウトプットについてのフィードバックを集めるための会議のことです。

とのこと。

## どんなものを作ったか

**課題1：名刺を改善してみよう**
![スクリーンショット 2024-12-24 210421.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827898/6baaa230-6fcb-aef5-cf04-c673a6f79973.png)

Ｚの流れで情報をキャッチできるような構成にしてみました。
できあがったものを見ると現行の弊社名刺と似たようなデザインになりました。


**課題2：ポスターを改善してみよう**
![スクリーンショット 2024-12-24 210453.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827898/45050b16-73a3-00e8-8696-b9224d778509.png)


作っていて一番楽しかったのがこちら。地図作りを無駄に凝ってしまいました…。
考えるのが難しかったポイントはキービジュアルをどう扱えばいいのか？というところ。

>【サイズ】B2~B1
【掲示場所】最寄り駅やオフィスビルの商業エリア
【メインターゲット】同じビルまたは近隣のオフィスで働く20-30代の男女
【その他要件】
・少し高めの価格帯で、1人～少人数の利用者向けに落ち着いたイメージを押し出したい
・イラスト素材はキービジュアルとして外注にて制作したもの

ということだったのですが、どうしてもこのイメージ画像を使って落ち着いた雰囲気にすることができず、最終的にはものすごくサイズを小さくして上部に配置することにしました。
外注にて制作したもの、という前提だったのでなくすのもどうかなぁということで無理やり使うことにしましたが、仕上がりがイメージと乖離することのないよう、実際にはしっかり外注先とやりとりをすることが必要なんだろうなと感じました。
　　

**課題3：ダイアログのメッセージとボタンのラベルを改善してみよう**
![スクリーンショット 2024-12-24 210526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827898/23065b5f-c306-7e92-1f95-5acc8a3a6c99.png)

この題材はとても学びが多かったです。
何を目的とするか、重要視するかで配置・色・順番が変わるというのは非常に興味深かったです。
私の場合は誤ってキャンセルをしてしまうことで無用なトラブルを避けたい、という思いでこのような構成にしましたが、サービス内容や作り手の方針で大きく変わりそうです。
ECサイトなどを利用するときにこういったダイアログが出てくると気にするようになりました。

## 感想、振り返り
・デザインはコミュニケーションだなぁと改めて感じた
・デザインについて考えるのはとても楽しいなと感じたし、もっと勉強したい
・デザインを本業としなくても、デザイン思考はどんな仕事でも活かせるし誰でも積極的に学んだ方がよいと感じた

ここまでお読みいただきありがとうございました！
25日間のまとめ -OpenChain Japan Advent Calendar 2024-

メリークリスマス！
4日以来2度目の登場の遠藤です。
この期間、ゆっくりドラクエ3を進めて昨日ようやくゾーマを倒しました！

今年は「人」をテーマに、OpenChainのみならず日本のオープンソース界のキーパーソンの皆様にも寄稿頂き、これまで最大の21人参加による非常に賑やかなAdvent Calenderになりました。
そのおかげで、本当に色んなトピックスを扱うことができました。
と同時に今年のトレンドも見えてきましたので、
いくつかのテーマで今年のAdvent Calenderを振り返っていきましょう！

# Linux Foundation Japan Evengelist全員登場！
最初の1週間はJapan Evangelist Programを立ち上げたLFを福安さんも含め、初代Japan Evangelistの皆様から、各コミュニティの最新情報や各自のノウハウを共有頂きました。
OpenChainというとどうしてもライセンスコンプライアンスのイメージが強いですが、実はOpenChainの標準にはコントリビューションについての記載もありますし、Japan WGにはOSPO SGの活動も推進しています。
引き続き、OpenChainの場でもコミュニティ活動の活性化に取り組んでいきたいと思います！

[2024 OSS マクロトレンドを振り返る](https://qiita.com/fukuyasu/items/31db7c726f025c056ab9)
[CNCFとFinOps FoundationのJapan Chapterの紹介](https://qiita.com/yuichi-nakamura/items/60a58332cd36fa8a00f5)
[エヴァ？エバー？ Japan Evangelistの活動について](https://qiita.com/MasatoENDO/items/1a094ebe87c75510b032)
[Decentralized Trustとガバナンス](https://qiita.com/sfuji822/items/1418a0e5b5a471d24517)
[Program Committee やってみた](https://qiita.com/Muuhh/items/aa998ef6195690bd7524)
[SBOMの専門家から見た いま時点のSBOM](https://qiita.com/AyumiWatanabe/items/d2124e2588882930288c)

![eva.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537313/b87d4525-3c3a-f163-fb90-0afa79f8a285.jpeg)


# 今年もブーム真っただ中のSBOM！
25日間の中で今年も一番目立ったのはSBOMに関する記事でしょう。
今年はついにSPDX3.0がリリースになりましたし、Japan SBOM Summitも初開催され、欧州でもサイバーレジリエンス法が発効されるなど、まだまだしばらくはこのトレンドは続きそうです。

[SBOM狂騒曲 OpenChain SBOM study groupについて](https://qiita.com/nori0428/items/d606568cac8e1389e467)
[SBOM Element Comparison、その他、SBOM関連の検討資料の紹介](https://qiita.com/TakashiNinjouji/items/4b3b8c69b0658e2aa8a9)
[SPDXの仕様を日本語訳しよう！](https://qiita.com/yum41/items/380fc1e4481ea7369b6d)
[Japan SBOM Summit 参加レポート](https://qiita.com/yum41/items/ccbc69c864b829ae1fcf)
[SBOM関連ツールの一覧情報が絵でわかる！SBOM-Catalogの紹介 + OpenChain Security Assurance自己認証の取得](https://qiita.com/flying-pan/items/2f48237e144e783f9dbc)

![SBOMjpg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537313/b24f1a46-9fda-5f40-a6e9-cff87120059c.jpeg)



# 新たなコミュニティ！
AIやFinOpsなど旬な技術の日本のコミュニティの立上げに関わっている@chacco38さんや@kimusakuさんからそれぞれのコミュニティについてご紹介頂いた他、12/24には@imamura-kazukiさんから日本のオープンソースエコシステムをどのように変えていくかという熱い投稿を頂きました。
ここからどのように活動につながっていくかとても楽しみです！

[FinOps FoundationおよびFinOps Foundation Japan Chapterのご紹介](https://qiita.com/chacco38/items/30c1d9617e4773f3e912)
[LF AI Community Japan (仮)を立ち上げます！](https://qiita.com/kimusaku/items/cc9ea8b377b0558523ff)
[オープンソースエコシステムをどのように変えていくか](https://www.ipa.go.jp/digital/kaihatsu/oss/column-open-source-ecosystem.html)


# 今年もありがとうございました！
さて、このように今年のOpenChain Advent Calenderも様々なトピックで盛り上がりましたが、2025年も引き続き、グローバルではSBOMやOSPOといったトレンドは継続すると思いますし、日本ではついにKubeConが開催されますし、Open Source Summit Japanも3日間に拡大するなどよりコミュニティ活動の勢いは増していくと思います。
LFに限らず、コミュニティ活動の場で皆様にお会いできるのを楽しみにしています。

皆様、25日間ありがとうございました！

良いお年を！

![OSSJ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537313/c7022aaf-fac1-efd7-3841-c3abb504aad4.jpeg)
WindowsでOpenAIのwhisper.cppを設定して音声認識を実現する方法

## イントロダクション
- 最近、C++/Qtを使って音声認識ツールのソフトウェアを開発しており、その中でOpenAIのwhisper.cppを試しています。
- whisper.cppは、OpenAIのWhisperモデルのC/C++移植実装であるオープンソースプロジェクトです。
- OpenAIのWhisperは、大量の多言語および多タスクの監視データでトレーニングされており、複数の言語での音声認識、音声翻訳、言語識別などのタスクを実行できる自動音声認識（ASR）システムです。whisper.cppプロジェクトは、このモデルをWindows、Mac OS、Linux、Android、WebAssemblyなど、さまざまなプラットフォームでローカルに実行できるようにします。
- whisper.cppの主な利点は以下の通りです：

- 依存関係なし：whisper.cppは、外部ライブラリやフレームワークをインストールする必要がなく、C/C++コンパイラさえあればコンパイルして実行できます。これにより、外部ライブラリへの依存が減ります。
- 軽量：whisper.cppライブラリは非常に小さく、1つのソースファイルで構成されているため、プロジェクトに統合しやすく、大小問わず過剰な負担をかけません。
- 高性能：テンプレートメタプログラミングとC++17の特性を活用することで、whisper.cppは実行時にほとんど追加のオーバーヘッドがありません。タイプセーフな方法を使用し、イベント処理の効率が保証されています。
- シンプルで使いやすい：デザインがシンプルでわかりやすく、APIが使いやすいため、開発者はすぐにイベント駆動型のコードを書くことができます。


## 手順
- step1 コードをダウンロード
```
git clone https://github.com/ggerganov/whisper.cpp
```

- step2 モデルをダウンロード
whisper.cppプロジェクトのルートディレクトリに「models」フォルダがあります。その中に移動して、コマンドでモデルをダウンロードします。以下はCMDコマンドです。CMDで実行してください：
```
download-ggml-model.cmd small
```
またはシェルコマンド：
```
download-ggml-model.sh medium
```
もし上記の2つの方法がうまくいかない場合は、次のURLから手動でダウンロードできます：
```
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin
```

- step3 コンパイル
上記の2つの手順が成功した後、Whisper.cppプロジェクトの「build/bin」ディレクトリでmain.exeを生成します：
```
cmake .
mingw32-make
```

- step4 実行
ルートディレクトリに移動して、次のコマンドを実行すると、ターミナルに認識された字幕が表示されます：
```
.build/bin/whisper-cli.exe -m ./models/ggml-small.bin -f ./samples/jfk.wav
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/39ab54dd-1d4b-1215-3717-4a073874a174.png)
Snowflakeよ、CDPってCustomer Data Platformじゃないんかーい

UdemyでSnowflakeのSnowPro Advanced Architectのお勉強してたんですよ。
そしたらね、「CDP、CDP」言ってるんです。
正式名称書かずにですよ。
普通CDPっつったら**C**ustomer **D**ata **P**latformだと思うじゃないですか？
でもそれだと問題の意味が全然わかんない。
ググったらコレ。

https://docs.snowflake.com/ja/user-guide/data-cdp

継続的なデータ保護
**C**ontinuous **D**ata **P**rotection
お、おう。

内容をマルっと貼り付けますと。
>継続的データ保護（CDP）には、Snowflakeに保存されたデータを人為的エラー、悪意のある行為、およびソフトウェアの障害から保護するのに役立つ包括的な機能セットが含まれます。Snowflakeは、データライフサイクルのあらゆるステージで、偶発的または意図的な変更、削除、または破損が発生した場合にデータにアクセスし、回復できるようにします。

- ユーザーの IP アドレスに基づいてサイトへのアクセスを許可または制限するためのネットワークポリシー（つまり、IP 許可リスト）。
- アカウントにアクセスするすべてのユーザーに確認/認証が必要です（ MFA および SSOのサポートを含む）。
- システム内のすべてのオブジェクトへのユーザーアクセスを制御するためのセキュリティロール。
- データのロードおよびアンロード操作のために内部ステージに格納されているすべてのファイルは、サーバー側で AES-256の強力な暗号化を使用して自動的に暗号化されます。デフォルトでは、Snowflakeは128ビットのキー（オプションで256ビットのキーを構成可能）による追加のクライアント側の暗号化を提供します。
- Snowflake Time Travel（データのクエリと復元用）およびFail-safe（災害復旧用、Snowflakeのみで実行可能）による履歴データ（つまり、変更または削除されたデータ）のメンテナンス。

とまあ、よく知られているような基本機能でデータを保護する機能をまとめてCDPと呼ぶらしいんです。

いやでもさ、Snowflakeさん、CDPはメジャーなCDPがいるんだからさ、紛らわしい名づけはやめてください。さすがに**C**ustomer **D**ata **P**latformからCDPの座を奪うのは無理です。

継続的なデータ保護
Continuous Data Protection
って長くても言ってください。

でも観測したのはUdemyの試験問題集であって、Snowflake自体はCDPって言ってなかったらゴメンね。
Udemy講座の作者が言ってるだけの可能性もある。
講座名は「Snowflake SnowPro Advanced Architect Certification Exam Prep: Scenario-Based Practice Tests with Detailed Explanations」。
エンジニアだろうがなんだろうが1on1って大切じゃないですか？

新卒で実際に配属が決定してから、普段の業務に加えて意識的に先輩社員の方々にお願いして1on1をお願いしてきました。普段の業務ももちろん大事ですが、1on1をする意味と利点を自分なりにまとめてみました。

### 自分の知らない価値観を学ぶことができる
   
   1on1を通じて、先輩社員の業務経験や成長の過程、直面した課題とその克服方法を学ぶことができます。通常の業務中では、個人のバックグラウンドに関する話を聞く機会は多くありません。しかし、1on1の場を設けることで、その人がどのように考え、どのように成長してきたかを直接知ることができます。これにより、他者の経験を自分の働き方に応用したり、新しい視点を得ることができるでしょう。   

### 職場における知り合いを増やすことができる
   
   仕事を進める中で、わからないことや困難に直面する場面は少なくありません。特に新卒にとっては、質問をすること自体に心理的なハードルがある場合も多いでしょう。しかし、1on1を通じて職場の人々との接点を増やしておくことで、質問しやすい関係を築くことができます。また、疑問や課題に対して適切な解決策を持っている人にすぐ相談できるようになるのも大きなメリットです。

### 自分の考えをアウトプットする機会に（しかもフィードバックもらえるかも）

   1on1の場は、自分の悩みや考えを率直に共有し、それに対するフィードバックを受ける絶好の機会です。同じ会社や部署で働いていても、考え方や価値観は人それぞれ異なります。そのため、他者の視点や意見を取り入れることで、自分自身の考え方に新たな視点を加えることができます。これにより、思考の幅が広がり、自分の課題解決力や成長にもつながります。
特に日本では学生のころからアウトプットする機会が少ないと言います。アウトプットすることに慣れていないのです。だからこそアウトプットする機会を自ら作ることで、そこから学べるものはたくさんあるでしょう。

## まとめ

1on1を活用することで、他者から学び、関係を広げ、自分の成長を加速させることができます。また、日頃の業務では得られないような新しい視点やアドバイスを受けることで、より柔軟で効果的な働き方を実現できるでしょう。積極的に1on1を活用することで、職場でのコミュニケーションが円滑になり、自己成長の機会も増えるはずです。
GitHub Desktopでファイルの一部のみコミットしてみた。

今日初めて、GitHubDesktopでファイルの一部のみコミットできることを知ったため
手順を共有する。

## Test用のファイルを作成する。
test.txt
```
test1
test2//この部分はコミットしません。
```

## GitHub Desktopで選択してコミット
行ごとにチェックをつけることで、コミット対象か非対象か選択できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633053/19b68485-4f6f-c1f4-06f9-617bcfd8f879.png)

## 1行のみコミットされていることが確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633053/a0a5063a-c4cb-04b3-8009-eae3cd8780c7.png)
7. Reverse Linked List

## 1 Stack
```python3
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        found_values = []  #stack
        node_in_original = head

        while node_in_original:
            found_values.append(node_in_original.val)
            node_in_original = node_in_original.next
        
        dummy = ListNode()
        node_in_reversed = dummy

        while found_values:
            node_in_reversed.next = ListNode(found_values.pop())
            node_in_reversed = node_in_reversed.next
        
        return dummy.next
```
スタック積み込んで、一個ずつ出す。

```python3
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        current_node = head
        previous_node = None

        while current_node:
            next_node = current_node.next
            current_node.next = previous_node
            previous_node = current_node
            current_node = next_node
        
        return previous_node
```
ポインター2個使って繋ぎ変えていく。空間計算量が定数。ぶっちゃけあまり思いつかないなぁ。
Javaのラッパークラスをわかりやすく解説！

Javaには、「**基本データ型（プリミティブ型）**」という数字や文字を簡単に扱うデータの種類があります。でも、これだけではちょっと足りないことも。そんなときに使うのが **「ラッパークラス」** です！

この記事では、ラッパークラスが何なのか、どうやって使うのかを、わかりやすく説明します！

---

## **ラッパークラスって何？**

Javaでは、数字や文字などの「シンプルなデータ（プリミティブ型）」があります。

| **プリミティブ型** | **ラッパークラス（包むやつ）** |
|--------------------|-----------------------------|
| `int`              | `Integer`                  |
| `double`           | `Double`                   |
| `boolean`          | `Boolean`                  |

**プリミティブ型**は、軽くて速いけど、「他の特別な機能」を使うことができません。そこで、ラッパークラスを使うと、これを「オブジェクト（機能を持つデータ）」として扱うことができます。

---

## **ラッパークラスを使うと何がうれしいの？**

### **1. コレクション（リストやマップ）で使える！**

例えば、たくさんの数字をリストに入れたいとします。でも、リストは「オブジェクト」しか入れられないので、そのままではプリミティブ型は使えません。

こんなとき、ラッパークラスを使えば解決！

```java
import java.util.ArrayList;

public class Example {
    public static void main(String[] args) {
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(10); // 数字をラッパークラスに変換してリストに追加
        numbers.add(20);

        System.out.println("リストの中身: " + numbers);
    }
}
```

**出力結果**:
```
リストの中身: [10, 20]
```

---

### **2. `null` が使えるようになる！**

プリミティブ型は「0」や「false」みたいな「決まった初期値」しか使えません。でも、ラッパークラスなら「データがない」という状態を表す`null`を使えます。

```java
public class Example {
    public static void main(String[] args) {
        Integer age = null; // 「年齢が不明」の状態を表現
        System.out.println("年齢: " + age);
    }
}
```

**出力結果**:
```
年齢: null
```

---

### **3. 数字や文字を変換できる！**

ラッパークラスには、「文字列を数字に変える」「数字を文字列にする」みたいな便利な機能があります。

```java
public class Example {
    public static void main(String[] args) {
        String input = "123"; // 文字列の"123"
        int number = Integer.parseInt(input); // 文字列を数字に変換
        System.out.println("数字: " + number);

        int value = 456;
        String text = Integer.toString(value); // 数字を文字列に変換
        System.out.println("文字列: " + text);
    }
}
```

**出力結果**:
```
数字: 123
文字列: 456
```

---

## **ラッパークラスの仕組み**

Javaでは、**プリミティブ型**と**ラッパークラス**を「自動的に変換」してくれます。これを **「オートボクシング（包む）」** と **「アンボクシング（ほどく）」** と言います。

```java
public class Example {
    public static void main(String[] args) {
        int primitive = 10; // 普通の数字
        Integer wrapped = primitive; // 自動で包む（オートボクシング）
        int unwrapped = wrapped; // 自動でほどく（アンボクシング）

        System.out.println("ラッパークラス: " + wrapped);
        System.out.println("プリミティブ型: " + unwrapped);
    }
}
```

**出力結果**:
```
ラッパークラス: 10
プリミティブ型: 10
```

---

## **ラッパークラスを使うときの注意点**

### **1. メモリを多く使う**
ラッパークラスは、プリミティブ型よりも「重たい」ので、大量のデータを扱うとメモリをたくさん使います。

### **2. `null` に注意！**
ラッパークラスでは、`null`が使える分、`null`をそのまま使うとエラーになることがあります。

```java
public class Example {
    public static void main(String[] args) {
        Integer value = null;
        // int unwrapped = value; // エラーが出る（NullPointerException）
    }
}
```

---

## **現場でのラッパークラスの使われ方**

### **よく使われる場面**
- **リストやマップ**で数字を管理するとき
- **データベースやAPI**から受け取るデータが`null`になるとき
- **文字列を数字に変換**するとき

---

## **まとめ**

### **ラッパークラスができること**
1. プリミティブ型を「オブジェクト」に変える。
2. コレクションや`null`の扱いを可能にする。
3. 便利な変換機能が使える。

### **注意すること**
- メモリを多く使うため、大量のデータ処理には向いていない。
- `null`が原因でエラーが出る場合がある。

ラッパークラスは、ちょっとした数字の操作から大規模なデータ処理まで、Javaプログラミングでよく使われるツールです。**シンプルな使い方を覚えて、便利に活用してみましょう！**
WordPressのカスタムフィールドとは？？？


# カスタムフィールドとは

カスタムフィールドとは、データベースやシステムにおいて、標準的なフィールドに加えて、ユーザーが独自に定義し追加できるフィールドのことです。これにより、特定のニーズや要件に合わせてデータ構造をカスタマイズすることができます。

## カスタムフィールドの特徴

- 柔軟性：ユーザーのニーズに応じて自由に設定可能
- 多様性：テキスト、数値、日付など様々なタイプのデータを扱える
- 拡張性：既存のシステムの機能を拡張できる

## カスタムフィールドの利点

- 業務プロセスの最適化：特定の業務フローに合わせたデータ管理が可能
- データの詳細化：より細かな情報を記録・管理できる
- レポート作成の改善：カスタマイズされたデータを基に、より詳細な分析やレポートが作成可能
Azure Search Service で ClientSession._request() got an unexpected keyword argument 'query_language'= が出たら、ベータ版SDK を使う

# 背景

アプリの機能の一部をスクリプトで動かそうとした際に以下エラーが発生した際の対処記録

```powershell: エラー
ClientSession._request() got an unexpected keyword argument 'query_language'=
```

# 結論

単純に、GA 版ではまだ対応していない機能を使っていたってだけ

ってことで、以下のように `.in` で、ベータ版の指定をしてやれば OKだった

```diff: requirements.in の差
- azure-search-documents
+ azure.search.documents==11.6.0b1
```
バージョン指定をしないと、現時点の最新である 11.5.2 が設定される。
```diff: requirements.txt の差
- azure-search-documents==11.5.2
+ azure.search.documents==11.6.0b1
```

https://pypi.org/project/azure-search-documents/

## 原因

スクリプト用に `requirements.*` を単純化しようとした際に、バージョン固定を外してしまったのが失敗

Document Intelligence が 2024/11/30 に GAしました！ :flower_playing_cards: 
って喜びによる勇み足で、GA の際の破壊的変更だろうと勝手に勘違いしてしまっていたのも躓きポイントだった :sweat_smile: 


https://pypi.org/project/azure-ai-documentintelligence/

なんにせよ、Form Recognizer から移行しての正式版はめでたいですね

あ、ということで、以下の記事は訂正しておかないとか・・

https://qiita.com/baku2san/items/1055a20b321cafaf8d82

# 詳細

以下で、復活したってことなので、11.5.* では一旦消えてた感じかな？

> Added back query_language, query_speller, semantic_fields and debug for Search method.

https://github.com/Azure/azure-sdk-for-python/blob/8bff4275f1d09f4f6e28fa3288dc405c371e8f01/sdk/search/azure-search-documents/CHANGELOG.md#1160b1-2024-01-31

# あとがき

requirements.in にバージョン指定ある理由を理解せずに、消しちゃうのが失敗のもとですね。

とはいえ、まぁ、即座にエラーが出ればすぐ想定は付くので、放置せずに試せばそんな時間もかからないし、理解も得られるしなので、一石二鳥？ :laughing:
Eclipseにおける「Refresh」って？

## Eclipseにおける「Refresh」

「Refresh」とは、プロジェクトやワークスペースの状態を最新の状態に更新する操作です。具体的には、Eclipse内部で管理しているリソースの状態と、実際のファイルの状態を同期させる役割を果たします。

### なぜ「Refresh」が必要なのか？

Eclipseは独自のキャッシュを利用して、プロジェクト内のリソースを管理しています。そのため、以下のような状況でファイルの変更がEclipseに反映されないことがあります

- **外部ツールでのファイル編集・追加・削除**
  - Eclipse以外のエディタやツールでファイルを操作した場合、Eclipseはその変更を自動的には認識しません。

- **バージョン管理ツールでの操作（Gitなど）**
  - コマンドラインや他のクライアントでGitの操作を行い、ファイルの追加や削除が行われた場合

- **自動生成ファイル**
  - MavenやGradleなどのビルドツールによって生成されたファイルがある場合
OpenCV5での、C++Standard要求をどうするのか選ぶの手伝って！（の話）

この記事は[OpenCV Advent Calendar 2024](https://qiita.com/advent-calendar/2024/opencv)の22日目の代打記事です。
他の記事は目次にまとめられています。

はじめに
=======
OpenCV5のC++ Standard要求を決めるためのアンケートの意見をいくつか紹介したい。

https://github.com/opencv/opencv/discussions/25039

まず結果。

| C++ Std | 得票 |
|:--------:|:----:|
| C++14    | 6% |
| C++17    | 93% |

こんな感じで、OpenCV5で必要となるC++ Standardは、C++17になりました。

この中で皆さん、色々なベクトルで物事を捉えていて、なるほどーとなったので紹介していく。

C++11
------
- （賛成）衛星搭載コンピュータではC++14非サポートであり、C++11にしたい
- （賛成）組み込みボードデバイスの多くはC++17サポートできていません

C++14
-----
- （否定）古いGCCのC++14だと、constexprで問題が起きることもあるのでC++17が良い

C++17
-----
- （賛成）gcc/clang/msvcではC++17をほぼサポートしている！
- （賛成）std::string_viewサポートするために、C++17が必須！
- （賛成）C++17サポートにはGCC7が必要。Ubuntu 18.04に含まれる。もうこれ以上古いバージョンは使ってないでしょ？
- （賛成）どうしても古いコンパイラが必要な方はOpenCV4を引き続き利用できます。既にC++17は保守的な選択です！
- （賛成）任意の値マップに、現状のcv::dnn:DistやFileNodeの代わりに、std::anyが使えます！
- （賛成）既に成熟するのに十分な時間が経過しています。OpenCV5はC++17ベースで、OpenCV6はC++20ベースでモジュールを完全に取り入れると良いでしょう。

C++20
-----
- (否定) まだ主流コンパイラでサポートしきれていない
- (賛成）モジュール付きC++20は、夢です！

まとめると
=========
- C++17は、主要コンパイラで成熟済み！もうこれはチャレンジではなく保守的な選択ですよ！
- C++20は、もうちょっと安定化が必要…　モジュール機能は将来やりたいね！
- 組み込み環境とかでC++11とかC++14が難しい場合は、OpenCV4を継続利用してね

ということで、OpenCV5のminimum requirement C++ standardは、C++17になりました、と。


個人的な主観は？
===============
最後に個人的な主観を申し上げると、ほぼ、まとめと同じですね。

- OpenCV5は、C++17以上がよい。もう7年経過しており、枯れている安定化してある技術(2024～2025年リリース）
- OpenCV6は、C++20かC++23が良い。そのころにはコンパイラも成熟していそう(2027～2028年リリース）

それでは、皆様、楽しいOpenCVライフをお過ごしくださいませ！！
【PostgreSQL】トランザクションの中に別のトランザクションを入れる

# はじめに
これは、[PostgreSQL Advent Calendar 2024](https://qiita.com/advent-calendar/2024/postgresql)のシリーズ 2の24日目の記事となります。

2024/12/16 に1年以上かけて作成したアプリケーションをリリースしました。大きなトラブルはなく無事に本番稼働しています。
もともと `Classic ASP(VB)`で作成されていたアプリケーションを改善しながら10数年稼働させていましたが、`.NET 8`の`Blazor(C#)`で作り直しました。

# 複数台検証
ずっと1台で動かして開発してきましたが、実際に使用する環境は10数台が同時に動きます。
Webアプリケーション向けテスト自動化フレームワーク`Playwright`を使用して自動で複数台検証をしたところ、たまに一意制約違反が発生していることが分かりました。

## 原因
アプリケーション独自の採番を使用しているのですが、タイミングによって同じ採番が取得されて登録するために、一意制約違反となってしまう。

筆者の中では採番は別のトランザクションで実行させているため、同じ採番が取得されることはないと思い込んでいたのです。しかし、実際には同じ採番が取得されてしまう。
それではと、リトライ処理を追加して一意制約違反となったら採番をやり直せばいいと思って実装してみるのですが、ロールバック無しでリトライすると下記エラーになってしまう。		

current transaction is aborted commands ignored until end of transaction block

### Copilotに聞く
>PostgreSQLのNPGSQLにて、C#でトランザクションの中に別のトランザクションを入れて実行したい。どうすればいいですか

Copilotからの回答
>PostgreSQL自体はネストされたトランザクションを直接サポートしていませんが、セーブポイントを使用することで、ネストされたトランザクションのような動作を実現できます。セーブポイントを使うと、トランザクション内で特定のポイントに戻ることができます。

そうか、PostgreSQL自体はネストされたトランザクションを直接サポートしていない。

## 対応
トランザクションの中に別のトランザクションを入れるってことは「トランザクションのネスト」のことでした。キーワードが分かれば検索がしやすくなります。
`SAVEPOINT`を使えば、トランザクション内で指定した位置までロールバックできることが分かりました。

https://qiita.com/yuba/items/9b5b86bc3e128a84db5e

リトライ処理を追加し一意制約違反エラーになった場合、`SAVEPOINT`の位置まで戻して採番をやり直します。ロールバックすることになるため、先程の`transaction is aborted`エラーも出ません。

```csharp
try
{
    bool isSuccess = false;

    for (int retry = 1; retry <= 3; retry++)
    {
        // シリアルを採番する
        serial = GetNewSerial(serial);

        manager.ExecuteNonQuery("SAVEPOINT retry_point");

        if (!Construction(serial, manager))
        {
            // 一意制約違反
            Logger.Debug($"Duplicate Serial={serial} Retry={retry}");
            manager.ExecuteNonQuery("ROLLBACK TO SAVEPOINT retry_point");
            continue;
        }
        isSuccess = true;
        break;
    }

    // 登録を行う
    if (isSuccess && !Registered(serial, manager))
        return false;

    return isSuccess;
}
catch (Exception e)
{
    return false;
}
```

## 別案
Copilotに聞く
>メイントランザクションの中で、採番の値だけ自動コミットさせることは出来ますか

Copilotからの回答
>PostgreSQLでは、メイントランザクションの中で特定の操作だけを自動コミットさせることは直接的にはできません。しかし、シーケンスを使用することで、採番の値をトランザクションの外で取得することが可能です。シーケンスはトランザクションに依存せずに動作するため、トランザクションの中でも外でも同じように動作します。

シーケンスを使えばトランザクションに依存しないとのことです。
アプリケーション独自の採番も8桁中の末尾5桁は連番となっているため、シーケンスを使う修正案も考えたのですが、上記対応で解決できたのでやめました。

# 最後に
生成AIのいいところは、「トランザクションの中に別のトランザクションを入れる」といった質問でも、「トランザクションのネスト」と解釈して回答をくれるところですね。
ネストと指摘されれば、そうなんですが、このキーワードが意外と思い付かないもんです。
ilasmでstack machine その61

# 概要
ilasmでstack machineやってみた。
練習問題やってみた。

# 練習問題
AtCoderを解け。
整数 a,b,cと、文字列 s が与えられます。 a+b+c の計算結果と、文字列 s を並べて表示しなさい。

# サンプルコード

```

.assembly AtCoder {}
.method public static void Main() {
	.entrypoint
	.locals init ([0] int32 a, [1] string line, [2] string[] lines, [3] int32 b, [4] int32 c, [5] string s)
	call string [System.Console]System.Console::ReadLine()
	call int32 [System.Runtime]System.Int32::Parse(string)
	stloc.0
	call string [System.Console]System.Console::ReadLine()
	stloc.1
	ldloc.1
	ldc.i4.1
	newarr [System.Runtime]System.String
	dup
	ldc.i4.0
	ldstr " "
	stelem.ref
	ldc.i4.0
	callvirt instance string[] [System.Runtime]System.String::Split(string[], valuetype [System.Runtime]System.StringSplitOptions)
	stloc.2
	ldloc.2
	ldc.i4.0
	ldelem.ref
	call int32 [System.Runtime]System.Int32::Parse(string)
	stloc.3
	ldloc.2
	ldc.i4.1
	ldelem.ref
	call int32 [System.Runtime]System.Int32::Parse(string)
	stloc.s 4
	call string [System.Console]System.Console::ReadLine()
	stloc.s 5
	ldloc.0
	ldloc.3
	add
	ldloc.s 4
	add
	stloc.0
	ldloc.0
	call void [System.Console]System.Console::Write(int32)
	ldstr " "
	call void [System.Console]System.Console::Write(string)
	ldloc.s 5
	call void [System.Console]System.Console::WriteLine(string)
	ret
}



```

# 実行結果

```
>at0
1
2 3
test
6 test

```

以上。
ちょっとした手抜きをしたいときに、時々使いたくなるシリーズ～cmd編～

# 初めに
気が付けば、社会人歴も増えてきて、いい感じに時間をかけずに物事をすすめたい！
という感情がまま目立つようになってきました。（いい意味での怠惰と思い込んでいます！）

そんな中で、過去も登場しつつ、今年も登場したような？コマンド関連をご紹介します。
皆様の何気ない手抜きのサポートになればと思ってますので、ご参照くださいませ。

## 概要
業務上、いろんなデータを取り扱ったりしますが、「いっぱい分かれているファイルをまとめたいな」とかなんかまぁ、いろいろあると思いますが、そんな時にこういうことやったよ～。というのをピックしました

## 1. どっかから持ってきたlogファイルを結合したい！(やり方①)
```
C:\tmp>copy /b C:\tmp\data\*.log C:\tmp\all.log
C:\tmp\data\A.log
C:\tmp\data\B.log
C:\tmp\data\C.log
        1 個のファイルをコピーしました。
C:\tmp>

```
## 2．ローカルに複数フォルダを一気に作りたい

ブラウザ上で、新規作成＞フォルダと1個作るくらいならいいかなと。
でもたまにありますよね？『1か月分作りたい！！』みたいな
そんな時は、cmdも使うと楽ちんなので、抵抗なければぜひ

### 手順①：コマンドをExcelとかスプレッドシートとかで作る
楽な方法でOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124041/158243a7-3b00-9ca5-8411-b6673ac2e05f.png)

最終的には、下記のようなmkdirしたい！
```
mkdir 20241201
```

### 手順②：Excelとかで作ったものを僕は、サクラエディタで正規表現でちょこちょこするのが好きなんでタブを成形して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124041/bafc3bc4-3cb9-58b3-8b96-a5b9a9d4924c.png)

### 手順③：出来上がったコマンドを作成したいフォルダまで、cmdで移動して、実行すれば出来上がり！


## あとがき
毎年ちょっとした小技だけと、新人とかできてくれるといいんじゃないかなー？
と思うようなものは書き書きしていきますね！
ragas で prompt_trace.outputs.get("output", {})[0], となったときは、Timeout を伸ばして対処

# 背景

ragas 2.0 を利用しようとしていて、あるとき、意味不明なエラーが出たので対処した記録

```powershell: error
{path}\Lib\site-packages\ragas\callbacks.py", line 167, in parse_run_traces
    "output": prompt_trace.outputs.get("output", {})[0],
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
```

# 結論

直接の原因は以下のように、Time Out が発生し、その結果 outputs が欠如していたって話っぽい

> Exception raised in Job[33]: TimeoutError()

で、結果が無いまま進むと、件名のエラーに

## 対処法

`ragas.RunConfig` を使って、Time Out 設定を延長してやると解決はする

```python: Time out の延長
from ragas import RunConfig, evaluate

run_config = RunConfig(timeout=300) # timeout を伸ばす
result = evaluate(
    dataset,
    metrics=[
        faithfulness,
        ...,
    ],
    run_config=run_config # timeout を設定
)
```

## 補足
以下を見ると logging も出来るって話

```python: log
run_config = RunConfig(timeout=120, log_tenacity=True)
```

https://github.com/explodinggradients/ragas/issues/1280

# あとがき

RAG としての検証は 8軸あるんかな？まずはこれらを見えるようにするのが第一目標ですね・・ :?

https://docs.ragas.io/en/latest/concepts/metrics/available_metrics/
[Bevy] 丸をキーボード入力で動かし、無限ループさせる

丸いオブジェクトをキーボード入力（矢印キー）で動かし、フィールドを無限ループさせる動作をさせてみます。

前回に加筆する形で作成します。

https://qiita.com/fujino_tech/items/4362437f88062775c102

# オブジェクトの設置

丸い形を作成し、設置します。
座標軸はどうやらウィンドウ中央が(0, 0)で、右方向がx軸プラス、上方向がy軸プラスのように見えたけれど、気のせいかも知れません。

```rust
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
（略）
    let shape = meshes.add(Circle::new(100.0));
    commands.spawn((
        Mesh2d(shape),
        MeshMaterial2d(materials.add(Color::WHITE)),
        Transform::from_xyz(0.0, 0.0, 0.0),
    ));
（略）
```

# キーボード入力処理

キーボード入力イベントとオブジェクトのquery？を引数とするkeyboard_input関数を作成し、Updateへ登録します。

Mesh2dのエンティティ？を取りだし、キーボードの矢印キーの入力イベントがあればエンティティの座標を加算または減算し、変更します。

これによって、丸が動きます。

もし、変更後の座標が画面外へはみ出した場合は、画面の反対側に配置するように座標を書き換えます。

これにより、無限ループ移動が可能となります。

```rust
fn keyboard_input(
    window_size: ResMut<WindowSize>,
    keys: Res<ButtonInput<KeyCode>>,
    mut query: Query<&mut Transform, With<Mesh2d>>,
) {
    for mut transform in &mut query {
        if keys.pressed(KeyCode::ArrowLeft) {
            transform.translation.x -= 10.0;
        }
        if keys.pressed(KeyCode::ArrowUp) {
            transform.translation.y += 10.0;
        }
        if keys.pressed(KeyCode::ArrowDown) {
            transform.translation.y -= 10.0;
        }
        if keys.pressed(KeyCode::ArrowRight) {
            transform.translation.x += 10.0;
        }

        if transform.translation.x < -window_size.width / 2.0 {
            transform.translation.x = window_size.width / 2.0;
        }
        if transform.translation.x > window_size.width / 2.0 {
            transform.translation.x = -window_size.width / 2.0;
        }
        if transform.translation.y < -window_size.height / 2.0 {
            transform.translation.y = window_size.height / 2.0;
        }
        if transform.translation.y > window_size.height / 2.0 {
            transform.translation.y = -window_size.height / 2.0;
        }
    }
}
```

# 動作確認

これで、丸を動かせるようになりました。

やっぱり、実際に動くと感動しますね。

# 終わりに

ここは簡単に実現できました。

これができれば、簡単なゲームやアートのような描画もできそうな気がしてきます。

引き続きやっていきましょう。

ここまで読んでいただき、ありがとうございました。