OmniAICreator/Qiita-1.07M huggingface dataset:
あけよろ（SpringBootのstaticフォルダに作る際の命名メモ

# 404 Error! Motivation Not Foun!!
昨年は９月ぐらいからなんやかんやありまして、盛大に更新をサボってたえ～すけさんですよ。
今年はスカウトを来ることを期待して、そこそこに更新していければと考えてますよ。
※フルテレが出来てひたすら実装するだけの仕事をしたい。。。

# SpringSecurityを使った際のリソースファイルの制限メモ
SpringBootでSpringSecurityを使う際に、認証関係にて以下のような設定ファイルを定義するかと思います。
```java:SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    // 省略
    http.authorizeHttpRequests(authz -> authz
        .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
    // 省略
    );
  }
}
```
この`PathRequest.toStaticResources().atCommonLocations()`って、
具体的にどこのフォルダに当たるんじゃい？ってあまり理解しないまま適当な名前でフォルダ切って作ってる方もいるかと思うので、上記の定義でどのフォルダが認証対象外（`permitAll()`）になるのかを備忘録として残す。

## で、どこで定義してあるん？
`org.springframework.boot.autoconfigure.security.servlet.StaticResourceRequest.class`の`atCommonLocations`ではこんな実装がされてる。
```java:org.springframework.boot.autoconfigure.security.servlet.StaticResourceRequest.java
public final class StaticResourceRequest {
	public StaticResourceRequestMatcher atCommonLocations() {
		return at(EnumSet.allOf(StaticResourceLocation.class));
	}
}
```
なるほど`StaticResourceLocation.class`というEnumで定義されてるPathが対象なんだね。

## ということで、StaticResourceLocationを見てみる
```java:StaticResourceLocation.class
public enum StaticResourceLocation {
	/**
	 * Resources under {@code "/css"}.
	 */
	CSS("/css/**"),
	/**
	 * Resources under {@code "/js"}.
	 */
	JAVA_SCRIPT("/js/**"),
	/**
	 * Resources under {@code "/images"}.
	 */
	IMAGES("/images/**"),
	/**
	 * Resources under {@code "/webjars"}.
	 */
	WEB_JARS("/webjars/**"),
	/**
	 * The {@code "favicon.ico"} resource.
	 */
	FAVICON("/favicon.*", "/*/icon-*");

	private final String[] patterns;
	StaticResourceLocation(String... patterns) {
		this.patterns = patterns;
	}
	public Stream<String> getPatterns() {
		return Arrays.stream(this.patterns);
	}
}
```

## 要はこんな感じでresources/staticフォルダ内を作っていくよ
```text:ディレクトリ構成
/プロジェクト名/src/main/resources/static/
　├css/
　│　├CSSファイルを置くよ
　├js/
　│　├JavaScriptを置くよ
　├images/
　│　├画像を置くよ
　├webjars
　│　├webjarを置くよ
　├favicon.*(favicon.icoやfavicon.pngとかのファビコンを置くよ)
 ```
ファビコンに関しては、staticフォルダ内なら`icon-*`って名前で定義したファイルが有れば認識してくれるっぽいです。
例：/images/icon-fav.ico　とかでもイケるのではないかなと

 # やべぇ、今更フォルダ名とか返らんねぇよ。。。というプロジェクトの方へ
 単純に`requestMatchers`を追加するだけで大丈夫だよ（知らんけど
```java:SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    // 省略
    http.authorizeHttpRequests(authz -> authz
        .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
        // 画像フォルダをimagesじゃなくて、imgで作っちゃったよって場合
        .requestMatchers("/img/**").permitAll()
    // 省略
    );
  }
}
```
今年(2025年)の抱負ー仕事、趣味、家計

## 2025年にやりたいこと
あっという間に１年が終わり、今年も始まりました。
初詣に行った際に、おみくじを引いたいのですが、
- 家族全員大吉
- 初めて1000円お賽銭を入れる

などめでたいことをたくさんしたので、きっと良い年になるでしょう。

さて、そんな中、今年の抱負を認めたいと存じます。

# 1. 本業の話〜資格、プロジェクト
本業では名ばかりPMOをやっているのですが、
そんな私も以下の願望を抱くようになりました。

**企業のDX戦略で食っていけるような人材になりたい**

DXとは何かを考える年末年始だったのはさることがなら、
３０歳を超えて、悲観も楽観もせず、冷静に人生をどうやって進めて行くかを、
キャリアを本当に実直に考えた結果、以上のような願望を抱くようになりました。

そこで、今年の目標は以下のように設定。
- ITストラテジスト資格取得（４月）
- 国家キャリアコンサルタント資格合格（３月）
- PMP取得（５月）
- GC professional data engineer取得（６月）
- 現在のプロジェクト完遂
- アジャイルのプロジェクトに参画

# 2. 趣味の話〜LinuxとYoutube
これは、趣味の話になりますが、ちょっと以下のことを極めたいという願望。

**Linuxに詳しくなって、Youtubeで創作活動やりたいなぁ**

Linuxは最近、本当に興味が出てきたのですが、あまり金にならなそう？（笑）です。
しかし、本業とはばっちり噛み合うので、それを言い訳にして、楽しみながら詳しくなっていけたらなぁと思っています。LPICとか受けて定点観測しようと思っています。

Youtubeは最近やりたいなぁと改めて思い始めました。
今までまぁまぁ小説とか書いてきたのですが、それを動画にすれば良いじゃんって感じで、これも楽しみながらやっていきたいです。

# 3. 家計の話〜月15万捻出
最後は家計の話です。
去年は結構放漫会計でしたので、改めてここに記します。

**月15万円を貯蓄と投資に回して、ボーナスは全部投資か貯蓄に回す！**

というのをやっていきたいです。
今、ある事情で月5万円という格安の家賃で、妻と子と過ごせています。
そして、妻が働き始めたのでまた家計が少し楽になりそうですので、
頑張ってやっていきたいです。
果たしてできるか、、、
それも、ここで報告していきたいです。
今一度基礎からアウトプットしていこう。AWSサービス【データベース】編

### RDS
- AWSで簡単にリレーショナルデータベースを使えるサービス。EC2にデータベースを入れる方法に比べてインフラ管理が少ない。主にメンテナンス・バックアップ・高可用性が高まる。
- メンテナンス・・・OS、データベースエンジンのメンテナンスの自動化
- バックアップ・・・自動バックアップ、手動スナップショットが可能。
- 高可用性・・・マルチAZをオンにすることで可能

#### Amazon Aurora
- AWSがクラウドに最適化したリレーショナルデータベースエンジン。MySQL,PostgreSQLに互換性。

### DynamoDB
- NoSQL型のフルマネージド型サービス。AZを意識する必要がなく、最初からマルチAZの構成になっている。データ容量が無制限で、使用している容量が課金対象。非リレーショナルデータベース。

- 中規模アクセスで整合性や複雑クエリを必要とする場合はRDS
- 大規模アクセスで自由度の高いデータモデルを扱う場合はDynamoDB

### Neptune
- フルマネージドのグラフデータサービス。
### MemoryDB for Redis
- インメモリデータベースとして使えて、Redisと互換性がある。
### Secret Manager
- データベース認証機能やAPIキーなどのシークレットを安全に保管し、共有利用できるようにするサービス。自動ローテーション機能により定期的にパスワードを更新できる。
年が明けたので素因数分解してみた

えー皆さん、あけましておめでとうございます。2025年になりましたので2025を素因数分解してみようと思いましたのでプログラムを作ってみました
```Python3
year = 2025
prime = []
prm_dic = {}
for i in range(2, year+1, 1):
    cnt = 0
    for j in range(2, i, 1):
        if i % j == 0:
            cnt += 1
    if cnt == 0:
        prime.append(i)
while year != 1:
    for prm in prime:
        if year % prm == 0:
            try:
                prm_dic[prm] += 1
            except:
                prm_dic[prm] = 1
            year = year // prm
for key in prm_dic:
    print("("+str(key)+"^"+str(prm_dic[key])+")", end="")
```
```
(3^4)(5^2)
```
というわけで
```math
3^4×5^2
年明けましておめでとうございます
```
年賀状書くときは句読点付けないようにしませう。
【ポエム】HHKBからKeyball44にしたら心身ともに健康になった話

# はじめに
Keyballは、はんだ付けをして自分で組み立てる必要があります。
「そんなの無理だよ！」という人は、下記の記事を一読することを強くおすすめします。
あなたの悩みがすべて解決されるはずです！

https://fadotech.com/keyball-how-to-build/

ちなみに、私は約半年前に4年間使用した「HHKB Hybrid Type-S」から「Keyball44」という自作キーボードに乗り換えました。

それがきっかけで肩こりや腰痛などの悩みがなくなって心身ともに健康？になったので、その過程を記事としてまとめておきます。

なお、当記事はあくまで個人的な体験談であり感想です。
HHKBが合う人もいれば、Keyballが合う人もいると思います。
あくまで「こういうこともあるんだなー」的な感じの軽い気持ちで読んでいただけますと幸いです。

