OmniAICreator/Qiita-1.07M huggingface dataset:
(リンクだけ)噴水も大変ですね。衛生面と維持コスト。噴水つながり?ヘロンの公式へ。

「3つの噴水の問題」新課程共通テスト2025(令和7年)数学の勉強中です。
???テストのテーマは、**放物線、2次関数**でした。

https://ja.wikipedia.org/wiki/噴水
https://en.wikipedia.org/wiki/Fountain
＞衛生面と維持コスト
噴水も大変ですね。

噴水 仕組み 原理　google検索

https://ja.wikipedia.org/wiki/ヘロンの噴水 　←←←←
https://en.wikipedia.org/wiki/Heron%27s_fountain

https://ja.wikipedia.org/wiki/アレクサンドリアのヘロン
https://en.wikipedia.org/wiki/Hero_of_Alexandria
＞数学では測量法の改良者として知られる。また、著書 Metrica においてヘロンの公式の証明を与えた。

https://ja.wikipedia.org/wiki/ヘロンの公式
https://en.wikipedia.org/wiki/Heron%27s_formula

# google検索
Metrica heron

https://www.google.com/search?q=Metrica+heron&sca_esv=75d2da38486ca9c2&rlz=1CAUHAM_enJP1105&sxsrf=AHTn8zqL-kF6z80R_HhCLsvyJ-kb--gmJg%3A1738060697253&ei=mbOYZ_WSD_ne1e8P97yCoA4&ved=0ahUKEwi1w9TTnJiLAxV5b_UHHXeeAOQQ4dUDCBA&uact=5&oq=Metrica+heron&gs_lp=Egxnd3Mtd2l6LXNlcnAiDU1ldHJpY2EgaGVyb24yBBAAGB4yBBAAGB4yBhAAGAoYHjIFEAAY7wUyBRAAGO8FMggQABiABBiiBDIFEAAY7wUyCBAAGAgYChgeSIsrUMkOWJ4jcAF4AZABAJgB0gGgAaYHqgEFMC41LjG4AQPIAQD4AQGYAgegAoIIwgIKEAAYsAMY1gQYR8ICBRAAGIAEwgIGEAAYBBgewgIHEAAYgAQYE8ICBhAAGBMYHsICCBAAGBMYBBgewgIIEAAYExgKGB7CAggQABgTGAUYHsICCBAAGBMYCBgemAMAiAYBkAYHkgcFMS41LjGgB7kT&sclient=gws-wiz-serp

＞現代ではシラクサのアルキメデスにも既知であったと考えられています。﻿...
プロジェクトマネージャーのアンチパターン: 失敗を招く行動とは？

# はじめに

プロジェクトマネージャー（PM）は、プロジェクトの成功を左右する重要な役割を担っています。しかし、その役割を誤った形で実行すると、プロジェクト全体に悪影響を与える可能性があります。本記事では、**プロジェクトマネージャーのアンチパターン**を紹介し、それがなぜ問題なのか、どのように回避すべきかを解説します。

---

## アンチパターンとは？

アンチパターンとは、最初は良さそうに見えるものの、長期的には悪影響を及ぼす行動や手法を指します。プロジェクトマネージャーが陥りがちなアンチパターンを理解することで、チームの生産性やプロジェクトの成果を改善するヒントが得られます。

---

## プロジェクトマネージャーの主なアンチパターン

### 1. **マイクロマネジメント**

#### 問題点:
PMがチームメンバーの作業に過剰に介入し、細部まで管理しようとする行動です。これにより、メンバーの自主性が損なわれ、ストレスや不満が生まれることがあります。

#### なぜ起こるのか？
- PMがメンバーを信頼していない。
- プロジェクトの遅れを恐れて過剰に干渉する。

#### 解決策:
- メンバーにタスクを任せる勇気を持つ。
- 結果にフォーカスし、プロセスはメンバーに委ねる。

---

### 2. **不明確な目標設定**

#### 問題点:
プロジェクトの目標やタスクが曖昧だと、メンバーは何をすべきか分からず、方向性を見失います。

#### なぜ起こるのか？
- PM自身がプロジェクトの全体像を把握していない。
- クライアントやステークホルダーとのコミュニケーション不足。

#### 解決策:
- SMARTな目標（具体的・測定可能・達成可能・関連性がある・期限がある）を設定する。
- 定期的に目標を見直し、必要に応じて調整する。

---

### 3. **優先順位の管理ミス**

#### 問題点:
すべてのタスクを「最優先」として扱い、チームが混乱する状況を引き起こします。その結果、本当に重要なタスクが後回しになることがあります。

#### なぜ起こるのか？
- PMがクライアントや上司の要求を無批判に受け入れる。
- 優先順位付けのスキルが不足している。

#### 解決策:
- タスクの優先順位を明確にし、チームと共有する。
- 無理な要求には断る勇気を持つ。

---

### 4. **コミュニケーション不足**

#### 問題点:
PMが必要な情報を共有しない、または一方的に指示を出すだけのコミュニケーションを取ると、チーム内の連携が崩れます。

#### なぜ起こるのか？
- PMが忙しすぎてメンバーとの対話を軽視している。
- 双方向のコミュニケーションを重視していない。

#### 解決策:
- 定期的なミーティングや1on1を実施する。
- メンバーからの意見や質問を積極的に受け入れる。

---

### 5. **リスク管理の軽視**

#### 問題点:
プロジェクトのリスクを適切に予測・管理しないことで、問題が発生した際に迅速な対応ができなくなります。

#### なぜ起こるのか？
- リスクを過小評価する。
- 「楽観的すぎる」計画を立ててしまう。

#### 解決策:
- リスクアセスメントを定期的に実施する。
- バックアッププランを用意し、リスク発生時に備える。

---

### 6. **エンジニアに丸投げ**

#### 問題点:
PMがプロジェクトの責任を回避し、タスクをすべてエンジニアに任せきりにする行動です。これにより、エンジニアは過剰な負担を感じ、全体の方向性が見失われることがあります。

#### なぜ起こるのか？
- PMが技術的な理解を持っていない。
- 自分の責任を軽減しようとする意図。

#### 解決策:
- タスクを適切に分配し、進捗を把握する努力をする。
- チームと積極的にコミュニケーションを取る。

---

### 7. **お客様の言いなり**

#### 問題点:
クライアントの要望を無批判に受け入れることで、プロジェクトのスコープが膨らみ、チームが疲弊します。結果的に納期遅延や品質低下を招く可能性があります。

#### なぜ起こるのか？
- クライアントとの関係を重視しすぎる。
- 断ることへの恐怖や不安。

#### 解決策:
- 要望の優先順位を整理し、実現可能性を慎重に検討する。
- 必要に応じて、合理的な代替案を提案する。

---

### 8. **技術系の話から逃げる**

#### 問題点:
PMが技術的な課題や議論を避けることで、チームの信頼を失ったり、重要な意思決定が遅れることがあります。

#### なぜ起こるのか？
- 技術に対する理解不足。
- 技術的な話題に対する恐れや自信の欠如。

#### 解決策:
- 技術的な基礎知識を学び続ける。
- 技術的な議論に積極的に参加し、チームと協力して解決策を模索する。

---

## アンチパターンを回避するためのポイント

1. **自己認識を高める:** 自分の行動を振り返り、改善点を探る。
2. **チームメンバーを信頼する:** 自主性を尊重し、任せる勇気を持つ。
3. **学び続ける:** プロジェクト管理のベストプラクティスやツールを積極的に活用する。
4. **フィードバックを受け入れる:** チームやステークホルダーからのフィードバックを柔軟に受け止める。

---

## まとめ

プロジェクトマネージャーが陥りがちなアンチパターンは、プロジェクトの成功を妨げる大きな要因となります。しかし、それらを理解し、回避するための対策を講じることで、チームの生産性とプロジェクトの成果を大きく向上させることができます。

あなた自身が抱える課題に気づき、一歩ずつ改善していきましょう！
Docker Desktopがmac book proのバッテリーを浪費するのでColimaにしてみた話

# ことの発端は
* Docker Desktop for macがバッテリーをとても消費するようだ
* そして遅い、何よりこれが一番のストレス
* なので代替を探してたどりついたのが、colima

# colimaって

https://github.com/abiosoft/colima


公式Githubにはこう書いています
> Colima - container runtimes on macOS (and Linux) with minimal setup.

つまりは、macOSに最適化されたコンテナランタイムだよってことでしょう

# インストールの前にDocker Desktopはさようなら
* dockerで永続化してるデータも消える(というか再構築)ので、必要あればどこかに保存
* Docker Desktopのバイナリは不要なので削除で良いですが、dockerコマンドとか別途入れてない人はいるのかなとか思ったり思わなかったり。この辺は環境依存ですので適宜
* 置いときたい人は自動起動をOFFにする必要があります

# 早速インストール
これはまあbrewで入るので楽

```
brew install colima
```

# colimaのVMをつくる
* お使いのmacがappleシリコンであれば、以下のようにすると快適なdocker環境ができます
* virtioを使うとめちゃくちゃ遅いファイルIOがめちゃくちゃ速くなります(個人の感想です)

```
colima start --cpu 8 --memory 12 --disk 128 --arch aarch64 --vm-type=vz --vz-rosetta --mount-type virtiofs
```

# dockerコマンドに教えてあげる必要がある
.bash_profileなどに
```
export DOCKER_HOST="unix://$HOME/.colima/docker.sock"
```

と

# dockerコマンドで確認
```
docker ps -a
```

これでエラーにならなければOKです。あとは普通にdocker compose up などしてみてください。

# Special Thanks
https://qiita.com/rairaii/items/c59531998e21d44678a4

# (2025/01/30)追記
* mac osを最新にアップデートしたほうが良いみたいです
  * colima自体がstartできないという現象があるみたい
