OmniAICreator/Qiita-1.07M huggingface dataset:
AR(1)モデル

## AR(1)モデルの基本

AR(1)モデルは以下のように表される。

$$
X_t = \phi X_{t-1} + \epsilon_t
$$

ここで、$X_t$は時刻$t$での時系列の値、$\phi$は自己回帰係数、$\epsilon_t$は平均がゼ$0$で分散が $\sigma^2$ のホワイトノイズ誤差である。
また、定常性の条件$|\phi|<1$を仮定する。



## AR(1)モデルの分散
$V[X_t]=\tau^2$とおくと、
$$\tau^2 = V[X_t]=\phi ^2[ X_{t-1}] + V[\epsilon_t] = \phi ^2\tau^2+\sigma^2$$より、
$$\tau^2=\frac{\sigma^2}{1-\phi ^2}$$が成り立つ。

## AR(1)モデルの共分散
$X_t$と$X_{t+1}$の共分散は
$$Cov[X_t,X_{t+1}]=\phi V[X_t]=\frac{\sigma^2}{1-\phi ^2}\phi$$となる。同様に$X_t$と$X_{t+2}$の共分散は
$$Cov[X_t,X_{t+2}]=\phi \thinspace Cov[X_t,X_{t+1}]=\phi^2 V[X_t]=\frac{\sigma^2}{1-\phi ^2}\phi^2$$となる。この議論を繰り返し、定常性と合わせて
$$Cov[X_i,X_{j}]=\frac{\sigma^2}{1-\phi ^2}\phi^{|i-j|} $$を得る。

## 自己共分散関数と自己相関関数
時系列モデルでは
$$\gamma_t=Cov[X_0,X_{t}], \enspace \gamma_{|t-s|}=Cov[X_t,X_{s}]$$という様に表し、自己共分散関数と呼ぶことが一般的である。
また、
$$\rho_k=\frac{\gamma_k}{\gamma_0}$$をラグ$k$の自己相関関数と呼ぶ。
上記の式から、AR(1)モデルの場合、$\rho_1=\phi$が成り立っていることが分かる。

## AR(1)モデルのコードの例

```python:
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm

# ダミーデータの生成
np.random.seed(42)
nobs = 100
time = np.arange(nobs)
phi = 0.7  # AR(1)モデルのパラメータ
epsilon = np.random.normal(0, 1, size=nobs)
y = np.zeros_like(time)

# AR(1)モデルの構築
for t in range(1, nobs):
    y[t] = phi * y[t-1] + epsilon[t]

# プロット
plt.plot(time, y, label='AR(1) Process')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

# AR(1)モデルのフィッティング
model = sm.tsa.AR(y)
result = model.fit()

# パラメータの表示
print(result.summary())
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359600/0109b250-85e8-34ad-dceb-84ac65216265.png)


## ホワイトノイズの条件
$$E[\epsilon_t] = 0$$$$Cov[\epsilon_t,\epsilon_{s}]=0, t \neq s $$$$Var[\epsilon_t]=E[\epsilon_t^2] = \rm{const}$$
Apple Silicon搭載のMacBookでPythonとJupyter Notebookのインストールに関する問題とその解決法

もしbrewを使用してPythonをインストールした後、
pipでJupyter Notebookもインストールした場合、
特にApple Siliconを搭載したMacBookを使用している場合、
私と同じ問題に遭遇する可能性があります。:joy:

ターミナルで`jupyter notebook`と入力して起動すると、ブラウザで表示されるのは以下のような画面です：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430985/405f5c7b-885b-9413-afd2-8c27c7cb38e6.png)

そして、ターミナルには長いログが表示され、その中には以下のような内容が含まれています：

```
Missing or misshapen translation settings schema: HTTP 404: Not Found (Schema not found: /opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/share/jupyter/lab/schemas/@jupyterlab/translation-extension/plugin.json)
```

これは新しいバージョンのJupyterがbrewやPythonと完全に互換性がないために発生するバグである可能性が高いです。
インターネットで調べた結果、最も簡単な解決策は以下のコマンドを実行することです：

```
ln -s /opt/homebrew/share/jupyter/ /opt/homebrew/Cellar/python@3.11/3.11.4_1/Frameworks/Python.framework/Versions/3.11/share/jupyter
```

これにより、Jupyterが再びschemaを見つけることができるようになります。
この方法でブラウザを再起動すると、ページが正常に表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430985/bf3e0509-60da-2a24-0d82-531bb452429a.png)

同じ問題に直面している方は、この方法を試してみてください。:metal::metal_tone1::metal_tone4:
python 処理時間を計算する

timeモジュールを使用することで、処理時間を計測できる。

```py
import time

start = time.time()
#処理
end = time.time()
print(end - start)


HH:MM:SS のフォーマットで表示することは、以下の関数で可能である。

import time
def elapsed_time_str(seconds):
    seconds = int(seconds + 0.5)
    h = seconds // 3600
    m = (seconds - h * 3600) // 60
    s = seconds - h * 3600 - m * 60
    return f"{h:02}:{m:02}:{s:02}"
