OmniAICreator/Qiita-1.07M huggingface dataset:
Jupyter参考サイトまとめ

![スクリーンショット 2024-10-09 22.05.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/f794bdeb-31a3-8365-37c3-7363b4b35620.png)


![puyopuyo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/1fdf8221-96c5-fcfa-3a52-383422a6fdc3.gif)
　ぷよぷよプログラミングAI学習システムは、中高生の自己調整学習に向けて開発されました。
　どうやって、Chromebookで、１０分で、素敵な人工知能を作れるのでしょうか？
　秘密は、３つ。
　１　jupyter liteで、webクライアントがpythonコードを実行
　２　超軽量な機械学習フレームワークdezeroを採用
　３　ぷよぷよのstageとactionがコンパクト

### Github&X

https://github.com/Lunanaedu/jupyterlite-puyopuyo

https://github.com/Lunanaedu/puyopuyo-kai

https://x.com/educationai_ai

### ぷよぷよプログラミングAI学習用まとめ

https://qiita.com/educational-ai/items/50c0fa689c01794d145e



# Jupyter Notebookのインストールと使い方
https://qiita.com/ktr_ch/items/f3ddc4d6a9cac9fa2b89

https://udemy.benesse.co.jp/development/python-work/jupyter-notebook.html
[Python] 中央値を求める

# 中央値とは
中央値とはデータを小さい順に並べたデータのちょうど中央にあるデータのことですが、データが偶数個の場合にはちょうど中央にくる値がないので、中央に最も近い2つの値の平均値を中央値とします。今回はPythonで中央値を求めてみます。
# 中央値を求める　その１
組み込み関数のlen()関数とsort()関数を使用して中央値を求めます。
~~~Python:median1.py
score = [48,52,46,48,53,58,52,48,51,63]

# データの数の半分を求める
half = len(score) // 2

# データを昇順に並べ替える
score.sort()

# データの数が偶数・奇数の場合で場合分け
if len(score) % 2 == 0:
    mdn = (score[half - 1] + score[half]) / 2.0
else:
    mdn = score[half]

print("中央値は", mdn, "です。")
# 出力結果
# 中央値は 51.5 です。
~~~
# 中央値を求める　その２
標準ライブラリstatisticsのmedian()関数を使用して中央値を求めます。その１と違ってデータをソートする必要がないので楽ですね。ちなみに今回の例のようにデータが偶数個の場合にmedian_low()関数を使うと、中央2個の値の小さい方の値、median_high()関数を使うと中央2個の値の大きい方の値を返します。
~~~Python:median2.py
import statistics

score = [48,52,46,48,53,58,52,48,51,63]
mdn = statistics.median(score)
print("中央値は", mdn, "です。")
# 出力結果
# 中央値は 51.5 です。
~~~
# 中央値を求める　その３
数値計算ライブラリのNumPyにあるmedian()関数を使用して中央値を求めます。
~~~Python:median3.py
import numpy as np

score = score = [48,52,46,48,53,58,52,48,51,63]
mdn = np.median(score)
print("中央値は", mdn, "です。")
# 出力結果
# 中央値は 51.5 です。
~~~
# 中央値を求める　その４
今度はNumPyのpercentile()関数を使用して中央値を求めてみます。データの数が偶数個なのでpercentile()の第二引数に50パーセンタイルを指定しています。
~~~Python:median4.py
import numpy as np

score = [48,52,46,48,53,58,52,48,51,63]

# 第二引数に50パーセンタイルを指定
mdn = np.percentile(score, 50)
print("中央値は", mdn, "です。")
# 出力結果
# 中央値は 51.5 です。
~~~
# 中央値を求める その５
データ解析ライブラリのPanadasにあるDataFrame.median()関数を使用して中央値を求めます。ただしPandasはこの例のような少ないデータを処理するために使うものではないですが、中央値を求めるには色々なやり方があるよということで例に挙げます。
~~~Python:median5.py
import pandas as pd

# DataFrame型のデータを準備
score = pd.DataFrame([48,52,46,48,53,58,52,48,51,63])

# score[n]で中央値を求めたい列を指定
mdn = score[0].median()

print("中央値は", mdn, "です。")
# 出力結果
# 中央値は 51.5 です。
~~~
python参考サイトまとめ

![スクリーンショット 2024-10-09 22.05.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/da43f670-1b19-3994-4855-b8363d06365a.png)

![puyopuyo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/1fdf8221-96c5-fcfa-3a52-383422a6fdc3.gif)
　ぷよぷよプログラミングAI学習システムは、中高生の自己調整学習に向けて開発されました。
　どうやって、Chromebookで、１０分で、素敵な人工知能を作れるのでしょうか？
　秘密は、３つ。
　１　jupyter liteで、webクライアントがpythonコードを実行
　２　超軽量な機械学習フレームワークdezeroを採用
　３　ぷよぷよのstageとactionがコンパクト

### Github&X

https://github.com/Lunanaedu/jupyterlite-puyopuyo

https://github.com/Lunanaedu/puyopuyo-kai

https://x.com/educationai_ai

### ぷよぷよプログラミングAI学習用まとめ

https://qiita.com/educational-ai/items/50c0fa689c01794d145e



# インストール方法　Windows＆Mac
https://udemy.benesse.co.jp/development/python-work/python-install.html

# 環境構築　Windows ver
https://qiita.com/SAITO_Keita/items/ddcde4fdcdf5e5eaa933

# 環境構築　Mac ver
https://hoshi-it-o.com/python-build-environment/

# 実現できること
https://note.com/naosuke_ultra/n/n422d1557e3ec

# 機械学習
**[機械学習入門]機械学習を学び始めたい人がはじめに見る動画｜いまにゅのプログラミング塾**

https://www.youtube.com/watch?v=EeSerya_9XE

***

**[入門]機械学習に役立つPythonの学習方法**

https://www.skillupai.com/blog/tech/python-study/

# pyautogui
**[Python]PyAutoGUIとは？できることや使い方を解説**
マウス操作やキーボード操作を自動化するためのライブラリ
インストール方法や使い方が記載されている

https://one-div.com/programming/python/what-is-pyautogui

# モンテカルロ木探索
* 木探索アルゴリズムの一種
* 適当な回数ランダムに実行し、その結果から結論を導くアルゴリズム

https://qiita.com/pocokhc/items/392a7f89c79f5e1e6bca

# ニューラルネットワーク
**ニューラルネットワークの基礎**
* ソースコードあり
* 図あり

https://tutorials.chainer.org/ja/13_Basics_of_Neural_Networks.html

***

**[完全図解]10分で理解できる！ニューラルネットワークの基本[初心者向け]**
* ソースコードなし
* 図あり


https://www.youtube.com/watch?v=1hbvFlZjZgc

# chatGPT×ぷよぷよ
https://qiita.com/gatuwo_jp/items/a2c63c960c3c9480a91e
自己調整学習の説明サイトまとめ

![スクリーンショット 2024-10-09 22.05.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/da43f670-1b19-3994-4855-b8363d06365a.png)


![puyopuyo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900427/1fdf8221-96c5-fcfa-3a52-383422a6fdc3.gif)
　ぷよぷよプログラミングAI学習システムは、中高生の自己調整学習に向けて開発されました。
　どうやって、Chromebookで、１０分で、素敵な人工知能を作れるのでしょうか？
　秘密は、３つ。
　１　jupyter liteで、webクライアントがpythonコードを実行
　２　超軽量な機械学習フレームワークdezeroを採用
　３　ぷよぷよのstageとactionがコンパクト

### Github&X

https://github.com/Lunanaedu/jupyterlite-puyopuyo

https://github.com/Lunanaedu/puyopuyo-kai

https://x.com/educationai_ai

### ぷよぷよプログラミングAI学習用まとめ

https://qiita.com/educational-ai/items/50c0fa689c01794d145e



# 自己調整学習説明サイト
学習環境デザイン研究室のサイト

https://noyuri.jp/domain


https://core-net.net/keywords/kw012/

https://career-ed-lab.mynavi.jp/career-column/2397/

https://note.com/teacher_x/n/naaeb000a7941


https://note.com/teacher_x/n/n66b4610e1678

https://note.com/teacher_x/n/n3663d20b7b2a

https://note.com/teacher_x/n/n59ce45897617
相手のための言語化

## 本の情報
**本のタイトル**
人気スピーチライターが教える モヤモヤを言葉に変える「言語化」講座

**著者**
ひきた よしあき

## 本の内容
言語化力を3つに分けて、それぞれの視点から言語化力を伸ばしていくことができる。
1. 思いを言葉にする言語化力
1. 相手に伝わる言語化力
1. 表現するための言語化力

#### 思いを言葉にする言語化力
現代は、受け取る情報が増えたり、リモートでの会話が増えたりしたことで、言語化力が落ちている。
そんな中で思いを伝えられるようになるには、以下のようなことを意識して試してみると良い。
* 完璧主義をやめ、「必ず伝えたいこと」を明確にする
→完璧主義だと、伝えられなかった内容ばかり思い浮かび伝えることを避けてしまう。最低限伝えたいことを伝えつつ、他のことも伝えられた と考えるようにする方が良い。
* 物事を正確に描写したり、頭に浮かんだ言葉を書きだしたりして、使える語彙を増やす
→正確に描写したり言葉を書き出したりすることで、使える語彙や連想される語彙が増え、自分の思いを言葉にしやすくなる。

