OmniAICreator/Qiita-1.07M huggingface dataset:
LovyanGFX でコンパイルエラー Sketch too big に対処

「LovyanGFXで画面描画(7):内蔵日本語フォント」https://qiita.com/nanbuwks/items/04ea0538c52b620de656
では LovyanGFX で使用できるフォントを紹介しましたが、調子に乗って lgfxJapanGothicP_32 とか lgfxJapanMincho_40 とか使いまくっていると以下のようなエラーが出ます。


```
Arduino：1.8.19 (Linux), ボード："ESP32 Dev Module, Disabled, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, Core 1, Core 1, None, Disabled"

最大1310720バイトのフラッシュメモリのうち、スケッチが1511633バイト（115%）を使っています。
text section exceeds available space in board
最大327680バイトのRAMのうち、グローバル変数が48840バイト（14%）を使っていて、ローカル変数で278840バイト使うことができます。
Sketch too big; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing it.
ボードESP32 Dev Moduleに対するコンパイル時にエラーが発生しました。


「ファイル」メニューの「環境設定」から
「より詳細な情報を表示する：コンパイル」を有効にすると
より詳しい情報が表示されます。
```

その時は アプリケーションに割り当てるフラッシュのサイズを大きくすると解決します。



「ツール」-「Partition Scheme」にて「Huge App(3MB No OTA/1MB SPIFFS)」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a996c69e-0776-7782-ade1-f4ae8dc4afc6.png)

また、ESP32 のフラッシュサイズによっては他の選択も可能でしょう。


コンパイルできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/523bc7f2-5358-7467-0cab-146782e1e997.png)
LovyanGFX Version 1系での変更点

# LovyanGFX のバージョン

2022年のアドベントカレンダー
https://qiita.com/advent-calendar/2022/lovyangfx

は Version0.4 系で執筆しましたが、2023の年頭に Version1 系がリリースされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/183a93be-21f1-c486-c5c2-3951c75fd3bd.png)

2024/1/10現在では、Version1.1.12 となっています。

# Version1 系での変更点

新機能やバグフィックス以外で、過去の使い方と異なる点としては以下が不要になったことが挙げられます。

```
#define LGFX_USE_V1

```
この設定は以下の経緯で導入されたものですが、

https://twitter.com/lovyan03/status/1399178745408225280?lang=en

今後は v0 系の動作をする時以外は必要が無くなります。

https://twitter.com/lovyan03/status/1612326194208477184

# 以前のスケッチとの互換性

特に影響はないようですが、検証を進めていきます。
C#でのファイルパスの重複排除（大小文字無視）は、Dictionaryなどのコレクションにやらせると便利

# 概要

Windowsのファイルパスなどで、大文字小文字を無視して文字列比較をしたい場合があります。C#では、単純な比較もできますし、ソートと一致判定を伴うコレクション（HashSet,Dictionaryなど）でもそうした比較を行うことができます。ただし比較方式にはいくつかの選択肢があります。これらについて、意外とちゃんと使えていないコードを見かけるので、小ネタですが記事を書きました。


# 結論

最初に結果だけ言うと、このように書けば、大文字小文字を無視して比較し重複排除するリストができます。これを見て「常識だろ」と思う人も多いと思いますが、意外に「何それ？！」という人もいます。

```csharp
HashSet<string> filePaths = new(StringComparer.OrdinalIgnoreCase);
var add = @"C:\FilePath1"; //追加するファイルパス
filePaths.Add(add);
```


# よく見るコードとその改善

使えていないというのは、.NETがやってくれることを次の例のように自力でやってしまうということです。意外に、次のようなコードはよく見かけます。（そういうコードではLINQも使っていないことが多いですが、この話と無関係なので使うサンプルにします）

## 使えていない例

```csharp
List<string> filePaths = new();
var add = @"C:\FilePath1"; //追加するファイルパス
if (filePaths.All(d => d.ToUpper() != add.ToUpper()))
{
    filePaths.Add(add);
}
```

大小文字無視の比較のためにToUpper()を使い、既存のListに含まれていない場合はListへ追加しています。

もちろんこのコードでも動くとは思いますが、次のように.NETにやってもらった方が保守性も、おそらくは性能も上がります。

## 改善1：大小文字無視の比較はEqualsメソッドで

ToUpper()で頑張らなくても、文字列のEqualsメソッドは、大小文字無視の比較ができます。

```csharp
List<string> filePaths = new();
var add = @"C:\FilePath1"; //追加するファイルパス
if (filePaths.All(d => d.Equals(add, StringComparison.OrdinalIgnoreCase)))
{
    filePaths.Add(add);
}
```

## 改善2：コレクションの重複は、コレクションに判定させる

重複排除したリストを作りたいなら、HashSetが使えます。HashSetは、コンストラクタに指定することで大小文字無視の比較ができます。

```csharp
HashSet<string> filePaths = new(StringComparer.OrdinalIgnoreCase);
var add = @"C:\FilePath1"; //追加するファイルパス
filePaths.Add(add);
```

### Dictionaryでも使えます

Dictionaryのキーの判定にも同じ方法を使えます。それ以外にもConcurrentDictionary等のソート・一致判定を伴うコレクションなら、おそらく全て使えます。

```csharp
Dictionary<string, int> filePathAndValues = new(StringComparer.OrdinalIgnoreCase);
//追加するファイルパスと値
var addFilePath = @"C:\FilePath1";
int addValue = 1;
filePathAndValues.Add(addFilePath, addValue);
```

# StringComparerの選び方

StringComparerというのが出てきましたが、大小文字無視（IgnoreCase）のものだけでも3種類あります。どれを使ったら良いでしょう。これも割と、書く人によってバラバラだったりします。

Windowsのファイルパスの判定が目的なら、StringComparer.OrdinalIgnoreCaseを使いましょう。大文字小文字の差を無視した上でのシンプルなバイナリ比較なので、ファイルパスのような一致判定には適しています。

悩む人が多かったのか、Learnにまとまっていました。ここでもやはり、ファイルパスなどはOrdinalIgnoreCaseが推奨されています。

[.NET での文字列の比較に関するベスト プラクティス - .NET | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/best-practices-strings#choosing-a-stringcomparison-member-for-your-method-call)


# まとめ

単純なファイルパスの一致判定と重複排除だけの話ですが、ちゃんと.NETのライブラリを使うかどうかによって、コードの見やすさもおそらくは性能もだいぶ変わって来ます。こうしたことの積み重ねが、意外と保守性や性能に効いてくることもあると思うので、知らなかった人はぜひ使ってみてください。知っていた人は、周りに分かっていない人がいたらぜひ教えてあげて欲しいなと思います。
365日を52週に集約する(SPSS Modeler データ加工逆引き1-17)

# 365日を52週に集約する

![スクリーンショット 2023-12-20 15.51.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/09b91657-5f3b-7fac-b332-bba87e7260ed.png)

要約済みの値を曜日按分で日に割り戻す場合には逆引き1-８を参照ください。

## 1.想定される利用目的

・時系列予測モデルの対象とする単位（粒度）の変更
・回帰モデルによる時系列予測作成のための説明変数作成

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/365to52.str

## 3.サンプルストリームの説明

![スクリーンショット 2023-12-20 15.52.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/57a3991c-bc62-fe47-c1aa-9ffbc7ba1343.png)

a.対象データは以下の通りです。

![スクリーンショット 2023-12-20 15.55.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/d1d29b8f-fda8-2e46-3217-2892c30c0faf.png)

#### 週番号を付番

b.[フィールド作成]ノードを編集します。５２週の週番号を取得して年と文字列結合します。

![スクリーンショット 2023-12-20 15.54.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/338cda69-3290-35f9-64c6-97a77ef10e3d.png)

c.[ソート]ノードを編集します。

![スクリーンショット 2023-12-20 15.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/fadcfab0-612a-9bac-ec3a-e1a7e57d5916.png)

[テーブル]を表示します。

![スクリーンショット 2023-12-20 15.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ced7ab3a-8c1f-8318-7999-fb5658956e92.png)

#### 週番号で値を合計

d.[レコード集計]ノードを編集します。

![スクリーンショット 2023-12-20 15.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5778caa6-f5ad-ad43-90b1-1ad2c43d771b.png)

e.[ソート]ノードを編集します。

![スクリーンショット 2023-12-20 15.56.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/95768741-b0f3-4304-0dc3-fce4c9d09fb9.png)

[テーブル]を表示します。

![スクリーンショット 2023-12-20 15.56.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/abe6b359-ce75-a9c8-9605-f4d6be0af594.png)

#### 注意事項

年の文字列との結合を行わないと、多くの年の元旦は前の年の52番に該当し、そのまま利用すると不整合が発生します。

## 4.参考情報

#### 52週の予測値を曜日重みで日毎に割り戻す

https://qiita.com/416nishimaki/items/3f185f90fe184786789b

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
複数行かつ溢れたコンテンツを3点リーダーで表現する

タイトル通りの内容をcssで表現するには下記のように書きます。
行の数は`-webkit-line-clamp`の値で指定できます。

```css
.content {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}
```


## 参考リンク
https://zenn.dev/bicstone/articles/webkit-line-clamp
Refused to Connect Error

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)


