OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでメールチェッカーを作成する方法

メールアドレスの検証は、メールマーケティングやオンラインサービスで非常に重要なプロセスです。不正確なメールアドレスは、バウンス率の増加やスパムフィルターへの影響、さらにはビジネスの信用を失うリスクを引き起こします。この記事では、Pythonを使ってシンプルなメールチェッカーを作成する方法を紹介します。Mailtester Ninjaからインスピレーションを得て、効率的で実用的なメールアドレス検証ツールを構築します。

### Mailtester Ninjaからのインスピレーション
**[Mailtester Ninja](https://mailtester.ninja/)**は、簡単かつ迅速にメールアドレスを検証するツールとして知られています。メールアドレスの有効性を確認することで、無効なアドレスをリストから取り除き、メールの到達率を向上させることができます。このアイデアを元に、Pythonのみを使って独自のメールチェッカーを作成してみます。

### Pythonでのメールチェッカー作成

#### 必要なライブラリ
まず、Pythonでメールアドレスの検証を行うために、次のライブラリが必要です。

1. **smtplib**: SMTPプロトコルを使用して、メールサーバーに接続し、アドレスの検証を行います。
2. **re（正規表現）**: メールアドレスのフォーマットが正しいかどうかを確認するために使用します。

```python
import re
import smtplib

# メールアドレスのフォーマットをチェック
def check_email_format(email):
    email_regex = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return re.match(email_regex, email) is not None

# メールサーバーに接続してアドレスの有効性を確認
def check_email_existence(email):
    domain = email.split('@')[1]
    try:
        # MXレコードを取得してメールサーバーに接続
        server = smtplib.SMTP(f'mx.{domain}')
        server.set_debuglevel(0)
        server.helo('example.com')
        server.mail('me@example.com')
        code, message = server.rcpt(email)
        server.quit()
        return code == 250
    except Exception as e:
        print(f"Error: {e}")
        return False

# メールアドレスの検証関数
def validate_email(email):
    if check_email_format(email):
        if check_email_existence(email):
            print(f"{email} is valid!")
        else:
            print(f"{email} does not exist.")
    else:
        print(f"{email} is not a valid email format.")
```

### コードの解説

1. **check_email_format関数**: 正規表現を使用して、メールアドレスのフォーマットが正しいかどうかを確認します。これにより、最初に不正なフォーマットのアドレスを除外できます。
   
2. **check_email_existence関数**: `smtplib`ライブラリを使用して、メールサーバーに接続し、指定したメールアドレスが実際に存在するかを確認します。このプロセスは、SMTPプロトコルを通じて行われ、特定のメールサーバーがそのアドレスを受け取る準備ができているかを調べます。

3. **validate_email関数**: この関数は、まずメールフォーマットをチェックし、次にそのメールアドレスが存在するかどうかを確認します。
30代の今だからこそ考える[キャリア論]

:::note info
あくまで一個人としての考え方ですので、気楽に読んでいただければ幸いです。
:::

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

30代として「今後のキャリアどうしよう」といった悩みを抱えている方（もちろん私も）向けに私が考えている「キャリア論」についてお話しできればと思います。

# 目次
- 私の略歴
- 20代と30代での違い
- 30代だからこそのキャリア論
    1. 業務に対してプラスαを考えてみる
    1. アウトプットの比率を高めていく
    1. 未知のコミュニティに飛び込んでみる
    1. 「手遅れだから」という考えを捨ててみる
- まとめ

## 私の略歴
- 名前：Masaki（今年31歳）、社会人8年目
- 現在の業務：インフラエンジニア（IaCを活用したプロダクト開発）
- 今までの経歴：
    - 2016年～2019年（１社目）：
        - 某システム会社で「システム運用監視オペレータ」として従事
        - 当時は「システムって何？インフラって何？」というレベル感
        - 日々の仕事に嫌気がさし、転職を志す
    - 2019年～現在（2社目）
        - 現在の会社に入社し、ネットワークエンジニアとして活動し始める
        - 入社当初は、某社のネットワークサービス立ち上げ支援に約3年携わる
        - その後、社内教育担当として教育基盤設計業務に約1年半携わる
        - 現在は、インフラエンジニアとしてIaCを活用したプロダクト開発に携わる
    - 資格
        - LPIC Level3（300,303,304）
        - AWS SAA
        - JSTQB Foundationなどなど

## 20代と30代での違い
改めて私の働きかたを振り返る中で、20代と30代でいくつか大きな違いがあると感じています。

### 20代としての過ごし方
- とりあえず、インプット活動に重きを置く
- 自分の知っているコミュニティのみで活動する
- とりあえず、「与えられた業務」を淡々を行うことに注力する
- ミスを極端に恐れる

### 30代として過ごし方
- アウトプット活動への比重を多くしてみる
- 自分が知らないコミュニティへも参加してみる
- 業務に対して「なんで行うのだろう」という考えをめぐらす
- ミスに対するリカバリを考えるようになる

## 30代からのキャリア論
私個人として「30代からのキャリア設計」が人生のなかで一番大きいと考えています。もちろん、20代のうちにある程度キャリア設計を行うことが理想だと思いますが、日々の生活を過ごすのに精いっぱいでなかなか考えるのが難しいと思います。
だからこそ、30代という「社会の酸いも甘い理解した年代」に「自身のキャリア設計」を考えるのが大切だと考えています。

そのうえで、いま私が30代から心がけたことについていくつか説明したいと思います。

### 業務に対してプラスαを考えてみる
与えられた業務のもとをだとると、「ビジネス活動」があるはずです。
30代として働くなかで、「この業務を通じてどのようなビジネス価値を生み出すことができるだろうか？」を考えることが重要だと考えています。
偉そうに書いていますが、私自身、きちんとできているわけではありません。
「業務の裏にあるビジネス活動・ビジネス価値を考える」ことに大きな意味があると考えています。

### アウトプットの比率を高めていく
インプット活動も重要ですが、インプットだけだと「ナレッジが自分だけにしか蓄積されない」といった状況になってしまいます。
もちろん、自己研さんの一つとしてインプット活動も大切だと思いますが、アウトプット活動を行うことで「読み手からのフィードバック」や「新たなディスカッションの機会」など、**おいしい特典**がたくさんあると思います。
また、アウトプット活動を通じて「自身が持っている知識の棚卸し」と「持っている知識を相手にわかりやすく伝える訓練（＝言語化）」にも役立てられると思います。

### 未知のコミュニティに飛び込んでみる
知らない領域に飛び込むことには大いなる勇気が必要だと思います。（私も教育担当に拝命されたときは、「教育活動って何を行えばいいの？」といった不安がありました。）
ただ、自身が知らない領域に飛び込んでみることで、「新たな発見」や「今まで出会わなかった方々との交流機会」が生まれると思います。
「未知のコミュニティ」に入って、多くのチャレンジを行っていくことが大切なのかなぁと考えています。

### 「手遅れだから」という考えを捨ててみる
30代になると「いまのままでいい」や「これからスキルアップしても手遅れでしょ」といった、ネガティブなキャリアイメージをどうしても持ってしまいます。（私自身もネガティブなキャリアイメージを払しょくしきれてはいません）
ただ、「チャレンジしない」より「チャレンジした」方が新しい経験を行えると考えています。
また、新しいチャレンジには年齢は全く関係ないと思います。

30代だからこそ、「手遅れだから」という考えを捨ててチャレンジを行ってみたらよりよくなると思います。

## まとめ
技術をテーマにした記事ではなかったため、内容が抽象的になってしまっていたかもしれません。また、私個人の経験から執筆した内容ですので、もしかしたら間違っている内容があるかもしれません

ただ、私個人としては、今回の記事をきっかけに、読み手の皆さんが「自身のキャリアを見つめなおすきっかけ」にしてもらえたら幸いです。

:::note info
最後まで読んでいただきありがとうございます。
定期的に技術ブログを執筆していきますので、お気軽に読んでみてください。
また、読んでみて「良かった」と思った方は「ハートボタン」と「ストック」をお願いします。コメントに関しても遠慮なくお願いいたします。
:::
Reactでハマった要素についてまとめる

Reactを触り始めてstateやレンダー周りで苦戦することが多いことがわかった。
そもそも個々の要素がどうあるべきなのかといった考え方や基本方針みたいな部分が欠けていると思い、公式ドキュメントを読んで確認したので自分なりにまとめておく。

## 用語
#### 純粋
以下の2つの性質を有していること。
- 同じ入力に対し常に同じ出力(JSX)を返す
- レンダー前に存在したオブジェクトや変数を変更しない

#### イミュータブル
状態の変更を伴わないこと。
読み取り専用。

#### レンダー
**コンポーネントの呼び出しのこと。**

#### パスカルケース
Reactコンポーネントの命名で使用する。
大文字で始まり、続く単語の最初の文字を大文字にする。
（例：MyComponent）

#### キャメルケース
変数や関数の命名で使用する。
小文字で始まり、それ以降の単語には大文字を使用する。
（例：myVariableName）。

## コンポーネント
コンポーネントは次の2つのコードから成る。

### レンダーコード
コンポーネントのトップレベルにあるコード。
propsやstateを受け取ってそれらを変換し、画面に表示したいJSXを返す。
コンポーネントのロジックは可能な限り、レンダーコードのJSXの中で表現する。
**レンダーコードは純粋でなければならず、副作用を伴ってはいけない。**

### イベントハンドラ
コンポーネント内にネストされた関数。
特定のユーザーアクション(ボタンクリック等)をトリガーとして実行される。
何かを「変える」必要がある場合、イベントハンドラで実施する。
**副作用を伴う処理が含まれる。**

副作用を伴う処理は通常イベントハンドラ内に記述する。
非同期処理など副作用を伴う処理を実行するのに適切なイベントハンドラがない場合は、
`useEffect`を利用する。

## State

### 前提
stateはイミュータブルとして扱う必要がある。
stateは同じコンポーネントが同じ位置でレンダーされている限り、値を保持する。
削除されたりした場合はstateの値は破棄される。

### stateのセット
- stateをセットするとレンダーのトリガーが予約される。
- stateのセットは現在のレンダーでは変更後の値は反映されない。変更が反映されるのは次回のレンダー。
- `useState`を呼び出すと、その回のレンダーのためのstateの値を返す。
- **stateをセットする際は元の値を書き換えるのではなく、新しく変更後の値を保持したオブジェクトを作成し、stateにセットする。**

即座に値を反映したい時はset関数に更新用関数を渡す。
更新用関数の第1引数に現在の値が入る。
更新用関数は副作用を伴ってはならない。
```jsx:即座に値を反映したい時
<button onClick={() => {
  setNumber(n => n + 1);
  setNumber(n => n + 1);
  setNumber(n => n + 1);
}}>+3</button>
```

### stateとローカル変数の違い

#### state
- レンダー間で値が保持される
- レンダーがトリガーされる

#### ローカル変数
- レンダー間で値は保持されない
- レンダーはトリガーされない

## あとがき
- レンダーは画面の描画のことかと思っていたが、Reactではコンポーネントの呼び出しのことを指すことが分かった。
（公式ドキュメント上でも画面への描画は「ペイント」と呼んで区別している）
- 純粋・副作用について意識するのがとても重要だと感じた。
- 公式ドキュメントは割とわかりやすい。

### 参考
https://ja.react.dev/learn/adding-interactivity

https://zenn.dev/axoloto210/articles/use-state-pitfall
MuJoCoを用いたToroboの動作方法


## MuJoCoとは？
Google DeepMind社が提供する物理シミュレーターです。

高速かつ正確な物理演算を特徴としたシミュレーターであり、ロボティクス分野ではロボットシミュレーションや強化学習などに使用されています。

## Toroboとは？
[東京ロボティクス社](https://robotics.tokyo/ja/)が開発する力制御可能な全身人型ロボットです。

新型Toroboは2025年3月頃発売予定(詳細: [PR TIMES記事](https://prtimes.jp/main/html/rd/p/000000018.000077249.html))で、今回はその新型モデルを使用します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335112/104a4e40-c294-016b-23c7-3f11e7a5633b.png" width="20%">

## MuJoCoのインストール

### 使用要件
使用可能OSは、Linux (x86-64 and AArch64)、Windows (x86-64 only)、macOS (universal)で、Python 3.8以上がインストールされていることが前提になります。
なお、必要なPythonバージョンはMuJoCoの更新によって変更になる可能性があるので、[MuJoCo公式リポジトリ](https://github.com/google-deepmind/mujoco)を確認することを推奨します。

### 実行環境
社内では以下の環境で動作確認済みです。
| 項目 | 仕様 |
|------|------|
| OS | Ubuntu 20.04.6 LTS |
| CPU | Intel Core™ i9-10900X CPU @ 3.70GHz × 20 |
| RAM | 32 GB |
| Storage | 2.5 TB |
| GPU | GeForce RTX 3080 |
| VRAM | 10 GB |
| Python | 3.8.10 |


### MuJoCo(Pythonパッケージ)のインストール
pipインストールすることによってインストールが完了します。2024年10月23日時点ではversion 3.2.3がインストールされます。

```terminal:terminal
pip install mujoco
```

C++で使用したい場合や、URDFをMJCFに変換したい場合は、シミュレーターのインストールも行います。

### MuJoCo(シミュレーター)のインストール

[Releases](https://github.com/google-deepmind/mujoco/releases)より使用するOSに適した最新版のものをダウンロードし、解凍したフォルダの中にあるmujoco-(version名)フォルダを適当な場所(例: ~/.mujoco/)に配置します。

正しくインストールされているか確認したい場合は、mujoco-(version名)/binフォルダに移動し、以下のコードを実行します。

```terminal:terminal
./simulate ../model/humanoid/humanoid.xml
```

以下のような画面が出力されていればインストールは成功しています。

![humanoid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335112/ad375e56-9092-15ae-25be-461ea8ad614a.png)


## Toroboの動作確認

[torobo_mujoco](https://github.com/TokyoRobotics/torobo_mujoco)を適当な場所にgit cloneします。

```terminal:terminal
git clone https://github.com/TokyoRobotics/torobo_mujoco.git
```

torobo_mujoco/exampleに移動し、以下のスクリプトを実行します。

```terminal:terminal
python example_torobo2.py
```

以下の画面が表示されていればOKです。

![torobo2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335112/9b36e46e-be35-0fbc-7df0-2d87a735ed45.png)

右のControlをクリックするとActuatorのjointが表示されるので、動かしたいjointの欄を左右にドラッグすることによってjointを動かすことができます。

![torobo2_move_leftarm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335112/a896c02f-a30d-cff3-96e2-b6f4614a6e24.gif)


## 参考
https://github.com/google-deepmind/mujoco
JITコンパイラについてまとめてみた

## 経緯
日頃業務でpythonを触る中で、10月7日にリリースされたpython3.13にJITコンパイラが試験搭載されるという記事を見た。ただ日頃pythonでコンパイラを意識していない自分にとってはJITコンパイラと聞いても何のことか全くだったので、今回はそのJITコンパイラについて簡単に調べて備忘録としてまとめてみた。

## JIT(just in time)コンパイラ
JITコンパイラ（Just-In-Timeコンパイラ）は、プログラムの実行時にバイトコードをネイティブコードに変換する技術です。
これは、プログラムの実行速度を向上させるために使用され、通常はランタイム環境の一部として機能します。
JITコンパイラが導入されていないインタプリタ言語は逐次実行は同じでもプロファイル情報の蓄積はないため同じコードを実行しても実行に時間がかかってしまいます。
今後本導入が行われればpythonの実行速度向上などが期待できます。
実際にJITコンパイラが使用されているjavascriptエンジン(V8)やjava仮想マシン(JVM)などの実行速度を見るとJITの速度が感じると思います。
JITの解析手法なども下記参考記事に記載されているので興味があればぜひご覧下さい。

## pycacheとの違いは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113724/1dddbc0b-2b8e-f0ef-9d93-036d876c0b31.png)

## イメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113724/14fa2187-cad1-918a-6026-65b2fe03b547.png)

## 参考
https://drew.silcock.dev/blog/everything-you-need-to-know-about-python-3-13/#how-do-i-try-out-the-jit
https://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-MA16-JIT.pdf
https://medium.com/couger-blog/vhl-podcast-jitcompiler-d16c5aba7704
https://www.issoh.co.jp/tech/details/3314/
https://www.slideshare.net/slideshow/jit-compiler-jjugccc-2020-fall-nttdata-sakata/239273496
https://www.publickey1.jp/blog/24/pythonjitpython_3130.html
VirtualBoxでMetasploitable2を使用する

VirtualBoxでMetasploitable2を使用する方法です。
# ダウンロード
以下のURLからダウンロードします。
https://sourceforge.net/projects/metasploitable/files/Metasploitable2/
# インストール
ダウンロードしたmetasploitable-linux-2.0.0.zipを展開します。
展開してできたMetasploitable2-LinuxフォルダをC:\Users\ユーザー名\VirtualBox VMsフォルダに移動します。（必ずしも、ここに移動する必要はないですが）
VirtualBoxから「追加」をクリックして、名前：任意、タイプ：Linux、バージョンを入力し、「次へ」をクリックします。
メインメモリー、プロセッサー数を選択して、「次へ」をクリックします。
「すでにある仮想ハードディスクファイルを使用する」にチェックをいれて、右のアイコンをクリックします。
「追加」をクリックして、Metasploitable2-LinuxフォルダのMetasploitable.vmdkを選択します。
「次へ」をクリックして、「完了」をクリックします。
# 設定
Metasploitable2を選択して、「設定」をクリックします。
「ネットワーク」をホストオンリーアダプターにします。（安全のため）
# 起動
この画面の間に「ESC」キーをクリックします。
Metasploitable2を選択して、「起動」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770088/6391dbe2-574c-89ca-6321-ce6d50d57c7a.png)
「e」キーを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770088/18af55a8-2d7d-3cf1-6e09-2db24913dd35.png)
下矢印で２行目を選択して、「e」キーを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770088/ebd3f8a9-7868-0bb2-8b5e-1fe51d841f24.png)
最後に「noapic」を追加して、エンターキーを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770088/e70e0f8e-2c47-b573-1131-6268201a9db8.png)
「b」キーを押下します。
# ログイン
ユーザー名：msfadmin、パスワード：msfadminでログインします。
# grubの編集
以下のコマンドでgrubのメニューを編集します。
```
sudo vim /boot/grub/menu.lst
```
一番下の「End Default Options」にある「kernel」の項目に先程と同様に最後に「noapic」を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770088/a47241bb-7263-bc88-f2d4-2a6c2723911f.png)
`:wq`で保存します。

:::note info
注意
USキーボードなので、:は、shift+; です。
:::
# ネットワーク設定
固定IPに設定します。
```
sudo vim /etc/network/interfaces
```
以下のように編集します。
IPアドレスを192.468.56.20にする場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770088/328b9f3b-0376-0ab7-80d2-0abc0d6788d8.png)
`:wq`で保存します。
再起動します。
EventBrigeでスケジューラを作成して日次でLambdaを実行する

# はじめに
本記事ではAWSのEventBridgeを使用して、日次で特定の時間にLambdaを動かすスケジューラを実装していきます。


# ゴール
日次で21時にLambdaが実行されるようにEventBrigeでスケジューラを作成する



# 1. Lambdaの作成

EventBrigeから実行する簡単なLambdaを作成しておきます。

```python:lambda_function.py
def lambda_handler(event, context):
    print("スケジューラにより処理を実行")
    return {
        'statusCode': 200,
        'body': 'test'
    }
```


# 2. EventBridgeの作成

- **ルールの作成**

Amazon EventBridge > ルール > ルールの作成から定義を作成していきます。
任意のルール名、説明 を記載しルールタイプは `スケジュール` を選択します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/9294ea56-1be7-d77f-813d-aac854bedc13.png)


