OmniAICreator/Qiita-1.07M huggingface dataset:
DBでインデックスを使う理由とその原理を理解する

## はじめに
私は仕事でRuby on Railsのバックエンド開発をしているのですが、マイグレーションファイルを作成するとき、このテーブルのこのカラムに対してインデックスを貼るべきかどうかで迷うことが多いです。

そもそも、なんでインデックスを使っているのかが完全にわかっていなかったので、何にインデックスを貼るべきがわかりませんでした。

また、すでに運用しているテーブルに新しくインデックスを貼ったら、デプロイでものすごい時間がかかることを見たことがあります。その時に「なんで時間がいっぱいかかるんだろ？」と疑問に思いつつちゃんと理屈を調べていなかったため、今回はインデックスについて原理を含めてなぜ使うのかを理解してみました。

## インデックスとは？
そもそもインデックスとはなんでしょう？「貼る」という動詞と一緒に使われているイメージはありましたが、まず実態が知りたいところです。

### 意味

> データベースのテーブルに対する検索速度を向上させるデータ構造
>
>テーブルの特定カラムに対してインデックスを生成するとそのカラムのデータをソートし、別途のメモリ空間に物理アドレスと共にkey valueの形で保存される

なるほど、インデックスというものはDBの中身を元に「ソート」し、メモリの中に入れておくということですね。

「貼る」と表現しているのも、DBとは別で状態をメモリに持つこととなるので、「貼って」おくイメージになると理解できました。

### 必要性
#### 線形データの限界
DBは基本的に線形データとしてどんどん保存される仕組みで、以下のように入ってきた順番で並びます。

``` mermaid
graph TD
    subgraph "DB内の線形データ"
        A1[["15, 3, 27, 8, 42, 11, 30, 5"]]
    end

    style A1 fill:#f9f,stroke:#333,stroke-width:2px
```

ここで問題があります。`15`を探したい時にはすぐ見つかりますが、`5`を探すためにはこのデータの中身を全部見る必要が出てきます。

例ではデータが8個しかありませんが、もし10万、もしくは10億のデータが存在すると検索するものによっては検索にかかる時間が大きく異なることになります。

また、線形データはデータの`不在`を検出するためにも全データを見回る必要があります。

#### インデックスでできること

インデックスは、以下のようなことができます。
1. どんな要素を検索しても、同じような時間がかかるようにする
2. 範囲検索を容易くする

なぜこのようなことができるのでしょう？
以下の図を見てみましょう。

インデックスで出来上がったソートされたデータは一見線形データに見えていてあまり特別な感じがしませんね。

``` mermaid

graph TD
    subgraph "DB内の線形データ"
        A1[["15, 3, 27, 8, 42, 11, 30, 5"]]
    end

    subgraph "ソートされたインデックスデータ"
        B1[["3, 5, 8, 11, 15, 27, 30, 42"]]
    end

    A1 --> B1

    style A1 fill:#f9f,stroke:#333,stroke-width:2px
    style B1 fill:#bbf,stroke:#333,stroke-width:2px
```

実は、このソートをするためにはよくB+Treeというデータ構造が使われています。
非線形のTreeになっていることで、どんなデータに対しても同じような実行時間でデータを探すことができます。

線形データでは`30`というデータを探すため、15, 3, 27, 8, 42, 11, 30の7回でデータが見つかるのですが、ツリーだと15, 27, 30の3回でデータを見つけることができます。

``` mermaid
graph TD
    subgraph "Step 1: 線形データ"
        A1[["15, 3, 27, 8, 42, 11, 30, 5"]]
    end

    subgraph "Step 3: ソート済みデータ"
        B1[["3, 5, 8, 11, 15, 27, 30, 42"]]
    end

    subgraph "Step 2: B+Tree構造"
        C1[["15"]]
        C2[["8"]] --> C1
        C3[["27"]] --> C1
        D1[["3, 5"]] --> C2
        D2[["11, 13"]] --> C2
        D3[["15, 19, 23"]] --> C3
        D4[["30, 42"]] --> C3
    end

    A1 --> C1
    C1 --> B1

    style A1 fill:#f9f,stroke:#333,stroke-width:2px
    style B1 fill:#bbf,stroke:#333,stroke-width:2px
    style C1 fill:#bfb,stroke:#333,stroke-width:2px
    style C2 fill:#bfb,stroke:#333,stroke-width:2px
    style C3 fill:#bfb,stroke:#333,stroke-width:2px
    style D1 fill:#eff,stroke:#333,stroke-width:2px
    style D2 fill:#eff,stroke:#333,stroke-width:2px
    style D3 fill:#eff,stroke:#333,stroke-width:2px
    style D4 fill:#eff,stroke:#333,stroke-width:2px
```

同じような理屈で、ツリーは範囲の検索やデータの不在もすぐ見つけることができます。

## どこでインデックスを使う？
もちろんですが、データの検索頻度が高いと効率よく使うことができそうです。

また、データの範囲が広いとtreeにまとまったノードを集めるだけでデータの検索ができるので良さそうです。また、ソートされたデータ構造になるため、ソートされて欲しい時にもインデックスを貼った方が良さそうです。

## おわりに
SQLでSELECT句はなぜFINDではないんだろ？と思ったことがありましたが、条件にあったデータを「選択」して上の図のようなソート済みデータを作成するところからSELECTと呼んでいるのかな？と思いました。

今度はB+Treeについてももっと深掘りしていきたいですね~

## 参考

https://products.sint.co.jp/siob/blog/index
【VRChatワールド制作】アイテムのコライダーと衝突してプレイヤーが吹っ飛ぶ現象の解決方法

# 【問題点】

　コライダーを設定したアイテムをインタラクトするとプレイヤーが吹っ飛んでしまいます。

(コライダーが設置されたアイテムを掴む)
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/7a4588b0-e44b-aa91-6605-bda7ea97d6f5.png)

↓

(吹っ飛ぶ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/b1c0a721-e18b-b1b6-6ac8-d7989068e035.png)


#  【回答】

　プレイヤーがコライダーに衝突した際、何らかの作用を行うという設定にしているため、吹っ飛びます。
　レイヤーごとに設定されているコライダー接触時の作用をオフにすることで、アイテムをインタラクトした際に吹っ飛ばなくなります。

# 【解決策】


 ### ①コライダーを設置しているアイテムに新しいレイヤーを設置します。
　コライダーを設置しているアイテムのインスペクターからLayerタブのプルダウンを押下します。Layer下部のAdd Layerからレイヤーを追加します。
今回は、coliderresolveを追加しました。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/32133833-6002-ff55-d374-435c29ec8cf7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/c6011bda-a80a-2939-dd66-02b375ef20d2.png)

### ②アイテムのインスペクターから先ほど作成したレイヤーを設定します。

　先ほど作成したcoliderresolveを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/ef7eafca-baf2-1a59-0baa-66754fc6f593.png)

### ③上部メニューバーのEditからProjectSettingsを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/cdbdc84f-f6dc-bb77-a42e-bc23861277b0.png)

### ④ProjectSettings > Project > PhysicsからLayer Collision Matrixまでスクロールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/2b2b83bb-4d7b-6aa1-6d04-89567efd9411.png)



### ⑤先ほど作成したレイヤーからPlayer,PlayerLocalのチェックボックスを外します。

　ローカルアイテムの場合は、PlayerLocalを外します。

![player.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/2d8c5111-5f23-5701-b152-1b23ee2ed9a7.png)

(コライダーが設置されたアイテムを持つ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/789868f0-126d-4c65-3aa4-49f0e7f54ecf.png)

↓

(吹っ飛ばなくなる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3984019/b54ee01d-3436-b5ee-0f58-ead407acfe57.png)
Go言語(プログラミング)入門メモ㉕

## サードパーティパッケージを利用する
Goには様々な機能をもつ標準パッケージがあるが、開発したい機能によってはサードパーティのパッケージを活用する場合もある。
サードパーティのパッケージをインストールして使用する方法を確認する。

## インストール
サードパーティが公開しているパッケージは、次のURLで検索できる。
https://pkg.go.dev/
今回はtalibという株価を分析するサードパーティパッケージをインストールしてみる。
https://pkg.go.dev/github.com/markcheno/go-talib
Goではgo getというコマンドで、サードパーティのパッケージをインストールする。
ターミナルでページに記載されているダウンロード用のコマンドを実行する。
「go get github.com/markcheno/go-talib」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3579705/c6d91926-00e3-d624-1319-8e511b044931.png)
また、株価などの情報をダウンロードするquoteというパッケージもインストールする。
「go get github.com/markcheno/go-quote」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3579705/bea17825-5d02-b27c-29cc-661cfa441df3.png)
talibのGitHubに掲載されているサンプルコードを実行すると、SPY(アメリカ企業500社の株価を基に算出される日本の日経225的なもの)と呼ばれる値を出力する
~~~
package main

