OmniAICreator/Qiita-1.07M huggingface dataset:
MySQLサーバーと接続できない問題

# MySQLのコネクションエラーについて

MySQLに接続しようとすると、なぜか以下のようなエラーが出現しました。

```
Can't Connect to MySQL Server on 'localhost:3306'
```

ただMySQLをインストールしてから特に何もいじっていないのに、起動しようとしたらこのようなエラーが出ます。

また、mysqldやmysqldlogなどをファイルから起動してmysqlを開いたり、そのエラーのログを見ようとしてもなぜかすぐ落ちてしまいます。
こうした原因は何なのか、いろいろウェブサイトやAIに聞いて調べてみましたが、なかなか答えとなるようなものが出ませんでした。

## 結局何が問題なのか
このエラーが現れている原因は何個か考えられます。
それを見ていきましょう。

**1. MYSQLサーバーが実行されていない**

最もシンプルな理由で、MySQLサーバーが開いていないことが理由となります。

**2. FireWallが邪魔をしている**

もし、あなたのPCでFireWallが3306ポートへの接続をブロックするように設定されているのなら、あなたのその接続は失敗します。

**3. 接続の設定が間違っている**

ポート先、ホストネームやＩＰアドレスが接続設定として間違っているかもしれません。

**4. ネットワークの問題**

単純にネットワークが悪いのかもしれません。


## 解決した

ただ単にmysqlと打っても
```
ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' (using password: NO)
```

こうしたエラーが出ていましたが、そうではなくて
```
mysql -u root -p
```
と入力することで、その後パスワードを求められ、そして正しいパスワードを無事入力することができ、MySQLサーバーと接続することができました。

## 更なる問題

このようにしてMySQLサーバーと接続することができましたが、node.jsでMySQLサーバーと接続しようとしても以下のようなエラーが出ます。

```
ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
```

調べてみると、これはNode.jsがMySQLサーバーが要求する認証プロトコルをサポートしていないそうです。
MySQL8.0.4以降のログイン認証方式は`caching_sha2_password`方式がデフォルトになっています。
しかし、nodeはそれをサポートしていないため、元の`mysql_native_password`に戻す必要があります。

そのためには以下のコマンドをSQLコマンドラインで入力する必要があります。
```
alter user 'root'@'localhost' identified with mysql_native_password by '新パスワード';
```

これを実行して
`Query OK, 0 rows affected (0.05 sec)`
と帰ってくれば成功です。
その後に
`select user, plugin from mysql.user;`
を実行すると

| user             | plugin                |
|-------------------|----------------------|
| mysql.infoschema | caching_sha2_password |
| mysql.session    | caching_sha2_password |
| mysql.sys        | caching_sha2_password |
| root             | mysql_native_password |

といったように、rootにmysql_native_passwordの認証方法が当たるようになったことが分かります。

これで無事にnodeからmysqlに接続することができます！

## 備忘録

ちなみにWindowsの人はMySQLでエラーが出た際に、my.iniファイルをいじる必要がでるかもしれませんが、my.iniファイルは初期ダウンロードの際にはProgramFileフォルダではなくて、ProgramDataフォルダの中に入っています。
コードを追うためには？

# はじめに
コードを追う場合、コードを追う前の事前準備が非常に重要だと考えています。
「コードを追う前にやること」と「コードを追ってみる」という２部構成で記載していきます。

# 1. 事前準備：コードを追う前にやること
## 1-1. 設計パターンの理解
・MVPやMVVMなど採用されているデザインパターンが何かを理解する。 
・ソースファイルが格納されているディレクトリ構成を理解する。 
・共通クラスや基底クラスがどういう構成なのか理解する。

## 1-2. コーディングルールの理解
・チーム独自のコーディングルールを理解する。 
・ファイル名、クラス名、メソッド名などの命名規則があるのであれば規則性を理解する。
・コメントの付け方を理解する。

## 1-3. 何のためにコードを追うのかを明確にする 
・コードを追う目的、またはどこまでコード分析できれば良いのか？を具体的に決める。 
　→目的や知りたい情報を明確化することで、関係がある箇所と無い箇所の線引きをする

## 1-4．追いたい画面/機能の実機やシミュレータなどの操作手順の明確化 
・操作手順を明確にすることで、コードを追う時の当たりや取っ掛かりを掴みやすくなる 

## 1-5．期日を確認する 
・コードを追う作業にどれくらいの時間をかけて良いのか確認する 
　（別にコードを追う作業に限った話ではないが、時間は有限で期日感を確認しようね、話です。） 

## 1-6．開発環境やプログラミングエディタの使用方法を学ぶ 
つらつらと基本的なことばかり書きますが、ここを理解しておくのは重要だと思うので記載しておきます。
・検索 
　Grep方法、１ファイル内での検索方法、検索範囲の指定、正規表現の検索方法 
・対象クラスのメソッド一覧表示方法 
・クラス一覧表示方法 
・対象メソッドの呼び出し箇所の検索方法 
・メソッド呼び出し箇所から定義されているメソッドに移動する方法 

## 1-7．ソース種別の理解 
　追っている最中に外部ライブラリのクラスに行きついたり、OS特有のクラス、または言語特有のクラスに行きつくことがあります。
お初の案件のコードを追っていると最初は混乱することがありますが、自分が今見ているクラスがどの部分のコードなのか意識的に確認しながらコードを追う必要があります。

　そのため、コードには以下種類があることを認識する必要がある。 
　①自作メソッド/クラス（実装されているコード部） 
　②組み込んでいる外部ライブラリ 
　③OSのクラス群 
　④言語のクラス群 

　※上記①以外は公式HPなどのリファレンスマニュアルを確認し仕様を確認することも必要になってくるだろう 

また、追う時にInput/Outputを意識することも重要。
　例）ある機能のInputがxxの場合、Outputはxxになる仕様であれば、コードの処理の箇所はxxになるはず、とかね

## 1-8．仕様書の確認 
・画面設計書、機能仕様書、シーケンス図など既にある仕様書を確認し、コードを追う時のヒントを探します。
・業務知識・担当機能への理解を深める 


# 2.コードを追ってみる
## 2-1. 取っ掛かりを見つける 
・まずは追いたい箇所となる対象画面、もしくは対象機能のソースファイルを特定する。 

## 2-2．検索してみる 
・UIに特徴的な日本語が使われているのであれば、その文字列をまずはGrepしてみる。 
・特定のクラスや使われているであろうファイル名が判明しているのであれば、そこから検索してみて、影響範囲を調査する。 

## 2-3．実際に動かしてみる 
　ある程度当たりを付けたソースファイルの必ず通りそうな箇所などにBreakPointをはって、実際に動かして確認する。
 （推測している箇所が本当にその通りかを確認する、または新しい疑問点が生まれるかもしれない）。 

ローカルに環境を構築せずにサーバ上のプログラムを動かして確認する必要がある場合やシーケンスやタイミングを調査したい場合は、ログを仕込んで確認するのも有効
（いちいちBreakPointをはってステップ実行は非効率　→　ここはケースバイケースだけどね）。 

## 2-4．メモをとって整理しながら追う（超重要） 
・複数のクラスやライブラリ、時には複数のアプリを跨ってコードを追う必要がある。
　そういった場合は、簡易的なメモでも構わないので一つ一つ呼び出し元と呼び出し先をまとめながらコードを追う。 

## 2-5．上記方法を試しても分からない場合は？
・有識者にヒアリングする 
・もちろんコードを追った結果、どこまで分かってどこが分からないのかを明確に説明する必要がある
 （何が分からないのかが分からない、といったことが無いようにする）
Salesforce　Lightningページコピー方法と注意点

SalesforceはLightningページコピーができます


コピー方法は

## ステップ1 コピーしたいLighnitngページの選択を行う

オブジェクトマネージャーの「Lightnigページ」の表示ラベルの青文字をクリックしてください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/efb1d938-fe44-8764-d13c-cbd949f87d6b.png)


## ステップ2 編集ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/40feca03-a3f3-29ec-6663-db3c02548f5e.png)


あとは右上の「保存」ボタンをクリックすればLightningページ複製は完了です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/3d3eb9d6-2e58-40bf-07f6-ebbbe2c4fa35.png)



注意点としては何も考えないでLightningページをコピーすると表示ラベルAPI参照名が同じページが出来るのでややこしいです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/efb1d938-fe44-8764-d13c-cbd949f87d6b.png)


なので、保存前に右上部の表示ラベル、API参照名を任意に設定することをお勧めします

![表示のラベル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4733e938-0e33-3d67-7e3e-2ce5f6c6aaf5.png)
devcontainer.jsonのデバッグ設定(launch)で環境変数を使うためにエスケープする裏技

## 結論
devcontainer.jsonで以下の設定を行う（PORTが本来設定したい環境変数）

```json:devcontainer.json
{
  "customizations": {
    "vscode": {
      "settings": {
        "launch": {
          "version": "0.2.0",
          "configurations": [
            {
              ...
              "args": [
                "$${env:DUMMY}{env:PORT}",
              ],
...
```

## 理由
devcontainer.jsonに書かれた設定はリモートのsettings.json（ex. /root/.vscode-server/data/Machine/settings.json）に反映される。
その反映時に環境変数を読み込んでしまうので、エスケープが必要だった。

該当部分だけ取り出して、挙動を見てみる

```json:devcontainer.json
"$${env:DUMMY}{env:PORT}"
```

```json:/root/.vscode-server/data/Machine/settings.json
"${env:PORT}"
```

```shell
# デバッグ実行を行った際のコマンド
8000
```

