OmniAICreator/Qiita-1.07M huggingface dataset:
wslでelixir その72

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
LivebookでExplorerがエラー吐く件

# Explorerがエラー吐く

```
Mix.install([
  {:explorer, "~> 0.7.0"}
])

```

```
==> rustler_precompiled
Compiling 4 files (.ex)
Generated rustler_precompiled app
==> explorer
Compiling 24 files (.ex)

08:43:47.371 [debug] Copying NIF from cache and extracting to /home/ore/.cache/mix/installs/elixir-1.14.5-erts-13.2/82f330905a03115e831c0915fa1c9b98/_build/dev/lib/explorer/priv/native/libexplorer-v0.7.1-nif-2.15-x86_64-unknown-linux-gnu.so

08:43:48.291 [warn] The on_load function for module Elixir.Explorer.PolarsBackend.Native returned:
{:error,
 {:load_failed,
  'Failed to load NIF library: \'/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28\' not found (required by /home/ore/.cache/mix/installs/elixir-1.14.5-erts-13.2/82f330905a03115e831c0915fa1c9b98/_build/dev/lib/explorer/priv/native/libexplorer-v0.7.1-nif-2.15-x86_64-unknown-linux-gnu.so)\''}}

```

# 調査

Expolorerがlibc.so.6の2.28バージョンを要求してるが、ubuntu18.04は、2.27バージョンでした。

# 対応

2.27バージョンのExpolorerがないか探す。

0.3.1 -> 2.29
0.4  -> 2.28
0.5.5 -> 2.28
0.1.0 -> 2.29
0.2.0 -> 2.29
0.7.0 -> 2.28

無いです。

以上。
flashromでfirmware update

最近はもっぱらラズパイで有名なBroadcomですが、昔はMIPSのSOCを作っていました。

この頃のブートローダーはCFEをいう独自のものでした。

CFEはu-bootと同じようにtftpが使えるのですが、今いじっているターゲットにはEthernetの口がありません。

幸い[SPI Flashを取り外し可能](https://qiita.com/yamori813/items/65667a14a939b7a877d3)にしたので、flashromでfirmwareを焼いてみます。

まずflashromでオリジナルのfirmwareを読み出します。

```
$ flashrom --programmer ch341a_spi -r original.bin
```

これからCFEの部分を抜き出します。

```
$ dd if=original.bin of=boot_only.bin bs=64k count=4
```

CFEのサイズはオリジナルの起動ログなので確認できます。

CFEは設定をFlashの最後のほうに保存しているので、これも抜きます。

```
$ dd if=originl.bin of=nvram.bin bs=64k skip=31
```

最後の64Kを保存してますが、実際は最後の32Kに設定が保存されていました。

これと新しくビルドしたfirmwareを引っ付けてflashのイメージを作ります。

```
$ cat boot_only.bin main.trx > tmp1.bin
$ dd if=tmp1.bin of=tmp2.bin ibs=1984k conv=sync
$ cat tmp2.bin nvram.bin > 2m.bin
```

これをflashromで焼いて出来上がりです。

```
$ flashrom --programmer ch341a_spi -w 2m.bin
```

ターゲットに焼上がったFlashをつけて無事起動した。

```
CFE version 1.0.37 for BCM947XX (32bit,SP,LE)
Build Date: Tue Aug  9 14:39:48 IDT 2005 (igor@linuxbox.fotonation.local)
Copyright (C) 2000,2001,2002,2003 Broadcom Corporation.

Initializing Arena
Initializing Devices.
et0: Broadcom BCM47xx 10/100 Mbps Ethernet Controller 1.0.1.0
rndis0: Broadcom USB RNDIS Network Adapter (P-t-P)
CPU type 0x29007: 200MHz
Total memory: 8192 KBytes

Total memory used by CFE:  0x80300000 - 0x803A5830 (677936)
Initialized Data:          0x8033B840 - 0x8033E080 (10304)
BSS Area:                  0x8033E080 - 0x8033F830 (6064)
Local Heap:                0x8033F830 - 0x803A3830 (409600)
Stack Area:                0x803A3830 - 0x803A5830 (8192)
Text (code) segment:       0x80300000 - 0x8033B840 (243776)
Boot area (physical):      0x003A6000 - 0x003E6000
Relocation Factor:         I:00000000 - D:00000000

Device eth0:  hwaddr 00-90-4C-68-00-40, ipaddr 192.168.0.206, mask 255.255.255.0
        gateway not set, nameserver not set
Reading :: Failed.: Timeout occured
Loader:raw Filesys:raw Dev:flash0.os File: Options:(null)
Loading: .... 776328 bytes read
Entry at 0x80001000
Closing network.
Starting program at 0x80001000
bcmbm-mruby e312bc1(master) Fri Sep 29 16:30:57 JST 2023
mruby 771b56c79(master)
Mem : 800000
BOOT_CONSOLE : uart0
Clock : 200000000
MRB SIZE 686
MRB SHA256 3e609014
ORG DIR: 0 CTL: 0
0: 1010101010
1: 1010101010
2: 1010101010
3: 1010101010
0: 1010101010
1: 1010101010
2: 1010101010
```
素因数分解をMySQLで実装した

仕事の会議中に暇つぶしに作成したので、ここにさらしておきます。実用性はありません（´・ω・｀）

100以下の自然数について、素因数分解するSQLです。MySQL8にて稼働確認をしています。

```SQL
WITH RECURSIVE 
numbers(x) AS (
    SELECT 2
  UNION ALL
    SELECT x+1 FROM numbers WHERE x < 100
),
factors(x, y, i, divided) AS (
    SELECT x, x, 2, 0 FROM numbers
  UNION ALL
    SELECT
      x,
      CASE WHEN y MOD i = 0 THEN y DIV i ELSE y   END, 
      CASE WHEN y MOD i = 0 THEN i       ELSE i+1 END,
      CASE WHEN y MOD i = 0 THEN 1       ELSE 0   END
    FROM factors
    WHERE y > 1
)
SELECT x, GROUP_CONCAT(i ORDER BY i SEPARATOR ' ') AS primes
FROM factors 
WHERE divided = 1
GROUP BY x
ORDER BY x;
```

実行結果は以下の通りです。

|x|primes|
|:-|:-|
|2|2|
|3|3|
|4|2 2|
|5|5|
|6|2 3|
|7|7|
|8|2 2 2|
|9|3 3|
|10|2 5|
|11|11|
|12|2 2 3|
|13|13|
|14|2 7|
|15|3 5|
|16|2 2 2 2|
|17|17|
|18|2 3 3|
|19|19|
|20|2 2 5|
|21|3 7|
|22|2 11|
|23|23|
|24|2 2 2 3|
|25|5 5|
|26|2 13|
|27|3 3 3|
|28|2 2 7|
|29|29|
|30|2 3 5|
|31|31|
|32|2 2 2 2 2|
|33|3 11|
|34|2 17|
|35|5 7|
|36|2 2 3 3|
|37|37|
|38|2 19|
|39|3 13|
|40|2 2 2 5|
|41|41|
|42|2 3 7|
|43|43|
|44|2 2 11|
|45|3 3 5|
|46|2 23|
|47|47|
|48|2 2 2 2 3|
|49|7 7|
|50|2 5 5|
|51|3 17|
|52|2 2 13|
|53|53|
|54|2 3 3 3|
|55|5 11|
|56|2 2 2 7|
|57|3 19|
|58|2 29|
|59|59|
|60|2 2 3 5|
|61|61|
|62|2 31|
|63|3 3 7|
|64|2 2 2 2 2 2|
|65|5 13|
|66|2 3 11|
|67|67|
|68|2 2 17|
|69|3 23|
|70|2 5 7|
|71|71|
|72|2 2 2 3 3|
|73|73|
|74|2 37|
|75|3 5 5|
|76|2 2 19|
|77|7 11|
|78|2 3 13|
|79|79|
|80|2 2 2 2 5|
|81|3 3 3 3|
|82|2 41|
|83|83|
|84|2 2 3 7|
|85|5 17|
|86|2 43|
|87|3 29|
|88|2 2 2 11|
|89|89|
|90|2 3 3 5|
|91|7 13|
|92|2 2 23|
|93|3 31|
|94|2 47|
|95|5 19|
|96|2 2 2 2 2 3|
|97|97|
|98|2 7 7|
|99|3 3 11|
|100|2 2 5 5
AZ-900 Azure Fundamentals を4日で取得

AZ-900 Azure Fundamentals を4日で取得したので、どういう勉強をしたかの共有です。

やった勉強は2つ。

・Udemy
　　【6万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問)
・参考書
　　徹底攻略　Azure Fundamentals 教科書

