OmniAICreator/Qiita-1.07M huggingface dataset:
Sharepointのリストをキャラリーで表示するときに、選択Onlyにする方法

Sharepointのリストを利用してFAQページを作成してみました。
上部にはカテゴリ一覧キャラリーで表示し、下にはFAQ一覧を表示します。

上部のカテゴリを選択すると下の一覧が自動的にフィルタリングされるよう作成しましたが、
キャラリーでアイテム自体をクリックすると詳細ページに遷移してしまうのが問題。

下記のようにカスタマイズし、
customRowAction定義のactionを変更し、
クリック時は選択のみになるように修正可能でした。


:::note info 
Sharepointの定義のレファレンスは下記から
https://learn.microsoft.com/ja-jp/sharepoint/dev/declarative-customization/formatting-syntax-reference
:::

:::note info 
ほか、SharepointのCSS定義などのサンプルがあるサイトを見つけたのでここにメモっておきます。
https://pnp.github.io/List-Formatting/groupings/classes/sp-card/
:::

### １．該当リストビューのキャラリーモードのビューに切り替え
    ビュー一覧のドロップダウンメニューをクリックし、「現在のビューの書式設定」を選択

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159211/0ebeeb8e-e263-6e62-3002-ff8351c31b8d.png)

### ２．「カードを編集」クリック後、下の「詳細モード」リンクをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159211/3d85a1a5-a357-2f4f-10b0-fe3c201dbfcd.png)

（すでに詳細モードで修正したことがある場合は、JSONコードが見えるはず）

### ３．customRowAction定義のactionを"defaultClick"から"none"に修正し、保存。

``` JSON
{
  "$schema": "https://developer.microsoft.com/json-schemas/sp/v2/tile-formatting.schema.json",
  "height": 135,
  "width": 254,
  "hideSelection": false,
  "fillHorizontally": true,
  "formatter": {
    "elmType": "div",
    "attributes": {
      "class": "sp-card-container"
    },
    "children": [
      {
        "elmType": "div",
        "attributes": {
          "class": "sp-card-defaultClickButton"
        },
        "customRowAction": {
          "action": "none"
        }
      },
```

### ４．リストのキャラリービュー画面をリフレッシュする。アイテムをクリックすると、今回は選択のみになり、詳細画面に遷移しなくなる。


以上。
Microsoft Build 2024 シアトル現地参加レポート ～Day0編～

# この記事のサマリ(AIによる作成)
・Day0はバッジとTシャツのピックアップのみ
・シアトルコンベンションセンターで参加資格確認後、バッジなどを受け取る
・受け取るもの：バッジ、Swagカード、セレブレーション案内、Tシャツ引換券

# Day0の内容
Day0は事前のバッジとTシャツのピックアップのみとなります。
(※時間はシアトル現地時間)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/82c5cbc9-8a89-4f88-535d-be5bdb0abb43.png)

## バッジピックアップ
現地での参加資格確認と会場に入れるパス(＝バッジ)の受け取りとなります。
会場は本会場であるシアトルコンベンションセンター(サミット)で画像の右側の「Build」書いてあるステッカーのところから入れました。
![メディア.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/f6ead71d-ce36-c4b9-f14e-1937cb90b753.jpeg)

バッジピックアップ時に参加資格の確認をされます。ID確認としてパスポートの提示が求められますのでご注意ください。またその他にBuildの参加申し込みメールがあるとスムーズです。参加の確認が取れたら以下をもらいました。
・バッジ
・Swagカード(スタンプラリー台紙)
・MSとAMDによるセレブレーションの案内
・Tシャツ引換券

・バッジ
立派です。
![メディア (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/8205a894-075f-c64b-80f0-26cf7e2db059.jpeg)

・Swagカード(スタンプラリー台紙)
・MSとAMDによるセレブレーションの案内
リストバンドはセレブレーションの参加資格に必要なようで、無くしたら再発行できないとのことでした。
![選択した写真.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/d1a64e93-6d93-61b8-3723-fdd3e39ab24e.jpeg)

・Tシャツ引換券
Tシャツは3つのデザインから1枚選択できました。受け取り方を選択できその場でもらうことも後日もらうことも可能みたいです。~~自分は後日受取としたので受け取り次第追記します。~~
Tシャツは以下三種類から選択可能です。追加でほしい人は3日目あたりに販売されるので購入することも可能です。サイズはユニセックスの場合は日本サイズとほぼ同じと思ってよいかと思います。絶妙なデザインですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795074/66676a60-e6e3-d081-de3d-beb11f83f3c9.png)



以上でDay0は終了です、特に混雑する様子もなくトータルで20分程度で終わりました。

おわり
Discord.js v14 botの作り方【基礎・環境構築編】 (2024/5/21現在)

# Discord.js とは
Discord.js (以下d.js) とは、discordのbotを開発するときに使用するパッケージの1つです。
同様に、Discord.pyというものがあります。これはpythonで開発する場合のパッケージになります。
詳しくは[こちら](https://qiita.com/minoru_kinugasa/items/e1bdee4ca016b2a38e2c)をごらんください！

# 環境構築とは
discord.jsというパッケージをインストールする`npm`と、
discord.jsを実行する`Node.js`をインストールしなければ、botを開発したり、動かしたりすることができません。

そのための環境を作り、開発や実行を行える状況にすることを`環境構築`といいます。

# インストール方法
:::note warn
Node.jsのインストール方法は頻繁に変更される可能性がございます。
現時点でのインストール方法を記載しますが、できない場合は`Node.js install`などとググったほうが早いと思われます。
:::
|手順|説明|備考|
|---|---|---|
|1|[https://nodejs.org/en/download/package-manager](https://nodejs.org/en/download/package-manager)にアクセスします。||
|2|真ん中のメニューにて、自分のPCのOSを選択します。[^1]|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/cb1c0ec0-c797-4a4e-c5f8-d707a00abf43.png)|
|3|表の右下にある「**Copy to clipboard**」ボタンをクリックします。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/e70bd925-11d5-58a8-a12c-6b6d3f690f0d.png)|
|4|ターミナルまたはコマンドプロンプトを開きます。 (以下ターミナル) [^2]|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/9c4a5ef4-4371-fbd8-7dfe-68dcf47deca9.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/20f83506-f2b2-c379-40f3-898ca2e28735.png)|
|5|ターミナルに先ほどコピーしたものを`Command + V`または`Ctrl + V`でペーストします。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/d0a23a19-6aac-b2d1-fe35-daf18ed6d90e.png)|
|6|貼り付けたものを実行するため、`Enter`を押します。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/d84f5950-3c56-9c4e-73ff-f57603a22031.png)|

これでインストールすることができました！
インストールできたかどうかの確認には、以下のコマンドを実行します。
|Node.jsの確認|npmの確認|
|---|---|
|`node -v`| `npm -v`|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/e67b5df4-60c7-cde2-3baa-929587a35c46.png)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/4ec08597-137f-9f68-c424-e75bda26f01e.png)|

このように、バージョンが出てきたら正しくインストールできています。
バージョンではなく、`zsh: command not found: node`や`zsh: command not found: npm`などが出てきた場合はインストールすることができていません。
もう一度やり直すか、別の記事をごらんください(-_-;)

[^1]: OSがわからなくても、すでに自分自身のOSが適用されている場合がおおいです。
[^2]: Windowsの場合は、スタートキーを押して、`cmd`と入力、`Enter`を押します。
Macの場合は、`Command + スペース`を押してターミナルと入力、`Enter`を押します。

# 終わりに
これで環境構築編は完了です！環境構築に関しては、バージョン、OSとの互換性など色々なものが絡まってきてしまい、この記事ではリアルタイムの情報を書ききることが難しいので、できなかった方はご自身で調べてみてください！