`${env:DUMMY}`が""に置き換わることを利用して`${env:PORT}`をエスケープすることができた
Amplify v6を使ってidTokenを取得し、headerに含めるやり方

## はじめに
新人研修でWebアプリケーションをチームで開発しています。
APIが叩き放題だったため、Cognitoを使ってAPI Gatewayのアクセス認証をすることにしました。
## 発生した問題
- Amplify v6では、idTokenの取得など、Amplify v5から変更があった。
- 調べてもAmplify v5の記事しかなく、苦戦した。
## 結論
```typescript
import { fetchAuthSession } from "aws-amplify/auth";

//idTokenを取得
const session = await fetchAuthSession();
const token = session?.tokens?.idToken?.toString();

//headerに含める
const headers = { headers: { Authorization: token } };
//GETする際にheaderを含める例
const response = await axios.get(ENDPOINT_URL, headers);
```
## さいごに
これからAmplify v6を使う人の助けになれたら嬉しいです。
100%正しいとは言い切れないので、もっと良い方法などがあったらぜひ教えてください！
次は、Amplifyを使って簡単にサインイン、サインアップを実装する記事を書こうと思います。
## 参考
[Amplify公式ドキュメント](https://docs.amplify.aws/react/)
[Cognitoを使ってAPI Gatewayのアクセス認証をしてみた](https://qiita.com/ist-m-k/items/f956e3005b2e83272cb2)
"ls -l"した時に権限の後ろについてる数字はなに？

この部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261800/fb15cd11-79d5-2a87-62e8-ea69f642d318.png)

# 発端
ある日いつものようにファイルの権限を見ようと `ls -l` したところ、いつもはスルーしてた上記の個所がふと気になったので調べました。

# 結論
「ハードリンク」の数

# ハードリンクとは？
## 前提
ext4など、linuxでよく使用されるファイルシステムでは以下の3つに分けてファイルを管理しています。

- ディレクトリエントリ
    - ファイル名orディレクトリ名とi-node番号（後述）の組み合わせのみを保持
- i-node
    - ユニークなi-node番号を持つ
    - ファイルorディレクトリのメタデータを保持
        - 例）
            - ファイルタイプ（通常のファイル、ディレクトリなど）
                - `ls -l`した時のパーミッションの先頭についている文字のやつ
            - パーミッション
            - 所有者
            - ファイルサイズ
            - **データブロックへのポインタ**
- データブロック
    - ファイルの実体
    - ディレクトリの場合は子のファイル/ディレクトリのディレクトリエントリが格納されている

## ではハードリンクとは
既存のi-nodeに別のファイル名を紐づけたもの。
i-node、データブロックは既存のものと共通なのでハードリンクからファイルを編集すると元のディレクトリエントリからファイルを開いても編集が反映される。


# 似たようなの：シンボリックリンク
リンク先のファイルへの参照を保持するファイル。
ハードリンクと異なりまったく別個のi-node、データブロックを持つ。

データブロックにリンク先のパスを保持する。

`cat`などをシンボリックリンクに対して実行すると、ファイルシステムはシンボリックリンクのi-nodeからそれがシンボリックリンクであることを認識し、リンク先を参照しに行く。
VscodeでSSHを使用してVirtualboxのゲストOSに接続

基本は下にあるサイトの通りにやれば問題ない。

https://nakadalog.com/vscode-remotessh-virtualbox/

詰まった部分があったのでメモとして残す

# ゲストOSにopenssh-serverがあるか確認する
ないならインストール
$sudo dnf install openssh-server


# ポート番号の指定
本来sshはポート番号２２だけどVirtuallboxでポートフォワーディングで経由する必要があるため
ポートフォワーディングの設定でホスト２２２２　ゲスト２２としてあげる。

configの設定
Host linux
    HostName localhost
    User root
    Port 2222

# SSH 経由の root ログインの有効化
ゲストOS側でのroot権限でログインしたいときは設定を変更する必要がある

$ vi /etc/ssh/sshd_config でファイルを見ると

#Authentication:
#LoginGraceTime 2m
PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

PermitRootLoginという部分がある。最初はコメントアウトをしているため解除をしてyesを追記

そして再起動
$service sshd restart
[Dify]自動でベクターDBに保存する用のワークフローを作成してみた

## はじめに

例えば、DifyでURLを要約させたら、URLの内容やその要約内容を自動でベクターDBにデータを入れたいと思ったことはありませんか？
LangChainなどを使ったコードベースで実施するのは簡単ですが、Difyだとやり方わからないなどあると思います。
今回は自動でベクターDBにデータを入れるようなワークフローを作成したいと思います。

## 全体像

まず全体像からです。
流れとしては、
1. 空のナレッジを作成→ナレッジのIDを抜き出し→ナレッジIDに対してデータを保存
2. またはすでにナレッジがある場合は、IDを見つけ出してそのナレッジIDにデータを保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/036ab6f8-1e71-b427-fddf-33e11977b2c1.png)

※ナレッジ操作のAPIは以下から確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/e7f6927f-fc7b-c068-6b96-0104f2747774.png)


## 空のナレッジを作成
まずは空のナレッジを作成します。
認証からAPIキーの設定を忘れないようにしてください。
URLやAPIキーはナレッジ操作のAPI画面から取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/03dca0d8-cb30-3833-3c3b-c841ecf58188.png)


## 次に場合分け

空のナレッジが作成できた場合はステータスコードが200で返ってきます。
すでに作られている場合は409で返却されます。
今回は面倒なので200とそれ以外で場合分けするようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/67dbdd32-f4f8-a199-4ff1-4f94b599d6c1.png)

## 空のナレッジをできたら？
作成できたら以下のようなレスポンスが返却されるのでidを取り出しましょう。
```
{
  "id": "",
  "name": "name",
  "description": null,
  ....
}
```

コードは以下です。
```python
import json

def main(arg1: str) -> dict:
   
   decoded_json = json.loads(arg1)
   id = decoded_json["id"]
   return {
        "result": id,
    }

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/372e399f-6fcc-0fca-b99c-f4000f5c5a84.png)


## すでにナレッジがあったら？
すでにナレッジがあった場合はそのナレッジに対して保存処理をするようにします。
そのためにidを取得しますので、一旦ナレッジを呼び出して名前で全探索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/3e94cc4f-b9cf-414c-c0ff-0ef30124ffe0.png)



コードは以下です。
```python
import json

def main(body: str,name:str) -> dict:
   
    decoded_json = json.loads(body)
    
    for item in decoded_json["data"]:
        if item["name"] == name:
            result=item["id"]
            return {
                "result": result,
            }
   

    return {
        "result": "",
    }
```

## Variable AggregatorでIF/ELSEを統合する

Variable Aggregatorで分かれたブランチを統合しましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/fdf212f1-20f1-20f1-f04d-186b4af7409b.png)


## ナレッジに保存
最後に保存します。おわり〜
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/0f4a8e3d-c4d1-7bd7-1324-6e921f8f8e08.png)


## 最後に

これでURLの論文などをどんどん要約して、すぐにベクトルDBに保存して行こう！
Xやってるので気になる方はフォローお願いします。
https://x.com/hudebakonosoto
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（7/100）

【7日目】
トピック2：SAPS/4HANA生産計画の概要（1/5）

≪問題7≫
B品目とC品目の計画にかかる労力を削減しようとしています。推奨される計画手法は以下のどれですか。
□消費主導型計画
□チェックなしマニュアル計画
□アドバンスト計画
□資材所要量計画

≪解答≫
■消費主導型計画
□チェックなしマニュアル計画
□アドバンスト計画
□資材所要量計画

≪解説≫
◆資材所要量計画における基本計画タイプは、品目マスタのMRPタイプを使用して、各品目ごとに定義されます。品目は、基本的なコンセプト（計画主導型または消費主導型）に基づいて計画されます。
（1）計画主導型計画-MRPは、現在および将来の販売に基づいており、部品表/配合表（BOM）構成全体（多段階）に対して実行されます。
・所要量計算の開始ポイントは、受注の独立所要量の数量および日付と、独立所要量の数量および日付です。
・主に、高額なA部品に使用されます。
（2）消費主導型計画は、履歴消費値に基づいており、需要予測または統計処理を使用して将来の所要量を決定したり、在庫品目が減少した場合には単に補充をトリガーしたりします。
・調達提案はMRP中に登録されます。
・主に、重要性が低い低額なB部品およびC部品に使用されます。
Excel VBA Match 関数で検索

検索はFind か、VLookup を使っていましたが、Match が最速らしいので練習しました。
YouTubeのメンタExcelさんの動画を参考にさせていただきました。

変数RをRange型で宣言するとエラーが出ましたが、Variantにしたら動きました。

```vb
Sub kensaku()

  Dim R As Variant
  Dim FindRow As Long
  
  R = Range("A1:A4").Value
  
  FindRow = Application.Match(Range("D2"), R, 0)
  Range("E2") = Cells(FindRow, 2)
  
End Sub

