OmniAICreator/Qiita-1.07M huggingface dataset:
久しぶりにGNS3（その31：MTUとフラグメント）

# MTU越えサイズのパケットのフラグメント化
ルーターに小さめのMTUサイズを設定し、ルーターにてフラグメント化する様子を観察する。

## 環境
![topology.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/bd8dab69-58c1-ced7-0d9c-054cd0daf70f.png)
ルーターR1およびR2にて、MTUサイズを300として、左側のPC1からPC2へMTUサイズ以上のデータ（ここではICMPパケット）を送る。IPアドレスは記載されたとおり。

## 設定
関連するところのみ記載。「mtu 300」以外、特筆すべき事項はないだろう。

### R1

```
interface FastEthernet0/0
 mtu 300
 ip address 10.1.1.1 255.255.255.0
!
interface FastEthernet0/1
 ip address 192.168.10.254 255.255.255.0
!
router rip
 network 10.0.0.0
 network 192.168.10.0
```

### R2
```
interface FastEthernet0/0
 mtu 300
 ip address 10.1.1.2 255.255.255.0
!
interface FastEthernet0/1
 ip address 192.168.20.254 255.255.255.0
!
router rip
 network 10.0.0.0
 network 192.168.20.0
```

## 検証
### ping実行
PC1からPC2へ、MTU以上のデータサイズを指定したpingを実行する。ここでは、MTU=300に対して、400バイトを指定。その結果が下記となる。
```
PC1> ping 192.168.20.1 -c 10 -l 400
192.168.20.1 icmp_seq=1 timeout
192.168.20.1 icmp_seq=2 timeout
428 bytes from 192.168.20.1 icmp_seq=3 ttl=62 time=50.823 ms
428 bytes from 192.168.20.1 icmp_seq=4 ttl=62 time=60.813 ms
428 bytes from 192.168.20.1 icmp_seq=5 ttl=62 time=66.587 ms
428 bytes from 192.168.20.1 icmp_seq=6 ttl=62 time=51.184 ms
428 bytes from 192.168.20.1 icmp_seq=7 ttl=62 time=57.308 ms
428 bytes from 192.168.20.1 icmp_seq=8 ttl=62 time=48.957 ms
428 bytes from 192.168.20.1 icmp_seq=9 ttl=62 time=58.319 ms
428 bytes from 192.168.20.1 icmp_seq=10 ttl=62 time=50.798 ms
```

### 考察（Wiresharkで取得したデータ）
#### PC1-R1
![PC1-R1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/6d966481-9f70-a4e8-2e09-2d704fb79239.png)
PC1(192.168.10.1)からはフラグメント化されていないデータを送信しているが、PC2(192.168.20.1)からはフラグメント化されているデータを受信している。パケット番号461-463参照。

#### R1-R2
![R1-R2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/1193509f-ab28-4377-33d0-468edc55dd6b.png)
PC1からのデータは、R1にてフラグメント化されて送られる。PC2からのデータもフラグメント化されて送られる。パケット番号883-886参照。

#### R2-PC2
![R2-PC2のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/6129a792-a9b9-7af1-2c79-931e6099e177.png)
R2からフラグメントされたデータはPC2にてリアセンブルされ、応答自体はフラグメント化されずに送られる。パケット番号193-195参照。

フラグメント化されたデータは下記。最初データは、DFビットが立っている。
![DF=1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/8cf7ab77-9c1e-b3cd-b352-9a76d109baab.png)
最後（２番目）のデータは、DFビットが立っていない。
![DF=0のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/022e92af-d399-861b-d074-fb7c88aeaea5.png)

期待どおりの結果である。

EOF
nextcloud mixhostに実装後の事後設定メモ

## 実装後の設定
https://deaimobi.com/nextcloud-settings/

## PHP.ini
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51918/89436803-9e35-48d2-1bb2-1df42d63bd1d.png)

## アプリのインストール/設定
- アプリから「Default encryption module」を有効
- CRONの設定
    - cPanel > CRONジョブ 5分に1回 / 
    - コマンド: /usr/local/cpanel/3rdparty/bin/php -f /home/XXXXXXX/public_html/mydomain.net/cron.php
    ※ php -f では駄目みたい。古いバージョンで実施され、初期化で問題が発生し実行が完了出来ない
        - Nextcoud 基本設定 > バックグラウンドジョブ Cron(推奨)


## 動画のサムネが表示されない件
- ❌️ ImageMagick
    - mixhostでは対応していない
- ❌️ PerlMagick
    - ImageMagickのPerlラッパー版
    - mixhostにインストールされてるが、NextCloud側が対応していない
- ffmpeg で対応出来ないだろうか検証中

# エラー対応
### Nextcloud 28 では、少なくとも PHP 8.1 が必要になる可能性があります
cPanelのファイルマネージャーから、該当のドメインのルートになるファイルを選択
`MultiPHP マネージャー`
を選択。インストールしたドメインを選択して、該当のPHPバージョンを反映する

### Strict-Transport-Security "HTTP ヘッダーの秒数が少なくとも"15552000" に設定されていません。
インストールしたドメインのディレクトリルートの.htaccessの行頭に以下を追加

cPanelのファイルマネージャーから、該当のドメインのルートになるファイルを選択し、
`右クリック → メニュー → edit`
```.htaccess
### HSTS設定 1年以上は安全な接続（HTTPS）を強制、サブドメインにも適用する
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
```


## その他エラー
- サーバーにはメンテナンスウィンドウの開始時間が設定されていません。これは、リソースを多く使用する日常のバックグラウンドジョブが、メインの利用時間中にも実行されることを意味します。利用者がこれらの重いタスクによる負荷の影響を受けにくくするために、低い利用時間に設定することをおすすめします。
- メモリキャッシュが設定されていません。パフォーマンスを向上させるため、利用可能であればメモリキャッシュを設定してください。
- このインスタンスには、いくつかの推奨 PHP モジュールがありません。パフォーマンスと互換性を向上させるために、これらをインストールすることを強くお勧めします: sodium.
- ご使用のシステムには、デフォルトの電話地域が設定されていません。これは、プロフィール設定で国コードなしの電話番号を有効にするために必要です。国コードなしの電話番号を許可するには、"default_phone_region" を地域の ISO 3166-1 コードとともに設定ファイルに追加してください。
- メールサーバーの設定が未設定または未確認です。「基本設定」で設定を行ってください。その後、フォームの下にある「メールを送信」ボタンで設定を確認してください。
- テーマ別アプリは有効ですが、PHPモジュール「imagick」が有効ではありません。ファビコン生成を正しく行うには、このモジュールをインストールし、有効化する必要があります。
- インストールガイド ↗を再確認して、 ログ にあるすべてのエラーや警告を確認してください。

