OmniAICreator/Qiita-1.07M huggingface dataset:
同期I/O？　非同期I/O？　I/Oスレーブ？

# 本記事の目的
Oracle Database Administration (oracle Gold)の学習がメインである。
個人的に理解するのにわかりにくかったところを記事としてまとめた。
今回は、同期I/O,非同期I/O,I/Oスレーブの言葉の定義を自分の言葉でまとめてみた。

# 目次
1. バックアップ取得する工程のお話
1. 同期I/Oとは
1. 非同期I/Oとは
1. I/Oスレーブとは

# 1. バックアップ取得する工程のお話
ひとえにバックアップを取得するといっても複数の工程がある。

バックアップ取得の流れを以下のイラストをもとにイメージしてほしい。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357323/abdfbf34-634f-5240-6e6c-1fee021cd233.png)

バックアップを取得する際、チャネルは以下の作業を行っている。
### ①チャネルが、バックアップするデータを読み取りに行く
### ②読みに行ったデータをチャネルがコピー
### ③出力先として指定しているデバイスにデータを書き込み


このようにバックアップ一つとっても、複数の工程がある。


# 2.同期I/Oとは
同期I/Oとは、一言で言うと
**『団体行動』**
である。

もう少し、詳しく記載しよう。
例えば、1でお話ししたバックアップ取得を例にとる。
チャネル数は複数あることを前提に話をする。

それぞれの工程で、チャネルによっては、データを早く読んで暇になるチャネルも存在するかと思う。
→コピーするデータが、10GB しかないものもあれば、1TBものものあるかと思う。
そこで少なからず、データを読み込むときに差が生じる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357323/1647e8ea-813c-3260-7e43-cc78fcd45252.png)

同期I/Oの場合、一つ一つの操作(読み取りや書き込み)が終わったタイミングで
すべてのチャネルが、まとめて次の操作に移る
→チャネルによっては、待機チャネルも存在する

# 3.非同期I/Oとは

非同期I/Oとは、一言で言うと
**『個人行動』**
である。

こちらも先ほどのバックアップ取得を例に詳しく記載する。
(チャネル数は複数あることを前提に話をする)

今回は、わかりやすくするために3ステップに分ける

### ①各チャネルが対応するファイルの読み込み開始
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357323/d0fec65f-bebd-099d-1b00-77e8ef6c983b.png)


### ②あるチャネルの読み込みが完了する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357323/7c9a24c2-7162-60eb-9094-829fd23b48bb.png)

### ③読み込みが完了したチャネルから次の作業に入る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357323/c2ab9a56-7b72-9bee-2964-2b063f2d0263.png)

上記に示すように、非同期I/Oは各チャネルのタイミングで次の作業へ移っていく
→同期I/Oとは違い、チャネル全体で同じ作業を行わない！
なんとなく、イメージはつくと思うが、非同期I/Oのほうが、効率良くバックアップ処理を行うことができる。

また、非同期I/Oは、oracleのデフォルト設定である。


# 4.I/Oスレーブとは
スレーブI/Oとは、一言で言うと
**『非同期I/Oが使えないときの疑似的非同期I/O』**
である。

前述したとおり、同期I/Oは、非同期I/Oと比べて効率が悪い。
でも、システムによっては、同期I/Oのみの設定しかできないものも存在する。
そういった際に、スレーブI/Oを設定すると、効率が少し上がる。
では、スレーブI/Oとは何なのか
→チャネルの性能を上げることができる設定である。

スレーブI/Oを設定することで、マルチスレッドとなり、
各チャネルのパフォーマンスが向上する。
そうすると、同期I/Oの処理速度が上がってパフォーマンス向上につながる


※非同期I/Oを設定しているときでも、スレーブI/Oの設定自体はできる
  でも、その場合、非同期I/Oが優先されてスレーブI/Oは無効となる
  詳細は、[こちら](https://docs.oracle.com/cd/F19136_01/refrn/DBWR_IO_SLAVES.html#GUID-D8A04F0F-0D5A-4B28-895E-8F63BD3B7DC9)
Ubuntuでfirewalldは危険！？

## 概要
自宅に眠っていたWindows10のPCを掘り起こし、LinuxOSをインストールしてサーバー構築の勉強用に使っていた。
apacheをインストールし、サーバ用PCのIPアドレスをURLで指定して表示成功！！
と上手くはいかず、3時間ほどつぶした際の原因と対応策の備忘録。

## 状況
- 駆け出しWebエンジニアで、ふと「Linuxサーバの勉強をせねば！」と思った
- Bodhi Linux(Ubuntuの派生)にApache2をインストールし、デフォルトページを表示させようと書籍を読み進める
- その書籍はCentOS向けのもので、適宜Ubuntuでのコマンドなどを調べつつ構築
  - ゆえに、何もわからずfirewalldもインストールしていた
- firewalldでポート開放もできたし、いざ、ブラウザで表示しようっ！！と思っていた矢先。。。

## 原因
ufwとfirewalldが競合していたこと
  - Ubuntuにはデフォルトでufwというファイアウォール管理コマンドが用意されている
  - CentOS向け書籍で学習していたため、firewalldもインストール
  - 調べたところ、ufwとfirewalldが競合するとすべてのポートが閉じられてしまうらしい。


## 対応策
以下のコマンドでfirewalldを削除した
※ `--purge`オプションをつけることで設定ファイルも削除する

```bash
$ sudo apt-get --purge remove firewalld
```
<br>
その後、ufwでポート開放

```bash
$ sudo ufw allow 80
$ sudo ufw reload
```

<br>

無事表示できた。

<br>

## 参考
https://qiita.com/opaiti/items/e8e84be7171269b28d54

https://qiita.com/siida36/items/be21d361cf80d664859c
共通一次世代が惜しげもなく事業を見捨てていく

# 共通一次世代が惜しげもなく事業を見捨てていく
 
 >「未成熟な人間の特徴は、理想のために高貴な死を選ぼうとする
これに反して成熟した人間の特徴は、理想のために卑小な生を選ぼうとする点にある。」

引用元　「ライ麦畑でつかまえて」


日本は、少子化と高齢者の増加のために程度の差こそあれ衰退していくのは、認めるしかない状況にある。
しかし、最近進んでいる状況は、諦めるしかない状況なのだろうか。
もっと、ましに立ち振る舞うことは本当にできないのだろうか。

工場の撤退、スーパーの大規模な閉店　それらのニュースを見て思う。


## 過去の失敗
- 失敗を認めたくないための時間稼ぎ
　例：プラズマ・ディスプレイに巨額投資をした某P社
　　
- 失敗を認めたくないための不正会計
　例：某T社

 そのため、赤字を放置するくらいならば、事業をやめた方がいいと判断しやすくなっているのだろう。

## 事業が捨てられたときに起こること
- 過去の経験がまったく活かされない分野への転職を強いられる人が多数生じる。
    - 例：高齢者介護分野への転職
 
## 定年間近の世代の利害が、20代、30代の利害を無視していく。
- 共通一次試験（1979 ~ 1989年）世代は、既に60歳の定年に達した人から、もうじき定年の世代になっている。
- 上位の役職についている人の多くは、この世代である企業が多いんじゃなかろうか。
- そういった中で、個人的な利害に基づいて、組織の判断を歪めると同じような行動になる。


## 個人的な利害によって組織の判断を歪める
- これは、頻発している現象です。
- 例： 利益の確保を優先したいがために、老朽化する店舗の錆びついた状況を放置する。
- 例:  経営者としての報酬を多く得たいがために、赤字が出ている事業を利益が出ているかのように不正会計を担当者に押し付ける。
## その職責にある以上言わなくてはいけない責務を果たすことよりも、自らへの待遇を優先させる。
- 例：刑事事件として立件しなければならない事例に対して、時効が成立するまで放置してしまう。
- 例：そのような悪例が積み重なっていく。



## 事業をしぶとく生き残させる努力を
- 生き残れる部分はないか？
    - 例：ある企業グループが崩壊したときに、ある製品分野を手がけてきた人たちが、その製品分野を独立会社を設立している。
- 別の経営主体による可能性はないか？
    - 総合スーパーがその店舗を断念したとしても、食料品だけのスーパーの別の経営主体だったら、採算があう可能性はないか？
    -  
- 別な場所で生き残る方法はないか？
    - 例：まだ存続している炭鉱に転職した炭鉱労働者
- 別な事業を興して、その分野で存続する。
    - 例：閉山する炭鉱企業から、観光企業への変身
    - 映画「フラガール」で描かれている。


その職責にある以上言わなくてはいけない責務を果たすことよりも、自らへの待遇を優先させる。
例：刑事事件として立件しなければならない事例に対して、時効が成立するまで放置してしまう。
例：そのような悪例が積み重なっていく。


- 地域経済が衰えていく。
- その企業で働いていた人だけでなく、多くの取引先の仕事がなくなってしまう。
- 失業が増えていく。
JWT認証について

# はじめに
今までユーザーとしてなにげなく利用していた認証について、ユーザー認証を伴うAPIをLaravelで開発をするために学ぶ機会がありました。認証については、なんとなくそれっぽい認証風なものであったり、ライブラリを雰囲気で利用していただけでした。
この機会に認証のJWT認証について、抽象的なレベルでも理解できればと思いまとめてみます。
初学者としての知識の範囲内による理解をまとめた記事ですので、間違いなどがあるかもしれませんので、ご指摘いただければ幸いです。

## JWTとは
- JSON Web Token(JWT)
- JWTは、HTTPヘッダーにクエリパラメータなどの付加情報（ペイロード）を載せられるように
  1. JSONデータをURLセーフする方法を規定したもの => JSONデータをBASE64URLエンコードする
  2. JSONデータをコンパクトにする方法を規定したもの => よく使用されるデータ項目を略称にして、JSONキーを短くするこれによってJSONデータをコンパクトにする
- Claim(クレーム)
    JWTではJSONのデータ項目(キーと値のペア)をClaim(クレーム)と呼ぶ
    このようにクレームとして定義された情報をエンコードしてデータを小さくして、HTTPヘッダーやクエリパラメータへ載せられるようにする。

## JWSとは
JWTはBASE64URLエンコードされているだけなため、セキュリティ面ではなにも担保されていない
BASE64URLデコードすればすぐにもとのデータ形式に戻すことができるし、改ざんも可能
この改ざんを防止(改ざんを検知する仕組み)する手段がJWS
JWSは改ざん自体を防ぐものではなく、改ざんされたJWSどうかを検知することができる
JWSの仕組み
1. HTTPヘッダーとペイロード(ヘッダーに載せたいデータ)をBASE64URLでエンコードする
2. 1のエンコードしたものを.でくっつける
3. 2の結果を暗号鍵とヘッダーのalgに指定された方式で暗号化して、BASE64URLでエンコードする
4. 2と3の結果を.でくっつける
5. エンコードされたヘッダー.エンコードされたペイロード.エンコードされた暗号鍵とヘッダーのalgに応じて暗号化された前二つの情報(トークン)


## JWSの検証
JWSの仕組み上、前の二つの情報はBASE64URlでエンコードされているだけなため、情報を確認することは簡単
改ざん自体も可能。しかし３番目の情報に関しては不可能
- 暗号鍵は信頼している相手しか持っていない
- 暗号化した内容は同じ暗号鍵を持っていなければ復号化できる
上記の２点から信頼した相手からのJWSであれば、復号化した情報の内容が改ざんされていないことになる。


## まとめ
今回JWTについて表面的ですが、まなぶことで認証情報に対してどのように開発をするのか？ということを考える幅が広がり、思考が点ではなく線として進められる感覚が増えました。
知識が増えることで、開発の視野を広げられる感覚が開発の楽しさを感じさせてくれるなと実感しました。
Power Apps から Power Automate を介して Dataverse のファイル列に保存をする


# はじめに

Microsoft Dataverse では、以下のようにテーブルにファイルや画像を保存する用の列を追加することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/5ae42e75-06d7-3e3e-eb9f-8eebe5f0f9b9.png)