```

![Match.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/defaa5e4-b2ca-e679-d0e2-7ba4728a9496.png)

D2セルに番号を入力して実行すると、E2セルに対応する品名が表示されます。
検索範囲が大量にあるときはFindやVLookupよりMatchが速いみたいです。
DriveAPIを使用せずにxlsxファイルをGASで読み込む

# 概要

DriveAPIを利用せず, GoogleDrive上のxlsxファイルを読み込むためのコードです.

## 目次

- [概要](#概要)
  - [目次](#目次)
  - [使用データ](#使用データ)
  - [Google Driveに格納されたxlsxのURL](#google-driveに格納されたxlsxのurl)
  - [コード](#コード)
  - [スプレッドシートに転記する例](#スプレッドシートに転記する例)


## 使用データ

以下をxlsxファイルに書き込み, Google Driveに格納したファイルを用いる

| 商品 | 価格 |
|------|------|
| a,b  |  900 |
| b    |  500 |
| c    |  800 |
| b,c  | 1500 |

## Google Driveに格納されたxlsxのURL

xlsxファイルをブラウザ上で展開(スプレッドシートで展開)すると以下のようなURLが表示される.

https://docs.google.com/spreadsheets/d/{ここに記載されるIDを利用}/edit?gid=~#gid=~

URLに表示されるIDをコードで利用する.

## コード

以下でxlsxファイルをCSV形式で読み込むことができる.

```javascript
const xlsxId = "xlsxのIDを記載"
const xlsxDownloadUrl = `https://docs.google.com/spreadsheets/d/${xlsxId}/export?format=csv`
const responseText = UrlFetchApp.fetch(xlsxDownloadUrl,{
  headers:{
    // Bearer の後のスペースは空けておく
    'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
  }
}).getContentText();
```

GAS上で実行するとresponseTextは以下のように表示される.

![実行結果1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357884/e259bd25-02e8-efa7-d40c-b69c7955da47.png)

データ中にカンマがある場合はダブルクォーテーションで囲まれる.

## スプレッドシートに転記する例

スプレッドシートに転記する例を示す.

```javascript
var GET_SHEET_LIST = [
  {downloadId: "IDを記載", outputSheetId:"出力先のSSのIDを指定", outputSheetName: "出力先のシートを指定"},
  // 複数指定可能

  // {downloadId: "", outputSheetId:"", outputSheetName: ""},
]

function fetchXlsxData() {
  for (const row of GET_SHEET_LIST){
    const xlsxDownloadUrl = `https://docs.google.com/spreadsheets/d/${row["downloadId"]}/export?format=csv`
    const responseText = UrlFetchApp.fetch(xlsxDownloadUrl,{
      headers:{
        'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(),
      }
    }).getContentText();

    // シートを指定
    const sheet = SpreadsheetApp.openById(row["outputSheetId"]).getSheetByName(row["outputSheetName"])
    // 書き込み先のシートのデータを全て削除
    sheet.clear()
    // CSVテキストを二次元配列に格納
    var writeArray = Utilities.parseCsv(responseText)    
    // ~2025/02/09 追記~ 
    // コメントでUtilities.parseCsv()について教えていただいたので, 上記コードに変更
    // 以下は元々記載していたコード
    // ダブルクォーテーションで囲まれたカンマでは区切らないように指定
    // =(?:\"[^\"]*\")　でダブルクォーテーションで囲まれた箇所を除外
    // var writeArray = responseText.split('\n').map((row, index) => {
    //   return row.split(/,(?=(?:\"[^\"]*\")*[^\"]*$)/);
    // })
    
    // シートにデータを全て書き込む
    sheet.getRange(1,1,writeArray.length, writeArray[0].length).setValues(writeArray)
  }
}
```

スプレッドシートには以下のように格納される.

![実行結果2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357884/31dc0458-4cd1-ca24-1df3-b20a2fca7d08.png)
GASの自動デプロイ環境を組もうとしたら躓いた

## 背景
- GASのWebエディタだと書くのしんどい
- デプロイを手動でやるのは手間だし、オペレーションで事故る可能性上がりそうだから避けたい

## 取り組み
- コード量が増えそうなので、claspを使ってIDEの恩恵を受けよう
- おまけにGitHubActionsでCD構築してしまおう

## 遭遇した問題
- ローカル環境で作成した`.clasprc.json`をGitHubActionsでも利用するとエラーになる
    - ローカルで`clasp push`後、Actions上での`clasp push`は実行可能
    - しかし、一定時間経過後にいずれの環境からも実行不可となる(`invalid_grant`)

## うまくいく条件を探索...
- ローカル環境では**トークンの払い出しのみ**を行う
    - 払い出した後、`clasp push`や`clasp pull`を行わない
    - 行わない状態で`GitHub Secrets`へ登録して利用する

## 何が問題だったか
GWSのアカウント1つを用いて、複数環境から実行させようとしたことが原因と思われます:cold_sweat:
※明示的に記載されているドキュメントは見つけられておらず、推測になります...

ただ、GitHubActionsのランナーも毎度環境立ち上げなおしていると思うので、環境的にはローカルからのpushと変わらないのでは？と思ったりもする。
この辺りの先入観があったので、たどり着くのに時間がかかった...(´・ω・｀)

## 結論
開発用のアカウントとは別途デプロイ用のアカウントを準備すると、一旦は解決しそうです:v:
ネットワーク入門: 入門中の入門

# 初めに

エンジニアをやっている以上プログラミングだけやっていれば良いということはありません。
自分が作成したプログラム・ソフトウェア・アプリケーションが、それを利用したり、閲覧したりするユーザに届けて、やっとその役を果たします。
つまり、自分の PC 内で開発したものを誰でも（もしくは特定のユーザ）に提供する環境が必要になります。
Web アプリケーションであれば、「サーバ」に自分の制作物を「デプロイ」することで、他の人に提供できるようになります。
そのためには、そのサーバというものがどういうものなのか、そもそも他の人に自分の制作物が届く仕組みやそれに付随する情報技術の知識を理解しておく必要があります。

本記事では、その初歩としてネットワークの基礎についてご説明していこうと思います。

# インターネットとは

さて、早速ですが、インターネットとはなんでしょうか？
みなさんもこの Zenn 記事にアクセスするためにインターネットを利用しているかと思いますが、その仕組みはあまり理解せずに利用しているかと思います。

インターネットとは世界規模のネットワークのことを指します。世界規模とはスケールがデカいですね。

では、ネットワークとは何でしょうか？

## ネットワークとは

ネットワークとは、人やものの繋がりのことを指します。人脈のことを人的ネットワークなんて言ったりしますね。
このように線がたくさん繋がっている集合をイメージすることが多いかと思います。

![ネットワークのイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/5efc3555-0f07-e658-4c71-37dfacd49402.png)
_ネットワークのイメージ_

ネットワークというのは、このように点と点が線で繋がって接続している状態を指します。

### ネットワークを簡単に捉える

しかし、一度落ち着きましょう。
さて、あまり物事を難しく考えてはいけません。
もっと簡単な例でネットワークを考えてみましょう。
上にも書いたように「人の繋がり」を「点と点を線で繋がって接続している」と考えると、実はこれもネットワークと言えるのです。

![糸電話](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/20d0cb02-4d1e-dc2b-81a9-e79e198d07ee.png)
_ネットワーク？_

ふざけていると思われるかもしれませんが、そんなことはなく、
基本的にネットワークを考える時に、
ある対象物(ノード)と別のノードが線(リンク)で繋がっているだけの単純なネットワークを考えると思考がスッキリするのです。
そう、どのネットワークも糸電話のようになっていると考えると、良いということです。

![いわゆるネットワーク](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/07b75295-29b8-f203-e3f9-805f19a08709.png)
_いわゆるネットワーク_

![ネットワークを糸電話として考える](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1655179/4be69ca3-2ddf-65f0-f40e-4ab9a3b1cbd3.png)
_ネットワークを糸電話に置き換える_

実際にパソコンはルーターという通信機器と 1 本の LAN ケーブルで接続されており、
局所的に見れば、糸電話と同じ状態になっています。
このように局所的に見れば、1 対 1 で構成されたネットワークが大量に存在し、インターネットを構築しているのです。
そのネットワークに接続したスマホや PC を介して、どこかのサーバにあるこの記事を見ているのです。

### リンクの存在しないネットワーク

スマホやノート PC は充電・電源ケーブルは刺さっていても LAN ケーブルや通信を行うための線は接続されていません。
これらは、Wi-fi や 5G などがケーブルの役割を果たしています。
これらは電波を利用して通信を行う技術です。
電波は目には見えないけれどもこういった技術を利用することで、通信業者が設置した電波塔や家にある Wi-fi ルータとスマホやノート PC は接続、つまり上で示した画像のように糸電話で会話することで、インターネットが利用できる状態にあるのです。

## ネットワークの基本概念

さて、ここから改めてネットワークの基本概念について触れていきます。

### ネットワークの定義

ネットワークとは、複数のコンピュータやデバイスが互いにデータをやり取りできるように接続されたシステムを指します。ネットワークの目的は、情報の共有やリソースの効率的な利用を可能にすることです。例えば、インターネットは世界中の無数のネットワークが相互接続された巨大なネットワークの集合体です。

### ネットワークの重要性と役割

ネットワークは現代社会において非常に重要な役割を果たしています。以下の点でその重要性が強調されます：

1. **情報共有**: ネットワークを利用することで、企業や個人が簡単に情報を共有できます。例えば、メールやファイル転送などが代表的な例です。
2. **リソースの共有**: プリンタやストレージなどのハードウェアリソースをネットワーク上で共有することにより、コスト削減や効率的な運用が可能になります。
3. **コミュニケーション**: ネットワークを利用することで、音声通話、ビデオ会議、インスタントメッセージングなど、さまざまなコミュニケーション手段が提供されます。
4. **データの一元管理**: ネットワークを通じてデータベースを一元管理し、組織内のすべてのユーザーが最新のデータにアクセスできるようにすることができます。
5. **ビジネスの効率化**: ネットワークは、サプライチェーンの管理やオンライン販売など、ビジネスプロセスの効率化に寄与します。

# まとめ

ネットワークは、コンピュータやデバイスを互いに接続し、情報やリソースの共有を可能にするシステムです。
その重要性は、情報共有、リソースの共有、コミュニケーションの促進、データの一元管理、ビジネスの効率化など、多岐にわたります。
現代の社会やビジネスにおいて、ネットワークは欠かせない基盤となっており、その理解は IT の基礎知識として非常に重要です。

本記事を通して、ネットワークを改めて見直し、興味を持って次のステップに進んでもらえてらと思います。
SpringBootTest + JUnit5のbeforeAllでDataSourceをinjectionしてテスト用DB初期化

# 解説

下記ドキュメントにあるように、```@ExtendWith(SpringExtension.class)```（```@SpringBootTest```はこれを含む）とJUnit 5を組み合わせる場合、テストメソッドやライフサイクルコールバックにinjectionが可能となっている。

> Dependency injection for test constructors, test methods, and test lifecycle callback methods. ? See Dependency Injection with the SpringExtension for further details.
> 
> https://docs.spring.io/spring-framework/reference/testing/testcontext-framework/support-classes.html#testcontext-junit-jupiter-extension より抜粋

> Specifically, the ```SpringExtension``` can inject dependencies from the test’s ```ApplicationContext``` into test constructors and methods that are annotated with Spring’s ```@BeforeTransaction``` and ```@AfterTransaction``` or JUnit’s ```@BeforeAll```, ```@AfterAll```, ```@BeforeEach```, ```@AfterEach```, ```@Test```, ```@RepeatedTest```, ```@ParameterizedTest```, and others.
> 
> https://docs.spring.io/spring-framework/reference/testing/testcontext-framework/support-classes.html#testcontext-junit-jupiter-di より抜粋

以下はTestcontaniersでの使用例。```@BeforeAll```で```DataSource```をinjectionしてテーブルに初期データを投入している。```@Test```でも同様なinjectionをしている。

```java
import javax.sql.DataSource;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.testcontainers.containers.OracleContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@SpringBootTest
@Testcontainers
class SpringBootInitBeforeAll {

