OmniAICreator/Qiita-1.07M huggingface dataset:
カルマンフィルタの簡単な紹介

#  目的
カルマンフィルタの備忘録を残す。 

カルマンゲインが、分散が小さいほうの状態に重みをつけることで、カルマンフィルタは真の状態に近い状態を推定している。

# カルマンフィルタの概要
状態空間モデルが与えられたとする。

```math
\begin{eqnarray}
x(i)&=&ax(i-1)\\
y(i)&=&x(i)+\varepsilon(i), \ \ \varepsilon(i)\sim N(0,\sigma(i))
\end{eqnarray}
```

カルマンフィルタは、真の状態$x(i)$と推定値$\hat{x}(i)$の分散$V\[\hat{x}(i)-x(i)\]$が最小となるようにすることで、カルマンフィルタは$\hat{x}(i)$を推定する。

カルマンフィルタによる推定値$\hat{x}(i)$は、状態空間モデルと推定値$\hat{x}(i-1)$から算出される$\hat{x}_M(i)$と、観測値$\hat{x}_O(i)$および、カルマンゲイン$K_i$から構成される。

```math
\hat{x}(i) = (1-K_i)\hat{x}_{M}(i) + K_i \hat{x}_{O}(i)
```

このとき、分散$V\[\hat{x}(i)-x(i)\]$は、

```math
V[\hat{x}(i)-x(i)]=(1-K_i)^2 V[\hat{x}_M(i)]+K_i^2 V[\hat{x}_O(i)]+V[x(i)]
```

分散$V\[\hat{x}(i)-x(i)\]$が最小となるカルマンゲイン$K_i$は、分散$V\[\hat{x}(i)-x(i)\]$をカルマンゲイン$K_i$で微分すれば求まる。

```math
K_i=\dfrac{V[\hat{x}_M(i)]}{V[\hat{x}_M(i)]+V[\hat{x}_O(i)]}
```

**カルマンゲインが、分散が小さいほうの状態に重みをつけることで、カルマンフィルタは真の状態に近い状態を推定している。**


# 参照

https://qiita.com/IshitaTakeshi/items/740ac7e9b549eee4cc04

https://www.youtube.com/watch?v=zVAq_3HClGs
P5.js 日本語リファレンス(beginGeometry / endGeometry)

このページでは[「P5.js 日本語リファレンス」](https://qiita.com/bit0101/items/91818244dc26c767a0fe) の beginGeometry() / endGeometry()関数を説明します。

## beginGeometry / endGeometry

### 説明文

beginGeometry() は図形形状情報を保持する p5.Geometry オブジェクトへ図形の追加を開始します。
endGeometry() は図形形状情報を保持する p5.Geometry オブジェクトへ図形の追加を終了します。
beginGeometry()とendGeometry()の間で複数のシェイプ（図形）を追加することで複雑な図形形状を作成することができます。

beginGeometry() と endGeometry() は、描画のパフォーマンスを向上させるのに役立ちます。たとえば、以下の(a)の方が(b)よりも高速に描画することができます。
(a)beginGeometry() と endGeometry()の間で個々のシェイプ(図形)を  p5.Geometry に追加しておき、一括して繰り返し描画する
(b)個々のシェイプ（図形)を繰り返し描画する

注: beginGeometry()WebGL モードでのみ使用できます。


### 構文

beginGeometry() 
endGeometry()

### パラメタ

### 例
https://editor.p5js.org/bit0101/sketches/6u_oB0xWD

### 著作権
p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス
Creative Commons(CC BY-NC-SA 4.0) に従います。
検索した文字列の隣をクリックする方法


```js
// 仮の変数にPower Automate Desktopから取得した文字列を設定
var searchText = "ここに検索文字列を入力"; 

// 検索文字列を含む<td>要素の左隣の<td>内の<a>タグをクリックする関数
function clickLinkInAdjacentLeftTd(searchText) {
    const tds = document.querySelectorAll('td');

    // 全ての<td>要素をループ
    for (let i = 0; i < tds.length; i++) {
        if (tds[i].textContent.includes(searchText) && i > 0) {
            const previousTd = tds[i - 1]; // 左隣の<td>要素を取得
            const link = previousTd.querySelector('a'); // 左隣の<td>内の最初の<a>要素を取得
            if (link) {
                link.click(); // <a>タグが存在すればクリック
                break; // 最初に見つかった要素のみ操作
            }
        }
    }
}

// 関数を呼び出す
clickLinkInAdjacentLeftTd(searchText);


```
【ChatGPT＋DALL-E3】生成画像の詳細を書き出す。


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

　今回は、生成画像の詳細を書き出します。KEITOさんのショート動画より。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　ニュースなし。

　今回は、
　　YouTuberのKEITOさんの
　　　ショート動画第二弾です。
　　　　下記はX-Twitterのポストです。
[画像生成のやり取りで返信に困ったらこれ](https://x.com/keitowebai/status/1787826063076467136?t=qmccj7zrh2z_JOXS-fPQQw&s=03)

　中身的には、
　　画像生成で
　　　思ったように
　　　　いかないときの方法の
　　　　　ひとつを紹介しています。

　さっそく
　　やってみました。

　KEITOさんの方法では
　　プロンプトからに
　　　なっていますが、
　　　　ここでは画像自体から
　　　　　書き出させています。
***
***user***
猫。描画

***ChatGPT***
（画像）

***user***
この画像のスタイル、オブジェクト、構図、細部の描写を項目ごとに振り分けて、詳細に書き出してください。

***ChatGPT***
画像の分析を以下のように項目別にまとめました。

### スタイル
- リアルで細部まで緻密に描かれています。
- 色彩は鮮やかで、自然光を感じさせる色使いがされています。

### オブジェクト
- 主要なオブジェクトは灰色と白色の模様のフサフサした毛を持つ猫です。
- 猫は窓辺に座っており、窓の外を見ています。

### 構図
- 猫が中央に位置し、窓枠によって自然にフレームが形成されています。
- 背景には開かれた窓から見える豊かな庭が描かれています。

### 細部の描写
- 猫の毛並みは非常にリアリスティックに描かれ、毛の一本一本が感じられるほどです。
- 猫の目は大きく、表情豊かで深い緑色が特徴的です。
- 背景の庭は、花や蝶がいる様子が細かく描かれており、生き生きとした自然が感じられます。

これらの要素が組み合わさり、視覚的に魅力的な作品になっています。
***

　ここまでが
　　KEITOさんの
　　　ショート動画の
　　　　内容です。

　この書き出された内容を
　　修正して、DALL-E3に渡せば
　　　イメージに近い画像が
　　　　生成される、としています。

　確かにこれでも
　　生成してくれますが
　　　プロンプトらしくしたい
　　　　場合は、下記を参考にして。
***
***user***
上記から、DALL-E3に渡す指示プロンプトを作成してください

***ChatGPT***
以下のような指示プロンプトをDALL-E3に渡すことで、求められる画像を生成することができます。

「リアルで詳細に描かれた絵画で、フサフサした灰色と白色の毛を持つ猫が窓辺に座っており、その大きく表情豊かな緑色の目で日当たりの良い庭を見つめています。庭には色とりどりの花と蝶があり、自然光が差し込む様子を鮮やかな色で表現してください。スタイルはリアリズムで、猫の毛並みや庭の植物の質感にこだわった細かい描写を施してください。」
***
　これを
　　新しく開いたセッションで
　　　やったところ、
　　　　似たものになりました。

　ここでは
　　修正は掛けていませんが、
　　　必要ならば、このプロンプトを
　　　　修正・描画してください。

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

　今回は、ここまで。
どのエラーを Sentry.captureException するかという話

`Sentry.captureException` で飛ばすほどではないが、別のエラーが起きた時に有用な情報かもしれないものはconsole.logだけしておけばSentryのtimeline上で後で確認できる

```typescript
export const errorLogger = (exception: any, enableSentry = true) => {
  console.error(exception);
  if (enableSentry) {
    captureException(exception, { level: 'error' });
  }
};
```
Listの参照項目でタイトル以外に複数のカラムを表示させる


タイトルが自分でもちょっと分かりにくいかも...

ETCカードは参照項目で、別のETCカードというリストを参照しています。
このETCカードと言うリストには営業所を持っているので、ここに表示させたい。何故か表題が消えている01のところです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6ca9ce90-eaa7-68a7-2e5c-05e9739bcadf.png)

あああ、幅が狭かっただけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f759a935-da77-8143-5433-6e19275fd9d9.png)

# 追加の方法

参照しているカラムでVをクリック、 列の設定--> 編集

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f48fc354-07ea-8196-1dfa-0d173335f593.png)

その他のオプションを展開

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/51bdfc1d-38ee-7db3-e82b-b212fec720c5.png)


