OmniAICreator/Qiita-1.07M huggingface dataset:
LINE Messaging API で利用する groupId を無課金で取得する方法

# 目的
Line Notifyが2025/年03月31日に終了するにあたり、Line Messaging APIに乗り換える必要がある。
Line Notifyのように単純にプッシュメッセージを送る方法は、[公式が用意してくれているリファレンス](https://developers.line.biz/ja/reference/messaging-api/#send-push-message "Messaging APIリファレンス プッシュメッセージを送る")を参照したらいい。

https://developers.line.biz/ja/reference/messaging-api/#send-push-message

しかし、リクエストボディの`to`に、`userId`、`groupId`、または`roomId`の値を設定しなければいけないのだが、値を取得する方法がわからなかったので備忘録としてメモを残しておく。

# 具体的な方法
## 1\. Webhook.siteでWebhook URLを発行する。
[Webhook.site](https://webhook.site/) にアクセスすると、自動でURLが発行される。
`Your unique URL`の部分のURLをコピーしておく。

![20250108_webhooksite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/8d5d6508-ef3f-0a3c-9efa-11a3d532c567.png)

https://webhook.site/

## 2\. LINE Developers コンソールでWebhook URLを設定する。
1. 1\. の手順で発行したURLをLINE Developers コンソールの`Messageing API設定`→`Webhook設定`の`Webhook URL`に設定する。
![20250108_qiita_messaging-api-webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/399e1ffc-0f20-8fc7-71ea-f19da1b464e7.png)
1. Webhook URL設定後に正しく設定できたか確認を行う。
LINE Developers コンソール側で`Webhook URL`の`検証`ボタンを押下し、`成功`とポップアップが出ることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/f919906a-764c-7583-4050-05a2ded1f1d6.png)
また、Webhook.site側ではRequestが確認できる。
![20250108_webhooksite_check.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/d50ddc13-a62b-3019-5bfe-9a48513da0ef.png)
1. Webhookが利用できるように、`Webhookの利用`をオンにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/54fb6698-7765-7c20-f07a-cedb4f7db717.png)

## 3\. LINEを操作して`userId`等を取得する。
1. Line Messaging APIでプッシュメッセージを送りたいトークルームを用意し、そこにLINE公式アカウントを招待する。
1. トークルーム内で自分のアカウントでメッセージを送る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/e2e7b458-bc13-db3e-8942-ced77bb34c6c.png)
1. しばらくすると、Webhook.site に新しいRequestが表示される。
`Raw Content`の、`"events"`→`"source"`に`"userId"`等が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240150/6cf78e35-63ec-ab78-afd0-3270f9470d77.png)

# 最後に
* LINE Messageing API で正しくプッシュメッセージを送信できることを確認した後に、`Webhookの利用`をオフにすること。
* 無料版のWebhook.siteはログインなしで動作するため、URLのIDを知っている人なら誰でもデータにアクセスできるようになっている。
メニューの`… More`の`Delete URL...`からデータを削除すること。
RPAについて

## 特徴と概要
ロボティックプロセスオートメーション
複数のインターフェースをまたぐ定型作業に著しい効果をもたらす

PCで行う作業を自動化できるもの
#### 例
複数のサイトにIDとパスワードを入力してExcelに必要情報を入力する作業

### メリット
・生産性向上
・人的エラーが防げる
・安価で導入できる
・ノーコード、ローコードで導入できるため教育コストが少ない
・従来の自動化では業務フローの理解や変更が必要だったが、少しずつ導入が可能

### デメリット
・自動化できない業務が存在する
・一定のITスキルが必要


### 発生する課題と解決方法の例
まずは自動化方法の検討を行う
情報システムの改修は時間が
業務フローを確認して自動化できるところとできないところを見極める

ヒアリングを設計者ごとに分ける
機能の重複がある


## 種類

#### powerautomate
【AWS】イベントメモ【2025/1/8】 #しむそくRadio 新春！冬休みの宿題LTスペシャル


## イベント

https://shimagaji.connpass.com/event/341023/

## Step Functions冬休み復習！直近アップデートと生成AIとの組み合わせ検証	

- JSONataの対応
- バケツリレーの解放

JSONata・Variablesは便利な反面、使いすぎるとデバッグが大変になる。

## Storage Browser for Amazon S3 を Web アプリに組み込んでみた

Storage Browser for Amazon S3をアプリに組み込んだ話です。

S3にファイルをアップロードするときはやはり、AWS SDKを使うことが多いと思う。
アクセス制御の実装もしないといけないため大変である。そこでStorage Browser for Amazon S3を使ってみました。

Storage Browser for Amazon S3はAmplify UIのドキュメントから確認可能であり、Reactベースで使えるものです。StorageBrowserコンポーネントを配置するだけで導入できる。

基本操作はコンポーネントで対応しているため、自分で実装する必要はない。
また、パフォーマンスの最適化は既存で実装されている。

よく使うカスタムとしてはDisplay Textがあると思う。他にもAmplify UIテーマの設定やビューのカスタマイズもできます。

今日紹介できなかった話については2024年12月のアドベントカレンダーを参照してください。

