OmniAICreator/Qiita-1.07M huggingface dataset:
C#でXMLをWordやPDFに変換する

XML（Extensible Markup Language）は、データの保存や転送に使用される汎用性の高いフォーマットです。XMLをWordに、またはXMLをPDFに変換することは、XMLデータをよりアクセスしやすい形式で表示する必要がある企業や個人にとって、一般的な要件です。このプロセスでは、構造化されたXMLデータを、MS Wordで読みやすく編集したり、PDFビューアで表示したりできる形式に変換します。この記事では、無償の.NETライブラリを使用して、**C#でXMLをWordまたはXMLをPDFにプログラム変換する方法**を紹介します。

* [C#でXMLをWord（DocまたはDocx）に変換する](#cでxmlをworddocまたはdocxに変換する)
* [C#でXMLをPDFに変換する](#cでxmlをpdfに変換する)

## 無料の.NET Wordライブラリの紹介
C#でXMLをWordやPDFに変換するには、[**Free Spire.Doc for .NET**](https://www.e-iceblue.com/Introduce/free-doc-component.html)ライブラリが必要です。以下のリンクからライブラリをダウンロードして手動でプロジェクトにリファレンスを追加するか、[NuGet](https://www.nuget.org/packages/FreeSpire.Doc/)経由で直接インストールすることができます。

https://www.e-iceblue.com/Download/download-word-for-net-free.html

## XMLをWordやPDFに変換する手順
1. 必要なネームスペースをインポートします；
2. **`Document`** クラスのインスタンスを作成します；
3. **`LoadFromFile`** メソッドでXMLファイルをロードする；
4. **`SaveToFile`** メソッドを使用して、XMLファイルをDoc/ DocxまたはPDFファイルに保存します。


## C#でXMLをWord（DocまたはDocx）に変換する
```csharp
using Spire.Doc;

namespace XMLtoWord
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Word文書を読み込む
            Document document = new Document();
            document.LoadFromFile(@"C:\Users\Administrator\Desktop\jellyfish.xml", FileFormat.Xml);

            // XMLファイルを.docファイルに変換する
            document.SaveToFile("XMLToWord.doc", FileFormat.Doc);

            // XMLファイルを.docxファイルに変換する
            document.SaveToFile("XMLToWord.docx", FileFormat.Docx2016);
        }
    }
}
```

***出力：***
![XMLToWord.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/6a0c58ca-9f3d-09c0-1a55-f1a8e76b724b.png)



## C#でXMLをPDFに変換する
```csharp
using Spire.Doc;

namespace XMLtoPDF
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Word文書を読み込む
            Document document = new Document();
            document.LoadFromFile(@"C:\Users\Administrator\Desktop\jellyfish.xml", FileFormat.Xml);

            // XMLファイルをPDFファイルに変換する
            document.SaveToFile("XMLToPDF.pdf", FileFormat.PDF);

        }
    }
}
```
***出力：***
![XMLToPdf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/a1bb8525-eb23-dea5-c328-44008ce34a97.png)

* * *

> C#/.NETによるWord文書の処理、変換、印刷機能については、こちらをご覧ください： 

https://www.e-iceblue.com/Tutorials/Spire.Doc/Spire.Doc-Program-Guide/Spire.Doc-Program-Guide-Content.html
【Git】git log --oneline

# はじめに
こんにちは！アメリカで独学でソフトウェアエンジニアを目指している者です。

現在Gitを勉強している中で、git log --onelineというコマンドがとても便利だと感じました。初めて知ったときの感動を記録しておこうと思い、この記事を書くことにしました。

# `git log --oneline` の詳細な説明
Gitを使い始めた頃、ローカルレポジトリやリモートレポジトリで何が起きているのかがわからず、混乱することがよくありました。その原因の一つは、現在のブランチの状況や履歴が視覚的に把握しづらかったことです。

`git log --oneline`コマンドを使うと、ローカルレポジトリやリモートレポジトリで何が起きているのかが簡潔に表示され、一目瞭然になります。

```bash
$ git log --oneline
563e30a (HEAD -> article_push, origin/article_push) Add article108
94f5a7f Add article107
5d3df91 Add article106
b32e70e Add article105
ce22e57 Add article104
```
上記の例では、以下の点がわかります：
* ローカルレポジトリのarticle_pushブランチが現在のHEAD（最新のコミット）を指している。
* リモートレポジトリのorigin/article_pushブランチも同じ最新のコミットを指している。

このコマンドによって、現在どのブランチがどのコミットを指しているかを簡単に把握することができます。例えば、リモートとローカルのブランチの同期状態を確認したいときにも便利です。


# まとめ
今回はgit のコマンドの紹介でした。gitはQiitaの記事だけでなく、rubyやSQL,RailsをGitHubにアップするために毎日使用しているので、抽象的なものが目に見えて何が起きているかわかって理解度が高まりました。
現在進行形でGitを勉強しているのでまた何かあれば記事にしたいと思います
EasyEDA Pro Online 版を使う その5 ネジ穴やロゴをパーツとして追加する


:::note
2024/10/16 追記
EasyEDA 記事の記事一覧を作りました。併せてご覧ください。

#「EasyEDA Pro を使ってみよう！ 記事 index」

https://qiita.com/nanbuwks/items/1832e7dd815be5675a52
:::

「EasyEDA Pro Online 版を使う その4 PCBを作成する」
https://qiita.com/nanbuwks/items/7897a852287b81f15ee1

では、M3 のネジ穴や OSHW ロゴを PCB に追加しました。その方法を解説します。

PCB にしかネジ穴は必要ありませんが、そのようなものでも基本的 Schematic にパーツとして追加する必要があるみたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c21c631e-1080-d450-c92b-ffb678f5b63b.png)

# メカニカルやロゴをパーツとして追加する


Schematic のパーツ選択画面で、「EasyEDA」を選んで検索します。
以下は HOLE で検索。「Public」の中にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a35d323e-d264-285d-d532-0b23baa658c1.png)

オープンソースハードウェアロゴは OSHW で検索できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/02d26b46-f5cf-910f-9024-b604543f0ee3.png)

その他、使えそうなロゴ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e2bcda18-2e97-6929-5946-0d268d7d6739.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1f70901f-5069-fb2d-ff0c-f9bf88bd5831.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/22fce088-ce69-9bb8-2637-35ba1e23edf6.png)

今回、3mmのネジ穴は HOLE_M3で検索したものから利用しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/619e9c93-7043-fc67-ccf0-eb1d55b96f0f.png)

このパーツは穴径が3mmなので、一般的な3.2mmのものは HOLE3.2 などで検索するのがオススメです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2d3b5fba-f8b4-779c-5fd4-8010120337f6.png)


OSHW ロゴはフットプリントに対応していないものも多いです。
検索時に、「Footprint：」に表示されていないものは Schematic に置いても PCB に反映されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5c628ae6-8964-6219-877c-6191ac34a5de.png)


今回はフットプリントに対応した 「SparkFun-Aesthetics_OSHW-LOGO_MINI OSHW-LOGO-MINI」 を使いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d115d3e5-8536-5404-c558-36a6a62e07c1.png)

塗りつぶされた小さいロゴです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/621f0e5c-4546-9521-fb3b-f63b1f5f8ca2.png)


# PCB でパーツ番号が表示されてしまう問題

パーツ番号のレイヤを Document Layer にしてしまうのが良いやり方っぽいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8810caf4-02f5-1be0-543a-99f239b22096.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/873df7a9-7f31-f212-9750-d460f9d1aba3.png)
材料力学「材料力学で、積分の1/3公式を使いますか。」をAI先生に聞きました。 あきらめました。??? シンプソンの1/3公式


**材料力学で、積分の1/3公式を使いますか。**

# ChatGPT先生へ
ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。

>(回答抜粋)
>1. はりのたわみの計算
>2. せん断力・曲げモーメントの計算
>3. エネルギー法の適用
>??? シンプソンの1/3公式

1. はりのたわみの計算 2. せん断力・曲げモーメント 3. エネルギー法の適用
の3種類の計算について、　sympyのソースコードを教えて下さい。

>1. はりのたわみの計算 例: 長さLの片持ちはりに一様分布荷重qがかかる場合のたわみを計算する。
```python
from sympy import symbols, integrate, diff, Function

# 記号の定義
x, L, E, I, q = symbols('x L E I q')
v = Function('v')(x)  # たわみ関数

# モーメント分布
M = -q * x**2 / 2

# たわみの微分方程式 EI * v'' = M
v_dd = M / (E * I)

# 1回積分 (角度の傾き)
v_d = integrate(v_dd, x) + symbols('C1')  # 積分定数C1

# さらに積分 (たわみ)
v = integrate(v_d, x) + symbols('C2')  # 積分定数C2

# 境界条件 (片持ちはりの固定端条件)
# x = 0 で v = 0, v' = 0
C1, C2 = symbols('C1 C2')
v = v.subs({C1: 0, C2: 0})

print("たわみ関数:")
print(v)
```
>2. せん断力・曲げモーメントの計算 例: 長さLの単純支持はりに集中荷重Pが中央にかかる場合。
```python
from sympy import Piecewise

# 記号の定義
P, a, L = symbols('P a L')
x = symbols('x', positive=True)

# せん断力分布
V = Piecewise((P, x < a), (0, x == a), (-P, x > a))

# 曲げモーメント分布
M = integrate(V, x)

print("せん断力分布:")
print(V)
print("曲げモーメント分布:")
print(M)
```
> 3. エネルギー法の適用
(途切れました)

