OmniAICreator/Qiita-1.07M huggingface dataset:
この間作ったGoアプリをRenderにデプロイしてみる

## はじめに  
今回は、以前Golangの練習がてらに作成した[トレーニング記録アプリ](https://qiita.com/RyutoYoda/items/b44472e766ce7bfebf22)を、Renderにデプロイする手順を解説します。データベースの作成から、Goアプリケーションとの接続、環境変数の設定、デプロイ方法までをカバーします。

## **Step 1: Renderに PostgreSQL データベースを作成する**  
1. **Render.com にログイン**  
   まだアカウントを作成していない場合は、Render.com にサインアップします。
2. **新しいデータベースを作成**  
   - Render のダッシュボードから「New」ボタンを押し、「PostgreSQL」を選択します。
   
   - データベースをホストするリージョンを選びます。
   - データベース名やユーザー名などの詳細を入力します。
   ![スクリーンショット 2024-12-31 0.36.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/ab899426-65ba-b02e-c408-2fb1efa70498.png)

3. **データベース接続の確認**  
   データベースが作成されると、接続に必要な情報（ホスト名、データベース名、ユーザー名）が表示されます。**PSQL Command**の情報を使って接続を確認します。ターミナルを開き以下のコマンドと表示されたパスワードでデータベースに接続します。
   ```bash
   psql -h ******oregon-postgres.render.com -U root workoutdb_k0zf
   PGPASSWORD=********
   ```
   ![スクリーンショット 2024-12-31 0.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/de18c8a4-23a1-8b6c-7ecd-5b1da763f589.png)
   接続が確認できます。![スクリーンショット 2024-12-31 0.50.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/a311e889-70e2-bd04-94cf-e7a0fd969aec.png)
   
## **2 : Go アプリケーションを Render.com にデプロイする**  

### 1. **Renderにアプリケーションをデプロイ**  
   Render ダッシュボードから「New」ボタンを押し、「Web Service」を選択します。GitHub リポジトリを選び、クリックします。
   ![スクリーンショット 2024-12-31 2.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/10d9f2d4-3d87-a182-f579-f2446596a41a.png)

### 2. **環境変数の設定**  
データベースの接続情報（パスワードなど）を本番環境のコードにハードコーディングしてしまうの危険です。代わりに、環境変数を使用して接続情報を管理します。**docker-compose.yml**内でパスワードなどの秘匿情報を環境変数に置き換えます。
```yaml
version: '3'

services:
  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"

  go-app:
    build: .
    depends_on:
      - db
    environment:
      - DB_HOST=${DB_HOST}
      - DB_NAME=${DB_NAME}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
      - DB_SSLMODE=require 
    ports:
      - "8080:8080"

volumes:
  postgres_data:
```

アプリケーションのサービス設定ページで「**Environment Variables**」セクションを開き、下記の環境変数を入力します。

![スクリーンショット 2024-12-31 1.22.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/6ba82cba-78b7-2e47-063f-05421e7e38aa.png)
   
### 3. **デプロイ**  
   設定が完了したら、デプロイを行います。Render.com でアプリケーションがデプロイされ、指定した URL からアクセスできるようになります。ブラウザで確認して、正しくデプロイされていることを確認しましょう。
```
#14 DONE 2.4s
Pushing image to registry...
Upload succeeded
==> Deploying...
2024/12/30 17:10:41 サーバーがポート8080で起動しています...
==> Your service is live 🎉

https://アプリ名.onrender.com/
```

![スクリーンショット 2024-12-31 2.42.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/b0bf6895-32c4-229b-8a16-3583cfaec77e.png)



## **まとめ**  
この記事では、PostgreSQL を使った Go アプリケーションを Render.com にデプロイする方法と、ローカル開発環境での連携方法について説明しました。環境変数を使用してデータベース接続情報を安全に管理し、Render.com でアプリケーションをホスティングする手順を紹介しました。この手順を参考にして、あなたのアプリケーションをクラウド環境にデプロイしてみましょう。
Pythonのmatch文で他言語のswitch文のような条件分岐を書く

# はじめに
本記事はPythonでif … elif文を書いていて、他言語のswitch文ような構文が使えないか気になったので調べてみた備忘録になります。


# 環境
Python 3.12

# match文の活用

Pythonのバージョン3.10で追加されたmatch文を活用できそうです。
参考：https://docs.python.org/ja/3.10/reference/compound_stmts.html#the-match-statement

簡単なif … elifの条件分岐を書いてみます。

```python:index.py
def get_day(day_number):
    if day_number == 1:
        return "月曜日"
    elif day_number == 2:
        print("火曜日")
        return "火曜日"
    elif day_number == 3:
        return "水曜日"
    else:
        return "不正な値です"

get_day(2) # "火曜日"
```

上記のようなif … elif  …条件分岐をmatch文では次のように書けそうです。

```python:index.py
def get_day(day_number):
    match day_number:
        case 1:
            return "月曜日"
        case 2:
            print("火曜日")
            return "火曜日"
        case 3:
            return "水曜日"
        case _:
            return "不正な値です"

get_day(2) # "火曜日"
```

# 参考

https://docs.python.org/3/tutorial/controlflow.html#match-statements
Java関数名に便利な単語表

Java関数名に便利な単語表：より良い関数命名のためのガイド

Javaの関数名をつける際に、わかりやすく、意図が伝わるような命名は、コードの可読性を高め、保守性を向上させる上で非常に重要です。本記事では、関数名に使える便利な単語表と、効果的な命名のポイントをご紹介します。

なぜ関数名に気をつけるべきか？
可読性向上: 関数名が何を意味するか一目瞭然であれば、コードの理解が容易になります。

保守性向上: 関数名が適切であれば、コードの変更や追加がスムーズに行えます。
コラボレーション促進: チームで開発する際、共通の命名規則があると、誤解を防ぎ、効率的な開発が可能になります。

関数名に使える単語の分類と例
関数名は、その関数の動作を簡潔かつ正確に表す必要があります。以下に、よく使われる単語の分類と例を示します。

### 動詞 (何をするか)
```
取得: get, fetch, retrieve, load
設定: set, update, modify, replace
追加: add, append, insert
削除: remove, delete, erase
計算: calculate, compute, evaluate
比較: compare, match, equals
変換: convert, transform, map
チェック: check, verify, validate
生成: create, generate, produce
表示: display, show, render
```
### 名詞 (対象)
```
データ: data, value, item, element
リスト: list, array, collection
オブジェクト: object, instance
ファイル: file, document
エラー: error, exception
状態: state, status
前置詞 (対象との関係)
in: ～の中に
from: ～から
to: ～へ
by: ～によって
with: ～と一緒に
```

### 接頭辞・接尾辞
```
is: 真偽値を返す
has: 属性を持っているか
able: ～できる
ing: ～している
```

#### 効果的な関数名をつけるためのポイント

動詞+名詞 の組み合わせが基本
簡潔でわかりやすい 名前にする
ドメイン知識に合わせた 名前にする
camelCase を使う (例: calculateTotalPrice)
同じ種類の処理には同じような名前 をつける
否定形の単語は避ける (例: isNotValid ではなく isValid)
文脈によって意味が変わる単語は避ける (例: find, get)
lambdaレイヤー+ openai apiでimportエラーが起きる時の対策（備忘録）

生成AIを使ったLine botをlambdaを使って作る際の備忘録です。

# 結論
下記のようなバージョンを指定する。
```
mkdir python
python3 -m pip install -t ./python fastapi==0.99.0 openai==0.28.0
zip -r openai.zip ./python
```

# 参考リンク
https://qiita.com/naoto_koyama/items/a3af50f858dbd62d63db

# つまづくステップ
- pydanticエラー
```
Unable to import module 'lambda_function': No module named 'pydantic_core._pydantic_core
```
https://qiita.com/nabata/items/903a2ebff8e44516598e

- jiterエラー
```
No module named 'jiter.jiter' 
```
https://zenn.dev/galapagos/articles/a222e38a32f4ba
TC001 (Awtrix) で Year Progress や Internet Time を表示する

## Year Progress を少しいじって表示させてみた
今年も残すところあと1日。巷ではカウントダウンイベントが多数開かれるであろう大晦日。

そんな日なので、今さらながら Awtrix Flow の Year Progress を入れてみることにした。

https://flows.blueforcer.de/flow/MYjJZA67oyrL

当然ながら、これをそのまま使うと 99% としか表示されないので少しだけいじる。
![yearprog1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/120e4da7-142d-f432-3866-a91f24bd6e99.png)

### 切り捨て整数化しかなければ、掛けて割ればよい
JavaScript の切り捨て関数 `Math.floor` は切り捨て整数化しかできないように見える。
```javascript: original
const progress = Math.floor((diffInMillis / totalMillis) * 100);
```
だが、例えば10倍して整数切り捨て→10で割れば小数第1位までで切り捨てと同じ結果になる（小数点以下の0を補う方法は別途考えないといけない）。

https://zenn.dev/katoaki/articles/d9646053e3ff2f

ということで、
```javascript: 小数第2位まで表示
const progress = (Math.floor((diffInMillis / totalMillis) * 10000) / 100).toFixed(2);
```
こういじればよいことになる。
小数第1・2位に0を補うのは `to.Fixed(2)` の部分。前段は全部カッコで括っておく。

https://qiita.com/koob/items/17411f409699e52012d1

https://zenn.dev/shinkano/articles/0fa71ad65614b6

![yearprog2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/b86e6e81-4dc6-7de7-faa3-584a1699ae24.png)
無事表示することができた。

小数第3位まで表示することも考えたが、%をつけるとスクロールするので2桁で妥協。

これで物足りなければ、いっそ ppm （百万分率）で表示させる手がある。
これなら1分に2カウントくらい進む。
![yearprog3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/4c455d85-c024-7081-b64b-9caf53f4b5d3.png)

## Internet Time を表示させる
これだけだとあまりに記事としてしょぼいので、応用として Internet Time の表示も作ってみよう。

Swatch が商品化もした Internet Time だが、現在 Swatch 内でも解説ページがある位で、 Web にすら大々的な時刻表示はなく、左上にちょこっと表示される程度である。

https://www.swatch.com/en-en/internet-time.html

![yearprog4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/228e15cb-6306-64be-87fc-b4c6a75894b2.png)

（実物も持っているが電池切れ。電池を交換したらここに載せる予定。）

Internet Time はタイムゾーンが UTC+1、1日を1000分割した beat を用いて表す十進時計である。

### PHP は標準で使える
何と、 PHP は時刻のフォーマット文字列に B を指定するだけで表示できるようだ（！）。

https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%82%BF%E3%82%A4%E3%83%A0

```php: internet_time.php
<?php
echo date("B");
?>
```
```:実行結果 (22:14 JST 頃)
593
```
おおぉ…これを Node-RED に読め込めば…

### Node-RED で実装する
とはいえ、 JavaScript で Internet Time を求めるのもそれほど難しくはない。
```javascript: Internet Time
var utcmillitime = new Date().getTime();
var bieltime = utcmillitime / 1000 + 1 * 60 * 60; 
var inet_time = Math.floor((bieltime % 86400) / 86400 * 1000);
inet_time = ( '000' + inet_time ).slice( -3 );
msg.payload = {"text":inet_time, "icon":"inet_time"};
return msg;
```
`getTime` で 1970/1/1 0:00:00 UTC からのミリ秒が求まるので、秒に直して UTC+1 にゾーンシフト。あとは1日の秒数(86400秒)で剰余を取り、割って小数化、1000倍して切り捨てれば OK 。

頭の0埋めは以下を参考にした。

https://rfs.jp/sb/javascript/js-lab/zeropadding.html

こんな感じに表示できる。
![yearprog5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/bccfd630-aaf6-96d2-dbea-9ec2fdae6f2b.png)
大雑把でよければ MQTT による更新は1分毎で十分である（1 beat は 1分26.4秒）。

それでは、よいお年を。
Flaskで初めてのWebアプリケーション開発

# 大学生が挑戦するFlaskアプリ開発記 - 学科選択支援ツールの進化

こんにちは、情報系大学3年生のharuです。
今回は、ハッカソンをきっかけに始めた「学科選択支援アプリ」の開発記録を共有していきます。
# プロジェクトの生まれ方

大学のハッカソンで、受験生の進路選択を支援するWebアプリを開発しました。20の質問に答えると、その回答から最適な学科を提案してくれる簡単なシステムです。さらにChatGPT APIを活用して、個別化されたアドバイスも提供します。
- スタート画面
![学科適性判定クイズ - Google Chrome 2024_12_31 1_32_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3745562/fffafb13-706a-f8fd-9182-3ffaf3146877.png)
- 質問画面
![学科適性判定クイズ - Google Chrome 2024_12_31 1_33_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3745562/5a882552-cb99-a89b-f0ac-bd3714d326d5.png)
- 結果画面
![学科適性判定クイズ - Google Chrome 2024_12_31 1_34_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3745562/52fddf40-2483-2a05-5a64-4dcf14962073.png)



このアプリを開発していく中で、「他大学版も作られるようにし､より多くの受験生が役に立ちたい」という思いが浮かび、より多くの受験生の役に立てるプロジェクトに発展させることを決意しました。

# 技術スタック

開発環境の構築にはDockerを採用し、以下の技術で実装していきます：

- Python/Flask - 高速な開発と拡張性の実現
- MySQL - 堅牢なデータ管理 
- Docker - 環境構築の効率化

# 今後の展開

現在のアプリを以下の機能で進化させます：

1. マルチユーザー対応
  - ユーザー認証システムの実装
      - サインアップ機能
      - ログイン・ログアウト機能
  - 大学ごとの質問集の作成・管理機能
      - データベース設計
      - SQL実装
  
2. コミュニティ機能
  - 質問集の共有システム
  - 他大学の質問集へのアクセス

この開発記録では、実装の過程で得た知見や直面した課題、その解決方法を詳しく共有していく予定です。
paiza 勉強記録【宝くじ】【Java】

paizaでの勉強記録です。
今回は下記のレベルアップ問題集のCランク問題の「宝くじ」を実施しました。
各賞の判定に用いる数字を変数に設定して、最後にそれと宝くじの番号の比較を行っていますがもう少しスマートにしたい、、、特に前後賞あたりとか
あと各賞に当選しているかの判定は別でメソッドを定義して、mainメソッドではそれを呼び出して受け取った結果から何等かを出力するようにした方がアーキテクチャ的にはいいのだろうか、、、

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/lottery
```java
import java.util.Scanner;

public class paiza {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int prizeNumber = sc.nextInt();
        int purchaseNumber = sc.nextInt();

//        前後賞の番号の設定
        String upperPrizeNumber;
        String underPrizeNumber;
        
        if (prizeNumber==100000) {
        	upperPrizeNumber = Integer.toString(prizeNumber+1);
        	underPrizeNumber = "0";
		} else if (prizeNumber==199999) {
			upperPrizeNumber = "0";
			underPrizeNumber = Integer.toString(prizeNumber-1);
		} else {
			upperPrizeNumber = Integer.toString(prizeNumber+1);
			underPrizeNumber = Integer.toString(prizeNumber-1);
		}
        
//        2等賞、3等賞の番号の設定
        Integer prizeNumberInteger = Integer.valueOf(prizeNumber);
        String secondPrizeNumber = prizeNumberInteger.toString().substring(2, 6);
        String thirdPrizeNumber = prizeNumberInteger.toString().substring(3, 6);;
        
//        各宝くじの当選チェック
        for (int i = 0; i < purchaseNumber; i++) {
        	String ticketNumber = sc.next();
        	if (ticketNumber.equals(prizeNumberInteger.toString())) {
        		System.out.println("first");
        	}else if (ticketNumber.equals(upperPrizeNumber) || ticketNumber.equals(underPrizeNumber)) {
        		System.out.println("adjacent");
			} else if (ticketNumber.substring(2, 6).equals(secondPrizeNumber)) {
				System.out.println("second");
			} else if (ticketNumber.substring(3, 6).equals(thirdPrizeNumber)) {
				System.out.println("third");
			} else {
				System.out.println("blank");
			}
		}
        
        sc.close();
    }
}
```

### 参考

https://www.javadrive.jp/start/string/index11.html
STS3032を使ってみる

STS3032というサーボモータを知っていますか？
FEETECHが出している連続回転シリアルサーボモータで、秋月電子やスイッチサイエンス等で購入可能です。

今回はSTS3032をArduino等で使う方法について紹介します。

# STS3032とは

連続回転のシリアルサーボです。
連続回転というのは180度までと角度が制限されているのではなく、ロボットのタイヤのように何周でも回転できるという意味です。
サーボモータというとSG90やFS90RのようにPWMで制御するのでは？と思うかもしれませんが、このサーボはシリアルサーボなのでシリアル通信で制御します。

そのため、モータの動作の仕方を細かく指定したり、モータ側からフィードバックを得たりすることができます。
その分回路や制御が難しく、値段もそこそこ高いのですが、小型ロボットの足回りに使用できるほどトルクとスピードともに優れており、便利なサーボモータです。

こちらが秋月電子のページです。

https://akizukidenshi.com/catalog/g/g116311/


# 通信方式・回路
シリアル通信といいましたが、詳しくはRS485（なのかRS485もどきなのかよくわからないが以後RS485とします）の半二重通信方式で通信します。

半二重通信というのは、受信と送信を一つの信号線で行う通信方式のことです。
一方でUARTのように受信と送信を別の信号線で行う通信方式を全二重通信と言います。

Arduinoなどのマイコンについているのは全二重通信のUARTであるため、制御するためにはUARTをRS485に変換する回路を作らなければなりません。

そのために販売されているのがこちらのFE-URT-1ボードです。

https://akizukidenshi.com/catalog/g/g116295/

これはUSBやUARTをRS485に変換してモータと接続できるボードで、このコントローラを使うことでモータを制御できます。ちなみにサーボモータにはidを割り振って制御するので、一つの変換回路で複数のサーボモータを制御できます。

しかし、これはロボット等に組み込むには大きくて邪魔だし値段も高いしであまり使いたくないですよね。

そこでは回路を自作しましょう！

なんと！ありがたいことに秋月電子さんが公開しているPDFに参考回路がのっています。

https://akizukidenshi.com/goodsaffix/feetech_digital_servo_20220729.pdf

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/4716a626-3430-e121-225c-31e0800b487a.png)