[Storage Browser for Amazon S3 を Remix アプリに組み込んでみた](https://qiita.com/ore88ore/items/089214ce80a9dcd6053d)

## Amplify Gen2 AI Kitで始める！AIサービスをサクッと開発

※登壇者は今回初登壇

Amplify Gen2はフロントエンドバックエンドを統合的に管理できるプラットフォーム
今回はAI Kitについて説明する。

AI KitはAI機能を備えたアプリケーションを迅速に開発するツールキットのこと
Amazon Bedrockとの連携機能などがある。

できることとしては文章生成や構造化データなど主なタスクには対応している。
Amplify UIは10分から15分くらいでセットアップできる。
Conversationルートを使うと多機能なチャットを機能を簡単に実装できる。

AI Kitで気になった機能

- マークダウンの表示
    - テキストの表示が簡単にセットするためのReactコンポーネントがある
- Responseコンポーネント
    - 会話の文脈に応じてUIコンポーネントをAIが使う機能

## Aurora DSQLを使ってTodoアプリ作ってみた	

Aurora DSQLの特徴

- サーバレス
- PostgresQL互換

今回はHonoとDrizzle、backendにAurora DSQLを使う構成でtodoアプリを作った話
DrizzleクライアントではUUIDを使用（serialが未対応のため）
HonoでAPIの実装ではLambdaを使用

課題

- DrizzleとDSQLの互換性問題
    - マイグレーションコマンドを実行できない
- 一部利用できないAPIがある
    - find first関数で別のテーブルを取得しようとするとjsonが取得できない

まとめとしてHonoは使いやすくていい感じだった。ORMの機能はフルで利用できないと思った方が良い。

## Amazon ECS サービスディスカバリーって知ってる?

ゆるふわエンジニアからの登壇、犬がカワイイ、絵本風のLT登壇

App RunnerからOLAP（ECS Fargate）に対してアクセスしたい。VPCコネクターを使うことで接続できる。ALBを使った接続方法もあるけどもOLAPの接続だけでALBを使うのは勿体無い。
ECS サービスコネクトを使って接続することもできるけど結局、ALBが必要になる。
App Mesh（そもそもサービス終了、以下略）

では、サービスディスカバリーを使うのはどうだろうか。これならALBを使う必要がない。
サービスディスカバリーはCloud MapとRoute 53を使っている。

## AWSを使って自分を追い込むための「残っているタスク通知」を作ってみる vol.1

ガンダム=人生の人

今回やりたいこと

- Backlogの未解決になっている課題をSlackに通知したい
- 課題のカテゴリごとに通知するSlackチャンネルを振り分けたい

Step FunctionsのMap機能を使って実装した。
BacklogとSlackチャンネルの対応付けやっているためCSVを使っている。

まとめとしてサーバレスで個人的にも触りやすい。今回はvol1として出しているので今後もアップデートしていきます。

## 感想

最近のアップデートとAmazon ECS、Step Functionsの内容がメインでした。
盛りだくさんだったのでもう一度配信を観てみたいと思いました。また、2024年12月に開催されたアドベントカレンダーについても言及されていたので気になる方は読んでみると良いでしょう。

[KDDIアジャイル開発センター株式会社 - Qiita](https://qiita.com/organizations/kddiagile)
GeoPandas の geometry 列を普通の配列にする

# この記事について

仕事で GIS データを扱うことになったので、基本から学ぶことにしました。
以下の講座を受けながら、学んだことをメモ。

https://www.udemy.com/course/python_gis/

今回はこれ⬇️の逆をやります。
https://qiita.com/IQ_Bocchi/items/1705a0887ae9da14b3b4

# GeoPandas の geometry 列を普通の配列にする

`geopandas.geometry.coords` で座標オブジェクトを取り出し、それをリストにするという手順です。

```python:for 文を使う場合
geo_list = []
for index, row in gdf.iterrows():
  geo_list.append(list(row['geometry'].coords))
```

```python:lambda 関数を使う場合
geo_list2 = gdf.apply(lambda row: list(row.geometry.coords), axis=1)
```

上記の方法で、`Point`、`LineString` どちらの型にも対応ができます。

（`Polygon` は未検証だけどたぶんできるんじゃないか）
動的にボタン制御

動的に生成された<input type="button">も問題なく対象に含めることができます。jQueryの.find()メソッドは、現在のDOMツリーの中で指定したセレクタに一致する要素を動的に検索するためです。

以下のポイントを確認してください。

理由

1. 動的に生成された要素も検索対象
$('#targetDiv').find('input[type="button"]')は、#targetDivの現在の状態（動的に生成された要素も含む）を検索するため、動的要素でも問題ありません。


2. 再検索の仕組み
.find()は呼び出されるたびにDOMツリー全体を調査するため、動的に生成された要素がすでに#targetDivの子孫であれば正常に処理されます。


3. 非活性化の適用
.prop('disabled', true)も対象の要素が現在のDOMツリー内にあれば適切に動作します。




---

確認用の動的生成を含むHTML例

以下の例では、動的に生成された<input type="button">も含めて非活性化します。

<div id="targetDiv">
    <button>既存のボタン1</button>
</div>
<button id="disableButtons">すべてのボタンを非活性化</button>
<button id="addButton">ボタンを動的に追加</button>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
    // 動的にボタンを追加
    $(document).on('click', '#addButton', function() {
        $('#targetDiv').append('<input type="button" value="動的ボタン">');
    });

    // すべてのボタンを非活性化
    $(document).on('click', '#disableButtons', function() {
        $('#targetDiv').find('button, input[type="button"]').prop('disabled', true);
    });
</script>


---

実行の流れ

1. ページロード時は#targetDivに1つの<button>しかありません。


2. 「ボタンを動的に追加」をクリックすると、<input type="button">が追加されます。


3. 「すべてのボタンを非活性化」をクリックすると、既存と動的に生成されたボタンの両方が非活性化されます。




---

注意事項

もし、動的生成された<input type="button">が#targetDiv外に配置される場合や、動的生成時に一時的にDOM外で処理される場合は、以下のようにイベント委譲を利用して適切に制御します。

$(document).on('click', '#disableButtons', function() {
    $('#targetDiv').find('button, input[type="button"]').prop('disabled', true);
});

これにより、動的生成に伴うタイミングの問題も解消できます。
測定器のエネルギー分解能における誤差のつけ方（素粒子実験）

# 始めに
素粒子実験においてエネルギー分解能を求め誤差をつけることは日常茶飯事（多分）。ただ、自分がネットを見たときにその導出方法に対するいい記事が転がっていなかったので、メモ代わりに書いておきます。

# この記事で解説すること
* エネルギー分解能の定義$R = \frac{\Delta E}{E}$から、誤差伝播式に従って、$\sigma_R = R \sqrt{\left( \frac{\sigma_{\Delta E}}{\Delta E} \right)^2 + \left( \frac{\sigma_E}{E} \right)^2}$を導出する。


# エネルギー分解能の誤差伝播の証明

## 1. エネルギー分解能の定義
エネルギー分解能は次のように定義されます

```math
R = \frac{\Delta E}{E}
```
ここで：
- $\Delta E$: エネルギー幅（FWHM など）
- $E$: 中心エネルギー

## 2. 誤差伝播の一般式
ある関数 $f(x, y)$ が $x$ と $y$ に依存する場合、その誤差 $\sigma_f$ は次の式で与えられます：
```math
\sigma_f^2 = \left( \frac{\partial f}{\partial x} \sigma_x \right)^2 + \left( \frac{\partial f}{\partial y} \sigma_y \right)^2
```
ここで：
- $\frac{\partial f}{\partial x}$ と $\frac{\partial f}{\partial y}$ はそれぞれ $f(x, y)$ を $x$ と $y$ で偏微分したもの。
- $\sigma_x$ と $\sigma_y$ はそれぞれ $x$ と $y$ の誤差。

以下のサイトにより詳しい説明があります。
* [誤差伝搬の法則の導出~図を用いて丁寧に解説~](https://qiita.com/yusuke_s_yusuke/items/6222d8565cb22d51051f) 


## 3. エネルギー分解能の偏微分
$f(x, y)$ に対応する $x = \Delta E$ および $y = E$ とし、エネルギー分解能 $R$ に対して偏微分を求めます。

$\frac{\partial R}{\partial (\Delta E)}$：
```math
\frac{\partial R}{\partial (\Delta E)} = \frac{\partial}{\partial (\Delta E)} \left( \frac{\Delta E}{E} \right) = \frac{1}{E}
```

$\frac{\partial R}{\partial E}$：
```math
\frac{\partial R}{\partial E} = \frac{\partial}{\partial E} \left( \frac{\Delta E}{E} \right) = -\frac{\Delta E}{E^2}
```

## 4. 誤差伝播式に代入
上記の偏微分結果を誤差伝播式に代入します：
```math
\sigma_R^2 = \left( \frac{\partial R}{\partial (\Delta E)} \sigma_{\Delta E} \right)^2 + \left( \frac{\partial R}{\partial E} \sigma_E \right)^2
```
```math
\sigma_R^2 = \left( \frac{1}{E} \sigma_{\Delta E} \right)^2 + \left( -\frac{\Delta E}{E^2} \sigma_E \right)^2
```
```math
\sigma_R^2 = \frac{\sigma_{\Delta E}^2}{E^2} + \frac{(\Delta E)^2 \sigma_E^2}{E^4}
```

---

## 5. 変換
エネルギー分解能$R=\frac{\Delta E}{E}$を抜き出し、平方をとります。：
```math
\sigma_R^2 = \frac{\sigma_{\Delta E}^2}{E^2} + \frac{\Delta E^2 \sigma_E^2}{E^4} = \frac{1}{E^2} \left( \sigma_{\Delta E}^2 + \frac{\Delta E^2 \sigma_E^2}{E^2} \right)
```
```math
\sigma_R = \sqrt{\frac{1}{E^2} \left( \sigma_{\Delta E}^2 + \frac{\Delta E^2 \sigma_E^2}{E^2} \right)} = R \sqrt{\left( \frac{\sigma_{\Delta E}}{\Delta E} \right)^2 + \left( \frac{\sigma_E}{E} \right)^2}
```


## 6. 結論
最終的に、エネルギー分解能 $R$ の誤差は以下の式で表されます：
```math
\sigma_R = R \sqrt{\left( \frac{\sigma_{\Delta E}}{\Delta E} \right)^2 + \left( \frac{\sigma_E}{E} \right)^2}
```


# あとがき
この記事はChatGPT 4oで大部分を作成しました。もちろん、内容のチェックはしていますし、文章の微妙な手直しもしています。しかし、書ききるのに10分程度しかかからなくて驚き。ｶｶﾞｸﾉﾁｶﾗｯﾃｽｹﾞｰ!!
SCPの役割とIAMポリシーの違い及び特徴についてざっくり理解を深めたい

### SCPはボスの命令であり絶対。IAMポリシーは部下で命令の範囲内で実行する

SCP（ボス）:

全体の「上限」を定める。
部下がどれだけ権限を持っていようとも、SCPで禁止されていれば何もできない。

IAMポリシー（部下）:

SCPが許した範囲内で、実際に行動できる内容を細かく指定する。
SCPが許可していないことは、IAMポリシーで許可されていても実行できない。


SCP「このAという部屋の中でなら何をしてもいいが、他の部屋の出入りは禁止する！」
IAMポリシー1「Aの部屋でシチューを作る」　→OK
IAMポリシー2「Aの部屋でカレーを作る」　→OK
IAMポリシー3「Aの部屋でシチューを食べる」→OK
IAMポリシー4「Aの部屋でカレーを派手にこぼす」　→SCPが禁止してないのでOK
IAMポリシー5「Bの女子部屋にこっそり入る」→NG SPCが禁止しているので、Bの女子部屋に入ろうとしても、鍵がかかっていて入れない。



### SCPボスの命令書はこれ

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "arn:aws:rooms:A:*"
        },
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "arn:aws:rooms:*",
            "Condition": {
                "StringNotEquals": {
                    "aws:ResourceTag/Room": "A"
                }
            }
        }
    ]
}

```

### IAMポリシーの命令書がこれ（※実際に食べるなどのコマンドはありませんよ！）

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "cook:MakeStew",
            "Resource": "arn:aws:rooms:A:*"
        },
        {
            "Effect": "Allow",
            "Action": "cook:MakeCurry",
            "Resource": "arn:aws:rooms:A:*"
        },
        {
            "Effect": "Allow",
            "Action": "eat:EatStew",
            "Resource": "arn:aws:rooms:A:*"
        },
        {
            "Effect": "Allow",
            "Action": "spill:SpillCurry",
            "Resource": "arn:aws:rooms:A:*"
        },
        {
            "Effect": "Allow",
            "Action": "enter:SneakIntoRoom",
            "Resource": "arn:aws:rooms:B:*"
        }
    ]
}
```

### SCPが許可した範囲であってもIAMポリシーが許可していないと何もできません。

っということは…
IAMポリシーAは、女の子に会うことも、話すことも、触れることもできません。残念でした。IAMポリシーはいちいち許可をしないと何もできません。

## 女の子との関わりに例えると

##### SCP
「女の子がいる部屋に入ることを許可する！」
→ 大枠では部屋に入ることが可能です。

##### IAMポリシーA

何も許可していない
→ 結果: 部屋に入れても、以下はできません。
女の子に 会う → NG
女の子と 話す → NG
女の子に 触れる → NG


