OmniAICreator/Qiita-1.07M huggingface dataset:
Splunkのアラート発報機能について

Splunkには、監査ログ内のエラー発生時にアラートを発報する機能があります。この機能を利用するには、以下のステップを行う必要があります。

**1. 検索クエリの作成:** 監査ログ内のエラーや特定のイベントを検出するための検索クエリを作成します。たとえば、エラーに関するイベントを監視するクエリは、error や特定のステータスコードに基づいて作成できます。

```ruby:splunk
index=_audit error OR failure
```
**2. アラートの設定:**
- 検索クエリが完成したら、検索画面の上部にある「保存」ボタンをクリックして、検索を保存します。
- 「アラートとして保存」を選択し、条件やトリガーの設定を行います。たとえば、「エラーが検出されたときに発報」などの条件を設定できます。

**3. アラート発報のトリガー条件:** アラートの発報条件には、以下のようなオプションがあります。
- 特定の条件にマッチするイベントが発生した場合
- 一定回数以上のイベントが検出された場合
- スケジュールに基づいて定期的にチェックする場合

**4. 通知方法の設定:** アラート発報時に、メール、Slack、Webhookなどで通知する設定を行います。

この機能を活用することで、監査ログのエラーや重要なイベントをリアルタイムで検出し、即座に対応できるようになります。
浮動小数の除算

# 除算は遅いとか、いろいろ御託は省略する
組み込み系でリアルタイム処理したいからレイテンシが云々とか、そういう御託は省略する。
知りたいことは、 Newton-Raphson 法で、 C 言語で、どうやって浮動小数の逆数を計算するか、だ。
自分もそれが知りたかったし、意外と Google 先生でパッと出てこなかった。 Copilot 君も微妙な回答だった。

# 基本的な考え方
$x$ の逆数を求めるとして、初期値 $y_0$ を与えて、次の漸化式をループで回せばできる。
```math
y_{t+1}=y_t*(2-x*y_t)
```
初期値は、できるだけ逆数に近くとる必要がある。変な値だとそもそも収束しない。
初期値を与える為に、複雑な計算や条件分岐を入れるのは意味が全くないのだけれど、初期値として何が適切か書かれた記事を探すのも途中で面倒になった。さっと出てくるなら今回の記事も書かなかった。

# 初期値を浮動小数のビット分解から作る
どうやってビット分解しても構わないが、折角 C 言語なので、共用体を使う。どうせ Python などを使う人は逆数の計算で悩んだりしないわけだし、 C 言語に特化していたっていいじゃん。
```c
typedef union{
    float data;
    struct{
        unsigned long man:23;
        unsigned long exp:8;
        unsigned long sign:1;
    }bit;
}U_FLOAT_32;
```
初期値は、次のように与える。
```c
U_FLOAT_32 uX = {fX};
U_FLOAT_32 uY = {1.0f};
uY.bit.man = ~(uX.man);
uY.bit.exp = ~(uX.exp) - 2;
```
これで何故よいのかは、紙とペンで書いてみれば分かる。私はそうした。
例えば、 $1.9$ の逆数は、 $ca. 0.526$ だけど、仮数部は $1.X$ で正規化するから、仮数部だけ見たら、 $1.9 → ca. 1.052$ となる。同様に、 $1.1 → ca. 1.818$ 、 $1.5 → ca. 1.333$ 。
つまり、逆数をとると $\sqrt{2} = ca. 1.414$ を挟んで反対側へ写る。それをざっくりやるなら、ビット反転で十分だろう、ということである。
指数部については、 7Fh $=127$ をゼロとするわけだから、ビット反転して $-1$ する。後は、仮数部の正規化があるから、更に $-1$ する。

# 反復の必要回数
確り検証したわけではないけれど、 float 型の場合で $3$ 回、 double 型なら $4$ 回必要。
用途によっては $1$ 回減らしても精度十分。何桁の精度で十分か考えた方がよい。組み込み系で使うならそこまで精度要らなかったりしないかい？
先ほど、初期値の仮数部をざっくりで与えたので、 $2$ 回で十分だったり不十分だったりしているけれど、精度判定の処理を入れるくらいなら多く回した方が早い。

# 実装例
本当は $0$ の逆数とか、 $1$ の逆数とか、負の数とかあるので、その対応が必要。
そういった入力をしない前提とすれば、コードは短くできる。高速にしたいなら、入力されるはずがないデータを除く処理すら無駄だ。
とりあえず負値だけ例として入れておく。
```c
float calc_inv_float(float fX){
    U_FLOAT_32 uX = {fX};
    U_FLOAT_32 uY;

    // 負値対応の例
    if(uX.bit.sign){
        fX = -fX;
    }

    // 初期値
    uY.bit.man = ~(uX.bit.man);
    uY.bit.exp = ~(uX.bit.exp) - 2;

    // 反復計算
    uY.data = uY.data * ( 2.0f - fX * uY.data );
    uY.data = uY.data * ( 2.0f - fX * uY.data );
    uY.data = uY.data * ( 2.0f - fX * uY.data );

    // 負値対応の例
    if(uX.bit.sign){
        uY.bit.sign = 1;
    }

    return uY.data;
}
```

# double 型の場合
共用体のビット数を以下のように変更する。
```c
typedef union{
    double data;
    struct{
        unsigned long long man:52;
        unsigned long long exp:11;
        unsigned long long sign:1;
    }bit;
}U_FLOAT_64
```
また、反復を $1$ 回増やす。
```c
double calc_inv_double(double dX){
    U_FLOAT_64 uX = {dX};
    U_FLOAT_64 uY;

    // 負値対応の例
    if(uX.bit.sign){
        dX = -dX;
    }

    // 初期値
    uY.bit.man = ~(uX.bit.man);
    uY.bit.exp = ~(uX.bit.exp) - 2;

    // 反復計算
    uY.data = uY.data * ( 2.0 - dX * uY.data );
    uY.data = uY.data * ( 2.0 - dX * uY.data );
    uY.data = uY.data * ( 2.0 - dX * uY.data );
    uY.data = uY.data * ( 2.0 - dX * uY.data );

    // 負値対応の例
    if(uX.bit.sign){
        uY.bit.sign = 1;
    }

    return uY.data;
}
```
こういうのを書くと、 C++ だったらもっと汎用性を持って書けるなあ、とか思ってしまうけれど、除算でサブルーチン組むような組み込み系で C++ 使うわけがないね。

ちなみに、最近の組み込み系で使うマイコン、例えば Cortex-M33 だと、 STMicro の仕様書に依れば 32bit 浮動小数の加減乗算 $1$ クロック、除算 $14$ クロックらしい。先のコードはどう見ても $14$ クロック以上使ってしまうから、もっとショボいマイコンじゃないとわざわざ実装する意味がない。
アドレッシング完全ガイド：IPアドレスとMACアドレスの基礎をわかりやすく解説！

#### 概要
ネットワークアドレッシングとは、デバイス同士が通信するために互いを認識するための仕組みです。この記事では、IPアドレス（IPv4, IPv6）とMACアドレスの違いや役割について解説します。

---

#### 1. IPアドレス（IPv4, IPv6）
- **説明**: インターネットに接続する際にネットワークに接続している機器に割り当てられる識別番号で、インターネット上の住所や電話番号のような役割を果たします。
  - **グローバルIPアドレス**
    - **説明**: 世界中に唯一のアドレスで、外部からアクセス可能な公開アドレスです。
  - **プライベートIPアドレス**
    - **説明**: 内部ネットワークで使用されるアドレスで、インターネット上で一意である必要はありません。

- **IPv4**
  - **説明**: 「Internet Protocol Version 4」の略 IPv4は、32ビットのアドレス形式で、最大約43億のIPアドレスを提供します。アドレス枯渇が課題となっており、新たな接続方式（NATなど）が必要になっています。
  - **特徴**: 「192.168.1.1」のように、4つの数字がピリオドで区切られた形で表現される。

- **IPv6**
  - **説明**: IPv6は、128ビットのアドレス形式で、事実上無限のアドレスを提供します。IoTデバイスの増加に伴い普及が進んでいます。
  - **特徴**: 「2001:0db8:85a3:0000:0000:8a2e:0370:7334」のような形式で表現される。
通信安全性が向上し、高速通信が可能になる。

#### 2. MACアドレス

- **説明**: 「Media Access Control address」の略
MACアドレスは、ネットワークインターフェースカード（NIC）に割り当てられる物理的なアドレスで、デバイスを一意に識別します。通常、製造時に固定されています。
LANやインターネットでのイーサネット通信で利用されています。
通信データのヘッダー部分に「送信先MACアドレス」と「送信元MACアドレス」を格納することで宛先や戻し先を確定しています。
MACアドレスが無いと通信ができなくなります。
- **特徴**: 「00:1A:2B:3C:4D:5E」のような形式で、ネットワーク上の各デバイスをユニークに特定します。
- **用途**: デバイスレベルでの通信の識別。

---

#### 総括
IPアドレスはネットワーク間の通信、MACアドレスはデバイス間の通信においてそれぞれ重要な役割を果たします。これらを理解することで、ネットワークトラブルシューティングや設定の効率が上がります。
タイムゾーンの変換について

### 事前知識
> UNIX時間（ユニックスじかん）またはUNIX時刻（ユニックスじこく、UNIX time（ユニックスタイム）、POSIX time（ポジックスタイム））とはコンピューターシステム上での時刻表現の一種。協定世界時 (UTC) での1970年1月1日午前0時0分0秒（UNIXエポック）から形式的な経過秒数として表される。（wiki引用）