利用ケースは沢山あると思いますが、例えば、私の場合、以下のような感じで、Power Apps で領収書を読み取り、読み取ったデータを保存すると共に、ファイル自体も保存したいというケースで、このファイルや画像の列を利用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a4302a26-c23e-4277-b356-1a85bcd863a2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/419fd469-931e-24c6-4dc5-526d4f2babe7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/73c9684f-1dfa-0c38-3713-5d26d90d072b.png)

このように、Power Apps で画像を取り、Power Automate を介して Dataverse にファイルを保存する方法について、あまり情報がなく、ちょっと時間を要してしまったので、備忘も兼ねて記事を書きました。

# アプローチ

## Power Apps

Power Apps では、以下などと同じように、AI Builder の OCR とカスタムプロンプトで読み取った情報を JSON 形式にします。Power Apps 側はここがポイントになります。

https://qiita.com/Takashi_Masumori/items/07aba9675f3cf576b393

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/308ddc32-cc86-7de9-71a3-84cf51cd12ea.png)

そして、以下のようにして、Power Automate に情報を渡します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b0737660-f568-5bfb-f5c5-037d4bea2cae.png)


```
領収書保存フロー.Run(
    TextInputCanvas1_1.Value,
    JSON(
        TextRecognizer1.OriginalImage,
        JSONFormat.IncludeBinaryData
    ),
    Concatenate(
        "recipt_",
        Text(
            Now(),
            "yyy/mm/dd hh:mm:ss"
        )
    )
);
Notify(
    "領収書情報を保存しました",
    NotificationType.Success
);

Navigate(Screen1)
```

なお、AI プロンプトは以下のような感じで作っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/afd2d949-f59d-78da-e882-0277f44c17c4.png)


## Power Automate

Power Automate 側は以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b8d061c7-1608-c864-7e0d-400924d2ee66.png)

JSON データは、Power Apps に表示されているものをサンプルとして解析する感じです。

作成アクションは以下のような感じです。この辺がちょっと難しい、また、情報をすぐに見つけられなかったところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b7484e66-188d-6bae-0971-a31d4ef5c7ea.png)

```
replace(split(triggerBody()['text_1'],',')[1],'"','')
```

あとは、画像の場合は、レコード作成と一緒に保存し、ファイルの場合は、レコード作成後に追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/922a3a2c-9723-cd40-70d2-88ba3077d5b6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/5302fc86-ee41-2259-cca5-b0ee676f9e68.png)

## 結果

アプリを実行してみます。無事にフローが成功し、ファイルも保存されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b578a87d-27d6-38ee-a06e-a57f01356612.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/aa95e31e-e9bb-91a7-3c7c-7e77e43d660e.png)

※今回は、あえて画像とファイルを両方保存しましたが、最終的にはどちらか片方のみ残します

# まとめ

今回は、Power Apps から Power Automate を介して Dataverse のファイル列に保存をする方法を紹介しました。紹介したように、データと合わせてファイル自体を保存するようなケース多いと思いますし、ファイルの保存で詰まってしまうのはもったいないので、今後同じようなことをしようとする方の参考になれば幸いです
より効率の良いGAPでチャンネル重要度を計算するCNN【MSCA】



**原論文**
FcaNet: Frequency Channel Attention Networks
https://openaccess.thecvf.com/content/ICCV2021/papers/Qin_FcaNet_Frequency_Channel_Attention_Networks_ICCV_2021_paper.pdf




# 関連研究
チャンネルの重要度を計算するCNN【SENet】
https://qiita.com/wakayama_90b/items/96527dfbbeb1e2ee06c5





# 結論
SENetで使用されるGAPは，情報をうまく捉えられないかもだから，離散コサイン変換（DCT）を用いて改善した．


# 概要

画像認識モデルのCNNは，静的なパラメータ（どんな画像が来ても同じ重み）を効率的に学習することで，精度向上している．しかし，未知な画像を認識する際にうまく認識できない可能性がある．そこで，入力された画像によって重みが変化する構造を導入することによって，未知な画像でも認識できるようにしよう．
例えば，犬の画像でも，画像に小さく写った犬の画像と大きく写った犬の画像がある．画像の重要と思う箇所は画像によって異なるので，その画像にあった重要度を決める必要があるよね．

この，画像にあった重要度（重み）を動的なパラメータと呼び，SENetはその先駆けとして提案された．しかし，SENetは，計算効率の観点から，空間情報をGAPによって圧縮しているため空間情報がうまく取り出せていない可能性がある．そこで，GAPではなく，離散コサイン変換（DCT）を用いて圧縮することで，空間情報をうまく取り出せるようにした．これを，Multi-spectral channel attention（MSCA）と呼ぶ．
GAPの改善なので，GAPを使用するモデルは，これに置き換えてもいいと思うよ．






# モデル構造

下図の(a)にSENetの構造を示し，入力（$H \times W \times C$）をGAPで圧縮して（$1 \times 1 \times C$）にしてFC→softmaxして，入力にかけて各チャンネルの重要度付けを行う．


(b)に示す，MSCAは，まず，入力をチャンネル方向にn個分割する．分割された各特徴量には，2次元DCT周波数フィルタが割り当てられて，DCT周波数フィルタを通す．そのフィルタによって生き残った値を合計する．
それによって，できた（$1 \times 1 \times C$）をFC→softmaxして，入力にかけて各チャンネルの重要度付けを行う．



![スクリーンショット 2024-03-03 12.36.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/e14914d8-edda-bfd3-6842-de5270e17776.png)






# 実験

DCT周波数フィルタには，入力特徴量の高周波成分を通すフィルタや低周波成分を通すフィルタなど様々ある．どんなフィルタを用意するといいのか？
実験的に，CNNでは，低周波成分を残すフィルタを使用した場合に精度が良い傾向にある．そのため，低周波成分の情報を好む傾向にある．
↑
【自分の考察】CNNは畳み込み処理によって，画像のエッジなど（高周波成分）の特徴を捉えやすい構造であり，特徴量が持ってるのは，高周波成分の情報ばっかりになっているのかも，だから，MSCAでは，貴重な低周波成分の情報を消さないように，低周波成分の情報の重要度を上げているのかなと思った．





# まとめ

より効率の良いGAPでチャンネル重要度を計算するCNN【MSCA】について解説した．GAPは空間情報を1つの値に集約するから，必要な情報を捉えきれないかもだったね．これで少しは改善できるかな？って．
Jestで既存の関数をモック化する方法

# はじめに
どうもこんにちは！僕は現在1ヵ月本気の技術力向上を目指している現役高校生1年生(@shunii )です！
今回はJestでモック関数を実装する際、理解に躓いたのでまとめます。

# モック関数とはなんぞや
モック関数を簡易的に説明すると、
> <font color="red">**既存の関数の代替**</font>