  @Container
  @ServiceConnection
  static OracleContainer oracle = new OracleContainer("gvenzl/oracle-xe:21.3.0-slim-faststart")
      .withInitScript("create_table.sql");

  @BeforeAll
  static void beforeAll(
      @Autowired DataSource ds,
      @Autowired ResourceLoader loader) {
    ResourceDatabasePopulator populator = new ResourceDatabasePopulator(
        loader.getResource("classpath:init_sample.sql")
    );
    populator.execute(ds);
  }

  @Test
  void test(@Autowired DataSource ds) {
    Integer v = JdbcClient.create(ds).sql("select count(*) from emp").query(Integer.class).single();
    System.out.println(v);
  }
}
```

# 参考リンク
- https://docs.spring.io/spring-framework/reference/testing/testcontext-framework/support-classes.html#testcontext-junit-jupiter-extension
- https://docs.spring.io/spring-framework/reference/testing/testcontext-framework/support-classes.html#testcontext-junit-jupiter-di
- https://agohack.com/how-to-execute-sql-scripts-once-before-in-spring-test/
- https://stackoverflow.com/questions/29340286/how-to-autowire-field-in-static-beforeclass
AI時代のプログラム初心者

齢３７にして初めてプログラマーとして求人に臨んでいますがなかなか書類選考で落ちる。
githubのリボジトリはAIに書かせたものを中心に載せています。
某サイトの年収評価は620-720万と初心者とは思えない評価をされるんですよ。
豆腐文字が倒せない・・・？

# 豆腐文字？
あなたは、豆腐文字　をご存じでしょうか？？

こういうやつです⇒（□□）

Pythonのmatplotlib を使ってグラフを作成すると
おおよそ日本語に対応していないフォントなので
□□　になっていまうこと　ありますよね・・・。

「matplotlib 文字化け」等で検索すると、便利ライブラリ「japanize-matplotlib」を使った解決法があります。
また、日本語に対応しているフォントを追加して、手動で設定する方法もあります。

ー参考記事ー

https://qiita.com/uehara1414/items/6286590d2e1ffbf68f6c

https://qiita.com/katuemon/items/5c4db01997ad9dc343e0

公式：japanize-matplotlib

https://pypi.org/project/japanize-matplotlib/



これで解決することが多いのですが、ドツボにはまってどうしようもない・・・
という方向けの記事になります！

# AWSのSagemaker Studio　でドツボにはまった。

上記手段を試しても、うまく日本語表示ができない時期があり、今回紹介する方法で乗り切っていました。

# 対応方法

★日本語を使わずに、日本語として理解できればOKじゃん！

ということで、ローマ字表記に変換　しました💡

# 事例
以下のような列をもつデータがあったとします。
これをChatGPTの力を借りて変換します！

変換前
```
2015年（平成27年）の人口（組替）
5年間の人口増減数
5年間の人口増減率
面積（参考）
人口密度
平均年齢
年齢中位数
```

変換後
```
2015nen(Heisei27nen)-no-jinko(kumikae)
5nenkan-no-jinkozougensu
5nenkan-no-jinkozougenritsu
menseki(sanko)
jinkomitsudo
heikinnenrei
nenreichuiisuu
```

★なんとなく読めますよね・・・ね！



ー変換に使ったプロンプトー
```
以下の列名をローマ字表記に変換してください。
例：5年間の人口増減数　⇒　5nenkan-no-jinkozougensu

2015年（平成27年）の人口（組替）
5年間の人口増減数
5年間の人口増減率
面積（参考）
人口密度
平均年齢
年齢中位数
```


ー参考コードー
```Python
import pandas as pd

# 元の列名
columns = [
    '2015年（平成27年）の人口（組替）',
    '5年間の人口増減数',
    '5年間の人口増減率',
    '面積（参考）',
    '人口密度',
    '平均年齢',
    '年齢中位数'
]

# 変換後の列名
columns_romaji = [
    '2015nen(Heisei27nen)-no-jinko(kumikae)',
    '5nenkan-no-jinkozougensu',
    '5nenkan-no-jinkozougenritsu',
    'menseki(sanko)',
    'jinkomitsudo',
    'heikinnenrei',
    'nenreichuiisuu'
]

# サンプルデータフレームの作成
data = {columns[i]: [i] for i in range(len(columns))}
df = pd.DataFrame(data)

# 列名をローマ字表記に変換
df.columns = columns_romaji

# 結果を表示
print(df)
```

# 終わりに
どうでしたでしょうか？　
ちょっとバカらしいですが、とりあえずは先に進むことができます・・・！
（ここが大事！）

というわけで、倒すのではなく、迂回ルートを通る感じの記事でした！
Windowsでバイオインフォマティクス(分子系統解析)の実行環境を構築する

## 背景
バイオインフォマティクスでは、MacBookの使用が推奨され、Windowsでの環境構築に関する情報が少ないです。この記事では、WSL2を使用して、Windows PCで分子系統樹解析を行うための環境構築方法を紹介します。バイオインフォをこれから始める人に向けて、丁寧に書いていきたいと思います。

## 動作環境
- Windows11
(Anaconda3のインストール後の操作は、Macの人も参考になると思います)

## 環境構築フロー
1. WSL2のインストール
2. Anaconda3のインストール
3. Anaconda3で解析用の仮想環境を構築
4. 各種パッケージのインストール

## 1. WSL2のインストール
WSL2とは、Windows Subsystem for Linux 2の略称で、Windowsコンピュータ上でLinux環境を構築することができます。Linuxと聞くとギョッとしてしまうかもしれませんが何も恐れることはありません!今までのWindows環境が壊れることもありません。
### 手順
1. Windows PowerShellを管理者として実行する
   <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602355/fc61b56c-29d2-1f60-71d1-3494fc59ad0d.png">
2. 以下のコマンドを実行
   ``` bash:Windows PowerShell
   wsl --install
   ```
3. 再起動

これだけです。UbuntuというLinuxディストリビューションが自動的にインストールされます。ユーザー名とパスワードを設定しましょう(アルファベット)。

## 2. Anaconda3のインストール
AnacondaはPythonの開発環境を一括でインストール・管理できるツールです。バイオインフォマティクスで使用するツールを簡単にインストールできます。また、環境構築に慣れないうちは、試行錯誤の過程で現在の環境を汚してしまうことが多いですが、Anacondaの仮想環境を使えばそのような心配をしなくても大丈夫です。

Anaconda3のインストールについては[このブログ](https://qiita.com/L40S38/items/32115e0683218c621d88)で詳しく紹介されています。この方法にならってインストールしてみましょう。

## 3. Anaconda3で解析用の仮想環境を構築
実際に仮想環境を構築します。一行目のコマンドはpythonのバージョンを3.12に指定し、「bioinfo」という名前の仮想環境を構築します。二行目のコマンドは、「bioinfo」の仮想環境を起動します。コマンドラインの先頭が`(base) $`から `(bioinfo) $`に切り替わったと思います。このコードを使用する場合は「$」以降をコピペしてください。
```bash:Ubuntu
(base)$ conda create -n bioinfo python=3.12 
(base)$ conda activate bioinfo