- **スケジュールの cron 式**

今回はタイムゾーンに `東京リージョン` を指定しておきます。
cronベースのスケジュールを選択し、日次で21時に実行するよう設定します。

```:cron式
cron(0 21 * * ? *)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/2563cbdc-aca4-382b-2673-f30c5881fae6.png)


- **呼び出すLambdaの選択**

`1. Lambdaの作成` で作成したLambdaを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/338a10a4-ef57-5f25-be1a-feb69bb52b03.png)

ここまで出来たらデフォルトの設定のままルールをデプロイします。


# 3. 動作の確認

Lambdaの実行ログをCloudWatchで確認すると、21時にLambdaが実行されてることを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/77cc1b0e-3cfd-5daf-9c47-b907fa1f9272.png)
時間効率UP：Macのターミナルで使える便利なショートカットまとめ

## はじめに
Macのターミナルには、コマンド入力や編集を効率化するための多くのキーボードショートカットが用意されています。

これらのショートカットを活用することで、日常の作業をよりスムーズに進めることができ、開発効率が格段に向上します。

本記事では、特に便利なショートカットをまとめて紹介します。

## エンジニアは時間が命
エンジニアにとって、時間は最も大切な資源の一つです。

キーボードショートカットをマスターすることで、無駄な操作を減らし、より重要な作業に集中することができます。

私自身、ショートカットを使うようになってから、コーディングやターミナル操作が格段に効率化されました。

時間を節約することは、より多くのことを成し遂げる鍵です。

## テキスト編集系ショートカット
ターミナルでのテキスト編集を素早く行うためのショートカットです。

**・``Control + A``: カーソルを行の先頭に移動
・``Control + E``: カーソルを行の末尾に移動
・``Control + U``: カーソルから行の先頭までを削除
・``Control + K``: カーソルから行の末尾までを削除
・``Control + W``: カーソル前の単語を削除
・``Control + Y``: 直前に削除したテキストを貼り付け
・``Option + ←``: カーソルを左側の単語の先頭に移動
・``Option + →``: カーソルを右側の単語の先頭に移動
・``Control + L``: 画面をクリアしてカーソルを上部に移動（コマンドは消えません）**

:::note warn
特に「``Control + A``」や「``Control + U``」は、頻繁に使う非常に便利なショートカットです。
:::

## コマンド履歴関連ショートカット
以前に実行したコマンドをすぐに呼び出せる便利な機能です。

**・``Control + R``: コマンド履歴を逆順で検索
・``↑``: 前に実行したコマンドに戻る
・``↓``: 次のコマンドに進む（↑で戻った履歴を進む時に使用）**

:::note warn
履歴検索はとても便利で、直前に使ったコマンドを素早く見つけ出せるのが魅力です。
:::

## 実行系ショートカット
実行中のコマンドを制御したり、シェルの状態を操作するためのショートカットです。

**・``Control + C``: 実行中のコマンドを強制終了
・``Control + D``: シェルを終了（ログアウト）
・``Control + Z``: 実行中のプロセスを一時停止し、バックグラウンドに送る**

:::note warn
強制停止のショートカットはあまり使う機会が少ないかもしれませんが、知っておくと便利です。
:::


## その他
さらに便利な補助的なショートカットを紹介します。

**・``Tab``: コマンドやファイル名の自動補完
・``Control + T``: カーソル位置の文字とその前の文字を入れ替え
・``Command + K``: ターミナルの表示をクリア**

:::note warn
「``Tab``」による自動補完や「``Control + T``」の文字入れ替えは、日常的に頻繁に使っています。
:::


## まとめ
Macのターミナルでは、キーボードショートカットを駆使することで、作業スピードを大幅に向上させることができます。

日々のコマンド操作を効率化し、エンジニアとしての生産性を高めるために、ぜひこれらのショートカットを習得してみてください。

## おまけ：historyコマンドとgrepコマンドを使った過去コマンドの検索

``history`` コマンドは、これまでに実行したコマンドの履歴を表示するための便利なツールです。

しかし、履歴が多い場合には特定のコマンドを見つけるのが難しくなります。そんなときに ``grep`` コマンドと組み合わせて使うと、簡単に特定のコマンドを検索できます。

例えば、以前に使った ``git`` コマンドを検索したい場合は、以下のように実行します。

```bash
history | grep git
```

このようにして、必要なコマンドをすぐに見つけることができます。

## 参考文献

https://www.sejuku.net/blog/124447

https://qiita.com/free-honda/items/ae82ecf888352b839c5b
Salesforceアクションの新規行動

Salesforceの新規アクション作成時の注意点


今回は「取引先から取引先に紐づく行動を作成」するアクションについて2パターン作成方法があることを解説します


## パターン1 表示ラベル設定可能

「標準の表示ラベル種別」を「なし」に設定することで表示ラベルを任意に設定可能
（今回は例として「新規行動AA」と表示）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c7909d09-cb88-9fe0-10ff-785be7307692.png)



## パターン1 表示ラベル設定可能でない

「標準の表示ラベル種別」を設定すれば表示ラベルは設定できません

今回は「標準の表示ラベル種別」を【新規[レコード]】に設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/979211f3-3217-05a7-45ef-8c846b518967.png)


上記パターン1 パターン2ともに
・「取引先から取引先に紐づく行動を作成」するアクション
です。

しかし、
もしも表示ラベルの変更ができないパターン2の場合、設定時に既存のアクション「新規行動」と同じ見え方になるので設定誤りを引き起こす可能性が高くなります


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a8eac25f-e54e-ddb8-f3aa-290d80f2829f.png)


## おまけ
もしもこのように新規行動のアクションを複数ページレイアウトに配置した場合は

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7ff373ce-6467-067d-c419-7d04608c8e1b.png)


レコードページからだとこのように「▼」ボタンをクリックすることでどの新規行動アクションかを設定することが可能です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/3f45c5c3-489d-1838-b3e4-02c86eecf0e7.png)
Python で breakpoint を使うと， bdb.BdbQuit と出る．

# TL;DR;
`num_workers=0` にしましょう．

# 経緯
- 諸事情で `PyTorch` コードを解析していた．
- `breakpoint()` を駆使してコードを解析．
- 何故か特定の位置に `breakpoint()` を挟むと `bdb.BdbQuit` と出て落ちる．

# 解決
- `breakpoint()` の前後が複数回出力された後に落ちている．
- 適当にググると良さそうな [issue](https://github.com/Megvii-BaseDetection/YOLOX/issues/843) が見つかる．
- `torch.utils.data.DataLoader` のインスタンス作成時に， `num_workers=0` を指定する．
PaizaCloudをさわってみた①

# PaizaCloudをさわってみた①

AWSのCloud9を使って学習しようと考えていたものの、
新規の受付停止してしまっていたため、代替案を探していたところ
[PaizaCloud](https://paiza.cloud/ja/)を発見。さわってみることにしました。

## サーバ作成画面

登録作業は割愛します。
登録後のサーバ作成画面。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904514/5d24d04a-07f4-91b0-8c10-78712ef13562.png)

好きなものを選んで、作成ボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904514/63e456d8-73cc-c922-1afc-b74fbb19ef45.png)

数秒後にできた！
左上のメニューからターミナル起動したりできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904514/3b962f25-5720-34d2-aeac-ad3e0e01695a.png)

いいかんじ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904514/db3171c7-7fd1-e577-fed7-4b5ab2ef0b1b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904514/73b7c546-ea58-11d1-bb89-af0d8da92ea4.png)

次回はもっとさわっていく。
無料プランは以下の制約があるので、まとめて時間とれるときに集中してさわるのがよさそう。

- 利用期間 24時間
   (同じサーバ環境を継続利用できる時間)
- 連続起動時間 ブラウザ開いている間 (最大4H）

とはいえ無料で使えるの本当ありがたい。
よかったらアップグレードも視野に入れる。
【ServiceNow】テーブルのリストをカスタマイズしてみよう

はじめに
---
ServiceNowを使用しているとテーブルのリストに表示させたい項目が出てくると思います。

簡単なやり方なので、ぜひ使用してください。

---

[前回の記事]

https://qiita.com/masa3150/items/7b0d3fe4428234d8e24e


テーブルのリストをカスタマイズしよう
---
１.対象テーブルのリストビューを表示し、「リストをカスタマイズ」を選択します。
![スクリーンショット 2024-10-22 20.33.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/c5b2d22a-7159-6ded-9ede-874ae1925498.png)


2.今回は項目「アクティブ」を表示させるため、
アクティブを「利用可能」→「選択済み」に追加します。
![スクリーンショット 2024-10-22 20.41.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/e1b7e575-25e4-65be-5af4-c057833dc451.png)

![スクリーンショット 2024-10-22 20.41.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/780dbc74-81e5-837d-320d-4e01f34204a8.png)

3.番号の隣に表示させたいので、アクティブの位置を移動させ、OKボタンを押下します。
![スクリーンショット 2024-10-22 20.44.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/ca25c156-5d73-01b5-db58-e58902d5f6f4.png)

![スクリーンショット 2024-10-22 20.45.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/df54ebed-415d-b007-6b59-cf35126cfdab.png)

4.リストビューを確認すると、番号の隣にアクティブが追加されていることが確認できます。
![スクリーンショット 2024-10-22 20.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/78b3dbda-e092-be2e-b00c-b2f0b57c354d.png)


終わりに
---
表示させたい項目をリストに追加すれば、レコードの情報を簡単に参照ができるので
単体テストなどを効率よくできると思います。
【Jenkins】java.io.IOException: CreateProcess error=2, 指定されたファイルが見つかりません。

# 原因
`Cannot run program "nohup"`がエラーにあれば、`C:\Program Files\Git\usr\bin`がWindowsのPathに追加されていないため

# 対応方法
`C:\Program Files\Git\usr\bin`をシステム環境変数`Path`に追加する。

# 参考
https://teratail.com/questions/186520
DatabricksのNewダッシュボードで地図がサポートされました

一年ほど前にDatabricksのダッシュボードの機能がLakeviewの名前の元、リニューアルされました。

https://qiita.com/taka_yayoi/items/32afd1566b5bc3bedbec

様々な点で改善が図られていたのですが、レガシーのダッシュボードでサポートされていた地図のビジュアライゼーションがNewダッシュボードでサポートされていなかったことに悲しい思いをしていました。

しかし、今回改めて**シンボルマップ**として地図のビジュアライゼーションがサポートされました！

https://docs.databricks.com/ja/dashboards/visualization-types.html#symbol-map
> **シンボルマップ**
> シンボルマップは、定量的なデータを特定のマップ位置に配置されたシンボルとして表示します。 マーカーは緯度と経度の座標を使用して配置され、このグラフの種類の結果セットの一部として含める必要があります。 次の例では、ニューヨーク州ニューヨークでの自動車衝突事故のデータを使用しています。 

![](https://docs.databricks.com/ja/_images/symbol-map.png)

嬉しい。早速使ってみます。

# データの準備

最低限でも緯度経度のデータが必要です。以下のような空港のデータを使います。

![Screenshot 2024-10-22 at 20.27.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1933435a-5d2e-fcc1-d326-91d7c3335481.png)

# ビジュアライゼーションの作成

カタログエクスプローラでテーブルにアクセスし、右上の**作成**から**ダッシュボード**を選択します。

デフォルトでは地図は表示されませんでした。アシスタントにも頼ってみたのですがイマイチだったので、手動で作成します。可視化のタイプから**Point map**を選択します。

![Screenshot 2024-10-22 at 20.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/29052f6e-0a5e-ff23-a3d2-351aa5e00c89.png)

緯度経度を選択すると、地図上にプロットが表示されます。

![Screenshot 2024-10-22 at 20.31.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9fd52be4-1ca0-c56c-c9e3-4e1494f7eeb5.png)

公開すれば地図ダッシュボードの完成です。

![Screenshot 2024-10-22 at 20.32.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/da2fe004-5d82-6073-8a53-729714407d21.png)

ズームも可能です。

![Screenshot 2024-10-22 at 20.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a9f38fff-3f36-a720-c38d-be8ef067c8a3.png)

もう一つの設定に**色/グループ化**があります。名前の通り、グルーピングに用いる列を選択することで、それに応じてマーカーが色分けされます。以下の例では国図別に色分けしています。

![Screenshot 2024-10-22 at 20.33.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3e1ed32f-5446-f34e-b40d-84a084db970d.png)

高度で分類も可能です。

![Screenshot 2024-10-22 at 20.34.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/20cb0032-e715-2f20-d4dc-1dfa03a1f15a.png)

名前の列`name`は一意なので、空港ごとに色分けされてラベルも設定されます。

![Screenshot 2024-10-22 at 20.35.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/31de80a4-9d99-87ac-1245-9bc8a37218c5.png)

是非試してみてください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
出力引数とは

### 出力引数とは何か

**出力引数**とは、メソッドや関数に渡された引数のうち、メソッド内部で処理され、結果がその引数を通じて呼び出し元に返されるものです。通常の戻り値では1つの値しか返せませんが、出力引数を使うことで、複数の値を返すことが可能になります。

**例:**

```java
public class OutputParameterExample {
    public static void calculateSumAndProduct(int a, int b, int[] results) {
        results[0] = a + b;  // 和
        results[1] = a * b;  // 積
    }