次は[ワークスペース作成編](https://qiita.com/minoru_kinugasa/items/ea3d193562ec27b6f9c2)となります！
botの開発をするファイルやフォルダなどの準備や、パッケージのインストールを行いますのでぜひごらんください！
【Type Script】read only な list の宣言

## 結論からいえ
```typescript

class Hoge {

    constructor(
        // どちらでも可能
        private readonly mylist: readonly string[]
        public readonly mylist2: readonly string[]
    ){
    
    }
}

```

## 詳しく

### readonly属性への理解
リストは基本的に「順番が保証されていて、操作可能な可変長の集合」を使いたいときに使うものです。
なので操作可能な事自体は必要なことなのですが…
まれに、このリストそのものを使わせてもよいが、変更は加えてほしくない、という場面に遭遇します。
そして思いつくのがこれです。

```typescript

class Hoge {

    constructor(
        public readonly mylist: string[]
    ){
    
    }
}

```

これでreadonlyなリストが宣言できました、というわけにはいきません。

```typescript

class Hoge {

    constructor(
        public readonly mylist: string[]
    ){
    
    }
}

const hoge = new Hoge(["0", "1", "2"])
hoge[0] = "3"

console.log(hoge)
// "3", "1", "2"
```
はい、mylistは普通に変更できてしまいます。
対して、これはエラーとなります。

```typescript
class Hoge {

    constructor(
        public readonly mylist: string[]
    ){
    
    }
}

const hoge = new Hoge(["0", "1", "2"])
hoge.mylist = ["3", "1", "2"] // error!
```
このことから、readonly属性はリスト内部の変更を制限しないことがわかります。
あくまで、その変数そのもの(今回はmylist)を変更することを制限するにとどまります。

### readonly T[]
readonly T[]として宣言することで、typescriptコンパイラに、破壊的動作をするメソッドを
このlistは持たない、ということを宣言します。

```typescript
class Hoge {

    constructor(
        public readonly mylist: readonly string[]
    ){
    
    }
}

const hoge = new Hoge(["0", "1", "2"])
hoge.mylist[0] = ["3"] // error!
hoge.mylist.push("4") //error!

```
これにより、mylistが外部から汚染されることを免れます。

### 注意点
`readonly T[]`はあくまでコンパイラに、破壊的メソッドが存在しないことを宣言する(隠す)だけであり、
強引に実行すると普通に実行される点に気をつけてください。
また、readonlyは再帰的ではありません。list内のオブジェクトがミュータブルな実装をしている場合、
値が変更されます。
[Amplify]boto3でS3のオブジェクトを操作するときの権限を付与する。

# はじめに
Pythonでboto3を使用してS3バケットのオブジェクトを操作するときに、エラーにハマったので、メモとして残しておきます。

# エラーの内容
boto3を使用して、S3のオブジェクトを操作しようとしたときに、以下のエラーが発生した。
```
An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied"
```

このエラーはS3のオブジェクトを操作するにあたって、権限が足りていないことが原因です。
しかし、以下のように権限は付与されていました。
```  custom-policies.json
{
 "Version": "2012-10-17",
 "Statement": [
    {
        "Action": [
            "s3:GetObject",
            "s3:ListObject"
            "s3:PutObject",
            "s3:DeleteObject"
        ],
        "Resource": [
            "arn:aws:s3:::bucket-name/folderA/folderB",
            "arn:aws:s3:::bucket-name/folderC/folderD",
            "arn:aws:s3:::bucket-name/folderE/folderF"
        ],
        "Effect": "Allow"
    }
 ]
}
```
ここでなぜ権限が付与されていないのかで詰まりました。

# 解決方法
以下のサイトに解決方法が書いてありました。

https://awsjp.com/AWS/Faq/c/Access-Denied-Remove-S3Object-5416.html

ポリシーは以下のように、「/*」をつけないARNと、「/*」をつけるARNを記述しなければいけないみたいです。
```  custom-policies.json
{
 "Version": "2012-10-17",
 "Statement": [
    {
        "Action": [
            "s3:GetObject",
            "s3:ListObject"
            "s3:PutObject",
            "s3:DeleteObject"
        ],
        "Resource": [
            "arn:aws:s3:::bucket-name/folderA/folderB",
            "arn:aws:s3:::bucket-name/folderC/folderD",
            "arn:aws:s3:::bucket-name/folderE/folderF",
            "arn:aws:s3:::bucket-name/folderA/folderB/*",
            "arn:aws:s3:::bucket-name/folderC/folderD/*",
            "arn:aws:s3:::bucket-name/folderE/folderF/*"
        ],
        "Effect": "Allow"
    }
 ]
}
```

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

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

https://qiita.com/hukuryo/items/2c07c52ff3386d5d75b9

https://qiita.com/hukuryo/items/ebeb26823f944f143b11
仮想記憶

# 仮想記憶がない場合の問題点
## メモリの断片化
プロセスが生成された後に、```メモリの獲得、開放を繰り返すと発生```する。
メモリの領域が細かく断片化され領域の確保に失敗する。
扱うデータが領域より大きいと失敗する。
プログラム側が断片化を意識して実行するので不便。

## マルチプロセスの実現が困難
* ```同じプロセスを二つ同時に実行すると正しく動作しない```。
* ```違うプロセス同士を同じメモリ領域で実行できない```。

これらを意識して```配置場所が重ならないように意識```する必要がある。

## 不正な領域へのアクセス
カーネルやたくさんのプロセスがメモリ上に配置されている場合、あるプロセスがカーネルや他のプロセスに割り当てられたメモリのアドレスを指定すれば、それらの```領域にアクセス```できてしまいます。
このため```データの漏洩や破壊のリスク```があります。

### 気づき
メモリを使い続けるとごちゃごちゃしてリスクあるのか

## 参考
https://gihyo.jp/book/2022/978-4-297-13148-7

# 仮想記憶
仮想記憶は、プロセスがメモリアクセスする際に、システムに搭載されているメモリに直接アクセスさせるのではなく、```仮想アドレスというアドレスを用いて,間接的にアクセス```させるという機能です。
...
メモリの```実際のアドレスを「物理アドレス」```
...
```アドレスによってアクセス可能な範囲を「アドレス空間」```と呼びます

### 物理アドレスを指定できない
readelfコマンドやcat　　/proc/＜pid＞/mapsの出力で記載されたアドレスは実は、```すべて仮想アドレス```です。なお、プロセスから実際のメモリに直接アクセスする方法、言い換えると、```物理アドレスを直接指定する方法はありません```。

### 気づき
前見ていたアドレスはすでに仮想アドレスだったのか。

# ページテーブル
仮想アドレスから物理アドレスへの変換には、```カーネルのメモリ内に保存されている「ページテーブル」```という表示を用います。CPUはすべてのメモリを```ページ```という単位で区切っており、アドレスは```ページ単位で変換```されます。
ページテーブル中の```一つのページに対応するデータを「ページテーブルエントリ」```と呼びます。ページテーブルエントリには、```仮想アドレスと物理アドレスの対応情報```が入っています。
...
```ページテーブルを作るのはカーネル```です。...カーネルはプロセス生成時にプロセスのメモリを確保して、そこに、実行ファイルの内容をコピーすると書きました。そのときに同時に、プロセスようのページテーブルも作るのです。プロセスが```仮想アドレスにアクセスした際に物理アドレスに変換するのは、CPUの仕事```です。

### 気づき
CPUは仮想アドレスから物理アドレスの変換を行い、仮想アドレスにアクセスされたときも物理アドレスに変換する他の部品のことなのにCPUはお世話をするのか。
カーネルは子プロセスを生成するときもプロセス専用のページテーブルを作成もするのか。
つまりページテーブルに対応されていなければアクセスできないのか。

# ページフォールトハンドラ
ページテーブルが物理アドレス部分と対応していない仮想アドレスにアクセスすると```ページフォールト```という例外が発生します。
...
ページフォールト例外によって```CPU上で実行中の命令が中断```されて、カーネルのメモリに配置された```ページフォールトハンドラ```という処理が実行されます。
...

カーネルは、ページフォールトハンドラにおいて、プロセスによるそのメモリアクセスが不正なものであることを検出します。この後は```SIGSEGV```というシグナルをプロセスに送信します。SIGSEGVを受信した```プロセスは、通常は強制終了```させられます。
# 参考
https://gihyo.jp/book/2022/978-4-297-13148-7

# ページフォールトハンドラを見てみよう
```
root@**********:************# go build segv.go 
root@**********:************#./segv
不正メモリアクセス前
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=]

goroutine 1 [running]:
main.main()
	/************/************/************/************/************/segv.go:9 +0x7b
root@**********:************## make segv-c
cc     segv-c.c   -o segv-c
root@**********:************## ./segv-c
Segmentation fault (コアダンプ)
```
### 気づき
エラーで終了している

# 仮想記憶による問題の解消の気づき
### メモリの断片化
断片化していても仮想アドレスは一塊になっているよう見えるからプロセス側は楽に処理ができる
### マルチプロセスの実現が困難
プロセスごとのページテーブルを作成しているので重複することはない
### 不正な領域へのアクセス
プロセス側から物理メモリを見ることができないから他にアドレスを指定できないから不正アクセスができない

# 感想
CPU、カーネルを使ってメモリの混雑状況の中うまくやっているんだな。
jetpack のコピー機能が使えない

wordpress jetpackプラグインの機能

jetpackの設定 > 執筆 > 「投稿およびページの全体 (タグと設定を含む) をコピーするオプションを有効にします。」

記事のコピーができるようになるが、

jetpackのmarkdownブロックの記事が
「このブロックには、想定されていないか無効なコンテンツが含まれています。」となった。

「Yoast Duplicate Post」プラグインでは正常に複製できる。
行数カウントしてって頼まれてサボった話

### 追記
コメントを記載しないPJであるため、コメント行は考慮していません。
また、空行については事前にエディタで`^\n`の置換を実施しています。
コメントいただいた @shiracamus さん、ありがとうございます。

### どのようにカウントしたのか
プロジェクトで製造したファイルのステップ数（行数）カウントを依頼された。
１つずつ目視で確認するのは非常に手間なので、スクリプトに数えてもらった。

```powershell
# PowerShellスクリプト
# srcフォルダのパスを指定
$srcFolder = "C:\Users\Elmo\development\ec_cookies"

# *.vueファイルのパスを再帰的に取得
$targetFiles = Get-ChildItem -Path $srcFolder -Recurse -Filter "*.vue"

# 総行数を初期化
$totalLines = 0

# 各index.mtsファイルの行数をカウントして総行数に加算
foreach ($file in $targetFiles) {
    $lineCount = (Get-Content $file.FullName).Count
    $totalLines += $lineCount
}

# 総行数を出力
Write-Output "Total lines in ec_cookies files: $totalLines"
```

不要なファイルをカウントしたくなかったので、vueファイルのみを対象にしています。

[ラリー・ウォール](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB)によれば、プログラマの三大美徳とは次の通りである。

- 怠惰（Laziness）
- 短気（Impatience）
- 傲慢（Hubris）

楽（怠惰）、してこうぜ。
zabbix接続確認

## serverからagentに接続してみる

```
zabbix_get -s <agentのIPアドレス> -k ＜取得したいアイテムキー＞
```

`取得したいアイテムキー`に設定できる項目は以下のとおり

https://www.zabbix.com/documentation/2.2/jp/manual/config/items/itemtypes/zabbix_agent

### 例えば

成功

```
$ zabbix_get -s 127.0.0.1 -k agent.hostname
Zabbix server
```

失敗

```
$ zabbix_get -s 127.0.0.1 -k agent.hostname
zabbix_get [102490]: Get value error: cannot connect to [[127.0.0.1]:10050]: connection timed out
```

## agentからserverに接続してみる

```
zabbix_sender -z <serverのIPアドレス> -s "test" -k db.connections -o 43
```

agentからserverは「送信する」処理しかないので、適当な値を送信しています
【TouchDesigner】かすみ除去フィルター

# なんぞや

かすみ除去フィルターについて

https://affinity.help/photo2/ja.lproj/index.html?page=pages/Filters/filter_haze.html?title=%E3%81%8B%E3%81%99%E3%81%BF%E3%81%AE%E9%99%A4%E5%8E%BB

Lightroomやスマホの画像編集にある処理で、英語だと`Dehaze Filter`というらしいです。

「コントラストをあげたいけど白と黒が潰れないようにしたい」という話の流れで実装することになりました。

鮮鋭化フィルターともいうのも候補に上がりましたが、かすみ除去の処理について書きます。

https://imagingsolution.net/imaging/unsharpmasking/


# 実装

https://github.com/He-Zhang/image_dehaze/blob/master/dehaze.py

とりあえず時間がなかったので、`OpenCV`を使ったかすみ除去の処理を見つけてそれを`Script TOP`に移植しました。

```python
import cv2
import math
import numpy as np

# Dehaze Filter
# https://github.com/He-Zhang/image_dehaze/blob/master/dehaze.py
def DarkChannel(im,sz):
	b,g,r = cv2.split(im)
	dc = cv2.min(cv2.min(r,g),b)
	kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(sz,sz))
	dark = cv2.erode(dc,kernel)
	return dark