## 結論、SCPが許可している範囲内で、かつIAMポリシーが許可していないと何もできません。

SCPはボス、IAMポリシーは女王様？
IAMポリシーが女王様だったら、部屋に入っても何もできませんね。結論、女王様の命令は絶対です。
React Native プロジェクト作成時に出る（EMFILE: too many open files）エラーの解決法

# エラー内容

React nativeのプロジェクトを作成したとき、以下のようなエラーに出会った。

```
npx react-native start
```

```
node:events:495
      throw er; // Unhandled 'error' event
      ^

Error: EMFILE: too many open files, watch
    at FSWatcher._handle.onchange (node:internal/fs/watchers:207:21)
    ...
{
  errno: -24,
  syscall: 'watch',
  code: 'EMFILE',
  filename: null
}
```

同時に開けるファイル数がOSの制限を超えてしまったというエラー。watchmanはインストール済みだった。

# スペック

MacOS 
React v19.0 


# 解決法

`node_modules`フォルダを消去、`npm install`で再作成

```
rm -rf node_modules
npm install
```

どうも`node_module`にファイルがありすぎてファイル数の上限に引っかかっていた模様。


# 効果がなかった解決法

1.  Nodeのバージョン変更
v18やv16に落としたが効果がなかった。ネットでは聞いたという人も見られるので試してみてもいいかも。

2. watchmanの再インストール
  そもそも新規プロジェクトにインストールしたばかりなので効果がないのは当然。

3. Homebrewの更新
効果なし



# 参考文献

https://stackoverflow.com/questions/58675179/error-emfile-too-many-open-files-react-native-cli
【ChatGPT】何かを毎日続けるための助言をもらうためのPromptです。


　どうも、カーブミラーです。

　今回は、何かを毎日続けるための助言をもらうためのPromptです。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　さっそく、【本題】です。

　今回は、
　　何かを毎日続けるための助言を
　　　もらうためのPromptです。

　仕事を毎日続けるのは、
　　大変ですよね。

　プライベートの楽しみや
　　彼氏・彼女・子どもやペットとの
　　　交流を癒しとして得られれば
　　　　まだいいのですが、
　　　　　それが難しい場合も
　　　　　　ありますよね。

　そこで
　　ChatGPTに助言をもらえないかと
　　　このPromptを作成しました。

　一問一答して
　　あなたの状況を確認したあと、
　　　助言をもらえます。

　＊＊＊に毎日続けたいことを
　　入力して、送信してください。
```Text:毎日続けるための助言Prompt
毎日、[＊＊＊]を続けるためには、どうすればいい？

私の状況を一問一答してから、回答してください。
```

　まぁ、ないよりは、という
　　レベルかもしれませんが、
　　　ここからさらに深掘りしていけば
　　　　良い知見が得られるかも。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
RAGの仕組みとサンプルコード

RAG（Retrieval-Augmented Generation）は、AIが質問に答える際に「検索」と「生成」を組み合わせることで、より正確で有益な回答を提供する技術です。本記事では、RAGの基本的な仕組みや構築のステップ、Pythonによる実装例を分かりやすくまとめます。
※この記事は、ChatGPTの出力を基に作成しています。

---

# RAGとは？
RAGは、情報を外部から検索（Retrieval）し、それを元に回答を生成（Generation）する仕組みを持つAI技術です。例えば、「日本で一番高い山は何ですか？」という質問に対して、まず外部データベースを検索して富士山の情報を取得し、その内容を基に自然な形で答えを生成します。

RAGの特徴は以下の通りです：
- 最新の情報にアクセス可能：事前学習だけでは対応できない新しい情報も取り入れることができます。
- 正確性の向上：関連する情報を外部から取得するため、回答の精度が高まります。

---

# RAGを構築するステップ
RAGシステムを構築する手順を以下に示します。

### 1. データ準備
- 回答に必要な情報を収集し、検索しやすい形式（例：JSON、CSV）に構造化します。
- 検索を効率化するためにインデックス（索引）を作成します。ElasticsearchやFAISSが一般的なツールです。

### 2. 検索モデルの構築
- ユーザーの質問に関連する情報を検索する仕組みを用意します。
- 例えば、Dense Passage RetrieverやSentenceTransformerを利用して質問やドキュメントをベクトル化し、類似性検索を行います。

### 3. 生成モデルの準備
- GPTやT5など、回答を生成するモデルを用意します。
- 必要に応じて、特定分野に特化した微調整を行うと、より自然な回答が得られます。

### 4. リトリーバルとジェネレーションの統合
- 検索で取得した情報を生成モデルに渡し、回答を作成するフローを構築します。

### 5. ユーザーインターフェースの作成
- ユーザーが質問を入力し、答えを受け取れるインターフェースを用意します（例：ウェブアプリやチャットボット）。

### 6. 精度と性能の改善
- システムの動作を確認し、検索精度や生成品質を繰り返し改善します。

---

# PythonでのRAG構築例
以下は、簡単なRAGシステムをPythonで構築するサンプルコードです。

```python
import faiss
from sentence_transformers import SentenceTransformer
from transformers import pipeline

# データ準備
documents = [
    "富士山は日本で一番高い山で、標高は3776メートルです。",
    "東京は日本の首都で、多くの観光名所があります。",
    "桜は日本を代表する花で、春に美しく咲きます。",
]

# 埋め込みモデルで文書をベクトル化
embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
doc_embeddings = embedding_model.encode(documents)

# FAISSインデックス作成
dimension = doc_embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(doc_embeddings)

# 検索関数
def retrieve(query, top_k=1):
    query_embedding = embedding_model.encode([query])
    distances, indices = index.search(query_embedding, top_k)
    return [(documents[i], distances[0][idx]) for idx, i in enumerate(indices[0])]

# 生成モデルを設定
generator = pipeline('text-generation', model='gpt2', tokenizer='gpt2')

# 質問応答
def answer_question(question):
    relevant_docs = retrieve(question, top_k=1)
    if not relevant_docs:
        return "すみません、適切な情報が見つかりませんでした。"
    
    context, score = relevant_docs[0]
    prompt = f"質問: {question}\n\n参考情報: {context}\n\n答え:"
    response = generator(prompt, max_length=100, num_return_sequences=1)
    return response[0]['generated_text']

# 実行
question = "日本で一番高い山は何ですか？"
print(answer_question(question))
```

# 実行結果
上記のコードを実行すると、以下のように回答が生成されます。

**入力:**
```
「日本で一番高い山は何ですか？」
```

**出力:**
```
「日本で一番高い山は富士山です。標高は3776メートルです。」
```

# まとめ
RAGは、AIの質問応答の精度を大幅に向上させる技術です。検索モデルと生成モデルを連携させることで、AIが外部の情報を活用して新しい知識や正確な答えを提供できるようになります。

この記事では基本的な仕組みと構築手順、Pythonでの実装例を紹介しましたが、応用次第で多くの分野に適用可能です。より精度を高めるためには、データ拡充やモデルの微調整が重要になります。

今後、より高度なシステムを作るためのアイデアがあれば、ぜひ試してみてください！
Laravel+viteにSwiper.js(v11.2.0)を導入する

### 導入の準備
まずはresources/jsに`swiper.js`、resources/cssに`swiper.css`を作ります。
次に`app.js`、`app.css`にそれぞれ`@import "swiper";`を記述します。
### インストール
`npm install swiper`
### swiper.jsの記述
Initializeする時にうっかりmodulesの記述を消してしまい、動作しないため原因究明のために無駄に時間を過ごしてしまったので気をつけてください。
```Javascript:resources/js/swiper.js
// import Swiper JS
import Swiper from 'swiper';
// import Swiper styles
import 'swiper/css';

// core version + navigation, pagination modules:
import { Navigation, Pagination } from 'swiper/modules';
// import Swiper and modules styles
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';

// init Swiper:
const swiper = new Swiper('.swiper', {
  // configure Swiper to use modules
  modules: [Navigation, Pagination], // 記述を忘れずに
  
  // Optional parameters
  // direction: 'vertical',　// コメントアウト
  loop: true,

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },

  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },

  // And if we need scrollbar
  scrollbar: {
    el: '.swiper-scrollbar',
  },
});
```
### swiper.cssの記述
```css:resources/css/swiper.css
.swiper {
  width: 600px;
  height: 300px;
}
```
### HTMLの記述
```HTML
<!-- Slider main container -->
<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <div class="swiper-slide">Slide 1</div>
    <div class="swiper-slide">Slide 2</div>
    <div class="swiper-slide">Slide 3</div>
    ...
  </div>
  <!-- If we need pagination -->
  <div class="swiper-pagination"></div>

  <!-- If we need navigation buttons -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

  <!-- If we need scrollbar -->
  <div class="swiper-scrollbar"></div>
</div>
```
ここまで記述すれば`npm run dev`で動作します。
#### 参考
https://swiperjs.com/get-started
p5.jsで機械学習用のカスタムデータセットを作成するツールを作ってみた

## はじめに

機械学習、特にGANの学習においてMNISTデータセットは代表的な教材として使用されています。しかし、MNISTに限らず独自のデータセットで実験したいケースも多いのではないでしょうか。

そこで、p5.jsを使用して簡単にカスタムデータセットを作成できるツールを開発しました。

## 開発したツールについて

