OmniAICreator/Qiita-1.07M huggingface dataset:
Sequence MakerでUSB-シリアル変換器を使う時の⚠注意事項⚠

## はじめに
Sequence MakerはExcelから測定器を制御可能にするアドインです。Sequence Makerではシリアル通信（RS-232C）する測定器を制御したり、測定値を取得できたりするのですが、時々「なんか応答が変？？」と感じる場合があります。応答が返っては来るけど、データの後ろが切れていたり、応答データがずれていたり・・・この記事ではそんなときの対処方法を紹介します。なお、Sequence Makerについての詳細は以下の記事を参照ください。

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

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

## USB-シリアル変換器
最近のPCにはシリアルポートが付いていないので、多くの場合はUSB-シリアル変換器を使うことになると思います。USB-シリアル変換器はAmazon等で探すと各社のものが出てきますが、変換ICの種類によって以下の3タイプに分類されます。

- Windows標準のUSBドライバーを使用するもの（刺せばすぐ使える！）
- FTDI社のUSBドライバーを使用するもの（FTDIのドライバーを別途インストールする必要がある）
- Prolific社のUSBドライバーを使用するもの（Prolificのドライバーを別途インストールする必要がある）

ちなみに変換器はこんな感じのモノです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/7390a4c4-92a2-e453-fa2c-9f9024f6d586.png)

（https://www.buffalo.jp/product/detail/bsusrc0710bs.html より引用）

## 変換器を使うときの注意
適切なUSBドライバーを使用する事はもちろんなのですが（ドライバーの認識が失敗しているとそもそも通信できない）、通信ができるようになってからもなんか受信データがおかしい、、、という場合は、以下の点を確認して、必要に応じて設定変更をしてみてください。

### FTDIのドライバーの時
デバイスマネージャーから変換器のプロパティを開き、「ポートの設定」⇒「詳細設定」を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/3866e2c8-cbed-ea94-30de-cd3737650447.png)

この中の「BMオプション」がデフォルトでは「**16**」とかになっていると思います。
**BMオプションは「1」に変更しましょう**。
　**BMオプションは「1」に変更しましょう**。
　　**BMオプションは「1」に変更しましょう**。
※大切なことなので3回言いました:upside_down:

### Windows標準 or Prolificのドライバーの時
デバイスマネージャーから変換器のプロパティを開き、「ポートの設定」⇒「詳細設定」を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/582af293-941b-c8dd-9835-6e045cef1171.png)

一番上の **「FIFOバッファーを使用する」の✅を外しましょう**。
ただし、私の経験上、こちらの対策はあまり効果が出たことが無いです。。。

 ## 実はシリアル通信は難しい
 シリアル通信は手軽に使える通信方式ですが、ケーブルの種類も何種類かあったり、フロー制御もあったり、通信速度もいろいろあったりと、実は結構ハマりどころが多く、初心者はトラブルに巻き込まれがちです。ここにも書いたように、USB-シリアル変換器を使うとさらに問題が複雑化します。もしうまく通信ができない…という時は、以下の記事を参考にしてみてください。

 https://qiita.com/sequencemaker/items/3ecb7f63e567578a1cc4

 ## まとめ
 **BMオプションは「1」に変更しましょう**。
 知らないと絶対に変更しない設定だと思います。お近くで困っている人がいたら、この設定を変えて、どや顔してやりましょう:triumph:
CodeDeployのLambdaフック設定についてまとめてみた

