OmniAICreator/Qiita-1.07M huggingface dataset:
OCI Cloud Free Tier をもぎ取れ その8

# 概要
OCI Cloud Free Tierを取得してみた。
ubuntuにapache、php、mysqlをインストールした。
ubuntuに wordpressをインストールする。

# 手順
- wordpressをインストール。
```
$ wget https://ja.wordpress.org/wordpress-6.7.1-ja.tar.gz
--2025-01-23 02:51:00--  https://ja.wordpress.org/wordpress-6.7.1-ja.tar.gz
Resolving ja.wordpress.org (ja.wordpress.org)... 198.143.164.252
Connecting to ja.wordpress.org (ja.wordpress.org)|198.143.164.252|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 34001888 (32M) [application/octet-stream]
Saving to: ‘wordpress-6.7.1-ja.tar.gz’

wordpress-6.7.1-ja.tar.gz     100%[=================================================>]  32.43M  5.72MB/s    in 5.1s

2025-01-23 02:51:05 (6.30 MB/s) - ‘wordpress-6.7.1-ja.tar.gz’ saved [34001888/34001888]


$ ls
wordpress-6.7.1-ja.tar.gz

$ tar xvfz wordpress-6.7.1-ja.tar.gz

$ ls
wordpress  wordpress-6.7.1-ja.tar.gz

$ pwd
/home/ubuntu

$ ls /home/ubuntu
wordpress  wordpress-6.7.1-ja.tar.gz

$ ls /home/ubuntu/wordpress
index.php    wp-activate.php     wp-comments-post.php  wp-cron.php        wp-load.php   wp-settings.php   xmlrpc.php
license.txt  wp-admin            wp-config-sample.php  wp-includes        wp-login.php  wp-signup.php
readme.html  wp-blog-header.php  wp-content            wp-links-opml.php  wp-mail.php   wp-trackback.php

$ cp -R /home/ubuntu/wordpress/* /var/www/html

$ ls /home/ubuntu/wordpress
index.php    wp-activate.php     wp-comments-post.php  wp-cron.php        wp-load.php   wp-settings.php   xmlrpc.php
license.txt  wp-admin            wp-config-sample.php  wp-includes        wp-login.php  wp-signup.php
readme.html  wp-blog-header.php  wp-content            wp-links-opml.php  wp-mail.php   wp-trackback.php

$ ls /var/www/html
index.html   readme.html         wp-comments-post.php  wp-includes        wp-mail.php       xmlrpc.php
index.php    wp-activate.php     wp-config-sample.php  wp-links-opml.php  wp-settings.php
info.php     wp-admin            wp-content            wp-load.php        wp-signup.php
license.txt  wp-blog-header.php  wp-cron.php           wp-login.php       wp-trackback.php


```
- wp-config.phpを作る。

```
$cd /var/www/html
$cp wp-config-sample.php wp-config.php
$nano wp-config.php

```
下記を設定する。

define('DB_NAME', 'wpdb');
define('DB_USER', '%wordpressuser%');
define('DB_PASSWORD', '%your_password%');


- 初期設定する。
ブラウザでwordpressを開く。



![wp2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ef38b3e1-8fb3-45a4-82d9-a4f8da14bd67.png)

- ダッシュボード

![wp3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b44b409b-82e4-005e-018a-e9aa9ab1e365.png)


以上。
SC-900 合格まで (2025.01)