```

経過時間を正確に測定したい場合は、「time.time」よりも「time.perf_counter」を使った方がいいと言われています。

余談ですが、以下で1秒停止もできます。

```py
import time
time.sleep(1)
```
CoreBluetoothForUnity で toio と通信する

## 本記事について

この記事は [CoreBluetoothForUnity Advent Calendar 2023](https://qiita.com/advent-calendar/2023/core-bluetooth-for-unity) の4日目の記事です。

CoreBluetoothForUnity のサンプル 01_LightControl, 02_ButtonInformation で toio のランプの色変更と、ボタンの状態を取得する方法を紹介します。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/9b98b48a-a650-0cf0-8537-7eaca8b9b8c7.gif)

## toio とは

https://toio.io/

小さいロボットです。
Unity で扱うための公式の SDK が公開されています。

https://github.com/morikatron/toio-sdk-for-unity

本記事ではこの SDK を使わずに toio と通信します。

## toio の通信仕様

大変ありがたいことに、各種機能・Service, Characteristic の UUID ・データのフォーマットが以下に綺麗にまとまっています。

https://toio.github.io/toio-spec/docs/ble_communication_overview

学習する上では非常に便利です。

## サンプルで通信する手順

### LightControl

データフォーマットは同じなため、以下のように Service, Characteristic の UUID を差し替えるだけで接続・通信可能です。

```SampleLightControl_Data.cs.diff
public static class SampleLightControl_Data
{
    // See the following for generating UUIDs:
    // https://www.uuidgenerator.net/
-   public static readonly string ServiceUUID = "068C47B7-FC04-4D47-975A-7952BE1A576F";
-   public static readonly string LightControlCharacteristicUUID = "2AE0B518-1DF2-4192-9E4A-EDEF2F30B04C";
+   public static readonly string ServiceUUID = "10B20100-5B3B-4571-9508-CF3EFCD7BBAE";
+   public static readonly string LightControlCharacteristicUUID = "10B20103-5B3B-4571-9508-CF3EFCD7BBAE";
```

Service UUID は[通信概要](https://toio.github.io/toio-spec/docs/ble_communication_overview)のページ
Characteristic UUID は各種機能の[ランプ](https://toio.github.io/toio-spec/docs/ble_light)のページから取ってきています。


データフォーマットは以下です。

https://toio.github.io/toio-spec/docs/ble_light#%E7%82%B9%E7%81%AF%E6%B6%88%E7%81%AF

### ButtonInformation

toio にはボタンが1つだけ、ランプが押せるようになっています。

手順は LightControl と同様です。
Service UUID と Characteristic UUID を以下に差し替えることで通信できます。

```
ServiceUUID: 10B20100-5B3B-4571-9508-CF3EFCD7BBAE
CharacteristicUUID: 10B20107-5B3B-4571-9508-CF3EFCD7BBAE
```

Characterictic UUID およびデータフォーマットは以下のページにあります。

https://toio.github.io/toio-spec/docs/ble_button

## おわりに

toio 面白いし、BLE の学習に非常に有効なため値段の価値ある良いおもちゃだと思います。
ぜひ遊んでみてください！
[リサーチ・メモ]標準入力、標準出力、標準エラー出力

## リダイレクトとは
コマンドラインにおいて、プログラムやコマンドの出力をデフォルトの出力先（通常は画面またはコンソール）から別の場所へ向ける操作

## 0 - 標準入力 (Standard Input, stdin)
キーボード入力を意味し、ファイルや他のプログラムからの入力にリダイレクトすることができる
|コマンド|内容|
|:--:|:--:|
|command < file.txt|file.txt の内容が command に入力として渡される|

## 1 - 標準出力 (Standard Output, stdout)
コンソールに表示され、ファイルや他のプログラムにリダイレクトすることができる
|コマンド|内容|
|:--:|:--:|
|command > file.txt|commandの出力をfile.txtに書き込む|
|command >> file.txt|commandの出力をfile.txtの既存の内容の後に追加する|

## 2 - 標準エラー出力 (Standard Error, stderr)
コンソールに表示されずに標準出力とは独立しており、別々にリダイレクトができる
|コマンド|内容|
|:--:|:--:|
|command 2> error.txt|commandの出力をfile.txtに書き込む<br>※ここでの2は標準エラー出力を示す|

## 仕事でよく使うコマンド「command > file.txt 2>&1」
標準エラー出力(2)を標準出力(1)にマージしてリダイレクトすることでログファイルの作成ができる
Rのバージョンアップ時に旧バージョンのライブラリを全インストール

OSのアップグレードをした際に R のバージョンが知らないうちに上がることがあります．
その後，気づかずに古いRプログラムを実行すると，Rの新バージョン用のライブラリが入っておらず，改めてライブラリのインストール作業を始めたりすることがあります．
そんなことになる前に，以下のスクリプトを実行しておくと便利です．

R Ver. 4.2 から 4.3 にアップデートした場合:
```R
liba <- dir("~/R/x86_64-pc-linux-gnu-library/4.2/");
libb <- dir("~/R/x86_64-pc-linux-gnu-library/4.3/");

for (x in setdiff(liba, libb)) {
  install.packages(x);
}
```
ロボットアーム教示デバイスの作成

お受けした案件で使いたく、以下のようなロボットアームの教示デバイスを作成する事にしました

https://x.com/philippswu/status/1706339022518513896?s=20

作成していくにあたりメモを残していけたらと思います

- 部品表

https://docs.google.com/document/u/0/d/1pzV8LDIGZh6zq8z-ZyKjUZ1ISkdCQctfu_05-ZY95eg/mobilebasic

- リポジトリ

https://github.com/wuphilipp/gello_software

# ソフトウェア

```
git clone https://github.com/wuphilipp/gello_software.git
```

実行(docker使用)
1. docker install 
 https://qiita.com/nanbuwks/items/0ba1d13b3cd27e5c6426

2. gello docker image install
```
sudo docker build . -t gello:latest
```

# ハードウェア

- cad data
https://github.com/wuphilipp/gello_mechanical
システムの品質を高める方法あれこれ

品質を高める手法あれこれ


- プログラムのテスト
    - 情報処理技術者試験で出てくるレベルで体系化されてる
        - 境界値テスト・同値テスト
        - ブラックボックステスト・ホワイトボックステスト
    - xUnitを始めとするオブジェクト指向言語のテスティングフレームワーク
    - RSpecを代表とする結合テストを含めたフレームワーク
- プログラムのレビュー
    - コーディング規約などで「読めばわかる」レベルで情報は整理されている
- 本番でのログ監視
    - このあたりから体系化されてない
    - ただ眺めるのも大事（結構なミスが「ただ見るだけ」でわかる）
    - 集計して異常値をみるのも大事
    - リリース直後と翌日・翌週・翌月のポイントが大事（データが溜まったあとのローテーションとかでみすりがち）
- バックドアでのテスト
    - 本番環境でしか起き得ないこともある
    - その場合はバックドアで本番環境での動作を確認する
    - ゲームの世界では裏口を用意してテストしやすくする手法はある
    - 「購入」などのテストは本物サイトで支払い処理をしないと全く安心できない
- 本番データの集計
    - プログラムにバグがなくても想定外のインプットで想定外のアウトプットになってるかもしれない
    - 本番データの集計はとても大事
    - ログと似てはいるがここで言うデータは実際の納品物であるため「検品」に近い
    - システムのテストは念入りにするけどそのシステムが出力した納品物の検品をしないというのはありない（が以外とそういう現場は多い）
    - エンジニアが本番データを見れちゃいけないというルールがある現場もあっておろそかになりがち
        - エンジニアの納品物はIPOでいうPであってOではないという認識だとそうなる
        - しかし実際の提供価値はOなのでOの検品なしに品質は語れない
        - さらに言えばIの品質も大事だけど、そこもログで見るべきなのが見てない現場が多い
スライドショーアプリを作るためのアーキテクチャ検討

スマホのスライドショーアプリを作りたい。その時のアーキテクチャ検討のメモ。サクッと作るにはどうしよう。まかない飯に最適なアーキテクチャはなんだろう。

### その１：普通のスライドショーアプリ

- アプリが起動してる間はスリープしない
- フォルダじゃなくてファイルを選択するだけのアプリ
- PhoneGapで作れればいい？
    - コマンド多くてむしろ面倒
    - Monacaがいいかとも思ったけどむしろ被せ物がおおい
        - onsen UIが邪魔
- Googleのチュートリアルにしたがって、Windows上のAndroidSDKだけで作る方がシンプル（Bashに依存しない）

### その２：ブラウザ上のVideoタグで作れないか

- jpegを3コマのmp4に変換してそれをvideoタグに変換
- もしくはjpegをmp4に変換してm3u8でプレイリスト化
- あとはvideoタグで再生スピードを変えるだけ
- ブラウザの機能がしっかりしていれば、別画面でも再生できる
- 変更先の動画形式は（mp4,m4v,webm）のいずれか（軽さややりやすさで）
- ブラウザ上でやるならffmpeg-wasmを使うか
    - https://gigazine.net/news/20201109-ffmpeg-wasm/
    - デモはすでに動作してなかったので、大人しくサーバーサイドでやるか https://zenn.dev/sugar/articles/ce971201435814b0350c

### ffmpegで静止画を動画に変換してみよう

原点回帰

https://qiita.com/NT1123/items/87e6d46f86f4c6c89a8a

```
ffmpeg -loop 1 -y -i n225.jpg -vcodec libvpx -pix_fmt yuv420p -t 5 -r 1 n225.webm
```
- `-loop 1 -y -i n225.jpg` この静止画だけをループする
- `

https://ws.tetsuakibaba.jp/doku.php?id=ffmpeg:%E9%80%A3%E7%95%AA%E5%90%8D%E7%94%BB%E5%83%8F%E3%82%92%E5%8B%95%E7%94%BB%E3%81%AB%E5%A4%89%E6%8F%9B

以下のように -crf 18 でクオリティの高いオプションを設定すればよい．-crf 0 でロスレスエンコード

```
$ ffmpeg -r 30 -i %4d.png -vcodec libx264 -pix_fmt yuv420p  -crf 18  output.mp4
```

ミニマムの動画変換（30fps）

```
ffmpeg -r 30 -i jpeg/kazuha1.jpg output.mp4
```

これだとすぐ終わる。
フレームレートを変えてみる。

```
ffmpeg -r 0.1 -i jpeg/kazuha1.jpg output.mp4
```

これでもすぐ終わってしまう。フレームレートではなく動画の尺自体を指定しないとだめかも。


```
ffmpeg -r 1 -t 10 -i jpeg/kazuha1.jpg output.mp4
```

これでもすぐに終わってしまう。

ループをしていすることで一つのファイルになった

```
ffmpeg -r 1 -t 10 -loop 1 -y -i jpeg/kazuha1.jpg output.mp4
```

これで初めて10秒の動画が完成

次にスライドショー的に複数のファイルを指定してみる

```
ffmpeg -r 1 -t 10 -loop 1 -y -i jpeg/kazuha%1d.jpg output2.mp4
```

これだと1秒おきに変わる。
フレームレートを買えてみる。

```
ffmpeg -r 0.5 -t 10 -loop 1 -y -i jpeg/kazuha%1d.jpg output2.mp4
```

これでも1秒おきに変わる


```
ffmpeg -r 1 -t 10 -loop 1 -y -i jpeg/kazuha%1d.jpg -r 60 output2.mp4
```

出力のフレームレートを変えることで、もうちょっとゆっくり変わるようになった。
ただ、ここのコントロールは難しそうなので、jpegの個数とmp4の個数は一致させる方が良さそう。
ffpmegで動画を結合させるという案もあるが、縦横比が同じファイルでないとffmpegの動画結合機能は使えない。

スライドショーという使い方をする限り、縦横比の違う画像が入ってくることも考慮する必要がある。

次はm3u8ファイルで各動画をプレイリストにする。


まずjpegを10秒の動画に変換

```
ffmpeg -r 1 -t 10 -loop 1 -y -i jpeg/kazuha1.jpg kazuha1.mp4
ffmpeg -r 1 -t 10 -loop 1 -y -i jpeg/kazuha2.jpg kazuha2.mp4
```

次にこの2つの動画をプレイリストにする。

```te01.m3u8
#EXTM3U
file://wsl.localhost/Ubuntu-20.04/root/work/jpeg2mp4/kazuha1.mp4
file://wsl.localhost/Ubuntu-20.04/root/work/jpeg2mp4/kazuha2.mp4
```

m3u8は非常にシンプルで、ファイル名を絶対パスで並べるだけ。
この方法でVCLプレイヤーでは再生できた。

次にブラウザでm3u8を再生する方法

一旦素のvideoタグで当てはめてみる。

```te01.html
<video src="./te01.m3u8">
```

これが機能しなかった。
あれこれ調べても、直接m3u8ファイルを再生している例が見当たらない

ビデオが終わったことのイベントは認識できるから次の動画に切り替えるというJSをかけばいいか


### その３：壁紙変更アプリ

- 定期的にロック画面の壁紙を変更するだけのアプリ
- 壁紙に設定されている画像のファイル名を変更するだけってのはどうだろう
- もしくは壁紙に設定されている画像のファイル名に定期的にコピーする
- これならadbシェルでできないかな
- termux+cronでできると嬉しい

### 根本的な課題

スマホをスリープさせないというためにはどうしたらいいかということがいずれも考慮されてない。その点ではいずれも不合格。
エンティティの出し方

この記事は [Minecraft Command Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mccmd) 14 日目の記事です。

## はじめに
これはJava版の人のための記事です。__BE版では動かない__ かもしれません。
このコマンドを動かすには、__OP権限__ を持っている必要があります。
前提知識：__エンティティの意味__
想定バージョン：__1.20.x__

## エンティティを出す
### やってみる
エンダードラゴンを出してみましょう。
このコマンドを実行してみてください。
チャット欄に、__CtrlとC__ でコピー、__CtrlとV__ でペーストして、__Enter__ を押せば実行出来ます。
```nim
/summon ender_dragon
```

出来ましたか？出来なかったら、どこか間違っているかもしれません。__最初から__ やってみましょう。

### 解説
`summon`とは、__好きなエンティティを出す__ コマンドです。

`ender_dragon`の部分を、__エンティティのID__ と言います。
ここを、他のエンティティのIDに変えれば、そのエンティティを出す事が出来ます。
[ここ](https://minecraft.fandom.com/ja/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E5%80%A4/Java_Edition/%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3)で、__すべて__ のエンティティのIDを見ることが出来ます。やってみましょう。
```nim
# ゾンビ
/summon zombie

# 牛
/summon cow

# イルカ
/summon dolphin
```
__ゾンビだけ__ 出ませんでしたか？それは、__難易度がピースフル__ だからかもしれません。下のコマンドを実行して、難易度をイージーにして、__もう一度__ やってみましょう。
```nim
/difficulty easy
```

## 座標の指定
### 現在の座標の見方
xとyとzで、ゲーム内の場所を表現するのが、__座標__ と呼ばれている物です。
下の画像では、x / y / zの形で現在の座標が表示されています。
![座標](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589140/5b44b2c5-d373-fcd5-6485-33f732206a2a.png)
コマンドで座標を指定するときは、`x y z`と、スペースで区切って指定しましょう。

### やってみる
上の画像の座標、`5 -60 15`の位置にゾンビを出してみましょう。
```nim
/summon zombie 5 -60 15
```

出来ましたか？出来なかったら、どこか間違っているかもしれません。__最初から__ やってみましょう。
VMware ESXiでゲストがうまく起動しないときのリペア方法

# はじめに
<!-- 発端や概要を記載 -->
自宅のESXiサーバを再起動したりすると、「オブジェクト タイプにはホストされた I/O が必要です」と表示されうまくゲストが起動できないことが割と頻繁にある。
何度も調べるのが面倒なので備忘として記事を投稿する。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [リペア方法](#Chapter1)
1. [おわりに](#Chapter2)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# リペア方法

1. SSHの有効化
ESXiログイン後、左側のナビゲーションペインからホスト>アクション>サービス>SSHの有効化を選択し、SSH接続ができるようにする。

1. 対象ゲストの.vmdkファイルをcheck
   SSH接続後、`cd  /vmfs/volumes/データストア名/対象ゲスト`で対象ゲストの.vmdkファイルが保存されているディレクトリへ移動する。

   コマンドでチェックする。
   ```
   vmkfstools -x check 対象ゲスト.vmdk
   ```

   リペアが必要な状態の場合、`Disk needs repair.`と表示される。
   ```
   [username@hostname:/vmfs/volumes/データストア名/対象ゲスト名] vmkfstools -x check 対象ゲスト名.vmdk
   Disk needs repair.
   ```
1. 対象ゲストの.vmdkファイルをrepair
   コマンドでリペアする。
   ```
   vmkfstools -x repair 対象ゲスト.vmdk
   ```

   成功すると`Disk was successfully repaired.`と表示される。
   ```
   [username@hostname:/vmfs/volumes/データストア名/対象ゲスト名] vmkfstools -x repair 対象ゲスト名.vmdk
   Disk was successfully repaired.
   ```
1. 対象ゲストを起動

:::note warn
警告
有効化したSSHは無効化しておいてください。
:::

<a id="#Chapter2"></a>
# おわりに
ESXiでゲストが起動できなくなった時の対処法でした。

<a id="#reference"></a>
# 参考文献
- https://www.facebook.com/404723519706335/posts/1700198396825501/
メール受信トリガーで処理をする方法をあれこれ比較

ガラケーのころは「カラメール送信」をトリガーにあれこれ処理をしていたけど、今どきはどうなんだろうということを調べてみた。（実装はしてないです）

### 片っ端から比較

- 自前Postfix
    - 昔からある方法
    - 今どきはたぶんよりドメイン認証やらをしっかりしないといけないんだろうと思うので他にいい方法がないかを探す
- SendGrid でやる（単体のメール送信APIとしてはとてもメジャー。受信もできる。無難。）
    - 例） https://sendgrid.kke.co.jp/blog/?p=12114
    - 上記の例はめちゃくちゃシンプル。うけとるPOSTのWebサーバーを指定するだけ
    - 疎結合だからテストしやすい
- Cloudflare Email Workers  （ナウくてヤング）
    - https://blog.cloudflare.com/announcing-route-to-workers/
    - https://c-limber.co.jp/blog/5174
    - 受信してからR2にアップするとかが楽にできそう
    - ドメインレジストラやらDNSと密結合という別軸のロックインが発生する
- Amazon SES Lambda でメール受信トリガー（AWSのサービスをいろいろ組み合わせる）
    - 情報が多いのがいいところ
    - SES でメール受信を行い、Lambda 関数でメール本文、添付ファイルを抜き出す例
        - https://qiita.com/sugimount-a/items/f33992d7860bb730d53b
        - この例はまずはS3にデータが置かれてる
        - S3に置かれたトリガーでPythonを起動しているが、S3に置くところまでをやれば、あとはAWSの外にあるマシンがS3を参照して処理をするという方法でもいい
    - Pythonに限らず今はいろいろ言語が選べるみたい
- Google App Engineでメール受信トリガーの例
    -https://qiita.com/Kentaro91011/items/e8f9c5764ff6792c1d98
    - GAEがサーバーレスアーキテクチャでは一番の老舗
    - ただあまりに老舗でチヤホヤされてない
    - Javaで書くというのもWeb系ｎエンジニアには受けがわるいのかな

### 総評

- 自治体仕事ならAWSオンリーで構築するのが無難かな
- ただしCloudFlareがホットなのでCloudflare Workersで構築すると最先端のこと分かってる感がでる
BL652ファームウェアのアップデート

現在BL652で開発をしているのですが、
市販の開発ボードでは上手くいくのに自分が作った基板では
うまくいかないという訳の分かららない現象が発生していました。。。

なんやねんこれ。。。

もしかと思いBL652のファームウェアのバージョンを確認したら
結構違っていた。。。

ちなみに市販の開発ボードは、秋月で買った以下の製品。
https://akizukidenshi.com/catalog/g/gK-15567/
この製品のバージョンは「28.11.8.0」

モジュール単体も秋月で購入。
https://akizukidenshi.com/catalog/g/gM-14448/
このバージョンは、「28.6.1.2」

この違いによって動作しない文法とかがありました。。。
変なところで時間くったわ。。。

ということで今回はBL652のファームウェアをアップデートしてみます。

## 1、ファームウェアのダウンロード
以下のサイトから最新版のファームウェアをダウンロード。
https://www.lairdconnect.com/wireless-modules/bluetooth-modules/bluetooth-5-modules/bl652-series-bluetooth-v5-nfc-module

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/802b3dd0-a64a-2335-add4-83500b4b5758.png)
現時点では「28.11.8.0」が最新でした。

ファイルをダウンロード後、zipを解凍して、BL65xUartFwUpgrade.exeを実行。
詳細は以下
ITSE01052_12_BL652_Firmware_For_Upgrade_v28_11_8_0_r1\ITSE01052_12_BL652_Firmware_For_Upgrade_v28_11_8_0_r1\Firmware\BL65xUartFwUpgrade.exe

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/2914594f-5751-5036-ec31-cce32aab4a09.png)
OKボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/d958517f-d592-eefa-817c-9448dd921582.png)

モジュールとPCをUSBケーブルで接続して、COMを選択し、OKボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/7bf064cd-ff6b-29ba-a592-be830004af40.png)

Proceedをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/35cc069e-79b0-a4c8-b8d3-0d7248d43664.png)

これでアップデートは完了です。
最後にUwTerminalX.exeで「AT I 3」のコマンドを打てばバージョンを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/5567b13d-8ccb-cdcd-7205-5f35edfeeab9.png)


今回はBL652ファームウェアのアップデートを行いました。

BL652は、安価でかなり省電力なモジュールです。
電池駆動の製品を作りたい方にはぴったりのモジュールになっておりますので、
今後開発を依頼した方はお気軽にご連絡ください。
擬似言語プログラム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/e9370e37-0c29-5f5a-ead2-c83f48f28722.png)
１：for命令
　forは、繰り返す回数が定まっている場合によく使われます。下記の形式で記述します。制御記述に従って、処理１を繰り返し実行します。制御記述の部分には繰り返しの回数などを書きます。

「forの記述形式」
for（制御記述）
 処理１
endfor

プログラム６は、forを利用したプログラムの例です。
for（i　を　１から１０まで１ずつ増やす）
iを表示する
endfor

プログラム６では、i = 1,2‥１０と変化させながら、「iを表示する」処理を繰り返し実行します。すなわち、「iを表示する」処理は、10回繰り返されます。繰り返す様子は次のようになります。

・i=１の時、「iを表示する」によって、１を表示する
・i=2の時、「iを表示する」によって、２を表示する
・i=3の時、「iを表示する」によって、３を表示する