def AtmLight(im,dark):
	[h,w] = im.shape[:2]
	imsz = h*w
	numpx = int(max(math.floor(imsz/1000),1))
	darkvec = dark.reshape(imsz)
	imvec = im.reshape(imsz,3)

	indices = darkvec.argsort()
	indices = indices[imsz-numpx::]

	atmsum = np.zeros([1,3])
	for ind in range(1,numpx):
	   atmsum = atmsum + imvec[indices[ind]]

	A = atmsum / numpx
	return A

def TransmissionEstimate(im,A,sz):
	omega = 0.95
	im3 = np.empty(im.shape,im.dtype)

	for ind in range(0,3):
		im3[:,:,ind] = im[:,:,ind]/A[0,ind]

	transmission = 1 - omega*DarkChannel(im3,sz)
	return transmission

def Guidedfilter(im,p,r,eps):
	mean_I = cv2.boxFilter(im,cv2.CV_64F,(r,r))
	mean_p = cv2.boxFilter(p, cv2.CV_64F,(r,r))
	mean_Ip = cv2.boxFilter(im*p,cv2.CV_64F,(r,r))
	cov_Ip = mean_Ip - mean_I*mean_p

	mean_II = cv2.boxFilter(im*im,cv2.CV_64F,(r,r))
	var_I   = mean_II - mean_I*mean_I

	a = cov_Ip/(var_I + eps)
	b = mean_p - a*mean_I

	mean_a = cv2.boxFilter(a,cv2.CV_64F,(r,r))
	mean_b = cv2.boxFilter(b,cv2.CV_64F,(r,r))

	q = mean_a*im + mean_b
	return q

def TransmissionRefine(im,et):
	gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
	gray = np.float64(gray)/255
	r = 60
	eps = 0.0001
	t = Guidedfilter(gray,et,r,eps)

	return t

def Recover(im,t,A,tx = 0.1):
	res = np.empty(im.shape,im.dtype)
	t = cv2.max(t,tx)

	for ind in range(0,3):
		res[:,:,ind] = (im[:,:,ind]-A[0,ind])/t + A[0,ind]

	return res


# press 'Setup Parameters' in the OP to call this function to re-create the parameters.
def onSetupParameters(scriptOp):
	return

# called whenever custom pulse parameter is pushed
def onPulse(par):
	return


def onCook(scriptOp):
	src = scriptOp.inputs[0].numpyArray(delayed=True)

	I = src.astype('float32')
	I = cv2.cvtColor(I, cv2.COLOR_RGBA2BGR)

	dark = DarkChannel(I,15)
	A = AtmLight(I,dark)
	te = TransmissionEstimate(I,A,15)
	t = TransmissionRefine(src,te)
	J = Recover(I,t,A,0.1)
	J = cv2.cvtColor(J, cv2.COLOR_BGR2RGBA)

	scriptOp.copyNumpyArray(J)
	return
```

# 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144702/704ab543-96dc-7198-d8b4-93af50a81ebc.png)

`OpenCV`を使ってるので`30fps`くらいしか出ず却下となり、最終的に目合わせで作ったLUT（Davinciでトーンカーブと彩度の調整したもの）をあてました。
チーン。
FlutterでSVGカスタムアイコンを使う

※備忘録的にまとめ、生成AIで文章化し内容を確認してから掲載しています。

## はじめに
Flutterでは標準でMaterial IconsやCupertino Iconsが利用できますが、プロジェクトによってはこれだけでは不足することがあります。そんなときに便利なのが「FlutterIcon」というサイトです。

## FlutterIconの使い方
FlutterIconは、手持ちのSVGファイルをアップロードすることで、カスタムアイコンを使用するためのフォントファイル（.ttf）と、それとIconを組み合わせて定義するDartファイル（.dart）をダウンロードすることができます。

FlutterIconの公式サイトはこちら：

https://www.fluttericon.com/

## 手順
1. FlutterIconのサイトにアクセスします。
2. 手持ちのSVGファイルをアップロードし、名前を編集する。
3. カスタムアイコンを生成し、ダウンロードします。
   - ダウンロードされるファイルには、フォントファイル（.ttf）とDartファイル（.dart）が含まれます。

![IMG_0420.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718653/321f8c63-a410-ca24-f58e-855250ee79e4.jpeg)


これらのファイルをFlutterプロジェクトに組み込むことで、カスタムアイコンを使用することができます。

詳しい使い方については、以下の記事を参考にしてください（2024年5月時点でも同じ手順で利用可能でした）：

https://qiita.com/tomoyanakano/items/79ac1391d4e3d9c9eec1

## 商用利用可能なSVGアイコンサイト
ネット上には、商用利用可能なアイコンデータをSVG形式でダウンロードできるサイトがいくつかあります。これらのサイトを活用してカスタムアイコンを作成できます。ただし、利用規約を必ず確認してください。

https://icon-rainbow.com/

https://icooon-mono.com/

https://icon-pit.com/

## デザイン上の注意点
Material Iconsと併せて他のデザインのアイコンを使う場合、デザイン的に問題が発生する可能性があります。見た目も含めて慎重に検討してから使用することをお勧めします。

## まとめ
FlutterIconを使うことで、簡単にカスタムアイコンをFlutterプロジェクトに組み込むことができます。商用利用可能なSVGアイコンを活用し、自分のプロジェクトに最適なアイコンを見つけてください。

---

この記事が皆さんの参考になれば幸いです。
【便利！！】現在いるブランチをコピペする

# 概要
gitを触っていると
- 「今ってどのブランチにいるんだっけ？」
- 「ブランチ名を毎回タイピングするのってめんどくさい！」

となること、多くありませんか？

主観ですがBacklogやgithub Projectsのチケット番号をブランチ名にしているプロジェクトでは、特に多い思います。
`例: task/123, feature/123など`

あとは機能名をブランチ名に設定する場合も同様です。
`例: task/add_XXXX_and_YYYYなど`

そこでgitコマンドで、現在いるブランチ名を取得、あわよくばコピペできないかなと思ってコマンドを作成しました！
個人的にとても使っているコマンドなので、ぜひ使ってみてください！

# 結論
githubのconfigファイルにエイリアスを設定する。
```
[alias]
   co（任意のコマンド名） = "!f() { git branch --show-current | tr -d '\n' | pbcopy; echo 'Current branch name copied to clipboard.'; }; f"