```
## 4. 各種パッケージのインストール
「bioinfo」の仮想環境に、分子系統解析に必要なパッケージをインストールしていきます。私は普段、以下の用途の時に右のパッケージを使用しています。他にインストールしたいパッケージがあれば、[ここ](https://anaconda.org/bioconda/repo)からパッケージを検索してインストールしましょう。
| 用途 | パッケージ|
|:-:|:-:|
| 配列クラスタリング | cd-hit |
| アラインメント | mafft |
| ギャップ除去 | trimal |
| 系統樹推定 | iqtree |

以下コマンドで実際にインストールできます。このコマンドを使用する場合は「$」以降をコピペしてください。
```bash:Ubuntu
(bioinfo)$ conda install bioconda::cd-hit -y
(bioinfo)$ conda install bioconda::mafft -y
(bioinfo)$ conda install bioconda::trimal -y
(bioinfo)$ conda install bioconda::iqtree -y
```

実際にmafftのインストール成功を確認します。`mafft -v`と入力し、mafftのバージョンが表示されれば成功です。
```bash:Ubuntu
(bioinfo)$ mafft -v
------------------------------------------------------------------------------
  MAFFT v7.505 (2022/Apr/10)
  https://mafft.cbrc.jp/alignment/software/
  MBE 30:772-780 (2013), NAR 30:3059-3066 (2002)
------------------------------------------------------------------------------
~~省略
```


## (おまけ)仮想環境の抜け方、削除
「bioinfo」の仮想環境から抜けるときは、`conda deactivate`と入力します。
特に出力はありませんが、コマンドラインの先頭が`(bioinfo) $`から `(base) $`に切り替わったと思います。この時、再度`mafft -v`と入力するとエラーが出力されます。

```bash:Ubuntu
(bioinfo)$ conda deactivate
(base)$ mafft -v
bash: mafft: command not found
```

仮想環境を削除する時は以下のようにします。この環境が不要になったときや、pythonのバージョンの不一致により一部パッケージがインストールできないときは、仮想環境を消してしまいましょう。
```bash:Ubuntu
(base)$ conda remove -n bioinfo
```

## まとめ
Windowsでバイオインフォマティクスの実行環境を構築する方法について説明しました。Anacondaを使用しましたが、もちろんMinicondaでも大丈夫です。仮想環境を使用すれば、既存の環境を汚さずに環境構築できるので、初めての人こそ挑戦してみましょう!
【Python】論理演算

論理演算とは、ブール値(TrueまたはFalse)を操作する演算のことです。主な論理演算子は以下の3つです。
- and: 論理積(AND)
- or: 論理和(OR)
- not: 論理否定(NOT)
# 論理積 (AND)
2つの条件がともに真(True)の場合のみ真となり、そうでない場合は偽(False)となります。
```python
print(True and True)     # True
print(True and False)    # False
print(False and True)    # False
print(False and False)   # False
```
# 論理和 (OR)
2つの条件のどちらか一方も真(True)であれば真となり、両方が偽(False)の場合のみ偽となります。
```python
print(True or True)      # True  
print(True or False)     # True
print(False or True)     # True
print(False or False)    # False
```
# 論理否定 (NOT)
条件を反転します。真はを偽に、偽を真にします。
```python
print(not True)          # False
print(not False)         # True
```
これらの論理演算子は、プログラムの制御フローを構築する場合に選択します。たとえば、次のように複数の条件を割り当てることができます。
```python
age = 17
has_license = False

if age >= 18 or has_license:
    print("運転できます")
else:
    print("運転できません")
    
# 出力: 運転できません
```
代わりに、`age`が`18`以上、または`has_license`が`True`の場合に「運転できます」と出力されます。論理和( or)を使うことで、複数の条件をまとめて評価しています。
論理演算はプログラミングで頻繁に使われる基本的な概念です。ぜひ他の例も試しながら、理解を深めてください。
######
参考)　[東京工業大学情報理工学院 Python早見表](https://chokkan.github.io/python/index.html)
VMware Workstation Proダウンロード（from Broadcom)

Broadcom社（旧Vmware社）が VMware Workstation Pro の個人利用を無償化すると発表がありましたが、ダウンロードの方法が分かったので手順をメモする。

https://www.itmedia.co.jp/news/articles/2405/15/news132.html

# 1. Broadcomサポートポータルにログイン

 https://support.broadcom.com 

:::note info
ログインするにはアカウントを作成する必要があります。
:::

# 2. ドロップダウンメニューより `VMware Cloud Foundation` を選択する
![get_attachment_content.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/22e66746-e2e7-577f-871a-e66214a10e9d.png)

# 3. サイドナビゲーションメニューより `My Downloads` を選択、製品一覧より `Vmware Workstation Pro` を選択する
![スクリーンショット 2024-06-14 213451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/c58930dc-0e46-1b78-be88-f4668221a612.png)

# 4. `Products`タブより`Vmware Workstation Pro 17.0 for Personal Use (Windows)` を選択する

:::note info
Personal Use と記載された方を選択しないと、無償でダウンロードすることができません。
:::

![スクリーンショット 2024-06-14 213927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/afd65f7c-0a5e-43c7-bbb2-0d5e5d00db99.png)

# 5. Releaseバージョン `17.5.2` を選択する

# 6. `I agree to Terms and Conditions` をチェックして、ダウンロードボタンを押す

![スクリーンショット 2024-06-14 213819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/b3b6df62-6372-827c-e0db-917167c857c7.png)
【個人開発】ニコニコ動画が簡易復旧したらしいので動画を変換できるツールを作ってみた

**(※この記事はnoteにも同じものを転載しています。)**

こんにちは。今日の午後簡易的ですがようやくニコニコ動画が復旧しました。
URLを見るとなんかいろいろできそうだったのでツールを作ってみました！。

## ニコニコ動画 Re:仮 URL変換ツール (unofficial)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518724/d9bb3f9e-28cf-13fc-cb4d-64fb7e7371b3.png)

https://ogatomo.net/nicorekari/?utm_source=qiita&utm_medium=link&utm_campaign=nicorekari

これはニコニコ動画のURLを入れると簡易版のリンクに変換できるツールです。簡易版で見れるのはごく一部ですが有名な奴は入ってることが多いのでこれで変換したらわざわざ探さなくても見れます。

たとえば ```https://nicovideo.jp/watch/sm9``` といれると「新・豪血寺一族 -煩悩解放 - レッツゴー！陰陽師」が見れます。

## 動画リスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518724/c9977aa5-5eea-4871-f83b-8becb7d27324.png)
こんなことをするのがめんどくさい人向けに事前に僕が動画を手動でリスト化しNotionにまとめておきましたのでこちらもご活用ください。

## まとめ
とりあえず簡易的でも復旧されたことはめちゃくちゃうれしいです。本復旧も頑張ってほしいです！
それでは！
【Pyhton】比較演算とブール値

# 比較演算
比較演算子は、2つの値を比較するための演算子です。

`==`: 等しい
`!=`: 等しくない
`>`: 大きい
`<`: 小さい
`>=`:以上
`<=`:以下

例えば、次のようなコードを書くことができます。
```python
x = 5
y = 10

print(x == y)  # False
print(x != y)  # True
print(x > y)   # False 
print(x < y)   # True
print(x >= y)  # False
print(x <= y)  # True
```
出力は以下のようになります。
```console
False
True
False
True 
False
True
```
# ブール値
ブール値とは、True(真)かFalse(偽)の2つの値をとる値のことです。Pythonでは、比較演算子の結果はブール値になります。

例えば、次のようなコードを書くことができます。
```python
is_raining = True
has_umbrella = False

if is_raining and has_umbrella:
    print("外出できます")
else:
    print("外出できません")
```
この場合、出力は外出できませんとなります。したがって、`is_raining`は`True`ですが、`has_umbrella`は`False`選択します。and演算子は、選択した条件の`True`時のみ`True`選択します。上の場合に`is_raining`は`True`でも`has_umbrella`がFalseなので、and演算子の結果に`False`なります。そのため、`else`のブロックが使用され、「外出できません」と出力されます。

