OmniAICreator/Qiita-1.07M huggingface dataset:
個人的備忘録：RDS のシークレット取得だけを許可する IAM ポリシー設定ガイドを体系的にまとめてみた

## はじめに
AWS Secrets Manager は、データベース認証情報や API キーなどの機密情報を安全に管理できるサービスです。RDS の認証情報のみを取得したい場合は、適切な IAM ポリシーを設定する必要があります。

本記事では、**RDS の認証情報のみを取得できる IAM ポリシーの作成方法** について解説します。

また、セキュリティの基本原則である **最小権限の原則（Principle of Least Privilege, PoLP）** に従い、不要な権限を付与しないことの重要性についても触れます。

## 記事を書こうと思ったきっかけ
AWS Secrets Manager を利用する際、シークレット全体に対するアクセス許可を与えるのではなく、**特定のシークレット（RDS の認証情報）だけにアクセスを制限したい** という要望が多くあります。

適切な IAM ポリシーを作成することで、**最小権限の原則** を適用し、不要な権限によるセキュリティリスクを軽減できます。

## RDS の認証情報のみを取得できる IAM ポリシー

RDS の認証情報だけを取得したい場合は、Secrets Manager の `GetSecretValue` アクションのみに限定する IAM ポリシーを作成します。

### **ポリシー JSON**
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:rds-*"
        }
    ]
}
```

### **ポリシーのポイント**
- `secretsmanager:GetSecretValue` のみを許可し、シークレットの取得以外の操作（作成・更新・削除など）は禁止。
- `"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:rds-*"` により、RDS 関連のシークレットのみ取得可能。
- AWS アカウント ID とリージョンを適切なものに変更。

このポリシーは、**最小権限の原則に基づき、必要なリソースにのみアクセスを許可する** ように設計されています。

これにより、IAM ユーザーやロールが不要なシークレットにアクセスすることを防ぎ、セキュリティリスクを最小限に抑えます。

#### **環境に応じた設定変更**
RDS のシークレットは通常 `rds-*` というプレフィックスがついていますが、環境によって異なる場合があります。その場合は、個別のシークレット ARN を指定することで適用できます。

```json
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:my-rds-credentials"
```

このようにリソースを細かく指定することで、アクセス権限をさらに制限し、**不要なシークレットへのアクセスを防ぐ** ことができます。

## 最小権限の重要性
IAM ポリシーを作成する際には、常に **最小権限の原則** を意識することが重要です。

### **なぜ最小権限が重要なのか？**
1. **セキュリティリスクの低減**
   - 不要な権限を付与すると、意図しない操作や情報漏洩のリスクが増加します。
   - 例えば、Secrets Manager の `ListSecrets` を許可すると、不要なシークレットの存在を知ることができ、潜在的な攻撃の対象になり得ます。

2. **内部不正の防止**
   - IAM ユーザーやロールに過剰な権限を与えると、内部の悪意あるアクションによってシークレットが漏洩するリスクがあります。
   - 必要最低限のアクセスのみ許可することで、悪意ある操作を防ぎます。

3. **コンプライアンス対応**
   - AWS 環境のセキュリティ基準を遵守するため、最小権限の原則を適用することが求められます。
   - SOC 2、ISO 27001 などのセキュリティフレームワークでは、適切な IAM 管理が重要視されています。

最小権限を適用することで、AWS 環境の安全性を高め、リスクを最小限に抑えることができます。

## まとめ
RDS の認証情報を適切に管理するために、**最小権限の IAM ポリシー** を設定することが重要です。

- `secretsmanager:GetSecretValue` のみ許可し、取得以外の操作は禁止する。
- `Resource` を制限し、RDS の認証情報のみにアクセスを許可する。
- 環境に応じて `rds-*` 以外のプレフィックスも検討し、適切な ARN を設定する。
- **最小権限の原則を適用し、不要な権限を付与しないことがセキュリティ強化につながる。**

適切な IAM ポリシーを適用し、AWS 環境のセキュリティ強化に役立ててください！
ステージング検証時の落とし穴！コメントアウトに頼らない安全な開発フロー

## 1. はじめに

鹿児島でエンジニアをやっているtsurupです。
先日、ステージング環境で動作検証をする際に、実行前のレビュー依頼を出しました。その過程での学びを自分の魂に刻むための記事になります。

## 2. やったこと

* ステージング環境での検証時に、特定のメソッドを実行しないように修正
* 「マージ前に戻す」とコメントアウト & PRの説明にも注意書きを記載

例
```ruby
class PaymentService
  def process_payment(params)
    # 実際にAPIを叩いてはいけない為、コメントアウトしています。
    # リリース時には戻します。
    # response = external_payment_api_call(params)
    
    response = { 'body' => { 'result' => { 'success' => true } } }
    response
  end
end
```

## 3. この方法の問題点

**① レビュー者が意図を正確に把握できない**

「マージ前に戻す」とコメントがあっても、どの部分をどう戻すのか明確でないと、レビュー者が正しく判断できません。

**② 実装者本人も状態を誤認する可能性がある**

タスクの差し込みや、検証がうまくいかずに修正を繰り返しているうちに、自分自身でもコードの状態を誤認することがあります。

**③ 単純に戻し忘れるリスク**

「絶対に戻す」と思っていたとしても、人は簡単に忘れてしまいます。たった1行の修正を戻し忘れたことで、思わぬトラブルにつながる可能性があります。

## 4. とった方法：検証用ブランチを作成する

今回のケースでは、リリースブランチから検証用のブランチを作成 し、専用の環境で検証を行うことにしました。

なぜこの方法が良いのか？

✅ 本番ブランチに影響を与えず、安全に検証できる
✅ 「マージ前に戻す」という不確実な作業をなくせる
✅ 他の開発者がレビューしやすくなる

## 5. ふりかえり：人は簡単に忘れる

この指摘を受けてから、いろいろな可能性が頭をよぎりました。
実際、複数のタスクを同時にこなしたり、相談を受けたりしている間に、メッセージへの返信を忘れたり、気付かないこともあるのが現実です。

「これは絶対に忘れない」と思っていても、簡単に忘れてしまう。むしろ、忘れることができてしまう。

たった1行の戻し忘れが原因で、とんでもない事態になりかねない ので、改めて肝に銘じておこうと思った日でした。

## 6. まとめ

検証時のミスを防ぐために、ブランチ運用を工夫することが大切！

コメントアウトや注意書きだけに頼らず、構造的にミスを防ぐ方法を考える！

## おわりに

事故る前に指摘してもらえてよかった。
また、10行もないブログをここまでいい感じにしてくれたChatGPTに感謝です！
原文：[朝活274日目 テックブログを書くブログ](https://note.com/hinataptyan/n/n59b746a43e16)
個人的備忘録：MySQLクライアントの確認からインストールまで、それぞれ簡単にまとめてみた

## はじめに

MySQLクライアントは、データベースとやり取りするために必要なツールです。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、MySQLクライアントが導入されているかを確認する方法を紹介します。

## 書こうと思ったきっかけ

開発環境の構築時に、MySQLクライアントが適切にインストールされているかを確認する場面がありました。

その際に、各OSごとに確認方法が異なるため、まとめておくことで利便性が向上すると考え、本記事を作成しました。

## MySQLクライアントの導入確認方法

MySQLクライアントが導入されているかを確認するには、以下の方法を試してください。

### 1. `mysql` コマンドの存在確認

ターミナルで以下のコマンドを実行し、`mysql` コマンドが存在するかを確認します。

```bash
which mysql
```
または

```bash
command -v mysql
```

### 出力例

```bash
/usr/bin/mysql
```

このような出力があれば、`mysql` コマンドがインストールされています。

### 2. パッケージ管理ツールでの確認

#### Debian/Ubuntu 系 (APT)

```bash
dpkg -l | grep mysql-client
```

### RedHat/CentOS 系 (YUM or DNF)

```bash
rpm -qa | grep mysql
```
または

```bash
dnf list installed | grep mysql
```

#### Arch Linux (Pacman)

```bash
pacman -Q | grep mysql
```

### macOS (Homebrew)

```bash
brew list | grep mysql
```

### 3. MySQL のバージョン確認

MySQLクライアントがインストールされている場合、以下のコマンドでバージョンを確認できます。

```bash
mysql --version
```
または

```bash
mysql -V
```

### 出力例

```bash
mysql  Ver 8.0.34 for Linux on x86_64 (MySQL Community Server - GPL)
```

このような出力があれば、MySQLクライアントが導入されています。

### 4. MySQLクライアントが見つからない場合

上記のコマンドを実行しても`mysql` コマンドが見つからない場合、MySQLクライアントが未導入の可能性があります。その場合は、OSに適したパッケージ管理ツールを使用してMySQLクライアントをインストールしてください。

- Debian/Ubuntu 系: `sudo apt install mysql-client`
- RedHat/CentOS 系: `sudo dnf install mysql`
- Arch Linux: `sudo pacman -S mysql`
- macOS (Homebrew): `brew install mysql`

## まとめ

MySQLクライアントの導入確認は、`mysql` コマンドの存在確認やパッケージ管理ツールを利用して簡単に行えます。

もしインストールされていない場合は、適切なパッケージ管理ツールを使用して導入しよと思いました！
TCP疎通確認用のコマンド2選

# コマンド一覧
## Windows(Powershell)
- Test-Netconnection 
  - 例：Test-NetConnection 172.31.100.10 -port 443

## Linux
- mtr
  - mtr -T -P 443 172.31.100.10

# Test-NetConnection
portを指定すれば、TCPでの疎通確認ができます。
詳しい説明は以下を参照。

https://learn.microsoft.com/en-us/powershell/module/nettcpip/test-netconnection?view=windowsserver2025-ps

ここでは一例を説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/d51c82e8-ac4c-4010-9f7a-c6420afb0d4b.png)

:::note info
TcpTestSucceededがTrueであるため、172.31.100.10の443 Portへ接続できている
:::


## 手軽なPingの落とし穴
その一方で、pingコマンドはあまり活躍できないです。
あっちこっちでICMPがblockされている可能性があります。
実際には接続できているにも関わらず、pingの応答がないためにで誤って接続不可と判断してしまうケースが多いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/76b6f0ca-079d-47fb-9679-0b8f1c496562.png)

:::note warn
Test-NetConnectionの実行時と同じネットワーク設定にも関わらず、ping失敗
:::


# mtr
tcp protocolとportを指定すれば、TCPでの疎通確認ができます。
詳しい説明は以下を参照。

https://man.archlinux.org/man/mtr.8.en

ここでは一例を説明します。
- 172.31.100.10への443 Portへの接続確認
  - mtr -T -P 443 172.31.100.10
  
## episode
あるプロジェクトである日、チームメンバーからmtr失敗の連絡がありました。
しかし、Test-NetConnectionは成功しました。

以下は失敗したとき取った画面キャプチャです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/0f33e3cb-6160-4f1e-9188-2e4b5b5c2556.png)

一見コマンドに問題ないと思われたが、改めて確認すると、なんと小文字の「-p」になっていました。
mtr optionでは小文字「-p」と大文字「-P」とで意味がまったく異なります。
```shell
-p, --split
 Use this option to set mtr to spit out a format that is suitable for a split-user interface.
