OmniAICreator/Qiita-1.07M huggingface dataset:
【Goで学ぶコンピューターサイエンス】データベースの基礎

## データベースの基本的な用語

### テーブル
- データを行と列で整理した、表形式のもの

| ID | 名前   | 年齢 | メールアドレス         |
|----|--------|------|------------------------|
| 1  | 田中太郎 | 30   | taro@example.com      |
| 2  | 鈴木花子 | 25   | hanako@example.com    |

### レコード
- テーブルの1行にあたるデータ

### フィールド
- テーブルの列にあたる項目

### 主キー(Primary key)
- レコードを一意に識別するためのフィールド
- 重複が許されない
- 上記テーブルの「ID」フィールド

## データベースの種類

### リレーショナルデータベース（RDB）
- データをテーブル（表）の形式で管理
- 関係（リレーション）を使ってデータを関連付けられる
- SQLで操作する
- MySQL、PostgreSQL、SQLiteなど

### 非リレーショナルデータベース（NoSQL）
- データを表形式以外の方法で管理
- 柔軟でスケーラビリティが高い
- ドキュメント形式やキーバリュー形式でデータを保存
- MongoDB（ドキュメント型）、Redis（キーバリュー型）

### インメモリデータベース
- データをメモリ上に保存し、高速な読み書きを実現
- Redis、Memcached

## SQL
※サンプルはMySQLの例です。
### DDL
#### 新しいテーブルの作成
```sql
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INT,
    email VARCHAR(255) UNIQUE
);
```

#### テーブルの変更
```sql
ALTER TABLE users ADD COLUMN phone_number VARCHAR(15);
```

#### テーブルの削除
```sql
DROP TABLE users;
```

#### テーブルのデータを全削除（テーブル構造は維持）
```sql
TRUNCATE TABLE users;
```

#### データベースの作成
```sql
CREATE DATABASE sample_db;
```

#### データベースの削除
```sql
DROP DATABASE sample_db;
```

### DML
#### **データの追加**
```sql
INSERT INTO users (id, name, age, email) VALUES (1, '田中太郎', 30, 'taro@example.com');
```

#### **データの取得**
```sql
SELECT * FROM users WHERE age > 25;
```

#### **データの更新**
```sql
UPDATE users SET age = 31 WHERE id = 1;
```

#### **データの削除**
```sql
DELETE FROM users WHERE id = 1;
```

### DCL
#### ユーザーに権限を付与
```sql
GRANT SELECT, INSERT ON users TO 'example_user'@'localhost';
```

#### ユーザーの権限を取り消し
```sql
REVOKE INSERT ON users FROM 'example_user'@'localhost';
```

#### ユーザーの作成
```sql
CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'password';
```

#### ユーザーの削除
```sql
DROP USER 'example_user'@'localhost';
```

## データベース設計の基本

### 正規化
- データの重複を排除し、構造を整理するプロセス
- 複数のテーブルに存在する共通項目を別テーブルに分離して共通化する

### インデックス
- 検索速度を向上させるための仕組み
- 本の「索引」と同じような役割

## Goサンプルコード

```go
package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/mattn/go-sqlite3" // SQLite用ドライバ
)

func main() {
	// データベースに接続
	db, err := sql.Open("sqlite3", "./example.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// テーブルの作成
	createTable := `
	CREATE TABLE IF NOT EXISTS users (
		id INTEGER PRIMARY KEY AUTOINCREMENT,
		name TEXT NOT NULL,
		age INTEGER,
		email TEXT UNIQUE
	);
	`
	_, err = db.Exec(createTable)
	if err != nil {
		log.Fatal(err)
	}

	// データの挿入
	insert := `INSERT INTO users (name, age, email) VALUES (?, ?, ?);`
	_, err = db.Exec(insert, "田中太郎", 30, "taro@example.com")
	if err != nil {
		log.Fatal(err)
	}

	// データの取得
	rows, err := db.Query(`SELECT id, name, age, email FROM users;`)
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	for rows.Next() {
		user := struct {
			ID    int
			Name  string
			Age   int
			Email string
		}{}
		rows.Scan(&user.ID, &user.Name, &user.Age, &user.Email)
		fmt.Printf("ID: %d, Name: %s, Age: %d, Email: %s\n", user.ID, user.Name, user.Age, user.Email)
	}
}
```
REDMINEでチケットを整理する最も簡単な方法

https://qiita.com/EasyCording/items/a7d6adc1ab5b1d41a95f

以前のTOPICSで生成ＡＩを使って、REDMINEチケットを自動で整理するようなことを考えていた・・・
pythonでAPI情報を使ったり、裏でCHATGPT-APIでデータ処理をしたり、何かと大変だろうと思っていた

しかしながら、下記の方法であれば、即日実行できることが分かった

１）ＴＩＣＫＥＴ一覧をＣＳＶエクスポート
２）生成ＡＩに適当な粒度で整理してと伝える　
３）ＴＩＣＫＥＴをインポートする

どうして、こんな簡単なことを思いつかなかったんだろう・・・

# 具体的な指示例
ChatGPTに渡す際の指示は、以下のようなものが考えられます。

```
このCSVデータを分析し、以下の条件で整理してください。
1. ステータスごとに分類し、それぞれのステータスにおける件数を表示してください。
2. 担当者ごとにチケットを分類し、それぞれの担当者のチケット数を表示してください。
3. 優先度ごとに分類し、それぞれの優先度におけるチケット数を表示してください。
4. 各チケットの概要欄を要約し、最大30文字で表現してください。
5. 期日が近い順に並び替えてください。
6. 上記の情報をもとに、REDMINEにインポートできるCSV形式で出力してください。
```

# 課題
この方法で問題になるのが、作業時間との紐付けが無くなることだ。
解決策としては、やはり一定周期で作業内容の要約を作ることだ。

## ログ記録例
2024-08-20 2時間 : 〇〇機能のUI修正, XXコンポーネントのスタイル調整に時間がかかった
2024-08-20 1.5時間 : YYモジュールのバグ修正, DB接続で想定外のエラーが発生、調査に時間を費やした
2024-08-21 2時間 : 〇〇機能の実装, API連携部分で想定外のレスポンスが返ってきた、API仕様書を再確認した

## ChatGPTへの指示例
```
この作業ログを分析し、以下の情報を出力してください。
1. 特定のキーワード（例：「UI修正」、「バグ修正」）を含む作業ログの時間を集計してください。
2. 作業時間が最も長い作業内容をトップ5で表示してください。
3. 各作業内容の所感をまとめ、改善点や反省点を抽出してください。
4. 作業時間と作業内容を基に、今後の見積もり精度を向上させるためのアドバイスをしてください。
```

作業ログは、自分自身の成長記録や振り返りの材料として活用できる
また、作業ログを蓄積することで、ＲＡＧシステムで類似タスクを関連付けて、次のタスクを作らせることもできる

いわゆる、タスク思考型のエージェントにつなげることが出来る
ちなみに、作業内容自体をＲＡＧデータで使うことは、言語ベクトル自体が疎なためお勧めできないが、この方法は密になるのでそれなりに機能する
こういうＲＡＧデータの作り方を「知識蒸留」または「知識圧縮」という

[1] https://note.ambitiousai.co.jp/n/n01070427eee5:
知識蒸留の基本的な概念と、その技術的な詳細を理解するのに役立ちます。

[2] https://qiita.com/heapjp/items/0ff0ef47823f10dbe6c3:
RAGシステムにおける知識蒸留の活用方法や事例について理解するのに役立ちます。

[3] https://qiita.com/applego/items/29546ed50d65bc9a8d56:
知識蒸留の応用例や、具体的な実装方法について理解するのに役立ちます。

# RAGシステムにおける知識蒸留の重要性
知識蒸留は、RAG（Retrieval-Augmented Generation）システムの効率と精度を向上させる上で重要な役割を果たします。RAGシステムは、大規模な知識ベースから関連情報を検索し、その情報を基に適切な応答を生成する能力を持っています。
# 知識蒸留の利点
データの密度向上: 作業ログのような詳細な情報を、より簡潔で意味のある形式に変換します。
検索効率の改善: 圧縮された情報は、ベクトルデータベースでより効率的に検索できます。
関連性の向上: 密度の高いデータは、より正確な意味的マッチングを可能にします。

# 実践的なアプローチ
あなたが提案した方法は、知識蒸留の実践的なアプローチの一例です。REDMINEチケットの整理や作業ログの分析を通じて、以下のような利点が得られます：

* タスクの効率化: チケットの自動整理により、管理作業が大幅に効率化されます。
* 洞察の獲得: 作業ログの分析を通じて、プロジェクト管理や個人の生産性に関する貴重な洞察が得られます。
* 将来の予測: 蓄積されたデータを基に、将来のタスクの見積もりや計画立案が改善されます。

# RAGシステムへの応用
知識蒸留された作業ログは、RAGシステムの強力な基盤となります。

* 類似タスクの関連付け: 過去の経験を活かした効率的なタスク管理が可能になります。
* タスク思考型エージェントの構築: 蓄積された知識を基に、より高度な自動化や意思決定支援が実現できます。
* 継続的な学習と改善: システムは新しい情報を取り込み、常に最新かつ関連性の高い情報を提供し続けることができます。
Webotsで四輪ロボットモデルを作成する方法

Webotsシミュレータで四輪ロボットモデルを作成する方法を書いていきます。

## Webotsの長所
Webotsでは次のような部分が特徴である
* 環境構築が容易
    * Webotsをインストールするだけで利用できる
    * 既成のロボットモデルが豊富
## Webotsワールド
Webotsでプロジェクトを作成すると次のような画面構成になると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/93c8593e-6f52-902e-1431-b64c7657f73e.png)

## 