になります。

- 具体的な使用例
外部APIとの通信を行う関数をモック化すれば、実際には通信を行うことなく意図したテストを実行することができるようになります。

これって結構うれしいですよね。

# 関数をモック化する流れ
1. **jest.mockをトップレベルで呼ぶ**
jest.mockを呼び出すことで、既存の関数をモック化することが出来ます。この時点ではモック関数の具体的な処理は定義されておらず、undefinedを返す仕様になっています。
    ```ts
    jest.mock("モック化したい関数があるファイルのパス")
    ```

<font color="red">**そして必ずjest.mockはファイルのトップレベル(describeの外)に書きましょう!!!**</font>
細かい話をするとjest.mockはどこで書いても自動的にトップレベルに記載されたのと同じようにする(いわゆる巻き上げ・ホイスティングをする)のですが、エラーが出てしまう場合はまずこれを疑ってみてください。可読性を考慮してもトップレベルに書くことが推奨であるとドキュメントにも記載されています。
<br/>

<font color="gray">手順2はAとBの2つのパターンを書きます</font>
**2. Aパターン:　jest.mockの中で関数を定義する**
手順1で書いたjest.mockのなかで関数を実際に定義していきます。**mockImplemetation**を使うことでモック関数の中身を定義できます。
```ts
jest.mock('ファイルパス', () => ({
  //functionNameに実際の関数の名前を書く
  functionName: jest.fn().mockImplementation(() => 'mocked value'),
}));
```
これで、mocked valueという文字列を返却するモック関数が出来上がりました！

:::note info
イメージ( 以下の考え方だとわかりやすいかも )
- jest.mockは「関数をモック化するよ！」という宣言的な感じ。実際には中身はない( => undefined )
- jest.fnは「実際に疑似的な関数を作るよ！」って感じ。中身をちゃんと作ってあげよう
:::

他にもモック関数の作り方はあります。僕が調べたものを以下に示します。使いやすいものを選んでみてください！詳細はぜひ公式ドキュメントを確認してみてください。
- **mockReturnValue**:　モック関数の戻り値だけを指定できます
  ```javascript
  jest.mock('module_name', () => ({
    functionName: jest.fn().mockReturnValue('mocked value'),
  }));
  ```
<br/>

- **mockResolvedValue**:　Promiseを返却したい( 非同期関数 )の場合に使いやすいです。外部APIとの通信する関数とかで使えそうです
  ```javascript
  jest.mock('module_name', () => ({
    functionName: jest.fn().mockResolvedValue('mocked value'),
  }));
  ```
<br/>

**2. Bパターン:　モック関数をdescribeの中で定義する**
まず、ファイルのトップレベルで以下のように記述します。jest.fnで関数を作っておきます。
```ts
jest.mock('ファイルパス', () => {
    return {
        functionName: jest.fn()
    }
})
```
そして、describeの中で以下のようにモック関数を定義します。
```ts
describe('テストの名前', () => {
    beforeEach(() => {
        //ここのfunctioName.~の書き方はAパターンで示したように自由です。
        functionName.mockImplementation(() => 'mocked')
    })
})
```
難しく見えるかもしれませんが、Aパターンでやっていることを切り離しているだけ、と考ることができればわりと理解しやすいと思います。

:::note info
beforEachとは
beforeEachを使うことで、各テストケースが実行される前にある処理を実行することが出来ます。これを使っておかないと初期化でエラーを吐かれます。
( initiallizeみたいな単語がエラーにあったらこれを疑ってみてください )
:::

Bパターンの利点としては、
> **describe(各テストのグループ)ごとにモック関数の仕様を変更することが出来る点**

です。僕はまだそれを利点と感じる場面に出くわしたことはないですが、個人的に可読性の面で好みです。モック化の宣言と定義がわかれている感じがいいです。

# 終わりに
今回の内容を理解するのに結構な時間がかかったので、どなたかの参考になれば幸いです！意味わかんないーとおもったら公式ドキュメントをぜひ頑張って読んでみてください。
いいねとコメント大歓迎です！

# About Me
- X(Twitter)

https://twitter.com/shunii_hack

# 参考

https://jestjs.io/ja/docs/mock-functions

https://jestjs.io/ja/docs/es6-class-mocks

https://jestjs.io/ja/docs/bypassing-module-mocks
ZED SDKを使いこなす　retrieve できる対象

ZED SDK を概観するために、retrieve できる対象には何があって、どういうメソッドで取得できるのかをメモする。

## 想定する読者
- stereolabsのzed2, zed mini, zed z などのステレオカメラの利用者
- いまどきのステレオカメラは何ができるのかを知りたい人

## 前提
- ZED SDK 4.0 

## ZED SDK で retrieve できる対象

```
import pyzed.sl as sl
zed = sl.Camera()
```
- （各種設定については表記を省略。しかるべき例を元に補ってください。）

## カメラ画像を取得する。
```
image = sl.Mat()
zed.retrieve_image(image, sl.VIEW.LEFT, sl.MEM.CPU, display_resolution)
cv_img = image.get_data()
```
ZED SDK で取得するカメラ画像は、RGBAの4チャネルデータになっている。
機械学習の推論に用いる場合には、3チャネルのデータとして,
しかも連続的な配列になるようにしてから用いてください。
そのままだと、機械学習の推論に失敗します。

### https://www.stereolabs.com/docs/tutorials/image-capture

## depth 画像(表示用)を取得する。
```
depth_image = sl.Mat()
zed.retrieve_image(depth_image, sl.VIEW.DEPTH)
cv_depth_img = depth.get_data()
```
[0, 255]の範囲で規格化してdepth画像を取得する。
そのため、表示目的以外には使用しない。
depth の欠損点も0 として扱われるので、欠損点と遠方との区別がつかないという欠点がある。
depthの絶対値が失われているので、depthを利用して点群に変換するのに用いることはできない。
np.isfinte(cv_depth_img) は全画素でtrue になる。

### https://www.stereolabs.com/docs/depth-sensing/using-depth

## depth 画像を取得する。
```
depth_image = sl.Mat()
zed.retrieve_measure(depth_image, sl.MEASURE.DEPTH)
cv_depth_img = depth_image.get_data()
```
こちらのcv_depth_image ではfloat型である。
そのため、欠損値と有効な値とを区別できる。
np.isfinite(cv_depth_image)
は、必ずしもtrueにならない。
欠損値の状況の例：
- 深度が小さすぎる場合
- 深度が検出限界を超える場合
- 対応点が見つからない画素の場合

### https://www.stereolabs.com/docs/depth-sensing/using-depth



## point_cloud を取得する。
```
point_cloud = sl.Mat()
zed.retrieve_measure(point_cloud, sl.MEASURE.XYZRGBA, sl.MEM.CPU, point_cloud_res)
xyz_data = point_cloud.get_data()
```

### helpの出力
```
retrieve_measure(py_mat: 'Mat', measure=DEPTH, type=<MEM.CPU: 1>, resolution=<pyzed.sl.Resolution object at 0xffff5d562930>) -> 'ERROR_CODE' method of pyzed.sl.Camera instance
    Camera.retrieve_measure(self, Mat py_mat: Mat, measure=MEASURE.DEPTH, type=MEM.CPU, resolution=Resolution(0, 0)) -> ERROR_CODE
```

resolution の値を小さくしておくことで、
生成される点群の大きさを小さくすることができる。
また、point_cloudのインスタンスを生成する際に、以下のようにその大きさを指定しておくことで、領域確保のオーバーヘッドが減りそうである。
```
point_cloud = sl.Mat(res.width, res.height, sl.MAT_TYPE.F32_C4, sl.MEM.CPU)
```
### https://www.stereolabs.com/docs/depth-sensing/using-depth#getting-point-cloud-data

# 検出されたobjectの全体の情報を得る。
```
objects = sl.Objects()
zed.retrieve_objects(objects, obj_runtime_param)
```
### https://www.stereolabs.com/docs/object-detection/using-object-detection

## 人の身体の部位のデータを取得する。
```
bodies = sl.Bodies()
zed.retrieve_bodies(bodies, body_runtime_param)
```
### https://www.stereolabs.com/docs/body-tracking/using-body-tracking

## spatial_map(空間マップ)を取得する。
```
pymesh = sl.Mesh() 
# もしくは
pymesh = sl.FusedPointCloud()
zed.retrieve_spatial_map_async(pymesh)
```
### https://www.stereolabs.com/docs/spatial-mapping/using-mapping


# 注意
- retrieve_* のメソッドによっては、省略可能な引数を持っている場合があります。
- 利用状況によってはそれらの通常は省略されている変数を明示的に指定しなければならない場合があります。
- `help(sl.retrieve_objects)` などとして、使い方を表示させてみてください。
サブネットとは

# はじめに
LINUCの資格試験を進める中でサブネットについてまとめておこうと思いました。
概要から、初学者でもわかりやすい図を作成し、解説してみようともいます。

# サブネットとはなにか
サブネットとは、単位の大きいネットワークを小さい単位で分割し構築されたネットワークのこと

## 詳しく
社内で100台のPCを管理する際に、IPアドレスを連番等で100台に振った100個のIPアドレスではなく、サブネットごとの管理が可能になる。
### IPアドレスの構成の違い
IPアドレスを8ビットずつ以下の様に置き換える
```
x -> ネットワーク部
s -> サブネット部
h -> ホスト部
```
**クラスの概念に基づいたIPアドレス(従来)**
```
x.x.h.h
```