-P PORT, --port PORT
 The target port number for TCP/SCTP/UDP traces.
```

「mtr -p 443」で実行すると、IP「0.0.1.187」と通信しようとすることです。当然失敗しました。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/18cfbd35-8127-410a-a7b0-694de34d1677.png)
【AI投資システム構築】1. 学習用データの集め方

# 学習用データの集め方

ディープラーニングで学習モデルを生成するためには、多くの学習データが必要になります。
為替レートを予測するための学習データは、為替レートを含む市場情報の時系列データ（ヒストリカルデータ）です。
**個人と大口投資家で最も差が出るところです。**
個人の学習データの集め方は大きくわけて3つあります。

 1. Web APIを用いてダウンロードする
 1. Webサイトからダウンロードする
 1. MT4/MT5でダウンロードする

:::note info
私はMT4/MT5を用いて自動売買システムを構築しており、
トレードと同じデータで学習させるため、
データ収集も「3. MT4/MT5でダウンロードする」の方法を用いています
:::

# 1. Web API を用いてダウンロードする
証券会社やFX会社等が提供するWeb APIを用いることで、為替レートを取得することができます。
#### 【メリット】
- Web APIを自動実行するシステムを構築すれば、データ収集を自動化できる
- トレード用のWeb APIが公開されていればトレードも自動化できる
- リアルタイムの情報を取得できる可能性が高い

#### 【デメリット】
- 利用料が発生する場合がある
- 利用制限がある場合がある
- Web APIの仕様が変更される場合がある

詳細については、Web APIサービスを提供している会社HPをご参照ください。
OANDA証券やGMOコインが有名なようです。

https://www.oanda.jp/fxproduct/api

https://coin.z.com/jp/corp/product/info/fx/api/


# 2. Webサイトからダウンロードする

証券会社やFX会社等のWebサイトからCSVファイル形式等でヒストリカルデータを取得することができます。

:::note warn
FX会社以外のヒストリカルデータだと、出来高（Volume）が含まれていない場合があります。
:::

#### 【メリット】
- 長期期間のヒストリカルデータを提供している会社が多い（10年以上）
- 為替レート以外のヒストリカルデータを入手できる（それこそなんでも）

#### 【デメリット】
- リアルタイムではない可能性が高い
- 実際の価格とあっていない可能性がある
- 欠損データが含まれている可能性がある（経験上）

:::note alert
私がデータを集め始めた10年ほど前は、まだWebにヒストリカルデータを公開している会社は少なく、海外の統計情報を公開している会社からダウンロードしました。しかしデータの欠損が多く、データクレンジングに苦戦した記憶があります。
**Webサイトからダウンロードする場合は、信頼のできる会社からダウンロードすることをオススメします。**
:::

ちなみに、ヒストリカルデータを提供しているFX会社は何社かありますが、
FXTF（ゴールデンウェイ・ジャパン株式会社）の場合は、マイページから多種類の通貨ペアデータをCSVファイルでダウンロードすることができます。

![FXTF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992567/c8bff076-2106-0ebf-4ce5-24ae9e35f525.png)



# 3. MT4/MT5でダウンロードする

MT4やMT5の機能を用いてヒストリカルデータを取得し、CSVファイル形式へエクスポートすることができます。

#### 【メリット】
- トレードで使うデータを学習データとして使用することができる
- トレードも自動化できる
- リアルタイムの情報を取得できる
- 為替レート以外の情報（日経平均株価や金の値段等）も取得できる場合がある

#### 【デメリット】
- ヒストリカルデータの期間が短い会社もある（長い会社もあります）
- MT4/MT5をサポートしているFX会社に限定される

:::note info
正確には、ヒストリカルデータは会社毎異なるため、実際にトレードで口座を開設するFX会社が決まっている場合は、同一のFX会社のMT4/MT5を用いて、ヒストリカルデータを取得した方が良いです。
:::

MT5では、下記図のように「情報呼出」機能でダウンロードし、「バーをエクスポートする」でCSVファイルに出力することができます。
詳細はFX会社の手順サイトやマニュアルをご参照ください。

![ヒストリカルデータ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992567/98d6c9b1-6427-8a4d-77c0-7405dc27c83c.png)


# 集める時系列データ（ヒストリカルデータ）について

冒頭で述べた通り、ディープラーニングで学習モデルを生成するためには、多くの学習データが必要になります。
集めるデータは、一定の時間における値動きを表した指標（時間足）で、
一定期間内の始値（Open）、終値（Close）、高値（High）、安値（Low）や出来高（Volume）の値を含んでいます。
この同一時刻における複数の要素の時間的変化を学習モデルに学習させるのです。
経験上、使用する時間足にもよりますが、5千～1万レコードは欲しいところです。
- 5千～1万レコードを集めるのに必要な期間
**1日足**を用いる場合：**15～30年分**
**4時間足**を用いる場合：**3～6年分**
**1時間足**を用いる場合：**0.75～1.5年分**

個人でデータを集める場合、日足以上の時間足データを集めるのは現実的ではありません。4時間足以下を集めることになります。

テクニカルチャート分析を経験した人ならわかると思いますが、
この制約により、今後構築していく学習モデルは長期予測には向いておらず、
短期予測（数分後、数時間後、トレンドに乗っていれば数日後）を行うモデルとなります。

# まとめ
学習用データの３つの集め方について説明しました。
実際に集める際は、１つの方法に絞る必要はなく、
「2. Webサイトからダウンロードする」で集めたCSVファイルを、MT4/MT5へインポートし、
「3. MT4/MT5でダウンロードする」で統合する方法も有効かと思います。
個人で大量の学習用データを集めるのは難しいため（昨今はだいぶ楽になりましたが）
少しでも参考にして頂けますと幸いです。

次回は、「2.データの前処理方法」について、投稿する予定です。
よろしくお願いいたします。
個人的備忘録：ディストリ別にLinuxでのvi/vimのインストール方法を体系的にまとめてみた

## **はじめに**

`vi`はLinuxでよく使われるテキストエディタの1つで、多くの環境に標準搭載されています。

しかし、環境によっては`vim`を別途インストールする必要があります。

ここでは、各ディストリビューションごとの`vi`（または`vim`）のインストール方法を紹介します。

## **書こうと思ったきっかけ**

Linuxを使用する際、テキストファイルの編集が必要になることがよくあります。

:::note info
**その際に`vi`がインストールされていない場合、スムーズに作業できないことがあります。**
:::

そこで、簡単に`vi`（または`vim`）をインストールする方法をまとめました。

## **Ubuntu / Debian 系**

UbuntuやDebianでは、デフォルトで`vi`がインストールされていることが多いですが、`vim`（Vi IMproved）をインストールすると拡張機能を利用できます。

```bash
sudo apt update
sudo apt install vim
```

インストール後、以下のコマンドでバージョンを確認できます。

```bash
vi --version
```

## **Red Hat / CentOS / Fedora 系**

Red Hat系のディストリビューションでは、`yum`または`dnf`を使用して`vim`をインストールできます。

### **Yumを使用（CentOS 7 など）**
```bash
sudo yum install vim
```

### **Dnfを使用（CentOS 8, Fedora など）**
```bash
sudo dnf install vim
```

## **Arch Linux**

Arch Linuxでは、`pacman`を使用して`vim`をインストールできます。

```bash
sudo pacman -S vim
```

## **Mac (Homebrewを使用)**

macOSではHomebrewを使用して`vim`をインストールできます。

```bash
brew install vim
```

## **`vi` コマンドが見つからない場合**

インストール後、`vi` コマンドが見つからない場合は、`vim` へのシンボリックリンクを作成することで解決できます。

```bash
sudo ln -s /usr/bin/vim /usr/bin/vi
```

これで`vi`コマンドが使用できるようになります。

## **まとめ**

各ディストリビューションごとに`vi`や`vim`のインストール方法は異なりますが、基本的には以下のパッケージマネージャを使用してインストールできます。

- **Ubuntu / Debian**: `apt`
- **Red Hat / CentOS / Fedora**: `yum` または `dnf`
- **Arch Linux**: `pacman`
- **Mac (Homebrew)**: `brew`

インストール後に`vi`または`vim`を実行し、エディタが開くか確認してみるのがおすすめです！
単精度浮動小数点のある範囲を0にする。(あまり正確では、ない)


注意、いろいろ
----

- あまり正確では、ない
- 「==」を使ってよいのは、0x00000000と0xffffffffのみ
- 比較で使っていいのは、「<」、「>」のみ
- あとは、適度に調整する
- 過去ログを見よ!!!
- M5NanoC6での予定は、未定

目的
----

アナログジョイステックの0点周辺のカットを行う


プログラム
----


オンラインコンパイラ paiza


```c++