上記の画像について、
* 左側のIMPORTABLE EXTERNPROTOの枠がワールドファイルを編集する部分
* 真ん中がシミュレーションの状況を表示する部分
* 右側がコントローラ、つまりロボットを操作するプログラム（C++やPythonなどで記述）を編集する部分
* 下がコンソール

となっています。

ワールドファイルでオブジェクトを作り、それをコントローラを利用して動かすことでシミュレーションを行うのが主な流れです。

## ワールド拡張とロボットオブジェクトの配置

最初のワールドサイズではロボットを動かすには狭いので、拡張をします。
左枠のRectangleArena → floorTileSizeを5×5にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/b1b7008e-c0f8-51cd-6aee-0f616faba801.png)

そしてロボットを追加します。
RectangleArenaを右クリックし、「新規の追加」でRobotを追加。
このときは何も実体はないです。

次にchildrenにSolidを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/1fa30d7d-fb76-3575-948a-0b0b2ea02bfa.png)

追加したSolidのchildrenにHingeJointを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/649ca3f2-ac16-4c45-1dca-e1ab1674eae8.png)

続いて次の三つ
* deviceにRotationalMotorを追加
* endPointにSolidを追加
* JointParametersにHingeJointParametersを追加
* ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/8e2267a4-6fa4-a962-c86b-effe1c66484a.png)

そろそろ見た目を反映させていきます。
* RobotのchildrenにShapeを追加
* ShapeのgeometryにBoxを追加
* Boxの値を0.3 0.6 0.1 に設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/8a440fc5-b3cb-3e21-b5b6-42a664a9e344.png)
この部分では本体部分を作成しています。車のボディーです。

次に本体に当たり判定を追加します。
boundingObjectにBoxを追加し、先ほどのgeometryのBoxと同じサイズにします。
physicsにPhysicsを追加します。

endPointのchildrenにShapeを追加し、geometryのBoxにCylinderを追加します。
位置と大きさを調整し、タイヤの位置に来るようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/7088f951-a5eb-ed3c-817d-9b57288b49a8.png)
また、追加したCylinderにもboundingObjectとPhysicsを追加します。

そしてこれを3つ複製し、バランスよく取り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2757127/124b6dba-9ddf-8708-3dbc-74ff5e2da093.png)

以上で簡易的な四輪ロボットモデルが作成出来ました。これをコントローラを利用することで制御して様々なシミュレーションを行うことが可能です。
フーリエ解析と画像処理

# 1.　はじめに
これは「imtakalab Advent Calendar 2024」の15日目の記事です。

https://adventar.org/calendars/10354

# 2.　著者について
* 私立理系大学の学部4年生
* 基礎数学勉強会（微分積分学）担当者
* とうとう「卒論」が迫ってきて**かなり追い詰められている**💦

# 3.　対象読者
* 研究室のメンバー
* 画像処理に興味を持っている方

# 4.　背景
私たちの生活の中で、画像や映像は欠かせない存在であり、付随して 、さまざまな場面で画像処理技術が活用されています。
僕自身、最近になって「Instagram」を使い始めた影響で、写真を撮影したり、それらを加工する機会が増えてきました（笑）
本記事では、フーリエ解析がどのように画像処理に応用されているのかをわかりやすく解説します。身近な画像加工技術を通じて、数学の持つ応用力と可能性に興味を持って貰えると嬉しいです！

# 5. フーリエ解析とは？
フーリエ解析とは、「フーリエ級数展開」や「フーリエ変換」などの数学的なテクニックを駆使して、「複雑な波」を「単純な波の足し合わせ」で表すことで、さまざまな波や信号を解析する手法のことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650322/f2ece00f-25e4-6287-3c4d-2138f022c7e1.png)

$$
f(x) = (\frac{\pi}{4}) \lbrace \sin x + \frac{1}{3}\sin{3x} + \frac{1}{5}\sin{5x} + \cdots + \frac{1}{2m-1} \sin(2m-1)x \rbrace
$$
上の式で、足し合わせる `sin` 関数（単純な波）の個数を徐々に増やしていくと、波の形が「方形波」と呼ばれる四角い波（複雑な波）に近づいていきます。
そして、「複雑な波」は「ある関数のグラフ」として見做せ、これをフーリエ級数の形（`sin`関数と`cos`関数の無限の足し合わせ）で表すことが可能です。
ここで重要なことは、適切なフーリエ係数を設定することであり、この値を求めるには「三角関数の直交性」が関わってくる。そして、ここでは**積分計算**が必要になっているが、そこまでの解説は本記事では行いません。

# 6. フーリエ解析と画像処理 
これまでは「1次元の波」の例として音声信号を扱いましたが、画像は2次元のデータであるため、**2次元フーリエ変換**を利用します。2次元フーリエ変換を使うと、画像の「周波数成分」を抽出し、さまざまな画像処理が可能になります。

#### **1. 周波数成分とは？**
画像の周波数成分は、以下のように解釈できます：
- **低周波成分**: 全体の輪郭や背景など、ゆるやかな変化を含む情報
- **高周波成分**: エッジやディテールなど、急激な変化を含む情報

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3650322/dff379b8-ee5f-db83-de3c-40704c6f6d9e.png)

たとえば、写真の中で滑らかなグラデーションは低周波成分に、シャープな輪郭や細かな模様は高周波成分に該当します。

---

#### **2. フーリエ変換を使った画像処理の例**
フーリエ解析を利用すると、画像データに対して以下のような処理を行うことができます：

1. **ぼかし処理（ローパスフィルタ）**  
   高周波成分を除去することで、画像をぼかします。これにより、ディテールを隠して全体を滑らかにすることが可能です。モザイクやぼかし処理の基礎にもなっています。

2. **シャープ化（ハイパスフィルタ）**  
   低周波成分を抑え、高周波成分を強調することで、画像の輪郭や細部をシャープにできます。

3. **ノイズ除去**  
   ノイズは通常、高周波成分として現れます。適切な周波数フィルタをかけることで、画像のクオリティを向上させることができます。

下記のリンクでは、実際のプログラムがあります。

https://vigne-cla.com/25-1/

# 7. おわりに
いかがでしたでしょうか？  
フーリエ解析は、単なる数学的なテクニックにとどまらず、画像処理や信号処理など、私たちの生活に深く関わる技術を支えています。
ぜひ、次に写真を加工したり、画像を扱ったりする際には、その裏に隠された数学の力を思い出してみてください。
拙い文章ですが、読んでくださり、ありがとうございました😁