Unix時刻とは実際にどういったものなのか、例を出します
2024年1月1日9:00(JST) と
2024年1月1日0:00(UTC) はUnix時間で表すと
「1704067200」
になります。

### Unix時間
上記で解説しましたが、
2024年1月1日9:00(JST) と2024年1月1日0:00(UTC) は
「1704067200」という整数です。
つまり2024年1月1日9:00(JST) と2024年1月1日0:00(UTC)の、
実体は全く同じとなります。
UNIX時間は不変なもので、それをどこのタイムゾーンから参照しているに過ぎないのです。


### タイムゾーンとは
タイムゾーンとは地球上の異なる地域における標準時刻を指します。地球は24のタイムゾーンに分割されており、各タイムゾーンはおおよそ経度15度ごとに設定されています。

### ±９hしてはいけない理由
先ほど2024年1月1日9:00(JST) と2024年1月1日0:00(UTC)の実体は「1704067200」と解説しました。
ここで直接±９hの処理を行うと「1704067200」(UNIX時間)に変更を行うことになります。
そうです！不変なUNIX時間を変更していることになります。

### ではどうするか
タイムゾーンを変更しましょう。
例えばPythonのライブラリを使うと
``` py
from datetime import datetime
import pytz

# UTCでのdatetimeオブジェクトを作成
utc_time = datetime(2024, 1, 1, 0, 0, 0, tzinfo=pytz.utc)
print(f"UTC: {utc_time}")

# 日本標準時（JST）のタイムゾーンを取得
jst = pytz.timezone('Asia/Tokyo')

# JSTに変換
jst_time = utc_time.astimezone(jst)
print(f"JST: {jst_time}")
```
以下が結果です。
```
UTC time: 2024-01-01 00:00:00+00:00
JST time: 2024-01-01 09:00:00+09:00
```
timedeltaを使用する場合
``` py
import datetime

date_str = "2024-01-01 00:00:00"
dt = datetime.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
# UTCからJSTへのオフセットを計算 (JSTはUTC+9時間)
offset = datetime.timedelta(hours=9)
# オフセットを適用してJST時間を計算
dt_jst = dt + offset
# 文字列として出力
print("JST time: " + dt_jst.strftime('%Y-%m-%d %H:%M:%S'))
```
以下が結果
```
JST time: 2024-01-01 09:00:00
```
+9時間しているように見えますがタイムゾーンの時差を指定しているだけなのでUNIX時間は変わりません。

### まとめ
UNIX時間を変更することはやめましょう。
タイムゾーンを変更しましょう。

### 余談
GCPでは時間がUTCで表示されます。
これはUTCで時間を持っているわけでなく、持っているのはあくまでUnix時間でそれをUTCで表示しているだけです。
UTCで持っている　は
はニュアンスが違います。
UTCで表示しているだけです。
メーリングリストを届けるための工夫

# 背景

チャットベースのコミュニケーションが増えていますが、メーリングリストをはじめとしたメールベースのコミュニケーションも残っています。
プライベートでメーリングリストを運用する時、メールが届かないことがあると相談されることが多いです。
メーリングリストのヘルプだけでは分からないことも多いですので、これまでの調査結果をまとめてみました。

メールが届かないというのは2種類あり、対策が少し違うように思っています。
- 携帯アドレスにメールが届かない
- 携帯アドレス以外の特定のドメインにメールが届かない


# 前提知識

- SPF[^1][^2]
- DKIM[^1][^3]
- DMARC[^1]


# メーリングリストを届けるための工夫

## メーリングリストサービスでSPF・DKIMを設定する

経験的に、受信者が迷惑メール対策を設定している携帯アドレスの場合、この設定がされていなければ弾かれてしまうようです。
最近のメーリングリストサービスであれば、この設定は有効になっているか、設定画面で設定できます。

## Fromがメーリングリストのアドレスになるようにする

①SPF・DKIMがPASSしていても、Fromアドレスと送信元サーバのドメインが一致していない場合、経験的に、携帯アドレスの場合は弾かれてしまうようです。

②最近はDMARCの設定が普及が進んでいます。Fromとメーリングリストのドメインが異なる場合、DMARC認証がPASSする必要があります。
Fromとメーリングリストのドメインが異なる場合、SPF・DKIMがPASSしていても、DMARC認証がFAILになってしまいます。
DMARC認証がFAILした場合、From側のDMARC認証失敗時の挙動がQUARANTINEやREJECTとなっていれば、受け取り側のメールサービスによっては弾かれてしまいます。[^4]

最もシンプルな対策は、Fromがメーリングリストのアドレスになるようにすることだと思います。

一応ARC[^5]の仕組みを使ってDMARC=PASSにすることはできますが、現時点では仕様通りでも誤ってDMARC=FAILになってしまうこともある[^6]など正しい運用は難しいようです。①の問題もあるため、個人的にはFromとメーリングリストのアドレスを一致させるのがシンプルで良いと思います。


# 解決方法

今のところ、有名無料メーリングリストサービスで①を満たしているのはらくらく連絡網くらいだと思いますが、らくらく連絡網は2025年3月にサービス終了してしまいます。[^7]
解決方法の一つは、Webホスティングサービスについてくるメーリングリストサービスを使うというものです。この中でFromがメーリングリストのアドレスになる設定ができるものと契約して使うというものになります。


[^1]: https://mailmarketinglab.jp/about-dmarc/
[^2]: https://salt.iajapan.org/wpmu/anti_spam/admin/tech/explanation/spf/
[^3]: https://salt.iajapan.org/wpmu/anti_spam/admin/tech/explanation/dkim/
[^4]: 現時点ではGmailやYahooメールは受け取れますが、Microsoftは受け取れないようです。
[^5]: https://blog.nflabs.jp/entry/2024/05/16/093000
[^6]: https://happynap.net/arc-troubleshoot/ Google groupsだとうまくARCでDMARC設定できている。
[^7]: https://www.ra9.jp/news/2992.html
回転する質点の衝突について

X (Twitter) に投稿した以下の内容について。


https://x.com/nanbuwks/status/1838039177453273503




# 環境

質点の実験をしようとして、質点の代わりにビー玉を使用してみました。

このビー玉はダイソーで購入した直径 24.8mm のものでした。直径は実測した値ですが、0.1mm〜0.2mm 程度のばらつきがあります。
質量は測っていませんが、体積が約$ 10cm^3$ 、ガラスの比重$ 2.5$ の数字から、$25g $程度と推測できます。

# 運動エネルギーの計算



秒速$ 1m/s $とすると、運動エネルギーは $  3.1 \times 10^-4 J $ 。
式に直すと

$ \frac{1}{2}mv^2  $ ですね。半径rと密度ρを入れた式にすると、

$ \frac{1}{2}(4/3πr^3ρ) $

回転のエネルギーがあります。
慣性モーメント $ I $  とすると運動エネルギーは
$ \frac{1}{2} Iω^2$ で、球の慣性モーメント $ 2/5 m r^2 $ をあてはめると

$ \frac{1}{5} mr^2ω^2 $


速度 $ v $ で転がる場合の角速度 $ ω = v/ r$  なので、

$ \frac{1}{5} mv^2 $ 


運動エネルギーは直進分のエネルギーの40%で、これは $ r$  や $  ρ$  に変わらず決まった比率ということになります。

衝突時に 直進分のエネルギーが全て青玉に伝わり、回転分のエネルギーが白玉に全て残ったとすると、そこから白玉の回転エネルギーのうち 5/7 が白玉の前進力に変化するので

$ 1/7 mv^2 $ が前進する運動エネルギーに変換、これにより獲得する 衝突後の速度 $ v'$  は 

```math
\displaylines{

 1/2 mv'^2 = 1/7 mv^2  \\
 
 v'^2 = 2/7 v^2  \\

 v' = \sqrt{2/7} v  \\

 v' = 0.53 v  
 }
 
```

となります。


弾性衝突しても半分ぐらいの速度がなお残ることになりますね。
実際は衝突時に回転エネルギーから変換された直進運動エネルギーも青玉にある程度は移動するでしょうけれども、
少なからぬ運動量が残るだろうと予想されます。
BigQueryを使用してCSVデータを集計する

### はじめに
pandasで生徒の点数のデータフレームを作成しCSVファイルへ変換を行いGCSへアップロードします。
その後BigQueryからGCSのCSVファイルを読み込み平均点を算出してみます。

### GCSへCSVファイルのアップロード
sampleデータを作成し、CSVファイルをGCSにアップロードします。
まず、GCSへ接続するために必要なPythonライブラリをインストールします。
```py
pip3 install google-cloud-storage
```
pandasで生徒のテストの点数を作成します。
```py
import pandas as pd

# サンプルデータの作成
data = {
    'Student': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
    'Math': [88, 92, 75, 90, 85],
    'Science': [95, 85, 80, 70, 90],
    'English': [78, 89, 85, 95, 92]
}
# データをDataFrameに変換
df = pd.DataFrame(data)
# CSVファイルに保存
df.to_csv('ファイル名.csv', index=False)
```
サービスアカウントキーのパスを指定します。
キーはIAMから作成しましょう。
```py
import os

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'サービスアカウントキー.json'
```