#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    
    int die = 1;
    
    float a = ((1650.0-0.001-(float)die) / 1000.0);
    float b = ((1650.0+0.001+(float)die) / 1000.0);
    float s;
    
    printf("START\n\n");
    
    printf("a = %f\n",a);
    printf("b = %f\n",b);
    
    for(int i = 1650-5;i < 1650+5+1;i++){
        s = ((float)(i)) * 0.001f;
        printf("%f,",s);
        
        if( (s > a) && (s < b) ){s=0.0f;}
        
        printf("%f\n",s);
    }
}

```


```

START

a = 1.648999
b = 1.651001
1.645000,1.645000
1.646000,1.646000
1.647000,1.647000
1.648000,1.648000
1.649000,0.000000
1.650000,0.000000
1.651000,0.000000
1.652000,1.652000
1.653000,1.653000
1.654000,1.654000
1.655000,1.655000

```
Webの技術を基礎から勉強する為には？(検討中)

色々アイディアをまとめながら書いてみてるので。
(ChatGPT君と話すと色々まとめてくれて助かる)

Webプログラミング的な要素は排除して説明しています。
どちらかというと大学とかでHTMLやCSS、PythonやNode.jsなどは触ったんだけど、そもそもの話を体系的に理解していない可能性がある人向けに溢れてそうなところを拾う話。



# ネットワークの基礎
- 基礎的な用語について(IPアドレス(プライベート、グローバル）、デフォルトゲートウェイ、サブネットマスク）
- IP v4とv6について
- インターネット通信の規格、TCP/IP
    - 大きく4層に分かれてる…が多分ほぼ全員が思ってる層は最上位のアプリケーション層（HTTPとかFTPとか）
    - インターネットのすごいところの一つは、パケットの概念。
- URLの基礎的な概念
    - なぜURLを叩いたら適切なページが表示されるのか？（DNS）
    - プロトコル、ドメイン、パス、パラメータ（GET、POST）

# サーバーの基礎
- 主要なサーバーとその役割
    - Webサーバー
    - アプリケーションサーバー
    - データベースサーバー
    - キャッシュサーバー
    - ロードバランサー
- なぜサーバーにはこんなに役割があるのか？
- Webサーバーとアプリケーションサーバーの違いとは？
    - サーバーに求められるものとは？
        - 静的コンテンツの配信
        - リクエストを適切な先に転送（リバースプロキシ）
        - SSL/TLSの処理
        - キャッシュ処理（レスポンスキャッシュ、クエリキャッシュなど）
        - 動的コンテンツの配信
        - ビジネスロジックの実行
        - セッション管理
        - 認証管理
- サーバーの高速化とキャッシュ
    - インターネットを早くする為には？
    - サーバーの処理とキャッシュの大事な関係
    - CDNの誕生、CDNの特徴（Origin、Edge）、主要なCDNプロバイダー

# Webブラウザの基礎
- Webブラウザが持つ機能を理解（HTMLの描画、Cookie、LocalStorage、SSL処理、Extensionなどなど）
- IEがあった時代、無くなった時代のそれぞれを理解しておく
- CookieとLocalStorageについて（デジタルマーケティング技術の主戦場）

# Webセキュリティの基礎
- 色々とセキュリティは日進月歩で内容が増えていくことは留意
- CSRF
- XSS
- CORS



# 参考
https://www.itmanage.co.jp/column/tcp-ip-protocol/
ubuntu に　cursorをインストール　したときの　備忘録

https://zenn.dev/mizki/articles/36535a1b75ab81

ただ単にこのデスクトップエントリーの一部にタイプミスがあっただけなんですけどね
```[Desktop Entry]
Name=Cursor
Exec=/opt/cursor/cursor.appimage --no-sandobox
Icon=/opt/cursor/cursor.png
Type=Application
Categories=Development
```
これの一部 "--no-sandobox" が "--no-sandbox"にするとうまく動きます
WordPress のページネーションで Prev/Next (戻る/進む) を常時表示させる


## はじめに

WordPress には `the_posts_pagination` を呼び出すことでページネーションを表示することができる。

```php
<?php the_posts_pagination([ /* 条件を配列で指定 */ ]); ?>
```

何も手を加えず標準のページネーションを表示させると、次ページ(前ページ)が存在しないと Prev/Next (戻る/進む) が表示されない仕様になっている。
個人的には Prev/Next (戻る/進む) ボタンは disable で表示されているべきだと考えているので `function.php` に1つ処理を書いて表示させるようにする。

## navigation_markup_template を定義する

ページネーションの処理を一部変更するには `navigation_markup_template` の定義を上書きしてあげることで対応可能。
WordPress 側の関連するコードは以下を参照してほしい。

https://github.com/WordPress/wordpress-develop/blob/8a52d746e9bb85604f6a309a87d22296ce1c4280/src/wp-includes/link-template.php#L3008-L3059

元の ページネーション表示の定義は以下のようになっている。

```php:src/wp-includes/link-template.php
	$template = '
	<nav class="navigation %1$s" aria-label="%4$s">
		<h2 class="screen-reader-text">%2$s</h2>
		<div class="nav-links">%3$s</div>
	</nav>';
```

`<div class="nav-links">%3$s</div>` の前後に 戻るボタン用の処理、進むボタン用の処理それぞれを追加してあげれば良い。
実際に functions.php に記載するコードは以下のようになる。

```php:functions.php
add_filter('navigation_markup_template', function ($template, $class) {
    global $wp_query;
    $total   = isset($wp_query->max_num_pages) ? $wp_query->max_num_pages : 1;
    $current = get_query_var('paged') ? (int) get_query_var('paged') : 1;
    $first = $last = '';

    if ($current == 1) {
        $first = '<span class="prev page-numbers inactive">' . _x('Previous', 'previous set of posts') .  '</span>';
    }
    if ($current == $total) {
        $last = '<span class="next page-numbers inactive">'. _x('Next', 'next set of posts') .'</span>';
    }


    $template = '
    <nav class="navigation %1$s" role="navigation" aria-label="%4$s">
        <h2 class="screen-reader-text">%2$s</h2>
        <div class="nav-links">
        '.$first.'
        %3$s
        '.$last.'
        </div>
    </nav>';
    return $template;
}, 10, 2);
```

## Ref

https://developer.wordpress.org/reference/functions/_navigation_markup/

https://developer.wordpress.org/reference/hooks/navigation_markup_template/

https://github.com/WordPress/wordpress-develop/blob/8a52d746e9bb85604f6a309a87d22296ce1c4280/src/wp-includes/link-template.php#L3008-L3059

https://developer.wordpress.org/reference/functions/get_the_posts_pagination/

https://developer.wordpress.org/reference/functions/the_posts_pagination/
Dartイントロダクション

# 元記事
https://docs.flutter.dev/get-started/fundamentals/dart

ところどころ意訳しています．

# 前書き

Flutterを始めるために，Dartというプログラミング言語に慣れる必要がある．
このページはDartの優しい紹介である．
もしコードの例を読んで十分であれば，このページをスキップしても良い．
このシリーズを通してDart専門家になる必要はない．

# Dart

FlutterはDartで記述されている．
DartはJavaやJavascript，C言語系を書いたことがあれば馴染み深い．

以下のコードは次の小さい処理を行う．
1. dart.devからデータをフェッチする
1. 返されたjsonをデコードする
1. コンソールに出力する

このプログラムを理解できる自信があるなら次のページに行って構わない．

```dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class Package {
  final String name;
  final String latestVersion; 
  final String? description;

  Package(this.name, this.latestVersion, {this.description});

  @override
  String toString() {
    return 'Package{name: $name, latestVersion: $latestVersion, description: $description}';
  }
}