    public static void main(String[] args) {
        int a = 5;
        int b = 3;
        int[] results = new int[2];  // 結果を格納する配列

        calculateSumAndProduct(a, b, results);

        System.out.println("Sum: " + results[0]);      // 出力: 8
        System.out.println("Product: " + results[1]);  // 出力: 15
    }
}

```

このように、メソッド内で処理された結果が配列を通じて呼び出し元に返されます。

---

### 出力引数が設計的によくないのはなぜか

出力引数は、**低凝集**を招きやすく、設計的に問題が生じることがあります。主な理由は以下の通りです。

1. **複数の責任を持ちやすい**: メソッドが複数の値を返すことで、単一責任の原則（Single Responsibility Principle）に反し、1つのメソッドが多くの役割を持つことになりがちです。これはコードの再利用性やメンテナンス性を損ないます。
2. **可読性が低下する**: 出力引数は、コードの意図を不明瞭にし、結果がどこで変更されているかが分かりにくくなります。これにより、バグの原因を特定しにくくなることがあります。
3. **副作用の発生**: 出力引数を使うと、呼び出し元のデータが予期せず変更される副作用が発生しやすく、コードの予測性が低くなります。

**悪い例:**

```java
public class OutputParameterExample {
    public static void modifyValues(int a, int[] result) {
        result[0] = a * 2;  // 呼び出し元の配列を変更
    }