筆者のキーボード遍歴：
・MacBookのデフォルトキーボード
・HHKB Hybrid Type-S（主に職場で使用していた）
・HHKB Studio（主に自宅で使用していた）
・Keyball44（職場・自宅用に2台持ち）
※ ゲーミングPCではRazerのロープロやラピトリを使用しています。

# 私のキーボたち
とりあえず私のHHKBとKeyball44の写真を置いてきます笑
どんなキーボードの話をするのか写真で確認しておくと、この後の話が理解しやすいと思うので！

### HHKB Hybrid Type-S
![IMG_2011 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/cba294bb-db1b-f57d-878c-559bc8597e1a.jpeg)

### Keyball44
![IMG_2012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/0c5ecd6f-3109-9b33-0572-c6762dd9427b.jpeg)


# HHKBとの出会い
未経験からエンジニア転職をした際に、自分へのお祝いとしてHHKB Hybrid Type-Sを購入しました。

購入したきっかけは、ガジェットYoutuberたちがこぞっておすすめしていたからという単純な理由です笑

確かに「最適化されたキー配列」と「極上の打鍵感」で、すっかりHHKBに魅了されていたのを覚えています。

そのため、当時の私はHHKB以外に自分に合うキーボードはないと確信していまし、今でも購入したことを全く後悔していません！

むしろ感謝しています。

# 違和感の始まり
しかし、HHKBを使い始めてから3年ほど経つころ、腰痛や肩こりに悩まされるようになっていました。

あまりの痛さに病院に通ったりもしましたが改善されず、ついには仕事に集中できなくなるくらいに悪化してしまいます。

「歳のせいもあるのだろうな」と半ば諦めていたのですが、そんな時に出会ったのがKeyball44でした。

# Keyball44との出会い
同僚がKeyball44を使っているのを目にしたのがきっかけでした。

「こんなかっこいいんだー」と一目惚れ的なサムシングです。笑
さらに、HHKB Studioをリモートで使い倒していて、メカニカルキーボードでも全然仕事できることがわかっていたのもデカかったと思います。

ただ、Keyball44はいわゆる自作キーボードというやつで、はんだ付けや組み立てなどを自分でやらなければならないとのこと。

「うん。私には無理！」と諦めかけていた頃、「肩幅に合わせてキーボードを配置できるから、腕や肩への負担が激減するよ！」的なことを同僚から教えてもらいました。

その話を聞いた私は、藁にも縋る思いでKeyballの導入を決意しました。
ちなみに、私のKeyballは組み立てサービスを使って組み立ててもらいました。笑

# Keyballを使い始めてからの変化
そんなこんなでHHKBからKeyballに乗り換えて約半年が経ちました。
現状、以下に紹介するような変化が起きたので、起こった変化となぜこのような変化が起きたのかを自分的に研究してまとめてみました。

### 1. 肩コリや首の疲れが改善
以前HHKBを使用していたときは、キーボードが体の中心に固定されていたため、それに合わせて首や肩に無意識に力が入っていました。

一方、Keyballは左右に分割されたデザインで、自然な手の位置に置くことができるため、首や肩への負担を感じることなく使用することができます。

これは実際に試してみるとわかるのですが、体の中心に腕を寄せて置く場合と、肩幅に合わせて自然に腕を置く場合とでは、首や肩への負担に大きな違いが生まれます。

結果として、肩こりや首の疲れが大幅に改善しました。

### 2.  腰痛の改善
前述の通り、Keyballは肩幅に合わせて左右のキーボードを自由に配置することができます。
そのおかげで腕を自然な角度に保つことができるようになり、姿勢が劇的に改善しました。

姿勢が矯正されたことで、慢性的だった腰痛もほぼなくなりました。

### 3. 腱鞘炎の解消
やや腱鞘炎気味だった右手首はマウス操作が激減したのをきっかけに、完全に治りました。

ただ、Keyballではトラックボール操作で親指を頻繁に使用するため、今度はそっちが心配笑

今はカーソル移動速度を最大に上げて、なるべく少ない動作でカーソルが動くように工夫しています。

### 4. 精神的な安定
健康問題からくるストレスがなくなり、心の余裕も生まれました。
そのお陰で仕事のパフォーマンスも向上しました。

# Keyballが教えてくれたこと
Keyballを導入して気付いたことは、「作業環境を最適化することが健康や仕事のパフォーマンスに直結する」ということです。

# 結論
私が最後に言いたいことは、「エンジニアは作業環境もこだわれ」ということです。
日々進化する技術にキャッチアップするのはもちろんのこと、作業環境も自分に最適化して、日々アップデートすることにより、心身ともに健康でパフォーマンスの高い仕事ができるのだと思います。

## Keyballが気になる人へ
Keyballが下記の記事を読んでみると良いと思います！
とても参考になる記事たちです。

https://pan-weblog.com/others/2237/
https://zenn.dev/kyoh86/articles/9b9da6d1e9d598
偽中国語プログラミング言語を作った話

# 言語の概要
https://github.com/natsuakane/Wei-lang

・計算・変数定義・関数定義・オブジェクト定義などができる普通の言語
・漢字以外を使ってはいけない
・偽中国語っぽい記法

# コード例
## GCD
![スクリーンショット 2025-01-05 8.11.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3572788/49b7c6ab-0ef7-79c2-d4e8-8f79ed867ea1.png)

## フィボナッチ
![スクリーンショット 2025-01-05 8.12.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3572788/2f45c9c9-a9d2-03f8-4f2b-d1ffee4df5aa.png)

# 使い方
## ビルド
```bash
git clone https://github.com/natsuakane/Wei-lang.git
cd Wei-lang
mkdir build
cd build
cmake ..
cmake --build .
```
## 実行
buildディレクトリ内で
```bash
./weilang ファイル名
```

# 文法
wiki参照

https://github.com/natsuakane/Wei-lang/wiki

# 作った感想
どうやったら偽中国語っぽい文字列になるか考えるのが楽しかったです。
はじめてサービス作成した

この度、軽いWebサービスを独力で作成したので備忘録。
筆者のレベルとしては、アプリ、ゲームはUnityを用いて開発経験が7年くらい、Webは今年度からでそろそろ1年。
内容としてはカードゲームのとあるイベントで、戦績をつけておくためのもの。カジュアルなイベントなことと、そこでしか使わないこともあり、ログイン認証などはかなり緩めに作成した。

要件定義
今回のサービスで最初に定義した要件は以下。
1.ユーザーの登録ができること
2.個人で戦績をつけ、記録すること
3.他の人の戦績が混ざらないこと
4.戦績を振り返る事ができること
5.戦績のツイート機能をつけること

使用言語
PHP、HTML、Java Script
そんなに大変そうではなかったのと、時間が割とあったのもあり、勉強も兼ねてフレームワークは使用せず、テンプレートエンジンは自作。

開発環境
ローカル環境はXampp、本番環境はInfinityfreeというサーバーでドメインを取ってそこで実行。
https://dash.infinityfree.com/accounts
大枠を決めてなんとなくコードを書き、css部分やhtmlのおおまかな要素の配置の部分などのフロントエンドはchatGPTに大部分を任せ、バックエンドは全部自力で行った。

苦戦した部分
·ローカルから本番環境にアップすること
普段お仕事ではstg,dev環境へ上げるのはバッチが全てやってくれ、本番環境へは責任者にやっていただいているので裏でどのように動いているのか理解していなかった。自分であげるに当たって接続設定が難航した。
·ローカル環境ではなかった文字化けが本番で現れる
サーバーがイギリス(だったはず)のものだったので、漢字を入力した時に文字化けが起こった。データベースサーバーに接続する際に、charsetを正しく設定する必要があった。ローカルでは日本語が既に許可されていたので特に問題なく進んでいたが、他言語のサーバーをもちいる際には設定を確認する必要がある。

反省点
普段通りMVCによる設計を行ったが、そんなに大きなものでなかったので、むしろ構造が分かりにくくなった気がする。プロジェクトのサイズ感からどのような設計がふさわしいかは導き出せるようにしたい。
逆にCSSは分けなかったが、こちらは分けて別ファイルにしたほうが楽だったかもしれない。複数回CSS部分をコピペするはめになった。
テスト内容をもう少し詰めておくべきだった。今回はカジュアルイベントでの使用だったので、ログインの手間を簡略化するために名前入力でユーザー登録、ユーザー名プルダウン指定でログインという形をとったが、複数回登録して多重にユーザー登録されてしまうという問題が生じた。ただ、この形式でのログインの都合上、同名登録を弾くという形になり、ユーザーの中に同名の人がいた場合に困るので、処理を定義しておくべきだ。
上につながるが、設計段階をちゃんとする。ふだんはすでにあるものを作っていたので全然気にしていなかったが、0から作るとなると会いますな仕様のまま進めると工数があとから膨らみ、大変なことになる。勉強していきたい。

http://pokecaeventquickshooterer.wuaze.com/GLC_event/user/login/
実際のページ
【TS】型抽出のまとめ

# Pick\<T,K>
- オブジェクト型から特定のプロパティの型を抽出する
- ハイフン区切りで複数のプロパティを抽出可能
- プロパティを指定するときは文字リテラル