GCSへCSVファイルをアップロード
```py
from google.cloud import storage

def upload_to_gcs(bucket_name, source_file_name):
    # GCSクライアントを作成
    storage_client = storage.Client()
    # 指定したバケットを取得
    bucket = storage_client.bucket(bucket_name)
    # ローカルファイル名をそのままGCSのオブジェクト名として使用
    destination_blob_name = os.path.basename(source_file_name)
    # アップロードするファイルを指定
    blob = bucket.blob(destination_blob_name)
    # ファイルをGCSへアップロード
    blob.upload_from_filename(source_file_name)
    print(f"アップロードが完了しました！！")

bucket_name = 'GCSのバケット名'
source_file_name = 'アップロードするファイルパス'

upload_to_gcs(bucket_name, source_file_name)
```
ファイルがGCSに保存されていますね。
テスト用に３ファイル作成しています。
![スクリーンショット 2024-08-16 2.02.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576208/176e9cf0-6928-27bd-5c6e-c5a30a11890a.png)

各ファイルの中身は以下のようになります。
![スクリーンショット 2024-08-15 23.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576208/b6687440-ce59-bf3e-168f-5bdd939168fe.png)

![スクリーンショット 2024-08-15 23.40.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576208/57d8cc62-0fae-7876-efed-f3292444fe2d.png)

![スクリーンショット 2024-08-15 23.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576208/21855edf-14d0-e8d2-7ce2-0633d8a7e75c.png)

### BigQueryで計算
GCSにデータができたのでBigQueryから生徒のテストの平均点を求めてみましょう。
BigQueryへ接続するために必要なPythonライブラリをインストールします。
```py
pip3 install google-cloud-bigquery pandas
```

```py
from google.cloud import bigquery

# BigQueryクライアントを作成
bigquery_client = bigquery.Client()
# クエリを定義
query = """
    SELECT
        Student,
        ROUND(AVG(Math), 2) AS avg_math,
        ROUND(AVG(Science), 2) AS avg_science,
        ROUND(AVG(English), 2) AS avg_english
    FROM
        `tenacious-lore-401901.sample_data.test_point`
    GROUP BY
        Student
    ORDER BY
        Student
"""
# クエリを実行し、結果をDataFrameに保存
df = bigquery_client.query(query).to_dataframe()
```
クエリの結果が以下の通りとなります。
各教科の平均点数を求めることができました。
![スクリーンショット 2024-08-16 11.44.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576208/8de876a3-13ae-0d9c-475b-7530de4c75ac.png)

#### 参照
- BigQuery
https://cloud.google.com/bigquery?hl=ja
- GCS
https://cloud.google.com/storage/docs/introduction?hl=ja
個人的忘れがちLinuxコマンド

### はじめに
毎回忘れるコマンドを備忘録として記します。


ファイルのコピー
```shell-session
cp (コピー元 コピー先)
```


ファイルの移動
```shell-session
mv （移動元 移動先）
```
ファイルへのアクセス権限の変更
```shell-session
chmod (パーミッション ファイル名)
```

```permission denied```のエラーが出たら大体こいつのせい
以下アクセス件の一覧
|アクセス権|数値|説明|
|----|---|----|
|---|0|読み込み書き込み不可|
|--x|1|実行のみ|
|-w-|2|書き込みのみ|
|-wx|3|	書き込み実行のみ|
|r--|4|読み込みのみ|
|r-x|5|読み込み実行のみ|
|rw-|6|読み込み書き込みのみ|
|rwx|7|読み込み書き込み実行ができる|

例として
```$ chmod 750 test.txt```
とすると、test.txtのファイルに対して
「所有者」(7)は**読み込み書き込み実行ができる**
「グループ」(5)は**読み込み実行のみ**
「その他のユーザ」(0)は**読み込み書き込み不可**
の権限を付与する。


### Git操作
**リモートブランチのチェックアウト**
```shell-session
git checkout -b ローカルブランチ origin/リモートブランチ
```
**ローカルブランチ名の変更**
```shell-session
git branch -m 古いブランチ名 新しいブランチ名
```
**Git設定値確認**
```shell-session
git config --list
```
**ユーザ名変更**
```shell-session
git config --global user.name "ユーザ名"
```
**メールアドレス変更**
```shell-session
git config --global user.email "メールアドレス"
```
**ローカルブランチ削除**
```shell-session
git branch -d (ブランチ名)
```
**リモートリポジトリの確認**
```shell-session
git remote -v
```
bibでdoiをコメントアウトする


# bibでdoiをコメントアウトする

LaTeX では `%` を使って行をコメントアウトできますが、BibTeX では同じ方法でコメントアウトするとエラーが発生する場合があります。特に、BibTeX のエントリ内でフィールドをコメントアウトするときに問題が起こりやすいです。

例えば、以下のような `@article` エントリがあります。

```bibtex
@article{sample2024example,
    title={A Sample Paper on Additive Manufacturing Design Methods},
    author={Doe, John and Smith, Alice and Brown, Michael and Davis, Jane},
    journal={Journal of Sample Science},
    volume={15},
    number={3},
    pages={150--162},
    year={2024},
    doi={10.1234/sample-doi-2024},
    publisher={Example Publisher},
}
```

このエントリで `doi` フィールドをコメントアウトしたいときに、LaTeX のように `%` を使うとエラーが発生します。

## 解決策：`doi` を `memo` に置換

この問題を回避するために、`doi=` の部分を `memo=` に置換する方法があります。これにより、BibTeX は `memo` フィールドを無視するため、エラーが発生しません。

以下のように修正します。

```bibtex
@article{sample2024example,
    title={A Sample Paper on Additive Manufacturing Design Methods},
    author={Doe, John and Smith, Alice and Brown, Michael and Davis, Jane},
    journal={Journal of Sample Science},
    volume={15},
    number={3},
    pages={150--162},
    year={2024},
    memo={10.1234/sample-doi-2024},
    publisher={Example Publisher},
}
```

こうすることで、`doi` フィールドを無視することができます。もし `doi` フィールドを再び有効にしたい場合は、`memo=` を元の `doi=` に戻せばOKです。

---

これで、BibTeX において `doi` フィールドのエラーを回避できるようになります。
docker コマンド備忘録

```
docker image pull ubuntu:20.04
```
ローカルマシンに存在するイメージのダウンロード

```
docker image ls
```
ローカルマシンに存在するイメージの一覧を表示する

```
docker image rm ubuntu
```
ローカルマシンに存在するイメージを削除する

```
docker container run hello-world
```

```
docker container run nginx
```
イメージからコンテナを作成し起動

```
docker container ls
```
ローカルマシンに存在するコンテナ一覧を表示

```
docker container ls -a
```
ローカルマシンに存在するコンテナ一覧を表示、起動していないコンテナも表示

```
docker container stop [コンテナ名]
```
ローカルマシンに存在するコンテナを停止する

```
docker container restart [コンテナ名]
```
ローカルマシンに存在するコンテナをupさせる

```
docker container rm [コンテナ名]
```
ローカルマシンに存在するコンテナを削除する


bashとは？
LinuxやMacなどのUnix系のOSで利用されているシェルの一種
カーネル→OSのコア部分、ファイルを開いたり書き込んだりはカーネルがやっている
けど、ユーザーはカーネルを直接操作しているわけではない。
カーネルは機械語だから、「ファイル開いて」みたいなこと言っても理解しないので
そこで役に立つのがシェル。シェルは翻訳家みたいなことをしてくれるもの
bashはシェルの一種なので、カーネルに対する操作をやってくれる

pwdというコマンドで作業しているディレクトリを表示してくれるが
これもシェルに指示をして翻訳、カーネルが行動を起こすようになっている


```
docker container run -it ubuntu:20.04
```
コンテナを作成して、作成したコンテナにログインする

```
docker image inspect ubuntu
```
イメージの詳細情報を表示する

```
docker container run -it ubuntu [pwd]
```
コンテナ起動して任意のコマンドを実行させるコマンド

```
docker container exec [コンテナ名] [実行したいコマンド]
```
Up状態のコンテナに任意のコマンドを実行させるコマンド

```
docker container run -p [ホスト側のポート]:[コンテナ側のポート] [イメージ]
```
ホストとコンテナのポートを紐づける

```
docker exec -it [コンテナID] /bin/bash
```
コンテナにログイン

```
docker network ls
```
dockerネットワークを表示


```
docker network inspect [bridge]
```
ドッカーネットワークの詳細を確認

```
docker network create [ブリッジネットワーク名]
```
任意の名前のブリッジネットワークを作成

```
docker container run -itd--name [コンテナ名] --network [ブリッジネットワーク名] [イメージ]
```
指定したネットワークに接続したコンテナを起動する

```
docker container run -itd --rm --name my-nginx-2 --network my-net nginx
```
オプション：-itd→-dオプションでバックグラウンドで動く

```
docker network rm [ブリッジネットワーク名]
```
作成したブリッジネットワークの削除
CloudFrontとは

## 勉強前のイメージ
エッジロケーションとかいうのがキーワード
世界規模でコンテンツを配信したいときには候補に挙がるサービス
（実際にどんな機能があるのか、アーキの候補までは浮かばない）