    public static void main(String[] args) {
        int a = 5;
        int[] result = new int[1];

        modifyValues(a, result);

        System.out.println("Modified Value: " + result[0]);  // 出力: 10
    }
}

```

この例では、呼び出し元で渡した配列がメソッド内で変更されており、予期しない副作用が生じています。

---

### 出力引数ではない方法で良い設計とは

出力引数の代わりに、オブジェクトを返す設計がより推奨されます。複数の値を返す必要がある場合は、**オブジェクトを使って単一の戻り値**として返すことで、メソッドの責任を明確にし、コードの凝集度を高めます。

また、Javaでは`Tuple`や`Result`クラスを使って複数の結果を返す方法があります。

**良い例:**

```java
// 複数の結果を持つクラス
public class Result {
    private int sum;
    private int product;

    public Result(int sum, int product) {
        this.sum = sum;
        this.product = product;
    }

    public int getSum() {
        return sum;
    }

    public int getProduct() {
        return product;
    }
}

public class GoodDesignExample {
    // 和と積を計算し、Resultオブジェクトで返す
    public static Result calculateSumAndProduct(int a, int b) {
        int sum = a + b;
        int product = a * b;
        return new Result(sum, product);  // 結果をオブジェクトとして返す
    }

    public static void main(String[] args) {
        Result result = calculateSumAndProduct(5, 3);
        System.out.println("Sum: " + result.getSum());      // 出力: 8
        System.out.println("Product: " + result.getProduct());  // 出力: 15
    }
}