比較演算子とブール演算子プログラミングの基本的な概念ですが、とても異なります。他にも例えば、リストやディクショナリーなどのデータ構造に含まれる際にも使用されます。練習を重ねることで、確実に理解が深まっていくでしょう。
######
参考)　[東京工業大学情報理工学院 Python早見表](https://chokkan.github.io/python/index.html)

https://qiita.com/Akuuuun/items/2e6bdbeb05ee79fd2fb7
Linuxでインバウンド帯域制限

https://www.uramiraikan.net/Works/entry-1988.html

の写経です。

まず、tcコマンドを使えるようにするには`iproute-tc`をインストールします。

```bash
# dnf install iproute-tc
```

`nwlimit.sh`としてファイルを保存します。

```bash:nwlimit.sh
#!/bin/bash
SWITCH=$1        # "on" or "off"
DEVICE=$2        # "eth0", "br0", etc.
RATE=$3        # for example "1000m"
 
if [ "$SWITCH" = "on" -o "$SWITCH" = "off" ]; then
   echo "--- Initialize $DEVICE and ifb0 ---"
   tc qdisc del dev $DEVICE ingress handle ffff:
   tc qdisc del dev ifb0 root handle 1: htb
   sleep 3
   rmmod ifb
else
   echo "Usage: $0 <on|off> <interface> <rate>"
fi
  
if [ "$SWITCH" = "on" ]; then
   echo "--- Load ifb module ---"
   sleep 3
   modprobe ifb
   sleep 3
   ip link set dev ifb0 up
  
   echo "--- Mirror $DEVICE to ifb0 ---"
   modprobe act_mirred
   sleep 3
   tc qdisc add dev $DEVICE ingress handle ffff:
   tc filter add dev $DEVICE parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
  
   echo "--- Traffic Shape ifb0 ---"
   tc qdisc add dev ifb0 root handle 1: htb default 10
   tc class add dev ifb0 parent 1:1 classid 1:10 htb rate ${RATE}bit
fi
 
exit
```

実行権限を付与して準備完了です。

```bash
# chmod +x nwlimit.sh
```

10mbitに帯域制限

```bash
# ./nwlimit.sh on eth0 10m
```


帯域制限確認

```bash
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install speedtest-cli
(venv) $ speedtest --no-upload
Download: 9.32 Mbit/s
```

帯域制限解除

```bash
# ./nwlimit.sh off eth0
```
PostgreSQLをWindows11にインストールしてみた

# はじめに
最近個人製作（という名の遊び）でWebアプリ開発の勉強をしているのですが、その過程で自分のWindows11にPostgreSQLをインストールしました。
QiitaEngineerFesta2024 のネタになるので中身の無い記事ですが、アウトプットを兼ねて手順を記録したいと思います。

https://qiita.com/official-campaigns/engineer-festa/2024

# PostgreSQLとは
PostgreSQLは、オープンソースのリレーショナルデータベース管理システム（RDBMS）です。他の一般的なRDBMS（例えばMySQL）と比べ、PostgreSQLはオブジェクトリレーショナルデータベース（ORDBMS）という特徴を持っています。これにより、リレーショナルデータベースの機能に加えて、オブジェクト指向の概念を取り入れたデータ管理が可能です。
オブジェクトリレーショナルデータベース（ORDBMS）はユーザー定義型や継承、関数のオーバーロードといったオブジェクト指向の概念を扱うことができ、柔軟で複雑なデータ構造を扱うのに適しています。これにより、PostgreSQLはリレーショナルデータベースの利点を保持しながら、より高度で柔軟なデータモデルを提供します。

# インストール手順

1. **ダウンロード**: [ダウンロードページ](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads)からPostgreSQL 16.3を選び、Windows用のインストーラーをダウンロードします。
2. **インストーラーの実行**: ダウンロードしたファイルをダブルクリックしてインストーラーを起動します。
3. **セットアップウィザード**: セットアップウィザードに従って進めます。基本的には「次へ」をクリックし続けるだけですインストールが完了しました。
   - **インストール先フォルダ**: デフォルトのままで進めた
   - **コンポーネントの選択**: 表示されるすべてのコンポーネントを選択したままで進めた
   - **データディレクトリ**: 最初から選択されている`Program Files`配下のままで進めた
   - **パスワード設定**: データベーススーパーユーザー（postgres）のパスワードを設定。後にDBを触るときに使用する。
   - **ポートの指定**: DBを使用するクライアントからの接続を受け付けるポート番号の指定。デフォルトで`5432`となっていたのでそのままでインストールを進める。他ソフトやアプリ（旧VerのPostgreSQLなど）でポートが使用されている場合は変更したほうが良いかも
   - **ロケールの設定**: ロケール（ユーザーインターフェイス用の言語別または国別の基本設定のセット）はDefaultかJapanを指定しようとしたが、日本語にすると処理が遅くなるようなので`C`を選択
4. **インストールの完了**: インストールサマリーを確認しNextをクリックするとインストールが実施され無事完了しました。

## 環境設定の追加
インストールが完了すると`すべてのアプリ`の中に`Postgres16`が追加されていると思います。

|すべてのアプリ|
|:---:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/b5bef09a-5d03-b56d-b317-6ace8989e2f2.png)|

この中で`SQL Shell(psql)`をクリックしてコマンドラインを呼び出しDBの操作をすることができますが、PowerShell等でも使用できるようにするため環境変数にPostgreSQLを追加します。

|環境変数名の編集|
|:---:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/361181bb-8fa3-1356-e86c-d1864c0bcac5.png)|



# インストール後の確認方法
インストールが確認できたので`psql`コマンドでサーバーの確認をしましょう。


#### 簡単なクエリの実行
新しいデータベースに接続し、簡単なSQLクエリを実行して動作を確認します。

```terminal
psql -U postgres
```

```
postgres=# \list
```
と入力するとデータベース一覧が表示されると思います。
技術記事を書くと「使える武器」が増える

## はじめに

◆この記事は何？
技術記事を書くことが未来の自分にどのように役立つかを紹介します。

◆対象は？
エンジニア
特に技術記事を書くモチベーションに悩んでいる人

## 先に結論
- 技術記事を書くと、**知識や経験が説明できる状態**になる
- ただの武器ではなく、「**使える武器**」を増やすために技術記事を書く

## 「使える武器」になる理由

技術記事を書くと、知識や経験が「使える武器」になる理由を5つ挙げます。

**①理解の深化**
技術記事を書くことで理解が深まっていきます。
説明するためには、深い理解が必要だからです。

「知る、わかる、できる、教える（能力開発の４つのステップ）」という記事が参考になります。

https://globis.jp/article/5149/

**②記憶の定着**
アウトプットすることで記憶に残りやすくなります。
記事を書くときに、何度も調査を行います。その結果、知識が定着しやすくなるためです。

例えば、私は次の記事を書く際にWebに関する書籍を複数冊リサーチしました。
その結果、webに関する書籍の関係性について説明できるようになりました。

https://qiita.com/mkt_hanada/items/d08e409fe90e829f5d34

**③再利用の易化**
誰かに説明しようとすることで、知識や経験が説明できる状態になります。
その結果、リファレンスとして使用できます。
リファレンス自体も「使える武器」ですが、リファレンスとして使用すればするほど定着が図れます。

例えば、私は次の記事を書いた後にリファレンスとして何度も使用しています。
結果的に、メタモルフィックテスティングなどは何も見ずに説明できるようになりました。

https://qiita.com/mkt_hanada/items/c416d3d4494ecc4217e3

**④フィードバックの獲得**
記事を書いた結果、フィードバックをもらえることがあります。
理解の誤りを修正できたり、新しい視点を得たりできます。

例えば、次の記事を書いたとき、「サンプルコードを活かすには？」という観点でフィードバックをいただきました。記事では触れていない視点でした。新たな視点になり、記事を振り返るきっかけになり、また新しい視点も「使える武器」として増えました。

https://qiita.com/mkt_hanada/items/a190c869467ce23242c0

**⑤発信をきっかけにした機会の獲得**
技術記事を発信することで、周りから機会をいただけることがあります。そうすると、次の実践の機会を得られます。

例えば、次の記事を書いたとき、「Wikiについて相談させて欲しい」等の相談をたくさんいただきました。
その結果、アウトプットの回数をさらに増やすことができました。

https://qiita.com/mkt_hanada/items/44c20c4db78db9d6c024


## 技術記事ではなくデジタルノートではダメなのか

まだ技術記事を書く勇気がないときや、発信できない内容があるときは「デジタルノートへのアウトプット」が選択肢となります。

「使える武器」として、デジタルノートを整理することができます。

[「世界一流エンジニアの思考法」](https://amzn.asia/d/hHNoU2h)に書かれているように、見る人が欲しい情報の形式で整理するのがおすすめです。

> 私がメモをとるときは、つい「自分用の、自分がわかるため」の書き方をしがちだが、彼女のメモは、見る人が欲しい情報はこれだろうという形で整理されている。

## おわりに

この記事では、技術記事のメリットについて、未来の自分から見たときの観点で事例を紹介しました。

技術記事を書く人/技術記事を書こうと思う人が増えると嬉しいです。
少しでも参考になれば幸いです。
nginxのリクエスト上限サイズに引っかかった話

# nginxのデフォルト値について

:::note info
nginxのデフォルトのリクエスト上限サイズは**1MB**
:::

公式では以下で言及されている
[https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43805/307607de-ecb6-308d-3d42-c3ec703d9f0a.png)  
> (GPT4oによる翻訳)
>クライアントリクエストボディの最大許容サイズを設定します。リクエストのサイズが設定された値を超える場合、クライアントには413（Request Entity Too Large）エラーが返されます。このエラーはブラウザで正しく表示されない可能性があることに注意してください。サイズを0に設定すると、クライアントリクエストボディサイズのチェックが無効になります。

# 引っかかった経緯

リバースプロキシにnginx、サーバーはdotnetのシステムに画像データを送信したとき
「はて、dotnetのデフォルトリクエスト上限は30MBのはずなのに413が返ってきとる、、」
となっていました

画像データのサイズが大きすぎるのか？（それにしてもデカすぎだろ、、
⇒ やはり送っているサイズ自体は1.5M程度だったのでおかしいなぁ
⇒ dotnetサーバーのログ設定を変えてそもそもリクエスト到達してない、、
⇒ そういえばnginx使ってたなとエラーログをみる
上記の流れで気づいた次第でした

毎度のことですがきちんと公式ドキュメントを読んでいるに越したことはないですね😓
VMware Remote Console ダウンロード（from Broadcom)

Broadcomサポートポータル からの VMware Remote Console のダウンロード方法が分かったので手順をメモする。

# 1. Broadcomサポートポータルにログイン

 https://support.broadcom.com 

:::note info
ログインするにはアカウントを作成する必要があります。
:::

# 2. ドロップダウンメニューより `VMware Cloud Foundation` を選択する
![get_attachment_content.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/22e66746-e2e7-577f-871a-e66214a10e9d.png)

# 3. サイドナビゲーションメニューより `My Downloads` を選択、製品一覧より `Vmware vSphere` を選択する

![スクリーンショット 2024-06-14 212026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/00b08cd4-bc12-a2a0-5b33-41eb52266232.png)

# 4. `Products`タブを選択し、`VMware vSphere - Enterprise` を選択する

![スクリーンショット 2024-06-14 212314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/a0e5d2f2-7014-7361-df68-e79150a760a9.png)