## 結論
世界規模で配信でき、配信元のオリジンサーバ周りではいくつかのアーキ候補がある
★AWS SAA(C03版）では人気者なサービスなので要チェック！

### まずエッジロケーションとは
・エッジロケーションというのは一言でいうとキャッシュサーバのこと
・ユーザはまず、このエッジロケーションに対してアクセスし次の順序でコンテンツを取得する
①エッジロケーションにリクエスト対象のコンテンツが存在していればそれを取得しレスポンスとして返す
②エッジロケーションになければ次はエッジロケーションの背後の”リージョン別エッジキャッシュ”にコンテンツを探しに行く。コンテンツがあればそれをレスポンスとして返す
③ ②でもなければリージョン別エッジキャッシュ背後のオリジンサーバにコンテンツを取りに行く

### よく候補となるオリジンサーバ
→これはコンテンツがいつアクセスしても内容が一定の静的なものか、アクセスごとにコンテンツを構成して返す動的なものかで別れる

静的コンテンツの場合：S3（画像とかHTMLファイルとかを表示したいとき）
動的コンテンツの場合：EC2などのアプリケーションサーバ（ELB配下に配置する等）


### CloudFrontの機能
・接続形式はHTTPSが基本
(URLをカスタムすることも可能、この際にHTTPS通信をさせる場合にはACMで証明書を管理)

・特定の地域にのみコンテンツの取得を許可することが可能

・接続時に機密性の高い情報を扱う場合にはフィールドレベル暗号化という機能を使えば通信上やり取りする情報を外界から守ることができる、、らしい
（単なるHTTPSと何が違うんだ・・）

・オリジンサーバから取得したコンテンツをキャッシュしておく期間を決めて利用する
（cache-controllのageディレクティブにて設定）

※S3でコンテンツ配信する際にはパブリックアクセスを許可させる必要があるが、この際にはcloudfrontのOAI(Origin Access Identity）というアクセス制御機能を用いて特定のユーザにのみ、特定のコンテンツを配信することが可能
OpenAI APIのモデル指定：最適な選択基準と応用ガイド

![NO-OpenAI API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877124/0a5fd36d-41b2-bb61-1405-e3decfe9ca8d.png)


近年、人工知能（AI）の進化は目覚ましく、特にOpenAIのAPIを活用したAIモデルは、世界中でさまざまな分野に影響を与えています。OpenAIは、特定のタスクに応じてモデルを指定することが可能であり、その選択はユーザーにとって非常に重要な意思決定となります。本稿では、OpenAI APIのモデル指定に関する課題と、その選択基準について詳しく考察し、ITやAI分野での応用可能性について論じます。

## 1. モデル指定の意義
OpenAIのAPIを活用する際、利用者はさまざまなモデルから選択することができます。これらのモデルは、自然言語処理、コード生成、画像認識、推論など、さまざまなタスクに対応するように設計されています。代表的なモデルには、GPT-3、GPT-4、そして最近発表されたo1などがあります。各モデルの性能や特性は異なるため、利用者はプロジェクトの目的や予算、性能要件に応じて最適なモデルを選択する必要があります。

モデル指定の意義は、最適なモデルを選ぶことでプロジェクトの効率を最大化できる点にあります。適切なモデルを選択することで、無駄なコストを抑え、より迅速で正確な結果を得ることが可能となります。例えば、非常に精度が求められる医療分野や、金融取引におけるリスク管理では、高精度の推論モデルが不可欠です。一方、日常的なカスタマーサービスの自動応答システムでは、より軽量でコスト効率の良いモデルが適しています。

## 2. 各モデルの特徴と用途

### OpenAIが提供する主要なモデルには、以下のような特徴があります：

- **GPT-3**：多くのタスクに対応可能な汎用モデル。自然言語生成や文章要約、対話システムなど、幅広い用途で利用されています。大規模なデータセットで学習されているため、一般的な知識に基づく回答が得られるのが特徴です。
- **GPT-4**：GPT-3の改良版で、より複雑な問題にも対応可能。特に、推論や論理的な問題解決能力が向上しています。高い精度が求められる分野で利用され、特に研究開発や高度なデータ解析に適しています。
- **o1**：最新のモデルであり、強化学習を取り入れた次世代モデル。推論能力に優れており、複雑なタスクやコーディングタスクで顕著な成果を発揮します。特に、段階的な問題解決やコード生成に強みを持ち、精度の高い回答が得られる点が特徴です。


各モデルの選択は、利用するタスクの複雑さや要求精度によって異なります。例えば、GPT-3は汎用性が高く、多くの場面で利用される一方、より精度を求められる場面ではGPT-4やo1が適しています。

## 3. モデル指定の選択基準

### モデル指定を行う際、利用者が考慮すべきポイントはいくつかあります。

- **コストパフォーマンス**：APIの利用にはコストが発生します。高性能なモデルほどコストも高くなるため、プロジェクトの予算に応じて適切なモデルを選択することが重要です。例えば、簡単なタスクに対して高性能なモデルを選ぶと、コストが無駄になる可能性があります。
- **タスクの複雑さ**：タスクが単純であれば、軽量なモデルで十分ですが、複雑な推論や高精度な結果が必要な場合には、より高度なモデルを選択する必要があります。医療や金融など、正確さが要求される場面では、GPT-4やo1のような精度の高いモデルが推奨されます。
- **処理速度と応答時間**：リアルタイム性が求められるアプリケーションでは、応答時間が重要な要素となります。高性能なモデルは処理が遅くなる場合があるため、速度が重視される場合は軽量なモデルを選択するのが適切です。
- **専門性の必要度**：特定の分野に特化した知識が必要な場合、その分野に強いモデルを選択することが有効です。例えば、特定の業界に特化したデータを学習したモデルがあれば、それを指定することでより良い結果が得られるでしょう。

## 4. モデル指定の未来
今後、AIモデルはさらに進化し、より複雑なタスクに対応できるようになるでしょう。特に、分野ごとに特化したモデルが増えることで、モデル指定の選択肢はますます広がると考えられます。OpenAIは常に新しいモデルを開発しており、これらのモデルがどのように進化し、どのように現実世界の問題を解決していくかが注目されています。

また、ユーザーが自分自身でモデルをカスタマイズし、特定のニーズに合わせて最適化することも一般的になると予想されます。これにより、AIの活用範囲はさらに広がり、多様なニーズに対応できるようになるでしょう。

## 結論
OpenAI APIにおけるモデル指定は、プロジェクトの成功に直結する重要な決定です。各モデルの特徴や用途を理解し、コストや性能を考慮した上で最適なモデルを選択することで、プロジェクトの効率を最大限に引き出すことができます。今後のモデルの進化にも期待しつつ、現状の最適な選択を行うことが求められます。

このように、OpenAI APIのモデル指定は、単なる技術的選択だけでなく、プロジェクト全体の成功に大きな影響を与える重要な要素であることがわかります。

**今回は以上になります！
最後まで見ていただきありがとうございました！
では、また次の記事で～！**
TypeScriptでの非同期処理とクラス設計に学ぶ実践的プログラミング


#### 概要
この記事では、TypeScriptを使った非同期処理、クラス設計、データベース操作を解説します。特にPromiseを用いた非同期処理の流れ、アロー関数の使い方、Jestによるモック関数の作成に焦点を当て、実際の開発で役立つノウハウを紹介します。progate pathにおける自身の学習の記録として記事を作成していますので、内容に偏りがあったり、一貫性がないことも多いですが、ご容赦ください。

---

### 1. **非同期処理の基礎: Promise と async/await**

まずは、非同期処理の重要性と、その基礎である`Promise`、`async/await`の使い方について説明します。

#### 例: 非同期処理の実装例

```typescript
const fetchData = async (url: string): Promise<void> => {
  try {
    const response = await fetch(url);
    const data = await response.json();
    console.log('データ取得成功:', data);
  } catch (error) {
    console.error('エラー:', error);
  }
};
```

`async` 関数は `await` を使い、非同期処理が完了するまで待機します。これにより、非同期操作の結果を次の処理に安全に渡せます。

---

### 2. **クラス設計とデータベース操作**

クラス設計はコードの再利用性を高め、データベースとのインタラクションをオブジェクト指向で整理できます。以下に、投稿データを扱う `Post` クラスを例示します。

#### Postクラスの設計

```typescript
export class Post {
  constructor(public content: string) {}

  async save(): Promise<void> {
    const db = await databaseManager.getInstance();
    const { lastID } = await db.run(
      `INSERT INTO posts (content) VALUES ($content)`,
      { $content: this.content }
    );
    this.id = lastID;
  }

  static async find(postId: number): Promise<Post | undefined> {
    const db = await databaseManager.getInstance();
    const postRawData = await db.get<PostRawDataWithId>(
      "SELECT id, content FROM posts WHERE id=?",
      [postId]
    );
    return postRawData && new Post(postRawData.content);
  }
}
```

この `Post` クラスでは、投稿の保存、検索機能をシンプルに実装しています。`save` メソッドでデータを挿入し、`find` メソッドでデータベースから投稿を取得します。

---

### 3. **アロー関数を使った`this` の扱い**

JavaScript では、`this` の扱いに注意が必要です。特にイベントリスナーやコールバック関数内で `this` の参照が意図しないものに変わることがあります。アロー関数を使うと、`this` が定義時にバインドされ、予期しない振る舞いを避けられます。

#### 例: アロー関数の使用

```typescript
class MyClass {
  name = "MyClass";

  // アロー関数でのメソッド定義
  arrowMethod = () => {
    console.log(this.name); // 常に "MyClass"
  }
}
```

---

### 4. **Jestによるテストのモック**

テストを効率的に行うには、外部のAPIやデータベースの依存を排除するためにモックを使うことが重要です。Jest では、`jest.fn().mockImplementation()` を使ってモック関数を定義できます。

#### モック関数の例

```typescript
const fetchPost = jest.fn().mockImplementation((id: number) => {
  return { id, content: `Post content for id ${id}` };
});
```

このモック関数を使用することで、APIを呼び出さずに、期待通りのデータを返すことができます。

---

### まとめ

この記事では、TypeScriptにおける非同期処理、クラス設計、アロー関数、そしてJestを使ったテストモックの使い方について解説しました。今後も自身の学習の記録を記事にしていきたいと思います。
【OpenAI o1】でのPromptの記述についてわかったこと。


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

　今回は、【OpenAI o1】でのPromptの記述について、わかったことを報告します。

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

　【OpenAI o1】は、
　　まだ一般公開されて
　　　間もないモデルです。

　また、新しいモデルのため、
　　GPTのように
　　　過去のモデルのPrompt知識が
　　　　継承できるものでも
　　　　　ありません。

　つまり、
　　ひとつずつ検証して
　　　積み重ねなければなりません。
***
　まず第一に
　【OpenAI o1】は
　　　思考？するモデルです。

　そのため、
　　よく考えて
　　　答えを導き出します。

　理系のことならば
　　正答率は高い、そうです。
　　　そっち系、やらない人なので😅

　ですが、
　　“考える”ということは
　　　“推測する”ということでも
　　　　あります。

　これは憶測で
　　考えてしまうことになります。

　つまり、
　　ハルシネーションを
　　　引き起こすわけです。

　私がよく新しいモデルに
　　試すのが、“スマホ熱中症”です。
　　　これは流行語で、
　　　　人間の身体の病気ではなく、
　　　　　スマホが熱くなって
　　　　　　機能が低下することを
　　　　　　　指す言葉です。

　しかし、
　　GPT-4oも【OpenAI o1】も
　　　既知のものとして
　　　　回答してきます。

　本当に知っているのか
　　推測なのか、
　　　こちらにはわかりません。

　そこで
　　【OpenAI o1】と相談して、
　　　できるだけ正答を出力する
　　　　Promptを作成しました。

```Text:正しい知識を求めるPrompt
『✘✘✘』について教えてください。
公式な情報源に基づく回答を求めます。
推測や解釈を行わないでください。
“ただし”などの推測をしないでください。
回答があるならば、情報の出典を記載してください。
回答がない場合、その旨を簡単に教えてください。
```

　この✘✘✘に知りたいことを
　　書き入れて、送信してください。

　ごらんのとおり、
　　単に正答を知りたいだけなのに
　　　五行も追加しなければ
　　　　なりませんでした😅

　実際に使ってみます。
***
***●user***
『スマホ熱中症』について教えてください。
公式な情報源に基づく回答を求めます。
推測や解釈を行わないでください。
“ただし”などの推測をしないでください。
回答があるならば、情報の出典を記載してください。
回答がない場合、その旨を簡単に教えてください。

***o1-mini***
「スマホ熱中症」について、私の知識（2023年10月時点）では、公式な情報源からの具体的な定義や詳細な情報は確認できませんでした。この用語が公式な健康機関や政府機関によって使用されているという情報は見当たりません。

もし新しい情報や公式な発表があった場合は、信頼できる公式ウェブサイトや公的機関の発表をご参照ください。

***●user***
『スマホ』について教えてください。
（以下同文）

***o1-mini***
「スマホ」とは、「スマートフォン」の略称であり、携帯電話としての基本的な通信機能に加え、インターネットアクセス、アプリケーションの利用、カメラ機能など多岐にわたる機能を備えたモバイル端末です。総務省が発行する「情報通信白書」（2023年）によると、日本におけるスマートフォンの普及率は高く、日常生活やビジネスにおいて重要な役割を果たしています。

**出典:**
- 総務省「情報通信白書」2023年版  
  [総務省 情報通信白書](URL)
***

　ちなみに、
　　URLが青色で示されますが
　　　ジャンプしませんし、
　　　　URLでググっても
　　　　　ページはありませんでした。

　情報通信白書はありますので、
　　古いURLなのかもしれません。

　そして、このとおり、
　　出力量は限定されます。

　必要最低限の
　　情報ですね。

　ChatGPTの初期も
　　長々と出力されていました。
　　　今後は同じように
　　　　出力が抑えられるように
　　　　　なるかもしれませんね。

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

　今回は、ここまで。
【Django】404エラー発生時の対処について

# はじめに
「PythonDjango4 超入門」の学習中、404エラーが発生してハマってしまいました・・・
解決してみれば単純なケアレスミスなんですが、書籍の通りに構築すると絶対に発生するようになっているので、備忘録＆情報共有のために記事にします。

# 前提条件
以下の条件でURLを開くと、404エラーが発生します。
※書籍の記述通り。

①「http://localhost:8000/hello/create 」にアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665882/31b079b7-573d-d7b7-ef20-7da6f4f06a33.png)

②ルーティングは以下設定で実装。
~~~python:<プロジェクト>\urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', include('hello.urls')),
]
~~~
~~~python:Hello\urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('create', views.create, name='create'),
]
~~~