こういったことを行うことで、脳内にあるものを言葉にできるようになっていく。

#### 相手に伝わる言語化力
自分の思いを言葉にできたら、その言葉を相手に届ける必要がある。
そのためには、相手の頭に白いスクリーンがあると想定して、相手に合わせて発する内容を変えていく。
相手に合わせるためには、以下のようなことを行っていくと良い。
* 相手の使った言葉を取り入れる
→人は、発した言葉が相手の口から出てくると、その言葉が気になる。そのため、相手が発した言葉を使うことで、相手が話に聞き入りやすくなる。
* 重要なポイント3か所を抜き出すことを意識する
→相手の話を聞く意識が高まるうえ、重要な言葉が見えることで「相手の使った言葉を取り入れる」にもつなげることができる。
* 相手が何を考えているか想像しながら話す
→相手の思いを振り返りながら話すと、自分の話す内容で不足している箇所が見えやすくなる。

#### 表現するための言語化力
表現をする際には、自分主体ではなく相手の視点に立って話すことで、相手に自分事として捉えてもらえる。(自分と関係がある話だと思わせる)
→同じ状況を別の人間の視点から描写する訓練で自分以外の視点を持つ力を養うことができる。
また、自分の話し方を直接聞いてみることで直すべき点が分かるという方法もある。
表現を磨くためには、気になった点をコツコツ直して、相手の心に伝わるような伝え方の学習を続けていく必要がある。

言葉は、自分の意思や感情を伝えて成就させるために使うものである。
相手がいて初めて成立する物であり、相手のためを思って言語化を行うことが言語化力を上げる秘訣になる。

## ためになった点
* 語彙の増やし方
これまでの読書の中で、言語化には自分の頭の中を正確に言葉にできる語彙力が必要だ としている書籍が多数あり、私もその通りだと感じていました。
中でも、この本で紹介されていた言葉の「言い換え」と「すり替え」という手法は、使える語彙を増やすのに有効な手段と感じました。
自分なりの語彙が磨ける方法だったので、取り組んでみたいと思います。

※言葉の「言い換え」と「すり替え」
ノートの見開きを用意し、中央に語彙を増やしたい言葉を書く。
左側のページには、その言葉の言いかえとして使える表現を何でも書く。
右側のページには、その言葉から連想される景色やモノ、コトを書く。
→これにより、特定の語とつながる自分だけの辞書を作ることができる。

## まとめ
30日の講義形式 ということで、大きな概念を1冊かけて理解する というより、言語化に関連する色々な考え方や技術が複数紹介されている本でした。
様々な角度からの内容が紹介されており自分に合ったものが見つかりやすいため、言語化向上のとっかかりに適していると感じた内容でした。
ありがとうございました。
aタグを入れ子にしていることに気が付かずに3時間以上費やした件


# 記事のカードコンポネント作成の際に

記事のコンポネント作成の際に、画像、タイトル、本文、ビュー数...などとコンポネントごとにファイルを分けて、ブロックで...とやっていたのですが、

カードの中にタグを表示させようとし、そのタグをカード以外の場所でも再利用しようとしたため、`<a>`を用いたのですが、そこで悲劇が起きました。

検証ツールを除いたところ、なぜか囲んでいたはずのブロックの外に空の`<a>`タグが生成されているのです。

# なぜこのようなことが起きるのか

HTML において、マークアップの際にコンテンツモデルというものがあるようです。

そのルールの中では、a タグのようなインタラクティブ・コンテンツ（他には`input`や`select`）などは入れ子にすることができないそうです。

※インタラクティブ・コンテンツ：閲覧者が操作する要素のこと。

# 解決策

入れ子にしない！

というのが恐らく正しいマークアップなのだと思います。
画面に表示されるだけで良いと思わず、SEO を意識したマークアップを心がけていきたいと思います！


# 参考サイト

https://t-file.blog/programming/93/


https://me-pro.co.jp/blog/creative_046.html
Goのinternalディレクトリに関して理解する

## はじめに
Goのinternalパッケージについて学ぶ記事です。
下記記事を実際に動かすとどうなるんだろうと思い、試してみました！

https://qiita.com/tenntenn/items/d8db61720a5ce7fbdeb6

## ソースコード
参考記事と同様のディレクトリ構成

```shell:ディレクトリ構成
~/go/internal_jikken$ tree
.
├── b
│   └── d
│       ├── d.go
│       └── internal
│           └── e
│               └── e.go -- d.goからのみアクセス可能
├── c
│   └── c.go　-- internal配下のe.goはアクセス不可能
└── go.mod

6 directories, 4 files
```

### internalディレクトリ内のファイル
```go:b/d/internal/e/e.go
package e

import "fmt"

func InternalFunc() {
	fmt.Println("This is an internal function!")
}
```

### import可能
internalと同階層ディレクトリに配置されているパッケージ`b/d/d.go`はimport可能

パス：`b/d/d.go`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/f6821298-b9ff-eed7-46c9-67dd8f966d13.png)

:::note info
問題なくimportできています
:::

### import不可
internalと異なるディレクトリに保存されている場合はimport不可

パス：`c/c.go`
![スクリーンショット 2024-10-03 17.34.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/a17fc107-cc44-7e2a-00ad-b5e8b255025c.png)

:::note warn
importしようとするとコンパイルエラーが発生します
:::

## おわりに
確かにimportエラーが発生しましたね。
外部からアクセスする要件がない場合に利用すると効果的ですね！！⭐️
VMware vSAN グローバル重複排除の紹介（リリース時期未定）

アメリカのラスベガスで開催された、VMwareのイベントである「VMware Explore 2024 Las Vegas」に参加したので、個人的に注目した機能に関して小出しですが紹介します。

今後リリース予定のVCF9（VMware Cloud Foundation 9）で実装されるVMware vSANの新機能として「グローバル重複排除（Global Deduplication）」が一部のvSAN関連のブレイクアウトセッションで発表されていました。
本記事では、このグローバル重複排除機能の概要とそのメリットについてご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385304/f451646c-4394-d659-85bc-b82d019be669.png)

グローバル重複排除機能とは？

vSAN ESAの今後のアップデートにより、ストレージ効率を向上させる「グローバル重複排除」機能が追加されます。従来のvSAN OSAはディスクグループ単位での重複排除機能を持っていましたが、新しいグローバル重複排除機能では、クラスタ全体を通じて重複データを削減できるようになります。

### 主な特徴
1.広範囲な重複排除ドメインの実現
クラスタ全体をカバーすることで、複数のノード間のデータ重複を効率的に削減し、ストレージ容量の削減に期待できます。
これにより、単一ノード内の重複排除よりも、さらなる効率化が期待できます。

2.仮想マシンへのオーバーヘッドを最小限に抑える設計
新しい重複排除の仕様は、パフォーマンスへの影響を最小限にするよう設計されています。従来のOSAの重複排除の際に発生していたオーバーヘッドを抑え、高いデータ効率を実現します。

### グローバル重複排除のメリット
この新機能の実装により、ストレージ効率の向上と同時に、総所有コスト（TCO）の削減を実現できます。具体的なメリットは以下の通りです。

•TCO削減
VMwareの社内検証情報によると、従来のストレージに比べて最大34%のTCO削減が可能となります。また、従来のストレージと比較して、1TBあたりのコストを46%削減することができ、vSAN OSAと比較しても、1TBあたりのコストが36%削減されると発表されています。

•コスト効率の高いデータ保護の実現
vSANをレプリケーションターゲットとして使用することで、データ保護にかかるコストも5倍の効率化が図れるため、バックアップや災害復旧におけるコストを大幅に削減できます。

### 今後の展望

今回のグローバル重複排除機能は、VCF9におけるvSANの目玉機能として、魅力的な機能になることが期待されています。
VCF9ではその他にも最適なインフラを提供する新しい機能や技術を導入していくことが発表されていますが、
本記事では、vSANのグローバル重複排除機能について解説しました。リリース時期は未定ですが、今後のストレージ環境の効率化に役立てていただければ幸いです。
【備忘録】Apple M1のRailsをインストールしてもrailsコマンドが使えない問題への対処法

## はじめに
私は、RailsをApple M1で動かすためにインストールしようとしましたが、いくつかのエラーに遭遇しました。その解決方法を備忘録として残します。

## 環境
- Apple M1
- macOS Venture: 13.2.1
- Homebrew: 4.0.19
- vi: version 9.0.981  

## どんな症状??
私は､rbenvにてRubyのバージョン管理をしたいと考えました｡
```zsh
$ gem install rails
Successfully installed rails-7.0.5
Parsing documentation for rails-7.0.5
Done installing documentation for rails after 0 seconds
1 gem installed
```
```zsh
$ rails -v
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.
```
Railsをインストールしたにもかかわらず、railsコマンドが使えませんでした。

## PATHの確認
https://tomoprog.hatenablog.com/entry/2017/02/03/015936

https://qiita.com/w7tree/items/0860e2856f2429b20eee