import (
	"fmt"

	"github.com/markcheno/go-quote"
	"github.com/markcheno/go-talib"
)

func main() {
	spy, _ := quote.NewQuoteFromTiingo("spy", "2016-01-01", "2016-04-01", "取得したAPIキー")
	fmt.Print(spy.CSV())
	rsi2 := talib.Rsi(spy.Close, 2)
	fmt.Println(rsi2)
}
~~~
実行結果は以下のようになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3579705/e4263911-c584-bead-71a3-5993185791bd.png)

## 学習に使用した教材
・『入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』M.A EduTech
https://www.udemy.com/course/golang-webgosql/?utm_medium=udemyads&utm_source=bene-msa&utm_campaign=responsive&utm_content=top-1&utm_term=general&msclkid=81e2f24a32cc185d275d953d60760226&couponCode=NEWYEARCAREERJP

・『シリコンバレー一流プログラマーが教える Goプロフェッショナル大全』酒井 潤 (著)
https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E4%B8%80%E6%B5%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B-Go%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%A4%A7%E5%85%A8-%E9%85%92%E4%BA%95-%E6%BD%A4/dp/4046070897
Factorybotでアクティブレコードを呼び出す

# ActiveRecordを呼び出せる

```rb
build(:user, name:"fafa").class.all
```
createでも可
この場合はテーブルの全てを取り出している
下のようにクラスでないとアクティブレコードは呼び出せない。
```rb
irb(main):001:0> Book.all
  TRANSACTION (0.2ms)  BEGIN
  Book Load (0.3ms)  SELECT `books`.* FROM `books`
=>
[#<Book:0x0000000106ffb958
  id: 1,
  name: "Book 1",
 ....
  >]

irb(main):004:0> Book.first.class
  Book Load (0.6ms)  SELECT `books`.* FROM `books` ORDER BY `books`.`id` ASC LIMIT 1
=> Book(id: ....)
`
irb(main):006:0> Book.all.class
=> Book::ActiveRecord_Relation
```
[Linux][directory] マウントオプション_/etc/fstab

# マウントオプション
|オプション|defaults|由来|説明|
|:--|:--|:--|:--|
| `defaults` | - | default options | デフォルトのオプション（`rw, suid, dev, exec, auto, nouser, async`）を適用 |
| `rw` | ○ | read-write | 読み書き可能でマウント |
| `ro` | - | read-only | 読み取り専用でマウント |
| `nouser` | ○ | no user mount | - マウント: 一般ユーザー不可<br>- アンマウント: 一般ユーザー不可 |
| `owner` | - | owner only | - マウント: ファイル所有者<br>- アンマウント: マウントユーザーのみ可 |
| `user` | - | allow user | - マウント: 一般ユーザー可<br>- アンマウント: マウントユーザーのみ可 |
| `users` | - | allow users | - マウント: 一般ユーザー可<br>- アンマウント: 一般ユーザー可 |
| `auto` | ○ | automatic mount | `mount -a` で自動マウントされる |
| `noauto` | - | no automatic mount | `mount -a` ではマウントされない |
| `exec` | ○ | execute | 実行ファイルの実行を許可 |
| `noexec` | - | no execute | 実行ファイルの実行を禁止 |
| `suid` | ○ | set-user-ID | `setuid`/`setgid` ビットを有効化 |
| `nosuid` | - | no set-user-ID | `setuid`/`setgid` ビットを無効化 |
| `dev` | ○ | device | デバイスファイルの使用を許可 |
| `nodev` | - | no device | デバイスファイルの使用を禁止 |
| `async` | ○ | asynchronous I/O | データの書き込みを非同期で実行 |
| `sync` | - | synchronous I/O | データの書き込みを同期的に実行 |

# /etc/fstabファイルの中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/c042d4d2-e68d-48b0-a949-121ea7bd0880.png)
(1) デバイス名
(2) マウントポイント
(3) ファイルシステムの種類
(4) マウントオプション
(5) dumpフラグ
(6) fsckフラグ


# Ping-t
- [3231_auto](https://mondai.ping-t.com/question_subjects/31/question_sessions/31551465/progressing_questions/483453577)
- [3531_async](https://mondai.ping-t.com/question_subjects/31/question_sessions/31551465/progressing_questions/483453574)
- [3533_async, auto, dev, exec, nouser, rw, suid](https://mondai.ping-t.com/question_subjects/31/question_sessions/32581786/progressing_questions/499228240)
- [3535_noexec](https://mondai.ping-t.com/question_subjects/31/question_sessions/30552498/progressing_questions/468099717)
- [3538_suid](https://mondai.ping-t.com/question_subjects/31/question_sessions/30892897/progressing_questions/473298365)
- [3539_user](https://mondai.ping-t.com/question_subjects/31/question_sessions/32569047/progressing_questions/499039897)
- [3540_users](https://mondai.ping-t.com/question_subjects/31/question_sessions/30205245/progressing_questions/462752074)

- [3718_defaults, nouser, noauto](https://mondai.ping-t.com/question_subjects/31/question_sessions/30205245/progressing_questions/462752068)


/etc/fstabファイルの中身
- [3544_/etc/fstab](https://mondai.ping-t.com/question_subjects/31/question_sessions/31763145/progressing_questions/486763763)
- [3640_/etc/fstab](https://mondai.ping-t.com/question_subjects/31/question_sessions/32441815/progressing_questions/497113393)
- [3672](https://mondai.ping-t.com/question_subjects/31/question_sessions/32448701/progressing_questions/497231323)
- [38073_/etc/fstab](https://mondai.ping-t.com/question_subjects/31/question_sessions/31551465/progressing_questions/483453570)
.gitignoreに書かれてるけどGitの管理対象になっているファイル群を対象外にしたい

## はじめに

Gitでプロジェクトなどの管理を行うとき、対象外にしたいファイルやディレクトリは`.gitignore`に記載するかと思います。

ただ（一度コミットした等で）すでにGitでの管理対象になっているファイルは、その後`.gitignore`に記載されても管理の対象から外れません。そのため「`.gitignore`に書かれているけどGitで管理されている」という状況が起こり得ます。

これを解消する方法を書き残しておきます。


### 環境

この記事を書いている時の動作環境は下記の通りです

macOS Sonoma 14.6
git version 2.48.1


## コマンド

もったいぶらずに書くと、↓のコマンドでほぼ終わります。
コマンドの意味は後で解説します。

```sh: shell
git ls-files -ci --exclude-standard | xargs git rm --cached
```

:::note info
いきなり管理対象から外すのがためらわれる場合、↓の通り前半だけ実行すれば対象外になるファイルの一覧が確認できます。

```sh: shell
git ls-files -ci --exclude-standard
```
:::

「ほぼ終わる」と書いたのは、上記のコマンドを実行しただけだと管理対象から外した状態がコミットされていないためです。

`git status`を実行して状態を確認すると、`deleted:`と付いた状態で、対象外になったファイルたちが表示されるはずです。
`deleted`と見るとファイルそのものが消えたようで驚くかもしれませんが、ファイル自体は消えていません。心配なら`ls`などのコマンドで確認してみてください。

問題なければ、その状態でコミットすれば完了です。


### git ls-files

`git ls-files`は、ざっくり言うとgitの管理対象となっているファイルを表示するコマンドです。各種オプションを使った絞り込みなどもできます。

#### `-c`オプション

`-c`オプションは`--cached`を短縮したものです。
Gitにキャッシュされているファイル、つまり**すべての追跡済みファイル**（管理対象ファイル）**を表示**します。

#### `-i`オプション

`-i`オプションは`--ignored`を短縮したものです。
**無視されるファイルのみを表示する**もので、`-c`または`-o`と組み合わせて使う必要があります。

今回の`-c`との組み合わせでは、「無視されるパターンに合致しているが、管理対象になっているファイル」を出力します。

ここでいう「無視されるパターン」については自分で指定する必要があります。「標準の設定がデフォルトで反映される」という仕様ではありません。そのため、何かしら除外に関するオプションを指定する必要があります。これについては次で触れます。

#### `--exclude-standard`オプション

`-i`オプションで触れた「除外に関するオプション」の1つが`--exclude-standard`オプションです。

Gitが標準で参照する除外ルール（つまり、リポジトリ内の`.gitignore`ファイルなど）での除外設定を使いたい場合、このオプションを指定します。
この他にも任意の除外ルールを追加することもできますが、今回は`.gitignore`を使いたいので`--exclude-standard`だけで問題ありません。


:::note info
`git ls-files`やそのオプションについて、より詳しくはこちらのページを確認してください。

Git - git-ls-files Documentation
https://git-scm.com/docs/git-ls-files
:::


### パイプ( | ) と xargs

2つのgitコマンドを繋いでいるパイプ(`|`)と`xargs`についても説明しておきます。
ちなみにこれらは別にgit用のコマンドではなく汎用的なものです。

パイプ(`|`)は前のコマンド（今回だと`git ls-files -ci --exclude-standard`）の出力を、次のコマンドの入力として渡します。

`xargs`コマンドは、入力を1行ずつ、後に続くコマンド（今回だと`git rm --cached`）の引数として渡します。

つまり、次のコマンドで行われる「Git管理からの除外」を、`git ls-files`でリストアップした各ファイルに対して適用している、ということです。


### git rm

`git rm`はGitで管理しているファイルを削除するためのコマンドです。

通常は↓のように引数で削除対象のファイルを渡しますが、今回のコマンドでは`|`と`xargs`で引数が渡されてくるので不要です。

```:shell
git rm fileA
```

ここで注意すべきが、このコマンドはファイル自体を削除するということです。
そこで必要になるのが次のオプションです。

#### `--cached`オプション

Gitにキャッシュされたファイルのみを削除し、ファイルそのものは削除しない時に使うコマンドです。
つまり**Gitでの管理から外すだけ**で、ファイル自体には何も変化を及ぼしません。


:::note info
`git rm`やそのオプションについて、より詳しくはこちらのページを確認してください。

Git - git-rm Documentation
https://git-scm.com/docs/git-rm
:::
032 AI屋さんの　マルチモーダルLLMにトークン全文入力　英会話　streamlit＋Gemini


032 AI屋さんの　マルチモーダルLLMにトークン全文入力　英会話　streamlit＋Gemini


音声入力、音声出力　の大規模言語モデルです。

streamlitの　標準機能にデフォルトで音声入力が実装されています。
インターネットのブラウザ越しのマイクも利用できます。
スマホ一台あれば　クラウドのwebアプリで　英会話教室の開校です。


準備は、pip install streamlit　のみでokです。
音声ファイルを　Gemini　へ　そのまま送信します。

https://docs.streamlit.io/develop/api-reference/widgets/st.audio_input



![スクリーンショット 2025-02-02 14.26.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/e1bb8f96-77d7-47bb-6ce6-eb8f7a7f1a89.png)





マルチモーダルLLMは、Geminiを使用します。

https://aistudio.google.com/


音声合成、音声出力は、gtts　です。
gttsは、Google製の無料の音声合成ライブラリです。
音声合成の、言語設定を固定するので
英会話向けには、英語固定です。


https://gtts.readthedocs.io/en/latest/

https://github.com/pndurette/gTTS



---
---

完成した、英会話アプリ


![スクリーンショット 2025-02-02 13.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/b4175efe-dd9e-5ff2-f9a8-1bf9d52a67e5.png)




音声ファイルを渡すだけで、勝手にLLMが　文字起こしして
翻訳して、JSON形式で　回答します。
音声は、日本語以外もそのまま認識されます。

翻訳した内容で、Geminiと会話をしてくれます。
プロンプトに設定資料を全文入力して
キャラ設定した、Geminiさんと　楽しくお話しできます。



---
---


ソースコードも下記参照、

![スクリーンショット 2025-02-02 12.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/c1dec4e8-13af-96d6-4b6b-6d70487360e8.png)


![スクリーンショット 2025-02-02 14.42.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/d700e40f-60d9-a731-09b4-6be56342fc4f.png)






---
---


目次

https://qiita.com/bono0/items/dc1d000c98af7e07c9a7



今回も無事に、マルチモーダルLLM　さんと英会話できました。

　032 AI屋さんの　マルチモーダルLLMにトークン全文入力　英会話　streamlit＋Gemini

完成です。おめでとうございます。


ー続くー
Snowflakeの勉強開始

はじめまして。SAKURAと申します。

このたび、会社の組織編成により、これまで名前しか聞いたことのなかった「Snowflake」 を触る機会を得ました。ちょうどそのタイミングでコミュニティへ右も左もわからない状態で飛び込んでみたところ——想像以上に温かく迎えていただきました。まだまだ学びはじめですが、この場をお借りして自己紹介と、これから目指す資格「SnowPro Core」取得への道筋について簡単にまとめたいと思います。


## 自己紹介
名前：SAKURA YOH
担当領域：これからSnowflakeに携わる予定だが不透明なところがおおい
IT経験：かれこれ10年ほど携わっていますが、特定分野のエキスパートというわけではなく、下流工程やインフラ構築、ビジネス寄りの業務など、幅広く経験してきました。
保有資格：
応用情報技術者試験
AWS Certified Solutions Architect - Associate
Python3 エンジニア認定基礎試験
他。

Snowflakeは今回が初めての挑戦です。データウェアハウスやデータエンジニアリングの深い知識はこれまでありませんでしたが、この機会にゼロから学んでみようと思いました。

## Snowflakeコミュニティへ参加してみた

コミュニティに飛び込んだきっかけ
会社で突如「Snowflakeを使うから、ちょっと学んでみて！」という話になり、いろいろ調べていくなかで見つけたのがSnowflakeのユーザーコミュニティでした。Slackが活発に動いているとのことで参加したところ、初心者の私にも親身になってくださる方がたくさんいてビックリ。
初心者向けの講座があるという情報をいただいたり、試験対策や具体的なサイト、問題集についても親切に教えていただいたりして、コミュニティパワーの大切さを痛感しています。

Slackでいただいたアドバイスたち
たくさんコメントやスタンプをいただきました。たとえば、

- Snowflake Ascent（初心者向け無料講座）は1月に開催されたが、次の開催はまだ未定。公式のドキュメントやトレーニングでも学べる。
- 「SnowPro Coreの試験は実務経験1年〜が推奨だけれど、ドキュメントやハンズオンを活用すれば、未経験でも合格している人がいる。」
- コミュニティで初心者向けの勉強会を定期的に開催予定なので、ぜひ参加してみてほしい。
- Udemyでも学べる

これだけ親切に教えていただけるとは思いませんでした。突然の組織編成に慌てて準備すすめていた自分の言葉の足りなさもあったと思いますが、皆様暖かくて本当に感謝いたしました。

## まずはSnowPro Coreを目指してみる
これから実務で必要となるのが、**SnowPro Core**という資格試験です。Snowflakeの基礎的な知識からアーキテクチャ、権限管理などを広く出題するらしく、難易度もそれなりだとか。

勉強方法の模索
私自身の学習方針としては、今のところ下記を考えています。

- トライアルアカウントで実際に触ってみる
Snowflakeは30日間の無償トライアルができるので、とにかく手を動かして慣れることを優先。
- 公式ドキュメント＆クイックスタートを活用
Snowflake Quickstarts のチュートリアルを一通り実施
- 公式ドキュメントを丸暗記するのではなく、試験範囲とリンクづけながら必要な部分を読む
試験範囲のガイド（[COF-C02] SnowPro Core試験学習ガイド）を参考に進める
- コミュニティやSNSで情報収集
- 有料講習を検討（Snowflake Fundamentalsなど）
会社の予算や上司の理解次第なので、ここは要相談。
- 問題集やUdemyコースを活用
SnowPro Coreの合格者に評判のよい問題集や、Udemyで提供されている講座をうまく組み合わせて学習したい。

不安要素：データ基盤設計の経験が乏しい。学習時間の確保。

## まとめと今後の展望
- Snowflakeは初心者でもコミュニティに飛び込めば学びやすいと感じた
- SnowPro Core取得を目指すと、自然とデータエンジニアリングやDWHの知識が身につくらしい
- 公式ドキュメント、ハンズオン、コミュニティでのQ&A活用が有効

これから学習を進めるなかで、試験対策で得た知見やハマりどころなどをQiitaで共有していこうと思っています。
最後までご覧いただきありがとうございました。
個人的な備忘録：Pythonのスライス機能を使って回文判定を簡単に実装し、振り返ってみた

## はじめに
回文とは、前から読んでも後ろから読んでも同じになる文字列のことです。***例えば、「level」「madam」「12321」などは回文に当たります。***

:::note info
**Pythonでは、文字列のスライス機能を活用することで、シンプルなコードで回文判定が可能です。**
:::

本記事では、Pythonを使って回文を判定する関数を作成し、その動作を解説していきます。

## 書こうと思ったきっかけ
プログラミングの学習を進める中で、文字列の操作や条件分岐を効率的に扱う方法を学びたいと考えました。

:::note warn
個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。
:::

特に、Pythonの文字列スライス([::-1])を活用すれば、簡潔に逆順の文字列を取得できることを知り、それを活かした実践的な例として、回文判定を試してみようと思いました。

## 完成したコード

```test.py
def is_palindrome(s):
    return s == s[::-1]

