OmniAICreator/Qiita-1.07M huggingface dataset:
TeachableMachineを使ってノーコードで音声認識を実装する

## はじめに
TeachableMachineを使ってノーコードで音声認識を実装する方法を紹介します。
## 1. TeachableMachineを始める
[TeachableMachine](https://teachablemachine.withgoogle.com/)を開いてください。
以下のような画面に飛ぶと思うので、`使ってみる`を押して始めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/9f76d12d-edc3-999c-106c-91d9b11ce697.png)

## 2. 音声プロジェクトを選ぶ
TeachableMachineでは音声以外にも画像認識やポーズ認識も実装できます。
今回は音声認識をしたいので`音声プロジェクト`を選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/eebbc536-db3a-b176-d285-8b38acbee5f1.png)

## 3. バックグラウンドノイズの抽出
何も音を鳴らしていない時の部屋の音を以下の手順で抽出してください。（本記事ではマイクを使用することを想定しています）

① `マイク`を押す
② `20秒録音する`を押す
③ `サンプルを抽出`を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/7656d1ab-ad1f-7e97-45db-09cacf3198b5.png)

## 4. 判別したい音をそれぞれ抽出する
① `マイク`を押す
② `2秒録音する`を押す
③ `サンプルを抽出`を押す
④ サンプルが8つ揃うまで`②`, `③`を繰り返す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/122a61fc-f22b-c1f7-48c7-4152d3f19eed.png)


⑤ クラスを追加して他の音も同様の操作を行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/03e729e7-6ff7-dc2f-ee46-b23d21e1f6fa.png)

## 5. モデルをトレーニングする
① `モデルをトレーニングする`を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/760ccf64-f90e-ee1c-d313-2dc3110a69b3.png)

## 6. 音声認識できているか確かめる
実際に音を鳴らしてみて音声認識が思ったように行われているかをプレビュー画面で確認する。
思ったようにいかない場合はモデルの抽出を調整しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/d17e6341-2b61-b461-2720-f9f5eb929890.png)

これで完成です🎉

## 最後に
TeachableMachineを使えばAI初学者でも簡単に音声認識を実装できます。エクスポートすればアプリに応用することもできるので、今後活用したいと思います。
サブドメインのサブドメインを登録したら疎通できない

## 概要

メインドメイン`hoge.com`にサブドメイン`test.hoge.com`を登録し、更にサブサブドメイン`www.test.hoge.com`を登録したらなぜか疎通できず困ったので自分の場合の解消方法をまとめる。

## 原因

メインドメインのRoute53のNSレコードにサブサブドメインのNSレコード情報を登録していた。
本来サブサブドメインのNSレコード情報はサブドメインのRoute53のNSレコードに登録する必要がある。

## 問題発生時の状況（問題あり）

メインドメイン、サブドメイン、サブサブドメインがそれぞれどのように登録されているのかをまずはまとめる。

![work__Visual_Workspace_for_Innovation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/20cadee6-d06f-6d0a-bd35-50f22bb07ca1.png)

サブドメインのNSレコード情報も、サブサブドメインのNSレコード情報もすべてメインドメインのRoute53に設定されている。
この状態だとサブサブドメインは使えない（疎通できない）状態となっている。
下記のコマンドを実行してNSレコードの情報を取得しようとしても、疎通できていないので取得できない。

```
dig www.test.hoge.com ns
```

## 問題解消時の状況

正しい構造は下記のような状態である。

![work__Visual_Workspace_for_Innovation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d2132f4e-db36-1e2a-bacd-8192ba12f6c9.png)

確かに言われてみればサブサブドメイン`www.test.hoge.com`の元になっているサブドメイン`test.hoge.com`はY環境のAWSのRoute53で管理されている。そのためサブサブドメインのNSレコード情報はサブドメインのRoute53に登録する。

## あとがき

考えてみれば当たり前かもしれないが、半日詰まった。。悔しい。
でも下記の記事の内容を元に一人で解決する事ができた。。嬉しい。

https://qiita.com/miriwo/items/01d8b0d5627f8fccd38b
django; OSError: No translation files found for default language 

タイトルの通り。

```
OSError: No translation files found for default language
```

これは`Django`で言語設定が間違っているときのエラー

この公式ドキュメントから飛べる
https://docs.djangoproject.com/en/5.0/ref/settings/

このページにリストが書いてある
http://www.i18nguy.com/unicode/language-identifiers.html

例えば、`settings.py`の言語設定で

```python
LANGUAGE_CODE = 'jp' # NG
```

とするとエラーになる。正しくは次の通り。

```python
LANGUAGE_CODE = 'ja' # OK => 日本語
```
toLocaleString()の罠

> javascript 数値 カンマ区切り

上記でGoogle検索すると、一番上にヒットするのが以下のサイト。