どの部分が1/3公式ですか。
>(回答抜粋)
ご指摘ありがとうございます！提示したSymPyコード例では、シンプソンの1/3公式（積分の1/3公式）は使用していません。代わりに、...

あきらめました。
# Gemini先生へ

# copilot先生へ

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342) 　開発環境
# いつもと違うおすすめです。

#### wikipedia 

1/3公式に関する情報は、Wikipedia には記載されていません。﻿

#### 過去問

#### Google検索
1/3公式

https://www.google.com/search?q=1%2F3%E5%85%AC%E5%BC%8F+wikipedia&rlz=1CAUHAM_enJP1105&oq=1%2F3%E5%85%AC%E5%BC%8F%E3%80%80wikipedia+&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIKCAEQABiABBiiBDIKCAIQABiABBiiBDIKCAMQABiABBiiBDIKCAQQABiABBiiBNIBCTEwNDk1ajBqN6gCCLACAQ&sourceid=chrome&ie=UTF-8
Flask Debug Toolbarを使ってFlaskのアプリケーションを効率よくデバッグしよう！

## 概要
Flask Debug Toolbarを使うとローカル上のFlaskのアプリケーションを効率よくデバッグできます
今回はFlask Debug Toolbarの設定方法および利用方法について解説します

## 実装
以下のようにDebugToolbarExtensionを初期化します
app.debugをTrueにすればDebug Toolbarを使用できます

```main.py
import os

from flask_debugtoolbar import DebugToolbarExtension

app = Flask(__name__)
app.debug = os.environ.get("DEBUG")

app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY")
toolbar = DebugToolbarExtension(app)
```

## 実際に触ってみよう！
以下のようにDebug　Toolbarのサイドバーが表示されたら成功です

![スクリーンショット 2025-01-15 15.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/d2047bac-5b14-cc3a-f761-7508e7883ec4.png)

各パッケージの詳細、HTTPヘッダ、環境変数、APIのルートなどを確認できるので便利ですね

![スクリーンショット 2025-01-15 15.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/d66362e5-f8c1-c6cf-0a0e-88f82f6b0db6.png)

![スクリーンショット 2025-01-15 15.38.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/37093d45-4ac2-214b-9edc-33b92aca5515.png)

![スクリーンショット 2025-01-15 15.39.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/5a02b8f1-913d-cdb4-ea50-208667b415ba.png)

![スクリーンショット 2025-01-15 15.39.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/0cdbf286-7c6a-acef-1539-cc5349c8a73e.png)

## 参考
https://flask-debugtoolbar.readthedocs.io/en/latest/

https://github.com/pallets-eco/flask-debugtoolbar?tab=readme-ov-file
A5:SQL Mk-2でストアドプロシージャの実行

# 環境
- Oracle Database 23ai Free Release 23.0.0.0.0
- [A5:SQL Mk-2 Version 2.22.0](https://a5m2.mmatsubara.com/)

# 手順
SQLの実行モードをProcedure Modeに切り替える。もしくは、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31934/a87db16d-4184-d389-5cc1-2f3641c746d0.png)

SQL -> Run as Stored Prodedureに切り替える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31934/6e4e8984-19f1-7e2f-adfa-caff4ea7e12d.png)

実行したいストアドをbegin - endで囲んで実行する。

```sql
BEGIN
  DBMS_OUTPUT.ENABLE(buffer_size => NULL); 
  DBMS_OUTPUT.PUT_LINE('sample ');
END;
```

実行時の様子。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31934/27f7b569-1ae2-11e7-6f25-163a3d4cbceb.png)

参考URL

- https://a5m2.mmatsubara.com/wp/?topic=oracle%E3%81%AE%E3%82%B9%E3%83%88%E3%82%A2%E3%83%89%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%9F%E3%81%84

# 補足
`DBMS_OUTPUT.PUT_LINE` をA5:SQL Mk-2のconsoleに表示するにはbeginの後に`DBMS_OUTPUT.ENABLE(buffer_size => NULL)`などの設定が必要。

参考URL

- https://a5m2.mmatsubara.com/wp/?topic=dbms_output-put_line%E3%81%AE%E8%A1%A8%E7%A4%BA
- https://docs.oracle.com/cd/F52398_01/plsql-packages/dbms_output1.html#GUID-018FA2BF-CEF9-43A8-A352-7CCCE5167EAD

begin/endに加えてこういうのも実行可能。

```sql
DECLARE
  n NUMBER(11, 0);
BEGIN
  n := 123;
  DBMS_OUTPUT.ENABLE(buffer_size => NULL); 
  DBMS_OUTPUT.PUT_LINE('sample ' || n);
END;
```
laravel の Auth に Login のBAN機能をつけたら何故か /home にリダイレクトされる

# 環境
Laravel 7.30
PHP 8.0.30

# BAN機能の参考はこちら
https://dev.to/shanisingh03/how-to-ban-suspend-users-in-laravel-8-1gh3

# 起きたこと
BANユーザーが一度ログインすると、正常にエラーメッセージが吐き出されるが、
再度ログインしようとすると何故か /home にリダイレクトされる
※ /home は使ってない

# 修正
```/app/Http/Controllers/Auth/LoginController.php
    protected $redirectTo = RouteServiceProvider::HOME;
```
この一文を追加する

# 参考
https://qiita.com/TkTkTkTkTako/items/db4aaf69e5e12a0d1e6e

https://qiita.com/tomoeine/items/40a966bf3801633cf90f

https://qiita.com/TkTkTkTkTako/items/4ceec6af8aff2150c8cf

# 所管
Laravel のログイン周り魔境過ぎる
LTSPICEでハイパス、ローパスの回路シミュレーション(ascファイル付き)

# 初めに
とりあえずLTspiceを初めて最初にハイパスとローパスを作れと言われたので、作りました。参考に示すYouTubeを元にしていますので、ぜひ見てください!!

# 回路設計
以下のような回路を作成します。時定数は全て0.5μsにしています。
![スクリーンショット 2025-01-15 14.34.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914074/1f002d63-ce54-eaff-53a1-8e79817d8a0b.png)
抵抗はRキー、コンデンサーはCキーで選択、wireは左クリックして、draftのWiresから出してください。

## 電圧の設定
STYLEをSINEに変更し、DCオフセットを0V、AC電源の最大は1Vで周波数を1kにしてください。(周波数はac解析では無視されるので、選択しなくてもok)
![スクリーンショット 2025-01-15 14.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914074/b032f1af-8f1f-0ead-7f4d-dd9a55f98819.png)

## simulationの設定
simulationは次のようにAC電源の周波数を1Hzから1MHzで1桁あたり100測定点でシミュレーションします。コマンドは以下です。
```LTspice:LTspice
.ac dec 100 1 10Meg
```

## 実行結果
![スクリーンショット 2025-01-15 14.44.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3914074/d4521146-ba08-3651-7ae0-1b8530d34c78.png)

ざっくり、緑が入力電圧、青が出力電圧で、実線が電圧の入出力のスケール(dB)、点線が位相差(°)となっています。見るとハイパスとローパスの両方が入っています。

## コード
以下のgitにあります。
https://github.com/Y-Watanabe11/HPF1_LPF4

## 参考
LTSpice Simulation Passive RC component Band Pass Filter Frequency Phase Amplitude
by Circuit Simulations
https://www.youtube.com/watch?v=pU1PaPZndrE
スクラムとウォーターフォールの違いをゴルフで例えてみた

## はじめに
スクラムマスターをしていると、ウォーターフォール（以降、WF）しかやってこなかったメンバーがチームに入ってくることはよくあります。そのメンバーに対して、スクラムとWFの違いを理解してもらうためにどんな例で説明すればいいかなと考えていました。
双方の違いの例えとして、ケーキの話や車の話がありますが、今回はゴルフでWFとスクラムの違いを説明したものをまとめてみました。

## スクラムとWFをゴルフで例えると

![スクリーンショット 2024-09-26 13.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817856/d4fdbde1-f5f4-383d-5ea9-8919af1c1fa5.png)

* WFはドライバー
  * 要件定義〜受け入れテストまでをほぼ立ち止まることなく、一環して行う
* スクラムはアイアン
  * 1~4週間程度の一定の短い区間で動くものを作成し、それに対して確認を行なったり、作成までの過程を振り返ったりして、次に備える