word = input("文字列を入力してください: ")
if is_palindrome(word):
    print(f"{word} は回文です")
else:
    print(f"{word} は回文ではありません")
```

### コードの流れ

- **回文判定用の関数を定義 (`is_palindrome(s)`) する。**  

- **ユーザーに文字列を入力してもらう (`input()`)。**  

- **`is_palindrome()` を使って回文かどうか判定する。**  

- **結果を `if-else` で分岐し、出力する。**  

## 実際に実行してみる
まず、以下のコマンドを実行して作成したコードの動作を確認します。

```bash
python test.py
```

**実行結果**

```bash
➜  Desktop git:(main) ✗ python test.py
文字列を入力してください: honda
honda は回文ではありません
➜  Desktop git:(main) ✗ python test.py
文字列を入力してください: 123321
123321 は回文です
➜  Desktop git:(main) ✗ 
```

## コードの解説

### 1.回文判定用の関数を定義

```py
def is_palindrome(s):
    return s == s[::-1]
```

- **`s[::-1]` は文字列 `s` を逆順にしたものを取得する。**  
- **元の文字列 `s` と `s[::-1]` が一致すれば回文であると判断し、`True` を返す。**  


### 2.ユーザーに文字列を入力してもらう

```py
word = input("文字列を入力してください: ")
```

- **`input()` を使ってユーザーに文字列を入力してもらい、それを `word` に代入する。**  

### 3.`is_palindrome()`を使って回文かどうか判定

```py
if is_palindrome(word):
```

- **`word` を `is_palindrome()` に渡し、`True` か `False` かを判定する。**  

### 4.結果を出力

```py
    print(f"{word}は回文です")