同じ問題が起きていると思い、PATHを再確認しました。
```zsh
$ which ruby
/Users/hoge/.rbenv/shims/ruby

$ which gem
/Users/hoge/.rbenv/shims/gem
```
```zsh
$ which rails
/usr/bin/rails
```
railsのみ、異なる場所を参照しています。

```zsh
$ cat ~/.zshrc
export PATH="$HOME/.rbenv/shims:$PATH"
eval "$(rbenv init - zsh)"
```
念のため､`.zshrc`を確認し､`rbenv rehash`をしました｡
しかし､私の場合では､解決することができませんでした｡

## 解決策
```zsh
$ gem install rails -v 7.0.5
$ rbenv rehash 
```
https://rubygems.org/gems/rails/versions

:point_up:上のサイトからバージョンを選択してください

```zsh
$ which rails
/Users/hoge/.rbenv/shims/rails

$ rails -v
Rails 7.0.5
```
railsのバージョンを明示的にすることによって解決することができた｡


## 考えられること
- インストールされているRailsのバージョン
古いバージョンのRailsがシステムにインストールされていた可能性
`gem install rails`ではなく､`gem install rails -v 7.0.5`を使用したことで、明示的に新しいバージョンのRailsをインストールし、正しくパスが参照されるようになった可能性があります。
- 環境のキャッシュやキャッシュの無効化
パスやgemの情報がキャッシュされることで動作しない可能性
パスの変更やgemのアップデートが反映されず、問題が発生することがあります。`gem install rails -v 7.0.5`､`rbenv rehash`を実行することで、キャッシュが無効化され、新しいパスが参照されるようになった可能性があります。

## 最後に
以上がApple M1でRailsをインストールしてもrailsコマンドが使えない問題への対処法です。
Railsをインストールした際に､ハマったことをメモしました。

## 参考サイト
https://tomoprog.hatenablog.com/entry/2017/02/03/015936

https://qiita.com/w7tree/items/0860e2856f2429b20eee

https://rubygems.org/gems/rails/versions
CSS Grid Layoutメモ

# はじめに
CSS Grid Layoutというものができていて、主要ブラウザで対応している。
10年前にはなかった。

# ブラウザ対応状況
https://caniuse.com/?search=CSS%20Grid%20Layout

# 習得用リンク

https://qiita.com/kura07/items/e633b35e33e43240d363

https://qiita.com/kura07/items/486c19045aab8090d6d9

https://developer.mozilla.org/ja/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout

https://www.ceroan.co.jp/cho-men/post/new-layout-method-introduction-to-css-grid-layout
Cisco設定

# 2960シリーズの設定サンプル

```cmd
Switch>en
Switch#conf t

! LLDP有効化
lldp run

! ホスト名の設定
Switch(config)#hostname RT1

! 未定義のコマンドをDNSサーバへ参照しに行かないようにする
RT1(config)#no ip domain-lookup

! 入力途中でログが割り込まないようにする
RT1(config)#line console 0
RT1(config-line)#logging synchronous
RT1(config-line)#exit

! sshの設定準備とログ割り込みしないように
RT1(config)#line vty 0 4
RT1(config-line)#login local
RT1(config-line)#logging synchronous
!sshのみ接続を許可
RT1(config-line)#transport input ssh
RT1(config-line)#exit

! ドメイン名を指定　ドメイン名は適宜変更してください
RT1(config)#ip domain-name cisco.com

! RSA鍵生成
RT1(config)#crypt key generate rsa

!
!
! ここで入力を求められます。を入力します。1024
!
!

! sshのVersion指定
RT1(config)#ip ssh version 2

! 特権モードへ入るためのPW
enable secret PASSWORD
! PWは暗号化されずに保存される
username USER1 password PASSWORD

! 最後にPW全般の暗号化
service password-encryption


spanning-tree mode mst
spanning-tree loopguard default
spanning-tree extend system-id
!
spanning-tree mst configuration
 name a_f_o_s
 instance 1 vlan 10
 instance 2 vlan 20
 instance 3 vlan 30
 instance 4 vlan 40
 instance 5 vlan 50
 instance 6 vlan 60
 instance 7 vlan 70
 instance 8 vlan 80
 instance 10 vlan 100
 instance 11 vlan 110
 instance 12 vlan 120
 instance 15 vlan 200
!
spanning-tree mst 0-200 priority 12288
```


* 管理VLANのIP決めと
* デフォルトゲートの設定
*
FlutterのshowDialogのAlertDialogサンプル

- Android、iOS用でそれぞれ環境に合うDialogを出力する
```dart
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CommonDialogView {
  static Future<T?> show<T extends Object>(BuildContext context, String text) {
    return Platform.isIOS
        ? _showCupertinoDialog<T>(context, text)
        : _showMaterialDialog<T>(context, text);
  }

  static Future<T?> _showCupertinoDialog<T extends Object>(
      BuildContext context, String text) {
    return showCupertinoDialog<T>(
      context: context,
      builder: (BuildContext context) {
        return CupertinoAlertDialog(
          content: _buildContent(text),
          actions: _buildCupertinoActions(context),
        );
      },
    );
  }

  static Future<T?> _showMaterialDialog<T extends Object>(
      BuildContext context, String text) {
    return showDialog<T>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: _buildContent(text),
          actions: _buildMaterialActions(context),
        );
      },
    );
  }

  static Widget _buildContent(String text) {
    return SingleChildScrollView(
      child: Center(
        child: Text(
          text,
          style: const TextStyle(fontSize: 16),
        ),
      ),
    );
  }

  static List<Widget> _buildMaterialActions(BuildContext context) {
    return <Widget>[
      TextButton(
        onPressed: () => Navigator.pop(context, 'Cancel'),
        child: const Text('キャンセル'),
      ),
      TextButton(
        onPressed: () => Navigator.of(context).pop(),
        child: const Text('OK'),
      ),
    ];
  }

  static List<Widget> _buildCupertinoActions(BuildContext context) {
    return <Widget>[
      CupertinoDialogAction(
        onPressed: () => Navigator.pop(context, 'Cancel'),
        child: const Text('キャンセル'),
      ),
      CupertinoDialogAction(
        onPressed: () => Navigator.of(context).pop(),
        child: const Text('OK'),
      ),
    ];
  }
}
```
```dart
    // 使用例
    CommonDialogView.show(context,"コンテンツのtext")
```
Django ORM のフィルタクエリfilter()の使用例

Djangoでは、クエリセットを使ってデータベースからオブジェクトを取得する際に、filter()メソッドを使用してフィルタリングを行うことができます。

# filter()の使用例
Django ORMのfilter()メソッドに入れた条件でフィルタリングができます。

```
# 例：field_aがTrueになっているものを抽出
Model.objects.filter(field_a=True)
```

また複数のフィールドを渡した場合、SQL文のAND条件になります。
つまり、filter()に渡された複数の引数の全ての条件を満たしたものを抽出します。

https://docs.djangoproject.com/en/5.1/ref/models/querysets/#filter

## 複数条件(AND条件)
```
Model.objects.filter(field_a=False, field_b=False)

# SQL文
SELECT * FROM model WHERE field_a = FALSE AND field_b = FALSE;
```

## OR条件
Qオブジェクトを使用して、field_aまたはfield_bがFalseであるレコードを取得
```
from django.db.models import Q
Model.objects.filter(Q(field_a=False) | Q(field_b=False))

# SQL文
SELECT * FROM model WHERE field_a = FALSE OR field_b = FALSE;
```

# NOT条件
~（ビットごとのNOT演算子）を使用して、field_aがTrueでないレコードを取得
```
from django.db.models import Q
Model.objects.filter(~Q(field_a=True))

# SQL文
SELECT * FROM model WHERE NOT field_a = TRUE;
```

## ANDとORを組み合わせた複雑な条件の例
たとえば、field_aがFalseかつfield_bがTrue、またはfield_cがFalseなレコードを取得する場合だと以下の様に書けます。
```
Model.objects.filter(Q(field_a=False, field_b=True) | Q(field_c=False))

# SQL文
SELECT * FROM model WHERE (field_a = FALSE AND field_b = TRUE) OR field_c = FALSE;
```

# Field lookups
__で構文を繋げて使うField lookupsで、フィールドに対するさまざまな操作が可能です。

https://docs.djangoproject.com/en/5.1/ref/models/querysets/#field-lookups

例えば

- exact: 完全一致
- iexact: 大文字・小文字を区別しない一致
- lt: より小さい
- gt: より大きい
- contains: 部分一致