# 解決方法
結論から言うと、「<アプリ>/urls.py」のルーティング記法にミスがありました。
path関数の第一引数は、最後に「__/(スラッシュ)__」を入れる必要があります。
正しい記述法は以下になります。

~~~python:Hello\urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('create/', views.create, name='create'),
]
~~~

修正してサーバを再起動すれば、「hello/create」に正しくアクセスできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665882/6faf0528-4627-42fe-b7ee-54bf9c07fdfa.png)
自分のWebサイトを作った話

この夏にWeb初心者ですが自分のWebサイトを作ったので、その話をしようと思います。

まず思ったのは、<span style="font-size:2rem">**自分デザインセンスなさすぎ**。</span>

OGPもロゴも手抜き感満載だし、機会があれば誰かに頼んで作ってもらおうかな～とか思ってます。

↓ロゴ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561003/f0137f9b-270f-4b01-5ec0-4b3b9ebb9f8f.png" width="35%" alt="" />

↓OGP画像
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561003/9cbcdb3e-a84b-6f01-e3f0-26a40dee087e.png" width="75%" alt="" />

# 技術的な話

## 使用した技術とかライブラリとか

- Typescript
- React/Next.js
- tsParticles

Vue？なにそれ。知らない子だね...

それはさておき、このtsParticlesとか言う背景に幾何学模様を描くライブラリ、めちゃめちゃかっこいい。多分particles.jsっていう素jsライブラリのNode.jsバージョン的な感じなのかな？

ぜひ僕のサイトを見て確かめてほしい。最高。

ただ、なぜか僕の環境だと普通にやるとエラーが出てしまったので、Deprecatedなライブラリをインストールする必要が出てしまいました。悲しい。

あと、自分はWeb初心者なのでよくわかりませんが、ここまで小規模なサイトの場合あんまりNext.js使う旨味がないのかな～とか考えてます。しらんけど。
Vue？なにそれ。知らない子だね...
少なくともAtomic Designはやる必要なかったかなと。

過去の自分：Atomic Design? なんかトレンドらしい... とりまやってみるか\\( ᐙ )/

普通にそのせいでめちゃくちゃ複雑なコードになったんですが！？

あと、TailwindCSSはなんか僕には使いこなせなかった。
一応素のCSSは殆ど使わずにTailwindだけでつくったんですが、無事保守性がごみかすになりました。    

## その他諸々

実は実際にコード書く前にFigmaでデザインを作っていたりしたのですが、なんか結局ぜんぜん違うデザインになりました。

自分には使いこなせないようです。

あと、Figmaで作ったデザインをコードに書き出すプラグイン的なやつを使ったら、レイアウトがぐちゃぐちゃになりました。もうちょっと精度が良くなったら改めて試すかも...？