void main() async {
  final httpPackageUrl = Uri.https('dart.dev', '/f/packages/http.json');
  final httpPackageResponse = await http.get(httpPackageUrl);
  if (httpPackageResponse.statusCode != 200) {
    print('Failed to retrieve the http package!');
    return;
  }
  final json = jsonDecode(httpPackageResponse.body);
  final package = Package(
    json['name'],
    json['latestVersion'],
    description: json['description'],
  );
  print(package);
}
```

このプログラムは主に2つに分けられる．
1. ```Package```クラスの宣言
1. ```main```関数に含まれるビジネスロジック

```Package```クラスはDartでクラスを扱うときに使うであろう多くの最も一般的な機能を含む．

Dart言語は型安全である．
型安全とは，変数の値は変数の型と合っていることを保証するために静的な型確認を行うこと．
クラスを定義したとき，```String```というアノテーションが必要であるが，型推論があるためしばしば不要となる．
この例における```main```関数では，多くの行で```final variableName =```から始まっている．
明示的に型を指定していないにも関わらず，これらの行は型安全である．

Dartは完全なNull安全である．
この例では，```description```メンバは```String?```型で定義されている．
```String?```の最後の```?```はnullになり得ることを意味する．
残り2つの変数はnullにはならず，nullを代入しようとしてもコンパイルエラーが起こる．
```Package```クラスのコンストラクタで確認できる．
2つの必須引数（位置引数）と1つのオプション引数（名前引数）を取る．

次は```main```関数の例である．
Flutterアプリを含むすべてのDartプログラムは```main```関数から始まる．
この関数は，使うライブラリをインクルードする，asyncで関数をマークする，関数呼び出しを行う，if文の制御フローなどいくつかのDartの特徴を例示する．

## 初期化コードはどこへ行ったの？

Flutterアプリを開始するエントリーポイントは```lib/main.dart```にある．
デフォルト```main```関数は以下のようになっている．
```lib/main.dart
void main() {
  runApp(const MyApp());
}
```

```runApp()```を呼ぶ前に1～2フレーム文の素早い初期化を行う．
ウィジェットツリーはまだ作成されていないことに注意する．
ディスクやネットワーク上からデータを読み込むなど時間がかかる初期化を行う場合，メインのUIスレッドをブロックしないようにする方法で行うこと．
より詳しくは以下のサイトを参考にすること．
* https://dart.dev/libraries/async/async-await
* https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html?_gl=1*jnjirq*_ga*MTMxODM3MDc4Ny4xNzQwMzI0NzM4*_ga_04YGWK0175*MTc0MDMyODAyNC4yLjAuMTc0MDMyODAyNC4wLjAuMA..
* https://docs.flutter.dev/perf/deferred-components
* https://docs.flutter.dev/cookbook/lists/long-lists

すべてのステートフル・ウィジェットは，ウィジェットが作られ，ウィジェットツリーに追加されたときに呼び出される```initState()```関数を持つ．
この関数はオーバーロードすることができ，そこで初期化を行えるが，このメソッドの最初に```super.initState()```を記述する必要がある．

最後に，ホットリロードは```initState```や```main```を呼び直さない．
ホットリスタートは呼び直す．

# Next : ウィジェット

このページはDartの紹介であり，FlutterとDartのコードを読むのに慣れ親しむ手助けをした．
このページのすべてを完全に理解できなくても，Dart言語の構文に慣れてくるだろう．
次のセクションでは，ウィジェットというFlutterアプリのブロックの組み立て方について学ぶ．
【Windows】DockerでPython環境構築で躓いた点

### はじめに
単語帳アプリを作るためにとりあえずPythonを使えるようにしようと思い、Dockerとかいうのを入れようとしましたがいきなり躓いたので、躓いた点と解決策を備忘として載せておきます。
すごく簡単に言うとバージョン違いのエラーでした。

https://qiita.com/druss1231/items/0e304e37767a4f442d06

### Dockerとは
仮想環境が**簡単に**作れるぜ、他の人（または自分）が作った仮想環境を自端末の環境に依存せず使えるようにできるぜ、みたいなやつです。詳しくは調べてください。

### Dockerのインストール
まずはDockerのインストールを行いました。さすがにここまでは問題ないです。
以下の記事がとても分かりやすくまとめてくれています。

https://qiita.com/zembutsu/items/a98f6f25ef47c04893b3

### DockerでPython環境の構築中にエラー
ここで躓きました。
そもそもMacOSでやる人が多いのか、それともWindowsでもLinuxコマンドでやる人が多いのかは知りませんが、たいていの記事はLinuxコマンドで書かれてました。
横着な私はWidows用の記事ないかなーと探していたところありました。どんなことでも探してみれば世の中やっている人が必ずいますね。ありがたいことです。

https://zenn.dev/code_journey_ys/articles/ddd8ba305a2538

この記事の通りコマンドを叩いたり、ファイルを作ってコピペしたりしていったら、、出ました！妖怪イワレタトオリヤッタノニ！コンポーズ？をビルド？してからRunしようとしたら以下のようなエラーが出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4018959/c88ee26e-fda5-421c-9c11-914fa28b0ea3.png)

見ての通り、cgiというモジュールが見つからないというエラーですね。

### 解決に向けてやったこと
#### 予想を立てる
画像のエラーをはいている直前のメッセージに「import cgi」と出ていることから、命令としては「cgi」とかいうのをインポートしようとしたけど、そんなもんねーよと怒られている感じだと思いました。
いろいろ知らべた結果、下記の記事にPythonのバージョン3.13から「cgi」なるものはなくなったみたいなことが書いてありました。

https://github.com/element-hq/synapse/pull/17741

ということは、自分がインストールしたPythonは3.13以降のバージョンなのでは？

#### 検証
で、実際インストールしたPythonのバージョンを確認するために自分が叩いたコマンドをさかのぼってみていくと…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4018959/f1e350a9-79c1-4d75-ac3e-ba763a1e8b83.png)
python3.13のフォルダを参照していたので、多分どこかで3.13をインストールしたのでしょう。

### 解決策
上記からPythonのバージョンを3.13より前のバージョンにすれば一旦環境構築はできるはず。。
自分でPython3.13を指定した記憶はないので、環境構築で参考にしていた記事でぺたぺたコピペしていたDockerfileを見てみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4018959/995c69a7-7db2-4c30-aecf-adf97a7c8865.png)
「Python:3」という指定はしていました。
ソースとかはないですが、多分「Python:3」としていたら3の中の最新のやつをインストールするんだろうなといった感じ。。

ダメ元で「Python:3.12」に変更して保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4018959/33f8b4c1-9311-4dfc-a9f7-4ba02e8c15c5.png)
そして念のためDockerに上がったイメージとコンテナを削除してからcomposeからやり直したところ、、

なんとうまくいきました！！完全にインストールしたバージョンと命令に齟齬があったのが原因でしたね。

### 学んだこと
バージョン違いによる上記のようなエラーは環境構築で本当によくある話だと思います。私自身何度環境構築がうまくいかず挫折したことか。。しかし、意外にエラー文をしっかり読んで予想を立てて調査すれば案外あっさりわかったりします。
また、最新のものをインストールするという手順書は当然使いやすいのですが、バージョンを指定しないことによって上記のようなエラーが出る可能性があるので注意です。（書いてくれた記事に文句を言うつもりはありません。手順書を使う側が注意、解決すべきことだと思います。）
今回のエラーは多分「import cgi」の命令が実行されている行をどこかのソースから削除すれば3.13をインストールできるはずですが、ちょっとそこまではやり方がわかりませんでした。このまま3.12で使い続けて問題があればまた調査してみようと思います。

・・・てｋcgiって何？
また時間があったら調べてみます。
エージェント依存化ライン ― AIツール依存がもたらすエンジニアリングの二極化現象

## はじめに

近年、AI技術の進歩により、ソフトウェア開発の現場でも自動補完やコード生成など、さまざまなタスクでAIツールが利用されるようになりました。しかし、その一方で、ジュニアエンジニアや基礎力が十分に身についていない技術者が、AIエージェントに過度に依存してしまう現象が懸念されています。本記事では、実際の検証事例をもとに、AIツールの補助的役割とその限界、そして「使う側」と「使われる側」との二極化現象に焦点をあて、これを「エージェント依存化ライン」と名付け、その意義や影響について考察します。

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">個人的にはエージェントを境界にして、それに依存するエンジニアとエージェントを適切に活用する自律的なエンジニアを分ける境界線がある気がします！<br>これを「エージェント依存化ライン」と定義していかにこの境界線を越えるかが重要になりそう！ <a href="https://t.co/sjeQXHgi40">https://t.co/sjeQXHgi40</a> <a href="https://t.co/7P4rolntZv">pic.twitter.com/7P4rolntZv</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1893286801348972976?ref_src=twsrc%5Etfw">February 22, 2025</a></blockquote>

## AIツールの現状と限界

最近、世界初のAIソフトウェアエンジニア「Devin」など、さまざまなAIエージェントが登場し、プロジェクトの初期段階や単純なタスクにおいては一定の成果を上げるケースも見受けられます。たとえば、Notion APIを利用したGoogle Sheetsへのデータ連携や、簡単なWebスクレイピングなど、定型的かつ既に学習済みのタスクについては、AIが補助的に役割を果たすことができることが確認されています。

しかしながら、実際の現場では、複雑なタスクや既存コードの解析、根本的な問題解決において、AIエージェントはしばしば期待に応えられず、コードの冗長化や論理的な穴が目立つなどの問題が発生しています。これらの現状は、AIツールがあくまで「補助」であり、エンジニア自身の基礎力や論理的思考が不可欠であることを浮き彫りにしています。

## エージェント依存化ライン ― 境界線の意味

ここで注目したいのが「エージェント依存化ライン」という概念です。これは、AIエージェントを効果的に「使いこなす側」と、ツールに依存してしまい自らの判断が行えなくなる「使われる側」との間に存在する、明確な境界線を指します。

### この名称が示すもの

- **直感的な理解:**  
  「依存化ライン」という表現は、どこからが自律的な技術活用で、どこからが過度な依存状態に陥るかを、視覚的かつ直感的にイメージさせます。

- **警鐘としての役割:**  
  この名称は、AIツールがどれほど高性能であっても、その限界を理解せずに利用することのリスクを、技術者自身や組織全体に強く訴えかけるものです。

- **教育・研修の指標:**  
  エンジニアの育成において、基礎知識や論理的思考の訓練が不可欠であるという認識を強め、依存状態に陥らないための明確な指標として機能します。

## ジュニアエンジニアの基礎力と論理的思考の重要性

実際に、Devinを用いた実験では、20のタスク中14が失敗し、成功したのはわずか3件にとどまりました。この結果は、AIエージェントに丸投げするだけでは、問題の本質に迫ることが難しい現状を示しています。以下の点が重要です。

- **問題解決のプロセス:**  
  AIは提示された情報や過去の学習結果に基づいて動作するため、独自の論理的思考や柔軟な発想が求められる場合、その限界が顕在化します。特に、既存コードの修正や新たなプロジェクトの立ち上げでは、根本的な理解や適切な判断が不可欠です。

- **依存リスクの拡大:**  
  ジュニアエンジニアがAIの出力にそのまま頼ると、ツールの限界やバグに気づかずに作業が進んでしまい、結果として組織全体の生産性や品質に悪影響を及ぼすリスクが高まります。

## 自律と依存の二極化現象

エージェント依存化ラインを超えた先には、明確な二極化現象が存在します。

### 自律的なエンジニア

- **特徴:**  
  自身の基礎力をしっかりと持ち、AIツールはあくまで補助として利用できる。自らの判断でツールの出力を検証し、必要に応じて修正や改善を行う能力がある。

- **効果:**  
  このようなエンジニアは、AIツールをうまく活用することで生産性を向上させ、難解な問題にも柔軟に対応できるため、組織全体の技術力向上に寄与する。

### 依存してしまうエンジニア

- **特徴:**  
  基礎力や論理的思考が十分に備わっていないため、AIツールに依存し過ぎ、ツールが出力するコードや情報をそのまま受け入れてしまう。

- **リスク:**  
  ツールの限界やエラーに気づかず、問題解決が滞る可能性が高まります。長期的には、組織全体の技術レベルの低下や、イノベーションの阻害といった深刻な問題に発展する恐れがあります。

## エージェント依存化ラインの提案とその影響

「エージェント依存化ライン」という名称は、単なるネーミングに留まらず、以下のような影響をもたらす可能性があります。

- **教育現場での活用:**  
  エンジニア教育において、基礎知識や論理的思考の重要性を再認識させ、AIツールはあくまで補助的な存在であることを強調する指標として活用できる。

- **組織内のスキル評価:**  
  自律的にツールを活用できるエンジニアと、依存状態にあるエンジニアとの違いを明確にし、育成計画や採用基準に反映させるための基準となる。

- **ツール開発者へのフィードバック:**  
  AIエージェントの開発側にも、「使われる側」と「使う側」の境界を意識した改善が求められる。たとえば、ツールが自動で問題に固執することなく、ユーザーに再評価を促す仕組みの導入などが考えられる。

## 結論

AIエージェントは、現時点では補助的な役割に留まり、技術者自身の基礎力や論理的思考がなければ真の意味での問題解決には至らないという現実があります。「エージェント依存化ライン」という概念は、エンジニアが自律的にツールを使いこなすか、あるいは依存してしまうかの分岐点を明確に示すものです。この境界線を意識し、組織や教育現場で基礎力の強化とAIツールの正しい使い方を促すことが、今後の技術進化とエンジニアリングの質向上に不可欠であると言えるでしょう。

## 参考資料

https://www.answer.ai/posts/2025-01-08-devin.html

 <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
「電脳少女プログラミング2088」Bランク問題「一番通りの繁華街」をコーディングしてみた

この記事では「電脳少女プログラミング2088 ─壊レタ君を再構築─」のBランク問題「一番通りの繁華街」の解答コードをResultとChatGPTを使ってリファクタリングしていきます。

https://paiza.jp/entry/denno2088_qiita

## 方針

- 縄張りの形状は正方形なので、縄張りの座標リストから組み合わせをして、絶対値分下に同じx座標のアジトがあるか判定する。
- 以下の順で処理：
    1. 標準入力からグリッドのサイズ `n` を取得
    1. 標準入力からアジトの座標リスト `a` を取得
    1. 縄張りの数 `ans` を作成
    1. 同じy座標の建物をリストから２つ抽出
        - 組み合わせには `itertools.combinations()` を使用
    1. 抽出した建物の距離 `d` 分離れたy座標に建物があるか判定し、あれば `ans`に+1
    1. 標準出力に `ans` を出力


```python
import itertools