```

**この設計のメリット:**

- **単一責任**: `Result` クラスが2つの結果を保持し、メソッドは1つの責任（計算すること）に集中できます。
- **可読性が向上**: メソッドが返すものが明確で、コードの意図が理解しやすくなります。
- **副作用なし**: 呼び出し元のデータが予期せず変更されることがないため、安全です。

---

### まとめ

- **出力引数**は、メソッドが複数の値を返すための方法ですが、凝集度が低くなり、コードの可読性や予測性が低下しやすいため、推奨されません。
- **良い設計**は、オブジェクトを使用して複数の値を1つにまとめて返すことです。これにより、単一責任を持たせ、コードの保守性を向上させることができます。
クロック周波数とCPUの性能指標

## はじめに
1日1項目1時間学ぼうの会
今回学んだ内容は**クロック周波数について**です。

## クロック周波数とは
クロック周波数は、CPU（中央処理装置）が1秒間に何回の命令サイクルを実行できるかを示す指標で、一般的にGHz(ギガヘルツ)で表わされる。
3.5GHzのCPUは1秒間に35億回の命令サイクルを処理できる能力があることを意味する。

## クロック周波数が高いほうがよい理由
クロック周波数が高いことは、CPUが1秒間に多くの処理サイクルを実行できることを意味し、いくつかの場面で大きな利点をもたらします。

### 応答速度の向上
高いクロック周波数により、CPUはより迅速にユーザー入力に応答できます。
例：Webブラウザでのページ切り替えや、OS上のUIの反応。
メリット：
・アプリケーションのレスポンスが良く、使い心地が向上。
・メール、ブラウジング、文書編集など、CPU負荷が少ない場面での体感速度が上がる。

### リアルタイム処理が必要な作業に有利
高速なクロック周波数は、リアルタイム性を要求する処理に有効です。
例：音楽制作（DAWソフト）、動画ストリーミング処理、金融取引システム。
メリット：
・音楽制作ソフトでの遅延が減少。
・動画や音声処理がスムーズになり、タイムラグが少なくなる。

### プログラムの高速コンパイル
プログラミングの際、コードのコンパイルはCPUに大きな負荷をかけます。クロック周波数が高ければ、1つのプログラム全体を迅速にコンパイルできます。
メリット：
・特に、JavaやC++などの複雑なプログラムのビルド時間が短縮。

## クロック周波数が高いことによるデメリット
CPUのクロック周波数が高いと多くのメリットがありますが、その一方でいくつかのデメリットも発生します。

### 発熱が増加する
クロック周波数が高いほど、CPUは多くのエネルギーを消費するため、発熱が増大します。
発熱によってCPUの温度管理が難しくなり、システムの安定性に影響を与える可能性があります。
十分な冷却ができないと、CPUはパフォーマンスを自動で落とす「サーマルスロットリング」が発生します。

### 消費電力が増加する
クロック周波数が高いCPUはより多くの電力を消費するため、特にノートPCや省エネが求められる環境では不利です。
電力消費が多いと、バッテリーの持続時間が短くなり、電気代も増加します。

## まとめ
クロック周波数基本情報技術者試験の時に学習したが試験対策では計算をメインに行うのであまり詳しくは調べなかった。
今回学習をしてより計算の内容や意味を理解することができた。
クロック周波数で一番しっくりきた表現がこれ

![スクリーンショット 2024-10-22 6.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2120218/37618a27-1760-819a-ad38-3624676e9812.png)


とてもわかりやすい。

## 参考
https://www.intel.co.jp/content/www/jp/ja/gaming/resources/cpu-clock-speed.html

https://www.pc-koubou.jp/magazine/23926
勤たろう(勤怠アプリ)を作成しました

自社の勤怠管理方法(自分でExcel手入力)が面倒くさすぎて、勤怠管理アプリを作成しました。
インストーラ等をGithubに配置してありますので、ご自由にお使いください。

https://github.com/shouzou-nozaki/AttendanceManagement/tree/main/%E5%8B%A4%E3%81%9F%E3%82%8D%E3%81%86_%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%A9

言語：C#
使用ライブラリ：(NuGetからインストールしたもの)
・EPPLUS　Excelファイル作成
・Extended.Wpf.Toolkit　TimePicker実装


（後日談）
自社で勤たろうの正式導入が決定しました。
ということで、もう少し改良しようと思います。
htmxを使ってみた-(12)確認ダイアローグ-

## htmxの確認ダイアローグ(hx-confirm)
htmxでは[確認ダイアローグを簡単に利用](https://htmx.org/examples/confirm/)できます。
利用方法は簡単で、タグに
```HTML
<td class="pseude_link" hx-delete="/del_institution/26/5" hx-target="#inst_26" hx-swap="delete" hx-confirm="データを削除します。
削除したデータを戻すことはできません。">x</td>
```
などと、hx-confirm属性を付けるだけです。
上記の例では、
タグをクリックすると、
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/43d4700b-87e0-57d3-9223-8a723768c8ba.png)

というダイアローグが表示されます。
OKを押せば処理を実行し、キャンセルを押せば処理を行いません。
生のJavaScriptで、OK/Cancel判定をするよりも簡単です。

:::note info
~~改行できない？
htmx ver.2.0.2では、
hx-confirm="データを削除します。\n削除したデータを戻すことはできません。"
として、改行コードを入れましたが、改行できませんでした。~~
改行すれば良いだけでした。
:::


## ht-promptの利用
htmxには、[ht-promptとht-confirmを組み合わせた例](https://htmx.org/examples/dialogs/)があります。

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(11)データベースの排他制御-

## 楽観的な排他制御
データベースを利用する際に、同じデータを同時期に複数の端末から変更（削除）する場合を考えておく必要があります。
データベースの排他制御、または、長時間トランザクションと呼ばれる処理です。
排他制御には、楽観的制御と悲観的制御がありますが、練習プログラムでは、簡単に実装できる楽観的排他制御を用いています。
具体的には、データ構造に「更新回数」というカラムを作り、
```SQL:sightseeing.sql
CREATE TABLE `sightseeing` (
  `ID` int(10) UNSIGNED NOT NULL,
-- (中略)
  `登録日` date NOT NULL DEFAULT current_timestamp(),
  `更新日時` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `更新回数` int(10) UNSIGNED NOT NULL DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='高山市の観光施設：オープンデータ';
```

更新フォームに、更新回数のタグを用意し、
```HTML
<tr>
	<th>更新回数</th>
	<td><input type="text" name="version" readonly value="0"></td>
</tr>
```

「更新回数」の名前は version です。
サーバーから情報を得たときと更新回数が変化していなければ、データの更新を行うようにしています。
```python:p02.py
@router.put('/update_institution')
def update_institution(ID:int=Form() , name:str=Form() , kana:str=Form() , addr:str=Form() , exp:str=Form(None) , url:str=Form(None) , note:str=Form(None) , version:int=Form()):
	'''指定されたデータを更新する
 (中略)
	'''
	conn = mydb.connect(**config.database)
	cur = conn.cursor(dictionary=True)
	sql = ("UPDATE `sightseeing` SET "
		   "`名称` = %s , "
		   "`名称_カナ` = %s , "
		   "`住所` = %s , "
		   "`説明` = %s , "
		   "`URL` = %s , "
		   "`備考` = %s , "
		   "`更新回数` = `更新回数` + 1 "
		   "WHERE (`ID` = %s) AND (`更新回数` = %s) " )
	param = (name , kana , addr , exp , url , note , ID , version)
	cur.execute(sql , param)
# (中略)
	return HTMLResponse(content)
```
プログラムでは、`更新回数` = `更新回数` + 1 として、更新に成功すれば、更新回数を上げるようにもしています。
また、readonly属性を付けて、編集不可にしています。
type="hidden"として、ユーザーに見せなくても良いかもしれません。

:::note info
更新の判断について
MySQLには、ON UPDATE current_timestamp()という属性があるので、以前は、更新日時を更新されたかどうかの判断に使っていました。
データが更新されれば、MySQLが自動的に日時を変更してくれるので便利です。
しかし、日時では不具合があるという記事を読んだので、「更新回数」を使うようにしました。
:::

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(9)ページの再読み込み-

## 画面の再読込
HTML では、\<form>、\<a>タグをクリックすると画面が遷移（ページの書き換え）します。
htmxでは、[hx-boost="true"属性](https://htmx.org/docs/#boosting)を\<form>、\<a>タグに付与することで、画面全体を再読込せずに、\<body>タグの中身だけを更新できるような機能があります。
\<head>タグ内で、多くのCSS、JavaScript を読み込ませている場合、再度、CSSやJavaScriptを読み込み評価しなくて済むので、処理が軽くなる（？）そうです。

## hx-boost属性の利用
練習プログラムでは、「データ再読み込み」ボタンとして使っています。
```HTML:html00.j2
<form action="/reload_institution" method="get" hx-boost="true" style="display: inline">
	<input type="submit" value="データ再読み込み" title="施設を追加した後に実行すると、名称のヨミガナ順に並び替えます">
</form>
```
練習プログラムでは、追加したデータを「施設追加」ボタンの上に表示して、追加データの確認を行いやすいようにしています。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/e74072bc-5a5f-7a5e-512f-d33eafdf202e.png)
追加の確認は、ボタンのうえに出てきた方が便利ですが、名前から探す場合は、ヨミガナ順に並んでいた方が便利です。
そこで、「データ再読込み」ボタンをつくって、サーバーからヨミガナ順に並べられたデータをもらいます。

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(7)データ追加-

## データの追加ダイアローグを出す
練習プログラムでは、一覧表の最下部に、追加ボタンを取り付けています。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/682f0370-adb3-cfdc-645c-f7b78e9de705.png)
ボタンのHTMLデータは、htlm00.jsのテンプレート内で次のように作っています。

```HTML
<input type="button" value="施設追加" hx-get="/new_institution" hx-target="#detail" hx-on::after-request="show_dialog()">
```
「施設追加」ボタンを押すと、次のようなダイアローグが出てきます。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/6cf9065b-17a2-3b78-f641-0780ba9ea590.png)
ダイアローグの内容はhtml04.j2です。
「個別表示」と同じようにして、\<dialog\>の中身を変えています。

## AJAXリクエストのトリガー
htmxは標準で次のようなイベントが起きたときに、AJAX通信を行います。
| HTMLタグ | トリガー |
|:-|:-|
| input、textarea、select  | 内容が変わったとき(onChange)  |
| form  | submitされたとき(submitボタンが押された)(onSubmit)  |
| その他  | クリックされたとき(onClick)  |

とても”自然”なAJAXリクエストとなっています。
標準を変えたい場合は、hx-trigger属性で指定します。
hx-trigger では、コントロールキーを押しながら等の修飾も加えることができます。

## データ追加ダイアローグ
html04.j2がダイアローグの中身です。
```HTML
<form hx-post="/add_institution" hx-target="#add_btn" hx-swap="beforebegin">
	<input type="hidden" name="ID" value="-1">
	<table style="width:27rem">
		<tr>
			<th>名称</th>
			<td><input type="text" required name="name" value=""></td>
		</tr>
  <!-- 中略 -->
	</table>
	<div class="right_button">
		<input type="submit" value="　追加　">
		<input type="button" value="閉じる" onclick="close_dialog()" autofocus>
	</div>
</form>
```
練習プログラムでは、
1. 「追加」(type=submit)ボタンが押されると、submitイベントが発火し、
1. hx-post属性により、HTTPのPOSTメソッドで、サーバーの/add_institutionにアクセスし、
1. hx-target属性により、サーバーからの応答で、idにadd_btn"を持つタグの中身を、
1. hx-swap属性による方法(beforebegin)に従って書き換えます。

hx-swap属性ではbeforebeginが指定されていますので、hx-target属性で指定される要素の前に、応答が追加されます。
サーバー側のプログラムは、p04.pyにある、add_institution()関数です。
add_institution()関数は送られてきたデータをデータベースに登録し、成功した場合は、登録データを整形成形して返します。
登録に失敗した場合は、エラーを返します。

:::note warn
htmxによってformタグの動作が書き換えられている。
:::

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(6)データの表示-

## データを表示する
施設名をクリックすると、個別のデータをダイアローグで表示します。
施設名の内容は、例えば、
```HTML
<td class="pseude_link" hx-get="/view_institution/26" hx-target="#detail" hx-on::after-request="show_dialog()">あかんだな駐車場</td>
```
のようにしています。
上記の例では、
1. \<td\>タグをクリックすると、
1. ht-get属性により、HTTPのGETメソッドでサーバーの/view_institution/26にアクセスし、
1. ht-target属性により、サーバーからの応答で、idに"detail"を持つタグの中身を書き換え、
1. hx-on属性により、AJAXのリクエストが終了した(after-request)ら、show_dialog()を呼び出します。

:::note info
中身を書き換えた後のHTMLデータにも、しっかりイベントがついています。（けっこうすごい！）
:::

pseude_linkクラスは、文字にアンダーラインを付け、カーソルの形状を変えるというもので、機能的に意味はありません。
こんな感じのダイアローグがでます。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/8d8f5ace-da74-5732-0132-1a5488813649.png)
show_dialog()では、モーダルダイアローグを表示していますので、「閉じる」ボタンを押すまで他の操作はできません。

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(5)HTMLのdialog-

## HTMLのdialogタグ
HTML5で\<dialog\>タグが新設されました。
```HTML
<dialog id='detail'> <!-- id名は任意 -->
<!-- dialogに表示する中身 -->
</dialog>
```
と簡単に書き、JavaScriptで開いたり閉じたりします。
JavaScriptを利用してモーダルダイアローグを開く場合は
```JavaScript
document.getElementById("detail").showModal();
```
ダイアローグを閉じる場合は、
```JavaScript
document.getElementById("detail").close();
```
とします。
showModal()ではなく、show()とすれば、単純にダイアローグが開きます。
練習プログラムでは、 p00.js に書いてあります。

## htmxのJavaScriptAPI
htmxでは、要素へのアクセス、要素へのクラスの追加・削除などの[JavaScriptAPI](https://htmx.org/reference/#api)が用意されています。
この関数群を使えば、生のJavaScriptよりも、簡単に記述することができます。
上記の例では、
```JavaScript:p00.js
/**
 * 詳細ダイアローグボックスを開く
 */
function show_dialog() {
	htmx.find("#detail").showModal();
}

/**
 * 詳細ダイアローグボックスを閉じる
 */
function close_dialog() {
	htmx.find("#detail").close();
}
```
と書けます。生のJavaScriptより、若干ですが簡単になります。

:::note info
ソースファイルのコメント
ソースファイルにコメントを書かない人がいますが、来週の自分のためにコメントはこまめに書きましょう。
VSCodeなどのモダンエディターでは、関数にカーソルを合わせると、コメントを表示してくれる機能があり便利です。
:::

## dialogの修飾
CSSでdialogを修飾しています。
```CSS:p90.css
/* 詳細ダイアローグ */
#detail {  /*ダイアローグの外形*/
	padding: 0.5rem;
	width: 27rem;
	border: 1px solid var(--color-main);
	border-radius: 7px;
}