else:
    print(f"{word}は回文ではありません")
```

- **`True` の場合 (`is_palindrome(word)` が `True`) → 「○○は回文です」と出力。**  
- **`False` の場合 (`is_palindrome(word)` が `False`) → 「○○は回文ではありません」と出力。**  

## まとめ
ここまで読んでいただきありがとうございました。***今回の内容は基本的な部分でしたが、Pythonの関数の作り方、`if-else`による条件分岐、文字列のスライス操作を振り返ることができました。***

今後もこのような基礎的な部分については丁寧にまとめていこうと思っています。
低画質映像を4K画質に！RTX Video Super Resolutionベースのアップスケーラー公開（無料体験あり）

 こんにちは、ABUSです。年末年始はいかがお過ごしでしたでしょうか？

![20250202_124138.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977019/5e7a446c-d9ad-ef92-1f33-2eaff47d732d.png)


この度、弊社ABUSでは、NVIDIA RTX Video Super Resolutionに対応したGradio Web-UIベースの**rtx-upscaler**を開発し、公開いたしました。

**rtx-upscaler**は、RTX 20以上のグラフィックカードをお持ちの方であれば誰でも簡単に低画質映像を高画質に変換できるツールです。最大4K（4320p）までのアップスケールに対応しており、簡単な操作で所有している低画質映像を高画質で鑑賞することができます。

## :star: 主な特徴

- **NVIDIA RTX Video Super Resolution対応**: 最新技術を活用し、高品質なアップスケール結果を提供
- **Gradio Web-UIベース**: 誰でも簡単に使える直感的なインターフェース
- **最大4K（4320p）アップスケール対応**: 高解像度映像で画質向上
- **高速処理**: NVIDIA SDKを使用し、高速なアップスケール処理を実現（映像によって品質に差が生じる可能性あり）


## :scales: 既存のアップスケーラーとの比較
Topaz LabsやWaifu2x-Extension-GUIをご利用されたことがある方は、速度や費用面でrtx-upscalerと比較検討されることをお勧めします。rtx-upscalerはNVIDIAが提供するSDKを使用しているため処理速度が非常に速く、無料で利用できるという利点があります。

## :movie_camera: RTX Video Super Resolution関連動画

- ラデオンはFluid Motionがあるのに？[NVIDIAアップスケーリングテスト]：https://www.youtube.com/watch?v=n5jVw6rF9-o
- 720P SDR、すべて4K HDRに変換します/NVIDIA RTXビデオ＆ダイナミックバイブランス：https://www.youtube.com/watch?v=j9m_v2n5x98
- Introducing RTX Video Super Resolution - 4K AI Upscaling for Chrome & Edge Video: https://www.youtube.com/watch?v=n9m_v2n5x98


## :mailbox_with_mail: 無料体験とお問い合わせ
GitHubで公開されているFree-Trialバージョンは、動画の最初の60秒のみ処理可能です。動画全体の処理をご希望の場合は、メール (abus.aikorea@gmail.com) にてお問い合わせください。無料体験用認証ファイルをお送りします。


**GitHubリポジトリ**: https://github.com/abus-aikorea/rtx-upscaler

皆様からのご関心をお待ちしております。よろしくお願いいたします。
.NETのお勉強5_htmlを返すルートを定義

# 概要
AmazonLinux2023インスタンス上にコンテナで.NETを利用したサーバをたてる
そのお勉強メモ5

htmlをリターンするAPIルートを定義する

# ソース
``` src/Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "redis:6379";
});
builder.Services.AddControllers();
builder.Services.AddControllersWithViews(); // これ追加

var app = builder.Build();
app.MapGet("/", () => "Hello, World!");
app.MapControllers();
app.Run();
```

``` src/Controllers/ViewController.cs
using Microsoft.AspNetCore.Mvc;

[Route("[controller]")]
public class ViewController : Controller
{
    [HttpGet("{id}")]
    public IActionResult Index(int id)
    {
        ViewBag.Message = $"id: {id}";
        return View();
    }
}
```

``` src/Views/View/Index.cshtml
<!DOCTYPE html>
<html>
    <head>
        <title>index.cshtml</title>
    </head>

    <body>
        <h1>@ViewBag.Message</h1>
    </body>
</html>
```

# 実行テスト
xx.xx.xx.xx/view/1にアクセスして、「id : 1」と表示されればok

# その他メモ
### 継承元の親クラスについて
今まで使っていたMysqlController等はControllerBase、ViewControllerはControllerが親クラスになっている
使い分けることが重要
| **クラス** | **用途** | **その他** |
|----------------------------------|----------------------|--------------|
| ControllerBase | textやjsonなどの文字列を返す。RestAPI用 | 軽量で高速 |
| Controller | HTMLをView()やViewBagを使って返す。jsonも返せる | (CotrollerBaseよりは)重い |

### View()関数の参照先HTMLファイル
return View();だけだと、以下の順で参照しに行く
ただし、引数に文字列を入れて、アクション名部分を変更することも可能
```
/Views/{コントローラー名}/{アクション名}.cshtml
/Views/Shared/{アクション名}.cshtml
```

### [Route]属性について
コントローラ、アクションそれぞれにつけることでルーティング定義を行う

##### つけない場合
そのコントローラはルーティング設定されず404になる
ただし、Program.csにデフォルトルーティング設定をすることは可能

##### [Route("[controller]")]
コントローラ名が最上位ルートになる
以下の例だと/sample/{アクション名}
```
[ApiController]
[Route("[controller]")]
public class SampleController : ControllerBase
```

#### [Route("hoge/[controller]")]
コントローラ名の前にプレフィックスを付けたルートになる
以下の例だとhoge/sample/{アクション名}
```
[ApiController]
[Route("hoge/[controller]")]
public class SampleController : ControllerBase
```

#### [Route("hoge")]
コントローラ名に限らず、固定ルートになる
以下の例だとhoge/{アクション名}
```
[ApiController]
[Route("hoge")]
public class SampleController : ControllerBase
```

#### [HttpGet("hoge")]
アクション名が関数名に関係しないルートになる
以下の例だとsample/hoge
```
[ApiController]
[Route("[controller]")]
public class SampleController : ControllerBase
{
    [HttpGet("hoge")]
    public string Get() => "Hello from sample/hoge";
}
```

#### [Route("[area]/[controller]/[action]")]
[controller]のようなプレースホルダー(ルートトークン)を組み合わせるとこんな指定も可能
以下の例だとhogeArea/sample/hogeAction

[Route("[controller]/[action]")]の指定が一番使い勝手良いのかも？
```
[Area("hogeArea")]
[Route("[area]/[controller]/[action]")]
public class SampleController : ControllerBase
{
    [HttpGet]
    public string hogeAction() => "hogehoge";
}
```
【Web】オブジェクト構造のJSONをリストへ変換する方法

# はじめに
今年に入ってWebの開発を進めています。
Next.js+TypeScriptの組み合わせで実装を行なっていますが、そんな中でAPIを叩いて取得したデータに関しリストでの返却を期待していたところ、まさかのオブジェクトとしてそれz独立した構造で返ってくるという問題が発生しました。
そこでオブジェクト構造で返却されたJSONデータを扱いやすいリストへと受け取った側で変換する方法を備忘録的にまとめておこうと思います。

# リスト化の方法
まず、以下のようなJSONが帰ってくるとします。

```sample.json
{
	"tests": {
		"test1": {
			"name": "テスト"
		},
        "test2": {
			"name": "テスト"
		}
        "test3": {
			"name": "テスト"
		}
        "test4": {
			"name": "テスト"
		}
	}
}
```
本来であればtestsはリスト構造で返却されればベストなのですが、API的な都合などでリスト的な返却が難しい場合、受け取った側で扱いやすいようリスト化する必要があります。

上記レスポンスをリスト化するためには以下のように実装することで実現可能です。

```page.tsx
type TestData = {
  name: string;
};