**p5-shape-table-generator**は、p5.jsを使用して手軽に機械学習用のデータセットを作成できるWebアプリケーションです。

### デモ

以下のURLで実際に試すことができます：
https://koya-kimura.github.io/p5-shape-table-generator/

### 生成データについて

#### 画像データ

![0009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2236620/b0d2eb62-9435-4af2-bf5e-333f8b940395.png)

- ランダムな位置に正多角形を生成
- 3〜6角形の自動生成
- 図形のパラメータをCSVファイルに保存
- 生成された図形をPNG形式で保存
- 中心座標の正規化（0-1の範囲）

#### csvデータ

- CSVデータ（shape_data.csv）

| カラム名 | 説明 | 値の範囲 |
|---------|------|----------|
| file | 画像ファイル名 | 4桁の連番 |
| centerX | X座標（正規化） | 0-1 |
| centerY | Y座標（正規化） | 0-1 |
| radius | 半径（ピクセル） | 実数 |
| vertices | 頂点数 | 3-6 |
| angle | 回転角度 | 0-2π |
| perimeter | 周の長さ | 実数 |

### 特徴

- ブラウザ上で直接描画が可能
- MNISTデータセットに近い形式でデータを生成
- p5.jsの描画機能を活用した直感的なインターフェース

## 使用技術

- p5.js
- HTML5 Canvas
- JavaScript

## 使い方

1. ブラウザでツールにアクセス
2. キャンバス上に任意の図形を描画
3. データセットとして保存

## ソースコード

GitHubでソースコードを公開しています：
https://github.com/koya-kimura/p5-shape-table-generator

## おわりに

このツールを使用することで、機械学習の実験用データセットを手軽に作成することができます。MNISTデータセット形式の独自データセットが必要な場合に、ぜひ活用してください。
石橋を叩いて絶対に渡らない人のためのapt upgradeガイド

パッケージリストを更新する（実際のパッケージのインストールやアップグレードは行われない）。
```bash
sudo apt update
```

アップグレード可能なパッケージの一覧を表示する（実際のパッケージのアップグレードは行われない）。
```bash
apt list --upgradable
```

セキュリティ関連のアップデートが可能なパッケージの一覧を表示する（実際のパッケージのアップグレードは行われない）。
```bash
apt list --upgradable | grep security
```

パッケージのアップグレードをシミュレーションする（実際のパッケージのアップグレードは行われない）。
```bash
sudo apt upgrade --dry-run
```

あるパッケージ（たとえば`openssl`）のアップグレードをシミュレーションする（実際のパッケージのアップグレードは行われない）。
```bash
sudo apt install --only-upgrade --dry-run openssl
```

`--dry-run`オプションを除外すれば、実際にアップグレードが行われる。
【Android】ホームボタン押下時にPIP (Picture in Picture) 実行

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/f19a4c3f-0bf3-0d26-0b53-0cf4167f4b03.gif" width="140">

# はじめに

Androidアプリ開発で、ホームボタン押下時にPIP (Picture in Picture) 実行する処理について解説。

# 方法

Android 12以降→Android`PictureInPictureParams`の`autoEnterEnabled`を`true`にする。

Android 12未満→`onUserLeaveHint`でPIP実行する。

# コード

```Kotlin
class MainActivity : AppCompatActivity() {

    /** ViewBinding */
    private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        // SDKバージョンが31以上の場合
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            //ここでPIP設定
        }
    }

    override fun onUserLeaveHint() {
        super.onUserLeaveHint()

        // SDKバージョンが26以上31未満の場合
        if (Build.VERSION.SDK_INT in Build.VERSION_CODES.O until Build.VERSION_CODES.S) {
            //ここでPIP実行
        }
    }
}
```

詳しくは[こちら](https://note.com/naka_inc/n/n374087bc7e8e)に記述。

https://note.com/naka_inc/n/n374087bc7e8e
HTML上にバイナリデータから画像を復元する方法

# HTML上にバイナリデータから画像を復元する方法

今回はHTML上にバイナリデータから画像を復元する方法を紹介します。

## 用意するもの

復元に必要なのは元画像のバイナリデータと、横幅、縦幅なので、それらを用意します。
自前で用意したい場合は以下のコードで取得できます。

``` byteToImage.js

//ここだけ取得したいimage要素のIDに変更
const img = document.getElementById('img');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
//width取得
console.log(img.width);
//height取得
console.log(img.height);
//画像のバイナリデータ取得
console.log(imageData.data.toString());

```

今回は以下の画像から復元します。
![job_programmer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350501/09dd38e1-d644-1de2-a13e-faff27c31a67.png)


取得した値はこちらで、JavaScriptで配列に入れておきます。(バイナリデータは2057600と長くなるので省略)

``` javascript

//元画像の横と縦
const width = 800;
const height = 643;

//元画像のバイナリデータ
const bytes = [
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...........
];

```
</details>

## バイナリデータから画像を復元する

バイナリデータから画像を復元するには、以下のようなコードを使います。

``` byteToImage.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>byteToImage</title>
  </head>
  <body>
    <img id="img" src="" alt="" />
  </body>
  <script src="./byteToImage.js"></script>
  <script>
    //復元した画像を表示するimageタグ
    const img = document.getElementById("img");
    //縦と横を指定する。値に注意※1
    img.width = width;
    img.height = height;
    const pixels = new Uint8Array(bytes);
    // ImageDataを作成
    const imageData = new ImageData(
      new Uint8ClampedArray(pixels.buffer),
      img.width,
      img.height
    );
    //作成した画像データをcanvasを通じてimageタグに表示する
    const canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    const context = canvas.getContext("2d");
    context.putImageData(imageData, 0, 0);
    img.src = canvas.toDataURL();

    //今回は画像が大きかったので表示の際に1/3のサイズに縮小
    img.width = img.width / 3;
    img.height = img.height / 3;
  </script>
</html>

```

※1
new ImageData()の際に元画像のwidth * height * 4した値がバイト数と一致していないとエラーになるので注意してください。
今回だったらwidthが800,heightが643になって、バイト数が2057600です。
800 * 643 * 4 = 2057600 です。

以上です！
circuitjsの作法 その20

# 概要
circuitjsを調査してみた。
練習問題やってみた。

# 練習問題
リレーで、nor回路を作れ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6aefbd0f-625f-0250-b1a3-5617a9bad6e7.png)


# ネットリスト

```
$ 1 0.000005 10.20027730826997 50 5 50 5e-11
g 608 448 608 496 0 0
R 304 128 224 128 0 0 40 5 0 0 0.5
178 640 288 640 448 6 1 0.2 0 0.05 1000000 0.02 20 0.015 0.005 0
w 608 192 608 288 0
w 304 128 352 128 0
w 352 128 640 128 0
162 640 160 640 208 2 default-led 1 0 0 0.01
x 462 84 501 87 4 24 nor
s 384 192 496 192 0 1 false
s 384 256 496 256 0 1 false
w 384 192 304 192 0
w 304 176 304 128 0
w 304 176 304 192 0
w 496 192 608 192 0
178 528 288 528 448 6 1 0.2 0 0.05 1000000 0.02 20 0.015 0.005 0
g 496 448 496 496 0 0
w 496 256 496 288 0
w 384 256 304 256 0
w 304 256 304 192 0
w 640 160 640 128 0
w 544 448 544 464 0
g 656 448 656 496 0 0
w 640 208 640 224 0
w 640 224 576 224 0
w 576 464 544 464 0
w 528 288 528 224 0
w 576 224 528 224 0
w 576 464 576 288 0
w 576 288 640 288 0

```


以上。
緯度・経度をもつCSVを GeoDataFrame に変換する

# この記事について

仕事で GIS データを扱うことになったので、基本から学ぶことにしました。
以下の講座を受けながら、緯度・経度を持つCSVをGeoDataFrameに変換する方法をメモ。

https://www.udemy.com/course/python_gis/

※この記事のデータは講座で出てくるものとは違うものを使います。

# やりかた

## 準備 - 緯度・経度を持つCSVを用意する

今回は東京都のオープンデータで、多摩市のスポーツ施設の一覧を使います。

データは以下のように、緯度と経度の情報が入ってはいるものの、`geojson` などの形式になっていないただのCSVです。

![Screenshot 2025-01-08 at 10.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/979bc1f6-79a7-d466-a205-3d6290fbc2a1.png)

以下のサイトでデータの内容を参照できます。

https://catalog.data.metro.tokyo.lg.jp/dataset/t132241d3100000004/resource/a9a89c5b-8e22-4357-a0d2-97ae8e6f7b7e

⬆️にもリンクがありますが、以下のリンクから CSV をダウンロードできます。

https://www.opendata.metro.tokyo.lg.jp/tama/132241_tama_sportsfacilities.csv


csvを任意のフォルダに置いた状態で、以下に進みます。

## Step1. CSVを普通の pandas の DataFrame として読み込む

まず、CSVを普通の pandas の DataFrame として読み込みます。

```python
# 普通の pandas の DataFrame として読み込む
path = './132241_tama_sportsfacilities.csv'
df = pd.read_csv(path)
```

`path` の指定は、適宜変更してください。

今回の多摩市のデータは、カラム数がやたら多い(23行、122列)ので、必要に応じてほしい列だけに絞ります。