# はじめに
みなさんはCodeDeployを利用しているでしょうか？
CodeDeploy は、「Amazon EC2 インスタンス、オンプレミスインスタンス、サーバーレス Lambda 関数、または Amazon ECS サービスへのアプリケーションのデプロイを自動化するデプロイサービスです」。
私はCodeDeployのLambdaフックという機能を使って、デプロイ時にLambda処理を追加することを行うときの設定でややてこずったので、今回どんな設定が必要かまとめていきます。
>こちらの投稿もご参考にしてみてください。
>[【CodeDeploy】デプロイステータスとライフサイクルの関係性についてまとめてみた](https://qiita.com/yoshi_610/items/0544d7382d0b1b74154d)

# 前提
- CodeDeployを使ってECSへのデプロイを行う
- CodePipelineのデプロイステージでCodeDeployを利用する(ソースステージはCodeCommit、ビルドステージはCodeBuild)
- LambdaをVPC内で実行する

# 内容
以下の3つの点を確認して設定してみてください。
1\. Lambdaの実行ロールでCodedeployへライフサイクルのイベント状態を返すアクション「codedeploy:PutLifecycleEventHookExecutionStatus」を許可する。
> AWSのこちらのサイトをご覧ください。
> [ステップ 3: ライフサイクルフック Lambda 関数を作成する](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/tutorial-ecs-with-hooks-create-hooks.html)

2\. Lambdaの環境変数にCodeDeployのエンドポイントを設定する。
>[CodeDeployのエンドポイントはこちら](https://docs.aws.amazon.com/ja_jp/general/latest/gr/codedeploy.html)

3\. 必要に応じてLambdaの環境変数に自身の環境のプロキシのURLを設定する

# まとめ
一度構築したことある方は特に悩むことないかもしれませんが、はじめて構築する方に参考にしていただければと思います。このほかにもご自身の環境によって追加で設定が必要な可能性もあると思いますので、その点ご注意ください。
Breadcrumbs（パンくずリスト）を作りながら Remix の useMatches と handle の使い方を学ぶ


## はじめに

Remix の公式ドキュメントには Breadcrumbs （パンくずリスト）の作成方法とともに、useMatches および handle の使い方について説明しているページが存在します。
Breadcrumbs（パンくずリスト）を作りながら、useMatches および handle を使う際の注意点を簡単に記載します。

## useMatches と handle について

useMatches は、Active な Route の Data や Meta 情報に Access するための hook です。
useMatches を使うことによってデータの共有を実行しやすくなります。

handle は、Root module で任意のデータやロジックを定義するためのプロパティです。
handle を使うことで、各 Route に独自の設定、メタ情報を組み込むことができます。

## useMatches と handle を使って breadcrumbs を作成する

Remix を使用して 簡単な Blog を作成していたとします。
それぞれの tsx に下記のような記述をします。

- `/blog` ... 記事一覧
- `/blog/$id` ... 記事詳細

```tsx:routes/blog._index.tsx
export const handle = {
  breadcrumb: () => "Blog Index",
};
```

```tsx:routes/blog.$id.tsx
export const handle = {
  breadcrumb: () => "Blog Detail",
};
```

これらの値を `routes/blog.tsx` で取得する場合は以下のように記載します。

```tsx:routes/blog.tsx

export default function Blog() {
  const matches = useMatches();
  const breadcrumbs = matches
    .filter((match) => match.handle && match.handle.breadcrumb)
    .map((match) => (match.handle.breadcrumb(match)))

  return (
    <>
      <div>
        {breadcrumbs.join(" / ")}
      </div>
      <Outlet />
    </>
  );
}
```

上記のように記載することで、 `/blog/$id` にアクセスされた場合、
`Blog Index / Blog Detail ` のように表示されるようになります。

また、(当然と言えば当然ですが) 各 tsx ファイルで固定された値を利用したい場合は、 `routes/blog.tsx` からデータを渡して上げる必要があります。

## Ref

https://remix.run/docs/en/main/guides/breadcrumbs
自動演奏キーボードを作った

[PONOS Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ponos) 25日目の記事です🎄🎄🎄
# はじめに
今年の10月に[キー部in京都](https://keeb.connpass.com/event/329756/)が弊社で開催されました🎉
せっかく参加するなら新しくキーボードを作りたいと思い、この機会に自動演奏キーボードを作ることにしました。
# 自動演奏キーボードとは
ホテルのロビーなどに置いてあり、無人で演奏をするピアノ。それをキーボードで真似したものを自動演奏キーボードと呼ぶことにしました。
人がいなくてもキーがカタカタと動き、文字が入力される。そんなキーボードを作りたい。
# 仕組み
「勝手に動く」ことを重視したかったので物理的に上から押す方法ではなく、下から引っ張る方法を採用しました。構造は単純でソレノイドを使ってキースイッチを下から引っ張ります。
# 構造
キースイッチは中身のステムが上下することで入力が行われます。つまりこれを引っ張ればキー入力ができます。もちろん普通にはアクセスできないのでボトムハウジングにピンバイスで穴を開けることにしました。そして穴からワイヤーを通してステムと接着し、このワイヤーをソレノイドで引っ張ります。

![キースイッチ改造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356727/5b4ae389-bd23-9970-7b31-690582b4c799.jpeg)
# ソレノイドの制御
ソレノイドの制御にはタカハ機工株式会社さんの[ソレノイド制御基板](https://www.takaha-shop.com/SHOP/sb-6565-01.html?_gl=1*1giz2mb*_ga*MTc0Nzg2MTcwMS4xNzM0ODc5MDg1*_ga_NLHW3KSNBB*MTczNDg3OTA4NS4xLjEuMTczNDg3OTEwNS40MC4wLjA.)を使いました。
# 動いているところ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">とりあえず自動演奏キーボードできたからキー部持ってくぞ！ <a href="https://t.co/9pO06QFqBS">pic.twitter.com/9pO06QFqBS</a></p>&mdash; アキーラ (@ackyla) <a href="https://twitter.com/ackyla/status/1842196441693081774?ref_src=twsrc%5Etfw">October 4, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 作ってみて思ったこと
* 見た目や動きは思ったように作れた
* 時間がなくて入力は実装できなかった
* キースイッチ改造がめんどくさすぎるのでフルサイズは無理
* 青軸も真っ青のうるささ
* 打鍵音が完全にソレノイドの音なので、ちゃんとキースイッチの音がする構造にしたい

# さいごに
そろそろちゃんと新しい自作キーボードを設計するぞ！
メリークリスマス！！！
Santaモード＆ビデオ対応のAdvanced Voiceが登場！ChatGPTが一気にお祭りムードに

OpenAIが発表を続ける「12 Days of OpenAI」、Day 6は**“Advanced Voice”のビデオ共有機能**と、期間限定の**Santaモード**で盛り上がり必至のアップデートです。  
音声会話に加えて、カメラや画面共有が使えるようになり、そこへクリスマス仕様の“サンタ”を呼び出せるのが最大の目玉。動画でも実演されていましたが、まるでZoom感覚でChatGPTと会話・映像をやりとりできるのは新鮮です。

この記事は[ChatGPT Advent Calendar 2024](https://qiita.com/advent-calendar/2024/chatgpt)の11日目です（空いていたので書いてみました）今年は「12 Days of OpenAI」ということで毎日発表がありましたが、その内容を復習しながらまとめます

## 主なアップデート内容

1. **Advanced Voiceにビデオ＆スクリーンシェア機能が追加**
   - 既存の音声会話モードに、**カメラ映像**や**画面共有**をリアルタイムで伝送するオプションが加わった。
   - コーヒーの入れ方を教えてもらったり、画面上のアプリを見せてレスポンスをもらったりと活用幅が大幅に拡大。

2. **“Santaモード”が期間限定で登場**
   - 12月中はChatGPT内でサンタと直接会話が可能に。**サンタの声でリアルタイムに応答**してくれる。
   - 設定画面、またはホーム画面の**雪の結晶アイコン**からサンタを呼び出し、質問やクリスマスのリクエストができる。
   - **一度限りの音声制限リセット特典**もあり、既に月間の音声上限を使い切った人でもサンタとはすぐに音声で話せる。

3. **音声会話の自然さがさらに向上**
   - 昨日までにも話題となっていた**Advanced Voice**は、**GPT-4.0 マルチモーダルモデル**をフル活用。
   - オーディオの入出力がネイティブに処理されるため、応答速度や言い回しがリアルで**感情表現も豊か**に感じられる。

4. **ダウンタイムへの謝罪と早期復旧**
   - 発表冒頭では、Day 5に数時間のサービスダウンがあった件について謝罪がなされた。
   - 内部調査の結果は後日レポートとして公開予定とのこと。

## 新機能の使い方

1. **Advanced Voiceによるビデオ通話の始め方**
   - モバイルアプリやデスクトップアプリで**最新バージョン**を使用。
   - チャット画面右下の「Advanced Voice」ボタンをタップすると、音声に加えて**ビデオや画面共有**が可能になる。

2. **カメラ共有**
   - スマホやPCのカメラを通じて、ChatGPTに物体や人を見せながら説明を受けられる。
   - 例: コーヒー器具を映して抽出手順を教えてもらう、クリスマスセーターを披露して評価してもらう…など。

3. **画面共有**
   - アプリの設定やコードエディタ画面をChatGPTに見せられる。  
   - 例: メッセージアプリを見せて、相手への返信案を作ってもらう。

4. **Santaモードの開始方法**
   - ホーム画面の**雪の結晶アイコン**をタップ、またはチャット設定からサンタを選択。
   - サンタ特有の陽気な声や口調で応答してくれる。  
   - **すでに音声制限を超えている場合でも、一度だけ上限リセット**され、すぐ声モードで会話可能。

## リリースと対応状況

- **ビデオ＆スクリーンシェア**:
  - 最新モバイル版アプリから順次解禁し、約1週間かけて全ユーザー（Plus/Pro中心）に広がる予定。
  - 欧州ユーザー向けは現地法規などの兼ね合いでやや遅れるが、対応準備中とのこと。
  - Enterprise/Edu向けは来年初頭の導入が予定されている。

- **Santaモード**:
  - 音声モードが使用できる全地域・全デバイスで12月中利用可能。
  - デスクトップWeb版 (chat.openai.com) でも音声が有効な環境なら、**サンタの声**が使える。

今回の発表は、単なる「季節イベント」以上に、**動画＋音声＋画面共有**というマルチモーダルをフルに活用するChatGPTの**未来像**を垣間見せてくれた印象。  
「AIアシスタントが目の前に“実在”するような体験」が、いよいよ当たり前になる段階に近づいてきました。

## まとめ
Advanced Voiceモードは今までにないコミュニケーション体験を得ることができます。今まではパソコン上でテキストベースでのデータのやり取りが当たり前でしたが、ついに音声会話が自然に行えるようになりました。

あまり使っていない方からすると微妙なアップデートと感じる内容ですが、日々使っていると全く別物に生まれ変わっている感覚を受けます。

---

**参考動画**: [Santa Mode & Video in Advanced Voice—12 Days of OpenAI: Day 6 - YouTube](https://www.youtube.com/watch?v=NIQDnWlwYyQ)
Google CloudのDMS（Database Migration Service）でデータ移行が遅延する

# 概要
CloudSQLの5.7から8.0に移行するため、DMSを使用をして実施する時に、
事前に検証で行ったときと異なり、データ移行が遅延するということがあった件について、
対応したことを記載します。
# 事象
移行先のDBを新規作成して、DMSのジョブを作成し、移行を実施しました。
実行後５分程度で、ディスクの自動拡張にしていたのですが、
拡張が追いつかず、データが容量不足でLOAD出来ないとのエラーになってしまい、
DMSの自動リトライでデータ移行が再開されました。
それ以降のデータ移行が、かなり遅くなり、以前実施した時は、CPUが50%使用されていたのですが、
6%で留まり、そのままの状態で移行が行われました。（以前はエラーが発生していません。）
その後、何度やり直しても、同様な状態でデータ移行が遅延しました。
# 調査
確認のため試したこと。
- ディスクの自動拡張されないように、移行データ分を確保した状態で再実行
    - 変化なし
- DMSのJOBを削除して再作成し再実行　
    - 変化なし
- 移行元のprofileを削除して再作成し再実行
    - 変化なし
- 移行先のDBを別途新規で作成し、そっちに移行（ディスクはデータ移行分を確保した状態）
    - 問題解消

移行先のDBを再作成することで、別リソースとなり、問題解消したと思われる。

# まとめ
DMSは移行元や移行先に負荷をかけないように、最適化を行いデータ移行を実施するとのことだったので、
最初に作成したDBに関しては、エラーが発生したことにより、負荷がかからないように調整されたように見える。
そのため、別で作成したDBで実施すると問題がでなかったと考えられる。
下の並列ダンプが無効になったのではと推測。
https://cloud.google.com/database-migration/docs/mysql/known-limitations#parallelism-considerations
label タグと input タグをセットで使うのはなぜか？

## はじめに
超シンプルなテキストボックスを用意しました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613261/eec53eb3-7cab-6836-3813-550c29f343ab.png)


こちらは以下のようなコードでも実現できます。が、下のサンプルコードは悪い例です。
```
// ex1
<div>
  <div class="hoge">名前</div>
  <input type="text" />
</div>

// ex2
<div>
  <label class="password">パスワード</label>
  <input type="password" id="password" />
</div>
```
このコードのどこが問題か分かりますか？
また、labelタグとinputがセットで使われる場面はよく見ると思いますが、それはなぜかは説明できますか？この記事ではその理由について、解説します！

## 理由
早速ですが、結論から。
フォームを作成する際に、labelタグとinputタグをセットで使用するのには、大きく三つの理由があります。

1. 操作性の向上: 
ラベルをクリックしたときに、自動で入力欄にフォーカスできる。  <br>

1. アクセシビリティの向上: 
スクリーンリーダーなどが「この入力欄はこのラベル」という対応を正しく読み上げられる。  

1. 保守性の向上: 
コード上で「どのテキストがどの入力欄を指すのか」が明確になり、後から見ても分かりやすい。

divタグを使っても見た目上は変わらないですが、labelを使うことで操作性が格段に向上します。
以上の観点から、labelタグとinputタグはセットで適切に使いましょう！


## 上記のコードの問題点を解説する
上記の説明を踏まえた上で、　badコードを改めてみていきます。

```
// 問題点1: 「名前」の文字が単なるdivタグなので、ラベルの機能を果たしていない。
// 文字をクリックしてもフォーカスは移動しないし、スクリーンリーダーにも「これは何の入力欄か」が伝わらいコードになっている。
<div>
  <div class="hoge">名前</div>
  <input type="text" />
</div>

// 問題点2: 
// label タグは使っているものの、htmlFor="password" が指定されていない。そのため実質「パスワード」という文字と <input> が紐づいていない状態になっている。
<div>
  <label class="password">パスワード</label>
  <input type="password" id="password" />
</div>
```

修正例は以下のとおりです！
label, input, htmlFor(for)を適切に使いましょう。

## 修正例
```
      <div>
        <label className="name" htmlFor="name">
          名前
        </label>
        <input type="text" id="name" />
      </div>

      <div>
        <label className="password" htmlFor="password">
          パスワード
        </label>
        <input type="password" id="password" />
      </div>
```


## まとめ
[用法]
* label タグと input タグはセットで使う
* label の htmlFor 属性と input の id 属性を一致させる

[効果]
* アクセシビリティ・操作性向上のために必須
* ラベルをクリックして入力欄にフォーカスを当てることができる
* スクリーンリーダーが「ラベル → 入力欄」の対応関係を正しく読み上げることができる
23日目: TopologicalSortを実装する

[競プロ用ライブラリを作る Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yukkku-ribitol)の23日目です.

https://qiita.com/advent-calendar/2024/yukkku-ribitol

# TopologicalSortって?

DAG (有向非巡回グラフ) の頂点を良い感じに並べ替えるアルゴリズムです. DAGとはループが無い有向グラフのことです


↓はA→C→D→Aと辿ると元の場所に戻ってこれるのでDAGではないです.
```mermaid
graph LR;
    A((A));
    B((B));
    C((C));
    D((D));
    E((E));
    F((F));
    A-->B;
    A-->C;
    D-->A;
    C-->D;
    B-->E;
    E-->F;
    D-->F;
```
↓はどう矢印を辿っても元の場所に戻ってこれないのでDAGです
```mermaid
graph LR;
    A((A));
    B((B));
    C((C));
    D((D));
    E((E));
    F((F));
    A-->B;
    A-->C;
    B-->D;
    C-->D;
    B-->E;
    E-->F;
    D-->F;
```
これを`[A, C, B, D, E, F]`のように, 矢印の行先が必ず後ろの要素になるように並べ替えるのがTopologicalSortです.
`[A, B, C, E, D, F]`みたいな順番でも条件を満たしますが, こういうときはどちらを返してもいいものとします.

# 仕組み

仕組みは簡単,「追加しても良い頂点を追加する」を繰り返すだけです.
ここで追加しても良い頂点は「その頂点に向かって辺が向かってる頂点が全部既に配列に入ってる頂点」です.

具体的にアルゴリズムを説明します

まず, 最初に「各頂点に入ってくる辺はいくつあるか」を数えておきます.
そしてそこから「入ってくる辺が無い頂点」をスタックに入れます. このスタックは追加しても良い頂点が入るスタックです.

そして

1. スタックから要素を取り出す
2. その要素を答えの配列の末尾に追加する
3. その頂点から出てる辺全部について以下のことを行う
   1. その辺が入る頂点の「入ってくる辺のカウント」を1つ減らす
   2. カウントが0になったなら, その頂点をスタックに入れる

を繰り返せばTopologicalSortできます.

```rs
pub fn sample_topological_sort(edges: &[Vec<usize>]) -> Vec<usize> {
    let n = edges.len();
    // 各頂点に入る辺の数を数える
    let mut count = std::iter::repeat_n(0usize, n).collect::<Vec<_>>();
    for v in edges {
        for &u in v {
            count[u] += 1;
        }
    }
    // 入ってくる頂点が無い頂点をスタックに入れる
    let mut stack = count
        .iter()
        .enumerate()
        .filter_map(|(i, &c)| (c == 0).then_some(i))
        .collect::<Vec<_>>();

    let mut ret = vec![];
    // スタックに入ってる頂点が無くなるまで取り出して処理する
    while let Some(v) = stack.pop() {
        // 結果の配列に頂点を入れる
        ret.push(v);
        // その頂点から出てる辺でループを回す
        for &u in &edges[v] {
            // 入る頂点のカウントを減らす
            count[u] -= 1;
            // カウントが0になったらその頂点をスタックに入れる
            if count[u] == 0 {
                stack.push(u);
            }
        }
    }
    ret
}
```

# 実装

- [`topologicalsort.rs`](https://github.com/Yukkku/ribitol/blob/main/src/topologicalsort.rs)

やるだけです. 柔軟性を持たせるためにイテレータを返すようにしてみました.

# まとめ

いかがでしたか?

明日はAtCoder出禁データ構造を作ります.
「人気急落馬は穴馬」説を検証してみた

# はじめに
競馬予想AIを作る記事の続きです。（[前回](https://qiita.com/lefirea/items/f69c868f78ce1b561590)）
現状の自作AIでは、人気の影響を強く受けるため、1番〜5番人気をよく選んでしまう。
その結果、荒れたレースは全損、勝ててもリターンが少なかったり赤字となってしまうため、短期的な勝ちを目指すなら穴馬の特定が必須である。

今回の目的は「短期的に勝つために穴馬を探す方法を検討する」ことである。
そのためには荒れたレースで勝つ必要がある。
荒れたレースでは人気の低い馬が3着以内に入っているため、タイトルに書いている通説を検証する。

この通説の根拠としては、以下のようなものがよく挙げられている。
- たまたま相手がバケモンだったので負けただけで、そのグレード内では十分強い
- たまたま苦手な馬場や距離だったので負けたが、得意な状況では十分強い

これらは納得できる根拠ではあるものの、データとして示されることは少ない。
そこで今回はデータから検証することにした。

# 分析方法
中央競馬のレースデータから、**今走人気**と**前走人気**を取得し、各馬が3着以内に入ったかどうかを集計し、勝率を求める。
ここでの勝率とは、その人気遷移の馬が3着以内に入る確率とする。
また、確率の求め方は、`その人気遷移で勝った回数 / その人気遷移だった馬の総数`とする。

分析に使用するデータは2022年の中央レースのうち約1200件である。
（過去走の人気を取得していなかったので集め直している最中。最終的に約5万レース分になる予定）

# 分析結果
実際に集計してヒートマップにしたものが下図である。
色が明るいほど勝率が高いことを表している。
![pops.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382806/5f3185f8-0258-0107-bcc3-c39b27fa951b.png)


前走人気が高く、今走人気が低く、勝率が高い場所を探すと、左上あたりが目に付く。
前走人気が7番以上で、今走人気が12番以下の領域が少し明るい。
特に前走が3番人気のとき、最も穴馬率が高い傾向にあることが分かった。

この結果から、通説「人気急落場は穴馬」が概ね正しいと確認できた。

# 実際のレースはどうか
[2024年の有馬記念](https://race.netkeiba.com/race/result.html?race_id=202406050811&rf=race_submenu)の結果を見ると、以下のようになっていた。
|着順|馬名|今走人気|前走人気|
|:---:|---|-------:|-------:|
|1|レガレイラ|4|1|
|2|シャフリヤール|10|3|
|3|ダノンデサイル|2|1|

前述した通り、10番人気で2着のシャフリヤールが穴馬となっていることが確認できる。
加えて、シャフリヤールは前走人気が3番であり、今回の結果とそこそこ合致する。
この通説を知っているかどうかで稼ぎが大きく変わる事例と言える。

# まとめ
今回は「人気急落馬は穴馬」説を検証した。
人気遷移を基に集計を行い、3着以上に入る確率（勝率）を求めた結果、前走人気が6番以上なら勝率が比較的高いことが分かった。
実際に2024年の有馬記念では、前走人気3番、今走人気10番のシャフリヤールが2着に入っていることが確認できる。
以上のことから、この通説は概ね正しいことが確認できた。
今後は更にデータを増やして再集計した結果で検証し直す予定である。
また、その結果を用いて各馬の勝率予測することを検討している。
Renovateを導入してみた

既存プロジェクトに Renovate を導入したため、設定や運用方法を紹介します。

# Renovate とは

**Renovate** は、依存関係のアップデートを自動化してくれるツールで、GitHubなどでリポジトリを連携すると、パッケージの更新を自動検出して PR を発行してくれます。

https://renovatebot.com/

# 導入理由

バージョンアップ作業が滞り、一部ライブラリでは既にサポート切れが発生していたため、チーム全体で定期的に更新を促す仕組みとして Renovate を導入しました。

# 設定内容

今回の主な設定ポイントは以下のとおりです。

## Node.js のバージョンを固定

- package.json に Node.js のバージョンを明記
- GitHub Actions でも、このバージョンを参照するように統一

```yaml
- uses: actions/setup-node@v4
  with:
    node-version-file: "package.json"
    cache: "npm"
    cache-dependency-path: "package-lock.json"
```

## PR の作成に関する設定

- マイナーとパッチバージョンの更新は 1 つの PR にまとめて作成するように
- 逆にメジャーアップデートは、1.x.x → 3.x.x のように一気にアップデートせず、1.x.x → 2.x.x, 2.x.x → 3.x.x のように段階的に分ける
- PR は一気に大量作成される可能性があるので、一旦 Draft PR として作成（limitも指定できるので、場合によってはそちらでも良いかも）
Draft の PR では CI が走らないようにしています。

:::note info
draftのときにCIが発火しないように、 GitHub Actions に下記のような条件を追加しています
`if: github.event_name != 'pull_request' || (github.event_name == 'pull_request' && github.event.pull_request.draft == false)`

pull_request以外のときも発火する場合があるためこのようになっていますが、pull_requestでしか発火しない場合は
`if: github.event.pull_request.draft == false` だけで良いと思います
:::

- PRが業務中にノイズにならないように、Renovate の実行は業務時間外に設定
  - 例えば 夜 10 時以降 ~ 朝 6 時 や週末など、プロジェクトの状況に合わせて時間を指定できます

## パッチバージョン更新のオートマージ

- パッチバージョンの更新の場合は CI が通ったら自動的にマージするように設定
- 後方互換性を壊すリスクが低いため、速やかに取り込めるようにしています

:::note warn
セマンティックバージョニングに従ってないライブラリも存在するため注意が必要です
:::

## バージョン指定は「固定 (Pin)」

- 好みの問題もあると思いますが、可読性と運用の明確化を目的に、package.json のバージョン指定は ^ や ~ を使わず、固定のバージョンで指定

参考: [Renovate: Should you pin your JavaScript dependencies?](https://docs.renovatebot.com/dependency-pinning/#should-you-pin-your-javascript-dependencies)

# 運用方法

プロジェクトにより最適な方法は変わると思いますが、今回のプロジェクトでは下記のように運用しました

- マイナー・パッチアップデート
	- 後方互換が保たれている可能性が高いため CI が通っていれば即マージ
- メジャーアップデート
	- レビュワー全員の Approve 必須
	- 破壊的変更が入る可能性があるため、事前にテストやドキュメント確認を徹底
- 定期的なチェック
- 毎週決まった曜日 に、溜まっている PR の進捗を確認

# 実際のコード例

```json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended",
    "group:definitelyTyped",
    "group:allNonMajor",
    ":automergePatch",
    ":disableRateLimiting"
  ],
  "enabledManagers": ["npm", "dockerfile", "github-actions"],
  "packageRules": [
    {
      "matchUpdateTypes": ["major", "minor"],
      "draftPR": true
    }
  ],
  "labels": ["dependencies"],
  "rangeStrategy": "pin",
  "separateMultipleMajor": true,
  "timezone": "Asia/Tokyo",
  "schedule": [
    "after 10pm every weekday",
    "before 6am every weekday",
    "every weekend"
  ]
}
```

## コード概要

- `config:recommended`: Renovate 公式のおすすめ設定
- `group:definitelyTyped`, `group:allNonMajor`: TypeScript の型定義やマイナー・パッチ更新のPRをグループ化
- `automergePatch`: パッチバージョンの更新を自動マージする設定
- `draftPR`: メジャー、マイナー更新に関しては Draft PR にする
- `rangeStrategy: pin`: 依存関係を固定バージョンにする

# まとめ

最初は大量に PR が作成されて焦りましたが、設定を調整していくうちに、「段階的にメジャーアップデートを進める」「Draft PR でまとめておく」「業務時間外に実行する」などの運用が定着してきました。
現在では、ほとんどのライブラリが最新に近い状態になっています（ようやくESLintもv9にできそう）
MS-DIALの動作確認用アプリケーションを作ってみた

# はじめに

自分たちの研究室では、MS-DIALという質量分析データの解析用ソフトウェアを開発しています。最近、コアな機能の改修を実施しなければならない案件がいくつかあり、そのアップデートを進めています。

ただ、自分が研究室に入る以前から存在しているコードには、ユニットテストがなかったり、ドキュメント化されていない部分が多く、開発が困難を極めています。その結果、意図しないプロセスでデグレが発生し、手戻りが多くなっているのが現状です。

現状の動作を保証するために動作チェックは行っているものの、それらは完全に手動で行われています。特に、異なる解析プロセスの結果に影響を与えるような変更については、テストが煩雑になるため課題となっています。

そこで、決まったテストケースに対して簡易的に動作チェックができるツールを作ってみました。

# メソッド

## 対象

今回対象としたのはMS-DIALのコンソール版です。このツールでは、いくつかの解析プロセスや生データのフォーマットに対して動作を確認できるようにしました。

## 実行結果の評価

実行結果の評価としては、以下のアプローチを採用しました

* 出力ファイルのハッシュ値を取得する

* 前回の結果と比較することで動作確認を行う

## 使用技術

* フレームワーク: Blazorを使用。

* サーバーアプリケーション: 複数人で利用することを考慮し、ローカルサーバー上で動作する形にしました。（開発してくれる学生さんはいませんか？）

* オブジェクトストレージ: テストケースや実行結果の管理には、研究室のS3互換ストレージであるMinIOを活用しました。

## ユースケースの想定

以下の流れを想定しています：

1. 手元のPCで開発。

2. サーバー上にコンソール版のアプリケーションをアップロード。

3. 事前に登録したテストケースを実行。

4. 実行している間は手元で他の作業を続行。

5. 実行完了後、ハッシュ値から結果が変わっていないことを確認。

ローカルPCで直接実行させると生成されたファイルが煩雑になるため、ローカルサーバー上で動作させ、不要なファイルは一括削除できるようにしました。

## 開発手法

ソースコードの生成にはChatGPT o1 を活用しました。事前にChatGPT-4oと話し合いながら仕様を詰めておいたことで、質問回数を抑えつつ十分なコードを生成することができました。

基本的には生成されたコードをそのまま使用し、エラーや細かな変更が必要な箇所のみ手直しを行いました。

# 結果

以下のスクリーンショットは、完成したアプリケーションの一部を示しています：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944004/53b022a0-b9ab-a77f-3f13-ea915f4205d1.png)

過去のテスト結果を一覧で確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944004/562e44bf-7437-138a-e10c-40ba8c91ac87.png)

ここのテストケースに関して、うまく実行できているのかをチェック
必要があれば、結果のダウンロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3944004/b885dda7-6e17-1968-1686-f23e47b93df3.png)

テストケースごとに過去の結果と比較

# 終わりに

公開されている便利なツールもあるでしょうが、今回のように"ちょっと使う"用途であれば十分なツールを短期間で作成することができました。

MS-DIALはまだまだ開発が続くソフトウェアです。今後もできるだけ安定したものになるよう努力していきたいと思います。

今回作成したツールはそのうち研究室のGithubに上げようと思ってます。
ゼロから始めるSnowflake（2/10）


# Snowflakeの操作
## Snowsightユーザーインターフェース

### Snowsightの概要

Snowsightは，Snowflakeを操作するためのウェブインターフェースである．主な機能は下記の通りである．

### オブジェクトベースナビゲータ
- Snowflakeのロゴをクリックすると，ホーム画面が表示される．
- ホーム画面は，検索ボックス，クイックアクション，最近表示の3つのセクションから成り立つ．

### SQLワークシート
- SQL文を記述し，実行し，結果を表示できる．
- オブジェクトブラウザを使用し，実行したいオブジェクトを選択することが可能である．

### Pythonワークシート
- Pythonコードを記述し，実行できる．記述したコードをPythonストアドプロシージャとしてデプロイするオプションも有する．

### Snowflakeノートブック
- Markdownセルと実行可能なSQLとPythonセルを含む．
- 主な機能として，セッションの開始，セルの追加，セルタイプの変更，セルの削除が行える．

## Snowflakeノートブックの機能

### セッションの開始
- SQLやPythonセルでコードを実行するために，アクティブなコンピュートリソースが必要である．これはセッションの開始ボタンやセルの実行により開始される．

### ノートブックセルの追加と変更
- 新しいセルの追加やセルタイプの変更は，セルの横メニューやカーソルスライダーを使用することで行える．

### セルの実行オプション
- 個別のセルを実行するときは，セルの右上にある実行ボタンやキーボードショートカットを使用する．
- 全てのセルを順番に実行するときは，ノートブックの右上にあるすべて実行ボタンを使用する．
bashのブレース展開

## ブレース展開とは？

ブレース展開は、`{}` で囲まれたパターンを、指定された文字列の組み合わせに展開する機能です。

例えば、以下のようなパターンがあるとします。

```bash
echo {a,b,c}-{1,2,3}.txt
```

これは次のように展開されます。

```bash
a-1.txt a-2.txt a-3.txt b-1.txt b-2.txt b-3.txt c-1.txt c-2.txt c-3.txt
```

このように、`{}` 内のカンマ区切りの文字列と、その前後の文字列を組み合わせて、複数の文字列を生成できます。

## 基本的な書式

ブレース展開の基本的な書式は以下の通りです。

```
{文字列1,文字列2,...,文字列N}
{<始まり>..<終わり>}
{<始まり>..<終わり>..<インクリメント>}  # Bash 4 以降
<頭に付けたい文字列>{........}
{........}<後尾に付けたい文字列>
<頭に付けたい文字列>{........}<後尾に付けたい文字列>
{文字列1,文字列2}{文字列3,文字列4}
{,文字列1,文字列2}
<文字列0>{文字列1,,,文字列2}
<文字列>{,,,}
```

## 使用例

### 1. カンマ区切りの文字列展開

```bash
$ echo {a,b}.txt
a.txt b.txt

$ echo {a,b,c}-{1,2,3}.txt
a-1.txt a-2.txt a-3.txt b-1.txt b-2.txt b-3.txt c-1.txt c-2.txt c-3.txt
```

### 2. 連番の生成

```bash
$ echo {1..5}
1 2 3 4 5

$ echo {a..e}
a b c d e

$ echo {1..10..2} # 1から10まで2ずつ増やす
1 3 5 7 9

$ echo {a..z..5} # aからzまで5つ飛ばし
a f k p u z
```

### 3. ファイル名の生成

```bash
$ mv file.{txt,bak} # file.txt を file.bak にリネーム
```

### 4. ディレクトリの一括作成

```bash
$ mkdir dir{1,2,3} # dir1, dir2, dir3 を作成
```

### 5. ループ処理

```bash
$ for i in {1..5}; do echo "Number: $i"; done
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
```

### 6. 変数と組み合わせた利用

```bash
$ PREFIX=image
$ echo ${PREFIX}_{a,b,c}.jpg
image_a.jpg image_b.jpg image_c.jpg
```

**参考記事**

* [第42回　bashの便利な機能 | gihyo.jp](https://gihyo.jp/article/2022/08/ganshiki-soushi2-0042)
* [Bash Reference Manual](https://www.gnu.org/software/bash/manual/bash.html)
[Python] math : factorial / log / gcd / degrees / radians

Pythonのmathについて、復習メモ。
[[Python] math : sqrt / pow / ceil / floor / fabs](https://qiita.com/yam_dev/items/4db71b30c04b9cf2eab7)の続きです。

## math.factorial(x)

xの階乗を返す（x は正の整数である必要がある）

```python
import math

x = 5
result = math.factorial(x)
print(f"{x}! = {result}")  # 出力: 5! = 120
```

## math.log(x[, base])
xの対数を返す
baseが指定されている場合 : その底における対数を返す
baseが指定されていない場合 : 自然対数を返す

```python
import math

x = 10
result = math.log(x)
print(f"ln({x}) = {result}")  # 出力: ln(10) = 2.302585092994046

result = math.log(x, 10)  # 底を10に指定
print(f"log10({x}) = {result}") # 出力: log10(10) = 1.0
```

## math.gcd(a, b)
a と b の最大公約数を返す

```python
import math

a = 12
b = 18
result = math.gcd(a, b)
print(f"gcd({a}, {b}) = {result}")  # 出力: gcd(12, 18) = 6
```

# math.degrees(x)
ラジアンで表された角度 x を度に変換する

```python
import math

x = math.pi / 2  # ラジアンで90度
result = math.degrees(x)
print(f"{x} radians = {result} degrees")  
# 出力: 1.5707963267948966 radians = 90.0 degrees
```

# math.radians(x)
度で表された角度 x をラジアンに変換する

```python
import math

x = 90  # 度
result = math.radians(x)
print(f"{x} degrees = {result} radians")  
# 出力: 90 degrees = 1.5707963267948966 radians
```


# まとめ
今回は、mathモジュールの関数 factorial, log, gcd, degrees, radians について紹介しました。
mathの関数は全部で60以上あるので、引き続きチャレンジしようと思います！
Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction：画像生成における自己回帰モデル(VAR)

# 画像生成における自己回帰モデル(VAR)

## この記事について
> 本記事は「Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction」の内容を解説したものです。図表は論文から引用しています。

## はじめに
近年、自己回帰型の大規模言語モデル(LLM)が注目を集めていますが、コンピュータビジョン分野でもLLMの優れた拡張性や汎化性を備えた大規模モデルの開発が求められています。しかし、従来の自己回帰型画像生成モデルは生成品質や速度の面で拡散モデルに大きく劣っており、LLMのような性能を引き出せていませんでした。本研究では、従来の「次トークン予測」という概念を「次スケール予測」に置き換えた新たな自己回帰型画像生成手法VARを提案し、この課題に取り組みます。

## 技術の基礎知識
自己回帰型モデルでは、データを離散トークンの系列に変換し、時系列の順序で次のトークンを予測していきます。画像に適用する場合は、Vector Quantized Variational AutoEncoder(VQVAE)で画像を離散トークン列に量子化し、ラスタースキャン順に予測するのが一般的です。

![IMG_3552.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610305/610ea8f6-ce8c-0fe9-93ac-35bfaa302370.jpeg)

（Fig. 2から引用）

**図の説明：**
- (a)は言語に対する自己回帰で、左から右へ単語を順番に予測
- (b)は画像の標準的な自己回帰で、画像トークンを左上から右下へラスタースキャン順に予測
- (c)がVARで、低解像度から高解像度へと、段階的にトークンマップ全体を並列に予測
- VARには、階層的なトークン化が必要

しかし、このアプローチには数学的前提の違反、汎化性の制約、構造の劣化、非効率性など様々な問題があることが指摘されています。

## 新しく提案する手法
VARでは、「次トークン予測」から「次スケール予測」へと発想を転換します。まず、画像を多段階のtoken map$(r_1, r_2, ..., r_K)$に量子化し、低解像度から高解像度へと段階的に予測していきます。各ステップでは、それまでのtokenを条件に、次の解像度のtoken map全体を並列に予測します。

![IMG_3553.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610305/20a4c4ff-3d8a-ab39-44e4-9409e6c8396a.jpeg)
（Fig. 4から引用）

**図の説明：**
- Stage 1では、多段階のVQVAEを学習し、画像を階層的なtoken mapとして特徴抽出
- Stage 2では、VAR transformerを学習し、低解像度から高解像度へと自己回帰的にtoken mapを予測
- 学習時は因果的なAttention maskで、各解像度が過去の情報のみに依存するよう制約
- 推論時はキャッシュを利用し、高速並列生成が可能

VARは、従来の問題点を解消し、計算量をO(n^6)からO(n^4)へ大幅に削減できます。

## 実験結果
ImageNet 256x256の条件付き画像生成タスクで、VARは18.65から1.73へとFIDを大幅に改善し、初めて拡散モデルを上回る性能を達成しました。推論速度も20倍高速化しています。 

![IMG_3554.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610305/0456d89d-5eda-64ed-2647-ee0a416fa118.jpeg)

（Tab. 1から引用）

**図の説明：**
- VARは全ての評価指標で最高性能を達成
- 拡散モデルのDiTと比べ、FID/ISで優位、データ効率や速度、scalabilityでも勝る
- 従来のARから大幅に改善し、拡散モデルを上回る初の快挙

さらに、VARはパラメータ数やデータ量を増やすと滑らかに性能が向上するスケーリング則に従うことが確認されました。言語モデルで見られるこの特性は、コンピュータビジョンでも再現されたと言えます。

## 今後の可能性
VARは、言語モデルの優れた特性を画像生成の分野に持ち込むことに成功しました。今後は、テキストや動画への拡張、LLMとの統合による汎用知能の実現など、様々な発展が期待されます。特に動画生成は、従来のARモデルでは計算量が膨大で実用的ではありませんでしたが、VARなら高解像度の長尺動画も効率的に生成できる可能性があります。

## まとめ
本研究では、「次スケール予測」という新たな発想で自己回帰型画像生成を再定義したVARを提案しています。VARは従来手法の問題点を解消し、画像生成タスクで初めて拡散モデルを凌駕する性能を示しました。
ChatGPT × Apple Intelligence — iPhoneやMacでさらに便利に！

OpenAIが「12 Days of OpenAI」5日目として発表したのは、**Appleデバイス**との深い統合。  
SiriやApple独自の「Apple Intelligence」機能を通じて、**iPhone・iPad・Mac**の各OSレベルでChatGPTを活用できるようになりました。  
それだけでなく、チャット履歴や生成結果をワンタップでChatGPTアプリに引き継げるなど、ユーザビリティも格段にアップしています。

この記事は[ChatGPT Advent Calendar 2024](https://qiita.com/advent-calendar/2024/chatgpt)の10日目です（空いていたので書いてみました）今年は「12 Days of OpenAI」ということで毎日発表がありましたが、その内容を復習しながらまとめます

## このアップデートのポイント

1. **Siriとの連携がスムーズに**
   - Siriが「複雑な質問だ」と判断すると、自動的にChatGPTに処理を渡してくれる。  
   - 送信前に「現在の画面を共有してよいか」などの確認が入り、**ユーザーが明示的に承認**したデータのみChatGPTへ渡る。  
   - 返答はSiriのUI上に表示されるが、ワンタップでChatGPTアプリへ移動し、続きのやりとりを行うことも可能。

2. **どのアプリからでも呼び出せる「Apple Intelligence」**
   - iOSやmacOSの「設定」→「Apple Intelligence」から**ChatGPT拡張**を有効化。  
   - 任意のアプリ（ブラウザ、PDFビューワ、メールなど）で表示中のコンテンツを素早くChatGPTに送信し、要約やコード生成などを依頼できる。  
   - 特に**Macの「ダブルコマンドキー押し」でSiriを呼び出し→ChatGPT**が便利。

3. **カメラ連携でビジュアル解析もOK**
   - iPhone 16以降では、カメラで映しているものをChatGPTに直接問い合わせることが可能。  
   - たとえば撮影中の人々を比較して「一番派手なクリスマスセーターは誰？」と尋ねると、ChatGPTがリアルタイムに回答してくれる。  
   - そのまま生成画像（Album artなど）を作ったり、ランキング評価をしてもらったりと**ユニークな使い方**が広がる。

4. **ドキュメントやPDFも一気に解析**
   - macOS上で表示しているPDFファイルまるごと、**49ページなど大容量でもChatGPTに投げられる**。  
   - ChatGPTアプリ側でやり取りを続行しつつ、要点の抽出やグラフ化、コードの自動生成などを行うことができる。  
   - 画面キャプチャだけ渡す（サマリを依頼）か、全文を送る（詳細を分析）かの選択も可能で安心。

## 実際の使い方とメリット

- **音声アシスタントとして**:  
  「Hey Siri, can you ask ChatGPT ○○?」と話しかけるだけ。認証が済んでいればシームレスに回答が返ってくる。  
  一度でもChatGPTに情報を送れば、その履歴は続きのやり取りに反映されるので会話がスムーズ。

- **PDF・長文への素早い要約**:  
  ビジネス文書や論文を開いたままSiri→ChatGPTに送信すれば、**アウトラインや要点を高速で抽出**できる。  
  追加で「この内容をチャートにして」「全文をもう少し簡単に」などのリクエストも可能。

- **画像認識で遊びやすさアップ**:  
  動画でも紹介されていた「クリスマスセーターのコンテスト」では、撮影中の人物を解析してChatGPTがランキング化してくれたり、専用の優勝トロフィー風画像を生成してくれたりと、パーティーシーンが一気に盛り上がる。

## まとめ

**iPhoneやMac上でのChatGPT連携が、一段と身近かつパワフルに**なった印象です。  
「Siriから手軽に振る」「大きなPDFをまとめて送って要約」「カメラを通じたリアルタイム画像解析」など、既存ユーザーはもちろん、新規ユーザーにも魅力的な機能が盛りだくさん。  
あらためて、**スマートフォンやPCの“OSレベル”でChatGPTが根付く時代**が来たと実感させられるアップデートでした。

---

**参考動画**: [ChatGPT x Apple Intelligence—12 Days of OpenAI: Day 5 - YouTube](https://www.youtube.com/watch?v=mBhkD0iFf4w)
Vivadoでxvlogが無限に停止しなくなった時の対処法

# はじめに
この記事はVivadoを用いてコマンドプロンプト上にてVerilogファイルのシミュレーションを行おうとした際に、プログラムが停止しなくなった時の対処法についてです。同じ現象を踏んだ人のために備忘録として残しておきます。

# xvlogとは
Vivadoのシミュレーションをコマンドライン上で行う際、まず最初にxvlogコマンドを用いて以下のように使用するファイルを分析させておく必要がある。
```
xvlog --sv [SystemVerilogもしくはVerilogのファイル]
```
この際依存関係があるファイルがあるならば、それも同時に読み込ませる必要がある。

# xvlogが止まらない
しかし、ある日xvlogを実行しようとするとプロセスが止まらなくなってしまった。CPU使用率などを見ると20%程度を保っているため、プロセスが固まっているわけでは無さそう。しかもある特定の一部ファイルを読み込ませたときにのみ停止しなくなり、それ以外の時は正しくファイルが出力されるため、xvlogそのものが壊れたわけでもない。

# 対処法
結論から言うと、xvlogは既に分析したファイルの情報をある程度キャッシュして持っており、これを参照することで毎回の動作を高速化しているが、このキャッシュデータにミスがあり無限ループが発生していた。
そのため、対処法は単純に該当キャッシュファイルを削除してやればよい。シミュレーションを実行したディレクトリの`./xsim.dir/work/work.rlx`というファイルを見てあげると、各moduleの依存関係をcsvのような何かの形式で保存されていることが分かる。そのためこのファイルの中から動作が停止するプロジェクトに該当する行を見つけ出し、その行を削除すればよい(もしくは面倒ならwork.rlxそのものを吹き飛ばすほうが速い)。もしそれでも解決しないなら、同ディレクトリにある`.sdb`ファイルおよび一つ上のディレクトリにある`.sim`ディレクトリ以下をすべて削除してから再度実行すると治る。
今回の案件では`A.sv`と`B.sv`に対して、なぜか`A.sv`は`B.sv`を、`B.sv`は`A.sv`を参照するような循環参照が発生していたため、ファイルの解析が無限に停止しなくなっていたものと思われる(実際のmoduleの構成としてはそのようなことはなく、`A.sv`が`B.sv`に依存しているのみであった)。

# 終わりに
Vivado初心者が故、このような単純な問題でも解決に時間を要してしまった。僕が探した範囲ではこの問題の解決策を提示しているものを見つけられなかったため、この情報が同じ問題を踏んだ人の参考になれば幸いである。
Emacs Lisp 超初心者がコマンドを作ってみる 〜 if文のクセ 〜

理解を進めるために、 Emacs Lisp の諸々について、他のプログラミング言語と見比べてみます。

# if
EXCELのワークシート関数 if に似ています。 EXCEL のは if(condition, then, else) ですけども Emacs Lisp のは

````elisp
( if condition then-form else-forms… )
````

となっています。

前回より、再掲
````elisp
(if (not untranslated-regions)
    (error "Nothing previous msgid."))
````

このように else-forms... を省略することもできます。

Emacs Lisp (Lisp?) の if のハマりどころとして、 then-form は「1個だけ」ですが、 else-form は0個以上というのがあります。

````elisp
(if condition (A) (B))
````

これをC言語で書くと

````C
#include <stdio.h>
void main(int argc, char *argv[]);

void main(int argc, char *argv[])
{
  if (argc > 1)
    printf("exit args\n");
  else {
    printf("no args\n");
  }
}
````

注意して欲しいのは then が 単文 ( { と } で囲まれてない) けど、 else は複文( { と } で囲まれている)という点です。

よって、

````elisp
(if condition (A) (B) (C) (D) (E) (F))
````

はC言語でに書くと

````elisp
#include <stdio.h>
void main(int argc, char *argv[]);

void main(int argc, char *argv[])
{
  if (argc > 1)
    printf("exit args\n");
  else {
    printf("no args\n");
    printf("C\n");
    printf("D\n");
    printf("E\n");
    printf("F\n");

  }
}
````

となります。 どうしても then に複数の文を入れたい時は progn を使います。

````elisp
(if (conditon) (progn (A) (B) (C)) (D) (E) (F))
````

::: note warn
なので、 C言語で { } を追加するみたいに if-else 文を
````elisp
(if conditon
    (
     (A) (B) (C)
    )
    (D) (E) (F)
````

とやると Invalid-function エラーで怒られます。

:::


今回はここまで
LeetCodeを1日1題解いてみる (day48)

48日目に取り組んだ問題はこちら！

# 598. Range Addition II

https://leetcode.com/problems/range-addition-ii/?lang=pythondata

## 問題文
You are given an m x n matrix M initialized with all 0's and an array of operations ops, where ops[i] = [ai, bi] means M[x][y] should be incremented by one for all 0 <= x < ai and 0 <= y < bi.

Count and return the number of maximum integers in the matrix after performing all the operations.

## 僕の回答 (失敗作)
```py
class Solution:
    def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int:
        M = [[0] * n for _ in range(m)]
        if not ops:
            return m * n
        for oper in ops:
            a, b = oper
            for i in range(a):
                for j in range(b):
                    M[i][j] += 1
        max_val = None
        max_count = 0
        for i in range(m):
            temp = max(M[i])
            if not max_val or temp > max_val:
                max_val = temp
                max_count = 0
            if max_val == temp:
                max_count += M[i].count(max_val)
        
        return max_count
```
`Memory Limit Exceeded`で失敗で終わってしまった。

## 回答例

```py
class Solution:
    def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int:
        if not ops:
            return m * n

        # 操作の行数と列数の最小値を求める
        min_row = min(op[0] for op in ops)
        min_col = min(op[1] for op in ops)

        # 最大値が存在する領域の面積
        return min_row * min_col
```

## 学んだこと
`M = [[0] * n] * m`は、`0`が`n`個ある配列を`m`行分作って初期化するという意味だと思っていたが、実際には、`[[0] * n]` のリストへの参照が`m`回複製されるという意味だった。

## コメント
僕は丁寧に１つずつ計算してそこから最大値を探して最大値の個数を数えるという平凡な案しか思いつかなかったが、回答例は美しい解法でびっくりしました。柔軟に考えられるようになりたいです。

## 次の問題はこちら!
https://qiita.com/h_y_s_d/items/cdf12c549bd369aca699
【cron設定】Raspberry Pi 5 でスケジュール実行する。

# 1.今回確認した動作環境
・Raspberry Pi5 （Raspberry Pi OS）

# 2.cronで出来ること
・cronはLinux標準のジョブスケジューラーの常駐プログラム。
・任意の時間に指定のLinuxコマンドやプログラムを実行できる。

# 3.cronの状態確認・環境設定
## 3.1.状態確認
デフォルトでは常駐起動しているcronが実行中か確認します。
```bash:
sudo /etc/init.d/cron status
```
コマンド実行後に「Active:」が「active (running)」になっていれば実行中です。
## 3.2.cronの開始・停止・再起動
cronの開始
```bash:
sudo systemctl start cron
```
cronの停止
```bash:
sudo systemctl stop cron
```
cronの再起動
```bash:
sudo systemctl restart cron
```
## 3.3.タイムゾーンの設定
cronの開始
```bash:
timedatectl set-timezone Asia/Tokyo
```
# 4.cronジョブの設定
ジョブ登録を行うcronタブの起動
```bash:
crontab -e
```
初回cronタブ起動時にはどのエディタを使うか選択肢が表示されます。
お好みで。
```bash:
no crontab for user_name - using an empty one
Select an editor.  To change later, run 'select-editor'.
 1. /bin/nano        <---- easiest
 2. /usr/bin/vim.basic
 3. /usr/bin/vim.tiny
 4. /bin/ed
Choose 1-4 [1]: 
```
設定例：ホームディレクトリに決まった時間でログ書き込み。
```bash:
# 毎日10時にlogにHELLO WORLDを出力
00 10 * * * echo "HELLO WORLD" > ~/hello.log 2>&1
```
「00 10 * * *」の部分が日時などの設定です。
|単位|指定内容|
|:-|:-|
|minute|「0~59」分を指定|
|hour|「0~23」時を指定|
|day|「1~31」日を指定|
|month|「1~12」月を指定|
|day of week|「0~6」曜日を指定　0:日曜|

|設定例|説明|
|:----|:----|
|1,2,3|カンマ区切りで複数の値を指定|
|1-10|連続した時間を指定。minuteで左記の値を入力すると1-10分に処理を実行|
|1,2,3,1-10|上記２つを同時に指定も出来る|
|1-10/2|minuteで左記の値を入力すると1-10分の間で２分おきに処理を実行|

設定内容を確認
```bash:
# 設定内容を確認
crontab -l
```
米田の補題 #5 対象と射　補足説明

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

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

# 対象と射は単純ではありません。

対象は一つで、しかも複数の射があってもいいのです。この図では、しかも特別の射である恒等射が書かれています。恒等射については、定義④で説明します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/2c0a657e-8ac0-0c84-a6bf-b4d11520c022.png)

射、対象ともに同じか違うかを識別できます。
射は、（域、射の値、余域）の３つの組からなっているので、射の値が違えば、域、余域が同じでも全体としての射は異なるものになります。そして、域と余域は、同じでも違う射になり、複数の射がありえるのです。このあたりから、素朴な矢印の世界からは離れます。

**米田の補題川柳　ひとつでも中身があるなら面白い**
対象は、内部構造がないという前提で話がすすんできましたが、内部構造があるものを扱うのが、数学上の考察です。普段の生活の接点で言うと、普段の会話での質問は内部構造がよくわかっていないのではっきりさせる過程だとも言えます。量子コンピューターとよく似てますね。だんだんとはっきりさせる過程はadvent calendar で最初のうちは扱いません。でも実際に活躍するのは、だんだんと進む過程です。
ゼロから始めるSnowflake（1/10）

# 初めてのSnowflake入門
これからSnowflakeを始める人向けに複数の記事に分けて解説を行う．

## Snowflakeとは？
Snowflakeはクラウドベースのデータウェアハウスである．従来型のデータウェアハウスと比べて，以下の特徴がある．

- **完全クラウドネイティブ**：AWS，Azure，Google Cloud上で動作し，インフラ管理を意識する必要がない．
- **スケーラブル**：ストレージとコンピュートが分離されており，必要に応じてリソースを柔軟に拡張可能．
- **マルチクラウド対応**：複数のクラウドプロバイダー間で一貫性のある環境を提供．
- **使いやすさ**：SQLをベースにした操作と直感的なWeb UIで，データ分析を簡単に実行．

Snowflakeはデータの**統合**，**変換**，**分析**に特化しており，現代のデータドリブンな組織に適している．

---

## Snowflakeのオブジェクトの概念
Snowflakeでは，データを管理するためにさまざまなオブジェクトが提供されている．主なオブジェクトの概要を以下に示す．






### 1. **Database（データベース）**
データを論理的にグループ化する単位．1つのデータベース内に複数のスキーマやテーブルを持つことができる．

```sql
CREATE DATABASE example_db;
```

### 2. **Schema（スキーマ）**
データベース内でさらにデータを整理するためのコンテナ．スキーマ内にはテーブルやビューを作成する．

```sql
CREATE SCHEMA example_schema;
```

### 3. **Table（テーブル）**
データを格納する基本単位．Snowflakeでは，通常のテーブル（Permanent Table）のほかに，以下の種類がある．
- **一時テーブル（Temporary Table）**：セッション終了時に削除される．
- **トランジエントテーブル（Transient Table）**：バックアップ不要なデータ向け．

```sql
CREATE TABLE example_table (
    id INT,
    name STRING,
    created_at TIMESTAMP
);
```

### 4. **View（ビュー）**
SQLクエリの結果を仮想的なテーブルとして定義．データを物理的に持たない．

```sql
CREATE VIEW example_view AS
SELECT id, name FROM example_table WHERE id > 10;
```

### 5. **Warehouse（ウェアハウス）**
Snowflakeにおけるコンピュートリソース．クエリの実行やデータ処理を担当する．スケーリングや停止が簡単にできるため，コスト効率が高い．

```sql
CREATE WAREHOUSE example_wh
WITH WAREHOUSE_SIZE = 'XSMALL';
```

---

## Snowflakeのコストの考え方
Snowflakeのコストモデルは，**ストレージコスト**と**コンピュートコスト**の2つが主要な要素である．

### 1. **ストレージコスト**
- データの保存にかかるコスト．
- GB単位で課金され，保存データ量に比例する．
- 圧縮技術により，コスト効率が良い．

### 2. **コンピュートコスト**
- クエリの実行やデータ処理にかかるコスト．
- **ウェアハウス（Warehouse）**の稼働時間に基づいて課金される．
- ウェアハウスのサイズが大きいほど高コストになるが，クエリのパフォーマンスが向上する．

| ウェアハウスサイズ | 仮想CPU数 | コスト（時間単位） |
|-------------------|----------|------------------|
| XSMALL           | 1        | 低               |
| SMALL            | 2        | 中               |
| MEDIUM           | 4        | 高               |

### 3. **コスト削減のポイント**
- **必要な時だけウェアハウスを起動**：クエリの実行後は自動で停止する設定を活用．
- **クエリの最適化**：不要なデータスキャンを減らし，効率的にクエリを実行．
- **データのライフサイクル管理**：古いデータをアーカイブして，ストレージコストを削減．

---

## まとめ
Snowflakeは，シンプルな使いやすさと強力なスケーラビリティを兼ね備えたクラウドデータウェアハウスである．オブジェクトの概念やコストモデルを正しく理解することで，効率的なデータ分析基盤を構築できる．
[tauri] アプリの背景色を透明にするときはまった話

## tl;dr
`tauri.config.json`で`decorations: false`、`transparent: true`を設定し、`macOSPrivateApi`も設定する。
``` json
{
  "app": {
    "windows": [
      {
        "width": 360,
        "height": 280,
        "decorations": false,
        "transparent": true,
        "shadow": false,
        "fullscreen": false,
        "resizable": false,
        "maximizable": false
      }
    ],
    "macOSPrivateApi": true
  }
}
```
## 今回試したこと
Webviewの方でborder-radiusをかけたら、角に白い部分が残っていた。

![Screenshot 2024-12-22 at 23.30.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754242/d8d63fba-b993-e3df-ea96-4619f49dbdec.png)

bodyタグ、htmlタグに`background: transparent`をかけても直らなかった。
vueのアプリであったため、id="app"の要素にもcssをかけてみたが直らず...

## `tauri.config.json`の見直し

https://stackoverflow.com/questions/77344488/tauri-transparent-window-only-works-when-resized

`decorations: false`、`transparent: true`を設定するとできるという話を複数見かけた。これでいけた人が多そうだったが、それでも直らず

## 解決：`macOSPrivateApi`の設定

https://v1.tauri.app/v1/api/config/#theme

v1のドキュメントに以下のようなことが書いてあったので、試してみたら成功

> Note that on macOS this requires the macos-private-api feature flag, enabled under tauri > macOSPrivateApi. WARNING: Using private APIs on macOS prevents your application from being accepted to the App Store.

v2のドキュメントにも書いてそうではあるが、読みづらすぎて全然目に入らなかった。。。

https://v2.tauri.app/reference/javascript/api/namespacewebview/#properties-1

## おわりに
このように長く詰んでるとき、結局はドキュメントで解決することが多い。
もっと読み込もう.. tauri v2のドキュメントもう少し読みやすくしてくれないかな
GPUの性能を最大限引き出す！FlashRNNによる50倍高速化

# GPUの性能を最大限引き出す！FlashRNNによる50倍高速化

## はじめに
近年、自然言語処理や時系列予測などの分野では、**Transformer**に代表されるシーケンス並列化可能なニューラルネットワークが大きな成功を収めています。しかし、これらのモデルは状態追跡能力に欠けるという課題があります。一方、**RNN**（Recurrent Neural Network）は状態追跡に優れていますが、逐次的な処理が必要なため、GPUの性能を十分に引き出せないという問題がありました。

> RNNの逐次処理は、GPUの大規模並列処理能力を活用できない。

そこで本研究では、**FlashRNN**というRNNの高速化手法を提案します。FlashRNNは、GPUのキャッシュ階層を考慮した最適化により、RNNの計算を高速化します。

## 技術の基礎知識
RNNは、各ステップの隠れ状態が前のステップに依存する逐次的なモデルです。**LSTM**や**GRU**などのRNNでは、ゲートと呼ばれる制御機構により、長期的な依存関係を学習できます。しかし、RNNの実装では、行列積と要素ごとの非線形演算が交互に現れるため、メモリアクセスがボトルネックになります。

![IMG_3550.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610305/1319ec6d-e444-087c-5d2b-ba06c6088367.jpeg)


> GPUは、レジスタ、SRAM、HBMの階層的なメモリ構成を持つ。

単純なRNNの実装では、これらのメモリ階層を効果的に活用できず、GPUの性能を十分に引き出せません。

## 新しく提案する手法
FlashRNNは、RNNの行列積と非線形演算を1つのカーネルに融合し、レジスタとSRAMを活用してメモリアクセスを最小化します。時間方向のループをカーネル内に組み込むことで、重み行列や状態をレジスタにキャッシュし、HBMへのアクセスを大幅に削減します。

さらに、FlashRNNでは、RNNを複数の**ヘッド**に分割し、ヘッドごとに並列処理を行います。ヘッドサイズとバッチサイズを適切に調整することで、メモリ使用量とパフォーマンスのトレードオフを制御します。

最適なタイリングサイズは、**ConstrINT**という整数制約充足ソルバーにより自動的に求められます。

$\text{Tiling Size} = \arg\max_{\text{size}} \text{Performance}(\text{size}) \text{ s.t. } \text{Memory Constraints}$

## 実験結果
FlashRNNの性能を評価するため、言語モデルの学習と状態追跡タスクにおいて、FlashRNN LSTMとTransformerを比較しました。

![IMG_3551.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2610305/08f32992-4eda-d9c5-bf89-2a8c4df4b69f.jpeg)


8つのH100 GPUを用いた学習では、LSTMは単一ヘッドでTransformerより40%程度遅くなりましたが、12ヘッド構成ではその差は25%程度に縮まりました。状態追跡タスクでは、LSTMは完璧な精度を達成し、Transformerを大きく上回りました。

> FlashRNNの融合カーネルは、PyTorchの50倍、cuDNNの3倍高速。

バッチサイズが小さい場合は、融合カーネルの方が交互カーネルより2-4倍高速でしたが、大きいバッチでは交互カーネルがスケールしました。

## 今後の可能性
FlashRNNにより、RNNの推論と学習の高速化が実現しました。これにより、状態追跡が必要な時系列予測やロジカル推論など、Transformerの苦手な問題への応用が期待できます。

今後は、非同期メモリ操作やSRAM間通信など、より新しいGPUの機能を活用した最適化が課題です。FlashRNNのソースコードは公開されており、RNN関連研究の新たな基盤となることが期待されます。
List<T>について調べてみた / I looked into List<T> (日本語 / 英語)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/3a7b401e-0b6b-0df7-d968-b912a1b8b7eb.png)
# 日本語
こんばんわ！
Advent Calendar 2024に参加してまして、23日目の記事を書いていこうと思います。
題材は「C# Advent Calendar 2024」ということで、List<T>について書いていこうと思います。

### List<T> とは？
C# の List<T> クラスは、最もよく使われる汎用コレクションの一つです。配列と似ていますが、サイズ変更が可能で、便利なメソッドが多数用意されているのが特徴です。

###### ・任意の型 (T) のデータを扱えるジェネリックコレクション。
###### ・要素の追加・削除が簡単。
###### ・インデックスによる要素のアクセスが可能。
###### ・様々なメソッドで柔軟な操作が可能。

### 使用例

```csharp
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

class Program
{
    static void Main()
    {
        // リストの宣言と初期化
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        // 要素の表示
       foreach (var l in CollectionsMarshal.AsSpan(list))
        Console.WriteLine($"{l}");
    }
}
```

また、CollectionsMarshal.AsSpan()を使って、リストの要素をメモリ領域することで、foreachループで要素にアクセスする際のパフォーマンスが向上します。←いただいたコメントから学べました♪

### 操作
```csharp
numbers.Add(6);                // 単一要素を追加
numbers.AddRange(new[] { 7, 8 }); // 複数要素を追加

numbers.Remove(3);  // 値 3 を削除
numbers.RemoveAt(0); // インデックス 0 の要素を削除
numbers.Clear();     // 全要素削除

bool hasFive = numbers.Contains(5); // true
int index = numbers.IndexOf(4);     // 3 (値 4 のインデックス)

numbers.Sort();   // 昇順に並べ替え
numbers.Reverse(); // 要素を逆順に
```

とこんな風に可変的なリストに対し、柔軟な操作を行えるようになります！
とても便利ですね

ここまでです。
読んでいただきありがとうございます
# ENGLISH
Good evening!
I am participating in Advent Calendar 2024 and I am going to write an article for the 23rd day.
The subject is “C# Advent Calendar 2024” and I will write about List<T>.

### What is List<T>?
C#'s List<T> class is one of the most commonly used generic collections. It is similar to an array, but it is resizable and has a number of useful methods.

###### ・Generic collection that can handle data of any type (T).
###### ・Elements can be easily added and removed.
###### ・Elements can be accessed by index.
###### - Flexible operations with various methods.

### Example usage

```csharp
using System; using System.
Generic; using System.Collections.
InteropServices; using System.Runtime.

InteropServices; class Program
{
    static void Main()
    {
        // Declare and initialize the list
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        // Display the elements
       foreach (var l in CollectionsMarshal.AsSpan(list))
        Console.WriteLine($“{l}”);
    }
}
```

Also, using CollectionsMarshal.AsSpan() to memory area the elements of the list improves performance when accessing the elements in the foreach loop. ← I learned from the comments I received...

### Operation.
```csharp
numbers.Add(6); // add a single element
AddRange(new[] { 7, 8 }); // add multiple elements

numbers.Remove(3); // remove value 3
RemoveAt(0); // remove element with index 0
numbers.Clear(); // remove all elements

bool hasFive = numbers.Contains(5); // true
int index = numbers.IndexOf(4); // 3 (index with value 4)

Sort(); // sort in ascending order
numbers.Reverse(); // sort elements in reverse order
````

and so on! Very useful!

That's all for now.
Thank you for reading!
Canvas で文書もコードも快適編集！OpenAI が新ツールを投入

「**Sora**」の大盛況に続いて、今回は **Canvas** というコラボエディタ機能が登場しました。  
サイドバイサイドで **ChatGPT** と文書やコードの共同作業ができるうえ、 **Python** を直接実行して結果をすぐに確認できるのが目玉。  
これまでの「テキスト出力を都度コピペ」という不便さが一気に解消される、画期的なアップデートといえます。

この記事は[ChatGPT Advent Calendar 2024](https://qiita.com/advent-calendar/2024/chatgpt)の9日目です（空いていたので書いてみました）今年は「12 Days of OpenAI」ということで毎日発表がありましたが、その内容を復習しながらまとめます

---

## Canvas の主な特徴

1. **文書モードとコードモードを自動判別**
   - 文書ならワープロ感覚で文章を編集し、ChatGPT から提案や訂正を得られる。  
   - コードならシンタックスハイライトや即時実行ができる。  
   - ChatGPT が適切と判断すれば、自動で Canvas を開いてくれる。

2. **Python 実行を内蔵**  
   - WebAssembly 版 Python がエディタ内に組み込まれていて、解析やグラフ描画を瞬時に実行。  
   - 実行結果やエラーログはそのまま ChatGPT に渡され、即フィードバックが可能。  
   - ChatGPT がエラーをチェックし、自動的に修正してくれる（コメントに「Fix Bug」などのボタンが出現）。

3. **リアルタイム共同編集 (ChatGPT + 自分)**  
   - サイドバイサイドでエディタを表示し、ChatGPT とユーザーが同一ドキュメントを同時に編集するイメージ。  
   - 文章の校正コメントや差分 (Diff) がわかりやすい。  
   - **「Add Emojis」や「Adjust Length」** など、ワンクリックで行える便利ボタンも多数搭載。

4. **Custom GPT への統合**  
   - 既存・新規のカスタム GPT に対して、「Canvas」の機能を有効化できる設定を追加。  
   - 例えば「Santa’s GPT」という Custom GPT を作り、「すべての返信を Canvas に表示してね」といった指示をすれば、自動でエディタを介して文章を生成してくれる。

---

## 使い方をざっくり解説

### 1. Canvas の基本操作

- **文書作成**  
  1. ChatGPT の入力欄（Composer）の “ツール” ボタンを押し、「Canvas」を選択。  
  2. 作成したい内容を文章で指示すると、右側にエディタが出現。  
  3. ChatGPT と自分、どちらも編集可能。文字装飾や見出しなどの基本操作も OK。

- **既存テキストの取り込み**  
  - もしチャット欄に一度に大量のテキストをペーストした場合、「Open in Canvas」ボタンが表示される。  
  - ボタンを押すと、そのテキストをまるごと Canvas に読み込める。  

### 2. コメントと修正提案機能

- ChatGPT が文章中の具体的な箇所をハイライトしてコメントをつける。  
- コメント欄に「Apply」ボタンがあれば、自動で該当箇所を修正。  
- 手動で修正した場合はコメントを「Dismiss」して処理完了にする、というフロー。

### 3. Python コード実行

- **Canvas がコードと認識すると、自動的にコードモードへ**  
- 「Run」ボタンを押すと、WASM 版 Python が即時にコードを実行し、出力やエラーを画面下部に表示。  
- エラーが出ると、エラー内容を ChatGPT が取得してコメントをつけてくれる。  
- 「Fix Bug」ボタンを押すと、ChatGPT がコードを自動修正 → 差分を確認できる。

### 4. Custom GPT との連携

- Canvas 機能は **「GPT の編集設定画面」** でチェックを入れるだけで有効化可能。  
- Custom GPT に「必ず Canvas を使って文書を作成する」などの指示を加えると、ユーザーが何か入力した際に、ChatGPT 側が「Canvas が適切」と判断して自動でエディタを開いてくれる。  
- スタイルや文体なども Custom GPT の設定で自由にカスタマイズ。

---

## 今回のリリースまとめ

- **全プランのウェブユーザーに Canvas を提供**  
  - 無料ユーザーも含め、誰でも Canvas 機能が利用可能になる。  
- **「Open in Canvas」ボタンで、大きめのテキストを一発編集**  
- **Python コードの実行とグラフ生成が超高速**  
- **カスタム GPT (ChatGPT Store) にも組み込めるように**

今回の Canvas は **文書執筆 + コード支援** が大きく強化された印象です。  
リアルタイムにエディタ上で ChatGPT と共同作業できるのは、学習効率や生産性向上に直結しそう。  
特にプログラミングのデバッグや数値解析では **「対話型 IDE」** としての活用幅が大きく広がります。
[Python] math : sqrt / pow / ceil / floor / fabs

先日、Pythonで`math`関連の関数を使ったので、復習としてメモ。

# mathの関数 : sqrt / pow / ceil / floor / fabs
## `math.sqrt(x)`

xの平方根を返す

```python
import math

x = 25
result = math.sqrt(x)
print(f"√{x} = {result}")  # 出力: √25 = 5.0
```

## `math.pow(x, y)`

xのy乗を返す

```python
import math

x = 2
y = 3
result = math.pow(x, y)
print(f"{x}^{y} = {result}")  # 出力: 2^3 = 8.0
```

## `math.ceil(x)`

x以上の最小の整数を返す（切り上げ）

```python
import math

x = 3.2
result = math.ceil(x)
print(f"ceil({x}) = {result}")  # 出力: ceil(3.2) = 4
```

## `math.floor(x)`

x以下の最大の整数を返す（切り捨て）

```python
import math

x = 3.8
result = math.floor(x)
print(f"floor({x}) = {result}")  # 出力: floor(3.8) = 3
```

## `math.fabs(x)`

xの絶対値を返す

```python
import math

x = -5
result = math.fabs(x)
print(f"|{x}| = {result}")  # 出力: |-5| = 5.0
```

# まとめ
今回は、mathモジュールの関数について、5つ紹介しました。
他にもたくさんあるので、改めてご紹介します！
Redisでのキャッシュ互換性確保の戦略

# この記事について
サービス運用中にRedisのキャッシュ互換性で困った経験について書きます。

# 何が起きたのか
運用中のサービスで、APIのドメインを変更した際に、Redisのキャッシュ取得時にエラーが発生しました。
例えばUserというドメインがあり、以前のデータ構造は以下の通りです。
```
{
    "id": 1,
    "name": "Alice",
    "age": 20
}
```
キャッシュのキーは一意のidを使用していました。ここに新たに`gender`というフィールドを追加し、その変更を行なったAPIをデプロイしようとしKubernetesクラスター上で旧APIのPodと新APIのPodが混在する状況が発生した際に、旧APIのPodがidをキーとして新APIのキャッシュデータを取得しようとすると、存在しない`gender`フィールドが原因でエラーが発生し、逆に新APIのPodが旧APIのキャッシュデータを取得しようとすると、存在するはずの`gender`フィールドが無いためエラーが頻発しました。

このような状況ではキャッシュ取得がうまくいかず、サービス全体のパフォーマンスが低下してしまいます。そこで、この問題をどのように解決したかについて説明します。

# どうやって解決したか
この問題を解決するために、新バージョンのドメインに予め追加しておいた`gender`フィールドと共に`version`フィールドを追加しました。
```
{
 "id": 1,
 "name": "Alice",
 "age": 20,
 "gender": "Woman",
 "version": 20241201
}
```
さらに、キャッシュキーにもバージョン情報を追加しました。新バージョンのAPIでは`id`と`version`がなければ、キャッシュがヒットしなくなります。
```
user-1-20241201
```

## なぜversionを追加したか
`version`フィールドを追加することで、新旧APIのキャッシュを区別できるようにしました。旧APIで作成・取得されるキャッシュには`version`フィールドが無いため、新APIでは取得されません。逆に、新APIで作成・取得されるキャッシュには`version`フィールドがあるため、旧APIでは取得されません。

## versionの値はどうするか
`version`の値は、APIのドメインを変更した日付を採用しました。APIのコミットハッシュを使用することも考えましたが、デプロイのたびに変わるためキャッシュの効果が薄れてしまいます。そのため、ドメインに変更があった場合にバージョンの日付を変更する運用を採用しました。

# まとめ
このように、APIのドメインを変更した際にRedisのキャッシュ互換性を保つために、`version`フィールドを追加し、キャッシュキーにもバージョン情報を追加することで、新旧APIのキャッシュを区別できるようになりました。