これと全く同じ回路で動作しました。これを基板実装なりブレッドボード上で作ってみるなりすると動かすことができます。（MAX485にSOP8変換基板などを使えばブレッドボードでも作れます）

TX、RXをマイコンにつないだりUSB-シリアル変換モジュールを挟んでPCにつないだりしましょう。


ちなみにこのPDFには5V用と書いてありますが、動作電圧が3.3Vのマイコン（STM32など）でもこの回路で問題なく動作しました。


# モータの設定

STS3032はPCと接続することで専用のソフトウェアを使用して設定をすることができます。
詳しくは先ほど挙げた秋月電子さんの[こちらの資料](https://akizukidenshi.com/goodsaffix/feetech_digital_servo_20220729.pdf)にのっているのでそちらを参考にしてください。
このソフトウェア上でidを変更することで、同じ通信バス上で複数のモータを制御できるようになります。

# マイコンで動かしてみよう

それではArduinoやSTM32などのマイコンで動かしてみましょう。

STS3032を含むSTSシリーズ、SCSシリーズ、SMSシリーズのためのSCServoというライブラリがあります。

秋月電子のサイトからダウンロードしたり、PlatformIOで開発するならPlatformIOからダウンロードしてください。

以下はWheel Modeで回転するプログラムです。

``` sts3032.ino

#include <INST.h>
#include <SCS.h>
#include <SCSCL.h>
#include <SCSerial.h>
#include <SCServo.h>
#include <SMS_STS.h>

#define ServoID 1  // your STS3032 ID

int speed=2000;

SMS_STS sts3032;



void setup() {
  // These Serial Port should be the port you are using
  Serial.begin(1000000);
  sts3032.pSerial = &Serial;

  //Change STS3032's Mode to Wheel Mode
  sts3032.unLockEprom(ServoID);
  sts3032.EnableTorque(ServoID, 1);
  sts3032.WheelMode(ServoID);
  sts3032.writeByte(ServoID, SMS_STS_MODE, 1);
  sts3032.LockEprom(ServoID);

  
}

void loop() {
  sts3032.WriteSpe(ServoID,speed);
  delay(1000);
  sts3032.WriteSpe(ServoID,-speed);
  delay(1000);

}
```


マイコンのUARTと変換基板とSTS3032サーボをつないだうえで、プログラムを書き込んで実行してみてください。

これで動けば成功です！

他にもモード等あるので試してみてください。ちゃんとしたドキュメント等はなさそうなので、ライブラリの中のコードやサンプルコード、他の人のプログラムなどを見ながら書いてみるとよいと思います。


# 最後に
一個5000円くらいするので少し高いですが、小型でトルクが高くてエンコーダ付きで金属ギアでというとても優秀なサーボモータなのでぜひ使ってみて下さい。


ご質問やご指摘等ございましたらお気軽にコメントください！


# 補足
4つのモーターを動かそうとすると少しタイムラグが生まれます。
この原因は通信の度にACK（確認応答）の処理をしていることです。

なくても通信に問題がなければ動作するので、いらない場合はライブラリの中のコードを書き換えて（ACKの部分をコメントアウト）しまってよいと思います。

四輪駆動ロボットなどを作ろうとしている人はぜひお試しください。

↓詳しくはこの一連のポストをご覧ください

https://x.com/shuji_4649/status/1847944572435050664
Pythonの環境構築M1 Mac使用

## 実行環境

- チップ:Apple M1
- macOS:Sonoma 14.6.1

## 手順

- pyenv導入します。`brew install pyenv`コマンドを実行してください。
- シェル設定(zshの場合)を行います。1~4を順番にターミナルで実行します。
1. `echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc` 
2. `echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc`
3. `echo 'eval "$(pyenv init -)"' >> ~/.zshrc` 
4. `source ~/.zshrc`
- 今回はPython3.10.0を使用するので、インストールをします。
1. `pyenv install 3.10.0`
2. `pyenv global 3.10.0`
- プロジェクトの作成、`mkdir sample-fastapi` そして、作成したプロジェクトに移動してください。
- 仮想環境を作成します。`python -m venv venv`を実行します。
- 仮想環境を有効化するために、`source venv/bin/activate`を実行します。
- 必要なパッケージのインストールをします。`pip install fastapi uvicorn`を実行します。
- `main.py`に下記の記述をします。

```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}
```

- サーバの起動、`uvicorn main:app --reload`を実行します。
- 念の為、仮想環境などGitに上げないように`.gitignore`の記述です。

```bash
# Python
__pycache__/
venv/
env/
.env
.venv

# IDE
.idea/
.vscode/

# Local development
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
```

## 参考記事

[MacでPythonをインストールする方法  - Qiita](https://qiita.com/omo_taku/items/bc97f69391b2f4627f36)

[venv: Python 仮想環境管理 - Qiita](https://qiita.com/fiftystorm36/items/b2fd47cf32c7694adc2e)
linuxのログファイルの世代数について

# はじめに

ログファイル数の世代数について知識不足のため、有識者にご教示いただきました。

①の数え方は「ログファイル自体の世代」という観点
```
cd /var/log

messages 1世代

messages_20241230 2世代
messages_20241229 3世代
```

②の数え方は「ログローテーションしたバックアップの世代管理」という観点
```
cd /var/log

messages → 現役
messages_20241230 1世代
messages_20241229 2世代
```
# まとめ
よく実務でもバックアップを1世代のみ残してくださいと依頼がありますが、
「ログローテーションしたバックアップの世代管理」という観点でいうと②が適切です。
曖昧な部分のため、「ログファイル自体の世代」又は「ログローテーションしたバックアップの世代管理」なのか念のため、確認する必要があります。
Gitで過去の草を生やす方法

<h2>過去のプロファイルに草を生やしたい</h2>
検索してすぐ出てこなかったので備忘録として書く

コミット忘れていて、草が生えなかった
DECの30にコミットを過去に遡ってしたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/43371eb7-65d0-6d46-4f6b-71a3a38e2396.png)

以下のコマンドで草を生やしました
data=より後ろのところを適宜変えることで任意の時間へコミットできます

```terminal:過去へコミット
git commit -m "コメント" --date="dec 30 23:59:59 2024 +0900"
```

DECの30日のところに草を生えました↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/1817def1-0223-c795-6e85-616c9e44b07f.png)

あんまり草が生えていても意味がないですが、これでコード書く習慣が途切れて萎えるのをケアできます

<h2>参考</h2>

https://qiita.com/keito8080/items/eaab75b35d91c8d73f78
リーダブルコードを読み終わってしまった

# 現状報告
前回投稿したのが、僕の記憶が正しければ確か11月中頃だったと思います。
そして今この文章を書いているのが12月30日です。
年末になってしまいました。そして、2回目の投稿を待つ前にリーダブルコードは読み終わってしまいました。
みなさん、よいお年を。

# 何かしらのアウトプットはしたい
そんなわけで、もう意味がないと言われたらぐうの音は出ませんが、それでも自分の頭の中に残っているものをできるだけアウトプットしておきたい。それだけのために誰に需要があるかわかりませんが、書き残しておきます。
優しい貴方、お付き合いください。

## 本題
#### 何できれいなコードを書かないといけないのか？
ソースコードが「書かれる時間」と「読まれる時間」はどちらが長いか？「読まれる時間」の圧勝である。
自分の書いたコードは、その後保守や追加開発を行う人が、どんな処理をしている箇所なのか理解するために、時間を使って読む必要がある。何なら自分で書きながら、その直前に自分で書いたコードを読んで処理の流れを理解する必要がある。
そんな形でいろんな人に何度も何度も読まれるのがコードであるから、それにかかる労力を最小限にするために、きれいで読みやすいコードである必要がある。

#### 十分な情報量で誤解されない名前
コーディングをする際には、変数やメソッドに名前を付ける。その際、それぞれの変数やメソッドが何をする者かが名前を見ただけで理解できるようになっていれば、可読性が格段に上がる。
そのためには、ただ短さにこだわるような名前ではだめ。とりあえず印象に残ってることは↓のような感じ。
・スコープに合わせて変数名を決定
・変数の方やメソッドの内容に合わせて接頭辞や接尾辞を決定
・具体的な名前にして汎用的な名前にしない

#### 無駄を省く
先ほど書いた通り、"コードを読む"ということのコストを削減するという大前提を達成するために、コードは可能な限り短く、無駄の少ないものとすべきである。例えば以下のようなものが無駄とされている。
・不要な中間変数
　→結果を返すための値を一時的に格納するためだけに宣言された変数
・ソースで記載したことを日本語にしたコメント
　→一番の理想はソースを読んだだけで何をしているかが直感的にわかること。ソースに書いていることをそのまま説明するようなコメントがある場合、単純に読むコストは2倍になる。
 　　コメントに書くべきは、Whyの内容。WhatやHowはコードに含まれるべき。

#### 単純化することに悪はない
処理ロジックを書く際に、小さい部品に分割して単純化していくということによるデメリットはなし。
1つのメソッドには1つの役割しか持たせない。
この原則を守ることによるメリットは多数。
・機能改修時の影響範囲が小さく、改修のハードルが下がる
・メソッド名を見ただけで詳細の処理内容を予測することができ、究極読まなくてもよいということも実現できる
・短いとシンプルに読みやすい

## 感想
非常に読みやすく、面白くで、なんでもっと早く読んでおかなかったんだろうと過去の自分が雑魚すぎて悲しくなりました。自分が参画しているプロジェクトのソースコードを思い出しながら読むとリファクタリングしたくて仕方ない気持ちにもなりました。
アウトプットとして今回Qiitaに内容の要約を書かせてもらっていますが、その他にも自分の業務の中でコードレビューなどの際でもアウトプットができました。（やたらと細かい部分を指摘してしまった後輩さんよ申し訳ない、、）
本使って勉強するのは久々だったんですが、楽しかったです。味を占めて、また別の本を読み始めてます。
また余裕出来たら、アウトプット用の投稿をしようかと思います。また今度、よいお年を。
プログラミング超初心者がAIと二人三脚でWEBアプリ作ってみた

# 🌱 プログラミング超初心者がAIと二人三脚でWEBアプリ作ってみた

## 🎯 はじめに

みなさん、こんにちは！プログラミング歴3ヶ月の超初心者です。今回、AIと一緒に「びょういんナビ」というWEBアプリを開発してみましたので、その過程で学んだことを共有させていただきます。

初心者ならではの試行錯誤や、**AIとの効果的なコミュニケーション方法**について、私なりの発見がありましたので、それを中心にお話しできればと思います。

## 🏥 アプリケーションの概要

「びょういんナビ」は、症状から適切な診療科を提案してくれるWEBアプリです。開発のきっかけは、「病院に行きたいけど、どの診療科に行けばいいかわからない」という身近な悩みでした。

### 主な機能
- 🎈 年齢選択（子供向けのUIを実装）
- 🤒 症状選択（部位別に整理）
- 🏥 診療科レコメンデーション（AIによる判断）

### 技術スタック
```mermaid
graph TD
    A[びょういんナビ] --> B[Frontend]
    A --> C[Backend/AI]
    
    B --> D[React]
    B --> E[Tailwind CSS]
    B --> F[Framer Motion]
    
    C --> G[AWS Bedrock]
    G --> H[Claude]
    
    style A fill:#d0e8f2,stroke:#0077be,stroke-width:2px
    style B fill:#e6f3ff,stroke:#0077be
    style C fill:#e6f3ff,stroke:#0077be
    style D fill:#f8fcff
    style E fill:#f8fcff
    style F fill:#f8fcff
    style G fill:#f8fcff
    style H fill:#f8fcff
```

### 技術選定のポイント

1. **React** 🎯
   - コンポーネントベースの開発
   - 豊富な教材とコミュニティ
   - 直感的な状態管理

2. **Tailwind CSS** 🎨
   - 高速なUI開発
   - モバイルファーストの設計
   - クラス名で直感的にスタイリング

3. **Framer Motion** ✨
   - 直感的なアニメーション
   - スムーズな遷移効果
   - ユーザー体験の向上

4. **AWS Bedrock (Claude)** 🤖
   - 高精度な症状分析
   - 柔軟なプロンプト設計
   - 医療知識の活用

## 🤖 AIとの二人三脚開発

### AIとの効果的なコミュニケーション

🔍 **開発プロセスで発見した3つの重要ポイント**：

#### 1. 課題の明確な定義
```markdown
❌ 改善が必要な例：
「UIをもっと使いやすくしたいです」

⭕ 具体的な例：
「年齢選択画面で、子供向けに
大きなボタンと絵文字を使いたいです。
TailwindCSSでの実装方法を
教えてください」
```

#### 2. 段階的な問題解決アプローチ
1. 全体像の設計を相談
2. 具体的な実装方法の確認
3. エラー発生時の適切な情報共有
4. フィードバックに基づく改善

#### 3. イテレーティブな開発サイクル
- 実装 → テスト → 改善点の特定 → 実装
というサイクルを小さく回す

## 🚀 実装のハイライト

### 1. インタラクティブなUI
```jsx
<motion.button
  whileHover={{ scale: 1.05 }}
  whileTap={{ scale: 0.95 }}
  className="bg-green-500 text-white px-8 py-3 rounded-full"
>
  びょういんをさがす 🏥
</motion.button>
```

### 2. 効率的な状態管理
```javascript
const [age, setAge] = useState(null);
const [selectedSymptoms, setSelectedSymptoms] = useState([]);
const [recommendedDepartment, setRecommendedDepartment] = useState(null);
```

- ユーザー入力の段階的管理
- 状態に応じたUI制御
- エラーハンドリング

### 3. レスポンシブデザイン
```jsx
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
  {/* コンテンツ */}
</div>
```

## 🎯 今後の展望

### 追加予定の機能
- 📝 症状データベースの拡充
- 📱 スマートフォン最適化
- 🌍 多言語対応

### 学んだこと
1. AIは明確な目標設定で真価を発揮
2. エラーメッセージは重要な学習機会
3. 小さな成功体験の積み重ねが大切
4. コミュニティの知見活用が成長の鍵

## 🌟 おわりに

プログラミング初心者でも、AIとの適切なコミュニケーションを通じて、実用的なアプリケーションを開発できることが分かりました。

特に、**課題を具体的に定義する**能力は、プログラミングに限らず、様々な場面で活きてくるスキルだと実感しています。

みなさんも、ぜひAIとの協働開発に挑戦してみてください！

---

ソースコードはこちらで公開しています：
[GitHub - medical-department-finder](https://github.com/YersiniaPestis899/medical-department-finder.git)
Node.jsについて調べる

## 基礎知識を徹底的に叩き込もうDAY1🎉（24-25年末年始企画）

2024年末〜2025年始の期間は、普段使う技術についてとにかく徹底的に足元を見直す期間にします。🔥
先日、研究室の後輩にnodeバージョンのエラーについて聞かれ、上手く対応できなかったのが悔しかったのです…

今回は **「Node.js」** について。
普段、Vue.jsのプロダクトを開発していますが、根本としてNode.jsが動いています。しかし、それが一体なんなのか、なぜ必要なのか、説明できる自信はありません。
ただ私は今冬卒論があるので、「Node.jsって何？」に対してざっくり返答できる程度を目指して簡潔に調査しまとめたいと思います。

## Node.jsとは

Node.jsとは、WebサーバでもWebフレームワークでもありません。**JavaScript実行環境**のことです。PythonやRubyなどの言語とは異なり、ブラウザ上で動作するJavaScriptはOS上では基本的に動作しません。そこで、Node.jsがOS上でJavaScriptを実行することを可能にします。

JavascriptでWebアプリケーションを動かすことを可能にしてくれるNode.js。
それゆえ、サーバサイドも実装可能です。そしてサーバとしても一般的に使われているため、Node.jsはサーバサイドのJavaScript実行環境であるという言われ方もされているようです。
**サーバサイドであれ、クライアントサイドであれ、Javascriptでアプリーケーションを動くようにしてくれるのが、Node.jsです。**

## 参考記事

- [Node.jsとはなにか？なぜみんな使っているのか？](https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb)
- [コラム：『Node.js』とは？ 利用シーンやメリットを紹介](https://www.softbanktech.co.jp/corp/hr/recruit/articles/64/)
【CleanArchitecture】コンポーネントの凝集性についてのまとめ

久しぶりにCleanArchitectureを復習したので、今の理解を残しておこうと思います。

# ■ コンポーネントとは
まず、コンポーネントとは **「システムの一部として独立してデプロイ・再利用できる最小限のまとまり」** のことです。  
そして、コンポーネントには一貫したテーマや目的があり、コンポーネントの構成要素はコンポーネントの目的と関連性の高いものでなければなりません。


# ■コンポーネントの凝集性

:::note info
凝集性とは

コンポーネントが担う責務や機能がどの程度のまとまりを持っているかを示す概念で、具体的には **「コンポーネントの責務が一つに絞り込まれているか」** **「構成要素がコンポーネントの責務と強い関連性を持っているか」** を図る指標となります。  
「高い」または「低い」で表します。


- **凝集性が高い**  
  - 単一の責務に特化している
  - コンポーネントの責務を達成するための関連性の強い要素のみで構成されている
  - メンテナンス性・再利用性が高い
- **凝集性が低い**  
  - 複数の異なる責務を持っている
  - コンポーネントの責務と関連性の薄い構成要素が雑多に詰め込まれている
  - 一つの変更に対する修正範囲が大きい
:::

コンポーネントの凝集性を評価するには3つの原則が材料となります。

1. **再利用・リリース等価の原則(REP)** (再利用性のためのグループ化)  
再利用可能な単位でひとまとめにすること
2. **閉鎖性共通の原則(CCP)** (保守性のためのグループ化)  
同じ理由、同じタイミングで変更されるものはひとまとめにすること
3. **全再利用の原則(CRP)** (不要なリリース作業を減らすための分割)  
不要なものに依存しないこと

## ◎ 再利用・リリース等価の原則(REP)
> *再利用の単位とリリースの単位は等価になる。*

つまり、**再利用可能な単位でひとまとめにすること**


再利用の単位でクラスやモジュールをコンポーネントにまとめ、再利用の単位でリリースできなければいけないということです。
コンポーネントを再利用の単位で作成し、再利用の単位でリリースできるようにすることで、コンポーネントの再利用がしやすくなります。  

::: note warn
**この原則を無視すると...**
再利用の際に複数のコンポーネントを参照しなければならなくなり、バージョンの互換性の考慮が発生するなど、再利用が難しくなります
:::


## ◎閉鎖性共通の原則(CCP)

> *同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめること。変更の理由やタイミングが異なるクラスは別のコンポーネントに分けること。*
>
> ※ 単一責任の原則(SRP)をコンポーネント向けに言い換えたもの

つまり、**同じ理由、同じタイミングで変更されるものはひとまとめにすること** 

コンポーネントが、変更理由や変更タイミングが同じ要素で構成されていれば、一つの変更に対して一つのコンポーネントの変更とデプロイ行うだけで良くなります。  
つまり、変更に対して閉じている(=閉鎖性)ということです。


- 単一責任の原則(SRP)  
クラスを変更する理由が複数あるべきではない
- 閉鎖性共通の原則 (CCP)  
コンポーネントを変更する理由が複数あるべきではない

::: note warn
**この原則を無視すると...**
同じ理由、同じタイミングで変更されるべきリソースが複数のコンポーネントに散らばっていると、一つの変更で複数のコンポーネントの修正が必要になります。(修正範囲の拡大)  
異なる理由、異なるタイミングで変更されるべきリソースが同一コンポーネントにまとまっていると、一つの変更が関係ない機能に影響を及ぼす可能性があります。(影響範囲の拡大)  
どちらもメンテナンス性が低下します。  
:::


## ◎全再利用の原則(CRP)
> *コンポーネントのユーザーに対して、実際には使わないものへの依存を強要してはいけない*
>
> ※ インターフェイス分離の原則(ISP)をコンポーネント向けに言い換えたもの

つまり、**不要なものに依存しないこと**


コンポーネントに依存する場合、コンポーネントに含まれるすべてのクラスに依存すべきで、依存するクラスもあれば、しないクラスもあるという状況は避けるべきということ。
コンポーネントが本当に必要な依存先にのみ依存することで、不要な依存先の変更に起因するリソースを避けることができます。

- インターフェイス分離の原則(ISP)  
使っていないメソッドを持つクラスに依存しないこと
- 全再利用の原則(CRP)  
使っていないクラスを持つコンポーネントに依存しないこと

::: note warn
**この原則を無視すると...**
コンポーネントが不要な依存先に依存することで、不要な依存先の変更の影響ででリリースを強制されるようになります。
:::


## ◎コンポーネントの凝集性のテンション図

これら3つの原則はすべて遵守すべきといったものではありません。  

**再利用・リリース等価の原則(REP)** と **全再利用の原則(CRP)** はコンポーネントを大きくする方向に働き、 **全再利用の原則(CRP)** はコンポーネントを小さくする方向に働くといった点で3つの原則にはトレードオフな部分があり、どの原則を重視するかはプロダクトの状況によってバランスを取りながら変えていく必要があります。  
これら3つの原則のバランスを上手く取るのがアーキテクトの腕の見せ所です。

### テンション図

テンション図は3つの原則がそれぞれどのように影響を及ぼし合うかを示したもので、辺にある記述は反対側の頂点にある原則を無視したときにかかる **コスト** を表しています。


- **再利用・リリース等価の原則 (REP)** と **全再利用の原則 (CRP)** にだけ力を入れていると
  - 些細な修正で多くのコンポーネントの修正が必要になったり、一つの修正が関係のない他の機能に影響を及ぼします
- **再利用・リリース等価の原則 (REP) ** と ** 閉鎖性共通の原則 (CCP)** にだけ力を入れていると
  - コンポーネントの依存先が増え、不要な依存先の変更に起因した不要なリリースが増加します
- **全再利用の原則 (CRP)** と **閉鎖性共通の原則 (CCP)** にだけ力を入れていると
  - 再利用の単位が複数のコンポーネントにまたがり再利用しづらくなります

![component_02.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/fedc028e-d170-059e-6958-f050b1520c75.png)
paiza 勉強記録【単語のカウント】【Java】

paizaでの勉強記録です。
今回は下記のレベルアップ問題集のCランクの「単語のカウント」を実施しました。
ざっくりとしたイメージとしてはMapを用いて文字列と出現回数をカウントしています。

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/word-count

```java
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class paiza {
    public static void main(String[] args) {
    	try (Scanner sc = new Scanner(System.in);){
    		
//    		文字列と出現回数の保存用のMap
//    		出現した文字列順で出力するように、Mapへの登録順で値を保持するLinkedHashMapを使用
    		Map<String, Integer> map = new LinkedHashMap<>();
//    		標準入力から取得した文字列が既出かの判断用変数
    		boolean containsjudge = false;
    		
//    		標準入力の値を取得できる間処理を実行
    		while (sc.hasNext()) {
    			String inputString = sc.next();
    			containsjudge = map.keySet().containsAll(List.of(inputString));
//    			取得した文字列がMapに登録されている場合、登録されている値を＋１する。
//    			既出でない場合、Mapに登録する
    			if (containsjudge) {
    				map.put(inputString, map.get(inputString)+1);
    			} else {
    				map.put(inputString, 1);
				}
    		}
//    		Mapのキー・バリューを標準出力で表示する
    		for (String key : map.keySet()) {
    			System.out.println(key + " " + map.get(key));
    		}
		}
    }
}
```

### 参考

https://qiita.com/Shoma0210/items/5820098122d39c400d6d

https://qiita.com/shimazuzuzu/items/28f58b267fab5900e0fa

https://qiita.com/Air_Hold/items/6535b96a06ec7308fda5

https://qiita.com/shitika/items/6750e8af53c955eceb1f
【Zed】devcontainerを使用する方法

## DevPodをインストールする

`devcontainer`を使用するために以下のページからDevPodをインストールします。

https://devpod.sh/docs/getting-started/install

## プロバイダーを追加する

以下のコマンドを使用して`docker`を追加します。

```terminal
devpod provider add docker
```

## Devcontainer CLIでコンテナを起動する

プロジェクトのディレクトリで以下のコマンドを実行してコンテナをビルドし、起動します。

```terminal
devcontainer build && devcontainer up
```

## 起動したコンテナからDevPodのワークスペースを作成する

起動しているコンテナのIDを確認し、以下のコマンドの`$CONTAINER_ID`を置き換え、実行します。

```terminal
devpod up my-workspace --source container:$CONTAINER_ID --ide zed
```

するとZedが起動してVSCodeと同様にコンテナ内で作業できるようになります。

## `.zed_server`がインストールできない場合

コンテナをrootユーザー以外で起動すると権限がなく、`.zed_server`がインストールできない旨のエラーが発生します。

ホームディレクトリではなく、ルートディレクトリに`.zed_server`がインストールされることが原因です。
ルートの`.zed_server`に適切な権限を与えればエラーは解消されます。
IPAのiLogScannerでWebサーバ等のアクセスログを確認する

# 初めに
IPAがフリーで公開しているウェブサイトの攻撃兆候検出ツール iLogScannerの紹介です。
ウェブサーバのアクセスログから攻撃と思われる痕跡を検出するためのツールです。
ApacheやIIS等のログ解析が可能です。
設定や利用が簡単なため、一度利用してみたいと思います。

↓HP
https://www.ipa.go.jp/security/vuln/ilogscanner/index.html

利用環境
・Windows 11
・JDK 11以上
・GUI版を利用。　※CUI版もあります。

# 設定方法
1.以下のサイトからダウンロードします。

https://www.ipa.go.jp/security/vuln/ilogscanner/operation.html#howtousegui

2.ダウンロードしたファイル「iLogScanner.zip」を解凍して任意の場所に保存。
　ここではC:\iLogScannerといます

# 起動方法
・bin\iLogScanner.bat を実行します。

※ 実行できない場合
ファイルを右クリックしてプロパティからセキュリティを「許可する」にチェック、適用をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/42c6ee04-6faf-9f99-9b57-6b52225bf503.png)

起動するとメイン画面が表示されます。

# 利用方法
1.解析するログを指定
2.結果ファイルを保存するフォルダを指定
3.解析開始をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/dd25c101-8587-8544-c3d7-6974090f0615.png)

★結果が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/c3bea1ad-b22d-1b52-30eb-fe4262c1b755.png)
攻撃があったと思われる場合、件数等のメッセージが表示されます。