+ [Web tab showing "Refused to connect"](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000074VZ2G)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/44a26d89-7643-b088-660f-11bf4710eeaf.png)

:::note
1. In Salesforce Setup, navigate to Session Settings.
2. In the Trusted Domains section, click Add Domain.
3. Enter the following domains in the domain field/

https://*.lightning.force.com
https://*.visual.force.com
https://*.my.salesforce.com

4\. Select Visualforce Pages for iFrame Type.
5\. Click Save.

https://support.leveleleven.com/s/article/Refused-to-Connect-Error
:::
mindの研究 その68 link集

# 概要
mindが、謎なので調べてみた。
linkを、集めてみた。

# Qiita

https://qiita.com/tags/mind

# Wikipedia

https://ja.wikipedia.org/wiki/Mind_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)

# マニュアル
https://www.scripts-lab.co.jp/mind/ver8/doc/

# 配布先
https://www.scripts-lab.co.jp/mind8download/download.html

# サポート掲示板
https://www.scripts-lab.co.jp/support/public/html/mind.cgi?tframe+035+-s+F001

以上。
openframeworksのexample shader

## shader
openframeworksのshader実行結果です。
### 01_simpleColorQuad
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/ca16d79a-4ef9-ce88-03e5-30764c8a64bd.png)

### 02_simpleVertexDisplacement
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/eaf74083-2cdb-6b6f-dadb-79347a630ad4.png)

### 03_simpleShaderInteraction
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/80ee3e56-4d9f-3b6c-f266-ea5ac47ee6a0.png)
### 04_simpleTexturing
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/9b922488-6247-9fc4-d5da-e9e4853fc97f.png)
### 05_alphaMasking
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/9edfa2d6-481b-10f4-ffeb-068a3da6cb4e.png)
### 06_multiTexture
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/c50b98e9-65d2-8f67-be9d-de952d39b14d.png)
### 07_fboAlphaMask
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/882f2f52-6468-6f29-13d0-842a2db3affc.png)
### 08_displacementMap
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/ceb5c810-d4d7-70b7-ed13-adb19b4caa80.png)

### 09_gaussianBlurFilter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/3be3bb3c-64f6-c7d6-cec4-7a204e0b792a.png)
Kaggle with Wandb入門した

![black_cat_cartoon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3605750/90415324-2749-559b-31a7-3f85774f85dc.jpeg)

## 背景
実験管理をマニュアルで行ってきましたが、効率化欲が高まったためWandbの利用を試みることにしました

## 概要
今回はKaggle notebookからの利用を試します
利用ケースは”GBDTのハイパラとCV記録を行いたい”とします。
具体的にはCatboostのハイパラとCV記録を取っていきます。
(LightGBMはwandb_callbackが準備されていることが分かりいろいろ出来そうなのでやるとしたら次回)

## 前提
- Kaggleへの登録/Kaggle notebookが利用できる
- wandBへの登録/APIキーの取得

## 作業
### wandBのインスタンス化/ハイパラ記録

```python
import wandb

params = {
    'loss_function': 'RMSE',
    'eval_metric': 'RMSE',
    'iterations': 1,
    'learning_rate': 0.1,
    'random_seed': 0,
    "early_stopping_rounds": 200,
    "max_depth": 10,
    "subsample": 0.9,
} 

#wandb初期化
run = wandb.init(config = params, project="wandb_test", name="wandb_test_run")
```

configにparamsを辞書型で入れることでハイパラの記録が可能
projectは管理する箱の名前
nameはprojectの中で管理する実験名　こちらは実験するたびに名称変更することになる部分

実行するとAPIキーを求められるため、あらかじめ取得したAPIキーを入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3605750/89ca0fb5-f044-b518-d5b9-963a3b1a2330.png)


### cvごとの結果を記録するテーブル作成

```python
cv_table = wandb.Table(columns=['Fold_%d'%d for d in range(5)])
```

cvごとの結果を記録するためのテーブルを作成
columnsにはテーブルの列をリスト型で定義　今回はn_splits=5を想定

### 実験結果を記録

```python
# scoresはcvごとの結果が入っているリスト型
# 例: [0.7, 0.2, 0.3, 0.4, 0.5]
cv_table.add_data(*scores)

run.log(
    {        
        "cv_table": cv_table
    }
)

run.log({f"oof_score_mean: ": np.mean(scores)})
run.log({f"oof_score_std: ": np.std(scores)})
```

学習後に取得されたscoresをあらかじめ作成したcv_tableにadd_dataメソッドを使って記録
add_dataのにはcv_tableで作成した列の数だけ引数を与える必要があるため、*scoresとしてリストを分解して与えている

### 記録の終了

```python
run.finish()
```

finishメソッドで実験記録の終了

## 記録の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3605750/6ee1ce44-3a4f-cca8-2187-893cb4c25a9c.png)


WandBサイトにアクセスしてログインしてみると、定義したprojectが作成されていて、Runsにnameで指定した実験名で記録がされました

マニュアルで実験管理を行なってた際は面倒でCV毎の記録は取ってなかったですが、これであれば簡単に記録ができて全CVで改善がされているかの確認もできることになるので嬉しい

## まとめ
実験管理を効率化するためにWandB入門をしました。
ディープ系についてよく使われているのは見ていたのですがGBDT系でも使えることがわかり有益でした。
まだまだスイープやアーティファクトなどまだまだ機能が盛り沢山そうなので色々試してみようと思います。

## 参考文献
[5行でカッコいい可視化を「WandB」入門 - Qiita](https://qiita.com/Yu_Mochi/items/4fc283ebc31225d4e106)
[Quickstart | Weights & Biases Documentation](https://docs.wandb.ai/quickstart)
[Starter_Notebook with WandB](https://www.kaggle.com/code/nejumi/starter-notebook-with-wandb)
【ひとくちメモ】Pythonの関数ポインタ

# 概要
Pythonのクラスに関数を登録するときの挙動

# うまく行かない場合
```Python
class Hoge:
    def __init__(self):
        self.func = lambda: None
        self.trigger = self.func

def hello():
    print('hello')

hoge = Hoge()
hoge.func = hello
hoge.trigger() # 出力なし
```
`hoge.trigger()`をすると`hello`が実行されてほしいが、実際には何も出力されない

# うまくいく場合
```Python
class Hoge:
    def __init__(self):
        self.func = lambda: None
        self.trigger = lambda: self.func() # 変更箇所

def hello():
    print('hello')

hoge = Hoge()
hoge.func = hello
hoge.trigger() # 出力: hello
```

# 解説
`self.trigger = self.func`だと関数ポインタが渡されるのであとから`self.func`を変更しても最初に指定した`lambda: None`が呼ばれ続ける
Pythonで「文字列、タプル、rangeなどから集合を作成する」の動作を確認してみた

# 概要

Pythonで「文字列、タプル、rangeなどから集合を作成する」の動作を確認してみました。
以下のファイルを作成しました。

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

# 実装

以下のファイルを作成しました。
```sample.py
myset = set("Hello Python")
print(myset)

myfrozenset = frozenset("Hello Python")
print(myfrozenset)

mylist = ["A", "B", "C"]
myset = set(mylist)
print(myset)

myfrozenset = frozenset(mylist)
print(myfrozenset)

mytuple = ("A", "B", "C")
myset = set(mytuple)
print(myset)

myfrozenset = frozenset(mytuple)
print(myfrozenset)

myset = set(range(10))
print(myset)

myfrozenset = frozenset(range(10))
print(myfrozenset)
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
{'e', 'y', 'l', 't', 'P', 'H', 'o', 'n', ' ', 'h'}
frozenset({'e', 'y', 'l', 't', 'P', 'H', 'o', 'n', ' ', 'h'})
{'A', 'B', 'C'}
frozenset({'A', 'B', 'C'})
{'A', 'B', 'C'}
frozenset({'A', 'B', 'C'})
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
```

# まとめ

何かの役に立てばと。
パワポで動画作成メモ

# パワポ使用バージョン
Microsoft PowerPoint 2019 (32ビット)
Microsoft Office Professional Plus 2019

# 動画作成で使う [記録] の表示確認
1. パワポの上部メニュータブに [記録] があることを確認
    - あれば気にしないでOK
    - ない場合は以降の手順で [記録] が表示されるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/f58b407c-c751-f73d-11c5-65bd1b416e5b.png)

1. [ファイル] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/4d9d62de-0676-2d0a-d31f-e9b6407ffa23.png)

1. [オプション] をクリック
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/b777d21d-0cff-96cb-00c8-be8c2667833d.png)