# 使用例
```Python
# 社員番号が "12345" と一致する従業員を取得
Employee.objects.filter(local_id__exact='12345')

# 氏名が "john" と一致する従業員を取得（大文字・小文字を区別しない）
Employee.objects.filter(first_name_kanji__iexact='john')

# メールアドレスに "gmail" を含む従業員を取得
Employee.objects.filter(email_address__contains='gmail')

# 退職日が2023年1月1日より前の従業員を取得
Employee.objects.filter(removed_at__lt='2023-01-01')

# 退職日が2023年1月1日以下の従業員を取得
Employee.objects.filter(removed_at__lte='2023-01-01')

# 年齢>30の従業員を取得
Employee.objects.filter(age__gt=30)

# 年齢が30歳以上の従業員を取得
Employee.objects.filter(age__gte=30)

# 氏名が "佐藤" で始まる従業員を取得
Employee.objects.filter(first_name_kanji__startswith='佐藤')

# 氏名が "john" で始まる従業員を取得（大文字・小文字を区別しない）
Employee.objects.filter(first_name_kanji__istartswith='john')

# 氏名が "太郎" で終わる従業員を取得
Employee.objects.filter(first_name_kanji__endswith='太郎')

# メールアドレスが "gmail.com" で終わる従業員を取得（大文字・小文字を区別しない）
Employee.objects.filter(email_address__iendswith='gmail.com')

# 指定された社員IDリストに含まれる従業員を取得
Employee.objects.filter(local_id__in=[123, 456, 789])

# 退職日が未設定（NULL）の従業員を取得
Employee.objects.filter(removed_at__isnull=True)

# 退職日が2023年1月1日から2023年12月31日の間にある従業員を取得
Employee.objects.filter(removed_at__range=['2023-01-01', '2023-12-31'])

# 退職日が2023年1月1日である従業員を取得
Employee.objects.filter(removed_at__date='2023-01-01')

# 退職年が2023年の従業員を取得
Employee.objects.filter(removed_at__year=2023)

# 退職月が1月の従業員を取得
Employee.objects.filter(removed_at__month=1)

# 退職日が1日の従業員を取得
Employee.objects.filter(removed_at__day=1)

```
生成AIでFFRPGプログラムは生成できるのか？ - ③社員マスター照会・入力プログラムを作ろう！

[前回の記事](https://qiita.com/2024_Rising_team_D/private/1cf09a411a734302622e)ではHello World!出力や四則演算といった初歩的なプログラムのソースコードを [Copilot](https://www.microsoft.com/ja-jp/microsoft-copilot) / [ChatGPT](https://openai.com/chatgpt/)に生成してもらいました。
結果としては簡単なプロンプトを投げることでほぼ手直しなくそのままコンパイル・動作できるコードを書いてもらうことができました。

今度は発展的なプログラムのソースも書いてもらおう、ということで、「社員マスターの照会・更新プログラム」のソースコードを生成できるか？を試してみます。

# プログラム仕様・外部ファイル
#### 仕様
+ 5250のグリーンスクリーンより、社員マスターの内容を画面に表示/画面より内容編集ができるプログラムを作成します。
+ 処理部分のプログラミング言語はFFRPGを使用します。
+ キーフィールドとして社員コードを指定し、社員コードを入力することで社員マスターの内容を表示します。

#### 画面イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3872367/307c9897-44df-23d8-70e0-e3a6a4cb23cc.png)

#### 外部ファイル
+ データベースファイル
以下のフィールドを持ったデータベースファイル（物理ファイル）を使用します。
<table>
<thead>
<tr><th>フィールド名</th> <th>カラム名</th> <th> タイプ </th>　<th> 長さ </th><tr>
</thead>
<tr><td>EMCODE</td><td>社員コード</td><td>文字</td><td>5桁</td></tr>
<tr><td>EMNAME</td><td>氏名</td><td>文字</td><td>10桁</td></tr>
<tr><td>EMDEPT</td><td>部署名</td><td>文字</td><td>20桁</td></tr>
<tr><td>EMDATE</td><td>入社年月日</td><td>日付</td><td>8桁</td></tr>
<tr><td>EMSALA</td><td>給与</td><td>数値</td><td>8桁</td></tr>
</table>

+ 画面ファイル
データの入出力のフロントとして画面ファイルを作成します。


次回の記事より実際にソースを生成してみます。
処理部分だけではなく、ファイルのソースもAIに生成してもらいたいと思います！
App Service EasyAuthとアプリロールを用いた認可でStreamlitアプリを構成する

# この記事で紹介すること
以下を用いてStreamlitアプリの簡単に認証認可を構成し、アプリロールを用いてページを出し分けする

- App Service 組み込み認証(トークンストア有効)
- Azureの機能であるアプリロール


## 前提
- Web App（コンテナ）
- Microsoft Azure


組み込み認証の概要は、以下リンクが図解されておりとても分かりやすいです

https://azure.github.io/jpazpaas/2023/05/11/what-is-appserviceauthentication.html

https://learn.microsoft.com/ja-jp/entra/architecture/auth-oauth2

https://learn.microsoft.com/ja-jp/entra/architecture/auth-oidc

## 実装方法
### App Service 組み込み認証

https://learn.microsoft.com/ja-jp/azure/app-service/scenario-secure-app-authentication-app-service?tabs=workforce-configuration

### アプリロールを設定する

1. ポータルからMicrosoft Entra IDに移動する
1. 管理＞アプリの登録から上述の「App Service 組み込み認証」で自動的に追加されたアプリケーションを選択する
1. 管理＞アプリロールで権限管理用のロールを追加する(今回はgeneralとadminの二つで,許可されたメンバーの種類：ユーザーまたはグループです)
1. ポータルからMicrosoft Entra IDに移動する
1. 管理＞エンタープライズアプリケーションから2.と同じ名前のアプリケーションを選択する
1. 管理＞ユーザーとグループ＞「+ユーザーまたはグループの追加」からユーザーまたはグループ、ロールを選択する
※複数ロールを同じユーザーに選択したい場合、追加で作成してください（１回の操作で１つのロールしか付与できません）

### streamlitアプリ

auth.py

```python
import os
import requests
import streamlit as st

def get_user_info():
    user_roles = []
    user_name = None

    # AppServiceAuthSessionクッキーを取得
    cookie = st.context.cookies.get("AppServiceAuthSession")
    auth_cookie = {"AppServiceAuthSession": cookie}
    host = os.getenv("APP_SERVICE_URL")
    try:
        auth_me_data = requests.get(f"{host}/.auth/me", cookies=auth_cookie).json()
    except Exception as e:
        return e

    user_claims = auth_me_data[0].get('user_claims', [])
    
    for claim in user_claims:
        if claim['typ'] == 'roles':
            user_roles.append(claim['val'])
        elif claim['typ'] == 'name':
            user_name = claim['val']
    return user_roles, user_name

```

main.py

```python
def main():
    user_roles, user_name = get_user_info()
    top_page = st.Page("front_pages/main/top.py", title="Top", icon=":material/home:")
    logout_page = st.Page("front_pages/main/logout.py", title="Logout", icon=":material/logout:")
    user_page = st.Page("front_pages/admin/user.py", title="User", icon=":material/account_circle:")

    page_dict = {}
    if "general" in user_roles:
        page_dict["Main"] = [top_page, logout_page]
    if "admin" in user_roles:
        page_dict["Admin"] = [user_page]

    if len(page_dict) > 0:
        pg = st.navigation(page_dict)
    else:
        pg = st.navigation([st.Page("front_pages/unauth/unauth.py")])
    pg.run()

if __name__ == "__main__":
    main()
```
これで完成です！

## 結局どういう認証の経路なの？
図を描きました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950120/b1c8f23c-4353-52af-1de7-e6ea0944424c.png)

良かったらいいねお願いします！

## 参考

https://learn.microsoft.com/en-us/azure/app-service/overview-authentication-authorization?source=recommendations

https://learn.microsoft.com/en-us/entra/identity-platform/howto-add-app-roles-in-apps#assign-users-and-groups-to-roles 

https://azure.github.io/jpazpaas/2022/12/02/Tips-for-App-Service-authentication.html
入力フォームの電話番号でハイフンを入力させてはいけない

とあるフォームを入力していたところ、ハイフン無しで電話番号入力したらエラーになって、ムッ！としてしまったのでポエムです。

## 入力された番号をシステム側でハイフンを入れられる法則がある
10桁もしくは11桁の電話番号を、市外局番-市内局番-加入番号に自動的に分解する方法があります。であれば、人があえて入力するよりも、システム自体でハイフンを自動挿入すればよい話です。

## ハイフンがはいっていると何がよいの？
固定電話全盛期であれば、市内通話時に、市外局番を省略して電話していたと思います。そんな時代なら、ハイフンがある表記の電話番号みて、市外局番を除いた電話番号知れたのは確かに重宝されたかもしれません。が、もう、そんな時代ではないのは、あえて説明する必要ないですよね。

## ハイフンを入力させ検証するのがダメな理由
ハイフンがはいっていないからといってエラーを表示して再入力させるなど、UXの観点ではあり得ない話です。ユーザーの離脱につながります。
【備忘録】 HDD の交換方法

# なにこれ？
たくさん HDD や SSD が搭載されたパソコンで、特定の問題のあるデバイスを探し当てるのは面倒である。昨今のはホットプラグに対応しているので、だったら「いったん全部 HDD/SSD をぶっこ抜いて、一台ずつ追加していって異常のあるのはその都度取り除けばよくね？」という発想によるリプレース方法である。もちろんデバイスの UUID　なんかを控えて、オフラインにしてから処理するのは理想だろうが、こんな記事を読むということは「準備ができていない」ということだろうから、次からこうならないように対策を講じることをおすすめする。もちろん、まったくおすすめできる内容ではないのだが、とりあえず書いておく。