Zabbixのテンプレートを使ってProxmoxを監視してみた

こんにちは。
ALJの江口と申します。

Proxmoxの監視メニューのMetric Serverには、GraphiteとInfluxDBがプルダウンで選択でき、これらは容易に連携できますが、既にZabbixがあるという環境や、Zabbixになじみがあるという方もいると思います。

Zabbixのページを見ると、ProxmoxのAPIを利用した**Proxmox VE by HTTP**というテンプレートが用意されており、Zabbix AgentをインストールしなくてもCPUやメモリなどの監視であればすぐにZabbixでデータ収集することができます。このテンプレートは、Zabbix6.0以降に対応しています。

Zabbixのテンプレートの利用方法は公式ページに設定手順が記載されており、おおむね記載の通りで情報の取得ができますが、自分の環境（Zabbix6.0）では、少しだけ追加の設定が必用だったので、その点を含めて、設定の流れを説明したいと思います。

https://www.zabbix.com/jp/integrations/proxmox

設定が完了すると以下のように各PVEと稼働しているVMのデータが可視化されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662107/dbdfe2ce-4373-3318-6a51-0048f6eaccb0.png)

:::note info
設定した環境は以下の通りです。
・Zabbix 6.0
・ProxmoxVE 8.3.2
:::


# 設定の大まかな流れ
設定作業は以下を行います。

| 対象 | 作業内容 |
|:-|:-|
| Proxmox  |  ・ユーザー追加 [推奨]<BR> ・APIトークンの作成<BR>・Permissionsの設定 |
|  Zabbix | ・ホストの追加  |

# 実際の設定
### ユーザー追加
ユーザーの追加は必須ではありませんが、セキュリティの観点からAPIアクセス用ユーザーの追加が推奨されています。
Server View - Datacenter - Permissions - Users の順に移動して、[Add] をクリックします。以下の例では、zabbixというユーザーを追加しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662107/4a169b35-6177-42ff-a465-d3a7209a558d.png)

### APIトークンの作成
Server View - Datacenter - Permissions - API Tokens の順に移動して、[Add] をクリックします。以下の例では、IDにzabbixという名前で登録しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662107/c77f4f5f-dfda-a417-3a00-9a9c966b1ff2.png)

### Permissionsの設定
Server View - Datacenter - Permissions の順に移動して、[Add] をクリックします。
- "/"　に　"Sys.Audit"
- "/storage"　に　"Datastore.Audit"
- "/vms"　に　"VM.Audit"

公式ページに上記のアクセス権の説明がありますが、PVEAdminは上記の権限を持っているので、PVEAdminで設定しました。UserとTokenの両方に設定が必用ですので、計６個追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662107/5668799f-69aa-01f9-48ad-a89b139ae0f0.png)

### Zabbixにホストの追加
ホストの追加では、[ホスト]と[マクロ]に設定が必用です。

[ホスト]
ホストでは以下の項目を設定します。
- "ホスト名" に 任意のホスト名
- "テンプレート" に "Proxmox VE by HTTP"
- "グループ" に 任意のグループ
- "インタフェース" にエージェントを選択し、IPアドレスに PVEのIPアドレス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662107/6cb455d8-43bd-6407-2f9c-d80bdff5f23e.png)

:::note info
インターフェースの設定は公式ページに説明がありませんでしたが、ここに設定を入れないとデータが取得できませんでした。ポートは関係ないようで、デフォルトの10050で動作しました。
:::

[マクロ]
マクロでは、以下の３項目を設定します。
「継承したマクロとホストマクロ」で変更したい項目がある場合は、追加してください。

- {$PVE.TOKEN.ID}
- {$PVE.TOKEN.SECRET}
- {$PVE.URL.HOST}

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662107/89555c6f-6f3e-2742-b3d9-e903d81b6d52.png)

クラスターを組んでいる場合は、PVEのノード全てのホストを作成します。

# 設定後、しばらく待つ
数分ほど待つと、データが収集されると思います。

テンプレートを使うと、PVEノードのみではなく、稼働しているインスタンスの情報も取得できるので、便利だと思います。


多くのデータが収集されるため、ダッシュボードの作成は必須なので、あとは好みのダッシュボードを作成してください。

以上です。
新しい Windows の IME のせいで KiCad の PCB エディタが飛ぶ

やっと分かりましたよ検索しても語の選択が適合していなかったようで、それが「飛ぶ」なのか「コケる」なのか「クラッシュ」なのかはたまた企業内隠語なのかは年代とかどこで育ったとかによって変わりますからねえというハナシ。

ときどき線幅とか数値の設定を変えようとキャレットを置こうとしただけで「さよーなら」されて困ってたところ

要は、IME を旧式のにすれば

> <h3>あーら快適</h3>

という具合でしたよ、やれやれだぜ。 ww
コードを書くときに気を付けたいこと

## はじめに

最近、「コードを書く」ということが減ってきて、AIに投げた結果を修正することがほとんどのような感じになってきた私です。使い捨てのコードに関しては特に気にしていないのですが、ちょっとちゃんとしたものを作るときにAIの出してきたコードで違和感を感じることも多くあります。そこで、その違和感の正体を言語化していきたいと思います。

## 余計なことをする：クソコードの主な原因

基本的に、自分がクソコードを作るときは「余計なことをする」が原因なことが多いように思います。典型的な例を見てみましょう。

```typescript
// データを取得する...はずの関数
const fetchUserContents = async (userId: string) => {
  const response = await fetch(`/api/users/${userId}`);
  const userData = await response.json();
  
  // 実は取得だけでなく保存もしている
  localStorage.setItem('userData', JSON.stringify(userData));
  
  return userData;
};

// React componentでの使用例
const UserProfile = () => {
  const [userData, setUserData] = useState(null);

  useEffect(() => {
    // 関数名からはローカルストレージへの保存が行われることが予測できない
    fetchUserContents('123').then(data => setUserData(data));
  }, []);

  return <div>{/* ... */}</div>;
};
```

このようなコードは、特にReactなどのフロントエンド開発でよく見かけます。取得したデータをそのまま`useState`などに入れてしまうことも多いですよね。

## 問題点：時限爆弾としてのコード

正直、私自身も面倒くさくて、わかっていながらこのような実装にすることもあります。特に、このタイプのクソコードは基本的に時限爆弾式なので、忘れたころにやってきます。

よくあるケースとして、以下のような状況があります：
- ファイルサイズが大きくなったためリファクタリングが必要になった
- 外部に切り出してほかのユーザーのデータも取得できるようにしたところ、自分のページのデータが最後に確認したユーザーのデータになってしまう（実際に経験しました...）

## 単一責任の重要性

「単一責任」や「単一目的」の重要性は、よく語られますが、正直わかりづらい部分も多いです。今回の例で言えば、関数名が嘘をついていたことが問題です。

もちろんコードの中を見れば防げることではありますが、通常は関数名のみで判断したいものです。特に他人のコードを見るときなどは、一度でもそのようなことがあると、利用側はそのコードの中身が信じられず、利用のたびに中身を見に行くというコストが発生してしまいます。

チーム開発などの場合は使えませんが、特に面倒くさいときは次のようにすることがあります。場当たりな対処でBestではありませんが、少なくとも「データを取得して保存する」という名前であれば、嘘はついていないと言い聞かせながらつぎのようにします。

```ts
const fetchAndSaveUserContents = async (userId: string) => {
  const response = await fetch(`/api/users/${userId}`);
  const userData = await response.json();
  localStorage.setItem('userData', JSON.stringify(userData));
  return userData;
};
```

何をしているかはわかるので、最悪ではなくなりました。しかし、このような対処は名前が長くなったり等、問題も多く生まれます...

## 改善案：責務の分離

より良い実装を見てみましょう。

```typescript
// データ取得に特化した関数
const fetchUserData = async (userId: string) => {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
};

// ローカルストレージ操作に特化した関数
const saveUserDataToStorage = (userData: UserData) => {
  localStorage.setItem('userData', JSON.stringify(userData));
};

// ユースケースとして両者を組み合わせる
const UserProfileUseCase = {
  loadUserProfile: async (userId: string) => {
    const userData = await fetchUserData(userId);
    saveUserDataToStorage(userData);
    return userData;
  }
};

// React componentでの使用例
const UserProfile = () => {
  const [userData, setUserData] = useState<UserData | null>(null);

  useEffect(() => {
    // 処理の内容が明確で予測可能
    UserProfileUseCase.loadUserProfile('123').then(data => setUserData(data));
  }, []);

  return <div>{/* ... */}</div>;
};
```

この実装では、各関数が一つの責務に集中しています。私のイメージとしては、「一つの動詞で説明できる範囲の処理を関数とする」というのが良い指標になります。

動詞1つで説明できない状態になった場合は、恐らく責任が増えてきています。しかし、複数の処理が連続して行われることは一般的です。

そのような場合は、HogeUseCaseやFugaServiceなどの命名にして複数の処理をつかさどっているということを明示するとよいです。ほかにもProcessなどもありますが、自分は、個人の好みとしてUseCaseとServiceを利用しています。UseCaseを一連の処理として、ServiceをUseCseをまとめた処理のイメージです。

ここら辺は正直プロジェクト次第ではあるので、自由に決めてしまうのが良いと思います。

## まとめ

結局のところ、面倒くさくて直さないことで後々問題になることが多いので、気が付いたときに直すのが良いのかなあとか思ったりします、、
【AWS】（ちょっぴり解説）Amazon Nova

## この記事で伝えたいこと（ポイント）