```

実際にコマンドを実行し、クリップボードに現在いるブランチ名が表示される。
```
git co

> Current branch name copied to clipboard.
```

# 解説
#### 1. 現在のブランチを取得する
現在いるブランチは以下コマンドで取得できます。
```
git branch --show-current

> feature/123
```

#### 2. 取得したブランチを整形する
以下コマンドにより、現在取得しているブランチから改行コード(\n)を削除して、整形することができます。
※返却された値の%は無視してください。
```
tr -d '\n'

> feature/123%
```

#### 3. ブランチ名をクリップボードに保存する
以下コマンドにより、②で取得できたブランチ名をクリップボードに保存ができます。

```
pbcopy
```

#### 4.コマンド実行の完了メッセージを出力
コマンドを入力して何も返却されなかったら（個人的に）味気ないので、実行後に「現在のブランチ名がコピーされたよー」っていうメッセージが出力されるようにします。

```
echo 'Current branch name copied to clipboard.'
```

#### 5. 以上をまとめる!
このコマンドを実行してみると、実際に現在いるブランチ名がクリップボードにコピーされていると思います！！

```
git branch --show-current | tr -d '\n' | pbcopy; echo 'Current branch name copied to clipboard.';
```

#### 6. gitのエイリアスに保存
毎回⑤のコマンドを実行するのは面倒なので、gitのエイリアスに保存しちゃいましょう。

まずmacの場合、gitの設定ファイルは以下にあります。
Windowsの方は別途調べてみてください。
```
vim ~/.gitconfig
```
or
```
vi ~/.gitconfig
```

すると、gitの設定ファイルが開かれると思うので、以下を参考にエイリアスを追加します。
※エイリアス(`co`の部分)は適宜変更してください。
```
# This is Git's per-user configuration file.
[user]
# Please adapt and uncomment the following lines:
        name = xxxx xxxx
        email = xxxxxxxx

#　↓↓↓ 以下を追加！！　↓↓↓
[alias]
    co = "!f() { git branch --show-current | tr -d '\n' | pbcopy; echo 'Current branch name copied to clipboard.'; }; f"
```

これで設定完了です！

では実際にコマンドを実行してみましょう！
クリップボードを確認すると、現在いるブランチ名が保存されているはずです！

```
git co