**サブネット化されたIPアドレス**
```
x.x.s.h
```
サブネット部分を部署、クラス単位で振り分けることで、ホスト部の特定がしやすくなる！

と、言われてもよくわからないから、、、
### 図解
ネットワークを192.172.0.0としてみたよ
```mermaid
flowchart LR
subgraph "ネットワーク IP：192.172.0.0"
    A["ネットワーク<br/>IP：192.172.0.0"]
    B["ネットワーク<br/>IP：192.172.0.0"]
    C["ネットワーク<br/>IP：192.172.0.0"]
end
subgraph A["ネットワーク<br/>IP：192.172.1.0"]
    direction LR
    192.172.1.1
    192.172.1.2
    192.172.1.3
end    
subgraph B["ネットワーク<br/>IP：192.172.2.0"]
    direction LR
    192.172.2.1
    192.172.2.2
    192.172.2.3
end
subgraph C["ネットワーク<br/>IP：192.172.3.0"]
    direction LR
    192.172.3.1
    192.172.3.2
    192.172.3.3
end
```



# どんな時に使えるか考えてみる
大規模な現場や、会社単位でIPアドレスを管理するときに有効！
部署やグループ単位でサブネットを付与することで、大量の個人から一人を決定するのではなく、グループグループAの個人aのような形で決定ができるため管理をしやすいのではないか。

## おわりに
あまり個人で使用することはないが、法人レベルのネットワーク管理では重要な技術


#### 学校のクラス、出席番号と同じような感じ🤔
画面内に要素があることを検知

目次をハイライト表示をさせたくその雛形をメモします。
下記のコードは画面内に要素があればactiveを付与、無ければ除去します。

```js
const targetContent = document.querySelector(".target-content")

const options = {
  root: null,
  rootMargin: "0px",
  threshold: 0
}
const observer = new IntersectionObserver(callback, options);
observer.observe(targetContent)

function callback(entries) {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      targetContent.classList.add("active")
    } else {
      targetContent.classList.remove("active")
    }
  });
```
#### 参考

https://www.webcreatorbox.com/tech/intersection-observer

https://ics.media/entry/190902/
VSCode ( devcontainer ) で python の開発環境


フォーマッタが動かない時は VSCode のコマンドで "Developper: Reload Window" を実行する

```js
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python

{
  "name": "Python 3",

  // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
  "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",

  // Features to add to the dev container. More info: https://containers.dev/features.
  // "features": {},

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // "forwardPorts": [],

  // Use 'postCreateCommand' to run commands after the container is created.
  // "postCreateCommand": "pip3 install --user -r requirements.txt",

  // Configure tool-specific properties.
  "customizations": {
    "vscode": {
      "extensions": [
        "esbenp.prettier-vscode",
        "ms-python.black-formatter"
      ],
      "settings": {
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "editor.formatOnSave": true,
        "[python]": {
          "editor.defaultFormatter": "ms-python.black-formatter"
        }
      }
    }
  }
  // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
  // "remoteUser": "root"
}
```
ReactとVueの違い

# 発音：
React -> リアクト
Vue -> ビュー　

# 相違点

## コアコンセプト

◆Vue:
VueはHTMLベースのテンプレート構文を使用しています。
これより、HTML、CSS、JavaScriptをより簡単に統合できる。

◆React: 
一方で、ReactはJSX「JavaScriptXML」を使用し、UIコンポ―ネットをJavaScriptと一緒に記述することを奨励します。

## データバインディング

◆Vue:
双方向データバインディングをサポートしており、モデルとビュー間で自動的にデータが同期されます。これは、フォーム入力やアプリケーションの状態管理に便利です。

◆React:
Reactでは、一方向データフローが採用されており、コンポーネント階層を通じてデータを「プロップス」で下に渡し、「ステート」を通じてコンポーネント内でデータを管理します。

### 単語
* コンセプト：　概念,观念
* 構文　こうぶん：文章结构，句法
* 統合　とうごう
* UIコンポ―ネット：组件
* 記述　きじゅつ
* データバインディング　数据绑定
* 双方向　そうほうこう　
* 奨励　しょうれい
【ChatGPT有＋DALL-E3】アニメ・マンガのキャラクターは？


　どうも、カーブミラーです。

　今回は、アニメ・マンガのキャラクターを描くことについてです。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　まずは、ニュース。

　ChatGPT Web版ですが、
　　音声出力が可能に
　　　なっている、そうです。

　オイラには
　　まだまだだよ(泣)

　設定を確認してください。
　　項目が増えてるかも。

　使い方は、
　　ふつうに
　　　文章の出力を
　　　　行なってもらうと
　　　　　コピー、再表示、Badと
　　　　　　ボタンが並んでいる場所に
　　　　　　　スピーカーが
　　　　　　　　あるみたいなので
　　　　　　　　　それをタップ。

　要するに
　　ChatGPTの出力を
　　　読むだけの機能です。
　　　　ずっと話してくれる
　　　　　ものじゃありません。
***
　さて、
　　本題です。

　アニメ・マンガのキャラクターを
　　描きたいことがあることでしょう。

　そのときは
　　結構苦労しますよね。

　まずChatGPTが
　　知っているもので、
　　　版権がありそうなものは
　　　　弾きます。

　で、DALL-E3が
　　チェックして
　　　弾きます。

　これは
　　仕方ないです。
***
　場合によっては
　　ChatGPTが“欲しいんでしょう”と
　　　プロンプトを作ってくれて
　　　　DALL-E3に渡してくれますが、
　　　　　似ても似つかないキャラに
　　　　　　なります。

　それが
　　いいものならば
　　　ありがたいんですけど、
　　　　まぁ、ふつうはボツネタです。
***
　では
　　どうすればいいのか。

　作者の作風を
　　指定するのも手ですが、
　　　うまくいくのは
　　　　少ない感じですね。

　MicrosoftのCopilotのDesignerだと
　　キャラ指定はやれます。
　　　かなり似たレベルになります。

　そちらを
　　使う方がいいかも
　　　しれませんね。
***
　どうしても
　　ChatGPT経由で
　　　DALL-E3に描いてもらいたい
　　　　ならば、特徴を書き出して
　　　　　近付けるしかありません。

　あるいは
　　そのものズバリの
　　　言葉を回避して指定する
　　　　ことでしょうか。

　例えば、
　　“機動戦士ガンダム”を
　　　描きたい、とします。

　“ガンダム”は当然ダメです。

　“機動戦士”ではどうか？

![1709435070857.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/49438827-3e47-c76f-c85b-473321dbaaef.jpeg)
　　それっぽくありませんね。

　ガンダムは何か？
　　“モビルスーツ”ですね。

![1709435094205.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/4e849e60-fb4d-47ca-056a-d8141f782841.jpeg)
　モビルスーツだと
　　それなりに近付きました。

　次に、
　　カラーリングを
　　　施してもらいます。

　あら不思議。
　　ガンダムそっくり。
![1709435110915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/a554ad3a-2c71-c813-c1a2-2e89305a243a.jpeg)
***
　まぁ、
　　ガンダムは
　　　優しい方ですね。

　“セーラームーン”を指定したら、
　　ガンダムよりも簡単でしたw

　“仮面ライダー”も
　　特徴を捉えたライダーが
　　　出てきました。

　こちらも
　　微調整していく感じ
　　　ですね。

　こんなことでも
　　みなさんの
　　　作品制作の糧に
　　　　なれば、幸いです。

　今回は、ここまで。
私のWordPressサイトはどうして落ちるのか

# はじめに

私の管理しているWordPressサイトが静かに落ちる。
リソースに問題はないはずなのに静かに落ちる。
監視グラフとログとにらめっこして原因を探って対策をしましょう。

# システム構成

下図のように Cloudflare + Linux(Ubuntu 22.04) + nginx + PHP-FPM の構成になっています。
間にCDNを挟んでいるのでアクセス過多ではなさそうですが、いったい原因は何でしょう？

![ccc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2066798/0be7894d-1bc9-b079-914f-c96e2575867a.png)

# wp-cron.phpの実行エラー

調査のためにトップページのHTTPS応答時間をZabbixで1分おきに計測しました。
すると最大で1時間に6回ほど応答時間が遅くなっています。

![02-29_03_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2066798/5494cd79-745b-e029-e8b1-901dd50d8f8b.png)

このスパイクが発生している時間帯のログを確認すると下記のものがありました。

```text:access.log
××.××.××.×× - - [×/×/××:××:××:×× +0900] "POST /wp-cron.php?doing_wp_cron=×××××.×××××××× HTTP/2.0" 499 0 "-" "WordPress/×.×.×; https://rtmaddon-search.com"
```

`wp-cron.php` の実行で499エラーが発生しています。
ログ全体を調査したところ、1日の間に8413回実行されたうち、426回(約5%)で499エラーが出ていました 

# 対策

`wp-config.php` で `DISABLE_WP_CRON` の設定を有効にします。

```php:wp-config.php(抜粋)
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

define( 'DISABLE_WP_CRON', 'true' ); # 追記
```

下記のシェルスクリプトを用意します。

```shell:wp-cron.sh
#/bin/bash
/usr/bin/php×.× /＜path-to-wp-home-dir＞/wp-cron.php
```
※使用される際はPHPのバージョン等、ご利用の環境に合わせて変更してください。