まず、Udemyでひたすら問題を解きました。AZ900模擬試験１からAZ900模擬試験５。
【オプショナル】高難度の模擬試験６（2回分）は解かなくていいです。
実際の試験では難しい問題は数個なので、合格を目的にするなら解かなくていいです。1000点取りたかったら解きましょう。

Udemyで問題を解くことで、どういう単語があるのかと問題の傾向をまず頭にいれました。

次に教科書。
頭の中に散らばっている単語や機能を、教科書で整理。

最後に、Udemyの問題集の2回目解きます。
2回目は1-5回とも合格点を超えました。
ここまで出来たら余裕で合格できます。

試験時間20分で857点で合格しました。

勉強時間は、会社の休み時間や通勤時間を使って勉強(Udemy)して、定時後は2時間ぐらい勉強しました。
合計10時間程度です。
絵コンテをＡＩで生成する

面白いサービスを発見した

https://prtimes.jp/main/html/rd/p/000000014.000040654.html:embed:cite


最近はただでさえ、生成ＡＩがブームだというのに、やや世間の反応は冷ややかなものである。

それはまだ、どこかしか試行錯誤段階にあると言うのが、全体的な課題だと思える。

# 作ってみた

とりあえず、自分の過去のブログ記事を題材に突っ込んでみた。

https://lifehacking1919.hatenablog.jp/entry/2023/09/30/034000

できたページがこれ

![life_動画台本_20230930081243_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/4064a20b-d15f-777c-3b94-d9b762197f7d.jpeg)
![life_動画台本_20230930081243_page-0002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/917ed197-5b6a-22fb-f6dc-77fd268be350.jpeg)
![life_動画台本_20230930081243_page-0003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/37405922-73d8-f119-b2e7-97a2650070e0.jpeg)
![life_動画台本_20230930081243_page-0004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/bdcb6883-d95f-393b-6721-01f3977d2d91.jpeg)
![life_動画台本_20230930081243_page-0005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/0e70ca2f-43ed-6e02-d939-f4c74a1e38c0.jpeg)
![life_動画台本_20230930081243_page-0006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/2ca62804-a9fa-e960-ff8f-67b227774dec.jpeg)
![life_動画台本_20230930081243_page-0007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/bb7de271-7649-3934-c4f6-68688d40709b.jpeg)



これって、どうなんだろうか・・・
Javaで「文字列や他の値を追加する」の動作を確認してみた

# 概要

Javaで「文字列や他の値を追加する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/stringbuilder/index1.html

# 実装

以下のファイルを作成しました。
```JSample1_2.java
class JSample1_2{
  public static void main(String[] args){
    StringBuilder sb = new StringBuilder();
    sb.append("Hey");
    sb.append(75.2);
    sb.append(18L);
    sb.append(true);

    System.out.println(sb.toString());
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample1_2.java 
$ java JSample1_2 
Hey75.218true
```

# まとめ

何かの役に立てばと。
【React】key属性があることで解決してくれる問題

:::note info
開発者は key プロパティを与えることで、異なるレンダー間でどの子要素が変化しない可能性があるのかについてヒントを出すことができる。
:::

### keyがない場合
Reactは、DOMノードの子に対して再帰的に処理を行う場合、両方の子要素リストのそれぞれ最初から同時に処理を行っていって、差分を見つけたところで毎回更新を発生させる。

具体例：子ノードの最後に一つ要素を追加する場合

##### うまく動作するケース
```typescript
<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>
```
Reactは2つの `<li>first</li>` ツリーを一致させ、2つの`<li>second</li>`ツリーを一致させ、最後に`<li>third</li>`ツリーを挿入する。


##### 非効率なケース
```typescript
<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>
```


:::note warn
先頭への要素の追加はパフォーマンスが悪くなってしまう。
React は `<li>Duke</li>` と `<li>Villanova</li>` サブツリーをそのまま保てるということに気づくことなく、すべての子要素を変更してしまい,この非効率性は問題になることがある。
:::

### keyの使用
上記の問題を解決するために、key属性を使用する。

:::note info
子要素が key を持っている場合、React は key を利用して元のツリーの子要素と次のツリーの子要素を対応させる。
下記のコードの場合、これで React は、'2014' の key を持つ要素が新規の要素であり、'2015' と '2016' の key をもつ要素は移動しただけだ、と理解してくれる。
:::

```typescript
<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>
```
Ubuntu Desktop22.04に日本語化

言語を日本語でインストールしても実際ログインしてみると普通に英語…
なので日本語化することにした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/a3794eac-592a-bfd6-070f-fad9fce804ae.png)

まず、設定を開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/0b393002-926a-488d-926b-4be21bfc9d73.png)

「Region＆Language」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/dd2b085d-5085-7211-09e1-7433e8e971d7.png)

Languageが「日本語」になっていることを確認し
「Manage installed Languages」をクリックしてインストール
パスワード求められるので入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/a05fcc64-109d-3214-5ffc-30dfa9f50f15.png)

「システム全体に適用」を押下　　

再起動する

日本語化完了！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/b244b888-d7dd-584b-6be8-918068e60034.png)
Deployment ManagerでJinjaを使ってデプロイする

# 構成ファイルを作成する
deploy.yml、vm-jinja-template.jinja、parameter.jinjaを作成します。
以下の内容をそれぞれのファイルに記述してください。
```yaml:deploy.yml
imports:
- path: vm-jinja-template.jinja
- path: parameter.jinja

resources:
- name: jinja-template
  type: parameter.jinja
```
```yaml:vm-jinja-template.jinja
resources:
- name: {{ properties["name"] }}
  type: compute.v1.instance
  properties:
    zone: {{ properties["zone"] }}
    machineType: zones/{{ properties["zone"] }}/machineTypes/{{ properties["machineType"] }}
    disks:
    - deviceName: boot
      type: PERSISTENT
      boot: true
      autoDelete: true
      initializeParams:
        sourceImage: {{ properties["sourceImage"] }}
    networkInterfaces:
    - network: global/networks/default
```
```yaml:parameter.jinja
resources:
  - name: jinja-template
    type: vm-jinja-template.jinja
    properties:
      name: demo-jinja-vm01
      zone: us-west1-a
      machineType: e2-micro
      sourceImage: projects/debian-cloud/global/images/family/debian-11
```

# デプロイメントを実行する
CloudShellで以下のコマンドを実行してください。
```
$ gcloud deployment-manager deployments create demo-jinja-deploy --config deploy.yml
```

# インスタンスの作成を確認する
GCPコンソールでComputeEngineを表示してください。
![スクリーンショット 2023-09-30 6.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/041337d9-ed45-082e-4a5e-4af6078b18ce.png)


# デプロイメントを確認する
以下のコマンドを実行してください。
```
$ gcloud deployment-manager deployments list
```

# デプロイメントを削除する
以下のコマンドを実行してください。
```
$ gcloud deployment-manager deployments delete demo-jinja-deploy --async
```
Deployment ManagerでYAMLを使ってデプロイする

# 構成ファイルを作成する
deploy.ymlを作成し、以下の内容を記述してください。
```yaml
resources:
- name: demo-yaml-vm01
  type: compute.v1.instance
  properties:
    zone: us-west1-a
    machineType: zones/us-west1-a/machineTypes/e2-micro
    disks:
    - deviceName: boot
      type: PERSISTENT
      boot: true
      autoDelete: true
      initializeParams:
        sourceImage: projects/debian-cloud/global/images/family/debian-11
    networkInterfaces:
    - network: global/networks/default
```

# デプロイメントを実行する
CloudShellで以下のコマンドを実行してください。
```
$ gcloud deployment-manager deployments create demo-yaml-deploy --config deploy.yml
```

# インスタンスの作成を確認する
GCPコンソールでComputeEngineを表示してください。
![スクリーンショット 2023-09-30 6.14.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/e7ab0311-2329-980b-fbd9-be285e51d921.png)

# デプロイメントを確認する
以下のコマンドを実行してください。
```
$ gcloud deployment-manager deployments list
```

# デプロイメントを削除する
以下のコマンドを実行してください。
```
$ gcloud deployment-manager deployments delete demo-yaml-deploy --async
```
【Windows向け】GitHubでSSH接続時にパスフレーズを要求されないように設定

## 環境
Windows10 Pro
git 2.39.1 (scoopでインストール)

## 参考記事
https://www.azciel.co.jp/blog/2021/10/29/windows-vscode-ssh/

https://untitledreport.com/windows%E7%92%B0%E5%A2%83%E3%81%AB%E3%81%A6git%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%B8ssh%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B/

https://tktechblog.hatenadiary.jp/entry/2017/10/09/105702

## はじめに
GitHubのSSH接続にて、passphraseを設定するとコミットやプッシュ時に毎回passphraseを入力しなければならなかったため、その解決方法を備忘録としてここに記します。
GitでSSH認証を済ませている前提で話すため、
SSH認証がお済みでない方は、以下の記事を参考に認証を済ませてから読み進めてください。