> Current branch name copied to clipboard.
```


# まとめ
今回は、現在いるブランチ名をコピペするコマンドをご紹介させていただきました！
gitの機能で、現在いるブランチを表示するところまではできるのですが、それ以上の機能は自分で実装しないといけないんですよね。。。
もしよかったら、参考にしてみてください！

ここまで読んでいただきありがとうございます！

ではでは。
AccessのレポートをPDF出力して既定のPDFビューワで開くコード

## はじめに
Accessのレポートを、不特定多数のPCで同じように印刷できるようにするのって結構めんどくさいですよね。プリンタ設定が端末ごとにばらばらだったり。

めんどくさい部分はそれが得意なツールに任せてしまおう、ということで印刷部分はPDFビューワに丸投げしてみました。

標準モジュールを適当な名前で新規作成して以下のコードを貼り付けて[DoCmd.OpenReport]の代わりに呼んでください。

どこかの誰かが同じ悩みを持っていたりしないかな、と、初投稿。先輩方のご指導ご鞭撻よろしくお願いします。

## コード
chatGPTさんに結構手伝ってもらいました。
```vb
'
'  渡されたフォームをPDFへ出力し既定のPDFビューワーで開く
'
'　　呼出し例
' Call OutputPdf("YourReportName", "FilterName（省略可能）", "Condition（省略可能）", Papersize, Orientation)
'
' Call OutputPdf("YourReportName", , , 12, 2) ' B4用紙の横向き
' Call OutputPdf("EmployeeReport", "ActiveEmployees", "[Status] = 'Active'", acPRPSA4, acPRORPortrait)  ' A4用紙の縦向きでフィルターを適用
'
Option Compare Database
Option Explicit

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Function GetEnvironmentVariable Lib "kernel32" Alias "GetEnvironmentVariableA" (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long

Function GetEnvVariable(ByVal VarName As String) As String
    Dim buffer As String
    Dim length As Long
    
    buffer = String$(255, vbNullChar)
    length = GetEnvironmentVariable(VarName, buffer, Len(buffer))
    
    If length > 0 Then
        GetEnvVariable = Left$(buffer, length)
    Else
        GetEnvVariable = ""
    End If
End Function

Function IsReportLoaded(ReportName As String) As Boolean
    Dim obj As AccessObject
    Set obj = CurrentProject.AllReports(ReportName)
    IsReportLoaded = obj.IsLoaded
End Function

Function OutputPdf(ByVal ReportName As String, Optional ByVal FilterName As String = "", Optional ByVal WhereCondition As String = "", Optional ByVal PaperSize As Long, Optional ByVal Orientation As Long)
    On Error GoTo ErrorHandler

    Dim RepNAME As String
    Dim pdfPath As String
    Dim tempDir As String

    RepNAME = ReportName
    
    ' 環境変数から出力ディレクトリを取得
    tempDir = GetEnvVariable("TMP")
    
    ' 環境変数が取得できない場合、デフォルトでC:\TEMPを使用
    If tempDir = "" Then
        tempDir = "C:\TEMP"
    End If
    
    pdfPath = tempDir & "\" & RepNAME & ".pdf"
    
    ' レポートをプレビューで開く
    DoCmd.OpenReport RepNAME, acViewPreview, FilterName, WhereCondition, acHidden
    
    ' レポートが開かれるのを待つ
    Do While Not IsReportLoaded(RepNAME)
        DoEvents
    Loop
    
    ' 用紙サイズと向きを設定
    Reports(RepNAME).Printer.PaperSize = PaperSize
    Reports(RepNAME).Printer.Orientation = Orientation
    
    ' PDFへ書き出し
    DoCmd.OutputTo acOutputReport, RepNAME, acFormatPDF, pdfPath
    
    ' プレビューで開いているレポートを閉じる
    DoCmd.Close acReport, RepNAME

    ' PDFを開く
    ShellExecute 0, "open", pdfPath, vbNullString, vbNullString, vbNormalFocus

    Exit Function

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    ' 必要に応じてエラーログに記録するコードを追加できます。
    ' 例: LogError Err.Number, Err.Description
End Function
```
【Swift】よく使われる String の format で打線組んでみた


打線に並び替えるとかだるいのでやめました。

```swift
String(format: "%02x", 255)
// ff

String(format: "%02X", 170)
// AA

String(format: "%02d", 1)
// 01

String(format: "% 5d", 2)
//     2

String(format: "%.2f", 1.2)
// 1.20

String(format: "%.2f", 1.204)
// 1.20

String(format: "%.2f", 1.205)
// 1.21

String(format: "%.0f", 1.23)
// 1

String(format: "%f", 3.12)
// 3.120000

String(format: "%+.2f", -123.5)
// -123.50

String(format: "%p", 3)
// 0x3

String(format: "%@", "x")
// x

String(format: "%2$@ %1$@", "world", "Hello")
// Hello world

```

四捨五入できることに驚いたので。


# 🤔 参考

https://android.benigumo.com/20240521/common-string-format/

https://x.com/maochanz/status/1792728772128743762
  
https://zenn.dev/maochanz/articles/c0b5d4e62602c8
ToggleButton + AttchedFlyout によるオン切替時のみ追加設定するUIパターン

## モチベーション

* 編集UIが複雑になった場合、一つの機能文脈を基にUIをシンプルにしたい
* 小規模な設定UIはFlyoutに逃がすのも手段としてありえる

## 動作の様子

![レコーディング-2024-05-21-125915.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62922/b22b93b6-d2a6-ad0a-15b2-cf81d8c7fdeb.gif)


## 実装

```xml
<ToggleButton IsChecked="{x:Bind _vm.IsDisplayOnionSkin, Mode=TwoWay}"
              Checked="OnionSkinToggleButton_Checked"
              x:Name="OnionSkinToggleButton"
              >
  <TextBlock Text="ｵﾆｵﾝｽｷﾝ" />

  <FlyoutBase.AttachedFlyout>
    <Flyout>
      <StackPanel Orientation="Vertical">
        <Slider x:Name="OnionSkinOpacitySlider"
                Header="不透明度"
                Maximum="1"
                Minimum="0"
                Value="{x:Bind _vm.OnionSkinOpacity, Mode=TwoWay}"
                TickFrequency="0.01"
                StepFrequency="0.01"
                ThumbToolTipValueConverter="{StaticResource ToPercentStringConverter}"
                HorizontalAlignment="Stretch" />
        
      </StackPanel>
    </Flyout>
  </FlyoutBase.AttachedFlyout>
</ToggleButton>
```

```csharp
private void OnionSkinToggleButton_Checked(object sender, RoutedEventArgs e)
{
    var target = sender as FrameworkElement;
    if (FlyoutBase.GetAttachedFlyout(target) is { } flyout)
    {
        flyout.ShowAt(target);
    }
}
```

## 適用できそうな場面

* 有効・無効を切替えて使うケース（使わないシーンもある）（任意のタイミングで使いたい）
* たまに使う機能で追加設定UIも表示したいが、頻繁に使うわけでもないため設定UIに画面を専有させたくもない
複数のLaTeXファイルを1つにまとめる

$\LaTeX$で文書を作成する際，.texファイルの見通しをよくするために複数の.texファイルに分けて執筆する方法があります．
しかし，この方法だと，1つの.texファイルにまとめて提出しなければならない状況で困ります．例えばarXivに投稿するには，1つの.texファイルで提出する必要があります．

そこで作ったのがこれです！

https://github.com/Mya-Mya/latexmerger

これは，`\input`や`\subfile`によって複数ファイルで作成されている$\LaTeX$プロジェクトを，1つの.texファイルにまとめるプログラムです〜

使い方は簡単．例えば`main.tex`が出発点にある$\LaTeX$プロジェクトなら，
```bash
python3 mergelatex.py main.tex
```
とやればおーけー．`\input`と`\subfile`の参照先を再帰的に渡っていきます．

## ちょっと詰まった点
実は，`\input`と`\subfile`とで引数の仕様がちょっと違います．
* `\input`:参照先ファイルは，常に出発点にある.texファイルから見たパスで書きます．
* `\subfile`:参照先ファイルは，当該コマンドが書かれた.texファイル（自分自身）から見たパスで書きます．

なので，ちょっとだけ実装が難しかったですね．

## 安全性
1つにまとめた後のファイル名は，初期設定では，出発点として指定されたファイル名に対し，`merged_`を先頭に付けたものとしています．
また，書き出し先のファイルが既にあった場合は，上書きをしてよいかどうかの確認が出ます．
せっかく書いた.texファイルが無駄にならないように（といっても自分の書いたものが完全に消えることはないですけど）安全策を講じています．

## 動作例
次のような$\LaTeX$プロジェクトを考えます（詳細は当該GitHubのexampleを参照）．
```plaintext
📄entry.tex
📄input_sub.tex
📄subfile_sub.tex
📄subfile_nest.tex
📂subfile_dir
    📄subfile_dir_sub.tex
    📄subfile_dir_nest.tex
📂input_dir
    📄input_dir_sub.tex
    📄input_dir_nest.tex
```
このプロジェクトは`entry.tex`を起点としています．これを指定して本プログラムを実行すると，▼こんなのがでます．
```latex
\documentclass{article}
\usepackage{subfiles}

\begin{document}
Entry\\
% > input_sub.tex > : LaTeX Merger
Input Sub\\
% < input_sub.tex < : LaTeX Merger
% > subfile_sub.tex > : LaTeX Merger
Subfile Sub\\
% >> subfile_nest.tex >> : LaTeX Merger
Subfile Sub - Nest\\
% << subfile_nest.tex << : LaTeX Merger
% < subfile_sub.tex < : LaTeX Merger
% > input_dir/input_dir_sub.tex > : LaTeX Merger
Dir Sub\\
% Note that the entry file's directory - based relative path is required for \input.
% >> input_dir/input_dir_nest.tex >> : LaTeX Merger
Input Dir Sub - Nest\\
% << input_dir/input_dir_nest.tex << : LaTeX Merger
% < input_dir/input_dir_sub.tex < : LaTeX Merger
% > subfile_dir/subfile_dir_sub.tex > : LaTeX Merger
Subfile Dir Sub\\
% >> subfile_dir/subfile_dir_nest.tex >> : LaTeX Merger
Subfile Dir Sub - Nest\\
% << subfile_dir/subfile_dir_nest.tex << : LaTeX Merger
% < subfile_dir/subfile_dir_sub.tex < : LaTeX Merger
\end{document}
```
見事，全てのファイルが1つになりました．また，ネスト先まで正しく参照されていることも分かります．
UPMでtarballインポートする際に発生するエラーの解決

# エラー内容

URDFImporterをローカル管理するために、以下を参考にtgzファイルを作成

https://bluebirdofoz.hatenablog.com/entry/2022/05/22/231133

UPM > Add package from tarballで以下のエラーが発生

```unity.console
[Package Manager Window] Error adding package: file:com.unity.robotics.urdf-importer.tgz.
Unable to add package [file:com.unity.robotics.urdf-importer.tgz]:
  The file [C:\Users\{UserName}\AppData\Local\Temp\.tmp-43804-shvAJ9gqLvPp\package.json] cannot be found
UnityEditor.EditorApplication:Internal_CallUpdateFunctions ()
```

# 解決
- どうやら、package/package.jsonとなるように配置しなければいけないらしく。

https://forum.unity.com/threads/package-manager-does-not-import-from-tarball.1361269/

- packageCacheから取得したファイルは以下の構成になっていた
    - com.unity.robotics.urdf-importer@90f353e435
        - Editor
        - Runtime
        - ...
        - package.json
        - ...

ので「com.unity.robotics.urdf-importer@90f353e435」→「package」としtgzファイルを作成。
List<>よりも、ImmutableList<>を使った方が、パフォーマンスが上がる

Kotlin実装で学んだことの、自分用の覚え書きです。m(_ _)m
# ポイント 
- List<>よりも、ImmutableList<>を使った方が、パフォーマンスが上がる
# 
- 可変であるList<>を使うと、更新したComposeのアイテム以外も再度作り直しが発生する
- 全く変更がされない(読み取り専用)のImmutableList<>を使うと、変更が無かったComposeのアイテムの作り直しは発生しない
(入力に変更が無ければスキップされるため)
- **ImmutableList<>の方が、無駄な再描画がかからないため、パフォーマンスがいい**


# 参考サイト
- そもそもImmutableがよく分からなくて調べたサイト
https://qiita.com/TOM117/items/383460b8f262f74afd6e

- Immutableにする理由は、このサイトが参考になるかも
https://speakerdeck.com/moriatsushi/shi-li-karaxue-bujetpack-composenopahuomansugai-shan
非JS系フロントエンド環境でのパフォーマンス改善

様々な制約により、ReactやVue、SvelteのようなナウいJS系フレームワーク（or ライブラリ）の導入が難しい場面があります。しかし、そういった状況であっても、サーバーサイドだけではなく、フロントエンドでのパフォーマンス改善を求められることもまたあります。奇縁により、私はそういった仕事が多く、知見が溜まってきたので皆さんにシェアしたいと思います。



## ルール1：自前のCSSは書かない、読み込ませない

BEMやFLOCSSのようなルールでなるべくCSSファイルを簡素化させたとしても、「CSSを書かない」より軽くなることはありません。

### じゃあスタイリングはどうしたらいい？

- 高速CDNで配布されているCSSフレームワークを使いましょう。ただし、React前提だよねみたいなCSSフレームワークが多いのでそのあたりのリサーチは入念に。自分はBootstrapを使っています。イケてるとは思わないですが、汎用性も高く、また読み込みパフォーマンスも及第点なので選んでいる感じです。
- それでも足りない場合はstyleタグを用いましょう。CSS in JSの展開後のイメージで、Linkさせずにページ内でスタイリングを完結させるのです。
- また、ページ内スタイリングに際しても、CSSの基本原則（後読みなど）は当然ハックしておきましょう。BEM等のように、ネストしないで単一のクラス目での修飾にするのが基本です。

## ルール2：jQueryは絶対使わない

CSSファイル同様jQueryのJSファイルもレンダリングブロックを盛大にかましてきてフロントエンドパフォーマンスを悪化させます。使わずにどうにかしてください。

### じゃあアニメーション系とかどうしたらいい？

- BootstrapのようにスタイリングとJSが一体化しているライブラリを使うのも手です。
- それ以上にCSSでどうにかするのが一番良いです。簡単なアコーディオンやモーダルウィンドウ、バーガーメニュー、スライドインアニメーションなどは頑張ればCSSだけで作れます。「アコーディオン CSSのみ」などでググると作例が出てくるのでそこからパクりましょう。
- 自前でアニメーションJS書いても良いですが、その場合もファイル化せずにページ内に記述しましょう。
- 上記では効かないような派手にアニメーションさせたいときは…CDNで軽量のものを配布しているライブラリをなるべく用いましょう。

## ルール3：画像は枠内サイズの軽量化gifをまず読み込ませて、Lazyload系jsライブラリで置き換える

React環境であれば良い感じの画像パフォーマンス改善ライブラリが山程ありますが、私達が相対している環境では使用できるものは限定されています。そんなときに私のおすすめは[vanilla-lazyload](https://github.com/verlok/vanilla-lazyload)。この手のライブラリは、ブラウザでLazyloadが標準装備になって枯れた技術になったと思いきや今でも開発が行われており、かつ軽量なのでおすすめです。

下記では、ダミーのgifを可能な限り軽量化しておき、かつ寸法を読み込み後のサイズにしておくことでCumulative Layout Shift (CLS)も防いでいます。

```html
<!-- JSライブラリの読み込み -->
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.5.0/dist/lazyload.min.js"></script>

<!-- 画像本体 -->
<img data-src="/assets/some_image.webp" src="/assets/dummy/100_100.gif" loading="lazy" alt="some_alt" class="lazy">

<!-- JSの駆動部分 -->
<script>
    document.addEventListener("DOMContentLoaded", function () {
        var lazyLoadInstance = new LazyLoad({
            elements_selector: ".lazy",
            use_native: true
        });
    });
</script>

<!-- 読込中に表示するアニメーション -->
<style>
    .lazy:not(.loaded) {
        animation: fadeInOut 2s infinite;
    }

    @keyframes fadeInOut {
        0%,
        100% {
            opacity: 0.2;
        }

        50% {
            opacity: 1;
        }
    }
</style>
```

画面サイズの明示的表示については現在ベストプラクティスを探っている途中ですので、また見つかったら加筆しておきます。
Generative AI Test 2024 #1のシラバスを並べる

Generative AI Test 2024#1 試験を受けようと思っています。
去年は忙しくて受験を忘れてた…。

「JDLA Generative AI Test」オンライン説明会（過去出題問題解説あり）を視聴したところ「とにかくシラバスにある用語を調べよ」とのことでしたので、今後1つ1つ調べて行こうと思います。

とりあえず以下のシラバスにある用語を並べてみた。

https://www.jdla.org/certificate/generativeai/#toc7

## 生成AIの技術
### 特徴

**大規模言語モデルの基本構造を理解している。**
- 基盤モデル
- 言語モデル
- 大規模言語モデル (LLM)
- トランスフォーマー (Transformer)
- アテンション (Attention)
- GPT-3

**大規模言語モデルにおけるモデルの学習方法を理解している。**
- 教師あり学習
- 自己教師あり学習
- 事前学習
- ファインチューニング

**大規模言語モデルのアラインメントを理解している。**
- アラインメント (Alignment)
- 人間のフィードバックによる学習
- インストラクション・チューニング (Instruction Tuning)

**大規模言語モデルにおける生成の仕組みを理解している。**
- コンテキスト内学習 (In-Context Learning)
- Zero-Shot
- Few-Shot
- Chain-of-Thought
- サンプリング手法

**大規模言語モデルの性能評価について知っている。**
- リーダーボード
- ベンチマーク

### 動向

**テキスト、画像、音声等の生成モデルの技術動向を俯瞰して理解している。**
- 条件付き生成
- 拡散モデル (Diffusion Model)

**大規模言語モデルのオープン化の動向と原因について理解している。**
- オープンコミュニティ
- オープン大規模言語モデル
- オープンデータセット
- オープンソース
- 量子化や蒸留による推論の効率化

**大規模言語モデルの性能を決める要素の動向と原因について理解している。**
- スケーリング則 (Scaling Laws)
- データセットのサイズ
- データセットの質
- モデルのパラメーター数
- 計算資源の効率化
- LoRA
- GPU

**大規模言語モデルのマルチモーダル化の動向と原因について理解している。**
- マルチモーダル

**大規模言語モデルの外部ツール・リソースの利用の動向と原因について理解している。**
- 学習データの時間的カットオフ
- 大規模言語モデルの知識
- 大規模言語モデルの不得意タスク


## 生成AIの利活用
### 特徴
**生成AIには何ができるのかを理解している。**
- ケイパビリティ

**生成AIをどのように使うのかを理解している。**
- 活用事例

**生成AIの性能を拡張する使い方を理解している。**
- プロンプトエンジニアリング

### 動向
**生成AIの新たな活用方法を生み出すためのアプローチを理解している。**
- ハッカソン
- 自主的なユースケース開発
- インターネット・書籍
- 活用の探索

**生成AIの活用を制限する要因を理解している。**
- 生成AIの学習データ
- 生成AIの性能評価
- 生成AIの言語能力

**業界に特化した生成AIの活用方法を理解している。**
- LLMを利用したサービス (ChatGPT, Bard, Claude など)
- RAG (Retrieval-Augmented Generation)の利用
- エージェント・コード生成
- 外部ツール呼出し
- 広告クリエイティブへの応用
- ドメイン固有

## 生成AIのリスク
### 特徴

**生成AIが、技術面・倫理面・法令面・社会面などで多様なリスクを孕むことを理解している。**
- 正確性
- ハルシネーション (Hallucination)
- セキュリティ
- 公平性
- プライバシー
- 透明性
- 悪用
- 誤情報の拡散
- プロンプトインジェクションなどの敵対的プロンプト
- 特定の生成AIサービスへの依存
- 環境問題

**生成AIの入力（データ）と出力（生成物）について注意すべき事項を理解している。**
- 著作権
- 個人情報
- 機密情報
- 商用利用
- 利用規約

### 動向
**生成AIについて、現時点では認識されていない新たなリスクの出現とそれに伴う規制化の可能性を理解している。**
- 新たなリスク
- 規制化
- 情報収集

**生成AIの活用に伴うリスクを自主的に低減するための方法を把握している。**
- 自主対策






---
1日1つの単語を調べていけば…。
いや、それじゃあ時間が足りないか！
【React Bootstrap】Enterキーが押された時、Submitボタンを押した時と同じ振る舞いをするようにする。

# Submitボタンを押す or Enterキーを押した時の振る舞いが同じになる凡例
- 入力フォームセクションを、submit時の処理関数をプロパティとして持ったFormタグでラップする。
- Formタグ内のButtonタグのtypeプロパティに、"submit"を指定。

こうすることで、クリックイベントとキーボードイベント（Enterキーを押す）を統合的にウォッチしてくれるようになる。
```
const onSubmit = (e) => {
　// 入力フォームコンポーネントのデフォルト機能（画面のリロード）を禁止。
  e.preventDefault();
  // Submit時の処理
};

<Form onSubmit={onSubmit}>
  <Form.Control /> //入力フォーム1
  <Form.Control /> //入力フォーム2
  <Button type="submit">Submit</Button> //Submitボタン。
</Form>
```

# 簡単なログインフォームで実装する


![スクリーンショット 2024-05-21 12.46.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796362/887761aa-f7b9-6aec-68b4-557b07381b65.png)


**仕様**
- ID、パスワードは入力必須
- React BootStrapを利用
- Submitボタンを押す or Enterキーを押す　→　ログインしました。という文字を表示。


**ソースコード**
```

import React from "react";
import { useState } from "react";
import { Form, Button } from "react-bootstrap";

export const EasyLogin = () => {
  const [id, setId] = useState<string>("");
  const [password, setPassword] = useState<string>("");
  const [loginStatus, setLoginStatus] = useState<boolean>(false);

  const onSubmit = (e) => {
    e.preventDefault()
    if (id && password) {
      setLoginStatus(true);
    }
  };

  return (
    <>
      <h1>
        Easy Login
      </h1>
      <Form onSubmit={onSubmit}>
        <Form.Group>
          <Form.Label>ID</Form.Label>
          <Form.Control 
            type="text"
            placeholder="IDを入力"
            value={id}
            onChange={(e) => {setId(e.target.value)}}
          />
          <Form.Label>パスワード</Form.Label>
          <Form.Control 
            type="password"
            placeholder="パスワードを入力"
            value={password}
            onChange={(e) => {setPassword(e.target.value)}}
          />
          <Button 
            type="submit"
            disabled={ !id || !password }
          >
            Submit
          </Button>
        </Form.Group>
      </Form>

      {loginStatus && <h2>ログインしました。</h2>}
    </>
  );
};

```
Q. 実装とリファクタリングのどちらを優先するか？ (システム開発)

# Q. 実装とリファクタリングのどちらを優先するか？

という問いは愚問である。
愚問すぎてあくびが出る。ぐもん。

- 実装とリファクタリングは両輪である
- 実装とテストは両輪である

どちらか片方が欠けてはうまく走行できない。(開発には車輪がある)

自分の場合は開発の苦しみを感じ取ると、すぐにリファクタリングに取り掛かってしまう。

# 三つの柱

- テストが充実しているのでリファクタリングがしやすい
- 日頃からリファクタリングされているので開発がしやすい
- 開発が進みやすいのでテスト・リファクタリングに時間を割きやすい

これが三つ巴の好循環である

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
【PHP】西暦から干支・干支から西暦を算出する

小ネタ。
PHPで西暦から十二支を出す必要があったので、ついでに十干十二支(干支＝えと)を出す関数を作ってみた。

#### 西暦→干支
```getEto.php
function getEto(int $yyyy = NULL, bool $with_jikkan = TRUE) {
 // yyyyに西暦を入れるとその年の干支(十干十二支)を返す
 // yyyyが空のときは今年の干支
 // 第2引数を0にすると十二支のみ返す
 $yyyy = $yyyy ?: date("Y");
 if ($yyyy > 0) {
  $jikkan = [
   '庚',
   '辛',
   '壬',
   '癸',
   '甲',
   '乙',
   '丙',
   '丁',
   '戊',
   '己',
  ];
  $juunishi = [
   '申',
   '酉',
   '戌',
   '亥',
   '子',
   '丑',
   '寅',
   '卯',
   '辰',
   '巳',
   '午',
   '未',
  ];
  return ($with_jikkan ? $jikkan[$yyyy % 10] : '') . $juunishi[$yyyy % 12];
 }
 return NULL;
}
```
西暦が10で割り切れる年は「庚(かのえ)」、12で割り切れる年は「申(さる)」なので、そこから算出している。配列が「甲(きのえ)」や「子(ね)」から始まってないのはこのため。
第2引数を0(やfalsyな値)にすると十干ナシで十二支だけ返す。
まあこれは処理が簡単。

#### 干支→西暦
```getYearFromEto.php
function getYearFromEto(string $eto, int $yyyy = NULL) {
// yyyy年以降でeto(十干十二支)に当てはまる年を出す
// yyyyが空の場合は今年以降で算出
// 存在しない干支を入力した場合はNULLを返す
 $yyyy = $yyyy ?: date("Y");
 if ($yyyy > 0) {
  $jikkan_r = [
   '庚' => 0,
   '辛' => 1,
   '壬' => 2,
   '癸' => 3,
   '甲' => 4,
   '乙' => 5,
   '丙' => 6,
   '丁' => 7,
   '戊' => 8,
   '己' => 9,
  ];
  $juunishi_r = [
   '申' => 0,
   '酉' => 1,
   '戌' => 2,
   '亥' => 3,
   '子' => 4,
   '丑' => 5,
   '寅' => 6,
   '卯' => 7,
   '辰' => 8,
   '巳' => 9,
   '午' => 10,
   '未' => 11,
  ];
  $ji = $jikkan_r[mb_substr($eto, 0, 1)] ?? FALSE;
  $ju = $juunishi_r[mb_substr($eto, 1, 1)] ?? FALSE;
  if (($ji || $ji === 0) && ($ju || $ju === 0) && (($ji + $ju) % 2 === 0)) {
   for ($i = 0; 1; $i++) {
    $yi = $yyyy + $i;
    if (($yi % 10 === $ji) && ($yi % 12 === $ju)) {return $yi;}
   }
  }
 }
 return NULL;
}
```
第1引数は干支(十二支でなく十干十二支)、第2引数には西暦を入れると、その年以降で入れた干支に当てはまる西暦を返す。第2引数を省略すると今年以降から探す。
手順としては西暦→干支より複雑で、

1. 干支を十干と十二支に分割
2. 十干と十二支に当てはまる剰余を出す
3. 西暦に1ずつ足していき、10の剰余と12の剰余の両方が一致する年を出力

というやや力技。もう少しスマートなやり方があるかもしれない。
```if```の条件の1つめと2つめは干支にない文字を入れた場合に無視する(```NULL```を返す)ためだが「余りゼロ」も```TRUE```にしないといけないためちょっと手間がかかっている。3つめは例えば「甲丑」という干支は存在しない(十干の偶数番目は必ず十二支の偶数番目と結合する。奇数番目も同様)ので、それを回避するためのもの。2つの剰余の和が偶数なら偶数&偶数か奇数&奇数しかないので。```XOR```を使うより簡単なんじゃあないかなと思った。

これがあると例えば「辛亥革命って何年だっけ?」というときに
```php
echo getYearFromEto('辛亥', 1900); //1911
```
みたいなことができる。もっとも60年ごとに同じ干支が回ってくるので「だいたいこのあたりの年」がわかってないと使えないが…。

##### 関連記事
[西暦から和暦・和暦から西暦を算出する](https://qiita.com/Kokusui/items/7bb2466a50290c2b2e9e)
VSCodeで現在のファイルをデバックする: Python

# 目的

VSCodeのデバッグ機能を使用して、現在開いているファイルをデバッグしたい。

# つまづきポイント

sys.pathがディレクトリ全体ではなく、そのmoduleが存在するパスしか読み込みません。なので、自作moduleをインポートする場合importエラーが出ます。

例えば、以下のようなディレクトリ構造で、retriever.pyからutils.normalize_text.pyをインポートするとエラーなります。

```text
├── keyword_retriever
│   └── retriever.py
├── utils
│   └── normalize_text.py
```

```python
from utils.normalize_text import normalize_documents 
```
importエラーが発生
```
例外が発生しました: ModuleNotFoundError
No module named 'utils'
  File "/usr/src/app/keyword_retriever/retriever.py", line 28, in <module>
    from utils.normalize_text import normalize_documents
ModuleNotFoundError: No module named 'utils'
```

# 解決策

launch.jsonに以下を追加する

```json
{
  "name": "Python デバッガー: 現在のファイル",
  "type": "debugpy",
  "request": "launch",
  "program": "${file}",
  "console": "integratedTerminal",
  "cwd": "${workspaceFolder}",
  "justMyCode": true,
  "env": {
    "PYTHONPATH":"${PYTHONPATH}:${workspaceFolder}", // 追加
  }
},
```

PYTHONPATHに現在のプロジェクトディレクトリを指定することで、sys.pathがmodeleを読み込むようになります。
【ChatGPT＋DALL-E3】ビールの中にロウソクの火を灯したい。失敗談。


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

　今回は、ビールの中にロウソクの火を灯したい、と考えて描画生成に奮闘。その失敗談です。

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

　まずは、ニュース。

　OpenAIは
　　ChatGPTの
　　　音声のSkyの提供をやめました。

　女優スカーレット・ヨハンソンの
　　声に酷似していたためとしている。

　元記事はこちら。
[しょーてぃー　ポスト](https://x.com/shoty_k2/status/1792701370522574906?t=MwyQhXtmfR8je5D9rOWlnA&s=03)
***
　次に、
　　Microsoftが
　　　AI標準搭載のPCを
　　　　発表しました。

　目玉機能は、
　　時を巻き戻せる機能『Recall』

　どうやら
　　過去のアクセス記録を
　　　簡単にたどれる、らしい。

　ほかにも
　　落書き程度のイメージ画と
　　　テキスト入力により、
　　　　AIがイメージ通りの画像を
　　　　　リアルタイム生成する機能。

　もとのポストはこちら。
[【速報：MicrosoftがAI標準搭載のPCを発表](https://x.com/masahirochaen/status/1792703977253150782?t=3nO7SLhOobmBRW-_LLQfgQ&s=03)

　なお、
　　簡単なスペックはこちら。
[Copilot+PCs](https://x.com/shoty_k2/status/1792686332223094909?t=jcu_Y1bnhd_HQHMmyFhisw&s=03)
***
　さて、本題です。

　ビールの中に
　　ロウソクを描けるか、に
　　　挑戦しました。

　わかります？

　ジョッキの中に
　　ビールがなみなみと
　　　注がれて出てきた。

　その中から
　　ロウソクの明かりが
　　　もれ出てくる。

　そんなイメージです。

　ところが
　　これがうまく出せない。

　まぁ、とりあえず
　　やり取りをどうぞ。
***
***user***
ビールジョッキにビールが入っている。そのジョッキの表面には水滴がついていふ。描画

***ChatGPT***
（指示どおりに出ました）

***user***
ビールの中に、ロウソクの火が灯っている

***ChatGPT***
![Beer_Mug_with_Candle.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/ebef3bdb-9bce-4e15-0dc5-da7185cdc7a5.jpeg)

***user***
ビールの中に、ロウソクの火が灯っている。火はジョッキの中

***ChatGPT***
（似たりよったり）
***

　ここで
　　ロウソクを諦めて
　　　LEDを灯してみました。
***
***user***
ビールの中で、赤いLEDが灯っている。水滴があるために、中はよく見えない

***ChatGPT***
![Beer_Mug_with_Red_LED.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/f9b74062-6b8d-157f-8253-00968ff127db.jpeg)
***

　うまく描けました。

　ふたたび、
　　ロウソクにすると
　　　戻ってしまいました。

　その後も
　　あれこれ試しましたが、
　　　どれもダメでした。

　ビールを入れないとか
　　ロウソクが燃え尽きそうだとか。

　ダメでした😭

　これが
　　みなさんの
　　　作品制作の糧に
　　　　なれば、幸いです。
　　　　　ならんよね😅

　今回は、ここまで。
【OutSystems】ClientActionから複数ServerActionを呼ぶとレスポンスが悪化する話

クライアントアクションを実装していた際に以下の警告が出たので原因調査をしました。
<B>
Performance Warning
The 'ClientAction1' Client Action calls several Server Actions. To avoid performance issues, group them all in a single Server Action and call it instead.
</B>
結論から言うと一つのClientActionから複数のServerActionを呼び出す実装をするとサーバへのリクエスト回数が増えるからよした方がいいよ、という警告でした。

というこで実際にパフォーマンスに影響がでるのか検証してみる。

## 1.ClientActionから複数のServerActionを呼ぶ実装
一つのクライアントアクションから以下のサーバアクションを呼び出すロジックを作ります。

・開始と終了のログを出力する
・Aggrigateを2回実行する
・開始と終了の差分の時間を画面に表示返す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/5346b624-7ae9-c42a-0ae9-60ec9d03de10.png)
<br>


## 2.ClientActionから呼び出すServerActionを集約する実装
一つのクライアントアクションから呼び出すServerActionは一つにしてServerAction内でさらに各Actionを呼び出すように実装します。ロジックを集約させているだけで処理内容は基本的に変わりません。

・開始と終了のログを出力する
・集約したServerActionを呼び出す（ServerAction側でログ出力、Aggrigateを呼び出す）
・開始と終了の差分の時間を画面に表示返す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/af75fa52-0a24-deae-6d50-317b363c24e1.png)

ServerAction側でさらにログ出力やAggrigateのアクションを呼び出すように変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/28000503-19f0-4644-1339-f90f4d389717.png)
<br>

## 3.レスポンスを計測する

それぞれのボタンごとに呼び出すクライアントアクションを分けて時間を計測する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/0f160632-4a75-476d-4284-d0b2208c57a8.png)
<br>

結果としてClientからのServerAction呼出しを１本に集約したほうが１秒で処理が終わり（複数回呼び出しているほうは３秒）レスポンスに差異が発生している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/5d14be2b-a3b9-a130-d30d-df52bdc8a585.png)

ということでClientActionからのリクエストが増えれば当然レスポンスは低下するのでなるべく呼出しは一回にまとめてServerAction側で対応しようというお話でした。
Workato：条件分岐が個別のブロックに分割され If / Else If / Else に対応

2024/5/14に、Workatoの条件分岐の改善がリリースされました。この更新により、IfブロックとElseブロックが個別のアクションに分割され、独立して追加および削除できるようになりました。

# これまでの条件分岐

これまでは、`If` と `If~Else` のみを条件分岐として選択することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/6f087858-7334-6d41-8742-cfc7d388efab.png)

これまでの条件分岐については、以下を参考ください。

https://www.workato.com/product-hub/if-else-conditions-control-recipe-flow/

しかし、この条件分岐には次のような欠点がありました。

- `If` から `If~Else` へ変更できない、あるいは `If~Else` から `If`へ変更できない
  - `If` から `If~Else` （あるいは `If~Else` から `If`）へ変更したい場合は、条件分岐の実装をやり直す（当該ブロックを削除してから再実装する）必要がある（変更に対するコストが高い）
- `Else If`が設定できない
  - `If` や `If~Else` の組み合わせや、Formulaの活用で `Else If`相当の処理を実装することは可能であるが、条件分岐が冗長になったり、複雑化する（レシピの見通しが悪くなり、メンテナンス性が悪くなる）

特に、`If~Else` の使い勝手があまり良くなかったため、`If`のみを利用している、`If~Else`は運用上使わない方針でレシピ作成をされていた方もいらっしゃったであろうと思います。

# 改善された条件分岐

今回の改善により、 条件分岐が個別のブロックに分割され、`If` `Else If` `Else` が個別に実装できるようになりました。

初めて `If` ブロックを追加する場合や、直前のステップに `If` ブロックが存在しない場合は、`If` のみ選択することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/5956fbab-9996-6d5c-9c41-c3b2c8310c2a.png)


直前のステップに `If` ブロックが存在する場合は、`If` の他に `Else If` と `Else` も選択することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/447ae763-4ec7-f3b5-aa16-7e8bfac6a3b9.png)

`If` ブロックと `Else` ブロックの中間のステップである場合は、 `Else If` のみ選択することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/1904a7b7-41ff-5fe4-a73c-6411aa6a5c2d.png)

また、ブロックが独立したことで、`If` `Else If` `Else` いずれもブロックごとに削除することができるようになりました。これにより、`Else` から `If` （あるいはその逆）への変更、 `Else　If` から `Else` （あるいはその逆）への変更が行いやすくなり、従来の`If~Else` で生じていた欠点が解消されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/28ed72d9-f6a5-0522-04ad-d7360d55b51a.png)

# 最後に

これまで `IF~Else` が使いにくいなと思っていた方にとっては、非常に嬉しいアップデートだと思います。また、レシピ開発・メンテナンスにおける生産性の向上にも繋がる改善であると思います。既にリリース済みの機能ですので、Workatoをお使いの皆様は是非お試しください。
robloxでassistant その62

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
Eキーでパーツを消す

# 手順
- workspaceに、partを追加。
- partに、ProximityPromptを追加。
- partに、scriptを追加。
- スクリプトを書く。

```
local part = script.Parent
local proximityPrompt = part.ProximityPrompt
proximityPrompt.Triggered:Connect(function(player)
	part:Destroy()
end)

```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5b890813-603b-02c1-cb95-ef6ed3e41414.png)


以上。
生成AIは抽象度を変えて返事するのが苦手だよね

技術的な質問に答えるときに、質問そのものには回答していないけど、ひとつ抽象度高めの観点からアドバイスをすることってありますよね。

例えば今日あったのが、
「PythonコードをLangChainのTextSplitterで分割したいとき、separatorはどのように書くべきですか？」
と聞かれて、
「RecursiveCharacterTextSplitterのfrom_languageメソッドの引数でlanguage=Language.PYTHONとするのが楽で良いと思います」
と答えました。

この私の回答って、質問自体には答えてないんですよね。separatorの書き方を答えていないので。
でも、質問の内容からそもそもの問題を推測して、それに答えるためにひとつ抽象度高めの観点から回答しています。
こういうやりとりって生成AIって苦手だよなーと思った次第です。

実際LLM(GPT-4o)に聞いてみたところ、具体的にseparatorに書くべきコードを教えてくれました。
これはこれで間違ってないし有益だけど、質問に回答するだけが質問に回答することじゃないよなー（？）と思いました。
java 文字列の検索

## 文字列の検索
文字列の内部から、別の文字列（または文字）を探すためのメソッド
2種類ある
①含まれているか否かだけの判定
②文字列のどこに含まれているかという位置情報を返すもの

|メソッド定義|操作|
|:----------|:--------|
|contains|ある特定の文字列(文字）が対象の文字列に含まれているか|
|startsWith|文字列がある特定の文字列(文字）で始まるか|
|endWith|文字列がある特定の文字列(文字)で終わるか|
|indexOf|ある特定の文字列(文字)が最初に登場する位置を調べる|
|lastIndexOf|ある特定の文字列(文字)を後ろから検索して最初に登場する位置を調べる|


#### contains
特定の文字列(文字)が含まれているかを調べる
（大文字/小文字の区別する）
`対象の文字列.contains(検索する文字列)`
```Main.java
public class Main {
 public static void main(String[] args) {
  String s1 = "Hello";
  System.out.println(s1.contains("e"));
  System.out.println(s1.contains("ell"));
  System.out.println(s1.contains("E"));
 }
}
```
```結果.
true
true
false
```
#### startsWith
文字列が特定の文字列(文字）で始まるか
`対象の文字列.startsWith(検索する文字列)`
```Main.java
public class Main {
 public static void main(String[] args) {
  String s1 = "Hello";
  String s2 = " Hello";
  System.out.println(s1.startsWith("H"));
  System.out.println(s1.startsWith("h"));
  System.out.println(s1.startsWith("He"));
  System.out.println(s2.startsWith("H"));
 }
}
```
```結果.
true
false
true
false
```
#### endsWith
文字列が特定の文字列(文字)で終わるか
`対象の文字列.endsWith(検索する文字列)`
```Main.java
public class Main {
 public static void main(String[] args) {
  String s1 = "Hello";
  String s2 = "Hello ";
  System.out.println(s1.endsWith("o"));
  System.out.println(s1.endsWith("O"));
  System.out.println(s1.endsWith("lo"));
  System.out.println(s2.endsWith("o"));
 }
}
```
```結果.
true
false
true
false
```

#### indexOf
ある特定の文字列(文字)が最初に登場する位置を調べる
`対象の文字列.indexOf(検索する文字列)`
```Main.java
public class Main {
 public static void main(String[] args) {
  String s1 = "Hello World";
  System.out.println(s1.indexOf("l"));
  System.out.println(s1.indexOf("World"));
 }
}
```
```結果.
2
6
```

#### lastIndexOf
ある特定の文字列(文字)を後ろから検索して最初に登場する位置を調べる
`対象の文字列.lastIndexOf(検索する文字列)`
```Main.java
public class Main {
 public static void main(String[] args) {
  String s1 = "Hello World";
  System.out.println(s1.lastIndexOf("l"));
  System.out.println(s1.lastIndexOf("World"));
 }
}
```
```結果.
9
6
```
rex0220 項目検証プラグイン 印刷時に項目を非表示

[項目検証プラグイン](https://qiita.com/rex0220/items/be20fd879f5e1bc9e035)で、印刷時に項目を非表示にする例です。

# 概要

[項目検証プラグイン](https://qiita.com/rex0220/items/be20fd879f5e1bc9e035)は、入力項目必須チェック、バリデーションチェック、入力抑止、表示制御の処理条件を計算式で指定するプラグインです。

印刷時に不要な項目を非表示にすることができます。
「備考」を非表示にする例です。

![2024-05-21_11h27_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3a668693-f10f-9bba-47f6-23e5766e02b0.png)

# 項目検証プラグイン設定

「備考」の非表示の計算式に、印刷イベントの判定条件を指定

![2024-05-21_11h35_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0f94f001-52a3-9049-f14b-778f437bfa01.png)

```.js
// 備考 非表示
EV_INFO("cate")="print"
```