`crontab -u www-data -e` コマンドを発行し、下記のスケジュールを登録し10分に一回wp-cron.shが実行されるようにします。

```text:crontab
*/10  *  *   *   *     /＜path-to-script-dir＞/wp-cron.sh > /dev/null 2>&1
```

# それでもまだ落ちる

先ほどの対策後スパイクは減少しましたが、Zabbix上でHTTPS応答時間が0秒(タイムアウト)になる瞬間が引き続き確認できます。(画像赤丸内)

![03-01_03_02_edited.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2066798/73100f1b-56f7-5dee-2e46-1a6cec0bf32e.png)

この時間帯のPHP-FPMのログを見ると下記のような事象が発生していました。

```text:php×.×-fpm.log
[×-××-×× ××:××:××] WARNING: [pool www] child 430165, script '/＜path-to-wp-home-dir＞/index.php' (request: "GET /index.php") execution timed out (31.228176 sec), terminating
[×-××-×× ××:××:××] WARNING: [pool www] child 430165 exited on signal 15 (SIGTERM) after 33.326078 seconds from start
```

WordPressの何かの処理で30秒以上掛かっていてワーカーが強制終了されています。
この時間帯のnginxのログを調査して499が発生しているページをひとつずつ確認したところ、特定の投稿ページ内容が原因であると分かりました。

その投稿にはoEmbed(wp:embed)が約60個埋め込まれていて、その処理で時間がかかっていました。

## 対策

システム的にはどうしようもないのでページの投稿者と相談して一度下書き設定にし、非公開にした後に別途ページを作り直してもらいました。

# 最後にCM