n = int(input())
a = []
for i in range(n):
    t = {i for i, x in enumerate(list(input())) if x == '.'}
    a.append(t)

ans = 0
for i in range(n):
    for x1, x2 in itertools.combinations(a[i], 2):
        d = abs(x1 - x2)
        if i + d >= n: continue
        if {x1, x2} <= a[i+d]:
            ans += 1

print(ans)
```
Reference: [enumerate()](https://docs.python.org/3/library/functions.html#enumerate) | [list()](https://docs.python.org/3/library/functions.html#func-list) | [abs()](https://docs.python.org/3/library/functions.html#abs) | [combinations()](https://docs.python.org/3/library/itertools.html#itertools.combinations) | [list](https://docs.python.org/3/library/stdtypes.html#list)

## 改善

ChatGPTを使って可読性や効率を意識してみる：

```python
import itertools

n = int(input())
pos = [{i for i, x in enumerate(input()) if x == '.'} for _ in range(n)]

num_territories = sum(
    1
    for i in range(n-1)
    for x1, x2 in itertools.combinations(pos[i], 2)
    if i + (distance := abs(x1 - x2)) < n and {x1, x2} <= pos[i + distance]
)
print(num_territories)
```

改善点：

- ループ最後は正方形が成立しないので `range()` を `n` から `n-1` にした
- リスト内包表記を使用して `pos` を１行にまとめた
- 必要のない `list()` の削除
- 変数名の最適化
    - `a` → `pos`
    - `ans` → `num_territories`
    - `length` → `distance`
- セイウチ演算子(`:=`)を使用し、再計算する無駄を省いた
- リファクタリング前は `ans` にインクリメントしていく形式だったが、`sum()` を使用することでカウント処理が簡潔になった。

## 終わりに

itertools 便利なので、適切なタイミングで使えるようにしたい。
type-challenges解いてみた 初級 7-Readonly編


# 問題

````md
組み込みの型ユーティリティ`Readonly<T>`を使用せず、`T` のすべてのプロパティを読み取り専用にする型を実装します。実装された型のプロパティは再割り当てできません。

例えば：

```ts
interface Todo {
  title: string
  description: string
}

const todo: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar"
}

todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
```
````


TypeScriptの組み込みユーティリティ型`Readonly`を使用せずにすべてのプロパティを読み取り専用にする型を作成してくださいという問題です。
JSのreadonly修飾子を禁じられているわけではないのでご注意ください。(一敗)

https://typescriptbook.jp/reference/type-reuse/utility-types/readonly


## 回答

```ts
type MyReadonly<T> = {
  readonly [key in keyof T] : T[key] 
} 
```

初級だけありかなり単純ですね。

### 詳細解説

#### **`keyof T`**

`T`のすべてのプロパティ名のユニオン型を生成します。
  例えば T が `{ a: number, b: string }` なら、`keyof T` は "a" | "b" になります

#### **Mapped Types（マッピング型）**

`[key in keyof T]`の部分は、T の各プロパティ名を取り出し、対応するプロパティを生成するための構文です。

#### **readonly 修飾子**

`readonly` を付けることで、オブジェクト生成後にそのプロパティが変更できなくなります。

#### **`T[key]`**

元の型 T の各プロパティの型がそのまま引き継がれます
例えば以下のような場合

```ts
{
  a: "aaa",
  b: "bbb",
  c: "ccc",
}
```

`keyof T`でプロパティ名のユニオン型を生成すると "a" | "b" | "c" となり、`[key in keyof T]`で "a" | "b" | "c" がプロパティ名のオブジェクトが作成されます。
そして各プロパティのvalueは`T[key]`なので...

```ts
{
  a: `T["a"]` // -> "aaa"
  b: `T["b"]` // -> "bbb"
  c: `T["c"]` // -> "ccc"
}
```

と、元のオブジェクトが復元されるような形となります。
HTML/CSS/JavaScript

## 1. HTML とは
HTML（HyperText Markup Language）は、**ウェブページの骨組みを作るための言語**で、ウェブサイトの**部品（見出し・文章・画像・ボタンなど）**を作る役割を担ってる。

## 2. CSS とは
CSS（Cascading Style Sheets）は、**HTMLで作られたページのデザイン（見た目）を整えるための言語**。
HTMLが「家の骨組み」なら、CSSは「壁紙や家具などの装飾」のようなもの。

## 3. JavaScript とは
JavaScriptは、**ウェブページに動きをつけるためのプログラミング言語**。
HTMLが「骨組み」、CSSが「デザイン」なら、JavaScriptは「動きや機能を追加するエンジン」のようなもの。

## 4. ECMAScript とは
ECMAScript（エクマスクリプト）は、**JavaScriptのルール（仕様）を決めたもの**。
JavaScriptは、もともと自由に開発されていましたが、ルールを統一するためにECMAScriptという基準が作られた。

### ECMAScript 2015（ES6）以降について
ECMAScriptは定期的にアップデートされており、特に**ECMAScript 2015（ES6）**以降は、モダンな書き方が導入された。JavaScriptを学ぶときは、ES2015（ES6）以降の書き方を使うようにする。

ES6以前とES6以降の違い👇

🔹 変数の宣言
ES6以前（古い書き方）
```js
var name = "佐藤";
```
ES6以降（推奨される書き方）
```js
let name = "佐藤"; // 変更可能な変数
const age = 25; // 変更できない定数
```

🔹 関数の書き方
ES6以前（古い書き方）
```js
function hello() {
  return "こんにちは！";
}
```

ES6以降（アロー関数）
```js
const hello = () => "こんにちは！";
```

🔹 テンプレートリテラル（文字列の扱い）
ES6以前
```js
let name = "佐藤";
console.log("こんにちは、" + name + "さん！");
```

ES6以降
```js
let name = "佐藤";
console.log(`こんにちは、${name}さん！`);
```
→ 「`（バッククォート）」を使うことで、文字列を簡単に組み立てられる！