https://qiita.com/inakuuun/items/3c1116027cb97135a8db

## 問題
ssh接続によるGitを使ったコミットやプッシュを実施した際にpassphraseを入力しなければならない。
```
> git push origin name_of_branch
Enter passphrase for key '/Users/[user_name]/.ssh/id_ed25519':
```
毎回要求されるのはしんどいので、要求されないようにする

## Gitコマンドに秘密鍵を設定
gitコマンドが発行される際に、「とあるgitのリポジトリ(ホスト)と通信する際にはこの鍵を使ってね」と設定する場所が`C:\Users\user/.ssh/config`ファイル。このconfigファイルに、以下のように記載して保存する
- `Host` = 鍵を使い分ける単位を指定するためのもの。区別できればなんでもいい。
  - `HostName` = GitHubのホスト名もしくはIPアドレスなので「github.com」で良い
  - `IdentityFile ` = 当該ホストへの接続に使用したい秘密鍵のフルパス
  - `User ` = 「git」で良い
詳しくは次を参照すると良い => https://qiita.com/miriwo/items/976d21e9a42fd3b01d08
```
Host github
  HostName github.com
  IdentityFile C:\Users\user\.ssh\id_ed25519
  User git
```

## SSHサービスが動いていない
- 毎回passphraseを要求される原因はWindowsのssh-agentが動いていなかったことだったが、`ssh-add -l`コマンドでssh-agentが動いているか確認
```
ssh-add -l
Could not open a connection to your authentication agent.
```
`Could not open a connection to your authentication agent.`を直訳すると、「認証エージェントへの接続を開けませんでした。」になる。(SSHサービスが動いていない)

## OpenSSHサービスの起動
- 「Win + Q」で、サービスと打ち込んで実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/6a3addfb-b341-8c34-37c9-0d8d0d2c0c33.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/90029860-2ca8-0fcb-e466-37f9b00ae3e2.png)

- `OpenSSH Authentication Agent`をダブルクリックし、スタートアップの種類の「自動」を選択し、「適用」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/ef0deca3-c8a8-59c1-cac4-3d222a544edd.png)

- 緑の三角ボタンをクリックしてサービスを開始
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/5c992c07-84f7-9c22-a725-8883f560b05a.png)

## 秘密鍵の登録
- `ssh-add sshの秘密鍵ファイルのパス`を実行
```
ssh-add .ssh/id_ed25519
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/92531a09-0521-3b1c-b686-8c8758550ce7.png)

## Gitがssh-agentを利用するように設定
- 以下のコマンドを実行して、Gitの設定を、WindowsのOpenSSHを見に行くように設定。
この設定ができてないと、先ほど設定したはずのパスフレーズを聞かれたり、vscodeからpushしようとしたときに、 C:\Users\user/.ssh/config を見に行ってくれなかったりする
```
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"
```

## Git で push
- pushを実行すると、passphraseを求められることはなくなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/f212c1a2-d1e5-6cfb-472d-9654f28076f7.png)
【Windows版】GitHubでSSH認証

## 環境
- Windows 10 Pro
- Git 2.39.1.windows.1

## 参考サイト
https://untitledreport.com/windows%E7%92%B0%E5%A2%83%E3%81%AB%E3%81%A6git%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%B8ssh%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B/

https://qiita.com/suthio/items/2760e4cff0e185fe2db9

https://onoredekaiketsu.com/generate-key-pair-for-public-key-authentication-in-windows10-and-connect-to-server-with-ssh/

https://zenn.dev/urin/articles/347f6e5b9b0628

## SSHキーを作成
- SSHキーを格納するための.sshディレクトリを作成
C:\Users\ユーザー名 直下に.sshディレクトリがない場合は、秘密鍵や公開鍵を格納する必要があるため、mkdirコマンドで.sshディレクトリをユーザーディレクトリ直下に作成します。
```
mkdir ~/.ssh
```

- `ssh-keygen`コマンドを実行して、SSHキーを作成
`-t` = 署名アルゴリズムの指定
`-f` = ファイル名の指定
`-C` = コメント(※コメントとしてGitHubに登録しているEmailを残す風習があるらしい)

```
ssh-keygen -t ed25519 -f .ssh/id_ed25519 -C "your_email@example.com"
```
passphraseが2回求められるので、任意で設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/add50cf8-bc8e-e201-51e6-e5f36bf00afd.png)

- 秘密鍵と公開鍵が作成されていることを確認
※「C:\Users\ユーザー名\.ssh」に作成される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/e9180284-d458-7b3d-cff7-8202c5439c7d.png)

## 公開鍵をGitHubに貼り付け

- メモ帳やサクラエディタ、VSCodeなどで開いて、公開鍵を全てコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/42f19b3c-617c-728c-dbb3-3cdb863ced45.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/01e6ca18-2795-2670-e6d3-a6c3ea614c83.png)

- GitHubにログインして、「Settings」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/bb82fab4-db9b-45a4-a4da-f6e653cc0f57.png)

- GitHubのSSH Keyを管理しているダッシュボードにアクセス
`SSH and GPG keys`をクリック後、`New SSH key`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/6d9b10bf-fe1f-2454-c8c5-1fde7c188708.png)

- コピーし、公開鍵の内容を全て貼り付けて「Add SSH key」をクリック
`Title` = 識別しやすい任意のタイトル
`Key` = エディタでコピーした公開鍵(全部コピーしてそのまま貼り付ける)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/1b068955-e468-5713-eb94-d12b9614c337.png)

## 接続確認
`ssh -T git@github.com`コマンドを実行して疎通確認
```
> ssh -T git@github.com
Hi inakuuun! You've successfully authenticated, but GitHub does not provide shell access.
```
`Hi inakuuun! You've successfully authenticated, but GitHub does not provide shell access.`のメッセージが表示されればOK

## プッシュ時などで毎回パスフレーズを要求されないように設定
パスフレーズを要求されないように設定する手順は下記の記事を参照ください。

https://qiita.com/inakuuun/items/0dd0288461d3a4718d3b

GitHubのSSH認証を行う手順は以上になります。
POV-rayを使った3DCGの描画・アニメーション作品紹介

### ㊗︎初投稿
はじめまして！Reishinと申します.
記念すべき１投稿目、POV-rayでできることや作品例を紹介していきたいと思います！

実は私のプロフィール画像のカエルもPOV-rayで制作したものです🐸

## POV-rayってなんぞ？？
レイトレーシング技術を用いた「**３次元コンピュータグラフィクス**」を制作できるツールです.

ちなみに・・・
レイトレーシング(ray-tracing, 光線追跡法)とは
ざっくり言うと、物体に対して光の当たり具合をシミュレーションしてくれる技術のことです.
この技術があるかないかで、画像のリアル度が大幅に変わります.