type ApiResponse = {
  tests: Record<string, TestData>;
};

const parseTests = (data: ApiResponse): TestData[] => {
  return Object.values(data.tests);
};

// APIから取得したデータ（仮）
const apiResponse: ApiResponse = {
  tests: {
    test1: { name: "テスト" },
    test2: { name: "テスト" },
    test3: { name: "テスト" },
    test4: { name: "テスト" }
  }
};

// tests を配列化
const testArray = parseTests(apiResponse);

console.log(testArray);

```
実装のポイント
1. `Record<string, TestData>` を使用
tests のキー（test1, test2 など）は 動的に増減 する可能性がある為、
`Record<string, TestData>` を使用することで、任意のキー名を持つオブジェクトを表現可能です。

2. `Object.values()` を使って配列化
Object.values(data.tests) を使うと、testsのすべての値（TestData）だけを配列に変換可能です。

3. 型安全にデータを扱える
ApiResponse 型を定義することで、API のレスポンス構造が変わったときに型エラーで気付くことが可能です。

以上になります。

# さいごに
Web側はJSONを扱いやすくて便利ですね。
緑によるABC391振り返り


# はじめに
えーとE問題、本当に緑diffですか?
あのー僕、E問題水diffだと思って、離脱したんですけど....(こいつ、スノーシュー行って疲れてたくせに、rated参加+4完したくせに満足してねーのかよ)

結局、結果はこんな感じでした

> ユーザ名	hidehico
> コンテスト名	AtCoder Beginner Contest 391
> 順位	2358th / 11611 (top 1.96%)
> パフォーマンス	1119
> レーティング	874 → 901 (+27)

ていうか、2000位で、緑パフォって相当、レベル高いな

コンテスト中は、こんな感じでした

### コンテスト中の流れ
#### 開始4時間前
スノーシューに行ってくたびれて、帰宅

#### 開始30分前
ratedで参加登録する

#### 開始3秒
atcoder-cliで、テストケースを取得する

#### 開始2分
Aを通す
時間がかかった理由は、強行手段でACしたから

#### 開始9分
Bを通す
インデックス調整をミスって、時間をかけてしまった
幸い、サンプルケースが強かったので、0ペナ

#### 開始12分
Cを通す
明らかに、得意な、クエリ系だったので、難無くACできた
3分で通して、Bでのロスをリカバリーした

#### 開始40分
Dを通す

多分、Eは解けそうにないし、離脱した
翌日diffを確認すると、緑diffビックリ仰天、レートもそこまで上ってない、萎えた

こんな感じでした

### 使っているライブラリ
[github](https://github.com/hidehic0/library)
前回からの、変更点は、バグの修正だけです

そんじゃ、一問ずつ感想書きますか

# [A問題](https://atcoder.jp/contests/abc391/tasks/abc391_a)

簡潔な案を思いついたけど、バグらせたら嫌だなーと、思い、普通に書いた
無限ifよりは、簡潔に書けた

ACコード(ライブラリ抜粋)
```py
D = {
    "N": "S",
    "S": "N",
    "E": "W",
    "W": "E",
    "NE": "SW",
    "SW": "NE",
    "NW": "SE",
    "SE": "NW",
}
print(D[s()])
```

# [B問題](https://atcoder.jp/contests/abc391/tasks/abc391_b)

全探索した、だけど1-indexedから、0-indexedへの変換に時間がかかり、タイムロスした
~~すべての問題が、0-indexedだったらいいのに~~

ACコード(ライブラリ抜粋)
```py
N, M = il()
S = li(N, s)
T = li(M, s)

for a in range(1, N - M + 2):
    for b in range(1, N - M + 2):
        flag = True
        for i in range(M):
            for k in range(M):
                if S[i + a - 1][b + k - 1] != T[i][k]:
                    flag = False

        if flag:
            print(a, b)
            exit()
```

# [C問題](https://atcoder.jp/contests/abc391/tasks/abc391_c)

鳩の現在の場所と、各巣の鳩の匹数を、とっておいて
移動先の、鳩の匹数、が1だったら、ansを増やす
移動元の、鳩の匹数、が2だったら、ansを減らす

で鳩の移動の処理をやれば、ACできる

ACコード(ライブラリ抜粋)
```py
N, Q = il()
D = [i for i in range(N)]
L = [1] * N
ans = 0

for _ in [0] * Q:
    l = il(-1)

    if l[0] == 0:
        a = D[l[1]]

        if L[l[2]] == 1:
            ans += 1

        if L[a] == 2:
            ans -= 1

        L[l[2]] += 1
        L[a] -= 1

        D[l[1]] = l[2]
    else:
        print(ans)
```

# [D問題](https://atcoder.jp/contests/abc391/tasks/abc391_d)

diffの崖がすごい

各列の一番下にある、ブロックの高さ-現在時刻、の最大値+現在時刻が、各ブロックの答えになる
それであーだこーだやればできる

ACコード(ライブラリ抜粋)
```py
N, W = il()
D = defaultdict(list)
L = li(N, il)
ans = [INF] * N

for i in range(N):
    D[L[i][0]].append((L[i][1] - 1, i))

for i in range(1, W + 1):
    D[i].sort(reverse=True)


cur = 0
while True:
    flag = True
    m = 0
    l = []

    for i in range(1, W + 1):
        if len(D[i]) == 0:
            flag = False
            break

        y, ind = D[i].pop()
        m = max(m, y - cur)
        l.append(ind)

    if not flag:
        break

    for ind in l:
        ans[ind] = m + cur

    cur += m

Q = ii()

for _ in [0] * Q:
    T, A = il()

    YN(ans[A - 1] >= T)
```

# [E問題](https://atcoder.jp/contests/abc391/tasks/abc391_e)

眠すぎぎた
問題文の理解ができなかった

解説見たらDP使うみたい

# 最後に

順位表を見たら、消えてる人が数人いた(AI使ってたのかな?)
まあ関係ないけど

まあ眠かったし、ABCD 4完でも満足でした

:qa!
【電脳少女プログラミング2088 ─壊レタ君を再構築─】「巨大コーポの最上階」をやってみた。

paizaの新作プログラミングゲーム【電脳少女プログラミング2088 ─壊レタ君を再構築─】[巨大コーポの最上階](https://ppg.paiza.jp/denno2088/areas/14)（paizaランク：A相当）をやってみました。

person (人物) のうち重要度が 5 の人物の person.deleted_at と同じ battle (戦闘) の battle.created_at (戦闘.作成日) から memory (記憶) と battle (戦闘) と person (人物) の memory.id (記憶.ID), memory.talk (記憶.会話内容), person.name (人物.人物名), battle.created_at (戦闘.作成日) を出力するので

```sql
SELECT
    m.id,
    m.talk,
    name,
    b.created_at
FROM person p
INNER JOIN battle b ON p.id = person_id
INNER JOIN log l ON b.person_id = l.person_id
INNER JOIN memory m ON memory_id = m.id
WHERE p.importance = 5
    AND p.deleted_at = b.created_at;
```

となります。
個人的な備忘録：Pythonでフィボナッチ数列を実装し、関数とループ処理を振り返ってみた

## はじめに
フィボナッチ数列は、プログラミング初心者が関数の使い方やループ処理を学ぶのに最適な題材の一つです。

:::note info
**この数列は、前の2つの数を足して次の数を作るというシンプルなルールで構成されており、数学的な概念をプログラムで表現する練習にもなります。**
:::

本記事では、Python を使ってフィボナッチ数列を生成する関数を作成し、その動作を解説していきます。

## 書こうと思ったきっかけ
プログラミングを学び始めた頃、関数の使い方や変数の更新方法が分かりにくいと感じました。

:::note warn
***特に、ループの中で変数をどのように更新すればよいかという部分が理解しづらかったため、分かりやすい例を探していました。***
:::

フィボナッチ数列は、関数の基本・ループの使い方・タプルのアンパックを一度に学べる便利な題材であり、初心者の学習に最適だと考えました。

## 完成したコード

```test.py
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        print(a, end=" ")
        a, b = b, a + b

