OmniAICreator/Qiita-1.07M huggingface dataset:
【Zabbix】DELL・Idracでのハードウェア状態の監視方法

# 概要

DELLの実機の状態を確認するために、Idracを使用する方法があると思われる。
Idracを使用すると、WEBUIの画面からメモリの何番が壊れたり、とか、ファンの何番が壊れたりとかというのを確認することができる。
これを、Zabbixで検知できるようにしたい。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/37a846f5-aea1-b606-e4e5-545c6386679f.png)

# 手順
前提条件として、ZabbixサーバとDELLサーバ（監視対象）はSNMPの疎通できるものとし、ZabbixサーバのFWは空いているものとする。Idrac（BIOSレベル）の通信で監視項目を取得するため、OSには入らない。


## Zabbixサーバに、テンプレートをインポートする。
XMLファイルのリンク元：https://github.com/lucasafonsokremer/zabbix-templates/blob/master/iDRAC-9/Template-SNMP-iDRAC-9.xml

上記のGitのリンクからTemplate-SNMP-iDRAC-9のxmlファイルをダウンロードする。
その後、テンプレート->右上のインポートクリック。
ファイルの選択でxmlファイルを選択し、インポートする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/469f9eca-5836-8d99-bef0-7dd92aea75dc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/cd50d226-5bd4-8eab-507c-42363e048cf7.png)

テンプレートに、先ほどインポートしたIdrac-9が設定されている事を確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/414fd692-474c-7ca6-d69d-65d71fd9291d.png)

## 監視対象のIdracを確認する。
Idracのアドレスをブラウザに入力し、ログイン画面を見る。ここで、
`Integrated DEll remote Access Controller 9` とあるのなら、バージョン9が使用可能である

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/ad7b7cc2-6ce5-82d1-0648-c3d42fba8071.png)

Idracにログインして、`Idrac設定->サービス->SNMPエージェント`を開く。
そして、コミュニティ名とポート番号を確認する。ここでは

- コミュニティ名：public
- ポート番号：161

になっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/6d369e61-f2bd-fc9c-0338-9be5c4d0cc6b.png)

# Zabbixサーバからホスト登録を行う。
Zabbixサーバの、設定→ホストから、ホストの作成を行い、編集を行う。
ホスト名、グループは任意のものをつける。

- エージェントのIP：そのまま。
- SNMP：Idracのアドレス（161ポートを選択する）

さらにSNMPの所を開き、SNMPのバージョンとコミュニティ名を確認する。

- SNMPバージョン：SNMPv2
- SNMPコミュニティ：{$SNMP_COMMUNITY}

ここではコミュニティ名にマクロを使用しているため、マクロからコミュニティ名をpublicにしておく。（SNMPコミュニティに直打ちしても通る）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/b818f96a-d160-959c-9a49-993e1b2ad7e4.png)

その後、テンプレートの欄から新規テンプレートのリンクで、`Template-SNMP-iDRAC-9`を選択し、リンクさせる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/d8b0c0d3-0ee4-3187-48a5-3a6e1f9a733c.png)

対象ホストのアイテムから、`Template-SNMP-iDRAC-9`のアイテムの値が取れる事を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1288524/4cef0190-b1cc-3cac-13a1-c514aea61bb9.png)

またホストの画面に戻り、エージェント状態でのSNMPが取得でき、緑の状態になっている事を確認する。
ここまでできたら、問題なく取得ができている。

以上

# 参考サイト

https://www.zabbix.com/integrations/dell#3rd_party
UseStateとUseEffectについて

## UseState
Reactの状態管理で使われるフック。
状態を保持する変数と、その変数の状態を更新する関数を提供する。

```jsx
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>カウントアップ</button>
    </div>
  );
}

```
上記例では、初期値が0のcount変数を定義して、setCount関数を使用して状態を更新する。
setCountは、新しい状態を引数として受け取り、countを更新することで状態を変更する。
余談だが私は初めてReactを勉強した時、上記例のsetCount関数とhandleClick関数がごっちゃになっていた…。

## UseEffect
コンポーネントの副作用を制御するために使用するフック。
UseStateと同じで、使用する場合はreactからimportする必要がある。

>useEffectの役割は「ある値が変わった時に限り、ある処理を実行する」機能になります。
>>モダンJavaScriptの基本から始める React実践の教科書　p.121

例えば、numというStateの値が変わった時にアラートを表示したいとき、
下記のように書くことができる。
```jsx
  useEffect(() => {
    alert("ほげほげ");
  }, [num])
```
注意点として、
numの更新時だけじゃなくて、コンポーネントのマウント時（一番最初）にも実行される。
コンポーネントを表示した初回のみ実行させたい場合（初期データを取得したい時等）は、[num]の部分を[]と設定すれば良い。
Android Studio Flamingoにアップデートするとプロジェクトのビルドに失敗する

## ビルドエラーの内容

ある日の朝、Android Studioのアップデートが来てたのでアップデートを実行すると、下記のようなエラーでプロジェクトのビルドが通らなくなりました。

```
class clojure.lang.Reflector cannot access class com.sun.tools.javac.model.JavacElements (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.model to unnamed module @14b2a021
	at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Unknown Source)
```

## 原因

Android Studio Flamingo の日本語版リリースノートを見てもこのようなエラーの原因っぽい更新が行われた様子はなく、エラー内容で調べてみても有力そうな情報が見当たらずで困っていたところ、ありました。英語版リリースノートに。

https://developer.android.com/studio/releases#jdk-17

> Android Studio bundled with JDK 17
Starting from Android Studio Flamingo Canary 3, the Studio IDE is bundled with JDK 17. If Android Studio is configured to use the embedded JDK, new projects will use the latest stable version of the Android Gradle plugin and JDK 17. However, existing projects might break, and you might have to manually set the JDK to a compatible version.

Android Studio Flamingo Canary 3 から JDK 17 がbundleされるようになったとのこと。これまでの Android Studio にbundleされていた JDK 11 を利用するプロジェクトではビルドが失敗するケースがあるようで、今回のプロジェクトもこのケースでした。

## 対処方法

`Android Studio > Preferences > Build, Execution, Deployment > Build Tools > Gradle` で、ビルドの際に利用するJDKを指定できます。
ここで JDK 11 を指定すると、 Android Studio Flamingo 以前と同様 JDK 11 を利用したビルドを行うよう設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238072/8bd155e5-4c09-4998-f6c2-ca8fca697a55.png)
プロジェクトを JDK 17 に対応させる、が100点の解決方法だと思いますが、すぐには対応できないことも多いので...。
すぐにビルドしたいのにエラーになった！JDK 17 対応なんてすぐにはできないよ！という場合の対処方法としてのご紹介でした。
【暴露】個人開発で失敗した4つのこと

# はじめに
2020年から約1年半かけて株のポートフォリオ管理アプリをリリースしました。
仕事が終わってから夜は開発に没頭し、土日も一人でずっと開発を行っていました。
そして、1年半かけて作ったものをやっとリリースしたものの、
登録ユーザーは半年で100人ほどしか集まりませんでした。
そして、ほとんどのユーザーは継続して使ってくれずに、
DAU(デイリーアクティブユーザー数)は脅威の3という数字を叩き出しました。
みなさん、打ち間違えじゃないでよ。3ですよ。3。

もうね、ショックでしたよ。
あんなにしてやったのに、誰からも使われないアプリになってしまいました。

そして誰からも使われないということは、これ以上モチベーションを維持することができなくなって
1年後にはそっとアプリを閉じました。

皆さんには同じ失敗をしてほしくないので、ここで何がいけなかったのかを暴露していきます。

# 開発したもの
株のポートフォリオ管理アプリをリリースしました。
私自身、株を買って資産形成をしており、毎日株価を確認するのが日課です。
10種類以上の銘柄を所有しており、どの銘柄が上がったのか、下がったのかを一目で確認したいのです。

しかし、証券会社のアプリはポートフォリの確認以外の機能がものすごくいっぱいあったため使いにくかったです。

かといって、Yahooファイナンスをずっと使っていたのですが、
ポートフォリオの構成比率（どの株をどれくらい持っている）を円グラフで表示する機能がなかったり、
資産の推移が見れなかったりして不便という課題を感じていました。

だったら自分で作ればいいじゃないか！という発想で開発に着手しました。

# 実際に開発したもの
<img width="200" alt="Snowlys_iPhone13_ストア画像.001.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249502/8537fa6b-06fb-ced4-e6d8-952c6216a086.jpeg">

<img width="200" alt="Snowlys_iPhone13_ストア画像.001.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249502/24470aad-7fc7-d0e5-6a2a-127dfa18d849.jpeg">

<img width="200" alt="Snowlys_iPhone13_ストア画像.001.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249502/57bc7d65-7385-0247-23f4-64c23dc4837a.jpeg">

<img width="200" alt="Snowlys_iPhone13_ストア画像.001.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249502/b980833a-1d4d-b2a1-b42a-e7ec38e7bf9e.jpeg">

<img width="200" alt="Snowlys_iPhone13_ストア画像.001.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249502/8537fa6b-06fb-ced4-e6d8-952c6216a086.jpeg">

<img width="200" alt="Snowlys_iPhone13_ストア画像.001.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249502/5986b994-bcb4-23fc-925f-24568c6d5d56.jpeg">