詳細確認のため、作成されたファイルを開きましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/36e516d7-b964-5938-ebda-f8d13412bbf5.png)
※スクロールが長いので途中で切れています。

今回のサンプルではSQLインジェクションの形跡があったようです
同ファイルの下部には対象のログも表示されています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/4f0d57fe-f545-6e23-6c23-50d7e107f0c4.png)

ログを見ると「 user_id=aa&password=aa 」となっていますね。

※注意
検証のため、自端末で簡易ログインフォームを作り、SQLインジェクションしました。
そのため、アクセス元がローカルIPです。

もし、痕跡があった場合はアドバイスに沿った対策を行いましょう。


# 最後に
今回はIPAのツール、iLogScannerを試しました。
上手に利用するとWebサーバのセキュリティ対策に役立つでしょう。
Windows,Linuxで利用でき
CUI版もあるため、cronで定期的に実行したりも良さそうです。
損失関数と出力層の活性化関数の組み合わせ

機械学習において、問題に応じて適切な損失関数と出力層の活性化関数を選ぶことは非常に重要です。ここでは、回帰問題、二分類問題、多分類問題のそれぞれに適した損失関数と活性化関数をまとめました。

### 1. 回帰問題

回帰問題では、モデルが連続値を予測します。

| 問題 | 損失関数 | 出力層の活性化関数 |
| ---- | -------- | ---------------- |
| 回帰 | 均方誤差（MSE） | なし |