# 5. Releaseバージョン `8.0` を選択し、`Drivers & Tools` タブを選択する

# 6. 一覧から `Vmware Remote Console 12.0.5` を選択し、ダウンロードボタンを押す

![スクリーンショット 2024-06-14 211721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987509/47313aac-d42a-035e-95e3-16674964d075.png)
私が考えるエンジニアプラン

# はじめに
お疲れ様です！
今日は、エンジニアとしてのキャリアをどう築いていくか、どんなスキルを身につけるべきか、そして最終的にどのような生活を送りたいかを書いみます。

# 目標
まずは、私のエンジニアとしての目標です。
明確な目標を決めることでエンジニアとしてのライフプランがより現実的なものになると思っています。

## 短期目標（1-2年）
**新しいプログラミング言語の習得**：例えば、PythonやGoなどの人気言語を学び、実務で使えるレベルに達する
**オープンソースプロジェクトへの貢献**: GitHubなどで他の開発者と協力し、実際のプロジェクトに携わることでスキルを磨く

## 中期目標（3-5年）
**フルスタック開発者としてのスキルアップ**: フロントエンドとバックエンドの両方のスキルを持ち、幅広いプロジェクトに対応できるようにする
**資格取得**: AWS認定や情報処理技術者試験などの資格を取得し、専門性を高める

## 長期目標（5年以上）
**リーダーシップスキルの向上**: チームリーダーやプロジェクトマネージャーとしての経験を積み、マネジメント能力を高める
**自分のプロダクトを持つ**: 自分のアイデアを形にし、独自のプロダクトを開発・運営する

## 最終的には
最終的には会社のCTOくらいの立場になりたいと思っています。
簡単なことではないですが、諦めてしまっては何も生まれないので目指します。
努力した結果慣れなければそれはそれで仕方ないかなと思っています。。

# スキルの習得と自己研鑽
## 継続的な学習
エンジニアリングの世界は日々進化するので、継続的に学習をする必要がありますよね。
特に、最高のエンジニアライフを送るには学習は必要だと思います。
新しい言語は知らなくていいやが通用する世界では戦いたくないので、日々の学習を大切にしたいです。
学習した内容を業務で使う、業務で使った内容をまた学ぶ。
この繰り返しでエンジニアとして成長していければいいかなと思っています。

**オンラインコース**: UdemyやCourseraなどのプラットフォームで最新の技術を学ぶ（インプット）
**技術ブログの執筆**: 自分の学んだことをブログにまとめ、アウトプットすることで知識を定着させる（アウトプット）

## 実践経験
学んだことを実践に移すことで、本当に理解できたかを確認する機会を持つようにします。
これをすることで、自分が理解できているのか理解できていないのかを客観的に確認することができます。

**個人プロジェクト**: 趣味のプロジェクトを通して新しい技術を試す
**ハッカソンへの参加**: 短期間で集中してプロジェクトを完成させる経験を積む

# ワークライフバランス
## 健康管理
長く健康でいるためには、身体と心の健康を保つことも大切にします。

**定期的な運動**: ジムに通ったり、ランニングを習慣にする
**メンタルヘルスのケア**: 瞑想や趣味の時間を取り、ストレスを軽減する

## 家族や友人との時間
仕事だけでなく、家族や友人との時間も大切にします。

**週末のアクティビティ**: 家族や友人と一緒に過ごす時間を確保する
**休暇の計画**: 定期的に休暇を取り、リフレッシュする

結論
最高のエンジニアライフプランは、明確な目標設定と継続的な学習、実践経験を通じて成り立ちます。
また、ワークライフバランスを保ちながら、財務計画もしっかりと立てることが重要です。
ゴールデンイメージってなんだっけを改めて調べてみた

# ゴールデンイメージとは？
事前に構成された環境をマシンイメージ化し、テンプレートとして使えるようにしたもの。
このイメージは、新しいハードウェアや仮想マシンに迅速にデプロイするための使用されるってことみたいです。

### ゴールデンイメージを使用することの利点
- 一貫性：全てのデプロイメントが同じ設定とソフトウェアを持つため、一貫性が保たれます。
- 時間と労力の節約：手動でのインストールや設定作業を省略できるため、時間と労力を節約できます。
- セキュリティと管理の容易化：標準された環境を保つことで、セキュリティ対策や管理が容易になります。

# 【本題】AWS上のゴールデンイメージは？
AWSにおけるゴールデンイメージは、Amazon Machine Image(AMI)と呼ばれています。
AMIは、特定のインスタンスの設定を保存したテンプレートで、以下の内容が含まれます。

- オペレーティングシステム(OS)：WindowsとかLinuxのこと
- アプリケーションソフトウェア：ソフトウェアとかミドルウェア、ツール、サービスなど
- アプリケーションサポートファイル：設定ファイルとかデータ

### AMIを使用することの利点
- 迅速なデプロイメント：新しいEC2を素早く展開できる
- 一貫性：複数のインスタンスに同じ設定とソフトウェアを適用できる
- スケーラビリティ：同じAMIから複数のインスタンスをスケールアウトできる
- バックアップとリカバリ：特定の状態を保存しておくことで、必要に応じて同じ状態にリストアができる

### ゴールデンイメージに入れるものが多いと？
アプリケーションソフトウェアとかミドルウェアなどイメージに含むものが多ければその分は作成時間がかかってしまうので、定期的に作成する場合は、イメージ作成の自動化やCI/CDを検討する必要があるよねって話になりそう。

### 自動化やCI/CD化を検討する上でどんな課題が出るの？
- CI/CD化は高スキルが要求される
- 既存自動化ツールの維持運用が必要になる
- ソフトウェア更新の都度、手動で構築やテストが必要になる
- 事前に問題検知ができず、本番運用後に問題が発生してしまう

### 自動化やCI/CD化の実現手段はどんなのがあるか調べてみる
- Packer + Ansibleでやる
- EC2 Image Builderを使う

# まとめると
Packer + Ansibleで今度検証してみよって話。
続編に期待。
[GitHub] pushした後にcommitとIssueを関連付ける

# Introduction
コミットメッセージに`#1`などIssueのIDを含めることで、コミットとIssueを関連付けられますね。
ですが、何気無くPushして「あ〜やってしまった」となることも。
そんな時はWebの方で操作して関連付けましょう。

# 方法
1. Issueに関連付けたいcommitを表示する（右端のCommits）
![コミットを表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454084/cee7f89f-1e4d-1c0f-a786-0dc308e59c4a.png)

1. 一覧が出るので、関連付けたいコミットをクリック
![コミット一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454084/aa5393d3-d4fc-107f-41de-e9e84fec1a85.png)

1. 下の方にあるコメントのところにIssueのIDを書く
![コミットのページの下部にあるコメントフォーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454084/e8e03f7f-ad4e-6150-eb67-244b3269f9df.png)

1. 「Comment on this commit」をクリックしてコメント

これで、Issueにコミットが関連付けられます。
以上。
【Linux入門】Sudoのダウングレード方法

# はじめに