## 5. データ型とは
データ型（Data Type） とは、**プログラムで扱う値の種類**のこと。
もし型がなかったら、数値か文字列かわからず、プログラムが正しく動かなくなる 可能性がある。
データ型を正しく選択することで、メモリの使用量を最適化できるため、パフォーマンスの向上に寄与する。
## 6. JavaScriptのデータ型の種類
1. number（数値）
2. string（文字列）
3. boolean（真偽値）
4. null（ヌル）
5. undefined（未定義）
6. symbol（シンボル）
7. object（オブジェクト）

## 6. DOMとは
DOM（Document Object Model、ドキュメント・オブジェクト・モデル）は、**Webページ（HTML）をプログラムで操作できるようにする仕組み**のこと。
簡単に言うと、「Webページの地図」みたいなもので、ページ内のタグ（HTML要素）をプログラムで変更したり、追加・削除したりするために使う。
ブラウザに表示された Webページの内容（HTML）をJavaScriptで操作できるようにするためにある。

## 7. npmとは
npm（エヌピーエム） は、Node.jsを使うときに**便利なツールやプログラムを管理するためのシステム**のこと。
どのライブラリを使ったかpackage.jsonというファイルに記録して、後で簡単に同じ環境を再現できるようにしてくれる。

## 8. 非同期処理とは
まず、同期処理（順番に進む処理）とは、**1つの処理が終わるまで、次の処理を待つというルール**のことで、非同期処理（待たずに進む処理）
**処理を待たずに、別の作業を同時に進められる仕組み**のこと。
非同期処理を使えば、データを待っている間に他の部分を表示できたり、ダウンロード中にページの他の部分を表示できる。
【Mac】画像をWebPに変換する方法

## CLI

コマンドを実行して画像をWebPに変換するには`webp`をインストールします。

```terminal
brew install webp
```

以下のようにコマンドを実行すると画像がWebPに変換されます。

```terminal
cwebp input.jpg -o output.webp
```

https://developers.google.com/speed/webp/docs/cwebp?hl=ja

## ブラウザ

ブラウザで変換する場合にはTinyWebpが使用できます。

![スクリーンショット 2025-02-23 23.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/d298b5bf-f413-4094-9aa7-52f8893083e1.png)

https://tinywebp.app
【電脳少女プログラミング2088 ─壊レタ君を再構築─】Python初心者がやってみた（ギャングのアジト編）

## はじめに

前回の記事で「データセンター」をクリアして、今回は「ギャングのアジト」をクリアしたので書こうと思います。

難しくてまだクリアできてない方などに参考にしてもらえると嬉しいです。

https://paiza.jp/entry/denno2088_qiita

## 【問題】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/80deaeb9-a4ce-403f-82d1-46aea220a032.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526750/73e0d985-34f2-4906-ac4a-a039506d39c0.png)

## 解答

今回もPython3を選択して書いてみました。

```python:解答
# coding: utf-8
# 自分の得意な言語で
# Let's チャレンジ！！

N = int(input())  # ピクセルアートの大きさを整数として受け取る

result = "Yes" # 答えをいれる変数

for i in range(N): # Nの数繰り返す
    input_str = input()  # 入力を受け取る
    
    b = list(map(int, input_str.split())) # スペースで区切ってリストに変換
    
    if b != b[::-1]: # スライスを使って左右対称かを判断
        result = "No" # 左右対称じゃない場合にNoを代入する
    
    
print(result)  # 結果を表示
```

## コード解説

上のコードの解説をすると

`N`（ピクセルアートの大きさ）を整数として`input_line`に代入

```python:４行目
N = int(input())
```

***

答えをいれる変数`input_line`を作成して初期値を`"Yes"`にする

```python:６行目
result = "Yes"
```

***

for文で`N`の数だけ下の処理を繰り返す
1. 入力を受け取る
2. スペースで区切ってリストに変換
3. if文とスライス（`b[::-1]`の部分）を使って、もし、左右対称じゃないならば`result`に`"No"`を代入

左右対称かの判断は、Pythonのスライスを使ってリスト`b`を反転させて、反転させる前のリスト`b`と反転後のリスト`b`が同じかをif文で確認しています。

例（左右対称）
`[1, 0, 1, 0, 1]`をスライスで反転させると
`[1, 0, 1, 0, 1]`になって同じ

例（左右対称じゃない）
`[1, 1, 0, 0, 0]`をスライスで反転させると
`[0, 0, 0, 1, 1]`になって同じにならない


```python:８行目～１４行目
for i in range(N): # Nの数繰り返す
    input_str = input()  # 入力を受け取る
    
    b = list(map(int, input_str.split())) # スペースで区切ってリストに変換
    
    if b != b[::-1]: # スライスを使って左右対称かを判断
        result = "No" # 左右対称じゃない場合にNoを代入する
```

スライスについてはわかりやすい記事があったので紹介します。

https://qiita.com/tanuk1647/items/276d2be36f5abb8ea52e

***

こんな感じのコードで問題を解くことができました。

## 最後に

記事を最後までお読みいただきありがとうございます！
今回は難しかったです。Pythonのスライス操作をしたことがなかったので解き方が思い浮かばなくて結構苦戦しました。次回は「自然の残る公園」をしようと思っています。次回も見てくださると嬉しいです。

ではまた他の記事で会いましょう！またねーヾ(*´∀｀*)ﾉ
デュアルブートでWiFi消えたらやること

# 環境
| windows | 11 |
| - | - |
| Ubuntu | 22.04 |

# 状況
いつもはUbuntuを使用しているがWindowsを開かざるを得なくなり、Windowsを起動。
再起動でUbuntuを開いたらWiFiが消えてた！

```
 ↪ $ ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:34:17:77:5e  txqueuelen 0  (イーサネット)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (ローカルループバック)
        RX packets 4897  bytes 495651 (495.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4897  bytes 495651 (495.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

# 解決策
まずはWindowsを再度起動すると、WiFiがいると思います
いなかったら他の記事へGO!!!
また以下コマンドはすべて管理者権限つきPowerShellで実行してください

## 1. 「高速スタートアップ」を無効化する
```PowerShell
powercfg -h off
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f
```
## 2. Wi-Fiアダプターの電源管理設定を変更する
```PowerShell
Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Format-Table -Property Name, InterfaceDescription
```
でアダプター名を検索(今回は`WiFi`)
```PowerShell
$deviceName = "ネットワークアダプタの名前"  # デバイスマネージャで確認できるデバイス名
Get-WmiObject -Namespace root\wmi -Class MSPower_DeviceEnable -Filter "InstanceName LIKE '%$deviceName%'" | ForEach-Object {
    $_.Enable = $false
    $_.Put()
}
```
を実行するとInstanceNameを複数取得できる
```powershell
InstanceName="{00000000-0000-0000-0000-000000000000}\\vwifimp_wfd\\0&0000000&0&xx_0"
```
最後のxx部分が違うものが入手できるはずなので、それを以下コマンドで使用する

```powershell
# 対象デバイスのインスタンス名を指定
$instanceNames = @(
    "{00000000-0000-0000-0000-000000000000}\\vwifimp_wfd\\0&0000000&0&xx_0",
    "{00000000-0000-0000-0000-000000000000}\\vwifimp_wfd\\0&0000000&0&yy_0"
)