1. [リボンのユーザ設定] - [メインタブ] - [記録] のチェックボックスをチェック - [OK] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/62d0d420-bad8-97e0-b239-05b06f25bb4c.png)

1. パワポの上部メニュータブに [記録] が追加されればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/f58b407c-c751-f73d-11c5-65bd1b416e5b.png)

# 動画の作成
パワポ全体の動画を作成する

1. [記録] - [スライドショーの記録] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/73b8201c-f9c7-42e1-50f4-453cde47dc43.png)
1. 記録用の画面で操作
    - 左上の [記録] / [停止] をクリックで録画の 開始 / 終了 ができる
    - 右下の [マイク] / [カメラ] をクリックで音声、カメラ映像の ON / OFF 切り替え
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/60602f66-02c6-d09f-2865-ad610772cbec.png)

# 作成した動画ファイル確認

1. [スライドショー] - [最初から] をクリック
    - 全画面で作成した動画が流れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/5aeeabd5-432c-1b6d-28ce-20f9906010c6.png)

# 作成した動画ファイル保存(出力)

1. [ファイル] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/f1c5cc60-4408-c0f1-ed06-ce2fae9d3ee8.png)
1. [エクスポート] - [ビデオの作成] - [ビデオ作成] をクリック
    - 任意で画質を変更してもOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/deb2fbc8-86df-a220-3072-7579de6bb61b.png)
1. 保存先を指定して [保存] をクリック
    - 保存に結構、時間がかかるので作成のバーが終わってから作成したファイルを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/b9a27f72-3589-94b8-261f-599ee7cb510c.png)

# 素材の作成：画面録画の挿入
素材としてPCの画面操作などを録画して挿入する
1. [記録] - [画面録画] をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/bd5a3253-b576-7644-9380-5441f8c63186.png)
1. [領域を選択] をクリックして画面範囲を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/f7febb5e-b798-9b57-99c4-0d865d1333b6.png)
1. [録画] をクリックして録画を開始する
    - カウントダウン表示後に録画がはじまる
    - 画面操作を行う
    - [Windowロゴ] + [Shift] + [Q] で録画終了
    - 上部の [マイク] / [ポインタ] をクリックで音声、ポインタの ON / OFF 切り替え 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/95ef981d-3df8-e0f6-fb3b-4eb93998d09d.png)
wslでelixir その130

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
githubに、.gitattributes、導入してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5968dd79-139c-e5a0-f1d2-2e117608ccba.png)

# 手順

```
$ echo "*.livemd linguist-vendored=false" >> .gitattributes

```

以上。
文章で指定したものをなんでも検出できるAI Grounding DINO

# 言ったものをなんでも探してくれる
このモデルでは、ただ一言、

**「ライオン」
と言うだけでいい。**

![4cf94521-fff1-4e43-b8fd-5e2b0a8c3640.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/fe350010-05bd-8ece-91f7-4ee1b07a64e0.jpeg)

しかも、

**「たてがみの生えたライオン」**

も検出できる。
![946d6f8a-cdde-4230-9d70-64bbe230bb2e.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/2b20a18b-d823-3d09-59c9-e28a07f906f8.jpeg)

**「もっとも口を開けているライオン」**

も検出できる。
![b204200f-ba6a-47e3-b92e-3a4c0684eedd.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/4e51276d-1411-616d-e5aa-abeccc94bfc3.jpeg)

# トレーニング必要なし

これまで物体検出では、検出する物体の画像と座標データセットを用意してモデルをトレーニングする必要があった。
例えば、ライオンを検出するためにはライオンのデータを用意してモデルに覚えさせる必要があった。

しかし、このモデルは**トレーニングの必要なく色々知っている**のである。

https://github.com/IDEA-Research/GroundingDINO

# 使い方

### インストール

```shell
# clone
git clone https://github.com/IDEA-Research/GroundingDINO.git
cd GroundingDINO/
# install libraries
pip install -e .
# download the model weights
mkdir weights
cd weights
wget -q https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth
cd ..
```

### 実行

```python
from groundingdino.util.inference import load_model, load_image, predict, annotate
import cv2

model = load_model("groundingdino/config/GroundingDINO_SwinT_OGC.py", "weights/groundingdino_swint_ogc.pth")
IMAGE_PATH = "lions.jpg"
TEXT_PROMPT = "lion with mane"
BOX_TRESHOLD = 0.35
TEXT_TRESHOLD = 0.25

image_source, image = load_image(IMAGE_PATH)
boxes, logits, phrases = predict(
    model=model,
    image=image,
    caption=TEXT_PROMPT,
    box_threshold=BOX_TRESHOLD,
    text_threshold=TEXT_TRESHOLD
)

annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)
cv2.imwrite("annotated_image.jpg", annotated_frame)
```

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

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

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

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

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

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
wslでelixir その129

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

# 練習問題
Livebookで、github apiを叩け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6692b68e-bd42-e3c7-87b9-8080c601ec17.png)

# セットアップ

```
Mix.install([
  {:req, "~> 0.3.1"},
  {:kino, "~> 0.10.0"}
])
```

# サンプルコード

```
Req.get!("https://api.github.com/users/ohisama")
|> Map.get(:body)

Req.get!("https://api.github.com/users/ohisama/repos?per_page=100")
|> Map.get(:body)
# |> Enum.map(&Map.take(&1, ["name", "url"]))
# |> Kino.DataTable.new()
|> Kino.Tree.new()

Req.get!("https://api.github.com/repos/ohisama/ohi_Livebook/contents/stage1/hello2.livemd")

Req.get!("https://api.github.com/search/code?q=user:ohisama+extension:livemd",
  headers: [
    Accept: ["application/vnd.github+json"],
    Authorization: ["token ghp_*****"]
  ]
)

```


以上。
vol2. DNS のやりとりをwiresharkで覗いてみる


### DNSのながれ

とてもシンプル。

DNSクライアントは、DNSサーバーにQueryを投げる。
Queryは"www.yahoo.co.jp"といったURL。

DNSサーバーは、DNSクライアントにAnswerと返す。
Answerは"182.22.31.252"といったIPアドレス。

Ipv4とIpv6version がある。(Type field で識別)

### Wireshark Screen Shot

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271660/ba6013d2-f79a-a57b-2b70-e1f1a10aacb4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271660/7df2fa82-9c85-493e-3f8f-ca3b61adce1b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271660/d277612a-40ea-e17d-7a7e-ab9d9ab80ba7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271660/3a5a31a7-9647-a5cd-4834-6c83415cd37a.png)

### DNSサーバーへの問い合わせコマンド

@を指定することで、DNSサーバーを指定することができる。

```
$dig www.yahoo.co.jp @8.8.8.8

; <<>> DiG 9.16.1-Ubuntu <<>> www.yahoo.co.jp @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43848
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.yahoo.co.jp.               IN      A

;; ANSWER SECTION:
www.yahoo.co.jp.        900     IN      CNAME   edge12.g.yimg.jp.
edge12.g.yimg.jp.       24      IN      A       183.79.249.252

;; Query time: 173 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Jan 09 14:31:56 EST 2024
;; MSG SIZE  rcvd: 88
```
2024/1/10主にITとかセキュリティの記事

近年多発　医療機関にサイバー攻撃、取引先の脆弱性突く(1/8)
https://japan.cnet.com/release/30931612/?ref=rss

生成AIの悪用リスクが増大　セキュリティー大手が警鐘(1/8)
https://dempa-digital.com/article/512509