[JavaScript で数値を3桁のカンマ区切りにする簡単な方法](https://gizanbeak.com/post/js-tolocalestring)

```js
var num = 10000;
num.toLocaleString();
// "10,000"
```

とても簡単にできた。
ただ、注意しなければいけない点があって、
引用元のページにも記載がある通り、
小数点や桁区切りに使用される記号がlocaleによって異なること。

ブラウザの言語設定がドイツ語のユーザーの環境では、以下のようになる。

```js
var num = 10000;
num.toLocaleString();
// "10.000"
```

そのままデータベースに登録したら、本来Ten thousandだったはずのデータがTenになってしまい、千分の一になってしまう……

ユーザーの環境によってTen thousandだったりTenになってしまうのは不具合なので、もし値をどこかに保存するような場合は別の方法を使うこと。

[Number.prototype.toLocaleString() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#locales_%E3%81%AE%E4%BD%BF%E7%94%A8)

ドイツ人エンジニアの間ではあるあるだったりするのだろうか……？
【Linux】ディレクトリとパスについて

# ディレクトリ

### ルートディレクトリ

Linuxの全てのファイルやディレクトリが入っている最上位のディレクトリのことをルートディレクトリという。「 / 」はルートディレクトリを意味している。

### カレントディレクトリ

現在作業中のディレクトリをカレントディレクトリという。

### ホームディレクトリ

ユーザーごとに用意されている、ユーザーが自由に変更を加えることのできるディレクトリをホームディレクトリという。

## ディレクトリを巡回するコマンド

| コマンド | 説明 | 由来 |
|:-:|:-:|:-:|
| pwd  | カレントディレクトリを表示する  |　print working directory |
| ls  | ディレクトリの中身を表示する  |　list |
| cd  | カレントディレクトリを変更する  |　change directory |

### pwd

```bash
sampleuser@sampleuser-VirtualBox:~$ pwd
/home/sampleuser
```

### ls
```bash
sampleuser@sampleuser-VirtualBox:~$ ls
ダウンロード  デスクトップ  ビデオ    ミュージック
snap      テンプレート  ドキュメント  ピクチャ  公開
```

### cd
```bash
sampleuser@sampleuser-VirtualBox:~$ cd ダウンロード
sampleuser@sampleuser-VirtualBox:~/ダウンロード$ cd ~
sampleuser@sampleuser-VirtualBox:~$ 
```

# パス

あるファイルやディレクトリに辿り着くまでの経路を表した文字列のことをパスという。パスには、絶対パスと相対パスがある。

### 絶対パス
ルートディレクトリ（ / ）を起点としたパス

### 相対パス
カレントディレクトリ( . )を起点としたパス
一つ上のディレクトリを「 .. 」で表現する

### 例
<img width="450" height="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585818/ea1c9ad6-fd58-8bb0-566d-aa8a0a64e564.png">

図のfile.txtを絶対パスで表現すると、
ルートディレクトリ( / )→ディレクトリB( B/ )→file.txtなので「　/B/file.txt　」となる。

相対パスで表現すると、
カレントディレクトリ（ ./ ）→一つ上のルートディレクトリ（ ../ ）→ディレクトリB(B/)→file.txtなので「 ./../B/file.txt 」となる。相対パスでは、最初の「 ./ 」を省略可能なので、「　../B/file.txt 」とすることもできる。
CHF-GM12-N20モータのエンコーダについての備忘録


# 目次
CHF-GM12-N20モータのエンコーダの動作について、
こういうことなのかと腹落ちしたことを記録しておく。
CHF-GM12-N20モータについての日本語の説明なんかも少ないので、
日本語で調べる人の一助になれば幸甚。

[1. はじめに](#1-はじめに)
[2. 課題](#2-課題)
[3. 考えたこと](#3-考えたこと)
[4. おわりに](#4-おわりに)

# 1. はじめに
エンコーダ付きCHF-GM12-N20モータを買いました。

https://ja.aliexpress.com/item/32824126014.html

エンコーダの使い方として下記を参考にさせて頂きました。

https://electricdiylab.com/controlling-n20-encoder-micro-gear-motor-with-arduino/


# 2. 課題
コードを眺めてなんとなく動くのはわかりますが、
void updateEncoder()
関数内でなんやかんやビットシフトしているのが何なのかよくわからないので、
モータ動作とビットの動きを考えた。

# 3. 考えたこと
エンコーダはHallセンサを2つ持っている。
センサの位置は回転軸に対して正対はしておらず、
下記の左図のような配置になっている。
AとBと置いておく。
AとBの間は若干近いので、右図のように回転中にAとBが両方ONする場所が存在する。
ここがミソ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1112433/83c2ac3e-c6c3-aa0f-6d74-4d250ae0524a.png)

参考URLのコードでは、PinA, BはattachInterruptをMode "change"で割り込むように
定義されているので、0→1 or 1→0と遷移したときに割り込みが発生する。
また、encodedでAとBの状態を2進数表記している。
さらに、sumで前回のencode値と今回のencode値を同時に表記するようにしている。

踏まえて右回り時と左周り時でA,Bの割り込みが発生する際のencodeとsum値をシミュレーションする。
面白いもんで、回転の方向によってsumの値が見事に異なっている。
これによって、sumの値を見ればどっちに回転しているのかを判別することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1112433/bbe1bf56-e995-0224-b2af-f9806f214f10.png)


# 4. おわりに
各状態の遷移がユニークだからこうなるのはわかるんですが、
こうシンプルな実装でそれを表記できるのがとっても美しい。
なので忘れないように書いておくようにしたのでした。
VSCodeでPythonインテリセンス（入力補助）を無理やり使う話【備忘録】

# はじめに
この手法はそもそも非推奨かもしれないし、もっといい方法があるかもしれないが"なんか知らんけどとりあえずやりたいことはできた"のでまとめておく。
推奨される方法等があれば教えてくださると助かります。

# 経緯（文句）
個人的にぺちぺちコーディングをしているときに、クラスオブジェクトを引数に渡したりしてこねくり回すことがある。
クラスオブジェクトを引数に渡したりしたときに、デフォだと型がanyになって、インテリセンス（入力補助とかF12で宣言元に飛ぶとか）が効かなくなる。
入力補助はともかく、F12で宣言元に飛べなくなるのはつらいって言うのは共感していただけると思う。
ここでインテリセンスを有効にするためには型ヒントをつけてあげる必要がある。
自分が作った別ファイルに定義しているクラスだと、型ヒントをつけるためだけに行うインポートで、やれ上位のパッケージだ、やれ循環参照だと実行時に余計なおせっかいを焼いて来ることがある。
あくまでインテリセンスを使うためだけにインポートするのであって、実行時にはインポートしなくていいのに、実行エラー出されてもなぁと言うことで、それを回避する方法を見つけた。

# やり方
`TYPE_CHECKING`をインポートして、`TYPE_CHECKING == True`のときだけインポートさせる。
```python
from __future__ import annotations
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from ..my_class_a import MyClassA

class MyClassB:
    def __init__(self, class_a: MyClassA):
        self.class_a = class_a

    def func_b(self):
        return self.class_a.func_a()

```

TYPE_CHECKING は、型チェッカーがコードを分析するときにのみ True になるみたい。
これにより、実行時にはインポートが行われず、型チェック時にのみインポートしているように見せることができるようだ。
これでVSCodeのインテリセンスを活用しつつ、実動作時にはインポートさせないことで循環インポートとか本来考えなくていい問題を避けることできる、と。

# おまけ
ちなみにannotationsをインポートしない場合、TYPE_CHECKINGでインポートしたクラスはクウォートで囲う必要があるみたい。
```python
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from ..my_class_a import MyClassA

class MyClassB:
    def __init__(self, class_a: "MyClassA"):
        self.class_a = class_a

    def func_b(self):
        return self.class_a.func_a()

```
PostgreDBでSQLの実行時間を測る:SQLチューニング#2

### はじめに

PostgreDBでSQLの実行時間を測るにはtimingコマンドを使います。

### timingコマンドの使い方

①pgAdmin4でtimingコマンドを使用したいDBを右クリック。「PSQL Tool」を選択する。
②①を選択すると開くウィンドウに「\timing」と入力。
③実行したいSQLを入力し、実行。
④表示された実行時間を確認。

### 実行結果

![コマンドで実行時間測定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/dd3844df-eff4-df40-d9aa-cc36ad7c31fc.png)

「133.885」という実行時間が表示されています。単位はミリ秒です。

ここまで読んで頂きありがとうございました。
Google の Magika を Python から C#に移植するまでの過程 (Day 4 / 7)

Google のファイル判定プログラム Magika を Python から C# に移植する過程を共有する記事の第4回目です。

前回から本格的に C# で Magika のコードをクラスライブラリとして移植する作業を始めました。しかしひとつひとつのコードを調べながら移植していく作業はどうしても時間がかかり、少しばかりうんざりしてきてしまいました。

今回はもっと効率的に移植作業を進めるべく、**GitHub Copilot** を使った AI によるコード生成を試してみることにしました。

## 目次
- [Day 1 : まずは Magika の中身を見てみよう](https://qiita.com/mkht/items/64b02b8648266d40380a)
- [Day 2 : C# で 概念実証コードを書いてみる](https://qiita.com/mkht/items/fa76b0238ed976d20ca9)
- [Day 3 : C# クラスライブラリとして Magika を移植していく](https://qiita.com/mkht/items/a7fa36c5446b5fad5092)
- [Day 4 : GitHub Copilot を使って作業効率アップ](https://qiita.com/mkht/items/2c2b23ceb0bc1df66599)
- [Day 5 : クラスライブラリとしての Magika を完成させる](https://qiita.com/mkht/items/9d7a8a16ed1d60e353fa)
- [Day 6 : コンソールアプリを作成する](https://qiita.com/mkht/items/0b2d1546cf8a25ab4cce)
- [Day 7 : 移植したMagikaをビルドし、動作確認する](https://qiita.com/mkht/items/f36d87afe50eae2be5f1)

## GitHub Copilot を使って作業効率アップ

GitHub Copilot は GitHub が提供しているサブスクリプションサービスで、AI がコーディング作業の補助をしてくれるサービスです。

https://docs.github.com/ja/copilot/using-github-copilot/getting-started-with-github-copilot

月額 10 ドル（約 1500 円）と決して安くはありませんが、30 日間は無料でトライアルできますので、一か月以内に移植作業を終えて解約すればそれきりで済みますし、それで作業効率が大きく上がるのであれば支払う価値があるのではないかと思いました。

> GitHub Copilot は 30 日間は無料でトライアルできますが、私は以前にトライアルを使って解約したことがあるため、今回は 10 ドル支払って使っています。

### GitHub Copilot の使い方

GitHub にサインインして https://github.com/github-copilot/signup からサービスに申し込みます。

続いて Visual Studio Code に GitHub Copilot 拡張機能をインストールします。インストール後、GitHub にサインインするよう要求されるのでサインインします。これで準備は完了です。

![github-copilot-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177762/4d49f34f-04be-68fe-2c05-5816c6d1041a.png)

GitHub Copilot には大きく分けて2つの機能があり、ひとつはインラインでのコード補完、もうひとつはチャット形式でコードの説明をしたり、コードを生成してもらうCopilot Chatです。

#### インラインでのコード補完
コード補完については、普通にソースコードを書いていると薄いグレーでAIが続きのコードを提案してきてくれます。その提案内容が気に入ればTabキーを押すとそのままコードが挿入されますし、気に入らなければ無視してそのまま自分でコードを書き続けることもできます。

![github-copilot-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177762/c17225d2-e5bd-0f1f-5976-ac8d5b14fb14.gif)

特に同じようなコードを、変数名などを少しずつ変えながら繰り返し書かないといけないような場合に、そのパターンを学習してそれっぽいコードを提案してきてくれるので便利だと感じました。

ただ、提案されたコードをそのまま使うというよりは、参考にしつつ自分で手直ししていく必要がある感触でした。

#### Copilot Chat
今回のような Python のコードを C# に移植させるような作業にはこちらの Copilot Chat の機能が特に役に立ちました。

Python から C# に移植したいコードを選択した状態で、Copilot Chat の入力ボックスに「**C#のコードに書き換えたい**」と入力すると、AIが書き換えたコードを提案してくれます。

うまくハマると、ほぼそのままコピペで使えるようなコードを提案してくれます。100 行くらいあるメソッドを十数秒の待ち時間でまるごと完璧に変換してくれたときには、「俺がこれまで苦労して移植してた作業はなんだったんだ」と思わざるをえませんでした。

ただ、実際のところは当たり外れが大きく、うまく変換してくれない場合も多々ありました。入力できるコードの量にも制限があるようで、全コードをまるごと選択して移植させようとすると「コードを指定してください」などと言われてしまうため、少しずつ区切って変換させるなどの工夫も必要なようです。

![github-copilot-03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177762/cbc550de-10ff-ab1f-c79a-c4bed60320ee.gif)


## 続く
GitHub Copilot の導入で作業効率は確かに上がりましたが、時間的には10%～20%の短縮といったところでしょうか。月額10ドルに見合うかどうかは状況次第かなぁという印象です。

GitHub Copilot の助けも借りつつ、引き続き Magika の C# 移植作業を進めていきます。[次回](https://qiita.com/mkht/items/9d7a8a16ed1d60e353fa)はクラスライブラリとしての Magika をひとまず完成させるところまでを目指していきます。
LaravelのResourceControllerについて

## 問題　
ResourceControllerを使いたい

## 手順解説
https://nebikatsu.com/8570.html/

### routeでnameを使いたい場合
```
ターミナル
php artisan route:list
```
コマンドを打って、表示される表の中の「 Name 」の箇所を使用すればOK
![スクリーンショット 2024-04-19 22.15.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/8e83ec3e-78df-7725-8d4e-3271dadd699a.png)

これもここで解説あり↓

https://nebikatsu.com/8570.html/
新卒がLLMハッカソンに参加してみた！

# はじめに
突然ですがハッカソンに参加してきました。
「LLM(大規模言語モデル)を用いて現実にある問題を解決しよう」をテーマに開催されたグループ会社横断ハッカソンです。
今回がはじめましてのメンバーで4日間をフルに使ってプロダクトを作り、そして最後にプレゼン発表するというとても刺激的なイベントに縁あって参加がすることができ、個人的に興味深い気づきや今後やっていきたいな〜と思うことがあったのでここに書き留めておこうと思います。
※この記事では技術系の話は出てこないです


# ハッカソンの準備
ハッカソンのキックオフから当日まで3週間ほど期間がありました。
その間メンバー同士で議論を重ね、プロダクトのアーキテクチャをざっくり決めるところまで行い当日を迎えました。
この期間を振り返っての反省にはなりますが、特に大切だなと感じたことが2点あったので紹介します。

#### ①一次情報のインプットをたくさんする
良い仮説を得るためにはまず生のデータをみて、イメージを膨らませ、メンバーとフリーで議論することが大切です。そうすることでテーマの本質的な課題とその解決に役立ちそうな情報が見えやすくなります。そしてその中から自ずと独創性のあるアイデアが生まれてくるのだなと思いました。闇雲に「〜だろう」といった思いこみのまま話を進めてしまうとやることが迷走しがちになるので、ここのインプットは特に入念に行うことをおすすめします。

#### ②当日までにできることはあらかじめやっておく
察していただけるかも分かりませんが、ハッカソンはとにかく時間がないです。
開発で使用するgithub、APIキー、一元管理できるメモ置き場の用意など、事前にできることは何でもやってしまいましょう。
また、アーキテクチャの全体像の共有およびメンバー間での合意はなるべく詳細にやっておくといいです。ここをきちんとできているチームほど、最終的な評価が高かった印象でした。（今回のハッカソンの準備は通常業務と並行して行わないといけなかったので色々と難しい面はありましたが）

# ハッカソンで作ったプロダクト
データ処理、および今回のハッカソンでテーマとなった問題に対する出力をLLMを用いて実装しました。プロダクトの詳細については申し訳ないのですがここでは割愛させていただきます！
いい感じのものを作ってしまったがゆえに社外公開不可...orz

超ざっくりと本プロダクトの概要を説明すると、人間の能力(情報処理能力、認知能力、思考力、etc...)にはさまざまな限界があるため従来の手法ではアプローチ可能な領域に限界がありました。その限界をLLMを使って乗り越えてしまおうというものです。テーマについてのヒアリングを重ねる中でいくつか見えてきたペインポイントに対してLLMを使用した本プロダクトを適用することで、人間ならではの限界に縛られない網羅的なアプローチを可能とし、かつその先のアクションについての提案を行うところまで実現しました。



# ハッカソンをふりかえって
私自身経験が浅く、どのように進めればうまくいくかのイメージが持てなかったため、自分主体で動くのが難しい場面が多々ありました。期間中にたびたびフォローして頂いたり、修行を兼ねてやれること何でもやってみたり、またまたLLMを使い倒すという開発経験を積む中で学ばせていただくことは本当に多かったです。そのうえで、特に大きな気づきになったなと思うのが以下の2点です。

#### ①アウトプットにとことんこだわる
ハッカソンは技術と時間の勝負です。何もできずに時間を浪費してしまうのだけは絶対に避けたい。しかし振り返ってみると、今回のハッカソンで無駄にしてしまった時間が多々あったと思います。
その反省から、大事だなと思ったスキルは言語化能力です。
どんなに面白い考え・発想が頭の中に浮かんだとしてもそれを言語化してチーム全体で共有することができなければもはや何の役にも立たないんですよね。今回のようにスピード感が求められる状況では、自分自身で確証がなかったとしてもどんどん案出しをし、議論の中でアイデアを磨いていくことが必要になります。そして話す側はもちろん、聞く側もこの能力は持つべきだと思います。なぜならば話す側からのインプットを得てどんどん不明点や指摘事項を返していかないとアイデアを磨くということが実現しえないし、何より構造化したイメージをチームメンバーで共有することが難しくなるからです。そのため各メンバーが主体性をもち、どんどん言語化してブラッシュアップしていくことでプロジェクトを前へ前へ進めて行こうとする意識は絶対になくてはならないと感じました。
私自身、ハッカソン期間中に実践を重ねる中で言語化できることが増えてきた感覚があったのでこれは本当に実践あるのみだと思っています。できるだけ緊張感をもってこういった経験が出来る環境になるべく身を置いていきたいですね。


#### ②LLMは万能ではない
どれだけ凄くても、やっぱりLLMに出来ることは人間が普段行っていることの「置き換え」でしかないんだと思います。当たり前ですが最初からLLMに丸投げしたところで、求めている出力はなかなか出してくれません。よく分からないけど良い感じに出力してくれたからと、無闇に信用してしまうとあとで痛い目を見ることもあります。
事前に調査を重ねた上で、
・今回取り組む課題にはどこに問題があるのか
・何が解決できればありがたいのか
などの課題分析を人間側で事細かに行い、その上で仮説立てをして使うことが必要なんだと思います。
例えば今回のプロダクトの中で人間個人の発想の限界を超えるような、独創的な要素をLLMに出力させることを試みたのですが、ここはかなり苦戦しました。なぜならば独創的とは何かを定義してその情報をLLMに与えるのが困難だからです。われわれ人間が独創性、言い換えれば「今までにないような斬新な要素とは何なのか」を理解していないのに、LLMがそれを理解してよしなに出力してくれるはずがありません。課題解決のためにほしいアウトプットはどんなものか自分自身で明確にイメージし、例えば思考回路が自分と異なり、非常にユニークな思考をする人格設定をLLMに盛り込めばうまくいくのでは？と仮説を立てた上ではじめてLLMに頼ることで、ほしいアウトプットに近い情報が得られるのだと思います。


# さいごに
自分自身技術力がなくて不安...という気持ちで参加しましたが、終わってみると収穫が多くとても楽しいイベントでした。ハッカソンに参加して別に何かを失う訳ではないので、よほどの理由がなければ興味本位で参加しちゃっていいと思います。そして困ったときは(困ってないときでも)パッションがあればだいたいどうにかなります笑　
軽い感じで書いていますがこれは意外と侮れないことだと思っていて、やっぱり人の強い気持ちは関わる人やプロジェクトを大きく動かすことができるんですよね。実際にハッカソンに参加してそう感じずにはいられなかったですし、その実感を得たいならハッカソンは本当におすすめです！
あとはハッカソンを通して仲間が出来るというのが本当に良いことだと思います。ワクトのみんながグループ会社のメンバーとも今後もっともっと繋がって行ければ理想的だなと感じますし、自分自身としては機械学習や分析などの分野に挑戦したいので出来るだけ...と言わずどうにかしてより強い関わり方をしていきたいですね！
Mac – CleanShot X のおすすめ設定 (スクリーンショット撮影のおすすめアプリ)

# 基本 – Macへのログイン時に自動で起動する

![CleanShot 2024-03-04 at 19 38 33@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/b4750ff7-7e0d-4a0b-aa5d-a4e04e1d9f1f)

# 基本 – スクリーンショットの保存先ディレクトリを変える

![CleanShot 2024-03-04 at 19 38 38@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/2c87e97e-ea2a-47de-855d-a0bfc9e00e9a)

# おすすめ – キャプチャ撮影後の自動アクション

**General > After Capture**

キャプチャ撮影した時のアクションを細かく決められる

たとえば

- クイックアクセスを表示する
- 自動でファイル保存もする
- 自動でクリップボードにコピーする

という全てを同時にさせることができる

CleanShotXの欠点として、クイックアクセスが表示された後のファイル保存・クリップボードへのコピーがひと手間だったが、これは良さそうだ

しかもお絵描き(Annotationの編集)を確定させた時にもちゃんと働いてくれる


![CleanShot 2024-03-04 at 19 36 46@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/ef14d7af-969e-4e7d-b86b-0dfb28c2e4ab)


# クイックアクセスを自動で閉じる

自分のニーズによっては使えるかも

![CleanShot 2024-03-04 at 19 40 45@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/622d37ba-76cf-4143-a2dd-c740bf5055b5)

# ドラッグした時に閉じない

自分のニーズによっては使えるかも

![CleanShot 2024-03-04 at 19 42 27@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/ae868fc8-4e5f-453e-9e8b-e48e7feb7f5d)



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
フェランチ効果の数値解析

# はじめに
交流回路では、電源側の電圧の大きさよりも負荷側の電圧の大きさの方が大きくなるという不思議な現象であるフェランチ効果なる現象がある。これによって、負荷側の電圧が異常に高くなってしまうため装置の絶縁破壊が問題となる。一般に送電モデルにおいて、軽負荷の場合にこの現象が発生しやすくなる。今回は、どうして軽負荷のとき、この現象が発生するのかをPythonの複素数計算機能とベクトル描写機能を用いて説明する。

# 無負荷運転時
負荷側に、機器が接続されていない場合を考えて欲しい。送電線と地面は巨大なコンデンサとみなすことができる。また、3相での送電の場合、近くにも送電線が存在している。ゆえに、無負荷での運転時において常にコンデンサのようなものが接続されているのである。

まとめると、無負荷運転時の力率は”進み”になる。なので、軽負荷時も場合によっては進みの力率になる場合が多いと言える。特に長距離送電の場合、長くなるに従い静電容量は比例的に増えることから例え負荷が接続されていたとしても、結果的に進み力率になってしまう可能性が高くなる。

# 進み力率の弊害

以下の送電モデルで考える。ただし、電圧、電流は単位法として単純化する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/c13c5de6-23d6-41ae-3248-fdf1640aeb8d.png)

```math
\dot{V_s}=V_r+(r+jx)\dot{I}
```


受電電圧と送電電圧のベクトル図は以下のように描くことができる。


ただし、受電端基準電圧を黒、送電端電圧をピンクとして、赤を電流とした。


![anime.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/e8c90eb7-fe3c-4129-125f-2a558bf3cb76.gif)

これは、　力率角を遅れから進みに徐々に変化させていったときの送電端電圧の変化の様子を示してある。

プログラムはPythonを用いて行い、まず静止画を複数作成してそれをgif化した。

図を見て分かる通り、力率を進みにするに従って、送電端電圧の大きさが受電端電圧と比較して徐々に小さくなってしまうことが分かる。これがフェランチ効果と呼ばれていて軽負荷時の異常電圧原因の一因となる。

# プログラム
最後に、このベクトル図の静止画を描写するプログラムを示す。
ただし、送電電流を力率$\theta$を用いて以下のように表す。
```math
\dot{I}=I(cos \theta - j sin \theta)
```
このように、虚部側の符号が負となるところに注意したい。




```　python feranti_effect.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math
# 5×5サイズのFigureを作成してAxesを追加
fig = plt.figure(figsize = (5, 5))
ax = fig.add_subplot(111)

# 格子点を表示
ax.grid()

# 軸ラベルの設定
ax.set_xlabel("実軸", fontsize = 16)
ax.set_ylabel("虚軸", fontsize = 16)

# 軸範囲の設定
ax.set_xlim(0,3)
ax.set_ylim(-3,3)

# x軸とy軸
ax.axhline(0, color = "gray")
ax.axvline(0, color = "gray")

# ベクトルを表示
# quiver(始点x,始点y,成分x,成分y)
I=1.0
#力率角
theta = math.radians(-60)
#複素電流
I_bar=I*(np.cos(theta)-1j*np.sin(theta))
#受電端電圧
V_r=1.0
#送電線の抵抗値
r=1
#送電線のインダクタンス
x=1

#送電端電圧
V_s=V_r+ (r+1j*x)*I_bar


#電流ベクトル
ax.quiver(0, 0, I_bar.real, I_bar.imag, color = "red",
          angles = 'xy', scale_units = 'xy', scale = 1)

#受電電圧（位相の基準）
ax.quiver(0, 0, V_r.real, V_r.imag, color = "black",
          angles = 'xy', scale_units = 'xy', scale = 1)

#抵抗にかかる電圧
ax.quiver(V_r, 0, (r*I_bar).real, (r*I_bar).imag, color = "blue",
          angles = 'xy', scale_units = 'xy', scale = 1)
          
#インダクタンスにかかる電圧
ax.quiver((V_r+r*I_bar).real, (V_r+r*I_bar).imag, (1j*x*I_bar).real, (1j*x*I_bar).imag, color = "yellow",
          angles = 'xy', scale_units = 'xy', scale = 1)
          
#送電端電圧ベクトル
ax.quiver(0,0, V_s.real, V_s.imag, color = "pink",
          angles = 'xy', scale_units = 'xy', scale = 1)
plt.show()
```
これを実行すると以下のような画像が出力されるはずである。


![vector_souden.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/617f64fd-e39e-668f-9916-80decda9c49c.png)

# まとめ
今回は、フェランチ効果の原因が進み力率であることについてPythonを用いたベクトル図を描写することで考察してみた。結果、確かに力率が進みになるにつれて、受電端電圧の方が送電端電圧よりも高くなる傾向があるということが分かった。これは、交流には大きさだけでなく、位相も重要になってくるからである。Pythonはこのような数式や複素数を上手く扱うことができるため、データサイエンスや統計学だけでなく、電気工学や電力工学にも適用が可能であると考えられる。
【初心者】「:before」というCSSの擬似要素について

## :before　とは
擬似要素。

### そもそも要素とは
要素はタグと比較して説明されることが多い。以下の写真を参照。
![スクリーンショット 2024-03-04 19.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3692854/88bc2991-9f69-3402-1c86-e59b3347a787.png)
参考
https://allabout.co.jp/gm/gc/23843/#google_vignette

### :before　の使用例
実際の機能は以下のサイトが参考になった。
参考
https://proengineer.internous.co.jp/content/columnfeature/5950
Pythonで「str関数の使い方(文字列に変換する)」の動作を確認してみた

# 概要

Pythonで「str関数の使い方(文字列に変換する)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/function/index2.html

# 実装

以下のファイルを作成しました。
```sample.py
print("My age is " + str(100))
print("Value = " + str([10, 20, 30]))
print("Result is " + str(True))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
My age is 100
Value = [10, 20, 30]
Result is True
```

# まとめ

何かの役に立てばと。
[Rails]ppでActiveRecordオブジェクトをログ出力すると一部消える！？


# 記事執筆に至る経緯
以下のように複数のテーブルをjoinし、特定のカラムを選択したActiveRecord::Relationオブジェクトの内容を確認しようとppを使ってログ出力してみました。

```ruby
relation = Staff.joins(:division).merge(Division.where(division_id: 1)).select(:staff_name, :division_name)
pp relation
```

すると以下のような結果に。

```ruby
 # [#<Staff:0x00003b9efdp771d8 staff_name: 'スタッフ太郎'>]
```

あれ、staff_nameしか出てきてない。取得できていないのか。。
いやでもデータは取得できてそう。。なんでや？？
この状況で先輩に質問した時に教えてもらったのが.as_jsonでした。

```ruby
pp relation.as_json
```

このように書くと、以下のようにJSON形式できちんとselectした値が確認できる。

```ruby
# [{"staff_name"=>"スタッフ太郎","division_name" => "テスト部署"}]
```

なぜppでは出てこないんだ。。あ、調べて記事にするかーーー。という経緯でこの記事を執筆しています。
# 調査開始
### 仮説1: ActiveRecord::Relationオブジェクトの特性かも？
ActiveRecord::Relationオブジェクトから個別のレコード（ActiveRecordモデルのインスタンス）を取得し、このオブジェクトをppでログ出力してみました。しかし、期待した追加のカラム（この例ではdivision_name）が表示されませんでした。
どうやらActiveRecord::Relationに限った話ではなさそうなので、この仮説は間違いです。
```ruby
pp relation[0]
# 出力結果
#<Staff:0x00003b9efdp771d8 staff_name: 'スタッフ太郎'>
```

### 仮説2：そもそもppでレコードは読み込まれていないから出力されないのでは？
```ruby
relation = Staff.joins(:division).merge(Division.where(division_id: 1)).select(:staff_name, :division_name)
puts relation.loaded? # => false
pp relation
puts relation.loaded? # => true
```
検証してみた結果、ppでオブジェクトをログに出力するとレコードの読み込みが行われています。以下のサイトにも同様の記述があり、この仮説も正しくないことが判明しました。

https://www.docswell.com/s/pink_bangbi/K88ELK-2022-10-22-133810#p70

# 調査結果
以上の結果から、
**ActiveRecordがどのようにデータをオブジェクトとしてマッピングしているか**
が今回の現象に起因しているのではないかと思いました。

調べてみると、ActiveRecordは、デフォルトでクエリの結果をモデルのインスタンスにマッピングする際、**そのモデルのテーブルに定義されているカラムに基づいてマッピングを行う**ようです。

https://api.rubyonrails.org/classes/ActiveRecord/Base.html

今回の例だと、Staffモデルのインスタンスには、Staffテーブルのカラムが属性として自動的にマッピングされますが、Divisionテーブルのdivision_nameなど、関連する他のテーブルから選択したカラムは自動的にはマッピングされません。
ですので、ppでrelationをログ出力した場合、Staffモデルのインスタンスを出力することになるのでstaffテーブルに定義されているカラムの情報のみが出力されていました。

#### ではなぜas_jsonメソッドだと全て出力されるのか
as_jsonメソッドを使用すると、オブジェクトが保持するデータをハッシュマップに変換し、関連するテーブルのデータも含めて現在のオブジェクトが持つ全てのデータをロードしようとします。結果として、StaffとDivisionのデータが含まれたJSONが生成され、ログ出力されます。
# 終わりに
ここまで読んでいただきありがとうございました！
ActiveRecordは何となくで使えてしまうので、その仕組みをしっかり理解した上で使うことが大切だなと改めて痛感しました。
もし間違い等ありましたら、ご指摘くださると幸いです。

# 参考文献

https://www.docswell.com/s/pink_bangbi/K88ELK-2022-10-22-133810#p70

https://api.rubyonrails.org/classes/ActiveRecord/Base.html

https://railsguides.jp/active_record_basics.html

https://ja.stackoverflow.com/questions/86277/rails-console%E3%81%AB%E3%81%A6-%E3%83%A2%E3%83%87%E3%83%AB%E5%90%8D-all%E3%81%AFactiverecord-relation%E3%82%92%E8%BF%94%E3%81%99%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AA%E3%81%AE%E3%81%ABdb%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B-%E3%81%93%E3%82%8C%E3%81%AF%E6%AD%A3%E3%81%97%E3%81%84

https://railsdoc.com/page/as_json
Ubuntu 20.04

受信サーバのファイル編集
vi /etc/rsyslog.conf

#################
#### MODULES ####
#################

    module(load="imuxsock") # provides support for local system logging
    #module(load="immark")  # provides --MARK-- message capability

    # provides UDP syslog reception
    module(load="imudp")
    input(type="imudp" port="514") 
    # provides TCP syslog reception
    module(load="imtcp")
    input(type="imtcp" port="514")

保存フォルダの指定+許可IPの記載とIP振り分けを記載

    $AllowedSender TCP, 127.0.0.1, 192.168.20.0/24

    $template remote-incoming-logs,"/var/log/%FROMHOST-IP%/%$year%/%$month%/%$day%filename.log" 
    *.* ?remote-incoming-logs
    & stop

# provides kernel logging support and enable non-kernel klog messages
module(load="imklog" permitnonkernelfacility="on")

###########################
#### GLOBAL DIRECTIVES ####
###########################

#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# Filter duplicated messages
$RepeatedMsgReduction on

#
# Set the default permissions for all log files.
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog

#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog

#
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf


編集後はチェックして問題なければ再起動とステータスチェック
    rsyslogd -N 1
    systemctl restart rsyslog
    systemctl status rsyslog    


送信(転送側)

ファイル編集

    vi /etc/rsyslog.d/50-default.conf
Ultimate Interview Tips for the Engineering Candidates. Follow These Tips and Crack the Interview Questions Easily

Regardless of your major in engineering, the huge objective of the candidates would be to get the job. Here, Villupuram engineering College gives the expert tips for the engineering students to attend the job interview with ease.

Interviewers will look into the confidence level of the candidates. And the confidence will be high only if you prepare for the interview. Before attending the on-campus or off-campus interviews, you must look into the company's details. The recruiters will like to know whether or not you know about them. It will create an embarrassing situation with the recruiters if you don’t know about their organization, how they work, who is their CEO and other niche details.

There are two types of interview preparation – preparing in advance and before-day preparation. We, engineering College in tamilnadu know the importance of the interview and inform the students in advance. Hence, after knowing the date, start your preparation accordingly. Some companies will conduct analytical test, group discussions, technical interview and finally HR interview. The candidates must clear all these interview rounds to get the job from the company. Some organizations might skip any of these interview rounds. Know about it and start your preparation.

Preparing for the analytical test is surely not the one-day process. The engineering students must start their preparation before a month. In our Villupuram college of engineering, we offer continuous practice for students to clear the analytical interview round. Secondly, for the group discussion, it is good to practice with fellow engineers taking various topics of discussion. Knowing the current news updates is also necessary to speak in group discussion.

For the before-day interview preparation, dress well and be punctual to the interview place. Carry necessary documents along with you. These things will keep you focused to the interview.

As a key-take away, get help from the placement staffs to build a strong resume that portrays your achievements, your strength and other niche stuffs. Be prepared for the basic interview questions that includes – introduce yourself, explain your final term project etc.

Hope these tips will guide the engineering college candidates for placement.
エンジニアでも知っておきたいUIの使い分け〜選択させるUI編〜

## 選択させるUI
ユーザーに「選択させるUI」と聞いて何が思い浮かぶでしょうか？
ラジオボタン、ドロップダウン、チェックボックス...など様々です。
これらはどのように使い分けるのでしょうか？

### ラジオボタンを使う時
![radiobutton.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/46c05169-a954-20ba-7807-15bf3ace4a6e.png)


ラジオボタンは、ユーザーが**複数の選択肢から1つだけを選択する必要がある場合**に適しています。通常は単一の選択肢を選択するために使用されます。

具体的な使用例：

* 性別選択
「男性」「女性」「その他の性別」の中から1つを選択する必要がある場合
* 質問の回答
「はい」「いいえ」の選択肢からどちらかを選択する必要がある場合

ラジオボタンは、ユーザーが選択肢の中から1つを直感的に選択できるため、選択肢が相対的に少ない場合や選択を容易にさせたい場合に最適です。
また、選択肢間で主従関係がなく、関係性としても並列なものが適しています。

ドロップダウンとは違い、全ての選択肢が見えるようになっているので、ユーザーがそれぞれの選択肢の比較を容易に行えるというメリットがラジオボタンにはあります。

選択肢の並び順は、シンプルなものから複雑なものに、またリスクの少ないものからリスクの高いものにすると良いですね。


### ドロップダウンを使う時
![dropdown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/f50e0d29-8d66-4691-7219-2bdd1b62436e.png)

ドロップダウンも複数の選択肢から1つだけを必ず選択する場合に適していますが、ラジオボタンと異なるのは**選択肢が多い場合**に使われるのが一般的であることです。
選択肢が多くUIが複雑になる場合はドロップダウンを使用して、選択肢を一覧表示することが効果的です。

具体的な使用例：

* 国や地域の選択
* 言語の選択
* 職業の選択


UI上のスペースが制限されている場合でもコンパクトに複数の選択肢を提供できるのが良いところです。

また、選択肢が少なくてもドロップダウンを使った方がいい場合もあります。

ドロップダウンではユーザーが選んだ値のみが画面に表示され、選ばなかった値はすべて非表示になるので、ユーザー自身が選択した値を認識しやすくなります。
ユーザーに選択した値を印象付け、間違いがないか確認してもらいたい場合にはドロップダウンが有効です。


### チェックボックスを使う時
![checkbox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/fbeeffac-15d4-fbe7-8809-3e548c7a5963.png)

チェックボックスはユーザーが**複数の選択肢から1つ以上選択する必要がある場合**に適しています。

具体的な使用例：

* 興味や関心の選択
複数のチェックボックスが表示され、ユーザーが興味のあるものを選択する場合

* 検索条件の選択
ユーザーが複数の項目を選択して検索結果を絞り込む場合

* 同意や承認の選択
ユーザーの同意や承認を得る場合

チェックボックスを使用する際に気をつけることは、ラベルを明確な文言にして否定を避けることです。
「〜しない」や「〜を除く」といったような否定的な表現よりも、肯定的な表現を使用することでユーザーは期待される動作を明確に理解しやすくなります。
（例）「メールでお知らせを受け取らない」→「メールでお知らせを受け取る」


### トグルスイッチを使う場合
![toggleswitch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/4e426e1d-da69-d1f4-dceb-40d565c77277.png)


トグルスイッチは特定のオプションや状態の有効・無効を切り替えるために利用されます。
**有効・無効の行き来が繰り返し可能なもの**はトグルスイッチが適しています。

具体的な使用例：
* 通知の有効/無効
* 機能の有効/無効
* テーマの切り替え
「ダークモード」「ライトモード」

トグルスイッチは、ONとOFFの状態を視覚的に表現するためユーザーに現在の状態を明確に示します。これにより、ユーザーは状態を一目で理解することができるのが良いところです。
また、指でスライドするだけで状態を切り替えることができるため、モバイルデバイスでも使用しやすいUI要素です。



## 参考
* [ラジオボタンをUIに用いる時のポイントを解説！より良いサイト、アプリの利用環境のために](https://www.seleqt.net/design/radiobuttonsuxdesign/)
* [UIクイズ - 2つのうち、どちらか1つを選ぶUI](https://note.com/9b0sk/n/n1f76f5754a7e)
* [選択式フォームをより使いやすくするポイント](https://baigie.me/blog-ui/2021/10/19/select_ui_usage/)
* [【UIシリーズ】選択肢の管理](https://caroa.jp/article/IhEq8__-)
Microsoft Entra ID の サービスエンドポイントを試す

こんにちは、アーキテクトのやまぱんです。
今回 Microsoft Entra ID (旧 Azure AD) のサービスエンドポイントを試してみましたので簡単にメモしておきます。

補足コメントや質問、<font color="red">いいね、拡散</font>、是非お願いします🥺！
間違ってたら<font color="red">優しく</font>教えてください！

# サービスエンドポイントとは
VNet から Private IP (送信元IP) を使って Azure の PaaS サービスにアクセスできるようになるものです。
また、その際のルーティングはシステムルートとして追加されます。
 

https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-network-service-endpoints-overview


https://learn.microsoft.com/ja-jp/azure/virtual-network/virtual-networks-udr-overview


似た名前の Private Endpoint もあります。
これらの違いや詳細については下記をご覧ください。

https://jpaztech.github.io/blog/network/pe-difference-se/

# 検証
## 前提環境
+ 1 VNet / 1Subnet + 1 VM (Public IP付) の環境 + ルーティング初期設定 + NSG Outbound 全開放
このような状態から進めます。

## UDR の設定
以下のようにデフォルトルート (0.0.0.0/0) を上書き/強制トンネリングします。
(myIP は検証用にアクセスしている端末の IP アドレスへのルーティングです。)

こうすることで Outbound 通信は RDP している端末向けの通信を除き、ルーティングが構成されていないので疎通不可となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/ea2d3f48-6652-767e-c274-661248c50105.png)
作成したルートテーブルを対象の VMが存在する VNet/Subnet に紐づけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/2d685d05-e1d3-db79-a1df-eb26914bd107.png)

## Microsoft Entra ID への疎通確認
想定通り 以下の両方のコマンドが通らないことを確認します。
```powershell: Microsoft Entra ID への 疎通確認コマンド
tnc -port 443 login.windows.net
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/3ddb0bbb-3bbe-975d-d1a0-7526b1a69cf4.png)

:::note info
Microsoft Entra ID の 宛先 URL は以下から確認できる
以下 URL の 56 / 59 が Microsoft Entra ID の宛先 URL
https://learn.microsoft.com/ja-jp/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide#microsoft-365-common-and-office-online
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/0ae40ccd-ad98-87a9-0a41-18439c42f8cd.png)

:::

## 次に サービスエンドポイント を有効化します。
対象の VM が存在する VNet / Subnet に Microsoft Entra ID (旧AAD) の サービスエンドポイントを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/06331777-4b0b-44f8-07f3-4883217df812.png)
1 分程度で有効化されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/40f4973c-849f-38e6-3eb9-d6d533ad99f4.png)

:::note info
対象 の VM のルーティングを確認します。
対象の VM  → ネットワーク → NIC  → 有効なルート 、より確認可能。
黄色ハイライト：サービスエンドポイントの構成によって自動的に追加されたもの
水色ハイライト： UDR で手動で追加したもの

0.0.0.0/0 より、黄色ハイライトの方が具体的なプレフィックスを指定しているので黄色ハイライトのルート(＝Microsoft Entra ID のサービスエンドポイントルート) が優先されるはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/471e60c7-777b-0755-4f71-2ff413d704a8.png)
:::

## Microsoft Entra ID への疎通確認
想定通り 以下の両方のコマンドが通ることを確認します。

```powershell: Microsoft Entra ID への 疎通確認コマンド
tnc -port 443 login.windows.net
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/33e6520b-28ca-5b24-daea-c3f1e07f7f3e.png)

はい、無事にサービスエンドポイントが構成されて機能していることが分かりました✨
中国語と英語版のChatGPTみたいなdeepseekをつかう

# 簡単に使える

https://github.com/deepseek-ai/DeepSeek-LLM

https://huggingface.co/deepseek-ai/deepseek-llm-7b-chat

まあ中国版ChatGPTみたいなものか。
以下のPythonコードだけで簡単に使える。

```python
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig

model_name = "deepseek-ai/deepseek-llm-7b-chat"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.bfloat16, device_map="auto")
model.generation_config = GenerationConfig.from_pretrained(model_name)
model.generation_config.pad_token_id = model.generation_config.eos_token_id

messages = [
    {"role": "user", "content": "Who are you?"}
]
input_tensor = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt")
outputs = model.generate(input_tensor.to(model.device), max_new_tokens=100)

result = tokenizer.decode(outputs[0][input_tensor.shape[1]:], skip_special_tokens=True)
print(result)
```

せっかくなので中国のクールなスポットをきいてみる。

>"中国时尚人士玩的时尚景点"
>（中国のスタイリッシュな人が遊ぶ流行のスポット）

```
中国には多くのファッションの人々が多くのアトラクションがあります。いくつかの例があります：

1.上海箱：これは上海の象徴的なアトラクションの1つであり、ヨーロッパのスタイルの建物と美しい夜の景色を眺めることができます。

2.北京798アート地区：かつて放棄された工場エリアでした。今では芸術的な雰囲気に満ちた場所になりました。多くのギャラリー、アート展、カフェがあります。

3.杭州西湖：ウェストレイクは、中国で最も有名な湖の1つであり、美しい自然の景色と長い歴史と文化があります。

4.広州真珠川川ナイトツアー：パールリバーは広州のマザーリバーです。夜のパールリバーの両側にあるライトショーは非常に人気があります。

5. Chengdu Kuanzhai Lane：これはよく保存されている清王朝通りです。伝統的な四川料理や手工芸品がたくさんあります。

6. Xi'anの古代都市の壁：これは、自転車に乗ったり、古代の都市の魅力を感じるために歩いたりできる、保存されていた古代都市の壁です。

7. Hongya Cave、Chongqing：これは、主に垂れ下がった足の建築スタイルに基づいた商業地区です。夜は明るく、とても美しいです。

これらのアトラクションは、多くの観光客を惹きつけただけでなく、ファッションの人々が写真や社交をするための人気のある場所にもなりました。
```

![pexels-traveler-stories-photos-旅人故事相片集-19400764.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/956fd77c-76df-9070-47ba-ebdc83722792.jpeg)

![202308_Hongya_Cave_at_night_from_Qiansimen_Bridge.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/b7aa9d83-2376-5837-862e-fc354c5aa86f.jpeg)

中国語の回答が充実している。

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[X](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
AWS EC2インスタンスとしてCatalyst8000Vにログインする際のTips

# はじめに
AWSではEC2インスタンスなどの仮想サーバが立てられますが、サードパーティベンダから仮想ルータ製品が提供されており、AWS MarketPlaceから利用することが可能になっています。オンプレミスと変わらない操作性を持つルータをクラウド上で動作させることができます。この記事ではAWS上で仮想ルータをデプロイする場合に便利な小技を紹介していきたいと思います。

# そもそも仮想ルータとは
各ネットワーク機器メーカが提供しているソフトウェアルータです。ルータに限らずファイアウォールやロードバランサなどの仮想アプライアンスも各社から提供されており、クラウド上のインスタンスや、仮想サーバ上のゲストOSとしてルータソフトウェアが動作する。クラウドサービスのみでは実現不可能なネットワーク機能を提供したいケースに適用し、様々な要件に対応することが可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731465/54d3352e-7945-d79d-8636-c425dfef4fc1.png)

# Catalyst 8000Vについて
Catalyst 8000VはCiscoが提供するソフトウェアルータ製品です。2022/12/16にEoSとなった先代のCSR1000Vに変わって本記事執筆時点での現行プロダクトとなっています。
[End-of-Sale and End-of-Life Announcement for the Cisco CSR1000V](https://www.cisco.com/c/en/us/products/collateral/routers/cloud-services-router-1000v-series/csr1000v-prepaid-subscription-broadband-license-memory-eol.html)
AWS上ではEC2をデプロイする際にAWS Marketplace AMIから要件に合ったCatalyst8000Vを選択することで利用できます。ライセンスの購入方法はBYOL (Bring Your Own License) 所有ライセンス持ち込みモデルもしくはPAYG (Pay as You Go) ライセンス込みの従量課金モデルがありますが、日本国内においてはBYOLのみが選択可能となっていますので、自分で購入するかCiscoパートナーから調達しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731465/16dffb99-8be4-aff5-2da2-3d81986b5536.png)
# 【Tips】Catalyst8000Vへのログイン方法
デフォルトでは仮想ルータには「ec2-user」というユーザが設定されており、このユーザの認証にはキーペアを保持したマシンからのSSHログインのみ可能な設定になっています。この仕様はAWS上でたくさんのルータを一気にデプロイしたい場合に少し手間に感じる方が多いのではと思います。
この問題はEC2インスタンスの「ユーザーデータ」オプションを活用することで解決できます。EC2インスタンスを起動する際の画面で仮想ルータのユーザ定義を追加して起動することで、キーペアが無いマシンからでも通常のユーザID＋パスワードでのSSHログインを可能にできます。検証環境などセキュリティを緩和できる状況では便利なテクニックなので、覚えておくとよいでしょう。
以下は、仮想ルータへのログインユーザIDが「admin」で、パスワードが「test」に設定するためのユーザデータオプションの例です。
```
ios-config-1="username admin privilege 15 password test"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3731465/a7c4ea93-6033-7a0a-0a0c-19395c4c952d.png)
なおprivilege 15というのはCiscoルータにログインした後の権限を最大にするコマンドです。通常の権限ではログイン後に「enable」コマンドを打たないと特権モードに遷移できませんが、上記の例ではadminというユーザでログインすればenableコマンドを打たなくてもログイン後に自動的に特権モードになっており、さらに省力化できます。
ios-configはCisco製品のブートストラッププロパティとしてドキュメントがありますのでこちらも参考にするとよいと思います。
[Cisco Catalyst 8000V Edge Software Installation And Configuration Guide](https://www.cisco.com/c/en/us/td/docs/routers/C8000V/Configuration/c8000v-installation-configuration-guide/day0-bootstrap-configuration.html#Cisco_Concept.dita_9a071ada-30b7-4014-bbb0-6630e78810a4)

他にもTipsをアップデートしていく予定です。
Spring Security 6のPathRequestにおけるConsider switching to 'HttpSecurity' Lambda DSL syntaxvscode-spring-boot(JAVA_LAMBDA_DSL)について

Spring Security 6を使っている場合、静的リソースへのアクセス許可を設定する際に`PathRequest.toStaticResources().atCommonLocations()`を使用すると以下の`PathRequest`において、`Consider switching to 'HttpSecurity' Lambda DSL syntaxvscode-spring-boot(JAVA_LAMBDA_DSL)`というエラーが出ました。

```java
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final WebOidcUserService userService;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.
            authorizeHttpRequests(authorize -> authorize
                .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                .anyRequest().authenticated()
            ).oauth2Login().userInfoEndpoint().oidcUserService(userService);
        return http.build();
    }

}
```

## 解決策
`PathRequest`クラスを適切にインポートする必要があります。以下のインポート文を追加することでエラーを解消できます。

```markdown
```java
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
```

このインポートを追加することで、Spring Securityの設定内で`PathRequest.toStaticResources().atCommonLocations()`メソッドが正しく認識され、静的リソースへのアクセス許可が適切に設定されます。

## 参考にした記事
https://qiita.com/suke_masa/items/908805dd45df08ba28d8
書籍感想「リーダーになって伸びる人、伸び悩む人」

はじめに
---
今回は、書籍感想という形で、本の紹介をさせていただきます。

書籍名:リーダーになって伸びる人、伸び悩む人
著者　:延原　典和

選んだ理由
---
1．Amazon KindleでPrime readingであったため
2．自分がリーダーと呼ばれる立場になりつつあるため
3．後輩育成のヒントがあるのではないかと思ったため

本の紹介
---
この本は、著者がアメリカンフットボールのコーチをしていた頃に経験してきたことをもとに、リーダーとしての「考え方」や「方法論」を紹介しています。
この本を読むことで、これまでの自分の立ち振る舞いや後輩育成の考え方を見直すことができました。

気になった点
---
読んでいて、一番気になった点は【上司を尊敬している部下は1%以下？】というところです。
「あなたが尊敬する人を一人だけ思い浮かべてください。そして、その人を尊敬する理由を教えてください」と研修で質問した際に、直属の上司が尊敬の対象になることはあまりないそうです。
確かに【一人だけ】とした場合に自分も直属の上司が対象になるかというとそうではないですし、自分が対象になるとも思えません。そうなると、部下やメンバーが自分の話を聞いてくれるのは何故なのかと考えることになります。そして、話を聞いてくれているのはその【立場】であって【自分】ではないということに気づきました。
尊敬される上司となるには、【立場】ではなく【関係性】を築いていく必要があるのではないかと感じました。

印象に残った点
---
この本ではリーダーとして大切な3つの考え方を紹介、そしてそれの詳細ついて教えてくれました。
それについてそれぞれ印象に残ったことを紹介します。

***1．受容〜メンバーのありのままの姿を受け入れる〜***
「受容」の反対を「非受容」としたとき、人（リーダー）はその人（メンバー）に対して「非受容」になった時には、その人（メンバー）の起こした言動や行動を良くないと考えて正そうとするそうです。
人（リーダー）はその人（メンバー）に対して「非受容」になった時、大きく分けて7つの対応をするそうです。全ては紹介できませんが、自分も良くやってしまいがちなこととして学者分析タイプ（分析・診断）というタイプがありました。相手の状況を勝手に分析して、アドバイスをしてしまうといったものです。例えば「人間関係がうまくいっていないから、そんな風に考えているんじゃないの？」といった感じです。
ですが、この本では客観的に見たら、部下が明らかに良くない行動をとっていたとしても、「その人にとっての正当な理由」が存在すると書いていました。そして、その「正当な理由」を知ろうとすること（リーダーによる受容）でメンバーがリーダーの話を聞こう（メンバーの受容）という姿勢に繋がるとあります。
これを読んで自分は、リーダー側の受容ができるとリーダーとメンバーはお互い良い関係性を築いていくことができるのではないかと思いました。

***2．支援〜メンバーの可能性を信じ、その人にとっての最大の支援者となる〜***
２つ目のこれを読んだ時、自分はメンバーの可能性を信じられていただろうか、と考えされました。
「支援」の反対語は一般的には「妨害」と言われているようですが、この本では「評価」だと言っています。
「評価」をすることでメンバーのパフォーマンスの「妨害」につながることがあるからということみたいです。
確かにリーダーという立場になると、どうしてもメンバーのことを「評価」してしまっていると、思いました。
「評価」が上司にとって大切な仕事であるのは間違いないですが、「評価」はリーダーとメンバー間で信頼関係がなければ、「妨害」でしかなく、まずメンバーの可能性を信じ、「支援」することが大事だと書いています。
「支援」の反対が「評価」なのかは、自分には分かりませんでしたが、「支援」の先に「評価」があると思い、「評価」をする前に「支援」メンバーの可能性を信じ支えていこうと思いました。

***3．自己責任〜部下は上司の鏡〜***
３つ目の自己責任ですが、こちらの考え方といったところは様々な場でも良く見聞きする内容でした。しかし、タイトルに記載した「部下は上司の鏡」といったところに、強い印象を受けました。
やはり、メンバーが不平不満を言っていたり、問題を起こしている時に何故そのメンバーはそんな行動をしているのだろうと、メンバーにフォーカスを当ててしまうことが大半でした。
しかし、この本では、自己責任の立場に立って、部下の起こしている問題の原因を自分の中に見出す必要があると、書いています。メンバーがリーダーの話を聞かない場合、その原因は普段リーダーがメンバーの話を聞いていなかったり、指示の出し方にあるのがほとんどで、自己責任を持ち、部下に手本を見せていく必要があるそうです。
また、なんでも自己責任とするのではなく、原因は自分で直接コントロールできるものと、そうでないものを切り分ける必要があるとも書いてます。
これが自己責任の範囲なのだと自分は感じました。
他人の思考や行動、周囲の環境、過去といった自分で直接コントロールできないものに原因を求めることはせず、自分の直接コントロールできることから原因を求められた人だけが、今、目の前にある問題を改善・解決するチャンスを手に入れられるとあります。
問題に対して、真正面から取り組む姿勢にメンバーは共感し関係性を築くことができ、次につながるのだと思いました。

***まとめ***
上記に書いた３つの考え方を支えるのはメンバーに対する「愛」だそうです。「愛」だと重たいかもしれませんが、本を読むことで利他意識（「その人のために」という意識）を持つことが重要なのだと理解することができました。

***最後に読んだ感想***
リーダーとなって伸びる人と伸び悩む人の原因が、この本を読んだことで理解、そして言語化することができました。
自分もいろんなリーダーや上司と関わってきましたが、良いと感じた人や、もう少しこちらのことを考えてほしいと思った人などがおり、それらの違いの理由をこの本を読むことでより理解することができました。
リーダーで悩んでいる人だけでなく、これから先輩として後輩を指導するといった立場の人にも読んでほしい一冊だと思いましたので、興味がある方はぜひ読んでみてください。

参考
---
***リーダーになって伸びる人、伸び悩む人***

https://www.kinokuniya.co.jp/f/dsg-08-EK-0913802

前回の書籍感想
---
https://qiita.com/ogataro/items/b9ce504c646d8ddfc8ab
Lightsail上のWordPressがデータベース接続エラーになったけど直したメモ

## 治ったのでひとまずメモ
 - 原因：未解決
 - 対処：MySqlの再起動

## やって解決こと
```bash
$ sudo /opt/bitnami/ctlscript.sh start mysql
/opt/bitnami/mysql/scripts/ctl.sh : mysql  started at port 3306
Monitored mysql
```
## 試行錯誤したこと
- Apatchの再起動

```bash
$ sudo /opt/bitnami/ctlscript.sh stop apache
$ sudo /opt/bitnami/ctlscript.sh start apache
```
※効果なし

## 背景
WAFの設定をして遊んでいたところ、急にエラー画面が出る。
あまり考えずに、WAFの設定が悪かったのだろうと手直しをしようとしたのだが、よくよく考えたらWordPressはlocalhostでMySQLに接続しているというのを思い出して、ヒヤヒヤとしながらコンソールに入り、```ps -aux | grep mysql```などをやって、動いていないことに気付く。
起動させて、無事終了。

## 参考にした資料
WordPressをEC2のt3.nanoで稼働してたらMySQLがOut of memoryになった話 | WAKU'S Notebook
https://waku.nagoya/blog/2022/02/16/post-871/
[LangChain]AzureChatOpenAIでseedを固定する方法


# はじめに
GPT4-TurboのseedをLangChainのAzureChatOpenAIで指定する方法が分からなかったので調べてみました。
結論はmodel_kwargsに書くそうです。しかし、結果が安定しなかったので、本当に固定できているのか簡単な検証をしてみました。


```python
gpt4 = AzureChatOpenAI(
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    openai_api_key=os.environ["AZURE_OPENAI_API_KEY"],
    openai_api_version="2023-09-01-preview",
    deployment_name=deployment_name,
    model_name=model_name,
    model_kwargs={"seed": 42}, #ここにseedを書く
    temperature=0.0
)
```


# 検証
ランダムな値を出力するプロンプトで実験しました。

```python
prompt = """
完全にランダムな数字を1つ返してください。数字だけ返してください。
"""

for i in range(10):
    response = gpt4.invoke(prompt)
    print(response)
```


```bash
#seedなしの場合
content='2473659'
content='7548329'
content='9827'
content='7429'
content='156349'
content='3759'
content='3478'
content='54783921'
content='9827'
content='4179'

#seedありの場合
content='4287'
content='4287'
content='4287'
content='4287'
content='4287'
content='4287'
content='4287'
content='4287'
content='4287'
content='4287'
```
seedありの方は結果が固定されています。

# まとめ
LangChainのAzureChatOpenAIでseedを固定する方法を調べました。
ただし、結果は結構ぶれるので、現状はそこまで期待しないほうがよさそうです。
MySQL8でストアドファンクションを登録できない問題

# はじめに

MySQL5系からMySQL8.0にアップデートした時、ストアドファンクションを登録できなくなったので、解消方法をまとめます。

# 問題

エラー内容

```ruby
Mysql2::Error: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

# 翻訳
# SUPER 権限がなく、バイナリ ロギングが有効になっています (安全性の低い log_bin_trust_function_creators 変数を使用することもできます)
```

# 解決方法

mysqlの設定のlog_bin_trust_function_creatorsの値がOFFだと上記のエラーが出ます。

```sh
SHOW variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF   |
+---------------------------------+-------+
```

関数を作成するには、ユーザーがSUPER権限を持っている必要があるため、今回エラーが出ていた模様。

> ストアドファンクションを作成または変更するには、通常必要なCREATE ROUTINEまたはALTER ROUTINE権限に加えて、SET_USER_ID権限 (または非推奨のSUPER権限)が必要です。
関数作成に関する前述の条件(SUPER権限を持つ必要があることと、関数が決定的であるか、データを変更しないと宣言する必要があること)を緩和するには、log_bin_trust_function_creators グローバルシステム変数を1に設定します。デフォルトでこの変数には0の値が設定されていますが、次のように変更できます。
mysql> SET GLOBAL log_bin_trust_function_creators = 1;


以下のコマンドを使ってlog_bin_trust_function_creatorsの値をONにすることで、ストアドファンクションの登録ができるようになります。

```sh
SET GLOBAL log_bin_trust_function_creators = 1;
SHOW variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | ON    |
+---------------------------------+-------+
```

# 参考

https://dev.mysql.com/doc/refman/8.0/ja/stored-programs-logging.html

https://qiita.com/runeri_1128/items/2a0e682f1f2dd800109d
AttributeError: module 'huggingface_hub.constants' has no attribute 'HF_HUB_CACHE'の応急対応

# なんかエラー起きた
Bark GUI（ https://github.com/C0untFloyd/bark-gui ）をローカル環境で動かしていたのですが、StartBark.bat を実行実行したらいきなりタイトル通りのエラーが出ました。

```
AttributeError: module 'huggingface_hub.constants' has no attribute 'HF_HUB_CACHE'
```

# 【結論】やったこと
```
pip install --upgrade huggingface_hub;
pip install --upgrade transformers;
pip install --upgrade tokenizers;
```

→いくつかページは見たのですが、どういう経路で直ったのかをメモり忘れたのでとりあえず結論だけ。。。
　ひとまず上記モジュールのアップグレード・再インストールで再稼働しています。
　モジュールのアップデートで対応できました＝エラーは消えました。
　Bark GUI側の動作にどのような影響が出ているかは不明です。

# 原因は不明です
特にモジュールのアップデートをした覚えがないのに上述のエラーが発生しました。
直近2週間くらいでGitHubやStackOverflowで同様のエラー報告上がっているのを見かけましたが、解決策なかったので取り急ぎ投稿してみます。
（英語系のサイトを総ざらいしているわけではないので、もしかすると既出かも）
修正経路わかる方の投稿をお待ち下さい（他力本願）
[Linux / job] 長時間かかるプロセスを起動後に、ログアウトしてもそのプロセスが落ちないようにする

# 概要

長時間かかる処理を、

- 既に起動してしまった。
- `nohup <command> &` を使わずに起動したい。

でも、その処理の終了を待たずに PC やログイン shell からは exit したい。その後も処理を実行させ続けたい。

そんな方のための記事です。

## こんな時に使う

こういう時に自分はこの問題に直面した。

- `mysqldump` で数百GBとかTBレベルのデータを dump しようとするとき
- 長時間かかる処理の途中でパソコン消すかもしれないし、ssh でリモートログイン中だったら、途中でネットワークが切断されるかもしれないとき


# 手順概要

1. 実行中の処理を一時停止させる
1. 停止させたジョブの job id を確認
1. 同処理をバックグラウンド実行させる
1. ログイン中の shell からそのプロセスを切り離す

この4段階を踏んで対策を取りますよ。

実行するコマンドだけを並べると以下のようになるのですが、

```bash
# 実行した重い処理
$ mysqldump <色々 option>

# 1. 実行中処理を一時停止させる
# Ctrl + Z を押下

# 2. 停止させたジョブの job id を確認
$ jobs
[1]+  Stopped                mysqldump <色々 option>

# 3. 同処理をバックグラウンド実行させる (job id が 1 の場合)
$ bg %1

# バックグラウンド実行させたプロセスの job id を再度確認
$ jobs
[1]+  Running                 mysqldump <色々 option>

# 4. ログイン中の shell からそのプロセスを切り離す (実際には、必ずしも 1 ではなく、該当ジョブの job id を入力する)
$ disown %1
```

それぞれの詳細は以下で説明します。


# 手順詳細

## 1. 実行中処理を一時停止させる / 2. 停止させたジョブの job id を確認

まず `Ctrl + Z` で、処理を一時停止させて下さい。

次に、 `jobs` コマンドで、停止させたプロセスの job 番号を確認します。

```bash
$ mysqldump <色々 option>

# 1. 実行中処理を一時停止させる
# Ctrl + Z を押下

# 2. 停止させたジョブの job id を確認
$ jobs
[1]+  Stopped                mysqldump <色々 option>
```


## 3. 同処理をバックグラウンド実行させる

そして、その停止中のプロセス...もとい、ジョブを bg コマンドでバックグラウンド実行させてあげます。

```bash
# 3. 同処理をバックグラウンド実行させる (job id が 1 の場合)
$ bg %1
```

これで、長い処理がバックグラウンド実行されます。
でも、まだこれでは終わりませんよ。

## 4. ログイン中の shell からそのプロセスを切り離す

次に、今ログインしているユーザから、そのバックグラウンドプロセスを切り離しましょう。

今 jobs コマンドを実行すると、先ほどバックグラウンド実行させたプロセスが表示されますね。おそらく `Running` 中のはず。

このままだと、あなたのユーザがそのターミナルからログアウトした時に、そのプロセスは強制終了してしまいます。

これを防ぐために、 `disown` コマンドを打ちますよ。

```bash
# バックグラウンド実行させたプロセスの job id を確認
$ jobs
[1]+  Running                 mysqldump <色々 option>

# 4. ログイン中の shell からそのプロセスを切り離す (実際には、必ずしも 1 ではなく、該当ジョブの job id を入力する)
$ disown %1
```

これで、ログインしている shell から exit したりしてもプロセスが落ちずに実行され続けるようになります。
こうなると、 `jobs` コマンドを打っても、その処理が表示されなくなります。


```bash
$ jobs
# さっき disown した処理が表示されない！
```

これが、「ログイン中の shell からプロセスを切り離す」ということでした。

ここまでやって初めて、シェルからログアウトしてもプロセスが継続実行されるようになります。


# 参考資料


https://atmarkit.itmedia.co.jp/ait/articles/1708/25/news012.html

https://developers-book.com/2021/08/22/255/#toc3
PythonでCloud Vision APIを使用して画像からJSON形式でテキストを読み込む

コードのみ貼り付けます。
導入手順については[画像内のテキストを検出する](https://cloud.google.com/vision/docs/ocr?hl=ja)から。

```python
from google.cloud import vision
import io
import json
import tkinter as tk
from tkinter import filedialog

def save_and_download_text(image_path):
    # クライアントを初期化
    client = vision.ImageAnnotatorClient()

    # 画像ファイルを読み込む
    with io.open(image_path, 'rb') as image_file:
        content = image_file.read()

    image = vision.Image(content=content)
    image_context = vision.ImageContext(language_hints=["ja"])  # 日本語のヒントを追加

    # APIを呼び出して画像からテキストを抽出
    response = client.document_text_detection(image=image, image_context=image_context)

    # 結果をJSON形式で保存
    extracted_texts = [text.description for text in response.text_annotations]
    output_file_path = 'extracted_text.json'  # 保存するファイルのパス
    with open(output_file_path, 'w', encoding='utf-8') as f:  # UTF-8エンコーディングを指定
        json.dump(extracted_texts, f, ensure_ascii=False, indent=4)

    # ダウンロードするファイルのパスを出力
    print(f"保存先: {output_file_path}")

# ファイル選択ダイアログを表示
root = tk.Tk()
root.withdraw()  # Tkのルートウィンドウを表示しない
file_path = filedialog.askopenfilename()  # ファイル選択ダイアログを開く

if file_path:
    save_and_download_text(file_path)
else:
    print("ファイルが選択されませんでした。")
```

## 参考リンク
[画像内のテキストを検出する](https://cloud.google.com/vision/docs/ocr?hl=ja)