dialog::backdrop { /*ダイアローグの背景*/
	backdrop-filter: blur(1px);
	background-color: rgba(0, 0, 200, 0.1);
}
```
ダイアローグの表示、ブロック要素の角を丸くすること、背景をぼかすことなどをCSSで実現しています。
楽になったものです。

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(4)htmxを使う-

## htmxを使う
練習プログラムでは、一覧表の１行を次のように出力しています。
```html
<tr id="inst_26" hx-on::before-swap="change_institution(event)">
	<td class="pseude_link" hx-get="/view_institution/26" hx-target="#detail" hx-on::after-request="show_dialog()">あかんだな駐車場</td>
	<td>高山市奥飛騨温泉郷平湯791番地38</td>
	<td>有料駐車場、バス待合所</td>
	<td></td>
	<td></td>
	<td class="pseude_link" hx-get="/edit_institution/26" hx-target="#detail" hx-on::after-request="show_dialog()">*</td>
	<td class="pseude_link" hx-delete="/del_institution/26/5" hx-target="#inst_26" hx-swap="delete" hx-confirm="データを削除します。削除したデータを戻すことはできません。">x</td>
</tr>
```

上記の２行目
```html
<td class="pseude_link" hx-get="/view_institution/26" hx-target="#detail" hx-on::after-request="show_dialog()">あかんだな駐車場</td>
```

の意味は、
1. \<td\>要素がクリックされたら、
1. hx-get属性により、HTTPのGETメソッドで/view_institution/26にアクセスし、
1. hx-target属性により、サーバーからの応答で idに"detail"を持つ要素(の中身を書き換え、
1. hx-on属性により、AJAX終了後(after-request)に、JavaScriptのshow_dialog()関数を呼び出します。

show_dialog()関数はp00.jsにあります。
ht-get などと一緒によく使われると思われる属性には次のようなものがあります。

| htmx属性 | 内容 |
|:-|:-|
| hx-target  | サーバーからの応答を書き換える要素を指定。<br>デフォルトは自分自身<br>ターゲットはCSSセレクタの形式で指定  |
| hx-swap  | 要素を書き換える方法。<br>デフォルトは中身を書き換える。<br>９種類用意されている  |
| hx-on  | イベントを設定する。<br>要素が書き換えられたらなど多くのイベントを設定することができる  |

:::note warn
hx-onで指定するイベント名について
[htmxのホームページ](https://htmx.org/reference/#events)には、イベントの名前をキャメルケース（afterRequestなど）で書いてありますが、指定するときにはケバブケース（after-requestなど）にしないといけないようです。
:::

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
htmxを使ってみた-(3)ルート関数-

## ルート関数
```
http://localhost:8001/
```
にアクセスしたときに呼び出される関数（勝手に「ルート関数」と呼んでいます）は、fastapi\app\prog\p00.y にあるdef root_function()です。
```python:p00.py
@router.get('/')
def root_function():
	'''ルート関数。データの一覧表を出力する
	'''
	conn = mydb.connect(**config.database)
 # (中略 データベースを開いてデータを取り出す)
 
	template = env_j2.get_template('html00.j2')  #テンプレートを利用して出力データを整える
	main = template.render(table_caption='観光施設一覧' , institutions=institutions)