・i=10の時、「iを表示する」によって、１０を表示する

最終的に、画面上には、１〜10までの数値が表示されます。なお、制御記述で使われている変数iのような変数をループ変数と呼ぶこともあります。
Angular + Docker + Visual Studio Code + WSL開発環境構築

最終的な実装結果は[こちら](https://github.com/shi-tak/angular_docker)。

## 事前準備

### やること

1. WSLのインストール[^wsl]
1. Visual Studio Code (VS Code)のインストール[^vscode]
1. VS Codeの拡張機能のインストール
    - Remote Development[^remotedev]
1. Dockerエンジンのインストール[^docker]

[^wsl]: [WSL公式ページ](https://learn.microsoft.com/ja-jp/windows/wsl/install)
[^vscode]: [Visual Studio Code 公式ページ](https://code.visualstudio.com/)
[^remotedev]: [Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
[^docker]: [Dockerエンジンのインストール](https://docs.docker.com/engine/install/ubuntu/)

### チェックリスト

- [ ] WSLの起動: ターミナルで`wsl -v`を実行しWSLのバージョンが取得できる。
- [ ] VS Codeの起動: インストールしたVS Codeが起動できる。 
- [ ] VS Code拡張機能の導入: VS CodeでCTRL+SHIFT+Xを打ち，表示された拡張機能一覧にRemote Developmentがある。
- [ ] Dockerの起動: ターミナルで`docker run hello-world`を実行し，「Hello from Docker!」が表示される。

## Dockerコンテナの準備 

### やること

新しいプロジェクトのディレクトリを作成

```sh
mkdir /path/to/new_project
cd /path/to/new_project
```
Dockerfileとdocker-compose.ymlの作成

```:ディレクトリ構成
.
├── Dockerfile
└── docker-compose.yaml
```

```dockerfile:Dockerfile
FROM node:latest

RUN mkdir /usr/local/app
WORKDIR /usr/local/app

RUN rm -rf node_module
RUN npm install -g @angular/cli
```

```yaml:docker-compose.yaml
services:
  web:
    build:
      context: .
    ports:
      - 4200:4200
    volumes:
      - .:/usr/local/app
    stdin_open: true
    tty: true
```
### チェックポイント

- [ ] Dockerfile: `docker build .`でDockerイメージが作成される。
- [ ] docker-compose.yaml: `docker compose up`でコンテナが起動する。
- [ ] Angular CLI: `docker compose run --rm web ng version`でAngular CLIのバージョン情報が出力される。

## Angularプロジェクトの作成

### やること

プロジェクトの新規作成

```sh
docker compose up -d
docker compose exec web ng new my-app --directory .
```

### チェックポイント

- [ ] `docker compose exec web ng serve  --host 0.0.0.0`を実行した後，ブラウザで http://localhost:4200 にアクセスしてAngularの初期画面が表示される。
STM32F303K8のSPIで遊ぶ


目的
遊ぶ

![o_cop770.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e89d6d2b-5524-d9db-0a06-434add4def87.jpeg)


```c++


#include <SPI.h>


#define DW    digitalWrite

//#define s60() for(ii=0;ii<60;ii++)delay(1000);
#define s60() delay(1000);

void setup() {
  
  int ii; //ループカウンター
  
  // SPIの初期化
  SPI.begin(); // 11 12 13
  DW(SS, LOW); // 10
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV8);  // 2Mhz
  
  //0
  SPI.transfer(0x00);DW(SS,HIGH);DW(SS,LOW);
  SPI.transfer(0x00);DW(SS,HIGH);DW(SS,LOW);
  s60();
  
  //1
  SPI.transfer(0x00);DW(SS,HIGH);DW(SS,LOW);
  SPI.transfer(0x55);DW(SS,HIGH);DW(SS,LOW);
  s60();
  
  //2
  SPI.transfer(0x00);DW(SS,HIGH);DW(SS,LOW);
  SPI.transfer(0xaa);DW(SS,HIGH);DW(SS,LOW);
  s60();
  
  //3
  SPI.transfer(0x00);DW(SS,HIGH);DW(SS,LOW);
  SPI.transfer(0xff);DW(SS,HIGH);DW(SS,LOW);
  
} //setup

void loop() {
} //loop




```
AtCoder Beginners Selection

今日はABSとやらに挑んでます。
めっちゃ簡単な問題から徐々にレベルアップしていくやつですね。
途中からしんどくなってくるやつ。

一番簡単なﾔﾂ。というか、答え問題文の下に書いてあるし＾＾；；；

https://atcoder.jp/contests/abs/tasks/practice_1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/1c4a316f-ced2-374e-a8c4-de99197bd0ee.png)

```python
a=int(input())
b,c=map(int,input().split())
s=input()

print(a+b+c,s)
```


2番目。今日覚えたif文短くするやつを使ってみる。

https://atcoder.jp/contests/abs/tasks/abc086_a

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/31a68c6e-bd4b-3503-842c-c7a80ef9cf65.png)

```python
a,b=map(int,input().split())
print('Even') if a*b%2==0 else print('Odd')
```

3番目。いつも思う。「すぬけ君」ってどなた・・・。

https://atcoder.jp/contests/abs/tasks/abc081_a

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/cda1c141-c211-9165-115d-49570bfd5424.png)

この問題は文字列sの中に含まれる「1」の数を数えて出力しました。
```python
s=input()
print(s.count('1'))
```

4番目。ぐぬぬ。難しくなってきた。

https://atcoder.jp/contests/abs/tasks/abc081_b

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/02018f8a-d322-d606-565c-569555bd94f6.png)


```python
n=int(input())
a_lst=list(map(int,input().split()))    #入力をリストする

ck=0
ans=0

while ck==0:    #ckが0の間（偶数）はループさせる
    for a in a_lst: #リストの要素を順番にaに入れる
        if a%2!=0:  #aが偶数じゃなかったら
            ck=1    #ckを1（奇数）に変えて
            break   #forから抜ける
    if ck==0:   #ckが0（偶数）だったら
        a_lst=list(map(lambda x:x/2,a_lst)) #リストの要素を全部2で割る
        ans+=1  #操作をカウントアップ
print(ans)
```

5問目。小学生の問題か？と思ったら、苦戦した:dark_sunglasses:
全探索とか時間が・・・と思ったけど、他のいい答えが思い浮かばなかった。
所詮50^3なので時間はそれほどかからないのか。
そのあたりの感覚値がまだわからないんですよね。

https://atcoder.jp/contests/abs/tasks/abc087_b

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/f1367314-983e-035c-f844-8cfa598187e0.png)


```python
a=int(input())
b=int(input())
c=int(input())
x=int(input())
ans=0

# 全探索させる
for A in range(a+1):    #500円玉の数だけループ
    for B in range(b+1):    #100円玉の数だけループ
        for C in range(c+1):    #50円玉の数だけループ
            gokei=A*500+B*100+C*50  #合計額を計算
            if gokei==x:    #合計額がちょうどx円だったら
                ans+=1      #カウントアップ
print(ans) 
```

6問目。生意気にも自作関数などを作ってみた。
ちまちまfor文を書いていたのだけど、意味わからなくなってきたので、
各桁の総和を求めるところを切り取ったら、すんなりいった。
°˖☆◝(⁰▿⁰)◜☆˖°

https://atcoder.jp/contests/abs/tasks/abc083_b

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556392/5549764d-f916-9746-c310-3667cc7583fd.png)

```python
#引数の各桁の総和を求める関数
def wa(suti):
    result=0
    for x in str(suti): #数値を文字列にして1桁ずつ取得
        result+=int(x)  #1桁ずつ足す
    return result       #足しあげたものを返す
    
n,a,b=map(int,input().split())
#整数1～nまでの間に各桁の総和がa以上b以下となる数値をリスト化
list=[i for i in range(1,n+1) if a<=wa(i)<=b]
#リストを全部足したものを出力
print(sum(list))
```

疲れたので、今日はここまで！( ´Д｀)ﾉ~ﾊﾞｲﾊﾞｲ
jQueryが要らなくなった背景メモ

- querySelectorがでてきた
    - これで$が要らなくなる
- NodeListにforEachできるようになった
    - これが結構大きい
    - querySelectorAllが返すNodeListがforEachできなくて苦労をした時代もあった
    - 配列にキャストが必要だったが直接forEachできるようになった
- fetchでAjaxは事足りるようになった
    - これは結構最近
    - XHRが要らない
    - ただし今でも大半のサイトはXHRとfetchが混在している
    - fetchの戻り値がPromiseなので縦に書きやすい
未経験エンジニアからの転職（Wantedly編）

今回は、エンジニアになる際に使用していたWantedlyについて、記事を書いていきたいと思います！
「企業選ぶ際に自社開発に行きたいけど、他にもSESや受託などがあってその見極め方がわからない」といった声をもとに執筆したものとなっております。
僕自身、転職する際はキャリア設計的に自社開発がメインだったので、それ以外の会社の選考はなるべく避けるようにしていました。元SES営業兼キャリアアドバイザーとしての視点を基に、独自の基準を設けていたので、自分と同じように自社開発などがメインの方は参考になる部分もあるかもしれません！