```ts
type Person = {
  name: string;
  age: number;
  hobby: "soccer" | "game";
  exam: {
    subject: string;
    score: number;
  };
};


// type PickPerson = {
//    name: string;
//}
type PickPerson = Pick<Person, "name">;


/* ハイフン区切りで複数抽出可 */
// type PickPerson = {
//   name: string;
//   age: number;
// }
type PickPerson = Pick<Person, "name" | "age">;
```

:::note warn
#### 指定したプロパティ名も取得するので、ネストしたオブジェクト型を取得する際は注意する
:::

```ts
type Person = {
  name: string;
  age: number;
  hobby: "soccer" | "game";
  exam: {
    subject: string;
    score: number;
  };
};

/* 以下のようにexamプロパティ名も含まれる */
// type PickPerson = {
//   exam: {
//       subject: string;
//       score: number;
//   };
// }
type PickPerson = Pick<Person, "exam">;
```

もしネストしたオブジェクト型のプロパティ名がいらない場合はlookup型を使う。

# lookup型
- 通常のオブジェクトのようにプロパティ名を指定して型を取得できる

```ts
type Person = {
  name: string;
  age: number;
  hobby: "soccer" | "game";
  exam: {
    subject: string;
    score: number;
  };
};

/* 指定したオブジェクト型のプロパティの型のみ取得できる */
// type PickPerson = {
//   subject: string;
//   score: number;
// }
type PickPerson = Person["exam"];
```

もし取得したい対象のオブジェクト型が配列型になっている場合は当たり前だけど、配列型で取得される

```ts
type Person = {
  name: string;
  age: number;
  hobby: "soccer" | "game";
  exam: {
    subject: string;
    score: number;
  }[];
};

/* 元の型と同じく配列型になる */
// type PickPerson = {
//   subject: string;
//   score: number;
// }[]
type PickPerson = Person["exam"];
```

取得した際に配列型にしたくない場合はなんでもよいので数字を指定する
```ts
type Person = {
  name: string;
  age: number;
  hobby: "soccer" | "game";
  exam: {
    subject: string;
    score: number;
  }[];
};

/* 配列のlookup型として指定する */
// type PickPerson = {
//   subject: string;
//   score: number;
// }
type PickPerson = Person["exam"][0];


/* 数字はなんでもよくて、なんならnumber型でもOK */
type PickPerson = Person["exam"][number];
```
UTM上のRISC-V DebianでPythonをビルドしてPythonを実行するまで

# 筆者について

- もうすぐ卒業の高校３年生（何をかこうかな）

# 本編

だいぶ前にRisc-V版のDebianをUTMで実行しました。

https://qiita.com/0_terarin_0/items/9c47ab3637c301a20ba7

最近Pythonを勉強しなおしているのですが、その中でふと「Risc-Vでも実行できるんかな？」と思ったところ、`riscv-gnu-toolchain`を使ってやっていましたが、いろいろ用意するのはめんどくさかったのでUTMのVM上でやってみました。

## 準備

まずはCPythonのソースコードをダウンロードしましょう。

```zsh
git clone https://github.com/python/cpython.git
```

また、依存パッケージをインストールしましょう。必要なものは全てPythonのページに書かれています。

https://devguide.python.org/getting-started/setup-building/#build-dependencies

```zsh
sudo apt-get install build-essential gdb lcov pkg-config \
      libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \
      libncurses5-dev libreadline6-dev libsqlite3-dev libssl-dev \
      lzma lzma-dev tk-dev uuid-dev zlib1g-dev libmpdec-dev
```

もしパッケージが見当たらなかったりしたら、`apt`のソースリストとか確認にしてみてください。参考に載せておきます。

```bash
sudo nano /etc/apt/sources.list
```

```config:/etc/apt/sources.list
deb [arch=riscv64] http://deb.debian.org/debian unstable main
deb [arch=riscv64] http://deb.debian.org/debian sid main
deb-src [arch=riscv64] http://deb.debian.org/debian sid main
```

## ビルド

それではビルドしていきましょう！

```bash
cd cpython
./configure
make -j3
make test -j3
sudo make install -j3
```

`-j3`オプションでマルチプロセスを有効化していますが、ここは適宜変更してください。ちなみに、僕の環境では30分ぐらいかかった記憶です。

## 試してみよう！

ということで、ビルドが終わったら早速遊んでみましょう！

```bash
cd ~; nano test.py
```

```python:test.py
import sys
import os
import platform

def main():
        print(platform.platform())

main()
```

```bash
Linux-6.12.8-riscv64-riscv64-with-glibc2.40
```

## pipは使えない

ここで便利な`pip`が使えるといいのですが、なんと使えません。ビルド時に`openssl`のエラーが出ていた気がしたので、なんとなくそれ関連でビルドがスキップされたのではないかと考えています。この辺はまたじっくり調べていきたいなと思います。

# 最後に

今回はRisc-VエミュレーションでPythonをビルドするというまるで誰得やねん見たいな記事になってしまいましたが、これで多少自分もRisc-Vにのめり込みやすくなったと思っています。お金にさえ余裕があれば、Milk-Vとかもぜひ買ってみたいですね！

https://milkv.io/ja/
Laravelのbladeでコンポーネントを作成する際のJS、CSS記述方法を検討

`@include`を利用して呼び出せるコンポーネントを作成する際、JSとCSSの記述方法について迷ったのでどのような方法が良いのか検討してみました。

## 最初に作成したコンポーネント

最初は以下のようなコンポーネントを作成しました。

```php:popup-component.blade.php
<div>
    <button type="button"></button>
    <div>ポップアップ</div>
</div>

<script>
    jsの処理
</script>

<style>
    cssの記述
</style>
```
上記コンポーネントを以下のように`@include`を利用して特定ページのbladeファイルに設置します。
```php:post-create.blade.php
~ 省略 ~

<div>
    <p>投稿内容を記述してください</p>
</div>
@include('popup-component')
<div>
    <textarea></textarea>
</div>

~ 省略 ~
```
上記のようにすると、HTMLが生成された際にscriptタグやstyleタグがbodyの途中に存在することとなりパフォーマンスや可読性的にもあまり良くないのかなと思いました。
そこで、popup-componentにて`@section`を利用することで、レイアウトファイルの`@yield`で設定したbodyの閉じタグ前に設置できるか試みました。しかし、`@section`の使用上、ページファイルのJSがコンポーネントのJSで上書きされてしまいました。

## 改善したコンポーネント

上記を踏まえてコンポーネントはHTMLのみに変更しました。
```php:popup-component.blade.php
<div>
    <button type="button"></button>
    <div>ポップアップ</div>
</div>
```
上記コンポーネントを以下のように`@include`を利用して特定ページのbladeファイルに設置します。JSやCSSをそれぞれ用意して呼び出します。
```php:post-create.blade.php

@extends('layouts')

~ 省略 ~

@section('style')
    <link href="{{ asset('css/popup-component.css')}}" rel="stylesheet">
@endsection

~ 省略 ~

<div>
    <p>投稿内容を記述してください</p>
</div>
@include('popup-component')
<div>
    <textarea></textarea>
</div>

~ 省略 ~

@section('script')
    <script src="{{ asset('js/popup-component.js') }}"></script>
@endsection

~ 省略 ~
```
JSやCSSの読み込み位置としては問題ないが、「ポップアップを出す」という要件のために複数ファイルを読み込まないといけないのは残念だなと感じました。

## `@stack`と`@push`を利用

`@stack`と`@push`を利用することで上記問題点を解決できました。`@push`はsectionと異なり何度でも追加できるとのことで複数のコンポーネントを読み込む場合も柔軟性がありそうです。

```php:popup-component.blade.php
<div>
    <button type="button"></button>
    <div>ポップアップ</div>
</div>

@push('component-css')
    <script>
        jsの処理
    </script>
@endpush

@push('component-js')
    <style>
        cssの記述
    </style>
@endpush
```
```php:post-create.blade.php

@extends('layouts')

~ 省略 ~

<div>
    <p>投稿内容を記述してください</p>
</div>
@include('popup-component')
<div>
    <textarea></textarea>
</div>

~ 省略 ~
```
```php:layout.blade.php
~ 省略 ~

@yield('style')
@stack('component-css')
</head>

~ 省略 ~

<div>
    <p>レイアウト</p>
</div>

~ 省略 ~

@yield('script')
@stack('component-js')
</body>

~ 省略 ~
```

現状、同一処理の記述が複数箇所に散らばっているので、今後やってくるNext.jsへの移行に備えて、関連するHTML、CSS、JSをまとめていい感じにコンポーネント化できないかと考えていました。`@stack`と`@push`を利用したコンポーネント化は相性が良さそうです。

## 参考文献

https://stackoverflow.com/questions/35672485/what-is-the-difference-between-section-and-stack-in-blade
FastAPI学習コンテンツのご紹介

# はじめに
みずほリサーチ＆テクノロジーズ株式会社の @fujine です。