**説明**：
- 回帰問題の場合、損失関数として**均方誤差(MSE)** がよく使用されます。出力層には活性化関数を使わず、そのまま連続的な数値を出力します

### 2. 二分類問題

二分類問題では、出力が「はい」または「いいえ」の2つのクラスのどちらかに分類されます。

| 問題 | 損失関数 | 出力層の活性化関数 | 出力張量の長さ |
| ---- | -------- | ---------------- | ------------ |
| 二分類 | バイナリ交差エントロピー（BCELoss） | シグモイド（Sigmoid） | 1 |
| 二分類 | クロスエントロピー（CrossEntropyLoss） | なし | 2 |

**説明**：
- **BCELoss**では、出力層の活性化関数として**シグモイド**を使い、出力を0または1の確率値で表示します
- **CrossEntropyLoss**の場合、シグモイドは不要で、2クラスの出力（0または1）をそのまま出力します

### 3. 多分類問題

多分類問題では、複数のクラスに分類する問題で、出力はクラス数と同じ長さのベクトルになります。

| 問題 | 損失関数 | 出力層の活性化関数 |
| ---- | -------- | ---------------- |
| 多分類 | クロスエントロピー（CrossEntropyLoss） | なし |
| 多分類 | NLLLoss（負の対数尤度） | torch.log_softmax |