```python
# ほしい列だけを取り出す
wanted_cols = "ID 名称 緯度 経度 電話番号 利用可能曜日".split()
df = df[wanted_cols]
```

## Step2. 緯度と経度の列を geometry 列として定義する

現時点では、緯度と経度の情報は名前こそ緯度・経度であるものの、データ型としては numpy の float 型として入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/0e8c472b-c975-1370-455a-8366284e7efe.png)

以下の記事で記載したとおり、GeoPandasには _アクティブなジオメトリ列_ の定義が必要です。

https://qiita.com/IQ_Bocchi/items/a80ff63a053116264b7d

なので緯度・経度情報を、ジオメトリ型に変換しつつ、_アクティブなジオメトリ列_ として使えるように準備する必要があります。

以下のコードで、緯度と経度をまとめて `GeometryArray` にすることができます。

```python:geometry として使う列を定義する
# geometry として使う列を定義する
geometry_cols = gpd.points_from_xy(df['経度'], df['緯度'])
```

## Step3. もとの DataFrame に geometry 列を合わせて GeoDataFrame を作る

以下のコードで、今作った geometry 列用の `GeometryArray` をもとの `df` に足して、GeoDataFrame を作ることができます。

```python:GeoDataFrame を作る
# もとの df に geometry 列を足して GeoDataFrame を作る
gdf = gpd.GeoDataFrame(df, geometry=geometry_cols)
```

`gdf` を表示すると、以下のように、緯度経度を `Point` として持つ `geometry` 列が、もとの `df` のうしろにくっついた形になっていることがわかります。

![Screenshot 2025-01-08 at 10.57.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/298e0bfb-402a-d1e7-f2c2-80af30251292.png)

## おまけ

上記の `gdf` を geojson として保存することは、以下のコードで可能なのですが、今のままだとcrsの情報がないと怒られます。

```python
outpath = './tama.geojson'
gdf.to_file(outpath, driver='GeoJSON', encoding='shift-jis')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/7d1fba90-cf63-3b56-a111-267d1cfc59ea.png)


たぶんcrsの情報を別途定義する方法があるのだろうと思いますが、そちらはわかり次第（必要になり次第）まとめたいと思います。
ESモジュールの挑戦記です。

# はじめに
この記事は、コードの書き方は説明していません。
なぜ、ESモジュールに興味を持ったか、また、テスト的に作成したモジュールで実行した体験記です。

# ESモジュールに興味を持った経緯
この仕様は2015年版とのことです。
javascriptのコードステップ数が増大してくると、モジュール化して分割してロードする必要が出てくるということです。
今のコードは確かに延べたんで、だらだらと長くなっています。あとから見ると理解に時間がかかっています。

もう少し、すっきりしとしたコーディングはできないものかと思っていました。
クラス化やオブジェクト化も進めた方がいいと思っています。
そういう時に、以前にもこのES5とかES6とかしいう文字はネットで目にしていました。モジュールかなのかという程度で、それ以上深入りはしませんでした。
この仕様が、公開されたのが2015年ということですから、すでに9年近く経っています。

その時は、少し、exportやimportを試してみましたが、全く動作できませんでした。結構、難解かなと思ってあきらめていました。今日まで、その状態で来てしまいましたが、
そろそろ、もう一度試してもいいかなと思いはじめました。

# 調べて行くうちに
いろいろ、調べて行くと、何でもかんでもES対応できるというものではないようです。
たとえば、youtube player APIのようなスクリプトファイルはES対応していないとか、ChromeのプラグインはES対応していないとか出てきます。
ただし、ある対処をすれば、ES化することは可能とも出ています。
確かに、youtube player APIの時は、exportやimportを試しても全く動作しませんでした。
プラグインの時もどのようにして、type='module'を指定すればいいのかがわかりませんでした。

それらについても、調査を続けて行くうちに、その解決方法に出会いました。まだ、試してはいませんが、対処方法はあるようです。


# どのようなテストをしたか
やはり、これまでもyoutube player APIを使用して、動画の再生ページを作成してきましたから、そのあたりでexport/importをテストしようと思いました。ただ、ネットにもでていましたが、youtube player APIは、そのままでは対応していないので、その周辺からESモジュール化を試してみました。
　
今回のテストでは、youtube player APIはそのまま使用しています。モジュール化したのは、再生リストの作成、表示部分です。
かなりの試行錯誤をしてようやく成功しましたが、そこで、わかったことは、次のことです。

1. 決定的だったことは、この`<script type='module' src='........'></script>`の`type='module'` でした。このスクリプトタグで、jsのモジュールファイルを指定することが必要だったことです。
`<script  type ='module' src="./js/stampTube.js"></script>`

2. exportの指定
これについても様々な指定方法があるようです。
`export default List;`

3. importの指定
`import List from 'https://favorite.tecoyan.net/slim/js/favoriteClass.js';`

# ちょっと邪道かもしれませんが
モジュール内で生成したオブジェクトですが、本来であれば、他のモジュールでimportはできるようですが、モジュールになっていない通常のjsファイルがそのオブジェクトを参照したいときがあります。モジュールのオブジェクトなので、グルーバル変数にもできないようで、この時にwindow.オブジェクト変数= 生成したモジュールのオブジェクト変数が代入されるようで、そうすると他のjsファイルからもそのオブジェクト変数が参照できるようになりました。

# 結果
今回のモジュールテストで、youtube player APIを使用して、リストの再生、リストのサムネイルクリック再生、リストの自動連続再生(リストのループ)が確認できました。
ただし、youtube player APIは、ES対応はしていません。
とにかく、要件がそろわないとexport/importは動かないということはわかりました。
最初はかなり、難解でした。


# あとがき
今後は、javascriptのESモジュール化は推進して行くかまだ、迷っています。どこをどうモジュール化するかの設計がまだ明確にできていないためです。中途半端にES化をしてしまうとES化していないjsファイルとうまく、整合がとれなくなりそうで、するとなると大変なボリュームなので、無理かなと思っています。
過去のものは捨てて、新規のみにするとかしないと混乱するかと思っています。
利用しているライブラリーやAPIにもまだ、ES対応していないものもあります。
今は、少し勉強したかなという段階です。
circuitjsの作法 その19

# 概要
circuitjsを調査してみた。
練習問題やってみた。

# 練習問題
リレーで、nand回路を作れ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d4193dd6-91cb-2e6d-21c0-94d9eaa0fdbc.png)


# ネットリスト

```
$ 1 0.000005 10.20027730826997 50 5 50 5e-11
g 608 448 608 496 0 0
R 304 128 224 128 0 0 40 5 0 0 0.5
178 640 288 640 448 6 1 0.2 0.24999999999997224 0.05 1000000 0.02 20 0.015 0.005 1
w 608 192 608 288 0
w 304 128 352 128 0
w 352 128 640 128 0
162 640 160 640 208 2 default-led 1 0 0 0.01
x 462 84 520 87 4 24 nand
s 384 192 496 192 0 0 false
s 384 256 496 256 0 0 false
w 384 192 304 192 0
w 304 176 304 128 0
w 304 176 304 192 0
w 496 192 608 192 0
178 528 288 528 448 6 1 0.2 0.24999999999997224 0.05 1000000 0.02 20 0.015 0.005 1
g 496 448 496 496 0 0
w 496 256 496 288 0
w 384 256 304 256 0
w 304 256 304 192 0
w 640 160 640 128 0
w 640 208 640 288 0
w 640 288 528 288 0
w 544 448 544 464 0
g 656 448 656 496 0 0
g 544 464 544 496 0 0