# (中略)
	# データを返す
	return HTMLResponse(content=head + main + footer + "\n</body>\n</html>\n")
 ```

:::note info
MySQLへのアクセス
SQLAlchemyというライブラリを使うことが標準みたいですが、SQLを書くことができるmysql-connector-pythonを利用しました。
:::

:::note info
MySQLのストレージエンジン
MySQLは色々なストレージエンジンを使うことができますが、InnoDBが良いとされています。
しかし、コールドバックアップができるという１点のため、MyISAMを使っています。
コールドバックアップは、MySQLを止めてからファイルをコピーするのですが、私は、誰もアクセスしていない時間に、MySQLを止めずに、ディレクトリごと圧縮・コピーしています。
:::

:::note info
MySQLのカラム名
カラム名に日本語（マルチバイトコード）を使っています。
最初は怖かったのですが、今のところ問題なく動いています。
UTF-8なので、ソースコードのラベル（関数、変数名など）にも、日本語が使えるはずなのですが、怖いのでやったことがありません。
:::

# ページ（データ）出力
root_function()関数で出力するデータを整えています。
前半で、データベースからデータを取り出し、後半でテンプレートにデータを流し込んで、HTML形式でデータをクライアントに返しています。
テンプレートは、html90.j2 , html99.j2 , html00.j2 と３つ使っています。３つに分けるのが良いかどうかわかりません。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/799cfe6f-9dfc-94d7-c4f6-ae854cfbfe4f.png)
のような画面ができます。

:::note info
ファイル名について
普通の人は、「load_data.py」とか「save_data.py」などと機能が分かる名前を付けると思いますが、私は、英語の名前を考えるのが面倒なので、通番にしています。案外便利です。
:::

## 関連記事一覧
[htmxを使ってみた-(1)htmxの基本-](https://qiita.com/Final1900/items/49a8ac6f27a2427f6306)
[htmxを使ってみた-(2)準備-](https://qiita.com/Final1900/items/9e46fd6630e4bdf90a73)
[htmxを使ってみた-(3)ルート関数-](https://qiita.com/Final1900/items/293a0c8b42465bbb5142)
[htmxを使ってみた-(4)htmxを使う-](https://qiita.com/Final1900/items/f745c4cc34c8d36548f7)
[htmxを使ってみた-(5)HTMLのdialog-](https://qiita.com/Final1900/items/8584ead01e9c842cc60f)
[htmxを使ってみた-(6)データの表示-](https://qiita.com/Final1900/items/33df506cbeb5979c3cfc)
[htmxを使ってみた-(7)データ追加-](https://qiita.com/Final1900/items/a8206948e6d9ac98f105)
[htmxを使ってみた-(8)要素の変更-](https://qiita.com/Final1900/items/aefc518dacbfaf5d9a2a)
[htmxを使ってみた-(9)ページの再読み込み-](https://qiita.com/Final1900/items/783284ff1ad1d02810d5)
[htmxを使ってみた-(10)データの変更-](https://qiita.com/Final1900/items/9541c05d392b137266f3)
[htmxを使ってみた-(11)データベースの排他制御-](https://qiita.com/Final1900/items/db2a48748cd45262ac8b)
[htmxを使ってみた-(12)確認ダイアローグ-](https://qiita.com/Final1900/items/08e1fb3608d3cf0cbc8c)
[htmxを使ってみた-(13)データ削除-(最終)](https://qiita.com/Final1900/items/5389a4890e0d08549810)
PythonのUnboundLocalErrorが発生する原因を理解する

# 概要

グローバル変数を使っていたところ`UnboundLocalError`が発生しました。
ドキュメントにも書いてあることなのですが、改めて簡単にPythonのスコープを検証してみます。

# 環境

Python3.12

# UnboundLocalErrorが発生するコードとハマった原因

```Python