# 環境
```shell
$ uname -a
Linux ubuntu 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
$ lsblk
sda           8:0    0   1.8T  0 disk
sdb           8:16   0   1.8T  0 disk
sdc           8:32   0 931.5G  0 disk
└─sdc1        8:33   0 931.5G  0 part
sdd           8:48   0   2.7T  0 disk
└─sdd1        8:49   0   2.7T  0 part
sde           8:64   0   1.8T  0 disk
└─sde1        8:65   0   1.8T  0 part
sdf           8:80   0   1.8T  0 disk
sdg           8:96   0   1.8T  0 disk
```       

# 手順
1. なにか「HDD/SSDを交換する必要がある」だろうから、パソコンをシャットダウンする前に処理すべきことはやっておく。たとえば BTRFS で RAID を組んでいるのだったら、予めヤバいデバイスを取り除くなどしておく。会社組織とかに所属しているのであれば、メールとかでちゃんとホウレンソウしておく。
1. 適切にシャットダウンする。
1. パソコンのケースを開けて、関係ある全ての HDD か SSD なんかを外す。いじるデバイスに OS とかが入っているのだったら、適宜ライブUSB を準備する。もちろん、静電気対策や怪我を防止するための処置は行う。
1. 今回利用するすべとのデバイスがホットプラグに対応しているかを確認し、そうでなければ中止する。念のために書くが、NVMe の SSD は多分このやり方は良くない。
1. パソコンのスイッチを入れる。ひょっとすると起動しないかもしれない。
1. OS が起動したなら、ログインし、HDD の見れるアプリかシェルを起動して、現在の HDD/SSD の状態を確認する。
1. それで、ホットプラグに対応した HDD/SSD を１台ずつ接続し、上でかいたアプリでシェルでデバイスの健康状態を確認し、適合するならそのままつなげる。不適切なデバイスであれば「適切な方法でシャットダウンした後に、HDDを外す」という処理をする。
1. デバイスの選択が完了したなら、ちゃんと後始末をして、システムを復帰させる。

# おわりに
こんなことはしなくて良い可能性が高いので、責任が負えないと判断したらリスクを他所に転化すること。怒られるのが怖くてこのページを開いたなら、先に説教されたほうが賢い選択だと思われるますので「ホウレンソウ」を行うこと。たぶん、こういうことはクラウドとかベンダーに金を払ってやらせるほうが良いことなはずだ。それでは、諸君らの健闘を祈る。
Webアプリケーションについて


## Webアプリケーションとは 

**WebアプリケーションとはWebブラウザ上で動作するアプリケーションソフトウェアです。**
Webブラウザを通じてインターネットやインターネット上のサーバーにあるアプリケーションにアクセスし、機能を利用します。
Webブラウザを通す事により、ソフトウェアをユーザーのコンピューターにインストールする必要がなく、ネットワーク接続とブラウザがあれば利用可能です。

## WebアプリケーションとWebサイトの違い
<dl>
<dt><strong>Webアプリケーション</strong></dt>
<dd>

**目的**

- ユーザーが特定のタスクや機能を実行できる。

**特徴**

- 動的なコンテンツや複雑な機能を提供。
- ユーザーとの双方向のインタラクションが可能。
- データ操作が必要。
- データベースと連携して情報の処理や保存を行う。

**例**

- オンラインバンキングシステム
- ソーシャルメディアプラットフォーム
- 電子メールサービス
- オンラインショッピングサイト
</dd>

<dt>Webサイト</dt>
<dd>

**目的**

- 情報の提供。
- コンテンツ閲覧。

**特徴**

- 静的なページが多い。
- ユーザーが情報を受け取ることが中心。

**例**

- 企業のコーポレートサイト
- ニュースサイト
- ブログ
- ポートフォリオサイト
</dd>
</dl>

## Webアプリケーションとネイティブアプリケーションの違い
<dl>
<dt>Webアプリケーション</dt>
<dd>

**定義**

- Webブラウザ上で動作するアプリケーションソフトウェア。
- インターネット経由でサーバーにアクセスし、機能を利用。

**特徴**

- **プラットフォーム非依存** :  ブラウザがあればOSに関係なく利用可能。
- **インストール不要** :  URLにアクセスし使用。
- **更新が容易** :  サーバー側で更新を行うため、ユーザー側でのアップデート不要。
- **アクセス性** :  インターネット接続が必要。ただしPWA( プログレッシブウェブアプリ )の導入により一部オフラインでも利用可能。

**メリット**

- **クロスプラットフォーム**：一度の開発で複数のデバイスで利用可能。
- **即時利用可能**：ダウンロードやインストールの手間がない。
- **自動更新**：常に最新のバージョンを提供。

**デメリット**

- **パフォーマンスの制限**：ネイティブアプリに比べて処理速度が遅い場合がある。
- **ハードウェアアクセスの制限**：デバイスの機能（カメラ、GPSなど）へのアクセスが限定的。
- **オフライン機能の制限**：インターネット接続が必要な場合が多い。
</dd>

<dt>ネイティブアプリケーション</dt>
<dd>

**定義**

- 特定のプラットフォーム( iOS, Android, Windows )向けに開発されたアプリケーション
- デバイスに直接インストールして使用

**特徴**

- **プラットフォーム依存** :  書くOS専用に開発され、他のOSでは動作しない
- **インストールが必要** :  App StoreやGoogle Playなどからダウンロード
- **更新** :  ユーザーがアップデートを行う必要がある ( 自動更新も可能 )
- **アクセス性** :  オフラインでも動作可能な場合が多い

**メリット**

- **高いパフォーマンス**：デバイスのハードウェアを直接利用できるため、速度や応答性が良い。
- **フル機能の利用**：カメラ、GPS、加速度センサーなど、デバイスの全機能にアクセス可能。
- **優れたユーザーエクスペリエンス**：UI/UXがプラットフォームに最適化されている。

**デメリット**

- **開発コスト**：各プラットフォームごとに別々の開発が必要。
- **インストールの手間**：ユーザーがダウンロード・インストールする必要がある。
- **更新の遅延**：ユーザーがアップデートしないと最新機能を利用できない。
</dl>

## Webアプリケーションの仕組み
<dl>

<dt>基本的な構成要素</dt>
<dd>

1. **クライアント（ユーザー側）**

    - **ウェブブラウザ**：ユーザーがWebアプリケーションにアクセスするためのソフトウェア。
    - **ユーザー操作**：クリック、入力、フォーム送信など。

2. **サーバー（提供側）**

    - **ウェブサーバー**：ユーザーからのリクエストを受け取り、適切なコンテンツをクライアントに返すソフトウェア、またはそのソフトウェアが動作するハードウェアを指します。
    - **アプリケーションサーバー**：ビジネスロジックを実行し、データベースと連携するためのソフトウェアまたはプラットフォーム。
    - **データベースサーバー**：データを一元的に保存・管理し、他のアプリケーションやサービスがそのデータにアクセスできるようにするソフトウェア、または動作するハードウェアを指します。データの保存、更新、取得,  削除などを行う。
</dd>
</dl>
<dl>
<dt>動作の流れ</dt>
<dd>

1. **ユーザーのリクエスト送信**

    - ユーザーがブラウザで特定のURLにアクセスしたり、フォームにデータを入力して送信します。
    - ブラウザはその操作に基づいてHTTPリクエストをサーバーに送信します。
    
2. **サーバーでの処理**

    - ウェブサーバーがリクエストを受け取り、適切なアプリケーションサーバーに渡します。
    - アプリケーションサーバーがリクエスト内容を解析し、必要なビジネスロジックを実行します。
    - 必要に応じてデータベースと通信し、データの取得・更新を行います。

3. **レスポンスの生成と送信**

    - アプリケーションサーバーが処理結果をHTML、JSON、XMLなどの形式で生成します。
    - ウェブサーバーがこのレスポンスをクライアントに返します。

4. **ブラウザでの表示**

    - ブラウザが受け取ったレスポンスを解析し、ユーザーに視覚的なコンテンツとして表示します。
    - 必要に応じてJavaScriptを実行して、ページの動的な部分を更新します。
</dd>
</dl>

今回はWebアプリケーションとはについて解説しました。
RPCエンドポイントを利用してウォレットを実装してみる　＃５現在のガス代を取得

# テーマ設定
RPCエンドポイントを利用して現在のガス代を取得する機能を実装してみる。

# 前提環境
+ Node.js がインストールされている。
+ Web3.js ライブラリがインストールされている。

+ RPCエンドポイントを取得（無料）
https://cabinet-node.com/ja/docs/user-guide/create-access-token

### web3のインストール
```bash
npm install web3
```

# 実装
以下の内容でget_current_gas_price.jsファイルを作成してください。
 ```js
const { Web3 } = require('web3');

// InfuraなどのRPCエンドポイントを設定
const web3 = new Web3('https://gateway-api.cabinet-node.com/{access_token}');

async function getCurrentGasPrice() {
    try {
        // 現在のガス価格を取得 (Wei単位)
        const gasPrice = await web3.eth.getGasPrice();
        
        // WeiをGweiに変換して表示
        const gasPriceInGwei = web3.utils.fromWei(gasPrice, 'gwei');
        
        console.log(`Current Gas Price: ${gasPriceInGwei} Gwei`);
    } catch (error) {
        console.error('Error fetching gas price:', error);
    }
}

getCurrentGasPrice();
 ```

 # 実行
 
  ```
node get_current_gas_price.js
  ```