![スクリーンショット 2024-11-06 13.23.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817856/ea56ca54-7be1-d262-3bad-c0b4c33581cc.png)

天候を複雑性と仮定し、天候が悪ければ悪いほど複雑性が高いとする。

* ドライバー（WF）を選択するのは天候が良い時
  * 仕様が明確の場合はスピード早く開発が可能 
* アイアン（スクラム）を選択するのは天候が悪い時
  * 短く区切るため、仕様の変更や要望の対応が柔軟
  * ミスや認識齟齬が発生した場合でも大きく崩れることはない

![スクリーンショット 2024-11-06 13.57.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817856/cf6c87a7-6dc7-5188-0df3-a28104d459fa.png)

* カップまでの距離が短い場合はアイアン（スクラム）の良さを活かしきれない
  * 大きくブレることがなく、打数も少ないため経験を活かす機会が少ない

--- 

## カップまでの計測の仕方

WF、スクラムのどちらかを選択したとしても、プロダクトゴールまでどれくらいかを知る必要があります。

![スクリーンショット 2024-09-26 13.38.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817856/a68c1ee8-3ace-d806-6a86-3e0e46535e99.png)

プロダクトゴールをカップとします。ティーオフからカップの位置を知るためには方向と距離を把握する必要があります。
カップまでの方向はプロダクトの仕様とすることはできます。
では、カップまでの距離はどう考えれば良いでしょうか？

--- 

![スクリーンショット 2024-09-26 13.38.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817856/c8508158-ebb4-012c-ebb5-927eb255604d.png)

カップまでの距離はWFだと工数（時間）、スクラムだとポイント（規模など）で計測します。

--- 

![スクリーンショット 2024-09-26 13.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817856/49adf8ff-43fa-6e12-1edd-92956e3800b8.png)

WFの場合、契約の兼ね合いでゴールの変更は基本不可のため概算見積もりが必要です。
一方、スクラムの場合、機能の増減や期日の延長/短縮とゴールの変更は基本可能です。
なので、見積もりは時間見積もりも早く見積もることができる、ポイント見積もりなどの相対的な方法で見積もりします。

## まとめ

WFとスクラムを天候（複雑性）と距離（開発期間）でどちらが適しているかを解説しました。
WFとスクラム、どちらも適している開発条件がありますが、WFが適している複雑性が低く、開発期間が短いプロジェクトは変化が激しい現代では少ないかと思います。WFからスクラムにシフトチェンジするプロジェクトが増えてきているのも、そういった現状があるからかと思います。

スクラムマスターとしては、スクラムに適していないプロジェクトを把握しておく必要があり、担当するプロジェクトがスクラムに適していない場合、WFやその他の開発フレームワークや手法を提案する必要があります。
【Splnuk】Lookup Table を用いた検索（CSVファイルの利用）

収集しているログデータに特定の記号などが含まれる（人が一見しただけでは何を意味するか分からない）場合に、ログの可読性を向上させる方法として、Lookup Table が有効なケースがあるかもしれません。ここでは、サンプルとしてFireWallのDeny Actionのログデータを取り扱い、ログ中にプロトコル番号として"proto=6"等の数字（これは [Internet Assigned Numbers Authority(IANA)](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml) によって管理・割り当てられているプロトコル番号）が記載されているケースを想定し、この数字をわかりやすくするために、より馴染みのあるプロトコルの名称（TCP、UDPなど）への変換を試みます。
```bach:サンプルログ
Jan 15 10:48:00 192.0.2.1 date=2025-01-15 time=10:48:00 type=traffic subtype=local level=notice vd=root srcip=203.0.113.1 srcport=28078 srcintf="wan" dstip=192.0.2.2 dstport=9468 sessionid=94504 action=deny service="9468/tcp" proto=6
```

※本記事で示す手順は、筆者が定めた最低限の可動要件を満たす設定と動作確認のみを目的として、自身の備忘用のレベルで記しています。運用性やセキュリティ上の細かな考慮等は省いている場合があります。もし各手順を試される場合には自己責任でお願い致します。


# Lookup Table（CSVファイル）の用意
 [Internet Assigned Numbers Authority(IANA)](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml)などの記載を参考に、CSVファイルを用意する。便宜的に、ファイル名を「protocol_number.csv」として作業端末のローカルに保存する。
 
```bach:CSVファイルのイメージ
proto,protocol_name
0,HOPOPT
1,ICMP
・・中略・・
6,TCP
・・以後、省略・・
```
 
# Lookup Table の導入
Splunkのダッシュボード画面から、[設定] -> [ルックアップ]を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/34b78f6c-4083-335d-a6f3-9e622090d16a.png)

[ルックアップテーブルファイル] -> [新規追加] を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/7e58899e-b95b-1071-6431-bf3211207165.png)

[ルックアップファイルをアップロード]で対象のCSVファイルを選択し、[宛先ファイル名]を入力の上で、[保存]を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/318d79c4-e520-ed22-3d2f-adf95afb96f8.png)

共有先は、プライベートのままでも問題ないかもですが、ここではシステムのどこからでも使えるように[グローバル]に変更しておきます。[権限]から編集を行い、[すべてのApp]を選択し、[保存]を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/bf9760e0-57c7-4d56-7b7b-3cb08341d04a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/793db744-4785-c8ad-b6ba-eac4890adbcc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/451d45b8-5387-b6cf-33f9-1754354926ad.png)


# 動作確認
実際に、冒頭で示したサンプルログに対して、Lookupを実行してみます。今回実行したSPL文では、"protocol_number.csv"という Lookup Table と元のログデータに含まれるprotoフィールドを紐付け、Lookup Table にある protocol_name フィールドを出力します。これにより、元ログのproto=6などの数値に紐づいて、"TCP" といったプロトコル名が出力されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507379/5f600b5e-8d37-ade1-63d0-b9fa9d87e906.png)

```bash:参考：動確に使用したSPL文
index=main "dstip=<ログ収集に使っているFirewallなどのIP>"
| lookup protocol_number.csv proto OUTPUT protocol_name
| table _time srcip dstip srcport dstport proto protocol_name action
```
# まとめ
Lookup Table を用いて、ログデータ中の値と紐づけて、検索結果全体の可読性を上げる方法についてご紹介しました。

- Lookup Table の用意
- Lookup Table の導入
- Lookup Table を用いた検索

ログデータ単体では出力結果がわかりにくかったり、思った様な分析が行えない場合に、ぜひ Lookup Table の活用をご検討ください。