## どうやって作るんじゃ？？
図形同士を組み合わせたり引いたりする！！！
Cube(立方体), Sphere(球), Cylinder(三角錐)など使いたい立体図形の、座標位置や大きさ、角度などをコードで調整して作り上げていきます.(((地道

図形同士を引くというのは、例えば
立方体から球を引いて、立方体に球形の穴を作ったりなど.

## 実際どういうのが作れるの？？　〜作品紹介〜

こんなのが作れます.

#### カエルくん
![input.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530344/56d226ae-23e5-d1fb-25fe-e015e21fbb75.jpeg)
この子は、Sphere(球体)のみを組み合わせて作成しました.

え？この葉っぱの茎部分はどうしたのかって？
鋭い指摘ですね・・・

実は茎部分はよ〜〜〜く見るとSphereが連なっているのです！
ちょこっとだけコードを見せます.
```
	// stem
	   union{
	   #declare Kara4 = -1.4;
	   #declare Made4 = 2.3;
	   #declare T4 = Kara4;

	   #while (T4 < Made4)
    	    #declare X4 = T4;
     	    #declare Y4 = (1/4) * X4 * X4 - 0.15;
     	    object {
   		   Sphere
   		   pigment { color DarkGreen }
   		   scale 0.03
   		   translate <X4, Y4, -0.145>
   		   rotate <0, 0, -120>
  	    }
   	   #declare T4 = T4 + 0.01;
	   #end
```
何をしているかと言うと、
-1.4 <= x座標 < 2.3 の範囲を0.01ずつ変化させるごとに
y = 1/4 * x^2 - 0.15 に当てはめてy座標を算出し
求まったxy座標の位置にSphereを設置しています.

そう、茎の部分は実は２次関数になっているんです.

```
	// mouth
	#declare Kara = -0.7;
	#declare Made = 0.7;
	#declare T = Kara;

	#while (T < Made)
 	  #declare X = T;
  	 #declare Y = (1/3) * X * X + -0.15;
  	 object {
   		Sphere
   		pigment { color Black }
   		scale 0.01
   		translate <X, Y, -0.47>
  	 }
   	#declare T = T + 0.01;
	#end
```
口の部分も同じ要領です.
こちらは y = 1/3 * x^2 - 0.15 ですね.

![kadai4_animated.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530344/66597af9-42f9-8e6b-bc31-a82f0dd9de78.png)
アニメーションにもできちゃいます.👀

#### 汽車
![スクリーンショット 2023-09-30 1.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530344/f8c52213-89e3-d2bd-a923-e77ed97c6135.png)

Sphereはもちろんのことcubeやcylinderも使っています.
また、図形同士を組み合わせるだけでなく、引いています(窓や荷台部分).

```
difference {
	object {
		Cube
		texture { T_Wood4 }
		scale <0.8, 0.35, 0.6>
		translate <-1.9, 0.2, 0>
	}
	object {
		Cube 
		texture { T_Wood10 }
		scale <0.65, 0.25, 0.5>
		translate <-1.9, 0.4, 0>
	}
}
```
この部分は、２車両目の部分で、CubeからCubeを引いて穴を開けています.

## 最後に

約１年前に作成して以来、POV-rayは触ってなかったため、時間を作ってまた何か制作したいな〜〜〜と考えています.
コード自体は書きやすいのですが、座標の調整が大変で地道な作業にはなります.
その分、完成した時の達成感は尋常じゃないです！

ぜひ、この機会にPOV-rayを始めてみてはどうでしょうか？

ここまでお付き合いくださり、ありがとうございました！
UbuntuをCドライブからDドライブに移す方法

# はじめに
Cドライブの容量を空けるためにUbuntuをDドライブに移す方法を記載します。

# 手順
1. エクスプーローラーでUbuntuを移したいフォルダを作成しておく(ここではwslという名前にしておく)
2. Windows PowerShellを管理者権限で開く
3. 以下のコードで手順1で作成したフォルダに移動する
   ```
   cd D:\
   cd wsl
   ```
4. Ubuntuを.tarファイルとしてエキスポート。Ubuntu-22.04の部分は使用しているディストリビューションの名前にする。
   ```
   wsl --export Ubuntu-22.04 ubuntu.tar
   ```
5. UbuntuのWSLからの登録解除を行う。Ubuntu-22.04の部分は使用しているディストリビューションの名前にする。
   ```
   wsl --unregister Ubuntu-22.04
   ```
6. 登録解除が行われたかの確認を行う。「サブシステムには、ディストリビューションがインストールされていません」と表示されていれば、登録解除成功。
   ```
   wsl -l -v
   ```
7. 最初に作った.tarファイルから元のUbuntu環境を引越し先に復元する
   ```
   wsl --import Ubuntu-22.04 D:\wsl D:\wsl\ubuntu.tar
   ```
8. 引越し完了

# 参考

https://zenn.dev/shittoku_xxx/articles/066cfd072d87a1#2.%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E5%A4%89%E6%9B%B4
VSCode に インストール済みの拡張機能をデバッグする

# はじめに

VS Code の拡張機能がなんかおかしい、うまく動いていないといったときにデバッグする方法のメモ

基本的には↓のスレッドに記載のとおり。

https://stackoverflow.com/a/67099176/1868209

# 試した環境は以下の通り

Windows PC で WSL2 上で VS Code が動作している

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/f8f0186b-de63-5769-1b66-f4625f780315.png)

この VS Code の 拡張機能を、Windows 上の Edge の DevTools でデバッグ

devcontainer は未検証

# 手順

## extension host の プロセスを特定する

VS Code の拡張機能は、extension-host というプロセスで動いているそうです。

https://code.visualstudio.com/api/advanced-topics/extension-host

そのプロセスの PID を探します。

```bash
PID=$(pgrep -f ".*--type=extensionHost")
echo $PID
132242
```

```bash
ps 132242
    PID TTY      STAT   TIME COMMAND
 132242 pts/5    Rl+    4:27 /home/toshida/.vscode-server/bin/abd2f3db4bdb28f9e95536dfa84d8479f1eb312d/node --dns-result-order=ipv4first /home/toshida/.vscode-server/bin/abd2f3db4bdb28f9e95536dfa84d8479f1eb312d/out/bootstrap-fork --type=extensionHost --transformURIs --useHostProxy=true
```

## inspector を有効にする

Node.js の仕組みで、`SIGUSR1` シグナルを送ると、そのプロセスで inspector が起動できるそうです。

https://nodejs.org/en/docs/guides/debugging-getting-started#enable-inspector

```bash
kill -SIGUSR1 $PID
```

このコマンドでは、該当のプロセスは動きつづけたままとなり、停止や再起動されるわけではありません。

## inspector の listen ポートを特定する

inspector が listen してるポートを探します。

```bash
$ lsof -p $PID  -a -i4tcp
```

こんな感じで、`SIGUSR1` シグナル送信後には、LISTEN が増えているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/872bcef6-0186-b067-3f5f-67c2b6326a06.png)


## DevTools(Chrome / Edge) から接続する

`edge://inspect/#devices` からリモート接続をします。

https://learn.microsoft.com/ja-jp/microsoft-edge/devtools-guide-chromium/remote-debugging/local-server


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/70d7d3cf-7d47-54eb-1579-cc9c222a5ab7.png)

`inspect` のリンクで別ウィンドウが開きます。

## Debug する

ワークスペースに、実際の拡張機能のコードがあるフォルダを追加して、アクセスを許可します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/72930d75-be0d-7a9a-1aa2-600f84ccb7a6.png)

目的の拡張機能のファイルを探します。
Azure 系だと、代替 `dist/extension.bundle.js` になると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/44338781-da90-62e7-70c2-a0673f4c3e56.png)

デフォルトでは bundle.js は無視リストに入っているのでデバッガが止まりませんので、解除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/af222ded-7e7d-415a-ab44-915e92f4a13d.png)

あとはブレークポイントを追加したりは、普通の使い方です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/3b476c7b-44fd-6287-2015-18b0d5037f6f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/48be38ea-1246-54c1-2055-22aed3cf75d8.png)

ブレークポイントの使い方については、↓でも少し書いてた

https://qiita.com/georgeOsdDev@github/items/bb2667a5bb5f06ef29fa#breakpointslogpoints-%E3%81%AE%E8%A8%AD%E5%AE%9A


Happy Hacking!
PythonパッケージをPyPIに公開するはじめの一歩

この記事では、簡単な Python パッケージを PyPI に公開する方法を解説します。

## PyPI とは