追加したいカラムを選択して保存

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c32f4876-137c-ed54-1f91-7e8f00fbee57.png)

# いつも忘れるビューの並び順の変更

すべてのアイテムをクリック、現在のビューの編集

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/937bca9a-49f9-00f1-d5e4-5ab64932c8f5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b11295c2-17c9-3f41-3698-331bdd38c6c2.png)
[初心者向け] MySQL8.0の権限の確認および付与・削除する方法について解説

## 概要
DBを特定のユーザで直接操作したり、フレームワークのマイグレーション機能経由で操作する際にはDBの権限設定について理解する必要があるので

- 権限の種類
- 権限の確認方法
- 権限の付与方法
- 権限の削除方法

について解説していきたいと思います

## 前提
- 今回はMySQL8.0系を例に説明します

## 権限の種類
MySQLに限らず、DBにはさまざまな権限が存在します
よく見かける権限だけ列挙していきます
他の権限を見たい場合は以下の記事を参照してください

https://dev.mysql.com/doc/refman/8.0/ja/privileges-provided.html

### SELECT
- DBのテーブルから行を選択できる権限

### INSERT
- DBのテーブルに行を挿入できる権限

### UPDATE
- データベース内のテーブルで行を更新できる権限

### DELETE
- データベース内のテーブルから行を削除できる権限

### CREATE
- 新しいデータベースおよびテーブルを作成できる権限

### REFERENCES
- 外部キー制約を作成できる権限

### DROP
- 既存のDB、テーブル、ビューを削除できる権限

### ALL, ALL PRIVILEGES
- 全ての権限が付与される

## 権限の確認
権限を確認する際は以下のようにユーザ名を指定して確認します

```
show grants for 'dev_user'@'%';
+------------------------------------------------------------------------------------------------------------------+
| Grants for dev_user@%                                                                                            |
+------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `dev_user`@`%`                                                                             |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, REFERENCES, ALTER, INDEX ON `dev_database`.* TO `dev_user`@`%` |
+------------------------------------------------------------------------------------------------------------------+
```
## 権限の付与
GRANTを使って権限を付与できます
付与する権限はGRANTの後ろに記載します
今回はdev_databaseの全てのテーブルにREFERENCEの権限を付与しています

```
GRANT REFERENCE ON dev_database.* TO 'dev_user'@'%';
```

## 権限の削除
REVOKEを使って権限を付与できます
削除する権限はREVOKEの後ろに記載します
今回はdev_databaseの全てのテーブルからREFERENCEの権限を削除しています

```
REVOKE REFERENCE ON dev_database.* FROM 'dev_user'@'%';
```

## 参考
https://dev.mysql.com/doc/refman/8.0/ja/grant.html

https://dev.mysql.com/doc/refman/8.0/ja/revoke.html

https://dev.mysql.com/doc/refman/8.0/ja/privileges-provided.html

https://qiita.com/shuntaro_tamura/items/2fb114b8c5d1384648aa
【Rails】RailsでBootstrap5系を取り入れる際はCDNが楽だった

# はじめに
Rails6.1の環境に、yarnでBootstrap5を導入してみようと思いましたが、なぜか反映されませんでした。
Bootstrap4.6を導入した際は上手くいったのでおかしいな…と思いつつ、調べるとどうやら5系はjQueryではなくJavaScriptを利用するそう。

仕組みが違うからなのか…？と困ってしまった際の私が行った解決方法をご紹介します。

# 結論
Bootstrap5はyarnを使って導入しようとすると、rails-ujsとの兼ね合いが悪くなってCompileでエラーが発生します。
それと同時にrails-ujsも機能しなくなってしまいます。

わたし自身がCompileについての理解が浅いので詳しく説明はできませんが、そもそもの仕組みが違うようです。
さらに、Bootstrap5系をyarnを使って「app/javascript/packs/application.js」などに設定する方法だと、Compileに関わる他の部分の設定も修正が必要になり、ちょっと作業が大変になってしまうとか…。

具体的な解決方法としては、単純にCDNを使えば良いとのことです。

また、私の場合はBootstrap5をyarnで導入したことによるrails-ujsの不具合が発生していたため、こちらを削除する必要がありました。

# 実際に修正した手順

```
$ yarn add jquery bootstrap@5.3.0 popper.js
```
既に上記のようにyarnでBootstrap5.3をインストールしてしまっていたので、まずはこちらを削除していきます。

## 1. application.jsに書いた記述を削除する

```diff_javascript:app/javascript/packs/application.js
import "jquery";
- import "popper.js";
- import "bootstrap";
import "../stylesheets/application.scss";
```
不要なimportを消していきますが、私の場合はjQueryを使いたいので、「import "jquery";」は残しています。
また、popper.jsはbootstrap用に入れていたものなのでこちらも削除します。

## 2. application.scssに書いた記述を削除する

```diff_css:app/javascript/stylesheets/application.scss
- @use '~bootstrap/scss/bootstrap';
```
application.scssで呼び出すために記述していたこちらも削除。

この段階でいったん起動し直して確認すると、既にrails-ujsが反映されるようになりました。

rails-ujsは、link_toに使用するオプションの「"data-confirm" => "本当に削除しますか？"」の表示にも関わってくるので、リンクにdata-confirmを付けて動作を確認するのが手軽でおすすめです。

## 3. yarn removeで不要なデータを削除する
ここまでの作業でアプリ自体の動作としては問題ないのですが、yarnでインストールしたデータは不要になるので、削除しておきます。

```
$ yarn remove bootstrap
$ yarn remove popper.js
```
bootstrapはバージョンを指定しなくてもyarn自身が探して削除してくれました。
popper.jsも使用しないので削除しておきます。

念のため、yarn.lockやpackage.jsonのファイルを確認してみましょう。
削除が完了していればこちらからもbootstrapやpopper.jsはなくなっているはずです。

## 4. CDNでbootstrap5.3を使う
これでエラーも解消されたので、CDNを使ってbootstrap5.3を取り入れていきます。
こちらの記事でシンプルに分かりやすく説明されているので、参考にしてみてください。

https://qiita.com/gintaro0111/items/98d47368711aecdca6a6

# ちなみにrails-ujsが怪しいと思った理由
Bootstrap5系を取り入れる際の不具合に関しては、どうしても分からずにメンターの方に相談して解決できました。
相談する前に、rails-ujs関連が怪しいと感じていて、そう思った理由についても簡単にご説明します。

## 1. CSSが反映されない
まず最初の疑問はCSSが反映されないことからでした。
CSSを読み込むための記述は合っていたので不思議に思っていました。

この時点で既に「app/javascript/stylesheets/application.scss」が読み込まれていないように感じていたので、yarnはそのまま置いておいて、CDNでbootstrapを導入してレイアウトを進めています。
いったんレイアウト問題は解消されたので、後でまとめて確認しようと思い作業を進めることにしました。

## 2. deviseのログアウト時にルーティングがgetになってしまう
こちらも何度か遭遇したエラーで、だいたいjQueryを導入する際の記述ミスから発生した記憶があったので、CSSが反映されない問題と同じだろうと考えました。

ですが、今回の場合は記述ミスも発見できず、解決に詰まってしまったので、ひとまずdeviseの環境設定を書き換えてルーティングを変更することで対応しました。

CSS問題が解消されたら一緒に解決できるだろうと考え、こちらもいったん置いておいて作業を進めます。

https://qiita.com/ken_sasaki2/items/ef0802ed0d8257753a6d

## 3. data-confirmも機能しないことに気づく
```ruby:text
<%= link_to "削除", chat_path(chat), method: :delete, "data-confirm" => "本当に削除しますか？" %>
 ```
 この「"data-confirm" => "本当に削除しますか？"」を設置したにもかかわらず確認画面が表示されないことが判明。
薄々怪しいとは思っていましたが、ここまで来るとさすがにrails-ujsが機能していないことが原因ではないかという疑いが確信へと変わってきました。

そろそろ動いてくれないと困る場面が出てきたので、rails-ujs問題と向き合うことに。
状況を整理しつつ調べてみたのですが、どうにも原因がつかめなかったのでメンターの方へ相談することにした…という流れになります。


# おわりに
メンターの方に作業の経緯の説明と共にに相談をしたら一瞬で解決しました。
ついでにCDNとyarnやGemの違いなどのお話も聞けて、さらに理解が深まりました。

CSSの手詰まりの段階で相談していたら、理解度も今より低くなってしまっていたと思うので、良い意味での後回しも大事だなと感じています。
【TryHackMe】Intro to Offensive Security : WalkThrough

# 概要

TryHackMe「Intro to Offensive Security」ルームのWalkthroughです。
このルームではEthical Hackingの基礎を体験できます。

https://tryhackme.com/r/room/introtooffensivesecurity

# Task1