## 機能を盛り過ぎた
大きく分けて企画段階で2つの機能を考えていました。
1. ポートフォリオの管理
1. SNS機能（Twitterのような、つぶやき、いいね、リプライが可能）

そして、ポートフォリオ管理の機能は無事にリリースしたのですが、
SNS機能は開発ボリュームが大きかったので最後の最後でリリースしました。

開発ボリュームが膨大すぎて、後に説明するマーケティングに全くと言って手が出せなかったです。
その結果、誰にも認知されることなく終わってしまいました。

### 反省点
機能は必要最低限にしよう。
それでいて、ユーザーのニーズを満たすものを開発しよう。

## SNS機能でユーザーをどうやって獲得するか考えていなかった
SNS機能は投稿をしてくれるユーザーがいて初めてそれを見るユーザーが生まれます。
ですが、誰も見てくれないアプリに投稿をするユーザーはいません。

俗にいう鶏と卵問題です。

この対策をしっかりと取っていないと詰むことになります。

## マーケティングの知識の甘さ
なんとなくSNS運用をすればいいじゃないかと思っていました。
3ヶ月くらい続けてみてTwitterのフォロワーは100人くらいになりました。

しかし、これが大変大変。
とてもじゃないけど、昼間仕事しながら、夜は個人開発やっているので、SNS運用が疎かになってしまいました。

ここでやっとSNS運用の大変さが分かりました。

また、ツイートをしているだけで、他の人のツイートにリプライをしたりすることが全くできていませんでした。
Twitterはある種のコミュニティなので、積極的に他のユーザーと絡んでいって仲良くなることが必要です。

また、伸びているツイートにもリプライすることで他のユーザーにも自分の考えを発信することができます。
恥ずかしがらずにリプライしましょう！

## ピッチ資料を作ってVCに連絡したが全然ダメだった
ベンチャーキャピタル（VC）から投資してもらえないかと思いピッチ資料を作成しました。
この時はまだイケイケの精神で、まだリリースもしていないのに調達できると思っていました。

最初のアポイントは簡単に取れますが、以下のような指摘がきて、結果はダメダメでした。
1. 参入障壁は？大手企業が参入してきたらどうするの？
1. 資産を共有したいというニーズはTwitterじゃダメなの？あなたのアプリである必要は何？

非常に手厳しい言葉ですが全くもってこの通りですね。
最初からVCに投資してもらおうなどという甘い考えはよしておいた方がいいです。

# 良かったこと
ここまで散々なことを書いてきましたが、もちろん良かったこともあります。
アプリの開発にはAWSのサーバーレス環境とFlutterを使用したことにより
これらの知識量が格段に上がりました。

そのため、フリーランスで働く案件も高単価のものになり、
かつ、開発環境や働き方も今まで以上のものになりました。

# さいごに
現在はバーチャルコミュニケーションアプリのピクセルトークを開発しています。
これらの失敗を糧に引き続き、足掻いて足掻いて足掻きまくります！
よければどのようなアプリかホームページを見てみてください。
どうぞよろしくお願いします。

https://www.pixeltalk.app/
【Salesforce】標準オブジェクトのSalesforce モバイルおよび Lightning Experience のアクションの挙動

# デスクトップ
Lightningレコードページの強調表示パネルを反映
ページレイアウトのSalesforce モバイルおよび Lightning Experience のアクションを無視

# モバイル
Lightningレコードページの強調表示パネルを無視
ページレイアウトのSalesforce モバイルおよび Lightning Experience のアクションを反映

# 参考リンク

[モバイルでのカスタムオブジェクトの動的アクションの使用](https://help.salesforce.com/s/articleView?id=release-notes.rn_mobile_dynamic_actions_custom_objects.htm&release=230&type=5)

カスタムオブジェクトは動的アクションで切り替えられる

手間・・・
ペイロード とは

## 勉強前イメージ

聞いたことあるけど、なにかって言われればわからん、、

## 調査

### ペイロード とは

英語ではpayloadと書く。
いろんな用語で使われますが、元々運輸の世界で運行に必要なものを除いた貨物や乗客などの積載量のことを指します。
ネットワークでは送受信されるデータの伝送の単位がありますが、その内宛先などの付加情報を除いたデータ部分のことを指します。
データのことを指すときはペイロード、データの長さをペイロード長という風に言われます。

### カプセル化について

OSI参照モデルでは各層で処理が行われると情報はヘッダとしてデータの前につけます。
それがL7ヘッダやL6ヘッダと書かれるものです。

送信時はレイヤ7からレイヤ1まで包んでいき、最終的に一つのデータのイメージで送信されます。
それを `カプセル化` と言います。

逆に受信時はレイヤ1からレイヤ7までヘッダを外していくことを `非カプセル化` と言います。

![12023-05-02名称未設定ファイル.drawio - diagrams.net - Google Chrome 20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/28d57ae0-1154-c794-f63a-27b7a49a6e21.png)


### ペイロード

カプセル化や非カプセル化が行われていく中で、コンピュータの間で送受信される最小データのことを `PDU(Protocol Data Unit)` と言います。
PDUは各層の付加情報と通信データの中身のペイロードからなります。

![22023-05-02名称未設定ファイル.drawio - diagrams.net - Google Chrome 20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/82e02d84-593a-f26b-7185-fc6315b59611.png)


## 勉強後イメージ

久々にカプセル化とかやった。
中身は全然理解できないなぁと。
ただ、各レイヤのデータのことということはわかった。

## 参考

- [OSI参照モデルをわかりやすく解説](https://www.seraku.co.jp/tectec-note/industry/osi-reference-model/)
- [ペイロード](https://www.sophia-it.com/content/%E3%83%9A%E3%82%A4%E3%83%AD%E3%83%BC%E3%83%89)
Windowsでバージョン切り替え可能なPython環境を構築する方法

# 課題
  Pythonで使いたいライブラリが最新では動作しない。
  例えばMediaPipeは3.9まで対応なので、最新の3.11だと動かない

# 解決策
  pyenv-winで切り替え可能にする。
  https://github.com/pyenv-win/pyenv-win
  
# 疑問
  業務でもバージョン合わせみんなしているのか？？
  私は職務ではPython使わないのでどう解決しているのか知らないけど
  結構制約が強いのではないか？
  
  必要なライブラリがEOLしてしまうと大量のSWが連鎖的に使えなくなってしまうのでは。

# 手順
* PowerShellがスクリプトを動かせるように、管理者権限のPowershellで
Set-ExecutionPolicy RemoteSignedを実行する。


* PowerShell に pyenv-win をインストールする。

Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"

* PowerShell を再度開く
* pyenv --versionを実行して、インストールが成功したかどうかを確認する。
* pyenv install -lpyenv-win を実行して、サポートされている Python バージョンのリストを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17098/9603a031-104f-9eca-6a48-fe6be36857b3.png)

* pyenv install <version> を実行して、サポートされているバージョンをインストールします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17098/436683bf-118c-f8a9-e814-50827c3c5adc.png)

* pyenv global <Python version> を実行して、利用するバージョンを設定する。
* 使用している Python のバージョンとそのパスを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17098/2c841f76-202a-6af3-d402-d04b52c9f730.png)


* Python が動作していることを確認する

$ pyenv version
<version> (set by \path\to\.pyenv\pyenv-win\.python-version)
$ python -c "import sys; print(sys.executable)"
\path\to\.pyenv\pyenv-win\versions\<version>\python.exe

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17098/01007144-cf7e-45d1-1175-823ac0e01671.png)
Macbookを買った時にやったこと

# 環境
- M1 Macbook
- USキーボード