[AZ-900 と MS-900 合格まで (2023.01) - Qiita](https://qiita.com/e99h2121/items/4ee69f047e555990065d)
[AZ-104 合格まで (2023.06) #AZ-104 - Qiita](https://qiita.com/e99h2121/items/de97a5e78b083739b5a1)
[AI-900 合格まで (2023.11) #AI-900 - Qiita](https://qiita.com/e99h2121/items/f32fcf4648bdf33a5ebd)
[AZ-305 合格まで (2023.12) #AZ-305 - Qiita](https://qiita.com/e99h2121/items/18ed097e6ecb66aafb3f)
[DP-900 合格まで (2024.02) #DP-900 - Qiita](https://qiita.com/e99h2121/items/51bf98981bffa218a712)
[AZ-204 合格まで (2024.05) #AZ-204 - Qiita](https://qiita.com/e99h2121/items/efbc9164bf5276880d9d)
[AZ-400 合格まで (2024.09) #AZ-400 - Qiita](https://qiita.com/e99h2121/items/00801184d7309b36b933)
[AZ-700 合格まで (2024.12) #AZ-700 - Qiita](https://qiita.com/e99h2121/items/ea446701bfe5f9c5c309)


2025.01.23 SC-900 を受けて合格したメモです。

## 感想

- 830 点位取れたので良かった良かった。
- 正月ぼけ気味の頭をリセットできた。
- 内容は、MS に関わるセキュリティ用語的なところをひとしきり。
- 受かると自信がつく 900 系の資格試験...



## MS Learn

[Microsoft Certified: Security, Compliance, and Identity Fundamentals - Certifications | Microsoft Learn](https://learn.microsoft.com/ja-jp/credentials/certifications/security-compliance-and-identity-fundamentals/?practice-assessment-type=certification)

[Microsoft のセキュリティ、コンプライアンス、ID の基礎: セキュリティ、コンプライアンス、ID の概念について説明する - Training | Microsoft Learn](https://learn.microsoft.com/ja-jp/training/paths/describe-concepts-of-security-compliance-identity/)
[Microsoft のセキュリティ、コンプライアンス、および ID の基礎: Microsoft Entra の機能について説明する - Training | Microsoft Learn](https://learn.microsoft.com/ja-jp/training/paths/describe-capabilities-of-microsoft-identity-access/)
[Microsoft のセキュリティ、コンプライアンス、および ID の基礎: Microsoft セキュリティソリューションの機能について説明する - Training | Microsoft Learn](https://learn.microsoft.com/ja-jp/training/paths/describe-capabilities-of-microsoft-security-solutions/)
[Microsoft Security, Compliance, and Identity Fundamentals:Microsoft Priva および Microsoft Purview の機能について説明する - Training | Microsoft Learn](https://learn.microsoft.com/ja-jp/training/paths/describe-capabilities-of-microsoft-compliance-solutions/)

ともかく以上を読む。自分で自分に問題を作って出しながら読む。

## 参考

[SC-900: Microsoft セキュリティ、コンプライアンス、ID の基礎 模擬問題集 | Udemy](https://www.udemy.com/course/sc-900-microsoft-id/?couponCode=KEEPLEARNING)

結局役立ったのは Udemy。お正月の特売で選んでみて、そちらを利用。

[SC-900を説明したい #初心者 - Qiita](https://qiita.com/takaki-imura/items/9418df69ecd523843585)
[SC-900合格までの道のり｜Kernel](https://note.com/kernel_91/n/n13e50d34c8af)
[SC-900合格記(2024/11/27投稿) #Azure - Qiita](https://qiita.com/handy-dd18/items/00d4a3ca9bac0c6cf977)




## 次ステップ

AZ-500 をちゃんと勉強すると良いかなあ、と思っている。次はいつになるかな...

以上です～
Node.js 初心者向け備忘録: 初期設定と基本コマンドまとめ

## はじめに
Node.jsを初めて触るので、自分用に初期設定や基本的な使い方を簡単にまとめました。、


## 1. プロジェクトの初期化: `npm init`
まず`npm init`でプロジェクトを初期化して、package.jsonを生成します。

プロジェクト名、バージョン、エントリポイントなどを対話形式で設定できます。
### コマンド
```
 npm init
 ```

### オプション
```
npm init -y
```
対話形式をスキップして、デフォルトの package.json を作成します。

- 参考リンク

https://docs.npmjs.com/cli/v11/commands/npm-init

 https://zenn.dev/hinoshin/articles/aadfdd7ba958a9
 
https://qiita.com/sugurutakahashi12345/items/1049a33b86225f6345fe

## 2.  Expressのインストール:  `npm i express`
今回はNode.jsのExpressというフレームワークを使う

### コマンド
```
$ npm install express
```
- 参考リンク

https://expressjs.com/ja/

## 3.自動再起動ツール: `npm i nodemon`
`nodemon` はコード変更を監視して、自動的にサーバーを再起動してくれるツールです

## コマンド
開発用のツールなので`--save-dev`をつけてインストール


```
npm i nodemon --save-dev
```

- 参考リンク


https://www.npmjs.com/package/nodemon

## 4 `package.json`のスクリプト設定
`nodemon`を使いやすくするために、`package.json`にスクリプトを追加します。

### 設定例
```
  "scripts": {
  　"start": "node index.js",
    "dev": "nodemon index.js"
  }
```

###  実行コマンド

- 開発用（nodemon使用）：
```
npm run dev
```

- 本番用（nodemonなし）：
```sql
npm start
```
## 簡単に動かしてみる
以下の手順で、nodemonの動作確認をします

1. `index.js`を作成し、以下の内容を記述
```javascript:qiita.rb
console.log('Hello!')
```

2.ターミナルで次のコマンドを実行：
```
npm run dev
```
3.ターミナルに以下が表示されます：
```
Hello!
```

4.内容を変更して再確認
```javascript:qiita.rb
console.log('Hello World');
```
保存すると、自動的にターミナルに以下が表示されます：
```
Hello World
```
Google Map上に賃貸情報一覧をパッと表示したい

# はじめに
こんにちは。もうすぐ春、新生活ということで、新しい環境に身を置く方々は一人暮らしの季節がやってきますね。一人暮らしのために様々な物件情報を仕入れる中で気に入った物件はお気に入りに登録といった作業をしていると思います。私は来年から一人暮らしを始める予定ですが、いろいろな物件をお気に入り登録しても全ての物件をまとめてどこにあるか把握することができません。ということで、今回は`Google Colaboratory`と`Python`を用いて気に入った賃貸情報をまとめて`Google Map`上に表示します。
# 準備
`Excel`のファイルを`Google Colaboratory`にアップロードします。
ファイルは自由に設定して構いませんが今回は以下のように作ります。賃貸料は例として適当に書いてます。
| 場所名 | 位置情報 | 賃貸料 | URL |
|:-----:|:-----:|:-----:|:-----:|
|浅草駅|35.7119534,139.7971771|10.0|https://www.google.co.jp/maps/place/%E6%B5%85%E8%8D%89%E9%A7%85/@35.7119534,139.7971771,17z/|
|品川駅|35.6275112,139.7250494|15.0|https://www.google.co.jp/maps/place/%E5%93%81%E5%B7%9D%E9%A7%85/@35.6275112,139.7250494,14z/|

## 1\. 場所名
マンション名やアパート名を入れます。
## 2\.位置情報
緯度経度を「,」区切りで入れます。
この時、緯度経度情報を調べるため、少し手間のかかる作業をします。
### 1\.住所を調べる
物件情報サイト上に住所が載っているのでその住所をコピーします。
### 2\.Google Map上で検索
コピーした住所をGoogle Mapで検索します。検索することでGoogle Mapに住所の情報が出ます。この時重要なのは**URL**の方です。
### 3\.URLから緯度経度情報をコピーする
以下は浅草駅のURLとなっています。
（URLが長いので細かい部分のURLを削って浅草近辺のみ表示されるようになってます）

<a href="url">https://www.google.co.jp/maps/place/%E6%B5%85%E8%8D%89%E9%A7%85/@35.7119534,139.7971771,17z/</a>

このURLの **@** 以降に緯度経度が「,」区切りで記されています。
<dl>
  <dt>緯度</dt>
  <dd>35.7119534</dd>
  <dt>経度</dt>
  <dd>139.7971771</dd>
</dl>
今回は上記のようになります。この緯度経度情報をコピーして貼りましょう。

## 3\.賃貸料
物件情報サイト上に載っている賃貸料金を入れましょう。
## 4\.URL
調べている物件情報サイトのURLを入れましょう。サイトURLを入れておくことでマップからすぐにサイトにアクセスすることができるようになります。
（例ではGoogle MapのURLを貼っています）

# Colabで実行する
準備が整えばあとは実行するだけです。
まず必要なライブラリをインストールしましょう。
```python
# 必要なライブラリをインストール
!pip install pandas openpyxl folium
```
次にライブラリをインポートします。
```python
# ライブラリのインポート
import pandas as pd
import folium
from google.colab import files
```
保存したExcelファイルをColab上にアップロードします。実行後にファイルをアップロードするように言われるので準備で用意したExcelファイルをアップロードしましょう。
```python
# スプレッドシートファイルをアップロード
uploaded = files.upload()

# アップロードされたファイル名を取得
filename = list(uploaded.keys())[0]
```
1行目のラベルを読み込みます。
```python
data = pd.read_excel(filename)
```
マップを作成します。今回は東京を初期の位置に設定します。
```python
m = folium.Map(location=[35.6895, 139.6917], zoom_start=10)  # 初期位置を東京に設定
```
マップ上にピンを追加し、情報を紐づけます。
```python
# ピンを地図に追加
for index, row in data.iterrows():
    name = row['場所名']  # 1列目: 場所の名前
    location = row['位置情報']  # 2列目: 位置情報 (緯度,経度形式)
    amount = row['賃貸料']  # 3列目: 金額
    url = row['URL']  # 4列目: URL
    lat, lon = map(float, location.split(','))  # 緯度と経度に分割

    # ポップアップのHTMLを作成
    popup_html = f"""
    <b>{name}</b><br>
    賃料: {amount}万円<br>
    <a href="{url}" target="_blank">詳細を見る</a>
    """    
    popup = folium.Popup(popup_html, max_width=300)
    folium.Marker(location=[lat, lon], popup=popup).add_to(m)

# 地図を表示
m.save("map.html")
m
```
これでマップ上に表示されるようになります。
以下が実行結果です。マップは自由に移動、拡大が可能で、ピンが立っているところをクリックすることで情報を確認することができます。
また、詳細を見るをクリックすることでExcelファイルに載せていた物件情報サイトに飛ぶことができます。
![ピン表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993674/b7d9e4fd-1005-2ca0-24c7-b54b2c3433ec.png)
# おわりに
今回は`Google Map`上に賃貸情報一覧をパッと表示したいということで、`Google Colaboratory`と`Python`を用いて実装を行いました。
一人暮らしのための準備として実装しましたが、賃貸というジャンルだけでなく、旅行の思い出として記録を残したりしてもいいのかもしれません。
この記事を読んだ物件を探している人がいい物件を見つけられますように祈ってます。
おわりです！
Synology NASに預けた画像をFlutterで表示する

## はじめに
SynologyのNAS上にアップロードした画像を自作のFlutterアプリで表示しようとしたところ、思ってた方法と違ったのでここに備忘録&共有(必要な人いるのか？)として書き記します。

## 共有リンクから表示しようとした...
NASにアップロードされた画像は一応ネットワーク上の画像に分類されるので、FlutterであればImage.networkを使うことで表示できるはずです。
実装を始めた頃はImage.networkの引数に、共有リンクのURLを渡せば表示できるものだと思っていました。

というわけで、[FileStationAPI](https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf)の「SYNO.FileStation.Sharing(共有リンク取得)」を利用して、表示したい画像の共有リンクを取得し、Image.networkに渡したところ...
![スクリーンショット 2025-01-24 3.09.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667865/8225040a-a49d-7969-4cd7-617fd9c41508.png)
**Flutterアプリ上の表示**

![スクリーンショット 2025-01-24 3.09.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667865/14029ddf-25e6-cc29-dcbf-ff13dc7b2deb.png)
**コンソールログ上の表示**

あら、失敗してしまいました...
エラーメッセージを見る限り、URLが適切な値じゃなかったようです。
念の為、FileStationから直に共有リンクを発行しImage.networkに渡してみたのですが、やはり同様のエラーが発生してしまいます。

試しに、共有リンクをブラウザで開いてみたところ...
<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667865/78bc2b1d-52e1-c350-6d6d-9be21db747be.png>


うーん...確かに想定していたものと違うなと
想定していたのは、以下のようにブラウザいっぱいに画像だけが表示されるような状態
<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667865/489b393f-f3f1-e643-8b9c-6f2c2477e9e8.png>


さて困りましたね...
ネットワーク画像なのにImage.networkで表示することがこれではできないようです。

### 渡すのはダウンロードリンクだった！
上記エラー解消のために色々と調べていたところ、興味深い記事が
[Image.networkでGoogle Drive上の画像を取得しようとした話](https://qiita.com/krohigewagma/items/383bb5b46409990a61dd)

上記記事の筆者の方はGoogleDrive上の画像を表示しようとして私と同じ問題にぶち当たったようです。
調査していくと、Image.networkに渡すURLは**ダウンロードリンクだということ**が判明。これを渡したところ、見事画像が表示されるようになったようです。

Synology FileStationでダウンロードリンクはどのように用意するかというと、FileStationAPIの「SYNO.FileStation.Download(ファイルダウンロード)」で可能なのではないかと考えました。
このAPIはクエリのmodeによって、ブラウザに表示するモードかファイルをローカルに落としてくるモードか決められるので、前者でAPIのURLを作りImage.networkに渡してみましょう。

```dart
// Uriを文字列化してURL生成
final imageUrl = Uri(
  scheme: 'http',
  host: '192.xxx.yyy.zzz',
  port: 5000,
  path: 'webapi/entry.cgi',
  queryParameters: <String, dynamic>{
    "api": "SYNO.FileStation.Download",
    "version": "2",
    "method": "download",
    "path": "\"/target\"", // パスはダブルクオーテーションで囲む必要がある
    "_sid": sid,           // ログインAPI呼び出し時に得られるsid
  },
).toString();


// Urlから画像表示
Image.network(imageUrl)
```
<img width=500 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667865/9e0e463f-a218-2710-a051-06e5c2f86207.png>

お！表示されました！
大成功です！！

## おわりに
というわけで、Synology NASにアップロードした画像をFlutterのImage.networkで表示する方法でした。
Image.networkに渡すURLが、ダウンロードリンクである必要があるということに気づけなければ解決できませんでしたね。ツールは違えどGoogleDriveで調査していただいた方に感謝です。
WordPressのテーマCocoonにおいて、CSSの見出しタグで極太ゴシックを使う方法(全て無料)

WordPressを学習中の方へ情報を提供します。お役に立てば幸いです。

ローカル環境でWordPressを導入している方に無料テーマCocoonを使いつつ、見出しタグ(h1など)で極太ゴシックを使う方法を説明したいと思います。ローカルではなくて、サーバー環境でも使えると思います。
試してませんが。

準備　https://seed.line.me/index_jp.html
(メッセージアプリLINEが無料で提供している極太ゴシック体フォントです。商用、非商用共に可)
よりzipファイルをダウンロードして下さい。解凍します。そうするとフォルダが3つDesktop、WEB、Appと3つのフォルダが出来ます。DesktopはExcelやWordで使う場合です。WordPressで使う場合はWEBを選択します。そしてさらにその中にあるwoff2を選び、さらにそのフォルダの中に
LINESeedJP_OTF_Th.woff2　細字ゴシック　Thin
LINESeedJP_OTF_Rg.woff2　普通ゴシック Regular
LINESeedJP_OTF_Bd.woff2　太ゴシック　Bold
LINESeedJP_OTF_Eb.woff2　極太ゴシック　ExtraBold
細ゴシックから極太まで4種類あるので好きなのを選んで下さい。全部使ってももちろん構いません。

ローカルサーバー環境(疑似サーバー環境)
・Local(旧Local Host)
・WordPress
・Cocoon
・Cocoon-child
をそれぞれインストールして設定します。

私の場合、LINESeedJP_OTF_Eb.woff2を使いました。CSSでh1～h3に使いたかったので。
C:\Users\hogehoge\Local Sites\wish-fulfilled\app\public\wp-content\themes\cocoon-child-master\fontsにお好きなフォントファイルをコピーします。fontsフォルダがない場合は作ります。

次にC:\Users\hogehoge\Local Sites\wish-fulfilled\app\public\wp-content\themes\cocoon-child-masterフォルダにある、style.cssを開きます(開くソフトはVSCodeが良いと思います)
style.cssは念の為コピーをとっておき、次の内容で上書きして下さい。

'''CSS
/* style.css */
@charset "UTF-8";
@import url('../cocoon/style.css'); 

/* LINE Seed JPフォントの定義 */
@font-face {
  font-family: 'LINE Seed JP';
  src: url('fonts/LINESeedJP_OTF_Eb.woff2') format('woff2'); /* フォントファイルのパスは要確認 */
  font-weight: 400;
  font-style: normal;
}

/* 共通スタイル */
body #main .entry-content h1,
body #main .entry-content h2,
body #main .entry-content h3 {
  font-family: 'LINE Seed JP', sans-serif; /* 詳細度を上げてフォントを指定 */
  font-weight: 400;
  line-height: 1.4;
  margin: 1em 0;
}

/* h1スタイル */
body #main .entry-content h1 {
  font-size: 2.5em;
  color: #505050;
  padding: 0.5em;
  background: linear-gradient(transparent 70%, rgba(167, 214, 255, 0.5) 70%);
  text-align: center;
}

/* h2スタイル */
body #main .entry-content h2 {
  font-size: 1.5em;
  padding: 1rem 2rem;
  border-top: 4px solid #d8dcdc;
  border-right: 4px solid #666;
  border-bottom: 4px solid #333;
  border-left: 4px solid #868888;
  border-radius: 0;
  background-image: -webkit-linear-gradient(135deg, #ccc 0%, #868888 20%, #d8dcdc 34%, white 53%, #ccc 100%);
  background-image: linear-gradient(-45deg, #ccc 0%, #868888 20%, #d8dcdc 34%, white 53%, #ccc 100%);
  color: #000004;
  box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}

/* h3スタイル */
body #main .entry-content h3 {
  font-size: 1.25em;
  color: #333;
  background-color: #fffacd;
  border-left: 5px solid #d9534f;
  padding: 10px 15px;
  margin: 20px 0;
  box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
}

/* #toc2 */
body #main #toc2 {
  all: unset;
}
'''
CSSは一例です。ご自分でカスタマイズして下さい。
Cocoonにはh1,h2,h3に目次生成機能がありますが、不要な場合はCocoonの設定画面からOFFに出来ます。

通常はCSSを書き換えても、Cocoonによって上書きされるのですが、これは上書きされません。
理由は今回使用したセレクタの詳細度が、Cocoonのデフォルトスタイルで使用されているセレクタの詳細度を上回ったためです。CSS内の.entry-content はh1～h3のスコープを記事本文に限定するためです。
セイバーメトリクスで利用できる MLB データ

## STATCAST
　MLB 公式の Bassball Savant から利用します。
[savant](https://https://billpetti.github.io/baseballr/index.html)

STATCAST は、MLB で利用されているトラッキング技術を使用したデータで、１球ごとのピッチングデータ、バッティングデータ、フィールディング、ベースランニング、キャッチングデータを、直接、CSV データとして利用出来るほか、R の baseballr パッケージでも使用できます。

STATCAST が導入されたのは 2015年なので、当然にデータも 2015年以降のものに限定されます。

## FanGraphs

　[FanGraphs](https://www.fangraphs.com/) から直接、ダウンロードまたは、STATCAST 同様に R の baseballr パッケージでも利用できます。

 MLB 公式推奨の FanGraphs では、ゲームごとのデータ、バッティング、ピッチング、フィールドの成績データ、セーバーメトリクス指標が利用できます。
 2002年までのゲームごとのデータは、[RETROSHEET](https://www.retrosheet.org) のデータが使われています。

 ## Lahman

　[Lahman](http://www.seanlahman.com) データは、1871年以降のバッティング、ピッチングデータ、フィールディング統計、順位、チーム、ポストシーズンデータ等を利用できます。

サイトでは、Access, CSV, Microsoft SQL Server 用の SQL バージョンが用意されていますが、CSV が利用しやすいでしょう。また、R では、Lahman パッケージを利用できます。

## データの再構築

　基本的には、以上３つのデータを必要な形に再構築しながら取り組んでいくことになると思います。

## その他のデータ
　他に利用できるデータとして、以下の２つを載せておきます。
- [BASEBALL-REFERENCE](https://www.baseball-reference.com)
- [Baseball Prospectus](https://www.baseballprospectus.com)

 ## Out of the Park Baseball

 [Out of the Park Baseball](https://www.ootpdevelopments.com) はセーバーメトリクスに利用するデータではなく、MLB 公式ライセンスのシミュレーションゲームです。
 MLB 公式記事の2023年のポストシーズンの予想企画「[Out of the Park Baseball simulates the '23 World Series winner](https://www.mlb.com/news/out-of-the-park-baseball-simulations-of-2023-mlb-season)」などでも利用されているように、選手データを編集できるので、シミュレーションのツールとして使えます。

 　また、GM としてゲームプレイができるので、MLB のフロントオフィスの運営やロースタールールの理解にも有用です。
  選手データには、BASEBALL-REFERENCE の ID、マイナー ID が含まれています。
 
 　以前は NPB データも含まれていましたが、権利関係で現在は、削除されています。

  OOTP は、毎年、3月中旬頃に新しいバージョンが発売されます。
  早期予約では安く購入できますが、シーズン中も頻繁に割引が行われます。
  例年、シーズンが終了すると80%オフで販売されています。

  Mac、Windows PC で利用できます。スタンドアロン版と Steam 版があります。
+
lazy loadingでルーティング

## lazy loadingとは？

Lazy Loading（遅延読み込み）は、初期ロード時のパフォーマンスを向上させるために使われます。
アプリケーション内のルートやページコンポーネントを必要なときにだけ読み込むことで、初期表示の速度を向上させます。

## lazy loading する前のコード

ルートのページコンポーネントとしてHome, About, Contactをimportしています。
ですがこのままだと全てのコードを1つのファイルにまとめるため、
初期ロード時に大きなJSファイルをダウンロードすることとなり、
初期表示が遅くなります。
なので必要な時だけ各ページコンポーネントがimportされるようにしたいです。

```tsx
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import NavBar from "./components/NavBar";
// 下記三つがlazy loadの対象
import Home from "./components/Home";
import About from "./components/About";
import Contact from "./components/Contact";

function App() {
  return (
    <div className="p-8">
      <Router>
        <NavBar />
        <Routes>
          <Route path="/" element={<Home />}></Route>
          <Route path="/about" element={<About />}></Route>
          <Route path="/contact" element={<Contact />}></Route>
        </Routes>
      </Router>
    </div>
  );
}

export default App;

```
## lazy loading した後のコード

各ページコンポーネントはlazy loadingにしましたので、
Suspenseでロード中のfallbackを設定しました。

```tsx
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import NavBar from "./components/NavBar";
import { lazy, Suspense } from "react";

// lazy loading の設定
const Home = lazy(() => import("./components/Home"));
const About = lazy(() => import("./components/About"));
const Contact = lazy(() => import("./components/Contact"));

function App() {
  return (
    <div className="p-8">
      {/* Suspenseで囲む */}
      <Suspense fallback={<p>Loading...</p>}>
        <Router>
          <NavBar />
          <Routes>
            <Route path="/" element={<Home />}></Route>
            <Route path="/about" element={<About />}></Route>
            <Route path="/contact" element={<Contact />}></Route>
          </Routes>
        </Router>
      </Suspense>
    </div>
  );
}

export default App;

```
## まとめ
- Routingなど、ユーザーのアクションによって表示が切り替わるものは、逆を返すと表示しなくていいものもあるので、lazy loadingでimportしましょう
- lazy loadingを設定するとユーザーのアクションにより読み込む必要性が出てくるので、Suspenseで囲って、fallbackコンテンツを用意しましょう
IchigoJam Pをブレボで簡単製作

★ラズパイpicoを使いブレボで簡単IchigoJam Pの製作
Raspberry pi picoでHDMIで映像を出力したくネットで検索し、Adafruit DVI ブレークアウト ボード を使用すると簡単に出来る記事が目に留まり購入しました。
https://qiita.com/riris4488/items/252949e16af73e9fbcdb
このボードの回路がIchigoJam PのDVI(=HDMI)出力回路と同じなので、ブレボを使って製作しました。
Adafruit DVI ブレークアウト ボード は、スイッチサイエンスで468円(税込)です。
https://www.switch-science.com/products/7423
モニターはPC用のVGAタイプで、HDMI VGA変換ケーブルを使用しています。

![FB_IMG_1737650498078.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956987/1a4f9925-686d-5709-063d-ad18599c1262.jpeg)
Railsで`stylesheet_link_tag`が効かない問題の解決方法

Railsアプリケーションを開発しているときに、`<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>` を利用してCSSを読み込もうとしたにも関わらず、以下のエラーが発生することがあります：

```
Propshaft::MissingAssetError at /documents/1
The asset 'application.css' was not found in the load path.
```

この問題とその解決方法について、以下に解説します。

## 問題の原因
このエラーは、Railsがアセットファイル（ここでは`application.css`）を適切にロードできていない場合に発生します。
主な原因として以下が考えられます：

1. `sassc-rails` がインストールされていない。
2. `app/assets/config/manifest.js` が存在しない。
3. `manifest.js` に必要な記述が不足している。

## 解決方法

### 1. **`sassc-rails` をインストールする**
Railsで `.scss` ファイルを使用する場合、`sassc-rails` が必要です。このGemがインストールされていないと、`.scss` ファイルを処理できずエラーになります。

#### 手順：
1. `Gemfile` に以下を追加します：
   ```ruby
   gem "sassc-rails"
   ```

2. 以下のコマンドを実行してGemをインストールします：
   ```bash
   bundle install
   ```

3. サーバーを再起動します：
   ```bash
   bin/rails server
   ```

### 2. **`manifest.js` を作成する**
Rails 7以降、デフォルトのアセット管理ツールである `Propshaft` を利用する場合、`manifest.js` ファイルが必要です。

#### 手順：
1. 以下のコマンドでディレクトリとファイルを作成します：
   ```bash
   mkdir -p app/assets/config
   touch app/assets/config/manifest.js
   ```

2. `manifest.js` に以下を記述します：
   ```javascript
   //= link application.css
   //= link controllers/application.js
   //= link controllers/file_input_controller.js
   //= link controllers/hello_controller.js
   //= link controllers/index.js
   ```

### 3. **アセットを再コンパイルする**
設定を変更した後、アセットを再コンパイルする必要があります。

#### 手順：
以下のコマンドを実行してください：
```bash
bin/rails assets:clobber
bin/rails assets:precompile
```

これにより、`application.css` が正しくビルドされます。

---

### 4. **Railsのレイアウトファイルを確認する**
`application.html.erb` に以下のコードが正しいことを確認してください：

```erb
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
```

もし変更している場合は、必ず `application` と記載されていることを確認してください。


## 実際に試した解決手順
筆者のケースでは、以下の手順で問題を解決しました：

1. `Gemfile` に `sassc-rails` を追加し、`bundle install` を実行。
2. `app/assets/config/manifest.js` を作成し、以下を記載：
   ```javascript
   //= link application.css
   //= link controllers/application.js
   //= link controllers/file_input_controller.js
   //= link controllers/hello_controller.js
   //= link controllers/index.js
   ```
3. アセットを再コンパイル：
   ```bash
   bin/rails assets:clobber
   bin/rails assets:precompile
   ```
4. ブラウザのキャッシュをクリア（`Shift + F5`）。

これだけで問題は解決しました！

## まとめ
このエラーは、Rails 7以降で採用された `Propshaft` の設定やアセットの配置ミスが主な原因となることが多いです。以下を確認することで、多くの場合解決できます：

1. `sassc-rails` がインストールされている。
2. `app/assets/config/manifest.js` が存在し、必要な記述が含まれている。
3. アセットを正しくプリコンパイルした。
Googleスプレッドシート更新内容をLINEWORKSのトークで共有したい

GOOGLE スプレッドシートに蓄積されていくバーコードスキャナーで読み込まれたデータから、作業進捗率を計算して10%ごと進むごとにLINEWORKSのトークでメッセージを送信するようにしました。

※本当はVBAが良かったのですが、挫折してGASで作り直しました

こちらの記事を参考にして作りました。

https://qiita.com/kunihiros/items/4cdec5784f21598cfee0

個人宛に送れることを確認した後でトークルーム宛てに送るものに変更しました。

https://qiita.com/kunihiros/items/643f8a861dd715f0e020

# 使ったもの
LINEワーククスのライブラリ　
1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod 

LINEWORKS.userMessageSend（env,text)

```
function sendmsg(msg) {
  let env = getEnv_()
  env.userId = "送りたいユーザアカウント"
  env.channelId = "送りたいトークルームのチャネルID"

  // LINE WORKS にメッセージを送信（個人宛）
  LINEWORKS.userMessageSend(env,  msg)　

  // LINE WORKS にメッセージを送信（トークルーム宛）
  LINEWORKS.channelMessageSend(env,  msg)
}
```
macにCubase AI をインストールしたら、HALION Sonicのインストゥルメントがひとつも表示されなかった件

表記の状況でドはまりした。
CubaseAIをダウンロードしてインストールして、HALION Sonicも入れた。
アプリを起動してWindowsで作ったファイルを読み込んだら、「一部の楽器がないよ！！（意訳）」みたいなメッセージがでた。まあ、macのほうには無いやつもあるのかな..くらいにおもってたら...
全部の楽器がなかった。音が全く鳴らなかった。
Windowsでやったときは上手くいったのに。


## これがダメだった
SterinbergのWEBサイトにある、Cubase AI とか Halion Sonicとかのダウンロードリンクから個別にダウンロードしてインストールしたのがダメだったっぽい

## こうすればいい
- 「Steinberg Download Assistant(SDA)」を最初にダウンロードする
- SDAのダウンロード後、SDAを起動すると、ログインを要求される
- ダウンロード可能な製品一覧が表示されるので、片っ端からインストールする
- CubaseAIを起動する
- ちゃんと音が鳴った


めでたしめでたし


## 結論
Cubaseをインストールするときは、SDAを使わないとダメ！！
【Python】リストについて

### Pythonのリストの特徴
	
#### 1.	順序付きコレクション
•	リスト内の要素は順番が保持されます。インデックスを使って特定の要素にアクセス可能。
•	インデックスは 0始まり（最初の要素が 0 番目）。
#### 2.	ミュータブル（変更可能）
•	リストは作成後でも要素の追加、削除、変更が自由にできる。
#### 3.	多様なデータ型が混在可能
•	リスト内には、異なる型（文字列、数値、ブール値、リストなど）を混在させることができる。
***
### リストの基本構文
リストは、角括弧 [] を使って作成し、リストの要素は、カンマ , で区切る。

```python:python
fruits = ["りんご", "バナナ", "みかん"]
numbers = [1, 2, 3, 4, 5]
mixed = ["文字列", 123, True, 4.56]  # 異なるデータ型を含むことも可能
```
***
### リストの基本操作

#### 1. 要素のアクセス

リストの要素には、インデックス（位置番号）を使ってアクセスします。インデックスは0から始まる。

``` python:python
fruits = ["りんご", "バナナ", "みかん"]
print(fruits[0])  # りんご
print(fruits[1])  # バナナ
print(fruits[-1]) # みかん（負のインデックスは末尾からアクセス）
```

#### 2. 要素の変更

特定のインデックスの値を変更できる。

``` python:python
fruits[1] = "オレンジ"  # "バナナ"を"オレンジ"に変更
print(fruits)  # ['りんご', 'オレンジ', 'みかん']
```

#### 3. 要素の追加
•	append(): リストの末尾に要素を追加。
•	insert(): 指定した位置に要素を挿入。

``` python:python
fruits.append("ぶどう")  # 末尾に追加
print(fruits)  # ['りんご', 'バナナ', 'みかん', 'ぶどう']

fruits.insert(1, "いちご")  # インデックス1に挿入
print(fruits)  # ['りんご', 'いちご', 'バナナ', 'みかん', 'ぶどう']
```

#### 4. 要素の削除
•	remove(): 指定した値を削除。
•	pop(): 指定した位置（または末尾）の値を削除して返す。
•	del: 指定した位置の値を削除。
•	clear(): リストの全要素を削除。

``` python:python
fruits.remove("バナナ")  # "バナナ"を削除
print(fruits)

fruits.pop()  # 最後の要素を削除して返す
print(fruits)

del fruits[0]  # インデックス0の要素を削除
print(fruits)

fruits.clear()  # リストを空にする
print(fruits)  # []
```
***
### リストの便利な機能

#### 1. リストの長さ

``` python:python
fruits = ["りんご", "バナナ", "みかん"]
print(len(fruits))  # 3
```

#### 2. リストの結合

``` python:python
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2
print(combined)  # [1, 2, 3, 4, 5, 6]
```

#### 3. スライス（部分リストの取得）

``` python:python
numbers = [1, 2, 3, 4, 5]
print(numbers[1:4])  # [2, 3, 4] （インデックス1から3まで）
print(numbers[:3])   # [1, 2, 3] （最初からインデックス2まで）
print(numbers[2:])   # [3, 4, 5] （インデックス2から最後まで）
```


#### 4. リストの繰り返し処理

``` python:python
for fruit in fruits:
    print(fruit)  # リスト内の要素を順に出力
```


#### 5. リスト内包表記（リスト生成の簡略化）

``` python:python
# 1から10までの2乗をリストに格納
squares = [x**2 for x in range(1, 11)]
print(squares)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```

***

### まとめ
•	Pythonのリストは、柔軟性が高く、使いやすいデータ構造。
•	追加、削除、変更、検索、並び替えなどの操作が簡単に行える。
•	内包表記を使うことで、効率的なリスト生成が可能。
Googleスプレッドシートにバーコードリーダーで連続してデータ入力したい

EXCEL VBA → GAS への作り変え

EXCEL VBAは次のデータの読み取り用に新しいダイアログをすぐ再表示してくれていたので
ＧＡＳでも同じ動きにしたい

●ダイアログにバーコードデーターを次々に読み込ませたい
●バーコードリーダー以外は触りたくない
※バーコードリーダーはデータ読み取り＋エンターの動きをやってくれる

# １つ目の壁 マウスで「OK」ボタンをクリックしないと次の入力が出来ない
今回、GASで作り直したら、ダイアログは「OK」ボタンをマウスでクリックしないと
次のデータを読み込めないという壁にぶつかりました。

サイドバーであればINPUTにデータが入ったら自動的にOKボタンを押すのと同じ動きをしてくれるという記事見つけたので、サイドバーに作り直してみました。

参考文献
サイドメニューであればエンター効果があるという記載はこちらから入手

https://teratail.com/questions/281604

GASのサイドメニューのコードや設置の仕方はこちらを参考にさせて頂きました。

https://zenn.dev/howdy39/articles/7fc34d0f010da9

# ２つ目の壁 　サイドバーにしたけどマウスで「OK」ボタンをクリックしないと次の入力が出来ない

こちらの２つの記事を読んだ結果、おそらくこれが原因だろうと思ったので、
INPUTに入力してエンター押すとSUBMITするように書き直せばいいのだろうと予想

https://zenn.dev/silurus/articles/b111b2de6cc8d2


https://magazine.techacademy.jp/magazine/31038

formタグを追加してonsubmit= の記述を追加、
ボタンは<input type="submit" value="送信">に書き直しました。
入力＋エンターでプログラムが動くようになりました。

# ３つ目の壁 次の入力をしたいのに入力箇所にカーソルが当たっていない！
具体的には前の入力データが残ってしまってるのと、入力のカーソルがINPUTに当たっていないので、マウスでカーソルを移動しないと次の入力が出来ない

カーソルが当たるようにするのはこちらを参考にしました。

https://allabout.co.jp/gm/gc/23964/2/

# ４つ目の壁 入力エリアの文字が小さすぎて見にくい！！

style="font-size:50px;　を足しました。

```<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <div>
      <form method="post" action="" onsubmit="return convert()" id="form1">
      <input type="text" id="message" value="" style="font-size:50px;" size="5"/> 
      <input type="submit" value="送信">
      </form>
    </div>

    <script>
    function convert() {
      const message = document.getElementById('message');
      console.log(message.value);
      google.script.run.execute(message.value);

      message.value = ""
      document.getElementById('message').focus();
    }
    </script>
    <script type="text/javascript">
      document.getElementById('message').focus();
    </script>
  </body>
</html>
```
# 一応使えそうなレベルにはなったけども・・・

超高速で読み取ると、まだスプレッドシートへの書き込み処理が終わっていないのに、入力エリアがスタンバイになってしまう。
処理が終わっていない状態で次を読み込んでも多少は大丈夫そうなのだが、
1,2,3,4,5 と入れていくと　1,2,3,4 とか　1,3,4,5 とか時々飛んでしまうので、
そのうち少し直したい
【Zed】ホットキーでHTTPクライアントツールを表示する方法

## Postingをインストール

以下のコマンドを実行してPostingをインストールします。

https://github.com/darrenburns/posting

```terminal
brew install posting
```

## Zedのタスクを作成する

Postingを起動するタスクを作成するために`tasks.json`に以下を追記します。

```jsonc

  {
    "label": "Posting",
    "command": "posting",
    "hide": "always",
    "allow_concurrent_runs": false,
    "use_new_terminal": true
  }

```

## タスクにホットキーを設定する

ホットキーでタスクを実行できるように`keymaps.json`に以下を追記します。

```jsonc
  {
    "bindings": {
      "alt-p": [
        "task::Spawn",
        {
          "task_name": "Posting",
          "reveal_target": "center"
        }
      ]
    }
  }
```

上記のように記述した場合、`alt + p`を入力すると画像のようにHTTPクライアントツールが表示されます。

![スクリーンショット 2025-01-23 23.52.01のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/64f6b3bf-b3bd-4c8d-7a2a-6801ae8fcff3.png)
【小ネタ】Qiita公開時までのAPIレスポンスを調べてみた

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

個人的にQiitaでブログ執筆している中で、**下書き⇒限定公開⇒全体公開までのAPIレスポンスについて知りたくなった**と思い記事を執筆してみました。

小ネタレベルですので、お気軽に読んでいただければ幸いです。

# 目次
- ブラウザ環境
- その1：執筆時
- その2：下書き保存時
- その3：限定公開時
- その4：全体公開時
- まとめ

## ブラウザ環境

Googleブラウザで**バージョン: 132.0.6834.110**を利用して検証しました。
API検証時は、Googleブラウザの**検証ツール**を用いて実施しました。

## その1：その1：執筆時

初回執筆時のAPIレスポンスとして以下の通りでした。

![初回執筆.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/ea61a247-ebe3-b88b-e74d-b56668aab467.png)


レスポンスの中身はすべて見ていないですが、**notification**と**popup**が出ているので、**ページ更新と更新時の情報**が表示されていると推察できました。

また、**Graphql**のAPIレスポンスもあるので、おそらくですが、**Graphqlへのデータ登録**も行われているのではないかと推察できます。

個人的に**InternalPages**が何を意図しているかよく分からないと思いました。

## その2：下書き保存時

それでは、初回執筆⇒下書き保存へ遷移したときのAPIレスポンスについて見てみたいと思います。

![下書き保存時.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/d0be0310-100f-75de-e1a7-82b1fe50664e.png)

APIレスポンスとして下書き保存時と同じ内容のように見受けられました。

## その3：限定公開時

それでは、下書き保存⇒原型公開へ遷移したときのAPIレスポンスについて見てみたいと思います。

![限定公開1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/f91479e2-53e9-07e4-9f66-0309a9e8125a.png)
![限定公開2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/9ab6e1d6-4f59-f59f-173a-82e0ed1505c2.png)

執筆時、下書き保存時と比較してAPIレスポンスの量が多くなったように見受けられます。

そのうえで、**v3**といった（おそらく）認証関連のAPIレスポンスや、**uid**などのパスパラメータ内のID情報（おそらく記事ID）に関するAPIレスポンスが追加されていると推察できます。

個人的に、**khaos~**の名称のAPIレスポンスの内容が予想できなかったため、どのような役割があるかベット調査してみたいと思いました。

## その4：全体公開時

それでは、限定公開⇒全体公開へ遷移したときのAPIレスポンスについて見てみたいと思います。

![公開1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/dc21b2d9-6b5a-fb29-7d85-8b993f073eb2.png)
![公開2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846878/071518f7-1000-dd29-d51b-dd27c1c08f90.png)

内容として限定公開時のAPIレスポンスと大きく変化は内容に見受けられました。仮説ですが、**限定公開時と全体公開時のAPIレスポンスの挙動についてほとんど変わりはない**かと思われます。
（おそらく、パスパラメータからサーバー側でWeb公開/非公開を決めているのではないかと推察されます）

## まとめ

小ネタレベルの内容ですが、検証ツールを用いてSaaSサービスのAPIレスポンスを見てみることで、**どのように処理が遷移されているのか**を視覚的に理解することができます。

あわせて、今回検証した内容として**執筆⇒下書き⇒限定公開⇒全体公開**のみなので、**いいね**、**ストック**や**コメント登録時**のAPIレスポンスの挙動について調べてみると面白いかもしれません。

最後まで記事を読んでいただきありがとうございました！！
Dドライブで実行したnpm scriptsで ~ を指定したらCドライブのホームディレクトリを見てくれなかったので書きかたを修正したメモ

# 概要

```
    "azurite-https": "azurite --silent --location c:/azurite --debug c:/azurite/debug.log --oauth basic --cert ~/.ssh/mkcert/127.0.0.1.pem --key ~/.ssh/mkcert/127.0.0.1-key.pem"
```
これだと下記のエラーが出てしまった。

```
Exit due to unhandled error: ENOENT: no such file or directory, open 'D:\projects\async-ttrpg\apps\api\~\.ssh\mkcert\127.0.0.1.pem'
```

[パス変換が予期せぬ場合の記事][*1]で対策として書かれている`export MSYS_NO_PATHCONV=1`も`~/.bashrc`に設定している。

~~おそらく、CドライブではなくDドライブで実行していることが問題だと思われる。~~ gitbashで実行してもnpm scriptはcmd.exeで動いていることが問題の模様。
Copilotに聞いたところ、下記で解決した。
`~/.ssh/mkcert/127.0.0.1.pem` → `%USERPROFILE%/.ssh/mkcert/127.0.0.1.pem`

[ソースコード](https://github.com/hibohiboo/async-ttrpg/blob/9baf90e7e620ad0fdffa9dbaa33dab8e79367c30/apps/api/package.json)

# 2025.01.27追記 npm script が動作するshellを確認
コメントでいただいた下記の記事を参考に確認
https://zenn.dev/unsoluble_sugar/articles/96c3e32ac4e723

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/b7148e08-8e1d-e098-7f24-5c62904732dc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/cd7003af-5572-4c96-1f7a-ca2385d0cdc7.png)

たしかに、cmdが動いている。cmdでは `~`を解釈できていない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/8ea056a1-07fb-88f4-0cc8-ec73230b06b7.png)


# 参考
[WindowsのGit Bashでパス変換が予期せぬ動作をする場合の対処法][*1]
[%USERPROFILE%フォルダについて](https://qiita.com/gentaro/items/5f1e577b826537acbf01)

[*1]:https://qiita.com/nannany_stores/items/52c471d7b13bff9b285e
[個人開発 1月号] アプリ100個作るまで！#4

### はじめに
こんにちは、SET（Software Engineer in Test）のたくまを目指す男です。
この記事では、新卒QAエンジニアである私が、QAと開発の両方の知見を深めることを目的として活動している様子を記事にしています。目標として、アプリを100個作成することに挑戦しています。
 
### 目次

- エンジニア履歴書アプリ
- OCRアプリ開発
- その他やったこと

### エンジニア履歴書アプリ

学生時代に、インターン先を探していた際に、面接まで進んだら、経歴書のファイルを提出すると思います。経歴書はExcelでネットの典型的なフォーマットで提出するので、アプリなどで管理できたら、楽だな〜と思ったので、自分のエンジニア経歴書をアプリで一元管理できるアプリケーションを開発しようと思いました。
とりあえず、簡単に作りたいことを練って、超簡易的に資料にまとめました。

| ![Image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/bb0e50db-dc21-dca8-4998-c5bc59f96a09.jpeg) | ![Image2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/3d43de15-48c2-2e57-41d7-9b50f0a09894.jpeg) |
|---|---|
| 画像1 | 画像2 |

| ![Image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/1540a7de-32a1-b6d7-b5a9-66d8dd0ecb0d.jpeg) | ![Image2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/0f1a9e74-87f6-798a-bc6d-f932a07fa920.jpeg) |
|---|---|
| 画像3 | 画像4 |


大体5日くらいで開発しました。プロトタイプなので、かなり作りは荒いです。
以下、挙動です。次回は、Excelの出力後は、綺麗なフォーマットにしたいですね。

| ![Image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/7dc36d4d-e33a-fc5b-a014-c7358128eb59.png) | ![Image2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/991dce81-4c1d-c086-464d-ba825686b954.png) |
|---|---|
| 画像1 | 画像2 |

| ![Image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/140b9825-1e32-6b3b-98ac-e3e7745420e5.png) | ![Image2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/1a111c2e-b06f-a36b-a803-31e16eec0bbb.png) |
|---|---|
| 画像3 | 画像4 |

| ![Image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/e7a0edd2-78f0-1c94-d67d-b9003190f343.png) |
|---|
| 画像5 |


### OCRアプリ開発

ふとした時の会話で、領収書とかを写真撮って、情報取って電子化できたら確定申告とか楽だよね〜みたいな会話が上がったので、んじゃ、作ってみるかで開発してみました。Railsでrtesseractのライブラリから画像のテキスト取得する。そこにChatGPT APIを噛ませて、整形してもらってますね。
謝罪します。レシートを読み込ませているのですが、バリバリ住んでいるところのレシートを使っているので、画像一枚とさせてください。開発は本当にやったんです。。。1日くらいで開発しました。仕様書は作っていないです。

| ![Image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1788291/585b7b63-6e68-0bb6-e7f2-b0a7f068db58.png) |
|---|
| 画像１ |


### その他やったこと
社会人1年目の学習目的で以下、動画・書籍読みました。

https://www.mikasashobo.co.jp/c/books/?id=100289000

https://www.udemy.com/course/react-redux-beginner-course/?couponCode=ST18MT12125CROW

https://youtu.be/JHSI_K-14lU?si=e3NYs2gea_Xk9WOE

https://www.udemy.com/course/denki-kiso/?couponCode=ST18MT12125CROW

https://www.youtube.com/watch?v=oha59WayZ_A

以上でーす
Teams関連

# Teams Rooms

プロキシを使っている場合、レジストリ変更する必要あり

https://learn.microsoft.com/ja-jp/microsoftteams/rooms/rooms-prep#skype-user-registry-hive



# NewTeamsインストール

https://jpucsupport.github.io/blog/teams/Teams%20-%20%E6%96%B0%E3%81%97%E3%81%84%20Microsoft%20Teams%20%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%96%B9%E6%B3%95/

https://learn.microsoft.com/ja-jp/microsoftteams/troubleshoot/teams-administration/include-exclude-teams-from-antivirus-dlp#new-teams

https://jpucsupport.github.io/blog/teams/Teams%20-%20%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E9%80%9A%E4%BF%A1%E3%82%92%20Proxy%20Server%20%E7%B5%8C%E7%94%B1%E3%81%A7%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E9%9A%9B%E3%81%AE%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85/

# 個人用Teams

https://jpwinsup.github.io/blog/2023/09/20/UserInterfaceAndApps/DisablePersonalTeams/
#0023（2024/01/23）RTSP（Real Time Streaming Protocol）とは？

# RTSP（Real Time Streaming Protocol）とは？

RTSPは、動画や音声などの**ストリーミング**メディアを扱うために設計された**通信プロトコル**です。  
簡単に言うと、「**リアルタイムの映像や音声をネットワーク越しに再生・制御する**ための“ルール”」のことです。

---

## 1. どういうときに使うの？

- **IPカメラ**や監視カメラの映像をリアルタイムに配信する  
- ネットワーク上で**ライブストリーミング**を行う  
- クライアント（再生側）から**再生/停止/シーク**などをリモートで指示したい

RTSPは動画・音声データ自体を運ぶ役目だけではなく、  
「ストリームをどう再生するか・どのくらいの速度で送るか・途中から再生するにはどうするか」  
といった制御コマンドを取り扱う点が特徴です。

---

## 2. 具体的なイメージ

1. **クライアント（再生する側）**  
   - 動画プレイヤーや監視システム、ブラウザ拡張などが該当します。  
   - 「○○というストリームを再生したい」「一時停止したい」「この時間から再開したい」という命令をRTSP経由で送ります。

2. **サーバ（配信元）**  
   - IPカメラや映像配信サーバが、映像や音声データを保有しています。  
   - クライアントのリクエストを受け取って、RTPという別のプロトコルで映像・音声データをネットワークに流します。

3. **RTSPの流れ**  
   1. **SETUP**: クライアントがサーバに「ストリームを見たい」とセットアップを依頼  
   2. **PLAY**: 実際に「再生を開始」  
   3. **PAUSE/TEARDOWN**: 「一時停止」や「再生を終了」の制御

---

## 3. RTSPとRTPの違い

- **RTSP**: 主に「制御」や「どんな映像をどう再生するか」をやり取りするプロトコル  
- **RTP**(Real-time Transport Protocol): 実際の「映像・音声のデータ」を運ぶプロトコル  

RTSPが「再生開始して」「再生やめて」と命令を出し、  
RTPが「動画データ」のパケットをクライアントに送り届ける、  
という役割分担になっています。

---

## 4. よくある利用シーン

- **監視カメラ**: ネットワーク経由で録画機やモニタに映像を流すときにRTSPが使われることが多い  
- **メディアサーバ**: ライブ配信（ライブストリーミング）サービスで、RTSPで映像を受け付け、別の形式に変換して配信する場合もある  
- **動画検証ツール**: RTSPでカメラの映像を取り込み、リアルタイム分析や録画を行うソフトウェア

---

## 5. まとめ

- **リアルタイム性**: RTSPは映像や音声を「リアルタイム」で扱うために特化したプロトコル  
- **制御コマンド**: RTSPを使えば、ネットワーク越しで「再生」「停止」「時間指定で再生」などの操作ができる  
- **RTPとセット**: 実際のデータ伝送はRTPなど別のプロトコルを使い、RTSPはあくまでも“指示”や“やり取り”を担当

ネットワークカメラやストリーミング関連の分野では非常にポピュラーなプロトコルなので、  
「ネットワーク越しの映像・音声配信にはRTSPがよく使われる」というイメージを持っておくと分かりやすいです。
Linuxメモ

## プロセス一覧を表示するコマンド
```bash
ps aux
```

#### 親子関係でプロセス一覧を表示
```bash
pstree -p
```


## 使用しているポート番号を確認するコマンド
```bash
sudo ss -antup
```


# systemdとは
Linuxのプロセスは親子関係となっており、一番上の親のプロセスは`イニットプロセス`という。
イニットプロセスとして使えるプログラムは多数あるが、最近は`systemd`が主流。

ハンズオン研修などではnodeコマンドを使いシステムを実行しているが、実際の現場ではsystemdから、webアプリを起動させる必要がある。

systemdから起動することのメリット
- 何かしらの原因でサーバーが停止した場合でも、自動で再起動してくれる。
- 実行したアプリのログを取得してくれる

systemdは設定ファイルに記述した内容で動いてくれる。
systemdの設定ファイルは`/etc/systemd/system/`に配置される

# sshdとは
ssh接続を待ち受けるプログラム。systemdから起動している。
Security.any #2にて登壇してきました

- 経緯

[キタジーさん](https://x.com/kitaji0306)からDMで

「白”雪姫”さん、僕が開催しているSecurity.any」という勉強会、
登壇者を今募ってるんだけどセキュリティでいい感じにバズってたし登壇してみません？

という一言で登壇をすることになりました。

- 参加イベント

[Connpass](https://security-any.connpass.com/event/336993/) で公開されてるこちらのイベントです。
[3回目](https://security-any.connpass.com/event/343644/)もあるみたいなのでご興味ある方はどうぞ

- 所感

副題もあり、あの頃のセキュリティってこうだったよねぇという話がありました。
それと同時に私のはそこそこだなぁなというところもあり。。。
と思ってたのですが、「白”雪姫”さんは相当つよつよだよ、普通一人であそこまで話せないからね？」(要約)ということもいただき、大変恥ずかしく思いました。

今年の登壇初めというのもあり、だいぶ気楽にできたなぁとは思いましたが・・・・

絶対もうWindowsでは登壇品しない！！！
めちゃくちゃ重かったんだけど！！

- 公開資料

[こちら](https://speakerdeck.com/yuri_snowwhite/security-dot-any-number-2)、2ページ目にも書いてますがだいぶセンシティブなところも書いてたので部分的には削除しています。
完璧版を見たい方はXでDMをいただければと思います。
yukicoder No.3002 & No.3003 解説

類題である京大2023理系数学大問1の問2を解説している[とある動画](https://www.youtube.com/watch?v=qc8Q7dk1pPw)を思い出したので、簡単に解けました。
## 解説 ##
問題リンク
[No.3002(easy)](https://yukicoder.me/problems/no/3002) [No.3003(hard)](https://yukicoder.me/problems/no/3003)
問題は「$(Ax^B) mod (x^2+x+1)$ を求めよ.」というものでした。
hardになると $|A|$ と $B$ が大きくなります。
まず、$x^2+x+1 \equiv 0 \pmod {x^2+x+1}$ であることは明らかなので、両辺に $x-1$ を掛けます。すると、$x^3-1 \equiv 0 \pmod {x^2+x+1}$ → $x^3 \equiv 1 \pmod {x^2+x+1}$ となります。
本題に戻ります。$Ax^B = Ax^{3*\lfloor \frac{B}{3} \rfloor}Ax^{Bmod3}$ と変形でき、これは $mod(x^2+x+1)$ だと $Ax^B \equiv Ax^{Bmod3}$ となるので、これの右辺を考えればよいです。
(Ⅰ) $Bmod3 = 0$ の時、右辺は $A$ となります。なので、<code>0 A</code>が答えです。
(Ⅱ) $Bmod3 = 1$ の時、右辺は $Ax$ となります。なので、<code>A 0</code>が答えです。
(Ⅲ) $Bmod3 = 2$ の時、右辺は $Ax^2$ となります。これは $x^2+x+1$ で割ると、余りは $-Ax-A$ となり、<code>-A -A</code>が答えとなります。
計算量は $O(1)$ となります。
コード
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
int main() {
	ll A, B;
	cin >> A >> B;
	if(B % 3 == 0) {
		cout << "0 " << A << endl;
	}
	else if(B % 3 == 1) {
		cout << A << " 0" << endl;
	}
	else {
		cout << -A << ' ' << -A << endl;
	}
}
```
yukicoderはThe・数学という問題が沢山あるので、もっと解いていきたいです
FirebaseのプロジェクトにAppCheck(reCAPTCHA)を導入する際の備忘録

# 結論
**APIキー**の「**reCAPTCHAのAPI**」を有効にする

# 詳細な情報
多くの人が**Firebaseプロジェクト**を立ち上げて、コンソールから**AppCheck**なるものを選択して、使用すると思います。

**AppCheckの説明**で**reCAPTCHA**を**有効にすれば良い**ことが分かり、**有効にする**ことでしょう。なんやかんやあって、**reCAPTCHA**の**キーを作成**します。

すると、**初回**の**reCAPTCHA**の**認証を終えない**と**reCAPTCHA**が**使えない**ことが分かります。**reCAPTCHA**の**token**を**取得**して、書いてある通りに**JSONデータ**を**送信**すると、**403エラー**で悩みます。

なぜ**403エラー**になるかというと、**Firebaseプロジェクト**を**立ち上げた後**に**reCAPTCHA**を**導入**すると**APIの使用許可**が**下りていない**ため、**403エラー**になります。

そのため、**GCPコンソール**から**Firebase**で**立ち上げたプロジェクト**を**選択**して、**APIとサービス**から**認証情報**と**辿る**と「**APIキー**」**の欄**に**Firebaseから作成されたAPIキー**が**あるはず**なので、「**操作**」のところにある「**APIキーを編集**」を**クリック**して編集を行います。

**どこを編集**するのかですが、「**APIの制限**」**の欄**の「**XX個のAPI**」を**選択**して、**フィルタ**に「**reCAPTCHA**」と**入力する**と**有効にした**「**reCAPTCHAのAPI**」が出てくるので、**有効**にします。

その後、再度**token**を**取得**して、**JSONデータ**を**送信する**と**認証**に**成功**します。

自分のための備忘録なので、このケースに当てはまらない人はごめんなさい...
モノリポプロジェクトでGitHub ActionsによるHerokuとVercelへの自動デプロイを設定する

## はじめに
このガイドでは、バックエンドとフロントエンドを一つのリポジトリで管理するモノリポ形式のプロジェクトで、GitHub Actionsを使用して以下を実現する方法を解説します。
最近の構成ではフロントエンドにVercelが選択されることが多く、ここではフロントエンド＝Vercel、バックエンド＝Herokuの場合で進めたいと思います。
以下の機能を持たせたいと思います。

- mainブランチの更新時に実行される
- CI workflowの成功後のみデプロイが始まる
- バックエンドに変更があった時だけHerokuに自動デプロイ
- フロントエンドに変更があった時だけVercelに自動デプロイ

HerokuとVercelはGitHubと連携した自動デプロイ機能がありますが、GitHub Actionsを使用する理由としては以下の理由があります。
- デプロイの設定や履歴をGitHub上で一元管理
- 複数のデプロイ先を同じワークフロー形式で管理
- デプロイ前後の処理を自由に追加可能などカスタマイズ性が高い

## プロジェクト構成例
```
your-project/
├── backend/         # バックエンドディレクトリ
├── Procfile         # Heroku Procfile
├── frontend/        # フロントエンドディレクトリ
└── .github/
    └── workflows/   # GitHub Actions設定ディレクトリ
```

## 認証情報の取得

### Heroku認証情報の取得
1. **HEROKU_API_KEY**
   - [Herokuダッシュボード](https://dashboard.heroku.com/account)の"Account Settings"にアクセス
   - "API Key"セクションで"Reveal"をクリックしてキーを表示

2. **HEROKU_APP_NAME**
   - Herokuダッシュボードで新しいアプリケーションを作成
   - 作成したアプリケーション名を使用

3. **HEROKU_EMAIL**
   - Herokuアカウントのメールアドレス

### Vercel認証情報の取得
1. **VERCEL_TOKEN**
   - [Tokens](https://vercel.com/account/settings/tokens)にアクセス
   - "Create Token"をクリック
   - 名前を入力（例："GitHub Actions"）
   - スコープ（わからなければ"Full Account"）を選択
   - 作成されたトークンを保存

2. **VERCEL_ORG_ID** / **VERCEL_PROJECT_ID**
   - [Vercel CLI](https://vercel.com/docs/cli)をインストールする
    npmなら`npm i -g vercel@latest`
   - `vercel link`コマンドを実行する
    コンソールの指示通りに進めていく
   - `.vercel`ディレクトリが作成され、`project.json`の中に`projectId`と`orgId`が記載されている

## GitHub Secretsの設定
1. GitHubリポジトリの"Settings" → "Secrets and variables" → "Actions"にアクセス
2. "New repository secret"で先ほど取得した情報を追加する
   - `HEROKU_API_KEY`
   - `HEROKU_APP_NAME`
   - `HEROKU_EMAIL`
   - `VERCEL_TOKEN`
   - `VERCEL_ORG_ID`
   - `VERCEL_PROJECT_ID`


## Herokuのモノリポ用Procfileの配置
```bash
# Procfile
web: cd backend && java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/*.jar --spring.profiles.active=prod
```

## GitHub Actionsワークフローの設定

### バックエンドデプロイ
```yaml
# .github/workflows/deploy-backend.yml
name: Deploy Backend

on:
  workflow_run:
    branches:
      - main
    paths:
      - 'backend/**' # backendに変更のあった時のみ実行

jobs:
  deploy:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - uses: akhileshns/heroku-deploy@v3.13.15
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: ${{secrets.HEROKU_APP_NAME}}
          heroku_email: ${{secrets.HEROKU_EMAIL}}
          buildpack: "https://github.com/lstoll/heroku-buildpack-monorepo.git,heroku/gradle" # 必要に応じて変更
```

### フロントエンドデプロイ
```yaml
# .github/workflows/deploy-frontend.yml
name: Deploy Frontend

on:
  push:
    branches:
      - main
    paths:
      - 'frontend/**' # frontendに変更のあった時のみ実行

jobs:
  deploy:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          working-directory: ./frontend
```

### 実行手順
あとはmainブランチに対して更新が入るとデプロイが実行されます。
tokio::io AsyncReadのimpl実装

簡単ですがメモしておきます。

poll_readを実装するだけ。

https://docs.rs/tokio/latest/tokio/io/trait.AsyncRead.html


「Readを提供 = こちら側はWriteする」という意識で、```buf: &mut io::ReadBuf```にput等でデータを突っ込んでいく実装を行う。

https://docs.rs/tokio/latest/tokio/io/struct.ReadBuf.html


```rust
/*
 HelloってN回Readさせるのを提供するコード
*/

use tokio::io::{self, AsyncRead, AsyncReadExt};

struct Hello {
    count: u64,
    limit: u64,
}

impl Hello {
    fn new(limit: u64) -> Self {
        Self {
            count: 0,
            limit: limit,
        }
    }
}

impl AsyncRead for Hello {
    fn poll_read(
        mut self: std::pin::Pin<&mut Self>,
        cx: &mut std::task::Context<'_>,
        buf: &mut io::ReadBuf<'_>,
    ) -> std::task::Poll<std::io::Result<()>> {
        if self.count > self.limit {
            return std::task::Poll::Ready(Ok(()));
        }
        let s: &str = "Hello";
        let b: &[u8] = s.as_bytes();
        buf.put_slice(b);
        self.count += 1;
        std::task::Poll::Ready(Ok(()))
    }
}

#[tokio::main]
async fn main() {
    let mut r = Hello::new(10);
    let mut buffer = Vec::new();

    if let Err(e) = r.read_to_end(&mut buffer).await {
        println!("Error: {}", e);
    };
    println!("{}", String::from_utf8(buffer).unwrap())
}

```

以上
v4が正式リリースされた後もtailwind css v3を使い続ける方法

[Tailwind CSS](https://tailwindcss.com/)がバージョン4にアップデートされました。
ビルド時のファイルサイズが大幅に小さくなったほか、Viteとの併用時にPostCSSやautoprefixerが不要になっているなど大幅に改善されています。

一方で[Shadcn/ui](https://ui.shadcn.com/)などV4に対応していないUIフレームワークもまだまだ存在しますので、対応が追いつくまでTailwind V3を導入する方法を備忘で残しておきます。


### npm
```bash:コマンド
npm install -D tailwindcss@3.4.17 postcss autoprefixer //tailwindだけバージョン3.4.17を指定

npx tailwindcss@3.4.17 init -p //dlxでもバージョン指定

```

### yarn(v4)
```bash:コマンド
yarn -D tailwindcss@3.4.17 postcss autoprefixer //tailwindだけバージョン3.4.17を指定

yarn dlx tailwindcss@3.4.17 init -p //dlxでもバージョン指定

```

### pnpm
```bash:コマンド
pnpm install -D tailwindcss@3.4.17 postcss autoprefixer //tailwindだけバージョン3.4.17を指定

pnpm dlx tailwindcss@3.4.17 init -p //dlxでもバージョン指定

```
Salesforce CLI でメタデータを取得するほうほう

### Salesforce Antがサポートされないんだってニュース聞いたので、
ずっとSalesforce Antでメタデータを取得したけど、
もうそろそろサポートされなくなるよ: 
https://developer.salesforce.com/docs/atlas.ja-jp.daas.meta/daas/meta_development.htm
Slaesforce DXへ移行しますよなので、使い方は掴んでおく

### Salesforce CLIでメタデータを取得する方法
~~~ CMD
# Generage Salesforce DX Project
sf project generate --name {project_name_here}
# Change to project folder and retrive package.xml
sf project retrieve start -x .\manifest\package.xml --target-org xxx_admin@xxxxxx
# Retrieve all meta using package.xml
sf project retrieve start -x .\manifest\package.xml --target-org xxx_admin@xxxxxx
~~~

まずはここまで
【リーダブルコード】初心者エンジニアが読み解く「コメント」 の効果的な書き方- 第5章

こんばんは。マル太です。

前回は、リーダブルコードの第4章「美しさ」についてまとめました。

今回は、第5章「コメントすべきことを知る」の内容を、私なりに解釈し、Qiitaに投稿していきたいと思います。
<br>

# なぜコメントを書く必要があるのか
理想的には、コードはそれ自体で理解できるものであるべきです。

しかし、コードだけでは表現しきれない情報や、コードの意図を明確に伝えるために、コメントが必要となる場合があります。

コメントを効果的に使用することで、コードの可読性を高め、理解＆保守しやすいコードを作成することができます。
<br>

# コメントを書く際の注意点
コメントを書く際には、以下の点に注意する必要があります。

**正確な情報を記述する**
・コメントの内容が間違っていると、コードを読む人を混乱させてしまいます。

**簡潔で分かりやすい文章**
・コメントは、簡潔で分かりやすい文章で書くように心がけましょう。

**コードの意図を説明する**
・コメントは、コードの動作を説明するのではなく、コードの意図を説明するために使いましょう。

**必要最低限の情報**
・コメントは、必要最低限の情報に絞って書くようにしましょう。

**最新の状態を保つ**
・コードを修正したら、コメントも合わせて修正しましょう。
<br>

# どんな時にコメントを書くべきか
5章では、コメントを書くべき場面として、以下の4点が挙げられています。

**1.なぜそのコードを書いたのか**
　コードの意図や背景を説明する。
**2.コードの欠陥**
　コードの改善点やバグなどを指摘する。
**3.全体像**
　コード全体の構造や流れを説明する。
**4.重要なデータ**
　データの構造や意味を説明する。
 <br>

# コメントの種類
コメントには、大きく分けて以下の2種類があります。

**行コメント**
1行だけのコメント。 `//` や `#` などの記号を使って記述します。

**ブロックコメント**
複数行にわたるコメント。 `/* */` や `/** */` などの記号を使って記述します。

※ブロックコメント例⤵️
```ruby:C++
/*
これはブロックコメントです。
複数行に渡って記述できます。
この部分はコードとして実行されません。
*/
```

<br>

# まとめ
今回は、「リーダブルコード」第5章「コメントすべきことを知る」の内容をまとめました。

コメントは、コードの可読性を高めるための重要な要素です。

ただし、1章でも述べた通り、コメントに頼りすぎず、コード自体で意図が伝わるように書くことも重要です。

5章で紹介されているポイントを参考に、効果的なコメントを記述することを心がけたいですね。

次回は、第6章「コメントは正確に、簡潔に」についてまとめます。