本記事は、**FastAPIを活用したAPI開発の解説記事の目次ページ**となります。主に初学者を対象に、FastAPIによるアプリケーションの設計・実装・テストをスムーズに習得するためのノウハウを共有することが目的です。

![logo-fastapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2969456/4491fa1a-db0a-acd5-7026-bf6ae1fa26d3.png)

公開済みの解説記事は、次章の「記事一覧」より各リンクをご参照下さい。今後、FastAPIとその関連機能を対象に、テーマ毎に随時執筆していきます。

:::note
FastAPIの公式ドキュメントにもチュートリアルが公開されております。
https://fastapi.tiangolo.com/ja/learn/

基本的にはこのチュートリアルだけでも十分ですが、写経した感想として、

- 記載の通りに実装すると`DeprecationWarning`が発生することがある
- 基本的な機能解説に留まる箇所があり、もう少し実践的な事例が欲しい
- 実装されたコードを検証するテストコードが欲しい

といった課題を感じ、今般、学習コンテンツを新たに作成するに至りました。
:::

# 記事一覧

## FastAPI
|No|タイトル|
|:--|:--|
|1|[FastAPIによるHello Worldとドキュメント生成、テストの実行](https://qiita.com/fujine/items/1fe6a29180befb589854)|
|2|パスパラメータ|
|3|クエリパラメータ|
|4|リクエストボディ|
|5|エラーハンドリング|

## Pydantic
|No|タイトル|
|:--|:--|
|1|BaseModelによるモデル定義|


# 実行環境とバージョン情報
各記事のPythonバージョンは3.13、各パッケージは以下バージョンで統一しております。
実行環境はWindows10 22H2です。

```sh
fastapi[standard]==0.115.6

# tester
pytest==8.3.4
pytest-cov==6.0.0
```
:::note
`fastapi[standard]`とすることで、FastAPIと併用する[Uvicorn](https://www.uvicorn.org/)（ASGIサーバー）等の代表的なパッケージ群を同時にインストールできます。

同時インストールされるパッケージ一覧とそのバージョン情報は、FastAPIの[pyproject.toml](https://github.com/fastapi/fastapi/blob/b9a27be0d44ddcfafd93eae42750ea4d55c4c488/pyproject.toml#L58-L75)をご参照ください。
:::

:::note 
テストを行わない場合は、`# tester`のインストールは省略可能です。
:::

各記事の仮想環境は標準ライブラリの[venv](https://docs.python.org/ja/3.13/library/venv.html)で構築しております。
[poetry](https://python-poetry.org/)や[uv](https://github.com/astral-sh/uv)など、すでに使用しているパッケージマネージャーがあれば適時読み替えて下さい。
出力フィールドは連続型です(SPSS Modeler データ加工逆引き12-9)

# 出力フィールドは連続型です（判別モデル)

![スクリーンショット 2024-12-09 9.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/43f1f6bd-9230-2bbf-4f2b-d19656b44c83.png)

## 1.想定されるトラブル

・ロジスティック回帰/C5.0などの判別予測モデル作成時にエラーが起きる

*判別モデルにカテゴリカルやフラグ型ではなく間違えて数値を予測対象にしてしまった場合に生じるエラーのハンドリング
   
## 2.ストリームとデータのダウンロード

ストリーム

https://github.com/yoichiro0903n/blue/raw/aff54e457bbd858430a65917409de9f803dad3af/binary_model_ng.str

データ

https://github.com/yoichiro0903n/blue/blob/aff54e457bbd858430a65917409de9f803dad3af/datafile.csv

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

![スクリーンショット 2024-12-10 8.24.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/011c9140-1909-dd66-bf4a-2296bb8d92c3.png)

a.入力は以下の通りです。

![スクリーンショット 2024-12-10 8.26.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/c123b29f-83e5-52f5-3fed-20aae83d5c43.png)

b.[データ型]ノードを編集します。[解約フラグ]の[ロール]を[対象]にして解約を予測する判別モデルを作成します。

![スクリーンショット 2024-12-10 8.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/bf202e4a-b1cf-92f0-f6cc-f9ba0e971364.png)


#### エラーの現象を確認する

c.[ロジステック回帰]ノードを実行します。

![スクリーンショット 2024-12-10 8.27.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/102cc10f-1c2c-bd46-1914-060011ed6556.png)

#### 問題を解決する

d.[データ型]ノードを編集します。[解約フラグ]の[尺度]を　[連続型]から[フラグ型]に変更して[値の読み込み]ボタンを押します。

![スクリーンショット 2024-12-10 8.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4dd30d5d-ccce-2a9a-9a76-191e06aeda31.png)

d.[ロジステック回帰]ノードを実行します。モデルが生成/更新されます。

![スクリーンショット 2024-12-10 8.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/fe16e3f1-9d8c-54cf-56f9-57a9bfc230a3.png)

#### 注意事項

CHAIDやランダムフォレストなど連続量を予測できる判別モデルをこのストリームで実行するとエラーにならずモデル作成します。しかし予測値として0から1までの連続量として出力し、本来の2値いずれかを予測してスコアを求める本来の目的とは異なる結果になります。

CSVなどのテキストデータを入力すると1と0の整数2値をフラグとして判別しませんが以下のように読み込み時点で強制的に文字列にする回避策もあります。

![スクリーンショット 2024-12-10 8.29.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0c4f0845-5a0b-216c-b80c-546ab4c69449.png)


## 4.参考情報

#### 可変長ファイルノード

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

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

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

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

https://qiita.com/416nishimaki/items/4bf813e6cba84b2a1008
Windows 11 + WSL2環境でのPython開発環境構築とブラウザ自動操作

# Windows 11 + WSL2環境でのPython開発環境構築とブラウザ自動操作

## 環境構築

### WSL2とUbuntuのインストール
```powershell
wsl --install
wsl --install -d Ubuntu-24.04
```

### Python 3.11の環境構築
```bash
# deadsnakesリポジトリの追加
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.11 python3.11-venv python3.11-dev
```

### 仮想環境の作成
```bash
python3.11 -m venv jupyter_env
source jupyter_env/bin/activate
```

## パッケージのインストール

### 基本パッケージ
```bash
python -m pip install --upgrade pip setuptools wheel
pip install jupyter notebook jupyterlab
```

### browser-useとその依存パッケージ
```bash
pip install browser-use
```

## インストール確認

### 依存パッケージの確認コード
```python
try:
    from maincontentextractor import MainContentExtractor
    from playwright.sync_api import sync_playwright
    import httpx
    from langchain import LangChain
    
    print("Main dependencies imported successfully!")
    
    # パッケージのバージョン確認
    import pkg_resources
    version = pkg_resources.get_distribution('browser-use').version
    print(f"browser-use version: {version}")

except ImportError as e:
    print(f"Import error: {e}")
except Exception as e:
    print(f"Error: {e}")
```

## ブラウザ操作の基本コード

```python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    # ブラウザの起動
    browser = p.chromium.launch()
    
    # 新しいページを開く
    page = browser.new_page()
    
    # Googleにアクセス
    page.goto('https://www.google.com')
    
    # スクリーンショットを保存
    page.screenshot(path='screenshot.png')
    
    # ブラウザを閉じる
    browser.close()
```

## 注意点

- Python 3.12では一部の依存パッケージに互換性の問題があるため、Python 3.11の使用を推奨
- BrowserUseクラスは現在利用できないため、代わりにPlaywrightを直接使用
- テレメトリーを無効化する場合は環境変数 `ANONYMIZED_TELEMETRY=false` を設定

## トラブルシューティング

- Jupyter Notebookが応答しない場合は、カーネルの再起動を実行
- パッケージのインストールに問題がある場合は、`--no-cache-dir`オプションを使用
- WSL2環境でブラウザの表示に問題がある場合は、`headless=True`オプションを使用
【Tips】SAP Fiori（SAPUI5）画面でワイルドカードを使ったあいまい検索を表現したい

# 概要・課題
受託開発企業で働く@fussasyです。SQLではワイルドカード（ * ）を付けてあいまい検索が可能です。SAP GUIの操作でも、ワイルドカード（ * ）を付けてあいまい検索が可能です。しかし、Fioriアプリケーションにおけるプレフィックスやサフィックスは、ただのアスタリスクとして認識されているようです。例えば、以下のサンプルでダイアログの検索フォームで確認してみてください。アスタリスクを含む文字列に対して部分一致検索が実行されています。
【Sample: Select Dialog】

https://sapui5.hana.ondemand.com/#/entity/sap.m.SelectDialog/sample/sap.m.sample.SelectDialog/

「ote」と検索した場合、各Notebook～が検索結果として表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727556/ffe7f40a-ac3a-3072-becd-ffe975dcfe4c.png)

「Note*」とアスタリスクを付けて検索した場合、検索結果には何も表示されない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727556/0b29c5f9-63f7-e5d9-84a7-712ae46c6bc6.png)

SAPシステムに慣れている方にとって違和感を感じるみたいです。あいまい検索の機能について、該当する処理に少し修正を加えてあげる必要がありそうですね。

# 解決策
FioriモデルがJSONModelの場合、検索時の比較はフロントエンド側で実行されます。そしてそれを実現するSAPUI5ライブラリは「sap.ui.model.FilterOperator」となります。

https://sapui5.hana.ondemand.com/#/api/sap.ui.model.FilterOperator

デフォルトでは「FilterOperator.Contains」になっていることが多いです。

```javascript.controller.js
		onSearch: function (oEvent) {
			var sValue = oEvent.getParameter("value");
			var oFilter = new Filter("Name", FilterOperator.Contains, sValue);
			var oBinding = oEvent.getParameter("itemsBinding");
			oBinding.filter([oFilter]);
		},
```

実現したいあいまい検索の仕様は以下の通りです。

①部分一致は、入力値が*で開始および終了する場合
例：「*bc*」で検索すると「bc」「abc」「bcd」「abcd」が結果として表示される。
②前方一致は、入力値が*で終わっている場合
例：「ab*」で検索すると「ab」「abc」が結果として表示される。
③後方一致は、入力値が*で始まっている場合
例：「*cd」で検索すると「bcd」「cd」が結果として表示される。
④完全一致は、入力値の先頭と末尾が*でない場合
例：「abc」で検索すると「abc」が結果として表示される。

上記を実現すると以下のようになります。（一例です）

```javascript.controller.js
		onSearch: function (oEvent) {
          var sValue = oEvent.getParameter("value");
          var oFilter;
          if (sValue === "") {
            // 空文字の場合はフィルターを適用しない
            oFilter = []; 
          } else {
            // ①部分一致
            if (sValue.startsWith("*") && sValue.endsWith("*")) {
              sValue = sValue.substring(1, sValue.length - 1); // 前後の*を削除
              oFilter = new Filter("Name", sap.ui.model.FilterOperator.Contains, sValue);
            } 
            // ②前方一致
            else if (sValue.endsWith("*")) {
              sValue = sValue.substring(0, sValue.length - 1); // 後方の*を削除
              oFilter = new Filter("Name", sap.ui.model.FilterOperator.StartsWith, sValue);
            } 
            // ③後方一致
            else if (sValue.startsWith("*")) {
              sValue = sValue.substring(1, sValue.length); // 前方の*を削除
              oFilter = new Filter("Name", sap.ui.model.FilterOperator.EndsWith, sValue);
            } 
            // ④完全一致
            else {
              oFilter = new Filter("Name", sap.ui.model.FilterOperator.EQ, sValue);
            }
            oFilter = [oFilter]; // フィルターを配列で渡す
          }
          var oBinding = oEvent.getParameter("itemsBinding");
          oBinding.filter(oFilter);
		},
```

アスタリスクであいまい検索可能となりました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727556/68bad2b8-20b8-f7b3-5138-0c1baea01b90.png)

個人的にはワイルドカードでのあいまい検索について、できない方が自然な動作に感じてしまいます。しかし、SAPシステムを使い慣れたユーザーにとっては、コチラの方が自然に感じることが多いそうで、要望としてあがることがあるみたいです。
NEXT.jsで配列から要素を表示する方法


# はじめに
NEXT.jsでのアプリ作成中に、APIから取得した配列データを表示する方法について迷ったので調べてみました


## 1.mapを使用する
map関数の中に記載を行う一般的な方法です、関数の中にJSXを直接記載出来るため可読性も高いです

ちなみにkeyにindexを使うのは非推奨のため、keyに使用する要素がない場合以外は控えた方が良いです

```javascript:page.tsx
"use client";
const array = ['Apple', 'Banana', 'Cherry'];

export default function Page() {

  return (
    <div>
      <ul>
        {array.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
    </div>
  );
}

```

## 2.forループを使用する
forループを使用して要素の表示をすることも可能です、途中で複雑な処理を追加する場合などはこちらでもよいかもしれません

whileなども同様に使用可能です

例

```javascript:page.tsx

"use client";
import { ReactElement } from "react";

const array = ['Apple', 'Banana', 'Cherry'];
const list:ReactElement[] = [];;

for (let i in array) {
  list.push(<li key={i}>{array[i]}</li>);
}

export default function Page() {

  return (
    <div>
      <ul>{list}</ul>
    </div>
  );
}

```
ポイント:

key属性を明示的に設定する必要があります。
手動で配列を生成してからReactの要素に渡します。

## 3.直接記載する
配列を展開する際はあまり良い方法ではありませんが、配列の個数が固定の場合などは直接記載することも可能です

```javascript:page.tsx
"use client";

const array = ['Apple', 'Banana', 'Cherry'];

export default function Page() {
  return (
    <div>
      <ul>
        <li>{array[0]}</li>
        <li>{array[1]}</li>
        <li>{array[2]}</li>
      </ul>
    </div>
  );
}

```

## まとめ
基本的にmap関数を使用した方が可読性がよく使いやすそうです、複雑な処理を途中で入れたい場合であればfor文を使用するといった使い分けてもよいと思います
マネジメント業務は嫌いなので「マネジメントは嫌いですけど」を読んだ

[最強のスタッフ エンジニアは意外とマネジメントぽいこともするかもしれない #スタッフエンジニア - Qiita](https://qiita.com/e99h2121/items/0651c457ebd277b05e5f) と「スタッフエンジニアの道」で思いつつ、でもマネジメントというものが好きになれない。そんな私だがタイトルで興味を持った「マネジメントは嫌いですけど」を読んだ。

[マネジメントは嫌いですけど | 関谷 雅宏 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4297145812)

![](https://m.media-amazon.com/images/I/61Pt5F7XBLL._SY466_.jpg)

マネジメントを生涯やりたくないので、やらないで済むために、2025 年はマネジメントを理解したい。

## 感想

エッセイの趣が強い。それが面白みでもあるのだが、体系だってマネジメントを理解する本ではない。良いフレーズが気まぐれに出てきがちなので、それを拾いながら読むのが良さそう。

「部下やお金や人事評価の面倒なんて見たくない、けれど、現実を変えたい あなたへ」
- アウトプットは60%の力でおこなう理由
- 初心者を教育する仕組みをどう作るか
- 技術者の貢献を評価してもらうには
- 維持·メンテナンスの予算がとりにくいのはなぜか

みたいなことが自伝的にかかれている。書評でも「中小企業でのお財布事情を気にしながらのマネジメントから大企業のVPとしてのマネジメントまでをやってきた筆者の自伝に近い内容」とのこと。


## キーフレーズ

以下、私が線を引きたくなったフレーズ。

- 「やりたくない」というのなら、マネジメントはいらないのでしょうか？
    - 要らないわけはない、ということだと思う。そしてこれが終盤への伏線。
- 問題を発見したら発見者が解決しなければならないという、謎の脅迫観念
    - これがあると、問題を発見、指摘することができないチームになってしまう。それが良くない。マネージャーはそんなしこりを取り除く役割も担う。
- マネジメントの目的は「現実に変化を起こすこと」
    - それがまさにこれ
- うまくいくか、失敗するかは、大雑把に50％の確率で、表が出るか裏が出るかくらいのものでしかない
- 仕事は頼んだほうにも責任がある
    - そう思ってくれているマネージャーは部下として本当にありがたい...
- 今現在ないものを作るのだから、失敗しても今より悪くはならない
- アウトプットを個々の力で測るのではなく、全体の力の総和の割合で考える
- 好かれていようが、嫌われていようが、部下は意地悪なテストをしてくる
- 犬はワンと鳴き、猫はニャンと鳴くのだから、逆はやめて
    - 犬と、猫と、ハイエナも、ナマケモノも、活かせるマネージャーはすごい
- 組織で生かしにくい技術者の例、挙げた例に共通しているのは、組織の目的や相互の能力の向上より、自身の興味と力を優先する傾向が強い
- 仮説を立てて、目標を設定し、実行して、評価する。まちがっていたら修正し、いいものを目指していく。論理的に物事を捉え、現実を見ながら変化させていく。
    - すごく基本的なことだがこれなのだろう。
- 技術も人も進歩していくものだということは、現状に何らかの問題があるのだから、失敗を恐れずに試行錯誤を繰り返して、記録を残していく。
- 今となってつくづく不幸だと思うのは、技術者の貢献を享受する側が、何も問題が起きないということにどれだけ彼らの貢献があるか評価する術を持たないということ。何事もなく昨日と同じように日々が過ぎていくことの裏側にある膨大な技術や、それを維持するための努力を評価することは本当に難しい。
- マネジメントはだれかがこなさなくてはならない役割にすぎないことを忘れないでいるということです。そして、その役割を果たしている人間に特別な価値はない。
    - マネジメントでない立場からしたら、全くそんなことは無いとしか言えない締め。

## まとめ

なんとも、マネジメントは偉大だな、と感じてしまう。

読みやすかった。書評に戻るが「部下」の方が書いておられる以下からすると、やはり筆者はマネージャーとしてもすぐれた方なのだとわかる。笑

> 多分読み進めていて感じる表面的な感想は、「部下に恵まれてんじゃね？コイツ？」になるんじゃないかなと思うんですが、それは文中にある筆者の自身の作り方や環境の作り方によるもので、偶然ではなく必然性があるのではないでしょうか。

> まぁ、全てのマネージャーがこんな感じだと、それはそれで殺伐としてて嫌だなって思いますけど笑
ほら、自主的にレビュー書いてやったぞ。いい部下だろ。ほめろ。

エッセイではありますが、良い部下、良いマネージャー、良いチームのエッセンスが詰まったエッセイなのだと思います。

以上です～
secrets と MYSQL_PASSWORD_FILE と optional:configtree と .gitignoreを使ってみた

# はじめに
自宅PCのDockerでSpring BootとMySQLの趣味管理システムを運用しようと思い、パスワードをGitHubに上げたくなかったので、調べた結果をまとめました。

同じような人は少ないかもしれませんが参考になれば幸いです。

# 実現したいこと
MySQLのパスワードをGitHubに上げない。

# バージョン
Docker 27.4.0
Docker MySQL Image 8.4.3
Spring Boot 3.4.1
git 2.44.0
Windows 10


# やりかた
### 概要
secrets と MYSQL_PASSWORD_FILE と optional:configtree と gitignoreを使う。

### ソース
https://github.com/tarosuke777/spring-boot-docker-secret/

### 詳細
1.パスワードファイルを作成
```
secrets/mysql_root_password
secrets/mysql_user_password
```

2.docker-compose.yml の secrets に パスワードファイル を指定
```
docker-compose.yml
secrets:
  mysql_root_password:
    file: ./secrets/mysql_root_password
  mysql_user_password:
    file: ./secrets/mysql_user_password
```

3.docker-compose.yml の secrets に 2で指定した変数を指定
```
docker-compose.yml
    secrets:
      - mysql_root_password
      - mysql_user_password
```

4.docker-compose.yml の MYSQL_PASSWORD_FILE に /run/secrets/パスワードファイル を指定
```
docker-compose.yml
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
      MYSQL_DATABASE: secret-demo
      MYSQL_USER: secret-demo
      MYSQL_PASSWORD_FILE: /run/secrets/mysql_user_password
```

5.application.yml の spring.config.import: optional:configtree: に /run/secrets を指定
```
application.yml
spring:
  config:
    import: optional:configtree:/run/secrets/
```
6.application.yml の spring.datasource.password に ${パスワードファイル} を指定
```
application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: secret-demo
    password: ${mysql_user_password} 
```
7..gitignore に パスワードのフォルダを追加
```
### secrets ###
/secrets/
```

# 参考資料
### docker-compose の secrets
https://docs.docker.com/compose/how-tos/use-secrets/

### MYSQL_ROOT_PASSWORD_FILE
https://hub.docker.com/_/mysql

### Spring Bootの optional:configtree 
https://spring.pleiades.io/spring-boot/reference/features/external-config.html

### gitigonore
https://git-scm.com/docs/gitignore

# やりかたに辿り着いた流れ
1.docker-compose.xml にパスワードを書かないようにするためには？と調べて以下を発見。
https://qiita.com/myabu/items/89797cddfa7225ff2b5d

ふむふむと、環境変数ではなくsecretsがあることを知る。

2.application.yml にパスワードを書かないようにするためには？と調べて以下を発見。
https://stackoverflow.com/questions/70007676/how-to-handle-docker-secrets-in-application-properties-files

ふむふむと、spring.config.import と optional:configtree というモノがあることを知る。

3.spring.config.import を調べてみると、以下を発見。
https://spring.pleiades.io/spring-boot/reference/features/external-config.html

4.試してみる
windowsでiverilog その177

# 概要　
windowsでiverilogやってみた。
cpuなverilog見つけたので、やってみた。
テストベンチ、書いてみた。

# 参考にしたページ

https://qiita.com/asfdrwe/items/8dd955240b8291346384


# cpuの仕様
レジスタマシン
- レジスタ(4bit)
Aレジスタ
Bレジスタ
OUTレジスタ
プログラムカウンタ(PC)
フラグレジスタ キャリーフラグ(1bit)
算術論理演算装置(ALU) 4bit+4bitの加算演算のみ

- 命令メモリ
8bit16バイト

- 入出力
4bit入力ポート
4bit出力ポート(OUTレジスタ接続)
- 命令セット
8bit固定長
上位4bitが命令、下位4bitが即値

- 命令一覧
(A => Aレジスタ、B => Bレジスタ、OUT => OUTレジスタ、PC => プログラムカウンタ、 IN => 入力ポート、 IM => 即値)

|命令	|ニモニック	|意味
|:-|:-|:-|
|0000	|ADD A, Im	|A + 即値(Im)をAに代入 (A + Im => A)
|0001	|MOV A, B	|BをAに代入(B + 0000 => A)
|0010	|IN A		|入力ポートの値をAに代入(IN + 0000 => A)
|0011	|MOV A, Im	|即値(Im)の値をAに代入(Im + 0000 => A)
|0100	|MOV B, A	|AをBに代入 (A + 0000 => B)
|0101	|ADD B, Im	|B + 即値(Im)をBに代入 (B + Im => B)
|0110	|IN B		|入力ポートの値をBに代入 (IN + 0000 => B)
|0111	|MOV B, Im	|即値(Im)の値をBに代入 (Im + 0000 => B)
|1001	|OUT B		|BをOUTレジスタに代入 (B + 0000 => OUT)
|1011	|OUT Im		|即値(im)をOUTレジスタに代入 (Im + 0000 => OUT)
|1110	|JNC Im		|キャリーフラグが立っていないならImにジャンプ (Im + 0000 => PC if carry)
|1111	|JMP Im		|Imにジャンプ (Im + 0000 => PC)

# 投入したコード

```
		rom[0] <= 8'b1011_0011; // OUT 3
		rom[1] <= 8'b1011_0110; // OUT 6
		rom[2] <= 8'b1011_1100; // OUT 12
		rom[3] <= 8'b1011_1000; // OUT 8
		rom[4] <= 8'b1011_1000; // OUT 8
		rom[5] <= 8'b1011_1100; // OUT 12
		rom[6] <= 8'b1011_0110; // OUT 6
		rom[7] <= 8'b1011_0011; // OUT 3
		rom[8] <= 8'b1011_0001; // OUT 1
		rom[9] <= 8'b1111_1001; // JMP 9
		rom[10] <= 8'b0000_0000; // NOP
		rom[11] <= 8'b0000_0000;
		rom[12] <= 8'b0000_0000;
		rom[13] <= 8'b0000_0000;
		rom[14] <= 8'b0000_0000;
		rom[15] <= 8'b0000_0000;
```

# サンプルコード

```
module test;
	reg clock = 1'b0;
	reg reset_n = 1'b0;
	reg [3:0] reg_in = 4'b0000;
	wire [7:0] opcode;
	wire [3:0] out_port;
	wire [3:0] pc_out;
	wire [3:0] alu_data;
	TD4 u(clock, reset_n, reg_in, pc_out, opcode, out_port, alu_data);
	initial
	begin
		clock = 1'b0;
		forever
		begin
			#1 clock = ~clock;
		end
	end
	initial
	begin
		reset_n = 1'b0;
	#1
		reset_n = 1'b1;
	#100
		$finish;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$monitor("%t: pc = %h, opcode = %h, in_port = %h, out_port = %h, alu_data = %h", $time, pc_out, opcode, reg_in, out_port, alu_data);
	end
endmodule

```

# 実行結果

```
>vvp a.out
VCD info: dumpfile test.vcd opened for output.
                   0: pc = 0, opcode = b3, in_port = 0, out_port = 0, alu_data = 3
                   2: pc = 1, opcode = b6, in_port = 0, out_port = 3, alu_data = 6
                   4: pc = 2, opcode = bc, in_port = 0, out_port = 6, alu_data = c
                   6: pc = 3, opcode = b8, in_port = 0, out_port = c, alu_data = 8
                   8: pc = 4, opcode = b8, in_port = 0, out_port = 8, alu_data = 8
                  10: pc = 5, opcode = bc, in_port = 0, out_port = 8, alu_data = c
                  12: pc = 6, opcode = b6, in_port = 0, out_port = c, alu_data = 6
                  14: pc = 7, opcode = b3, in_port = 0, out_port = 6, alu_data = 3
                  16: pc = 8, opcode = b1, in_port = 0, out_port = 3, alu_data = 1
                  18: pc = 9, opcode = f9, in_port = 0, out_port = 1, alu_data = 9
td4.v:170: $finish called at 101 (1s)

```

以上。
Javaで「パネルにラベルやボタンなどのコンポーネントを追加する」の動作を確認してみた。

# 概要

Javaで「パネルにラベルやボタンなどのコンポーネントを追加する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/tutorial/jpanel/index3.html

# 実装

以下のファイルを作成しました。

```Sample.java
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.BorderLayout;

class Sample extends JFrame{
  public static void main(String args[]){
    Sample frame = new Sample("MyTitle");
    frame.setVisible(true);
  }

  Sample(String title){
    setTitle(title);
    setBounds(100, 100, 728, 400);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = new JPanel();

    JButton button1 = new JButton("Open");
    JButton button2 = new JButton("Cancel");
    JButton button3 = new JButton("Help");

    panel.add(button1);
    panel.add(button2);
    panel.add(button3);

    add(panel, BorderLayout.CENTER);
  }
}
```

以下のコマンドを実行しました。

```
$ javac Sample.java 
$ java Sample
```

# まとめ

何かの役に立てばと。
英語が苦手でも洋書の技術書を読破する

# はじめに

本記事は初めて洋書の技術書を１冊読破した際の体験記事になります。
初めて洋書の技術書の購入に迷っている方・読もうとしている方にとって参考になればと思い記事にしました。

# 動機

昨年末、正月休みにチャレンジすることを考えていて、Kotlin コルーチンの深堀りをしたいと思い、せっかくなので紙の本で勉強したいなと、書籍を検索していました。
しかし、深堀りするとなると英語の書籍が候補になってきます。
普段英語のドキュメントをブラウザの翻訳に頼ってきた自分に、紙の洋書が読めるのかという不安はありましたが、英語と技術の両方を向上させたくチャレンジすることを決意しました。

そして今回購入して読破した書籍はこちらになります。[Kotlin Coroutines: Deep Dive (Kotlin for Developers)](https://www.amazon.co.jp/Kotlin-Coroutines-Deep-Marcin-Moska%C5%82a/dp/8396395837)

本編が約450ページ、章末問題の回答が50ページの構成です。

# 結果

2024年12月19日からすこし読み始めて、30日から本腰を入れて読み、なんとか2025年1月5日に読み終えました。

内容理解度は、書籍の章末演習がほぼ自力で解けるくらいに身についていました。
もともとコルーチンの知識や経験がある状態で読んでいますので、理解へのハードルがそこまで高くなかったこともありますが、この書籍がコルーチンを体系的に上手く解説していたことが理解につながっていると感じました。

しかし、この後に記述しますが、実際に英語を読めて理解しているわけではありません。

# どのように読んだか

最初は頭で翻訳しながら読み進めようとしていましたが、正しく訳せていないところが多いと感じたため、すぐさま方針転換。

Google翻訳にひたすら打ち込み、結果を markdown テキストファイルに貼り付けていき、結局まるまる翻訳することに。

翻訳入力のコツですが、コードフォントのところは、\`\`で囲うと日本語に翻訳されず、\`\`も維持された翻訳になります。

例えば、

```
Asynchronous coroutine builders (`launch` and `async`), which start an asynchronous coroutine on a scope.
```
このように英文を入力すると、
``` 
非同期コルーチン ビルダー (`launch` および `async`)。スコープ上で非同期コルーチンを開始します。
```
のように翻訳結果が得られ、これを markdown で出力すると、

非同期コルーチン ビルダー (`launch` および `async`)。スコープ上で非同期コルーチンを開始します。

となっていい感じになります。

# まとめ

読破できた要因をまとめます

- ある程度前提知識のある技術書を選択した
- まとまった時間が確保できる正月休みを利用した
- 頭で翻訳しながら読むことを諦め、翻訳ツールに頼った
- 英語とコルーチンに対する学習モチベーションが高かった

得られた知識

- 技術書の内容
  サスペンドコルーチンからのレジュームを担う Continuation の存在は初めて知りました
- よく出てきた英単語の意味
  typical: 典型的,一般的　propagate: 伝播する　inherite: 継承する

# 最後に

翻訳ツールに頼ったことが英語の勉強になったかは疑問が残ります。

しかし英語の文章に慣れた感覚はありますので、そのうちツール無しで読めるようになるのか、今後も継続して洋書の技術書にチャレンジしていきたいと思います。
[AWS #35] Amazon Athena

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
皆さまお疲れ様です。
年末年始はいかがお過ごしでしたでしょうか？
私は大晦日に体調を崩し、受診したら「インフルエンザA型」と診断され元日以降も寝たきり状態で正月を迎える2025年となってしまいました。

今回はストレージサービスにある<font color="c00000">**「Athena（アテナ）」**</font>について見ていきたいと思います。
AWSが提供する **「データ分析サービス」** で、S3に保存されているデータを**SQLで分析することができます。**

## Amazon Athena
AthenaはAWSの **「データ分析サービス」** の１つです。
S3に格納されているデータを直接分析することができ、簡単に操作ができます。（記述の言語は「SQL」を使用しています）

:::note info
SQLは**データベース言語**の中でも**最も普及**しているため使い勝手も良い
:::

**S3バケット**に保存されている **「JSON」「CSV」** などのテキストデータに対してSQLクエリを実行できます。

「JSON形式」➡ これに保存されている大量のログデータに対する検索、集計、分析などの処理を一般的なSQLクエリで実行できます。

:upside_down: Athenaは <font color="c00000">**「サーバーレス」**</font> つまり、**サーバーを意識せずに利用することができる**サービス・アーキテクチャを指しています。これにより<font color="c00000">**セットアップや管理が必要なインフラストラクチャはありません**</font>..というのもポイントの一つになりますかね。
![AWS34_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/6a122dc2-ac6f-d15f-f8b3-02b47324907c.png)

## おわりに
今回のちょっとしたまとめになります。

:::note info
<font color="c00000">**Athena**</font>は、**S3に保存されているデータ**に対して**SQLクエリを実行できるサービス**です
:::

システムエンジニアに馴染みの深い「SQL」を記述言語として利用しており、様々なデータ形式に対応しています。またサーバーレスという点からクエリを実行した分だけの従量課金なため、より作業コストや運用コストが抑えられます。最後までお読みいただきありがとうございました！
>>**日頃より活用している参考書です。**
>> **「参考書」**
[**AWS認定クラウドプラクティショナー改定第3版（Amazon Athenaは280-281ページ）**](https://x.gd/19i6N)
>

> **「AWS公式サイト」**
[**Amazon Athena**](https://aws.amazon.com/jp/athena/)

> **「Youtube」**
[**【AWS Athena/QuickSigh】ソリューションアーキテクト アソシエイト 第25回講座**](https://x.gd/Y4XhR)
>
Javaでのオブジェクト指向プログラミング

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

今回は、Javaにおける`this`キーワードについて学んだことをアウトプットします。


インスタンス変数へのアクセス
--
`this`は、現在のオブジェクト（インスタンス）を指し示す参照です。

例えば、クラス内のインスタンス変数とメソッドの引数が同じ名前である場合、`this`を使うことで区別できます。

```java
public class Person {
    String name;  // インスタンス変数

    // コンストラクタ
    public Person(String name) {
        this.name = name;  // 引数とインスタンス変数を区別する
    }

    public void introduce() {
        System.out.println("My name is " + this.name);  // インスタンス変数にアクセス
    }
}

```

この場合、コンストラクタの引数`name`とインスタンス変数`name`が同じ名前なので、`this.name`を使ってインスタンス変数にアクセスしています。

```java
public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice");  // "Alice" を引数として渡す
        person.introduce();  // introduce メソッドを呼び出す
    }
}

My name is Alice
```

コンストラクタから別のコンストラクタを呼び出す
--
Javaでは、1つのコンストラクタから別のコンストラクタを呼び出すことができます。これを「コンストラクタチェイニング」と呼びます。その際、`this`を使って別のコンストラクタを呼ぶことができます。

```java
public class Person {
    String name;
    int age;

    // 引数なしのコンストラクタ
    public Person() {
        this("Unknown", 0);  // 別のコンストラクタを呼び出す
    }

    // 引数ありのコンストラクタ
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println("My name is " + name + " and I am " + age + " years old.");
    }
}

My name is Unknown and I am 0 years old.

```

引数なしのコンストラクタから`this("Unknown", 0)`で引数ありのコンストラクタを呼び出しています。

メソッド内での自己参
--
`this`を使って、現在のインスタンスを他のメソッドに渡すことができます。たとえば、インスタンス自身を引数として別のメソッドに渡すときに使用します。

```java
public class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    public void greet(Person otherPerson) {
        System.out.println("Hello, " + otherPerson.name);
    }

    public void introduce() {
        this.greet(this);  // 自分自身を引数として渡す
        System.out.println("My name is " + this.name);
    }
}
```

`introduce`メソッドが自分自身を引数として`greet`メソッドに渡しています。

### 実行の流れ

例えば、次のように `Person` のインスタンスを作成し、`introduce()` メソッドを呼び出すと仮定します。

```java
public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice");  // 名前が "Alice" の Person インスタンスを作成
        person.introduce();  // introduce メソッドを呼び出す
    }
}