**説明**：
- **CrossEntropyLoss**は、各クラスのスコアをそのまま出力層から得るため、活性化関数は使用しません
- **NLLLoss**を使用する場合、出力層では**torch.log_softmax**を使って、確率的なスコアを出力します。この場合、ラベルは**独熱表現（one-hot encoding）**でなければなりません

これらの損失関数と活性化関数の組み合わせを理解することで、問題に最適なモデルを構築できます。
APIの認証・認可について学ぶ

## はじめに
先日、先輩がAPIの認証・認可について勉強会を開いてくれました。その復習も兼ねて、この記事では認証と認可の基本から、OAuthやAPIキーの仕組みまでを整理してみます。

## 認証と認可

### 認証
:::note info
認証は「**あなたは誰ですか？**」を確認する仕組み
:::
認証は、ユーザーやクライアントが本人であることを認証するプロセスです。これによって、APIやクライアントは「誰がアクセスしているのか」を確認できます。

例えば、以下のような認証があります。
- **ユーザー認証**：ユーザー名とパスワードを入力してログインする仕組み（一般的なログイン画面）
- **クライアント認証**：アプリケーションがAPIにアクセスする際に、クライアントIDとシークレットを使用して自分を証明する仕組み（OAuthでの認証）

認証の手法には以下の種類があります。
- **パスワード認証**：説明不要の一般的な認証方式
- **多要素認証**：パスワードに加えて、生体認証を使用
- **OAuth認証**：トークンベースの認証方式で、ユーザーのパスワードを共有せずに認証を行う
- **APIキー**：アプリケーションごとに発行されるキーを利用

