OmniAICreator/Qiita-1.07M huggingface dataset:
開発歴半年でハッカソンに出て感じたこと

# 開発歴約半年でハッカソンに出て感じたこと

開発歴が少なくてもハッカソンに挑戦してみたい、参加することになったけど怖い、といった方に届けばいいなと思っている記事になります。こういったものを書くのが初めてなので、不慣れな点があるかもしれませんが、ご了承ください。

## 👤 簡単な経歴紹介

今年の1月、心機一転してUnityでゲーム開発を始めようと思い、全くの初心者として学び始めました。それまでは大学の授業でPythonなどに少し触れていましたが、プログラミングの基礎すらほとんど理解していない状態からのスタートでした。現在は、自分で開発したゲームをインディーズサイト等に公開し、プレイヤーの反応を見ながら「ゲーム開発って楽しいな」と実感しています。

## 🤔 なぜハッカソンに参加したのか

一言でいうと、「自分の実力が他のエンジニアと比べてどれくらい離れているかを知りたかった」からです。

周囲にエンジニアがいないため、学習を進める中で少しでもできることが増えると天狗になりがちだったり、勉強法への不安が出てきたりしていました。独学ならではの壁を感じていたり、「自分を鍛え直したい」「エンジニアの知り合いが欲しい」などの思いもあり、今回のハッカソン参加を決めました。

## 💻 実際に参加してみて

ハッカソンは2日間で、チームを組んでゲーム開発を行い、最後に優勝を決めるといった内容でした。

参加してすぐに感じたのは、他のエンジニアとの実力差の大きさです。他のチームメンバーは皆、開発歴3年以上の方々ばかりで、開発速度や知識が自分とは大きく離れていました。半年の初学者では到底ついていけるわけもなく、チームの皆さんには迷惑をかけてしまいました。

そこで私がとった方法は、「とにかくアドバイスを求めること」でした。自分ができることとできないことを明確にして、それを逐一チームに共有し、助けを求めました。このおかげで、技術的にサポートしてもらえたり、優先的に対応が必要なタスクをアサインしてもらえるなど、いくつか対策をとってもらえました。

具体的には、他のメンバーがわからない部分を的確に指摘し、理解を深める手助けをしてくれたことで、自分の技術力が大きく向上しました。また、他のメンバーのアプローチや考え方を見ることで、自分に足りない知識や技術を明確に実感でき、今後の課題を洗い出す良い機会にもなりました。チーム開発においても、技術面での遅れを最小限に抑え、適切なアサインによって作業を終わらせることができました。

最終的には迷惑をかけつつも、何とか割り振られたタスクを終わらせることができました。

## 🗣️ ハッカソン中に大切だと思ったこと

「ついていけない」と感じた時点で、すぐに周囲に聞く・助けを求める、そしてコミュニケーションを積極的にとることが大切だと思いました。

「実際に参加してみて」の節でも述べたように、報連相（報告・連絡・相談）をしっかり行い、進捗や不安点をチームに共有することで、サポートを受けたり、適切にアサインしてもらうことができました。早めに対策することで、遅れによるチーム全体への影響を最小限に抑えられたと思います。


## ✨ まとめ

今回のハッカソン参加を通じて、コミュニケーションの大切さや、他のエンジニアとの実力差を強く感じました。チームメンバーには迷惑をかけてしまったものの、非常に楽しく、多くを学べた濃い2日間となりました。

いつか今回のチームメンバーのようなエンジニアになれるよう、日々精進していこうと思います。ここまで読んでいただきありがとうございました。この記事が、ハッカソンに参加する方の背中を少しでも押すきっかけになれば幸いです。楽しんで頑張ってください！
'unrecognized selector sent to instance' エラーについて

## 事件の發端
ほんとにほんにさせるようにコードを入力してもエラーが止まらない、そして様々なことを比較している途端
![Screenshot 2024-11-05 at 14.08.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/b68f8dde-e119-5d9c-5a16-e847fbd174da.png)
そのように不要にアウレトがあったらrunする時には問題ずにできるんですけど機能とか使う時で![Screenshot 2024-11-05 at 14.12.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/a1fa6c04-a538-8d38-66a0-4b30bb551273.png)
appDelegateで問題が発生することを確認しました。
## 結論
![Screenshot 2024-11-05 at 14.14.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/86eacd23-ee03-e52e-ce42-2deac9acafb5.png)
uikitはその様に連結して作る方法なので、自分が手違いする可能性があるなので気をつけて使いましょう。
君、Railsでeager_loadした後の行でfind_by, where使ってないか？

# Railsでeager_loadした後の行でfind_by, where使ってない？

## 要約
`eager_load`や`preload`でデータを読み込んだ場合、以降の行で`find_by`, `where`を使うとクエリを発行してしまう(ロードしたデータを利用しない)

#### 【背景】
別件でサーバーの不具合原因を調査していると、eager_loadした後にも関わらずクエリが発行されていることを発見
#### 【実行環境】
|技術スタック|バージョン|
-|-
|Ruby|3.2.2|
|Rails|7.0.4|
|Postgresql|1.1|
## 具体例 (NG)
#### シナリオ
1. ログイン中のユーザーに紐づく投稿(posts)を取得し、その投稿に紐づくコメント(comments)を事前読み込み
    - has_manyとかで関連づいているとする
2. 前ステップで取得した各投稿に対して紐づくコメントの中から、
`user_id: 5`
のレコードを検索

    ```ruby
    # current_userは事前にUserテーブルから取得したことにする
    posts = current_user.posts.eager_load(:comments)
    
    posts.map do |post|
      # eager_loadで読み込んだcommentから、さらに絞り込みを行いたい 
      comments = post.comments.where(user_id: 5)
      puts comments
    end
    ```

上記の場合、ステップ2の
`comments = post.comments.where(user_id: 5)`
で再度Commentテーブルに対してクエリを発行してしまい、eager_loadした旨味がなくなってしまう。

---
## 解決例
`detect`メソッドを使う(Rubyのメソッド)
```ruby
posts = current_user.posts.eager_load(:comments)

posts.map do |post|
  # 変更点
  comments = construction.post.comments.detect { |comment| comment.user_id == 5 }
  puts comments
end
```

## eager_load / preloadについて
詳しくはちゃんと紹介している記事を見てほしいが、ざっくりと使用例をば
(それぞれの使い方を理解していれば、`include`メソッドを使用する必要はなくなるので、あまり使わないようにしたい。)

### eager_load
```ruby
# レコードを連結しているので、 post, commentのカラムの値で検索をかけることができる
# (user) - post - commentの順で紐づいているもので、commentカラムの値で検索をかける
current_user.posts.eager_load(:comments).where(comments: {user_id: 5})
```

### preload
```ruby
# レコードを連結していないので、postテーブルのカラムの値のみで検索をかけることができる
# (user) - post - commentの順で紐づいているもので、commentテーブルを読み込んでおく(postに紐づくcommentのみ)
# 例1
current_user.posts.preload(:comments)
# 例2: ベースとなっているpostテーブルのカラムの値で検索はできる
current_user.posts.preload(:comments).where(post_title: "【悲報】xxxが--な件について") 
# 例3 (NG): 読み込み先であるcommentテーブルのカラムの値で検索はできない
current_user.posts.preload(:comments).where(comments: {user_id: 5}) 
```
### まとめ
クエリ発行が行われる際は、どんなクエリが発行されているかを確かめるべし。

### 最後に
間違ってたら優しく教えてください

---
### 参考にしたサイト
* Railsドキュメント
    * [eager_load](https://railsdoc.com/page/eager_load)

* Qiita
    * [【Rails】eager_load, preloadの解説と、それに伴うスロークエリの改善【SQL Server】](https://qiita.com/Alt70155/items/e73175a1631a0845416c)
    * [ActiveRecordのincludesは使わずにpreloadとeager_loadを使い分ける理由](https://qiita.com/ryosuketter/items/097556841ec8e1b2940f#includes)
WireShrak BACnet MS/TP

WireSharkでModbus/RTUをキャプチャする方法を書いたので
ついでにBACnet MS/TPのキャプチャ方法を書いておく

https://qiita.com/1994koki/items/748c6f160db8251074a4

mstpcap.exeは昔これ入れたらいいと言われていて
どっから拾ってきたのかが不明だったのだが
Modbus/RTUの時にURLを見つけた

# USB-RS485アダプタ
https://www.fa.hdl.co.jp/jp/plink/usb-003.html

前回同様USB-003を使用した。(宣伝ではありません、、)
RS-485のものなら何でもよいと思います。
前回は書かなかったけどSW設定はいい感じに設定しておく。


# mstpcap.exe
https://sourceforge.net/projects/bacnet/files/

 bacnet-toolsの中にmstpcap.exeが入っているので
 WiresharkSerialAdapter.exeの時同様extcapの下において起動するだけ
C:\Program Files\Wireshark\extcapなど

 BACnet MS/TP on COMxxを選択して起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/24f4c1d9-fe2a-9736-1e14-23ab434e32e0.png)

伝送速度を合わせる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/c761a9ef-88b7-8e43-daff-12196ed0f4d5.png)

使ったらこんな感じ
Mac 00と0aがトークンの受け渡しをしている
(参考URLのmstp wtap.capを使用)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/798673e5-3962-4d24-50bc-4e318edd39a7.png)