# 企業の判断基準
・グループ会社であるところ（どんな企業がグループ会社にいるのか必ずチェックしていました）

・Wantedlyの企業紹介の内容が薄いもの
→受託・自社開発系は理念や企業した経緯などが記載されている場合が多く、良いSESの場合は「IT業界の人材不足を変えたい」とか「今はSESで、食い繋いでいますが（一時的な売上を稼ぐため）いずれはプロダクトを作って、〇〇業界などを変えていきたい」などちゃんとした理由が記載されている場合が多いです。

・メンバーの紹介文などがないor企業紹介文などが少ない
→採用にあまり力を入れていないと判断

・Wantedlyの記事のクオリティが低い
→記事に誤字があったり、内容が適当だったり、文章の細部にもこだわれない場合、プロダクトへのこだわりもないのではないか？と思う点があった。

・技術的な記事が少ない
→SESなどの会社は営業さんや広報さんが記事書いてる事が多いので、技術やプロダクトについての記事がない場合は、自分が進みたい方向ではないなと判断し、避けていました。

・メッセージの返答が、短文or定型文すぎる
→とりあえず、すぐに「一度カジュアル面談しませんか？」の文言を言うところは黄色信号（集めた情報により、判断）

・カジュアル面談が面接
→「次の選考に進みませんか？」などの言葉でたら、黄色信号です。カジュアル面談は、選考ではない。一般的に、有名な企業など採用に力を入れているスタートアップなどはレピュテーションリスクなども考慮してると思うので、そこの線引きを明確にしてる場合が多い。

・スカウトメッセージ短文or定型文
→採用したいところは、自分のどこに興味を持ってくれたのか、詳細に書いてくれるので、書いていないところは、好きでもない人にとりあえず「好きです」って言ってる男子みたいなものです。

・X(旧Twitter)のアカウントのチェック（どなたのアカウントでもOK）
→過去に炎上した事があるか、普段のつぶやきはどんなものかなどチェックしてました。

---

ざっくりではありますが、僕の経験が少しでも多くの人の役に立てばいいなと思うので、ぜひ参考にしてみてください🙇‍♂️
Mermaidを使って簡易ECサイトのER図をつくってみる

## はじめに
現在データベース学習中でmermaidを使用し簡易ECサイトのER図を作ってみました。


## エンティティ
今回簡易的なECサイトとして以下のようなエンティティを想定しています。
### ユーザー
- ID
- 名前

### 商品
- ID
- 名前
- カテゴリ
- 値段

### 商品カテゴリ
- ID
- 名前

### 購入商品
- ID
- ユーザーID
- 商品ID
- 購入日


## ER図
エンティティをベースにER図を作成します。
マークダウン形式でER図を作成することができます。
```markdown 
erDiagram
  users ||--o{ user_products : "" 
  products ||--o{ user_products : ""
  products ||--o{ categories : ""
  users {
    bigint id PK
    string name "ユーザー名"
  }

  products {
    bigint id PK
    string name "商品名"
    references category_id FK 
  }

  categories {
    bigint id PK
    string name "カテゴリ名"
  }

  user_products {
    bigint id PK
    references user_id FK 
    references product_id FK 
  }
```
上記のようにマークダウン形式で入力することで、下記のようなER図を生成可能。
```mermaid
erDiagram
  users ||--o{ user_products : ""
  products ||--o{ user_products : ""
  products ||--o{ categories : ""
  users {
    bigint id PK
    string name "ユーザー名"
  }

  products {
    bigint id PK
    string name "商品名"
    references category_id FK 
  }

  categories {
    bigint id PK
    string name "カテゴリ名"
  }

  user_products {
    bigint id PK
    references user_id FK 
    references product_id FK 
  }
```
## まとめ
今回はmermaidでER図を作成してみました。
そのほかの図も作成することができるようなので試してみたいです。


## 参考情報
- mermaid公式サイト

https://www.mermaidchart.com/

- ER図作成参考情報

https://zenn.dev/aldagram_tech/articles/a10166f763d30e
Python 多次元Dictionaryのキー、値の存在確認と値取得をする話。

Exifや動画のプロパティをいじっていると、多次元Dictでキーチェックや値チェックをする必要が出てくる。
RubyやJavascriptのようにdigが使えれば安全にハッシュ検索ができるが、調べた範囲で多次元Dictのキーチェック、値取得を簡単にやる方法が見つからなかったので自分で書いた。
たぶん車輪の再発明。自宅で書いたものを会社で参照するための備忘録でしかない。
こんなバカなことやらなくてもこれでできるよ！とかここをこうすると早くなるよ！とか教えてくださるとありがたいです。

## スクリプト
``` python
def check_key_multilevel_dict(var,*args):
    if len(args) == 1 and isinstance(args[0],list):
        args = args[0]
    if isinstance(var, dict) and len(args) > 0:
        for arg in args:
            if arg in var:
                var = var[arg]
            else:
                return False
        return True

def get_value_multilevel_dict(var,*args):
    if len(args) == 1 and isinstance(args[0],list):
        args = args[0]
    if isinstance(var, dict) and len(args) > 0:
        for arg in args:
            if arg in var:
                var = var[arg]
            else:
                return False
        return var
```
## 使い方
呼び出しは第一引数がDict、第二引数以降がキー名。
キー名は第二引数に配列で与えても第二引数以降に複数記載でもOK。
``` python
target_dict = 
{
    'format': 
    {
        'filename': '/share/public1/photo/2022/2022-04-08/20220408051255.MOV', 
        'format_name': 'mov,mp4,m4a,3gp,3g2,mj2', 
        'format_long_name': 'QuickTime / MOV', 
        'tags': {
            'creation_time': '2022-04-08T05:12:55.000000Z', 
            'com.apple.quicktime.creationdate': '2022-04-08T14:12:54+0900'
        }
    }
}
```
上記のようなdictがあった場合に
```
print(check_key_multilevel_dict(target_dict,['format','tags','creation_time']))
-> True
print(get_value_multilevel_dict(target_dict,['format','tags','creation_time']))
-> '2022-04-08T05:12:55.000000Z'
print(check_key_multilevel_dict(target_dict,['format2','tags2','creation_time2']))
-> False
print(get_value_multilevel_dict(target_dict,['format2','tags2','creation_time2']))
-> False
```
を返す。

`check_key_multilevel_dict` はキーの存在チェックだけなのでTrue/Falseで回答。
`get_value_multilevel_dict` は値をとるので該当キーが存在すれば値を回答する。
wslでelixir その100

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
nxやってみた。
練習問題、やってみた。

# 練習問題
nxだけで、xorを学習して推定せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b7bafb6b-09f7-d470-c877-a6edf61ea718.png)


# サンプルコード

```
defmodule Xor do
  import Nx.Defn

  defn init_random_params do
    key = Nx.Random.key(42)
    {w1, new_key} = Nx.Random.normal(key, 0.0, 0.1, shape: {2, 8}, names: [:input, :layer])
    {b1, new_key} = Nx.Random.normal(new_key, 0.0, 0.1, shape: {8}, names: [:layer])
    {w2, new_key} = Nx.Random.normal(new_key, 0.0, 0.1, shape: {8, 1}, names: [:layer, :output])
    {b2, _new_key} = Nx.Random.normal(new_key, 0.0, 0.1, shape: {1}, names: [:output])
    {w1, b1, w2, b2}
  end

  defn predict({w1, b1, w2, b2}, x) do
    x
    |> Nx.dot(w1)
    |> Nx.add(b1)
    |> Nx.tanh()
    |> Nx.dot(w2)
    |> Nx.add(b2)
    |> Nx.sigmoid()
  end

  defn loss({w1, b1, w2, b2}, x, y) do
    preds = predict({w1, b1, w2, b2}, x)
    Nx.mean(Nx.power(y - preds, 2))
  end

  defn update({w1, b1, w2, b2} = params, x, y, step) do
    {grad_w1, grad_b1, grad_w2, grad_b2} = grad(params, &loss(&1, x, y))
    {w1 - grad_w1 * step, b1 - grad_b1 * step, w2 - grad_w2 * step, b2 - grad_b2 * step}
  end

  def train(params, x, y) do
    for i <- 0..31, reduce: params do
      acc ->
        update(acc, x[i], y[i], 0.1)
    end    
  end
end

z0 = for _ <- 0..31, do: Enum.random(0..1)
z1 = for _ <- 0..31, do: Enum.random(0..1)
x0 = Nx.tensor(z0)
x1 = Nx.tensor(z1)
y = Nx.logical_xor(x0, x1)
x = Nx.concatenate([Nx.reshape(x0, {32, 1}), Nx.reshape(x1, {32, 1})], axis: 1)

params = Xor.init_random_params()
Xor.loss(params, x[0], y[0])
|> IO.inspect()
params = for i <- 0..310, reduce: params do
   acc ->
      for i <- 0..31, reduce: acc do
        bcc ->
          Xor.update(bcc, x[i], y[i], 0.1)
      end 
end
Xor.loss(params, x[0], y[0])
|> IO.inspect()
IO.puts("0 1")
Xor.predict(params, Nx.tensor([0, 1]))
|> IO.inspect()
IO.puts("0 0")
Xor.predict(params, Nx.tensor([0, 0]))
|> IO.inspect()
IO.puts("1 1")
Xor.predict(params, Nx.tensor([1, 1]))
|> IO.inspect()
IO.puts("1 0")
Xor.predict(params, Nx.tensor([1, 0]))
|> IO.inspect()

```