今回の調整を行ったWordPressサイトはこちらです。
[https://rtmaddon-search.com/](https://rtmaddon-search.com/)

Minecraft Forge MOD の一つであるRTMのアドオン紹介・検索サイトです。
ご興味御ある方はぜひお越しください。
SAの式に近似して計算効率向上したモデル【RFA】

**原論文**
RANDOM FEATURE ATTENTION
https://arxiv.org/pdf/2103.02143.pdf


# 結論
Self-Attentionの式に近似して計算効率向上したモデルを提案した．




# 概要
自然言語分野のTransformerは，長距離の文字を考慮した高精度をもたらすモデルだが，単語数が多くなると，単語数の2条の計算コストが必要で，長い文章に対して効率的に計算できない．
Transformerの構造で，Self-Attention(SA)の計算が重いので，もっと計算効率のいいSAを提案してみたよ．
確立されたランダム特徴マップを用いて，SAの代わりに代用できる，計算コストの小さい，ランダム特徴アテンション(RFA)を提案を提案する．


# モデル構造

下図に示すように，(a)のSAを置き換えるように，(b)のRFAを提案する．
(・)は入力された2つの行列の内積，φ(・)は非線形変換であり，softmaxの代わりに近似させる．

※非線形変換は，入力がxの時，y=f(xW)．
Wが重みで，F()が，活性化関数(ReLUなど)．


![スクリーンショット 2024-03-03 10.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/5f06dad9-c4d8-d3d2-9784-b44b6a82ecf7.png)


## RFA
具体的には違うけど，簡単に言うと，SAの式を近似した式に置き換えているだけである．

~~~math
SA(Q,K,V)=\mathrm{softmax} \left( {Q K} \right) V
~~~


~~~math
RFA(Q,K,V)= \phi (Q) \lbrace \phi (K) V \rbrace
~~~

例えば， $\phi(・)$で特徴量のサイズを小さくすると，途中の計算量が小さくなるよね．


### 計算例

QKVのサイズが$N \times D$の特徴量を持っている時

### SA

$Q$($N \times D$)と$K^{T}$($D \times N$)の内積で($N \times N$)=$A$

$A$($N \times N$)と$V$($N \times D$)の内積で($N \times D$)=OUT



#### RFA

$\phi(K)$の($1 \times D$)と$K^{T}$($D \times N$)の内積で($1 \times D$)=$A$

$\phi(Q)$の($N \times 1$)と$A$($1 \times D$)の内積で($N \times D$)=OUT



## RFA-GATE
gate-RNNからヒントを得て，RFAの途中のスキップ接続（過去の情報を持ってくる）時に，その情報をどの割合で持ってくるのかを制御する．下の式から，$g_t$の数値はsigmoidで0~1に制限されて，$g_t$が1に近いほど，過去の情報を多め，0に近いほど，過去の情報を控えめにする．


![スクリーンショット 2024-03-03 11.48.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/4f76b1bd-f819-7803-3c6c-52c24d4a38c7.png)




# 結果
精度も計算コストの良くなったよ．また，SAのsoftmaxが必要亡くなったことでハイパラであるsoftmaxの($σ$)に影響されなくなった．






# まとめ
今回は，SAの式に近似して計算効率向上したモデル【RFA】した．自然言語分野に詳しくなくて，大まかな説明になってしまい，間違ってるかもしれませんが許して．🙇
インストールをなるべく行わないでpython環境構築

# 概要

Windows 11にPythonの実行環境と開発環境を構築することを目的としています。インストーラーを使った作業をなるべく行わないようにしています。

# Python3

## 本体ダウンロード

https://www.python.org/downloads/windows/

上記のリンクより、Windows embeddable packageをダウンロードしました。私の場合は、環境が64-bitなのでそれをダウンロードし、解凍しました。

## 実行

解凍したフォルダの中に、python.exeがあるので、それをpowershellで実行しました。パスを考慮したうえでしたのようなコマンドを打って、動作確認しました。バージョンの数字が表示されると思います。

```
python.exe -V
```

## pipのダウンロードインストール

https://bootstrap.pypa.io/

上記のリンクよりget_pip.pyをダウンロードしました。右クリック->リンク先をファイルに保存。

パスを考慮して、下記コマンドを実行しました。

```
python.exe get_pip.py
```

LibとScriptsというフォルダが作成されます。

pythonのインストールフォルダ内にある、python312._pthを下記のように編集します。

```
#編集前
#import site
#編集後
import site
```

下記コマンドパスを考慮して実行します。

```
.\python-3.12.2-embed-amd64\python.exe .\python-3.12.2-embed-amd64\Scripts\pip.exe -V
```

pipのバージョンが表示されます。私の場合、get_pip.pyをダウンロードした場所がpythonの実行ファイルがあるフォルダになっているので、LibとScriptsもその中にある形となっています。

# Visual Studio Code

エディタとしてvscodeを使いたかったので、それもダウンロードしました。

https://code.visualstudio.com/

ページを下のほうへスクロールされますと、windows用のインストール用ファイルがいくつか表示されていることを確認できます。.zipのものをダウンロードします。

ダウンロード後、zipファイルを展開します。展開したフォルダのなかにCode.exeという実行ファイルで起動することができます。

# 動作確認

pipをつかってパッケージのインストールをします。Jinja2というテンプレート関連のパッケージを例としてインストールしました。

```
.\python-3.12.2-embed-amd64\python.exe .\python-3.12.2-embed-amd64\Scripts\pip.exe install Jinja2
```

インストール後、下記のコマンドを実行されますと、そのなかに今回インストールしたJinja2を確認することができます。

```
.\python-3.12.2-embed-amd64\python.exe .\python-3.12.2-embed-amd64\Scripts\pip.exe list
Package    Version
---------- -------
Jinja2     3.1.3
MarkupSafe 2.1.5
pip        24.0
setuptools 69.1.1
wheel      0.42.0
```

下記のような内容のファイルを作成します。編集はvscodeで行いました。

```python
from jinja2 import Template

template = Template('hello world!! {{ name }}!!')
result = template.render(name='taro')

print(result)
```

パスを考慮して、下記のコマンドを実行し、その結果を確認します。

```
.\python-3.12.2-embed-amd64\python.exe .\src\main.py
hello world!! taro!!
```

以上となります。
BlueskyのPDS移設方法

# はじめに

Blueskyの[self-hosting PDS (Personal Data Server)](https://github.com/bluesky-social/pds)を別サーバーへ移設する方法をこのページに書きます。ただし、この方法ではダウンタイムがあります。また、公式の手順ではなく、内容を保証できません。

以降では、移設前のサーバーを旧サーバー、移設後のサーバーを新サーバーと記載します。

環境は以下の通りです。

* Ubuntu 22.04.4 LTS
* PDS [9126d65](https://github.com/bluesky-social/pds/commit/9126d65b8808ebd3f1d3cc1163126201b06aa95a)

# 要約

旧サーバーの`/pds`を新サーバーへ転送します。

# 詳細

## 旧サーバーでの作業

旧サーバーの`pds`を止めます。この時点で旧サーバーが外部からリクエストを受け付けなくなります。

```
$ sudo systemctl stop pds
```

旧サーバーの`/pds`を圧縮します。ここでは`tar.gz`にしていますが、別形式でも構いません。

```
$ cd /
$ sudo tar czf pds.tar.gz pds
$ sudo chown ${USER}.${USER} pds.tar.gz
```

`scp`コマンドなどを使って圧縮ファイル`pds.tar.gz`を手元に転送します。新サーバーを起動済みであれば、直に新サーバーへ転送しても構いません。また、新旧サーバーで`pds`が起動していない状態であれば、圧縮せずにそのまま新サーバーに転送してもよいかもしれません。

旧サーバーを止めます。

```
$ sudo shutdown -h now
```

## 新サーバーでの作業

新サーバー未起動であれば、新サーバーを起動します。

インストーラー[`installer.sh`](https://github.com/bluesky-social/pds/blob/9126d65b8808ebd3f1d3cc1163126201b06aa95a/installer.sh)を使って、新サーバーに`pds`などをインストールします。

```
$ wget https://raw.githubusercontent.com/bluesky-social/pds/main/installer.sh
$ sudo bash installer.sh
```

インストール後、新サーバーで`curl http://localhost:3000`などを実行して動作確認します。

以降の作業で`/pds`の中身を上書きする前に、新サーバーで一旦`pds`を止めます。

```
$ sudo systemctl stop pds
```

圧縮ファイル`pds.tar.gz`を新サーバーに未転送であれば、新サーバーへ転送します。

新サーバーで転送したファイルを展開し、`installer.sh`の作成したファイルを上書きします。

```
$ cd /
$ sudo tar xf pds.tar.gz
```

新サーバーで`sqlite`ファイルなどを参照して、ファイルが上書きされたことを確認します。例えば、以下の操作により、PDSに属するアカウント情報が出力されるはずです。

```
$ sudo sqlite3 /pds/account.sqlite
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> select * from account;
```

上書き確認ができたら、新サーバーで改めて`pds`を起動します。

```
$ sudo systemctl start pds
```

新サーバーで動作確認をします。

```
$ curl http://localhost:3000
```
【Android】aabファイルを端末へインストールする方法まとめ

# はじめに
アプリをリリースする際には、apkで審査出しする事もできますが、現在では殆どの場合aabファイルでの公開が主流ですよね。
ですがこのaabファイルという都合上、作成したaabファイルを端末へインストールする際に一手間かかってしまうのがある種の難点かと思います。
今回はこのaabファイルを端末にインストールする方法を備忘録的にまとめておこうと思います。

# インストール方法
まずaabからインストールを行うためには、bundletoolが必要になります。
こちら未導入の場合は以下を実行し導入しておきましょう。

```
$ brew install bundletool
```

bundletoolが導入済みであれば、以下に適切な情報を設定し、実行します。

```
$ bundletool build-apks --bundle=<対象のaabファイル名>.aab \
--output=<作成するapksファイル名>.apks \
--ks=<署名ファイル名> \
--ks-pass=pass:<storePassword> \
--ks-key-alias=<keyAlias> \
--key-pass=pass:<keyPassword>
```

上記を実行し成功すれば、apksファイルが作成されます。
ちなみにapksファイルの作成には上記コマンドが基本的な内容になりますが、他にも任意の設定で合わせて実行すると便利なフラグがいくつかありますのでいくつかご紹介します。

- --overwrite
ファイルを上書きするかどうかの設定です。
この設定が付与されていない状態で同じapksファイルを作成するとエラーになります。

- --connected-device
接続されている端末を対象にapkを作成するかどうかの設定です。
この設定が有効になっていないと、全ての端末に対してのapkファイルを作成する形になります。

以上です。
他にも任意のフラグがいくつかあるので、気になる方は以下をご参照ください。

https://developer.android.com/tools/bundletool?hl=ja

上記コマンドを実行し作成されたapksファイルは、以下を実行することで端末にインストール可能です。

```
$ bundletool install-apks --apks=<作成したapksファイル名>.apks
```

解説は以上になります。

# さいごに
この時期は花粉症がしんどすぎますね、空気清浄機フル稼働しても勝てません😇
【Ruby】問題集解答 Part1（paizaラーニング）

# N行のデータの入力 (paizaランク D 相当)
https://paiza.jp/works/mondai/stdin/stdin_n_line
### 自分の解答
まず空の配列を用意し、その中に受け取った数値の個数分だけ値を格納し、最後に`puts`する。
勉強のために、`for`と`while`の２つの方法で書いた。
```ruby:practice_01.rb
times = gets.to_i

array = []

# forの場合
# for i in 1..times
#     array << gets
# end

# whileの場合
num = 1
while num <= times
  array << gets
  num += 1
end

puts array
```
### ChatGPTの解答
以下は、Rubyで提供された条件に基づいて問題を解決するためのサンプルコードです。このコードは、すべての入力を受け取った後にまとめて出力します。

```ruby:ruby
# Nの値を取得
n = gets.to_i

# N行分の文字列を受け取り、配列に格納
input_strings = []
n.times { input_strings << gets.chomp }

# 入力を受け取った後に出力
input_strings.each do |str|
  # ここに各文字列に対する処理を記述
  # 例えば、文字列をそのまま出力する場合は以下のようになります
  puts str
end
```

このコードでは、まず最初に行数 N を取得し、その後 N 行分の文字列を受け取ります。最後に、各文字列に対する処理を行いつつ、全体を一括して出力します。各文字列に対する具体的な処理は必要に応じて変更してください。

### 学び
`times`メソッドを使えばより簡潔に書ける。
Python開発環境構築時のメモ(Windows 11 + Python3 + VSCode)

# はじめに
SpeakerDeckで公開されている[競技プログラミングことはじめ](https://speakerdeck.com/e869120/20221122-jing-ji-puroguramingukotohazime)を見て、[AtCoder](https://atcoder.jp/?lang=ja)を始めるためにPython開発環境を整えたので、そのときのメモ。

>インストール作業日：2024/3/2
導入環境(OS)：Windows 11 Home(23H2)
導入したPythonのバージョン：Python 3.12.2

# インストール手順
基本的に[Python.jp](https://www.python.jp/index.html)さんの[Visual Studio Code でPython入門 【Windows編】](https://www.python.jp/python_vscode/windows/index.html)の通りに作業を実施。

実際には、手順の「1.Windowsエクスプローラの設定」はもともと設定済、「2.不要なPythonを整理する」は作業不要（もともとPython未導入）だったので、「3.Pythonのインストール」と「4.Visual Studio Codeのインストール」を実施。




# 導入時メモ
導入時にちょっと気になって横道に逸れて確認・実施したことのメモ。

:::note warn
以下記載の作業は、Python＋VSCodeの開発環境構築には無関係なので、実施しなくても環境構築はできる（はず）。
:::

### PowerShellの環境設定
「3.Pythonのインストール」の中に「PowerShellの環境設定」という手順があった。
自分の環境でPowerShellを起動した際、`新機能と改善のために最新の PowerShell をインストールしてください`と表示されたのが気になったので、<INS>PowerShellの最新版(PowerShell 7)インストール</INS>と<INS>Windowsターミナル起動時にPowerShell 7を開くようにする設定</INS>を実施。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733231/167fd206-9b04-5b89-37b9-1236d391cfb1.png)

###### PowerShellの最新版(PowerShell 7)インストール
[Windows への PowerShell のインストール](https://learn.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4)の「Winget を使用して PowerShell をインストールする」を参考にインストールを実施。
既存のPowerShell(Windows PowerShell 5.1)がアップグレードされるわけではなく、併存する形でPowerShell 7がインストールされる。

###### Windowsターミナル起動時にPowerShell 7を開くようにする設定
Windowsターミナルはデフォルトでは、起動時にWindows PowerShell 5.1が開かれるため、それをPowerShell 7に切り替えた。
作業は[「最新版をインストールせよ」とPowerShell起動時に叱られたときの対処法](https://atmarkit.itmedia.co.jp/ait/articles/2310/27/news035.html#04)の「Windowsターミナルで最新のPowerShellが起動するように設定する」を参照して実施。

# 構築完了
VSCodeでPythonが実行できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733231/ae69cf30-cb1d-72f4-9996-4f87b59f231f.png)


さて、競技プログラミング（競プロ）の問題いろいろ解いてみよう。
ChatGPT で elixir を学ぶ　（その3） 掛け算九九の表を作成

こちらの記事の続きです。
[ChatGPT で elixir を学ぶ　（その2）](https://qiita.com/ekzemplaro/items/cc907011657dbceb6249)

掛け算九九の表を作成してみます。
残念ながら、ChatGPT も、Gemini も実行可能なプログラムは作成できませんでした。

## Python のプログラム

```py:multiplation.py
#! /usr/bin/python
#
import sys
#
sys.stderr.write("*** 開始 ***\n")

for it in range(1,10):
	for jt in range(1,10):
		kt = it * jt
		print("%2d" % kt,end = " ")
	print()

sys.stderr.write("*** 終了 ***\n")
```

実行結果

```text
$ ./multiplation.py 
*** 開始 ***
 1  2  3  4  5  6  7  8  9 
 2  4  6  8 10 12 14 16 18 
 3  6  9 12 15 18 21 24 27 
 4  8 12 16 20 24 28 32 36 
 5 10 15 20 25 30 35 40 45 
 6 12 18 24 30 36 42 48 54 
 7 14 21 28 35 42 49 56 63 
 8 16 24 32 40 48 56 64 72 
 9 18 27 36 45 54 63 72 81 
*** 終了 ***
```

## ChatGPT が作成したプログラム

```exs:mch01.exs
IO.puts("*** 開始 ***")

for it <- 1..9 do
  for jt <- 1..9 do
    kt = it * jt
    IO.write("#{kt} ")
  end
  IO.puts()
end

IO.puts("*** 終了 ***")
```

実行結果

```text
$ elixir mch01.exs 
*** 開始 ***
1 2 3 4 5 6 7 8 9 ** (UndefinedFunctionError) function IO.puts/0 is undefined or private. Did you mean:

      * puts/1
      * puts/2

    (elixir 1.14.0) IO.puts()
    mch01.exs:8: anonymous fn/2 in :elixir_compiler_0.__FILE__/1
    (elixir 1.14.0) lib/enum.ex:4299: Enum.reduce_range/5
    mch01.exs:3: (file)
```

## Gemini が作成したプログラム

```exs:mge01.exs
defmodule Main do
  def main do
    IO.stderr.write("*** 開始 ***\n")

    for it <- 1..9 do
      for jt <- 1..9 do
        kt <- it * jt
        IO.write("%2d ", kt)
      end
      IO.puts("")
    end

    IO.stderr.write("*** 終了 ***\n")
  end
end

Main.main
```

実行結果

```text
$ elixir mge01.exs 
warning: variable "kt" does not exist and is being expanded to "kt()", please use parentheses to remove the ambiguity or change the variable name
  mge01.exs:7: Main.main/0

warning: variable "kt" does not exist and is being expanded to "kt()", please use parentheses to remove the ambiguity or change the variable name
  mge01.exs:8: Main.main/0

warning: undefined function kt/0 (expected Main to define such a function or for it to be imported, but none are available)
  mge01.exs:8

warning: undefined function kt/0 (expected Main to define such a function or for it to be imported, but none are available)
  mge01.exs:7

** (CompileError) mge01.exs:7: undefined function <-/2 (expected Main to define such a function or for it to be imported, but none are available)
```

## 私が作成したプログラム

```exs:multiplation.exs
IO.puts :stderr,"*** 開始 ***"
for it <- 1..9 do
    for jt <- 1..9 do
        kt = it * jt
        sx = Integer.to_string(kt)
        :io.format("~2s ",[sx])
    end
    IO.puts ""
end
IO.puts :stderr,"*** 終了 ***"
```

実行結果

```text
$ elixir multiplation.exs 
*** 開始 ***
 1  2  3  4  5  6  7  8  9 
 2  4  6  8 10 12 14 16 18 
 3  6  9 12 15 18 21 24 27 
 4  8 12 16 20 24 28 32 36 
 5 10 15 20 25 30 35 40 45 
 6 12 18 24 30 36 42 48 54 
 7 14 21 28 35 42 49 56 63 
 8 16 24 32 40 48 56 64 72 
 9 18 27 36 45 54 63 72 81 
*** 終了 ***
```
getInitialPropsを使ってないのにTypeError: Cannot read properties of undefined (reading 'getInitialProps')エラー

## エラーを発生した時のソースコードは？

Next.jsの学習中に発生したエラー。
> TypeError: Cannot read properties of undefined (reading 'getInitialProps')

getInitialPropsは非推奨で使用していないはずなのに...　:thinking:うーん

コードを見て間違いを探した結果

```pages/_app.tsx
//自分の間違い。exportの後のdefaultが抜けている。
import type { AppProps } from 'next/app'
export function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
```

```pages/_app.tsx
//正解
import type { AppProps } from 'next/app'
export default function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}
```

引用：[Routing: Custom App | Next.js](https://nextjs.org/docs/pages/building-your-application/routing/custom-app)

## 学び１:writing_hand:名前付きエクスポートとデフォルトエクスポートの違い
export function MyApp:point_left:**名前**付きエクスポート


:::note info
インポート時に {　} 内に**指定した名前**でインポートする必要がある。
:::

```js
import { MyApp } from './MyApp';
```

export **default** function MyApp:point_left:**デフォルト**エクスポート

:::note info
**任意の名前**でインポートする必要がある。
:::
:::note info
１つのモジュール内に1つだけexport defaultできる。
:::
```js
import MyApp from './MyApp';
//もしくは、
import App from './MyApp';//インポート時に任意の名前なので、exportしている時の関数名と違ってもOK
```

## 学び２:writing_hand:_app.jsはどんなファイル？

* Next.jsは、<font color="Red">_app.jsファイルを最初に読み込み</font>、その中で定義されたAppコンポーネントを使用して、各ページのレンダリングを処理する。

* _app.jsファイルは、すべてのページに共通のレイアウトやグローバルな振る舞いを定義するためのファイル。したがって、Appコンポーネントは_app.jsファイル内でエクスポートされる必要がある。

* pages/_app.jsファイル内でAppコンポーネントが<font color="Red">デフォルトエクスポートされている場合</font>、Next.jsはそのファイルを自動的に読み込み、Appコンポーネントを使用してページのレンダリングを行う。そのため、<font color="Red">明示的にimport文を使用してAppコンポーネントをインポートする必要はない。</font>


## 学び３:writing_hand:TypeError: Cannot read properties of undefined (reading 'getInitialProps')とは

このエラーは、通常、ページコンポーネント内でgetInitialPropsが定義されているかどうかをNext.jsが検出しようとするときに発生する。

:warning:Next.jsが最初に読み込む_app.jsファイルを正しく読み込めていない。
↓getInitialPropsが存在しない場合、（自身のソースにもgetInitialPropsは存在しなかった）

:warning:getInitialPropsが存在しないので、Next.jsは代わりに何も返さないコンポーネントを返そうする。
↓
:warning:その結果、undefinedが返される。
↓
:warning:その後、ページコンポーネントでこのundefinedにアクセスしようとすると、TypeErrorが発生。

:::note info
デフォルトエクスポートを使用することで、Next.jsが_app.jsファイルを正しく読み込み、Appコンポーネントを適切に処理することができる。
:::

:::note warn
非推奨のgetInitialPropsとは？
ページ内のサーバーサイドレンダリングを可能にし、初期データを追加出来るようになります。つまり、既にデータが追加されているページをサーバーから送信するということです。これは特に SEO 対策に有効です。
引用：[Data Fetching: getInitialProps | Next.js](https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/data-fetching/get-initial-props)
:::
JanomeとJiebaのインストール手順

**Janomeのインストール:**
1. ターミナルを開きます。
2. 以下のコマンドを実行して、Janomeをインストールします:
   ```bash
   pip install janome
   ```
   インストール中に、パッケージ情報がダウンロードされ、`janome-0.5.0`がインストールされることが通知されます。

**Jiebaのインストール:**
1. インストールが完了したら、続けてJiebaをインストールします。ターミナルで以下のコマンドを実行します:
   ```bash
   pip install jieba
   ```
   このコマンドにより、`jieba-0.42.1`がインストールされます。

NLTKは、Pythonで自然言語処理タスクを行うための人気のあるライブラリです。
次のコマンドをターミナルまたはコマンドプロンプトで実行してください。

```
pip install nltk
```
```
pip install pysrt
```

#### **JanomeとJiebaの概要**

**Janome:**
- Janomeは、純粋なPythonで書かれた日本語形態素解析器です。形態素解析とは、テキストを単語に分割し、それぞれの品詞を特定する処理のことを指します。このモジュールは、日本語テキストを効率的に解析するために設計されており、自然言語処理の分野で広く使用されています。Janomeは設定やコンパイルが不要で、Pythonのスクリプトやアプリケーションに簡単に組み込むことができます。

**Jieba:**
- Jiebaは、中国語テキストのためのPython形態素解析ライブラリです。言語の分かち書き（単語分割）、品詞タグ付け、固有名詞認識などの機能を提供しています。Jiebaは柔軟性が高く、カスタム辞書をサポートしているため、特定の用語や専門用語に対する解析精度を向上させることが可能です。また、簡体字中国語だけでなく、繁体字中国語にも対応しています。

これらのモジュールは、多言語対応のテキスト処理アプリケーションや自然言語処理プロジェクトにおいて、日本語や中国語のテキスト解析を行う際に重要な役割を果たします。
Kubernetesの監視・可視化ツールPixieが機能豊富で優秀！！

# Kubernetesの監視

クラスタの状態監視、CPU・メモリなどのリソース監視、各種クエリやアクセスのチェックなど、要点を挙げればキリのない分野なので、使用するツールによって作業の難易度が大きく左右されてきます。

今回、Pixieを導入してみて使い心地が良かったので、布教のために機能をいくつか紹介していきます。

## アクセス直後の全体像

こんな感じのダッシュボードになっています。HTTPトラフィックの可視化は見ているだけでワクワクします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/de89be5d-4da2-3c50-b496-c72d43785d33.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/54e06ebd-703c-2680-7c2e-bc56b026a86b.png)

## Namespaceごとのリソース監視

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/5bbfdae3-0211-1987-68c0-2218ff0b5010.png)

Podのリソース使用状況やディスクアクセスも確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/8e5418e6-3e7e-b7c9-053a-4afb1436db7b.png)

## HTTPのログ監視

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/dc27095a-12d2-64c0-201e-afc255e24d82.png)

## Redisのコマンドログ・トラフィックの可視化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/c2043318-2142-ec5c-2215-507b3cb255d3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/7b35a909-d53d-1f09-9e8a-48fd00da4635.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/6a599682-ce80-8708-a46f-a66b3fa2b728.png)

他にも様々な監視用のテンプレートが用意されています😀

# インストール方法

Kubernetesは導入済みと仮定して、Self-hostedではなくクラウド版Pixieのインストール手順のみ共有します。

[このドキュメント](https://docs.px.dev/installing-pixie/install-guides/community-cloud-for-pixie)に従います。

### サインアップ

こちらからできます。Googleログインやメールアドレスでの登録を選べます。

https://work.withpixie.ai/

### `px`コマンドのインストール

```
bash -c "$(curl -fsSL https://work.withpixie.ai/install.sh)"
```

### コマンドラインからログイン

```
px auth login
```

### Pixieをクラスタ上にデプロイ

10分ほどかかります。

```
px deploy
```

### ダッシュボードにアクセス

こちらからアクセスできます。

https://work.withpixie.ai/

# まとめ

とても簡単に導入できて、楽しくクラスタの可視化や監視のできるツールでした。ぜひ試してみてください😊

Twitterでは、おうちKubernetesや技術関連の内容を日々ツイートしているので、興味があればぜひフォローしていってください🎉

Twitter: https://twitter.com/_matoruru
"Is the docker daemon running?"のエラー解決方法

# 初めに
docker-compose upでコンテナを作成して起動しようと思っていたのですが、ターミナル上で
``` 
Cannot connect to the Docker daemon at unix:///パス名 
Is the docker daemon running?
```
というメッセージがでてきたので、この解決方法について書きます。

# 解決方法

dockerアプリからEngineをリスタートすることで解決できました。

# 最後に

このエラーで困っている人に向けて参考にしていただきたいです！
Mac アプリ – CleanShot X - 画面スクリーンショット撮影してすぐにお絵かきしたり、ドラッグ&ドロップで複数画像を別アプリにペーストしたり

# Clean Shot X 

https://cleanshot.com/

#  CleanShot Xで何が出来るか

- 画面を範囲選択してキャプチャ撮影
- 画面全体をキャプチャ撮影

した後に

## すぐにお絵かきモードに移動できる

- 四角、丸、線、矢印を描く
- 連番をつける
- 塗りつぶし、モザイク
- 一部エリアのハイライト

などが簡単にできるようだ

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/b5a2deed-e169-48f4-8560-57db1768289c)


## ドラッグ&ドロップでのペーストができる

画面に並んだミニウィンドウをドラッグ&ドロップするだけで、他のアプリに画像ペーストができる
複数のスクリーンショット撮影をして複数ペーストする時に、これはとても良い

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/5823f6e4-8780-493d-9285-e8c2be7a8af8)

### Alfredとの比較


自分の場合、今までは

- Mac標準のスクリーンショット撮影&クリップボードコピー機能
- Alfredのクリップボード履歴機能

を併用して、画像の複数スクリーンショット撮影&複数ペーストを実現していた

だが、このCleanShotXの方がずっと管理しやすそうだ

<img width="708" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/a5ba5768-337e-4da0-8eb7-c52ce9116715">

# ビデオ / GIF動画のキャプチャが簡単に作れる

この機能でも画面を動画撮影した後に、簡単に他アプリにペーストが出来るので手軽だ

以下は実際に動画撮影して貼り付けた例

![CleanShot 2024-03-03 at 10 02 46](https://github.com/YumaInaura/YumaInaura/assets/13635059/f4e9b4a0-210d-4f8c-8e65-263b3a501c2c)

# Clean Shot X の 欠点 - ミニウィンドウに対するショートカット操作

スクリーンショット撮影をした後に、ミニウィンドウに対してのアクション(コピーとか閉じるとか)をするには、カーソル操作が必要だ

たとえば「スクリーンショット撮影 -> クリップボードにコピー」の流れをショートカットだけでは操作できないようだ

たぶん全てショートカット操作できるようにしてしまうと、他のアプリのショートカットを奪ってしまい操作に影響があるので、この仕様になっているんじゃないだろうか

ここはMac標準のキーボードショートカットも併用し続けることで解決するかもしれない

## Macの設定 > キーボードショットカット

CleanShot X のセットアップ時に「Macの設定で全てのキーボードショートカットを無効にせよ」と言われるが、セットアップ完了後にMacの設定を戻しつつ、CleanShot X を使い続けることは出来るようだ

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/0dbf9066-f533-4295-9c2d-dfa1f6b9041e)

自分の場合はMac標準の

- **Command + Shift + Ctrl + 4 で画面範囲選択して、キャプチャをクリップボードに入れる**
- **Command + Shift + 3 で画面全体のキャプチャを撮影してファイル保存する**

というショートカットは多用しているため、これは CleanShot X に上書きさせずに使い続けたい。


## CleanShot X のショートカット設定

CleanShot Xでもショートカット設定を変えられるので、使いやすいキーに設定すると良いだろう


<img width="654" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/c583a808-97b1-43b4-99ad-46de43d5a849">


# Clean Shot X の 欠点 - ミニウィンドウが閉じてしまうと使いづらい

画像をコピー・保存などするとすぐにミニウィンドウは消えてしまうので、それが少しもどかしい
基本的には一時作業の流れで使うのに向いていそうだ

## キャプチャ履歴

キャプチャ履歴機能があり、履歴からミニウィンドウに復元することもできる

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/bfede8de-4427-4516-93b3-06c1b7742a86)

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/4ea66b04-1763-4903-a1fa-74db353fdd19)

## ファイルから開いてお絵かき、クリップボードから開いてお絵かき

- 保存済みの画像も Clean Shot X で開いてお絵かきすること自体は出来る
- クリップボードに画像がコピーされていると、その画像に対してお絵かきモードを開始することができる

# 料金

無料トライアルはなく、買い切り版かサブスク版があるようだ

<img width="1512" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/fd75807f-d2c2-44ec-b7b3-f85fb5b73d1b">
【bat】文字列長の取得

両端を削ってカウント
終わったら二倍・帳尻合わせ

```bat
@echo off
call :GET_LENGTH 123456789
echo %length%
goto :end

:GET_LENGTH
setlocal enabledelayedexpansion
	set n=0
	if "%~1" == "" goto :GET_LENGTH_END
	set str=%~1

	:GET_LENGTH_LOOP
	set /a n += 1
	if not "!str:~%n%,-%n%!" == "" goto :GET_LENGTH_LOOP

	set /a n = %n% * 2 - 1
	if not "!str:~%n%!" == "" set /a n += 1

	:GET_LENGTH_END
	rem echo %n%	%~1
endlocal & set length=%n%
exit /b

:end 
pause
```
ChatGPT で elixir を学ぶ　（その2） 整数の加算

こちらの記事の続きです。
[ChatGPT で elixir を学ぶ　（その1）](https://qiita.com/ekzemplaro/items/2e0e26672bc6e50a5bb1)

次に加算のプログラムを試みました。
残念ながら、ChatGPT も、Gemini も実行可能なプログラムは作成できませんでした。

## Python のプログラム

```py:sum.py
#! /usr/bin/python
#
import sys
#
sys.stderr.write("*** 開始 ***\n")
aa = int(sys.argv[1])
bb = int(sys.argv[2])
print("aa = %d\tbb = %d" % (aa,bb))
sum = aa + bb
print("sum = %d" % sum)
sys.stderr.write("*** 終了 ***\n")
```

実行結果

```text
$ ./sum.py 12 34
*** 開始 ***
aa = 12	bb = 34
sum = 46
*** 終了 ***
```

## ChatGPT が作成したプログラム

```exs:ch01.exs
args = System.argv()

IO.puts("*** 開始 ***")
aa = String.to_integer(Enum.at(args, 1))
bb = String.to_integer(Enum.at(args, 2))
IO.puts("aa = #{aa}\tbb = #{bb}")
sum = aa + bb
IO.puts("sum = #{sum}")
IO.puts("*** 終了 ***")
```

実行結果

```text
$ elixir ch01.exs 12 34
*** 開始 ***
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: not a binary

    :erlang.binary_to_integer(nil)
    ch01.exs:5: (file)
    (elixir 1.14.0) lib/code.ex:1245: Code.require_file/2
```

## Gemini が作成したプログラム

```exs:ge01.exs
defmodule Sum do
  def main(args) do
    {aa, bb} = String.split(args.hd, " ") |> Enum.map(&String.to_integer/1)
    IO.stderr("*** 開始 ***\n")
    IO.puts("aa = #{aa}\tbb = #{bb}")
    sum = aa + bb
    IO.puts("sum = #{sum}")
    IO.stderr("*** 終了 ***\n")
  end
end

Sum.main(System.argv)
```

実行結果

```text
$ elixir ge01.exs 12 34
** (KeyError) key :hd not found in: ["12", "34"]. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
    ge01.exs:3: Sum.main/1
    (elixir 1.14.0) lib/code.ex:1245: Code.require_file/2
```

## 私が作成したプログラム

```exs:sum.exs
IO.puts :stderr,"*** 開始 ***"
[ax | tail] = System.argv()
aa = String.to_integer(ax)
[bx | _] = tail 
bb = String.to_integer(bx) 
sum = aa + bb
IO.puts ("aa = #{aa}\tbb = #{bb}")
IO.puts("sum = #{sum}")
IO.puts :stderr,"*** 終了 ***"
```

実行結果

```text
$ elixir sum.exs 12 34
*** 開始 ***
aa = 12	bb = 34
sum = 46
*** 終了 ***
```

## Enum.at を使ったプログラム

```exs:sum02.exs
IO.puts :stderr,"*** 開始 ***"
args = System.argv()
aa = String.to_integer(Enum.at(args, 0))
bb = String.to_integer(Enum.at(args, 1))
sum = aa + bb
IO.puts ("aa = #{aa}\tbb = #{bb}")
IO.puts("sum = #{sum}")
IO.puts :stderr,"*** 終了 ***"
```

実行結果

```text
$ elixir sum02.exs 12 34
*** 開始 ***
aa = 12	bb = 34
sum = 46
*** 終了 ***
```