- Amazon Novaは、Amazon Bedrockで利用可能な、最先端の基盤モデル
- 高い知能と業界をリードする価格性能比を提供し、テキスト、画像、動画を扱える
    - [参考：What is Amazon Nova?](https://docs.aws.amazon.com/nova/latest/userguide/what-is-nova.html)

## はじめに

この記事では、Amazon Bedrockで新しく利用可能になったAmazon Novaについて解説します。

## サービスの説明

Amazon Novaは、最先端の基盤モデルであり、高い知能と業界をリードする価格性能比を提供します。
テキスト、画像、動画を扱うことができる基盤モデルです。Amazon Bedrockを介してAPIとして利用できます。

モデルによってできることが異なります。順番に見ていきましょう。

### Amazon Nova Pro

- テキスト、画像、動画を入力できる
- 300kのコンテキストウィンドウを持ちます
- 最大5kのトークンを出力することができます
- 200以上の言語をサポートしています

### Amazon Nova Lite

- テキスト、画像、動画を入力できる
- 300kのコンテキストウィンドウを持ちます
- 最大5kのトークンを出力することができます
- 200以上の言語をサポートしています

### Amazon Nova Micro

- テキストを入力できる
- 128kのコンテキストウィンドウを持ちます
- 最大5kのトークンを出力することができます
- 200以上の言語をサポートしています

## どんな時に利用できるか

Amazon Novaは、以下のようなユースケースで利用できます。

### テキスト生成

Amazon Novaは、テキスト生成タスクに利用できます。例えば、文章の要約、質問応答、翻訳などが可能です。

### 画像生成

Amazon Novaは、画像生成タスクに利用できます。例えば、画像のキャプション生成、画像の分類、画像の検索などが可能です。

### 動画生成

Amazon Novaは、動画生成タスクに利用できます。例えば、動画の要約、動画の分類、動画の検索などが可能です。

## まとめ

Amazon Novaは、Amazon Bedrockで利用可能な、最先端の基盤モデルです。高い知能と業界をリードする価格性能比を提供し、テキスト、画像、動画を扱うことができます。
Amazon Novaは、テキスト生成、画像生成、動画生成など、様々なタスクに利用できます。

## おわり

（いっぱい聞けて、いっぱい喋れる！）
弾幕系の弾をArrayListで管理する

# はじめに

弾幕系シューティングの弾を作りたいとき、配列だとちょっと都合が悪いので、ArrayList使うと楽だ、という話です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/dfcacf09-c406-3a8b-cb18-18d8371899b3.png)

# 配列とArrayList
両者は何が違うのか？

配列は要素数を決めて使うのに対して、
ArrayListは要素数の増減が簡単です。（実行中にという意味で or 動的）
そのかわり少し遅いです。
また、ArrayListは何でも入れられます。

# コード
１つの弾を管理するクラスを作り、それをベースにArrayListを作ります。
クラスには、
・位置
・速度
・（寿命）
メソッドとして
・１フレームでの移動
・表示
機能をつけます。

ポイントは、要素をremoveすると、空いた場所は詰められるので、番号が１つずれるため、正順ではなく、逆順で範囲外チェックすると、簡単だということです。

```java
ArrayList<Bullet> bs;

void setup() {
  size(400, 400);
  bs = new ArrayList<Bullet>();
}

void draw() {
  background(255);

  //初期位置、初速度指定で追加
  bs.add(new Bullet(mouseX, mouseY, cos(frameCount*0.1), sin(frameCount*0.1)));

  //削除すると番号ずれるので、逆順にやる
  for (int i = bs.size()-1; i >= 0; i--) {
    Bullet b = bs.get(i);
    b.move();
    b.draw();
    //範囲外に出たら削除
    if(b.pos.x<0 || width<b.pos.x || b.pos.y<0 || height<b.pos.y){
      bs.remove(i);
    }
  }
  //println(bs.size());//総数チェック
}

class Bullet {
  PVector pos;//位置
  PVector vec;//速度
  float r=5;//半径

  Bullet(float px,float py,float vx,float vy) {
    pos = new PVector(px, py);
    vec = new PVector(vx, vy);
  }

  void move() {
    pos.add(vec);
  }

  void draw() {
    circle(pos.x, pos.y, r);
  }
}
```
イーロン・マスクのxAI、GrokをXに統合し、ソーシャルメディアの未来を再定義

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917980/90f564fc-5a0d-9442-7988-f371d31fa6ae.png)
イーロン・マスク氏の人工知能プロジェクトであるxAIは、AIチャットボット「Grok」をソーシャルメディアプラットフォーム「X」（旧Twitter）に統合し、AIとソーシャルメディアの融合における画期的な進展を遂げました。この統合により、ユーザーはリアルタイムで知的かつ洗練された支援を受けることが可能となり、ユーザー体験の向上が期待されています。

**xAIとGrokの誕生**

2023年7月に設立されたxAIは、宇宙の真理を理解するという壮大な目標を掲げており、その一環として高度な推論と対話が可能なAIの開発を目指してきました。このビジョンは、洞察力とユーモアを兼ね備えた応答を提供するAIチャットボット「Grok」の導入によって具体化されました。

**Xへの統合：ソーシャルメディア交流の新時代**

GrokのXへの統合は、プラットフォームのユーザー体験を豊かにする戦略的な動きです。ユーザーは、ソーシャルメディア環境内でGrokとリアルタイムの対話を行い、情報の検索や確認、さらにはユーモアあふれる会話を楽しむことができます。この展開は、Xを多機能なプラットフォームへと変革し、AIがコミュニケーションと情報伝達の中心的な役割を果たすというマスク氏のビジョンと一致しています。 

**Grokのスタンドアロンアプリケーション：アクセスの拡大**

Xへの統合に加えて、xAIはGrokをスタンドアロンのアプリケーションとしても提供し、ソーシャルメディアプラットフォームを超えてそのアクセス性を広げています。当初はX Premium+の加入者向けに提供され、ユーザーはGrokと独立して対話し、リアルタイムの情報取得、質問への回答、画像生成などの機能を利用できます。この動きは、先進的なAIツールを一般に広く提供するというxAIのコミットメントを示しています。 

**Grokの進化：ベータ版から高度な機能へ**

2023年11月のベータ版リリース以来、Grokは大きな進化を遂げてきました。初期のバージョンでは、対話能力の向上とユーモアのある応答に焦点を当てていましたが、時間とともに以下のような機能が追加されました：

- **画像理解**：文書、図、写真などの視覚情報を処理・解釈する能力。

- **ウェブ検索の統合**：リアルタイムでウェブ情報にアクセスし、最新の情報を提供する能力。

- **PDFサポート**：PDF文書のアップロードと分析機能の追加。

- **テキストから画像への生成**：xAIが開発したテキストから画像へのモデル「Aurora」を導入し、テキスト入力に基づいてフォトリアリスティックな画像を生成する能力。

これらの強化により、Grokは多様なユーザーの要求に応える多機能なAIアシスタントへと進化しました。 

**プライバシーとデータ使用に関する考慮事項**

GrokのXへの統合に伴い、ユーザーデータの利用に関する議論が生じています。デフォルトでは、X上でのユーザーのやり取りはGrokの性能向上のために使用されます。プライバシーを懸念するユーザーは、設定を調整してデータ共有を制限することができますが、その手順はウェブとモバイルプラットフォーム間で異なります。この点は、ソーシャルメディア内でのAI技術の展開における透明性とユーザーのコントロールの重要性を強調しています。 

**今後の展望：AIとソーシャルメディアの未来におけるGrokの役割**

GrokのXへの統合の成功は、AIがソーシャルメディアプラットフォームを強化し、ユーザーに豊かな交流と情報へのアクセスを提供する可能性を示しています。xAIがGrokの機能をさらに開発し、そのアクセス性を拡大し続ける中で、AIアシスタントがデジタルコミュニケーションの重要な要素となる未来が期待されます。この展開は、技術的な進歩を反映するだけでなく、AIの倫理的な使用や革新とユーザープライバシーのバランスに関する重要な議論を促進します。

結論として、xAIのGrokとXの融合は、人工知能がユーザー体験を豊かにし、デジタル交流の境界を再定義するソーシャルメディアの進化における新たな章を開くものです。
PHPで、JavaやPythonで言うところのセレクタを実装する

PHP版BayServerを開発する際、セレクタが必要になったので実装してみました。

:::note info
BayServerは、横浜ベイキット(http://baykit.yokohama) が開発している爆速Webサーバーで、Ruby、Python、PHPなどさまざまな言語で開発されています。
:::

セレクタとは、JavaやPythonで取り入れられているソケットやパイプを扱うためのAPI（クラス）で、select関数などの低レベルのソケットAPIに比べて色々とメリットがあります。

メリットはこんなところでしょうか

- 低レベルなソケットAPIは使い方にクセがあり少し使いづらいのを分かりやすいメソッドにしてくれている
- select, epoll, kqueue など、プラットフォームによるソケットAPIの実装を隠蔽できる

実際、とても扱いやすいクラスだと思います。

で、JavaやPythonでのセレクタの使い方としては

1. セレクタのインスタンスを作成する
1. 監視したいソケットやパイプを登録する。登録する際は何をしたいか（読み込み/書き込み)も指定する
1. selectメソッドを呼び監視を開始する（ここでブロックされる）
1. 読み込みや書き込みが可能になったらselectメソッドから返る
1. 読み込みや書き込みの処理を行う

実際、従来のselectやepollなんかを使って書くのに比べて、メッチャ書きやすいし分かりやすいです。

で、BayServerの話に戻りますが、BayServerでは、実装言語が違っても、クラス構造やメソッド名、その中身のロジックは全く同じになるように記述されています。

ところが、PHPにはセレクタのAPIがないので、JavaやPythonのようには書けないんですね。

なのでSelectorクラスを実装してみました。

コードはGitHub上のを参照してください。

https://github.com/baykit/BayServer_PHP/blob/main/packages/bayserver-core/baykit/bayserver/util/Selector.php