# やったこと
- トラックパッドの軌跡の速さを最速にする
    - [やり方](https://suwaru.tokyo/【mac】マウス・トラックパッドカーソルを限界突/)
    - Better Touch Tool のせいでうまくいかない？
- Caps Lock -> Control
- Control -> Caps Lock
    -  Caps Lockの位置にあるControl + Spacebarで日英切り替えしたいので
-  Google日本語入力のインストール
    -  常に半角スペースを使いたいので
- ターミナルのテーマ -> iceburg
- Better Touch Toolをインストール
    - Macbookにした理由がこのアプリ・USキーボード・綺麗な液晶なので
    - 昔に買ったBetter Snap Toolのライセンスで使ってるからバージョンがめっちゃ古いけど使えてる
- Safariにad blockerを入れる
    - 最適じゃない気がするけどWipr使ってる
    - ChromeよりSafariのほうがメモリ使用量とかで優れてそう (?) だから、できるだけSafariで終わらせたい
- Launchpadを整理する
- Finderのデフォルトで開く場所をダウンロードにする
- ファイルの名前を英語にする
    - https://gist.github.com/sztwo/c91ba995525f442df702a8042741b303
    - https://qiita.com/narikei/items/60cdedf0efb616dd0bcd
- Dropboxをインストール
- Zoteroをインストール
- Clipyをインストール
    - コピペを快適にしたい
- Alfredをインストール
    - キーボードから手を離したくない
    - SpotlightのショートカットキーCommand+SpacebarをAlfredに割り当て
- すべてのアプリを終了させるアプリを作る
    - https://appleshinja.com/automator-allquit
- Dockを擬似的に完全非表示にする
    - https://qiita.com/xrxoxcxox/items/5dc3ef4eeea118a1aad2
- Google Chromeをインストール
    - [Overleafなどをアプリ化](https://qiita.com/nhancoromochi/items/50a9476ef03b46fa7d04)したいので
    - 拡張機能 uBlock Origin で広告ブロック
- Skimをインストール
    - PDFリーダーでプレビューを使いたくないので
- Amphetamineをインストール
    - スリープに入るまでの時間を簡単に制御できる。
- Hidden bar
    - 上のバーをタブっぽく整理できる
   


# ショートカットキーの覚え方
ぜんぜん覚えられないんですよね...
|コマンド|動作|覚え方|
|--|--|--|
|Ctrl + F|カーソルを右へ|Forward|
|Ctrl + B|カーソルを左へ|Back|
|Ctrl + P|カーソルを上へ|Peek|
|Ctrl + N|カーソルを下へ|Nether|
|Ctrl + A|カーソルを先頭へ|Ahead|
|Ctrl + E|カーソルを最後へ|End|
|Cmd + D|ブックマークに追加| |
|Cmd + L|検索タブに移動|Look for|
|Cmd + Shift + 4|範囲指定スクショ| |
|Cmd + Shift + 5|スクショ設定、保存場所変更とか| |
neosでlogix その128

# 概要
neosでlogixやってみる。
練習問題やってみた。

# 練習問題
websocketで、湯婆婆を実行せよ。


# 写真
![2023-05-02 05.39.09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6ab20cee-58f9-b78a-9c2c-49408c9ffd22.jpeg)

# サーバーは、これ。

https://qiita.com/ohisama@github/items/346ef48c2f631f88789f

# 手順

- websocketサーバーを起動。
- transceiverを実行する。

以上。
AWS S3にNext.js(React)から画像をアップロードする

# 画像投稿の流れ
・Next.jsからS3へ画像をアップロードする
・同時にS3からアップロードした画像のURLを取得する
・取得した画像のURLをバックエンドへ送信する
・データベースに画像URLが保存される

## はじめに
AWS SDK for JavaScriptをインストール

## S3でやること
・バケットの作成
・ブロックパブリックアクセス: 無効にする(ブロックのチェックをOFF)
・アクセス許可： Cross-Origin Resource Sharing (CORS) を編集
・公開設定：バケットポリシーを編集

## Next.jsでやること
・.envファイル作成（gitgnoneで設定すること忘れずに！）※「＊」の部分は実際の環境変数を入力する。
```
ACCESS_KEY_ID=********************
SECRET_ACCESS_KEY=***************
REGION=************
S3_BUCKET_NAME=***************
```
・next.config.jsファイルを編集
```
  // Next.jsの場合は.envをここで読み込む必要がある
  env: {
    ACCESS_KEY_ID: process.env.ACCESS_KEY_ID,
    SECRET_ACCESS_KEY: process.env.SECRET_ACCESS_KEY,
    REGION: process.env.REGION,
    S3_BUCKET_NAME: process.env.S3_BUCKET_NAME,
  }
```
・画像をアップロードするコードを書く
```typescript
// S3の設定
const s3 = new S3({
  accessKeyId: process.env.ACCESS_KEY_ID,
  secretAccessKey: process.env.SECRET_ACCESS_KEY,
  region: process.env.REGION,
});

// S3に画像をアップロードし、そのURLを取得する関数
const uploadImageToS3 = async (file: File) => {
  // アップロード時のファイル名を作成
  const fileName = `${Date.now()}-${file.name}`;
  // S3へのアップロードに必要な情報をまとめるオブジェクト
  const params: PutObjectRequest = {
    Bucket: process.env.S3_BUCKET_NAME ? process.env.S3_BUCKET_NAME : '',
    Key: fileName,
    ContentType: file.type,
    Body: file,
  };
  // Bucket: アップロード先のバケット名を環境変数から取得します。
  // Key: アップロードするファイルのキーを指定します。
  // ContentType: アップロードするファイルのMIMEタイプを指定します。
  // Body: アップロードするファイルデータを指定します。

  try {
    // S3に画像をアップロードする
    const data = await s3.upload(params).promise();
    // アップロード成功時の処理
    console.log('画像アップロード成功:', data.Location);
    // アップロードされた画像のURLを取得
    return data.Location;
  } catch (error) {
    // アップロードエラー発生時の処理
    console.error('画像アップロードエラー:', error);
    // null値を返す
    return null;
  }
};
```
クラス設計 Open Closed　〜トレードオフを考えよう〜

今回は前回のSingleResponsibilityの続きです。

https://qiita.com/F_Yoko/items/347101166fb81d301c45

# Open Closed
OpenClosdとは。「変更が発生した際に、なるべく既存のコードを修正せずにコードの追加だけで対応できるようにすべき」という考え方のこと。

つまり、「Open to adding new features & Closed to changing existing codes」ということです。

ここでいう拡張と変更は以下の意味を持ちます。

* 拡張
インタスタンス変数やメソッドの追加

* 変更
既存のインスタンス変数やメソッドの削除

# rubyではOpen Closedを完全無視している
しかしながら、rubyではOpen Closedの原則を無視しています。（むしろ推奨している？）

では、Open Closedを実現可能か？という問いに対しては以下の方法があります。

## 拡張と変更の両方に閉じる
これはシンプルで以下のように書けば拡張と変更が禁止されます。

クラスに新しいインスタンスメソッドを定義することはできません。また、既存のメソッドを上書きしたり、クラス変数を定義することもできません。
```
ClassName.freeze
```
しかし、これではOpenClosedを満たしていません。

では、OpenClosedをどのように満たせるのか？

Rubyでクラスメソッドを追加する方法は３つあります。これらによる変更にOpenClosedを適用させてみましょう。

:::note
1. モジュールをincludeしてクラスにメソッドを定義する方法
2. モジュールをprependしてクラスにメソッドを定義する方法
3. メソッドをクラスに直接定義する方法
:::

# includeとprependによる変更を禁止する
includeとprependよる変更を禁じることでOpen Closedを可能にできます。
具体的には、includeとprependメソッドをオーバーライドして、「クラスの既存のインスタンスメソッドを上書きするようなインスタンスメソッド」を持つモジュールが渡されたらraiseで例外を発生させる方法です。

```
class ImmutableModule
#モジュールが別のクラスで呼び出された時に発火
  def self.include(klass)
    raise "#{self} cannot be included in #{klass}."
  end
#モジュールが別のクラスで呼び出された時に発火
  def self.prepend(klass)
    raise "#{self} cannot be prepended to #{klass}."
  end
end

class MyClass
  include ImmutableModule
end

class AnotherClass
  prepend ImmutableModule
end
```
```
ImmutableModuleをインクルードしようとすると、例外が発生する
=> ImmutableModule cannot be included in AnotherClass.

ImmutableModuleをプリペンドしようとすると、例外が発生する
=> ImmutableModule cannot be prepended to YetAnotherClass.
```


:::note info
補足
self.includeやself.prependメソッドは、ImmutableModuleがinclude(prepend)メソッドを定義しているわけではなく、Module#include(prepend)が呼び出されたときにImmutableModule#include(prepend)メソッドが呼び出される。
:::
https://qiita.com/F_Yoko/items/4a9504ea2c0db1261aaf

# 直接定義はmethod_addedフック
クラスを直接追加されるのを防ぐ方法はrubyには存在しません。
したがって、次善策を取る必要があり、それが"method_addedフック"です。

method_addedはクラスに定義されるメソッドで、メソッドが定義されたら呼び出されます。
なので、もうすでにメソッドは書かれてしまっているんですが...

しかし、メソッドが定義された時点でエラーを返したり、既に作成したメソッドをオーバーライドするなどすれば、まるでOpenClosedにできるわけですね。

```
class ImmutableClass
  def self.method_added(name)
    raise "#{self} cannot add new methods"
  end
  
  def foo
    puts "This is a method"
  end
end

class MyClass < ImmutableClass
end
```

## method_addedの例
```
class X
    # #method_added はクラスメソッドとして定義
    def self.method_added name
        puts "== method_added =="
        puts name
    end

    def method
    end
end
```
```
== method_added ==
method
```

しかし、結論としてはrubyでOpenClosedを求め過ぎてもあまり意味がないような気がします。
必要な場合は使用を検討しても良いかもしれません。
Atcoder典型90問 003 - Longest Circular Road

# Atcoder典型90問 003 - Longest Circular Road（★4）
▶︎https://atcoder.jp/contests/typical90/tasks/typical90_c

## 問題
N 個の都市があり、それぞれの都市に 1 から N までの番号が付けられています。 
また、N−1 本の道路があり、
i 本目 (1≤i≤N−1) の道路は都市Aiと都市Biを双方向に結んでいます。 どの都市の間も、いくつかの道路を通って移動可能なものとなっています。

さて、あなたは整数 u, v (1≤u<v≤N) を自由に選び、都市 u と都市 v を双方向に結ぶ道路を 
1 本だけ新設することができます。そこで、以下で定められる値を スコア とします。

同じ道を2 度通らずにある都市から同じ都市に戻ってくる経路における、通った道の本数
 （この値はただ 1 つに定まる）

スコアとして考えられる最大の値を出力してください。

## 制約
```math
3 \leq N \leq 100000
都市同士は連結グラフをなす
```

## 試したこと & 適切な方針
* 調べつつ解けた、嬉しい
* 一筆書きなので深さ優先探索っぽいが...？
* N個の都市にN-1本の道路、全ての頂点は互いに到達可能(連結グラフ)　というかなり厳しい条件をうまく使いたい。
* これは閉路が存在しないのでは？→木構造説
    * 木構造であること(グラフ内に閉路が存在しないこと)の証明
```math
グラフの頂点集合を \mathbb{V}　、道の集合を \mathbb{E}と定める。\\
閉路の集合 \mathbb{L}と \exists L \in \mathbb{L} について、\\
閉路Lを構成している頂点の集合\mathbb{V}_{in} と \mathbb{V}_{out} = \bar{\mathbb{V}_{in}}を定める。\\
以下の操作を定義する。\\
- \\
* ∃V \in \mathbb{V}_{out} について、\mathbb{V}_{in} = \mathbb{V}_{in} \cup V と更新し、\mathbb{V}_{out} = \mathbb{V}_{out} \backslash V と更新する\\ - \\

以上の操作は、閉路LからLに所属していない頂点に辺を伸ばす操作と一致する。\\
ここで、\mathbb{V}_{in}を構成する頂点集合の要素数をkとすると、Lを構成する辺は最低でもk本存在する。\\
そのため、グラフ\mathbb{G} = {\mathbb{V}, \mathbb{E}}を連結グラフとするためにはのこり N-k-1本の\\
辺を用いて 操作(*)をN-k-1回行い、その結果として\mathbb{V}_{out}の要素であるようなN - k個の頂点を全て\\
\mathbb{V}_{in}に加える必要があるが、これは操作の性質上不可能である。よって、Gに閉路は存在しない。

```

* 以上の分析から、この問題で与えられるグラフは閉路のない連結グラフ、すなわち木構造グラフであり、その木構造に一本足してなるべく長い唯一の閉路を作れ、という問題に帰着する。
* 以上の考察を踏まえると、「辺を追加して最も長い閉路を作る」という行為は、「グラフの中で最も遠まわりのできる二点をつないでいる、一番長い"道"の始点と終点をつなぐ」行為と同一である(木構造のうち最も長い道の始点を最も高い頂点とした木構造グラフを考えれば自明である)
* 閉路がないので、ある点から別の点までに到達する道が一意に定まる。やっぱり木構造は強い性質をもってるなあという印象。
* 上は木の直径を求める操作であり、O(N)で解決する。
    * (参考)https://algo-logic.info/tree-diameter/#
* 到達距離の話になるので、やっぱり幅優先探索だとわかる。
    * (参考)https://qiita.com/takayg1/items/05d33193fbd7f2fc9256

## 解説付きコード
```py
from collections import deque

#幅優先探索の実装
def bfs(s, N, elist):
  #探索対象の点をqueueに格納していく
  queue = deque([s])

  #distはi番目の点までの距離、-1は未探索
  dist = [-1 for i in range(N)]
  dist[s] = 0

  #探索対象の点が無くなるまで実行
  while queue:
    v = queue.popleft()
    for i in elist[v]:
      　#iが未探索の場合、距離を更新し探索対象に新たに加える
      if dist[i] < 0:
        dist[i] = dist[v] + 1
        queue.append(i)
  return dist
 
N = int(input())
elist = [[] for i in range(N)]
for i in range(N-1):
  [a, b] = list(map(int, input().split()))
  a -= 1
  b -= 1
  elist[a].append(b)
  #無向グラフであることに注意
  elist[b].append(a)
 
dist = bfs(0, N, elist)
longs = dist.index(max(dist))
longestdist = max(bfs(longs, N, elist))
print(longestdist + 1)
```
【メモ】JSの分かりづらい記法のメモ

※コメント欄で指摘があったため追記しました。

## Array.from()
いずれも実行結果は同じ
```js
// ES6の構文
const arr = Array.from({ length: 10 }, (_, i) => i)
console.log(arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// スプレッド演算子の構文
const arr = [...Array(10).keys()]
console.log(arr) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// 従来の記法
const arr2 = []
for (let i = 0; i < 10; i++) {
  arr2.push(i)
}
console.log(arr2) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```
Excel VBA（マクロ）でセルの内容を声を変えて読上げ -その３-スピード、ピッチ（声の音程）、強調の指示方法

# Excel VBA（マクロ）でセルの内容を声を変えて読上げ -その３
[Excel VBA（マクロ）でセルの内容を声を変えて読上げ -その１](https://qiita.com/tom-sobue/items/aac051de117a45f9fecf)
では、Windowsに標準で組み込まれている読上げの声で、Harukaの声以外を使って読上げる方法

[Excel VBA（マクロ）でセルの内容を声を変えて読上げ -その２](https://qiita.com/tom-sobue/items/319c1943df9dd30c081a)
では、読上げ内容を音声ファイルに保存する方法

について、紹介しました。
今回は、軽く「その１」で紹介しました、スピード、ピッチ（声の音程）、更には、強調の指示を記述します。

## __スピード、ピッチ（声の音程）、強調の指示__
__（１）スピード指示には、２つの記述方法と２つの使い方があります。__
##### 1- SpVoiceのRate指示
~~~~
    sapi = CreateObject("SAPI.SpVoice")
    sapi.Rate = 5
    sapi.Speak ActiveCell
~~~~
これで、スピードが+5 されます。

##### 2- XMLタグを付けて指示（その１で紹介した方法）
~~~~
    sapi = CreateObject("SAPI.SpVoice")
    sapi.Speak "<Rate speed=5>" & ActiveCell & "</Rate>"
~~~~
同じように、スピードが+5 されます。
この書式は、W3Cという団体の規格に準じたものです。

##### 3- 以後のスピードを設定してしまう
上記の2-は、"\<Rate speed=""> \</Rate>"で挟まれた内容にだけ有効です。
1-と同じように切り替える指示もあります。
~~~~
    sapi = CreateObject("SAPI.SpVoice")
    sapi.Speak "<Rate speed=5/>" & ActiveCell
~~~~
以降のスピードは+5 に設定されます。
（「/」の位置です。）

__（２）ピッチ（声の音程）は、１種類__
~~~~
    sapi = CreateObject("SAPI.SpVoice")
    sapi.Speak "<Pitch middle=-4>" & ActiveCell & "</Pitch>"
~~~~
4ポイント低い音程の声になります。

**なぜ、middleなのか？*
*W3C規格では、声を５つに分けて設定できるようになっています。*
*ExtraHigh，High, Middle, Low, ExtraLowが規定されていますが、この中のMiddleだけをSpeech APIは使います。*

__（３）強調__
語気を強めるということです。
~~~~
    sapi = CreateObject("SAPI.SpVoice")
    sapi.Speak "<Emph>" & ActiveCell & "</Emph>"
~~~~
Windowsに組み込まれている声での、語気強調はあまり強くありません。

[その４ -シートに書いた内容で読上げする事例- へ続く](https://qiita.com/tom-sobue/items/e51cbdec59af545b232a)
アプリケーションサーバ

# アプリケーションサーバとは
アプリケーションサーバは， Webサーバから受けたリクエストをもとに，動的なコンテンツを生成するアプリケーション(プログラム)を実行するソフトウェアもしくはサーバコンピュータのこと．Web三層構造を構成するサーバの一つで．Webサーバとデータベースサーバの中間に位置する．

# アプリケーションサーバの機能
アプリケーションサーバは，主に３つの機能がある．

### １．コネクト機能
プログラムからデータベースに接続してデータの読書きを行う機能を**コネクト機能**と言います。事前にコネクション接続（データベース接続）を行う事で、接続を毎回行うのではなく、既存の接続を再利用して処理速度を向上させることができる。

### ２．トランザクション機能
データベースを管理する場合は何らかのエラーが発生したり、同時にアクセスするでも、整合性を保ち，不具合が起きないように制御するのが**トランザクション機能**です。
プログラム側で制御すると処理に時間がかかりますが、APサーバのトランザクション機能を利用することで、この処理をサーバー側に任せることができます。

### ３．ビジネスロジックの実行
ビジネスロジックは，アプリケーションシステムにおける**コア**となる処理を行う部分であり，アプリケーションソフトはこれを実行する機能を持つ．例えばデータベースから取り出したデータの計算はAPサーバで行う．

# Webサーバとの違い
WebサーバとAPサーバの違いはそれぞれの役割である．

||担当する位置|役割|
|:--:|:--:|:--:|
| Webサーバ | フロントエンド |ユーザと直接やり取りを行う|
| APサーバ | バックエンド |プログラムとしての処理を行う|

Webサーバがリクエストを受け付け、APサーバが処理を行い、Webサーバがレスポンスを返すという流れとなる。イメージとしては，Webサーバは受付で，APサーバは実際の作業場という関係となる．
![AP server image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/25f884fd-dcdf-e173-76cf-de0535fd5a35.png)

# アプリケーションサーバの種類
Webサーバは動作するOSやシステムの内容で適切なものを選ぶ必要がある．一方，APサーバは<INS>基本的に開発するプログラミング言語で選ばれる</INS>．ここでは代表的なJavaとRubyで使用されるものをあげる．

**○Apache Tomcat**
オープンソースで開発された，Javaで開発されたWebアプリケーションで使用されるアプリケーションサーバ．略して“Tomcat”と呼ばれる．
**○Unicorn**
Ruby on Railsなどで開発されたRuby言語のWebアプリケーションで使用されるアプリケーションサーバ．WebサーバのNginxやApacheなどと組み合わせて使用することができる．
include/prepend/extendの違い

Ruby では、以下の3つの方法でクラスにモジュールを取り込むことができます。

| メソッド | 説明 |
|:-:|:-:|
|include  |*モジュールのメソッドをクラスのインスタンスメソッドとして定義する<br>*既に同名のインスタンスメソッドがある場合、そのメソッドを上書き|
|prepend|*モジュールをクラスの継承チェーンの先頭に挿入し、挿入されたモジュールのメソッドがクラスのインスタンスメソッドとして定義される<br>*同名のインスタンスメソッドがある場合、クラスのインスタンスメソッドよりも優先してモジュールのメソッドが呼ばれる|
|extend   |*モジュールに定義されたメソッドをクラスメソッドとして使用可能   |

# include
include は、指定されたモジュールをクラス内にミックスインするためのメソッドです。ミックスインすることで、クラス内でそのモジュールに定義されたインスタンスメソッドを使用できるようになります。include によって取り込まれたモジュールのメソッドは、クラスのインスタンスメソッドとして定義されます。

```
module MyModule
  def my_method
    puts "Hello, world!"
  end
end

class MyClass
  include MyModule
end

obj = MyClass.new
obj.my_method #=> "Hello, world!"
```

# prepend
prepend は、指定されたモジュールをクラス内に先頭に挿入するためのメソッドです。prepend によって取り込まれたモジュールのメソッドは、クラスのインスタンスメソッドとして定義されます。ただし、同名のインスタンスメソッドが既に定義されている場合は、モジュールによる上書きが行われます。prepend によって挿入されたモジュールのメソッドは、クラスのインスタンスメソッドとして定義されます。

```
module MyModule
  def my_method
    puts "Hello, world!"
  end
end

class MyClass
  prepend MyModule
  def my_method
    puts "Goodbye, world!"
  end
end

obj = MyClass.new
obj.my_method #=> "Goodbye, world!"
```

# extend
extend は、指定されたモジュールをクラスに特異メソッドとして追加するためのメソッドです。モジュールに定義されたメソッドは、クラスのインスタンスメソッドとしてではなく、クラスメソッドとして使用できるようになります。

```
module MyModule
  def my_method
    puts "Hello, world!"
  end
end

class MyClass
  extend MyModule
end

MyClass.my_method #=> "Hello, world!"
```

以上が、include、prepend、extend の違いと用途です。適切に使い分けることで、コードの柔軟性と可読性を高めることができます。
SSH接続のやり方(簡単に備忘録)

## SSH接続とは(簡単に)
異なるホストに遠隔で接続する事。  
例)  
パソコンA から パソコンＢ に接続する。  
接続すると、パソコンＢに新規ファイルを作ったり、削除したり、色々な操作ができる。

## 簡単なSSH接続の仕組み(方法)
ssh keyという鍵とIPアドレスを使用して接続する。 
ssh keyには、秘密鍵と公開鍵が存在している。  
秘密鍵と公開鍵はペアとなっており、お互いを認識できる。  

ssh接続のやり方としては、  
接続元で秘密鍵と公開鍵を作成して、接続先の /home/ユーザ/.ssh/authorized_keys ファイルに公開鍵の中身をコピーする。  
※authorized_keys に書かれた公開鍵とペアになっている秘密鍵を持ったパソコン(ホスト)は接続してくることを許可するようになる。  
あとは接続元から秘密鍵と接続先のIPアドレスを使用して接続する。  

## 具体的な接続方法  
例)パソコンAからパソコンBに接続して、パソコンBに新規ファイルを作成する。  
接続元：パソコンA  
接続先：パソコンB  

### パソコンAに秘密鍵と公開鍵を作成する。
```ubuntu
~# ssh-keygen
```
上記コマンドで **.ssh** フォルダに **id_rsa** **id_rsa.pub** が作成される。  
秘密鍵：id_rsa  
公開鍵：id_rsa.pub (.pubはpublicの略)  

コマンドを実行すると、  

鍵が作成されるパス  

既に同じファイル名で鍵がある場合は上書の可否  
※ファイル名を指定して鍵を作成するオプションもあるので、必要なら調べて下さい。  

設定するパスワード(2回聞かれるので、同じパスワードを入力)  
※パスワードは空白でもOK  

が聞かれますので、必要に応じて入力してください。

```ubuntu
~#  ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hogehoge/.ssh/id_rsa): // 鍵が作成されるパス
/home/hogehoge/.ssh/id_rsa already exists.
Overwrite (y/n)? y // 既に一度作成しているため、上書きの可否が聞かれる。ここではyesを選択。
Enter passphrase (empty for no passphrase): // パスワード1回目 ※パスワードは入力しても表示されませんが、しっかり入力されています。
Enter same passphrase again: // パスワード2回目
Your identification has been saved in /home/hogehoge/.ssh/id_rsa.
Your public key has been saved in /home/hogehoge/.ssh/id_rsa.pub.
~
```
エラーが出なければ鍵が作成されます。  

## パソコンB(接続先)の OpenSSH を起動する
ubuntu18(私の環境)の場合  
```ubuntu
~# service ssh start
```
上記コマンドで ssh(sshd)サービスが起動する。 
※環境によっては service ではなく systemctl とかの場合があるので、自信の環境に合わせてください。   
もしかしたら、OpenSSHサービスがインストールされていない場合があるのでその場合はまずインストール  
```ubuntu
~# sudo apt install openssh-server
```
上記でインストールできる。  
このコマンドも自身の環境に合わせてください。  

## パソコンB(接続先)でSSH接続用のユーザ作成(既に作成済みのユーザに接続する場合はこの工程は省略可)
```ubuntu
~# sudo su
```
rootユーザに変更する。  
```ubuntu 
~# adduser -m {ユーザ名}
```
これでユーザ作成可能。  
-m オプションをつけることで、ユーザのホームディレクトリが作成されるため、つけて置く方が良い。 
追記：ubuntu22.04では **-m**オプションがなくなり、オプション無しでもユーザディレクトリが作成される。 
```ubuntu
passwd {ユーザ名}
```
ユーザにパスワードを設定。  
特に理由が無い場合はパスワードを設定しておく方が、セキュリティ的に良い。  

## パソコンA(接続元)で作成した公開鍵の内容をパソコンB(接続先)にコピー
接続するパソコンBのユーザの home/ユーザ/.ssh/authorized_keys に公開鍵をコピーする。  
パソコンA，B両方触れて、コピペで移せるならそれでも大丈夫。  
もし無理なら、下記コマンドでも可能
```ubuntu
 ~# ssh-copy-id パソコンBのユーザ名@パソコンBのIPアドレス
 ```
 IPアドレスの調べかた。  
 ```ubuntu
 ~# ip a
 ```
 ssh-copy-id コマンドは 接続先のsshd_config でパスワード接続が可能になっていないとダメ。  
/etc/ssh/sshd_config  
```ubuntu
PasswordAuthentication yes
```
これがNOだとできない。  
NOの場合は *vim sshd_config* 等で編集してください。

## ssh接続
```ubuntu
~# ssh 接続先のユーザ名@接続先IPアドレス
```
これで接続可能。
ネットワークについて（MACアドレス、IPアドレス等）

下記の応用情報講座で学習したことをアウトプットしたいと思います。

https://www.udemy.com/course/ouyou_joho/

## OSI基本参照モデル
コンピュータ同士が通信するための方式を層別にモデル化したもの。
アプセトネデブでおなじみ。
プレゼンテーション層とセッション層については、
アプリケーション層でやることが吸収されているため
ほぼ使われていないらしい。

レイヤー（層）を分けるメリット
→担当分けがしやすい。
　トランスポート層に関わるエンジニアであれば、データリンク層や物理層に関する知識が
　ほとんどなくても大丈夫。
　プログラマーなら、アプリケーション層より下はあまり意識したことがないはず。
　レイヤーを分けることで仕事がしやすくなる。

参考文献：
https://www.foresight.jp/fe/column/osi-reference-model/
https://www.itmanage.co.jp/column/osi-reference-model/

## プロトコル
コンピュータの機器同士で通信をするために取り決められた約束事（ルール）。
> 約束ごとは「コンピュータ間でどのようにデータを送るのか、どれだけのデータを送るのか」
コンピュータ間をただLANケーブルなどで物理的に接続しただけでは、相互に通信することができませんが
　このプロトコル（具体的にはIPやTCP等）を使用することで、コンピュータとコンピュータが通信できます。
https://www.infraexpert.com/study/networking2.html

## スイッチングハブ
同一ネットワーク内の機器を繋ぐ役割を持ったネットワーク機器。
>スイッチングハブは、複数のコンピュータをネットワーク接続する際に使用するネットワーク機器で、単にスイッチと呼ばれたり、L2スイッチと呼ばれたりもします。
スイッチングハブには、ネットワークケーブルを刺すための穴（ポート）が複数備わっていて、各ポートとコンピュータとをネットワークケーブルで接続すると、スイッチングハブを介して、全てのコンピュータがネットワーク接続される仕組みになっています。
http://www.words-search.com/it/276


## MACアドレス
ネットワーク機器に、工場出荷時に付与される全世界で重複しないアドレス。
48ビットのアドレスで構成されている。
上位24ビットがOUC（ベンダーコード）、下位24ビットが製品番号。
16進数で表す。
アドレスと名称が付いているが、「機械番号」と考えた方がわかりやすいらしい。
MACアドレスはレイヤー2に当たる。

## ルーター
異なるネットワーク同士の中継機。
スイッチングハブは同一のネットワーク内でのやりとりをすることができるが、
そのネットワークを超えて通信したい場合は、ルーターが必要となる。

## IPアドレス
端末に振られたアドレス。
32ビットのアドレスで構成されている。
10進数で表す。
IPアドレスはレイヤー3に当たる。

## ARP
MACアドレスからIPアドレスを得るためのプロトコル

## ARPテーブル
>ARPテーブルとは、ARP（Address Resolution Protocol）によって割り出したIPアドレスとMACアドレス（EthernetやWi-Fiなどの物理アドレス）の対応表。

https://e-words.jp/w/ARP%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB.html#:~:text=ARP%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%A8%E3%81%AF%E3%80%81ARP,%E7%89%A9%E7%90%86%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%EF%BC%89%E3%81%AE%E5%AF%BE%E5%BF%9C%E8%A1%A8%E3%80%82
neosでlogix その127

# 概要
neosでlogixやってみる。
練習問題やってみた。

# 練習問題
neos uiを使って、websocketで、オウム返しを取得するオブジェクトを作成せよ。
host は、localhost
port は、50002

# 写真

![2023-05-01 23.55.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/00eccbb5-567a-1b15-9a0f-07258033de9b.jpeg)


![2023-05-02 00.05.25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c4517229-7c92-0e83-d7ae-0e78883c6cb5.jpeg)

# 手順
- 空のオブジェクトの下に、buttonとtext fieldとbuttonとharu.txtを置く。
- それぞれのインターフェースを取り出す
- button eventsを２個、配置
- websoket connectを配置
- WebsocketTextMessageSenderを配置
- WebsocketTextMessageReceiverを配置
- writeを配置
- つなぐ

# 成果物

- 共有フォルダに置きました。
transceiver 
neosrec:///U-ohisama/R-0ee1ec21-db19-425b-ba63-9a699caff48e

以上。
google formの回答をslackに送信して行う鍵の管理【実装編】

# はじめに
鍵の管理をgoogle formとslackを使って簡単にできるようにしました。コードをコピペして簡単に実装できます。
デモは以下のリンクから見てください。

https://qiita.com/keigo1110/items/e78754686bb99d94f0b1

# 構想
研究室で鍵の状態を学生間で共有するためにslackを活用することになりました。しかし、毎回slackに時間と借りた部屋の鍵を入力するのが面倒でした。
![Screenshot 2023-05-02 at 13.18.21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346908/36b73111-9c99-b776-5144-ab9dd4acde2c.jpeg)
個人情報のため一部伏せていますがこんな状態です。

送信すべき情報は、
```
・誰なのか
・手続きを行った時刻
・該当する部屋の番号
・鍵の状態
```
と決まっていたため、これらを取得して送信できるようにgoogle formを利用しました。
google formであれば、ボタンで選択することができるため、入力するより簡単に送信できます。

google formからslackへの送信するのはGoogle Apps Scriptを利用しました。

# 準備
まずgoogle formからslackへメッセージ送信できるようにします。
以下のサイトを参考に準備しました。

https://goworkship.com/magazine/slack-usage-3/

# コード
以下のコードは先程の準備が完了していたら、コピペして使えます。
```
・回答者のメールアドレス
・回答した時間
・フォームの内容
```
これらが送信されるようになっています。


```javascript
function onFormSubmit(event) {
  // Googleフォームの回答者のメールアドレスを取得
  var message = "<!everyone> " + event.response.getRespondentEmail() + "\n";
  
  // 回答のタイムスタンプを取得して、Slackに送信するメッセージに追加する
  var timestamp = event.response.getTimestamp();
  var date = new Date(timestamp);
  var formattedDate = Utilities.formatDate(date, "JST", "yyyy/MM/dd HH:mm:ss" + "\n");
  message += "時間: " + formattedDate;

  // 回答の内容を取得して、Slackに送信するメッセージに追加する
  var items = event.response.getItemResponses();
  for (var i = 0; i < items.length; i++) {
    message += items[i].getItem().getTitle() + ": " + items[i].getResponse() + "\n";
  }

  // SlackのWebhook URLにPOSTリクエストを送信する
  UrlFetchApp.fetch(
    "webhookのURLを記入", // Webhook URLを入れる
    {
      "method" : "POST",
      "contentType" : "application/json",
      "payload" : JSON.stringify({"text": message})
    }
  );
}
```

webhookのURLだけは自分のものに置き換えてください。


# おわりに
Google Apps Scriptで簡単にgoogle formとslackを接続して行うことができました。ぜひ活用してみてください。
google formの回答をslackに送信して行う鍵の管理【デモ】

# はじめに
鍵の管理をgoogle formとslackを使って簡単にできるようにしました。

# デモ
google formに「借りる鍵の部屋番号」と「状態」を選択します。
![Screenshot 2023-05-02 at 12.55.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346908/cbb51639-59f2-b8cd-e7b7-4a94e43fec1c.png)

これを送信するとslackに、
![Screenshot 2023-05-02 at 12.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346908/90bc8be5-bc2f-377d-37b9-034fe0293b86.png)

上記のように送信されます。


これは、
```
・誰か（メールアドレス）
・時間
・該当の部屋番号
・鍵の状態
```
と必要な情報が送信されるようになっています。

# おわりに
google formの回答をもとにslackへ送信するというのは様々な場面で応用が効きそうです。

実装はこちらです↓

https://qiita.com/keigo1110/items/d350408a62fc6674cf12
RubyでAtCoder ABC270(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC270のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - 1-2-4 Test
https://atcoder.jp/contests/abc270/tasks/abc270_a
```ruby:a-270.rb
a, b = gets.split.map(&:to_i)
puts a | b
```
## 解説
どちらか一方が解いていればいいので、bit演算子のORを使うことで実装することができます。

# B - Hammer
https://atcoder.jp/contests/abc270/tasks/abc270_b
```ruby:b-270.rb
x, y, z = gets.split.map(&:to_i)
x, y, z = -x, -y, -z if y < 0
if x < y
  puts x.abs
else
  if y < z
    puts -1
  else
    puts z.abs + (x - z).abs
  end
end
```
## 解説
（公式解説を参考にしました）

yを正に揃えることで、場合分けの数を減らしています。

# C - Simple path
https://atcoder.jp/contests/abc270/tasks/abc270_c
```ruby:c-270.rb
n, x, y = gets.split.map(&:to_i)
array = Array.new(n + 1) { [] }
(n - 1).times do
  u, v = gets.split.map(&:to_i)
  array[u] << v
  array[v] << u
end

searched = Array.new(n + 1, false)
searched[x] = true
stack = [x]

parent = Array.new(n + 1, 0)

while node = stack.pop
  array[node].each do |i|
    next if searched[i]
    searched[i] = true
    stack << i
    parent[i] = node
  end
end

ans = [y]
while ans[-1] != x
  ans << parent[ans[-1]]
end
puts ans.reverse.join(" ")
```
## 解説
DFSで深さ優先探索しています。最後にyを親、xを子としてyからxに辿り着けるまでans配列に要素を格納していきます。

# 終わりに
B問題は自力で解いたのだと
```ruby
x, y, z = gets.split.map(&:to_i)
if x == 0
  p 0
elsif x > 0
  if x < y || y < 0
    p x
  else
    if y < z
      p -1
    else
      if z < 0
        p 2 * z.abs + x
      else
        p x
      end
    end
  end
else
  if x > y || y > 0
    p x.abs
  else
    if z < y
      p -1
    else
      if z > 0
        p 2 * z.abs + x.abs
      else
        p x.abs
      end
    end
  end
end
```
こんな感じですごく長くなってしまいました。yを正に揃えるいうことを思いつけなかったのが悔しいです...

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
クラス設計 SingleResponsibility　〜トレードオフを考えよう〜

# クラス設計
独自クラスをどのように設計し、どんな構造にするかは、コードのわかりやすさとメンテナンス性に多大な影響を及ぼします。

独自クラスを定義する前に「本当に独自クラスを定義する必要があるだろうか？」や「どれくらい広く使われるだろうか？」と問うことが大切です。


# 独自クラスの利点
* 状態のカプセル化
オブジェクト指向プログラミングの原則の1つであり、オブジェクトの内部状態を外部からアクセスできないように保護することです。要は、あるクラスに定義したメソッドは他のクラスから呼び出すことができないので、独立性を高めて、保守性が高まる訳です。

* クラスのインスタンスに関連づけられた関数（メソッド）を呼び出すためのシンプルな方法を提供
独自クラスを定義することで、そのクラスのインスタンスに関連づけられた関数（メソッド）を呼び出すことができます。これにより、プログラムの機能を分割して管理し、再利用可能なコードを作成することができます。

# SOLID原則のトレードオフ
SOLID原則とは、オブジェクト指向設計の5つの原則のそれぞれの頭文字を取ったもの。
| SOLID | 説明 |
|:-:|:-:|
|S (Single Responsibility)　単一責任の原則   |クラスは、単一の責任を持つべきだ。   |
|O (Open-Closed)　オープン・クローズドの原則   |クラスは、拡張にはオープンで、変更にはクローズドであるべきだ。   |
|L (Liskov Substitution)　リスコフの置換原則   |SがTのサブタイプである場合、プログラム内のT型のオブジェクトをS型のオブジェクトに置き換えても、そのプログラムの特性は何も変わらない。   |
|I (Interface Segregation)　インターフェイス分離の原則   |クライアントが使用しないメソッドへの依存を、強制すべきではない。   |
|D (Dependency Inversion)　依存性逆転の原則   |・上位モジュールは、下位モジュールに依存してはならない。どちらも抽象化に依存すべきだ。<br>・抽象化は詳細に依存してはならない。詳細が抽象化に依存すべきだ。   |

https://qiita.com/baby-degu/items/d058a62f145235a0f007

これらの原則は大切ですが、必ずしも盲目的に従えば良いというわけではありません。
それぞれの原則が自分の構築しようとしているアプリケーションやライブラリにとって適切なトレードオフになっているかを考える必要があります。

今回はSinglePossibilityのトレードオフについて見ていきます。

# Single Possibility
「クラスは基本的には１つの目的を果たすべきである。」
これは当然ですね。というより、普通に書いていたらこうなるような気がします。

問題は、既存の単一のクラスを複数のクラスに分割するときです。
クラスに色々と定義していると、「これは別のクラスに切り分けた方が良さそうだな」と思う時があると思います。

例えば、以下のようにEmployeeクラスがある場合、もちろん動作はします。
しかし、以下のような問題が挙げられると思います。

・コードの再利用性が低くなる
・テストが複雑になる
・クラスの機能が複雑になる
```
class Employee
  def initialize(name, title, salary)
    @name = name
    @title = title
    @salary = salary
  end

  def promote(new_title)
    @title = new_title
  end

  def raise_salary(new_salary)
    @salary = new_salary
  end

  def to_s
    "#{@name} is a #{@title} earning #{@salary} dollars per year."
  end
end
```

したがって、以下のようにクラスを分割するとコードを再利用できたり、何をするためのクラスなのかが明示的になります。
```
# 従業員の詳細情報を持つクラス
class EmployeeProfile
  def initialize(name, title, salary)
    @name = name
    @title = title
    @salary = salary
  end

  def to_s
    "#{@name} is a #{@title} earning #{@salary} dollars per year."
  end
end

# 従業員のアクションを扱うクラス
class EmployeeActions
  def initialize(employee)
    @employee = employee
  end

  def promote(new_title)
    @employee.title = new_title
  end

  def raise_salary(new_salary)
    @employee.salary = new_salary
  end
end

# 従業員を表すクラス
class Employee
  attr_accessor :title, :salary

  def initialize(name, title, salary)
    @profile = EmployeeProfile.new(name, title, salary)
    @actions = EmployeeActions.new(self)
  end

  def to_s
    @profile.to_s
  end

  def promote(new_title)
    @actions.promote(new_title)
  end

  def raise_salary(new_salary)
    @actions.raise_salary(new_salary)
  end
end
```

ただし、この分割を思考停止してやれば良いわけではありません。

「新しく分割したクラスには、アプリケーションやライブラリで他にも使い所があるだろうか？」を問うことが大切で、それがイエスならば分割してもよさそうです。なぜならば、それを他でも再利用できるからです。

もし、そうでないならば分割はしない方が良い可能性が高いということです。

つまり、クラスが１つの目的を果たすことは重要なのですが、何でもかんでも分割していては逆に複雑さを生みかねないということです。

__「複雑性とクラス分割のメリットはトレードオフになるため、どちらを取るか考慮した上でクラス分割しよう」__ ということですね。
クリーンアーキテクチャ（Presenter、Container）

## Presenter:
  Presenterは、UI層の中のコンポーネントで、アプリケーションのビジネスロジックとUIをつなぐ役割を担います。
一般的に、Presenterは以下のような責任を持ちます。

- ビジネスロジックから取得したデータをUIに適した形式に変換します。
- ビジネスロジックからのデータ変更やエラーをUIに通知します。
- UIからの入力やイベントをビジネスロジックに渡します。

Presenterは、UIの表示や操作を直接制御せず、ビジネスロジックとUIの間の橋渡し役として機能します。これにより、UIとビジネスロジックの依存関係が低くなり、再利用性やテスト性が向上します。

## Container:
  Containerは、UIコンポーネントを管理・構成する役割を担います。通常、Containerは以下のような責任を持ちます。
- UIコンポーネントのインスタンス化や配置を行います。
- UIコンポーネント間のデータの受け渡しやイベントの伝播を管理します。
- アプリケーションの状態管理やデータストアへのアクセスを行います。

Containerは、UIの構造やデータの管理に重点を置き、UIコンポーネントを組み合わせてアプリケーションのUI全体を構築します。また、ContainerはUIの表示ロジックやスタイルに関与せず、UIコンポーネントの管理やデータの流れに集中します。

PresenterとContainerは、アプリケーションのUI層を責任の分割によって整理・構造化し、コードの再利用性や保守性を向上させる役割を果たします。


本記事の内容を学習されている方の力になれたらとおもい投稿しました。
記事の内容に間違いがあれば是非ともご指摘いただきたいです。
ChatGPTでアドバイスをもらう場合に入力したい専門家たち

皆さんもChatGPTを色々活用していると思います。
同じようなニュアンスを質問しても全然違う回答が返ってきたり
そもそも期待した回答がこない場合がありますよね。

そこで、分野ごとで良さそうな意見をもらえる専門家をまとめてみました。

# ChatGPTでの入力例
現在、以下の問題があります。
**[ここにシチュエーションを入力]**
これらの問題にもとづいて **[ここにアドバイスをもらいたい人物]** は何をするように勧めますか？


## 全般
1. スティーブ・ジョブズ
2. ジェフ・ベゾス
3. ビル・ゲイツ

## javascript
1. Douglas Crockford - JavaScriptの生みの親
2. Kyle Simpson - 「You Don't Know JS」シリーズの著者
3. Eric Elliott - JavaScriptのエキスパート
4. Addy Osmani - Googleのエンジニア

## SQL
1. Michael Widenius - MySQLの創始者
2. Joe Celko - SQLの専門家
3. Craig Mullins - データベース管理

## セキュリティ
1. Bruce Schneier：セキュリティ技術者
2. Troy Hunt：セキュリティ専門家
3. Kevin Mitnick：セキュリティコンサルタント

## アルゴリズム、オブジェクト指向
1. Robert C. Martin - アルゴリズムやMVCフレームワークの専門家
2. Martin Fowler - ソフトウェア開発の分野で著名な専門家
3. Grady Booch - ソフトウェア開発における設計方法論の専門家

## 業務改善
1. Dr. Michael Hammer - ビジネスプロセス再設計の専門家
2. Dr. W. Edwards Deming - 品質管理と業務改善の専門家

## 新人教育
1. Paul J. Meyer - パーソナル開発、自己啓発、マネジメントトレーニング、リーダーシップの分野で専門家
2. Steve McConnell - ソフトウェア開発
3. Robert L. Glass - ソフトウェア工学
4. Johanna Rothman - ソフトウェア開発プロセスの専門家
5. Jeffrey Zeldman - Webデザインのパイオニア
6. Karen McGrane - Webデザインの基礎から応用までを網羅した書籍の著者
7. Luke Wroblewski - ユーザビリティやモバイルデザインの専門家

## コミュニケーション
1. Dr. Judith E. Glaser - コミュニケーションとリーダーシップの専門家
2. Dr. Marshall Goldsmith - リーダーシップ開発とコミュニケーションの専門家
3. Dr. Adam Grant - コミュニケーションとチームダイナミクスの専門家

## サービス企画
1. Joseph Pine - Strategic Horizons LLP
2. Clotaire Rapaille - Archetype Discoveries Worldwide
3. Martin Lindstrom - Lindstrom Company

## マーケティング
1. Philip Kotler - Kotler Marketing Group
2. Gary Vaynerchuk - VaynerMedia
3. Jay Baer - Convince & Convert

## SEO
1. Neil Patel - Neil Patel Digital
2. Brian Dean - Backlinko
3. Rand Fishkin - SparkToro
SOLID原則

設計原則の集合でオブジェクト指向プログラミングとソフトウェア設計において、より柔軟で、メンテナンスしやすく、理解しやすいコードを書くための5つの基本原則です。

以下の原則は複数重なることが多くあります。
一つの原則が守れたとしても他の原則違反を犯すことはありますので注意してください。

## 単一責任原則 (Single Responsibility Principle, SRP)
この原則は、クラスは1つの責任を持つべきで、それに変更がある場合はその責任にのみ関連する変更であるべきだと主張します。つまり、1つのクラスには1つの役割だけを持たせることで、コードの可読性や再利用性が向上します。
## オープン・クローズド原則 (Open/Closed Principle, OCP)
この原則は、ソフトウェアの構成要素（クラス、モジュール、関数など）は、拡張に対して開いていて（新しい機能を追加しやすく）、既存のコードの修正に対して閉じているべきだと主張します。これは、新しい機能を追加する際に既存のコードを変更することなく、拡張できるように設計することを意味します。(※ 既存のコードを変更せずに新しい機能を追加できるようにすること)
## リスコフの置換原則 (Liskov Substitution Principle, LSP)
この原則は、派生クラス（サブクラス）は、その基底クラス（スーパークラス）と置換可能であるべきだと主張します。つまり、サブクラスは、スーパークラスの振る舞いを変更せずに、その代わりに使用できるようになるべきです。これにより、コードの再利用性と維持性が向上します。
## インターフェース分離原則 (Interface Segregation Principle, ISP)
この原則は、クラスが必要としないインターフェースに依存しないように、インターフェースを小さく、特定の目的に特化させるべきだと主張します。つまり、多くの機能を持つ大きなインターフェースよりも、特定の機能に焦点を当てた小さなインターフェースが望ましいということです。
## 依存関係逆転の原則 (Dependency Inversion Principle, DIP)
この原則は、高レベルのモジュールは低レベルのモジュールに直接依存すべきではなく、両方のモジュールは抽象に依存すべきだと主張します。また、抽象は詳細に依存すべきではなく、詳細が抽象に依存すべきだとも言われています。これにより、コードの再利用性や疎結合性が向上し、変更やテストが容易になります。

```ts
interface Database {
  getData(): string[];
}

class MySQLDatabase implements Database {
  getData(): string[] {
    return ["MySQLデータ1", "MySQLデータ2"];
  }
}

class MongoDBDatabase implements Database {
  getData(): string[] {
    return ["MongoDBデータ1", "MongoDBデータ2"];
  }
}

// Databaseインターフェースに依存
class DataProcessor {
  constructor(private database: Database) {}

  processData(): void {
    const data = this.database.getData();
    // データの加工や表示などの処理を行う
    console.log("Processed data:", data);
  }
}

const mySQLDatabase = new MySQLDatabase();
const dataProcessor1 = new DataProcessor(mySQLDatabase);
dataProcessor1.processData(); // 出力: Processed data: [ 'MySQLデータ1', 'MySQLデータ2' ]

const mongoDBDatabase = new MongoDBDatabase();
const dataProcessor2 = new DataProcessor(mongoDBDatabase);
dataProcessor2.processData(); // 出力: Processed data: [ 'MongoDBデータ1', 'MongoDBデータ2' ]
```

本記事の内容を学習されている方の力になれたらとおもい投稿しました。
記事の内容に間違いがあれば是非ともご指摘いただきたいです。
高凝集、低結合、関心の分離

メモとして残そうと思いました。
基本的なことでもあると思い、私と同じくこのようなことを調べられている方の力になれたら幸いです。

## 高凝集
ある集合内の要素同士が密接に関連していることを指します。
例えば、あるプログラムのクラス内にあるメソッドや変数同士が密接に関連している場合、そのクラスは高凝集であると言えます。
反対に、あるクラス内のメソッドや変数同士が関連性が薄い場合、そのクラスは低凝集であると言えます。
## 低結合
システム内のある機能やクラスが、他の機能やクラスに依存しすぎず、独立していることを指します。つまり、ある機能が変更された場合に、その変更が他の機能に影響を与えることが少ないことを意味します。低結合のシステムは、変更に強く、保守性が高いとされています。

## 関心の分離
ソフトウェア設計の原則の1つで、コードの可読性や保守性が向上し、変更に強いコードを作成することができます。

関心の分離には、以下のようなに分けられます。

- 役割の分離: クラスやモジュールを、それぞれの役割に基づいて分割することができます。例えば、MVC (Model-View-Controller) パターンでは、モデル、ビュー、コントローラーという3つの役割に分割されます。
- レイヤーの分離: クライアントサイドとサーバーサイドのように、複数のレイヤーに分割することができます。レイヤーの分離により、コードの再利用性や拡張性が向上します。
- 機能の分離: 機能ごとにモジュールを分割することができます。これにより、コードの再利用性やテストの容易性が向上します。

関心の分離は、ソフトウェア設計の基本的な原則の1つであり、コードの品質を向上させるために重要な考え方です。
備忘録　navigation2 シミュレーションの環境構築

## 環境
　ROS 2
  　Ubuntu 22.0.4

## これ通り
https://qiita.com/sfc_nakanishi_lab/items/028edb3a7d5ed0300e33

## 自分の場合
ROS 2 Humble、navigation2を環境構築済みのため、実行方法を以下の通りに変更

```
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/opt/ros/humble/share/turtlebot3_gazebo/models
```
```
export TURTLEBOT3_MODEL=waffle
```

```
ros2 launch nav2_bringup bringup_launch.py use_sim_time:=True map:=/opt/ros/humble/share/nav2_bringup/maps/turtlebot3_world.yaml default_bt_xml_filename:=$HOME/ubuntu/btdata/sample.xml
```

```
ros2 run nav2_test_utils clicked_point_to_pose
```

```
ros2 run rviz2 rviz2 -d $(ros2 pkg prefix nav2_bringup)/share/nav2_bringup/rviz/nav2_default_view.rviz
```

## 今後webアプリから動かせるように
ROS Bridgeのインストール
```
sudo apt-get install ros-<distro>-rosbridge-server
```
<distro>部は自分のROS ディストリビューションに合わせる
(例)
```
sudo apt-get install ros-humble-rosbridge-server
```

ROS Brigdgeの実行
```
ros2 launch rosbridge_server rosbridge_websocket_launch.xml
```

webブラウザから以下にアクセス
http://localhost:9090
Java8 StreamAPI 多階層の末端の値で絞り込み

Streamは何でもできるような錯覚に陥りどハマりしてしまうことがあります。
Streamは何ができるのか実践を通して経験したことを紹介しています。
# はじめに
* 実装したStreamの動作を確認するために必要なインスタンスはリフレクションを使って自動生成しています。

https://qiita.com/flip-flop/items/e6047d75239b83bb2f23

# 4階層目の値で絞り込み

▼ クラス定義

```Java

@Data
static class Person {
 List<Pet> pets;
}

@Data
static class Pet {
 List<Cat> cats;}

@Data
  static class Cat{
      String id;
      List<Toy> toys;
  }

@Data
static class Toy{
  String name;// ここの値で絞り込み
}

```
▼ サンプルコード
```Java
public static void main(String[] args) {

  Person obj
  // インスタンス生成(参照リンク参照)
  obj = method(Person.class, "");

  // 生成したインスタンスの値はランダムなので絞り込み値を作成する
  // 絞り込み条件のために生成したインスタンスの末端の値をリストで取得する
  List<String> toyNames = obj.getPets().stream()
  .flatMap(e -> e.getCats().stream())
  .flatMap(e1 -> e1.getToys().stream())
  .map(e2 -> e2.getName())
  .collect(Collectors.toList());
  //--結果-------------------------
  // XIJZWRW1KQ ←この値で絞り込み
  // OX0BSBMB6P,
  // ZCNVD5T80S,
  // Z9HH4V3L3K,
  // 3MSL0MGSOA,
  // B563MF1D6L,
  // 3X85YBIZHK,
  // GJWUYFSS4Y;
  //------------------------------

  // 末端(toyクラスのname)の値で絞り込み
  // 最初filterしてその中でstream()にして下の階層をflatMapする
  List<Pet> pet = obj.getPets().stream()
  .filter(e -> e.getCats().stream()
           // flatMapすると以下のような形になっている
           //[IJZWRW1KQ,OX0BSBMB6P,ZCNVD5T80S,Z9HH4V3L3K,3MSL0MGSOA,
           //B563MF1D6L,3X85YBIZHK,GJWUYFSS4Y]
          .flatMap(e1 -> e1.getToys().stream())
                 // anyMatchでtoyNameの0番目の値と一致するものがあればtrueを返す
                 .anyMatch(e2 -> e2.getName().equals(toyNames.get(0))) 
          )
  .collect(Collectors.toList());
  // petsの値を上書きする
  obj.setPets(pet);
}

```

▼ 実行結果
```Java
//Person
Person(
   pets=[
        Pet(
            cats=[
                  Cat(
                      id=DRLNUCSV84, 
                       toys=[
                             Toy(name=XIJZWRW1KQ),// ここでヒット
                             Toy(name=OX0BSBMB6P)
                        ]
                   ), 
                   Cat(
                       id=YKZRJN3JPL, 
                        toys=[
                              Toy(name=ZCNVD5T80S), 
                               Toy(name=Z9HH4V3L3K)
                         ]
                    )
               ]
            )
        ]
);

```

# おわりに
深い階層の値の絞り込みであっても数行のコードで取り出すことができます。便利です。

# 参考リンク
* [Java でランダムな文字列を生成する](https://www.delftstack.com/ja/howto/java/random-alphanumeric-string-in-java/)
* [Java リフレクションを使って階層の深いインスタンスを自動生成する](https://qiita.com/flip-flop/items/e6047d75239b83bb2f23)
typescript-eslintのban-tslint-commentルールについて

## はじめに
この記事では[typescript-eslint](https://typescript-eslint.io/)のルールのうち`ban-tslint-comment`について解説します。
typescript-eslintの他のルールについても別記事で解説し、最終的にReact開発を行うにあたって最適なルール設定を構築することを目的としています。

## ルールについて
[`ban-tslint-comment`](https://typescript-eslint.io/rules/ban-tslint-comment)はTSLintが提供するコメントに対する制限を行うルールです。"plugin:@typescript-eslint/strict"で有効になります。
以下のようなTSLintが提供するルール
```ts
/* tslint:disable */
// tslint:disable-next-line
someCode(); // tslint:disable-line
```
に対するコメントを禁止することができるルールです。

## ルールの採用について
TSLintをすでに利用したり、新たに採用する予定がない場合は有効にするのが良いと考えています。