val = 0


def f():
    val += 1  # UnboundLocalErrorになる
    print(f"f scope: val = {val}")


f()
```

これをそのまま実行すると`UnboundLocalError: cannot access local variable 'val' where it is not associated with a value`のようにエラーとなります。


このコードを書いたときの思考としては

1. `val = 0`はグローバルで宣言している
1. 関数内でも`val`は使える
1. なら`val`の値も更新できる

でした。

特に最後の`val`の値を更新できるというのが間違っていました。

Pythonにおいて関数の外で宣言された変数（ここでいう`val`）は、参照しかされなければグローバル変数として振る舞います。ただし、値が代入された場合ローカル変数になります。

ややこしいのは`val += 1`が一見すると実行できそうに見えることです。
書き換えてみればわかりますが、`val += 1`は

```Python
val = 0


def f():
    val = val + 1
    print(f"f scope: val = {val}")


f()
```

のようになります。

`val = val + 1`で`val`へ代入しているためローカル変数として扱われます。
そしてローカル変数である`val`が関数内で宣言されていないために`UnboundLocalError`が発生するのです。

# グローバル変数として明示的に扱う

解決策は簡単で`global`を変数の前につけます。

```Python

val = 0


def f():
    global val
    val += 1
    print(f"f scope: val = {val}")


f()
```

このようにすると`val`をグローバル変数として扱うため`val += 1`が通ります。

# 参考

[なぜ変数に値があるのに UnboundLocalError が出るのですか？](https://docs.python.org/ja/3.10/faq/programming.html#id10)
サイトを要約して保存するショートカットを作成しました。

# 要約
ショートカットでサイトを要約し、あとから検索できるchrome拡張機能を作成しました。
# 経緯
一年前にGo言語でサーバーを作る練習をしており、ちょうど、Chromeのブックマーク機能の、タイトルだけ表示されてなんのサイトかわからなくなる点などに不満があったことから、自作することにしました。当時はガチガチに完成度を上げることにこだわっていたのと、ChatGPTの文字数(トークン)制限が厳しかったのもありやめてしまったのですが、思い立ってローカルで動く形に仕上げました。
# 構成
drawioでササッと作っただけですが、構成は以下の図のようにシンプルな形です。Goサーバーを中心として、拡張機能から保存したいウェブサイトを送信すると、サーバーにサイトと要約が保存されます。検索用ウェブサイトを利用してウェブサイトを検索できます。
![スクリーンショット 2024-10-22 18.54.30（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1829579/9bfd7969-30e3-a486-b58e-d21c76b45772.png)
# 使用方法
使用方法はGithubにあります。

https://github.com/tamakoshi2001/sitedb_local

一部だけ抜粋しておくと、``Cmd+Shift+A``でウェブサイトをサーバーに保存でき、保存できると通知が飛びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1829579/5b503928-f30d-1213-4ff1-36bc0e975c21.png)
検索用ウェブサイトはシンプルで、検索を行うと関連度順に表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1829579/5180b744-3b76-ac02-3d42-f340187adf64.png)
# 補足
構成の細かいところに対して、疑問が生じそうなところだけ補足します。
・ウェブサイトの保存方法について
そもそも(何万件もの)大量のウェブサイトが保存されるとは想定しづらかったので、サーバーにjsonファイルでウェブサイトの情報を保存しています。こちらのほうが持ち出しなども簡単なので、ローカルで動かす程度なら便利かなと思っています。
・ウェブサイトの検索について
検索はウェブサイトのEmbeddingをChatGPT APIであらかじめ取得し、GoサーバーでCos類似度を計算してスコア順に表示しています。理由は上と同様、大量にWebサイトをさばく想定をしていないためです。
# 今後について
・検索サイトに削除機能がほしい気がしています。追加したいです。
・上で完成度を上げたかったと触れたと思うのですが、本当はTerraformを使ってEC2に構築できるようにするつもりだったのでした。Terraform自体は問題なかったのですが、立ち上げるたびに保存したウェブサイトをリセットするように組んだせいでデバッグが面倒になりすぎてしまい、止まっています。こちらもできたらなと思っています。
Bashの事を色々

## はじめに
ネットで調べればわかる事も多いですが、自分の知識の整理も込めて、bashに関する事を書いていこうと考えています。
（意外と少ないかな。思い出したら随時変更しようと思います。）
この記事としては書きたい事の目次的な位置付けとなります。
個々の記事が出来たらここ記事からリンクを貼っていきます。
### この記事の対象者
初心者向けに簡単な事、よく使う事を書いていこうと思っています。
### 動作環境
執筆時点での情報ですが、以下の環境で動作確認を行なったものを記事としていきます。
Ubuntu 24.04.1 LTS
bash 5.2.21
## 1.シェル（bash）の事
### プロンプトでの操作
[CTRL＋？で出来る事](https://qiita.com/nyanbu/items/140eb04dcd0dd0c18724)
[バックグラウンド実行（fg、bg）の事](https://qiita.com/nyanbu/items/5afefdd654b0f32f896a)
リダイレクト、パイプ
などなど
### シェルプログラミング
if文、case文
ループ（カウンタ、ファイル取込み、コマンド実行結果など）
プロセス管理（バックグラウンド実行、終了待合せなど）
などなど
## 2.コマンドの事
### よく使うコマンドの使い方
history、ls、find、rm、rmdir、chmod、chown、cat、viなど
### コマンドの組み合わせ
パイプを使った事例など
## 最後に
尚、この内容は予告無く変更する場合がありますのでご了承下さい。