```

以上。
GeoPandas はじめの一歩

# この記事について

仕事で GIS データを扱うことになったので、基本から学ぶことにしました。

以下の講座を受けながら、登場した geopandas の基本について、[公式の introduction](https://geopandas.org/en/stable/getting_started/introduction.html) を参考にまとめてみます。

https://www.udemy.com/course/python_gis/

# 謎だったこと

`GeoDataFrame` を作ったときに、列名を `geometry` にしたときと別の列名にしたとき（`geo_col` など）で挙動が変わることがあった。

どちらも型はジオメトリ型として認識されていたので、`geometry` という列名に何か特殊な意味があるのか？ と思い調査開始。

# GeoPandas ことはじめ

## GeoDataFrame とは

`geopandas.GeoDataFrame` は Pandas の `pandas.DataFrame` のサブクラスで、GeoPandas の格となるデータ構造です。

違いとしては、`geopandas.GeoDataFrame` は地理空間関係の操作を行うための地理空間用カラムを持てること。この地理空間用カラムを扱うのは、Pandas の `pandas.Series` のサブクラスである `geopandas.GeoSeries` です。

したがって、`GeoDataFrame` は伝統的なデータ型（数値、boolean、テキスト等）を持つ `pandas.Series` と、地理空間用のジオメトリ型データ（point、polygon等）を持つ `geopandas.GeoSeries` の組み合わせです。

一般的なデスクトップのGISソフトウェアと異なり、地理空間用データの列は好きな数だけ持つことができます。

## GeoSeries とは

`GeoSeries` には任意のジオメトリ型のデータを持つことができ、ひとつの配列の中に複数のジオメトリ型を混在させることもできます。

`GeoSeries` は `GeoSeries.crs` という属性を保ち、参照系の情報を保持します。

:::note
座標参照系（CRS）ってなに？ という話を[こちらの記事](https://qiita.com/IQ_Bocchi/items/f2f7724534cba192dbca#crs---%E5%BA%A7%E6%A8%99%E5%8F%82%E7%85%A7%E7%B3%BB)に記載しています。
:::

## アクティブなジオメトリ列 - GeoDataFrame の中の特殊なGeoSeries

`GeoDataFrame` の中では、ひとつの `GeoSeries` だけが _アクティブなジオメトリ列_ とみなされ、地理空間関係の操作はすべてこのカラムに対して行われます。

この _アクティブなジオメトリ列_ には、 `GeoDataFrame.geometry` 属性でアクセスすることができます。

# たぶん謎が解けました

やはり `geometry` という名前には特別な意味があったらしい。

列名を `geometry` にしておくことで、デフォルトでその列に `GeoDataFrame.geometry` 属性によってアクセスできるようになり、 _アクティブなジオメトリ列_ として認識してくれるっぽい。

おそらく任意の列名を _アクティブなジオメトリ列_ に指定する方法もあるのかもしれないけど、一旦  _アクティブなジオメトリ列_ にしたい列は `geometry` という名前で持ちましょう、という結論でいいっぽい。
アタック事例：標的型ソーシャルエンジニアリング

# 攻撃手法

1. LinkedIn上でリクルーターになりすまし
1. リクルーターは、採用前試験を装った悪意あるPythonスクリプトへのURLを被害者へ送付
1. 被害者は、このPythonコードを自身のGitHubページにコピーし、その後、侵害された。 

# 被害

約482億円相当の暗号資産を窃取された

# 情報源

* 北朝鮮を背景とするサイバー攻撃グループTraderTraitorによる暗号資産関連事業者を標的としたサイバー攻撃について｜警察庁Webサイト
https://www.npa.go.jp/bureau/cyber/koho/caution/caution20241224.html
  * https://www.npa.go.jp/bureau/cyber/pdf/20241224_jp.pdf

> 2024年3月下旬、北朝鮮のサイバーアクターは、LinkedIn上で、リクルー
ターになりすまし、日本に所在する企業向け暗号資産ウォレットソフトウェ
ア会社Gincoの従業員に接触した。同脅威アクターは、Gincoのウォレット
管理システムへのアクセス権を保有する従業員に、GitHub 上に保管された
採用前試験を装った悪意あるPythonスクリプトへのURLを送付した。被害
者は、このPythonコードを自身のGitHubページにコピーし、その後、侵害
された。
正味価格と正味額

正味価格（净价，Net Price） 是指在商业交易中，去除了折扣、附加费用或税金之后的实际支付价格。它是买方需要支付给卖方的最终价格，通常用于清晰地表达货品的成本。

正味価格的计算公式
正味価格 = 基本価格（基本价，Gross Price） - 割引（折扣） + 附加费用 - 税金（在特定情况下）

正味価格的例子
例子 1：商品购买
商品的基本价格（标价）：10,000日元
折扣：500日元
附加费用（运费）：200日元
正味価格 = 10,000 - 500 + 200 = 9,700日元

在这个例子中，买方实际需要支付 9,700日元，这就是正味価格。

日本語解釈：
正味価格（正味単価） は、取引において最終的に支払う金額を指します。基本価格（標準価格）から割引を引き、必要な追加費用（例えば送料や保険料など）を加えた金額です。
--------------------------------------------------------
正味額
実際の取引で決定される金額で、正味価格に対して各種割引、調整、送料などの加減が反映された最終的な金額です。つまり、請求書上や決済時に実際に支払われる、受領される金額を意味します。

一般来说：基本计算公式是：
正味価格 × 数量 = 正味額
但需要注意以下几点：
调整因素：在实际业务中，可能还会有其他调整（例如折扣、附加费或特殊条件），这时最终金额可能不只是单纯的乘积。
精度问题：涉及小数的计算时，要注意四舍五入等精度问题。
noreply@ドメイン名のメールアドレスってどうなん？

迷惑メール対策中に話題があがったので、ちょっと調べました。そのメモです。
RFCでは定義されてないようです。

# 対応案

* (案1) noreply@ドメイン名は使わず、実在するメールアドレス(support@ドメイン名 等)を使う
* (案2) 今は配信できてるのであれば、そのままで様子を見る（緊急ではない）

# 情報源
[業務に適したメールアドレスは！？info！？support！？RFCで定義されているメールアドレスは！？調べてみました！ │ Webty Staff Blog](https://webty.jp/staffblog/production/post-2800/)
> noreplyはRFCでは定義されていないので使用する場合には注意が必要ですね。

* [返信不可メール「noreply@ドメイン名」を使用すべきでない理由と対処法 | 【公式】ブラストエンジン（blastengine）｜API連携・SMTPリレー](https://blastengine.jp/blog_content/noreply)
  * メール配信サービス ブラストメール を展開するブラストエンジンでは「使わないで」との事
  * 一部の国では法律に違反する恐れあり

# 所感

* 実在しないメールアドレス noreply@ドメイン名 でも現在（2025/1/8） gmail配信できる
* ただし、gmailのようなRFC＋独自ルールで迷惑メール判定を行っているサービスは、今はOKでも、いつ迷惑メール判定が変更されて、迷惑メール行になる可能性が捨てきれない。（ここが悩ましい）
【ITパスポート合格しました。使用教材の紹介】

昨年の９月にITパスポートを取得しました。

### 各科目点数
・ストラテジ➡７５０／１０００
・マネジメント➡７２０／１０００
・テクノロジ➡７１５／１０００

全体的に７割以上とれて合格でき、学習の成果が反映されて良かったと思います。:relaxed:

### 学習期間と使用教材について

・学習期間➡２か月（仕事をしながら）
・使用教材➡「ITパスポート絶対合格の教科書」と過去問道場

https://www.amazon.co.jp/%E3%80%90%E4%BB%A4%E5%92%8C%EF%BC%97%E5%B9%B4%E5%BA%A6%E3%80%91-%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84-IT%E3%83%91%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88-%E7%B5%B6%E5%AF%BE%E5%90%88%E6%A0%BC%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%EF%BC%8B%E5%87%BA%E3%82%8B%E9%A0%86%E5%95%8F%E9%A1%8C%E9%9B%86-%E7%B5%B6%E5%AF%BE%E5%90%88%E6%A0%BC%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4815629382/ref=asc_df_4815629382?mcid=6ba4424866b134c0ba76c907d9ef09fc&th=1&psc=1&tag=jpgo-22&linkCode=df0&hvadid=707442559095&hvpos=&hvnetw=g&hvrand=11502293293274201274&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9167754&hvtargid=pla-2452143942917&psc=1&gad_source=1

### 学習スケジュール


①「ITパスポート絶対合格の教科書」を３周
②過去問道場を最新分から５年分解く

３周目では教科書の細かいところまで暗記することに努めました。
（この細かい内容がけっこう試験にでました、、）

この方法でITパスポートに合格することができました。
IT未経験の私からしたら、システム開発の全体像が学べたので良かったと思います。

次は２月に基本情報技術者試験を受験します。必ず合格します！🔥
someの使い方、やっとピンときたので書き留めておくログ

## はじめに
someがJavaScriptで便利なメソッドだと知ってはいたものの、実際にどういうタイミングで使えばいいのかイメージが湧いていませんでした。しかし、コーディング中にピンとくる使用場面に出会ったので、その内容を記録として残します。

## someについて
公式ドキュメントから引用します。
> 指定された関数で実装されているテストに、配列の中の少なくとも 1 つの要素が合格するかどうかを判定します。配列の中で指定された関数が true を返す要素を見つけた場合は true を返し、そうでない場合は false を返します

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some

## やりたかったこと
たとえば、特定の形式のファイルのみアップロードを許可する関数を書きたかったとします。
指定した形式で終わっていたら、console.logでOK、合致しなかったらNGを表示します。
このような仕様があったと仮定した場合、私は最初次のようにコードを書いていました。
```js
const allowedExtensions = ['.jpg', '.png', '.gif', '.psd', '.tif', '.tiff'];

const isAllowedExtensions = (file) => {
  for(let allowedExtension of allowedExtensions){
    if (file.endsWith(allowedExtension)) {
      return true;
    }
  }
  return false;
};
```

上記のようにforループを使用して、許可された拡張子を1つずつチェックし、一致するものがあればtrueを返します。一方で全てのチェックを終えても一致しなければfalseを返します。

テストしてみます。
```js
const testFiles = [
  'document.pdf',
  'image.png',
  'video.mp4',
  'music.mp3',
  'photo.jpg',
  'script.js',
  'index.html',
];