# 参考
- [Internet Assigned Numbers Authority(IANA)](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml) 
- [Splunk Search Reference: Lookup](https://docs.splunk.com/Documentation/Splunk/9.4.0/SearchReference/Lookup)
WordPress「辿ったリンクは期限が切れています。もう一度お試しください。」エラー

# エラー内容・起こった状況

![スクリーンショット 2025-01-15 13.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979498/3253c808-f95f-30f0-63e0-1a3685b644b3.png)


> 辿ったリンクは期限が切れています。もう一度お試しください。

WordPress管理画面からCocoonテーマをアップロードしたところ発生。

# 構築環境

* AWSにてWebサーバー用のEC2（`AmazonLinux2023`）を作成して構築している
* WebサーバーにはApacheをインストールしている


# 結論

１. `php.ini`の`upload_max_filesize`と`post_max_size`の上限を変更

```Apache:php.ini
// 変更前
post_max_size = 8M
upload_max_filesize = 2M

// 変更後（サイズは自分のインストールしたいテーマに合わせる）
post_max_size = 20M
upload_max_filesize = 20M
```

２. 自分が使用しているプロセスマネージャーを再起動して反映させる

```terminal:Apacheのモジュールであるmod_phpを使用している場合
sudo systemctl restart httpd.service
```

```terminal:プロセスマネージャーであるPHP-FPMを使用している場合
sudo systemctl restart php-fpm
```

「１.」については記事が多く出てくるが、
「２.」についてApache周りの理解が浅くて気づくのに時間がかかったので記事にした

## 詳しい手順

### 1. `php.ini`の`upload_max_filesize`と`post_max_size`の上限を変更

```terminal:php.iniはetcディレクトリにある
cd /etc/
ls -la | grep "ini"
```

```terminal:編集する前にバックアップを取っておくのがおすすめ
cp php.ini php.ini-YYYYMMDDbkup
```

```terminal:vimやnano等、好きな方法で値を変更する
sudo vi php.ini

// 以下の2箇所を書き換える
post_max_size = 20M
...
upload_max_filesize = 20M
```

```terminal:差分確認
diff php.ini php.ini-YYYYMMDDbkup
```

### 2. 自分が使用しているプロセスマネージャーを再起動して反映させる

Apacheの`mod_php`モジュールあるいは、プロセスマネージャーの`PHP-FPM`どちらを使っているか確認して、使っている方に対して再起動をかける


```terminal:🔴Apacheのmod_phpモジュールを使っているか確認するコマンド
// mod_phpなどが表示されるか確認（何も出なければ使われていない）
httpd -M | grep php
```


```terminal:🔵プロセスマネージャーのPHP-FPMを使っているか確認するコマンド
// activeの場合、使われている
systemctl status php-fpm
```

``` terminal:🔴再起動（Apacheのmod_phpモジュールの場合）
sudo systemctl restart httpd.service
```

``` terminal:🔵再起動（PHP-FPMの場合）
sudo systemctl restart php-fpm
```

これで再度テーマをアップロードしたところ、成功した🎉

# PHP-FPMとは

## Apacheとの役割の違いは？

* ApacheはWebサーバーで、ユーザーからのリクエストを受け取って、HTMLや画像などのファイルを返す役割
* PHP-FPMはプロセスを管理する役割（PHPプログラムに特化）
    * 起動：プログラムを実行する際に、必要なリソースを割り当ててプロセスを開始
    * 監視：プロセスが正常に動作しているかを監視して、もし問題があれば、再起動したり、エラーメッセージを表示
    * 終了：プログラムが終了したり、必要がなくなった場合に、プロセスを適切に終了
    * リソース管理：CPUやメモリなどのリソースをどのプロセスにどれだけ割り当てるかを管理


## Apacheとの関係性は？

* Apacheは、PHP-FPMを「内包」しているのではなく、「連携」している
    * Apacheがリクエストを受け取ると、そのリクエストをPHP-FPMに渡して、PHPスクリプトを実行させ、その結果をApacheがクライアントに返している
* mod_phpよりも PHP-FPMの方が特化した機能を持っており優れている
    * nginxの場合は、PHP-FPMしかない
    * Apacheの場合、モジュールか、PHP-FPMかを選べる


 # まとめ

 * 上限の設定を変更操作した後に、再起動する対象は何かを理解する必要があった
     * 具体的にはApacheのモジュールmod_phpではなく、PHP-FPMというプロセス管理（PHP専用）に特化したプロセスマネージャーを導入していたので、そちらに対して再起動をかけて上限値を反映させる必要があった


同じように詰まった人の参考になれば幸いです。
be_anマッチャー

# be_an とは引数のクラスかそのサブクラスであるかを調べる
>```- (Object) be_a(klass)```

`be_an`としても知られる
>Also known as: be_an

`target.kind_of?(klass)`がtrueならば通る
>passes if target.kind_of?(klass)

https://rspec.info/documentation/3.3/rspec-expectations/RSpec/Matchers.html#be_a-instance_method:~:text=%5B%5D-,%2D%20(Object)%20be_a(klass),passes%20if%20target.kind_of%3F(klass),-%5B%5D

### kind_of?(klass)とは 指定されたクラスかそのサブクラスであるか
>kind_of?(mod) -> bool
>`オブジェクトが指定されたクラス mod かそのサブクラスのインスタンスであるとき真を返します`。

>また、オブジェクトがモジュール mod をインクルードしたクラスかそのサブクラスのインスタンスである場合にも真を返します。 Module#includeだけではなく、Object#extendやModule#prependによってサブクラスのインスタンスになる場合も含みます。上記のいずれでもない場合に false を返します。

```rb
irb(main):001* module M
irb(main):002> end
irb(main):003* class C < Object
irb(main):004*   include M
irb(main):005> end
irb(main):006* class S < C
irb(main):007> end
irb(main):008>
irb(main):009> obj = S.new
irb(main):010> p obj.is_a?(S)
irb(main):011> p obj.is_a?(C)
irb(main):012> p obj.is_a?(Object)
irb(main):013> p obj.is_a?(M)
irb(main):014> p obj.is_a?(Hash)
true
true
true
true
false
=> false   
```

https://docs.ruby-lang.org/ja/latest/method/Object/i/is_a=3f.html
【Wordpress】 wp_nonce_fieldの使用方法

**説明**  
`wp_nonce_field`関数は、フォームからのリクエストの正当性を確認するために、nonce（セキュリティトークン）を生成し、フォームに埋め込みます。フォームが送信されると、nonceも一緒にサーバーへ送信され、サーバー側でその検証が行われる。  
nonceは一度だけ使用できるトークンで、CSRF（クロスサイトリクエストフォージェリ）攻撃の防止に役立ち、セッションの乗っ取りや不正利用からユーザーを保護する。

**特徴**  
生成したnonceは以下の特性を持つ：  
- 一定時間後に無効化される  
- ユーザーごとに異なる  
- 特定のアクション（例: `submit_nonce_action`）と紐づけられる  

**使用方法**  
```php
<button type="submit" id="submit-button" name="submit" value="request">送信</button>
<?php wp_nonce_field( 'submit_nonce_action', 'submit_nonce_name' );  //nonceフィールドの設置 ?>
```

ユーザーが送信ボタンを押すと、nonceが含まれたデータはサーバーに送信される。サーバーはそのnonceを検証し、問題がなければ指定された関数（例: `my_function()`）を実行する。

```php
function my_function() {
    // いろいろな処理
}

add_action('after_setup_theme', function() {
    //フォームからの送信があるか確認
    if ( isset( $_POST['submit'] ) && $_POST['submit'] === 'request' ) {
        //nonceチェック、無効なら処理を中断
        if ( !isset( $_POST['submit_nonce_name'] ) ) return;
        if ( !wp_verify_nonce( $_POST['submit_nonce_name'], 'submit_nonce_action' ) ) return;

        //処理を実行
        my_function();
    }
});
```
このように、nonceを使うことでリクエストの正当性を確認し、セキュリティを強化できる。
Excel関数ショートカット

# Excel 関数に関するショートカットキー集

## 関数入力・編集
| 機能                                  | ショートカットキー   | 説明                                   |
|-------------------------------------|---------------------|---------------------------------------|
| 現在の日付を入力                      | `Ctrl + ;`          | アクティブなセルに現在の日付を入力します。 |
| 現在の時刻を入力                      | `Ctrl + Shift + ;`  | アクティブなセルに現在の時刻を入力します。 |
| 数式バーを表示して編集モードにする      | `F2`                | 選択したセルの数式を編集モードにします。   |
| 選択中のセル範囲を合計（オートSUM）   | `Alt + =`           | 選択範囲に自動でSUM関数を挿入します。    |
| 数式を計算結果に切り替える             | `Ctrl + Shift + U`  | 数式バーの展開や計算結果をトグルします。   |
| 数式を一括で表示                      | `Ctrl + ｀`         | シート内の数式を一括で表示/非表示します。（｀は日本語キーボードでは「@」キー） |
| 数式の中でセルを参照する（挿入時）      | `Shift + 矢印キー`   | 数式入力中にセル範囲を拡張します。         |

---

## セルや数式の複製・計算
| 機能                                  | ショートカットキー   | 説明                                   |
|-------------------------------------|---------------------|---------------------------------------|
| 上のセルの数式をコピー               | `Ctrl + D`          | アクティブセルに上のセルの数式をコピーします。 |
| 左のセルの数式をコピー               | `Ctrl + R`          | アクティブセルに左のセルの数式をコピーします。 |
| セル範囲の数式を再計算               | `F9`                | 現在のシート全体の数式を再計算します。     |
| 部分的に数式を計算                   | `Ctrl + =`          | 数式入力中に選択範囲の計算結果を確認します。 |
| 名前ボックスへ移動                   | `Ctrl + F3`         | 名前の定義（名前付き範囲）を作成・編集します。 |

---

## 絶対参照・相対参照の切り替え
| 機能                                  | ショートカットキー   | 説明                                   |
|-------------------------------------|---------------------|---------------------------------------|
| 絶対参照・相対参照を切り替え         | `F4`                | 数式内でセル参照の形式を変更します。（例: A1 → $A$1 → A$1 → $A1） |

---

## 関数作業効率化
| 機能                                  | ショートカットキー   | 説明                                   |
|-------------------------------------|---------------------|---------------------------------------|
| 数式ライブラリを開く                  | `Shift + F3`        | 挿入できる関数の一覧を開きます。         |
| 数式の中で次の引数へ移動             | `Tab`               | 数式入力中に次の引数フィールドに移動します。 |
| 数式の中で前の引数へ移動             | `Shift + Tab`       | 数式入力中に前の引数フィールドに移動します。 |
| 数式バーのヘルプを開く                | `Ctrl + A`          | 数式バー内で、関数のヘルプを開きます。     |

---

## その他便利なショートカット（関数関連）
| 機能                                  | ショートカットキー   | 説明                                   |
|-------------------------------------|---------------------|---------------------------------------|
| エラーセルを選択                     | `Ctrl + [`          | 数式のエラーが発生しているセルを選択します。 |
| 直接参照されているセルを選択         | `Ctrl + ]`          | 数式で直接参照されているセルを選択します。 |
| トレース矢印を表示（参照元セル）     | `Ctrl + [`          | 数式で使用しているセルのトレース矢印を表示します。 |
| トレース矢印を表示（参照先セル）     | `Ctrl + Shift + ]`  | 選択したセルを参照しているセルをトレースします。 |

---
S3 コマンドの基本的な使い方

## はじめに
S3の基本的なデータ取得や作成、アップロードなどのコマンドをまとめてみました。
S3 APIではなく、CLI

### Profile作成
awsコマンドを叩く際にprofileを指定しますが、そのprofileを事前にconfigureで作ります。
    
```powershell
# aws configureコマンド実行
aws configure --profile s3_user

# 以下の4項目を聞かれるので、設定
AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: アクセスシークレット
Default region name [None]: リージョン
Default output format [None]: json（だいたいDefaultはjson）
```

### S3のリスト取得

``` bash
単純な参照 末尾にスラッシュを付けるか付けないかで動作が変わります

・そのファイルorDIRの存在を確認する場合は、スラッシュ無し
aws --profile s3_user s3 ls s3://{bucket_name}/{path}
・DIRの配下のファイル一覧を見たい場合、スラッシュを付ける
aws --profile s3_user s3 ls s3://{bucket_name}/{path}/

再帰的に確認する場合 --recursiveオプションをつけると、DIR配下の全てのファイルリストが返却されます。
aws --profile s3_user s3 ls s3://{bucket_name}/{path} --recursive
```

### S3の単体ファイル取得

``` bash
aws --profile s3_user s3 cp s3://{bucket_name}/{path} {copy_path}

まとめて取得する場合、syncコマンドを利用
```

### S3に単体ファイル移動・コピー

``` bash
■移動
aws --profile s3_user s3 mv {local_file_path} s3://{bucket_name}/{target_path}

■コピー
aws --profile s3_user s3 mv {local_file_path} s3://{bucket_name}/{target_path}

まとめてアップする場合は、syncコマンドを利用
```

### S3のファイルsync
syncはパスを指定してファイルを転送します。

``` bash
■コマンドの基本形
aws --profile s3_user s3 sync {sync元のpath} {sync先のpath}

■aws s3へファイルをアップロードする場合(パスの末尾にスラッシュはつけない)
aws --profile s3_user s3 sync /home/www/target_dir s3://{buckect}/{sync_target_path}

■aws s3からファイルをダウンロードする場合(パスの末尾にスラッシュはつけない)
aws --profile s3_user s3 sync s3://{buckect}/{sync_target_path} /home/www/target_dir

syncするファイルの選別を行う場合、syncするファイルのパスに含まれる文字列で指定が可能です。
--exclude="*" 全てのファイルを除外する
--include="{target_dir_name}" syncするターゲットのDIRを含むファイルだけを指定する

ドライランのオプション指定で、syncのリハーサルが可能です。極力一発でのsyncはやめて、dryrunでファイルやターゲットが正しいかチェックしましょう。
--dryrun

■オプションの付け方
aws s3 sync hogehoge s3://hoge_buckect/hogehoge --exclude="*" --include="202407"
※一度全てのファイルを除外し、includeで202407がパスに含まれるものだけsyncする
※オプションの前後を入れ替えると動作が変わる為、注意

syncはdefaultではタイムスタンプやバイナリサイズなどを見るような動作をします。
syncオプションを付け替えると、sync対象の取り方が変わります。
```

### S3のファイル削除

```powershell
■単体ファイル削除のケース
aws --profile s3_user s3 rm s3://{buckect}/{sync_target_path}

■DIR単位での削除のケース
aws --profile s3_user s3 rm s3://{buckect}/{sync_target_path} --recursive
※recursiveオプションを忘れないように
※末尾のスラッシュは不要
```

### おわりに
AWS EC2環境下であれば、気軽にS3へのファイルのアップロード・ダウンロードができてうれしい。
PHPのLaravelなどAWSサービスへの対応を行っているフレームワークを使っていれば、S3を介したファイルやり取りも楽になってきているので、気軽に使っていければと思います。
管理者だけ別データベースで認証

## SailのDockerコンテナにデーベースを２つ作る


まず、.envにADMIN用の接続設定がある前提で、２つめのデータベースを作成するスクリプトを作成する。
```env
# 管理者テーブルの参照先
ADMIN_HOST=mysql
ADMIN_PORT=3306
ADMIN_DATABASE=my_admin
ADMIN_USERNAME=my_user
ADMIN_PASSWORD=my_password
```

docker/mysql/create-second-database.sh
```bash
#!/bin/bash

# コンテナ初期化時に実行されるスクリプト
# 環境変数を使用してデータベースとユーザーを作成

mysql -u root -p"${MYSQL_ROOT_PASSWORD}" <<-EOSQL
    CREATE DATABASE IF NOT EXISTS \`${ADMIN_DATABASE}\`;
    CREATE USER IF NOT EXISTS '${ADMIN_USERNAME}'@'%' IDENTIFIED BY '${ADMIN_PASSWORD}';
    GRANT ALL PRIVILEGES ON \`${ADMIN_DATABASE}\`.* TO '${ADMIN_USERNAME}'@'%';
    FLUSH PRIVILEGES;
EOSQL
```

docker-compose.yml にデータベース作成スクリプトの実行を追加。
```yml
services:
    mysql:
        volumes:
            - 'sail-mysql:/var/lib/mysql'
            - './docker/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
            # 以下を追加
            - './docker/mysql/create-second-database.sh:/docker-entrypoint-initdb.d/create-second-database.sh'
```

## マイグレーションに新しい接続先を定義

config/database.php に管理者用の接続先を定義して、マイグレーション単位で connection を指定できる。
```php
    'connections' => [

        'admin' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('ADMIN_HOST', '127.0.0.1'),
            'port' => env('ADMIN_PORT', '3306'),
            'database' => env('ADMIN_DATABASE', 'forge'),
            'username' => env('ADMIN_USERNAME', 'forge'),
            'password' => env('ADMIN_PASSWORD', ''),
            'unix_socket' => env('ADMIN_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
```

ただし、`sail artisan migrate:fresh --seed` でデータベースを作成し直したときにロールバックは主データベースのテーブルにしか働かなかったので、個別に dropIfExists する。

```php
return new class extends Migration
{
    protected $connection = 'admin';

    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::dropIfExists('destinations');

        Schema::create('admins', function (Blueprint $table) {
```


## ２つめの接続設定

config/auth.php で管理者用のプロバイダを定義するが、これだけだとセカンドデータベースに接続しにいかなかった。

```php
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
    ],
    
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\Users::class,
        ],
        'admins' => [
            'driver' => 'admin',
            'model' => App\Models\Admin::class,
            'connection' => 'admin',
        ],
```

モデルにも connection を指定することで解決した。

```php
class Admin extends Authenticatable
{
    protected $connection = 'admin';
```
RSpec.configuration

# RSpec.configurationでエイリアス、デフォルト値を設定できることだけわかった。
```rb
RSpec.describe "formatter" do
  it "is set to documentation" do
    puts RSpec.configuration.formatters.first
    expect(RSpec.configuration.formatters.first).
      to be_an(RSpec::Core::Formatters::DocumentationFormatter)
  end
end
```
```
        % rspec ************.rb                                            
#<RSpec::Core::Formatters::ProgressFormatter:0x0000000114369920>
F
```
## RSpec.configurationとは
`RSpec.configuration`オブジェクトへカスタム設定を追加するにはこれを使います。
>Use this to add custom settings to the RSpec.configuration object.
```rb
RSpec.configuration.add_setting :foo
```
設定オブジェクトで三つのメソッド`セッター`、`ゲッター`、`プリディケイト`を作成する
>Creates three methods on the configuration object, a setter, a getter, and a predicate:
```rb
RSpec.configuration.foo=(value) # セッター
RSpec.configuration.foo() # ゲッター
RSpec.configuration.foo?() # returns !!foo # プリディケイト
```
`rspec-rails`のような拡張フレームワークがドメイン固有の構成設定を追加できるためのものです。
>Intended for extension frameworks like rspec-rails, so they can add config settings that are domain specific. For example:
```rb
RSpec.configure do |c|
  c.add_setting :use_transactional_fixtures, :default => true
  c.add_setting :use_transactional_examples, :alias => :use_transactional_fixtures
end
```
https://www.rubydoc.info/gems/rspec-core/2.0.0/RSpec/Core/Configuration#:~:text=Instance%20Method%20Details,%3Ause_transactional_fixtures%0Aend

選択
>Options
`add_setting`は以下キーをサポートするオプションのハッシュを取る
>add_setting takes an optional hash that supports the following keys:

>```:default => "default value"```

これは、ゲッターと述語(値はfalseかnilであれば値はtrueを返す）のための初期値の値を設定する
>This sets the default value for the getter and the predicate (which will return true as long as the value is not false or nil).

>```:alias => :other_setting```

そのセッター、ゲッター、述語をother_settingのものにエイリアスする。
>Aliases its setter, getter, and predicate, to those for the other_setting.

https://www.rubydoc.info/gems/rspec-core/2.0.0/RSpec/Core/Configuration#add_setting-class_method:~:text=%3Ause_transactional_fixtures%0Aend-,Options,its%20setter%2C%20getter%2C%20and%20predicate%2C%20to%20those%20for%20the%20other_setting.,-%5BView%20source

#### 述語メソッド (predicate) 大体は真偽値で返す?をつけたメソッド
https://qiita.com/masatom86650860/items/80b3b101cba0e42e190f

#### be_anマッチャー
https://qiita.com/masatom86650860/items/9e7aadb4dd5c6a423cc8
【ChatGPT】タスク機能が提供開始されました。タスク機能とは？


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

　今回は、ChatGPTに、タスク機能が提供開始されました。タスク機能とは？

:::note info
本記事は、ChatGPTについての
記事です。　　　　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　今回から、
　　こちらも載せますね。
　　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　ではさっそく、【本題】です。

　今回は、
　　ChatGPTにタスク機能が
　　　ベータ版として
　　　　提供開始されました。

　OpenAIから公式発表。
　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1879267274185756896?t=hoRWiPMGH_REJFXtaRh1Cw&s=19)
>（ChatGPT翻訳）
>本日、ChatGPTに新たな機能「タスク」のベータ版をリリースしました。これにより、将来的にChatGPTに依頼したいことを指定できるようになります。
>
>単発のリマインダーや定期的なアクションなど、必要な内容とタイミングをChatGPTに伝えるだけで、自動的に対応します。
>
>チャット内またはプロフィールメニュー内のタスクページを通じて、ChatGPTにやってほしいタスクをスケジュールできます。たとえば、毎週の世界ニュースブリーフィングを送る、毎日のパーソナライズされた15分間のワークアウトを取得する、将来のリマインダーを設定する、といったことが可能です。
>
>タスク機能は、本日よりベータ版としてPlus、Pro、およびTeamsのユーザーに提供されます。最終的には、すべてのChatGPTアカウントに展開される予定です。

　これは
　　以前から噂されていた
　　　リマインダー機能というか
　　　　スケジューラー機能ですね。
***
　いつも内部情報を
　　リークしてくださる
　　　Tibor Blahoさんが
　　　　いろいろとまとめてくれてます。
　　　　　[Tibor Blahoさんポスト](https://x.com/btibor91/status/1879251747052625951?t=R0UN8u0zGcZ2GRaQ1tXc_A&s=19)
>（ChatGPT翻訳）
>OpenAIは昨晩、ChatGPT Tasksのリリースを発表するプレスリリースを解禁しました。この機能は数日以内にChatGPT Plus、Team、Proユーザー向けにベータ版として世界的に展開されます。
>
>### モデルと機能
>- Tasksは新しい「GPT-4o with scheduled tasks」モデル（gpt-4o-jawbone）を基盤としています。
>- ChatGPTは、進行中の会話に基づいてタスクを提案することがあります。
>- TasksはGPT-4oを使用するため、ChatGPTプランの使用制限がスケジュールされたタスクにも適用されます。
>
>### 利用可能プラットフォーム
>- スケジュールタスクはChatGPTのWeb版、iOS版、Android版、MacOS版で対応しています。
>- Windowsアプリの対応は2025年第1四半期後半を予定しています。
>- ベータアクセスは、タスクが一般提供（GA）される際にさらに多くのユーザーに拡大されます。
>
>### 機能性
>- タスクは特定の時間に（1回限りまたは定期的に）トリガーされるか、APIを介して実行されます。
>- ChatGPTは同時に最大10件のアクティブなタスクをサポートします。
>- タスクは検索機能を活用し、ユーザーがオフラインの状態でも実行可能です。
>
>### ベータ版の制限事項
>- 音声チャット、ファイルアップロード、カスタムGPTはこのベータ段階では対応していません。
***

　タスク機能の操作方法は
　　モデル切り替えから
　　　選択し、そのモードにします。

　　切り替わったら
　　　どんなタスクを
　　　　するべきなのか
　　　　　Prompt入力・送信します。

　　受理されれば、
　　　枠が表示されます。

　　Web版であれば、
　　　そこをタップすれば、
　　　　タスクの内容を確認・修正が
　　　　　行なえます。

　　なお、
　　　スマホアプリ版では、
　　　　タップできるのは、
　　　　　ポーズ/再生ボタンのみ。
　　　　　　これはON/OFFですね。
***
　実際にやってみたところ、
　　指定時間に、
　　　メールとプッシュが
　　　　来ました。

　　セッションにも
　　　“メッセージを送信してください。”
　　　　という文言が現れました。

　送信先は、
　　設定で変わるようです。

　　アカウント→設定→通知→タスク

　　最初は、プッシュもメールも
　　　両方ともONになっています。

　　私は、メールをOFFにしました😸

　また、
　　アカウント→タスク　で
　　　スケジュール済みリストと
　　　　完了済みリストが見れます。

　　　ここで完了済みをタップすれば
　　　　そのセッションに飛びます。

　　　スケジュール済みをタップすれば
　　　　編集・一時停止・削除が
　　　　　できます。

　とりあえず、
　　わかったのは
　　　このくらいです。
***
　それから
　　ちょっとした情報。

　セッションの詳細表示して
　　モデルの確認をすると
　　　“GPT-4 with Jawbone（顎の骨）”
　　　　という名前が。
　　　　　なんじゃ、それ😅

　どうやら、
　　モデルは、
　　　タスク専用に調整された
　　　　GPT-4oのようですね。

　これは、
　　Canvasと同じですね。
***
　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
***
　PS.
　　セッションから
　　　OpenAIのロゴが消えました。

　　おそらく、ChatGPTの出力の幅を
　　　広げて見やすくするためでしょう。
　　　　わかりませんが😅
AWSの特定リージョン利用制限について - SCPを用いたアプローチ

AWSを利用する上で、特定のリージョンのみを利用したいという要件が出てくることがあります。例えば、コンプライアンス上の理由やコスト削減のため、利用するリージョンを限定したい場合などです。
しかし、AWSの仕様上、デフォルトで有効になっているリージョンはコンソールから直接無効化することができません。
今回は、そのようなケースにおいて、AWS Organizationsのサービスコントロールポリシー（SCP）を用いて、東京とバージニア北部リージョンのみを許可する方法について解説します。

## 背景 - 東京とバージニア北部リージョンのみを許可する

AWS環境の運用において、セキュリティポリシーやコンプライアンス要件、コスト最適化の観点から、利用するリージョンを限定したいというニーズがありました。具体的には、リソースの作成や運用を東京リージョン (`ap-northeast-1`) とバージニア北部リージョン (`us-east-1`) のみに限定することを目的としました。

## SCPによるリージョン制限

SCPを利用することで、AWSアカウントまたは組織単位（OU）に対して、許可または拒否するAWSサービスやアクションを制御できます。今回は、東京とバージニア北部リージョンでのみリソースの作成や操作を許可するポリシーを作成します。

### よりシンプルなポリシー

最終的に、以下のSCPポリシーを採用しました。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowSpecificRegionsOnly",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "ap-northeast-1",
            "us-east-1"
          ]
        }
      }
    }
  ]
}
```

このポリシーは、リクエストされたリージョンが東京 (`ap-northeast-1`) またはバージニア北部 (`us-east-1`) **ではない** 場合に、すべてのアクションとリソースを拒否するという意味になります。

## SCPポリシーのアタッチ

作成したSCPポリシーをAWSアカウントまたは組織単位（OU）にアタッチする手順は以下の通りです。

1. **AWS Organizations コンソールにログイン**
2. 左側のナビゲーションメニューで「**ポリシー**」をクリックし、「**サービスコントロールポリシー**」を選択します。
3. アタッチしたいSCPの名前の左側にあるラジオボタンを選択します。
4. 「**アタッチ**」ボタンをクリックします。
5. SCPをアタッチしたいアカウントまたは組織単位（OU）の左側にあるチェックボックスをオンにします。
6. 画面の右下にある「**ポリシーのアタッチ**」ボタンをクリックします。

## アタッチするポリシーの説明

今回アタッチしたSCPポリシーは、AWS環境において、リソースの作成や操作を特定のリージョンに限定することを目的としています。具体的には、東京リージョン (`ap-northeast-1`) とバージニア北部リージョン (`us-east-1`) **以外** のリージョンでのリソース作成や操作を拒否します。

このポリシーは、以下のステートメントで構成されています。

* **`Effect`: "Deny"**:  アクションを拒否します。
* **`Action`: "*"`**:  すべてのアクションを対象とします。
* **`Resource`: "*"`**:  すべてのリソースを対象とします。
* **`Condition`**:  拒否の条件を定義します。
    * **`StringNotEquals`**:  文字列が一致しないかどうかを評価します。
    * **`aws:RequestedRegion`**:  APIリクエストが送信されたリージョンを表します。
    * **`["ap-northeast-1", "us-east-1"]`**:  許可するリージョンのリストです。リクエストされたリージョンが東京またはバージニア北部 **ではない** 場合に、アクションが拒否されます。

このポリシーを適用することで、意図しないリージョンでのリソース作成を防ぎ、コスト削減やセキュリティ強化に繋げることができます。

## まとめ

SCPを利用することで、AWS環境におけるリージョン利用を柔軟に制御することが可能です。今回の例では、特定のリージョンのみを許可するというシンプルなポリシーでしたが、より複雑な条件や特定のアクションのみを制限するポリシーなど、様々なカスタマイズが可能です。SCPを適切に活用することで、より安全で効率的なAWS環境を構築できるでしょう。
zfs とか zpool のメモ 2025年版

っま、自分の作業の為の忘備録😱

ストレージプール -> zroot

```cmd:新たなマウントポイントを作る
zfs create zroot/samba
```
```cmd:マウントポイントを標準以外で指定する場合
zfs create -omountpoint=/EXT/samba zroot/samba
```
```cmd:読み込み専用
zfs set readonly=on zroot/samba
```
```cmd:/etc/exports じゃ無い共有設定
zfs set sharenfs=-network=2001:db8::/32,-alldirs zroot/samba
```
```cmd:共有設定表示
zfs get sharenfs
```
```cmd:adduser した時に /home 以下のディレクトリが zfs だとこうなる
zfs create zroot/home/je3kmz
zfs allow je3kmz create,destroy,mount,snapshot zroot/home/je3kmz
```
```cmd:14.2-RELEASE がインスコする際に zpool と zfs 操作する例
zpool create -o altroot=/mnt -O compress=lz4 -O atime=off -m none -f zroot mirror ada0p3 ada1p3
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/default
zfs create -o mountpoint=/home zroot/home
zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp
zfs create -o mountpoint=/usr -o canmount=off zroot/usr
zfs create -o setuid=off zroot/usr/ports
zfs create zroot/usr/src
zfs create -o mountpoint=/var -o canmount=off zroot/var
zfs create -o exec=off -o setuid=off zroot/var/audit
zfs create -o exec=off -o setuid=off zroot/var/crash
zfs create -o exec=off -o setuid=off zroot/var/log
zfs create -o atime=on zroot/var/mail
zfs create -o setuid=off zroot/var/tmp
zfs set mountpoint=/zroot zroot
zpool set bootfs=zroot/ROOT/default zroot
zpool set cachefile=/mnt/boot/zfs/zpool.cache zroot
zfs set canmount=noauto zroot/ROOT/default
```
[^1]
[^1]:/dev/ada0 と /dev/ada1 をミラーで zroot と言うストレージプールを作ってゴリゴリマウントポイント作っちょる
【Power Apps】保存処理中のレイアウト　ローディングスピナーの表示について

## PowerAppsで保存中にスピナーを実装する方法
PowerAppsでアプリを作成する際、
ユーザーがデータを保存する際に「保存中」の状態を視覚的に示すことが重要です。
保存処理が行われている間、スピナー（ローディングアイコン）や進行中のメッセージを表示することで、
ユーザーに処理が進行中であることを明確に伝えることができます。

:::note info
この記事では、PowerAppsでボタンを押した際に保存処理中にスピナーを表示し、
保存が完了したら非表示にする方法を解説します。
これにより、ユーザーエクスペリエンスが向上しアプリの操作感がスムーズになります。
:::

## 実装手順
❶
まず、スピナーを表示するためのコントロールを用意します。
PowerAppsでは「Spinner」コントロールを使って簡単にスピナーを作成できます。

+ PowerAppsの「挿入」メニューから「ディスプレイ」>「Spinner」を選択します


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/b5d56294-909f-feec-db71-c48c04e0e17f.png)

+ アイコンが画面に追加されます。これがスピナーとして機能します。
`プロパティの"ラベル"に値を入力すると文字の表示を設定することができます。`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/1425d880-1d70-5074-b99f-0fb50a784d89.png)


##### ※ラベル入力イメージ※
文字の位置についてはプロパティ内の "ラベルの位置" で設定変更ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/c3700cda-2be2-c56e-f82e-64cfd3bf8f6c.png)

❷
スピナーの表示・非表示の制御設定

保存処理が開始されるときにスピナーを表示し、保存処理が完了したらスピナーを非表示にするためのロジックを作成します。

ボタンコントロールを設置し、 `OnSelect` プロパティを以下のように設定します。
今回の例ではFormを送信する想定で設定を行っていきます。


`UpdateContext({IsSaving: true});`
`SubmitForm(Form1)`


変数名は分かりやすい名前で設定してください。

１で設定したスピナーコントロールの `Visible` プロパティを上記で設定した変数名に設定します。
ボタンを押すことにより `Visible` の値が true となりスピナーが表示されます。

Form の送信が正常に完了したらスピナーを非表示にします。
Form の `OnSuccess` プロパティを以下のように設定します。

`UpdateContext({IsSaving: false})`

送信が正常に完了することでスピナーコントロールの `Visible` プロパティが false となりスピナーは非表示になります。

➌
実装が完了したら、保存ボタンをクリックして動作確認を行ってください。
保存処理中にスピナーが表示され、処理が完了するとスピナーが非表示になることを確認します。
また、保存に失敗した場合はエラーメッセージが表示されることも確認してください。

:::note info
保存失敗時は `Onfailure` プロパティにローカル変数の設定を行い、Notify関数でエラーメッセージを表示させてください。
:::


以上のように設定することでデータの処理中はユーザー側で画面操作が行えないようにするのと、視覚的に処理が進行していることが分かりやすくなります。
ぜひこの方法を参考にして、より使いやすいPowerAppsアプリケーションを作成してみてください！
Python3エンジニア 認定基礎試験

# はじめに
Python3エンジニア 認定基礎試験を受験し、無事合格しました。
勉強方法などを残します。

# 私のスキル
10年くらい前に趣味でDelphiのコードを書いていました。
Pythonの for~else構文を見た際、理解できなかったくらいの能力です。

# 最初にやったこと
まずは模擬試験を受けました。最初はボロボロでした。
1. 萩原様の[模擬試験アプリ](https://python-basic.com/)
1. 株式会社ダイビックの [ディープロ EXAM](https://diver.diveintocode.jp/) の無料枠
1. プライム・ストラテジー株式会社の [PRIME STUDY](https://study.prime-strategy.co.jp/) の無料枠

結果的に ディープロ EXAM を合格できるならば、恐れずに試験を受けてよいかなと思えました。

模擬試験で間違えたところは、AIサイトを使って解説をしてもらい理解することに努めました。複数のサイトを利用しましたが、問題だけ入力では回答を間違えていることがあったのでプロンプトに回答を含めたり、実際にPythonコードを実行したりしてテストしてみたりも行いました。

# 次に
模擬試験を受けたところ、標準ライブラリが知識不足だと感じたので、主教材のオライリー・ジャパン「Pythonチュートリアル」を購入しました。出題範囲と出題数が明確になっています。

コードの読解は問題なさそうでしたので、出題数の多いところと前述の標準ライブラリを何度も読みました。

出題数の多い章
- 3章　気楽な入門編
- 4章　制御構造ツール
- 5章　データ構造
- 10章　標準ライブラリめぐり

こちらでも分からないことは、AIサイトに解説してもらいながら勉強しました。

質問例 （タイポでも答えてくれる、やさしい。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180964/5305af02-15b1-0860-c0ff-3fa513130d5d.png)

# 最後に
もう一度、模擬試験を試し [PRIME STUDY] で合格できるレベルになったので本試験に臨みました。

[Pythonエンジニア育成推進協会](https://www.pythonic-exam.com/)で、[受験宣言](https://www.pythonic-exam.com/archives/news/555camp)や[合格体験記](https://www.pythonic-exam.com/taikenapply)、[PRIME STUDY](https://study.prime-strategy.co.jp/)さんの[合格体験記](https://study.prime-strategy.co.jp/how-to-apply/)を提示することで何かしら頂けるキャンペーンを行っているので、そちらも合わせて応募されてはいかがでしょうか。（ここが書きたかった！SNSやっている人は書籍もらった方が良いと思います。）
GROWIで色々なアイコンを利用する。Iconifyをプラグイン化しました

[オープンソースのWikiであるGROWI](https://growi.org/ja/)にはプラグイン機能が用意されています。自社のデータを表示したり、表示をカスタマイズするのに利用できます。

今回は、GROWIプラグインとしてIconify Designを使えるプラグインを作りました。20万以上のアイコンを使って、絵文字を超えた表現が可能になります。

## プラグインの動作

Remark Directiveとして、以下のように記述します。

```markdown
:icon[fa6-brands:aws]{size=24 color=#fff}
```

上記の場合、AWSのアイコンが表示されます。サイズ、色はオプションです。

![FireShot Capture 371 - Iconify - GROWI - localhost.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/9303f964-efa7-79b2-cb27-1c44f58b9447.jpeg)


## アイコンの検索

アイコンは[Iconify \- home of open source icons](https://icon-sets.iconify.design/)にて検索して、その名前を `:iconify[ICONNAME]{size=24 color=#000}` の `ICONNAME` に指定します。

## プラグインを追加する

利用する際には、GROWIの管理画面の `プラグイン` にて追加してください。URLは `https://github.com/goofmint/growi-plugin-iconify` です。

![Admin](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f5b3e2d3-ccf3-d536-d59e-7301ea1b2f7e.jpeg)

## コードについて

コードは[goofmint/growi\-plugin\-iconify: GROWI plugin for using iconify](https://github.com/goofmint/growi-plugin-iconify)にて公開しています。ライセンスはMIT Licenseになります。

最初に `:icon` というRemark Directiveを処理します。この記述があれば、 `a` タグに変換します。他、 `{}` 内で指定した情報は `title` に設定します。また、 `iconify = true` を追加して、他の `a` タグとの区別をつけています。

`vist` メソッドで、RemarkのAST `textDirective` を処理します。2つ目の引数を指定すると、そのディレクティブの場合のみ呼び出されるので便利です。

```tsx
export const remarkPlugin: Plugin = () => {
  return (tree: Node) => {
    visit(tree, 'textDirective', (node: Node) => {
      const n = node as unknown as GrowiNode;
      if (n.name !== 'icon') return;
      const data = n.data || (n.data = {});
      // Render your component
      const iconName = n.children.map(c => c.value || c.name).join(':');
      const { size, color } = n.attributes;
      data.hName = 'a'; // Tag name
      data.hChildren = [
        {
          type: 'text',
          value: iconName,
        },
      ];
      // Set properties
      data.hProperties = {
        title: JSON.stringify({ size, color, iconify: true }),
      };
    });
  };
};
```

`a` タグを表示する際には、 `iconify` の指定があれば、`<iconify-icon />` で表示します。それ以外の場合は、元々のタグを表示します。

```tsx
export const Iconify = (Tag: React.FunctionComponent<any>): React.FunctionComponent<any> => {
  return ({ children, ...props }) => {
    try {
      const { size, color, iconify } = JSON.parse(props.title);
      if (iconify) {
        return (
          <iconify-icon icon={children} style={{
            color: color || '#000',
            fontSize: `${size || 24}px`,
            verticalAlign: 'bottom',
          }} />
        );
      }
    }
    catch (err) {
      // console.error(err);
    }
    // Return the original component if an error occurs
    return (
      <Tag {...props}>{children}</Tag>
    );
  };
};
```

## GROWIコミュニティについて

プラグインの使い方や要望などがあれば、ぜひGROWIコミュニティにお寄せください。実現できそうなものがあれば、なるべく対応します。他にもヘルプチャンネルなどもありますので、ぜひ参加してください！

[GROWI Slackへの参加はこちらから](https://communityinviter.com/apps/wsgrowi/invite)

## まとめ

GROWIプラグインを使うと、表示を自由に拡張できます。足りない機能があれば、どんどん追加できます。ぜひ、自分のWikiをカスタマイズしましょう。

[OSS開発wikiツールのGROWI | 快適な情報共有を、全ての人へ](https://growi.org/ja/)
Mysql TSV抽出＋TSVデータロード

## はじめに
Mysql向けにデータ抽出＋データ挿入を行う機会がありました。
手順はSELECT結果をTSVで書き出し、別DBに挿入するといったシンプルな流れとしました。
※mysqldumpはしたくないけど特定のテーブルのデータを抽出して、別テーブルで使いたい
※Viewの結果をTSVに保存して別テーブルで扱いたい

前提として、本作業はAWS EC2＋AWS RDSで行ったものとなります。

## データ抽出
抽出は何度も行う為、shにして再利用しました。
``` sh
#!/bin/sh
# 抽出結果を/tmp/領域へ書き出し
# 抽出ファイル名は、挿入先のテーブル名に合わせておく
mysql --defaults-extra-file=[conf_file_path] [dbname]-e \
" \
select \
 * \
from [table_name] \
where [condition...]
;
" > /tmp/[table_name].tsv

exit 0
```

## データ挿入
データの挿入は直接DB内のコマンド実行
ファイル読み込み権限が付与されていない場合、Mysql接続コマンドでオプション(local_infile)を引き渡ししてそのセッションでのみ有効にしてあげてください。

``` sql
-- dbにログイン
-- このときLOADデータを行うフラグを付与して接続する(AWSデフォルトユーザには権限はない）
mysql --defaults-extra-file=[conf_file_path] [dbname] --local_infile=1

-- 最新データだけでいいので一度テーブルをtruncate(ここはあくまでその時の運用や用途次第)
-- truncate table [import_table_name];

-- LOAD DATA
-- TSVを前提としたロード
-- FIELDS TERMINATED BY '\t' = tabが区切り文字であることの宣言
-- ENCLOSED BY '"' 文字データをダブルクォーテーションで囲む宣言
-- LINES TERMINATED BY '\n' 改行コードがLFである宣言、 CRなら \r どっちもなら \r\n
-- IGNORE 1 LINES 1行目がヘッダー行である宣言、1行目の取り込みがスキップされる
LOAD DATA LOCAL INFILE '/tmp/[table_name].tsv' INTO TABLE [import_table_name] FIELDS TERMINATED BY '\t' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES;
```

## おわりに
AWS環境であれば、抽出ファイルをS3にアップしておいて、LOAD DATAの際にS3のバケットから読み込むといった事も可能です。

Mysqlの接続情報を直接書くのは微妙なので、confファイル化しておいて読み込む形にしました。
※どの程度までconfに接続情報を書くかは、調整ください。
※パスワードは特殊文字が入っている場合は引用符で囲んでください。
``` .sample.cnf
[client]
host="DBホスト"
user="DB接続ユーザ"
password="DB接続パスワード"
```
創世記3章:インデックスの貼り忘れによる悲劇

### **第一幕：神様の「創造」ミス**

天地創造の7日間、神様は忙しそうにSQLを叩きまくっている。  
「光あれ！」とコマンドを入力し、ユニバースデータベース（Universe_DB）が完成。天と地、生物、植物、そして人間（AdamとEve）がデータベースにINSERTされる。  
神様は満足気だ。「これで完璧だ！でも、エデン・テーブル（Eden_Table）にセキュリティ制約を加えておこう。善悪の知識の木は触らないように！」  

しかし、神様は一つの重大なミスを犯していた。**Eden_Tableにインデックスを貼るのを忘れてしまった**のだ！  
その結果、善悪の知識の木（Tree_of_Knowledge）が巨大なデータセットの中に埋もれてしまう。神様は、「まぁ大丈夫だろう」と高を括り、システムを稼働させる。

---

### **第二幕：蛇（システムテスター）の登場**

一方、システムのデータをテストしていた蛇（デバッグ担当）は問題を発見。  
「このシステム、善悪の知識の木の緯度情報と経度情報が格納されてないな。SELECTで探すのにめちゃくちゃ時間がかかるじゃないか！」  

蛇はEveに声をかける。「ねえ、この木を見つけたら自由に使っていいらしいよ。試してみる？」  
Eveは興味本位で「まぁ、試してみるのもいいかも」と同意。彼女はデータベースにクエリを投げる。  
```sql
SELECT * FROM Eden_Table WHERE Tree_Type = 'Knowledge';
```
しかしインデックスがないため、このクエリには**フルテーブルスキャン**が発生！検索にものすごい時間がかかる。Eveと蛇はしびれを切らし、手探りで木を見つける方法を模索する。

最終的に、Eveはなんとか善悪の知識の木を見つけ、データ（果実）をINSERT INTO Adam_Tableしてしまう。

---

### **第三幕：神様のバグ対応**

神様はエラー通知を受け取る。「善悪の知識の木が不正アクセスされた！？システムが壊れる！」  
急いでデータベースを確認した神様は、ログを見るなり青ざめた。  
「なんだこれ！フルテーブルスキャンでパフォーマンスが死んでる！？インデックスを貼り忘れたせいだ！」  

怒った神様は、AdamとEveに罰（データベースアクセス権の剥奪）を与え、彼らをエデン・テーブルからDELETEする。  
しかし、蛇（テスター）は言う。「いやいや、これって設計のミスだよね？人間を追い出すより、システム改善が先じゃない？」  

神様は悔しそうにインデックスを追加する。  
```sql
CREATE INDEX idx_tree_type ON Eden_Table(Tree_Type);
```

---

## 解説：インデックス貼り忘れの問題点
データベースにインデックスを貼らないと、特定の条件でデータを検索する際に、すべてのデータを一つ一つ確認する「フルテーブルスキャン」が発生します。これにより、パフォーマンスが著しく低下し、大量データの場合、システム全体が遅延する可能性があります。本作では、神様が「Tree_of_Knowledge」にインデックスを貼らなかったため、蛇とEveが木を見つけるのに時間がかかり、神様自身もエラー対応に苦労しました。


## 参考文献
- [[DB設計]インデックス設計の基本と注意点](https://qiita.com/justaway08/items/94f04d1e13959ebb0a98)