# 参考にしたURL
https://library.e.abb.com/public/2b037b07870b4af3831e88afe0bcf1a2/LVD-EOTKN123U-EN_WiresharkforBACnetMSTPtrafficcapture_REVA.pdf?x-sign=MeGy14LMDMFYK/sKpscTRKG0PHgqi0z3yPk99xwBBRiXzVi+Ccvk0IM8An3PRtWQ

https://steve.kargs.net/bacnet/wireshark-and-bacnet-mstp/
【NestJS】interceptor（インターセプター）でコントローラーの最初と最後にログを仕込む

## 経緯
NestJSをバックエンドAPIとして利用しているのですが、
あるフロントの1ページにアクセスした際にたくさんのデータ取得用apiが叩かれるため、各APIのコントローラーで
「SQLログを出しているけど、どのAPI内で実行されているか」
「各APIでどれくらいの時間がかかっているのか」
が少しわかりづらいなあと感じつつ、それぞれログを仕込んでいました。

調べてみると、NestJSにはinterceptorという機能があり、それを使えば全てのコントローラーの最初、最後に統一した処理を追加できるので、公式にある処理ほぼそのままですが試してみました。
※Laravelのミドルウェアのようなイメージです。

https://docs.nestjs.com/interceptors



## 手順

`logging.interceptor.ts`というファイルを作成します。
```ts
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // リクエストオブジェクトを取得
    const request = context.switchToHttp().getRequest();

    // コントローラーのメタデータを取得
    const handler = context.getHandler();
    const controller = context.getClass().name;

    const { method, url } = request;
    const now = Date.now();

    console.log(`--- コントローラー呼び出し開始 ---`);
    console.log(`Controller: ${controller}`);
    console.log(`Method: ${method}`);
    console.log(`URL: ${url}`);
    console.log(`Timestamp: ${new Date().toISOString()}`);

    return next.handle().pipe(
      tap(() => {
        const duration = Date.now() - now;
        console.log(`--- コントローラー呼び出し終了 ---`);
        console.log(`Duration: ${duration}ms`);
      }),
    );
  }
}

```


`main.ts`で`useGlobalInterceptors`として読み込みます。

```ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { LoggingInterceptor } from './logging.interceptor';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalInterceptors(new LoggingInterceptor()); //ここ
  await app.listen(3000);
}
bootstrap();

```


結果(Dockerのログです。。モザイク部分はsqlなので割愛)
![スクリーンショット_2024-11-05_12_50_35_png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/9b244622-2243-3e6d-806f-e63689040fc9.png)
BizRobo! Excelを開いた時に実行されるマクロをコマンド無しで実行したい

皆さんはBizRobo!でマクロを実行する際、
どのような手段を用いて実行されていますでしょうか？

DA端末上でExcelを開いてマクロを実行したり
コマンドライン実行ステップを用いて実行されているかなと思います。
しかし、コマンドライン実行ステップを用いる際は
コマンドを記入する必要があり、少しハードルが高いと思われる方もいらっしゃるかもしれません。

そこで今回は、**Excelを開いた時に実行されるマクロ**であれば
**コマンドライン実行を用いなくてもマクロ実行できるのでは**と思い検証をしてみました！

今回は「Excelを開いた際にA1セルの背景色を黄色にする」というマクロを用いて検証します。
※BizRobo!はver11.4を使用します


# ①Excelを青ロボット上で開いてみる
Load Fileステップ を用いて青ロボット上でExcelを開いてみます。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346701/e9131229-5e31-5c3b-07bf-45c5e27325b2.png)
A1セルは白色のままでマクロが実行されませんでした、、
⇒これは、ロボット上でExcelを開いているように見えますが
　実際にはロボット上でExcelに似せた形状で表示されているだけなので
　マクロが実行されない状況となっているようです。

# ②Built in Excelで開いてみる
緑ロボットのLocal上でExcelを開いてみます。

１．DA内で「Excel」ステップを作成
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346701/b139c1e0-4b86-aa74-01b6-d206aa3cdbb3.png)
２．ワークシートのパス欄に開きたいExcelのパスを記入
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346701/fe9d7fe9-8403-db4c-302d-995ac0282f68.png)
３．ステップを進めExcelを起動
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346701/05758e9e-aae6-af5a-c94b-32df3137777f.png)
A1セルが黄色となりマクロが実行されています！

:::note info
ここで保存をせずに閉じてしまうとマクロを実行したことも保存されないため
保存・閉じるステップを追加した後に青ロボットに戻りましょう
:::

４．保存と閉じるステップを作成
　　（レコーダービューのExcelのタブを右クリックし「アプリケーション」を選択すると
  　保存と閉じるのアクションを選択できます。）
![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346701/a3e8a52b-a27a-bf53-ba40-02b3a2576bf5.png)

青ロボットで確認すると、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346701/69bded9a-24cc-5bcb-4144-696e88692b0b.png)
該当Excelがマクロ実行された状態になっていることを確認できました！

# 
今回は、緑ロボットのLocal上でExcelを開くことで
起動時実行のマクロであれば実行できることを確認しました。

もちろんDA端末上でExcelを開く方法でも全く問題ないのですが、
DA端末が用意できない場合はこちらを試してみてもいいのではないでしょうか。

誰かのお役に立てば嬉しいです。
最後までお読みいただきありがとうございました。
JUnitの使い方 ＃忘備録


## JUnitのユーザーガイド
以下のJUnitのユーザーガイドを参考にJUnitの基本的な使い方を
まとめました。

https://junit.org/junit5/docs/current/user-guide/

## 基本的な使い方
　１、テスト対象クラスを作成する
　２、テストメソッドを作成する
　３、アノテーションを付けてテストを実行する
　４、テスト結果を確認する

### 1. テスト対象のクラスを作成
Calculator.javaというクラスを作成しています。
足し算・引き算を行う簡単なメソッドを定義しています。

```java

package hogehoge;

public class Calculator {

	// テストメソッド:足し算
	public int add(int a, int b) {
		return a + b;
	}

	//　テストメソッド：引き算
	public int subtract(int a, int b) {
		return a - b;
	}

}

```

### 2. テストクラスを作成
CalculatorTest.javaをテストするための
CalculatorTest.javaというクラスを作成しています。

テスト対象のクラス名＋Testの形でテストクラスを作ります。

```java

package hogehoge;

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class CalculatorTest {

	/**
	 * @throws java.lang.Exception
	 */
	@BeforeEach
	void setUp() throws Exception {
	}

	/**
	 * @throws java.lang.Exception
	 */
	@AfterEach
	void tearDown() throws Exception {
	}

	/**
     * 成功パターン 2+3のテストケース
	 * {@link hogehoge.Calculator#add(int, int)} のためのテスト・メソッド。
	 */
	@Test
	void testAdd１() {
		Calculator calculator = new Calculator();
		int result = calculator.add(2, 3);
		assertEquals(5, result, "2 + 3 should equal 5");
	}
	
	/**
 　　* 失敗パターン 8+3のテストケース
	 * {@link hogehoge.Calculator#add(int, int)} のためのテスト・メソッド。
	 */
	@Test
	void testAdd２() {
		Calculator calculator = new Calculator();
		int result = calculator.add(8, 3);
		assertEquals(5, result, "2 + 3 should equal 5");
	}


	/**
 　　* テストケース　5-3のテストケース
	 * {@link hogehoge.Calculator#subtract(int, int)} のためのテスト・メソッド。
	 */
	@Test
	void testSubtract() {
		Calculator calculator = new Calculator();
		int result = calculator.subtract(5, 3);
		assertEquals(2, result, "5 - 3 should equal 2");
	}

}

```

### 3. アノテーションを付けてテストを実行
テストメソッドに、@Testアノテーションを付けるだけでテスト実行可能です。
上記のコードの場合、**testAdd１**、**testAdd２**、**testSubtract**に@Testを
付けているためテスト実行することができます。

### 4. テスト結果を確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927184/956c510c-50a2-aee0-6d3c-7a303dd28b58.png)
実行結果の確認
　**testAdd１**：成功
　**testAdd２**：失敗
　**testSubtract**：成功


失敗したテストメソッドの実際と予想を比較確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927184/60fcc0e7-6e28-271b-4596-18aeca9bce24.png)


失敗したテストメソッドのコンソールの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927184/836b07fb-9210-f58c-f9c2-b7b943cdd563.png)

## よく使う JUnit のアノテーション

### 1. @Test
最も基本的なアノテーションで、テストメソッドに付けます。
これがないと、そのメソッドはテストとして認識されない

```Java
@Test
void testMethod() {
    // テスト内容
}

```
### 2. @BeforeEach / @AfterEach
各テストメソッドの前後に実行されるメソッドを定義するためのアノテーションです。
テストメソッドの前に共通の初期化処理を行ったり、テスト後に後処理を行ったりする。

```Java
@BeforeEach
void setUp() {
    // テストごとに実行される処理
}

@AfterEach
void tearDown() {
    // テスト後に実行される処理
}

```
### 3. @BeforeEach / @AfterEach
@BeforeEach と @AfterEach が各テストメソッドごとに実行されるのに対して
@BeforeAll と @AfterAll はクラス全体で 1 回だけ実行されます。
これらは静的メソッドに付ける必要がある。

```Java
@BeforeAll
static void initAll() {
    // テストクラス全体で一度だけ実行される処理
}

@AfterAll
static void tearDownAll() {
    // テストクラス全体で一度だけ実行される処理
}

```
Wio Terminal Wifi Analyzer