## **Q1**.*Which of the following options better represents the process where you simulate a hacker's actions to find vulnerabilities in a system? Offensive Security, Defensive Security*

**A**.**Offensive Security**

# Task2

初期状態では自身のアカウント`8881`に`-$1,232.32`が付与されています。
赤字です😥
このサイトをハッキングしてお金を得ましょう!!

![default.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/64642410-2068-5a02-00f2-c786a7a78f26.png)

## ステップ2

まず、ターミナルを開き`gobuster`を実行します。

```
gobuster -u http://fakebank.com -w wordlist.txt dir
```

`/images`と`/bank-transfer`のパスが見つかりました。

```
=====================================================
Gobuster v2.0.1              OJ Reeves (@TheColonial)
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://fakebank.com/
[+] Threads      : 10
[+] Wordlist     : wordlist.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout      : 10s
=====================================================
2024/04/26 11:07:40 Starting gobuster
=====================================================
/images (Status: 301)
/bank-transfer (Status: 200)
=====================================================
2024/04/26 11:07:49 Finished
=====================================================
```

`/bank-transfer`へアクセスすると送金管理画面が表示されます。

![bank transfer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/f0bd938d-9511-5c87-c23d-28275e1274b4.png)

## ステップ3

アカウント`2276`から自身のアカウント`8881`へ2000USDを送金してもらいます。

![send money.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/ad03b96f-cdc4-1260-1fe9-1ae9590ab6e5.png)

アカウント画面に戻ると2000USDが適用され黒字になりました!!

![get hack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3005822/9b9075f8-88c0-4dcc-8d38-e75a9848f70a.png)

## **Q1**.*Above your account balance, you should now see a message indicating the answer to this question. Can you find the answer you need?*

**Hint**.*Make sure your new balance is a positive number. If your balance still shows a negative value (even after refreshing the page), you may need to transfer more money.*

**A**.**BANK-HACKED**
GaussianBlur のカーネルを調べる

OpenCVの `GaussianBlur()` で実際に適用されるカーネルの中身は、要素がすべて0で中心だけが1の画像に `cv.GaussianBlur()` を適用することで調べられます。

5×5のカーネルのときは次のようになります（Python版）。

```Python
>>> import cv2
>>> import numpy as np

>>> img = np.zeros((5, 5))
>>> img[2, 2] = 1
>>> img
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])

>>> filter = cv2.GaussianBlur(img, (5, 5), 0)
>>> filter
array([[0.015625, 0.03125 , 0.046875, 0.03125 , 0.015625],
       [0.03125 , 0.0625  , 0.09375 , 0.0625  , 0.03125 ],
       [0.046875, 0.09375 , 0.140625, 0.09375 , 0.046875],
       [0.03125 , 0.0625  , 0.09375 , 0.0625  , 0.03125 ],
       [0.015625, 0.03125 , 0.046875, 0.03125 , 0.015625]])
```