名古屋港でシステム障害…サイバー攻撃にどう備えるか(1/8)
https://newswitch.jp/p/39955

サイバー犯罪の脅威から身を守るには？2024年のサイバーセキュリティーに関する5つの予測(1/8)
https://gunosy.com/articles/ewx2n

消費者行動がデータ悪用防止に重要な役割を果たす(1/8)
https://www.arabnews.jp/article/no-category/article_108866/

ランサムウェアの被害を止めるには身代金支払いを禁止するしかないとの主張(1/8)
https://security.srad.jp/story/24/01/08/0611219/

車両盗難に対抗する4つのアプローチ。 車を盗まれないための事前対策(1/8)
https://clicccar.com/2024/01/08/1338954/

ポリチェーン・キャピタルCEOのアカウントがハッキングされ、偽エアドロップ促進(1/8)
https://nextmoney.jp/?p=63267

マルチモーダルなAI時代の始まり：2023年12月に最も読まれた10本のストーリー(1/8)
https://wired.jp/article/10-most-read-stories-december-2023/

【国別】自動運転、2024年の業界展望＆超重要トピックス一覧(1/8)
https://jidounten-lab.com/u_44893

ベイルート空港のスクリーンが反ヒズボラのメッセージでハッキングされる(1/8)
https://www.arabnews.jp/article/middle-east/article_108854/

核・ミサイル開発の裏で北朝鮮の“外貨獲得”戦略 サイバー犯罪に密輸も…(1/8)
https://news.ntv.co.jp/category/international/65f19ed202d84d8f9943b029eb807f69

プログラム初心者が、2ヶ月でHTML→RubyonRailsまで学んだ勉強法(1/7)
https://qiita.com/eightbeat-8b/items/78d7920f8f3f1f320d84