fibonacci(10)
```

## コードの流れ

- **`fibonacci(n)` 関数を定義する**  

- **2 つの変数 `a`（初期値 0）と `b`（初期値 1）を用意する。**  

- **`for` ループを `n` 回繰り返す。**  

- **フィボナッチ数列の計算と出力を行う。**  
  - `print(a, end=" ")` で現在の `a` の値を出力（横並びで表示するため `end=" "` を指定）。  
  - `a, b = b, a + b` により、新しい `a` と `b` を更新する（タプルのアンパックを使用）。  

- **`fibonacci(10)` を実行する。**  
  - `n = 10` の場合、最初の 10 個のフィボナッチ数列を出力する。

## 実際に実行してみる
まず、以下のコマンドを実行して作成したコードの動作を確認します。

```bash
python test.py
```

**実行結果**

```bash
➜  Desktop git:(main) ✗ python test.py 
0 1 1 2 3 5 8 13 21 34 % 
```

## コードの解説
### 1. フィボナッチ数列を生成する関数の定義

```py
def fibonacci(n):
```

- **`n` を引数に取り、最初の `n` 個のフィボナッチ数列を出力する関数を定義する。**  

- **関数を呼び出すと、`n` の回数分ループが実行される。**  

### 2. 初期値の設定

```py
    a, b = 0, 1
```

- **フィボナッチ数列の最初の 2 つの値 `a = 0`, `b = 1` をセットする。**  

### 3. `n` 回ループを実行

```py
    for _ in range(n):
```
- **`n` 回ループを実行し、各回でフィボナッチ数列の値を更新していく。**  
- **`_` は「ループ変数を使わない」ことを示すために使用（慣習的に `_` を使う）。**  

### 4. 現在の `a` の値を出力

```py
        print(a, end=" ")
```

- **現在の `a` の値を表示する。**  
- **`end=" "` を指定することで、改行せずにスペース区切りで出力。**  

### 5. `a` と `b` の値を更新

```py
        a, b = b, a + b
```

- **`a` を `b` の値に更新し、`b` を `a + b` の値に更新。**  
- **これにより、フィボナッチ数列が次の値へ進む。**  
- **タプルのアンパックを使用することで、スワップ処理が簡潔に記述できる。**  

### 6. 関数の呼び出し

```py
fibonacci(10)
```

- **`n = 10` を指定して関数を呼び出し、最初の 10 個のフィボナッチ数列を出力。**  


## まとめ

ここまで読んでいただきありがとうございました。今回の内容は基本的な部分でしたが、Python の関数の作り方、`for` ループの使い方を振り返ることができました。

今後もこのような基礎的な部分については丁寧にまとめていこうと思っています。
1カ月でAZ-104とAZ-204とAI-102を一発合格した体験記

# 概要
2025年1月に以下の3つの資格をすべて一発合格しました。
- AZ-204: Developing Solutions for Microsoft Azure
- AZ-104: Azure Administrator Associate
- AI-102: Azure AI Engineer Associate

今後受験する方の参考になればと思い、勉強期間や勉強方法を記載します。

# 受験順序
以下の順番で受験しました。
1. AZ-204
1. AZ-104
1. AI-102

受験順序に特に理由はありません。強いて言うなら、AZ-104を1番最初に受験するのがいいかなと思いました。理由としては1番試験範囲が広いためです。AZ-104で出てきた知識は他の試験にも役立ちます。

# 勉強時間
それぞれ1週間以内程度です。毎日コツコツとやる感じではなく、ガッと集中して詰め込みました。

# 勉強記録
それぞれの試験の勉強記録は以下に記載しています。

https://qiita.com/TeddyTech/items/1d9e6268681c58580942

https://qiita.com/TeddyTech/items/c190cbc925edcf3858e8

https://qiita.com/TeddyTech/items/c3df82bb4bce75483d62

主に使用した教材は公式のMicrosoft PracticeとUdemyです。
間違えた問題はChatGPTに問題を食わせて、解説してもらいました。模擬試験は1回目はボロボロですが、繰り返し受けることで理解と記憶への定着を行いました。

# 今後の予定
AZ-400を受験しようかなと思います
複数のAsyncGeneratorをまとめて一つとして扱いたい

# AsyncGeneratorの並列化
複数のAsyncGeneratorから読み込みを行う場合、どのPromiseを先にawaitするかは非常に難しい問題です。
適切にPromise.raceを使えば解決できますが、読み込むコードはかなり複雑になります。

```mermaid
flowchart TD
    
    P[Your Program]
    P -->|next| A[Async Iterator A]
    P -->|next| B[Async Iterator B]
    P -->|next| C[Async Iterator C]
```

# AsyncGeneratorのマージ
Async GeneratorをまとめたAsync Generatorを新たに作成することで、一つのAsync Generatorとして扱えるようになります。

```mermaid
flowchart TD
    
    P[Your Program]-->M[Merged Async Iterator] -->|next| race
    race -->|next| A[Async Iterator A]
    race -->|next| B[Async Iterator B]
    race -->|next| C[Async Iterator C]
```

この方法であればPromise.raceの複雑性を隠蔽し、１つのAsync Generatorとして取り扱うことができます。

## ソースコード

```typescript
/*
IteratorResult does not have reference to generator itself.
Even if you put reference in data, data is not available on end of iterator

 */
type YieldResultWithId<T> = {
    id: string,
    value: T
}

type ReturnResultWithId<T> = {
    id: string,
    error?: unknown
}

type ResultWithId<T> = YieldResultWithId<T> | ReturnResultWithId<T>
type AsyncGeneratorWithId<T> = AsyncGenerator<YieldResultWithId<T>, ReturnResultWithId<T>>

/*
merge multiple async generators into one.
YieldResult from each iterator should be T
ReturnResult from each iterator should be void since there is only one chance to return value
 */