[記事](https://qiita.com/kk0128/items/60e33562f8c34dce659a)執筆のために脆弱なSudoを使用した環境を作ろうとしたが、環境構築に手間取ったので備忘録として残しておきます。
Sudoのダウングレードなんて、する機会はないかもしれないが…

# 現状と最終目標

現状は`sudo 1.8.29`がインストールされている状態です。

```
[root@localhost ~]# sudo --version
Sudo バージョン 1.8.29
```

最終目標は`sudo 1.8.27`をインストールすることです。

# ダウングレード方法

特権ユーザーで操作します。
まず、リポジトリに目的のバージョンが無いことを確認します。

:::note info
リポジトリに目標のバージョンがある場合は、そこからダウングレード出来ます。
:::

今回は上位バージョンのみがリポジトリにありました。

```
# dnf list sudo
利用可能なパッケージ
sudo.x86_64                            1.9.5p2-1.el8_9                            baseos
```

指定バージョンのソースファイルをダウンロードします。
いくつかソースファイルを提供しているサイトがあるので各々で選択してください。
今回は下記サイトからダウンロードしました。

https://layers.openembedded.org/layerindex/recipe/107347/

```
# wget https://www.sudo.ws/dist/sudo-1.8.27.tar.gz
```

ダウンロードした圧縮ファイルを解凍します。

```
# tar -zxvf sudo-1.8.27.tar.gz 
```

現在インストールされている`sudo`を削除します。

```
# dnf remove sudo
```

:::note warn
場合によっては`sudo`パッケージは削除されないように保護されており、削除できないことがあります。

```
エラー: 
 問題: 操作は結果的に以下の保護されたパッケージを削除します: sudo
(インストール不可のパッケージをスキップするには、'--skip-broken' を追加してみてください または、'--nobest' を追加して、最適候補のパッケージのみを使用しないでください)
```

その際は、`/etc/dnf/protected.d/sudo.conf`ファイル削除後、再度`dnf remove`を実行してください。

```
# rm -f /etc/dnf/protected.d/sudo.conf
```

```
# dnf remove sudo
```
:::

先ほど解凍した`sudo`のディレクトリに移動します。

```
cd sudo-1.8.27
```

コンパイルしてインストールします。

```
# ./configure
# make
# make install
```

最後に`Sudo`のバージョンが目的の物か確認します。

```
[root@localhost sudo-1.8.27]# sudo -V
Sudo バージョン 1.8.27
```

ダウングレードに成功しました。

# 参考サイト

https://www.reddit.com/r/Fedora/comments/n9n0mu/how_do_you_remove_sudo/

https://www.reddit.com/r/Fedora/comments/n9bsau/i_want_to_delete_sudo/
【Java】言語未経験者が2ヶ月でJava Silver SE11に合格した話

# ■はじめに
Java Gold SE11取得を決意したついこの頃、そういえばと思い立って言語未経験から2ヶ月でJava Silver SE11を取得した時の勉強方法をまとめてみました。

※2024年7月追記
無事、Java Gold SE11 に合格しました！！
Java Gold 合格時の記事も投稿したので良かったらご参照ください！

https://qiita.com/kiiiiiinusu/items/084934166714de349f65

# ■この記事の対象者
・これからJavaの学習を始める方
・Java Silverの資格取得を考えている方

# ■もくじ
**1.資格取得を決意した理由**
**2.試験日までのスケジュール**
**3.学習ロードマップ**
**4.まとめ**

# 1.資格取得を決意した理由
元々開発志望で会社にアピールするためにJava Silverの資格取得を決意しました。
なんでJavaなの？といった疑問には、やはりJavaの案件が聞いていた中で多かったからという単純な理由でしかありません。
そもそも言語にこだわりはなく、開発をやりたかったから取っ掛かりはなんでも良かったというのもある。

# 2.試験日までのスケジュール
**学習期間：2ヶ月**
※仕事をしながらだったので1日の勉強時間は大体1～2時間程度、合計で多分120時間ぐらい

**学習内容：**
・1日目
勉強方法リサーチ&試験日の確定

・2日目～7日目
スッキリわかるJava入門 第3版 (スッキリわかる入門シリーズ)

・8日目～試験日前日まで
ひたすら黒本を周回（周回数は3、後は間違えた問題を重点的に解いた）

# 3.学習ロードマップ
※学習内容の詳細

**・1日目：勉強方法リサーチ&試験日の確定**
Javaについては何も知らなかったので、まず勉強方法のリサーチなどから始めました。
最初はBronzeから取得しようかとも思っていましたが、リサーチする中で最初からSliverに挑戦したほうがよさそうなことに気が付き、Sliverから受験することを決意。

調べた結果、Sliverは黒本だけやり込めば資格が取れそうなことがわかり、期間についてもJava経験者で2週間程度、未経験者でも早くて1ヶ月、長くとも3ヶ月ぐらいかければ取得できるような感じだったので学習期間は間を取って2ヶ月に設定しました。

:::note warn
学習期間を決めたら、即試験申し込み。
自分を追い込まないとダラダラと理由をつけて後回しにしてしまう未来が見えていたので、学習を開始する前に即試験日を決めて申し込みました。
※試験申し込みした時もどなたかの記事を参考にした気がするが、結構前の話なので覚えておらず…
:::

**・2日目～7日目：スッキリわかるJava入門 第3版 (スッキリわかる入門シリーズ）**
早速、黒本に取り掛かったらびっくら仰天、全然頭に入ってこないことに絶望。
元々リサーチした時にもし黒本最初からやって出来なそうであればまずはスッキリわかる入門シリーズをやってみようと思っていたのですぐに購入し、最初の1週間はそれをやりました。

**・8日目～試験日前日：ひたすら黒本を周回（周回数は3、後は間違えた問題だけ解く）**
2週目からはひたすら黒本をやりました。
スッキリわかる入門シリーズをやったことで、スッと頭に入ってきたので先にやってよかったかなと。

:::note info
1周目(～22日目)・・・正答率 3～4割
2周目(～36日目)・・・正答率 4～5割
3周目(～50日目)・・・正答率 6～7割
50日目～試験日前日・・・各章の間違えた問題だけをひたすら解く
※大体2週間で1周（第1章から第13章まで）してました。
　正答率は総仕上げ問題の第12章と第13章のものですが、各章の正答率も似たような感じでした。
:::

# 4.まとめ
結果合格ライン **63％** のところ、**76％** で合格出来ました！

これからJava Silverを取得しようとしている方に言えるのは１つ、**ひたすら黒本** です。
あとは、試験日を先に確定させて自分を追い込んで「やるしかねえ」と奮い立たせてください。**（←これ非常に重要）**

:::note info
※注意
2023年12月1日から、新しくJava Silver SE17の認定試験が開始されています。
SE17については2024年6月時点で紫本のみで、黒本はまだ出版されていないみたいですのでご注意ください。
:::

この記事が皆様の合格の一助になれば幸いです。
それでは、良い学習ライフを！！！
RDB に「ふるまいを記述する言語」としての JSON を格納することについて

JSON を RDB に格納するというのは、最近では一般的な手法になってきたのではないかと思います。ここでは、「JSON を使ってデータを格納する」という考え方から一歩進んで、「JSON でふるまいを記述する」という使い方を考えてみたいと思います。
この記事は実践経験を伴わない短いポエムであって、現実に適用する際にはここでは触れないさまざまな困難があるものと思いますが、考え方自体には有用性があるのではと思います。

## データとしての JSON カラム

JSON カラムを検討する際によく聞かれるのが、「データの柔軟性」です。たとえば、そのテーブルが扱うモデルにとってあまり本質的ではない付加的な属性を持つために JSON カラムを使うケースです。このようなケースでは、純粋にデータを格納するための手段として JSON を使っているといえます。
実際、ちょっとした属性の追加の際にカラムやテーブルを増やすことなく対応できますし、格納する属性がはっきりと定まっていない場合（たとえばユーザーごとに異なるカスタム属性を付与したい場合など）にも、柔軟に対応することができます。
今回はこうした「データとしての JSON カラム」の利点や問題点には触れず、もうひとつのユースケースを考えてみます。

## ふるまいとしての JSON カラム

もうひとつのユースケースとは、「ふるまいとしての JSON カラム」です。これは、JSON カラムを単なるデータではなく、ふるまいを記述した DSL としての JSON を格納するという考え方です。

たとえば、業務システムにおける顧客への通知機能を考えてみます。さまざまなイベントをトリガーとして、顧客が定義した通知先に通知を送信するというものです。
こういった場合にもトリガーや通知先を柔軟に記述するための JSON カラムというものが考えられますが、このカラムに格納されるのは、単なる顧客の付加的な属性ではなく、「顧客ごとにカスタムされたシステムのふるまい」です。つまり、ふるまいを記述した DSL としての JSON を採用することで、データではなく、システムのふるまいそのものを柔軟にするということです。

このようにデータからふるまいへと考え方を転換することによって、 JSON カラムに格納すべきものが明確になり、システムの柔軟性も増すのではないかと思います。

## 考慮が必要な事項

このような利用方法は魅力的ですが、さまざまな考慮事項が存在します。最後にその一部をここで考察してみます。

### なぜ JSON なのか？

この場合は、ふるまいを記述するために十分な表現力をもった言語であれば何でも良く、JSON のシンタックスを借りているにすぎないのですが、よい DSL を一から設計するのは大変骨が折れる作業ですし、その DSL を正しく処理する処理系をシステムに組み込むのも大変な作業です。 JSON であれば、基本的な構造をうまく考えてあげる必要はありますが、JSON をパースしたり、ふるまいを表すオブジェクトにマッピングしたりといった処理は、多くのプログラミング言語で簡単に実装することができます。また、JSON の読み方は知っているエンジニアも多いですから、理解しやすさという面でも優れています。このように JSON の表現力があれば十分なケースも多く、扱いも容易なことから、ふるまいを記述する言語として JSON を採用することは現実的な選択肢ではないかと思います。

### RDB の JSON サポートは必要か？

このように「ふるまいを記述する言語」としての JSON を使用する場合、 RDB のサポートは必要でしょうか。言い換えれば、この DSL の文法に依存したクエリを書くべきでしょうか？

「データとしての JSON カラム」を使う場合には、JSON カラムはあくまで単にデータを格納しているにすぎないのですから、その内容をクエリしたくなるのは当然であるといえます。
しかし、「ふるまいとしての JSON」を使う場合には、形式こそ JSON であれ、本質的にはこれは DSL なのですから、その内容をデータとしてクエリすることにはあまり意味はありません（これが JSON でなければ、 DSL の文法を RDBMS に解釈してほしいと考える人はおそらくいないでしょう）。
したがって、「ふるまいとしての JSON」には RDB のサポートはほとんど必要ないと考えて差し支えないと思います。

### とはいえクエリ書きたくない？

この「ふるまいとしての JSON」に対してクエリを書きたくなるのは、「システムがどのようなふるまいをするか」を知りたい場合です。たとえば先ほどの例でいえば、この顧客はどのようなイベントを通知のトリガとして持っているか、通知先のおおまかなタイプ（webhook, slack, メール, ...）はなにか？といったふるまいの概要的な情報をクエリ可能にしておくことは、システムの効率性の観点から重要かもしれません。
そういった場合は、 JSON の中身そのものをクエリ対象とするのではなく、ふるまいの概要を表すビューとしての簡単なテーブルを用意しておくのがひとつの方法ではないでしょうか。そうすれば、複雑な SQL を書くことなく、ふるまいの概要を効率的に取得することができます。ただし、その場合の整合性の担保は困難な問題になるかもしれません。
私が開発を手伝った、Webサイトについてお話

私が開発を手伝った、Webサイトについてお話
最近、自分の所属しているグループの連携をしたInfinity Sky GroupのWebサイトについて、同じアカウントだったら、ばれるかもしれないので、別途アカウントを作って投稿してみます
ほかの連携したグループの人も別のアカウントで投稿してたからいいかなぁと思い投稿した、まあ、ばれてもいいとおもうけど、一応ね
作成したホームページはISGのグループまあ、Infinityskygroupだね
URLはhttps://infinitysky-group.com/