# 8. 参考文献
* [フーリエ変換](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B)
* [2章 画像処理の基本手法 ](https://www.ieice-hbkb.org/files/02/02gun_01hen_02.pdf)
* [画像のフーリエ変換で遊んでみた（Pythonコードあり）](https://vigne-cla.com/25-1/)
Macbook air(2024)買った

## MacBook Air届いたぞぉ！！ ##
皆さんは、ボーナスを何に使ったでしょうか。
私は、「本気を出すために」MacBook airを買いました！

カッコいい、、テンション上がる。
![22EEA3A2-9833-466A-8D68-54D69D305F18_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906022/0047b068-7674-ccf2-e37a-28374dd3bf8a.jpeg)

いつもは１３インチとか小さめのノートパソコンを買っていたのですが、
今回は大きめの１５インチを買ってみました！
でかいとやっぱり視認性が上がるので良いですねぇ
![IMG_8024.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906022/4d946291-bf63-c1f6-749c-9eaaabc48e8c.jpeg)

ちょっとした不満を。。。
パソコンを開ける時、ちょうど上のところが溝みたいになっているため、そこから開けるのですが、
指が奥まで入ってしまう時があって、その時に指紋がつく。。。
開け方ミスっているんですかね？
![IMG_8025.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3906022/a8424c20-b94f-6146-0840-1b507ad78813.jpeg)
HTML: script要素やlink要素の参照先をblob:fileに指定すると…

何が起こるかと言うと、しっかりちゃっかりうっかり`blob:file///…`などというURL指定がまかり通るのであります。勿論img要素等にも適用されやがります。
```html
<iframe id=a></iframe>
<iframe id=b></iframe>
<script>{
const url=(a,b)=>URL.createObjectURL(new Blob([a],{type:b})),
	js=url("console.log(new Date)"),
	css=url("a{color:red}"),
	img=url(new Uint8Array([71,73,70,56,55,97,38,0,14,0,240,1,0,252,206,85,51,102,153,44,0,0,0,0,38,0,14,0,0,2,71,140,143,169,203,237,15,129,156,212,208,11,44,158,40,47,239,41,32,19,6,101,103,153,151,153,150,153,75,182,235,200,214,240,215,162,180,122,220,98,222,179,245,66,190,196,8,70,75,234,102,178,202,81,135,194,213,126,83,99,103,35,209,96,181,27,136,247,11,14,51,10,0,59])),
	src=url("<a href=javascript:alert(1)>text</a>","text/html"),
	html='<script src='+js+'><\/script><link rel=stylesheet href='+css+'><a>text</a> <img src='+img+'> <input type=image src='+img+'>';
b.src=src;
document.write(a.srcdoc=html)
}</script>
```
`iframe`のsrc属性に`blob:file`的なものを指定すると、HTMLが反映されたりされなかったりbrowser依存です(`Blob`の第2引数に`{type:"text/html"}`を指定すると反映されるっぽいです)。
当然ながらsrcdoc属性の場合はURLが表示されるだけです。上記例ではhtmlを直書きして対応。
ちなみに`Worker`の引数に対しても有効。拒否するbrowserもあるかもしれませんが…
```js
new Worker(URL.createObjectURL(new Blob(["console.log(1)"])))
```
## ふーん、だから何?
そんな事私の知った事ではありませんが、面白い事ができるはずです。例えばchm fileもどきを作るとか?
勉強を「楽しみ」に変えて中毒になれば毎日続くよねと Duolingo を続けて思っている話

今年を振り返る「なんかかく」アドベントカレンダー 15 日目です。IT エンジニア、英語は出来てしかるべき...ということで英語の話題をいくつか書きたかった。科学的な学習法については [「科学的根拠に基づく最高の勉強法」を読んで、資格試験の勉強法を考えた #AZ-400 - Qiita](https://qiita.com/e99h2121/items/68470900a6bf79c10347) にて書きましたが、そもそもそれをどう続けるか、有効なのはそれに対して中毒になることだと思っています。

## Duolingo はじめた

はじめた。「中毒」などというと言葉が強いと感じる方もいるかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/8110135e-b92d-10f0-313e-488199128a58.png)

↑ いまこのくらいやっています。ゲーミフィケーションというやつですね。

[Duolingoのいいところ｜佑　多](https://note.com/lovely_bear945/n/n84fec10a3c37)
[「学びはゲームで楽しく！」 教育分野でのゲーミフィケーションの革命 #教育 - Qiita](https://qiita.com/aoinakanishi/items/b37d52dea1da209035dd)
[Duolingoは語学学習のゲーミフィケーションの極みで超オススメだぞな件｜マダオ　習慣化と読書とObsidianと瞑想とか](https://note.com/madao_remodeling/n/ne25a39035a9c)

ピクミン ブルーム の良さとも似ています。
[エンジニアはどこまで健康になればよいのか - 朝ランと個人的生産性への考察 #習慣 - Qiita](https://qiita.com/e99h2121/items/a279f8fb1fbe722aa31f)


 
## Duolingo のよいところ

多くの人がやっていること、だと思います。

https://x.com/parfaitthestudy/status/1864084643294880074
 
- 続けること
- 楽しむこと

にはいくつかコツがいると思いますがその要素をうまく拾ってサービスを作っているという様子が良く分かります。

というのもたとえば時間をどうやってねん出するかを考えたときに、逆に、見なくても良いのにスキマ時間に見てしまう SNS ってなんでかなと考えると。

SNS って、「なんとなく見てしまう」ものなわけで、それが積み重なって結構時間を消費しているわけで、だったら逆にその「なんとなく見てしまう」作用を利用してついつい勉強してしまう仕組みに応用できれば最高じゃないですか。

それをやろうとしているのが DuoLingo だと思うわけで、もっと Udemy とか他の学習も含めてついつい勉強してしまう仕組みを模索したいと考えています。引き続き...

せめて、Udemy をやる際にも前のスコアより良くなろうとか、自分の前回値を上回ろうとか考えると良いんだろうな。


[Storage Account の Applied Skills とか AZ-204 の更新とかの話 #AppliedSkills - Qiita](https://qiita.com/e99h2121/items/e42a3244ce7c4ab88994)
[「科学的根拠に基づく最高の勉強法」を読んで、資格試験の勉強法を考えた #AZ-400 - Qiita](https://qiita.com/e99h2121/items/68470900a6bf79c10347)


以上です～
PlaywrightのextraHTTPHeaders機能について

# extraHTTPHeaders機能とは

PlaywrghtにはextraHTTPHeaders機能というものがあります。これは、test内でAPIリクエストを行う際に、自動的に認証ヘッダーを添えてくれるものです。

例えば、

```tsx
  const deleteArticleResponse = await request.delete(`https://conduit-api.bondaracademy.com/api/articles/${forDaleteArticleSlag}`, {
    headers: {
      authorization: `Token ${accessToken}`,
    },
  });
```

としていたものが、

```tsx
  const deleteArticleResponse = await request.delete(`https://conduit-api.bondaracademy.com/api/articles/${forDaleteArticleSlag}`);
```

だけで済むようになります。

# 導入手順

## 1 .auth/user.jsonの作成

アクセストークンを保存するための.auth/user.jsonを作成します。

以下のようなものです。

```json
{
  "cookies": [],
  "origins": [
    {
      "origin": "https://conduit.bondaracademy.com",
      "localStorage": [
        {
          "name": "jwtToken",
          "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxNDE4Mn0sImlhdCI6MTczNDIwOTU1OCwiZXhwIjoxNzM5MzkzNTU4fQ.kJ_lo1xqpLI7fTVWscziBs2Z5ChbdJe1yjUMNfC04HM"
        }
      ]
    }
  ]
}
```

## 2 アクセストークンの取得

auth.spec.tsでログイン処理を行い、アクセストークンを取得します。

ログイン処理はUI操作によるものでも、API操作によるものでも、どちらでも構いません。

今回は、test処理時間の短縮の観点も考慮し、API操作によるものを行なっています。

```tsx
import { test as setup } from '@playwright/test';
import user from '../.auth/user.json';
import fs from 'fs';

const authFile = '.auth/user.json';

setup('authentication', async ({ page, request }) => {
  const response = await request.post('https://conduit-api.bondaracademy.com/api/users/login', {
    data: {
      user: {
        email: 'test@test.com',
        password: 'test',
      },
    },
  });
  const responseBody = await response.json();
  const accessToken = responseBody.user.token;

  user.origins[0].localStorage[0].value = accessToken;
  fs.writeFileSync(authFile, JSON.stringify(user));

  process.env['ACCESS_TOKEN'] = accessToken;
});
```

## 3 process.env.ACCESS_TOKENの設定

auth.spec.tsで以下のようにprocess.env['ACCESS_TOKEN']を設定します。

```jsx
  process.env['ACCESS_TOKEN'] = accessToken;
```

## 4 Playwright.config.tsを設定する。

以下のように、

    extraHTTPHeaders: {
      Authorization: `Token ${process.env.ACCESS_TOKEN}`,
    },

を追記します。
地形を技術で可視化・定量化した地名研究の可能性

近年のレーザー計測技術の進歩により、超高精度な地形データの取得が可能になりました。
さらに、これらのデータがDEM（Digital Elevation Model）としてオープンに利用できることも多くなってきました。
地形を感覚的ではなく、可視化や定量的解析で理解することが容易になってきています。
特に可視化では、赤色立体地図のような新しい可視化技術の発展により、地形の微細な特徴がより明確に表現できるようになりました。

これらの技術革新の結果、山中に新たな山城や古墳、遺跡が発見される例が増加しています。
また、既知の遺跡についても、より詳細な構造が明らかになってきました。

* [最先端技術で南伊豆の山城２城が現る](https://www.windy-net.co.jp/media/case/a92)
南伊豆町で行われたレーザー測量調査によって、白水城跡と矢崎城跡が三次元画像化されました。
地形の詳細な特徴が明らかになり、歴史的な価値が再評価されました。
* [未知の遺跡はAIで発掘…3次元地形データと組み合わせ、古墳や寺院跡35か所発見](https://www.yomiuri.co.jp/culture/20231112-OYT1T50096/)
奈良文化財研究所では、AIと航空レーザー測量を組み合わせ、未知の遺跡を発見する技術を開発しました。
たつの市揖西町では直径15メートルの円墳が発見されるなど、35か所の古墳や寺院跡が新たに確認されました。

## 地名研究への応用

詳細地形データの活用は遺跡発見や構造理解だけでなく、地名の由来を地形から可視化・定量化する可能性も開いていると筆者は感じています。
その手始めとして、筆者は群馬県邑楽館林地域の「シベ」と発音する地名に注目し、DEMから生成した微細地形の可視化と現地調査を通じ、「シベ」地名の由来に関する先行研究の仮説を検証しました。

* [『邑楽館林での「シベ」地形調査と考察』](https://drive.google.com/file/d/1jTWAuQlm_VbzmEVnYS-uDd7GgmMV6Vzs/view?usp=sharing) - [群馬歴史民俗 第44号に掲載](https://cir.nii.ac.jp/crid/1520014265833209984)

従来の研究では、「シベ」はくぼんだ地形を示す地名とされていましたが、具体的にどのような地形を指すのかが明確ではありませんでした。
従来の等高線が粗い紙の地形図では詳細な地形の把握が困難であったためでしょう。
しかし微細地形DEMを用いることで、「シベ」地名の場所と詳細地形を照合し、先行研究の仮説が成立しうることを可視化し、示すことができました。

## 新たな研究の可能性

このように新しいデータと技術を活用して、これまで感覚的だった地形と地名の関係を可視化・定量化して研究できる可能性が広がっています。
定量的研究の一例として、地形の形を特徴的なモデルに変換する手法も提案されています。

* [Classification of topography for ground vulnerability assessment of alluvial plains and mountains of Japan using 30 m DEM](https://progearthplanetsci.springeropen.com/articles/10.1186/s40645-020-00398-0)
* [地形量によって特徴づけられた地名の分類](https://chuo-u.repo.nii.ac.jp/records/15067)

今後、このような手法を導入した地名研究がさらに発展することで、地名に関する理解がさらに深まる可能性があります。
筆者も引き続きこの方向性での研究を進め、深めたいと考えています。
オブジェクト指向Cコンパイラ comelang version 10.1.0

-gcオプション廃止、integer, floatingクラス廃止。

comelang.hをincludeするだけでビルドできます。libcomelang.aを使わなくなりました。
main関数が含まれるソースにライブラリの本体が書き込まれます。
UNIXでないマイコンで-sでの出力ソースを使いやすくなりました。
【脱AE】番外編その１ - 「大学入試」

# はじめに

:::note info
この記事は、大学入試の面接を直後に控える私が都度リアルタイムに書き込みをしています。
:::

# 朝

現在午前４時４０分、、、
朝だよ、、、

６時間後には入試が始まり、そこから２時間経った頃には、全てが終わっているわけです。
ホントに実感が湧きません。

自己PRや志望理由でさえ、まだ完璧に復唱できる状態ではないです。
私は、生きて帰れるのでしょうか、、、？

# んなこといってられっかよ！！！

「◯す気でいけ」なんて言葉をどっかで見た覚えがあります。
流石に面接官を◯す気にはなれませんが、
絶対にそっちいってやるからなという強い意志を
覇気が伝わるほど
全力でぶつけて参ります。

# 直前

残すところ１時間となりました。
環境の準備は万端ですが、依然としてうまく受け答えできるのか不安でしかたありません。

# 終わり

ついに終わりました。
やっぱりやれば出来るじゃん。なんて
自己PR暗唱も意外とイケましたし、やれるとこはやり尽くしたって感じでした。
改めて１時間前の自分、おつかれ
ROS2のbagファイルから指定したトピックをまとめてcsvへ変換

## 概要
ROS 2を用いたシミュレーションや実験のbagデータから，論文・レポート等向けにMATLAB等を用いた綺麗な描画を行うためには，csv等の形式へデータを変換できると便利です．

コマンド`ros2 topic echo /topic --csv > output.csv`で取得することも出来ますが，複数のトピックを変換したい時などは少し不便です．

そこで，[rosbags](https://gitlab.com/ternaris/rosbags)を用いて実装した，事前に指定しておいた複数のトピックデータをまとめてcsvファイルへ変換するリポジトリを紹介します．
https://github.com/toshi67026/ros2bag2csv

### 特徴
- 複数のトピックデータを一括変換
- YAMLファイルによる変換対象管理
- トピックごとで個別の出力方法を実装可能（QuaternionはEuler角へ内部で変換してから出力したい等）

## 使用方法

基本的な使い方は以下の通りです．依存ライブラリのインストール方法など詳細はgithubを参照してください．
```bash
python3 ros2bag2csv.py [-t target_topic.yaml] {rosbag_file_dir}
```

### 変換対象のトピック設定の例
変換したいトピックは以下のようなYAMLファイルで指定します
```yaml
- /float
- /ns1/vel
- /ns2/array
```

### サポートされているメッセージタイプ
現在，サンプルとして以下のメッセージタイプが変換可能です．
- std_msgs
  - Bool
  - Float32
  - Float32MultiArray
- geometry_msgs
  - Point
  - Pose
  - PoseStamped
  - Quaternion
  - Twist
  - Vector3

カスタムメッセージを含む他のメッセージタイプは，個別に変換関数を実装することで追加可能です．MultiArrayのようなトピックは出力先がcsvのため，データの次元に制約があります．

## データの活用
変換したcsvデータは空白が多く含まれるスパースな形式であることに注意が必要ですが，MATLABなどの解析ソフトを使えば簡単に利用できます．リポジトリに`csv_visualize.m`というMATLABのサンプルスクリプトを用意しています．

参考
- [rosbag_to_csv](https://github.com/AtsushiSakai/rosbag_to_csv)
- [ros2のbagファイルをcsvにする
](https://zenn.dev/xen_nippon/articles/0ae35719f6cc44)
- [rosbags](https://gitlab.com/ternaris/rosbags)
GraphAIを使ってみた

# GraphAI入門ガイド

https://github.com/receptron/graphai-demo-web/

## 開発環境のセットアップ

GraphAIはローカル環境またはDockerコンテナで実行できます。以下では両方の方法を説明します。

### 1. ローカル環境での実行

```bash
npm i -g @receptron/graphai_cli
```

APIキーは`.env`ファイルまたは環境変数で設定:
```bash
# .envファイルの場合
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=... # Claudeを使用する場合

# または環境変数として
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=... # Claudeを使用する場合
```

### 2. Docker環境での実行

以下のDockerfileを使用してコンテナ環境を構築できます：

```dockerfile
# Use Node.js slim image
FROM node:20-slim

# Create app directory
WORKDIR /app

# Install essential packages and clean up
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    git \
    && rm -rf /var/lib/apt/lists/*

# Install GraphAI CLI
RUN npm install -g @receptron/graphai_cli

COPY ./ ./

# Set environment variable
ENV NODE_ENV=production
```

VS Code + DevContainerを使用することで、このDockerfile設定による開発環境を直接利用できます。

## Hello Worldサンプル

```yaml
version: 0.5
nodes:
  llm:
    agent: openAIAgent
    params:
      model: gpt-4
    inputs:
      prompt: あなたは誰ですか？簡単な挨拶をしてください。
  output:
    agent: copyAgent
    params:
      namedKey: text
    console:
      after: true
    inputs:
      text: :llm.text
```

実行方法:
```bash
graphai hello.yaml
```

出力例:
```
こんにちは、私はOpenAIの人工知能アシスタントです。あなたの質問に答えたり、情報を提供したりすることでお手伝いします。どのようなお手伝いが必要ですか？
{}
```

## 基本概念

GraphAIには2種類のノードがあります：

1. Computed Node
   - エージェントと関連付けられた実行ノード
   - 特定の計算や処理を実行

2. Static Node
   - 値を保持するノード
   - プログラミング言語の変数に相当

## 主要機能

GraphAIは以下の制御フロー機能を提供します：

- Loop: 繰り返し処理
- Map: 並列処理
- If/Unless: 条件分岐
- Nesting: グラフのネスト化

## 開発原則

1. コアをシンプルに保つ（Node/GraphAIクラス）
2. エージェントによる機能拡張
3. 効果的なテストの維持

詳細な使用例やより高度な機能については、[公式サンプル集](https://github.com/receptron/graphai_samples)を参照してください。


## 実際の実装集
https://qiita.com/yukiaprogramming/items/ea6d73e7017bbced9f9c

https://qiita.com/yukiaprogramming/items/14481231c709b20b168d
石造文化財の所在マップに使えるフリーアイコン: 長慶再紹介

アドベントカレンダーに書きたいネタはたくさんあるのですが、
しかし投稿が遅れているので追いつくためにも軽いネタも。

石造物を中心とした文化財の所在をマッピングできる、イラストアイコンセット「長慶」を、商用利用もOKなフリーで公開しています。
ぜひ使ってみてください。

* [石造文化財アイコン 長慶(Chokei)](https://github.com/code4history/Chokei)
* [歴史と地図に特化したIT開発を手がけているCode for Historyが、石造文化財をアイコンとして表示できる「長慶（Chokei）」を11月11日に公開](https://www.value-press.com/pressrelease/308926)
* [石造文化財のマップ用アイコン「長慶（Chokei）」](https://www.tnkj.com/pin_icon/)

しかし長慶も作成してメンテナンスしないままだったので、今確かめると、2年前にキリスト教研究者の[由愛](https://x.com/tenjounoao_yume)さんに教えていただいて、 **『キリシタン灯篭というようなものはなくて織部灯篭でしかない』** と認識を改めたにもかかわらず、長慶ではキリシタン灯篭のままになっていました。
そこで、採りあげたついでに、今回織部灯篭に改めました。

| 画像  | 間違い  | 正解 |
|---------|---------|---------|
| ![織部灯篭](https://raw.githubusercontent.com/code4history/Chokei/main/png/oribe_lantern.png)  | ~~キリシタン灯篭~~  | 織部灯篭  |

また、そろそろ新しいアイコンも増やしたいと思っています。
今のところ、候補に考えているのは、

* 竜神
* 水神
* 牛頭天王
* 道路元標
* 月待に漢数字を入れて、XX夜待を表す
* 蔵
* 民家（茅葺）
* 民家（町屋）
* 古墳

などです。
欲しいアイコンがあれば、ぜひ[Issue](https://github.com/code4history/Chokei/issues)に要望を寄せてください。
Wayland/GNOME学習メモ

### はじめに
Ubuntu24にするにあたって、キーのCapsLockを左Ctrlに変更したかった。Ubuntu初心者だったので、自身がWayland+GNOMEで利用していることもわかっていなかった。
特段、バージョンを指定しないでChatGPTに聞くと、どうしてもX11を前提として答えてきたので、詰まってしまった。
X11,Waylandの区別がちゃんとつくようになりたかったので、学習したときのメモを図で残す。また、GNOMEについてもあわせて勉強する必要があったので、メモを図で残す。

### URL
https://wayland.freedesktop.org/architecture.html

### XとWaylandのアーキテクチャの違い
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149425/a298afad-141c-dec5-c315-63a8e1e0964e.png)

### GNOMEデスクトップの構成要素
依存の順番は自分のイメージで作成。誤っているかもしれないが、目的としてはざっくり用語と役割を覚える際に、位置関係を把握するためにジャンル分けするために作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149425/22992a08-a199-774d-d096-75fd3ed0c840.png)

### おわりに
結果的に、`gsettings set org.gnome.desktop.input-sources xkb-options "['ctrl:nocaps']"` で変更できて、快適になった。

### 後日談
その後、fnキー+hjklでカーソルを割り当てたいと思った。そして、fnキーは(ctrlやaltなどとも異なり)押してもソフトウェア的に認識されない(fn+なにかキーを押したタイミングでようやくfnキーと押されたことがハードウェア的に伝わる)ことがわかった。つまり、fnキーの位置のキーは、多分変えられないということ(https://askubuntu.com/a/818421)。
fnキー以外のキーをfnキーのように振る舞わせること自体はソフトウェア的にできそうだった。また、udevなどでも、もう少し踏み込んだことができそうだった(https://bearmini.hatenablog.com/entry/2023/12/03/134330)が、どうもハードウェアをソフトウェアで頑張ってハックしているようだった。以前から気になっていたHHKBなら、ハードウェアレベルのキーマップをHHKBキーボード本体に記憶させる形で変更できるらしいので、HHKBにすることにした。
あと、そもそもgsettingsだと、GNOMEデスクトップ前提になりそう。xremapは、名前に反してwaylandでも利用できるとドキュメントにあるので、可能なら今後はGNOMEでなくxremapを利用してみたい。
SSH 生成された鍵

## 生成された鍵の確認方法
$ ls -l <生成された鍵のパス>
$ less <生成された鍵のパス>

※SSH 鍵は、デフォルトでは各ユーザーの ~/.ssh ディレクトリに置かれています。

## 秘密鍵のパーミッション
- 秘密鍵ファイルのアクセス権を示す設定
- 秘密鍵ファイルは他人によるアクセスを制限するために、パーミッションを設定する必要がある

chmod 600 が推奨される理由は、秘密鍵のセキュリティを守るための最適なアクセス制御を提供するためです。これを理解するために、UNIX/Linux のファイルパーミッションを簡単に説明します。

## パーミッション

### 基本的な仕組み
- ①誰に対して、アクセス権限を付与するのか②どのようなアクセス権限を付与するのか？を設定する。（9個の権限設定がある）

### 誰に対してのアクセス権限を設定するのか？
①Owner：自分
②グループメンバー：同じサーバーを利用するユーザー
③その他の人：第三者

### 与えることのできるアクセス権限
- 読み取り権限：ファイル、もしくはディレクトリを読み取りができる
- 書き込み権限：ファイル、もしくはディレクトリに書き込める
- 実行権限：ファイル、もしくはディレクトリを実行できる

### ファイルパーミッションの仕組み
UNIX/Linux システムでは、ファイルに対して次のようなパーミッションを設定できる。

- 読み取り（r）: ファイルを読むことができる
    - 数字：4
- 書き込み（w）: ファイルを変更することができる
    - 数字：2
- 実行（x）: ファイルを実行することができる
    - 数字：1
- 何もできない（-）：何もできない
    - 数字：0
    
これらのパーミッションは、所有者（ユーザー）、グループ、その他のユーザーの3つのカテゴリに対して設定できます。

## 9個の権限設定方法
- パーミッションは、3つの立場ごとに、3つの権限を組み合わせることで設定を行う。(権限設定を行うのは次の9個)

### オーナー権限
1.「オーナー（Owner）」の「読み取り権限」
2.「オーナー（Owner）」の「書き込み権限」
3.「オーナー（Owner）」の「実行権限」

### グループメンバー権限
4.「グループメンバー（Group）」の「読み取り権限」
5.「グループメンバー（Group）」の「書き込み権限」
6.「グループメンバー（Group）」の「実行権限」

### Other権限
7.「その他の人（Other）」の「読み取り権限」
8.「その他の人（Other）」の「書き込み権限」
9.「その他の人（Other）」の「実行権限」

この9個の権限を組み合わせて、パーミッション設定を行っていきます。

### 具体的な権限設定方法
- 644（rw-r-r-）
  - オーナー：実行権限以外あり
  - グループ：読み取りのみ
  - その他：読み取りのみ

### chmod 600 の意味
chmod コマンドを使ってファイルのパーミッションを設定する際、600 は次のように解釈される

- 最初の 6 は所有者（ユーザー）に対するパーミッションを示します。
  - 6 は、読み取り（r） と 書き込み（w） の両方を許可することを意味します（4 = 読み取り, 2 = 書き込み）。
  - つまり、所有者はファイルを読み書きできる。
- 次の 0 は、グループに対するパーミッションを示します。
  - 0 は、読み取りも書き込みも実行も許可しないことを意味します。
  - グループはファイルにアクセスできない。
- 最後の 0 は、その他のユーザーに対するパーミッションを示します。
  - これも 0 なので、その他のユーザーはファイルにアクセスできません。
  - なぜ 600 なのか

- 秘密鍵は非常に機密性が高い情報です。秘密鍵が第三者に渡ると、セキュリティが破られる可能性があるため、所有者だけに完全なアクセス権を与え、その他のユーザー（グループや他のユーザー）には一切アクセスを許可しないことが重要です。

chmod 600 により、次のことが保証されます：

- 所有者は秘密鍵を読み書きできる（鍵の管理や更新が可能）。
- グループやその他のユーザーはアクセスできない（秘密鍵が外部に漏れたり、悪用されたりするリスクを防ぐ）。
- もしパーミッションが 644 や 755 などであれば、グループやその他のユーザーにも読み取りや実行権限が与えられ、秘密鍵が外部に漏れるリスクが高まります。したがって、最低限のアクセス権限を設定することがセキュリティを強化するために非常に重要です。

### 結論
- chmod 600 は、秘密鍵が所有者のみによってアクセス可能であり、その他のユーザーには一切アクセスできない設定です。これにより、秘密鍵の漏洩や不正アクセスのリスクを最小限に抑えることができます。

## 参考になった記事
SSHは公開鍵・秘密鍵を使って楽にする by ラクスさんテックブログ
https://tech-blog.rakus.co.jp/entry/20210727/ssh

Permission（パーミッション）とは？基本的な仕組みや注意点
https://www.profuture.co.jp/mk/column/what-is-permission
[CSS]文字列が自動でリンクになる問題

ポートフォリオ作成中に、スマホからサイトを見ると文字列"2024/04 - 2024/6"が自動的に電話番号リンクになっちゃう問題に遭遇。。。。特にSafariだとこの問題起こるみたいです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784072/16757061-4497-c300-b6cc-d772c578b351.png" width=50%>





HTMLファイルの`<head>`


内に以下を追加すると解決。
```html:html
<meta name="format-detection" content="telephone=no">
```
`content="telephone=no"` で電話番号としてリンク化されるのを無効化できる。

無事解決！🥳
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784072/4ba1091a-1f2e-903c-8b86-920a8e0e134b.png" width=50%>
外部からSSH接続できる理想環境を作りたい！！(Raspberry Pi)

# 雑談
最近、色々あって家にいないことが多くなりました。
**ということで、Raspberry Piを外部から接続したいですね。**

はい、やりましょう。そして、今回も備忘録的なものです。

# 内容
- 自分の鍵ペアができるようにする
- SSHを鍵認証でログインできるようにする
- 外部にSSHポートを開放する


# キーファイルの作成
まずローカルでキーファイルを置くディレクトリを作ります。

```zsh
$ cd ~/.ssh/
$ ssh-keygen -t rsa
```
（今回自分は.ssh 直下に秘密鍵を置いておいてしまいましたが、ディレクトリ分けしておいて、後々増やす時に、ややこしくないようにするべきだったなぁと）

ま、コピーすればいいか。

これで`.ssh`配下に秘密鍵のid_rsaと、公開鍵のid_rsa.pubが作成されます。
そして今作成したキーペアの内、公開鍵のid_rsa.pubを Raspberry Pi に送ります。

```zsh
$ scp ./id_rsa.pub pi@raspberrypi.local:~
```
`pi@raspberrypi.local`の部分は自分用に変更してやってください。
パスワードを求められたら、入力してください。

これで、作成した公開鍵がRaspberry Piにコピーされました。

# Raspberry Pi側のsshの設定

ssh（Password 認証）で Raspberry Pi に接続し、次に ssh の鍵を管理する.sshディレクトリを作成します。
```zsh
$ ssh pi@Raspberrypi.local
$ mkdir ~/.ssh
$ chmod 700 .ssh
$ cd .ssh
$ cat ../id_rsa.pub >> authorized_keys
$ chmod 600 authorized_keys
$ rm -fv ../id_rsa.pub
```
#### 簡単なコマンドの説明
- **ssh pi@Raspberrypi.local**
 Raspberry PiにSSH (Secure Shell) を使用して、Raspberry Pi にリモート接続します。
- **mkdir ~/.ssh**
ホームディレクトリ (~) に .ssh ディレクトリを作成します。
- **chmod 700 .ssh**
.ssh ディレクトリのアクセス権を**所有者**のみアクセス可能に変更します。
- **cd .ssh**
.sshディレクトリに移動-
- **cat ../id_rsa.pub >> authorized_keys**
../id_rsa.pub ファイル（公開鍵）を読み取り、その内容を .ssh/authorized_keys ファイルに追記します。

    authorized_keys ファイルに公開鍵を登録することで、その鍵を持つクライアント（あなたの PC）が Raspberry Pi にパスワードなしで SSH 接続できるようになります。
- **chmod 600 authorized_keys**
authorized_keys の権限を所有者のみ読み書き可能に制限し、セキュリティを強化します。
- **rm -fv ../id_rsa.pub**
id_rsa.pub ファイル（公開鍵）を削除します。


次に`/etc/ssh/sshd_config`の中を編集します。
```zsh
$ sudo nano /etc/ssh/sshd_config
```
以下の３つの部分を変更または、追記しました。
```
PubkeyAuthentication yes
AuthorizedKeysFile     .ssh/authorized_keys
HostKeyAlgorithms=+ssh-rsa
PubkeyAcceptedAlgorithms=+ssh-rsa
```
編集ができて保存したら、テストしてみましょう
```
$ which sshd
$ /usr/sbin/sshd -t
```

<details>
<summary>sshd: no hostkeys available -- exiting.</summary>

$ sudo /usr/sbin/sshd -t

sudoつけたら行けた。
</details>

一応`exit`で、再起動しました。
```zsh
$ sudo ifconfig en0 down
$ sudo route flush
$ sudo ifconfig en0 up
```

完了したら自分の場合は、cloudflareにレコードを追加したので以下の文で接続できました。
```
$ ssh ユーザー名@cloudflareに登録したドメイン -p ポート番号
```

でけた🤩
TIMEREFINEの全貌：ビデオ時間的グラウンディングを再定義する革新技術

# TIMEREFINE: ビデオ時間的グラウンディングの精度を革新する新手法

今回は、最新の研究成果である「TIMEREFINE: Temporal Grounding with Time Refining Video LLM」を詳しくご紹介します。この研究は、ビデオ時間的グラウンディング（VTG）という複雑なタスクに対して、画期的な解決策を提案しています。本記事では、その背景、手法、実験結果、そして将来の展望について徹底的に掘り下げていきます。

---

## 論文情報
- **タイトル**: TIMEREFINE: Temporal Grounding with Time Refining Video LLM
- **リンク**: [arXiv:2412.09601v1](https://arxiv.org/abs/2412.09601)
- **発表日**: 2024年12月12日
- **著者**: Xizi Wang, Feng Cheng, Ziyang Wang, Huiyu Wang, Md Mohaiminul Islam, Lorenzo Torresani, Mohit Bansal, Gedas Bertasius, David Crandall
- **DOI**: N/A

---

## 背景と目的

### ビデオ時間的グラウンディング（VTG）とは？
VTGは、自然言語プロンプトに基づいてビデオ内の関連する時間的境界を特定するタスクです。このタスクは、異常検知、スポーツ解析、監視システム、教育分野など、多岐にわたる分野で重要な役割を果たします。

例として、「人がスープをかき混ぜている部分」を特定するシナリオを考えてみてください。システムは映像の開始時刻と終了時刻を自動的に特定する必要があります。このような能力は、特定の行動やイベントを識別する際に非常に重要です。

---

### 現在の課題
従来のVTG手法には以下のような課題があります：
1. **精度の限界**: 現在の手法は、時間的境界の特定において誤差が大きく、特に長時間のビデオでの適用に課題があります。
2. **計算コスト**: 境界を直接予測するアプローチでは、高い計算資源が必要です。
3. **汎用性の不足**: モデルが特定のデータセットや条件に強く依存しており、汎用的な適用が難しい。

---

## TIMEREFINEの概要

TIMEREFINEは、これらの課題を克服するために以下の2つの革新を導入しました。

### 1. 段階的な時間的洗練
TIMEREFINEは、粗い予測を初期値として設定し、それを反復的に修正することで予測精度を向上させます。このアプローチにより、従来の「直接予測」手法の限界を克服しました。

#### 数式による詳細
各ステップ $k$ における予測境界は以下のように更新されます：

$$
s_{k+1} = s_k + o^s_k, \quad e_{k+1} = e_k + o^e_k
$$

ここで、$s$ は開始時刻、$e$ は終了時刻、$o$ はそれぞれのオフセットであり、このプロセスを複数回繰り返すことで最適な境界を取得します。

---

### 2. 補助的な予測ヘッドの導入
TIMEREFINEは、クロスエントロピー損失（CE損失）に加えてL1損失を補助的に導入しました。これにより、モデルが境界に近い予測を優先的に学習する能力が強化されます。

#### 損失関数の詳細
TIMEREFINEで使用される総合損失関数は以下の通りです：

$$
L = \frac{1}{m} \sum_{i=1}^m \text{cross\_entropy}(a_i, \hat{a}_i) + \lambda \| \hat{S} - S \|_1
$$

ここで、$\hat{S}$ はモデルの予測した境界、$S$ は正解ラベル、$\lambda$ はL1損失の重みを調整するパラメータです。

---

## 実験の概要と結果

### データセット
1. **ActivityNet Captions**: 約20,000本のビデオが含まれる大規模データセット。
2. **Charades-STA**: 室内活動に特化したデータセットで、イベントの時間的境界を記録。

### 評価メトリクス
- **平均IoU（mIoU）**: モデルが予測した境界と正解の一致度を測る指標。
- **Recall@IoU=0.3/0.5/0.7**: 各IoU閾値での再現率。

### 実験結果
| モデル            | mIoU (ActivityNet) | mIoU (Charades-STA) |
|-------------------|--------------------|---------------------|
| VTimeLLM          | 30.4               | 31.2                |
| TIMEREFINE         | 34.0 (+3.6%)       | 36.2 (+5.0%)        |

- **ActivityNet Captions**: Recall@0.7では5%以上の向上。
- **Charades-STA**: 長時間ビデオでも高い精度を維持。

---

## 議論と限界

### 提案手法の意義
TIMEREFINEは、従来の手法では困難だった以下の点での改善を実現しました：
1. 時間的境界の精度向上。
2. 他のビデオ関連タスク（例：質問応答）への適用可能性の拡大。

---

### 制約
1. **計算コスト**: 段階的な洗練手法の導入により、トレーニングコストが増加。
2. **長時間ビデオ**: 長時間ビデオにおける精度向上はまだ課題が残る。

---

## 将来の展望

1. **リアルタイム処理の実現**: 計算効率をさらに向上させ、監視やスポーツ解析での即時応用を目指す。
2. **新たなタスクへの応用**: マルチモーダルタスクや異常検知など、応用範囲を広げる。

---

この記事が、皆さんの研究や実務に役立つことを願っています。ご質問やフィードバックがあれば、ぜひコメント欄でお知らせください。
MeePet で QPython を動かす

## GitHub からインストーラを入手
Android の Python 実行環境である QPython を MeePet で動かすことにした。
インストーラは例によって APK を入手する必要がある。
幸い、 GitHub にも QPython のページがあり、 Release にパッケージが置いてある。
**（実はこの選択が良くなかったことに後で気づかされる）**

https://github.com/qpython-android/qpython

2024年11月現在、最新バージョンは 3.2.3 （2023年2月）のようだ。
![qpython_apk_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/262d176b-7109-3138-fe56-89c003334427.png)

## いきなり動かせるかと思ったら動かない
起動するとこのような画面が表示される。
![qpython_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/124654d4-9080-101d-a668-20b5d9b07875.png)

エディタを選択し、ありきたりの Hello, world を入力して…
![qpython_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/4ad4fe2b-1a6f-ea79-1494-946d80eb4740.png)
再生ボタンを押す。
保存するよう求められ、保存終了後にコンソールが開くが…動かない（！）
![qpython_2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/27fcfecc-6073-795a-ffe6-f629a392e84c.png)


## Python のインストールは別途必要
もう一度メニュー画面に戻り、試しに左にあるボタンを押してみたところ、おもむろにボタン上部のマークがうにょうにょ動いた後、コンソールのインストーラが走った。
![qpython_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/6adc3564-2f85-b7fe-46cb-3ac7b9b05037.png)
![qpython_3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/763c7cb5-ef86-d98f-c88d-8b1c55e62f78.png)


無事にインストールが完了し、 Hello, world も表示できて一安心。
![qpython_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/5098ed3c-6f67-d51a-24a4-73835ae0ddef.png)

ちなみに Python のバージョンは 3.11.0 であった。
![qpython_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/d91d309f-bf11-ea39-b64b-50004b7d8cec.png)

## Play ストア版だと自動で Python がインストールされる
GitHub 版はインストールを必要としたが、Play ストア版はどうか。試しにスマホへ入れてみた。
初回実行時にインストーラが走り、何の問題もなく スクリプト が動いた（QPythonのバージョンは 3.3.8 、Pythonのバージョンは 3.11.9 である）。
![qpython_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/7c88d9ec-7d8f-3b88-d853-009915339457.png) ![qpython_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/31039fa4-3a27-5b32-f737-17a0187dcfb3.png)


## APK の最新版は GitHub ページ下部にある Google ドライブからダウンロードできる（こちらの方がよい）
ここでもう一度 GitHub のページを眺めたところ…何と、ページの下の方に「最新のバージョンは Google drive にある 3.2.5」と書いてあるではないか。
![qpython_apk_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/67f45f4e-8629-5cd3-4028-378d521253bf.png)

改めて Google トライブ版をダウンロードして再インストール。
こちらのバージョンは初回起動時にインストーラが走り、何もせずとも Hello world が動いた。 Python のバージョンは Release 版と同じく 3.11.0 である。
![qpython_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/a00a8974-9ae4-7842-61b9-c65e1d72b42e.png)
![qpython_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/e0ac4993-f647-4166-3904-555b3eeab0f8.png)

長々と書いたわりに、 GitHub のページをよく読みましょうという結論になってしまった気もするが、よく見るとコンソールの実行画面が Release 版や Play ストア版と若干異なる（Google ドライブ版は2行、他の2つは1行）。
GitHub Release 版が必要となった時の参考のため記事化しておく。
ABC384Eを解いた【優先度付きキュー】


筆者はレート800前後の茶～緑コーダ

ABC384当日にACできなかったE問題を解いていく
    
https://atcoder.jp/contests/abc384/tasks/abc384_e


# 実装コード

優先度付きキューを使い、
隣り合うスライムの強さと場所を格納していく

最小値のスライムが吸収できるならそいつを取り込み、
隣り合う場所が増えるので、新たな近傍をキューにまた追加

吸収できなかったら終了

```python:main.py
import sys
import heapq
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)


class Minheapq(object):
    q = []
    def push(self, v):
        heapq.heappush(self.q, v)

    def pop(self):
        return heapq.heappop(self.q)

    def get(self):
        return self.q[0]

    def values(self):
        for _q in self.q:
            yield _q

dy = [-1, 0, 1, 0]
dx = [ 0, 1, 0, -1]

def out_of_bounds(y, x, h, w):
    return y < 0 or y >= h or x < 0 or x >= w


def main():
    H, W, X = rLI()
    P, Q = rLI1()
    A = [rLI() for _ in range(H)]
    q = Minheapq()
    q.push((float('inf'),(-1,-1)))
    q.push((0,(P,Q)))
    visited = set()
    visited.add((P,Q))
    p = A[P][Q]
    e = p/X
    while q.q:
        cp,cur = q.pop()
        y,x = cur
        if cp >= e:
            break
        p += cp
        e = p/X
        # err(cur,p,e)
        for i0,j0 in zip(dy,dx):
            i=y+i0
            j=x+j0
            if out_of_bounds(i,j,H,W):continue
            if (i,j) in visited:continue
            cp = A[i][j]
            visited.add((i,j))
            q.push((cp,(i,j)))
    print(p)
    
    
if __name__ == '__main__':
    main()

```

# まとめ

ABC384当日は優先度付きキューと普通のキューを２つ組み合わせてしまい
処理が冗長的だったので優先度付きキューのみで実装してみた

グリッドの近傍をスニペットに登録してから
だいぶ苦手意識が減ってきたが、考えをもうちょっとシンプルにしたい
ラジコン3分クッキング（ESP-NOWを用いた爆速通信構築）

# はじめに
本記事は、長野高専アドベントカレンダー2024 16日目の記事です。
https://qiita.com/advent-calendar/2024/nnct

この記事では、工嶺祭（学園祭）での出し物でつくったラジコンで、ESP-NOWという触れたことのない無線規格を使ったという話でもしようと思います。

# 自己紹介
普段はロボコン部で回路・制御などなどいろいろやってます。
昨年までの工嶺祭（学園祭）クラス企画では画像認識をやったりしてました。

# 経緯
ロボコンが一段落ついた（地区大会敗退）ため、クラス企画に力を入れることにしました。
今年は二人三脚ラジコンを作ろうという話になったので、その電装をやってみることにしました。
工嶺祭準備も大詰めというような時期に作り始めたので、即席でラジコンとコントローラーを組むことになりました。

こんな流れで爆速でラジコンを作ることになったので、その話を振り返ってみます。

# 構想
二人三脚＝レバーを二人で操作してラジコンを動かすというものなので、レバーとラジコン間の通信のやり方などを考えました。

ラジコン側はたまたまESP32S3というマイコンの乗ったロボット用基板の設計データがあったので流用して作りました。
構成としてはESP32S3+モータードライバー＋αとちょうどラジコンに適した基板だったので、そのまま仕組むことにしました。

コントローラー側はそのマイコンと遠隔通信することになるので、送信する手段の選定をしました。
ESP32S3のBluetoothは5.0でBluetoothSerialが使用できないので、ESPNOWというマイコン間無線通信ができる規格を使って実装することにしました。

# コントローラーとラジコンの構成
コントローラーはバネで戻るレバーを作り、その角度をArduinoで読んでM5Atomに送り、ESP-NOWでラジコンに転送するという形の実装としました。
(M5Atom⋯ESP32で動く、ボタンとかLEDとかがまとまったモジュール）

ラジコンはESP32S3というマイコンが載っていて、ESP-NOWに対応しているのでその受信データを使ってモーターを駆動する形にしました。

# 実装
ESP-NOWをArduino環境（espressif公式)で使う場合、esp_now.hをインクルードして、起動時に初期化・コールバック関数指定のみ行えば最低限動作させられます。
実際のプログラムは見せられる完成度ではないため一部抜粋して紹介します。

受信側は以下のように書いて、espnow::init関数をsetup関数などから呼び出せば最低限受信できます。実際は、受信したASCII文字列から数値を起こしてモーター出力を調整するようにしました。
```C++
//インクルード
#include "WiFi.h"
#include "esp_now.h"

//初期化処理
namespace espnow{
    void onDataRecv(const uint8_t *mac, const uint8_t *buf, int len)
        {
//受信後の処理
        }
    
    void init(){
        WiFi.mode(WIFI_STA);
        if (esp_now_init() != ESP_OK)
        {
            Serial.println("[error] espnow init fail");
            return;
        }
        esp_now_register_recv_cb(wifi::onDataRecv);
    }
};
```

送信側は、送信先の指定が必要なので手間が若干増えますが、こちらも簡単に実装できます。
今回は、サクッと作りたかったのでブロードキャスト機能を使って無差別に送受信するようにしました。
このサンプルの場合、send関数を適当に呼べば勝手にデータが飛んでいきます。

```C++
//追加部分
namespace espnow{
//
esp_now_peer_info_t peerInfo;
    
    void init(){
        WiFi.mode(WIFI_STA);
        if (esp_now_init() != ESP_OK)
        {
            Serial.println("[error]espnow init fail");
            return;
        }
        memset(&peerInfo.peer_addr,0xFF,6);
        peerInfo.channel=0;
        peerInfo.encrypt=0;
        if(esp_now_add_peer(&peerInfo)!=ESP_OK){
            Serial.println("[error]espnow peer fail");
        }
    }
    void send(uint8_t *buf,uint8_t len){
    esp_now_send(peerInfo.peer_addr,buf,len);
    }
};

```
これらのコードを加えて適当に取り決めを作ってデータを送受信すれば無線化ができます。

# ESP-NOWのまとめ
ESP-NOWはラフに無線通信をしたいときに使いやすいプロトコルです。
単純にシリアル通信を無線化しているような使い勝手なので、シリアル通信で有線接続していた部分の置き換えにちょうど良さそうです。
また、BluetoothやWifiと違ってペアリング処理が省けるのも楽な点です。

上記の実装では同じチャンネルで違う通信が行われていた際に問題が起きますが、自分が使った際には学園祭程度の規模で他に使っている人がいなかったので特に問題は置きませんでした。

もう少しまともに実装すればMACアドレスで絞り込み等を行えるので、大会のような信頼性を求める場面でなければかなり開発の手間を省けると思います。

# さいごに
この規格を使ったことで、ラジコンの無線化実装は数十分だけで済みました。
また、ペアリングなどの煩雑な作業がなく当日のメンテナンスなしに安定稼働させることができました。

先人の知恵に感謝しつつ、無線で動かすちょっとした工作にまた使ってみたいと思います。

以上、お読みいただきありがとうございました。
#1 Claudeでコードを一切書かずにゲームを作成する話

ゲーム会社でUIUXデザインを担当しているKazzynaoと申します。

最近、Claude MCPが面白そうだぞということで、プログラム知識の全くない自分がClaudeを使ってゲーム制作にチャレンジしてみた話です。

## Claudeが楽しすぎる！
ちなみに、プログラムコードは一切かけません。
そんな自分がClaudeに出会い、さらに最近はClaude MCPも導入して仕事で使用しているUnityのコンポーネントだったり、GitHubとの連携、データーベースの勉強で簡単なデーターベースを作ったり、仕事から帰ってきてはClaudeと一緒に何かを作る毎日を過ごしています。
※全部Claudeの指示に従うだけなので身にはなってない様な気がしますが。。。

## 自作ゲームを作るにあたって
さて、Claudeと出会って語りたいことが多すぎるのですが、今まさに現在進行形で作成している自作ゲームについて、Claudeとのやりとりを掲載していこうと思います。

まずは、アイディアはあったのでClaudeにゲームの制作をお願いします。
その前に、なぜ仕事で使っているUnityではなくGodotエンジンを使ったのか。
・Unityは仕事で毎日使っているので飽きた。
・Godotはプログラミングが簡単らしい。
・調べてみると、思っていたよりもハイクオリティなゲームがリリースされている。
・完全に無料。←これ大事
です。

## Claudeとのやりとり
ということで、早速Claudeとのやりとりをスクショで解説したいと思います。
恥ずかしいやり取りもありますが、恥を捨てて全てのやりとりを掲載していきます。
*やりとりを見ていただければ、いかに素人かわかると思います...*

その前に、ゲームのアイディアですが、タップすると弾が発射され、リングの隙間を通過するとスコアが加算されるという簡単なゲームです。
タイトルは[FOCUS]で、集中力をどれだけ維持することが出来るかという単純ゲームです。

やりたいこと
・リングを回転させる
・リングの隙間を通るとスコアが加算される
・スコアが増えるとともにリングの回転速度を上げる

とりあえず、
・Godotについては何も調べていない
・新規プロジェクトを作成
・必要な画像を用意
で始めました。

![CleanShot 2024-12-15 at 01.39.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961653/4c8eebd1-81e1-9df8-ab57-0f3ae68b617e.png)
まずは、iPhoneアプリにしたかったので、適切な画面サイズを聞きました。
ただ、出力された結果のサイズがどう見ても小さいので、手持ちのiPhone 12Pro Maxのスクリーンショットサイズを参考に画面設定しています。
そして、Claudeが教えてくれたコードですが、早速つまづくことになり、そんな時もClaudeに聞けば手取り足取り教えてくれるので、本当に助かります。


## 配置したリング画像を回転させる
ここで驚いたのは、こちらが指示しなくてもInspectorから回転速度などを調整できるように勝手に追加してくれたことです！
ウチにいる若手はここまでやってくれません！w
![CleanShot 2024-12-15 at 01.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961653/bdece02a-43f1-f107-b66b-a4260b200998.png)


## スクリーンショットで状況を把握させる
Claudeを使っていて本当に素晴らしいと思うのは、文章だけでなくスクリーンショットを添付すれば、画像認識して指示をくれるところです。これは本当に凄いのと、言語化するのが難しい時など本当に助かります。
階層構造も罫線を使ってうまく伝えてくれるし。これで画像生成する機能が付いたらどうなるんですかね？？？
![CleanShot 2024-12-15 at 02.09.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3961653/d4112e37-476f-bc9c-fe69-f0f5c0dd5ed5.png)


ということで、まだまだ先は長いのですが今日はここまでにして、また近いうちに続きをアップできたらと思います。

それでは、ここまで読んでいただきありがとうございました！
ABC384Dを解いた【累積和】


筆者はレート800前後の茶～緑コーダ

ABC384当日にACできなかったD問題を解いていく

    
https://atcoder.jp/contests/abc384/tasks/abc384_d

# 実装コード

求める値Sは数列1周分の総和で剰余を取ればいいらしい、
そして2週分の累積和で該当する数を探すようだ。

探し方はS[i]=Sもしくは
S[j]-S[i]=Sを移項して
S[j]=S+S[i]となる数を探すようだ

```python:main.py
import sys
from itertools import accumulate
from bisect import bisect_left
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)



def main():
    N, X = rLI()
    A = rLI()
    B = A+A
    S = set(accumulate(B))
    M = X%sum(A)
    for s in sorted(S):
        if s == M or s+M in S:
            print("Yes")
            break
    else:   
        print("No")
        
if __name__ == '__main__':
    main()

```

# まとめ

累積和を出す発想はあったが
剰余を取るのと2週分まで累積和をとるという発想が難しかった。

もっと柔軟に解けるようになりたい
大学生活とプログラミング

大学生になってから講義や外部での活動、研究室生活などで触れたプログラミング言語について所感を述べるだけの記事である。

# C
プログラミングといえばこれ、と思うのは私だけだろうか。ハードを扱う研究室では必須の言語。
私が受けた講義ではコンソールで動くゲームのようなものを制作したが、その後担当教員が変わったとかでオンライン上のコンパイラを使うようになったらしい。そのためか研究室の後輩はコンパイルと実行の違いを理解しておらず、ひたすらgccコマンドを叩いて「このプログラム動かないんですけど」と質問してきて困惑した。
```c:hello.c
#include <stdio.h>

int main(void) {
    printf("Hello, World!\n");
    return 0;
}
```

# C++
Cを拡張しオブジェクト指向プログラミングなどの概念を導入したもの。クラスや名前空間などが使える。Cと混ぜて書けたりもする。
先述のCの講義で「最終課題をC++でやったら加点する」と言われたので使ったのと、研究室で深層学習モデルの推論を高速化するために使っている。
```cpp:hello.cpp
#include <iostream>

using namespace std;

int main(void) {
    cout << "Hello, World!" << endl;
    return 0;
}
```

# Java
オブジェクト指向プログラミング言語の代表格、だと私は思っている。仮想マシン上で動作するため同じコードが複数のアーキテクチャで動く。
教職課程の都合で履修していた隣の専攻の講義で使ったのと、MinecraftのModを開発する際に使っている。
```java:hello.java
class Program {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
```

# C#
Javaと似た設計思想を持ち、.NETの元でアーキテクチャに依存せず同じコードが動く。こちらもオブジェクト指向プログラミング言語の代表格、だと私は思っている。
Unityを触る際に避けて通れないので使っている。
```c#:hello.cs
class Program {
    public static void Main() {
        Console.WriteLine("Hello, World!");
    }
}
```

# Python
機械学習ブームの波に乗り時代を光り輝く言語。データ処理に長ける。可読性が高いとか言われることがあるがそんなことはないと私は思っている。どの言語でも可読性が高いかどうかは結局書く人による。
アルゴリズムを学ぶ講義で使ったのと、実験のデータ処理とグラフ作成に使った。それから研究室で深層学習を行う際に格闘している。
```python:hello.py
print('Hello, World!')
```

# Verilog
ハードウェア記述言語。FPGAなんかを扱う際には必須。
Verilogを扱う実験があり、かなり苦戦した思い出。
</br>
</br>
この言語さえやっておけばいい、なんてそんなうまい話は無い。どの言語にも得手不得手があるので、適材適所で用いていくべきだと私は考えている。
テストコードが必要な理由と良し悪しの判断指標

# はじめに

最近テストコードについて言及することが増えてきたので、テストコードについての自分の考えを伝える上で、整理したいと思って言語化してみた。
基本的に既にテストに詳しい方が書いた本やWebページはいろいろあるのでそちらを推奨する。
本稿についてはUT/IT/E2Eなどの違いについては言及しない。

# なぜテストが必要なのか？

大前提として「バグのないシステムは作れるか？」ということを考える。

ここでは非常にシンプルなプログラムを除いて業務で作るようなことを前提とするが、私の答えとしては「できない」である。
正確には作れるかもしれないが、それを証明するのはシステムの規模や複雑さに応じて困難である。

テストとは証明である。
それは人間がやる場合でもテストコードの場合でも同様である。
そしてテストで証明できることとして、

- ある動作が正常に動くこと
- ある動作が正常に動かないこと

などが挙げられる。しかし、バグーーーつまり意図しない挙動を発生させることは難しい。

- バグがあること → 想定しているパターンにバグがあればできる
- バグがないこと → 悪魔の証明。全てのパターンを洗い出す必要がある

テストを含む要件定義や設計などは人間が行うため、ミスが避けられない。

結論としてテストが必要な理由は以下により、一定の品質保証するためである。

- できることを証明する
- できないことを証明し、それを改善する

逆に言えばテストが行われていないものは、無保証のため、信頼性が低いと言える。

# テストは品質保証の手段。具体的なやり方は多様

前述の通り、テストは品質保証のための手段である。
高い品質を保証をするため、何種類ものテストや何段階かのテストを行う。

- テストコードによる自動テスト
  - 単体テスト
  - 結合テスト
  - E2Eテスト(エンドツーエンドテスト)
- 人間による手動テスト
  - 例) 環境による違い
    - 開発環境
    - 検証環境
    - ステージング環境
    - プロダクション環境

※ テストと別であるが同じようなものとしては、人間によるコードレビューや静的チェックによる構文や意味解析による自動チェックなども品質保証の手段として用いられる

観点や目的、環境などによってテストにはいろいろな種類のテストがあり、それらを何種類か行うことで少しでも高い品質を保証する。
当然ながらテスト自体にもバグやミスがあるので、1回のテストよりも何種類か、または何人かでテストした方が高い品質を保証できる。
ただし、テストは準備や実施にコストが掛かるため、無制限にテストを行うことは現実的でない。
そのため、テストでは、どれだけコストを抑えて、どれだけ高い品質保証をできるかが重要になる。
2つの観点を更に言及すると以下のような内容が挙げられる。

- コスト
  - 準備コスト
    - テストパターンの調査・検討
    - テストを実施するために必要な準備
    - テストコードの追加
  - 実施コスト
    - テストを行うための時間や手間
  - メンテナンスコスト
    - リファクタによる影響でテストコードを修正する
    - 機能追加・改修によるテストコードの改修
- 効果的な品質保証
  - 本番(実際の動作)に近い検証である　※ 本番でありえないものを保証しても価値は低い
  - 十分なパターンが検証される　※ どれだけ保証されているかで信頼性は増す

# テストコードのコスト

同じように人間がテストする場合でも観点によっては評価が変わることはある。
例えば異常パターンをテストする場合、エラー文言を確認する程度であればテストコードやIDEのデバッグ機能などで無理やりエラーを確認する方が簡単なこともあれば、不正操作によって人間が直接操作した方が早いこともある。

とはいえ、傾向としては、人間が行った方が本番に近い検証ができ、逆に実施コストは人間によるテストよりもテストコードによるテストが優れている。
当たり前のことだが、テストに限らず、プログラムである以上、一度書かれたプログラムを再度実行するのは圧倒的に容易だからだ。
そのため、実施コストや準備コストについては長期的に考えると、テストコードの方が優れていると考えられる。

![テストコスト.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263164/afe83482-7efd-5651-7a48-a731d40f5230.png)

では、同じテストを何度も実行する理由は何かというと以下のようなことが挙げられる。

|テスト|説明|
|:---|:---|
| リファクタのためのテスト | 同じ仕様でコードを変えた場合に仕様が変わってないことをテストする |
| リグレッションテスト | 別の機能の改修、仕様変更により元の挙動で意図しないバグが発生していないかを確認するためのテストする |

多くの場合、一度作成したアプリが変更されないことは滅多にない。
実装期間中に何度もコードを直したり、テストで見つかったバグの対応だったり、仕様追加や改善のために変更したりと、いろいろな理由でコードが変更される。
アジャイル開発の場合は、小さい変更を積み重ねて開発を行うため、より多くのコード変更が行われる。

リグレッションテストについては明らかに不要な場合は省略することが多いが、省略することを判断するためには設計やコードを読む必要な場合がある。
そのため、それらを判断しなくてもテストを実施可能であれば、その分効率が良い。

ただし、メンテナンスコストによっては当然ながらそのコストの優位性が失われることは考えられる。

![テストコスト2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263164/7e585907-bd33-a2a3-37c4-ccfcd04aa6bc.png)

メンテナンスをしないための最も簡単な方法はそもそもテストコードを追加しないことである。
しかし、最初に言った通り、テストがないコードは無保証の信頼できないコードである。
また、リグレッションテストの観点から言えば毎回確実に影響調査をしなければならないコードと言える。
つまり、テストコードがないコードは改修コストが高く、メインコードのメンテナンス性を下げている。

# テストコードの良し悪しを判断するための判断指標

テストコードがないコードは改修コストが高く、メンテナンスが大変なテストはその分のコストが掛かる。
すなわち、テストコードはメンテナンスが低く、かつリファクタやリグレッションに備えた十全なテストであることが望ましい。
これらを踏まえると、テストコード全般には以下のような指標で良し悪しが考えられる。

- メンテナンスコストが低いこと
- 本番(実際の動作)に近い検証であること
- 十分なパターンが検証されること

これらを実現するための具体的なやり方は別途言及する。

https://qiita.com/yhornisse/items/25260a499f39c27e1bf1
Macログイン後に好きな音を鳴らす

# 成果物
要するにこれがやりたかった。音必須。
<iframe width="560" height="315" src="https://www.youtube.com/embed/-5VJfxVzX6A?si=cvzIIIMit4WJvqg1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

起動時の＼ジャーン／を消す方法は検索したらいっぱい出てくるものの、
ログイン後に任意の音を、というのは情報が無かったので共有します。

# 手順
1\. 素材を配置
分かりやすい所に置いてください。

2\. Automatorで音を鳴らすappを作成
![スクリーンショット 2024-12-14 0.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240483/d60336ca-1d8c-e4e9-a5ed-19e4206ef781.png)

![スクリーンショット 2024-12-15 1.42.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240483/63a167bb-2538-6316-55a5-55e5c873acb2.png)
ポイント
- 「シェルスクリプトを実行」を追加
- `afplay [音楽ファイルのフルパス]`を入力
- 右上の「実行」で音が再生されるか確認

appも分かりやすい場所に保存してください。

3\. ログイン項目に登録
![スクリーンショット 2024-12-14 0.18.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240483/89927fc7-e519-3cf2-fe5b-b2f428836b05.png)

# 最後に
Automator初めて使った。
ここで役に立つとは。