# 実行結果


```
warning: variable "i" is unused (if the variable is not meant to be used, prefix it with an underscore)
  elixir/nx.livemd#cell:47fqo64rcwq6xj5l4abtmv4qkodbwts5:51

#Nx.Tensor<
  f32
  0.2594543695449829
>
#Nx.Tensor<
  f32
  7.133321487344801e-4
>
0 1
#Nx.Tensor<
  f32[output: 1]
  [0.9460618495941162]
>
0 0
#Nx.Tensor<
  f32[output: 1]
  [0.02670827880501747]
>
1 1
#Nx.Tensor<
  f32[output: 1]
  [0.03551710769534111]
>
1 0
#Nx.Tensor<
  f32[output: 1]
  [0.9710957407951355]
>
```

以上。
一分で読める小ネタ

この記事は [一分で読める小ネタのカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/raki) の１日目

# はじめに

- 初日なのでこのカレンダーを書くことについての説明など
- 正直なところアドカレに強いモチベーションはありません
- 言語化してみたらやたら言い訳がましくなったし、うまく伝わらないのも嫌だし、そもそも誰もそんなことに興味ないと思うので、なんやかやあって簡単に完走することにした、とだけ
- どうしてもモチベーションに興味があるぜって奇特な人がいたら飲みにでも誘ってください（行けたら行く
- 文才もなく、技術力も平凡な、経験だけが長い（30年やってるしね）IT系フリーランスです
- 手持ちの小ネタを共有することで、いつか誰かの役に立ったらいいな、くらいのノリでやっています

# 各記事について

- １記事１分で読めるくらいの分量を目指しています
- アドカレの時期は読みたい記事が他にたくさんあるだろうし、読まれなくてもくやしくないモン！みたいなテイです
- 対象読者は未経験、初心者、初級者、中級者までくらいです
- 実際のところ、業界参入を目指してる大学生の娘と、友人の息子、エンジニアとしての成長に停滞を感じている同僚氏たちに、何か伝えられればってのが大きい、はず
- こういうのがあるんだ、を知ってもらうきっかけみたいなものなので、既出のネタばかりです
- インストールとか環境差については説明書かないので、各自の環境にあわせて調べるなり読み替えるなりしてください
- どちらかといえば、知ってもらって、各自調べてもらって（ここが大事）、試してもらって、なんとなくわかった、になるといいなと思っています
- 特定の技術やスキルを深掘りして追いかけたいとか、一人前になりたい、みたいなののもっと手前にあると思ってもらえれば
- 広く浅く軽く、いろいろ知るだけ知っておけば、いざやる時に進＠ゼミで見た！になるんだよと
- 例えるなら、異世界転生ラノベで屋台のおっさんから通貨価値を教えてもらうとか、偶然知り合った異性から魔法属性について教えてもらう説明パートとか、そんな感じのあるある

# 意見募集

- マサカリでもなんでもウェルカムです
- 特に異なる意見、方法論、改善等々、変化のあるコメントを歓迎します
- 記事を見直した時、後から誰かが見た時に、多角的にとらえられるような建設的な内容が望ましいです
- そういう建設的な意見交換ができる人とお知り合いになりたい的な

# 目次

公開した記事はここでもまとめようかなと（@todo）
Homcloud自分用メモ１

HomCloudチュートリアルの内容の自分用メモです。
# pdgmファイルの見方
ファイル読み込み
`pdlist = hc.PDList("pointcloud.pdgm")`

:::note info
pdgmファイルは、0次から2次までのすべての次数のパーシステント図を保持している。
:::

1次のパーシステント図だけ書き出す
`pd1 = pdlist.dth_diagram(1)`

ヒストグラムを構築し、パーシステント図をプロットする。
　histogramメソッド　→　ヒストグラムの構築
　plot →　それをプロット

`pd1.histogram().plot()`

:::note info
HomCloudの軸の単位は$Å^2$である。これは、半径の2乗である。

％これをやめたいとき
→PD図を,`hc.PDList.from_alpha_filtration`で計算するときに、`no_squared=True`という引数を付けると、半径パラメータそのものがX軸、Y軸に現れる。
:::

ヒストグラムの解像度の変更
`histogram` メソッドの`x_bins`引数（第2引数）を指定する。
デフォルトでは128x128
`pd1.histogram((0, 0.01), 256).plot(colorbar={"type":"log"})`

保存
matplotlib.pyplot.savefigで保存することができる。
`pd1.histogram((0, 0.01), 256).plot(colorbar={"type": "log"})
plt.savefig("pointcloud-pd1.png")`

# 数値データの読み出し
`pd1.births`
`pd1.deaths`
２つの差を見ることで、lifetimeが計算できる。
`pd1.deaths - pd1.births`

lifetimeのヒストグラム
`plt.hist(pd1.deaths - pd1.births, bins=100);` 

:::note info
行末の`;`は、plt.histの返り値を無視するためのトリック
:::

# 逆解析
PD図の個々の点を、リング・空隙構造と対応させる

HomCloud逆解析ツール
・Birth/Death simplices
・Optimal Volume
・Stable Volume

ここではstable volumeを使う

例：0.0025,0.008)付近にあるbirth-death pairのstable volumeを調べる
pd.nearest_pair_to で (0.0025, 0.008) に一番近い birth-death pair を検索
`pair = pd1.nearest_pair_to(0.0025, 0.008)`

Pair クラスのオブジェクトで、birth timeやdeath timeといった情報を保持している。
`pair`
`pair.lifetime()`

以下のようにすると stable volume が計算できる
`stable_volume = pair.stable_volume(0.00005)`

boundary_points メソッドで、対応するリング構造に含まれる点の座標が得られる。
`stable_volume.boundary_points()`

このstable volumeを3次元可視化する
`pl = pv.Plotter()
pl.add_mesh(stable_volume.to_pyvista_boundary_mesh())
pl.show()`
Slim 5.2.0 で再び sass: が使えるようになった

Ruby のテンプレートシステム Slim では，

```slim
doctype html
meta charset="utf-8"
title test sass: in Slim
sass:
  body
    background: orange
h1 Hello
```

のような感じで，`sass:` として Sass コードを埋め込むことができる。

ところが，Sass の処理系として，もはや過去のものとなった `sass` gem や `sassc` gem でなく，イマドキの `sass-embedded` gem を使うと，`sass:` のところでエラーが出る。