export async function* mergeAsyncGenerators<T>(generators: AsyncGenerator<T, void>[]): AsyncGenerator<T, void> {
    // Assign Unique Id to each generator
    const generatorsById: {
        [id: string]: AsyncGeneratorWithId<T>
    } = {}
    for (const g of generators) {
        const id = crypto.randomUUID()
        generatorsById[id] = async function* () {
            try {
                for await (const value of g) {
                    yield {id, value};
                }
                // yield last value with id to signal iterator end
                return {id, error: undefined};
            } catch (e) {
                return {id, error: e};
            }
        }()
    }
    // Create promises from each iterator
    const nextById: {
        [id: string]: Promise<IteratorResult<ResultWithId<T>>>
    } = {}
    for (const [id, ite] of Object.entries(generatorsById)) {
        nextById[id] = ite.next()
    }

    // Keep reading value from each iterator using Promise.race
    while (Object.keys(nextById).length > 0) {
        const next = await Promise.race(Object.values(nextById))
        if (next.done === true) {
            // End of the iterator. Delete from waiting list
            const {id, error} = next.value
            delete nextById[id]
            if (error) {
                // propagate error to caller
                throw error
            }
        } else {
            const {id, value} = next.value as YieldResultWithId<T>
            // value from one of the iterators.
            yield value
            // Keep reading the iterator
            nextById[id] = generatorsById[id].next()
        }
    }
}
```

この実装は、ya-syn向けに作成した関数です。

https://github.com/tomohisaota/ya-syn/blob/main/src/utils/mergeGenerators.ts
Databricks AI/BIダッシュボードの計算メジャー

いつの間にこのような機能が。

https://docs.databricks.com/ja/dashboards/datasets/calculated-measures.html

>  計算メジャーは、元のデータセットを変更せずに新しいデータ フィールドを作成および視覚化する方法を提供します。 たとえば、アイテム、地域、価格、およびコストのデータを含む売上データセットで、各地域の利益率を計算して視覚化することができます。

元のデータセットを保持したまま、動的に計算結果を得ることができ、それをダッシュボードに組み込むことができます。

使ってみます。

最初にダッシュボードの**データ**タブでサンプルデータを読み込みます。

```sql
SELECT * FROM samples.nyctaxi.trips
```

右下にある**カスタム算式**をクリックします。

![Screenshot 2025-02-02 at 14.41.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c3832c5b-a2f9-4d67-5cfe-6b19e06d24d9.png)

![Screenshot 2025-02-02 at 14.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/816c571c-f457-18ed-c378-e5f8d856c27e.png)

以下のように入力します。

- **名前:** `マイルあたりのコスト`
- **説明:** `運賃額と移動距離を使用してマイルあたりのコストを計算します`
- **式:** `SUM(fare_amount) / SUM(trip_distance)`

![Screenshot 2025-02-02 at 14.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6c77fe44-518c-3098-9474-30753a275df5.png)

これで計算メジャーが作成されました。

![Screenshot 2025-02-02 at 14.45.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b75b0708-6306-812e-cb43-f19177355519.png)

**Canvas**タブに移動して、データセットを指定してX軸を`dropoff_zip`、Y軸を先ほど定義した計算メジャーを指定すると、計算メジャーを用いた可視化が作成されます。

![Screenshot 2025-02-02 at 14.46.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e329e311-fadc-baa0-2fc0-61213d58dcc7.png)

ダッシュボードを作成する際には色々な切り口が必要となります。元々のデータセットを取得するSQLを変更してしまうと、複雑度が高まりメンテナンスも困難になります。観点に応じた計算メジャーを作成することで、元のデータセットはそのままに柔軟に可視化を行えるようになります。是非ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
3Dポイントクラウドの未来：基盤モデル（FMs）の最新動向と応用可能性

# Foundational Models for 3D Point Clouds: A Survey and Outlook

今回は、最新の研究成果である **「Foundational Models for 3D Point Clouds: A Survey and Outlook」** という論文をご紹介します。本研究は、**3Dポイントクラウドの理解における基盤モデル（FMs）の役割を体系的に整理し、最新の研究動向を網羅的にレビューする** ものです。

## **1. 論文情報**
- **タイトル**: *Foundational Models for 3D Point Clouds: A Survey and Outlook*
- **リンク**: [GitHubリポジトリ](https://github.com/vgthengane/Awesome-FMs-in-3D)
- **発表日**: 2025年1月30日
- **著者**: Vishal Thengane, Xiatian Zhu, Salim Bouzerdoum, Son Lam Phung, Yunpeng Li
- **DOI**: arXiv:2501.18594v1

---

## **2. 背景と目的**

### **2.1 3Dポイントクラウドの特徴と課題**

3Dポイントクラウドは、センサーデータ（LiDAR、RGB-Dカメラ）から取得されるため、**密度のばらつき、部分的な欠損、ノイズ** などの問題が生じやすい。これにより、従来の畳み込みニューラルネットワーク（CNN）やトランスフォーマーベースのアプローチをそのまま適用することが困難となる。

また、3Dデータのアノテーションは時間とコストがかかるため、大規模データセットの構築が難しい。従来の3Dモデルは、小規模なデータセットで学習されることが多く、ゼロショット・少数ショット学習が求められる場面が増えている。

### **2.2 2D基盤モデルの進化と3D領域への応用**

近年、2D画像・テキストにおける基盤モデル（Foundation Models: FMs）は、**CLIP、DINO、Segment Anything Model (SAM)** などを筆頭に飛躍的に進化してきた。これらのモデルは大規模データセットを活用し、**転移学習、ゼロショット推論、マルチモーダル統合** などの能力を獲得している。

本研究では、これらの2D FMsの進展を3D領域に適用し、以下のような新たな可能性を探る：
1. **3D FMsの構築手法の分類と分析**
2. **3D FMsの学習に適したデータ表現と事前学習方法**
3. **ゼロショット、少数ショット学習のためのアプローチ**
4. **3D-2D-テキストのマルチモーダル統合**

---

## **3. 3D基盤モデルの構築手法**

### **3.1 直接適用（Direct Adaptation）**
- **PointCLIP (CVPR 2022)**: CLIPの画像エンコーダを3Dデータに適用。
- **Image2Point (ECCV 2022)**: 画像ベースのFMsを3D表現に変換。

### **3.2 デュアルエンコーダ（Dual Encoders）**
- **CLIP2Point (ICCV 2023)**: 2Dと3Dのエンコーダを並列に配置し、コントラスト学習を実施。
- **CrossPoint (CVPR 2022)**: PointNetとResNetを組み合わせ、マルチモーダル学習。

### **3.3 三重整合（Triplet Alignment）**
- **ULIP (CVPR 2023)**: 画像・テキスト・ポイントクラウドを統合。
- **OpenShape (arXiv 2023)**: マルチモーダルデータの統合による3D分類。

---

## **4. 実験の概要と結果**

### **4.1 データセットと評価指標**

本研究では、以下のデータセットを使用し、F1スコアやIoUを評価指標とした：
- **ModelNet40**（オブジェクト分類）
- **ScanObjectNN**（オブジェクト認識）
- **ShapeNet**（セグメンテーション）

| 手法 | ModelNet40 | ScanObjectNN | ShapeNet |
|------|-----------|-------------|---------|
| PointCLIP | 20.18% | 14.12% | - |
| ULIP | **60.4%** | **48.5%** | **72.3%** |

---

## **5. まとめと今後の展望**

### **5.1 研究の貢献**
- **3D FMsの分類と現状の整理**
- **2D FMsの3D領域への応用可能性の検討**
- **ゼロショット学習の展開**

### **5.2 今後の課題**
- **大規模3Dデータセットの不足**
- **計算コストの最適化**
- **テキスト・画像・3Dの統合学習**

本論文の知見は、今後の3D AIの発展に大きく貢献する可能性がある。
Dockerの使い方（自分用）

# Docker Hubからイメージを作成

イメージの取得
```bash
docker pull 'イメージ名':'バージョン'
```

取得したイメージの確認
```bash
docker images
```

イメージの削除
```bash
docker rmi 'イメージ名またはID'
```


# コンテナを作成して起動する

コンテナの作成と起動（同時）
```bash
docker run --name '作成するコンテナ名' -d -p 'ホストポート':'コンテナポート' 'イメージ名'
```
* -d：バックグランド（デタッチド）モードで実行

例：nginxのコンテナを起動し、ホストの8080ポートをコンテナの80ポートにマッピングする場合
```bash
docker run --name my-nginx -d -p 8080:80 nginx
```

### ※ Ubuntuなどの場合は以下のようにしないと、起動してもすぐに終了する
```bash
docker run -it --name myubuntu ubuntu
```

作成したコンテナの起動（再開）
```bash
docker start 'コンテナ名'
```

# コンテナの状態を確認する

すべてのコンテナの確認
```bash
docker ps -a
```
起動しているコンテナだけを確認
```bash
docker ps
```

# コンテナの操作
コンテナを停止する
```bash
docker stop 'コンテナ名またはID'
```

コンテナを削除する
```bash
docker rm 'コンテナ名またはID'
```

コンテナ内にアクセスする方法
```bash
docker exec -it 'コンテナ名' 'コマンド'
```
例：my-ubuntuコンテナ内のbashを起動
```bash
docker exec -it my-ubuntu /bin/bash
```
* -it : 対話モードで起動

※コンテナはプロセスが動いていないとすぐに終了する。
　この場合はbashを起動している

 起動しているプロセスに接続する
 
```bash
docker attach 'コンテナ名'
```

### 「exec」と「attach」の違い

| コマンド | 説明 |
|:-:|:-:|
| docker attach <コンテナ名>  |  現在動作しているプロセスに接続する |
| docker exec -it <コンテナ名> /bin/bash | 新しいプロセスを開始してコンテナに入る  |

例えば、すでに実行中のコンテナがあって、それにシェルがない場合、attachではシェルを開けません。その場合は、execを使って/bin/bashを実行する必要があります。

attach で接続すると、通常のシェルのように見えますが、抜けるときには特別な操作が必要です。
① 安全に抜ける（コンテナを停止せずに離れる）
```bash
Ctrl + P, Ctrl + Q
```

② exit で抜ける（コンテナが停止する）
```bash
exit
```
→ これを実行すると、コンテナ自体が終了してしまうので注意！

#### attachを使う場面
* デバッグやログの確認
attach を使うと、コンテナの標準出力をリアルタイムで監視できます。
たとえば、コンテナのログを追いかけたり、標準入力が必要なプロセスを直接操作したい場合に便利です。

* バックグラウンドで実行したコンテナに入る
docker run -d で起動したコンテナに接続し、実行中のプロセスの様子を見たり、対話的に操作できます。

### 単にログを見たいだけなら「docker logs」
```bash
docker logs -f　'コンテナ名'
```
-f（フォローオプション）を付けると、リアルタイムでログを見続けられる
【Docker】AlmaLinuxでOSのタイムゾーンを変更する

## はじめに
Dockerコンテナで動作するAlmaLinuxのタイムゾーンを変更したい場合、デフォルトでは`UTC`が使用されています。この記事では、タイムゾーンを`Asia/Tokyo`に変更する方法を説明します。

## タイムゾーン変更の概要

Linuxシステムでは、タイムゾーンは通常`/etc/localtime`で設定されます。このファイルは、適切なタイムゾーン設定を参照するシンボリックリンクとして構成されます。タイムゾーンを変更するには、以下のディレクトリにあるタイムゾーンファイルをリンクする必要があります：

```
/usr/share/zoneinfo/
```

例えば、`Asia/Tokyo`のタイムゾーンに変更するには、次のファイルをリンクします：

```
/usr/share/zoneinfo/Asia/Tokyo
```

---

## Dockerfileでタイムゾーンを変更する手順

Dockerfileに以下のコードを記載します。

Dockerfile例：

```dockerfile
# 必要なパッケージをインストール
RUN dnf install -y tzdata && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```
IntellijIDEAでtestファイルを作成するショートカットキーを設定する方法

## はじめに
IntellijIDEAでtestファイルを作成するショートカットキーが設定されていなかったためその方法を説明します

### 手順1
IntellijIDEAで「Ctr + ，」を押しセッティングを開く

### 手順2
keymapの検索欄に「test」を入力し、「Go to Tests」をダブルクリックする

### 手順3
[Add keyboard shortcut」から「Shift + Ctr + T」を押す
メッセージが表視されますが無視してRemoveを押す

## まとめ
ショートカットキーが設定されていなかった理由としては、元からなにかしらの動作にショートカットキーが割り振られていて使えなかった可能性があります
【一発合格】AI-102 Azure AI Engineer Associate

# 概要
AI-102を一発合格しました。
点数は730/1000点。
勉強期間は約3日間でした。勉強記録はすべて以下に残しています。

# 参考
https://qiita.com/HimatsubushiNiHitsubabushi/items/3cec2192502acd8a38b2

# 勉強に使用した内容
## Microsoft Practice
https://learn.microsoft.com/ja-jp/credentials/certifications/azure-ai-engineer/?practice-assessment-type=certification

## Microsoft Learning
https://learn.microsoft.com/ja-jp/training/courses/ai-102t00

# 模擬試験ログ
## 模擬試験4
回数: 1回目
日付: 2025/1/29
点数: 52%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/f611524f-c47a-5ea4-2a43-88baf8cf8e23.png)


## 模擬試験3
回数: 1回目
日付: 2025/1/29
点数: 52%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/bfaccc0b-571c-1327-5af4-4c3c2198e772.png)


## 模擬試験2
回数: 2回目
日付: 2025/1/29
点数: 100%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/698d0afb-57b1-e2cf-77b0-ad5308307c0f.png)


回数: 1回目
日付: 2025/1/29
点数: 20%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/345de692-6f6b-eb3e-913c-47af020670bc.png)

## 模擬試験1
回数: 2回目
日付: 2025/1/28
点数: 88%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/e8bca1b8-4962-d2d7-6cf0-3f36faaf077c.png)

回数: 1回目
日付: 2025/1/27
点数: 52%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/6c061f98-e1f5-f2ff-6ffc-6356a38d815b.png)


## Microsoft Practice
回数: 3回目
日付: 2025/1/28
点数: 86%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/afed1595-b1c9-6782-01a7-965e7e09910a.png)


回数: 2回目
日付: 2025/1/26
点数: 72%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/56bc9fd6-a03e-93ce-db14-aa0db0c035cc.png)


回数: 1回目
日付: 2025/1/25
点数: 48%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/c82f67e2-88ec-a4bc-3192-89e40c53974b.png)

# まとめ
AI-102を一発合格するまでの記録をまとめました。
これから受験される方にとって少しでも参考になると嬉しいです。
【備忘録】Docker・Docker Compose をUbuntuにインストールする

## 前提条件
WSL上のUbuntuを想定しています
## Docker及びDocker Compose をインストール

systemdの有効化 ( /etc/wsl.conf を作成します。)
```sh
echo "[boot]
systemd=true" | sudo tee /etc/wsl.conf
cat /etc/wsl.conf
```

・一度wsl を再起動する
```sh
wsl.exe --shutdown
```


・再度Ubuntu を開く
・Dockerのインストール (https://docs.docker.com/engine/install/ubuntu/)
```sh
sudo mkdir -p /etc/apt/keyrings
```
```sh
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
```
```sh
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
```sh
sudo apt update
```
```sh
sudo apt install -y docker-ce docker-compose-plugin
```