攻撃者の生成AI活用は続く セキュリティー(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500013/

労働生産性向上がカギ ITベンダーの競争環境(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500009/

群雄割拠から統一へ 中国の生成AI(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500004/

IT投資意欲は旺盛 ユーザー企業のIT投資動向(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500001/

専門人材不足でも開発生産性向上、プラットフォームエンジニアリングとは(1/9)
https://xtech.nikkei.com/atcl/nxt/column/18/02697/122700001/

Windows Helloを使って本人確認、パスワードの自動入力でもセキュリティー向上(1/9)
https://xtech.nikkei.com/atcl/nxt/column/18/02676/120500003/

丹青社のなりすましメール、委託先のサーバーが不正アクセスを受け個人情報流出も(1/9)
https://xtech.nikkei.com/atcl/nxt/column/18/00598/100500247/

2024年はSDVへの過渡期、ソフト人材の確保が喫緊の課題に(1/9)
https://xtech.nikkei.com/atcl/nxt/column/18/02667/122500008/

小規模言語モデルに注目 GAFA(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500015/

AIによるコード生成の盲点 ソフト開発(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500014/

通信業界も生成AIで激突 モバイル(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500012/

歴史的大転換の認識を持て 加速するデジタル革命(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500011/

建設ラッシュは全国に データセンター(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500010/

企業には二極化の洗礼 IT人材不足(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500008/

DX機能は事業部門へ IT・DX部門の役割(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500007/

生成AIの悪用に警戒 社会リスクとIT戦略(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500006/

自分の情報を自己管理 デジタル社会(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500005/

大手と新興が合従連衡 海外の生成AI(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500003/

利用者の戸惑いは続く 生成AI活用(1/9)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/122500396/122500002/
【Python】LINE Notify を使ってみよう


## はじめに

Pythonでの自動処理の第一歩として，日常生活で身近なLINEを使った自動処理をしてみたいと思います．

## LINE Notify について

LINE Notify とは，Webサービスと連携すると，LINEが提供する公式アカウント「LINE Notify」から通知を受信する事ができるサービスです．
詳しくは，以下のWebサイトを参照してください．

https://notify-bot.line.me/ja/

## LINE Notify を使えるようにする手順

### 手順１ LINE アカウントを作成する

LINE Notify を使うには，LINE アカウントが必要です．ほとんどの人は LINE アカウントを持っていると思うので，この手順については省略します．
詳しくは，「[新規登録をする](https://guide.line.me/ja/signup-and-migration/line-signup.html)」を参照してください．

### 手順２ LINE Notify にログイン

[LINE Notify](https://notify-bot.line.me/ja/) のWebサイトにアクセスし，ログインしてください．

![スクリーンショット 2024-01-10 1.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/3ba2d8e1-8d3b-d118-bdb4-173322806f86.png)

ログインが完了したら，右上の自分の名前が表示されているところからマイページに移動してください．

### 手順３ トークンを発行する

マイページの［アクセストークンの発行(開発者向け) ＞ トークンを発行する］に移動します．
トークルームの一覧が表示されるので，適当なトークン名を入力し（ここでは「テスト」としました）［1:1でLINE Notifyから通知を受け取る］を選択し，［発行する］を選択します．
すると，トークンが発行されるので，［コピー］を選択し，無くさないようにしましょう．

:::note warn
ページから移動すると，新しく発行されたトークンは二度と表示されません． トークンをコピーしてからページを移動して下さい．
もし，トークンを無くしてしまったら，［マイページ ＞ 連携中サービス］から連携を解除し，トークンを再度発行してください．
:::

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/10b7d9b5-db1f-91f4-b9d6-cbc31d73dd90.png">

## プログラムを実行してみよう！

### ソースコードにトークンを組み込む

ソースコード内の「発行されたトークン」を発行されたトークンに書き換え，以下のソースコードを実行してみましょう．
~~誤字のせいで30分くらい費やしたのでそのままコピペすることをおすすめします．~~

```python:ソースコードにトークンを組み込む
import requests #requestsモジュールについては，あとで補足します

#トークンを設定
token = '発行されたトークン' #発行されたトークンに書き換えましょう

def send_line(msg):
    #サーバーに送るパラメータを用意
    url = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization': 'Bearer ' + token}
    payload = {'message': msg}
    #requestsモジュールのpost関数を利用してメッセージを送信する
    #ヘッダにトークン情報，パラメータにメッセージを指定する
    requests.post(url, headers=headers, params=payload)

if __name__ == '__main__':
    #メッセージを送信
    send_line('Hello, world!')
    print('OK')
```

### 実行結果

![IMG_9718.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664417/32b2e2a7-3792-41e8-0776-6d1e6203711b.jpeg)

無事実行されました！

## 補足： requests モジュール

requestsモジュールを使うには，MacやLinuxならターミナル，Windowsならコマンドプロンプトから以下のコマンドを実行する必要があります．

```terminal
pip install requests
```

環境によっては

```terminal
pip3 install requests
```

とする必要があります．
pipコマンドの実行でエラーが出た場合は，pipのバージョンが古かったり，環境により違いがでたりするので，場合に応じて対応してください．

requestモジュールについて詳しくは，以下のWebサイトからどうぞ．

https://magazine.techacademy.jp/magazine/19195

## 参考文献

- [クジラ飛行机．シゴトがはかどる Python自動処理の教科書．マイナビ出版，2020．](https://book.mynavi.jp/ec/products/detail/id=119730)
マイクラサーバーのポート番号を引数から指定する

## どゆこと
マイクラサーバーのポート番号を変えるには `server.properties` の
```
server-port=25565
```
の部分を変えなければならない。けどプロキシ立ててマルチサーバー化するときいちいち編集するの怠くね？ってことで、引数で指定できないか、調べてみましたよ。
## あった
↓あった

https://gaming.stackexchange.com/questions/148864/how-to-set-minecraft-server-port-from-the-cli

↑あった
これによると起動するときに `-p=<port>` って感じで指定するらしい。やってみよう。
```
java -jar -Xmx6G -Xms5G paper-1.20.4-381.jar -p=4040 nogui
```
ちなみにjarファイルの名前の後に `-p=<port>` を置かないとエラー吐きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557115/acefcff8-2f84-400a-a16a-cf50c8cd64d1.png)
はい、4040番で起動できましたね。
あと`server.properties`の`server-port=`が書き換わります。
## 以上
以上です。英語で調べるのはいいですよ？~~SEO対策だけの空っぽブログ出てこねぇんだもん~~()
NIP-46 Nostr Connectのメモ

# 説明図
図を作って力尽きました。

試しに実装してみて、Started by the signer (nsecBunker)と、Started by the clientで「あれ、並べて書いてあるけど全然使い方が違う！？」となったのを整理。

クライアントを探してみても、どっちかにしか対応してないように見えるものがちらほら。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/7e11de3e-da1c-63cd-9f79-4ad94596b717.png)

wallet (Mobile App/nsecBunkerd)として動くコードを作りました。

https://github.com/gpsnmeajp/nip46rpctest/tree/main

# 関連

https://github.com/nostr-protocol/nips/blob/master/46.md

https://github.com/nostr-connect/connect

https://habla.news/a/naddr1qq9xuum9vd382mntv4eqzxthwden5te0wfjkccte9ehx7um5wf5kx6pwd3skueqpr9mhxue69uhhqatjv9mxjerp9ehx7um5wghxcctwvsq32amnwvaz7tmwdaehgu3wd9hx7um5vyhxxccpz4mhxue69uhkummnw3ezumtfd3hh2tnvdakqz9nhwden5te0wfjkccte9ehx7um5wghxyctwvsq3qamnwvaz7tmwdaehgu3wwa5kuegpvemhxue69uhkv6tvw3jhytnwdaehgu3wwa5kuef0dec82c33xpshw7ntde4xwdtjx4kxz6nwwg6nxdpn8phxgcmedfukcem3wdexuun5wy6kwunnxsun2a35xfckxdnpwaek5dp409enw0mzwfhkzerrv9ehg0t5wf6k2qgkwaehxw309a3xjarrda5kuetj9eek7cmfv9kqzxnhwden5te0wfjkccte9ehhyctwvajhq6tvdshxgetkqyd8wumn8ghj7un9d3shjtnwdaehgunsd3jkyuewvdhk6qguwaehxw309a6ku6tkv4e8xefwdehhxarjd93kstnvv9hxgqguwaehxw309ahx7um5wghx6at5d9h8jampd3kx2apwvdhk6qg4waehxw309ajkgetw9ehx7um5wghxcctwvsq3samnwvaz7tmjv4kxz7fwdehhxarjv96xjtnrdaksygrlts45uj9qa8lv5caydvfumwpy386qyquc6c9zqu9fdr92sxxht5psgqqqw4rs4a77p5?ref=nobsbitcoin.com
Ardupilotドローン制作② ～各種装備品の接続・設定と機体チューン～

# Ardupilotドローン制作② ～各種装備品の接続・設定と機体チューン～

[前回](https://qiita.com/keraFPV/items/c7811e8d5932f5a92396)、とりあえずアームして飛行するまでできました。  
今回はもう少し装備するパーツを増やすのと、デフォ設定で出るであろう飛行中の機体の振動取りを行いました。

## その他機器の設定

### (再掲：事前知識)フルパラメータで扱うSERIALの番号について

- 0:USB
- 1～:各UART

### (事前知識)SERIALn_PROTOCOLに設定する番号について

[ここ](https://ardupilot.org/plane/docs/common-serial-options.html#serialx-protocol)に一覧がある

### VTXのスマートオーディオ

VTXをFCにつなげる  
TX5にはんだ付けした場合、Mission Plannerでの設定手順は以下  

1. Mission Plannerの上部メニュー`設定/調整`をクリック
1. `フルパラメータ ツリー`を開く
1. `VTX_ENABLE`の値を`1`にする
1. `SERIAL5`の項目のツリーを開き、`SERIAL5_PROTOCOL`の値を`37`にする
1. `SERIAL5_OPTIONS`の値をクリック、`TX_PullDown`、`HalfDuplex`を選択。値が`68`となる
1. `SERIAL5_BAUD`の値を`4800`に設定

スマートオーディオの指令方法は[公式](https://ardupilot.org/copter/docs/common-vtx.html#video-transmitter-settings)を参照

- 国内頻出のFチャンネルは`Airwave`となってます
- チャンネル1は設定値0です。例えば`F1`にしたい場合、Airwaveの0なので、`VTX_BAND=3,VTX_CHANNEL=0`です

### OSD

1. Mission Plannerの上部メニュー`設定/調整`をクリック
1. `Onboard OSD`を開く
1. いい感じに設定する

### GPS

GPSをFCにつなげる  
TX6/RX6にはんだ付けした場合、Mission Plannerでの設定手順は以下  

1. Mission Plannerの上部メニュー`設定/調整`をクリック
1. `フルパラメータ ツリー`を開く
1. `SERIAL6`の項目のツリーを開き、`SERIAL6_PROTOCOL`の値を`5`にする

### WiFiモジュール

Wifiモジュールのファームウェアを更新する  
V1.2系を使うとプロトコルはMAVLink2  
V1.1系を使うとプロトコルはMAVLink1となる  
  
WiFiモジュールをFCにつなげる  
TX1/RX1にはんだ付けした場合、Mission Plannerでの設定手順は以下

1. Mission Plannerの上部メニュー`設定/調整`をクリック
1. `フルパラメータ ツリー`を開く
1. `SERIAL1`の項目のツリーを開き、`SERIAL1_PROTOCOL`の値を`2 (MAVLink2) または 1 (MAVLink1)`にする
1. `SERIAL1`の項目のツリーを開き、`SERIAL1_BAUD`の値を`921`にする

## 機体調整

### PIDチューン

公式サイトの情報より  
STABILIZEモードにて

- ATC_RAT_PIT_P
- ATC_RAT_PIT_I
- ATC_RAT_PIT_D
- ATC_RAT_RLL_P
- ATC_RAT_RLL_I
- ATC_RAT_RLL_D

の値を、振動が出なくなるまで1/2していくと良いとあり、実際にそうしたところ良好に振動が取れた。  
その他、ALTHOLD・LOITERモードのチューニングまで記述があるので、詳しくは下記参考先を読んで上から下まで実践するとよい

[(参考)](https://ardupilot.org/copter/docs/initial-tuning-flight.html#initial-aircraft-tune)

### ALTHOLDモード

気圧センサーを用いて高度維持を行うフライトモード。  
AltHold発動時、機体が急上昇出てしまう問題がある場合  
原因として、機体の振動が考えられる。  
FCのソフトマウントや、プロペラのゆがみを再確認。  
  
GPSが効かない室内で良好に動作する

### LOITERモード

GPSを用いて位置を保持する。
屋外専用。
DJI機みたいに自作機がピタッと止まるので楽しい
LLMのモデルパラメータ数とGPUメモリ使用量について


## 1. この記事の目的  

最近は右も左もLLMという風潮  
ぜひ、自分のPCで使ってみたいと思ったが、パラメータ数◯Bという表記  
馴染みの無い（特に日本人には）単位で実際にどこまでのサイズが自分の
PCで実行できるか、分からず検証してみようと

## 2. GPUメモリ使用量について

- LLMのGPUメモリ使用量の計算方法  
推論に必要なメモリは大まかに  FP16の1パラメータ(2バイト)に対してパラメータ数◯Bとすると  
$必要なメモリ(GB) = 2 \times ◯$  
となります。意外とシンプルです。 [[1]](#61-メモリ使用量についての質問)

- GPUメモリ使用量の実測  
GPUtil[[2]](#62-gputil)を使用して次のコードで計測。

```python
import GPUtil
def get_gpu_used_memory(device_id):
    byte_gpu_used_memory = GPUtil.getGPUs()[device_id].memoryUsed
    GB_gpu_used_memory = byte_gpu_used_memory / 1024
    return GB_gpu_used_memory
```

## 3. モデル  

- 計測対象モデル

1. [TinyLlama-1.1B-Chat-v1.0](https://huggingface.co/TinyLlama/TinyLlama-1.1B-Chat-v1.0)
2. [phi-2](https://huggingface.co/microsoft/phi-2)
3. [Mistral-7B-v0.1](https://huggingface.co/mistralai/Mistral-7B-v0.1)
4. [zephyr-7b-beta](https://huggingface.co/HuggingFaceH4/zephyr-7b-beta)
5. [SOLAR-10.7B-Instruct-v1.0](https://huggingface.co/upstage/SOLAR-10.7B-Instruct-v1.0)  
6. [LLaMA-MoE-v1-3_5B-4_16](https://huggingface.co/llama-moe/LLaMA-MoE-v1-3_5B-4_16)  
7. [xglm-4.5B](https://huggingface.co/facebook/xglm-4.5B)  
8. [idefics-9b-instruct](https://huggingface.co/HuggingFaceM4/idefics-9b-instruct)
9. [Yi-6B](https://huggingface.co/01-ai/Yi-6B)
10. [Qwen-1_8B-Chat](https://huggingface.co/Qwen/Qwen-1_8B-Chat)

- パラメータ数の実測
torchinfo[[3]](#63-torchinfo)を使用して、次のコードで計測。

```python
from torchinfo import summary
def get_billion_param(model):
    billion = 1000**3
    return round(summary(model, verbose=0).total_params / billion, 2)
```

## 4. コードと結果

- コード全体  

```python
from torchinfo import summary
def get_billion_param(model):
    billion = 1000**3
    return round(summary(model, verbose=0).total_params / billion, 2)
```

ここ[[4]](#作成リポジトリ)にもおいています。

- 結果  
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595608/de66caa4-93cb-a2d7-4cdb-8915e7953de9.png)

おおまかには  
[GPUメモリ使用量について](#2-gpuメモリ使用量について)
の通りになっています。  
ただし、いくらか誤差もありそうで内部で使用しているアルゴリズムの差もあるかもしれません。

## 5. まとめ

今後、モデルのファインチューニングをしてみたいと考えています。
モデルの全てのパラメータの再学習には  
$必要なメモリ(GB) = 4 \times ◯$  
が必要なよう[[1]](#61-メモリ使用量についての質問)なので、Phi-2くらいがローカルPCで使用できる最高ラインくらいになりそうですね。

## 6. 参考

### 6.1. メモリ使用量についての質問

https://discuss.huggingface.co/t/llama-7b-gpu-memory-requirement/34323/6  

### 6.2. gputil

https://github.com/anderskm/gputil?tab=readme-ov-file  

### 6.3. torchinfo

https://github.com/TylerYep/torchinfo  

### 6.4. 作成リポジトリ

https://github.com/SoseSose/LLM-need-memory
Djangoでfor文を使うとき要素がないときの処理を簡単に書く

Djangoで
```ruby:qiita.python
{% for comment in post.comments.all %}
    ：
    ：
{% endfor %}
```

のようにfor文を用いるとき要素がないとき
`{% empty %}` タグを用いることで簡潔に処理を書ける
[Swift文法] タプル

# はじめに
Swift の復習でまとめた記事になります。

# タプル型
**複数の型を1つの型として扱うもの**です。

## 定義の仕方
`変数名: (型名1, 型名2, ... , 型名n)`のような書き方をします。(nは自然数)

```swift
var tuple: (Int, String)
```
タプル型の値を**タプル**と呼びます。上記の例だと、`tuple`がタプルです。
値を代入するには、`(型名1, 型名2, ... , 型名n)` と同じように代入していきます。

```swift
let tuple: (Int, String) = (1, "apple")
print(tuple) // (1, "apple")
```

## 要素のアクセス
タプルの要素へのアクセスは主に３つの方法があります。
- インデックスによるアクセス
- 要素名によるアクセス
- 代入によるアクセス

### インデックスによるアクセス
各要素にインデックスでアクセスできます。

```swift
let tuple: (Int, String) = (1, "apple")
let number = tuple.0
let appleString = tuple.1
print(number) // 1
print(appleString) // apple
```

### 要素名によるアクセス
タプルの定義時に各要素に名前をつけると、その名前を通して要素にアクセスできます。
要素名を定義するには、`(要素名n: 要素n)` のような形です。(n は自然数)

```swift
let tuple: (int: Int, string: String) = (int: 1, string: "apple")
let number = tuple.int
let appleString = tuple.string
print(number) // 1
print(appleString) // apple
```

### 代入によるアクセス

() 内に、区切りで列挙された要素数分の変数や定数を代入することができます。
タプルの要素には、変数・定数を通じて値にアクセスできます。

```swift
let number: Int
let string: String
(number, string) = (1, "apple")
print(number) // 1
print(string) // apple
```

また、以下のように定義することもできます。

```swift
let (number, string) = (1, "apple")
print(number) // 1
print(string) // apple
```
Sharepointリストの画像列をPowerAppsで参照する方法


# 概要
2023年10月頃からSharepointリストの画像列にUPした画像データの保存先仕様が変更になったようで、PowerAppsで参照する方法も変更を迫られたので対応内容メモ共有します。
よりスマートな方法ご存じの方おられたらご指摘いただけると幸いです。
# Sharepointリストの画像列仕様変更
画像列にUPされた画像データの取り扱いが下記のように変更となった。
従来：SiteAssetsに保存
変更後： リストアイテムの添付ファイルとして保存
# PowerAppsでの問題点
1. 同じリスト内に従来と変更後仕様が混在
仕様変更前の既存レコードは従来仕様のままで、新規レコードは変更後仕様で保存されており、条件分岐して両方の仕様に対応必要。
2.  従来記述での画像読み込みが遅い
変更後の添付ファイルも従来同様`[画像列名].small`などで読み出し可能だが表示されるまでに数秒かかる。（従来仕様のSiteAssetsに保存されている画像は従来記述でストレスない速度で表示）

# 対応方法
1. まず`IsBlank`関数で画像列にデータが有ることを確認
1. `IsBlank`関数で添付ファイルに"Reserved_ImageAttachment"で始まるファイル有無確認
1. 有りの場合は`添付ファイル.Value`で画像データ抽出したり`添付ファイル.AbsoluteUri`でリンク抽出したり
1. 無しの場合は`[画像列名].small`等で画像データ抽出。リンクは[こちら](https://youtu.be/4JQcMblu3To?si=BBqRB7R8eeEFIS0G)を参考に下記で抽出。
```
Substitute(
Substitute(
Substitute(
Substitute(
Substitute(
Substitute(
    Last(Split(ThisItem.Image列.Full,"datasets%2F")).Value,
"%2F","/"),
"%25252f","/"),
"%25253a",":"),
"%3F","?"),
"%21","!"),
"%2525","%")
```

:::note warn
懸念事項
添付ファイルが"Reserved_ImageAttachment"というファイル名で始まることが前提なので、ユーザーが手動で添付ファイルに同じ文字列で始まるファイルを添付した場合そちらを参照してしまうかも。また、今後何等かの理由でこの仕様が変更されたときにエラーが・・・
:::
自分と会社用のコーディングフレームワークを考えたので、せっかくだからちゃんとサイトにまとめてみた

コーディングフレームワークを勝手にがっちり考えたので、せっかくだからサイトにちゃんとまとめて使えるものにして会社に持ち込みました、というお話です。

![スクリーンショット 2024-01-09 23.58.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390283/f8c9a502-08fb-bf90-3f5a-1f93cd969044.png)

https://floncss.dsflon.net/


デザインとかロゴとかそれっぽい感じになったなと自分では満足してる。

※ 一般配布は目的としていないので、ダウンロードファイルにパスワードがかかっています
※ 何分一人でしこしこ作っているだけなので誤字脱字などはご容赦ください


## 作成にいたる背景
- チーム内で実装ルールを統一したいのはもちろん
- 新人教育の場面でも教材としたい
- 納品時や協業するパートナーさんにコーディングドキュメントが求められた場合、こちらのサイトを渡すことでドキュメントとしてしまいたい

といったところで、とにかくこのURLを渡してあとはサボれるところはサボれればいいな、というのも本音です。
あとは、こんなものがあることで会社のブランディング向上や採用の一助となればいいなと夢見ています。

## 基本的な考え方

![スクリーンショット 2024-01-10 0.08.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390283/777e667f-07cc-5a09-f0ba-d0aef0345cb3.png)

tailwind に代表されるユーティリティファーストの良いところと、ITCSSの設計思想を取り入れたフレームワークです。

今さらとか、だまって tailwind 使えば...というご意見もあると思いますが、css 書けるし書きたし（好きだし）、なにより HTML がしっちゃかめっちゃかになるのが肌に合わなかったんです、。

なので、大手含めたくさんのサイトをつくった経験から「まずはこれだけあれば良いかな」というものだけ utility class にまとめました。

例）https://floncss.dsflon.net/utilities/gutters
![スクリーンショット 2024-01-10 0.18.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390283/25a79b58-68d7-35af-d1d3-3524bd5b0d41.png)

簡単なレイアウトや装飾はutility classを用いて素早く構築し、複雑な装飾はITCSSに基にコンポーネントを定義、あるいはページごとにcssを記述していく、というような考え方です。

詳しくはこちら↓
https://floncss.dsflon.net/docs/architecture

## これから
- これがこういう感じであったら便利、がいくつかあるので足していきたい
- このフレームワークと親和性の高いデザインシステムも開発しているので、デザインから実装までまるっとパッケージにしていきたい

## ちなみに
このサイトは next.js v14系で作っているが、もちろんこのフレームワークで作られている。
まあまあ良くできたかな、とホクホクしているし、実際まわりからも良い反応を頂いたりしている。
webでも使えるし、概念的にはflutterでも使えると思っている。

あと、Copilot もこのフレームワークを認識したコードを提案してくれるので、さらに使いやすい。
（これは Copilot が優秀なだけ）

生成aiが全力を出す時代が来るとこんなものは不要になるかもしれないが、こういうことを考えたり作ったりしているのが結局楽しいですね。

最後まで見ていただきありがとうございました。
おわり。
Kotlinのnull安全

## null安全とは
変数がnull値を持つことができるかどうかを表す概念のことを表します。
「null＝値がない」になります。
JavaやKotlinはnull参照を行うと、NullPointerExceptionという例外が発生します。

## null値非許容型とnull値許容型
* null値非許容型は、nullを保持できないです
* null値許容型は、nullを保持できます
変数をnull許容型にしたいときは、クエスチョンマーク（`?`）をつける。

```kotlin
// null値非許容型 nullを代入するとコンパイルエラー発生
var helloWorld: String = null

// null値許容型 nullを代入することが可能
var helloWorld: String? = null
```

## null値許容型変数のプロパティにアクセス
変数の後ろにセーフコール演算子(`?.`)を付与することで、null許容型変数のメソッドやプロパティにアクセスできます。この記法を使用すると、変数がnullでない時は、通常通りにメンバアクセスして、変数がnullの時は、メンバアクセスしないでnullを返します。
```kotlin
// helloWorldにnullが代入される可能性があり、
// その考慮をしていないためコンパイルエラー発生
var helloWorld: String? = "hello world"
println(helloWorld.length)

// セーフコール演算子を付与することで、null許容をしてメンバアクセスが可能になっている
var helloWorld: String? = "hello world"
println(helloWorld?.length)
```

## 非nullアサーション演算子（!!）を使用
変数の後ろに非nullアサーション演算子(`!!`)を付与することで、null許容型変数を強制的にnull非許容型変数として扱う。もしも変数にnullが代入されると例外が発生します。例外をcatchする文やif文やエルビス演算子(`?:`)などを使って、アプリの挙動が止まらないように回避する必要がある。基本的には、非nullアサーション演算子(`!!`)ではなくセーフコール演算子(`?.`)を使用することが望ましい。

```kotlin
// 非nullアサーション演算子を使用することでhelloWorldをnull非許容変数として扱う
var helloWorld: String? = "hello world"
println(helloWorld!!.length)

// NullPointerExceptionが発生
var helloWorld: String? = null
println(helloWorld!!.length)
```

## エルビス演算子（?:）を使用
エルビス演算子(`?:`)はこの演算子の左にある第1項の変数がnullでない時は、第1項の値を返し、nullの時は演算子の右にある第2項の値を返します。変数がnullの時にある特定のデフォルト値を設定したいときにエルビス演算子(`?:`)を使用します。

```kotlin
// 出力：11
// helloWorldの値がnullではないので、helloWorld?.lengthを返す
var helloWorld: String? = "hello world"
var helloWorldLength = helloWorld?.length ?: 0
println(helloWorldLength)

// 出力：0
// helloWorldの値がnullなので、0を返す
var helloWorld: String? = null
var helloWorldLength = helloWorld?.length ?: 0
println(helloWorldLength)
```

## おわりに
セーフコール演算子(`?.`) : nullを許容する
非nullアサーション演算子(`!!`) ：変数をnull非許容型にする
エルビス演算子(`?:`) : 変数がnullかどうかで値が変化する
CloudWatchアラームの状態変化でLambdaアクションが実行できるようになりました

# ■概要

CloudWatchアラームのステータス変更が起きた際の地味アプデを見かけたので書いてみます。
アラームの状態が変移した際にAWS Lambdaを指定できるというものです。

Amazon CloudWatch alarms adds AWS Lambda as an alarm state change action
https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-cloudwatch-alarms-lambda-change-action/


# ■CloudWatchアラームのアクションについて

cloudWatchアラームを設定する際、閾値に引っかかった時の動作を決定できます。
アクションとして、例えばよく使いそうなものだと、前もってSNSトピックにメールアドレスのリストを設定していて、そのリストにメールを送付する等です。

# ■コンソールからアクションを確認する

実際にコンソールから見てみましょう。
今回は現在設定済みのCPUアラートを編集する形で調べてみます。
アラーム編集の画面にてアクションの設定画面へ移るとスクショのような項目を確認できます。

![編集1_20240109232449.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/6682129a-9206-9460-8af9-248cefdbf0bb.png)

アップデート通りにLambdaも項目としてありますね。
何だか前からあったような…という自然な感じであります…

![編集2_20240109233135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/fdbaf4df-37d9-4722-506a-8031b4506451.png)

Lambdaアクションの詳細です。
他アクションと同様で、アラーム状態、OK、データ不足での変移でトリガーする事ができます。
よくよく見てみると別アカウントにあるLambda関数も実行できるみたいですね

アラームの状態変化でLambdaと連携できる、という所まではありそうな話ですがクロスアカウントで利用できるという点は結構痒いところに手が届きそうです。（今のところ使う機会なさそうですが…）

後は単純なインスタンス再起動や停止、削除に留まらずインスタンスのスペック変更、停止起動、他サービスの呼び出しなんかでも使えそうですし、Lambdaの自由度の分やれる事は広そうですね。

# ■その他のアクション項目

ざっと書きます。
特に「Systems Manager アクション」のアクションの部分はかなり興味あります。

### ・ 通知 
AWS User Notificationsを使用してCloudWatchアラームの状態変更を通知することができます。
これにより、CloudWatchアラーム毎に通知設定を行わずに全てのアラームの状態変更を通知可能です。

### ・ Auto Scaling アクション
CloudWatchアラームにEC2の標準メトリクス（CPUUtilzation）を監視させ、
それが一定値を超えた場合にアラームを起動することで、AutoScaling内のインスタンス数を調整することができます。

### ・ EC2 アクション
インスタンスの停止、再起動、削除もできます。
特定のインスタンスタイプではインスタンスの復旧まで出来るらしい…

### ・ Systems Manager アクション
CloudWatchアラームの発動により、Systems Managerからタスクやアクションが実行できます。
例えば、System Manager Automationでインスタンスにパッチ適用をするシーンで活用できます。

# ■最後に

今回アクションとしてLambdaが使用できるようになったので、回り道してLambdaを動作させていた方にとっては朗報だったのかもしれませんね…
かなり短い内容になりましたが、今回は以上です！
YJJPP自分用メモ

import org.junit.Test;
import org.junit.Before;
import static org.mockito.Mockito.*;
import java.lang.reflect.Method;

public class ExceptionHandlerWrapperTest {

    private ExceptionHandlerWrapper exceptionHandlerWrapper;
    private ExceptionHandler mockedWrapped;

    @Before
    public void setUp() throws Exception {
        mockedWrapped = mock(ExceptionHandler.class);
        exceptionHandlerWrapper = new ExceptionHandlerWrapper(mockedWrapped);
    }

    @Test
    public void testProcessViewExpiredException() throws Exception {
        ViewExpiredException viewExpiredException = new ViewExpiredException("测试消息", new FacesContext());

        // 反射
        Method method = ExceptionHandlerWrapper.class.getDeclaredMethod("processViewExpiredException", ViewExpiredException.class);
        method.setAccessible(true);
        method.invoke(exceptionHandlerWrapper, viewExpiredException);


    }
}
【TailwindCSS】dialog要素が開いている場合に背景がスクロールされないようにする方法

`body`要素に以下のように記述することで`dialog`要素が開かれている場合に背景がスクロールされないようにできます。

```html
      <body class="[&:has(dialog:modal)]:overflow-hidden">
        
      </body>
```

TailwindCSSが`v3.4`以降であれば以下のように記述できます。

```html
      <body class="has-[dialog:modal]:overflow-hidden">
        
      </body>
```

https://tailwindcss.com/blog/tailwindcss-v3-4#new-has-variant
ベイズ統計モデリング 写経 3.7

### 3.7.3 関数の作成

``` r
asqplusb = function(a, b=1)
{
  c = a*2 + b
  return(c)
}
asqplusb(2)
```

    ## [1] 5

``` r
asqplusb(2,3)
```

    ## [1] 7

``` r
asqplusb(3,2)
```

    ## [1] 8

``` r
asqplusb(a=2,b=3)
```

    ## [1] 7

### 3.7.4 条件分岐

``` r
x=5
if(x <= 3){
  show("small")
}else{
  show("big")
}
```

    ## [1] "big"

``` r
for(i in 5:1){
  show(i)
}
```

    ## [1] 5
    ## [1] 4
    ## [1] 3
    ## [1] 2
    ## [1] 1

時間計測

``` r
startTime = proc.time()
y=vector(mode="numeric",length=1.0E6)
for( i in 1:1.0E6 ){
  y[i]=log(i)
}
stopTime = proc.time()
elapsedTime = stopTime - startTime
show(elapsedTime)
```

    ##    ユーザ   システム       経過  
    ##       0.58       0.01       0.75

ループを使わないで、ベクトルで

``` r
startTime = proc.time()
y=log(1:1.0E6)
stopTime = proc.time()
elapsedTime = stopTime - startTime
show(elapsedTime)
```

    ##    ユーザ   システム       経過  
    ##       0.03       0.00       0.03

forループよりベクトル演算を先に使う。

## 3.8　グラフの展開と保存

``` r
library(ggplot2)
basic <- ggplot( mtcars , aes(x=mpg, y=wt)) + 
  geom_point()
basic
```

![](https://i.imgur.com/5qnEZXU.png)

``` r
ggsave("test.png")
```

    ## Saving 7 x 5 in image
職務経歴書をNotionにて作成を検討

引き続き就職・転職活動をすすめていますが、内定メールをいただくよりお祈り・何も連絡がない場合が圧倒的に多いので、提出書類について見直しを進めています。

以下テンプレートを使用すれば0から作成をしなくても済みそうなので、以下テンプレートを参考に対応をしてゆこうと思います。
https://www.notion.so/ja-jp/templates/search?query=%E5%B0%B1%E8%81%B7%E3%83%BB%E8%BB%A2%E8%81%B7%E6%B4%BB%E5%8B%95

上記以外にもNotionに参考となるテンプレートがあるので、それらも参考にして対応を進めてゆこうと思います。
https://www.notion.so/ja-jp/templates/search?query=%E8%BB%A2%E8%81%B7

書類選考が通らなかった理由・面接後不採用の理由については以下についても要因としてあるので、見直し後活動を再開しようと思います。
・経歴書の概要が存在しない
・技術について経験年数のみをしており、具体的にどのようなことができるか記載できていない
・参画したプロジェクトの内容について冗長な文章となっており、わかりにくい。

応募数・不採用・内定を頂いた数値については活動が落ち着いた際に、投稿しようと思います。
Nix+home-managerでagenixを利用する

home-managerでもagenixを利用したく、色々と詰んだのでその時のメモ

agenixにはhome-manager向けモジュールが用意されており、これを呼び出せばhome-managerでもagenixが利用できるようになった

```nix
    {
      homeConfigurations = {
        "user@host" = inputs.home-manager.lib.homeManagerConfiguration {
          modules = [
            inputs.agenix.homeManagerModules.age
          ];
        };
      };
    };
```

これで`age`使えるようになる

```nix
  age.secrets = {
    aws_config = {
      file = "${inputs.mysecrets}/aws/config.age";
      path = "/home/fabiiw05/.aws/config";
      mode = "644";
    };
    aws_credentials = {
      file = "${inputs.mysecrets}/aws/credentials.age";
      path = "/home/fabiiw05/.aws/credentials";
      mode = "644";
    };
  };
```

ただ、`home-manager switch`してもpathで指定したところにリンクが生成されない
調べたところ`agenix.service `をリスタートする必要があった

https://github.com/ryantm/agenix/issues/50
```
systemctl --user restart agenix.service 
```
全四字熟語データベースを作成するために必要な3つの注意点

# はじめに
こんにちは。sabapenです。
先日、Twitter（新X）で[**全俳句データベース**](https://horicun.moo.jp/contents/haiku/)というWebアプリが話題になっていました。
あ~んの50音+濁音等のひらがなの全ての組み合わせにIDを振って網羅した一種のジョークアプリとなっております。

ありそうでなかった発想の勝利とも思える作品に感動した私は、自分も似たようなWebアプリを作ってみようと思い立ち、Viteの練習も兼ねつつ**全四字熟語データベース**を作成しました。

全四字熟語データベースでは2136文字の常用漢字を使った約20兆通りの四字熟語を網羅する必要があります。その際に気をつけた以下の3つの注意点に関してこの記事で解説したいと思います。
1. 常用漢字の判定
2. 漢字の組み合わせとIDの1対1対応
3. 20兆程度の大規模な組み合わせ

# 制作物
https://x.com/sabapen120/status/1744370057910616183?s=20

https://sabapen.github.io/all-yojijukugo-DB/

全四字熟語データベースはVite+React+Typescriptを使って3時間ほどでサクッと制作しました。そのためUIが適当だったりコードが十分に最適化されていなかったりする点には目をつぶっていただけると幸いです。

# 常用漢字の判定
最初に躓いたのは常用漢字の判定です。常用漢字を判定できるライブラリがあればいいなぁと思って探してみましたが見つからなかったので、ここは力技で解決しました。

UTF-8で常用漢字のCSVを配布してくださっているありがたいサイト[^1]があったため、CSVを落としてきてJSONとして整えて利用しています。
```.json:joyokanji.json
{
  "1": "亜",
  "2": "哀",
  "3": "挨",
  "4": "愛",
  "5": "曖",
  "6": "悪",
  ...(省略)
}
```
あとはJSONをこねこねして入力された文字が含まれるか否かを判定すればOKですね。
文字コードの範囲で正規表現にかけたりすればもっとスマートなやり方はありそうですが、高々2136通りなので力技でやるのが一番速いと思います。

# 漢字の組み合わせとIDの1対1対応
次は漢字四文字の組み合わせとIDの1対1対応の取り方です。
こちらは四字熟語を**2136進数**の4ケタの数字とみなし、10進数へ変換することでIDと対応させることができます。

```.tsx:四字熟語に対応するIDを取得する関数
function getYojijukugoId(yojijukugo: string): number {
  const str = [...yojijukugo]
  const kanjiIds = str.map(
    (kanji) =>
      joyokanjiArray.find((joyokanji) => joyokanji.kanji === kanji)!.kanjiId,
  )
  const yojijukugoId =
    (kanjiIds[0] - 1) * joyokanjiArray.length ** 3 +
    (kanjiIds[1] - 1) * joyokanjiArray.length ** 2 +
    (kanjiIds[2] - 1) * joyokanjiArray.length +
    (kanjiIds[3] - 1) +
    1
  return yojijukugoId
}
```
上記の関数では、四字熟語の1文字目は2136進数の4桁目なので2136の3乗をかけ、2文字目は2136の2乗をかけ、……と繰り返すことでIDと1対1で変換しています。

50音なら50進数として扱いますし、アルファベット26文字なら26進数として取り扱うことができます。このような変換は意外と役に立ちますね。

# 20兆程度の大規模な組み合わせ
四字熟語の組み合わせは2136^4=20,816,369,750,016ということで、約20兆通り存在します。ここで気をつける必要があるのが、オーバーフローです。

### Javascriptの仕様
Javascriptでは数値を倍精度浮動小数で取り扱う関係上、整数として正確に扱える安全な値は-(2^53 − 1)から2^53 − 1の間、おおよそ+-900京までとなっています。
これよりも大きい値になる場合はなんらかの対応が必要となってきます。

### 本家全俳句データベース

本家全俳句データベースでは約6溝(こう)句を取り扱っている関係上、900京を遥かに上回る値になってしまいます。そのため、BigInt型を使って製作していたようです[^2]

### 全四字熟語データベース

では、全四字熟語データベースではどうしたかというと約20兆通りで900京まで全然余裕があったので**普通のnumber型**で制作できました。
オーバーフローには注意が必要ですが、問題がなければ無理にBigIntを使う必要はないですね。

# おわりに
全四字熟語データベースを作ってみると、簡単そうに見えていくつか注意点がありました。IDと紐づける必要のあるような制作物を作る際は参考にしてもらえると幸いです。


[^1]: 常用漢字と文字コードの対応表 https://x0213.org/joyo-kanji-code/
[^2]: https://x.com/horicun/status/1744016718568247583