# 対象デバイスの電源管理設定を無効にする
foreach ($instanceName in $instanceNames) {
    $device = Get-WmiObject -Namespace root\wmi -Class MSPower_DeviceEnable -Filter "InstanceName='$instanceName'"
    if
```

## 3. 完全シャットダウンをする
```powershell
shutdown -s -t 0 -f
```
で完全シャットダウンができる。

## 4. Ubuntu起動
電源が切れたら再度電源投入しUbuntuを起動したら...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1832609/faf2ef9c-84d9-4261-b933-1e6e8df0a1fa.png)
# WiFi復活!!!
GoogleのAIツールを活用しよう：初心者でも使える便利な機能


GoogleはAI技術の分野で世界をリードする企業の一つで、開発者や一般ユーザー向けにさまざまなAIツールを提供しています。プログラミングの知識がなくても使えるものから、高度な開発をサポートするものまで幅広いのが特徴です。ここでは、代表的なGoogleのAIツールをいくつか紹介しつつ、どんな場面で役立つのか見てみましょう。
### Google Colab：無料で使えるクラウド上のPython環境
Google Colab（正式名称：Colaboratory）は、ブラウザ上でPythonコードを実行できる無料のツールです。特にデータ分析や機械学習に便利で、CSVファイルの解析のような作業も簡単にできます。
- 何ができるの？
CSVファイルを読み込んでデータを整理したり、グラフを作ったり、簡単なAIモデルを試したりできます。たとえば、売上データやアンケート結果をアップロードして、傾向を分析するなんてこともすぐ可能です。
- ポイント
高性能なGPUも無料で使えるので、重い計算もサクサク。インストール不要で、Googleアカウントがあればすぐに始められます。
- 試してみたいとき
例えば、「sample.csv」というファイルをアップロードして解析するコードは、[Google ColabでPythonを使ってCSVファイルを解析する簡単な例](https://qiita.com/zhao-xy/items/eefca4d8a381aadd314f)のようにcsvモジュールを使って簡単に書けます。Colabならその場で結果を確認できるので、試行錯誤が楽しくなりますよ。
### Google AI Studio：生成AIを気軽に試せる
[Google AI Studio](https://aistudio.google.com/prompts/new_chat)は、Googleの最新AIモデル「Gemini」を使って、文章生成や質問応答を試せるツールです。開発者向けですが、プログラミングを知らなくてもブラウザ上で遊べます。
- 何ができるの？
「日本のおすすめ観光地を教えて」と入力すれば、詳しい回答が返ってくるし、「詩を書いて」と頼めばクリエイティブな結果も。APIを使って自分のアプリに組み込むことも可能です。
- ポイント
無料枠があるので、気軽に試せます。高度な使い方をしたいなら有料プランもあります。
- 試してみたいとき
「Google AI Studio」と検索してアクセスし、簡単な質問を投げてみてください。たとえば、「PythonでCSVを解析する方法を教えて」と聞いてみるのも面白いですよ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/6e3d7038-7f35-4006-81db-bb7db54357a7.png)


### NotebookLM：学習や研究をサポート
NotebookLMは、資料をアップロードするとその内容を要約したり、[NotebookLMとは？AIを活用した次世代のノートツール](https://qiita.com/zhao-xy/items/f9a61dac251c115d05f0)のように、質問に答えたりしてくれるAIツールです。教育や仕事でのリサーチにぴったりです。
- 何ができるの？
PDFやテキストを読み込ませれば、要点をまとめたノートを作ってくれるし、わからない部分を質問すれば解説も。音声で概要を聞く機能もあります。
- ポイント
無料で使えて、GoogleアカウントがあればOK。学生や忙しいビジネスパーソンにおすすめです。
- 試してみたいとき
「NotebookLM」と検索して試しにレポートや記事をアップロードしてみると、どれだけ時間を節約できるかが実感できます。

### まとめ
GoogleのAIツールは、無料で手軽に使えるものから、専門的な開発を支えるものまで揃っています。どれもGoogleの技術が詰まっていて、初心者でもすぐに始められるのが嬉しいポイントです。
Amazon Bedrock エージェントで複数のナレッジベース（Structured Data 含む）使用時の設定問題と解決法

Amazon Bedrock のエージェントに複数のナレッジベースを登録した際、Structured Data タイプのナレッジベースを使用すると、SQL クエリが実行されてもその結果がエージェントの回答に反映されない場合があります。
この記事では、その問題の解決策を説明します。

## 解決策

以下の手順でエージェントの設定を変更します。

1. **Bedrock コンソール**で対象エージェントを選択し、**編集**をクリック。  
2. **Orchestration strategy** を開き、**”KB の回答生成 - 非アクティブ”** タブを選択。  
3. **回答生成テンプレート** で以下を有効化：  
   - **”ナレッジベースの回答生成 テンプレートデフォルトを上書き”**  
   - **”ナレッジベースの回答生成 テンプレートを有効化”**  
4. **”保存して終了”** をクリック。  

#### 設定前の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988434/46a71dc0-f14b-4097-bcd0-0f57918069c3.png)

#### 設定後の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988434/0a1d8502-b0d4-4692-9bd8-43d070f7837a.png)

これで Structured Data ナレッジベースの検索結果がエージェントに正しく渡り、回答に反映されます。
画像生成AIを使ったTOEIC単語帳アプリを作成してみる

### はじめに
全ての単語に画像が付いたTOIEC用の単語帳アプリを、AIにおんぶにだっこで作ってみようと思う。

### アプリ作成の経緯

3年ほど前にTOEIC935点をとったが、そろそろ賞味期限切れだと感じ取り直そうと思った。…が、全然単語覚えてない。935点取ったときは過言じゃなくわからない単語なんてなかったのに…。
なぜ昔あんなに覚えていた単語を覚えていないのか、それは短期間でとにかく頭にぶち込んだだけだからである。当時使っていた単語帳は当然金のフレーズ、通称金フレ（というのかは知らない）。

https://www.amazon.co.jp/TOEIC-TEST-%E5%87%BA%E3%82%8B%E5%8D%98%E7%89%B9%E6%80%A5-%E9%87%91%E3%81%AE%E3%83%95%E3%83%AC%E3%83%BC%E3%82%BA-%E7%89%B9%E6%80%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4023315680

実際高得点が取れたので金のフレーズに文句を言うつもりはないが、画像などあったらもっと覚えやすいし、長期的に記憶できるだろうなと思ったので、すべての単語にイメージ画像がついている単語帳作成アプリを作りたいと思った。

しかしながら私には絵心は皆無だし、金のフレーズに収録されている単語だけでも1000単語もあるので、そんなに画像を描いている時間はない。ということで、画像生成AIに画像は作らせて、クイズ部分だけ実装すれば行けんじゃね？という甘い考えで初めてみます。

一応現役SEですが、全然知識ないので試行錯誤しながらやっていきます。

### なんとなくのアプリの構想

#### UI部分
- すべての単語に画像がついている単語帳アプリ
- 四肢択一のクイズもできる
- Webアプリとして公開する

#### 実装部分
- 単語と画像を紐づけるデータベースを用意
- 画像の作成には画像生成AIを使用
- 以下の手順で画像を作成
　1. 単語から生成AIでTOIECっぽい文章を作成する
　2. 作成した文章を画像生成AIに読み込ませ、画像を生成する。
　3. 2.で生成した画像を再度生成AIに読み込ませ、元の単語が説明の中に入っていればOK。入っていなければNG。再度生成しなおし。
- アプリ全体としてはPythonで実装（Pythonを使ってみたいだけで特に意味はないです。）

### プロフィール
- 28男
- 一応SE3年目(保守1年、開発：１年半くらい）
- TOIEC935点

### まとめ
 完全に見切り発車ではありますが、このアプリ作成を通じていろいろ学びたいと思います。SE3年目とはいえ全然知識がないので、手探りで進めていきたいと思います。知識がないなりの視点で詰まったところなど発信していければいいなと思っています。
仮の名前をつけるときに「xxx」や「aaa」を使っていたが辞めたいという話


# はじめに
開発する上で関数や変数を定義する際の話です。
実装を先にしてから名前をつけないと名前に実装が引っ張られる勘違いをしてしまいそうだったり、仮でつけた名前に満足して自己レビューで忘れてしまったりしちゃいそうで、何となく名前を明確につけるのを後回しにいがちです。
その時に「hoge」「fuga」をよく目にしますが、私は適当に「xxx」や「aaa」などと仮で定義することが多いです。

それについて最近見つけた最近のちょっとした問題を記事にします。

# TODOコメントについて

TODOコメントを使用していた際に、コメントをもっとわかりやすくしたいと思い調べてみたところその問題に出会いました。

https://qiita.com/taka-kawa/items/673716d77795c937d422

TODO 以外の記述とその意味について「こんなものもあるんだ〜」とか「今まで使ってたこういうコメントはこっちを使ったほうが適切だったな」とか思っていたところに目に入ってきた

>XXX:	|危険！動くけどなぜうごくかわからない。

という表の一部　これを見てタイトルのように思ったわけです。

「aaa」は少なくともいいかもしれませんが、「xxx」は辞めたいかも・・・

# 余談

「hoge」や「fuga」などは
>意味のない名称のこと
>意味を持たないということが重要


使用する際は、
>それぞれ使用する順番が決まっていて最初にhogeが使われて、次にfugaかpiyo、そこからhogeraというように続く

など意外とルールがあるみたいです。

https://qiita.com/mzmz__02/items/c68d99573c362bd561bb
WEBサーバとアプリケーションサーバの違い

## はじめに
オリジナルプロダクトを作成し、現在デプロイの段階に入りました
そこでよく見るWweサーバやアプリケーションサーバってなんぞやと思い調べました

## Webサーバとは
Webサーバはクライアント(ユーザ)のブラウザからのHTTPリクエストを受け取り、HTML、CSS、JavaScript、画像などの「静的コンテンツ」を配信する役割を持ちます
例
・Apache
・Nginx
これらのWebサーバは静的なWebページの処理だけでなく、動的リクエストをアプリケーションサーバに振り分ける役割も持っています。

## アプリケーションサーバ
アプリケーションサーバは、Webサーバからのリクエストを受けて、データベースとの連携、計算処理を行い、動的なWebページを生成します。
例
・Puma
・Unicorn

## Webサーバとアプリケーションサーバの関係
システムは、Webサーバとアプリケーションサーバを組み合わせて使用します。

1. クライアントがWebサーバにリクエストを送る
2. Webサーバが静的コンテンツを直接返す、または動的なリクエストをアプリケーションサーバに転送
3. アプリケーションサーバがリクエストを処理し、データベースと連携して動的なレスポンスを生成する
4. アプリケーションサーバがWebサーバにレスポンスを返し、Webサーバがクライアントにデータを送信する

## なぜWebサーバとアプリケーションサーバを分けるのか
・Webサーバがリクエストを適切に振り分け、負荷を分散できる
・静的コンテンツと動的コンテンツの処理をWebサーバ、アプリケーションサーバで分けることで高速なレスポンスを実現
・外部ユーザーからのアクセスをアプリケーションサーバにすることで、他のサーバはアプリケーションサーバからのアクセスのみに限定し、セキュリティを担保

## その他気になった用語集

### リバースプロキシ
Webブラウザなどのクライアントとサーバの間で仲介を果たすネットワークデバイス、またはサーバのことです。
つまりWebサーバはアプリケーションサーバのリバースプロキシとしても機能するということです。

### まとめ
インフラ面の構築にかなり手間取っており、調べるほどわからない言葉が出てくるのでしっかりと理解し疑問に対して深掘りしようと思いました
引き続き頑張ります。
見ていただきありがとうございました。
Google ColabでPythonを使ってCSVファイルを解析する簡単な例

[Google Colab](https://colab.research.google.com/)は、ブラウザ上でPythonコードを実行できる無料のツールで、データ解析や学習に最適です。特別なインストール不要で、すぐに試せるのが魅力です！

### ColabでCSVファイルを準備する
Google ColabでCSVを扱うには、まずファイルを用意する必要があります。

試作用に、以下のような簡単なCSVをテキストエディタで作り、sample.csvとして保存してからアップロードしてみましょう：

```csv
name,age,job
Taro,25,Engineer
Hanako,30,Designer
Jiro,22,Student
```

ファイルをアップロードする。

```python
from google.colab import files
uploaded = files.upload()
```

これで準備完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/9534c7aa-37aa-4619-aa43-951232df8dc0.png)


### CSVファイルを読み込む基本コード
Pythonの標準ライブラリcsvを使って、アップロードまたは作成したsample.csvを読み込んでみましょう。Colabのセルに以下を入力して実行します：

```python
import csv

# CSVファイルを開く
with open('sample.csv', 'r', encoding='utf-8') as file:
    # CSVリーダーを作成
    reader = csv.reader(file)
    
    # ヘッダー行を表示
    header = next(reader)
    print('ヘッダー:', header)
    
    # データを1行ずつ表示
    for row in reader:
        print('データ:', row)
```
実行すると、こんな出力が得られます：

```
ヘッダー: ['name', 'age', 'job']
データ: ['Taro', '25', 'Engineer']
データ: ['Hanako', '30', 'Designer']
データ: ['Jiro', '22', 'Student']
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/2a6c8930-e643-4913-9c2d-7e590e498557.png)