今は、内部的に従来のselect関数を使っていますが、selectは制限が多いので、今後epollやkqueueなども扱えるようにしたいと思っています。（まあ、今のところこれで十分なので、リクエストがあればですが笑）

と言うわけで、BayServerをよろしくお願いします！
postgres コマンド Cheatsheet

## Databases & tables

1. list databases: `\l`
2. use database: `\c newDatabaseName`
3. list tables: `\dt`
4. describe table: `\d table_name`  (show columns from)
5. schema check `\dn+`

## connection数

user ごとのconnection数の確認

```sql
SELECT usename, COUNT(*) AS connection_count
FROM pg_stat_activity
GROUP BY usename;
```

特定のUserのconnectionを終了する

```sql
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE usename = 'test_user';
```

## roles

### list

list roles:
```sql
\du
```

### create

```sql
CREATE USER test_user WITH PASSWORD 'test_user';
```

### grant

`cloudsqlsuperuser` を IAM userに付与 (CloudSQL)

```sql
grant "cloudsqlsuperuser" to "test-user@<gcp project>.iam";
```

初期ユーザに権限付与 (publicのすべての権限)

```sql
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO test_user;
GRANT ALL ON SCHEMA public TO test_user;
```

### pg_roles

roleの権限確認

```sql
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication
FROM pg_roles
WHERE rolname = 'test_user';
```
苦手なフロントエンド開発について学ぶ「目次」

# 始めに
皆さんには秘密なんですが私、フロントエンド開発が大変苦手で・・・（全く出来ないわけではないけど）
なので少しでもフロントエンド開発の苦手意識を下げるとともに自分のリスキニングの意味も込めて再度勉強してみようかと思いました。

そこで天下の「Chat-GPT」大先生にこんな質問してみました。

**「フロント開発と言われるジャンルが扱う言語には何があるか？」**
（陳腐な質問ですいません　:bow_tone1:）

で帰ってきたお言葉が以下の内容です。
（本投稿はこちらを目次としそれぞれのお言葉を別投稿としてリンクしていきます）

## Chat-GPT先生のお言葉

フロントエンド開発で主に使用されるプログラミング言語や技術は以下の通りです。これらは、ウェブアプリケーションやウェブサイトの「見た目」や「動作」を構築するために使われます。

---