# WiFi
WioTerminalで[WiFi Analyzerを作成](https://www.instructables.com/Dual-Band-WiFi-Analyzer/)した記事があったので、試してみた。

基本的には、記事に従って手順を進めていく。

## Firmwareのアップデート
WioTerminalのワイヤレス通信用ファームウェアをアップデートする。
手順はqiitaの記事[Wio Terminal RTLファームウェアのアップデート手順（Windows）](https://qiita.com/matsujirushi/items/030ca18a48d99b23a4cb)を参考に行う。

記事の中でブートローダモードに切り替えるとあるが、切り替えは以下の記事がわかりやすい。
[Wio TerminalのUSB書き込みエラーの回復方法](https://qiita.com/carcon999/items/ec8045adc1309b2e5361)

Firmwareは[Seeed ambd firmware](https://github.com/Seeed-Studio/seeed-ambd-firmware/releases)で公開されている最新版[v2.1.3_JP](https://github.com/Seeed-Studio/seeed-ambd-firmware/releases/download/v2.1.3/20210519-seeed-ambd-firmware-rpc-v2.1.3_JP.zip)をダウンロードして書き込んだ．

## Arduino_GFX Libraryの準備
githubから[Aruduino GFX Library](https://github.com/moononournation/Arduino_GFX)をダウンロードし、Aruduino IDEのライブラリに追加する。

ライブラリに追加できたら、
スケッチ例>GFX Library for Arduino>WiFiAnalyzer>WioWiFiAnalyzer
を選ぶと，WiFi Analyzerのサンプルスケッチが開く．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233756/dcdd0f1a-690b-4be3-23f5-3d4f08e9b3e7.png)

### 必要なライブラリをインストール
ソースコード中に必要なライブラリの記述があるので、インストールする。
Seed Aruduino rpcWiFiについては最新が1.1.0だが、**1.0.7**にする。
1.1.0でコンパイルすると、画面がブラックアウトして動作しない。
```
/*
 * Wio WiFi Analyzer
 * Require Wio Terminal.
 * 
 * Libraries:
 * https://github.com/Seeed-Studio/Seeed_Arduino_FS/releases/tag/v2.0.2
 * https://github.com/Seeed-Studio/Seeed_Arduino_SFUD/releases/tag/v2.0.1
 * https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls/archive/d1ca0175e24768120781bf4a43a1fb2c39fce85f.zip
 * https://github.com/Seeed-Studio/Seeed_Arduino_rpcUnified/releases/tag/v2.1.1
 * https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFi/releases/tag/v1.0.2
 * 
 * Firmware:
 * https://github.com/Seeed-Studio/seeed-ambd-firmware/releases/tag/v2.1.1
 *```
 
```
### 書き込み
Aruduino IDEからWioTerminalへ書き込むとWiFiAnalyzerが動く．

### 表示の回転
ディスプレイの向きを変更するには、118行あたりに以下を追加
`  gfx->setRotation(3); //0:0, 1:90, 2:180, 3:270`
### 表示例
これは，`gfx->setRotation(3);`をつかってサンプルスケッチと表示方向を回転している．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233756/467861f5-13e6-b3e8-1cc4-89c559dc85dd.png)
Rubyのパターンマッチで遊んでみた

## はじめに

Ruby でパターンマッチができるようになったと聞いてはいましたが、まだ試したことがありませんでした。

https://qiita.com/jnchito/items/9bb4aa1dcefa00257815

https://qiita.com/jnchito/items/a9c7030cb5697f992cb7

2019 年の Ruby 2.7 の時点ですでに実験的には導入されていたのですね。

https://www.ruby-lang.org/ja/news/2019/12/25/ruby-2-7-0-released/

試してみます。

## パターンマッチとは

公式ドキュメントに以下の通り記されています。

> パターンマッチは、構造化された値に対して、構造をチェックし、マッチした部分をローカル変数に束縛するという、深いマッチを可能にする機能です。
> (『束縛』は、パターンマッチの輸入元である関数型言語の用語で、Ruby では代入と読み替えても問題ありません)

https://docs.ruby-lang.org/ja/latest/doc/spec=2fpattern_matching.html

https://docs.ruby-lang.org/en/3.3/syntax/pattern_matching_rdoc.html

関数型言語の機能を参考にして導入されたようです。ひょっとすると Elixir かもしれません。

https://qiita.com/torifukukaiou/items/deadb6af7df6d15ad7a7

同僚が Elixir や Rust のパターンマッチを利用してスマートに課題解決しているのをみたことがあります。

https://qiita.com/haw_ohnuma/items/dd329bc9c5da78967e7c#fizz-buzz

https://qiita.com/torifukukaiou/items/966b71497f04c7fb5882

https://qiita.com/torifukukaiou/items/a273565bd2643c4017c1#elixir

## Ruby のパターンマッチで素振り

せっかくなので自分で手を動かしてみようと思います。

```rb
parse_data =
  lambda do |data|
    case data
    in { error:, **rest }
      error
    in { a: { b: { status: } }, **rest }
      status
    in Integer => v if v.positive?
      v
    in [first, *rest]
      rest
    else
      'なんじゃこれ'
    end
  end

p parse_data.call({ error: '失敗' })
#=> "失敗"
p parse_data.call({ a: { b: { status: '元氣' } } })
#=> "元氣"
p parse_data.call(123)
#=> 123
p parse_data.call([777, 888, 999])
#=> [888, 999]
p parse_data.call(-1)
#=> "なんじゃこれ"
```

## Ruby のパターンマッチで Fizz Buzz

```rb
def fizz_buzz(count)
  (1..count).map do |n|
    case [n % 3, n % 5]
    in [0, 0]
      "Fizz Buzz"
    in [0, _]
      "Fizz"
    in [_, 0]
      "Buzz"
    in [_, _]
      n
    end
  end
end

fizz_buzz(16)
#=> [1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "Fizz Buzz", 16]
```

:tada:

## さいごに

文法になれてしまえば、Ruby でも比較的簡単にパターンマッチができることがわかりました。

複雑なロジックを簡潔で明確なコードで表現できる可能性があると思いました。

今後、さらに実践的なプログラムでも試していこうと思います。
Windowsのショートカットキー

- Windowsキー : スタートメニューの表示/非表示
- Windowsキー + D : デスクトップの表示
- Windowsキー + E : エクスプローラーの起動
- Windowsキー + I : 設定の起動
- Windowsキー + L : パソコン画面のロック
- Windowsキー + M : 全てのウィンドウを最小化
- Windowsキー + Q または S : 検索ボックスの使用
- Windowsキー + T : タスクバーでアプリの切り替え
- Windowsキー + home : アクティブなウィンドウ以外を最小化
- Windowsキー + + : 拡大鏡ON、画面の拡大
- Windowsキー + - : 画面の縮小
- Windowsキー + esc : 拡大鏡OFF
- Windowsキー + 数字 : タスクバーのアプリを起動
- Windowsキー + shift + 数字 : タスクバーのアプリを新しく起動
- Windowsキー + alt + 数字 : タスクバーのアプリの右クリックメニューを表示
- Windowsキー + ↑ : アクティブなウィンドウを最大化
- Windowsキー + ↓ : アクティブなウィンドウを最小化
- Windowsキー + ← : アクティブなウィンドウを左半分に配置
- Windowsキー + → : アクティブなウィンドウを右半分に配置
- Windowsキー + alt + M : 録画中のマイクのON/OFF
- Windowsキー + alt + R : 録画の開始/停止
- Windowsキー + alt + prt sc : スクリーンショット
- Windowsキー + shift + S : フリーフォーム領域切り取り

- ctrl + A : すべて選択
- ctrl + C : 選択した項目をコピー
- ctrl + N : 新規ウィンドウを開く/ファイルを作成する
- ctrl + S : ファイルを保存
- ctrl + V : 切り取り、コピーした項目を貼り付け
- ctrl + W : 表示中のファイルやアプリを閉じる
- ctrl + X : 選択した項目を切り取る
- ctrl + Y : 元に戻した操作をやり直す
- ctrl + Z : 操作を元に戻す
- ctrl + + : 画面の拡大
- ctrl + - : 画面の縮小
- ctrl + shift + N : 新しいフォルダーを作成
- ctrl + shift + 2 : アイコンを「大サイズ」に変更する
- ctrl + shift + 3 : アイコンを「中サイズ」に変更する
- ctrl + shift + 4 : アイコンを「小サイズ」に変更する

- alt + tab : 開いているアプリ・ウィンドウの表示/切り替え
- alt + F4 : アクティブなアプリ・ウィンドウを強制終了する

- shift + delete : 完全に削除
- shift + 矢印 : 複数の項目を選択する
- shift + (fn) + F10 : 右クリックメニューを表示

- (fn) + F2 : ファイル・フォルダーの名前を変更する
- (fn) + F11 : アクティブなウィンドウを全画面表示にする

- home : 行の先頭に移動する
- end : 行の末尾に移動する

- ctrl + ←/→ : 単語ごとに移動する
反射型XSSとは

>`リクエストを実行したユーザーにスクリプトが戻される`ことから「反射型XSS」と呼ばれる。いわゆる基本的なクロスサイトスクリプティングの手法である。攻撃者は偽メールや偽サイトに不正なスクリプトを含んだリンクを用意し、ユーザーを脆弱性のあるWebサイトへ誘導し、ユーザーの`Webブラウザー上で不正なスクリプトを実行させることで、個人情報やCookieなどの窃取`を試みる。

https://eset-info.canon-its.jp/malware_info/special/detail/221115.html#:~:text=%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%9F%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%8C%E6%88%BB%E3%81%95%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8B%E3%82%89%E3%80%8C%E5%8F%8D%E5%B0%84%E5%9E%8BXSS%E3%80%8D%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%82%8B%E3%80%82%E3%81%84%E3%82%8F%E3%82%86%E3%82%8B%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E6%89%8B%E6%B3%95%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82%E6%94%BB%E6%92%83%E8%80%85%E3%81%AF%E5%81%BD%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%84%E5%81%BD%E3%82%B5%E3%82%A4%E3%83%88%E3%81%AB%E4%B8%8D%E6%AD%A3%E3%81%AA%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%90%AB%E3%82%93%E3%81%A0%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E7%94%A8%E6%84%8F%E3%81%97%E3%80%81%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E8%84%86%E5%BC%B1%E6%80%A7%E3%81%AE%E3%81%82%E3%82%8BWeb%E3%82%B5%E3%82%A4%E3%83%88%E3%81%B8%E8%AA%98%E5%B0%8E%E3%81%97%E3%80%81%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AEWeb%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%83%BC%E4%B8%8A%E3%81%A7%E4%B8%8D%E6%AD%A3%E3%81%AA%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E3%81%93%E3%81%A8%E3%81%A7%E3%80%81%E5%80%8B%E4%BA%BA%E6%83%85%E5%A0%B1%E3%82%84Cookie%E3%81%AA%E3%81%A9%E3%81%AE%E7%AA%83%E5%8F%96%E3%82%92%E8%A9%A6%E3%81%BF%E3%82%8B%E3%80%82

* `攻撃者は偽メールや偽サイトに不正なスクリプトを含んだリンク`のリンクはjavascriptを埋め込んでいるのか？

多分下記のようにスクリプトを埋め込んでいると考えている。
>```
><a href="javascript:alert('Hello, world!')">クリックしてね</a>
>```

https://developer.mozilla.org/ja/docs/Web/URI/Schemes/javascript#javascript_url_%E3%82%92_href_%E3%81%AE%E5%AF%BE%E8%B1%A1%E3%81%A8%E3%81%97%E3%81%A6%E4%BD%BF%E7%94%A8

# 感想
ブラウザ側でもセキュリティを高めている中どのようなコードを書いてスクリプトを埋めて作動させているのか気になる。
【ChatGPT】命題解決の思考プロセス（お遊び）


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

　今回は、命題解決の思考プロセスをPromptにしてみました。

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

　先日、Claudeのアプリで、
　　音声入力できるようになりました、
　　　とお伝えしました。

　その中で、
　　“日本語がない”と書きましたが、
　　　“Japanese”はありました。
　　　　何度か見直していたんですが😅
　　　　　失礼しました。

　なお、
　　試してみたところ、
　　　滑舌の悪い私でも
　　　　比較的認識してくれました。

　ChatGPTの
　　Advanced Voice Modeよりは
　　　いいですね。
　　　　用途が違いますけど。
****
　次もClaudeの話題です。

　Anthropicは
　　Claude 3.5 Haikuの提供を開始。

　トークン当たりの価格が
　　Claude 3 Haikuの
　　　4倍になったそうです。
　　　　下記を見ればわかりますが
　　　　　これは、APIの話です。
　　　　　　Web版・アプリ版の
　　　　　　　話ではありません。

　画像入力は
　　現在のところ
　　　対応していない、とか。

　[Anthropic公式ポスト](https://x.com/AnthropicAI/status/1853498267612438873?t=KOFp-mp8YHwuBXcu6bWbAQ&s=19)
　DeepL翻訳
>Claude3.5 Haikuが我々のAPI、Amazon Bedrock、Google CloudのVertex AIで利用可能になりました。
>
>Haikuは高速で、特にコーディングに強い。 モデルが実際のソフトウェアの問題をどのように解決するかを測定するSWE-bench Verifiedでは、GPT-4を含む最先端のモデルを凌駕しています。
>
>最終テストでは、Haikuは多くのベンチマークで、以前のフラッグシップモデルであるClaude 3 Opusを上回りました。
>
>その結果、Claude 3.5 Haikuの価格は、そのインテリジェンスの向上を反映して、引き上げられました。
>
>Claude 3 Haikuは、画像入力や低価格帯のメリットを享受できるユースケースには引き続き利用できる。

***
　さて、本題です。

　今回は、
　　命題解決の思考プロセスを
　　　Promptにしてみました。

　OpenAI o1の思考方法を
　　真似た感じでしょうか。

　なお、
　　本当に解決するわけでは
　　　ありません😅

　お遊び程度に
　　受け取ってくださいね。
***
　では
　　Promptから。
```Text:命題解決の思考プロセスPrompt
命題「✘✘✘」

1. 「命題の内容を正確に理解する。与えられた命題の要点や、解決すべき問題点は何か？」

2. 「命題を解くために必要な情報や背景知識は何か？既知の法則や原理はどのように関係するか？」

3. 「命題を小さな部分に分解し、それぞれの部分問題にアプローチできるか？」

4. 「どのような仮説を立てることができるか？仮説が成り立つための条件は何か？」

5. 「立てた仮説をどのように検証できるか？適切な手法や手順を決定する。」

6. 「仮説検証のための計算や実験を実行し、その結果を記録する。」

7. 「得られた結果を評価し、予測通りでない場合は原因を特定し調整を行う。」

8. 「結果から得られる結論を論理的にまとめ、証明を行う。」

9. 「以上から、命題を解決する（答えを導き出す）」
```

　これを使ったのが、こちら。
***
***●user***
命題「恋愛が成就する方法を教えてください」
（命題以外のPrompt）

***ChatGPT***
この命題「恋愛が成就する方法を教えてください」に対して、あなたの提示した各手順に沿って考察を進めてみましょう。


---

1.命題の内容を正確に理解する

命題は「恋愛が成就する方法」という目標を提示しています。具体的には、ある対象に対する好意を成功裡に発展させ、両者が望む関係性（恋愛関係や信頼関係）を築くことを意味します。

2.命題を解くために必要な情報や背景知識

恋愛心理学やコミュニケーション理論、社会心理学、自己成長に関する知識が役立ちます。恋愛が成就するためには、相手の心理や感情、相互理解、自己理解といった要素が絡むため、これらの分野の法則が関連します。

3.命題を小さな部分に分解

恋愛成就までのプロセスをいくつかの段階に分解できます。

1. 自分の気持ちを整理する


2. 相手の関心を引く方法を考える


3. 良好なコミュニケーションを築く


4. 信頼関係を深める


5. お互いの気持ちを確認し、関係性を発展させる



4.仮説を立てる

各段階での仮説としては、例えば「自分の気持ちが明確であれば相手に対する行動も一貫する」「相手の興味関心を理解することで接点が生まれやすい」「共通の経験を共有すると信頼が深まる」などがあります。

5.仮説検証のための手法や手順

自己分析や目標設定（自分の気持ちの整理）

共通の趣味や話題を見つけるためのリサーチ

コミュニケーションのテクニックを用いた会話の練習

関係性が進展した段階での気持ちの確認


6.仮説検証の実行と記録

仮説に基づいて行動し、その結果（例えば相手の反応や関係の変化）を記録します。これは日記やメモとして残すとよいでしょう。

7.結果の評価と調整

目標通りの進展が見られなかった場合、その原因を分析し、行動や仮説を再考します。

8.結果から得られる結論のまとめ

成功した要因や改善点を論理的に整理します。例えば「相手の反応から、趣味の共通点が信頼形成に効果的だった」などです。

9.命題を解決する

以上を踏まえた結果、特定の行動が恋愛成就に貢献したことが確認できれば、その方法が成就の手段として有効であったと言えます。


---

このような方法で、段階的に恋愛成就に向けてアプローチすることが可能です。
***

　なんか具体的な方法が
　　欲しいのですが、
　　　これではねぇ……

　まぁ、別に恋しているわけでもなし、
　　実験的にやってみただけなので
　　　あまり本気に取らないで😅　　

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

　今回は、ここまで。
DeepLabCutの出力データを「注目すべき行動」に変換するAIを作ってみた


## 0.DeepLabCutについて
DeepLabCutは、動物の姿勢推定のための深層学習ベースのオープンソースツールです。特徴として：

- マーカーレスでの動物の追跡が可能
- 少ない学習データで高精度な推定が可能
- GUIベースで簡単に操作可能
- 様々な動物種に適用可能（マウス、ラット、ハエなど）

DeepLabCutのインストール及びコマンドに関しては、[こちら](https://github.com/Banboo-glich/DeepLearning_Transfomer_analysis/blob/main/README.md)をご覧ください。

### DeepLabCutの結果
![trajectory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001770/c3449b1e-42e9-33f0-70ab-022a412906bf.png)
![plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001770/dfa7603b-cb53-c3a4-09fc-cd83246949b6.png)



## はじめに

みなさん、行動解析に悩んでいませんか？🤔

「DeepLabCutで座標は取れたけど、この大量のデータから何を見ればいいの...」
「行動の違いはありそうだけど、どこに注目すれば良いのかわからない...」

そんな悩みを解決するため、**Transformerベースの行動解析AI**を開発しました！

この記事では、Nature Communicationsで発表されたDeepHLという手法にインスパイアされた、マウスの行動解析システムを紹介します。

## 開発の動機 💡

DeepLabCutは素晴らしいツールですが、出力されるのは「座標データ」です。これを「意味のある行動の違い」に変換するのは、まだまだ研究者の手作業に頼っている部分が大きいのが現状です。

そこで、最新の深層学習技術である**Transformer**と**アテンション機構**を使って、以下のことを自動化してみました：

- 重要な行動セグメントの特定
- 特徴的な動きのハイライト
- 行動パターンの可視化

## システムの特徴 🚀

### 1. シンプルな入力

```python
# DeepLabCutの出力CSVを直接読み込めます
dataset = MouseTrajectoryDataset("dlc_output.csv")
```

### 2. 高度な行動解析

以下の特徴量を自動的に計算・解析します：
- 速度プロファイル
- 角速度の変化
- 移動距離のパターン
- その他の時系列特徴量

## 技術的な詳細 🔧

### アーキテクチャ

```python
class TransformerModel(nn.Module):
    def __init__(self, input_dim, num_classes=1, d_model=128):
        super().__init__()
        self.feature_extractor = nn.Sequential(
            nn.Linear(input_dim, d_model),
            nn.ReLU(),
            nn.Dropout(0.1)
        )
        # Transformer層の詳細は省略
```

### DeepHLとの違い

DeepHLは一般的な動物の軌跡解析のために開発されましたが、本システムは：

1. DeepLabCut出力に特化
2. マウス行動に最適化
3. よりシンプルな実装

という特徴があります。

## 使ってみよう 👨‍💻

```

### 基本的な使い方

```python
# モデルの初期化
model = TransformerModel(
    input_dim=dataset.features.shape[1],
    d_model=128,
    nhead=8,
    num_layers=4
)

# 学習実行
history = train_model(model, dataset)

# 結果の可視化
visualize_results(dataset, model)
```

## 結果例 📊
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001770/98792d3d-d549-a522-5f5a-a1d272853a66.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1001770/6890aaac-16ed-1fa0-1ae3-885c25f52d68.png)




### 見つかった興味深い行動パターン
- 上部と下部に分かれた特徴的な8の字型の軌道を描いている
- 特に外周部分（x座標0.8-1.0付近）で強いアテンションが検出されている
- マウスは規則的な往復運動を行っている可能性が高い
- 急激な損失の減少(3000エポックでの急激な損失減少は過学習の可能性がある)→学習率の調整、エポック数の見直し、正則化の強化
- 現状のアテンションスコアは閾値周辺で飽和している
- - アテンション機構のアーキテクチャの見直し
- - スケーリング関数の調整
- - 異なる損失関数の検討
## まとめ 🎯

このシステムを使うことで：
- 行動解析の時間を大幅に短縮
- 人間が見落としがちなパターンを発見
- 客観的な行動評価が可能


に！

## 今後の展望 🔮

- より多様な実験動物への対応
- リアルタイム解析機能の追加
- GUIの開発

などを予定しています。

## GitHub

コードは以下で公開しています：

https://github.com/Banboo-glich/DeepLearning_Transfomer_analysis

## 参考文献 📚

1. DeepHL: Deep learning-assisted comparative analysis of animal trajectories with DeepHL (Nature Communications, 2020)
2. DeepLabCut: Markerless pose estimation of user-defined body parts with deep learning

---

実装や使用方法について質問があればコメントください！
また、このプロジェクトに興味を持っていただけた方は、ぜひGitHubでスターをつけていただけると嬉しいです⭐️

#DeepLearning #MachineLearning #動物行動解析 #Python #DeepLabCut
【Facebook API】CustomConversionのStatsが「Invalid parameter」で取得できない

# はじめに
こんにちは、ユーゴです。今回は、Facebook API (コンバージョンAPI)を使用していた時に遭遇した問題について紹介します。

# やりたいこと
特定のカスタムコンバージョンの集計の値を取得したい。
日付の範囲まで指定できると良い。

以下を参考に実装した。
[グラフAPI リファレンス v21.0: Custom Conversion Stats](https://developers.facebook.com/docs/marketing-api/reference/custom-conversion/stats/)

# 問題
リファレンスを読通りにカスタムコンバージョンのStatsを取得しようとしましたが、エラーで取得できませんでした。


```Python:Python
from facebook_business.adobjects.customconversion import CustomConversion

# SDKのセットアップ
app_id = "xxx" # ご自身のアプリID
app_secret = "yyy" # ご自身のアプリシークレット(app secret)
access_token = "EAA...(略)" # ご自身のアクセストークン
FacebookAdsApi.init(app_id, app_secret, access_token)

# カスタムコンバージョンの取得
cc = CustomConversion("123456789") # カスタムコンバージョンID
stats = cc.get_stas()
print(stats)
```

```shell:HTTP
# v21.0：最新のAPIバージョン
# 123456789：ご自身のカスタムコンバージョンID
# access_token：ご自身のアクセストークン
curl "https://graph.facebook.com/v21.0/123456789/stats?\
access_token=EAA...(略)"
```

上記のコードは、以下のようなエラーが出ます。

```json
{
      "error": {
        "message": "Invalid parameter",
        "type": "OAuthException",
        "code": 100,
        "error_subcode": 1760016,
        "is_transient": false,
        "error_user_title": "Unsupported Aggregation Type",
        "error_user_msg": "Specified aggregation is not supported on custom conversion stats",
        "fbtrace_id": "xxxxxxxxxxxxxxxxx"
      }
}

```

特に「aggregation」指定してないのに`Specified aggregation is not supported on custom conversion stats`というエラーが出ました。

# 解決
aggregationを指定します。start_timeとend_timeも指定します。
逆に指定していないため空文字として扱われたためか、「無効なaggregation」というエラーだったようです。

```Python:Python
from facebook_business.adobjects.customconversion import CustomConversion

# SDKのセットアップ
app_id = "xxx" # ご自身のアプリID
app_secret = "yyy" # ご自身のアプリシークレット(app secret)
access_token = "EAA...(略)" # ご自身のアクセストークン
FacebookAdsApi.init(app_id, app_secret, access_token)

# カスタムコンバージョンの取得
cc = CustomConversion("123456789") # カスタムコンバージョンID
params = {
    "aggregation":"device_type", # 必要に応じてdevice_type, host, urlなどから1つ指定
    "start_time":"2024-11-05",
    "end_time":"2024-11-05",
}
stats = cc.get_stas(params=params)
print(stats)
```

```shell:HTTP
# v21.0：最新のAPIバージョン
# 123456789：ご自身のカスタムコンバージョンID
# access_token：ご自身のアクセストークン
curl "https://graph.facebook.com/v21.0/123456789/stats?\
access_token=EAA...(略)&\
aggregation=device_type&\
start_time=2024-11-05&\
end_time=2024-11-05"
```

これで、以下のようなデータが返ってきます。
```json
{
    "aggregation": "device_type",
    "timestamp": "2024-11-05T09:00:00",
    "data": [
        {
            "value": "mobile_iphone",
            "count": 999
        }
    ]
}
```

# まとめ
いかがだったでしょうか。今回は、Facebook API (グラフAPI)を使用している時に遭遇した問題を紹介しました。[リファレンス](https://developers.facebook.com/docs/marketing-api/reference/custom-conversion/stats/)にあるコード通りやったはずなのに上手くいかないのはなんででしょうか。~~やはりMetaのリファレンスは読みにk~~
このように、Facebook APIなど特定の媒体のAPIの紹介から、Unity, AWS, GAS, 量子コンピューティングなど、幅広いジャンルの紹介をしております。お役に立てましたら、いいね, フォローなどよろしくお願いします！
AWS CodeCommitでGitリポジトリの基本操作を行う

AWS CodeCommitは、AWSクラウド上で管理できるGitベースのバージョン管理サービスです。
この記事では、CodeCommitで新しいリポジトリを作成し、基本的なGit操作を行う方法について説明します。

## 事前準備
- AWSアカウントが必要です。
- Gitがインストールされていることを確認してください。

## リポジトリのクローン
まず、AWS CodeCommitで作成したリポジトリをクローンします。

```bash
git clone ssh://git-codecommit.[リージョン].amazonaws.com/v1/repos/[リポジトリ名]
```

## ファイルの追加とコミット
次に、新しいHTMLファイルをリポジトリに追加します。

1. リポジトリのディレクトリに移動します。
   ```bash
   cd [リポジトリ名]
   ```

2. `index.html` ファイルを作成します。
   ```bash
   echo '<html><body><h1>Hello, CodeCommit!</h1></body></html>' > index.html
   ```

3. ファイルをステージングに追加し、コミットします。
   ```bash
   git add index.html
   git commit -m "Add index.html"
   ```

## ファイルのプッシュ
ローカルでの変更をリモートリポジトリにプッシュします。

```bash
git push origin master
```

## ファイルの削除
最後に、リポジトリからファイルを削除する方法を紹介します。

1. ファイルを削除します。
   ```bash
   git rm index.html
   ```

2. 変更をコミットします。
   ```bash
   git commit -m "Remove index.html"
   ```

3. 変更をプッシュします。
   ```bash
   git push origin master
   ```

これで、AWS CodeCommitでの基本的なGit操作の流れが完了しました。

## まとめ

この記事では、AWS CodeCommitを使用した基本的なGit操作について説明しました。
具体的には、CodeCommitリポジトリのクローン、新しいファイルの追加とコミット、ファイルのプッシュ、そしてファイルの削除という一連のプロセスを実行しました。
これらの手順はGitの基礎を理解するのに役立ち、AWSのバージョン管理システムを効果的に利用するための出発点となります。

AWS CodeCommitは、セキュアでスケーラブルなGitベースのリポジトリサービスを提供し、チーム開発や個人プロジェクトにおけるコードのバージョン管理を容易にします。
今回の基本操作をマスターすることで、より高度な機能やワークフローへと進むための基礎が築かれます。
html2canvasで「oklch関数に対応していない」エラーが出る

## 作業内容
html2canvasを使ってHTML要素を画像化する際にブラウザでエラーが発生しました。

### エラーメッセージ
ブラウザのコンソールで表示されたエラー
`Error: Attempting to parse an unsupported color function "oklch"`

oklch関数は対応していないと表示されますが、実装する中でoklch関数は使用していないです。
なぜかこのエラーが出る。

## 解決方法
**html2canvas-proを使う**

https://www.npmjs.com/package/html2canvas-pro

html2canvas-proはhtml2canvasの修正と新規機能（カラー関数サポートなど）が追加されたライブラリ

## issueで解決
issueを見ると同じエラーでつまずいている方を発見
開発者が直接質問に答えていました。
![issue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721753/38ae9973-c2f3-6210-ec3b-56e4f7e37296.png)

## 結論
html2canvasだとoklch関数に対応していない
なので上位版のhtml2canvas-proを使おう
【Laravel】Eager LoadとLazy Loadの違いと使い分け

## はじめに

モデル間のリレーションを扱う際、データのロード方法によってパフォーマンスやメモリ使用量に大きな影響を与えることがあります。

今回は、「Eager Load（イーガーロード）」と「Lazy Load（レイジーロード）」について解説します。
## Eager Load（イーガーロード）とは？
### 特徴
一度のクエリでまとめてデータを取得する方法です。
これにより、後からデータをアクセスする際に追加のクエリを発行する必要がなくなります。Laravelでは、`with`メソッドを使用してEager Loadを実装できます。

```php
$users = User::with('posts')->get();
```
この例では、Userモデルに関連するpostsが一緒に取得され、各ユーザーの投稿を表示する際に追加のクエリが発生しません。

**メリット:**
- **クエリ数を削減:** データベースへのアクセス回数を減らせる
- **パフォーマンス向上:** 複数のリレーションを持つデータを一括で処理する場合に効果的
- **データの一貫性:** 関連データが同時にロードされるため、データの整合性を保てる

**デメリット:**
- **メモリ消費:** 必要以上にデータをロードすることになる場合があるため、大規模なデータセットではメモリ使用量が増加する

## Lazy Load（レイジーロード）とは？
### 特徴
関連データが実際にアクセスされた時に初めてデータベースからロードされる方法です。
これにより、必要なデータだけを効率よく取得できます。Laravelでは、明示的に`with`メソッドを指定しない場合、デフォルトでLazy Loadが適用されます。
```php
$users = User::all();

foreach ($users as $user) {
    echo $user->posts; // ここで初めてpostsにアクセスする時に関連データがロードされる
}
```

この例では、postsリレーションにアクセスした時点でデータベースから関連するデータが取得されます。

**メリット:**

- **メモリ効率:** 必要なデータのみロードするため、メモリ消費を抑えられる
- **初期パフォーマンス:** 初期クエリで最低限のデータしか取得しないため、応答速度が向上する

**デメリット:**
- **N+1問題:** データを個別にロードされるため、大量の追加クエリが発行され、パフォーマンスが低下することがある


## 使い分けのポイント

- **Eager Loadを使うべき場面:**
    - 複数のリレーションが一度に必要となる場合
    - 一度のクエリで関連データをすべて取得したい場合
    - リスト画面、検索結果画面など
- **Lazy Loadを使うべき場面:**
    - 必要なデータだけを逐次取得したい場合
    - 大量のデータを一度にロードすることを避けたい場合
    - 詳細画面など
No module named 'numpy' について

# はじめに
仮想環境をアクティベートした状態でライブラリをインストールする。
```terminal:pip
pip install [ライブラリ名]
```
これを Python ファイルや Jupyter notebook で用いてみる。
```python:import
import [ライブラリ名]
```
この時にこのモジュールが見つからないというエラーが吐かれることがある。
```terminal:error
No module named '[ライブラリ名]'
```
しっかりとインストールしたはずなのになぜ？？ということがあったので、解決方法を記録しておく。

# 解決方法
結論から言うと、原因は  **「インストール先とPythonファイルの実行の場所がずれている」** ことにある。

### インストール先の確認
pip によるインストール先の確認は以下のコードを Python ファイルで実行する。
```python:インストール先の確認
import pip
print(pip.__path__)
#['/Users/[User name]/Desktop/[working directory]/[virtual environment name]/lib/python3.10/site-packages/pip']

```
これによって pip のインストール先がちゃんと仮想環境になっていることが確認できた。

::: note
ここが仮想環境になっていない場合は、インタープリタ (Pythonファイルの場合)やカーネル (Jupyter notebook) を確認するといいだろう。
:::

pip でインストールを行うと、基本的には上記の仮想環境にライブラリはインストールされるはずである。しかし、ライブラリが **グローバル環境や他の仮想環境にすでにインストール済みである** 場合、目的の仮想環境へのインストールがうまくいかないことが起きうる。

### 目的の仮想環境へのインストール
ライブラリをインストールする際に、ターミナル（Mac の場合）において `-t` でインストール先を指定することで解決する。
```terminal:pip install
pip install numpy -t /Users/[User name]/Desktop/[working directory]/[virtual environment name]/lib/python3.10/site-packages/pip
```
これで目的の仮想環境に、ライブラリをインストールできるので、`No module named [ライブラリ名]`も解決されるだろう。

# 最後に
```terminal
pip show [ライブラリ名]
```
をターミナルで実行すると、出力内容の最後のあたりに以下のような内容が含まれる。
```terminal
Location: /Users/[User name]/Desktop/[working directory]/[virtual environment name]/lib/python3.10/site-packages
```
これはライブラリのインストール先を示すもので、仮想環境と一致することが確認された。
Processing系で巨大数の計算メモ

https://qiita.com/hextomino/items/0de35974bb3d167e57bf

# 巨大数
円周率、素数、フラクタルなど計算するときに、有効桁数が重要になってくる。しかし、ProcessingだとBigDecimalかBigIntegerを使う必要があり不便。

では、pyモードやjsモードはどうなのか。
Processingはjavaの制限を受ける。✗
Processing.pyもjavaの制限を受ける。✗
p5.jsのbigintも良さそうだがmathが使えない。
やっぱり「pythonしか勝たん」のか？

# 対象
Processing(java)
p5.js
Processing.py

※windowsでは32bit版と64bit版があるので、違うかも。



# 比較表（整数のみ）
| 環境 | min | max |
|:--|--:|--:|
| Processing int| -2,147,483,648 | 2,147,483,647 |
| Processing long|  -9,223,372,036,854,775,808 |  9,223,372,036,854,775,807 |
|Processing.py int|-9,223,372,036,854,775,808|9,223,372,036,854,775,807|
|java BigInteger|-2^5億?メモリ依存?|2^5億?メモリ依存?|
|java BigDecimal||桁指定可、2^31-1=2147483647桁|
|python 整数型|上限なし、メモリ依存|上限なし、メモリ依存|
| p5.js |同下 | 同下|
| JavaScript number | -(2^53-1)<br>-9,007,199,254,740,991|2^53-1<br>9,007,199,254,740,991|
| JavaScript bigint|-3.2億桁?メモリ依存 |3.2億桁?メモリ依存|

注：最大の素数は4100万桁

# 困るケース
例えば12^13 = 106,993,205,379,072であり、必要桁数は、int(32bit)とlong(64bit)の間であるが、
processing(java)のpowはfloat(32bit)で計算されているので正確ではない。
```java:processing(java)
print(pow(12,13));  // 1.06993205E1 精度不足
print(12*12*12*12*12*12*12*12*12*12*12*12*12); // 1275068416 桁溢れ
print(12l*12l*12l*12l*12l*12l*12l*12l*12l*12l*12l*12l*12l); // 106993205379072 正確
```

float(32bit)精度であれば、せいぜい7桁ぐらいしか保証されない。

```java:processing(java)
println(pow(10,6)+1);
println(pow(10,7)+1);
println(pow(10,8)+1);
println(pow(10,9)+1);
println(pow(10,10)+1);
println(pow(10,11)+1);
```

```java:output
1000001.0    // OK
1.0000001E7  // 表示がE表記になる
1.0E8        // 精度が限界を超える
1.0E9        // 同上
1.0E10       // 同上
9.9999998E10 // 誤差が目立つ
```

# オンラインpython,p5js環境

https://www.online-python.com/

https://trinket.io/processing

https://editor.p5js.org/
PowerShellの出力結果がきれたら

PowerShell のコマンドレットで実行結果が最後まで表示されないことありませんか？

例として、`Get-AppxPackage Microsoft.ScreenSketch` の実行結果にある Dependencies のところを横にスクロースすると、最後が `...` となり、実行結果が最後まで確認できません。

```powershell:例
Get-AppxPackage Microsoft.ScreenSketch
```
```text:出力結果
Name              : Microsoft.ScreenSketch
Publisher         : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture      : X64
ResourceId        :
Version           : 11.2409.25.0
PackageFullName   : Microsoft.ScreenSketch_11.2409.25.0_x64__8wekyb3d8bbwe
InstallLocation   : C:\Program Files\WindowsApps\Microsoft.ScreenSketch_11.2409.25.0_x64__8wekyb3d8bbwe
IsFramework       : False
PackageFamilyName : Microsoft.ScreenSketch_8wekyb3d8bbwe
PublisherId       : 8wekyb3d8bbwe
IsResourcePackage : False
IsBundle          : False
IsDevelopmentMode : False
NonRemovable      : False
Dependencies      : {Microsoft.UI.Xaml.2.8_8.2310.30001.0_x64__8wekyb3d8bbwe, Microsoft.WindowsAppRuntime.1.5_5001.275.500.0_x64__8wekyb3d8bbwe, Microsoft.VCLibs.140.00_14.0.33519.0_x64__8wekyb3d8bbwe, Microsoft.VCLibs.140.00.UWPDesktop_14.0.33728.0_x64__8wekyb3d8bbwe...}
IsPartiallyStaged : False
SignatureKind     : Store
Status            : Ok
```
PowerShell でコマンドレットの出力結果に `...` が出力される場合には、すべての情報が出力されておらず、省略されています。
その場合、コマンドレット実行前に `FormatEnumerationLimit` を -1 に設定してあげれば実行結果が省略されずに表示されます。

```powershell:例
$FormatEnumerationLimit = -1
Get-AppxPackage Microsoft.ScreenSketch
```

```text:出力結果
Name              : Microsoft.ScreenSketch
Publisher         : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
Architecture      : X64
ResourceId        :
Version           : 11.2409.25.0
PackageFullName   : Microsoft.ScreenSketch_11.2409.25.0_x64__8wekyb3d8bbwe
InstallLocation   : C:\Program Files\WindowsApps\Microsoft.ScreenSketch_11.2409.25.0_x64__8wekyb3d8bbwe
IsFramework       : False
PackageFamilyName : Microsoft.ScreenSketch_8wekyb3d8bbwe
PublisherId       : 8wekyb3d8bbwe
IsResourcePackage : False
IsBundle          : False
IsDevelopmentMode : False
NonRemovable      : False
Dependencies      : {Microsoft.UI.Xaml.2.8_8.2310.30001.0_x64__8wekyb3d8bbwe, Microsoft.WindowsAppRuntime.1.5_5001.275.500.0_x64__8wekyb3d8bbwe, Microsoft.VCLibs.140.00_14.0.33519.0_x64__8wekyb3d8bbwe, Microsoft.VCLibs.140.00.UWPDesktop_14.0.33728.0_x64__8wekyb3d8bbwe, Microsoft.ScreenSketch_11.2409.25.0_neutral_split.language-de_8wekyb3d8bbwe, Microsoft.ScreenSketch_11.2409.25.0_neutral_split.language-ja_8wekyb3d8bbwe, Microsoft.ScreenSketch_11.2409.25.0_neutral_split.scale-100_8wekyb3d8bbwe, Microsoft.ScreenSketch_11.2409.25.0_neutral_split.scale-125_8wekyb3d8bbwe, Microsoft.ScreenSketch_11.2409.25.0_neutral_split.scale-150_8wekyb3d8bbwe}
IsPartiallyStaged : False
SignatureKind     : Store
Status            : Ok
```

## 参考URL
about_Preference_Variables - PowerShell | Microsoft Learn
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables
GoのフレームワークGinの導入方法(初心者向き)

# 参考資料とオススメUdemy


[Gin入門 Go言語ではじめるサーバーサイド開発](https://www.udemy.com/course/gin-golang/?srsltid=AfmBOooo9QGLQPHIr6XvJTyWZqrihT7YlhGqMs9ibDC339OkfgQuDZou&couponCode=KEEPLEARNING)

# Ginとは
***Goのフレームワーク***です。***RESTAPIを簡単に構築***できます。
非常に軽量で他のGoのフレームワークと比べて1番使われています。

# Gin導入
Goモジュールの初期化をします。
```
go mod init プロジェクト名
```
次にGinをダウンロードします。
```
go get -u github.com/gin-gonic/gin
```

# main.go
以下が公式ドキュメントのサンプルです。

```main.go
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()//これはHTTPリクエストを処理
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run("localhost:8080") //ここだけ変更
```
> 引用　https://gin-gonic.com/ja/docs/quickstart

以下のコマンドで実行します。
```
go run main.go
```

別のターミナルで開いてみると
```
% curl localhost:8080/ping 
{"message":"pong"}%                                                       
```
になったらGinは起動できているみたいです。

## ホットリロード
コードを変更するたびにサーバーを起動したり、止めたりすると面倒なので```ホットリロード```します。

```
go install github.com/air-verse/air@latest
```
https://github.com/air-verse/air

その後、(Mac想定)
```
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc
```
または
```
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc
```
を実行する。その後に
```
air init
```
を実行して```.air.toml```を作成されます。

```
air
```
で***サーバーを起動し、コードを変更すると再ビルドされコードの反映***がされます。


## Goはフロントエンドみたいな変更が少ないけど。。。。
Goはフロントエンドみたいに破壊的な変更はそんなに無さそうです。
ただRailsやLaravelみたいにコマンド一発でファイルを作ったりできないのが難点です。💦

# Ginの公式ドキュメント
以下のドキュメントを読んでみてください。
[Ginの公式ドキュメント](https://gin-gonic.com/ja/docs/quickstart)
[ThoughtSpot]レコードに存在しない値で先回りしてフィルターをかける方法

## はじめに
パッと見タイトル何言ってるかわからない。

ThoughtSpotのフィルター（検索条件）って、基本的に『存在しているレコードから選択肢を選ぶ』ことになります。
が、例えば「今後絶対この値が入ってくるから先にその分のグラフ作っておきたい！でもデータ（レコード）自体がそもそもまだ出来上がってないからフィルターの選択肢に出てこない！」というときに使える方法です。

## 方法①フィルターの「一括で値を追加」を使う
フィルター右上にある「一括で値を追加」で解消できます。
例えば下図のように『あいうえお株式会社』『かきくけこ株式会社』しかデータがなくても、『さしすせそ株式会社』の条件を事前に指定しておくことができます。
これで今後さしすせそ株式会社のデータが入ってきたらその分だけが表示されるようになります。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/f2f41bf0-5f42-005d-f7c1-1a614b8b6dc2.png)

本来であれば一括でたくさんの選択肢を一気に指定するための機能ですが、こういう使い方もできるんですね。

## 方法②検索バーに直接打ち込む
ぶっちゃけこっちの方が速い（気がする）のですが、検索バーに直接打ち込む方法もあります。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/10c8f6eb-8033-2544-8acc-673c85a6799d.png)

ただフィルター条件が複雑なのであれば方法①の方が安全かなというのと、ビジネスユーザーにやってもらおうとするとやっぱり方法①の方がしっくりくるようです。
方法②は玄人向きなのかもしれません。
コマンド打った方が速い！的な。

## おわりに
子供の頃に「あいうえお」よりも「あかさたな」で全部言えた方がなんだかカッコいい時期ってなかったですか？え？なかった？？
KiCADを手探る

#目次
[1.はじめに](#1-はじめに)
[2.KiCADとは](#2-KiCADとは)
[3.ビルド方法](#3-ビルド方法)
[4.取り組んだこと](#4-取り組んだこと)
[5.得た知見、感想](#5-得た知見、感想)
[6.終わりに](#6-終わりに)

# 1. はじめに
この記事は、とある大学の「大規模ソフトウェアを手探る」という実験のレポートとして作成したものです。
「大規模ソフトウェアを手探る」は、「ソースを眺めて全容を把握できるわけがない程大きなソフトウェアをいかに扱い、必要なだけ動作を理解し、変更する」ことをテーマとした実験で実際に使われてるソフトウェアを解析して変更や拡張を行う課題です。

私たちはKiCADというオープンソースの回路エディタを題材に機能を追加することに挑戦しました。

# 2. KiCADとは
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927182/7766e95d-0c6b-6e6d-217e-ea7fd13c000a.png" width="10%">とは、オープンソースの回路設計用CADです。1992年リリースで30年以上の歴史があり、無料で使える回路CADとしては一強です。26年にサービスが終了するEagleから乗り換えを検討されている方も多いのではないでしょうか?

KiCADは様々なソフトウェアから構成される統合的なCADであるというのが特徴です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927182/f69b0de8-f3e2-47cd-50ca-023d1619bff7.png)

設計画面の例は以下の通りです。かなり自由度が高く、趣味から仕事まで問題なく使用できるといった印象です。3DViewerが標準で付いており、実装後の様子を確認できるのも嬉しいポイントです。

><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927182/86ae190e-0de1-f0cd-e4cf-90b8c7ac7319.png" width="40%">  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927182/0132e1dc-38d6-3c3d-9876-23bf4bf5b8a4.png" width="40%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927182/3889342a-2121-ab27-e4cf-7ef1d0e6b15e.png" width="40%">
引用:https://www.kicad.org

ソースコードは[https://gitlab.com/kicad/code/kicad](https://gitlab.com/kicad/code/kicad)にあります。言語はC/C++が大半で115万行以上の大規模なソフトウェアです。

公式ドキュメントが整備されており規約も多いため、コントリビュートする際には確認が必須です。

https://dev-docs.kicad.org/en/getting-started/index.html

# 3. ビルド方法
公式ページにOSごとの環境構築とビルド方法が詳しく書かれています。linuxかmacの人はmakeではなくNinjaでビルドすることをオススメします。(ドキュメントの下の方に書かれています。)

https://dev-docs.kicad.org/en/build/index.html

コードが大規模のため、最初のビルドには30分~1時間かかります。ストレージがかなり必要なので予め開けておきましょう。

# 4. 取り組んだこと
KiCADには多くのプラグインが存在し、思いつく機能拡張案が大体実装されていました。そこでgitlabのstarterラベルがついたIssueに取り組みました。
[starterラベルがついたIssue一覧](https://gitlab.com/kicad/code/kicad/-/issues/?label_name%5B%5D=starter&scope=all&state=opened&utf8=✓)

取り組んだIssueは以下の二つです。それぞれについて記事を参照してください。
## 4-1.Issue #17659
https://qiita.com/IkomaSo/private/1112da35c67f28fc7e74

## 4-2.Issue #13661
https://qiita.com/ogirin/private/6d31858bbd080bd36a71

# 5. 得た知見、感想
KiCADは規約が多くて大変でした。多くの人が参加する大規模なソフトウェアだと、これくらいしないと治安維持ができないのだと感じました。大規模なソフトウェアの開発方法について、大変勉強になりました。

また、管理者との時差が大きくやり取りに時間がかかり、世界に発信していると実感しました。深夜2,3時に返信されることが多く、少しのやり取りでも1日かかってしまうことが多々ありました。顔も見たことのない開発者とコミュニケーションを取る経験が新鮮でした。

私たちは自分からContributeするようなタイプではないので、貴重な経験になりました。普段から使っているソフトウェアに自分の実装した機能が入ると感動しました。

# 6. 終わりに
実験の一環でしたが、とても楽しく実りのあるものでした。皆さんも是非KiCADのコントリビュートに挑戦してみてください。
Vivliostyle でフォントを Noto Sans に設定するテーマを作った

この記事は、先日投稿した私の記事の続きになります。

https://qiita.com/mitsuharu_e/items/9bf2b7eee2767aee2613

事の詳細は以前の記事を読んでもらえればと思いますが、簡単にまとめると Vivliostyle で作成される PDF は一般にコマンドを実行した環境のフォントが採用されます。私は macOS のローカル環境で執筆をして、印刷入稿データは docker で作成しています。また、チームで執筆することもあり、それぞれの執筆環境が同じとは限りません。そのため、フォントが執筆環境に依存するという問題がありました。

## フォントを揃えたい

このフォント問題は認識してましたが、さほど重大ではないと思っていました。しかし、ローカル環境で調整した段落配置が、docker で作成した入稿データと異なっていたことに気付きました。今回はページ数が変わらなかったので影響は少ないですが、ページ数が変わったら大変です。そこで、執筆プロジェクトでフォントを組み込んで、どの環境でも同じフォントとなるようにしました。その方法を先日の記事で書きました。

ここで問題があります。私のいくつか執筆テンプレートを管理しています。それぞれにフォントデータや CSS を追加するのは面倒ですし、フォントデータ（約 50 MB）分ファイルサイズが増えてしまうことが気掛かりでした。そこで、このフォント設定をテーマとして作れば、ビルド設定にテーマを追加するだけ、フォントデータはテーマに付属するので執筆プロジェクト自体に影響しない、ということでテーマを作りました。

## @mitsuharu/vivliostyle-theme-noto-sans-jp

フォントを設定するテーマ [@mitsuharu/vivliostyle-theme-noto-sans-jp](https://www.npmjs.com/package/@mitsuharu/vivliostyle-theme-noto-sans-jp) を作成しました。なお、このテーマに組み込んでいるフォントは Google Fonts の Noto Sans JP と Noto Sans Mono です（Google Fonts のライセンスは商用利用、印刷、再配布を許可しています）。本文のフォントが Noto Sans に、ソースコードなどの等倍フォントが Noto Sans Mono に設定されます。

https://www.npmjs.com/package/@mitsuharu/vivliostyle-theme-noto-sans-jp

導入方法は `vivliostyle.config.js` の `theme` に設定します。フォントを設定するだけなので、他のテーマと一緒に利用してください。また、他の theme でフォントを変更している場合は、それに影響しないように注意してください。

```js:vivliostyle.config.js
module.exports = {
  theme: [
    '@vivliostyle/theme-techbook'
    '@mitsuharu/vivliostyle-theme-noto-sans-jp',
  ],
};
```

このテーマを導入した PDF のフォント情報です。これまでローカルのシステムフォントを利用してたところが、テーマに組み込まれた Noto Sans に変更されました。なお、全角と半角の間に不明な Times フォント（ゼロ幅？）があったり、𝕏 などの文字に T3Font が適用されるなど、一部の文字で他のフォントが使われました。気になりますが、見た目の影響は少ないと判断しました（正直なところ、よく分かってない）。また、埋め込まれていない T3Font に関しては、Adobe Acrobat Pro で文字のアウトライン化してください。

![スクリーンショット 2024-11-05 11.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24345/811e94a6-caeb-8280-9606-eaad407619a3.png)

### テーマ作成

自作テーマは公式ドキュメントを参考にして作成しました。雛形を作るコマンドを実行して、それを編集してテーマを作成しました。注意点として、現時点（2024/11/05）の雛形で設定される `@vivliostyle/cli` のバージョンに不具合があるのか、一部で動作が期待通りになりませんでした。その問題は最新バージョン（記事執筆時は `8.16.0` です）に更新したら直りました。

https://vivliostyle.org/ja/blog/2023/04/23/intro-new-themes/#%E8%87%AA%E5%88%86%E3%81%AE%E3%83%86%E3%83%BC%E3%83%9E%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

## まとめ

このテーマを作ったおかげで、フォント設定がとても簡単になりました。実際に印刷された本の段落が、執筆時と異なるという残念なことが起こらないようにしていきたいです。また、自作テーマの作り方を経験できたのはよかった。機会があればバリバリにカスタムテーマを作ってみたいです。おわり。
どうでもいいコード(もしかしたら勉強になるかも)

このHTMLコードは、無駄に効率が悪い、または意図的に使われている不合理なコードの例です。各部分を詳しく説明します。

### 1. イベントリスナーの追加
```javascript
document.getElementById('box').onclick = function() { alert('クリックしたよ'); };
document.getElementById('box2').onclick = function() { alert('ここもクリックしたよ'); };
```
- **説明**:
  - これは `onclick` イベントをそれぞれ `box` と `box2` の要素に直接バインドしています。この方法は、`addEventListener` を使った方法に比べて柔軟性がありません（複数のリスナーを追加できない、イベントの削除が困難など）。
  - 理想的には、`addEventListener` を使うべきです。例えば、同じ要素に複数のイベントを簡単に追加でき、後で削除も可能です。

### 2. 色をランダムに1秒ごとに変更する
```javascript
setInterval(function() {
    var colors = ["#ff0000", "#00ff00", "#0000ff", "#ffff00", "#ff00ff"];
    document.body.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
}, 1000);
```
- **説明**:
  - 1秒ごとにランダムな色を選んで、`body` の背景色を変更します。
  - 無駄に背景色が頻繁に変わるだけで、ユーザー体験を損ねる可能性が高いです。通常、こうした変更はユーザーの操作に関連した場面で使うべきです。

### 3. 無意味な再帰的関数（スパムアラート）
```javascript
function spamAlert() {
    alert('クリックし続けるよ！');
    setTimeout(spamAlert, 1000); // 終わらない再帰
}
spamAlert();
```
- **説明**:
  - このコードは `spamAlert` 関数を呼び出すと、1秒ごとに `alert` を表示します。しかもその後 `setTimeout` によって再帰的に自分自身を呼び出し続けます。
  - これは **スパム的なアラート** を発生させ、ブラウザを一時的に操作できなくする可能性があります。ユーザーにとって非常に不快であり、悪意のあるコードの一例です。実際には使用すべきではありません。

### 4. その他のスタイル（CSS）
```css
body {
    background-color: #ff0000;
    color: white;
    font-family: Arial, sans-serif;
}
#box {
    width: 100px;
    height: 100px;
    background-color: yellow;
    margin: 50px;
}
#box2 {
    background-color: blue;
    height: 200px;
    width: 200px;
}
.weird {
    color: black;
    background-color: green;
    border-radius: 50%;
    position: absolute;
    left: 50%;
    top: 50%;
    margin-top: -25px;
    margin-left: -25px;
    z-index: 99;
}
```
- **説明**:
  - `body` は赤い背景色、白い文字色、Arial フォントが指定されています。これ自体は特に問題はありませんが、ユーザーにとって視覚的にあまり快適ではないかもしれません。
  - `#box` と `#box2` はそれぞれ異なるサイズ、色、配置が指定されていますが、どちらも目立つ色使いとレイアウトです。
  - `.weird` クラスは円形で中央に配置される要素を定義していますが、`z-index: 99` を使って他の要素の上に表示されることになります。この要素が画面上で干渉する可能性があるため、あまり実用的ではありません。

### まとめ

- **効率が悪いコード**:
  - イベントリスナーの付け方が非効率（`onclick` 直接設定）。
  - 無駄な繰り返しのイベントやアラートの表示（無駄に色を変えたり、再帰的にアラートを表示）。
  
- **悪影響を及ぼす可能性のあるコード**:
  - スパム的なアラート表示 (`alert` の再帰的呼び出し)。これにより、ユーザー体験を著しく損なう可能性があるため、実際には避けるべきです。

このようなコードは意図的に不合理に書かれており、通常は避けるべきパターンです。