Hello, Alice
My name is Alice
```


- `greet(this)` の呼び出しにより、`this`（つまり、`person` インスタンス）が `greet()` メソッドの引数 `otherPerson` に渡され、`otherPerson.name` は `"Alice"` となります。これにより、`"Hello, Alice"` が出力されます。
- 次に、`introduce()` メソッド内で `this.name`（つまり `"Alice"`）が表示されます。



静的メソッド　使用不可
--
`this`はインスタンスを参照するため、静的メソッド内では使用できません。静的メソッドはクラス自体に属するため、インスタンスを指すことができません。

```java
public class MyClass {
    static void myMethod() {
        // this; // エラー: 静的メソッド内でインスタンスへの参照は使用できない
    }
}
```

静的メソッド内では、クラスのインスタンスを明示的に作成してからそのインスタンスを操作する必要があります。
Go言語でデスクトップアプリを開発できるツールWailsを使ってMac OS版を開発する時の注意点

# はじめに

Go言語でデスクトップアプリを開発できるツールWails

https://wails.io/ja/

があります。

このツールを使ってMac OS版のアプリを開発していますが、App Storeで購入した人から、Mac OSの古いバージョンで起動すると画面が真っ白になったというバグレポートを頂きました。

原因を調べてWailsのGetting Started

https://wails.io/ja/docs/gettingstarted/firstproject

に従って作成したプロジェクトのデフォルト設定で注意すべき点を見つけたので、その紹介です。


# 現象

本来は、起動すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/30b70d78-18b2-12d0-c1f3-369a99dac414.png)

という画面を表示するアプリがあります。

Mac OS  Catalina

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/90eec1fb-301c-0d74-dc7f-270b17f76d06.png)

で起動すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/1a09417d-5545-c91f-1231-4d712c5b48ed.png)

のようにプログラムは起動しますが、画面が真っ白になってしまいます。

2022年に同じWailsを使って開発した別のアプリは、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/cdfa5ece-50e4-5252-8a36-f9c144f7ac6a.png)

のように画面が表示されます。
2022年のWailsで開発したアプリは、問題なかったようです。

Montereyでも、画面は表示されました。


# 原因

Wailsのアプリをデバッグモードで起動してWebインスペクター（ブラウザーの開発者ツールと同じ）で確認するとどうやらJavaScriptのエラーで画面を読み込めないことが原因のようす。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/d7257472-b44e-3556-6842-8bf1aa89ea13.png)

WailsはWebKit（WebView）を利用して画面を表示しますが、古いMac OSの環境で対応していない機能を使っているようです。

# 対策

古いMac OSは、WebKit(たぶんSafari)のアップデートを提供していないためOSの更新では対応できません。
開発しているアプリの最低動作OSのバージョンを制限して対策するのがよいと思います。

Wailsの

```terminal
$wails init -n <Project Name>
```

コマンドで作成したプロジェクトの雛形では、OSの最低バージョンが

```xml:build/darwin/Info.plist
        <key>LSMinimumSystemVersion</key>
        <string>10.13.0</string>