このことは，以下の記事の「おまけ」の節に少しだけ詳しく書いた。
[Slim は死なず - Qiita](https://qiita.com/scivola/items/c80ff9da3fda4dcbd519#%E3%81%8A%E3%81%BE%E3%81%91%E7%A7%81%E3%81%8C%E5%9B%B0%E3%81%A3%E3%81%A6%E3%81%84%E3%81%9F%E3%81%AE%E3%81%AF)

これに困っていたのだが，2023 年 11 月 11 日にリリースされた slim バージョン 5.2.0 で sass-embedded に正式に対応し，解決したようだ。

以下のコードで確認できる（5.2.0 の一つ前のバージョンは 5.1.1）。

```rb:Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

gem "slim", "= 5.1.1"
# gem "slim", "= 5.2.0"

gem "sass-embedded"
```

```rb:sample.rb
require "bundler"
Bundler.require

slim = Slim::Template.new{<<~SLIM}
  doctype html
  meta charset="utf-8"
  title test sass: in Slim
  sass:
    body
      background: orange
  h1 Hello
SLIM

puts slim.render
```

Gemfile でバージョンを 5.1.1 にすると，エラー

```
unknown keyword: :cache (ArgumentError)
```

が出る。
バージョンを 5.2.0 にすると，期待どおり

```html
<!DOCTYPE html><meta charset="utf-8" /><title>test sass: in Slim</title><style>body{background:orange}</style><h1>Hello</h1>
```

が出力される。

ばんざーい！　関係者の方々，ありがとう〜！

ただ，[CHANGES](https://github.com/slim-template/slim/blob/main/CHANGES) を見ても

```md
5.2.0 (2023-11-11)

  * Fix logic less bug - #783
  * Support Rails 7.1 - #936
  * Fix splat arguments on Rails 7.1 - #942
```

としか書いてなくて，本件に言及が無い。うーむ？　まあ直ったからいいや。
NuxtBridge以外の方法で安全に移行を検討する

この記事に以下2点先に申します。
- NuxtBridgeで安全に移行できる方もいらっしゃると思います。
- NuxtBridgeを一切批判するつもりはありません。

# 目次
1. 背景
2. 代替方法
3. テストについて
4. その他参考
5. 最後に

# 1. 背景
業務でNuxtBridgeを使って移行を作業中でしたが苦戦してました。

NuxtBridgeで以下の点で苦戦してました。
- [nuxt.config](https://nuxt.com/docs/api/nuxt-config)の設定でbridgeだと設定できないプロパティがいくつかあった
    - 例）styleResources
- element-uiでエラー(Uncaught TypeError: Cannot read properties of undefined (reading '$isServer'))が出た為
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/a8293be4-b0a8-a7c9-f9ae-a9c23806ff38.png)
    - _vue2.default.prototype.$isServer
    - Nuxt BridgeとNuxt2.17でvueオブジェクトのプロパティが変わっている？？vue.versionでどっちも2.17.5でした。
    - Nuxt2.17だとエラーにならないです。

また先日こちらのイベントの参加者の方が言うには
vuefesで聞かれた所によるとNuxtBridgeでの移行の成功事例がないらしいです。。

https://peraichi.connpass.com/event/300611/

移行作業は私一人でやるのと、対象のリポジトリは2つあるのでNuxtBridge以外の方法でサクッと行う方が良いと思いました。
時間があればNuxtBridgeで出来るところまでやり切りたかったです。

# 2. 代替方法
## 2.1 一気に移行
- Nuxt2で対応可能な箇所は先に対応した上で、Bridgeは使わずにNuxt3に一気に移行します。
- 弊社としては以下の理由でこちらでも良いのかなと思いました。
    - コンポーネント数が少ない
    - 作業者が一人

## 2.2 部分的に移行
- [iFrameで部分的に移行](https://vuefes.jp/2023/sessions/mew-ton)できるらしいです
こちらについてはまだ理解してないので後日深掘りしたいと思います。

# 3. テストについて
- 移行先のプロジェクトでマニュアルテストに加え、E2Eテストを検討中です。
- E2Eテストは今まで弊社は導入した実績がないので、[playwright](https://playwright.dev/)だったり無料ツールでサンプルで作ろうと思ってます！

# 4. その他参考
- DiscordでNuxtの最新情報やバグ相談について参加、閲覧できます。
  [discordはこちら](https://discord.com/invite/nuxt)
  今後使えそうだなと思ったのは以下の二つのチャンネルです。
  - HELP
      - 困ったこととかを聞けますし、自分と同じことで困ってることを見つけれるかもしれないです。
      - BridgeのHELPチャンネルもありました。
  - LANGUAGES
      - 日本語のチャンネルがあったので気軽に議論、相談できそうです。

# 5. 最後に
- 今回、外部のエンジニアの方に相談したことがきっかけでNuxtBridgeを使わないで移行する方法も検討し直すことができました。
- イベントで相談に乗ってくださったペライチさんのエンジニアを始めとした皆さんに感謝致します。
- またペライチさん主催のイベントや、その他様々なイベントで外部のエンジニアの方と交流し、知見を増やして持ち帰ったり、自分と大多数のエンジニアとのギャップの確認をしたいです。
英字と数字を含めたパスワードを要求するバリデーション

## 英字と数字を含めたパスワードを要求するバリデーション

Ruby on Railsでのパスワード設定時に利用される `validates`メソッドには、パスワードのセキュリティを高めるためのバリデーションを設定する機能があります。特に、`:password`属性のバリデーションにおいて `format` オプションと正規表現の活用が重要です。下記のコードについて解説します。

```ruby
validates :password, format: { with: /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i }
```

このコードは、`:password`属性が特定の要件を満たしているかどうかを検証します。正規表現 `/^A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i` が行うことを要約します。

- `\A`: 文字列の先頭を表す記号。
- `(?=.*?[a-z])`: 少なくとも1つの小文字のアルファベットが含まれていることを要件とします。
- `(?=.*?\d)`: 少なくとも1つの数字が含まれていることを要件とします。
- `[a-z\d]+`: アルファベット（小文字）と数字の組み合わせを検証します。
- `\z`: 文字列の終端を示す記号。
- `i`: 大文字小文字を区別しない、ケースインセンシティブな検証を実行します。

この検証により、パスワードが少なくとも1つの小文字のアルファベットと1つの数字を含んでいるかどうかが確認されます。この強力なパスワードポリシーは、セキュリティを向上させるために設定されています。

この手法は、ユーザーにセキュアなパスワードを設定するよう促し、アプリケーション全体のセキュリティを確保する重要な手段です。
日付選択フォーム`f.date_select`のオプション設定

## 日付選択フォーム`f.date_select`のオプション設定

`f.date_select`はRuby on Railsのフォームヘルパーメソッドの1つで、日付を選択する際に使われます。このメソッドにはさまざまなオプションがあります。ここでは、主要なオプションについて説明します。

### サンプルコード:

```erb
<%= f.date_select(
  :birthday,
  class: 'select-birth',
  id: 'birth-date',
  use_month_numbers: true,
  prompt: '--',
  start_year: 1930,
  end_year: (Time.now.year - 5),
  date_separator: '%s',
  "<p> 年 </p>", "<p> 月 </p>") + "<p> 日 </p>" %>   
```

### オプションの説明:

1. `:birthday`: フォームと紐づけるカラム名
2. `class: 'select-birth'`: CSSクラスを適用しスタイリングを行う
3. `id: 'birth-date'`: 要素に一意の識別子を付与
4. `use_month_numbers: true`: 月を数字で表示（例えば、"1" から "12"）
5. `prompt: '--'`: 初期選択項目として表示する文字列
6. `start_year: 1930`: 年の開始範囲
7. `end_year: (Time.now.year - 5)`: 年の終了範囲
8. `date_separator: '%s'`: 年と月の間に入るセパレータ

これらのオプションを使って、日付選択フォームをカスタマイズできます。フォームのスタイルや表示形式を変更したり、特定の年月日の範囲を指定したりできます。

これにより、柔軟性の高い日付選択フォームを提供でき、ユーザーエクスペリエンスを向上させることができます。
[React] Suspenseをより深く解説

# はじめに
ReactにはSuspenseという機能がありますが、主にデータを取得してる間に、ローディング中のアイコンを表示するなどの使い方をします。
なので、Suspenseはローディング中の画面表示を実装するだけの機能と思われがちですが、そうではなく、もっと奥深い機能になっています。
今回はそのSupenseについて解説していきます。

# Suspenseの使い方
Suspenceの一般的な使い方は、以下のようになります。
(ドキュメント参照)

https://react.dev/reference/react/Suspense

```
import { Suspense } from 'react';
import Albums from './Albums.js';

export default function ArtistPage({ artist }) {
  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<Loading />}>
        <Albums artistId={artist.id} />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>🌀 Loading...</h2>;
}

```
このように書くと、データを取得して表示している<Albums>コンポーネント内の処理が完了するまでは、fallbackで指定した<Loading>コンポーネントが表示されます。

# 重要になるキーワード
Suspenseを理解するうえで、重要になるキーワードは以下の3つです。

**・SSR**
**・Streaming HTML**
**・Selective Hydration**

## SSR
　クライアント側でHTMLを生成するのではなく、サーバー側でHTMLを生成し、クライアント側に返して表示するレンダリング方法です。

## Streaming HTML
　これはSuspenseごとに処理の速度(データの受け取りからの画面表示など)が違う時、処理が終わった要素から表示をしてくれる機能になります。
　例えば、同じ画面に2つのSuspenseで囲った要素があった場合、今までは、全てのHTMLが生成されるまで、何も画面には表示していませんでした。
　しかし、Streaming HTMLの機能によって、1つの処理が終わり、もう1つの処理が完成していない場合は、処理が終わっている要素を先に表示してくれます。

## Selective Hydration
　Selective Hydrationというのは、ユーザーの興味のある箇所を優先して、HTMLの構築をする機能です。
　例えば、ユーザーが下の要素(本来であれば、後に読み込まれるはずの要素)に興味があり、ローディング要素が表示されている下の要素をクリックした場合、Reactが優先度を判断し、下の要素を優先的に読み込み、先に表示させます。
　それにより、ユーザー体験を向上させることができるということになります。

# まとめ
**☑データ取得中にローディングを宣言的に表示できるようになった。**

**☑Suspense単位でストリーミングされたり、ハイドレーションされるので、「どの単位をSuspenseで囲うか」という設計が重要になってくる。**

**☑今後、Reactはコンポーネント毎にSSRできるようになるので、Suspenseへの理解は必須になる。**

**☑Suspenseの設計を上手くすれば、より良いUXを提供することができるようになる。**

# 最後に
他にも色々な記事を書いているので、よければ読んでいってください、、、

https://qiita.com/hukuryo/items/97797a91d7e2ee0bcabc

https://qiita.com/hukuryo/items/265c676d17fe21e75242

https://qiita.com/hukuryo/items/ebeb26823f944f143b11
207. Course Schedule

### 問題文
prerequisites[i] = [a, b] 
a : second
b : first

### 例
```
Input:
  numCourses = 2
  prerequisites = [[1,0],[0,1]]
  
Output:
  false
  
Explanation:
  There are a total of 2 courses to take. 
  To take course 1 you should have finished course 0,
  and to take course 0 you should also have finished course 1.
  So it is impossible.
```

### CODE
```python
def canFinish(numCourses, prerequisites):

    # requirement：履修順番
    requirement = collections.defaultdict(list)
    for second, first in prerequisites:
        requirement[first].append(second)

    course_state = ['not-ckecked' for _ in range(numCourses)]

    # サイクルになっている場合　： True
    # サイクルになっていない場合： False
    def hasCycle(course_index):
        if course_state[course_index] == 'checking':
            return True

        if course_state[course_index] == 'no-problem':
            return False

        course_state[course_index] = 'checking'

        for next_course_index in requirement[course_index]:
            if hasCycle(next_course_index):
                return True
            
        course_state[course_index] = 'no-problem'
        return False

    for course_index in range(numCourses):
        if hasCycle(course_index):
            return False
            
    return True
```
ONUのランプの意味を調べてみた

# はじめに
<!-- 発端や概要を記載 -->
引越しに伴ってインターネット回線を更改するにあたり、ONUのことを何も知らなかったので調べてみました。
この記事は未完成のため、追記・修正する場合があります。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [そもそもONUとは？](#Chapter1)
1. [それぞれのランプの意味](#Chapter2)
1. [おわりに](#Chapter3)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# そもそもONUとは？
NTT東日本さんのサイトからのコピペとはなりますが、下記のような意味となります。

> ONUは、光回線を使用する際、光ファイバーの信号をデジタルに変換する機器で、「光回線終端装置」という意味です。

一般的な家庭用機器を使用している場合、光信号→電気信号に変換する必要があり、この役割を担っているのがONUとなります。
（逸般の誤家庭の場合はその限りではないかと思いますが、、）

<a id="#Chapter2"></a>
# それぞれのランプの意味
ここからが本題です。
まずそれぞれのランプの意味ですが

| 表示 | 意味 |
| ---- | ---- |
| 認証 | NTTさんの[技術ジャーナル](https://journal.ntt.co.jp/backnumber2/0511/files/jn200511059.pdf)によるとPONにはONU認証の機能があるとのことで、この認証のことを指していると思われます。PONについて詳しく知りたい方は[こちら](https://journal.ntt.co.jp/backnumber2/0508/files/jn200508071.pdf)の記事tに説明があります。<br> ※誤りである場合は修正いただけますと幸いです。 |
| UNI | User Network Interfaceの略で、ONUと配下の機器（ルータなど）との接続状態を表示します。 |
| 光回線 | 光回線との接続状態を表示します。 |
| 電源 | ONUの電源状態を表示します。 |

となります。


またそれぞれのランプの状態について記載します。
家で自宅で使用しているONUの説明書を参考にしています。

| 表示 | 状態 | 内容 | 備考 |
| ---- | ---- | ---- | ---- |
| 認証 | 緑点灯 | 正常運用状態 | - |
| | 消灯 | 装置運用準備中または故障発生状態 | 問い合わせ |
| UNI | 緑点灯 | 1000BASE-T, 1000BASE-TX, 10BASE-Tでリンク確立状態 | 通信中は点滅 | 
| | 消灯 | 端末機器とのリンクが確立されていない状態 | 端末機器を接続する | 
| 光回線 | 緑点灯 | 正常運用状態 | - |
| | 橙点灯 | 装置運用準備中または故障発生状態 | 問い合わせ |
| | 橙点滅 | ソフトウェアダウンロード中 | 電源ランプ 赤点滅→緑点灯まで待機 |
| 電源 | 緑点灯 | 正常運用状態 | - |
| | 消灯 | 電源が入っていない状態 | - | 
| | 赤点滅 | ソフトウェアダウンロード完了 | 自動再起動まで待機 <br> もしくは装置を手動で再起動 <br> 再起動後に緑点灯 |
| | 赤点灯 | 装置故障状態 | 問い合わせ |

<a id="#Chapter3"></a>
# おわりに
今回はONUについて調べてみました。
いつも使っている回線に関することでもなかなか知る機会がなかったので、この機会に調べられてよかったです。

<a id="#reference"></a>
# 参考文献
- [光回線のルーターとは？ONU・モデムとの違いや接続・設定方法、繋がらないときの対処法も解説](https://business.ntt-east.co.jp/service/flets-hikari/column/opticalline_router/index.html#id_01_1)
- [技術講座【GE-PON技術】第1回 PONとは](https://journal.ntt.co.jp/backnumber2/0508/files/jn200508071.pdf)
- [技術講座【GE-PON技術】第4回 GE-PONシステム技術](https://journal.ntt.co.jp/backnumber2/0511/files/jn200511059.pdf)
Flutter案件半年ぐらいの微経験者が内部テスト用AABのアップロードに手こずってる話

どーもこんにちは。
実務経験半年程度で2案件を掛け持ちすることになり、奮闘している中で直面した課題の備忘録として書き残していきます。

今回のお題はこちら。
## Flutter開発時の内部テストをgoogle play console で配布しようとした時の詰まったポイント

そもそも筆者は、現在で実務経験1年ちょっとです。
案件参画時は
- 実務経験半年程度
- Flutter未経験
- モバイルアプリ開発自体未経験

という状況だったので参画前にFlutter学習から始める、という感じでした。
そんなこんなで先輩エンジニアに助けてもらいながら実装を進めていき、ついにテスト版リリースのためのアップロード作業を行うことになりました。

その時点での筆者の内部テストへの認識
- とりあえずapk?的ななにかを使ってテストする感じ？

のみでした。やばすぎた。

で、実際に内部テストに必要な準備と手順
- google play console へのアカウント登録
- テストユーザーのメールアドレス登録
- リリース登録
- 開発アプリのソースコードアップロード(ここで詰まっている)

以上です。たぶん。
今回の話は
### 開発アプリのソースコードアップロード(ここで詰まっている)
これについてです。
詰まったポイントとしては
- aabファイル出力
- aabにflavorが反映されない

この2点が主な詰まりポイントでした。
1ポチ目は、
- バンドルツールの使用
- aabファイル作成コマンド

この2つでなんとかなりました。

2ポチ目が未だに詰まっているポイントです。
```dart
java -jar bundletool-all-0.7.1.jar build-apks \
--bundle=app.aab --output=app.apks \
--ks=keystore.jks --ks-pass=pass:PASSWORD --ks-key-alias=ALIAS \
--key-pass=pass:PASSWORD
```
こちらのコマンドをコマンドラインで実行するとaabが吐き出される。
が、ここで吐き出されるaabにはアンドロイドスタジオで設定しているflavorの設定が反映されておらず、スプラッシュでアプリが止まるという、、、
暫定的にflavorを返す処理を修正し、テストアプリが動くようになったものの根本的な解決には至っておらず、もしなにかご存じの方がいれば是非コメントお願いします。

またFlutter自体の知識も乏しいため、記事での発言で誤りがあればご指摘いただけると幸いです。

最後までご覧いただきありがとうございました。
GTPs BuilderでDatabricks Q&A botを作ってみる

どんどん凄いことになってますね。

https://chat-gpt.school/first-openai-devday/#index_id18

Builderにアクセスします。

https://chat.openai.com/gpts/editor/

**プロンプト**

> Databricksに関するQA botを作成して

**レスポンス**

この辺りは英語で返ってきました。

> **GPT Builder**
> Great! We're going to create a QA bot focused on Databricks. This bot will 
> specialize in answering questions about Databricks, ranging from basic usage to more advanced concepts.
>
> How about we name this GPT "Databricks Helper"? Does this name work for you, or do you have another name in mind?

名前はこれでいいのかと聞かれたので、

> それでいいです。

さらにはアイコンも作ってくれます。心遣い恐れ入ります。

![Screenshot 2023-11-11 at 17.49.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c7d9fbaf-ca0d-815f-7a0f-32d9243a180d.png)

ここからレスポンスが日本語になりました。

> **GPT Builder**
> 素晴らしいです！それでは、Databricks Helperの役割と目標についてもう少し詳しく定めましょう。
>
> Databricks Helperは、Databricksに関するどのような質問に答えることが期待されますか？例えば、基本的な使い方、特定の機能、最適なプラクティス、または高度なデータ分析のテクニックなどについての質問ですか？

**プロンプト**

> はい、マニュアルやブログの情報をベースに詳細な技術的な質問に回答できるようにしてください

挙動の説明があります。

**レスポンス**

> **GPT Builder**
> The behavior for Databricks Helper is now set. It's designed to assist with detailed technical questions about Databricks, providing answers based on ?official manuals and authoritative sources. The bot will maintain a professional tone, focusing on delivering high-quality technical support.
>
> Would you like to test Databricks Helper in the playground? You can try asking it questions like, "How do I optimize a Databricks cluster?" or "Can you explain Delta Lake in Databricks?"
> 
>After testing, feel free to let me know if there are any refinements or changes you'd like to make.

右のペインで問い合わせができるようになりました。すごい、お手軽すぎる。
![Screenshot 2023-11-11 at 17.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f32912ba-634e-00c5-42b0-b8d1ef3651d6.png)

しかし、レスポンスは英語です。
![Screenshot 2023-11-11 at 17.43.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fe0797c1-7ee4-30b3-94a2-704d3693d6f8.png)

ちなみに、**Configure**に切り替えるとアプリの設定ができます。

**Create**に戻って、日本語での回答を行うように指示します。

**プロンプト**

> 日本語で回答するようにしてください

これで画面も日本語に更新されました。すごい。
![Screenshot 2023-11-11 at 17.45.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4eece610-9087-94d8-be41-39e2f4a097b4.png)

レスポンスも日本語です。
![Screenshot 2023-11-11 at 17.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c1f7a94e-9fbb-288b-1a75-a6c9a6f0c569.png)

さらにLLMの活用形態の領域が広がった感がします。すごい(すごいしか言ってない)。

これなら、RAG(Retrieval Augumented Generation)いらないんじゃないかと言う論調もあるようですが、私はまだそこまでとは思ってないです。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)