・dockerをsystemdにサービス登録し、起動を確認
```sh
sudo systemctl enable docker
```
```sh
sudo systemctl status docker
```


・dockerグループへの追加
(自分のアカウントでsudoを使わずにdockerコマンドが使えるようにグループに追加します。)
```sh
sudo usermod 自分のユーザー名 -aG docker
id 自分のユーザー名
```


 ・反映の確認
 ```sh
docker version
```
ScreenCaptureKitについて勉強中


ただのメモ書きです

昔Rustで作ったVectorScopeアプリをMac Nativeで動かしたいと思い実装中

## 今回初挑戦なこと
- Swiftのコード記述
- SwiftUIという概念
- Xcodeでの開発

## すでに知見のあること
- VectroScopeの計算式

## 参考サイト

https://developer.apple.com/documentation/screencapturekit/capturing-screen-content-in-macos
- サンプルアプリが非常に良い
- ドキュメントを読んで1から実装するのが難しそうなので、サンプルを読み解いて改修する方が良さそう
    - [公式サンプルアプリLink](https://docs-assets.developer.apple.com/published/9db8b3fae777/CapturingScreenContentInMacOS.zip)
        - Licenseもかなり自由なので問題なし

## 悩み
- ScreenCaptureKitについて公式意外にほとんど情報がない
    - 一部日本語Blogでお試ししている記事もあるが、Swift初心者には全くわからない
    - ChatGPTがScreenCaptureKitをギリギリ知ってそうなので活用する
- プロジェクトのDir構成やらConfigやら何もわからない
    - 何もわからなすぎてなんと調べて良いかもわからない
        - Xcode入門みたいなのからやらないといけないかも
- SwiftUIもSwiftもわからないので読み解くのに時間がかかる
    - 悩みだけどもこれが一番醍醐味で楽しいかも

## TODO
- [x] サンプルコードからAudioキャプチャの処理削除
- [x] 不要なUIコンポーネント削除
- [ ] キャプチャした動画?画像?から各PixelのRGB取得する
- [ ] VectorScopeにプロットする
- [ ] プロットしたVectorScopeをUIに描画する
- [ ] キャプチャ解像度をUIから変更できるようにする
- [ ] フレームレートをUIから変更できるようにする
- Pickerを使いやすくする
    - [ ] Configuration不要かも
    - [ ] ボタン押下でPicker有効化し、対象選択後に自動で無効化する
【一発合格】AZ-204: Developing Solutions for Microsoft Azureの勉強記録

# 概要
AZ-204を無事一発合格しました。記録として残します。
点数は780/1000点。
勉強期間は約1週間。実施内容はすべて以下に記録しています。

# Microsoft Learning Path
https://learn.microsoft.com/ja-jp/credentials/certifications/azure-developer/?practice-assessment-type=certification

# 参考
以下記事の勉強方法を参考にしました。
https://hirahira.blog/az-204/#toc7



# 模擬試験ログ

## 勉強サイト
https://www.examtopics.com/exams/microsoft/az-204/

https://it-concepts-japan.com/az-204-azure-developer-associate

## Udemy英語テスト
https://www.udemy.com/course/azure-certification-1/?utm_source=aff-campaign&LSNPUBID=%2FNCY0s64yk4&utm_medium=udemyads&ranMID=47984&ranSiteID=_NCY0s64yk4-_CxZRNl9H.75TPJ09L_5rw

1回目：2025/1/4

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/6c9b328f-d00a-3999-c135-653ec3e3fa46.png)


## Microsoft公式Practice

5回目：2025/1/6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/032bb3bd-7711-d388-382c-ea968b88de4b.png)


4回目：2025/1/5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/020aa8d0-d609-ff87-7c80-ce2119c3bb81.png)


3回目：2025/1/5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/63e3d0cb-7c4f-1e4b-3458-3c6cfa196d60.png)


2回目：2025/1/4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/82f82e4d-8b18-4bb9-819f-1a286d73dbd2.png)


1回目：2025/1/3
状態：Udemy模擬試験受講後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/e684ba96-ee8d-a2b1-2503-41abdcbdb6ad.png)

## Udemy日本語テスト
https://www.udemy.com/course/az-204-developing-solutions-for-microsoft-azure-fp/?utm_source=aff-campaign&LSNPUBID=%2FNCY0s64yk4&utm_medium=udemyads&ranMID=47984&ranSiteID=_NCY0s64yk4-580nt1PtQcccepBv6IXUmA

3回目：2025/1/5
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/37d02cfa-216a-c733-5676-3779d5dbdd17.png)


2回目：2025/1/3
状態：Microsoft Learn一周
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/1b3ee1e4-109a-5d29-1f8d-68d0640ed5b3.png)


1回目：2024/12/30
状態：ノー勉強
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/03d87a98-84bc-7403-28b3-ea062ebd2633.png)

# まとめ
AZ-204を一発合格するまでの記録をまとめました。
これから受験される方にとって少しでも参考になると嬉しいです。