### 結果の例

```
Current Gas Price: 4.229144399 Gwei
```
Vercelデプロイ手順

## Vercelに登録
[Vercel](https://vercel.com/)にアクセスします。

「Sign Up」をクリックしてアカウントを作成します。GitHub、GitLab、Bitbucket、またはメールアドレスを使って登録できます。
必要な情報を入力し、アカウントを設定します。

## Vercelにプロジェクトをデプロイ

1. Vercelのダッシュボードにログインします。
2. 「New Project」をクリックします。
3. プロジェクトをアップロードするために、GitHub、GitLab、BitbucketのリポジトリをVercelに連携させるか、ローカルのファイルシステムからプロジェクトフォルダーをドラッグ＆ドロップします。
4. プロジェクトのリポジトリが選択されたら、「Import」をクリックします。
5. ビルド設定で、プロジェクトが静的サイトであれば特に設定は必要ありませんが、ビルドコマンドや出力ディレクトリについて設定する必要がある場合はここで設定します。ただし、HTMLとCSS、JavaScriptのみで構成されるプロジェクトの場合、大抵の設定は自動で適切に行われます。
6. 設定が完了したら、「Deploy」をクリックします。

## デプロイ後の確認

デプロイが完了すると、VercelはプロジェクトにアクセスできるURLを提供します。このURLを使って、ウェブサイトが正しく表示されるか確認できます。

これでVercelを使用してプロジェクトをデプロイする基本的な流れは完了です。
Oracle Analytics Cloud：OAC Client ToolsのModel Administration Toolの式リファレンス

はじめに
---
Oracle Analytics Cloud (OAC) は、データソースからデータをとってくる際に、データセットを使う方法と、セマンティック・モデルを使う方法があります
セマンティック・モデルを開発する際に、WebUIのセマンティック・モデラーを使う方法と、OAC Client ToolsのModel Administration Toolを使う方法があります
OAC Client ToolsのModel Administration Toolを使う場合についてOracle Analytics Cloudのマニュアでは簡易な手順しかないため、
Oracle Analytics Serverのマニュアルで"Oracle Analytics Serverメタデータ・リポジトリの管理"が参考になります
Oracle Analytics Serverメタデータ・リポジトリの管理のマニュアルをみてみます

マニュアルは、["こちら"](https://docs.oracle.com/cd/G15107_01/metadata-oas/index.html) です
以下、マニュアルイメージ
![g1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/3bb7ff9a-ba0e-ad9f-9e35-d2c4a5c7991a.jpeg)

記載時のOACバージョン：OAC 2024 Sep版


リファレンス
---
関数などのリファレンスは["こちら"](https://docs.oracle.com/cd/G15107_01/metadata-oas/reference-oasmg.html) です
以下、マニュアルイメージ
![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/e5aae0fa-fac5-c604-8d27-a2612e66401a.jpeg)


文字列関数を使う
---
物理結合の定義で、先頭２文字を切り取る関数を使ってみます
文字列を切り取る関数は、substringがあります
![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/916a6c61-3a0a-5406-d52c-8597dc3d0f31.jpeg)

例えば、先頭２文字を切り取る場合
substring(<列名> from 1 for 2)とします
![g3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/b67bafc5-4e60-74c0-60b4-74e99b742aaa.jpeg)

列が文字でなく数値の場合は、切り取る前に文字列に変換する必要があります
文字列への変換はCAST関数を使います
![g5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/1aef1b31-32aa-761a-4853-d448c42d885f.jpeg)

以上
PowerApps PatchとUpdateIfの違い

# Patch
1.新規追加
```
Patch(
    table,
    {id:Blank()},
    {
        product_name:"商品A"
    }
);
```
2.更新
```
Patch(
    table,
    {id:1},
    {
        product_name:"商品A"
    }
);
```

# UpdateIf
1.新規追加
```
条件式がfalseの場合、何もしない
```
2.更新
```
UpdateIf(
    table,
    id = 1 //IDのindexを作成すると、検索速度が速くなる
    And product_name = "商品A"
    And delete_flg = 0
    ,
    {
         product_name:"商品B"
    }
);
```
Windows11,Eclipse,Tomcat10 で古いJavaservletを動かす環境設定

# 業務忘備録

## インストール
eclipse C:\pleiades
tomcat10 C:\tomcat10
Java 21 C:\Program Files\Eclipse Adoptium\jdk-21.0.3.9-hotspot
Java 11 C:\Program Files\Eclipse Adoptium\jdk-11.0.23.9-hotspot

## 開発環境（本番環境）
Java 11
Tomcat 10

## Eclipse 設定
3. 新規立ち上げ
3. 新規フォルダ作成　C:\pleiades\workspace_
3. C:\pleiades\workspace_　選択
3. パッケージ ⇒「動的 Web プロジェクトを作成します」選択
3. 任意のプロジェクト名入力「n00a」
3. ターゲット・ランタイム、新規ランタイム、Apache、Apache Tomcat v10.1、新規ローカル・サーバーの作成（選択）、次へ、Tomcat インストール・ディレクトリー⇒参照、C:\tomcat10（選択）、JRE⇒インストール済みのJRE⇒追加⇒標準VM⇒C:\Program Files\Eclipse Adoptium\jdk-11.0.23.9-hotspot（フォルダー選択）、完了、jdk-11.x（チェック）、適用して閉じる、完了
3. 次へ
3. 次へ
3. web.xml デプロイメント記述子の生成（チェック）、完了

## EclipseTomac 設定
1. サーバータブ（選択）
1. localhost の Tomact v10.1　サーバー（ダブルクリック）
1. ポート、Tomcat 管理ポート、8005を任意の数字へ（例:8006)
1. ポート、HTTP/1.1 8000を任意の数字へ（例:8081)
1. Ctrl + S（保存）

## Eclipse Java 設定
1． パッケージ・エクスプローラー⇒n00a⇒JRE システム・ライブラリー[JavaSE-21]、右クリック、プロパティー、システムライブラリ⇒実行環境⇒JavaSE11（選択）、適用して閉じる

## Eclipse lib 設定
1. プロジェクト・エクスプローラー⇒n00a⇒右クリック、プロパティー、Java のビルド・パス、ライブラリー、クラスパス（選択）、外部 JAR の追加、プロジェクトで使用しているLibのリンクを追加する、適用して閉じる

## Eclipse サーバー設定
1. プロジェクト・エクスプローラー⇒n00a⇒右クリック、実行⇒１．サーバーで実行、既存のサーバーを選択、このプロジェクトを実行するときは常にこのサーバーを使用（チェック）、次へ、n00a⇒追加、完了
PowerApps Patchの一括登録機能を使って、多数データの登録のパフォーマンスを改善する方法

# 保存先のテーブル

Parent_table
|id |product_name|
|---|---|
|1  |商品A|
|2  |商品B|

# 普通のPatchの使い方
```
Patch(
    Parent_table,
    {id:Blank()},
    {
        product_name:"商品C"
    }
);

Patch(
    Parent_table,
    {id:Blank()},
    {
        product_name:"商品D"
    }
);
```
実行後
Parent_table
|id |product_name|
|---|---|
|1  |商品A|
|2  |商品B|
|3  |商品C|
|4  |商品D|

# Patch一括登録の使い方
```
Clear(save_col);
Collect(
    save_col,
    {
        id:Blank(),
        product_name:"商品c"       
    }
);
Collect(
    save_col,
    {
        id:Blank(),
        product_name:"商品d"       
    }
);

Patch(
    Parent_table,
     SortByColumns(save_col,"product_name")
);

```
実行後
Parent_table
|id |product_name|
|---|---|
|1  |商品A|
|2  |商品B|
|3  |商品C|
|4  |商品D|

# 注意点
1.save_colの構造は必ず、テーブル定義と一緒(物理名の使用)
2.一括登録の時、ソートしないと、登録順番がバラバラになる

# 参考サイト
https://ippu-biz.com/development/powerplatform/powerapps/patch-collection/
【学習メモ】Railsチュートリアル第５章5.2.2演習


## 演習＜footer用CSSをSassを使ってネストする＞

>演習
5.2.2で提案したように、footerのCSSを手作業で変換してみましょう。具体的には、リスト 5.16の内容を1つずつ変換していき、リスト 5.19のようにしてみてください。

### 学習メモ
・共通パターンがある
→ネスト

・2重に定義する箇所がある場合
（例hoverなど、「もし〇〇が～～したら」のイメージ）
→「&:」をつけてネスト



### ↓元のコード
・こちらを後ほど記載する「解答」と同じ状態に手作業で変換します
・今回は「編集用」に変換した内容を記載し、「解答」と見比べます
```
/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid #eaeaea;
  color: #777;
}

footer a {
  color: #555;
}

footer a:hover {
  color: #222;
}

footer small {
  float: left;
}

footer ul {
  float: right;
  list-style: none;
}

footer ul li {
  float: left;
  margin-left: 15px;
}
```


### ↓編集用
・記憶を頼りに変換をしてみました
```
$gray-white: #eaeaea;
$gray-light: #777;
$gray-midium: #555;
$gray-dark: #222;

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-white;
  color: $gray-light;
    &:a {
        color: $gray-midium;
        &:hover {
          color: $gray-dark;
        }
    }
    &:small {
      float: left;
    }
    &:ul {
      float: right;
      list-style: none;
      &:li {
          float: left;
          margin-left: 15px;
        }
    }
}
```

### ↓解答
```
/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-medium-light;
  color: $gray-light;
  a {
    color: $gray;
    &:hover {
      color: $gray-darker;
    }
  }
  small {
    float: left;
  }
  ul {
    float: right;
    list-style: none;
    li {
      float: left;
      margin-left: 15px;
    }
  }
}
```

### 「編集用」と「解答」との差分

・編集用では「&:」を多用しすぎ
→
再度Railsチュートリアルの説明を確認したところ、
重複して定義する場合に使う様子。
単純に共通する箇所がある場合には使わないように注意したいと思います。

### イメージ
footerのulについて
→ネスト
もしfooterがhoverした場合の定義をしたい
→「&:」を使う



### 上記を踏まえて再度編集しました。↓
```
$gray-white: #eaeaea;
$gray-light: #777;
$gray-midium: #555;
$gray-dark: #222;

/* footer */

footer {
  margin-top: 45px;
  padding-top: 5px;
  border-top: 1px solid $gray-white;
  color: $gray-light;
    a {
    color: $gray-midium;
        &:hover {
            color: $gray-dark;
        }
    }
    small {
      float: left;
    }
    ul {
        float: right;
        list-style: none;
        li {
            float: left;
            margin-left: 15px;
        }
    }
}
```

### 結果
上記へ変更したところ、正常に反映できました！

当然ながらカラーコードの定義名は見本（「解答」）とは異なりますが、
解答と同じ表示になり、満足しました！

インデントのつけ方も徐々に感覚をつかめてきており
解答と似た状態にできたのも嬉しかったです！

引き続きRailsチュートリアルを進めながら理解を深めていけたらと思います。
【DAY24】投稿画面における文字数の表示(1)

## はじめに
Laravelを用いてQ&Aサイトを作成しています。質問に対して文字数制限を設けているので、入力時に何文字書いたかわかると便利だと思い、その機能を実装することにしました。
以下の本を参考にしました。
[1冊ですべて身につくJavaScript入門講座](https://www.amazon.co.jp/%E3%80%90Amazon-co-jp-%E9%99%90%E5%AE%9A%E3%80%911%E5%86%8A%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8FJavaScript%E5%85%A5%E9%96%80%E8%AC%9B%E5%BA%A7-DL%E7%89%B9%E5%85%B8-JavaScript%E3%83%81%E3%83%BC%E3%83%88%E3%82%B7%E3%83%BC%E3%83%88-%EF%BC%91%E5%86%8A%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8F/dp/4815615756)

## 現在の質問投稿画面
機能実装前の投稿画面（一部抜粋）がこちらです。
![スクリーンショット 2024-10-02 11.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818045/b9effcf0-ca22-3008-c6b5-9a77ab469e80.png)
質問を打ち込んでも何も表示されませんが、質問の文字数が0または制限を超えた状態で投稿ボタンを押すとエラーメッセージが表示されます。
![スクリーンショット 2024-10-02 12.05.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818045/47a61cb1-0324-57a9-eb07-4b4fc600347b.png)

## 機能の実装
まずビューにて、質問タイトルのinputタグにid、その下に文字数表示用のpタグを記述
```html
<input type="text" name="question[title]" placeholder="タイトル" value="{{ old('question.title') }}" id="question-title-text" class="w-full rounded-2xl p-4 text-xl"/>
<p><span id="count">0</span>/50文字</p>
```

続いてJavaScriptで以下を記述
```count.js
const questionTitleText = document.querySelector('#question-title-text');
const questionTitleCount = document.querySelector('#question-title-count');

questionTitleText.addEventListener('keyup', () => {
   questionTitleCount.textContent = questionTitleText.value.length; 
});
```
私はLaravelBreezeを用いているので、作成したcount.jsをapp.jsでインポートします。
```app.js
import "./count"; //追記
```
おそらくHTML内にscriptタグを用いてJSを記述するのでも問題ないはずです。
これでリアルタイムで文字数が分かるようになりました。
![スクリーンショット 2024-10-02 12.28.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818045/92c8b0aa-92da-bb30-4c27-8b691a7a3cf1.png)

## 文字の色の変更
指定の文字数を超えた場合は数字の色が赤になると分かりやすそうなので、その機能を実装していきます。
JavaScriptにクラスを追加、または削除する処理を追記

```count.js
const questionTitleText = document.querySelector('#question-title-text');
const questionTitleCount = document.querySelector('#question-title-count');

questionTitleText.addEventListener('keyup', () => {
   questionTitleCount.textContent = questionTitleText.value.length; 
   if (questionTitleText.value.length > 50) {
       questionTitleCount.classList.add('text-red-500');
   } else {
       questionTitleCount.classList.remove('text-red-500');
   }
});
```
私はTailwindCSSを用いているので、text-red-500というクラス名を加えるだけで文字が赤色になります。通常はここで指定したクラス名に対してcsssで色を指定することになります。
これで指定の文字数を超えたら色が赤になるようになりました。
![スクリーンショット 2024-10-02 12.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818045/2a0a05e3-1907-7514-93c2-763a21ecf600.png)
プログラマーが落ち着かなくなるコードを書いてみた #4 (究極の意味不明を作る)

どうもこんにちはクソコードが大好きなAtsu1209です。
今日はクソコード第四弾です。

第一弾

https://qiita.com/Atsu1209jp/items/d4273320d5ce5f690e9a

第二弾

https://qiita.com/Atsu1209jp/items/a1b051107bca65e87ceb

第三弾

https://qiita.com/Atsu1209jp/items/ebee2ed3c07093b6696f

番外編

https://qiita.com/Atsu1209jp/items/b88c5e5ccbf037e76565

このシリーズ結構やってて草

# 今回やること
第二弾の記事にこんなコメントをいただきました。
`パッと見何をやりたいかわかるコードはクソコードではないｗｗｗ`
なら挙動もコードもなにもかもが意味不明なものつくろう
ということです。

# 作る
説明するより見てもらったほうが早い気がするので早速書いちゃいます。
```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>クソコード</title>
</head>
<body>
    <div id="a"></div>
    <button id="b">クリックしてはいけない</button>
    <script>
      var _=document.getElementById.bind(document),$=_('a'),O=0,x=function(_,A){return _+A};function y(){var Z="";for(var W=0;W<10;W++){Z+=W%2==0?"<p>"+x(W,O++)+"</p>":"";}return Z;}!function(){_('b').addEventListener('click',function(){$.innerHTML=y();var A=setInterval(function(){O%5==0?($.style.color='red'):($.style.color='blue');O++;O>50?clearInterval(A):null;},100);});}();

    </script>
</body>
</html>

```
かなりわかりにくくしました。

変数をアルファベット一文字にして、さらに挙動も意味わからない

挙動がわかりやすいようにJSを整形します
```javascript:index.js
var _ = document.getElementById.bind(document),
  $ = _('a'),
  O = 0,
  x = function(_, A) {
    return _ + A
  };

function y() {
  var Z = "";
  for (var W = 0; W < 10; W++) {
    Z += W % 2 == 0 ? "<p>" + x(W, O++) + "</p>" : "";
  }
  return Z;
}! function() {
  _('b').addEventListener('click', function() {
    $.innerHTML = y();
    var A = setInterval(function() {
      O % 5 == 0 ? ($.style.color = 'red') : ($.style.color = 'blue');
      O++;
      O > 50 ? clearInterval(A) : null;
    }, 100);
  });
}();
```
これを作ってる時間おれは何をしてたんだろう...

# おわり
たまにはクソコードでも書いてリラックスしましょ。
ではまた次の記事で
【UIアイディア】■■■で■■■する


## 前書き

これはただのアイディア
もしくは問題提起

## 本文

<img width=200 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/7a94ff97-3eff-0031-c5e7-5994f731fe3b.png>

よりも

<img width=350 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/4113746d-23d8-3fa2-b609-2c90aed92f66.png>

のほうが分かりやすくない？

もちろん、選択肢の数とか操作内容にもよってくるけど。

<!--

## チラ裏

SIerみたいなお堅い会社は前者しか選択肢になく、後者みたいなやり方は頭からすっぽ抜けるので備忘録的な意味合いも込めて書いた。

-->
Salesforce LWCで入力値に応じた画面表示/非表示の実装方法

## 目的
入力値に応じて、LWC（Lightning Web Component）の一部を表示または非表示にする実装方法について説明します。

例:`input1`と`input2`を両方チェックすると、非表示文章を表示に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3144795/f0306a7a-4c47-df33-9c7a-a31d59373417.png)

```html
<template>
  <lightning-input
    type="checkbox"
    label="input1"
    name="checkbox1"
    checked={isInput1Checked}
    onchange={checkbox1Handler}
  ></lightning-input>
  <lightning-input
    type="checkbox"
    label="input2"
    name="checkbox2"
    checked={isInput2Checked}
    onchange={checkbox2Handler}
  ></lightning-input>
  <template lwc:if={isVisiable}>
    <p>状況により表示する</p>
  </template>
</template>
```

## 方法１（推奨しない）：入力項目 setter で実装

`input1` と `input2` の setter を利用して、表示/非表示のフラグである isVisiable を設定します。

```javascript
export default class SampleLWC extends LightningElement {
  _isInput1Checked = false;
  get isInput1Checked() {
    return this._isInput1Checked;
  }
  set isInput1Checked(value) {
    this._isInput1Checked = value;
    this.isVisiable = this.isInput1Checked && this.isInput2Checked;
  }

  _isInput2Checked = false;
  get isInput2Checked() {
    return this._isInput2Checked;
  }
  set isInput2Checked(value) {
    this._isInput2Checked = value;
    this.isVisiable = this.isInput1Checked && this.isInput2Checked;
  }

  isVisiable = false;

  checkbox1Handler(event) {
    this.isInput1Checked = event.target.checked;
  }
  checkbox2Handler(event) {
    this.isInput2Checked = event.target.checked;
  }
}
```

### メリット
・直感的な実装方法です。
・必要なときに表示/非表示を切り替えるため、効率的です。

### デメリット
・参照項目が増えるほどコードの管理や保守が難しくなります。
　極端な例として、100項目で表示/非表示を決定する場合、それぞれの項目ごとにロジックを実装する必要があります。

## 方法２（推奨）：表示/非表示のフラグ `getter` で実装

`getter` を使って表示/非表示のロジックを実装します。これにより、`isInput1Checked` や `isInput2Checked` の変更に応じて、自動的に表示/非表示が画面に反映されます。

```javascript
export default class SampleLWC extends LightningElement {
  isInput1Checked = false;
  isInput2Checked = false;

  get isVisiable() {
    return this.isInput1Checked && this.isInput2Checked;
  }

  checkbox1Handler(event) {
    this.isInput1Checked = event.target.checked;
  }
  checkbox2Handler(event) {
    this.isInput2Checked = event.target.checked;
  }
}

```

### メリット
・コード管理が簡単
　表示/非表示のロジックを一箇所に集約しているため、コードの管理や保守が方法1より簡単です。

### デメリット
・効率性
　複雑な画面では、`getter` が複数回呼ばれることがあり、理論上は方法1よりもパフォーマンスが劣る可能性があります。ただし、実際には表示速度にほとんど影響はありません。
AWS WAF と AWS Shield の違いをまとめてみた

AWSには、**AWS WAF**（Web Application Firewall）と**AWS Shield**という2つのセキュリティサービスがありますが、それぞれ役割や機能が異なります。違いをわかりやすくまとめました。

## AWS WAF と AWS Shield の比較

| **特徴**                    | **AWS WAF**                                           | **AWS Shield**                                           |
|-----------------------------|------------------------------------------------------|---------------------------------------------------------|
| **主な目的**                | アプリケーションレベルの攻撃から保護                  | DDoS（分散型サービス拒否）攻撃から保護                   |
| **対応する脅威**            | - クロスサイトスクリプティング（XSS）<br> - SQLインジェクション（SQLi）<br> - その他のアプリケーション層攻撃 | - DDoS攻撃<br>（レイヤー3/4攻撃および一部レイヤー7攻撃）|
| **保護対象**                | HTTP/HTTPSリクエスト                                  | ネットワーク層とアプリケーション層のDDoS攻撃              |
| **レイヤー**                | アプリケーション層（レイヤー7）                      | レイヤー3（ネットワーク層）<br>レイヤー4（トランスポート層）<br>レイヤー7（アプリケーション層） |
| **カスタマイズ可能なルール** | - リクエストのヘッダー、IP、クエリ文字列に基づいたカスタムルールを作成可能 | カスタムルールは作成不可。<br>Shield Advancedではより高度な保護機能あり |
| **自動保護**                | 手動でルール作成が必要                                | AWS Shield Standardは自動でDDoS保護を提供（無料）<br>Shield Advancedではより強化されたDDoS対策（有料） |
| **使用例**                  | - Webアプリケーションの攻撃防止<br> - XSSやSQLインジェクションの防止 | - DDoS攻撃によるサービスダウンの防止<br> - サービス遅延の防止 |
| **料金**                    | 使用したルールの数やトラフィック量に基づいて課金      | - **Shield Standard**は無料<br> - **Shield Advanced**は有料、アカウント単位で課金 |

---

## 1. AWS WAFとは？

**AWS WAF**は、Webアプリケーションに対する**アプリケーション層の攻撃**を防ぐためのファイアウォールです。特に以下のような攻撃に対して有効です：

- **クロスサイトスクリプティング（XSS）**
- **SQLインジェクション（SQLi）**

AWS WAFでは、特定のリクエストパターンやIPアドレス、クエリ文字列に基づいたルールを作成し、それに基づいて攻撃をフィルタリングします。アプリケーション層（レイヤー7）のセキュリティを強化するためのツールであり、カスタムルールを使って細かい制御が可能です。

### 主な特徴
- **カスタムルールの作成**: ヘッダーやIP、パスに基づいた細かいルールを設定可能。
- **使用例**: XSSやSQLインジェクションなど、アプリケーション層の攻撃からの保護。

---

## 2. AWS Shieldとは？

**AWS Shield**は、**DDoS攻撃**からAWSリソースを保護するためのサービスです。DDoS攻撃は、大量のトラフィックを発生させてサービスを停止させる攻撃で、Shieldはこれを防ぐために設計されています。

Shieldには2つのプランがあります：

- **Shield Standard**（無料）: 全てのAWSアカウントで標準的なDDoS保護を提供。
- **Shield Advanced**（有料）: より高度なDDoS対策とサポートを提供。

### 主な特徴
- **自動DDoS防御**: Shield Standardは自動的にDDoS攻撃を防ぎます。
- **使用例**: EC2やELB、CloudFrontなどのリソースをDDoS攻撃から保護。

---

## 3. どちらを使うべきか？

- **アプリケーション層の攻撃**（XSS、SQLインジェクション）を防ぎたい場合は、**AWS WAF**が適しています。自分でカスタムルールを設定して、細かいリクエストのフィルタリングが可能です。
  
- **DDoS攻撃**に対して強固な保護を行いたい場合は、**AWS Shield**が適しています。特に、サービスのダウンタイムを最小限に抑えたい場合は、Shield Advancedの利用も検討しましょう。

---

## まとめ

AWS WAFとAWS Shieldは、それぞれ異なる攻撃に対応するセキュリティサービスです。**アプリケーション層の攻撃に対する防御**が必要ならWAF、**DDoS攻撃からの防御**が必要ならShieldを使う。
あるいは両方を使うのも良いです。
【備忘録】GA4で内部トラフィックを定義する際の注意点

##  IPv6も定義の中に入れる
wifiに繋いでいる状態で、下記サイトに入り、IPv6が表示される場合はGA4の内部トラフィックの定義でIPv4だけでなく、IPv6も定義の中に入れることでGA4で内部トラフィックが除外されない問題が解決したので、備忘録として残しておきます。

https://whatismyipaddress.com/ja/index
Misuse of Sign in with Google API: Use of `:googleid` classes without use of `GoogleIdTokenCredential`

Ladybug2024.2.1にアップデートしたところ、Lintが次のメッセージで失敗するようになりました。
```
Error: Use of :googleid classes without use of GoogleIdTokenCredential [CredentialManagerSignInWithGoogle]
          val googleIdOption = GetGoogleIdOption.Builder()
                               ~~~~~~~~~~~~~~~~~
  
     Explanation for issues of type "CredentialManagerSignInWithGoogle":
     When using :googleid classes like GetGoogleIdOption and
     GetSignInWithGoogleOption, you typically must handle the response using
     GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL or
     GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_SIWG_CREDENTIAL.
  
     This check reports all uses of these :googleid classes if there are no
     references to GoogleIdTokenCredential.
  
     https://developer.android.com/identity/sign-in/credential-manager-siwg#create-sign
```
メッセージを読む限り、本来の意図としては
`val googleIdOption = GetGoogleIdOption.Builder().build()` がある場合に
`GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL` 
があるかどうかを確認しているようです。

しかし、テストコードを読むと、次のような記述があります。
```
    // The code that references the Google ID classes is in a library module;
    // the warning should still be reported when we reach the app module.
```

https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-tests/src/test/java/com/android/tools/lint/checks/CredentialManagerSignInWithGoogleDetectorTest.kt;l=243;drc=7aa5466f5690ec728fdd88fbb467aaec981f1dfe

どうやら、ライブラリモジュール内で`Google ID`への参照があると警告を出すようです。

（ここからは個人の意見です）
UIレイヤで実行すべき、というのは理解できますが、アプリケーションモジュールで必ず実行しないといけない、というのは制約としてやや強すぎる気がします。
一時的な対処として `CredentialManagerSignInWithGoogle` のLintをdisableにして様子を見るのが良さそうです。