もとネタはstack overflow の「[How do I get to show Gaussian Kernel for 2d? (opencv)](https://stackoverflow.com/questions/61394826/)」という記事です（Chris Luengoという方の2020年4月のポスト）。方法を探していたら行き当たったのですが、説明があまりにかっこよくて感激しました。曰く「これ（中心だけ1のカーネル）はディラックのデルタ関数と等価である」。気づかんかったぁ！

単にコピーするだけでは付加価値がないので、JavaScript/Node.js版も示します。

```javascript
Module = {
  onRuntimeInitialized() {
    let img = new cv.Mat(5, 5, cv.CV_8UC1, new cv.Scalar(0));
    img.data[5*2 + 2] = 1;
    img.convertTo(img, cv.CV_32FC1);
    console.log('img: ', img.data32F);

    let kernel = new cv.Mat()
    cv.GaussianBlur(img, kernel, new cv.Size(5, 5), 0);
    console.log('kernel: ', kernel.data32F);
 }
}

const cv = require('./opencv.js');
```

結果はもちろん上記と同じ。

### 参考文献

Webブラウザから利用できるJavaScript版OpenCVについては、公式チュートリアルの[OpenCV.js Tutorials](https://docs.opencv.org/4.10.0/d5/d10/tutorial_js_root.html)が最も参考になります。APIドキュメントはC++とPythonのシグニチャしか示してくれませんが、C++のものに近いと思えば、当たらずとも遠からずです。

検索すると、自力でソースからコンパイルする必要があるとする記事が散見されますが、その必要はありません（2024年現在）。[https://docs.opencv.org/master/opencv.js](https://docs.opencv.org/master/opencv.js)から直接js（WebAssembly）ファイルをダウンロードするだけです。HTMLページ内でなら次の要領です。

```
<script async src="https://docs.opencv.org/master/opencv.js"></script>
```

書籍なら『[OpenCV.jsで作る画像・ビデオ処理Webアプリケーション](https://www.shuwasystem.co.jp/book/9784798072166.html)』（2024年6月）があります。`cv.GaussianBlur()`など4つの平滑化フィルタの用法と説明は6.2節で取り上げています。ご購入はこちらから【 [honto（電子のみ）](https://honto.jp/ebook/pd_33525394.html) | [amazon.co.jp](https://www.amazon.co.jp/dp/4798072168) | [ヨドバシカメラ](https://www.yodobashi.com/product/100000009003845169/) | [Rakuten](https://books.rakuten.co.jp/rb/17865150/) 】。

<img src="https://www.shuwasystem.co.jp//images/book/649302.jpg" width="200" alt="表紙"></img>
TFC Dynamic Credentialsの検証

:::note info
この記事はAWS前提のものです
:::
# TFC Dynamic Credentialsとは
* Terraform Cloud(以下TFC)に実装されたCredentialを動的に発行する仕組み
* Terraformで何かしらデプロイする際はデプロイ先にアクセスできるCredentialが必要となる
* AWSなどであれば、専用のIAMでAPIキー周りを発行して利用するような形がシンプル
* セキュリティ的にはできれば上記のAPIキーはローテーションするのが望ましいが運用コストがかかる(めっちゃ面倒)
* Dynamic Credentialsを設定すると動的にCredentialを発行することができ、セキュリティリスクと運用コストを減らせてハッピー

# 参考ドキュメント
[Hashicorp - Authenticate providers with dynamic credentials](URL "https://developer.hashicorp.com/terraform/tutorials/cloud/dynamic-credentials")
[Hashicorp - Dynamic Credentials with the AWS Provider](URL "https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/aws-configuration")

# 実装時の流れ
* デプロイ先のAWS上でOIDC IDプロバイダとそれに付与するIAMロールを作成する
* TFCのワークスペースに変数を追加する

# 事前準備
* あらかじめ必要な設定値

|名前  |説明 |
|---|---|
|SITE_ADDRESS|Terraform Cloud のアドレス(app.terraform.io を設定)|
|AUDIENCE_VALUE|aws.workload.identity を設定|
|ORG_NAME|TFC上のORG NAME|
|PROJECT_NAME|ポリシーを適用するTFC上のプロジェクト名| 
|WORKSPACE_NAME|ポリシーを適用するTFC上のワークスペース名|

# 手順
## AWS上でOIDC IDプロバイダを作成する
### デプロイ先のAWSアカウントでOIDC IDプロバイダを作成
* IAM > ID プロバイダ > プロバイダを追加を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146026/70933073-5495-2fd0-6b82-cfa0c583f566.png)

### 下記の設定値を入力する
* OpenID Connectを選択
* プロバイダのURL：https://app.terraform.io
  * サムプリントを取得を押下する
* 対象者：aws.workload.identity を入力

### IDプロバイダが作成されたことを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146026/f0496904-337b-35b3-bc25-2abc12fdad79.png)

## AWS上でOIDC IDプロバイダに付与するIAMロールを作成する
:::note info
下記ではterraform planとterraform applyで同一のロールを付与する前提の記載にしています。
planとapplyで別々の権限が必要である場合はロールを分ける形になるので、参考ドキュメントを参照して記述を適切に修正して下さい
:::

* IAMロール作成画面まで遷移
* カスタム信頼ポリシーを選択し、下記の設定を任意の値を差し替えて入力する
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "先ほど作成したOIDC IDプロバイダのARNを入力"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "app.terraform.io:aud": "{AUDIENCE_VALUE}"
                },
                "StringLike": {
                    "app.terraform.io:sub": "organization:{ORG_NAME}:project:{PROJECT_NAME}:workspace:{WORKSPACE_NAME}:run_phase:*"
                }
            }
        }
    ]
}
```
* 許可ポリシーはデプロイ内容に合わせて適切なものを設定
* 作成したIAMロールのARNを控えておく

## TFC上のワークスペースに変数を追加する

* TFCの目的のワークスペースに移動し、Variables画面に遷移する
* Workspace Variables に下記の設定値を入力する( <span style="color: red; ">必須</span> )
  * TFC_AWS_PROVIDER_AUTH(Environment variable)：true
  * TFC_AWS_RUN_ROLE_ARN(Environment variable)：OIDC IDプロバイダに付与したIAMロールのARN
* 必要に応じてオプションの変数の追加も検討する
  * (terraform コード内でregionを指定していない場合に設定)AWS_REGION：ap-northeast-1 など
  * (IDトークンをデフォルト(aws.workload.identity)から変更する場合の指定)TFC_AWS_WORKLOAD_IDENTITY_AUDIENCE：任意の値
  * (planとapplyでroleを分離する場合)TFC_AWS_PLAN_ROLE_ARN：planで利用するIAMロールのARN
  * (planとapplyでroleを分離する場合)TFC_AWS_APPLY_ROLE_ARN：applyで利用するIAMロールのARN

これでplan , apply 時に動的なCredentialが発行、利用されるようになるのでterraform plan などを実行して正常に動作するか確認して下さい。
PHP

# 大学で役立つアプリを作ろう（お茶会第1弾）
今回はとてもシンプルにwebアプリを作成しました。
xamppで気象庁のAPIから東京の天気を出力し、データベースを使用し掲示板的な用途を追加しました。

# 設定情報
データベース名はbbs-yt,テーブル名はgdsc-table,要素はcomment(Text型)とpostData(Data型)の２変数。
ユーザ名はrootでパスワードは無しで設定。

# デモ動画
Node.jsの対話環境


# Node.jsで対話環境を利用する

Node.jsにはJavaScriptのコードを対話的に実行ができる環境があります。

REPLは手軽にコードを実行できますので、簡単なテストやデバッグなどで使用可能です。

```nodejs
node
```

nodeコマンドを実行すると、「>」という表示がされます。
この状態でJavaScriptのコードを入力してエンターキーを押すとコードが実行されて戻り値が表示されます。
Report subscribe レポートの購読

[レポートのまとめに戻る](https://qiita.com/Keiji_otsubo/items/9c883d1e4bf0df549a2a)


# できないこと

+ [Subscribe to Joined Reports?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000EAZFDSA5)
+ [Subscribe to joint report](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ajaOiSAI)


# レポートを購読しますが、「ファイルを添付」オプションを非表示にします

+ [Subscribe to report but hide 'Attach file' option](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Pei9i)

:::note
Disabling the 'Let users attach reports...' checkbox does not impact the positive behavior on the UI. 

I could manage to turn off ' Export reports' user permission on profile page to get rid off 'Attach file' button. However, the same user permission controls the ability to export report as well ('Export' button on UI). Interesting how these 2 functionalities - export and subscribe - are interlinked.
[ユーザーにレポートの添付を許可する...] チェックボックスを無効にしても、UI の適切な動作には影響しません。 

プロファイルページで「レポートのエクスポート」ユーザー権限をオフにして、「ファイルを添付」ボタンを削除することができました。ただし、同じユーザー権限によって、レポートをエクスポートする機能も制御されます (UI の [エクスポート] ボタン)。これら 2 つの機能 (エクスポートとサブスクライブ) がどのように相互リンクされているかは興味深いです。
:::

# 制限の緩和

+ [We're becoming increasingly frustrated with the limit of 5 reports a user can be subscribed to. ](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000PXAjq)

:::note
The restrictions seem to have been relaxed slightly if the following applies: 

Currently, each user in an Unlimited Edition org can subscribe to up to 15 reports and 15 dashboards. Users in other orgs can subscribe to up to 7 reports and 7 dashboards. 

The maximum limit of 15 is hardcoded and cannot be increased further. For additional information, refer to Reports and Dashboards Limits, Limitations, and Allocations.

Notes:

+ For Salesforce Classic: The limit of subscribed reports is 5.
+ For Lightning Experience: The limit of subscribed reports for Unlimited Edition is 15. The limit of subscribed reports for other Editions is 7.
+ Portal Users cannot subscribe to a report.

https://help.salesforce.com/s/articleView?id=000383344&type=1
:::
(java silver)Stringクラス

## JavaSilverでメモしたところ備忘録として残しておこうと思います。

# Stringクラスについて

* stringクラスはimmutable(不変)なオブジェクトである
* 文字列の追加や変更のたびに新しいインスタンスを生成

```java
//Java
String str = "abc";
String str2 = str.toUpperCase();
System.out.println("str：" + str);
System.out.println("str2：" + str2);
```
```Java
//実行結果
str: abc
str2: ABC
```

## Stringクラスのメソッド
|メソッド名|説明|
|:----|:--|
|charAt(int i)|(i)で指定したインデックスの文字を返す|
|concat(String str)|(Str)の後ろに連結する|
|endsWith(String s)|文字列が指定した(s)で終わっていればtrueを返し、異なればfalseを返す|
|indexOf(int ch)|(ch) で指定した文字が最初に出てきたインデックスを返す<br>`なければ-1`|
|lastIndexOf(int ch)|(ch)で指定した文字を最後から探し見つけたインデックスを返す<br>`なければ-1`|
|length()|文字列の文字数・空白もカウントし数値を返す|
|replace(char o, char n)|文字列中にある文字oを文字nに置換した結果の文字列を返す|
|startsWith(String prefix)|文字列が実引数に入れた値から始まっていればtrueを返す|
|substring(int i)|0 ~ 実引数に入れた値までの部分文字列を返す<br>`始点を指定できる`|
|toLowerCase()|大文字を小文字に変換する|
|toUpperCase()|小文字を大文字に変換する|
|toString()|オブジェクトが保持する文字列を返す<br>`変数にnullが来ると実行時エラー`|
|equals(Object str)|二つの文字列が等しいか判別する|
|equalsIgnoreCase(String str)|大文字小文字を区別せずに比較|


# StrinBuilderクラス

* StringBuilderクラスはmutable(可変)
* デフォルトで16字分のバッファを持つ

## StringBuilderクラスのメソッド

* append()
文字の追加を行うメソッド

* toString()
文字列に変換するメソッド
`nullを変換しようとすると実行エラーが発生する`

## StringBuilderクラスのメソッド
|メソッド名|説明|
|:----|:--|
|append(String str)|(str)を文字列の後ろに追加する、Stringとは違い`元の文字列は変化`する|
|append(String str, int start, int end)|(Str)の範囲指定をして追加する|
|insert(int offset, String str)|(str)の文字列を付け加えるためのものですが、付け加える位置を(offset)で指定できます|
|delete(int start, int end)|(start)番目から、(end)番目の直前までの文字を削除します。|
|reverse()|文字列の並びを逆にする|
|void setCharAt(int index, char ch)|(index)番目の位置の文字を(ch)で置き換えます|
|replace(int start, int end, String str)|(start)番目から、(end)番目の直前までの文字を、(str)で置き換えます。置き換える文字数と(str)の文字数が一致していなくも大丈夫です|
|toString()|StringBuilderをStringに変換できる|
|substring(int i)|Stringと同じ使い方ができます|
一目でわかるRAG解説

## はじめに

LLMの活用方法の一つ、RAG（Retrieval-Augmented Generation）について説明する機会が多かったので、簡単な解説を作ってみました。

LLM…Large Language Model(大規模言語モデル)のことで、Chat GPTはLLMを使ったアプリケーション

## RAGとは
![rag1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781545/e598e723-8776-0f7a-a4a6-17e293213c95.jpeg)

**①ユーザーが質問**
「<font color="red">動物園は何時から開いていますか</font>」

**②質問に関連するデータを検索**
検索方法は様々ありますが、質問文をそのまま使って文の類似度などで検索したり、質問文から検索ワードをLLMに生成させて検索したりします。
デファクトスタンダードの[Azure OpenAI](https://azure.microsoft.com/ja-jp/products/ai-services/openai-service)であれば、Azure環境のため、[Azure AI Search](https://azure.microsoft.com/ja-jp/products/ai-services/ai-search)を使うことが多い印象です。

**③質問に関連するデータを取得**
ここでは、以下のデータが取得できたとします。
「<font color="blue">開園時間：9時～17時 休園日：水曜日(水曜日が祝日の場合は開園日となり翌日を休園日とする)、年末年始(12/29～1/3)</font>」

![rag2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781545/7dd03f5c-2180-18dd-75e5-c20a6cbadbf4.jpeg)

**④取得したデータと合わせてプロンプトをLLMに投げる**
ここがRAGのポイントです。
<font color="red">①のユーザーの質問</font>、<font color="blue">③の取得したデータ</font>、そして<font color="green">予め用意しておいたプロンプト</font>を組み合わせて以下のようなプロンプト(文章)を作ります。

***
「<font color="green">あなたは○○動物園について回答するアシスタントです。
質問に対して、参考情報を元に回答を作ってください。回答部分のみを生成してください。
参考情報を元に回答できない場合は、「わかりません。」と答えてください。
まず例を示します。
質問：入園料はいくらですか。
参考情報：入園料 大人：800円 子供：300円
回答：入園料は、大人800円、子供300円です。
では以下に回答してください。
質問：</font><font color="red">動物園は何時から開いていますか</font>
<font color="green">参考情報：</font><font color="blue">開園時間：9時～17時 休園日：水曜日(水曜日が祝日の場合は開園日となり翌日を休園日とする)、年末年始(12/29～1/3)</font>
<font color="green">回答：</font>」

![rag3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781545/04cb2b1e-53da-df36-037c-6688682ddd38.jpeg)

**⑤LLMの回答**
④の質問からLLMが回答を作成します。試しに④にある質問を「」の中身まるごとChatGPTに投げてみてください。ちゃんと答えが返ってくるはずです。

LLMがやっているのは、情報抽出や要約といったタスクになります。
また、LLMが生成した回答に引用元をつけてあげるのがよいです。
BingのCOPILOTもインターネット検索を情報源とするRAGで、引用元のURLが表示されています。

:::note info
④で作ったプロンプトには、いくつかのプロンプトテクニックと呼ばれるものが入っています。

![prompt_technique.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3781545/08e05c26-dd1d-b92b-8b61-d529f7e36bdc.jpeg)

:::

## まとめ

RAGとは、質問及び質問の答えとなる情報が載っているデータを使ってLLMに答えさせる仕組みです。
検索したデータを使ってLLMに質問しているので、実は欲しい情報が入っているデータを検索できるかがポイントです。
実際のプロンプトを見てもらえばわかるように、プロンプト内に答えが書いてあって、LLMはその情報を整理して答えているだけです。
欲しい情報を検索できるかは様々な工夫があり、RAGシステムを開発する場合はそこの工夫がミソだったりします。
ヒストグラムから均等にビン分割しバンドを作成する(SPSS Modeler データ加工逆引き10-14)

# ヒストグラムから均等にビン分割しバンドを作成する

![スクリーンショット 2024-04-30 10.58.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/07ddaceb-85c6-d867-e37f-107bdb9b2955.png)

　この内容は逆引き10-13マウスによる手動ビン分割の自動計算バージョンです。

## 1.想定される利用目的

・　特徴量作成のために分布を確認しながら値をカテゴリに分割する
・　集計のために分布を確認しながら値をカテゴリに分割する

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/hist_sprit.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-04-22 10.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5b497aaf-931c-1178-8685-017a7f637b4a.png)

a.入力するデータは次の通りです。
![スクリーンショット 2024-04-22 10.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/d03db9f8-3182-1ad9-d1ef-ab9f57b21343.png)

b.[ヒストグラム]ノードを編集します。
![スクリーンショット 2024-04-22 10.57.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/183b5b8f-2e1a-ceed-9761-89da9e44a0e5.png)

　
[実行]します。
![スクリーンショット 2024-04-22 10.58.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5d6ef261-ddce-6829-d689-5b94f4241b1b.png)

#### 分布を確認しながら任意の閾値でビン分割する

[表示]メニューから[インタラクティブ]にチェックを入れて、ツールボタンを表示させます。
![スクリーンショット 2024-04-22 10.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2c24f83a-bde7-7759-d81a-269e7f20ca09.png)

赤枠のボタンを押します。
![スクリーンショット 2024-04-30 11.08.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3fffe870-4da0-bf6b-afdd-6d60a68d965a.png)

[分割:]の数を5に設定して[分割]ボタンを押します。
![スクリーンショット 2024-04-30 11.09.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a6b9bbfc-2557-0699-b35a-6bc872ebc8ea.png)

５つに均等分割するため４つのビンがセットされました。
![スクリーンショット 2024-04-30 11.10.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/03c5bcbf-5eb2-7a17-4a1f-de2bf1e62655.png)

[生成]メニューから[バンドのフィールド作成ノード]を選択します。cのノードが自動生成されます。
![スクリーンショット 2024-04-30 11.10.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/c435aa6e-a183-67d5-54bc-6ad312863887.png)

c.[フィールド作成]ノードを編集します。閾値をキリの良い値に編集することも可能です。
![スクリーンショット 2024-04-30 11.11.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/52e0e503-a656-900c-3c1b-942f87f99e00.png)

[テーブル]ノードを実行します。表示はサンプルです。バンドに分類できていることが確認できます。
![スクリーンショット 2024-04-30 11.12.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/6a116b80-beac-9ec3-2350-6e8666a8f5f7.png)

d.[ヒストグラム]ノードを編集して実行します。
![スクリーンショット 2024-04-30 11.18.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/fed22d09-4e75-900d-fbee-751d0d8f1814.png)


#### 注意事項

赤枠のボタンを押すことで。均等分割したビンを任意の値にマウスで変更することができます（青枠）。

![スクリーンショット 2024-04-30 11.20.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ebd70de3-ebf6-e0f2-93f7-721f311e4216.png)

## 4.参考情報

#### ヒストグラムをマウスでビン分割しバンドを作成する

https://qiita.com/416nishimaki/items/ea2c2926e332fa496770

#### 値を25％（四分位）のランク毎に集計する

https://qiita.com/416nishimaki/items/8b7e583281a8ff869cd0

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
部署間のハレーションを打ち破れ！！

## プロダクトと開発のハレーション：物理的な垣根を超えて、サービス視点で解決する

**はじめに**

プロダクトと開発のハレーションは、多くの企業で共通する課題です。ボタン追加一つを例にとっても、プロダクト側と開発側で認識のズレが生じ、開発工数やリスクを巡って議論が膠着してしまうケースは少なくありません。

しかし、**「気持ちだけで解決しようとする」**のは非効率的です。関係者の立場や目標を理解した上で、**「物理的な組織構造**」**を変える**という解決策があります。

**物理的組織構造の変革：サービス視点のチーム編成**

具体的には、従来のプロダクトと開発の縦割り組織から、**「サービス名」**の**横断的なチーム**を編成します（exAサービス事業部など）。
このチームは、**サービス全体のKPIと目標を共有**し、**プロダクトと開発の担当者が共に所属**します。

**メリット**

* **共通の目標意識と一体感の醸成**: プロダクトと開発が同じチームに属することで、**目標達成に向けた一体感**が生まれます。**部門間の縦割り意識がなくなり**、迅速かつ柔軟な意思決定が可能になります。
* **情報共有の円滑化**: チーム内に情報共有の場を設けることで、開発に必要な情報が迅速に伝わり、**無駄な工数や手戻りを減らす**ことができます。
* **開発工数とリスクの明確化**: 開発担当者は、ボタン追加の裏にある**工数やリスクを具体的に説明**し、**代替案を提案**することができます。プロダクト担当者は、**より現実的な目標設定**を行うことができます。
* **迅速な意思決定と開発サイクルの短縮**: プロダクトと開発が同じチームで議論することで、**意思決定の迅速化**が図れます。結果的に、**開発サイクルの短縮**にもつながります。

**注意点**

* **チームワークの構築**: チームメンバーが**異なるバックグラウンド**を持つため、**相互理解を深めるための努力**が必要です。
* **リーダーシップ**: チームを**効果的にまとめるリーダー**が必要です。
* **評価制度**: チーム全体の目標達成に貢献した**個人の貢献度を評価する制度**が必要です。

**まとめ**

プロダクトと開発のハレーションは、**物理的な組織構造を変革**することで解決できます。**サービス視点**に立ってチームを編成することで、**共通の目標意識**と**情報共有の円滑化**を実現し、**開発工数とリスクの明確化**、**迅速な意思決定**、**開発サイクルの短縮**に繋げることができます。

**この解決策が、貴社のハレーション解消の一助となることを願います。**
401 Unauthorized の考察



401エラーとは、「Unauthorized」とも呼ばれ、あるWebサイトへログインする際、認証に失敗した場合やそのサイトへのアクセス権限がない場合に表示されるHTTPレスポンスステータスコードです。 

 401エラー（HTTP 401 Unauthorized）とは、Webサーバで起きるエラーの種類の一つで、ユーザー認証が必要であることを示すもの

+ [Social Customer Service エラー:401 Unauthorized](https://help.salesforce.com/s/articleView?id=000380566&type=1)

Salesforce に投稿を送信していますが、ケースが作成されません。ソーシャル投稿が「401 Unauthorized」エラーで失敗したことを示す Salesforce エラーダイジェストを受信しました。

:::note
401 Unauthorized エラーは [High Assurance Session Security Level Required at Login (ログインに必要な高保証セッションセキュリティレベル)] が [Run Apex as User's Profile (ユーザーのプロファイルとして Apex を実行)] で有効になっている場合に発生します。
:::

+ [401 Unauthorized Error from Embedded Service for MIAW](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ak7ThSAI)


+ [Einstein bot preview giving 401 unauthorized](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BrbVVSAZ)

:::note
Hmm, I'm not sure where you're embedded the chatbot, but you might need to enable access to that domain under Setup -> CORS. 
:::

# 未解決

+ [Argument 1 can not be null [System.HttpResponse[Status=Unauthorized, StatusCode=401]]](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GzcP1)

[Docusign to salesforce integration error - https://creative-koala-j01zpp-dev-ed.my.salesforce.com/services/apexrest/ContactAPIS :: Error - The remote server returned an error: (401) Unauthorized.; anybody help me to solve this.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000J8MyO)
WPFで3D

# 環境
Windows 11 Pro (64bit)

```dev.bat
@echo off
path %path%;C:\Windows\Microsoft.NET\Framework64\v4.0.30319
prompt $e[33m$p$g$e[m
cmd
```

```wpf.rsp
# csc @wpf.rsp foo.cs
/r:System.Xaml.dll
/r:WPF\PresentationCore.dll
/r:WPF\PresentationFramework.dll
/r:WPF\WindowsBase.dll
```

# 三角形

```wpf3d1.cs
// csc /t:winexe @wpf.rsp wpf3d1.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;

class MainWnd : Window {
	public MainWnd() {
		var pos = new Point3DCollection();
		pos.Add(new Point3D(1, 0, 0));
		pos.Add(new Point3D(0, 1, 0));
		pos.Add(new Point3D(0, 0, 0));

		var model = new GeometryModel3D();
		model.Geometry = new MeshGeometry3D() { Positions = pos };
		model.Material = new DiffuseMaterial(Brushes.LightGreen);

		var light = new DirectionalLight();

		var cam = new OrthographicCamera();
		cam.Position = new Point3D(0, 0, 5);

		var vp3d = new Viewport3D();
		vp3d.Camera = cam;
		vp3d.Children.Add(new ModelVisual3D() { Content = model });
		vp3d.Children.Add(new ModelVisual3D() { Content = light });

		Width = 300;
		Height = 300;
		Content = vp3d;
	}
}

class Program {
	[STAThread]
	static void Main() {
		var wnd = new MainWnd();
		wnd.ShowDialog();
	}
}
```

# 球
![wpf3d2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257554/7b97ac4f-c38a-1f9f-ad8b-61b84973309c.jpeg)

```wpf3d2.cs
// csc /t:winexe @wpf.rsp wpf3d2.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;

class MainWnd : Window {
	public MainWnd() {
		var stacks = 12;
		var slices = 16;
		var pos = new Point3DCollection();
		var idx = new Int32Collection();

		for (var st = 0; st <= stacks; st++) {
			var a = Math.PI * st / stacks;
			var y = Math.Cos(a);
			var r = Math.Sin(a);
			for (var sl = 0; sl <= slices; sl++) {
				var b = 2 * Math.PI * sl / slices + Math.PI;
				var z = Math.Cos(b);
				var x = Math.Sin(b);
				pos.Add(new Point3D(x * r, y, z * r));
			}
		}

		for (var st = 0; st < stacks; st++) {
			var h0 = (slices + 1) * st;
			var h1 = (slices + 1) * (st + 1);
			for (var sl = 0; sl < slices; sl++) {
				var i0 = h0 + sl;
				var i1 = h1 + sl;
				var i2 = h0 + sl + 1;
				var i3 = h1 + sl + 1;
				idx.Add(i0);
				idx.Add(i1);
				idx.Add(i2);
				idx.Add(i3);
				idx.Add(i2);
				idx.Add(i1);
			}
		}

		var model = new GeometryModel3D();
		model.Geometry = new MeshGeometry3D() {
			Positions = pos,
			TriangleIndices = idx,
		};
		model.Material = new DiffuseMaterial(Brushes.LightGreen);

		var light = new DirectionalLight();
		light.Direction = new Vector3D(-1, -2, -3);

		var cam = new OrthographicCamera();
		cam.Position = new Point3D(0, 0, 5);

		var vp3d = new Viewport3D();
		vp3d.Camera = cam;
		vp3d.Children.Add(new ModelVisual3D() { Content = model });
		vp3d.Children.Add(new ModelVisual3D() { Content = light });

		Width = 300;
		Height = 300;
		Content = vp3d;
	}
}

class Program {
	[STAThread]
	static void Main() {
		var wnd = new MainWnd();
		wnd.ShowDialog();
	}
}
```

# 参考

https://any-programming.hatenablog.com/entry/2017/08/01/021822
RGB8:8:8からRGB5:6:5に変換をかんがえる。


目的
bitmapで遊ぶ

やりかた

FFFFFF　の　並びから FF,FF,FF を取り出す

R = FF を　整数の値に変換　255
G = FF を　整数の値に変換　255
B = FF を　整数の値に変換　255

R = 下位3bitカット 
G = 下位2bitカット 
B = 下位3bitカット 



上位からR,G,Bの順に張り付ける


RGB5:6:5になる


FFFF の　16bitカラーになる




![o_coq096.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/df6eb5b5-b872-5c73-aab8-75e46412a63a.jpeg)

![o_coq097.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3d0d6122-ff12-01d2-6a32-8a7eae39f00f.jpeg)





```c++

#define hex_cov(aa)   ((aa<':')?aa-'0':aa-'A'+10)

        R = (hex_cov(bitmap[ii*6+0])<<4) + hex_cov(bitmap[ii*6+1]);
        R = R >> 3;
        
        G = (hex_cov(bitmap[ii*6+2])<<4) + hex_cov(bitmap[ii*6+3]);
        G = G >> 2;
    
        B = (hex_cov(bitmap[ii*6+4])<<4) + hex_cov(bitmap[ii*6+5]);
        B = B >> 3;
        
        
 
        RGB = (R<<11)+(G<<5)+(B);



```
RGB5:6:5の16bitカラーをかんがえる。


目的
カラーLEDで遊ぶため

Rが5bit,Bが6bit,Gが5bit


![o_coq097.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0d0564b7-03e1-8c40-c467-9f49ab49b3b8.jpeg)
Google Colabで少しだけ幸せになる方法

# はじめに
みなさんGoogle Colabは使用していますか？
少しだけ幸せになれる方法をお教えします。

# 設定
Google Colabでノートブックを開き、右上の歯車マーク、もしくは「ツール」から「設定」を開きます。
「その他」タブからお好きなモードを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493004/6c1cbecd-7fb2-6063-e482-a56a98c9b323.png)

全部チェックすると犬、カニ、猫が上部に走り出し、賑やかになります。
かわいいですね。

はい、幸せになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493004/7a62edd6-69dc-03c4-5b3b-f75183dbef79.png)


ちなみに猫は5種類いるみたいです。
犬は何種類いるのでしょうか。気になる方は調べてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493004/17fdc108-641d-9ec9-d6e2-cf0da3c28049.png)

ちなみに、モードの上部に「パワーレベル」の設定があります。
「Some power」と「Many power」が選べます。

「Some power」にすると連続タイピング（素早く30文字以上）で火花が散り、コンボ数が右下に表示されます。
「Many power」にするとタイピングの1手目から火花が散り、画面が激しく揺れます。


↓見づらいですが、火花が散り、右下にコンボ数が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493004/a6bb4b64-96a8-1825-6313-5d3fcae66422.png)


# おまけ

猫の品種をChatGPTとClaudeに聞いてみました。

### ChatGPT
>この画像に描かれている猫の品種について具体的に特定するのは難しいですが、スタイルと色から考えられる品種を推測できます：
1.左端の黒猫は、その特徴から一般的な「黒猫」を表している可能性が高いです。
2.二番目の猫は、三毛猫（カリコ）の特徴を持っています。白、黒、茶色の斑があり、日本では非常に人気があります。
3.真ん中のオレンジ色の猫は、アメリカンショートヘアやマンチカンなどの特徴を持つかもしれません。
4.四番目の猫は、タビー（縞模様のある）パターンが特徴です。このパターンは多くの品種で見られますが、アメリカンショートヘアやアメリカンタビーなどが該当するかもしれません。
5.右端の猫は、その色と目の色からシャム猫やラグドールのような品種を連想させます。
これらの品種はあくまで推測であり、イラストは特定の品種よりも猫の一般的な特徴を表現していることが多いです。

### Claude

> この5種類の猫のイラストは、それぞれ以下の品種を表現していると思われます。
1.アメリカンショートヘア(もしくはブリティッシュショートヘア) - 丸みを帯びた体型と短い毛が特徴的です。
2.エキゾチックショートヘア - ペルシャ猫に似た丸い顔立ちですが、短毛種です。
3.アメリカンカール - 後ろ向きにカールした特徴的な耳を持っています。
4.スコティッシュフォールド - 折れ曲がった耳が特徴的な品種です。
5.ロシアンブルー - 青みがかった灰色の毛並みが特徴的なロシア原産の品種です。
ただし、これらはイラストであり、実在する個々の猫を描いたものではないため、明確な品種の特定は難しい面もあります。

ChatGPTの方が画像の特徴をよくとらえている気がしますね。

# おわりに
いかがでしたでしょうか。開発者の遊び心が垣間見えるかわいい設定ですね。
よろしければ設定してみてください。

それでは次の記事でお会いしましょう('ω')ノ
初心者が音声認識を触ってみた （その１）

## まえがき

ある日のこと、[画像処理の調べもの](https://qiita.com/deratege/items/5c8ff08b58a807c141f6)に悪戦苦闘していると、ふらりとやってきた妖精さんがこう言いました。

「ついでに音声合成も調べといてくれる？」

え？なんですと？また無茶振りだネ？
まあ、Qiitaのキャンペーンもあるしちょうどいいかナ？
軽く安請け合いしたのでした。

## とりあえず最終目標

人が台本を読み上げてマイクから録音しつつ、テキストに落として字幕ファイル（SRT形式）を作成する。

![スクリーンショット 2024-05-08 071756.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99561/234309bd-288a-e1a1-6c9f-96326439eb21.png)
こんな感じ。
まずはマイク周りは後回しにして、音声認識を試してみる。

## サンプルプログラムをPythonで動かしてみる

AmiVoiceAPIの利用登録とクーポンの登録が終了したら、[Github上に公開](https://github.com/advanced-media-inc/amivoice-api-client-library)されているサンプルグロムをダウンロードします。
amivoice-api-client-library-main\Wrp\python 以下のファイル／フォルダと、amivoice-api-client-library-main\audioフォルダ、curl-ca-bundle.crt を一つの作業用フォルダにまとめたら、run.bat を以下のように変更します。
```bat:run.bat
REM @set /P AppKey="Please enter AppKey: "
set AppKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
set PYTHONPATH=src
set SSL_CERT_FILE=curl-ca-bundle.crt
REM 標準出力はjsonのみでファイルに落とす。jsonから取り出したテキストはエラー出力にして画面に表示する
python WrpSimpleTester.py wss://acp-api.amivoice.com/v1/ audio/test.wav 16K -a-general %AppKey% > %~dp0output.json
rem @pause
```
※ 接続先は「ログあり」を指定しています。機密情報を扱う場合は、”wss://acp-api.amivoice.com/v1/nolog/”を指定して「ログなし」にします。

また、WrpSimpleTester.py の106行目のprint文を、次のように変更して出力先を標準エラー出力に変更します。
```
print(" -> %s" % text, file=sys.stderr)
```
※ 今回はPython3.11を使います。現行のPython3.12は脆弱性対策のためssl.wrap_socket()が廃止されているとのことで、src\com\amivoice\wrp\Wrp_.pyの146,148行目が動作しません。

このバッチファイルをコマンドプロンプトから実行すると、jsonファイルが作成されたうえで画面には認識された文章が表示されます。
```
 -> アドバンスト・メディアは、人と機械との自然なコミュニケーションを実現し、豊かな未来を創造していくことを目指します。
```
そのうえで、[この参考記事](https://qiita.com/DianziYang/items/c82580abc84c98268b55)のソースコードをpyファイルに落として、run.batに次の1行を付け加えます。
```
python WrpParser.py output.json
```
これを実行すると、output.srt が以下のように作成されます。
```
1
00:00:00,506 --> 00:00:02,026
アドバンスト・メディアは

2
00:00:02,026 --> 00:00:05,626
人と機械との自然なコミュニケーションを実現し

3
00:00:05,626 --> 00:00:08,746
豊かな未来を創造していくことを目指します

4
00:00:00,000 --> 00:00:08,746


```
ここまで、ssl.wrap_socket()に悩んだ以外はすごく簡単でした。音声ファイルからは割にあっさりと字幕が生成できることを確認できました。

[次の記事](https://qiita.com/deratege/items/d07f12746f06e7afc9d0)では、マイク入力にしてリアルタイムに音声認識させてみます。

## 参考記事
[Qiita記事投稿キャンペーン開催中！クーポン発行方法をご紹介](https://acp.amivoice.com/blog/qiita_api240424/)
[AmiVoiceのJSONデータから字幕ファイル（SRT）をつくってみた](https://qiita.com/DianziYang/items/c82580abc84c98268b55)
RGB24bitカラーをかんがえる。


目的
bitmapやws2812で遊びたいから

24bitで1点のカラーを表現する

R,G,Bが8bitと毎に格納されている

![o_coq096.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2c6390bc-f003-f797-04e8-dba5d08a2258.jpeg)
GAS練習　配列

問題文
配列 numbers を作成し、その要素を 1, 2, 3, 4, 5 とします。この配列の要素をすべて2倍にして、新しい配列 doubledNumbers に格納してください。

考える順番
・配列numbersを作成
・numbersの要素に×２
・空の配列doubledNumbersにnumbers×2を格納

誤）考えたコード
```
function myFunction() {
  
  let doubledNumbers = [];

  let numbers = [1,2,3,4,5];
  doubledNumbers.push([numbers]*2)

  console.log(numbers)
}
```
間違い
`doubledNumbers.push([numbers]*2)`
→配列[numbers]に対して×２
→[numbers]が２つ作られる（出力ログ[1,2,3,4,5],[1,2,3,4,5])
■解決策
配列[numbers]から要素を取り出して２倍する必要がある


正）
```
function myFunction() {

 let doubledNumbers=[];

  const numbers = [1,2,3,4,5]
  for(let i=0; i<numbers.length; i++){
    doubledNumbers.push(numbers[i]*2)
  }
console.log(doubledNumbers);
}
```

【まず i とは】
インデックスの略
配列内の要素を取得する


for文 読み方
どこまで繰り返すか：
[i]～numbers.length(0番目の要素から配列numbersに入っている要素の長さまで

増減は：
i++(i=i+i)でiを1づつ増やす

｛処理｝
繰り返し対象の処理

１回目
numbers[i](0番目の配列なので、ここでは要素[1]）
→配列numberの箱に入っている[i]に×２
→配列doubledNumbersに結果を格納


for文により２回目以降は要素iに１づつ足される

i++([i]は0+1=1)となり、[i]=1
`doubledNumbers.push(numbers[i]*2)`
配列numbersの要素1番目（ここでは要素[2]）に×２がされる
→結果が配列doubledNumbers[]に格納


上記の計算をnumbers.lengthまで繰り返され
numbersの要素ごとに×２した結果が
配列doubledNumbers[]に格納

出力ログは[ 2, 4, 6, 8, 10 ]
16進をかんがえる。


目的
10進にあと6個たすと16進になる

0,1,2,3,4,5,6,7,8,9,A,B,C,E,Fになる

二進との対応は、表の通り。　4ピット分を表現できる。


![o_coq095.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/474750f4-7417-ee0c-1402-de3813ba6891.jpeg)
Javaで「整数リテラル」の動作を確認してみた

# 概要

Javaで「整数リテラル」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/num/index5.html

# 実装

以下のファイルを作成しました。
```JSample5_1.java
class JSample5_1{
  public static void main(String[] args){
    System.out.println(123);
    System.out.println(0x3F01);
    System.out.println(45 + 75);
  }
}
```

以下のコマンドを実行しました。
```
$ javac -encoding UTF-8 JSample5_1.java
$ java JSample5_1 
123
16129
120
```

# まとめ

何かの役に立てばと。
画像 16進数(hex)変換で遊ぶ。


目的
画像をダンプに変換

1, アドレスにアクセス

https://colorcodesearch.com/image-hex/

```

https://colorcodesearch.com/image-hex/

```

![o_coq088.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/11e4f14e-5dba-c6b5-8b0b-192554c31b68.jpeg)


2, なし,なしにする

![o_coq089.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ee9b9a45-4c2b-c819-0584-86307f2ebe13.jpeg)

↓

![o_coq090.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/591debfa-8843-4a01-2fa5-ec22bcf445b6.jpeg)

3, ファイルの読み込み

![o_coq091.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ea85b9ea-e7ea-f7f1-4ad1-aaf1402fd4eb.jpeg)

↓

![o_coq092.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7e6e56a9-a31e-ac3c-7b5a-83eeada8fdef.jpeg)


4, 読み込まれて結果が表示される

![o_coq093.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/79043b58-682d-4d47-e983-01b88f527349.jpeg)

5, コピーアンドペーストする

![o_coq094.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a8b7d710-16bf-5426-e3ed-5e3477e0e84f.jpeg)
Rust のデバッグ環境が死んだ【Mac / Intel → Apple Silicon】

## はじめに

こんにちは！ Shungiku です。

最近、5年ほど使っていた Intel プロセッサの MacBook がお亡くなりになったので、M3 MacBook Air を購入して Apple Silicon デビューを果たしました！

ところがどっこい、VsCode で Rust のデバッグが出来なくなってしまうという症状に遭遇したので、その解決法を書き残して置きたいと思います。


## 症状

自分はもともと VsCode に CodeLLDB（`vadimcn.vscode-lldb`）という拡張機能を入れて Rust のデバッグをしていました。
ところが、Intel プロセッサから Apple Silicon プロセッサの Mac にお引越ししてからというもの、デバッグ時に以下のエラーメッセージが表示されるようになりました。

```
process resume at entry point failed: Resume timed out.
```


## 解決法

Stack overflow のこちらの質問/回答に助けられました。

https://stackoverflow.com/questions/76475954/vscode-codelldb-mac-m2-error-the-platform-is-not-currently-connected

> what solved my problem was deleting the extensions directory at ~/.vscode/extensions (or ~/.vscode-insiders/extensions if you use the insiders version), and reinstalling my desired extensions. I believe there was an architecture mismatch. 

「アーキテクチャのミスマッチのせいでコケているはず。`~/.vscode-insiders/extensions` のディレクトリを削除して拡張機能を入れなおしたら直ったぜい！」とのこと。

自分の場合、拡張機能のディレクトリ毎消さずとも CodeLLDB のものだけで良いのでは？と思い、まずは以下のコマンドでディレクトリを削除し、

```
rm -r ~/.vscode/extensions/vadimcn.vscode-lldb-1.10.0
```

その後、VsCodeのUI上から CodeLLDB（`vadimcn.vscode-lldb`）の拡張機能を入れ直しました。

結果、見事解決という運びとなりました...！

## まとめ

しばらく脳内デバッグするしかないという暗闇の中にいたので危うく闇落ちするところだったぜ...

闇落ちしそうな誰かを本稿で救えることを願っています！（とはいえそんな人ほぼいない気も...）
【ポエム】「一か月」って何日だよ


他人が書いた設計書を読んでいるとたまに「一か月前のデータを削除する」のような文言がある。

そのたびに私は「一か月」って何日だよと感じてしまう。

30日なのか、31日なのか、それとも先月なのか。分からない。

もちろん質問はするが、こういう人によって捉え方が異なるかもしれない文言はあまり使ってほしくないと思う。

## おまけ

https://qiita.com/mogamoga1337/items/379989516a1cf83c43f8
2024/5/8主にITとかセキュリティの記事

複数のAndroidアプリにパストラバーサルの脆弱性、40億回以上ダウンロード(5/6)
https://news.mynavi.jp/techplus/article/20240506-2940185/

Node.js の進化に伴い不要となったかもしれないパッケージたち(5/6)
https://zenn.dev/morinokami/articles/npm-uninstall

銀行や公官庁系のフィッシング詐欺が急増中(5/6)
https://forbesjapan.com/articles/detail/70641

RetrieveAndGenerate の sessionId パラメーターはセッション保持以外にクエリ書き換えも行ってくれる(5/6)
https://dev.classmethod.jp/articles/retrieve-and-generate-sessionid-parameter-session-query-rewrite/

DEX（分散型取引所）とは？特徴・使い方・注意点などをわかりやすく解説(5/6)
https://bittimes.net/news/168293.html

＜独自＞ＦＢアカウント詐取攻撃、日本政府関係者も標的　露、米大統領選選挙工作か(5/6)
https://www.sankei.com/article/20240506-EBDQ6UPRHZLBBF3XBV2XAUJFOE/

AWSアカウントセットアップガイド 〜アカウント作成から最低限やるべき設定までやってみた〜(5/6)
https://dev.classmethod.jp/articles/aws-account-setup-guide-2024-05/

「もう使わないスマホ」を正しく処分する方法とは(5/6)
https://techtarget.itmedia.co.jp/tt/news/2405/06/news02.html

AIの危険性を知るには「数字を押さえておくこと」が重要だ：米ランド研究所所長インタビュー(5/6)
https://wired.jp/article/sz-jason-matheny-national-security-insider-dangers-of-ai/

米国のデジタル貿易政策 現政権支持するＩＴ労組(5/6)
https://vpoint.jp/opnion/viewpoint/228653.html

「誰もが脆弱」： 米学校の偽音声がAIへの警戒心を煽る(5/6)
https://www.arabnews.jp/article/features/article_118494/

医療機関の６割「マイナ保険証でトラブル」、最多は「旧字が表れない」…他人の個人情報ひもづけも(5/6)
https://www.yomiuri.co.jp/medical/20240501-OYT1T50196/

社内ブランディングにも全力を投じる日清食品、大切なのはIT部門が「目立つ」こと(5/7)
https://xtech.nikkei.com/atcl/nxt/column/18/00138/043001516/

JCBが「3Dセキュア2.0」対応の新たな認証方式を導入、EC利用時のかご落ち低減へ(5/7)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/09213/

全国の大学生協で使うスマホアプリが3日連続で障害、お昼時に電子マネー決済できず(5/7)
https://xtech.nikkei.com/atcl/nxt/column/18/00598/040500271/
`write`/`read`と`send`/`recv`の違い命名と責務による誤解を解く

# ソケットプログラミング：`write`/`read`と`send`/`recv`の責務と関係

ソケットプログラミングにおいて、`write`/`read`と`send`/`recv`の違いに戸惑う人は多いでしょう。この記事では、Unixの「Everything is a file」の思想による抽象化の背景を踏まえ、これらの関数の責務と関係を説明し、なぜ両方の関数で通信が可能なのかを解説します。

## Everything is a fileの思想とソケット

Unixシステムでは、「Everything is a file」という設計思想があります。この思想に基づき、ネットワークソケットもファイルディスクリプタとして抽象化されます。つまり、ソケットに対してファイル操作関数（`write`/`read`）を使用することができるのです。

この抽象化により、プログラマはファイルI/Oと同じインターフェースでネットワークI/Oを扱うことができ、コードの統一性と可読性が向上します。

## ユーザー空間とカーネル空間の責務

ソケット通信では、ユーザー空間とカーネル空間が異なる責務を担っています。

ユーザー空間の責務：
- ソケットの作成とファイルディスクリプタの管理
- `write`/`read`や`send`/`recv`関数を使ってソケットにデータを書き込み、読み取る

カーネル空間の責務：
- ソケットバッファの管理
- プロトコルスタックの処理
- ネットワークデバイスドライバの制御
- 実際のデータ転送

## `write`/`read`関数の責務

`write`関数は、ファイルディスクリプタに対してデータを書き込みます。ソケットの場合、`write`関数を呼び出すと、データはカーネル空間のソケットバッファにコピーされます。

`read`関数は、ファイルディスクリプタからデータを読み取ります。ソケットの場合、`read`関数を呼び出すと、カーネル空間のソケットバッファからデータがユーザー空間にコピーされます。

## `send`/`recv`関数の責務

`send`関数と`recv`関数は、ソケット通信に特化した関数です。これらの関数は、`write`/`read`関数と同様に、データをソケットバッファにコピーしたり、ソケットバッファからデータを読み取ったりします。

ただし、`send`/`recv`関数は追加のフラグ引数を受け取ることができ、送受信動作をより細かく制御できます。

## データ転送の責務はカーネルにある

重要なのは、実際のデータ転送はカーネルが担っているということです。ユーザー空間の`write`/`read`や`send`/`recv`関数は、データをソケットバッファにコピーしたり、ソケットバッファからデータを読み取ったりするだけです。

データがソケットバッファに書き込まれると、カーネルが以下の処理を行います：

1. プロトコルスタックでのデータ処理
2. ルーティングとARP
3. ネットワークデバイスドライバへのデータ受け渡し
4. ネットワークインターフェイスカード（NIC）からの送信

## まとめ

Unixの「Everything is a file」の思想により、ネットワークソケットはファイルディスクリプタとして抽象化されています。これにより、`write`/`read`関数を使ってソケット通信を行うことができます。

ソケット通信では、ユーザー空間の責務はソケットへのデータの書き込みと読み取りであり、実際のデータ転送はカーネル空間の責務です。`write`/`read`や`send`/`recv`関数は、データをソケットバッファにコピーしたり、ソケットバッファからデータを読み取ったりするだけで、直接的なデータ転送は行いません。

したがって、`write`/`read`関数でもソケット通信が可能なのは、カーネルがソケットバッファに書き込まれたデータを元に通信を行うからです。`send`/`recv`関数は、送受信動作をより細かく制御できる点で`write`/`read`関数と異なります。