### 認可
:::note info
認可は「**あなたは何をしていいですか？**」を確認する仕組み
:::
認可は、認証されたユーザーやクライアントが特定のリソースや機能にアクセスする権限があるかを判断するプロセスです。

これからOAuthやAPIキーについての仕組みを理解していきます。まずはOAuthから見ていきます。

## OAuth
OAuth（Open Authorization）とは、インターネット上で安全に認証や認可を行うためのプロトコルです。特に、他のサービスに自分のアカウントの情報を渡さずに、アプリケーションやサービス同士が連携できる仕組みを提供してくれます。

### OAuthの目的
- ユーザーが自分のパスワードや機密情報を第三者（アプリ）に直接共有せず、安全に特定のリソースやサービスへのアクセスを許可すること
- 認証と認可を分離し、第三者に許可する範囲を限定できる

### OAuthの仕組み
1. **クライアントがユーザーに対してアクセスをリクエスト**
2. **認可サーバーが認可コードを発行**  
   認可サーバーは、ユーザーが許可を確認した後、一時的な認可コードをクライアントに返す。
3. **クライアントがアクセストークンを要求**  
   クライアントは認可サーバーに対し、認可コードを使ってアクセストークンを要求する。
4. **アクセストークンが発行される**  
   認可サーバーはリクエストを確認後、アクセストークンをクライアントに発行する。
5. **クライアントがリソースサーバーにアクセス**  
   クライアントはアクセストークンを使って、リソースサーバーにリソースへのアクセスを要求。リソースサーバーはアクセストークンを確認し、許可された範囲内でデータを提供する。

### アクセストークンに含まれる情報
認可してもらったら、アクセストークンを使って認証を行うという流れになっていますが、アクセストークンにはどんな情報が含まれているのでしょうか？

アクセストークンに含まれている情報は以下の通りです：
- **発行者情報（issuer）**: 認可サーバーの情報
- **対象者情報（audience）**: このトークンが使用できるリソースサーバーの情報
- **ユーザー情報（subject）**: トークンが紐づいているリソースオーナー（ユーザー）
- **スコープ（scope）**: 許可された操作やリソースの範囲
- **有効期限（expiration）**: トークンの有効期限
- **トークンID（jti）**: トークンの一意な識別子

### スコープの具体例
例えば、Google APIを利用する場合、スコープを以下のように指定することでアクセス範囲を細かく制御できます：
- `https://www.googleapis.com/auth/drive.readonly`: Google Drive内のファイルを「読み取り専用」でアクセスする許可
- `https://www.googleapis.com/auth/calendar.events`: Googleカレンダーのイベントを管理する許可
- `https://www.googleapis.com/auth/userinfo.profile`: ユーザーの基本プロフィール情報へのアクセスを許可

アクセストークンにはスコープが含まれており、これによりクライアントがリソースサーバーにアクセスできる範囲を定義しています。

## APIキー
APIキーはアプリケーションやユーザーを識別するために使用されます。リクエストヘッダーやURLに含まれており、シンプルで使いやすい分、ネットワーク上で盗まれるリスクがあり、セキュリティはOAuthより劣ります。

### APIキーの構造
APIキーは通常、ランダムな英数字の文字列として生成されます。例えば以下のような形です：
```
123abc456def789ghi012jkl345mno678pqr
```

リクエストやクエリパラメータに含めて使用します。URLの一部としてAPIキーを送信する場合は以下のようになります：
```
https://api.example.com/v1/resource?api_key=123abc456def
```

APIキーの使用範囲を制限するために、IPアドレスやドメインで制限できます。これにより不正使用を防ぐことができます。

APIのダッシュボードやログを活用して、APIキーの使用状況を定期的に確認することも大事です。不審なトラフィックがあれば、APIキーを無効化して再発行することが推奨されます。また、使用期限や利用可能なAPIエンドポイントの制限を設定することで、セキュリティを向上させることができます。

## APIリクエストを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924509/9a251807-28a3-ab9d-481b-201447598883.png)

開発者ツールでリクエストヘッダーを確認したところ、**Authorizationヘッダー**にアクセストークンが含まれていることがわかります。このように、アクセストークンを用いて認証・認可を実現します。

## おわりに
APIの認証認可についての基礎を学びました。OAuthやAPIキーの仕組みはAPIを扱う際に必須の知識だと思うので、さらに理解を深め、実装できるようになりたいです。

最後までお読みいただきありがとうございました。

## 参考文献

https://qiita.com/OtsukaTomoaki/items/676daf96ea3217af8d20

https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be
OMCB031C(1040)

https://onlinemathcontest.com/contests/omcb031/tasks/11373

$f(x)$も$g(x)$も$x^3$の係数が$1$であるので、
　$f(x)=x^3+F_2x^2+F_1x+F_0$ $…①$
　$g(x)=x^3+G_2x^2+G_1x+G_0$ $…②$
と置けます。

$①-②$を、
　$h(x)=f(x)-g(x)$ $…③$
　$=ax^2+bx+c$ $…③'$
と置きます。

問題文の条件の上$3$つの$g(x)$を右辺に移項して、
　$h(-6)=-36$ $…④$
　$h(-2)=-4$ $…⑤$
　$h(2)=4$ $…⑥$
です。

$④～⑥$を$③'$を使って変形すると、
　$(-6)^2×a+(-6)×b+c=-36$
　$(-2)^2×a+(-2)×b+c=-4$
　$(2)^2×a+(2)×b+c=4$
と表せます。

これを解いて、$a=-\frac{3}{4},b=2,c=3$となります。

$h(6)$は、
　$h(6)=-\frac{3}{4}×6^2+2×6+3$
　$=-27+12+3$
　$=-12$
です。

問題文より、
　$f(6)=96$
です。

$③$より$g(x)=f(x)-h(x)$なので、
　$g(6)=f(6)-h(6)$
　$=96-(-12)$
　$=108$
となります。

問題ではすべての$g(6)$の和を問われていますが、考えられる値は$1$つしかないので、
解も$108$となります。
【RAG】2段階でChatGptを利用しよう

## 環境
OCI GenerativeAI
Python
ChatGpt4o

## こんな人にいい話
・RAGで精度が出ない。
・もっと細かい説明をRAGにさせたい。
・LLMに与える文章で極力余計な情報を紛れさせたくない。

## LLMを利用するうえでの前提条件
そもそものお約束として以下の３点があげられる。
１．LLMは最初と最後に与えられた情報を覚えて、中盤ほど忘れっぽい。
２．余計な情報を与えるとハルシネーションが起きやすくなる。
３．API連携時には、入力時と出力時の両方を合わせたトークン数で計算されている為、入力しすぎると出力する情報が少なくなる。

## RAGでやるべきこと
この前提条件を抑えると、やるべき対処は、
**与える情報を最小限に抑える。**
という有識者に貼り倒されそうな結論となります。

出来たらやっとるわ！と突っ込まれそうです。

基本的に、ベクトル検索は数字の距離感によって与える情報を決定している為、いくつ以下なら大丈夫みたいな数値がありません。（限りなく近いものは決められるかもしれませんが）

その為、今回私が取った対応は２段階に分けてChat機能を利用するというものでした。