Colabではセルごとに実行結果がすぐ下に表示されるので、動作確認がとても簡単です。

### 年齢でフィルタリングしてみる
データをただ読むだけでなく、少し加工してみましょう。たとえば、25歳以上の人だけを表示するコードです：

```python
import csv

with open('sample.csv', 'r', encoding='utf-8') as file:
    reader = csv.reader(file)
    header = next(reader)  # ヘッダーをスキップ
    
    # 25歳以上の人のみを表示
    for row in reader:
        name = row[0]    # 名前
        age = int(row[1]) # 年齢（文字列から整数に変換）
        job = row[2]     # 職業
        
        if age >= 25:
            print(f"{name} ({age}歳) - {job}")
```
出力結果：

```
Taro (25歳) - Engineer
Hanako (30歳) - Designer
```

Colabなら、このコードをセルに貼り付けて「再生」ボタンを押すだけで結果が見られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/d96259d5-fb39-46ca-9b51-cbba84d63310.png)


### 辞書形式で読み込む（DictReader）
csv.DictReaderを使えば、ヘッダーをキーとした辞書形式でデータを扱えます。コードはこちら：

```python
import csv

with open('sample.csv', 'r', encoding='utf-8') as file:
    reader = csv.DictReader(file)
    
    for row in reader:
        print(f"{row['name']} ({row['age']}歳) - {row['job']}")

```
出力は先ほどと同じですが、列名を直接指定できるので、可読性が上がります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/3cc1be65-c4be-45d9-ad91-201e0053bb29.png)


### Colabならではのポイント
- ファイルの管理: Colabの「ファイル」タブでアップロードしたCSVを確認したり、ダウンロードしたりできます。
- 一時性: Colabの環境はセッションが終わるとリセットされるので、重要なファイルはGoogle Driveに保存するのがおすすめ。
- Google Drive連携: 大きなCSVを扱う場合、from google.colab import driveでDriveをマウントすれば、簡単にアクセス可能です。
 
### まとめ
Google Colabを使えば、インストール不要でCSV解析をすぐに始められます。Pythonのcsvモジュールで基本的な読み込みやフィルタリングができ、Colabのインタラクティブな環境で試行錯誤も簡単です。さらに高度な分析をしたいなら、pandasライブラリを試してみるのも良いでしょう。
ぜひColabを開いて、このコードをコピペして動かしてみてください。データ解析の第一歩が踏み出せますよ！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155256/cd7f5d82-fa2f-4bf9-880a-40ef6c59b548.png)
自作OSのフォントを決めて、インストールした話

はい、miku_JK_Jbです

今回は私が開発している自作OSのフォントを決めて、インストールした話をしていこう。

最近忙しくて、ブログやYoutube動画の作成に中々時間が取れなかった🥺



まずは、何のフォントにしたのかを見ていこう



私が自作OSに採用したフォントはNotoSans-JPとNotoSansだ

![フォントインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765588/f19a6f4f-9dfc-4aa6-99dc-a1dfb10be7dd.png)


それでは何故NotoSans-JPとNotoSansの２つを採用したのかを説明していこう



まず私が重視したのは、見やすさと多言語性だ。
NotoSansシリーズはGoogleとAdobeが共同で開発したフォントなので、ほかのフォントと比べて見やすさが段違いだ。
私の開発しているOSはユーザーエクスペリエンスを重視しているので、見やすさはかなり重要だ。NotoSansはAndroidやデジタル庁にも採用されているので見やすさの面においては間違いなく上位にあがるだろう。

↓見たまえ、この見やすさを。GoogleFontsから引用
![スクリーンショット 2025-02-23 215645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765588/84f2efbf-0ed9-4dd7-9d97-ad9d281adea8.png)


次は多言語性について解説していく。
NotoSansはUnicode企画に含まれる800以上の言語に対応している。
もう、フォントの多言語のスペシャリストと言ってもいいくらいだ

では、なぜ多言語性が必要なのか？
これは、ユーザーエクスペリエンスを重視しているOS且つAmazonなどで世界的に販売することを考えているので、外国の人も問題なく使えるようにしたいからだ。

また、なぜNotoSansとNotoSans-JPの２つなのか？
これはNotoSans-JPは名前からもわかる通り日本語向けのフォントだ。
NotoSansは日本語以外の言語を対応してもらうために入れた。さっきも触れた多言語性だね。

そんな最強なフォントを私は何故渋ったのか？
それはライセンスだ。
とは言ってもNotoSansのライセンスはSIL1.1ライセンス
これは、フォントのライセンスの中でもかなり優しい部類のライセンスだ。

私は勘違いをしていた。
どこを勘違いしていたのかと言うと。「組み込みにフォントを使用した場合ライセンス情報と著作者情報を含める」という部分だ


これを私はソースコードのライセンスも同じようにしないといけないという頭の悪い勘違いをしていた。

実際の所はユーザーなどに、ライセンス情報と著作者情報が見れるようにすれば良いというだけだった（笑）

NotoSansを使用する私はライセンス情報と著作者情報を見れるようにしなければならない

そこで私が考えたライセンス情報と著作者情報の表記は以下の通りだ

設定アプリ内のシステム情報画面に「フォント情報」としてユーザーに見れるようにする
こうすることで、ユーザーもシステムフォントに何を使っているのか分かるし、ライセンス的にも大丈夫なので皆Happy Happyだ。

ちなみに私は最初システムフォントもユーザーの好きなように変えれるようにしようと思っていた
だが、それは流石にライセンス的にもまずいと思ったのでやめた。
まあ、大体の人は分かるだろうがフォントにはライセンスがある。
システムに組み込むのをやめてほしいフォントもあればOKなフォントもある

もし、ユーザーが組み込むのが駄目なフォントを選んだら？
これはライセンスに違反することになる。つまりペナルティを受けることになる。
対象はライセンス的にアウトなフォントを追加したユーザーとそれをいとも簡単にできるようにした私になるだろう。

流石に嫌でしょ
17でムショ行きで、パクられた理由がフォントの著作権法違反は流石にね😅
なのでやめた。

そうならないために
私が考えた対処法は以下の通りだ。

システムフォントはSystemディレクトリ内に配置し、OSのシステムに権限を持たせてユーザーが触れないようにする
ユーザーがフォントを追加したい場合は、専用のFontsディレクトリ内にインストールされるようにする
こうすることで、ライセンスを遵守することができるね😁✌️

ちなみにユーザーがOSのシステムフォントが何を使っているかを知りたい場合は、さっきも触れた、ライセンス表記&著作者情報と一緒で設定アプリから「フォント情報」から見れるようにする。見れるようになれば透明性が出るからね

ちなみに現在のファイルシステム内にはこんな感じ
![ファイルシステム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765588/a4cf559f-097b-4549-8099-1aae712e6f68.png)

システムディレクトリ内はこんな感じ
![Systemディレクトリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765588/4da2e207-aed0-46ab-b580-ebb33e82a720.png)


まあ、こんな感じかな。OSのシステムフォントに関しては。
ということで自作OSのシステムフォントはNotoSansとNotoSans-JPに決まったよ。という話でした☆

以上miku_JK_Jbでした