```

と設定されています。このままだとHigh Sierraから動作することになります。
当然Catalinaも対象になってしまいます。

そこで、ここを書き換えて、

```xml:build/darwin/Info.plist
        <key>LSMinimumSystemVersion</key>
        <string>13.0.0</string>

```
にしました。2025年の1月時点のサポートOSの範囲にしています。

https://wails.io/ja/docs/guides/mac-appstore

に基づいて作成したパッケージは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/7c5de8d7-2000-ebc5-77ea-703679cfcd8b.png)


のようにインストールできなくなりました。


# 余談

この問題が発生したWailsを使ったアプリは、

https://note.com/twsnmp/n/na5c62f59833d

で紹介しているものです。
デバッグの原則　エラーを直すとき守るべきこと

# デバッグで守るべきことを教えます。

## フォーラムを極力避ける
フォーラムなどでは基本、喧嘩売りたい人と、知ったかぶりであふれています。
Q:エラー○が起きています！△がしたいです！
A:なんで△がしたいのですか？
という回答は凄い多いです。

## トレースは嘘をつかない
トレースは神様のように拝めましょう。
デバッガーとトレースだけは嘘をつくことがほとんどないので、トレースの結果から物事を推測しましょう。

## 公式ビルドを必ず使わない。
難易度高いだと？ふざけるな。
公式ビルドは、エラーであふれていたりめちゃくちゃだったりします。
真面に動かない可能性があるのでソースコードから始めましょう。
クローズドソースの場合は知りません。

## 第三者が作ったものを絶対信じない
ソースコードについて良く知らず、自分の好き勝手に改造されたビルドやソースコードを使うと痛い目を見ます。
必ず公式のdocsなどを使いましょう。

## コードから直す。
必ずトレースを読んで、そのトレース先のコードもしくは表記されてる文面から原因を追究しましょう。
そうすれば、確実な答えが返ってきます。

極端な文ではありますが、これだけをすれば解決が楽になるでしょう。
【記事まとめ】自作Pythonモジュール公開のお役立ち情報

## はじめに
皆さんあけましておめでとうざいます。新年一発目の記事です。先日、PyPIに自作のモジュールを公開したので、その時に役立った情報や、知っておきたかった情報を初心者目線でまとめました。

## 公開する前に
公開手順に入る前に知っておきたい情報です。

### PyPI
そもそも公開する場所がよく分かっていないと困ります。簡単に言えば、アカウントを作って、ここにモジュールを上げれば、皆もpipして使えるようになるという感じです。

https://pypi.org/

### セマンティックバージョニング
semantic（意味論）から分かるように、バージョンの数字には意味があるみたいです。~~筆者は雰囲気でつけてるもんだと思ってました~~

https://semver.org/lang/ja/

>バージョンナンバーは、メジャー.マイナー.パッチ とし、バージョンを上げるには、
>1. APIの変更に互換性のない場合はメジャーバージョンを、
>2. 後方互換性があり機能性を追加した場合はマイナーバージョンを、
>3. 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。
>　プレリリースやビルドナンバーなどのラベルに関しては、メジャー.マイナー.パッチ の形式を拡張する形で利用することができます。

だそうです。これを知っていたほうが、この後の手順でバージョンをいじるときに、悩まなくて済みますね！

### READMEの書き方
README.mdはパッケージの顔みたいなもんなので、書くときに意識することくらいは知っていたほうがいいと思います。

https://qiita.com/koeri3/items/f85a617dcb6efebb2cab

ここでは載ってませんが、サンプルプログラムとか、短くて済むならREADMEに書いちゃった方が、個人的には親切だと思います。

### MITライセンス
自由度がとても高いライセンスです。個人でアップする分には、特にこだわりがなければ、これにしておいて問題ないと思われます。このくらいならAIでも書いてくれそうですが、以下の記事にサンプルが載っていたので紹介しておきます。

https://qiita.com/suwanishi77/items/82629633c16b086d1cd2

## 公開手順

### GitHub
GitHubを使うので、アカウントを持っていない人は作っておきましょう。Qiitaのアカウントを作るのにも使えるので、ここでやめずに、この機会にぜひ。

https://github.com/

### 詳しい手順
この記事を書くきっかけになったのがこちらでもあります。もともと公開手順を記事にしたかったのですが、もうめっちゃ詳しい解説があったので、断念しました。

https://qiita.com/c60evaporator/items/e1ecccab07a607487dcf

### `__main__.py`について
コマンドラインツールを公開する場合は、上の手順で`__init__.py`と一緒に、`__main__.py`というのも作りましょう。そうすると
```sh
python -m your_package
```
のようにパッケージ名から実行できる機能を持たせることができます。

`__init__.py`と違って、このファイルには直接処理を書いていいです。また、パッケージ内の他のファイルから`import`して、それらの機能を実行するみたいな使い道もアリだと思います。


## 公開後
### バージョンアップ
　機能を追加するときはバージョンアップをしましょう。`setup.py`のバージョンの数字を上げて、上の手順のビルドからやり直せばできます。GitHubにバージョンごとのタグも付けてあるわけですし、`dist`とか`build`とかは一回消しちゃってからやった方がいいと思います。distの中に旧バージョンと新バージョンが混在したりすると面倒なので。
　注意点として、同じバージョンでのアップロードができないので、**本当にちょっとした変更（README書き換えたとか）でも数字を上げる必要があります。**

### インストール数の確認
　パッケージを公開したら、どのくらいダウンロードされているのか気になりますよね？それが見られるサイトがこちらです。日ごとの推移とかもグラフにしてくれるので、筆者は毎日気になって確認しています。次の日の16時くらいになると更新されているかなって印象ですね。正確なところは分かりませんが。
 
 https://pepy.tech/

↓こんな感じのバッジも作ってくれます（押すとpepy.techのページに飛びます）
 [![PyPI Downloads](https://static.pepy.tech/badge/typehandler)](https://pepy.tech/projects/typehandler)

## 最後に
　ここまで読んで下さりありがとうございました。ここの記事とかサイトとかを全部活用すれば、とりあえず困ることはないと思いますがどうでしょうか？手順とかをまとめているサイトは、他にもいくつか見受けられました。しかし、バージョンの付け方とか、本題と違う情報は別途探さないと載ってないので、痒い所に手が届くといいかなと思っています。

　最後に宣伝です。筆者が公開したのは、タイピングゲームを簡単に作れるモジュールです。結構自信作なので、使ってみてもらえると嬉しいです。ゲーム制作未経験でも、なんなら課題以外でプログラムを書いたことがない人でも、使えるくらいの簡単さと自負しています。（というかサンプルコードのお題を書き換えれば、それだけで自作のタイピングゲームが作れてしまいますが）

PyPI

https://pypi.org/project/typehandler/

GitHub

https://github.com/Prosamo/typehandler/tree/main