## 未実施
### データベースがトランザクションファイルロックに使われています
https://docs.nextcloud.com/server/28/admin_manual/configuration_server/caching_configuration.html
- APCu、APCu 4.0.6 以降が必要です。
    - [旧サーバーのみ可能](https://help.mixhost.jp/hc/ja/articles/115003814011-APCu%E3%81%AE%E5%88%A9%E7%94%A8%E5%8F%AF%E5%90%A6%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)っぽい。対応不可
- Redis、PHP モジュール 2.2.6 以降が必要です。
    - [Redisをただのレンタルサーバー上で安定して使う方法](https://yaseiblog.org/redis-on-shared-hosting/#google_vignette)
    - キャッシュの設定にはRedisのインストールが前提になりそうで、インストールも検証も面倒臭いしネットで実績が見当たらないから辞め。
- Memcached
    - こいつもネットで実績が見当たらない。Redisよりカスリもしない。


# 調査したい/やりたいなぁ
- FFmpeg 
    - [エックスサーバーでffmpegを使う方法](https://taishou.ne.jp/xserver-ffmpeg/)
    - [FFmpegを使って動画や音声の処理を行う](https://www.otsuka-bs.co.jp/web-creation/blog/archive/20231011-02.html)
Salesforceエンジニアがkintoneを勉強してみた

## はじめに
私はSalesforceエンジニアですが、案件の関係でkintoneを勉強しています。
勉強する前は、Salesforceとkintoneはどちらもクラウドサービスで、類似した製品という印象でした。
しかし、ちゃんと勉強してみるとかなり違うことがわかりました。
今日は、私なりに感じたkintoneとSalesforceの違いについてまとめていきたいと思います。

## kintone用語
kintoneとSalesforceは当然用語が違います。
Salesforceを勉強し始めたときは、Salesforceの用語ってちょっとクセがあるなーと感じていたのですが、kintoneもなかなかクセがあります 笑
- ポータル
kintoneにログインして一番最初に開かれる画面です。ここから様々な画面に遷移できます。
Salesforceでいうところの「ホーム画面」になります。
- アプリ
業務システムのことを「アプリ」と呼びます。具体的には、1つのDBテーブルに関連する画面や機能が1つのまとまりになった単位です。Salesforceでいうところの「オブジェクト」になります。
1テーブルの単位で「アプリ」と呼ぶ点にいちばんクセを感じています 笑
- スペース
チーム内でのコミュニケーションを取ることができる場所です。任意のチーム単位で作成することができます。
チームメンバーでチャットをすることもできますし、スペース専用のポータルやアプリを設定することができます。
アプリの閲覧権限を制御する時に便利な機能になります。
kintoneはSalesforceのように複雑な権限設定をすることが難しいので、スペースという機能があるのかなと推測しています。

## kintoneができること
### ノーコードでシステム開発ができる
この点がkintoneの最も大きな特徴で、kintoneサービスを提供しているサイボウズ社が提唱している主要なコンセプトの1つです。
Salesforceも標準機能だけ使えばノーコードで実装できる点は同じですが、kintoneは標準機能による設定画面からもプログラミング要素を極力排除しており、ITに明るくない人でもシステムが作れるようになっています。
例えば、Salesforceでは各オブジェクトや項目にAPI参照名、いわゆる物理名を設定し、それは英数字で設定しなくてはなりません。kintoneでも物理名の設定は必要ですが、日本語でもいいんです！さすが日本生まれのノーコードツールですね。
物理名が日本語だと、論理名と物理名を同じ値に設定できて、数式等で項目を参照する際にとてもわかりやすくなります。これはプログラミングを知らない人にとってはかなりメリットなのではないかと思います。

### レコードのプロセスやステータスに応じた管理ができる
kintoneには、プロセスという機能が備わっています。
例えば、レコードの承認プロセスを設定し、承認者になったらそのユーザーに通知するといったプロセスを組むことができます。ステータスの変更と同時に特定のユーザーに通知するといったこともできます。
これらの機能については、Salesforceにも承認プロセスという機能がありますし、どちらかというとSalesofrceの方が難しいことができます。しかし、Excel等でデータ管理をしていたらできないことです。
標準機能だけでは実現できることが限られていますが、プラグインによる機能拡張は可能です。

### 追加機能のプラグインが豊富
kintoneの標準機能で実現できることは正直言って十分とは言えません。しかし、それを保管するプラグインがたくさんあり、プラグインを使いこなすことがkintoneを使いこなすことに繋がってきます。
プラグインには無料のものと有料のものがあるので、予算に応じてプラグインを選択していくことになります。

### 低予算でシステム開発ができる
kintoneのライセンス料はとてもリーズナブルで、1ユーザーあたり月額1500円です。プランにもよりますが、Salesforceの1/10以下になるのでしょうか・・　価格面は圧倒的ですね。
ただし、kintoneは標準機能でできることの範囲が限られており、プラグインの導入がほぼ必須なのですが、プラグインの種類によっては有料であるため、追加料金は考慮する必要があります。仮に有料プラグインを複数導入しても、Salesforceのライセンス料を超えることはないと思います。

##kintoneではできないこと
### アプリに複数の画面レイアウトを設定できない
kintoneはアプリに対して1つの画面しかつくることができず、Salesforceのようにレコードタイプによって画面レイアウトを切り替えるといったことができません。そのため、部署やロール毎に画面の表示を切り替えることに関しては柔軟に対応できません。
画面を切り替えることはできませんが、項目単位の参照権限の設定は可能です。

### アプリ同士のリレーションが基本的には1対1のみ
kintoneはアプリ同士のリレーションについて細かく設定することができないため、アプリ同士のリレーションは基本的に1対1になります。レコードにテーブルフィールドを設置することで1対多のようなデータの持ち方を実現することは可能です。
ただ、一般的なシステムの1対多と異なる点は、子レコードを変更しても親レコードで参照している値が更新されないことです。そのため、子レコードの更新に伴って親レコードの参照項目も更新するような仕様を実現するのは標準機能では難しいです。（プラグインを使えばできるかも）

### 標準機能で実現できる範囲が小さい
今までのご説明でも「プラグイン」というワードがたくさん出てきたように、kintoneは標準機能で実現できることに限りがあり、実現したい仕様によってはプラグインの導入やCSS、JavaScriptを用いた開発が必要になる場合が多々あります。Excelで管理しているものをkintoneに移行するのであれば標準機能で実装可能かもしれませんが、業務システムを作りたいとなると、ほとんどの場合追加実装やプラグインが必要になると思います。
kintoneで業務システムを開発したい場合は、標準機能だけでは実現できないことを認識しておいたほうがいいかもしれません。

## おわりに
今回は、Salesforceエンジニアである私が感じた、kintoneとSalesforceの違いについて解説してみました。
比較されることが多い2製品ですが、比べてみると結構違うなと感じています。

最後までお読みいただきありがとうございました。
【Salesforce】日付項目を数式の戻り値で時間を返す

Salesforceの日付項目を数式の戻り値で時間を返すについて記事にします。

日時型の項目はTIMEVALUE関数で時間型に変換できるようです。
また、数式項目では、UTCからのタイムゾーンの変換は行われないようです。
ですので、日本時間に直す場合は９時間を足す必要があります。

ちなみに、時間項目値の精度はミリ秒単位で、日付/時間項目値の精度は秒単位です。

実際に数式項目を作成します。

### 数式の戻り値のデータ型
データ型は数式で、戻り値は「時間」を選択します。

![01時間.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/789516/738ad21e-c931-ea63-029e-38f59c47d8a2.png)


### 数式オプション
以下の数式で、作成日の日付が含まれないタイムスタンプで返却しています。

`TIMEVALUE(CreatedDate )+ 3600000 * 9`

![02作成時間の例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/789516/d9d0dc7b-b41d-1cb3-948b-820f2b167b6b.png)


### 作成時間（数式）
数式で「時間」のみ表示されています。

![03時間の表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/789516/1c27bd59-5db2-08bc-10ab-ab365a25d899.png)


レポートで、時間帯毎に分析したいという要件などでも、使用できると思います。

もし宜しければ、お試しください。

※参考
https://help.salesforce.com/s/articleView?id=sf.custom_field_time_overview.htm&type=5
「変数名付きの用語集」で品質高く開発できた理由

## はじめに

◆この記事は何？
変数名付き用語集の作り方を紹介する記事です。
「上流品質を高める用語集」の作り方を紹介します。

◆対象は？
開発に関わる人

◆この記事のねらい
より良い用語集を作れるようになること

## 先に結論
- 用語集で変数名を定義することで品質が高くなった
- 品質が高いのは、ドキュメント/コード/テストデータで表記揺れがなくなったため
- 良い用語集にするために
    - メンテナンスしやすさを重視する
    - ジャンル別で整理する

## 「良い用語集」とは？

「良い用語集」とは、**上流品質の向上**に寄与している用語集だと考えます。

プロジェクト開始前に用語集を作成し、「用語集を正」として、要件定義書を作成して、データベース設計書を作成して、設計書を作成して、コーディングして、テストをしていきます。

つまり、全てのフェーズで用語集を活用し、表記揺れを無くします。

その結果、品質向上の活動をより上流に移すこと（Shitf Left）ができます。

## 変数名を定義する
上流品質を高めるために、変数名を定義します。

例えば、次のように整理します。

| # | 用語 | 変数名 | 意味 |備考 |
|:-:|:-:|:-:|:-:|:-:|
| 1 | 在庫型物流センター | distribution_center | 商品が一時的に保管され、さらなる配送のために分類される施設 | [DC（Distribution Center）とは？](https://imagers.co.jp/contents/966/)  |
| 2 | 最終目的地 | final_destination | 商品が最終的に届けられる場所 | 例：消費者の住所  |
| 3 |  バース |berth| 荷降ろしをするためにトラックを停車させておく場所 | 関連：バース予約 |

この変数名をテーブル定義、コーディング、テストなどで採用します。

◆用語集で変数名を定義するメリット

用語集で変数名を定義するメリットは次のとおりです。

- 変数の表記揺れがなくなる
- 変数名を考える時間が減る
- 使いまわせる箇所が増えて効率が上がる
- レビューの工数が減る
- 可読性が上がる
- 検索性が上がる

変数名を定義するだけで、挙げればキリがないくらいのメリットを享受できます。

## メンテナンスしやすさを重視する

特にプロジェクト序盤では、用語集は高い頻度で更新されます。

そのため、メンテナンスしやすい状態を保つことが重要です。

具体的には、列を増やしすぎないようにしています。

補足したいことは「備考」を積極的に使います。

## ジャンル別に整理する

用語はジャンル別で整理します。

これは用語集を使いやすくするための工夫であると同時に、用語集のメンテナンス性を高める工夫でもあります。

例えば、「場所に関する用語」と「時間に関する用語」は分けて整理します。
先ほど挙げた例は「場所に関する用語」です。

下記は「時間に関する用語」です。

◆時間に関する用語
| # | 用語 | 変数名 | 意味 |備考 |
|:-:|:-:|:-:|:-:|:-:|
| 1 | 予定配達日時 | estimated_delivery_datetime | 顧客に通知される商品の予定配達日時 |   |
| 2 | リードタイム | lead_time | 顧客が注文してから届くまでの時間  |  単位は時間(hour) |
| 3 | 出荷日 | ship_date | 商品が倉庫や配送センターを出発する日  |   |

※接尾語について、日付に関するものは「date」、日時は「datetime」などとあらかじめポリシーを決めておきます。

プロジェクトごとにジャンルを考える必要がありますが、まずは次のようなジャンルを考えると良いかと思います。

- 組織図/役職
- ステークホルダ
- 時間に関する用語
- 場所に関する用語
- お金に関する用語
- 業務フローに登場する用語
- マスタテーブルで使われる用語
- 既存サービス/システム

## おわりに

この記事では、良い用語集の作り方を紹介しました。

私は、変数名付きの用語集を作るようになって、良い開発ができるようになりました。
「上流品質が高い開発ができる」と自信を持てたのは「変数名付き用語集」のおかげです。

皆さんの用語集の工夫があれば、ぜひ教えてください。

この記事がお役に立てれば幸いです。

それでは。


## 参考

[ソフトウェア品質を高める開発者テスト](https://amzn.asia/d/bxyBfCL)
(レジ直)StampS3の5番、高速Lチカで遊ぶ。(マクロ展開化)(約8Mhz?)


目的
目にもとまらぬ速度でLチカ。
5番の高速化を明示的にマクロ展開化して
引数のスタックとリターンからの戻りを削減する。


![o_coq029.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/42e35f2f-568d-bb47-fce3-7eb6e8156166.jpeg)






```c++



//GPIO_HS_IO_M5S3_1
//ESP32-S3用の高速I/O


//インクルド
#include <Arduino.h>


//定義
#define GPIO_0to31SET_REG     *((volatile unsigned long *)GPIO_OUT_W1TS_REG)
#define GPIO_0to31CLR_REG     *((volatile unsigned long *)GPIO_OUT_W1TC_REG)

//I/Oの番号を指定
#define GPIO_D5_P 5

//セット
#define GPIO_0to31SET_REG_5  (GPIO_0to31SET_REG=(1<<GPIO_D5_P))

//クリア
#define GPIO_0to31CLR_REG_5  (GPIO_0to31CLR_REG=(1<<GPIO_D5_P))


//初期化
void setup() {

  //ポートの初期化
  pinMode(5, OUTPUT);

//無限ループ
while01:

  //高速I/O
  GPIO_0to31CLR_REG_5;
  //delay(1000);//debug

  GPIO_0to31SET_REG_5;
  //delay(1000);//debug

goto while01;

}//setup


//メインループ
void loop() {}


```
[Python3][Google Colab]画像ファイル名を一連番号に変更する方法

## 要　旨
Python3においてGoogle Colabを使用して、画像ファイル名を一連番号に変更する方法について記述します。
## 実行環境
PC: DELL G16 7630
言語:Python3
プラットフォーム:Google Colab
## 実施要領
imageフォルダ内の画像ファイル名を一連番号に変換するコードは、以下の通り。
```python3
import os
import glob

# 画像ファイル名を取得
files = glob.glob('image/*')

# 画像分だけ名前変更処理を繰り返す
for idx, f in enumerate(files):
    # ファイル名を分解
    ftitle, fext = os.path.splitext(f)
    
    # ファイル名を変更
    os.rename(f, format(idx, '04d') + fext)
```
このコードを実行すると、image フォルダ内の画像ファイル名が 0000.jpg、0001.jpg、0002.jpg といった連番に変更されます。
## 結　言
今回は、Python3においてGoogle Colabを使用して、画像ファイル名を一連番号に変更する方法について記述しました。
TDZによるエラー【JS】

# はじめに

未知の仕様がありましたので共有です。

```js
const f = () => console.log(x)
const x = 'xx'

f()
```

このコードを実行すると、`const x` ...つまり、`xx`と表示されます。
`const f`の定義時点では`x`が何者か定義されていませんが、これでも動くんですね。
（~~これはこれで、エラーにしてもいいのでは・・・？~~）

では、これではどうでしょう？

```diff_javascript
const f = () => console.log(x)
- const x = 'xx'

f()
+ const x = 'xx'
```

`const x`が`f()`の実行時に定義されていません。
エラーが発生するでしょう。
`ReferenceError: x is not defined`（`x`が定義されてないよ）と表示されるはずです。

<details><summary>答え</summary>

```
ReferenceError: Cannot access 'x' before initialization
```

あれ？
予想は「`x`が定義されてないよ」でしたが、
実際は「`x`が初期化する前にアクセスすることはできないよ」でした。

試しに、`const x`を消してみましょう。
これこそ、`ReferenceError: x is not defined`（`x`が定義されてないよ）が表示されるはずです。
```diff_javascript
const f = () => console.log(x)

f()
- const x = 'xx'
```
```
ReferenceError: x is not defined
```
予想通りですね。

ではやはり、最初のエラーは「`x`が定義されていない」とは別のエラーのようです。
</details>

# TDZの影響

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let#%E4%B8%80%E6%99%82%E7%9A%84%E3%81%AA%E3%83%87%E3%83%83%E3%83%89%E3%82%BE%E3%83%BC%E3%83%B3_tdz:~:text=%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82-,%E4%B8%80%E6%99%82%E7%9A%84%E3%81%AA%E3%83%87%E3%83%83%E3%83%89%E3%82%BE%E3%83%BC%E3%83%B3%20(TDZ),-let%20%E3%81%BE%E3%81%9F%E3%81%AF%20const

> `let` または `const` 変数は、ブロックの始まりからコードが実行されて変数が宣言され初期化される行に到達するまでは、「一時的なデッドゾーン」(TDZ) 内にあると言います。

https://developer.mozilla.org/ja/docs/Glossary/Hoisting

> 人によっては let, const, class を巻き上げが行われないと見なしますが、それは一時的デッドゾーンで宣言前に変数を使用することを厳しく禁止しているからです。

なるほど。どうやら一時的デッドゾーン（TDZ）というものが存在するようです。

直接、件のコードに対する言及ではありませんが、以下の記述がありました。

>  `const` 宣言が定義されているスコープ全体をまだ「汚染」しているため、 `console.log(x)` 文はまだ初期化されていない `const x = 2` 宣言から `x` を読み込み、 [`ReferenceError`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError) を発生します。

という説明がありました。「汚染」いいですね。

1. 初期化（宣言）の行われたスコープはTDZにより、ある種「汚染」される
2. その中での呼出は`ReferenceError: Cannot access 'x' before initialization`を発生させる
3. 事前に宣言されていても、TDZによるエラーが優先される

# 他の実例

これはどうでしょう？
`f()`と`console.log(x)`の2箇所で`x`の出力を試みています。
```js
const f = () => {const x = 'xxx'; console.log(x) }

f()
console.log(x)
const x = 'xx'
```
一見、どちらも`const x = 'xx'`の影響でエラーになりそうですが・・・

```
xxx
/home/runner/testtdz/tdz.js:3
console.log(x)
            ^

ReferenceError: Cannot access 'x' before initialization
```

`xxx`が出力されているので、最初の`f()`は予想に反して動いていますね。
`console.log(x)`は予想通りのエラーです。

なぜ、`f()`はエラーにならないのでしょう？
<details><summary>答え</summary>

**スコープが違うから**

`f()`は、関数内で宣言された`const x = 'xxx'`を優先します。関数内に`x`が存在する以上、これ以外の`x`を認識しません。
よって、TDZによる「汚染」は起きていないということですね。

なので、例えば以下の例では`ReferenceError: Cannot access 'x' before initialization`になります。
```js
const f = () => { console.log(x); const x = 'xxx' }
f();
```

</details>

# おわりに

知らない挙動がまだまだありますね。


さて、次は何を書こうかしら・・・
Pythonで「ディレクトリの作成と削除(pathlibモジュール)」の動作を確認してみた

# 概要

Pythonで「ディレクトリの作成と削除(pathlibモジュール)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/file/index11.html

# 実装

以下のファイルを作成しました。
```sample1.py
import pathlib
p = pathlib.Path('./test/code/java/2020')
p.mkdir(parents=True)
```
```sample2.py
import pathlib
p = pathlib.Path('./test/back')
p.rmdir()
```

以下のコマンドを実行しました。
```
$ python3 sample1.py
$ ls test
code
$ mkdir test/back
$ ls test
back  code
$ python3 sample2.py 
$ ls test
code
```

# まとめ
何かの役に立てばと。
謎解きでよく使う正規表現

謎解きで、いい感じの単語を探す時の正規表現です

# 文字数

```
^...$
```
３文字の単語を検索したい場合です


^は行頭、$は行末を意味します
多くの場合、１行に１単語の形でしょうから、^$で挟むこと文字数を指定します

```
^.{3}$
```
３文字検索を繰り返しで表現した形です

```
^.{3,4}$
```
文字数を３～４文字で検索します
もし、３文字以上なら、{3,}と書きます

# クロスワード的使い方

```
^.い.う$
```
○い○う、(例：かいそう)という風な単語を探したい場合です

# 文字指定
```
^[げつかすいもくきんどにち]{4}$
```
「げつかすいもくきんどにち」の文字だけを使った4文字を検索します
[]の中身に同じ文字が複数入ってても問題ないです

```
^.[げつかすいもくきんどにち]{2,}$
^[げつかすいもくきんどにち]{2,}.$
^[げつかすいもくきんどにち]{1,}.[げつかすいもくきんどにち]{1,}.$
```
１文字だけ何かを足して単語を検索します
先頭と末尾に足す場合は長さを指定しやすいですが、
中間になにかとなると３文字の単語が多く出てしまいますので、
一旦検索結果を保存して４文字以上と再検索するといいです

# ナンクロ的使い方

```
^(.)(.).\1\2.$
```
１文字目と４文字目、２文字目と５文字目が同じな６文字の単語を探します
括弧の中身を前から数えた部分と同じ文字を\1で指定します
「１２？１２？」(例：いちごいちえ)という単語を検索したい場合です
Fishシェルをインストールした時にやること

# はじめに

途中までであるかもしれませんがFishをインストールしたときの初期設定を書いていきます

環境はWSL Ubuntu です

# 設定

## vim


最初はfishでvimを開いたときにBS(バックスペース)のみで一文字戻ることができず不便でした
使えるようにするには
~/.config/fish/config.fishに

```shell
bind \b backward-delete-char
```
と追記
Ctrl + hでも左一文字を削除できるらしい

キーバインドはhttps://qiita.com/ryotako/items/ba7483b6fde025c91cef
またコマンドプロンプトの画面においてパス名が略されて表示されているのですべてを表示するなら
~/.config/fish/config.fishに
```
function fish_prompt
    echo -n (whoami)'@'(hostname)' '(pwd)' '
    echo -n '> '
end
```
と追記しましょう。

と書きました

## プラグインマネージャー

oh-my-fishかfisherの場合は以下に示します
fisherの開発頻度はoh-my-fishより高そうでfisherでいいかなって感じ

### oh-my-fishの場合

```shell
curl -L https://get.oh-my.fish | fish
```

または

```shell
wget -qO- https://get.oh-my.fish | fish
```

ちなみに
 omf destroyでoh-my-fishのアンインストールができ
 ```
 >read 
 ```
 と入力が求められる

```
yes
```
と打てばアンインストールされる

yesと打てって書いてない...

 こんな感じ
```
⋊> /m/c/U/{ユーザ名} omf destroy                                                                                                                     02:16:47
Checking for a sane environment...
This will uninstall Oh My Fish and all plugins and themes from 
/home/{ユーザ名}/.local/share/omf.
read> yes
Uninstalling from /home/{ユーザ名}/.local/share/omf...
Uninstall complete
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
```

### fisherの場合


```
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
```


プラグインをインストール
```
fisher install <プラグイン名>
```


プラグインをアンインストール
uninstallではないので注意
```
fisher remove <プラグイン名>
```


## その他

```
fish_config
```

と打つとGUIでfishの環境を変更できる
nftablesを用いたIPアドレス制限(国別)


# nftablesを用いたIPアドレス制限
## 国ごとに割り振られているIPアドレス一覧を取得する
IPアドレスの一覧を APINIC[^1] で公開されているものを取得する。
```sh
curl -LO http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
```

## 指定した国家のIPアドレスを取り出す
```awk:ip_by_country.awk
BEGIN{
    FS="|"
    ipv4="country_whitelist_ipv4"
    ipv6="country_whitelist_ipv6"
    stderr="/dev/stderr"
    print "define country_whitelist_ipv4 = {" > ipv4
    print "define country_whitelist_ipv6 = {" > ipv6
}
{
    if ($2 ~ country) {
        if ($3=="ipv4") {
            ip=$4
            if(and($5,$5-1) == 0) {
                mask=32-log($5)/log(2)
                if (!a[ip,mask]++) print ip"/"mask"," >> ipv4
            } else {
                print "Something is wrong with netmask(CIDR range).\n" ip " / " $5 > stderr
            }
        } else if ($3=="ipv6") {
            ip=$4
            prefix=$5
            if (!b[ip,prefix]++) print ip"/"prefix"," >> ipv6
        }
    }
}
END{
    print "}">> ipv4
    print "}">> ipv6
}
```
上記スクリプトは、カレントディレクトリにcountry_whitelist_ipv4,country_whitelist_ipv6を作成します。

### 日本のみ
```sh
awk -v country="JP" -f ip_by_country.awk delegated-apnic-latest
```
### 複数の国を指定する場合
```sh
awk -v country="JP|US|RU" -f ip_by_country.awk delegated-apnic-latest
```
## nftables.confの設定例(抜粋)
### /etc/nftablesにコピーしておきます
```sh
mkdir -p /etc/nftables
sudo cp country_whitelist_ipv4 /etc/nftables/
sudo cp country_whitelist_ipv6 /etc/nftables/
```
### nftables.confでincludeする。  
sshのポートが22の場合の例。
```nftables
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:

include "/etc/nftables/country_whitelist_ipv4"
include "/etc/nftables/country_whitelist_ipv6"

table inet filter {
    set country_accept_ipv4 {
        type ipv4_addr; flags interval;
        elements = $country_whitelist_ipv4
    }
    set country_accept_ipv6 {
        type ipv6_addr; flags interval;
        elements = $country_whitelist_ipv6
    }
```
```nftables
        ct state new tcp dport 22 ip saddr @country_accept_ipv4 counter accept
        ct state new tcp dport 22 ip6 saddr @country_accept_ipv6 counter accept
```
# 参考サイト

https://inaba-serverdesign.jp/blog/20191219/nftables-country-ipaddress-centos8.html


https://systemexpress.co.jp/centos/ipblock.html


https://www2.filewo.net/wordpress/2019/10/19/2206/


[^1]: http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
SQL 複数列の合計を求める

SQLの```SUM```関数を用いて、複数列の値の合計を求めたい場面がありました。

例えば以下のようなテーブルがあります。

| id | A | B | C |
| :---: | :---: | :---: | :---: |
| 1 | 100 | 50 | 30 |
| 2 | 150 | 200 | 300 |

列A,B,Cの値すべての合計を取得する場合、以下のように書くことができます。

```sql
SELECT SUM(A) + SUM(B) + SUM(C) FROM テーブル名; -- 830
```
また、次のように書くこともでき、コードがシンプルになります。しかし、この書き方では値にNULLが含まれている場合に注意が必要です。

```sql
SELECT SUM(A + B + C) FROM テーブル名; -- 830
```

### 値にNULLが含まれている場合
以下のテーブルのように、値にNULLが含まれている場合の対応について説明します。

| id | A | B | C |
| :---: | :---: | :---: | :---: |
| 1 | 100 | 50 | 30 |
| 2 | 150 | 200 | NULL |


```sql
SELECT SUM(A + B + C) FROM テーブル名; -- 180
```

合計を取得すると、2行目のC列がNULLのため、2行目のA,Bの値(150,200)も合計に含まれていません。
これを回避するために、```COALESCE```関数を使用し、NULL値をデフォルト値に置き換えます。

```sql
SELECT SUM(COALESCE(A, 0) + COALESCE(B, 0) + COALESCE(C, 0)) FROM テーブル名; -- 530
```

上記を実行すると、C列2行目のNULLが0に置き換えられ、すべての行が合計されます。
(レジ直)StampS3の5番、Lチカで遊ぶ。(キャスト)


目的
GPIOレジスターに直接出力する。
カラー液晶駆動の為に5番をLチカする。


![o_coq028.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cb1df4f1-9625-8184-33c8-f45b650f4aa9.jpeg)




```c++



//reg_di_gpio5_M5S3_2


//定義
#define GPIO_0to31SET_REG   *((volatile unsigned long *)GPIO_OUT_W1TS_REG)
#define GPIO_0to31CLR_REG   *((volatile unsigned long *)GPIO_OUT_W1TC_REG)


//初期化
void setup() {

  //GPIOの初期化
  pinMode(5, OUTPUT);
  
}//setup


//メインループ
void loop() {
  
  //digitalWrite(5, HIGH);
  GPIO_0to31SET_REG = GPIO_0to31SET_REG | (1<<5);
  delay(1000);
  
  //digitalWrite(5, LOW);
  GPIO_0to31CLR_REG = GPIO_0to31CLR_REG | (1<<5);
  delay(1000);
  
}//loop



```
このテキスト ファイルのデータは、1 つのワークシートに入りきりません。

エクセルでCSCファイルをインポートしようとした際にタイトルのようなエラーが出ることがあります。

ケースの一つとして __csvファイルの改行コードがLFとなっている__ ことが原因であることがあります。
<br>
この場合vscodeでcsvファイルを開き
![スクリーンショット 2024-04-13 0.05.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083286/5cffe5f2-1672-d37d-725a-60f21e9e1f23.png)
画像のLFをクリック

![スクリーンショット 2024-04-13 0.05.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083286/dc33cce1-f329-8761-89b2-a9c6bd8db4e5.png)
画像のCRLFをクリック
<br>
<br>



これで改行コードがCRLFとなりインポートできるようになります。

ちなみにインポートの際に文字化けしてしまうときは元のファイルの文字コードを Unicode(UFT-8) としてあげるとなおることがあります。
🧶 Backpropagation

数値微分を使う方法は1つのパラメータ(レイヤ0のbiasの0番目など)を少し小さくして、順伝播し、少し大きくして、順伝播する、そしてこれをすべてのパラメータに対して行うというとても遅い方法です。
これを改善したのがBackpropagationで、とても速い効率的なアルゴリズムです。
ここでは、シンプルにするために、各層のニューロンが1つの、以下のNN(ニューラルネットワーク)で解説します。
また、Loss fn（損失関数）はMean Squared Error (MSE)を使います。
```
Weight
Bias
ReLU
Weight
Bias
ReLU
```

目標は「Lossを小さくする」ことなので、シンプルにするためにLoss fnもネットワークに入れてしまいます。
損失関数は答えも知っています。
```
Weight
Bias
ReLU
Weight
Bias
ReLU
Loss fn (MSE)
```
こうすると、「出力を小さくしたい」ということにできます。
では、どうすれば高速に小さくできるでしょうか？

一つ一つのレイヤが数学の関数だと考えてください。いくつかの関数はパラメータを持っています。
一度forward（順伝播）します。このときにいろいろ保存します。
そして、Loss fnにどのような値を入力すればいいかを考えます。そのために、Loss fnを微分します。
これで、Loss fnへの入力をどのように変えればいいかわかりました。
でも、次はReLUであり、パラメータではありません。なので、ReLUも同様に微分します。ですが、ReLUは最後のレイヤではないので、最後のレイヤの微分も考えないと、ReLUを微分してReLUの出力を小さくしても意味がありません。なので、最後のレイヤの微分の結果にReLUの微分の結果を付け足すということをします。
つまり、最後のレイヤの微分の結果にReLUの微分の結果を掛けるということです。
「Back」してますね！
ReLUは入力によって微分の結果が変わります。これにはforward時に保存しておいたデータを使います。

そして、これをすべてのレイヤに適用します。
すると、あるレイヤの出力を1変えるとどれだけネットワークの出力(Loss)が変わるかがわかります。
Biasは1大きくすればどれだけLossが変わるかわかるので、簡単ですね。微分できました！
Weightは入力によって変わります。例えば入力が0なら、いくら変更しても何も変わりません。入力が保存してあるのでこれも簡単にできます。ReLUと似ていますね。

Backpropagationは、とても速いアルゴリズムです。
私は昔、自分でアルゴリズムを考えて遊んでいました。その頃は初期値などを知らなかったのもあり、うまくいくものはありませんでしたが楽しかったです。
少し変えてみたり、新しいアルゴリズムを考えて作って、遊ぶのはとても楽しいのでぜひやってみてください！

最後まで読んでいただきありがとうございました！🧶
【Next.js】サーバーコンポーネントでクエリパラメータを取得する方法

`page.tsx`に以下のように記述するとサーバーコンポーネントでクエリパラメータを取得できます。

```tsx:app/sample/page.tsx
type Props = {
  searchParams: { [key: string]: string | string[] | undefined }
}

export default function Sample({ searchParams }: Props) {
  console.log(searchParams)

  return (
    <>
      {/* ... */}
    </>
  )
}

```

`/sample?test=sample`に遷移するとコンソールに`{ test: 'sample' }`が表示されます。
Node single executable applicationsでnpmパッケージを使う

[Node single executable applications](https://nodejs.org/api/single-executable-applications.html) を使うと簡単にNodeのスクリプトをexe化できる。

しかし、その名の通り、exe化できるのは1つのJavaScriptのみ❗
つまり、 `import` で自作ライブラリを使うことはもちろん、npmパッケージも使えないのだ❗
なんて限定的な機能なんだ❗クソッ❗

...とまぁ、分かってる人はこの時点で「アホだな〜」と思われてると思う。

そう、解決策は簡単で、バンドラーを使えば良い。
WebPackとか、esbuildとか、そういうやつ。
バンドラーは複数のJavaScriptファイルを1つにまとめてくれるので、
SEAを作るときにはもってこいってわけだね。

っていうか、ドキュメント↓にそう書いてあるんだわ。ちゃんと読もう。

> Node.js supports the creation of single executable applications by allowing the injection of a blob prepared by Node.js, which can contain a **bundled script**, into the node binary.

## 実践: TypeScriptでSEAのexeを作る

肝心のSEA作るとこまでできてないけど、
esbuildでTypeScriptをバンドルするだけのシンプルなサンプルプロジェクトを作った↓。

- [esbuild-typescript-vscode-template](https://github.com/tenpaMk2/esbuild-typescript-vscode-template)

(VSCodeでブレークポイントを貼ってデバッグすることもできる。)

↑のサンプルプロジェクトをビルドすると、
サンプルソースをバンドルして `dist/index.cjs` ができる。

ポイントはesbuildのビルド設定で `--platform=node` にすること。
あとは `--format=cjs` かな。
ともかく、CommonJSの形式にしないと今のところSEAを使えないので、ここはマスト。

あとは、SEAのドキュメントに従って、 `dist/index.cjs` をexe化していけば良い。
全部まとめると↓。

```sh
echo '{ "main": "dist/index.cjs", "output": "sea-prep.blob" }' > sea-config.json
node --experimental-sea-config sea-config.json
node -e "require('fs').copyFileSync(process.execPath, 'index.exe')" 
npx postject index.exe NODE_SEA_BLOB sea-prep.blob `
    --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 
```

ちなみに、今確認したらWindowsだけ動いた。
Macでは `postject` するときにエラーを吐いた。
どうも [このissue](https://github.com/nodejs/help/issues/4313) と同じ症状のようだ。残念。
通信プロトコルについて

## 背景
学習した内容の備忘録です

## 概要
通信プロトコルの基礎的な内容を記載しております

## 通信プロトコルとは
一言で言うと、情報の連携をするための規約のようなもの

通信プロトコルとは、コンピュータが通信する際に必要な規約でそれぞれ階層ごとに異なる
ネットワーク上の通信で使用されているため 通信プロトコルと呼ばれている
プロトコルを決めることで送信側と受信側の通信を可能にする

## OSI参照モデル
一言で言うと、通信の方法を１つに統一したルールを機能別で７つの階層に分けたもの

ネットワークアーキテクチャを１つに統一したネットワーク標準規格で用いられる通信のモデル
コンピュータネットワークに求められる機能を７階層の構造に分解したもの

![スクリーンショット 2024-04-11 0.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518751/fbef8bba-13dc-b673-44e5-9d4a21360b67.png)

## TCP/IPモデル
TCP/IPとは
ネットワークの接続するためのプロトコル

TCP（Transmisson Control Protocol）、IP（Internet Protocol）とは、データの送受信などネットワーク上でのサービスを可能にしているプロトコルの集まりのこと
ネットワークの普及によって広く利用されるようになった

TCP/IPモデルは、各プロトコルを役割ごとに4つの階層に分けた階層構造のこと
⭐️アプリケーション層
　利用者が操作するアプリケーションの決まり事を定めること

【主な通信プロトコル】
・HTTP
　→Webサイトをお閲覧する際に使用する
・SMTP
　→メールを送信する際に使用する
・IMAP
　→電子メールを受信する際に使用する
・FTP
　→ファイルを転送する際に使用する

⭐️トランスポート層
　データの送受信に関しての信頼性の取り決めを行う
【面な通信プロトコル】
・TCP
　→まるで会話のように通信相手の状態を確認しながら通信を行う信頼性の高い通信プロトコル
・UDP
→通信相手に一歩的にデータを送ることで速度を優先した通信プロトコル

⭐️ネットワーク層
データを目的地まで送信する役割
【面な通信プロトコル】
・IP
→インターネット上で通信するためには欠かせない通信プロトコル
インターネット上の住所であるIPアドレスについて定義をしている
・ICMP
→IPを補助する役割を持つ通信プロトコル
IP通信において発生した各種エラー上歩の検知などを行う

⭐️ネットワークインターフェース層
隣接するコンピュータ間の通信を可能にしビット列を電気信号などに変換すること
【面な通信プロトコル】
・ARP
→IPアドレスからMACアドレスを取得するための通信プロトコル
・イーサネット
→コンピュータをネットワークに接続する時に使用するネットワークケーブルの規格（有線LAN）

## まとめ
プロトコルの簡単な概要を記載しました。
階層によって、さまざまなプロトコルが存在していてそれぞれがネットワークが接続されたコンピュータの通信を行う上で重要な役割を持っています。
WEBの仕組みを理解する上で土台となる知識なので、はじめに楽手することが重要かと思います。
VSCodeで謎の音が鳴り止まない

# はじめに
いつも通りコーディングしていたある日のこと，突然「フォンフォン（？）」鳴るようになった．
最初は他のアプリなどを起動していたこともあり，それの通知かと思っていたが，それにしても頻度が高い．

検索すると原因が`audioCues`にあるという記事[^ref]は出てくるが，私の`VSCode`にはそのような設定項目は無く……

# 対処法
色々と設定を手当たり次第に触ってみると，`accessibility.signals`が原因であると判明しました！

`VSCode`の設定は以下の手順で触ることができます．

1. `ctrl` + `,`で設定を開く
1. 設定の検索に`accessibility.signals`と入力
1. 項目の`sound`を`off`に変更

# 最後に
非常に短い記事ですが，`accessibility.signals`について言及している記事は（少なくとも私が検索した中では）見られなかったため，同じような環境の方の助けになればと思い，公開に至りました．

`VSCode`にも種類があるのか？あるいは，最新Verでは項目が変わったのか？
いずれにせよ，定かではありませんが，参考までに．


[^ref]: - [How to turn off (or on) sounds from Visual Studio Code?](https://stackoverflow.com/questions/54173462/how-to-turn-off-or-on-sounds-from-visual-studio-code)
    - [【VS Code 設定】編集中ファイルでエラー箇所があるとエラー音がうるさいので消したい時の方法](https://push.tokyo/kill-error-sound-vs-code/)
Godot スプライトシート化で起動時間を短縮する

## 要約
- スプライトファィルを集約したら起動時間が短くなった
- Sprite2DをAnimatedSprite2Dに置き換える事で変更作業量を軽減できる

環境：Godot4.2＋ C#(.Net Framework6.0)

## はじめに
　Godotで開発を始めて半年くらい経ちますが、開発環境の立ち上げに時間がかかるようになってきました。他のゲームエンジンに比べれば全然速いんですが、空白のプロジェクトの立ち上げ時間＋3秒位かかっています。
　ファィル数も増えてきたので仕方のない事かな…とも思いましたが、その時集中して行っていた作業が主に画像ファィルの追加（複数の敵キャラの実装）でした。単なる直感ですがスプライト画像ファィルの構成が影響しているかも？と思い至ります。
 　まだ開発序盤でありこの先さらに画像ファィルを追加する事がわかっています。徐々に遅くなる開発環境の立ち上げは精神衛生によろしくありません。

 という事で開発作業を一時中断して構成変更を試みます。


## 構成変更前
　思いつくままゲームオブジェクトをデザインしていたので、オブジェクト１つに1枚のスプライトシートの構成になっていました。

　構成変更前のイメージとしては以下のようなファィル構成です。

 <img width="600" alt="before" src="https://pbs.twimg.com/media/GK9pI3rbQAETjXn?format=jpg&name=large">

　この時のファィル数と起動時間は以下の通りです。
| 項目 | 数 |
|:-----------|:------------|
| 画像ファィル数 | 51 枚 |
| 起動時間平均 | 6.30 sec |
 

## 構成変更後
　上記の散逸した画像ファィルを3枚のスプライトシートファィルに集約します。背景画像やシェーダー用、パーティクル用の画像はスプライトシート化していません。


 <img width="600" alt="after" src="https://pbs.twimg.com/media/GK4c4P4aUAA05Q6?format=jpg&name=large">


　集約した後の画像ファィ数と起動時間は以下の通りです。
| 項目 | 数 |
|:-----------|:------------|
| 画像ファィル数 | 16 枚 |
| 起動時間平均 | 5.80 sec |


　単純計算ですが画像ファィルを35枚減らしたことで0.5秒の短縮になります。奇しくも1ファィル当たり1/60秒に近しい時間の短縮となり、結構な効果が得られた！という印象です。

## 構成変更に伴うコード修正
　Sprite2DのAnimation-hFrames, vFramesを用いて画像ファィルを分割し、Frameの値を更新してアニメーションしていた箇所は少々手間がかかります。

  <img width="300" alt="inspector" src="https://pbs.twimg.com/media/GK99PIqaIAAPZRS?format=png&name=360x360">

　Frame番号が連続した0～nである事を想定したハードコードを、スプライトシート全体を対象とした分割後のFrame番号に置き換える必要が出てきます。
 　スプライトシートに特に工夫をせずピクセル位置だけを合わせて配置しなおしたので、Frame番号の変更は当然として連続した番号ですらなくなります。

  <img width="300" alt="oh-no" src="https://pbs.twimg.com/media/GK-DTRwbMAASew8?format=png&name=900x900
">



　考えるだけで気を失いそうな作業です。この後もスプライトシートに追加変更を行う予定なので確実にエンバグするでしょう。
　ここはSprite2DからAnimatedSprite2Dに型の変更を行う事にしました。実際のスプライトシート上のFrame番号ではなくAnimatedSprite2DのFrame番号として扱えるよう仮想化(誤魔化し)レイヤーを挟んでエンバグを抑える回避策を採用しました。

  <img width="600" alt="virtualize" src="https://pbs.twimg.com/media/GK-FkWPbUAATD_T?format=png&name=large">



　Sprite2DをAnimatedSprite2Dに変更してもVisible、Frame、SelfModulateといったプロパティ名は変わりません。スプライトシート上のFrame番号をAnimatedSprite2Dのdefaultアニメーションフレーム番号として置き換える事で、現時点での色々な厄介事から解放されます。

　もちろん実行時のコストは多少増えるでしょうから性能影響が懸念されます。が…それは問題が顕在化した時に考える事とします(笑)
 
　※2DスプライトのSTGなので性能問題はほぼ起きないでしょう。

```before.cs

	private Sprite2D _sprite;
    _sprite = GetNode(GC.Sprite2D) as Sprite2D;

    _sprite.Visible;
    _sprite.Frame = trans.fno;
    _sprite.SelfModulate = color;

```

```after.cs

	private AnimatedSprite2D _sprite;
    _sprite = GetNode(GC.AnimatedSprite2D) as AnimatedSprite2D;

    _sprite.Visible;
    _sprite.Frame = trans.fno;
    _sprite.SelfModulate = color;

```


## 余談
　演出効果として自機の周りにチャージショットの溜め時間を円グラフで表示するシェーダーを使っていましたが、スプライトシート全体にたいしてシェーダーの効果がかかるのでスプライトシート化は諦め1ファィルで取り扱う事にしました。
　元々は徐々に円グラフを表示していましたが、スプライトシート化で一気に全体が表示されるようになりました。インスペクターで数値を変えながら観察した所、スプライトシート全体に効果が適用されたためだと理解しました。

https://x.com/cabbagestole/status/1778665280665002414

　またパーティクル用の画像ファィルはAnimationによるスプライト切り出しがそもそも出来ないので、これも1ファィルとして残しました。
ヒューリスティックなマルチエージェント経路計画手法

# はじめに．
ヒューリスティックな Multi-Agent 経路探索(path-plannning, path-finding)アルゴリズム：MAPF アルゴリズムの一部を簡単にまとめています．幅探索、深さ探索、均一コスト探索などの一般的な Singple-Agent 向けの経路探索アルゴリズムについては、知っていることを前提としています．
※筆者の理解に応じて追記する予定です．
2024/04/12 : A* と Extentions of A* (OD,ID)の説明記載．


## 通常 A* → Multi-Agent A* への適応.
　Single-Agent について、最もオーソドックスかつ有効な探索アルゴリズムとして A* アルゴリズムが知られています．幅探索、深さ探索のアルゴリズムを発展させた「最良優先探索アルゴリズム」に含まれるアルゴリズムです．A* アルゴリズムは、ある状態 $s$ に対してセット $\(s,g(s),h(s),f(s))$ を利用して探索を行います．ここで、

 - $g(s)$ はスタート状態 $\rightarrow$ 現在状態 $s$ への最小コスト
 - $h(s)$ は現在状態 $\rightarrow$ ゴール状態への推定コスト

です．A* アルゴリズムでは $f(s) = g(s)+h(s)$ の値を基に、コストの小さいノードを優先して探索することになります．A* アルゴリズムにおいては、推定コスト $h(s)$ がある条件を満たせば、解が見つかるという「完全性」と解が最短であるという「最適性」を持つ事が知られています． 

　この通常の A* を Multi-Agent の経路探索に用いることを考えます．この時、Agent の数を N 台、各 Agent の次に取れる行動集合を $A_i$ とすると、Multi-Agent の状態集合 $S = (s_1,...,s_N) $ を親ノードとする次の子(状態集合) S'の数は、$\Pi_{i\in N} |A_i|$ となります．仮に、全 Agent が「上、下、左、右」にしか移動しないとすると、その子ノード数の上限は $4^N$ となります．$1$ つの状態遷移でこれだけの分岐が増えることから、通常の A* を Multi-Agent に適応することは解の探索コストの観点から難しいことが理解出来ます．そして、この台数に対するスケーラビリティや探索のリアルタイム性を改善するために、これまで数多くの改良アルゴリズムが提案されてきました． 

## Extentions of A*：
Single-Agent 向けの経路探索アルゴリズムであった A* を Multi-Agent に拡張するために改善されたモデル達を、Extentions of A* と呼びます．前述の Multi-Agent 向けに通常の A* をそのまま用いた場合解の探索コストが指数関数的に増えてしまうという課題に対処することを目的としています．以降、Multi-Agent は $N$ 台の「上、下、左、右、静止」の $5$ つの行動を取る Agent から構成されているとします．

**Operator Decomposition(OD).**
Agent 達を優先度(priorlized)付きに変更し、優先度順に $1$ つのノード分岐を特定 Agent の状態変化のみで行う手法です．つまり、親-子ノードの差は $1$ つの Agent の状態変化のみで、他の Agents の状態は固定となっています．$1$ つの分岐では、通常の A* を適応した場合 $5^N$ 個の分岐があった一方で、OD では $5$ 個の分岐に減らすことが可能になっています． 

 ```math
 (s_1,...,s_{i-1},s_{i},s_{i+1},...,s_N) \rightarrow (s_1,...,s_{i-1},s'_{i},s_{i+1},...,s_N)
```

一方で、構築される探索木の深さは通常の A* の適応よりも $n$ 倍深くなります．

**Independence Detection(ID).**
ID は、$N$ 台の MAPF 問題をより小さい台数の MAPF 問題に分解するアプローチです．MAPF 問題において難点を生じさせているのは、環境の非定常性と協調性でした．環境の非定常性とは、ある Agent $i$ が時刻 $t$ 移動した場合に、他の Agent が同じ時刻 $t$ で移動することで、Agent $i$ が時刻 $t$ で想定していた時刻 $t+1$ の状態に移動出来ない可能性が生じることです．ID では、衝突する Agent の経路ペアのみを取り出してしまえば、$N$ 台のMAPF問題を衝突のペア数 $k$ 台のMAPF問題に分割出来るという発想を基にしています．ただし、全ての Agent 経路に衝突が存在するような場合は分割が出来ません．また、これ自体で経路が求まる訳では無く、あくまで分割アプローチであって分割後の MAPF 問題は別のアルゴリズムで解く必要があります．勿論、A*$+$OD を分割後の問題を解くために使うことも出来ます．
StreamlitとPlotlyを組み合わせた動的なグラフの作成方法

お疲れ様です。

今日は「StreamlitとPlotlyを組み合わせた動的なグラフの作成方法」について部分いたします。

Plotlyは、動的なグラフを作成するためのライブラリです。

Streamlitと組み合わせることで、ユーザーが操作できる動的なダッシュボードを作成することができます。

以下で解説していきます。

# Plotlyでの基本的なグラフ作成

Plotlyでは、各グラフごとに関数が用意されており、その関数を変数に格納することで、Streamlitで表示できます。

例えば、以下のコードでは`px.scatter`関数で散布図を作成し、`st.plotly_chart`関数でStreamlit上に表示しています。

```python
import streamlit as st
import plotly.express as px

# データの作成
df = px.data.iris()

# Plotlyでグラフを作成
fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species')

# Streamlitで表示
st.plotly_chart(fig)
```

上記のコードは、アヤメのデータセットを基にした散布図を作成するものです。

また、Plotlyは、`plotly.express`をpxとしてインポートします。

上記のコードを実行して出力されたグラフは以下の通りです。

![Screenshot 2024-04-12 at 10.48.03 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507088/90efbe96-4a3e-c7ff-4cdb-f83112e26b55.png)

Plotlyが特徴的な点は、右上のツールの所です。

画像のダウンロードやグラフの拡大縮小、表示範囲の選択など様々なツールが用意されているため、ユーザーが扱いやすいグラフを用意できます。

また、3Dグラフの作成も可能で、以下のようなグラフをStreamlit上で表示可能です。

![Screenshot 2024-04-12 at 10.48.30 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507088/5e5c4210-761f-090c-f4df-3adcfa247635.png)

このように、高度なグラフも作成できることから、ダッシュボードの作成にはPlotlyが用いられることがあります。

なので、覚えておいて損はないでしょう。

# StreamlitとPlotlyの組み合わせ方の例

Streamlitのウィジェットと組み合わせ方の1例を紹介します。

例えば、トグルを用意して、ONの状態でグラフを表示させることができます。

![Screenshot 2024-04-12 at 10.49.08 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507088/04b06928-2f1e-992c-1ad6-2a0d454be62e.png)

トグルのようにユーザーが表示するかどうかを選べるようにすることで、ユーザー満足度が上がります。

他にも、セレクトボックスで表示するグラフを変えたり、複数選択ボックスで変数の数を変えたりすることも可能です。

複数選択ボックスについて詳しく知りたい方は、[【完全網羅】Streamlitのmultiselectの扱い方を解説](https://shoblog.iiyan.net/data-engineering/python/streamlit-multiselect/)の記事をご参照ください。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
Streamlitの超ざっくりしたアーキテクチャ

# はじめに
皆さん、Streamlit使っていますか？
とても便利ですよね！！！ね(´・ω・｀)？
Streamlitは簡単にWebアプリケーションを開発するだけでなく、クラウドサービスへのデプロイも簡単であることから人気のあるWebフレームワークとなっています。
そんなStreamlitですが、データを読み込んだ際にどんな入出力の流れになっているのだろう？と思ったので、超ざっくりですがアーキテクチャとして流れをまとめてみました。
**※主観的な意見も混じっているかと思いますので、間違いがあればご指摘ください。**

もっと細かな仕組みを知りたい方は以下の記事を参照してみてください。

https://qiita.com/yasudakn/items/089aaf4488fc6a8396ae


# アーキテクチャ
![streamlit_exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/60bdcb06-46f4-1d5c-7d85-9d60b7c0200d.png)

早速アーキテクチャを示しました。
StreamlitはフロントエンドとしてReactを用いて開発されているようです。
バックエンドは当然Pythonですね。
Pythonのコードでフロントエンドも開発できるようにReact側？で設計されているのだと想像します。

データの流れとしてはアーキテクチャのように、ユーザーからの入力はブラウザを通してバックエンド側に読み込まれます（アーキテクチャではいきなりバックエンドに書いてますが、正確にはフロントエンドで入力したものがバックエンドで読み込まれます）。
フロントエンドから受け取ったデータ等をバックエンドで処理した結果を、JSON形式などにシリアライズしたものをフロントエンドに送信し、ユーザーに表示されるという仕組みになっています。
また、フロントエンド側でスライダーやボタンなどのユーザーインターフェースの操作をイベントとしてデータを取得し、その結果をバックエンドに渡すことで処理が実行し、最新の結果が表示されることになります。

ローカル環境で実行する際は、このデータの流れは特に意識する必要はありませんが、クラウド上にデプロイする際には、フロントエンドとバックエンド間の通信を暗号化するなどしてデータの安全性を高めることが重要です。
社内のIPアドレスからのみアクセスできるように制限をかけるなど、データ漏洩に細心の注意を払わないとですね！

# まとめ
いかがだったでしょうか。
今回は技術的なことを一切書いてはいませんが、Streamlitをより理解するために知っておいて良いのかなと思ったのでまとめました。
実際にITやDXに疎い企業はたくさんあります。私が転職する前に在籍していた会社もデータ漏洩などにはかなり気を付けていたので、こういうデータの流れというのを説明できるようにしておくのも必要かと思います。
はじめにも記載しましたが、間違いがあれば是非ご指摘いただけると助かります(/・ω・)/
それでは！！！
JVM - Native Method Interface (JNI) 

Java Virtual Machine（JVM）は、Javaプログラムが異なるプラットフォーム上で一貫した動作をするための環境を提供しますが、すべてのタスクをJavaのみで実行することが最適とは限りません。パフォーマンスの要求が高い、またはプラットフォーム固有の機能にアクセスする必要がある場合、JavaプログラマーはNative Method Interface（JNI）を利用して、ネイティブプログラミング言語（主にCまたはC++）を使用してJavaアプリケーションを拡張することができます。

![jvm_architecture_hotspot.drawio (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260307/a5c76eb7-dfdb-bd73-4260-90c09d047e87.png)

## JNIとは

JNIは、Javaコード内からネイティブメソッド（CやC++で書かれたメソッド）を呼び出すためのプログラミングフレームワークです。これにより、JavaアプリケーションはOSの低レベル機能やネイティブライブラリを利用できるようになります。例えば、システムのハードウェア情報にアクセスしたり、高性能が必要な数値計算ライブラリを使用したりする場合にJNIが役立ちます。

## JNIのメリット

* **パフォーマンスの向上**: 計算集約的なタスクはネイティブコードで処理する方が効率的な場合が多いです。JNIを使用することで、これらのタスクを高速化できます。
* **ライブラリのアクセス**: 既存のネイティブライブラリへのアクセスをJavaから行えます。これにより、アプリケーションの開発時間を短縮し、既存の資産を活用することができます。

## JNIのデメリット

* **複雑さの増加**: JNIを使用すると、アプリケーションの複雑さが増し、バグが発生しやすくなる可能性があります。
* **メモリ管理の問題**: Javaはガベージコレクションを使用してメモリ管理を行いますが、ネイティブコードではプログラマーが直接メモリ管理を行う必要があります。これにより、メモリリークや他のメモリ関連の問題が発生するリスクが増えます。

## JNIの使用例

Java標準APIでは多くの部分でJNIが使われています。

```java
// Object class
public final native Class<?> getClass();

// Thread class
private native void start0();
```

abstract以外の識別子と併用できます。

```java
public class NativeMethodTest {
    public native void Native1(int x);
    public native static long Native2();
    private native synchronized float Native3();
    native void Native4(int[] a) throws Exception;
}
```


## 最後に

JNIは、Javaとネイティブプログラムと橋渡しする重要なツールです。適切に使用すれば、Javaアプリケーションの可能性を大きく広げることができますが、その複雑性とリスクも理解しておく必要があります。JNIの使用は慎重に検討し、適切なテストとデバッグを行うことが重要です。

## 参考情報

* [Java Native Interface](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/jni/index.html)
nvidia-container-cli でrequirement error: unsatisfied conditionエラーが出た場合

GPUマシンで`docker run`時以下のようなエラーが出た場合。
nvidiaのdriverが古くて利用したいdocker image とミスマッチになっている場合に出るみたい。

```bash
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "process_linux.go:449: container init caused \"process_linux.go:432: running prestart hook 0 caused \\\"error running hook: exit status 1, stdout: , stderr: nvidia-container-cli: requirement error: unsatisfied condition: cuda>=11.8, please update your driver to a newer version, or use an earlier cuda continer\\\\n\\\"\"": unknown.
```

みんなで、開発しているとnvidiaのdriverをすぐに更新できないことも多い。（他の人のコンテナな起動できなくなってしまったら困る）

その場合は以下で一旦解決できることがある。


docker 起動時に以下の環境変数`NVIDIA_DISABLE_REQUIRE`を設定すればよい。

```bash
docker run --gpus all \
     -itd --privileged=true \ 
     -e NVIDIA_DISABLE_REQUIRE=true \ ★これ
     --name ${CONTAINER_NAME} ${IMAGE_NAME}
```

ただし、コンテナの動作中に動作は保証されてないようですが、だいたいうまくいく。
メインバージョンの差はスキップしてくれる。11 or 12 は無理だと思う。

参考URL:
https://forums.developer.nvidia.com/t/unable-to-start-cuda-container-with-recent-update-on-november-10/272883
自作ツールがMicrosoft Defenderでウィルスとして誤判定されて解消するまで

## TL;DR

Tauriを使用して作成したデスクトップアプリがMicrosoft Defenderによって誤ってトロイの木馬と判定され、誤判定の報告と解析依頼を行い、8時間ほどで誤判定がクリアされました

## 背景
Tauriでデスクトップアプリを作成し、[[MV2期限間近] ブラウザ拡張の Manifest V2/V3 をチェックできるツールを作った](https://qiita.com/owayo/items/49ae624fbaf8db8ff94d)の記事で紹介した。
普段 Mac を使っているのだが、Macからダウンロードできることも確認をした。
が、Windows使いの友人から「ダウンロードできないよー」と連絡をもらい、詳細を確認させてもらったところ**Trojan:Script/Phonzy.B!ml**としてウィルス判定されているようだった。
どういうことなの・・・？

![スクリーンショット-2024-03-12-135959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/7ca2f3c5-e63d-85a5-503c-a10eb0b8464b.png)

## VirusTotalで調べる
VirusTotal にツールのURLを渡してスキャンしてみる。
[スキャン結果](https://www.virustotal.com/gui/url/90adf76b9bf49094db3f9528c58649d4f125c1ed969189696ad5f293aeb0c7a2?nocache=1)
VirusTotalでは全てClean判定。
どうやらMicrosoft Defenderだけがウィルスとして誤判定するみたい。

## Microsoftへ解析を依頼
[Submit a file for malware analysis](https://www.microsoft.com/en-us/wdsi/filesubmission/)から、ファイルをMSに送信して詳しく調べてもらうことで、誤判定を改善できるみたい。
**Home customer** を選択し、必要事項を入力、 **What do you believe this file is?** で、 **Incorrectly detected as PUA (potentially unwanted application)** を選択してファイルを送信する。
受付が完了すると、**Submission Received**という件名のメールが届きます。
しばらく待ちましょう・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/a390246b-892f-5e83-6019-518cddaabd19.png)


## 8時間後・・・
**Analysis completed - submission ID xxxxx** という件名のメールが届きました。
解析が終わったとのことで、Submissionのページを見てみると、**Analyst comments**に以下のように書かれていました

> The submitted files do not meet our criteria for malware or potentially unwanted applications. No detection will be added for these files.
> 
> More detailed information about the approach and criteria categories currently used by the Microsoft researchers are available here:
> https://docs.microsoft.com/windows/security/threat-protection/intelligence/criteria
> 
> Thank you for contacting Microsoft.

送信してもらったファイルからはマルウェアは検出されなかったから、もう検出されなくなるよ
とのこと

Rescan submissionをクリックするとアップロードしたファイルへのスキャンが行われるようなので、ボタンをクリック。
すべてClean判定になったことを確認。
今回の場合、1.407.345.0 という定義パターン以降で誤判定されなくなるみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/6eb96754-5f5e-4eba-0d90-d225bd51b93e.png)

その後、Windows側でパターンの更新を行うと、該当のパターンがダウンロードされました

![スクリーンショット 2024-03-12 211114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3741957/bf621b7a-103b-565c-7e74-edc0be75c59e.png)

これで無事誤判定されなくなりました。

## ちょっと時間はかかったけどちゃんと対応してもらえました

この経験から、マイクロソフトがユーザーのフィードバックに基づいて迅速に行動を起こし、問題を解決できる体制が整っていることがわかりました。初めはウィルス判定されたという事実に多少の不安とフラストレーションを感じていましたが、結果的にMicrosoftのサポートチームが効率的に対応してくれたので、その点は大変心強く感じました。

誤判定という事態は開発者にとっては頭の痛い問題ですが、このような問題に直面しても冷静に対処すべき道がしっかりと存在することが確認でき、安心しました。また、自分のアプリケーションが安全であるという証明を迅速に行えるシステムがあることが、他の開発者にとっても心強いはずです。

この一件で、技術的な障壁だけでなく、セキュリティの側面からも自分の作品を守る重要性を改めて認識しました。また、必要な手続きを踏むことで、大きなプラットフォームにおいても個々の開発者の声がちゃんと届くことが実感できたのは大きな収穫です。数時間の待ち時間はありましたが、予想外に早く問題が解決して安心しました。
composerで古くなったパッケージをインストール出来なくて困った話

# 何があった
Dockerコンテナで運用中の、Laravelで動いているとあるプロジェクトにて、gitlab-ciのコンテナビルドjobが失敗した。

原因を確認すると、ビルド中のcomposerでエラーになっていた模様。
エラーを見ると、

```
Installing propaganistas/laravel-intl (1.2.5): Downloading (connecting...)Downloading (failed)           Failed to download propaganistas/laravel-intl from dist: The "https://api.github.com/repos/Propaganistas/Laravel-Intl/zipball/f85d7bda85ddb78a956cf7d10b68b16d0b0664fa" file could not be downloaded (HTTP/1.1 404 Not Found)
```

....?


404 Not Found ??

パッケージのダウンロード元が見つかりません？
つい先日までビルドできてたのに・・・。

とりあえず、何か代替えを検討しないと、
せっかく修正したコードが反映できない。

という事で、対応を検討していく。


# まずやったこと
まずは見つからないパッケージが何ものかを調べ、パッケージ名が変わっていないか、導入方法が変わっていないかを調査。

するとどうやら、バージョンが上がってパッケージ名も少し変わっていたようだ。

という事で、composerの設定を変更してみる。

改めてビルドしてみると・・・・

あえなく失敗。

どうやら、パッケージのバージョンが上がって、使用しているLaravelのバージョンと合わなくなったようだ。

Laravelのバージョンは、5系と古い。
これ自体もアップグレードしたいが、それをするとコード全ての調整という一大事業になる。
今はそれを行なっている時間がなく、別の方法を検討する。

# ローカル手元には、パッケージ本体がある
そう、手元には、以前composerでインストールした古いバージョンのパッケージが存在する。
これを使うことはできないだろうか？

という事で調べてみると、composerには、インストール元のリポジトリを指定する事ができる。
元々は自作パッケージなどを使用する際に指定するための設定欄のようだ。

```
"repositories": [
        {
            "type": "path",
            "url": "[パッケージのディレクトリ]",
        }
    ],
```
これで、composerはインストール際にまず指定したリポジトリから探してくれる。
見つからなければ、デフォルトのリポジトリから探し、従来通りに挙動してくれる。

これだ！これでなんとかなりそうだ。

# うまくいきそうで行かない落とし穴
意気揚々とビルドする。

しかし、エラーに。
最初のエラーと同じく、`404 not fouond`に。
え、なんで？ローカルパスを指定してるんですけど。

なぜかcomposerは、まだデフォルトのリポジトリからあるはずのないパッケージを探している。
なぁぜなぁぜ？

と、大事な事を忘れていました。

__composer.lock__

composerは、composer.jsonではなく、lockファイルに従ってインストールを行う。

という事で、lockファイルをちゃんと作り直して実行。

めでたく、composerが成功し、ローカルにあるパッケージでLaravelアプリケーションが無事動き出してくれたとさ。


# 備考
- コンテナビルド時には、cacheを使ってビルドする事もあるので、その時はno-cacheを指定して行う
- 古いパッケージを使うのは良くない。ちゃんとメンテナンスして、フレッシュな状態を保ちましょう。（自戒。近いうちに検討します・・・・）
ブック内のシートの選択セルをA1セルに統一

VBAやVBScriptでよく書かれてる奴をOfficeスクリプトで。

```ts
function main(workbook: ExcelScript.Workbook) {
  let sheets = workbook.getWorksheets();
  for (let i = 0; i < sheets.length; i++) {
      let sheet = sheets[i];
      sheet.activate();
      sheet.getRange("A1").select();
  }
}
```
【マップの扱い 2】マップの書き換え・縦横 (paizaランク B 相当)

【マップの扱い 2】マップの書き換え・縦横 (paizaランク B 相当)
https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_upsidedown

![2024_04_07 【マップの扱い 2】マップの書き換え・縦横 提出コード.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768836/4ff6beae-0ec9-d725-89bb-4deb6e0b5ca7.jpeg)

paizaのランクBレベルアップメニュー問題集のpython解答コードです。
2重ループとifを用いて、(x,y)から隣接、つまり上下左右1マスの条件を設定して"."と"#"の書き換えを行いました。

<br>

【マップの扱い 3】マップの判定・縦横斜め (paizaランク B 相当)
https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_row_col


![2024_04_07 【マップの扱い 3】マップの判定・縦横斜め.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768836/d101d64a-cde1-1908-7c80-86590d6304fc.jpeg)

この問題は上下左右複数マスに加えて斜めのマスを書き換えるというものですが、ヒントが本文に書いてあるので素直にコード記述すれば回答できます。整数aの大きさは、仕様書の条件を見ると1 ≦ H , W ≦ 20と書いてあるのでrange(1,20)と設定すれば回答できます。
【Java】Consumer<T>とかSupplier<T>ってなに？

## はじめに
久しぶりにJavaに触れたら、Consumer\<T>とSupplier\<T>が分からなかったため、復習を兼ねて本稿にまとめます。

## 要約
- ConsumerやSupplierは関数型インターフェース
- 関数型インターフェース：abstractメソッドが1つだけ含まれているインターフェース
- Consumerインターフェース：引数を受け取ってその引数を使った処理を実行する
- Supplierインターフェース：引数を受け取らずに値を戻す
- ほかにも様々な関数型インターフェースがある

## 関数型インターフェースとは

Javaの公式ドキュメントでは以下のように記載されています。

> A functional interface is an interface that is not declared sealed and has just one abstract method (aside from the methods of Object), and thus represents a single function contract.
This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.

https://docs.oracle.com/javase/specs/jls/se17/html/jls-9.html#jls-9.8

DeepLに翻訳してもらった結果がこちらです。

> 関数型インターフェイスとは、（Objectのメソッドは別として）1つの抽象メソッドのみを持ち、sealed宣言されていないインターフェイスのことで、1つの関数契約を表します。
この "単一の "メソッドは、スーパーインターフェースから継承されたオーバーライドと同等のシグネチャを持つ複数の抽象メソッドの形をとることができます。

つまり、**Functional Interface（関数型インターフェース）とは1つの抽象メソッドのみを持つインターフェース**となります。
また、`sealed`宣言の説明は割愛しますが、以下の記事が個人的にわかりやすかったです。

https://zenn.dev/gakuzzzz/articles/f1bfb3d4ac6a66


## Consumerインターフェースとは

[公式のJavaDoc](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Consumer.html)には以下のように記載されています。

> 単一の入力引数を受け取って結果を返さないオペレーションを表します。Consumerは他のほとんどの関数型インタフェースと異なり、副作用を介して動作することを期待されます。

つまり、Consumerインターフェースは**引数を受け取ってその引数を使った処理を実行するメソッドを定めている**と言えます。
その定められたメソッドが`accept(T t)`です。

また、副作用とは、[Wikipedia](https://ja.wikipedia.org/wiki/%E5%89%AF%E4%BD%9C%E7%94%A8_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0))によると以下のように記載されています。

> 式は、評価値を得ること(※関数では「引数を受け取り値を返す」と表現する）が主たる作用とされ、それ以外のコンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させる作用を副作用という。
副作用の例としては、グローバル変数や静的ローカル変数の変更、ファイルの読み書きなどのI/O実行、などがある。

そのため、コンソールに結果を出力したり、インスタンス変数の値を変える等の処理をConsumerインターフェースの`accept(T t)`メソッドに記載して使用します。

## Supplierインターフェースとは

[公式のJavaDoc](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Supplier.html)には以下のように記載されています

> 結果のサプライヤを表します。
サプライヤを呼び出すたびに新しい(異なる)結果が返される必要はありません。

なるほどわからん。
わからないなぁと思っていたら以下のような記事を発見しました。

https://qiita.com/110shun/items/4333e210f3fbfc449904

ここには以下のように記載されていました。

> 名前の通り、Supplerは引数を受け取らずに値を戻す関数型インターフェースです。
get()メソッドを持っています。

使用シーンに関しては、同記事に以下のように記載されていました。

> 引数を受け取らずに値を戻す時に使います。
具体的にはインスタンスを生成する時や、引数関係なく値を出力する時に利用します。

個人的にはあまり使用頻度は高くなさそうに感じました。（もし「実際にこういうシーンで使用しているよ！」みたいなのがあればコメントお願いします :pray: ）

## 他の関数型インターフェース

関数型インターフェースが存在するパッケージ（`java.util.function`）には、今回取り上げた関数型インターフェースの他にも多くの種類のインターフェースが存在するっぽいです。

https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/package-summary.html

他にも気になったのあれば勉強してまた記事にしてみようと思います。

## 参考
- https://zenn.dev/risu729/articles/function-names
- https://zenn.dev/gakuzzzz/articles/f1bfb3d4ac6a66
- https://qiita.com/110shun/items/4333e210f3fbfc449904