# 1段階目のChat
1段階目のChatでまずやるべきは、**ベクトル検索で抽出した文章の要約・トピック抽出**を行わせることです。
重要なポイントやトピックを抽出することで不要な情報を弾いて、選別することが出来ます。
これによって、与える文章が少なくなり、必要な文章のみを2段階目のChatで与えることが可能です。

 # 要約・トピック抽出に関する指示
        あなたは、与えられた情報から主要な要点やトピックを抽出するアシスタントです。次の指示に従って、要約・トピック抽出を行ってください。
        ## 前提条件
        - この情報は、RAG (Retrieval-Augmented Generation) プロセスの第1段階として、質問に対する回答を生成するための前段の情報整理に用いられます。
        - 抽出した要約やトピックは、次段階で詳細な回答生成に活用されるため、必要な範囲で具体的な内容を含むようにしてください。
        - 日本語で返答は記載してください。

        ## 抽出の条件
        - 与えられたテキストから以下の項目に基づいて情報を抽出してください：
        1. 質問に直接関係する主要なポイント
        2. 質問に対する答えを導くための重要なキーワードやフレーズ
        3. 関連するトピックやセクション（例：「法律」「プロセス」「手順」など）

        - 抽出結果は次の形式で示してください：
        - **要点の要約**：情報の主要なポイントを簡潔にまとめたもの。
        - **キーワード**：質問に対する回答を導くための重要なキーワードのリスト。
        - **関連トピック**：特定の回答に関係するトピックやセクション名。

        ## 出力例
        出力する内容は次の形式で記述してください：

        1. **要点の要約**
            - （要約内容）

        2. **キーワード**
            - （キーワードリスト）

        3. **関連トピック**
            - （関連トピックのリスト）

        ## 注意点
            - 抽出する内容は簡潔にまとめつつ、重要な要点を網羅するようにしてください。
            - 情報の見落としを防ぐため、関連性が不明確な情報については「関連トピック」に含めてください。
            - 抽出内容が正確かつ要点を損なわないようにし、冗長な情報は省略してください。
            - 分からない部分や不確実な情報は、「不明」と明記して抽出結果に反映してください。
        """

## 2段階目のChat
このChatでは、1段階目のChatの情報を与えつつ、自然言語での回答生成をさせます。
その際は、極力要約をさせないように指示を行い、詳細に回答を生成するように伝えて、最大限与えた情報を活用するように前提条件を指定します。
これにより、与える情報は最低限でありながらも求めた情報に近いものを作ることが出来ます。
この2段階目でも、要約文章を活用した抽出方法で質問した内容に近い情報が抽出されるように情報を与えていますが、その話はまたの機会に致します。

## 終わりに
通常1回で自然言語を生成するだけで行うChat機能を2段階に分けようというお話でした。
サービスとして運用する場合は、コストを考えて1回目のChatはGpt3を利用することをお勧めします。
Gpt4oの10分の1ほどの金額の為、安く済ませることが出来ます。
API連携の場合、情報を与えれば与えるほど正確な情報を返してくれるというのが、幻想であることを検証する中で気づきました。

与える情報と受け取る情報のバランスを考えながら、システムを構築してみてください。
それでは、また次回の記事で。
UnitV2にSSHで入ってVSCodeで開発したい

UnitV2というカメラを知っていますか？
m5stackが出しているLinuxがのっているAIカメラです。
Jupyter Notebookでの開発環境が準備されているのですが、VSCodeで書きたい人のためにVSCodeからSSHする方法を紹介します。

# 環境
UnitV2 M12カメラ
Windows11
Visual Studio Code

# UnitV2側の設定


まず、こちらの公式ドキュメントにのっとってドライバをインストールしてください。

https://docs.m5stack.com/en/unit/unitv2_m12


これでもうPCからSSHできるのですが、このままだとsudoが使えないので以下の作業を行います。

Jupyter Notebookからだとroot権限で入れるそうなので、ブラウザでUnitV2のJupyter Notebookを開きます。
UnitV2をつないだ状態で、ブラウザでunitv2.pyか10.254.239.1にアクセスすると以下の画面が開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/dc64c9b3-36e8-83f5-d839-27a958810cc3.png)

この右上の歯車マークをクリックし、``switch to notebook mode``をクリックするとJupyter Notebookの画面に切り替わります。OKを押して数秒待った後にリロードしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/9884e79c-116b-ef7f-e07e-181d4cb7cf71.png)

するとJupyter Notebookが開くので、右上の``New``から``Terminal``を開いてください。
そして以下の3つのコマンドを実行してください。

```bash
chown root:root /usr/bin/sudo && chmod 4755 /usr/bin/sudo
chown root:root /usr/libexec/sudo/sudoers.so
chown root:root /etc/sudoers
```
これでsudoが使えるようになりました。


# VSCodeで開発しよう

VSCodeからSSHをするための拡張機能としてRemote-SSHというものがあるのですが、これはうまくできませんでした（Raspberry pi zeroが使えないらしいのでそれと同じようなものかも？）

そのため、普通にターミナルを使ってscpをしましょう。
VSCode上のターミナルを使うとすべてがVSCodeで完結するので楽です。


どこかに作業用のフォルダを作ってVSCodeで開いてください。
そしてVSCode上でターミナルを開いてください。``Ctrl``+``@``でターミナルを表示できます。

## 1
最初に以下のコマンドを打ってください。
```console
ssh m5stack@10.254.239.1
```
パスワードが求められたら``12345678``と入力してEnterを押します。

これでUnitV2にSSHで入れます。

## 2
次に、scpコマンドでファイルを転送できるようにするために以下のコマンドを打ちます。
```console
sudo chmod o+rw /dev/null
```
ここでもパスワードが求められますが、先ほどと同じ12345678で構いません。
これでscpの準備が整ったので、exitでSSHから抜けてください。

## 3
以下のコマンドを打つと、UnitV2の/home/notebookにあるものをVSCodeで開いているフォルダに移せます。
```console
scp -r m5stack@10.254.239.1:home/notebook ./
```
-rはフォルダごと転送するという意味です。scpの書き方についてはネットにいろいろ載っているので調べてみてください。

/home/notebookにJupyter Notebookのファイルが、/home/m5stackにUnitV2にもともと入っているアプリケーションなどが入っているようです。SSHでログインした直後は/home/m5stackにいます。

これでUnitV2とローカルで自由にファイルを転送できる準備が整いました。
SSHとscpでいじくりまわしましょう。


電源が落ちると権限がリセットされてしまうので、UnitV2を再起動するたびに１と２は実行してください。

# 参考
https://qiita.com/niikura/items/d4c683347aa49441686b

https://zenn.dev/blkcatman/articles/89a2d54a77f020

https://rt-net.jp/humanoid/archives/3933
ViteでReactの環境を立てる方法

まず、Viteをインストール
npm create vite@latest

いくつかのライブラリを選ぶ選択画面に移行するので、
Reactを選択する。

その後、package.jsonに書いているライブラリを
node_modulesに入れるため、
npm i(install)を実行する。

その後、サーバ起動は、
npm run dev
ChatGPTで学ぶデザインパターン（シングルトンパターン）

ChatGPTでデザインパターンを学ぼうと思い立ち、記録していきます。
1つ目のデザインパターンはシングルトンパターンです。

### シングルトンパターンとは
ChatGPT
> 「クラスのインスタンスを1つだけ作る」というルールを作る方法です。
例えば、学校で校長先生が1人だけなのと同じように、何度呼んでも同じ校長先生（インスタンス）が返ってくるようにします。
> 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393013/eec835c9-9e62-98de-1bb9-535f71adecb9.png)

→　システム全体で唯一のものを扱いたいときに使うパターン。


### ユースケース
ChatGPT
> こんな時に使います
> 
> - **設定管理**：アプリ全体で共有する設定を1か所で管理したいとき
> - **ロギング**：アプリ全体で同じログファイルに書き込みたいとき
> - **データベース接続**：複数の接続を防ぎ、効率よく使いたいとき

→　設定はシステム全体で１つ。同期処理的なことにも使える。

### サンプルプコード
※サンプルコードは、ChatGPTに示してもらったものを自分なりに解釈して記載しています。

#### シングルトンクラス

```java
package singleton;

public class SingletonSample {
  // 唯一のインスタンスを保持
  private static SingletonSample instance;
  private String name;

  // コンストラクタをプライベートで宣言
  // 外部からのインスタンス化を禁止
  private SingletonSample() {}

  // 唯一のインスタンスを取得するためのメソッド
  public static synchronized SingletonSample getInstance() {
    if (instance == null) {
      instance = new SingletonSample();
    }
    return instance;
  }

  // setter
  public void setName(String newName) {
    instance.name =  newName;
  }    
  // getter
  public String getName() {
    return this.name;
  }    
}

```
**ポイント**
- staticなクラス変数としてインスタンスを保持
- コンストラクタをprivateで宣言することで、外部からインスタンス化を禁止
- getInstance()メソッドで唯一のインスタンスを返す
- getInstance()はマルチスレッド環境でも安全にインスタンス取得できるよう、synchronizedメソッドとしている

#### 呼び出し側
```java
import singleton.SingletonSample;

public class App {
    public static void main(String[] args) throws Exception {
        // 1.シングルトンパターン
        callSingletonSample();
    }    
    
    /**
     * 1.シングルトンパターン
     * 唯一のインスタンスを生成する
     */
    private static void callSingletonSample(){
      System.out.println("---1つ目のインスタンス取得処理---");
      SingletonSample singletonA = SingletonSample.getInstance(); 
      singletonA.setName("校長 太郎");
      System.out.println("1つ目のインスタンス："+singletonA.getName());

      System.out.println("---2つ目のインスタンス取得処理---");
      SingletonSample singletonB = SingletonSample.getInstance();
      System.out.println("2つ目のインスタンス："+singletonB.getName());

      System.out.println("---2つ目のインスタンスで名前変更---");
      singletonB.setName("校長 花子");
      System.out.println("1つ目のインスタンス："+singletonA.getName());
      System.out.println("2つ目のインスタンス："+singletonB.getName());
    }
}
```

#### 実行結果
```plaintext
---1つ目のインスタンス取得処理---
1つ目のインスタンス：校長 太郎
---2つ目のインスタンス取得処理---
2つ目のインスタンス：校長 太郎
---2つ目のインスタンスで名前変更---
1つ目のインスタンス：校長 花子
2つ目のインスタンス：校長 花子
```

**ポイント**
- singletonA、singletonBは同じオブジェクトを指し示していることがわかる

### 気になったこと
デザインパターンの初めの一歩で、必ず出てくるシングルトンパターン。
staticで宣言すればクラスに唯一の変数を用意することもできます。
シングルトンパターンの必要性をもう少し聞いてみました。
> static変数を使えば、同じクラス内でその変数が共有されるため、状態を1つに保つことが可能です。シングルトンパターンが必要なケースは
> 1. 動的な初期化や管理が必要：オブジェクトの初期化や制御をクラス自身が行える
> 2. 遅延初期化のサポート：インスタンスが必要になるまで生成を遅らせることができ、リソースを節約できる
> 3. 制御と拡張性：インスタンスの生成や管理に特定のロジック（例：スレッドセーフ性）を追加できる
> 4. 状態の隠蔽（カプセル化）：インスタンスへのアクセスをgetInstance経由に限定することで、内部の状態を適切にカプセル化できる
> 5. インターフェースやポリモーフィズムとの相性：シングルトンはクラスのインスタンスを返すので、インターフェースを使って依存性注入（DI）と組み合わせることができる

→　単純な状態管理だけでなく、同期をとって、アクセスを制限するような処理を実装したり、複雑な初期化処理を実装したいときなどに利用できる。公開するメソッドを限定することで、利用する側がメソッドの中身がどうなっているかを気にせず利用することができる。

### 関連

https://qiita.com/oqnoqn/items/2034e66a3a5100955503
OMCB005C(606)

https://onlinemathcontest.com/contests/omcb005/tasks/5463

$79$は素数なので、フェルマーの小定理
　$a^p≡a$ $(mod$ $p)$
を使うと、
　$1^{79}+3^{79}+…(2n+1)^{79}$
　$≡1+3+…+(2n+1)$ $…①$
と書くことができます。

$①$の右辺は、
　$\Sigma_{k=0}^n(2k+1)=2\Sigma_{k=0}^nk+(n+1)$
　$=n(n+1)+(n+1)$
　$=(n+1)^2$
です。
$79$は素数なので、$1$と$79$でしか割り切れないので、$n+1=79$のときが$79$で割り切れる最小になります。
したがって、解は$78$です。

ここまでは公式解説(動画解説含む)と同じなのですが、
$1$つ気になるのが、$n=78$なので、$2n+1=157>79$であることです。

$n=39$($2n+1=79$)のとき、$79^{79}≡0$となりますが、$0≡79$なので、$79^{79}≡79$としても良いことがわかります。

では、$n≧40$の場合はどうでしょうか？
$n=40$のとき、$2n+1=81$となり、二項定理を使って展開すると、
　$81^{79}=(2+79)^{79}$
　$={}_7{}_9C{}_0×2^{79}×79^0+{}_7{}_9C{}_1×2^{78}×79^1+…+{}_7{}_9C{}_7{}_9×2^0×79^{79}$
　$≡2^{79}$
　$≡2$
となり、$2≡81$なので、この場合も$81^{79}≡81$として問題はありません。
同じ調子で$41$以上の場合も$(2k+1)^{79}≡2k+1$として良さそうです。
【競技プログラミング】AtCoder Beginner Contest 248_D問題

# 問題
https://atcoder.jp/contests/abc248/tasks/abc248_d

## 要約
長さNの数列A = (A1, ..., AN)が与えられる。

その後、Q個のクエリに答える必要があります。各クエリは以下の形式で与えられる
- 整数L, R, Xが与えられる。
- 数列AのL番目からR番目までの要素（AL, ..., AR）の中で、値がXに等しい要素の個数を求める。

  - N: 数列Aの長さ
  - A: 与えられる数列 (A1, ..., AN)
  - Q: クエリの数
  - L: 各クエリでの範囲の開始位置
  - R: 各クエリでの範囲の終了位置
  - X: 各クエリで探す値


# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)

# アプローチ

累積和と二分探索を組み合わせてクエリを処理する

# 解法手順

1. 入力を受け取る：
   - 数列の長さNを読み込む
   - 数列Aの要素を読み込む

2. 累積和の準備：
   - 各値の出現位置を記録する配列acmを作成する
   - 数列Aを走査し、各要素の出現位置をacmに記録する

3. クエリ処理：
   - クエリの数Qを読み込む
   - 各クエリに対して以下の処理を行う：
     a. L, R, Xを読み込む
     b. Xの出現位置リストlstを取得する
     c. 二分探索を使用して、L以上の最小のインデックスlを求める
     d. 二分探索を使用して、R以下の最大のインデックスrを求める
     e. r - lを計算し、結果を出力する

4. 全てのクエリに対して3の処理を繰り返す



# ACコード
```python:ac.py
from bisect import bisect_left, bisect  # 二分探索のためのモジュールをインポート

def io_func():
    # 入力を受け取る関数
    N = int(input())  # 数列の長さを読み込む
    A = list(map(int, input().split()))  # 数列Aの要素を読み込む
    Q = int(input())  # クエリの数を読み込む
    queries = [list(map(int, input().split())) for _ in range(Q)]  # クエリを読み込む
    return N, A, queries

def solve(N, A, queries):
    # メインの処理を行う関数
    acm = [[] for _ in range(N+1)]  # 各値の出現位置を記録する配列を初期化
    
    # 数列Aを走査し、各要素の出現位置をacmに記録
    for i, a in enumerate(A, 1):
        acm[a].append(i)
    
    # 各クエリに対して処理を行う
    for L, R, X in queries:
        lst = acm[X]  # Xの出現位置リストを取得
        l = bisect_left(lst, L)  # L以上の最小のインデックスを二分探索で求める
        r = bisect(lst, R)  # R以下の最大のインデックスを二分探索で求める
        print(r - l)  # 結果を出力

if __name__=="__main__":
    # メイン処理
    N, A, queries = io_func()  # 入力を受け取る
    solve(N, A, queries)  # 解を求める

###
# N: 数列の長さ
# A: 入力された数列
# queries: クエリのリスト
# acm: 各値の出現位置を記録する配列
# L, R, X: 各クエリの左端、右端、探索する値
# lst: 特定の値Xの出現位置リスト
# l, r: 二分探索で求めた範囲内のインデックス

# 1. 入力処理（io_func関数）:
#    - 数列の長さ、数列の要素、クエリの数とその内容を読み込む
# 2. メイン処理（solve関数）:
#    a. 累積和の準備:
#       - 各値の出現位置を記録する配列acmを作成
#    b. クエリ処理:
#       - 各クエリに対して、指定された値Xの出現回数を二分探索で効率的に計算
#       - 結果を出力
# 3. メイン処理の呼び出し:
#    - io_func関数で入力を受け取り、solve関数で解を求める
```

# トレース

## 入力例
```
N = 11
A = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
queries = [(3,7,1)]
```

```python:trace.py
    # メインの処理を行う関数
    acm = [[] for _ in range(N+1)]  # 各値の出現位置を記録する配列を初期化
# [[], [], [], [], [], [], [], [], [], [], [], []]

    # 数列Aを走査し、各要素の出現位置をacmに記録
    for i, a in enumerate(A, 1):
        acm[a].append(i)
# [[], [2, 4], [7], [1, 10], [3], [5, 9, 11], [8], [], [], [6], [], []]

    # 各クエリに対して処理を行う
    for L, R, X in queries:
# L=3, R=7, X=1    
        lst = acm[X]  # Xの出現位置リストを取得
# [2, 4]
        l = bisect_left(lst, L)  # L以上の最小のインデックスを二分探索で求める
# l = bisect_left([2, 4], 3) = 1
        r = bisect(lst, R)  # R以下の最大のインデックスを二分探索で求める
# r = bisect_left([2, 4], 7) = 2
        print(r - l)  # 結果を出力
# 1
```
ROS2 mapvizでGNSSのトピックを可視化(2024年12月版)

tl;dr

**デフォルトのstamen mapは使えなくなってるぽいからOSMや国土地理院を指定しよう！！！**

ROSでサクッとGNSSの座標を見たいということがありますよね？
mapvizが使いやすいですが，2024年末の現在では，少し弄らないといけないようです．

## まずは実行

こちらを参考にしました↓

https://qiita.com/porizou1/items/211c10b5281b2073f4b9

## 起動したら色々設定

Fixed Frame: よーわからん
Target: よーわからん
この2つはテケトーにしても動くかも．

で，左下のAddから以下を追加します．

### tile map

tile_map: WMTSで配信されているタイルマップを読めます．

で，こいつはデフォルトでStamenもしくはBing Mapsが設定可能なのですが，APIキーなしで手軽に使える(はずの)Stamenマップは提供が終了してしまった(?)らしく，2024年12月末現在，他の地図ソースが必要です．

日本国内であれば，国土地理院のお世話になるのがイージーです．
以下のサイトで，タイル一覧が公開されています．

https://maps.gsi.go.jp/development/ichiran.html

写真地図が多様なズームレベルに対応しているため，これを使うとよいです．
https://maps.gsi.go.jp/development/ichiran.html#seamlessphoto

もしくはベースマップ．
https://maps.gsi.go.jp/development/ichiran.html#std

Sourceの"Custom WMTS Source..."を選択肢，Base URLに↑のURLの`z`を`level`に置き換えたものを設定します．
例えば，写真の場合は`https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{level}/{x}/{y}.jpg`になります．

Max Zoomには18を指定して，適当な名前でSaveしましょう．

OpenStreetMapも利用可能です．

`https://tile.openstreetmap.org/{level}/{x}/{y}.png`
を指定してみましょう．

Max Zoomは22くらいまでいけるらしい(?)ですが，手元で試した限りではあんまりズームするとmapvizが落ちます．

### navsatfix

Addから，navsatfixを追加してトピックを選んでおきましょう．

(たぶんgpsfixとかodometryとかでも動くと思いますが，試してません)

------------

おまけ

rvizが使いたい場合は

https://github.com/nobleo/rviz_satellite

もよさそうです．(試してないです)