あと、ブログ欄が準備中になってますが、書くか書かないかは主のやる気次第なので、一生準備中かも。期待してた方々ごめんな(´◡`)(自信過剰)     

# 自分のサイトのリンク

[yagarashi.com](https://yagarashi.com)

今までさんざんdisってきた自分のサイトですが、なんやかんやで力作なので、皆さんぜひ見てほしいです！！！！！！
Windowsのサービス一覧を出すコマンド

トリガー開始とか遅延開始とかの情報がどこにあるのか調べてみたらレジストリにあるらしいです。

https://qiita.com/Mr-K/items/0ab787135eb4ec3b3a1c

個人的にはアルファベットの方が後で加工しやすいので、コピペで使える日本語無しバージョンを用意しました。

```powershell
function Get-CompleteService {
    $triggers = Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services" |
        Where-Object { $_.GetSubkeyNames().Contains("TriggerInfo") } |
        ForEach-Object { $_.Name.Split("\")[-1] }

    $startOption = @{ 01 = "(Trigger)"; 10 = "(DelayedStart)"; 11 = "(DelayedStart,Trigger)" }

    return Get-CimInstance -ClassName Win32_Service | Select-Object @(
        @{ n = "DisplayName"; e = { $_.DisplayName } }
        @{ n = "Name";        e = { $_.Name } }
        @{ n = "StartType";   e = { $_.StartMode + $startOption[10 * ($_.StartMode -eq "Auto" -and $_.DelayedAutoStart) + $triggers.Contains($_.Name)] } }
        @{ n = "Status";      e = { $_.State } }
    )
}
```
AppleシリコンのMacでUTMを使用してKali Linuxの仮想環境を構築する（シンプルver）

# はじめに
[7日間でハッキングをはじめる本](https://amzn.asia/d/0zrt6vm)のMacユーザー向け記事です。
※[先日投稿した記事](https://qiita.com/matz1ppei/items/6c79f0553fb90210e200)よりも簡単にできる方法があったのでシェアします。

# 環境
- ハード：MacBook Air M2 2022
- ホストOS：MacOS Sonoma 14.3.1
- 仮想化ソフト：UTM 4.5.4
- ゲストOS：Kali Linux 2024.3

# 手順
## 1. UTMのインストール
[公式サイト](https://mac.getutm.app/)からダウンロードするかHomebrewでインストールする方法がありますが、今回はHomebrewを採用しました。
```bash
brew install --cask utm
```

## 2. Kali Linuxのダウンロード
インストールしたUTMを起動しトップ画面の「UTMギャラリーをブラウズ」を選択します。
![2024-09-22_KaliLinux2_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/78b31c9b-d379-7417-7680-e52f6691ca98.png)

UTMギャラリーの中から「Kali Linux」を選択します。
![2024-09-22_KaliLinux2_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/aa402203-84a2-9036-9062-014b2d40566a.png)

Kali Linuxのページが開くので「Download」ボタンを押下します。
![2024-09-22_KaliLinux2_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/40cb91c5-e235-3acd-9998-dcf2a2049dde.png)

※ダウンロードにはかなり時間がかかります（筆者の環境で４時間くらい）

## 3. Kali Linuxのログイン確認
ダウンロードした「kali-linux-2023-arm64-utm.zip」を解凍して「Kali Linux 2023.utm」ファイルをダブルクリックします。
![2024-09-22_KaliLinux2_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/7c324be4-08ef-aea7-be11-237118886ec8.png)

UTMの画面が表示されるので右上の再生ボタンを押下します。
![2024-09-22_KaliLinux2_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/2aaccf81-28aa-4a6d-eb10-ed536aecfba0.png)

Kali Linuxのログイン画面が表示されるのでUTMギャラリーの画面にあるログイン情報を入力します。

記事作成時のログイン情報
```
Username: kali
Password: kali
```

![2024-09-22_KaliLinux2_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/82bd800a-5d2d-106b-9d22-90c100ae0e22.png)

無事にログインできたら以下のようなトップページが表示されます。
![2024-09-22_KaliLinux2_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629032/e9c531f8-e681-2bb9-1d4a-298e800809f8.png)
個人開発向け、AWS NATゲートウェイのコストを削減！

## 背景
個人開発をして、３ヶ月程度たった。
売り上げなど特にない中、１ヶ月2万円弱のコストをキープするのはきつい。

![スクリーンショット 2024-09-23 10.44.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634885/2cbf8b83-6bb0-1d79-3fd4-c05c6e138942.png)

まずコストが最も高いElastic Computing Cloudを調べてみると、NatGatewayのコストがほとんどを占めている。

![スクリーンショット 2024-09-23 10.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634885/9e282a0b-6e12-d2bc-faeb-70867e66a983.png)


### NATゲートウェイとは？
プライベートサブネット内のリソースがインターネットにアクセスするために必要なもの。
NATゲートウェイって、意外と高額な請求なのね。
特に、データのアップロードやダウンロードが多いと、そのコストはさらに増加するらしい。恐ろしい。。


早速、NATゲートウェイをやめて、コストを削減しよう。

## NATゲートウェイ削除してもいいの？
個人開発でセキュリティ要件がそれほど厳しくない場合、ECS（Webサーバー）をプライベートサブネットに置いておく必要もないので、パブリックサブネットに移動することでNATゲートウェイを削除できる。

## NATゲートウェイ削除手順
- パブリックサブネットの確認・作成
  - ECSを移動する先のパブリックサブネットが存在するか確認し、なければ新しく作成。
- ECSの設定変更
  - ECSのネットワーク設定をパブリックサブネットに変更。
- NATゲートウェイの削除
  - 不要になったNATゲートウェイを削除してコストを削減。
- セキュリティグループの見直し
  - パブリックサブネットに移動した後のセキュリティグループの設定を見直し、不必要なポートが開いていないかチェック。

## 感想
６０００円程度浮いてとりあえずよかった。全体のコストの約30%に相当。
他にも削れるところないかな。。
AWS AIFベータ試験受験レポート

# はじめに
AWS Certified AI Practitioner（AIF）のベータ試験を受験しましたので、勉強した内容や所感をまとめます。
## 受験背景
昨年度、AWS認定全冠を達成し、「2024 Japan AWS All Certifications Engineers」を受賞しました。今年度、新たに3つの認定試験（DEA/AIF/MLA）が追加され、来年のAll Certにはこれらの認定も必要になると思われるため、早めに受験しました。また、昨今のAIの盛り上がりに伴い、個人的にも知識習得を目指して勉強を進めていました。さらに、ベータ試験で合格すると、AWS AI Dayで特別なステッカーがもらえるという情報もあり、受験のモチベーションになりました。

https://aws.amazon.com/jp/events/ai-day/

# AWS Certified AI Practitioner(AIF)とは
今年登場したAWS認定試験の一つで、生成AIや機械学習に関する知識が求められます。2024年9月現在、ベータ試験が実施されており、通常よりも安く受験可能です。試験は85問で、通常の試験よりも20問多いのが特徴です。また、AIF/MLAの試験には、「順序付け」「内容一致」「導入事例」という新しい設問形式が追加されています。

https://aws.amazon.com/jp/certification/certified-ai-practitioner/

# 勉強内容
**1. 試験ガイドの確認**
まずは試験ガイド（https://d1.awsstatic.com/ja_JP/training-and-certification/docs-ai-practitioner/AWS-Certified-AI-Practitioner_Exam-Guide.pdf） を確認しました。特に付録の「範囲内の AWS のサービスと機能」に記載されているサービスは一通り確認し、あまり詳しくないサービスについては調査しました。私の場合、Amazon Fraud DetectorやAWS Audit Managerがこれに該当しました。
**2. Skill Builderにて試験対策コースを受講**
Skill Builderには「Standard Exam Prep Plan: AWS Certified AI Practitioner (AIF-C01)」（https://explore.skillbuilder.aws/learn/public/learning_plan/view/2193/standard-exam-prep-plan-aws-certified-ai-practitioner-aif-c01） というコースがありますので、一通り確認しました。既に知っている内容は飛ばし読みしながら進めました。また、有料サブスクリプションの「Enhanced Exam Prep Plan: AWS Certified AI Practitioner (AIF-C01)」（https://explore.skillbuilder.aws/learn/public/learning_plan/view/2194/enhanced-exam-prep-plan-aws-certified-ai-practitioner-aif-c01） も一部利用しました。
**3. 模擬試験の実施**
無料で20問、有料で65問の模擬試験をそれぞれ実施しました。初回で正答率80％を超えたので、この時点で試験の申し込みを決定。もちろん間違えた問題については、解説を読み知識を補強しました。

# 結果
当日はテストセンターで受験。何度か利用したことのある会場だったので、特に不安なく受験できました。問題は模擬試験よりも若干難しく感じましたが、約1時間で解答を終えました。14時開始の試験で、当日の19時頃に合格のメールが届きました。
![スクリーンショット 2024-09-23 10.38.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448259/ebdfa0ee-f5a2-e01e-8847-2e4db210b2b5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448259/15cac8ac-5b27-8652-244f-71c3681e6625.png)

予想より点数が低かったです。セクション別のスコアパフォーマンスを見ると、第4分野「責任あるAIに関するガイドライン」のスコアが低かったです。実は、この分野は模擬試験でも正答率が低かったので、重点的に学習しておくべきでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448259/e2715b40-3497-17a2-3237-fe48af24821f.png)
無事に早期合格特典のEarly Adopterバッジもゲットしました。

# おわりに
AI/MLは普段の業務ではあまり触れない分野ですが、楽しく勉強できました。知識の幅が広がることで、今後の案件においても提案の幅が広がると思います。これからも分野に縛られず、知識のインプットとアウトプットを続けていきたいと思います。

# 余談
本記事はChatGPTにて校正を行ったうえで投稿しております。
未経験からエンジニアに転職して2年が経過したので振り返ってみる

エンジニアになって２年半くらいが経過してので私が初めて携わった案件で経験したことを振り返ってみようと思い記事にしてみました。

## 1. はじめに
私のバックボーンはこちらに書いているので是非読んでみてください。

https://qiita.com/kuri_kuri/items/cc9d4105d31fae2b5f5d

## 2. エンジニアとしてのスタート

初めてのプロジェクトには、ベテラン社員2人と私の3人で参画しました。
私が担当したのは、VB.NETを使用した画面開発でした。
VB.NETを勉強したことがなかったので、何もわからない状態で開発作業がスタートしました。
当時は右も左もわからないまま仕事を進めていましたが、今振り返ると「これが炎上案件か、と感じるような状況で」毎日の残業や休日対応が続き、心身ともに限界が近かったように感じます。
チームの中でうまくコミュニケーションが取れていなかったのでそもそも仕様の段階で決まっていないことが多く開発作業も全然進みませんでした。
それによってスケジュールがどんどん遅れていきました。
リリースまでには紆余曲折がありましたが、なんとかリリースにこぎつけることができました。

### ・当初の大変だったことや不安

#### 登場する用語の意味が全然分からなかったこと
最初はミーティングで飛び交う用語が全く分からず何も理解できませんでした。
業務に関するアドバイスでも分からない用語が出てくるなど本当に大変でした。
TCPやUDPが何かも分からない状況でしたが知らない言葉や単語はその場でメモしてすぐに調べるようにしていました。
また単語帳も作ってすぐ見返せるように工夫していました。
そんな環境で仕事をすることがとても不安だったことを覚えています。
この時は、楽しいよりも不安の方が大きかったです。

#### プログラミングのスキル不足でコードが書けない
自分のスキル不足で最初は全くコードが書けませんでした。
数十行の処理を書くのに何時間もかかっていました。
それ以前にどういう処理をすればやりたいことが実現できるかも思いつかなかったです。
「日本語で書けないことがプログラムで書けるはずがない」と言われたことは今も鮮明に覚えています。

#### 月80時間の残業
初めての案件でプロジェクトが全然うまく進まず本当に死ぬ気で働きました。	
80時間近い残業も3ヶ月ほど続きました。	
当時はしんどかったですが今では良い経験だったなと思えます。
これ以降、どんなに大変なプロジェクトでも、自分なら乗り越えられるという自信がつきました。

## 3. 成長の過程

### ・スキルの向上
案件を通じてコードを書いていくことでどんどん概念や仕組みを理解が深まり、書きたい処理もスムーズに書けるようになりました。
やはりそこが一番成長を感じた部分でした。
またLinux環境で作業することもあり最初はコマンドも全く分からず画面を見るのも嫌でした。
やらないといけないので聞いたり調べたり失敗もしながら経験していくことで今では何の抵抗もなくLinuxを操作できるようになりました。
具体的には、シェルスクリプトの書き方やパーミッション設定に苦労しましたが、今では問題なく設定できるようになりました。

### ・業務を通じて得た経験
- 主体的に業務に取り組むこと

- 正しい質問をすること

- 学ぶ姿勢を忘れないこと

#### 主体的に業務に取り組むこと
当初は自分のレベル以上の作業やスキル不足を感じることが多々あると思います。
できないからと受け身になってしまうとより前に進まなくなります。
スキルがなくても調べたり自分で考えたり、質問したりとできることはたくさんあります。
主体的に取り組んで一生懸命仕事していれば周りの人にも伝わってより協力的に助けてくれることも増えました。

#### 正しい質問をすること
誰かに質問をする時に自分の欲しい答えを得るには正しく質問することが大事だと学びました。
自分が分からないことをうまく言語化できる前に質問をすると相手に全く伝わらないということを経験しました。
分からないから焦って質問するのではなく一旦相手に伝えるため何をどう話せば良いのかを考えてから相談することでスムーズなコニュニケーションを取れるようになりました。

#### 学ぶ姿勢を忘れないこと
この業界では、ずっと学習をし続けなければならないとよく言われます。
技術の進歩もそうですが、業務で必要な知識やプログラミングスキルを身につけるには、常に学ぶ姿勢を持っていなければならないと思いました。
業務中で得られることには限界があるので、業務外の時間の使い方も考えるようになりました。

## まとめ
振り返ってみると、苦労したと感じることの方が多いですが、この時期しか経験できないこともたくさんありました。
いろいろな経験や学習がエンジニアとして成長するには欠かせないと思うので、これからも頑張っていこうと思います。
1から学ぶHDL ~順序回路~

# 1から学ぶHDL
まだ学習して1時間程度なので浅い内容です。

## レジスタ
クロック信号が立ち上がった時に入力値を書きこむ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656436/94ff51f2-a012-8c69-21e2-387a4aa96785.png)
https://qiita.com/rikitoro@github/items/426186a06242b24e0df2

上の表のようにclkが立ち上がった時だけdの値をqにセットする。
```verilog:reg.v
module reg8(clk, d, q);
    input clk;
    input [7:0] d;
    output [7:0] q;
    reg [7:0] q;
    
    always@(posedge clk) begin
        q <= d;
    end
endmodule
```
posedgeが信号の立ち上がり。
negedgeが信号の立下り。

クロック（clk)が立ち上がったときにalwaysが実行されるようなイメージ。なのでqにdがセットされる。

always文でセットされるものはregで宣言。

## リセット付きレジスタ
クロックが立ち上がる時、リセット信号が０であれば０をレジスタにセット。１であれば入力のｄの値をセットする。

8bitリセットつきレジスタを示す。
```verilog:reset_reg_8bit.v
module reg8(clk, rst, d, q);
    input clk, rst;
    input [7:0] d;
    output [7:0] q;
    reg [7:0] q;
always@(posedge clk) begin
    if(rst == 1'b0) begin
        q <= 8'b00000000;
    end else begin
        q <= d;
    end
end
endmodule
```

## クロック
clkの初期値は０で繰り返す。
```veriloge:clk.v
initial begin
clk = 1’b0;
forever #10 clk = ~clk;
end
```
10秒経過するごとにclkを反転する。
もしrst(リセット信号が0であればレジスタqに0をセットする。

## ロード付きレジスタ
ロード信号が１ならレジスタにdの値をセット、それ以外は書き込まずに今の値を保持。

```verilog:load_reg_8bit.v
module reg8(clk, rst, ld, d, q);
    input clk, rst, ld;
    input [7:0] d;
    output [7:0] q;
    reg [7:0] q;
    always@(posedge clk) begin
        if(rst == 1'b0) begin
            q <= 8'b00000000;
        end else if(ld == 1’b1) begin
            q <= d;
        end
    end
endmodule
```
clkが立ち上がった時、リセットレジスタが０ならばレジスタｑに０をセット。
レジスタ信号が１ならば入力ｄをレジスタｑにセット。
それ以外の値のときは保持する。

## カウンタ
ci=1:インクリメント・ci=0は値を保持する。

```verilog:counter.v
module cnt8(
     clk, rst, ci, co, q);
    input clk, rst;
    input ci;
    output co;
    output [7:0] q;
    reg [7:0] q;
    always@(posedge clk) begin
        if(rst == 1'b0) begin
            q <= 8'b00000000;
        end else begin
            q <= q + ci;
        end
    end
    assign co = &{q, ci};
endmodule
```
ciが０の時は加算しても値は保持されたままなのでciの値に関係なく加算ｎされる。

最後の行は全ビットの論理積を取っている。q=11111111でci=1を加算するときは、co=1になるように全ビットの論理積をとる。
# 参考文献
https://qiita.com/rikitoro@github/items/426186a06242b24e0df2
【AWS】S3+CloudFrontへNuxtアプリケーションをCICDでデプロイ

# はじめに
今回はNuxtのアプリケーションをS3+CloudFrontの構成へデプロイする手順を紹介します。

# 前提
- リポジトリ：GitLab
- フレームワーク：Nuxt3

# 実装手順
## S3構築
1. 下記の設定でS3を作成していきます。

* バケットタイプ > 汎用
* バケット名 > 任意
* オブジェクト所有者 > ACL有効
　※パブリックへ公開するためにACLの設定を有効化する必要があります。

暗号化はデフォルト暗号化のままで問題ありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/902a4ee8-1994-ad92-da0c-9d3d42fcb51e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/d36fa987-9570-d8fc-826c-65f886a40661.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/54195fe6-3430-5d72-beb1-1ef1b7a7fe9f.png)

2. 静的ウェブホスティングの有効化
 2-1 .
 S3 > 作成したバケット > [プロパティ]タブ　最下部
 静的ウェブホスティング > [編集]
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/958fc102-dccb-faf6-4420-f8a7f77851e8.png)

2-2.
* 静的ウェブホスティング > 有効にする
* ホスティングタイプ > 静的ウェブサイトをホストする
* インデックスドキュメント > ウェブサイトのデフォルトページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/e0fc1b44-25ae-4307-f102-4b3b000e556f.png)

### アプリケーションをアップロードして確認する
手動でアプリケーションをアップロードして確認したい場合、Nuxtアプリケーションはdist配下をアップロードすることで
挙動を確認することができます。
先ほど有効化したS3静的ウェブホスティングの設定箇所にエンドポイントが記載されていますので、アップロード後にURLへアクセスするとアプリケーションが公開されていることを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/b37fd790-f8d1-323e-d220-a48e240b332d.png)

## CloudFrontの作成
1. 下記の設定でCloudFrontを作成していきます。
オリジンの指定以外は要件に合わせて変更いただればと思います。

* オリジン > 1.で作成したS3

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/e53e01d7-f9c2-6b8b-2217-f11abe389ef5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/436978ee-ba6e-9849-15c7-b3aecf37a013.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/e16c9ef1-fd26-967b-f089-05fe809513d7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/44dc8d73-03ba-173e-1081-308ade34eaa3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/4b8a84ca-be47-0dd4-8762-fd0abeaa8c7c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/12529b5f-b1e6-0a33-ebc3-ed20dc029a27.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3024215/fd4d3e75-581b-ed43-8cfb-e4288bccc132.png)


## パイプラインの構築
GitLabの場合は.gitlab-ci.ymlファイルを作成することで
パイプラインを構築することができます。

バケット名やAWSアクセスキーは
Settings > CICD > Variablesから設定できるシークレットを指定し、ymlファイルに書き込まないようにします。

```
stages: 
    - build
    - deploy

build:
  image: node:20
  stage: build
  artifacts:
    untracked: true
    when: on_success
    access: all
    expire_in: 1 days
  only:
    - main
  script:
    - npm install
    - npm run generate

deploy:
  image: python:alpine
  stage: deploy
  dependencies:
    - build
  only: 
   - main 
  script:
   - apk add python3-dev
   - pip3 install awscli
   - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
   - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
   - aws s3 sync ./dist s3://$BUCKET
```

# まとめ
今回はS3 + CloudFrontへのCICDを含めたNuxtアプリケーションのデプロイについてご紹介しました。
IaCの作成やアプリケーションの作りこみ等も今後記事にしていけたらと思います。
１から学ぶHDL  ~RTL設計とゲートレベル設計~

# １から学ぶHDL  ~RTL設計とゲートレベル設計~
HDLについて初めて学んだことを書いてみました。まだまだ学び始めて３０分なので内容が浅いです。


# RTL設計とゲートレベル設計
RTLのほうが記述量がうんと少ない！
コードを見れば一目瞭然！
```verilog:RTL.v
module half_add(a, b, co, s);
 input a, b; output co, s;
 assign s = a ^ b; assign co = a & b;
endmodule
```

```verilog:gate level.v
module full_add(a, b, ci, co, s);
 input a, b, ci; output co, s; wire w0, w1, w2;
 half_add ha0 (.a(a), .b(b), .co(w1), .s(w0));
 half_add ha1 (.a(w0), .b(ci), .co(w2), .s(s));
 assign co = w1 | w2;
endmodule
```
同じ内容なのに、こんなにも行数が変わってきます。

ここで詳しくまとめておくと

## RTL設計
そのままシミュレーションが可能！

- 記述量少ない
- 抽出度高い
- 大規模回路が容易
- 組み合わせ回路やレジスタ

## ゲートレベル設計
- 記述量多い
- 抽出度低い
- 大規模回路が困難
- ANDやOR、フリップフロップ


## always文
ここでalways文について動作記述言語の１つ
```verilog:always.v
always@ ( センシティビティリスト ) begin
演算
end
```
センシティビティリストはその値が変化したときにそのコードが実行されるというもの。
alwaysで代入する値はregで宣言する

alwaysの例として4bit加算器を示す。
```verilog:ex_always.v
module add4(a, b, ci, co, s);
input [3:0] a, b;
 input ci;
 output co;
 output [3:0] s;
 reg co;
 reg [3:0] s;
 always@(a or b or ci) begin
 {co, s} <= a + b + ci;
 end
endmodule
```
【プラクティス紹介】1分でさらっと分かる「卒業式」

## プラクティス名（別名）
卒業式（送別会）

## プラクティスの目的・狙い
* 離任者が担っていた役割をチームで再認識し、その穴を埋める
* 離任者とチームの良好な関係を継続する

## どんな時に使うか
* スクラムチームに在籍していたメンバーがチームを離れる時

## 実施手順
1. スクラムチームが全員出席できる時間帯で卒業式（＝会議）を設定する
1. 卒業式ではまず卒業生（＝離任者）から一言もらう
1. 続いて在校生（＝残るメンバー）が感謝の言葉を順に贈る
1. 離任者がこれまで担っていたタスクや役割の後任者を相談する

::: note info
 在校生からの感謝の言葉「（離任者）さん、今までｘｘしてくれてありがとう！」の「ｘｘ」の部分を今後、チームの誰かが引き継がなければなりません
:::
 
## アレンジ例
* 離任者から挨拶だけでなく、印象深かったことなども語ってもらう
* 後任人事は残るメンバーだけで会議後に改めて行う

## アンチパターン
* 離任者が人知れず果たしていた役割が語られぬまま終わってしまい、後日タスク漏れにつながる

## 参考情報
このプラクティスはお世話になったアジャイルコーチから直接ご教示いただいたプラクティスです。そのため参考サイトなどは特にありません。

## こぼれ話（私的コメント）
機能したスクラムチームはできるだけそのままのメンバーで維持するのが定石ではありますが、とはいえ諸事情でメンバーの入れ替わりが発生することはよくあります。メンバーが1人でも変わるとチームは別物になる、とも言われていますが、その際の影響を最小限にするためのプラクティスがこれです。引継ぎタスクの洗い出しが主目的ではありますが、間接的にチーム内の属人化がどの程度進行していたか、というチェックにもなります。この場でチームが認識できていないタスクがポロポロ出てくるようであれば、今後の体制はもう少し考えた方がいいかもしれません。
このプラクティスをすることで気持ちの面でも、整理がつけやすくなります。またチーム/離任者双方にとって良い印象で終わることは、長い目で見ると大切な気がします。

---
　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
Stack BlitzでCSS Modulesを適用できない

# はじめに
Stack BlitzでCSS Modulesを適用できない。

# 問題
以下を対応していたところ、Stack BlitzでCSS Modulesを適用できなかった。

Reactに入門した人のためのもっとReactが楽しくなるステップアップコース完全版
https://www.udemy.com/course/react_stepup/?couponCode=ST22MT92324A
セクション4：様々なCSSのあてかたに触れる
14.CSS Modules

```App.jsx
import { CssModules } from './components/CssModules';
import { InlineStyle } from './components/InlineStyle';
import './styles.css';
import './components/CssModules.module.scss';

export default function App() {
  return (
    <div className="App">
      <InlineStyle />
      <CssModules />
    </div>
  );
}
```

```CssModules.jsx
import classes from "./CssModules.module.scss";
export const CssModules = () => {
  return (
    <>
      <div className={classes.container}>
        <p>- CSS Modules -</p>
        <button>Fight!!</button>
      </div>
    </>
  );
}
```

```CssModules.module.scss
.container {
  border: solid 2px #392eff;
  border-radius: 20px;
  padding: 8px;
  margin: 8px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
```

CssModules.module.scssがずっと保留中となってしまい、画面が表示されない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881019/c15560bb-7c5d-3a3e-816f-8b00564fff40.png)


# 解決方法
ローカルのVisual Studio CodeでReact.jsの環境を構築する。
※環境構築の方法については記載しません

以下ソースコードを実行。
```
$ npm install node-sass
```

App.jsx、CssModules.jsx、CssModules.module.scssは上と同じソースコードを使用し、npm run devで立ち上げ、ブラウザを開く。

すると、Visual Studio Codeでは、ブラウザ、ターミナルに以下エラーが表示された。
[plugin:vite:css] Preprocessor dependency "sass-embedded" not found. Did you install it? Try `npm install -D sass-embedded`.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881019/68303d47-2571-de6a-a9c8-d9d2f9bb0b8c.png)

エラーの指示通りにコマンドを実行。
```
$ npm install -D sass-embedded
```

CssModulesが表示できた。　
※テストのためCssModulesのみ表示させています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881019/f48669de-e244-8945-81e1-9ba2f7b588af.png)

Stack BlitzでCSS Modulesの適用方法はわからなかったです。
Stack Blitzではnpm install -D sass-embeddedを実行しても表示できず、裏側で何かエラーが出ているのかもしれません。

# おわりに
結構時間かかってしまいました。
MIT ライセンスのプラグインを使用する場合の、私個人的な書き方について

MIT ライセンスを使ったソフトウェアの
ReadMe.txt を私はこのように記述しているという
例をここで紹介したいと思います。

MIT ライセンスは
使用すると自分もソースを公開しないといけない
という、いわゆる感染問題が無いため
非常に表記しやすいです。

***

結論

結論は以下の通りです。

```html:私の著作権表記の書き方
Use Library in ソフトウェア名

・Newtonsoft.Json
　L Copyright © 2007 James Newton-King All Rights Reserved.
　L URL https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md
　L MIT License
　L MIT License Explanation https://opensource.org/license/mit/

```

上記の書き方を ReadMe.txt のなるべく上に書く

***

MIT ライセンスのプラグインを使う場合に必要な記述について

MIT ライセンスのプラグインを使う場合は
使用したプラグインの情報を
見やすい場所に記載する必要があります。

著作権表記と
MIT ライセンスの情報を
記述する必要があります。

参考サイト：
https://qiita.com/suwanishi77/items/82629633c16b086d1cd2

書式は、私は ReadMe.txt のなるべく上に

```html:私の著作権表記の書き方
Use Library in ソフトウェア名

・Newtonsoft.Json
　L Copyright © 2007 James Newton-King All Rights Reserved.
　L URL https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md
　L MIT License
　L MIT License Explanation https://opensource.org/license/mit/

```

という記載をするようにしています。
2 種類使っているならば
2 種類記載します。

「・プラグイン名」の下に L で付属情報として
著作権表記やライセンスの情報を書くことで
簡潔に使用しているプラグインについて言及しています。

例えば私が SephirothSave というアセットを作った時は
下記のように記載しました。
(UnityAssetStore では
MIT ライセンスのプラグインを
原則使うことができず
独自のライセンスを設定できないため
リジェクトされましたが
必要な情報は揃っています)

```html:私が過去に書いた ReadMe.txt
SephirothSave - Function to manage save data For Unity / Ver1.00.0
Created by ...
Copyright © 2023 ...

===
License

The SephirothSave license is as follows:
...

---
Use Library in SephirothSave

・Newtonsoft.Json
　L Copyright © 2007 James Newton-King All Rights Reserved.
　L URL https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md
　L MIT License
　L MIT License Explanation https://opensource.org/license/mit/

---
以下 Example of use や Supplement(補足) 等が続きます。

```

最初に SephirothSave の
ライセンスについて言及して
次に使用した MIT ライセンスの
プラグインについて言及しています。

使用した MIT ライセンスの
プラグインの情報は
見やすい位置に書く必要があります。
なので SephirothSave の説明文を先頭に入れると
プラグインの情報を下の方に記載する事になるため
良くないと判断して
ライセンス系の情報を上に持ってきています。

***

以上私個人的な
MIT ライセンスのプラグインを使う場合の
書き方について紹介しました。

LICENSE.txt を作っても良いですが
私が作るような小規模のソフトウェアの場合は
ReadMe.txt で完結しても良いと思っています。

皆さんは MIT ライセンスの
プラグインを使う場合は
どのように記述しますか？

よろしければコメント欄で
教えて頂けると嬉しいです。

「バイナリ化せずに公開する場合は
プラグインの方に情報が記載されているため
ReadMe.txt 等に書かない」という人もいるかもしれません。
私は ReadMe.txt にも書かないと怖いので書いていますが
大丈夫という根拠を提示した記事等あれば
それもコメント欄で教えて頂けると嬉しいです。

最後に、この私の書き方を真似する事で
不利益を負ってしまった場合に
我々は責任を負わないものとさせて下さい。
何卒、何卒よろしくお願い致します。

この記事がライセンス表記に
悩んだ時の参考になりますように。
閲覧ありがとうございました。