testFiles.forEach(testFile => {
  const isAllowed = isAllowedExtensions(testFile) ? "アップOK" : "ダメだよ！"
  console.log(`${testFile}は${isAllowed}`);
});
```
![スクリーンショット 2024-12-25 19.00.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889920/3067e011-591b-c4c7-e826-7169becd691f.png)


いい感じです！
ただ、もう少しスッキリと書けないか探してみました。
そこで登場するのがsomeです。

## someを使ってリファクタリングしてみる
someは配列内に指定した条件を満たす要素が1つでもあればtrueを返します。
この特性を活かしてリファクタリングをしました。

```js
const isAllowedExtensions = (file) => {
  return allowedExtensions.some(allowedExtension => file.endsWith(allowedExtension));
};
```
forループを使わずに同じ結果を得ることができます。

### さらにリファクタリングしてみます
アロー関数の省略記法を使ってみます。
引数が1つの場合()を省略でき、さらに１行のみの場合、returnと中括弧を省略できます。

```js
const isAllowedExtensions = file => allowedExtensions.some(allowedExtension => file.endsWith(allowedExtension));
```
なんと1行で書くことができました、すごい！！！
結果も期待通りです。
![スクリーンショット 2024-12-26 10.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889920/1833f7b1-5ca4-d8ea-ed5d-84cd4804c854.png)

## まとめ
便利だなと思いつつも使い所がピンとこなかったsomeですが、実際に使用してみたことで理解が深まりました！
全ての要素をチェックしたい場面に遭遇したら、someやeveryといったメソッドが使用できないか考えていきたいです。

## 参考にさせていただいた記事
以下の記事を参考にしました。ありがとうございました！

https://qiita.com/D_suke/items/53e26beaf5157eb928a3

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
EntraID関連でやりたい事まとめ

# EntraIDの基礎理解
## EntraIDの基本的な仕組みと機能
- 認証と認可の仕組み（OAuth2.0、OpenID Connect）
- ユーザー管理（ユーザー登録、グループ管理）
- 役割と権限（RBAC:Role-Based Access Control）の理解
## ドキュメントの確認
公式ドキュメントを参考

# ハンズオンやトライアルを行う
## EntraIDの無料アカウント作成
Azureポータルでテナントを作成して操作を試す
## よく使う機能を実践
- ユーザーやグループの作成、削除、管理
- アプリケーション登録（アプリをEntraIDに連携）
- マルチファクター認証（MFA）の設定
- シグナルサインオン（SSO）の設定
## 仮想プロジェクトを作成
サンプルアプリ（Node.jsやNEYアプリ）を作成しEntraIDでの認証を組み込む

# セキュリティとベストプラクティスの学習
## セキュリティの基本設定
- セキュリティの基本設定
MFA（多要素認証）の導入
セキュリティグループの利用
ユーザーへの最小権限の付与
- セキュリティレポートやログ監視
EntraIDの監査ログやサインインログを活用して不審な活動を監視する練習をする
- 条件付きアクセスの設定
アクセス制御ポリシーを構成し特定の条件下でアクセスを制限する方法を学ぶ

# 関連技術の習得
## Azure全般
AzureポータルやAzure CLIの基本操作
## Microsoft365の連携
TeamsやSharePoint、OneDriveなどの管理とEntraIDの連携方法
## 認証プロトコル
OAuth2.0、OpenID Connect、SAMLの概要を理解する
## PowerShell
Azure ADモジュールを使ったスクリプトでのユーザー管理

# ドキュメント化と成果物作成
## 学習内容を記録する
実践した内容やエラーの解決方法をノートに記録
必要なら技術ブログや社内共有資料として公開
## テンプレートを作成
よく使う設定（例えば条件付きアクセスのポリシー）をテンプレート化
## チェックリスト作成
業務での設定手順や確認ポイントを一覧化

# 実務に向けた質問・確認事項を整理
実務でどの機能を使う予定かを事前に確認
プロジェクトで利用するツールやシステム（例えばシグナルサインオン対象のアプリ）を把握
常駐先での運用ポリシー（アクセス制限やパスワードポリシーなど）確認


:::note info
EntraIDを使いこなすことでセキュリティ強化や効率的なアクセス管理が可能になる
:::
【2024年冬版】IT未経験が20日間でAWS CLFを取得した方法

## はじめに

先日、20日間の学習を経て、AWS Certified Cloud Practitioner（以下AWS CLF）試験に合格しました。このブログでは、私がどのように学び、合格まで至ったかをご紹介します。AWSに興味をお持ちの方やCLF受験を検討中の方の参考になれば嬉しいです。

## 試験概要

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

## AWS CLFを受験するメリット

### 1. AWSの基礎知識を習得

AWSの主要な概念やサービスを体系的に学ぶことで、今後の学習や業務に役立てられます

### 2. 次回受験が半額に

合格者は次回のAWS認定試験が半額になるクーポンを得られるため、「AWS Certified Solutions Architect - Associate（SAA）」など上位資格への挑戦がしやすくなります

### 3. 業務での理解度向上

AWSに関する会話や資料が理解しやすくなり、業務に役立てることができます

## AWS CLFを受験して得た変化

### 試験前の状況

試験勉強を始める前の私は、ITパスポートやJava Bronzeの資格を持つ程度のIT知識しかありませんでした。AWSについては研修で「S3」「EC2」「RDS」といった名前を聞いたことがある程度で、それぞれのサービス内容は漠然としか理解していませんでした。

業務や会議でAWSの話題が上がるたびに、内容についていけないもどかしさを感じていました

### 試験勉強を通じての変化

CLFの学習を進めるにつれて、AWSの主要サービス名やその特徴を覚えました。その結果、業務でAWSの構成図を見る際も、以前よりも深く理解でき、自分の成長を実感しました

AWS も CLFは、AWS初心者が基礎を学ぶ第一歩として最適な資格と紹介していましたが、本当にそうだなと感じました

## 使用した教材と学習期間

### 学習期間

20日間

### メイン教材

#### 書籍：一夜漬けAWS認定クラウドプラクティショナー

インプット教材として使用しました
- **おすすめポイント**
  1. サービスがカテゴリごとに整理されており、理解しやすい
  2. 必要最低限の情報で、効率的に学べる
  3. コンパクトな内容で、繰り返し学習がしやすい
  4. 書き込みできる余白がある

- **ものたりないと思ったところ**
  1. サービスの違いをさらに明確にしてほしい
  → 調べたり、ChatGPTを使用し明確化

#### Udemy講座：AWS認定クラウドプラクティショナー模擬試験問題集（6回分390問）

アウトプット教材として使用しました

- **おすすめポイント**
  1. 本番試験より難しい設問が多く、本番が簡単に感じられる
  2. 基本レベルと応用レベルに分かれており、段階的に学べる
  3. 豊富な問題数で、理解を深めやすい
  4. 解説が簡潔で分かりやすい

- **ものたりないと思ったところ**
  1. 正答確認が1回（65問）終わらないとできない

## 学習の流れ

1. **書籍を1周流し読みして概要を把握**
2. **基本レベルの模擬試験を2回分解いて出題傾向を確認**
3. サービスの概要や違いを意識しながら書籍を再読
4. **基本レベルの問題2回分＋応用レベルの問題2回分解く**
5. 書籍を再度読み直し、理解を深める
6. **応用レベルの問題をさらに2回分解く**
7. 不明点を調べて補強
8. **最終的に模擬試験を解いて総復習**

## Udemy模擬試験の正答率推移

- **基本問題①**：40% → 56% → 76%
- **基本問題②**：36% → 50% → 75%
- **応用問題①**：36% → 64% → 66%
- **応用問題②**：40% → 53%

正答率の上昇を通じて、着実に理解が深まっていくのを実感しました
Udemyの問題は本番よりも難しい印象がありました
時間の関係で応用問題③④は実施しませんでした

## 学習の工夫とポイント

### 解き直しや見直しで意識したこと

- **問題演習の量を絞る**
  - Udemyの問題をすべて行うのではなく、絞って理解度を深めた
  - 書籍も絶対に覚えるべきところと、何となく理解するところを切り分けた

- **問題の傾向を把握**
  - サービスの概要を理解
  - サービス間の違いを明確にする

- **ChatGPTの活用**
  - サービスの違いが分からない場合に解説を依頼
  - 模擬試験の不明点を質問して解消


## まとめ

AWS CLFは、AWS初心者にとって最初のステップとして最適な資格です。この学習を通じて、業務での理解度向上や次の資格への挑戦の自信が得られました

これからAWSを学びたい方やCLF受験を考えている方に少しでも役立つ情報となれば嬉しいです

最後までお読みいただきありがとうございました！
arm版 Windows 11を最新バージョン（24H2）にアップデート

2024年10月01日にWindows 11（24H2）が一般公開されたものの、待てど暮らせどアップデートされない。。。なんでかなぁ・・・と思い調べたところ、Windows 11インストールアシスタントがarm版では実行できないのが原因のようだ。
arm版 Windows 11を最新バージョンにアップデートするには、グループポリシーで更新を行うバージョンを明示的に設定してからWindows Updateを実行するとarm版でもアップデートできるようだ。

## <font color=green">[利用した環境]</font>
- iMac 2021 24inc（Apple M1）
　→ macOS Sonoma（14.6.1）
　　→ Parallels Desktop for Mac（20.1.1）
　　　→ Windows 11 Pro（23H2）

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896206/539e124d-c40f-3142-cf83-c398e4dc9ae8.png)

## <font color=green">１．ローカルグループポリシーでターゲットバージョンを設定する</font>
⑴. ローカルグループポリシーエディター（gpedit）を起動します
⑵. グループポリシー「ターゲット機能更新プログラムのバージョンを選択する」を選択します
```
ローカル グループ ポリシー
　→ コンピューターの構成
　　→ 管理用テンプレート
　　　→ Windowsコンポーネント
　　　　→ Windows Update
　　　　　→ Windows Updateから提供される更新プログラムの管理
　　　　　　→ ターゲット機能更新プログラムのバージョンを選択する
```
![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896206/2b538bda-4028-d61d-088b-a0c6263c1401.png)

⑶. 「状態」を有効にして、ターゲットバージョンを設定し「OK」ボタンをクリックします
```
【どのWindows製品のバージョンから機能更新を受け取りますか？】
Windows 11
【機能更新プログラムのターゲットバージョン】
24H2
```
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896206/fb600533-5bed-fb75-3556-b341fe34094e.png)


## <font color=green">２．最新バージョン（24H2）にアップデートする</font>
⑴. Windows Updateで「更新プログラムのチェック」をクリックして、24H2にアップデートします
⑵. グループポリシー「ターゲット機能更新プログラムのバージョンを選択する」を選択します
⑶. Windows 11が24H2にアップデートされていることを確認します
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896206/a56ae312-a43c-d3c8-fbf0-dac7adee00b3.png)


## <font color=green">３．ローカルグループポリシーでターゲットバージョンを戻す（念のため）</font>
⑴. ローカルグループポリシーエディター（gpedit）を起動します
⑵. グループポリシー「ターゲット機能更新プログラムのバージョンを選択する」を選択します
⑶. 設定した情報をクリアして「OK」ボタンをクリックします
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896206/0998e3d6-1f25-b2e7-bc59-8b7f7cd18680.png)
ディレクトリ構成 Java

はじめに
--
インフラの分野でも、Iac化が進んで行くと考えています。そこで、ノウハウが体系だっているものが学び易いと考えて、Javaを学びはじめました。

今回は、Javaにおける「ディレクトリ構成」について学んだことをアウトプットします。

「`javac -d ディレクトリ sample.java`」というコマンドを使う際の、test1というディレクトリを指定した例


### コマンドの構造

```bash
javac -d test1 sample.java
```

#### 解説
**`javac`**
Javaソースコードファイル（`.java`）をコンパイルして、バイトコード（`.class`）ファイルを生成するコマンド。
**`-d test1`**
コンパイル結果のクラスファイルを、指定されたディレクトリ（この場合は `test1`）に保存するオプション。
**`sample.java`**
コンパイルしたいJavaのソースコードファイル。

#### 実行後
- `sample.java` がコンパイルされ、生成された `.class` ファイルが `test1` というディレクトリに格納される。もし `test1` というディレクトリが存在しない場合、`javac` は自動的にそのディレクトリを作成。

### 実行例

まず、`sample.java` というファイルがあるとします。例えば、次のような内容のJavaソースコードだとします。

```java
// sample.java
public class Sample {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
```

次に、以下のコマンドを実行します。

```bash
javac -d test1 sample.java
```

#### 実行後のディレクトリ構造

**`test1`** ディレクトリが作成され、その中に `Sample.class` というコンパイルされたクラスファイルが格納されます。

```
現在のディレクトリ/
│
├── sample.java      (Javaのソースファイル)
└── test1/           (出力先ディレクトリ)
    └── Sample.class (コンパイル後のクラスファイル)
```

`javac -d test1 sample.java` を実行すると、`sample.java` がコンパイルされ、その結果の `Sample.class` ファイルが `test1` フォルダ内に保存されます。


`javac` コマンドは、Javaソースファイルをコンパイルしてバイトコード（.classファイル）を生成するために使用されます。`-d` オプションは、生成されたクラスファイルを指定されたディレクトリに出力するために使用されます。


### 補足
- `-d` オプションで指定するディレクトリ名（ここでは `test1`）は任意の名前を付けられます。例えば、`javac -d bin sample.java` とすると、出力先ディレクトリが `bin` になります。
c1kのpcieサポート

c1kのモジュールにはmini PICeコネクタでWIFIカードが接続されているので、PCIeのサポートを考えて見ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/24a32130-702a-f962-1266-947ef87e48af.png)

まずメモリからですが、

```c
#define AHB_PCIe0CMD_BASE               0x11400000
#define AHB_PCIe1CMD_BASE               0x11410000
#define AHB_PCIe0_BASE                  0x40000000
#define AHB_PCIe1_BASE                  0x50000000
#define APB_PCIe0_BASE                  0x10010000
#define APB_PCIe1_BASE                  0x10030000
#define APB_PCIePHY_BASE                0x10060000
```

の定義があります。

AHB_PCIe0CMD_BASEはコンフィグレジスタアクセス用のアドレスで、AHB_PCIe0_BASEはPCIeのデバイスのマップ用のアドレス空間です。

HOST-PCIブリッジの提供するコンフィグレジスタのアクセスはチップ毎に仕様が違います。

このSOCではAHB_PCIe0CMD_BASEに直接コンフィグレジスタがマップされるわけではなくて、ここのレジスタを操作する事でコンフィグレジスタが読み書きできます。

APB_PCIe0_BASEはHOST-PICブリッジの本体のアドレスで、APB_PCIePHY_BASEはPHYの設定用のアドレスです。

PHY以外はポート毎になっています。

割り込みは、

```c
#define IRQ_PCIe0_EXT                   14
#define IRQ_PCIe0_INT                   15
#define IRQ_PCIe1_EXT                   16
#define IRQ_PCIe1_INT                   17
```
IRQ_PCIe0_INTはHOST-PCIブリッジの本体の割り込みで、IRQ_PCIe0_EXTがデバイスの割り込みです。

コードを見ていてきがついたのですが、SynopsysのIPのようです。

このコントローラーはHOSTにもDEVICEにもなれるようです。

# PCIのBARの設定

PCIやPCIeではOSがコンフィグレジスタのBAR(Base Address Register)を設定する事で、そのアドレスをドライバーがマップしてデバイスにアクセスできます。

デバイスが32ビットの時はBAR0で、64ビットの時はBAR0,BAR1でアドレスを指定します。

BARはメモリアドレス以外にx86由来のIOアドレスも指定できますが、ホストが対応していないとそのデバイスは利用できません。IOだけという事はあまりなくてメモリとIOの二つのアクセスを用意しているケースが多いです。BARは計6本あり、複数のアドレスブロックを指定する事もできます。

デバイスのメモリサイズはさまざまでたとえば4Kバイトと8Kバイトのデバイスが2枚あったとします。

OSはデバイスごとのメモリサイズは以下のような方法で知ることが出来ます。

BAR0に0xffffffffを書き込み、読み出しをすると、4Kバイトのデバイスは0xfffff004が読み出され、8Kのデバイスは0xffffe004が読み出されます。

これはメモリサイズを越えた部分のビットはリード/ライト可能で、メモリサイズのビット部分はリードオンリーとなるためです。下位4ビットは属性ビットです。

OSはこのサイズを元にPICのデバイスマップ用のアドレスに適宜配置してBARを設定します。

デバイスドライバはデバイスのメモリサイズは知っているので、BARからそのサイズをマップします。

BARには物理アドレスが設定されているので、マップする時にはその物理アドレスを仮想アドレスでアクセスできるようにします。
ＴＦＩＤＦ

import collections
import math
import re

def tokenize(text):
    return re.findall(r'\w+', text)

def compute_tf(tokens):
    tf = collections.Counter(tokens)
    return tf

def compute_idf(documents):
    N = len(documents)
    idf = collections.defaultdict(int)
    for doc in documents:
        for term in set(doc):
            idf[term] += 1
    for term, count in idf.items():
        idf[term] = math.log(N / count)
    return idf

def compute_tfidf(tf, idf):
    tfidf = {}
    for term, freq in tf.items():
        tfidf[term] = freq * idf.get(term, 0)
    return tfidf

def cosine_similarity(vec1, vec2):
    dot_product = sum(vec1.get(term, 0) * vec2.get(term, 0) for term in set(vec1) | set(vec2))
    magnitude1 = math.sqrt(sum(val**2 for val in vec1.values()))
    magnitude2 = math.sqrt(sum(val**2 for val in vec2.values()))
    if magnitude1 == 0 or magnitude2 == 0:
        return 0
    return dot_product / (magnitude1 * magnitude2)

def similarity_search(query, documents):
    tokenized_query = tokenize(query)
    tokenized_docs = [tokenize(doc) for doc in documents]
    
    idf = compute_idf(tokenized_docs)
    
    query_tf = compute_tf(tokenized_query)
    query_tfidf = compute_tfidf(query_tf, idf)
    
    results = []
    for i, doc in enumerate(tokenized_docs):
        doc_tf = compute_tf(doc)
        doc_tfidf = compute_tfidf(doc_tf, idf)
        similarity = cosine_similarity(query_tfidf, doc_tfidf)
        results.append((i, similarity))
    
    results.sort(key=lambda x: x[1], reverse=True)
    return results

if __name__ == '__main__':
    documents = [
        "This is the first document.",
        "This document is the second document.",
        "And this is the third one.",
        "これは最初のドキュメントです。",
        "このドキュメントは2番目のドキュメントです。",
        "そして、これは3番目のものです。"
    ]
    query = "ドキュメント"
    results = similarity_search(query, documents)
    print(f"Query: {query}")
    for index, score in results:
        print(f"Document {index}: {score}")
    
    query = "first document"
    results = similarity_search(query, documents)
    print(f"Query: {query}")
    for index, score in results:
        print(f"Document {index}: {score}")