### **1. 基本的な言語**
1. **[HTML（HyperText Markup Language）](https://qiita.com/Tomo27/items/587ad05a675c4ba656e6)**
   - ウェブページの構造を定義するマークアップ言語。
   - 要素（ヘッダー、パラグラフ、リンク、画像など）の配置を指定。

2. **CSS（Cascading Style Sheets）**
   - HTMLで定義した要素のデザインやレイアウトを決めるスタイルシート言語。
   - 色、フォント、間隔、アニメーションなどを設定。

3. **[JavaScript](https://qiita.com/Tomo27/items/4893442850b9ba5afcc2)**
   - 動的な動作やインタラクティブな機能を実現するスクリプト言語。
   - ボタンのクリックイベントやフォームバリデーション、アニメーションの制御などに使用。

---

### **2. JavaScriptの周辺技術**
1. **フレームワーク / ライブラリ**
   - **React.js**：コンポーネントベースのUI構築に特化。
   - **Vue.js**：軽量で直感的なフレームワーク。
   - **Angular**：Googleが開発したフルスタックのフレームワーク。
   - **Svelte**：コンパイル時に効率的なコードを生成するフレームワーク。
   
2. **TypeScript**
   - JavaScriptを拡張した型付きのスクリプト言語。
   - 大規模開発やチーム開発での保守性向上に役立つ。

---

### **3. スタイルを補助する技術**
1. **CSSプリプロセッサ**
   - **Sass（SCSS）**：CSSを拡張し、変数やネスト、関数をサポート。
   - **Less**：CSSに似た構文で動的スタイリングを可能に。

2. **CSSフレームワーク**
   - **Bootstrap**：レスポンシブデザインやグリッドシステムを簡単に導入。
   - **Tailwind CSS**：ユーティリティファーストなデザインのフレームワーク。

---

### **4. ウェブアプリ構築で使用される他の技術**
1. **フロントエンドのビルドツール**
   - **Webpack**：モジュールバンドラー。
   - **Vite**：高速なビルドと開発サーバー。
   - **Parcel**：設定不要で使えるバンドラー。

2. **API通信**
   - **GraphQL**：効率的なデータ取得を可能にするクエリ言語。
   - **Axios**や**Fetch API**：HTTPリクエストを送信するライブラリやブラウザ組み込みAPI。

3. **テンプレートエンジン**
   - **EJS**や**Handlebars**：HTMLのテンプレートを動的に生成。

---

### **5. その他の関連技術**
1. **WebAssembly（Wasm）**
   - 高速なパフォーマンスが求められる部分に使用。
   - C/C++やRustなどで書いたコードをブラウザ上で実行可能に。

2. **PWA（Progressive Web Apps）**
   - ウェブアプリをネイティブアプリのように動作させる技術。

3. **Web Components**
   - 再利用可能なカスタム要素を作成するための技術（Shadow DOMなど）。

---

これらの言語や技術は、プロジェクトの規模や要件に応じて適切に選択され、組み合わせて使用されます。フロントエンド開発は進化が早い分野であり、学ぶべきツールや言語が常に更新されています。

## ありがたいお言葉を受けて
知っている言葉も多々ある中で少しでもフロントエンドの開発ができるようになるために学習を進めています
【Laravel】複数のカラムを指定してデータを取得する

## 複数カラムの組み合わせを条件にデータ取得したい！！！

foreachの中で一件ずつwhere繋げて条件指定して...なんてやってられん！ってことで、
[whereRaw使った方法](#whereRawで素のSQL書いちゃう)と、[whereIn使った方法](#結合してwhereIn)の2つで試したよ〜っていう個人的メモ。

### whereRawで素のSQL書いちゃう
```php
public function getItemList()
{
    $itemParam = [
        [1, 2, 3], //[a_id, b_id, c_id]
        [4, 5, 6],
        [7, 8, 9],
    ];
    
    $query = DB::table('items');
    $this->whereInItemParam($query, $itemParam);
    $query->get();
}


public function whereInItemParam(Builder $query, ?array $itemParam): void
{
    if (empty($itemParam)) {
        $query->whereRaw('0');
        return;
    }

    $placeholders = implode(',', array_fill(0, count($itemParam), '(?, ?, ?)'));

    $query->whereRaw("(a_id, b_id, c_id) IN ($placeholders)", array_merge(...$itemParam));
}
```

### 結合してwhereIn
```php
public function getItemList()
{
    $itemParam = [
        '1,2,3', //'a_id,b_id,c_id'
        '4,5,6',
        '7,8,9',
    ];
    
    $query = DB::table('items');
    $this->whereInItemParam($query, $itemParam);
    $query->get();
}


public function whereInItemParam(Builder $query, ?array $itemParam): void
{
    if (empty($itemParam)) {
        $query->whereRaw('0');
        return;
    }

    $query->whereIn(DB::raw("CONCAT(data_owner_shisetsu_id, ',', data_owner_id, ',', provide_service_id)"), $itemParam);
}
```


## それぞれで発行されるクエリ

#### whereRaw
```
select ＊ from `items` where (a_id, b_id, c_id) IN ((?, ?, ?),(?, ?, ?),(?, ?, ?));
```

#### whereIn
```
select ＊ from `items` where CONCAT(a_id, ',', b_id, ',', c_id) in (?, ?, ?);
```

<br>
少しでもクエリ短くしたい...!!<br>
みたいなこだわりのある場合は、whereIn使った方がプレースホルダ分短く済みますね<br><br>
個人的にはwhereRowのクエリが、対象のカラムとの対応がわかりやすくて好きです
Next.js と Tailwind CSS を使った Markdown 表示の実装

この記事では、Next.js と Tailwind CSS を使用して Markdown を表示する方法を説明します。前提として、Next.js と Tailwind CSS の環境が既にセットアップされていることを想定しています。

## 導入

以下のコマンドを使用して必要なパッケージをインストールします。

```bash
npm install react-markdown @tailwindcss/typography remark-gfm
```

## パッケージ説明

`react-markdown`

React コンポーネントとして Markdown をレンダリングするライブラリです。Markdown を HTML に変換するための主要なツールとして使用します。

`@tailwindcss/typography`

Tailwind CSS のプラグインで、リッチテキスト（Markdown や記事コンテンツ）を美しく整えるためのスタイルを提供します。こちらのpluginを導入していないとtailwindcssのpurge機能が発生してmarkdownの表示がされない可能性が高いです。（必要なクラスをすでに使用していれば表示されます）

`remark-gfm`

GitHub Flavored Markdown (GFM) をサポートするためのプラグインです。テーブルやチェックボックスリストなど、拡張された Markdown 機能を使用する際に便利です。

## サンプル実装


以下に、これらのパッケージを使用して Markdown を表示する簡単な例を示します。

```typescript
import React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

export const MarkdownViewer = ({ content }) => {
  return (
    <div className="prose mx-auto">
      <ReactMarkdown remarkPlugins={[remarkGfm]}>{content}</ReactMarkdown>
    </div>
  );
};
```

proseというcssクラスがtailwind typographyのクラスになります。こちらをつけることでmarkdownを綺麗に表示できます。（付けないとmarkdownが表示されない可能性があります。）

続いて、Tailwind Typography プラグインの有効化を行います。

```diff:tailwind.config.ts
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
+  plugins: [require("@tailwindcss/typography")],
};
```

これで、Next.js と Tailwind CSS を使って Markdown を美しく表示するアプリケーションを作成することができます！

## Tips

proseを使うとmarkdownを表示する幅が狭くて広げたい場合があります。
そんな時は`tailwind.config.ts`に下記の設定を追加してみてください。

```diff:tailwind.config.ts
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
+      typography: {
+        DEFAULT: {
+          css: {
+            maxWidth: "100ch",
+          },
+        },
+      },
    },
  },
  plugins: [require("@tailwindcss/typography")],
};
```
defaultだと`maxWidth: "65ch"`となっています。
変換させないTextField

入力する際に自動的にスペースを挿入することで変換を防ぐ！！！



```sample.swift
import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

    // ユーザーが文字を入力または削除するたびに呼ばれるメソッド
    // 返り値：テキストフィールドでの入力/削除の処理を許可するかどうか
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // 現在のテキストを取得
        guard let currentText = textField.text else { return true }

        // バックスペース処理の確認
        if string.isEmpty {
            // 削除の場合はそのまま削除させる
            return true
        }
        
        // Enterキーが押された場合はスペースを追加しない
            if string == "\n" {
                return true
            }

        // 入力後のテキストを生成
        let newText = (currentText as NSString).replacingCharacters(in: range, with: string)
        
        // 最初のスペースを削除
        let trimmedText = newText.replacingOccurrences(of: " ", with: "")
        
        // 文字間にスペースを追加
        let spacedText = trimmedText.map { String($0) }.joined(separator: " ")
        
        // もう一度スペースを取り除く
        let finalText = spacedText.replacingOccurrences(of: " ", with: "")
        
        // テキストフィールドを更新
        textField.text = finalText
        
        // デフォルトの処理をキャンセル
        return false
    }

}


```
【GitHub】トピックブランチの作成+適用方法

# 記事概要
GitHubでトピックブランチの作成方法及び、mainブランチへの適用方法をまとめる。

# 前提
- GitHubアカウントは作成済みである
- GitHub DesktopをPCにインストール済みである
- アプリケーションはGitHubに登録済みである

# 手順1(ブランチの作成)
1. GitHub Desktopを開く
1. 「Current Branch」をクリックする
1. 「New Branch」をクリックする
    [![Image from Gyazo](https://i.gyazo.com/8abcbc85806e55bd3385b1b03c030526.png)](https://gyazo.com/8abcbc85806e55bd3385b1b03c030526)
1. 「Name」にはブランチ名を入力する
    ※どのような作業を行うブランチなのかわかりやすいように記述すること
1. 「Create Branch」をクリックし、ブランチを作成する
1. 「main」と表示されていたタブが、先ほど設定したトピックブランチ名に変更されていることを確認する
    ※ローカルリポジトリでのブランチ作成が完了
1. 「Publish branch」をクリックする
    ※リモートリポジトリにブランチが反映される

# 手順2(コミット)
1. GitHub DesktopのCurrent Branchにて、トピックブランチを選択する
1. VSCodeでファイルの記述を変更する
1. 変更内容がわかるように、コミットメッセージを入力する
1. 「commit to main」をクリックする
    ※ローカルリポジトリのブランチに対して、修正内容が反映される

# 手順3(プッシュ)
1. 「Push origin」をクリックする
    ※リモートリポジトリへの反映を行う
    ※pushは取り消せないので、修正内容に不備がないことを確認すること
1. リモートリポジトリへ変更が反映されているか、[ブラウザ](https://github.com/)で確認する
    1. 「Repositories」の下にある「ユーザー名/[アプリ名]」をクリックする
    1. 「commits」をクリックする
    1. 手順2のコミットメッセージが最上部に表示されていることを確認する
    1. メッセージをクリックする
    1. 変更内容が反映されていることを確認する

# 手順4(プルリクエストの作成)
プルリクエストとは、ブランチでのコミット履歴を残すと共に、各コミットにおける変更修正にコメントをつけることができる機能である

1. GitHub Desktopにて、「Create Pull Request」をクリックする
1. ブラウザが起動して、プルリクエスト作成画面が表示される
1. マークダウン表記で、プルリクエストの情報を入力する
    ```
    # Message
    [必要に応じて、記載]
    
    # Why
    [なぜこの実装が必要なのかを記載]
    
    # What
    [どのような実装をしているのかを記載]
    
    # Test Evidence
    [必要に応じて、テストエビデンスを添付]
    ```
1. 「Create pull request」をクリックする

# 手順5(コードレビュー)
コードレビューとは、複数人での開発において、コードの記述内容に問題がないか、他の開発メンバー等が確認をすることである
コードレビューを担当する人をレビュアーと呼ぶ

1. プルリクエストのURLをレビュアーに共有する
1. レビュアーは、「Files changed」をクリックすると、変更修正されたコードが一覧として表示される
1. レビュアーは、修正内容を確認する
    1. 不備がある場合
        1. 特定のファイルの特定行にコメントを残す
            1. 特定のファイルのコメントを残したい行にカーソルを当てる
            1. 青色の＋ボタンが表示されるので、クリックする
            1. ＋ボタンをクリックすると、コメント用のフィールドが現れるのでコメントを記述する
            1. 「Start a review」をクリックする
        1. プルリクエスト全体に対してのコメントを残す
            1. プルリクエストの「Conversation」タブを選択する
            1. プルリクエストに対してコメントを記述する
            1. 「Comment」をクリックする
    1. 不備がない場合
        1. プルリクエスト「Conversation」タブを選択する
        1. プルリクエストに対して、「LGTM」である旨を記述する
            LGTMは「Looks Good To Me」の略であり、「コードに問題はないと思うよ！」という意味である
        1. 「Comment」をクリックする
1. レビュアーのコメントを確認する
    1. 修正する必要がある場合、手順2から実施する
    1. 修正不要の場合、手順6へ進む

# 手順6(マージ)
1. ブラウザにて、「Merge pull request」をクリックする
1. 「Confirm merge」をクリックする
1. 「Delete branch」ボタンをクリックする
    ※マージ済みのトピックブランチを削除する

# 手順7(プル)
プルとは、リモートリポジトリの変更をローカルリポジトリに取り込むことである

1. GitHub Desktopを開く
1. トピックブランチから、mainブランチに切り替える
1. 「Fetch origin」ボタンをクリックする
1. リモートリポジトリとの差分を確認する
1. 「Pull origin」をクリックする
    ※「Pull origin」ボタンが表示されない場合、Github Desktopの左側ウィンドウ「History」タブの内容が更新されていれば問題ない

# 補足：commit logの確認
1. GitHub Desktopを開く
1. 左側ウィンドウの「History」のタブをクリックする
1. 確認したいcommitをクリックする
    ※一番上のログが、最新である
1. commitの内容を確認する

# 補足：インデックスを使用したcommit
1. 修正作業を進め、複数のファイルがcommitの対象になっていることを確認する
1. ファイルのチェックを外すと、commit対象外となる
1. commitする
    ※チェックがついているファイルのみがcommitされる
【Rails】presenceメソッド

# はじめに
ActiveSupportの拡張機能である `presence` メソッドについて調べた内容をまとめます。

# `presence` メソッドとは
- RailsのActiveSupportのメソッド
- オブジェクトが存在すればそのオブジェクトを返し、存在しなければnilを返す


## 構文
```rb
object.presence

# 下記と同じ
object.present? ? object : nil
```
- ActiveSupportで下記のように実装されている
```rb
  def presence
    self if present?
  end
```

## 使い方
- `present?` を使った例
```rb
nickname = params[:nickname] if params[:nickname].present?
first_name = params[:first_name] if params[:first_name].present?
avatar_name = nickname || country || "Taro"
```
- `presence` で下記のようにリファクタリングできる
```rb
avatar_name = params[:nickname].presence || params[:first_name].presence || "Taro"
```

## 補足
- `&.` との比較
    - `presence` メソッドを空文字に対して実行するとnilを返す＝ `present?` メソッドでfalseになる空白文字、空の配列、空のハッシュ、false、nilに対して実行するとnilが返る

|  | presence | &.  |
|---|---|---|
|nilに対して実行した返り値  |nil  |nil  |
|空文字に対して実行した返り値| nil  |空文字  |

```rb
nil&.name
=> nil
nil.presence
=> nil

user.name 
=> " " # 空文字が保存されている場合
user&.name 
=> " "
user.name.presence 
=> nil 

user&.name || "名前が登録されていません"
=> " "
user.name.presence || "名前が登録されていません"
=> "名前が登録されていません"
```
- DBにデータがない場合
```
irb(main):001:0> User.where(id: 2)
=> #<ActiveRecord::Relation []>

irb(main):002:0> User.where(id: 2).presence || "idが2のユーザーは登録されていません"
=> "idが2のユーザーは登録されていません"
```

# おわりに
リファクタリングに重宝しそうです。空白文字をnilで返す点で`&.` `try!` よりも使い勝手が良いと思いました。
# 参考
https://railsguides.jp/active_support_core_extensions.html#presence

https://apidock.com/rails/Object/presence

https://pikawaka.com/rails/presence
統計検定1級　統計数理　2024　問3　解説

［3］［4］ギブアップです。いろいろ試しても答えが合いませんでした。
![img20250128_11051156.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/3e541f3e-478e-f255-1eb3-e73357769c04.jpeg)
TailwindCSSで動的なClassを設定するときに陥りがちなミス

## 概要

TailwindでCSSを指定しようといているときに下記のようにコードを書いていたところ、
例として`color`の場合以下のような挙動になった

- 文字の色がpropsで指定した色に変更されない

```ts
// importは省略

type Props = {
 color: 'red' | 'blue'
 text: string
}

export const SampleComponent: FC<Props> = ({ color, text }) => {
 return (
  <div className={twMerge('font-bold text-md', `text-${color}-500`)}>
    { text }
  </div>
 )
}
```

## 原因
下記ドキュメントに書かれている通り
https://tailwindcss.com/docs/detecting-classes-in-source-files#dynamic-class-names

> Don't use props to build class names dynamically
(クラス名を動的に構築するためにプロパティを使用しないでください)


## 解決方法
公式通りに完全なクラス名で記述する
```ts
// importは省略

type Props = {
 color: 'red' | 'blue'
 text: string
}

const colorVariants = {
 red: 'text-red-500',
 blue: 'text-blue-500'
}

export const SampleComponent: FC<Props> = ({ color, text }) => {
 return (
  <div className={twMerge('font-bold text-md', colorVariants[color])}>
    { text }
  </div>
 )
}
```

Tailwindはビルド時に静的に検出可能な完全なクラス名にプロパティをマップするため
上記の記述であれば期待通りに動作する
Windowsバッチ(.bat)学習メモ　演算子

* 四則演算子
・`+`：足し算
・`-`：引き算
・`*`：掛け算
・`/`：割り算

<br>

* 比較演算子
・`==` または `EQU`：等しい。**EQU**al
・`!=` または `NEQ`：等しくない。**N**ot **EQ**ual
・`>` または `GTR`：より大きい。**G**rea**T**e**R**
・`>=` または `GEQ`：以上。**G**reater than or **EQ**ual
・`<` または `LSS`：より小さい。**L**e**SS**
・`<=` または `LEQ`：以下。**L**ess than or **EQ**ual
**if文等では、記号表現を利用すると落ちてしまう！**
**必ずアルファベット表現を使用すること！**
というか常にアルファベット表現を使用するようにしていれば良いのかもしれない

<br>

* 論理演算子？
`コマンド 論理演算子 コマンド`の形で使用する。
（例：set echo target && echo success）

・`&&` 
`左側のコマンドが成功した場合、右側のコマンドを実行する`という意味。
**`※左側の記述がTRUEだった場合、右側の記述を実行する`という意味ではない！**
なお「コマンドが成功した」というのは、「コマンドを実行した直後のERRORLEVELが0である状況」のことを指す。<details><summary>例外：左側のコマンドに「set /a aaa=www」のようなものを配置した時</summary>計算式として「www」をセットしようとするため勿論失敗するが、これはあくまでも変数aaaに値をセットできなかっただけという扱いになり、ERRORLEVELの値は0のままとなるらしい（仕様？）。よってこの場合、右側のコマンドは実行される。</details>
・`||`
`左側のコマンドが失敗した場合、右側のコマンドを実行する`という意味。
**`※左側の記述がFALSEだった場合、右側の記述を実行する`という意味ではない！**
なお「コマンドが失敗した」というのは、「コマンドを実行した直後のERRORLEVELが0ではなかった状況」のことを指す。

・`|`（パイプ）**かなり便利。**
左側のコマンドによる標準出力結果を、次のコマンドへの入力として扱う。
<details><summary>（例：type origin.txt | find "20250125" | sort > result.txt）</summary>
origin.txtの内容を出力→その出力のうち"20250125"を含む行を抽出し出力→その出力をソートし、result.txtに出力する。</details>

<br>
.gitignoreに記載したのにファイルがプッシュされてしまう原因と対処法


機密ファイルを.gitignoreで指定し、非公開指定したにもかかわらず、Githubにコミット＆プッシュされてしまう事例があったので、原因と対処法を記します。

## 最初にやったこと（失敗したこと）

やったことは普通です。非公開にしたい.envファイルと同じ階層に.gitignoreファイルを作成し、.envファイルを非公開にするよう指定しました。

```markdown
📂 プロジェクト
├── 📄 その他ファイル
├── 📄 .env
└── 📄 .gitignore
```
```
# 環境変数ファイル
.env
```

そして、プロジェクト全体をgitにプッシュ。これで、.env以外のファイルのみがGithubに公開される見込みでした。

```bash
$ git add .
```

```bash
$ git commit -m "コミットメッセージ"
```

```bash
$ git push origin ブランチ名
```

しかし、残念なことに.envファイルはアップロードされてしまっていました。正しい手順で行ったはずなのに、なぜ？

## 非公開指定が効かなかった原因

原因究明は、こちらの記事のおかげでできました。この執筆者と同じく、私も一度gitにアップしていたものを非公開指定したことが原因でした。キャッシュにインデックスが残っているため、.gitignoreの設定が反映されなかったということです。

[.gitignoreに記載したのに反映されない件 - Qiita](https://qiita.com/fuwamaki/items/3ed021163e50beab7154#comments)

## 対処

### 対処１ Githubのコミットを削除する

何はともあれ、公開してしまった機密ファイルを削除しなければなりません。削除にあたっては、次の点を押さえないといけません。とくに、ローカルファイルまで以前の状態に戻してしまわないよう注意が必要です。

- Github上のコミットは、１つ前のコミット時の状態に戻すこと
- ローカルファイルは最新の状態を維持すること

つぎのコマンドで意図するとおりに処置できます。

```bash
$ git reset --soft １つ前のコミットハッシュ
```

```bash
$ git push origin ブランチ名 --force
```

### 対処２ キャッシュを削除し、再コミットする

キャッシュの削除は、次のコマンドで処置できます。先ほど参照した記事でも同じ手法が紹介されています。

```bash
$ git rm -r --cached .
```

`rm .` という物騒なコマンドですが、キャッシュを削除するだけです。しかし、不安な方はプロジェクトをどこかにコピペするなどし、バックアップをとっておくと良いでしょう。
## 感想
QiitaやZennで検索してみると、かなり多くの人が直面したことのある症状でした。エンジニアをやる以上、誰しもが一度は通る道なのかも？いずれにせよ勉強になりました。
Rasberry Pi Codec Zero オーディオボード

Rasberry Piで作ったSIPカメラをドアホンにすべく、raspi用のオーディオボードを買いました(raspi zero 2 wも買いました)。Rasberry Pi(IQAudio) Codec Zeroです。
ドキュメントは[Raspberry Pi Audio](https://www.raspberrypi.com/documentation/accessories/audio.html)、 [IQaudio
Product Guide](https://cdn.sparkfun.com/assets/e/6/5/a/9/20201209_IQaudIO_v32.pdf) にあります。
ピンヘッダをつけ、Codec Zeroをつけると、自動認識されました(bookwormです)。
スピーカーは、3.5cmのものを付けました。
```
$ git clone https://github.com/raspberrypi/Pi-Codec.git
```
をし、\<username\>を自分のに置き換えて、
```
$ sudo alsactl restore -f /home/<username>/Pi-Codec/Codec_Zero_OnboardMIC_record_and_SPK_playback.state
```
として、ボリュームなどを読み込みます。
```
$ aplay /usr/share/sound/Noise.wav
```
で、"さー"という音がでます。

マイクの方は、~~baresipを設定して使えるようになってから確認しました。~~
```
$ arecord -f cd test.wav
```
で、録音して(Ctrl-Cで止めます)
```
$ aplay test.wav
```
で、確認できます。
ip routeでは物足りない. 新しいルーティングテーブルを追加する.

# これはなに？

Ubuntu24.04のネットワークのルーティングの設定において新しいテーブルの追加方法を紹介する.

日本語の資料ではルーティングテーブルにルートを追加する方法を紹介してるものがあってもテーブルの追加は全く見つけられない.

新しいテーブルの追加が何に使えるかというと, 自分は2つのVPN（NordVPN, WireGuard）を共存させるために必要だった.

ルーティングテーブルの編集や追加と聞けば

```
ip route add 192.0.2.1 via 10.0.0.1 eth0
```

というコマンドしか思いつかない人は少なくないだろう. 実際, 私も数週間前までそうだった.

しかし, 多くの人は意識していないが, 上記のコマンドは**mainというルーティングテーブルにルートを追加しろ**というコマンドなのだ. これは **他にもテーブルが存在している** ことを暗示している.

NordVPNは自動的にテーブルを作成する. そのためNordVPNを利用してるPCでテーブルも含めてルーティングを確認すると

```
# ip route show table all
default dev nordlynx table 111 scope link 
999.99.0.0/99 dev nordlynx table 111 scope link 
default via 888.888.888.1 dev ens1 proto static 
999.99.0.0/99 dev nordlynx proto kernel scope link src 999.99.0.66
(以下略）
```

のような出力を得られる. この出力にテーブルの番号が含まれているのがわかる. オプションの *show table all* を書かずに *ip route* で表示されるのはmainテーブルだけのため, 知らないと怪我をすることもある.

またルートの追加だけでなくテーブルの追加ができるようになると, fwmarkを用いてより高度なルーティングを行えるようになる.

# ルーティングテーブルの追加方法

参考元はRed hat Enterprise Linuxのネットワークガイドの[ポリシールティングについて](https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/7/html/networking_guide/sec-Configuring_Static_Routes_in_ifcfg_files#sec-Understanding_Policy-routing).

Ubuntu24.04ではルーティングの設定をiproute2で行っている. iproute2のルーティングテーブルの設定は */etc/iproute2/rt_tables* に書かれている.

```
# cat /etc/iproute2/rt_tables
#
# reserved values
#
255	local
254	main
253	default
0	unspec
#
# local
#
#1	inr.ruhep
```

この内容から「番号が255, 名前がlocal」のテーブルが用意されることがわかる. 新しくテーブルを追加したいときはこのファイルを編集すればよい. ちなみにこの番号はルーティングのルールで使用する.

今, 100番でhogeというテーブルを作るなら


```
$ cat /etc/iproute2/rt_tables
#
# reserved values
#
255	local
254	main
253	default
100 hoge
0	unspec
#
# local
#
#1	inr.ruhep
```

となるように編集する. 追記して保存するだけでテーブルを利用できるようになる. 実際, この状態で

```
# ip route add 0.0.0.0/0 dev ens1 table 100
```

を実行するとルートが正常に追加できる. 確認してみると

```
# ip route show table 100
default dev ens1 scope link 
```

のようにちゃんとユーザが独自に追加したルーティングテーブルにルートが追加されているのがわかる. 素晴らしい.

以上.
【無料で使える】ローカルのDeepSeek-R1をRoo Codeで使うための拡張設定


[前回の記事](https://qiita.com/yonaka15/items/a69790be6eacd726f770)で解説したDeepSeek-R1のローカル実行環境は、そのままではRoo Codeでは使用できませんでした。この記事では、Roo Codeで使用するための追加設定について解説します。

## 問題の背景

DeepSeek-R1をRoo Codeで使用する際、デフォルトのコンテキストウィンドウサイズでは十分な性能を発揮できません。これを解決するには、モデルのコンテキストウィンドウサイズ（num_ctx）を拡張する必要があります。

## 環境要件

- Ollama v0.5.7以降
- DeepSeek-R1モデル（いずれかのバリエーション）
- 32GB以上のRAM（推奨）

## 設定方法

### REST APIを使用する方法（推奨）

```bash
curl http://localhost:11434/api/create -d '{
  "name": "deepseek-extended",
  "from": "deepseek-r1:14b-qwen-distill-q4_K_M",
  "parameters": {
    "num_ctx": 32768,
    "temperature": 0.7
  }
}'
```

### Pythonクライアントを使用する方法

```python
import ollama
ollama.create(
    model="deepseek-extended",
    from_="deepseek-r1:14b-qwen-distill-q4_K_M",
    parameters={
        "num_ctx": 32768,
        "temperature": 0.7
    }
)
```

### 設定の確認

```bash
# インストール済みモデルの一覧を表示
ollama list
```

## パラメータの説明

- `name`: 新しく作成するモデルの名前
- `from`: ベースとなるモデル
- `num_ctx`: コンテキストウィンドウサイズ（推奨: 32768）
- `temperature`: 生成時のランダム性（推奨: 0.7）


## 結果

ローカルモデルなので品質はあまり高くありませんが、**無料で使える** ところは大変魅力です

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">ローカルのDeepSeek-r1でRooCode動かせました。ローカルなので無料 <a href="https://t.co/KMvD2M6Sf8">pic.twitter.com/KMvD2M6Sf8</a></p>&mdash; よなか (@yonaka158) <a href="https://twitter.com/yonaka158/status/1884149115925528593?ref_src=twsrc%5Etfw">January 28, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## トラブルシューティング

### よくある問題と解決方法

1. **"neither 'from' nor 'files' was specified"エラー**
   - 原因：Modelfileを使用しようとすると上記のエラーが出ました
   - 解決：新しい構文（上記のAPI利用など）を使用する

2. **メモリ不足エラー**
   - 原因：コンテキストサイズが大きすぎる
   - 解決：num_ctxの値を下げるか、メモリを増設

3. **接続エラー**
   - 確認：Ollamaサービスが起動しているか（ポート11434）

## 参考情報

- [DeepSeek-R1 Issue #28](https://github.com/deepseek-ai/DeepSeek-R1/issues/28) - コンテキストサイズの議論
- [Ollama Issue #8468](https://github.com/ollama/ollama/issues/8468) - 新しい構文の説明
- [Ollama API Documentation](https://github.com/ollama/ollama/blob/main/docs/api.md)
【2025年最新】discord.jsでのephemeralメッセージの送信方法+α

こんにちは、りょうですー
今回は現在のephemeralメッセージの送信方法と、一部のMessageFlagsについて書く。
なんかephemeral: true使うと警告が出始めて、調べてたら変わってた()
# Ephemeralメッセージ(一時メッセージ)を送信しよう
これはコマンドを実行した人にしか見えない返信のこと。青いやつね。
これはinteractionの **`reply()`** か **`followUp()`** のときにしか使えないから注意。
ふつうのmessage.replyとかsend()では動作しないよ

```diff_javascript
- await interaction.reply({ embeds: [embed], ephemeral: true });

+ const { MessageFlags } = require('discord.js');
+ await interaction.reply({ embeds: [embed], flags: MessageFlags.Ephemeral });
```

# リプライ時などに使いそうなもの
- **MessageFlags.Ephemeral**
先ほども紹介したephemeralメッセージ。これは一番使うことが多そうだね

![Screenshot 2025-01-27 23.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/2c4dabd3-0fc3-1be9-1c49-2af73b8e65de.png)

- **MessageFlags.SuppressEmbeds**
メッセージ中のEmbedを表示しないようにするためのフラグ。
Embedが発生するリンクを送信するときとかに使うかな。
もしこのコードの状況で使った場合は実行はされるけどなにも表示されない変な感じになる
```suppresembeds.js
await interaction.reply({ embeds: [embed], flags: MessageFlags.SuppressEmbeds });
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/7fdfa6fa-694e-b874-c702-a5b5ab3d248e.png)

- **MessageFlags.SuppressNotifications**
メッセージ通知を飛ばさないようにするためのフラグ。時間の横にマークがでる。
reply()だけじゃなくてsend()でも使うことはありそうなやつだね

![Screenshot 2025-01-27 23.33.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/f5d092a0-b74a-1528-8ded-710dadcedcf1.png)

# まとめ
わからないことがあったらコメントしてもらえれば。

**Discordに湧く荒らしの情報や対策方法の共有をしている自鯖です**
よければぜひ参加を↓

https://discord.com/invite/ESRGwGQhxc

# 参考
https://discordjs.guide/slash-commands/response-methods.html#ephemeral-responses

https://discordjs.guide/slash-commands/response-methods.html#follow-ups

https://discord.js.org/docs/packages/discord.js/14.17.3/MessageFlags:Enum
AWS App Runner vs ECS Fargate 最小構成維持費比較

AWS App Runner vs ECS Fargate 最小構成維持費比較
# ECS + Fargate(AMD64)
1core $0.0506	
1GB $0.0055
ALB $0.0243
ALB 1 IPv4 $0.005

# App Runner 
1core $0.0810	
1GB $0.0090

# 最小構成
どちらも0.25core / 0.5GB 
App Runnerはアクセスが無い時はCPU料金がかからない
ストレージとか通信費は除く
150円/$ 換算

|  | CPU ($/h) | MEM ($/h) | ALB ($/h) | ALBのIP ($/h) | 合計 ($/h) | 合計 ($/月) | 合計 (¥/月) |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| ECS + Fargate | $0.0126 | $0.0028 | $0.0243 | $0.0050 | $0.0447 | $32.19 | ¥4,828 |
| App Runner (稼働率2割) | $0.0041 | $0.0045 |  |  |  $0.0086 | $6.16 | ¥923 |
| App Runner (稼働率5割) | $0.0101 | $0.0045 |  |  | $0.0146 | $10.53 | ¥1,580 |
| App Runner (稼働率10割) | $0.0203 | $0.0045 |  |  | $0.0248 | $17.82 | ¥2,673 |

テスト環境とか最小構成だとAppRunner安いすね。

台数が増えてもALB分は変わらないので、台数増えて稼働率が変わるとALBの方が安くなりそう
個人的な備忘録：Dockerを使ってAmazon Linux 2環境に入ってみたら、めちゃくちゃ軽量だった

## はじめに
Amazon Linux 2は、AWS（Amazon Web Services）で提供されるAmazon EC2インスタンスのデフォルトOSとして利用されています。

:::note info
**Docker上でAmazon Linux 2を動かしてみたところ、さまざまな操作が手軽にできることがわかったので、その経験を共有したいと思いました。**
:::

この記事は自分の備忘録を中心にまとめた内容です。***温かい目で読んでいただけると幸いです。***

## 書こうと思ったきっかけ
S3バケットとLambda関数の技術検証を進める中で、Amazon Linux 2をDocker環境で動かしてみる機会がありました。

:::note warn
***ローカル環境で手軽に試せるという利便性や、実際のAWS環境に近い設定で動作確認ができる点が非常に魅力的でした。***
:::

その結果、予想以上に新鮮で学びの多い体験が得られたため、この記事を通じてその経験を共有し、同じようなシチュエーションで役立ててもらえればと思いました。

## DockerでAmazon Linux 2環境に入る目的
Docker上でAmazon Linux 2を動かすことで、以下のようなAWS環境をローカルでシミュレーションできます。

- アプリケーションの動作確認
- パッケージや依存関係のインストールテスト
- システム設定の検証

本番環境がAmazon Linux 2を利用している場合、Dockerを使って同じ環境をローカルマシンに再現することで、開発・テスト効率を大幅に向上させることができます。

***これにより、環境ごとの動作の違いや依存関係の問題を早期に発見することが可能です。***

## めちゃくちゃ軽量で驚いた

Amazon Linux 2のDockerイメージは、非常に軽量で効率的です。実際の仮想マシンやクラウドインスタンスを立ち上げるよりも、簡単かつ素早くローカル環境で実験できます。

**例えば、以下のコマンドでAmazon Linux 2の環境をすぐに利用できます。**

```bash
docker run -it amazonlinux:2
```

実行後、プロンプトが以下のように表示されれば成功です。

```bash
bash-4.2#
```

Amazon Linux 2を使用するAWS環境での運用管理スキルを高めるために、ローカル環境でOSに慣れる目的でDockerを利用するケースもあるようです。

## まとめ
Docker上でAmazon Linux 2環境を使用することは、AWS本番環境に近い開発・テスト環境を効率的に構築するための有効な手段です。

:::note info
**これにより、開発者や運用チームはAWS環境への適応をスムーズに進めることができ、アプリケーションやシステム構成の検証を迅速かつ正確に行うことが可能です。**
:::

***この記事は短い内容でしたが、誰かの技術向上や作業効率化の一助になれば幸いです。***
【AgileWorks】数値フィールドでgetValue()を行うと未入力でも0が返される

## はじめに
以前、AgileWorks の入力チェックで
**金額欄がブランク**だったらエラーを出すように開発した時の話です。

## 問題

何も考えず以下のようにソースコードを書いてテストを行ったところ、
金額欄の項目には何も入力していない（ブランクの状態の）はずなのに
if文の中は通りませんでした。

```javascript
var money = table.getField(row, "money").getValue();

if(money = "")
{
    // エラー処理
}
```

## 解決策
結論、金額欄の値を呼び出している箇所を
getValue()からgetTextValue()に変えれば
ブランクかどうかの判定ができるようになりました。

```javascript
var money = table.getField(row, "money").getTextValue();

if(money = "")
{
    // エラー処理
}
```

## さいごに
数値フィールド、整数フィールドの設定値を**文字列のまま取得**する場合は
getTextValue()を使う必要があるみたいです。

逆を言えば、
数値フィールド、整数フィールドは内部的に初期値0が格納されているようなので注意が必要です。
Arduino IDE: Ubuntu 24.10 で動かす

## プログラムのダウンロード

[Software Downloads](https://www.arduino.cc/en/software) から次の実行プログラムをダウンロード

```text
arduino-ide_2.3.4_Linux_64bit.AppImage
```

## 実行

```bash
./arduino-ide_2.3.4_Linux_64bit.AppImage
```

実行結果

```text
$ ./arduino-ide_2.3.4_Linux_64bit.AppImage 
[20126:0128/163221.056477:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /tmp/.mount_arduinSfh5rh/chrome-sandbox is owned by root and has mode 4755.
Trace/breakpoint trap (コアダンプ)
```

## 解決方法

```bash
./arduino-ide_2.3.4_Linux_64bit.AppImage --no-sandbox
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f4d98a40-babb-9b37-9750-cb364de63980.png)
.NETのお勉強2_ホットリロード

# 概要
AmazonLinux2023インスタンス上にコンテナで.NETを利用したサーバをたてる
そのお勉強メモ2

C#だから当然と言えば当然だけど、phpと違って毎度ビルドしないといけないの超面倒
どうにかしたい

# ホットリロード
sdkイメージにも簡易なwebサーバが入っているらしく、これを使うことでビルド成果物をruntimeイメージ通さずに = 都度ビルドせず更新内容の反映が可能

# ソース
``` Makefile
hotload:
	docker compose -f docker-compose.hotload.yml up -d
```

``` docker-compose.hotload.yml
services:
  build:
    image: builder
    build:
      context: .
      dockerfile: Dockerfile.build
    volumes:
      - ./src:/src
    ports:
      - "80:8080"
    command: dotnet watch run --urls=http://0.0.0.0:8080
```

# 実行テスト
`make hotload`実行してコンテナを立ち上げ、xx.xx.xx.xx/helloアクセスで「Hello from API!」表示を確認した後、HelloController.csの出力メッセージを変更してブラウザ更新後に変更が反映されてればok

# 注意点
万能ではないっぽい
もちろん本番環境はビルド後プロジェクトをruntimeイメージで動かす必要があるし、変更内容によってはビルドし直しも必要

| **変更内容**                     | **再ビルドの必要性** | **即時反映** |
|----------------------------------|----------------------|--------------|
| メソッドの中身を変更             | 必要なし             | 可能         |
| 既存のコントローラーのロジック修正 | 必要なし             | 可能         |
| 新しいクラスやコントローラーの追加 | 必要                | 不可         |
| プロジェクトファイル（`.csproj`）の変更 | 必要                | 不可         |

# トラブルシューティング
ホットリロードした内容でエラーが出る場合はコンテナログを確認すればエラーログが出力される
逆に問題がなければ以下のメッセージがログに出力される
```
dotnet watch 🔥 [MyServerApp (net9.0)] Hot reload succeeded.
```
【ServiceNow】メールのステータスが"Ignored"になる

# はじめに
CSMの開発PJで、開発環境でメール通知のテストを実施していたところ、送信箱（sys_emailテーブル）にあるいくつかのメールのステータスが **"Ignored"**（無視）となる事象が発生しました。

本稿では、この **"Ignored"** の謎についてチームで調査した結果を残しておきます。

:::note info
調査していたインスタンスでは **メールの送信設定をOFF**（実際のメールが送信されない設定）にしているため、メールが正しく送信されたかの確認は、インスタンス内の送信箱から確認します。
:::

**【前提知識 - 各ステータスの意味】**
Ready：送信準備完了（＝送信され待ち状態）
Error：エラー
Ignored：メール送信が無視される（＝送信されない）
Processed：送信完了

# 事象
１つのレコードに対して、複数の操作を実行します。
例：インシデントへのコメント追加・ソリューション提案の更新

すると、操作が実行されたタイミングでそれぞれのメールが送信箱に生成されていますが、
生成されたほぼすべてのメールのステータスが、 **"Ignored"** になりました。
また、操作の中で最後に送信されたソリューション提案通知メールのみ、ステータスが **"Ready"** になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3335478/f3d97c5b-80c4-f87e-d8ee-dae958cde0f5.png)

# メールが **"Ignored"** ステータスとなる仕組み
<a href="https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0755061">「SMTP Sender」</a>というOOTBのスケジュールジョブによって、ステータスが **"Ignored"** になっていることが判明しました。
→「SMTP Sender」は2 分ごとに実行されるようにスケジュールされたジョブで、インスタンス上に保持されているすべての送信準備完了（ステータス＝Ready）メールを送信する（ステータス＝Processedにする）役割を果たします。
すべての送信準備完了メールがインスタンスから消去されるまで、実行は継続されます。

そこで、優先度の比較によって送信されない判断をされたメールが、ステータスが **"Ignored"** に更新されます。
※メールの優先度は通知（sysevent_email_action）テーブルの<a href="https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0829694#:~:text=The%20default%20value%20weight%200,assuming%20the%20conditions%20are%20met).">weight</a>の値で定義されます。

<br>

 **メールが実際に送信されるまでの流れはこんな感じ↓**

① イベント実行
イベントがトリガーされる（例: コメントが追加される）

② メール生成
weightに関係なく、通知条件が満たされる かつ 有効な受信者が存在する場合、送信箱（sys_emailテーブル）にメールが生成される。
<font color="orange">この時点でステータスは **"Ready"** <font>

③ スケジュールジョブ実行
ステータスが **"Ready"** かつ メールの'Recipient' と 'Target' がまったく同じである場合、最もweightの値が大きいメールと、weight=0 のメールのみが実際に送信される。
<font color="orange">送信されたメールは、ステータスが **"Processed**" に更新される<font>
<font color="orange">残りのメールは、ステータスが **"Ignored"** に更新される<font>

※同じ通知の場合は、作成日時が新しいほうが送信される
※メールの送信設定がOFFの場合はメールが送信できないため、"Ready"から更新なし
<br>
よって、インスタンスのメール送信設定をOFFにしていることにより、
ステータスが **"Ready"** のメールが滞留するため、複数のメールで③の比較がされて **"Ignored"** のメールが存在していた、ということでした。
<br>
メール送信設定をONにしている場合は、
③で各メールのステータスが順次 **"Processed**" に更新されるため、**"Ready"** でメールが滞留することは稀です。
そのため、本事象は発生しないと思われます。

# おわりに
前述の通り、メール送信設定がONの環境では、通常このような事象は発生しません。

ですが、弊社と同じように開発・テスト中のメール誤送信防止のため、インスタンスのメール送信設定をOFFにしている方も多いと思いますので、頭の片隅に入れておくと良いかと思います。

# 参考記事

https://www.servicenow.com/community/united-kingdom-snug/notifications-email-notification-weight-examples/ba-p/2271497
SimpleBarでクラスを対象にしてスクロールイベントを取得する書き方

## SimpleBarについて
Webページのスクロールバーを簡単にカスタマイズできるjavascriptライブラリです。

公式ドキュメントは[こちら](https://github.com/Grsmto/simplebar/tree/master/packages/simplebar)

## やりたいこと
例えば利用規約などの領域をスクロールで読ませて、その後チェックボックスにチェックができるような機能を想定する。
その導線が複数ある時に、利用規約を1回読むと他の箇所も連動してチェックされるような処理を行いたい。

・jQueryを使用した記述をする
・スクロールバーの見た目を同じにしたいので、クラスに対して適用する
・オプションの「スクロールバーの自動非表示」を「flase」にする
・スクロールイベントを取得して続く処理を記述する

## 方法
公式ドキュメントを見ながら考えて色々つまずきましたが、以下のコードで実現できました。
```javascript:script.js
//適用したいクラスを取得してeachで回す
$('.className').each(function () {
    //simplebarのインスタンスを作成してオプションを適用する
    const simpleBar = new SimpleBar(this, { autoHide: false });
    //スクロールイベントを取得する
    simpleBar.getScrollElement().addEventListener('scroll', function (event) {
      //続けたい処理を記述（チェックボックスのチェックがされるような）
    });
});
```

## つまずいた箇所
公式ドキュメントのjQueryを使用する方法の記述として以下が書かれています。
「If you want to use jQuery:」の箇所。
【idの場合】
```javascript:
new SimpleBar($('#myElement')[0]);
```

【クラスを使用する場合】
```javascript:
$('.myElements').each((el) => new SimpleBar(el));
```

元々idを取得した以下の書き方で動かしていた。
```javascript
  const simpleBar = new SimpleBar($('#idName')[0],{ autoHide: false });
  simpleBar.getScrollElement().addEventListener('scroll', function(event){
      //処理
  );
```
で、上記の【クラスを使用する場合】の記述を無視して「#idName」の箇所を「.className」をクラス名に変更した。
当然eachがないので、最初に出てきたクラスのみ処理が適用される動きになった。

## 参考

https://github.com/Grsmto/simplebar/tree/master/packages/simplebar#1-documentation

https://qiita.com/FumioNonaka/items/40d9b2a196a8a2ee52bd