[PyPI](https://pypi.org/) とは、Python Package Index の略で、Python のパッケージを公開するためのリポジトリです。
Python で書かれたソフトウェアとライブラリを公開、共有するための中央リポジトリとしての役割を果たしています。

### 仕組み

* パッケージの公開: 開発者は自分が作成した Python パッケージを PyPI にアップロードします。
* パッケージの検索とダウンロード: `pip`` はこの PyPI からパッケージを検索し、ダウンロードしてインストールします。

## 1. PyPI のアカウントを作成する

1. [PyPI のアカウント作成ページ](https://pypi.org/account/register/) にアクセスし、アカウントを作成します。
2. 二要素認証（2FA）を有効にします。[PyPI のアカウント設定ページ](https://pypi.org/manage/account/) にアクセスし、`Add 2FA with authentication application` から 2FA を有効にします。
3. 同じページで API トークンを作成します。API トークンの項目で `API トークンの追加` をクリックし、トークンを作成します。
4. `.pypirc` というファイルをホームディレクトリに作成します。以下のように記述します。
    ```ini:.pypirc
    [pypi]
    username = __token__
    password = <3 で作成した API トークン>
    ```

## 2. パッケージを作成する

ここではランダムな「コンプリメント」（褒め言葉）を生成するパッケージを作成してみます。
まずディレクトリを作成します。

```console
mkdir compliment_generator
cd compliment_generator
```

次に、プロジェクトディレクトリ内に `compliment_generator.py` という Python ファイルを作成します。

```python:compliment_generator.py
import random

def generate_compliment():
    compliments = [
        "You look great today!",
        "You're a smart cookie!",
        "I like your style!",
        "You're the bee's knees!"
    ]
    return random.choice(compliments)

```

次に `setup.py` というファイルを作成します。

```python:setup.py
from setuptools import setup

setup(
    name='compliment_generator',
    version='0.1',
    py_modules=['compliment_generator'],
    install_requires=[],
)
```

## 3. パッケージのビルド

`setup.py` が存在するディレクトリで以下のコマンドを実行します。

```console
python setup.py sdist bdist_wheel
```

## 4. パッケージを PyPI にアップロードする

`twine` というパッケージをインストールします。

```console
pip install twine
```

`twine` を使って PyPI にアップロードします。

```console
twine upload dist/*
```

## 最後に使ってみる

### インストール

```console
$ pip install compliment-generator
  Downloading compliment_generator-0.1-py3-none-any.whl (1.4 kB)
Successfully installed compliment-generator-0.1
```

### 実行

```console
$ python
Python 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import compliment_generator
>>> compliment_generator.generate_compliment()
'I like your style!'
>>> compliment_generator.generate_compliment()
"You're the bee's knees!"
```

以下のページから今回作成したプロジェクトを確認できます。
<https://pypi.org/project/compliment-generator/>
PrismaのSchemaの@idと@@idの違い

# TL;DR
`@id`は一つのフィールドの値をそのまま主キーにしたいときに使う属性です。
`@@id`は、複数のフィールドの値を組み合わせた値を主キーにしたいときに使う属性です。

## `@id`を使ったサンプルコード
```schema.prisma
model User {
  id   String @id
  name String
}
```

```
const newUser = await prisma.user.create({
  data: {
    id: 1,
    name: 'Alice',
  },
})
```

上記のコードでnewUserを作成した場合、このnewUserの主キーidは1になります。

そのため、以下のコードで一意のuserを探すことができます。
```
const user = await prisma.user.findUnique({
  where: {
    id: 1,
})
```


## `@@id`を使ったサンプルコード
```schema.prisma
model User {
  id   String
  name String
  @@id([id, name])
}
```

```
const newUser = await prisma.user.create({
  data: {
    id: 1,
    name: 'Alice',
  },
})
```

上記のコードでnewUserを作成した場合、newUserの主キーid_nameは、1_Aliceになります。

そのため、以下のコードで一意のuserを探すことができます。
```
const user = await prisma.user.findUnique({
  where: {
    id_name: {
      id: 1,
      name: 'Alice',
    },
  },
})
```

# そもそも@と@@の違い
属性は、フィールドやブロックの動きを編集するのですが、データモデルに属性を追加するのには2つの方法があります。

フィールドに対して属性を追加するなら、属性の頭に`@`をつけます。
ブロックに対して属性を追加するなら、属性の頭に`@@`をつけます。

`@id`と`@@id`の他に、`@map`と`@@map`のような属性も存在します。

---
**ここから下は意見です。**
# 複合主キーのデメリット
主キーとして用いているフィールドの値に修正が入った場合に、修正コストが高いです。
例えば、Aliceさんが名前を、Bobさんに変更した場合は`1_Alice`が`1_Bob`に変更になります。
外部テーブルからこのレコードが参照されている場合、そちらも変更する必要があります。

# `@id`と`@@id`のどちらを使うべき？
複合主キーのフィールドの値が二度と変更されない場合は、複合主キーを使っても良いです。
例えば、下記のような中間テーブルでは、postIdとuserIdは変更される可能性が低いので使うことができます。
```
model Like {
  postId String
  userId String
  @@id([postId, userId])
}
```
しかし、基本的には、サロゲートキーを使うべきです。

# 参考文献
https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#remarks-5
https://scrapbox.io/mrsekut-p/サロゲートキー_v.s._複合主キーでは、前者を選ぶ
https://zenn.dev/kaz_z/articles/prisma-unique-key
https://scrapbox.io/mrsekut-p/ナチュラルキーがある時はサロゲートキーは不要
初めてのチーム開発...

# チーム開発必要項目(Ruby on Rails)


- MVCモデルの再確認
- ER図
- GitHubの大まかな流れの確認
    - 統合ブランチってなに？
    - トピックブランチってなに？
    - add commit push
    - プルリク
    - merge
- その他
    - マークダウン記法など


【所感】
　おそらく、苦労するのがGitHub。個人で開発するのと違い、トピックブランチやマージ、checkoutの部分で混乱を起こす可能性あり。そこらへんがイメージできていれば、なんとなく行けるかもしれない。まー、他にも難しいと感じる部分はたくさんあると思うけど。
【Ruby on Rails】FactoryBot,Fakerの導入

### 各Gemの説明
① factory_bot_rails
model のデータに紐づいたテストデータを簡単に作るための gem です。
② faker
faker は、ダミーデータを作るのに便利な gem です。

### Gemの導入方法
```ruby:Gemfile
# 中略
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'pry-byebug'
  gem 'pry-rails'
  gem 'rspec-rails'
+  gem 'factory_bot_rails'
+  gem 'faker'
end

# 中略
```
追加したら、`bundle install`を実行します。

### 各ファイルの修正
**factory_bot_rails**
```ruby:spec/rails_helper.rb
# 中略

RSpec.configure do |config|
+  config.include FactoryBot::Syntax::Methods
# 中略
end

# 中略
```
上記のように修正することで、FactoryBot のメソッドを省略した形で呼び出すことができるようになります。

**faker**
```ruby:spec/rails_helper.rb
+ Faker::Config.locale = :ja
```
上記の修正を行うことで、Fakerで作成されるダミーデータが日本語になります。

**application.rbの修正**

```ruby:application.rb
    # 中略
    config.generators do |g|
      g.javascripts false
      g.stylesheets false
      g.helper false
      g.template_engine false
-      g.test_framework false
+      g.test_framework :rspec
    end
    # 中略
  end
end
```
modelやcontrollerを作成するタイミングでrspec のテストファイルも同時に作成されるようになります。
具体的には、`bundle exec rails g`を実行したときに、新しいmodel,contorollerファイルだけでなく、テストファイルも作成されます。

以上、FactoryBot,Fakerの導入でした。
【Ruby on Rails】rspec-railsの導入

### RSpecとは
RubyやRuby on Railsでテストを書く際に最も使われているフレームワークです。
作成したクラスやメソッドをテストすることができます。

### rspec-railsの導入方法
rspec-railsというGemを用いて導入します。
Gemfileに下記のように記述します。

```ruby:Gemfile
# (中略)

group :development, :test do
  # (中略)
  gem 'rspec-rails'
end

# (中略)
```

上記のように記述できたら、`bundle install`を行います。

次に下記のコマンドを実行します。
```
$ bundle exec rails generate rspec:install
```

```ruby
Running via Spring preloader in process 64223
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```
実行すると、3つのファイルが作成されます。
① .rspec
　RSpecの設定を記述するファイル(実行時の設定を行うファイル)
② spec_helper.rb
　RSpec全体の設定を記述するファイル
③ rails_helper.rb
　Railsに関するRSpecの設定を記述するファイル

### ファイルの修正

デフォルトでgit管理外になっているので、.rspecを.gitignoreから外す。

```ruby:.gitignore
（中略）

- .rspec

（中略）
```
次に.rspecファイルを修正します。
デフォルトでは、spec_helperを読み込んでいます。
```ruby:.rspec
--require spec_helper
```

以下のように修正しましょう。
```ruby:.rspec
--require rails_helper
--format documentation
--color
```

1.spec_helperを読み込んでいたが、rails_helperを読み込むようになります。
2.テストを実行すると、テスト内容をログとして出力してくれるようになります。
3.テストを実行すると、テスト結果の表示に色を使ってくれるようになります。

以上で、rspec-railsの導入は終了です。

次回はテスト実装でよく使われるgemの導入について記載します。
【React】特定のpropsが更新された際に全てのstateをリセットする

以下のように記述することでuserIdが更新された際に全てのstateをリセットすることができます。

```jsx
export default function Parent({ userId }) {
  return (
    <Child
      userId={userId}
      key={userId}
    />
  );
}

function Child({ userId }) {
  const [comment, setComment] = useState('');
}


```
【SQL Server】圧縮バックアップ

# 検証のきっかけ
最近SQL Serverの移行に携わることが増えてきました。
やはりお客様としては、なるべくデータ移行の時間を短縮したいという想いがあります。
1つの手段として圧縮バックアップがありますが、圧縮しない場合とした場合の差を比較したことがなかったので試してみました。

## バックアップファイルのサイズ
後程更新予定

## バックアップ時のCPU使用率
パフォーマンスモニタにて監視した結果
| 圧縮あり | 圧縮なし |
|:-----------|------------:|
| 最大34%上昇       | 最大15%上昇       |

## バックアップ時間
SSMSの経過時間の確認結果
| 圧縮あり | 圧縮なし |
|:-----------|------------:|
|  5秒      | 13秒      |

## リストア時のCPU使用率
大きな変化は見られませんでした。

## リストア時間
SSMSの経過時間の確認結果
| 圧縮あり | 圧縮なし |
|:-----------|------------:|
|  3分41秒      | 4分37秒      |

## 検証結果
バックアップの圧縮時にCPU使用率が上昇するので、高負荷の環境だと勧められなさそう。
しかし、静止点を取った後であればCPUのリソースに空きもあると考えられるのでタイミングを見計らって実行することは可能かと。
ファイルサイズは大幅に変わるし、リストアの時間も短縮することができるので有効活用できると考えられる
Rocky Linux 9.2でswatchを導入するときのエラー対処

# 概要
Rocky Linux release 9.2にてログ監視ツールswatchを、CentOS7,8系での方法で導入しようとするとエラーが表示されてサービスが実行できないため、その対処方法を書きました。

## /etc/rc.d/init.d/functionsのエラー
```systemctl start swatch```を実行した時に次のようなエラーが表示されます。

```
/etc/rc.d/init.d/swatch: line 9: /etc/rc.d/init.d/functions: No such file or directory
```

この場合、initscriptsがインストールされていないことが原因なのでインストールします。

```
yum -y install initscripts
```

## Failed with result 'exit-code'のエラー

さらに次のようなエラーが発生することがあります。

```
Starting swatch (via systemctl):  Job for swatch.service failed because the control process exited with error code.
See "systemctl status swatch.service" and "journalctl -xeu swatch.service" for details.
                                                           [FAILED]
```

指示通り、``` journalctl -xeu swatch.service```すると次のようなエラーが確認できます。

```
swatch.service: Failed with result 'exit-code'.
Failed to start SYSV: swatch start/stopscript.
```

これだけでは原因がわからなかったのですが、```vi /var/log/swatch.log```を確認すると、```/etc/rc.d/init.d/swatch: line 25: swatch: command not found```と記録されていました。

どうやらRocky Linux9.2では、swatchの実行ファイル名が"swatchdog"に名前変更されていることで、既存のスクリプトが動かないようです。

```vi /etc/rc.d/init.d/swatch```でスクリプトを開き、25行目付近の"swatch"を"swatchdog"に修正します。

```:/etc/rc.d/init.d/swatchの25行目付近
            swatchdog --config-file $conf --tail-file $WATCHLOG \
            --script-dir=/tmp --awk-field-syntax --use-cpan-file-tail --daemon \
            --pid-file /var/run/swatch_$pno.pid \
            >> /var/log/swatch/swatch.log 2>&1

```

保存して、```systemctl start swatch```を実行すると正しくサービスが起動します。

おしまい

## 参考ページ
[ログ監視ツール導入(SWATCH) - CentOSで自宅サーバー構築](https://centossrv.com/swatch.shtml)
Uncaught TypeError: Cannot read properties of null のエラー対処

# エラーが起きた状況
DOM操作を行うjsファイルをhtmlから読み込んだ時、addEventListenerの行に上記のエラー
# エラーの意味
直訳で「nullのプロパティは読みこめない」と言う意味。
主に、タイプミスなどで間違ったidによってDOM操作を行った場合に起こるエラー。
しかし、以下に示すように要素の指定自体には問題はなかった。
```HTML:event.html
//前後省略
<body>
    <button id="output-btn">文字列の出力</button>
    <script src="js/event.js"></script>

    <button id="add-btn">リストの追加</button>
    <ul id="parent-list"></ul>
</body>

```

```JavaScript:event.js
//前後略
const addBtn = document.getElementById('add-btn');
addBtn.addEventListener('click', () => )
```
# 原因＆解決法
結論から言うと、htmlでscriptタグによりjsファイルを読み込む位置に問題があった。
JavaScriptを直接記入ではなく読み込む場合、scriptタグより下のHTML要素にJavaScriptは干渉できなくなってしまう。
そのため、scriptタグをbodyの一番下に記入するか、scriptタグにdefer属性を記述することで、この問題を解決できる。
以下改善後コード例
```diff_html:event.html
//前後省略
<body>
    <button id="output-btn">文字列の出力</button>
-    <script src="js/event.js"></script>

    <button id="add-btn">リストの追加</button>
    <ul id="parent-list"></ul>
+    <script src="js/event.js"></script>

</body>

```
```diff_html:event.html
//前後省略
<body>
    <button id="output-btn">文字列の出力</button>
-   <script src="js/event.js"></script>
+    <script type="text/javascript" src="event.js"></script>

    <button id="add-btn">リストの追加</button>
    <ul id="parent-list"></ul>
</body>

```
# おわりに
かなり簡単な内容でしたが、プログラミングのアウトプットの一環としてエラー対処を記録してみました。
誰かのお役に立てれば幸いです。
【React】複数のエラーをまとめてハンドリングするカスタムフックの作成

## はじめに
Reactの非同期通信でのエラーを処理する中で、1つのページで複数のエラーが発生したときに個々でエラーを処理していくのは手間なので、エラーを一元管理し、効率的にハンドリングする方法を考えてみました。

複数のエラーが発生しても個々のエラーで表示を変える必要がない場合に使用します。

## カスタムフックの作成
```ts
import { useEffect, useState } from "react";

export const useErrors = (...errors) => {
    const [error, setError] = useState(null);

    useEffect(() => {
        for (let i = 0; i < errors.length; i++) {
            if (errors[i]) {
                setError(errors[i]);
                break;
            }
        }
    }, errors);

    return error;
};
```
このカスタムフックは、複数のエラーオブジェクトを受け取り、エラーが変更されるたびに実行され、最初にエラーが検出されたらそれを error ステートにセットします。

その後、他のエラーを無視します。これにより、複数のエラーが発生した場合でも、最初に発生したエラーだけを取得できます。

## 使用方法
このカスタムフックを使用するには、以下のように複数のエラーを引数として渡します。

```ts
const error = useErrors(fetchError1, fetchError2);
```
このようにして、複数のエラーをまとめて一つの error 変数で管理することができます。最初に発生したエラーが error 変数にセットされ、それ以降のエラーは無視されます。これにより、コンポーネント内でエラーを効果的に管理し、適切に処理できるようになります。

## 最後に
もっと効率的な方法があるとは思うので、他にも思いついたら記事にしたいと思います。
データ解析面倒だから半自動化してみた

# はじめに
最近、データを触ってみたり、データ分析、機械学習に触れる経験を積むためにkaggleやNishika、signateなどのデータコンペに参加しています。
面白そうなコンペに参加しては、データを眺めたり、EDAしたり、ヒストグラム作成したりしてから、じゃあ機械学習するかーって感じで進めています。
今回はそれらの作業が面倒なのでアプリケーションを作成して勝手にやらせればいいのでは？と思い、Webアプリケーションを作成したのでまとめていこうと思います。

# 背景
機械学習に行う際には、様々な作業が発生します。
そこで1つ頭の中に
**面倒臭くね？**
一からコードを書くの面倒なんですよね。
ということでStreamlitでWebアプリケーションを作成すれば、勝手にやってくれるんじゃね？と思い立ち、作ってみました（かなり雑）

# 機能
今回付けた機能は以下の通りです。
1. データの概要確認（データ型、欠損値、統計値）
1. ヒストグラム、箱ひげ図
1. ヒートマップによる相関係数
1. LightGBMによる機械学習モデルの学習/推論（ハイパーパラメータの変更可）
1. 特徴量の重要度
1. 推論結果の保存

それでは見ていきましょう

# アプリの見た目
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/abc8475c-e3bb-1247-fd8a-92ba7156f140.png)

最初の画面はこのような感じとなっております。
では、適当にkaggleからタイタニックのデータを取ってきて読み込んでみます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/8eea0248-a10e-78fc-298e-8022d48db69e.png)

読み込むとこんな感じですね。
サイドバーにチェックボックスが表示されます。いわゆるページってやつです。
それでは``EDA``にチェックを入れてみましょう。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/4b8f334d-aeeb-85ea-fb59-70d5b7fc60b1.png)

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/cbc4a5bc-54b4-08a9-7096-e75f26ea13a9.png)

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/b46e7681-c547-ab25-714a-90f1291ce1dc.png)

このように、データの概要、ヒストグラム等が自動で表示されます。
これで面倒なコードを書かなくて済む…
なぜか、数値型のデータのみしか可視化できないようなので数値型のカラムだけを抽出して表示しています。

欠損値やデータ型も確認してるので、ここでデータフレーム自体を弄って欠損値補完したり、エンコーディングしたりデータ加工できればいいんですけど、イマイチやり方がわからないのでわかる方いましたら教えてください！！！
ちなみに、試しにやってみてはいたんですが、マルチセレクトを複数個用意した場合、データが保持できない問題が起きました。
例えば、欠損値補完をしたあとにエンコーディングしようとするとすべて処理がなかったことにされます。
どうにかできればいいんですけどね～。私の知っている限りでは難しいので今後実装します。

それでは、``ML``にチェックを入れてみましょう。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/2a2cb31d-5a43-b43d-f743-50c46ab4cf1d.png)

サイドバーにハイパーパラメータを設定できるようにスライダーを作成しました。
個人的にいつも設定しているパラメータを入れています。
内部関数には固定のパラメータは事前に設定しています（``metrics``や``boosting_type``など）。
見切れていますが、特徴量の重要度も可視化しています。

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/2b47544a-d305-1ab1-23a7-abc9eba85ed8.png)
最後にテストデータを読み込ませれば、自動でLightGBMにより推論し、結果を表示してくれます。
``csvファイルを保存``ボタンを押すことで結果を保存することができます。

# まとめ
ご覧いただきありがとうございます！
今回はデータ入れれば全部やってくれるアプリを作成しました。
作成時間はだいたい1～2時間でしたので、個人的には満足です。
今後はアプリ内でデータ加工できるようにスクリプトを修正していけたらと思いますので、アドバイスお願いいたしますm(__)m
それでは！！！
【HTML 学習】見出しタグについて

## 見出しタグのｈは何という単語の略か？
見出しタグの「ｈ」は「ｈｅａｄｉｎｇ」の略。
つまり日本語で言う「見出し」そのまんま。

## 見出しの種類は６種類だけ
見出しの種類は以下の６種類
![スクリーンショット 2023-09-29 13.52.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567236/2b6e3cc8-becd-6dbf-7101-32ce091218d5.png)
ｈ７やｈ８などを試しに入力してみたが思ったとおり、テキストとして表示される。そもそもタグとして存在していないので、当然のことか…
どうしてもｈ７やｈ８のような表現をしたい場合、`dlタグ` `dtタグ` `ｄｄタグ` を代用して表現することは可能。
自分が必要になることはない？かな？

## 見出しタグで目次の判断がされている
目次を自動で作成してくれる各種サービスにおいて、目次作成の判断は見出しタグでされる。
また、目次はSEO効果を向上させることにもつながるので、見出しを設定すると言うことは、SEO的にも重要。

## 見出しタグ使用上の注意点

### 見出しレベルは飛ばして使わない
ｈ１のつぎはｈ２、ｈ２の次はｈ３という風に順番に使用する。
```
良い例
<h1>果物の種類<h1>
<h２>りんご<h2>
<h3>王林・フジ・ジョナゴールド<h3>
```
```
悪い例
<h1>果物の種類<h1>
<h3>りんご<h3>
<h4>王林・フジ・ジョナゴールド<h4>
```

### ｈ１タグは1つのページに１回だけ使用する
検索エンジンクローラはｈ１タグに何が書かれているかによって、その記事の内容を判断する。ｈ１タグが複数あった場合、何のことについて書かれた記事なのかを検索エンジンクローラが判断できなくなる。結果、記事のSEOの評価が悪り検索順位にも影響する恐れがある。

### 文字の大きさを変えるために見出しを使わない
見出しタグはテキストの重要な事柄を検索エンジンに伝えるためのもので、文字の大きさを変えるために使用するとSEOの評価に悪影響を及ぼす恐れがある。
文字の大きさはCSSで調整する。
Hyperledger FireFlyのIPFSの調整


前回からの続きで、
今回は、NFTデータを取り扱ううえで非常に重要な機能でもあるIPFS環境についての紹介です。

## 環境構築からNFT生成までのステップ（前回からの続き）

* [初回紹介](https://qiita.com/LJC-mobileapps/items/bbcd43332fa180bac20a)
Hyperledger FireFly環境を新規でWeb3 ゲートウェイ機能を有効にしBinaceテストネットと通信できるようにします。

* [前回紹介](https://qiita.com/LJC-mobileapps/items/4ebea4439c142fc314ef)
BinaceテストネットトークンをFausetサイトから入手します。
Binaceテストネット上にNFT用のコントラクト（ERC-721ベース）をデプロイします。

* **今回紹介**
IPFS環境の調整

* 次回以降紹介
NFT用のコントラクトの関数などのメタ情報をFireFly側に登録します。
NFTとして扱う画像をFireFly側に登録します。
FireFly側に登録した画像をPublicに公開します。
NFTテキストデータをFireFly側に登録します。
FireFly側に登録したNFTテキストデータをPublicに公開します。
発行したNFTを他のユーザに転送して、ウォレットから確認します。

## IPFSとは
IPFS（InterPlanetary File System）は、分散型のファイルシステムで、データの保存と共有を改革的な方法で行うための技術です。
特にNFTとして、当該データを特定するための技術の中核をなす、データのハッシュ化およびコンテンツアドレッシングという機能を応用して実現しています。

### 冗長化とデータの管理形式

IPFSは、従来のWebのように中央集権化されたサーバーに依存するのではなく、分散型のネットワークで動作します。データは一意のハッシュ値で識別され、ユーザーがデータをリクエストすると、そのハッシュを使ってデータを検索し、取得します。これにより、データの冗長性と可用性が向上し、中央のシングルポイントの故障を回避できます。

### データの分散とコンテンツアドレッシング

IPFSは、ユーザーがファイルをアップロードすると、そのファイルをブロックに分割し、ネットワーク上に分散保存します。各ブロックはユニークなハッシュを持ち、データが変更されると新しいハッシュが生成されます。データを検索する際には、ユーザーがハッシュを提供し、ネットワーク上でそのハッシュを持つブロックを検索して組み合わせデータを再構築します。
データのハッシュ化については、コンテンツアドレッシングという考え方のもと各種システムにおいて有用化されています。

### 情報のキャッシュと高速化

IPFSはデータのキャッシングをサポートし、ユーザーがデータをリクエストすると、近くにあるノードによってキャッシュされる可能性があります。これにより、データの高速な取得が可能となり、ネットワーク全体での負荷を軽減します。また、一度取得したデータはローカルにキャッシュされ、同じデータへの未来のアクセスが高速化されます。

## ローカル環境におけるIPFSサービスの調整
Fire Flyでスタックを起動すると、coreサービス以外にIPFSサービスが起動されます。Docker経由でのサービスのため、ポート番号がIPFS標準と異なるポートにマッピングされて起動されます。標準のIPFSサービスのポートとは異なり、この状態でUIにアクセスが出来ない **※** ため、Dockerの定義ファイルを変更してサービスを起動することにしました。
※ デフォルトのポートでブラウザから閲覧するにはリバースプロキシなどを用いてアクセスすることは可能。

## ローカルのIPFSサービスへの接続
ローカル環境のIPFS環境への接続はブラウザから行います。
URLにIPFS メイン画面は以下のURLにてアクセスします。

WebUI：http://localhost:10206/webui
Gateway：http://localhost:10207/ipfs/<CID>

### Docker定義ファイルの変更
WSL2（ubuntu）環境を起動します。
ホームディレクトリ下にあるdocker-compose.ymlファイル（97行目付近）を修正します。
ipfs_0下に定義されているportsの設定において、10206と10207ポートの定義を、標準のポート番号（5001、8080）に修正します。
```diff_abap
    ipfs_0:
        container_name: bsc_ipfs_0
        image: ipfs/go-ipfs:v0.10.0
        volumes:
            - ipfs_staging_0:/export
            - ipfs_data_0:/data/ipfs
        ports:
+            - 5001:5001
+            - 8080:8080
-              #- 10206:5001
-              #- 10207:8080
        healthcheck:
            test:
                - CMD-SHELL
                - wget --post-data= http://127.0.0.1:5001/api/v0/id -O - -q
            interval: 5s
            timeout: 3s
            retries: 12
```

#### 設定変更前:
WebUI：http://localhost:10206/webui
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/1a6eef42-af72-974e-8ee5-ef556f2a9b25.png)
#### 設定変更後：
WebUI：http://localhost:5001/webui
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/218324c1-d9d4-e668-88df-6ceb31035a4a.png)

## IPFS動作状態の確認
以上で、ローカルのIPFSに接続ができるようになったので、WebUIから稼働状態を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3514304/6da2544f-25ef-e6b2-5a0e-b3f25c58c0a4.png)

## 次回は
次回はNFT発行およびIPFSサービスを用いた管理方法を紹介します。
マルウェア、さまざまな攻撃

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/8fccb22f-fad3-9be0-9aae-c424d0bf01be.png)
「攻撃の種類」

①フィッシング
　偽メールや、偽Webページを用いた詐欺行為のことです。不正なサイトへ誘導し、言葉巧みに金銭を搾取します。

②ビジネスメール詐欺
　企業組織を狙って、業務に関連すると思われる内容の電子メールを送り付け、大規模な金銭取引（不正に金銭を振り込ませる）などの不正を行う攻撃のことです。取引先を装って、「監査中なので、今回に限っては、いつもとは異なることらの口座に振り込んでほしい」などという文面で、偽の口座に振り込ませたりします。

③ソーシャルエンジニアリング
　上司や管理部門になりすまして、ユーザIDやパスワードをぱすわーどを窃取するといったように、「社会的」な手段を用いて、機密情報を盗み取る攻撃です。人間がセキュリティ上の弱点であることうまく利用したものです。

④サラミ法
　大量のもの中から、わからないように少しずつ盗み取る攻撃です。よく話題になる例では、銀行口座の預金利息の端数を、特定の口座に振り込むようにして盗み取る攻撃があります。

⑤スキャベジング
　ゴミ箱アサリのことを言います。実際にゴミ箱を漁って機密情報を盗むことのほか、コンピュータのメモリ中に残された機密情報を盗み取る攻撃もあります。

⑥ポートスキャン
　全てのポートに対して、順番に接続を試みて、接続可能なポートがあるかどうかを調査することです。接続可能なポートがあれば、そのポートを対象に攻撃を開始します。ポートスキャンは直接的な攻撃ではありませんが、攻撃に至る事前著さであることが多いです。また、サーバのセキュリティチェックのために、自らでポートすっきゃんを背売る場合もあります。

⑦DoS（Denial of Service）
　サービス不能攻撃とも言います。サーバに対して大量の要求を送ることで、サーバ本来の業務を妨害する攻撃です。電子メールを大量に送りつける爆弾や、頼みもしないDNS応答パケットを送りつけるDNSamp攻撃など、さまざまな攻撃があります。
　ウイルスやポットを利用してさまざまなコンピュータから、特定のサイトに対してDoS攻撃を行うことを分散DoS（DDoS）攻撃と呼びます。

⑧バッファオーバフロー
　不正動作を行うプログラムを紛れ込ませた巨大サイズのデータを入力します。すると、アプリケーションプログラムで用意した受信バッファから入力データが溢れ出て、アプリケーションプログラムの一部分を書き換えてしまいます。その結果、アプリケーションプログラムは異常動作を起こします。これに乗じて、送り込んだ不正プログラムを実行する攻撃です。攻撃が成功すると、不正侵入が可能になります。

⑨DNSキャッシュポイズニング
　PCなどの端末が利用するDNSサーバをDNSキャッシュサーバといいます。DNSキャッシュサーバでは、調べたドメイン名とIPアドレスの対応を一定時間キャッシュに保管しておきます、。こうすることによって、次回からは、キャッシュから情報を取り出し、素早くIPアドレスを返答するのです。
　DNSキャッシュポイズニングは、DNSキャッシュサーバに偽のドメイン情報（偽のIPアドレス）を保管させる攻撃です。この攻撃が成功すると、ブラウザに正しいドメイン名を入力したにもかかわらず、偽サイト（偽のウェブサーバ）に誘導さえっると言ったことが起きます。

10：SQLインジェクション
　入力データとして、SQL文の一部を入れることで、本来のSQL分とは全く違った動作をするSQL文を生成させ、データベース女中のデータを盗み見たり、改ざん、消去する攻撃です。ウェブアプリケーションを対象にこの攻撃を行い、顧客情報が漏洩する事件が後を立ちません。

１１：クロスサイトスクリプティング（XSS）
　XSSは、掲示板サイトのように、記事の投稿を受け付けて投稿された記事を表示するサイト（標的サイト）を利用して行われます。標的サイトにJavaScoriptなどで書かれた不正プログラムを送信し、そのサイトに閲覧したユーザのブラウザ上で不正プログラムを実行させます。
　
　XSSでは、第三者のサイト（標的サイト）用いて、攻撃対象のユーザを攻撃します。標的サイトには実害は出ていないことに注意してください。しかし、実害がないからと言って放置しておくと、「あのサイトは危ない」という噂が広まり、サイトの信頼が失墜します。標的サイトとして利用されないよ対策を講じておかなくてはなりません。

　XSS対策としては、投稿内容をチェックし、JavaScriptプログラムなどが含まれていた場合は、プログラムとして実行できないように加工するという処理が有効です。これをサニタイジング処理と言います。
SQLでヒストグラムを作成する

SQLでヒストグラムを作成する仕様があり、パズルのように頭を悩ませたので、忘れないように書き残しておきます。

# 仕様

こういう階級テーブル(bin)が存在して...

| max_score |
|:-:|
|  10 |
|  20 |
|  :  |
|  90 |
| 100 |

こういう結果テーブル(record)があるときに...

| id | score |
|:-:|:-:|
|  1 | 45  |
|  2 | 12  |
|  3 | 98  |
|  4 | 68  |
|  : |  :  |

こういうヒストグラムを作成したい。frequenceは区間に含まれるrecordの件数。

| bin | frequency |
|:-:|:-:|
| 10  | 4  |
| 20  | 13  |
|  :  |   |
| 90  | 4  |
| 100 | 2  |

# テーブル定義とデータ挿入スクリプト

```sql:階級テーブル(bin)
drop table if exists bin;
create table bin (max_score integer);
insert into bin(max_score)
select (c1 + 1) * 10
from
(select 0 as c1 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d1
```

```sql:結果テーブル(record)
drop table if exists record;
create table record(id integer, score integer);
insert into record (id, score)
select c10 * 10 + c1 + 1, FLOOR(1 + RAND() * 10) * FLOOR(1 + RAND() * 10)
from
(select 0 as c10 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d10,
(select 0 as c1 union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d1
```

# 答え

```sql
-- 4. recordが1件もない区分が0として表示されるよう、区分マスタを外部結合する
select bin.max_score as bin, ifnull(z.frequency, 0) frequency from (
    -- 3. bin.max_scoreでグルーピングして、ヒストグラムを作成する
    select y.max_score as bin, count(*) as frequency from (
        -- 2. 1. の結果からbin.max_scoreに含まれるrecordレコードを抽出する
        select x.id, x.score, min(x.max_score) as max_score from (
            -- 1. 直積でbin.max_score以上のrecordレコードを抽出する
            select bin.max_score as max_score, record.id as id, record.score as score
            from bin, record
            where record.score <= bin.max_score
        ) as x
        group by x.id, x.score
    ) as y
    group by y.max_score
) z
right outer join bin on bin.max_score = z.bin
order by bin.max_score
```

```text:結果
+------+-----------+
| bin  | frequency |
+------+-----------+
|   10 |        25 |
|   20 |        18 |
|   30 |        15 |
|   40 |        14 |
|   50 |        10 |
|   60 |         9 |
|   70 |         2 |
|   80 |         2 |
|   90 |         2 |
|  100 |         3 |
+------+-----------+
10 rows in set (0.00 sec)
```

# 解説

SQLにつけたコメントで解説していますが、要望があれば詳しく書きます...
CTranslate2でembeddingモデルを楽に使う

# 導入

以下の記事でCTranslate2でEmbeddingモデルを使う(Sentence Transformersを使う)をやってみましたが、```hf_hub_ctranslate2```モジュールを使うとこれがサクッとできるようなのでやってみました。

https://qiita.com/isanakamishiro2/items/25045ed60bccd741be45

検証は前回同様Databricks環境下で行っています。

# 試す

モジュールをインストールします。

```python
%pip install -U -qq transformers accelerate ctranslate2 hf_hub_ctranslate2[sentence_transformers] sentence-transformers

dbutils.library.restartPython()
```

```hf_hub_ctranslate2[sentence_transformers]```をインストールしているところがポイントです。

というわけで、このモジュールを使ってベクトル計算します。

```python
from hf_hub_ctranslate2.ct2_sentence_transformers import CT2SentenceTransformer

def main():
    sentences = ["This is an example sentence", "Each sentence is converted"]
    model = CT2SentenceTransformer("/Volumes/hugginfaceのモデルが置いてあるパス/intfloat/multilingual-e5-large/")
    embeddings = model.encode(sentences)
    print(embeddings)

if __name__ == "__main__":
    main()
```

```:結果
Some weights of XLMRobertaForSequenceClassification were not initialized from the model checkpoint at /Volumes/training/llm/ctranslate2_models/intfloat/multilingual-e5-large/ and are newly initialized: ['classifier.dense.bias', 'classifier.dense.weight', 'classifier.out_proj.bias', 'classifier.out_proj.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
[[ 0.0269323  -0.01583179 -0.02195328 ... -0.02472305 -0.02929592
   0.0164552 ]
 [ 0.02027375 -0.01176006 -0.00298298 ... -0.019228   -0.03131687
   0.03152583]]
```

前回と同じ結果が得られました。

[こちら](https://github.com/michaelfeil/hf-hub-ctranslate2/blob/main/hf_hub_ctranslate2/ct2_sentence_transformers.py)のコードを見ている限り、変換済みモデルも指定できるようなのですが、Transformersのモデルが同じディレクトリ内に無いとエラーが出るのは変わりません。

# まとめ

というわけで、こっちのやり方が楽です。