OmniAICreator/Qiita-1.07M huggingface dataset:
Next.jsでexport(SSG)して、MicroCMSも使って画像最適化もしたい欲張りさんへ


MicroCMSを使ってレンタルサーバーにNext.jsをデプロイしたい、尚且つ画像はビルド時にダウンロードすることによってMicroCMSのデータ転送量を節約＆画像の最適化したかった。
こんな欲張りさんは自分だけかもしれない。
## Next Export Optimize Imagesを使って画像を最適化
レンタルサーバーにデプロイするために```output: "export"```(SSG)をしたかったので```next/image```の最適化は使えなかった。
```Next Export Optimize Images```を使って最適化した。
https://next-export-optimize-images.vercel.app/

## MicroCMSからダウンロードされる画像の最適化
```export-images.config.js```の```remoteImages```に画像のURLの配列を渡すとビルド時にダウンロードして最適化してくれる。すごい。
```js:export-images.config.js
module.exports = {
  remoteImages: ['https://next-export-optimize-images.vercel.app/og.png'],
  // remoteImages: async () => {
  //   const imageUrls = await getImageUrls() // get image urls from CMS, etc.
  //   return imageUrls
  // }
}
```

## 画像が日本語ファイル名の場合の対応
このままだと画像が```あいうえお.jpg```みたいなファイル名の場合、
URLエンコードされて```%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A.jpg```みたいなファイル名になる。
そうするとNext.jsで画像を表示できなくなる。多分。
この問題をどうしようか何時間も考えた。
```export-images.config.js```の```filenameGenerator```を使ってURLデコードすればいけた。
```js:export-images.config.js
filenameGenerator: ({ path, name, width, extension }) => {
	const fileName = `${path.replace(/^\//, "").replace(/\//g, "-")}/${decodeURIComponent(name)}.${width}.${extension}`;
	console.log(fileName);
	return fileName;
},
```

## 終わり
こんな事したい人がほかにいるか分かりませんが、参考になれば幸いです。
【備忘録】Next.js（App Router）でメタデータを設定する

## 環境
```
next: v14.2.3
```

## 設定方法
Next.js（App Router）では、メタデータを設定する方法として静的および動的な設定方法が用意されている。
これら実装方法について、簡単な例を交えて残す。

### 1. 静的な設定（オブジェクト`metadata`）
Pageファイル、またはRoot Layoutファイルにて、オブジェクト`metadata`をエクスポートすることで、簡単に静的なメタデータを設定可能。
下記例は、ページのタイトルを設定している。
```page.tsx
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Qiita',
};

export default function Page() {
  return (
    // 省略
  );
}
```

### 2. 動的な設定（関数`generateMetadata`）
動的な情報（現在のルートパラメータや外部情報、親セグメントの`metadata`など）を利用して、`Metadata`オブジェクトをエクスポートすることで、メタデータを動的に設定可能。
下記例は外部から取得したタイトルを設定している。
```page.tsx
import type { Metadata } from 'next';

export async function generateMetadata(): Promise<Metadata> {
  const fetchedTitle = await fetch('https://...')
    .then((res) => res.json())
    .then((json: { title: string }) => json.title);

  return {
    title: fetchedTitle,
  };
}

export default function Page() {
  return (
    // 省略
  );
}
```

### 3. 実装時の注意
- オブジェクト`metadata` と関数`generateMetadata` は**サーバーコンポーネントのみ**サポートされている。
- 一つのRoute Segmentでオブジェクト`metadata` と関数`generateMetadata` を両方エクスポートできない。どちらか一方のみ実装する必要がある。

## 参考文献
https://nextjs.org/docs/14/app/api-reference/functions/generate-metadata
OCI ログ・サービスの違い

OCIの運用では、Monitoringサービスによる定常的な性能監視だけでなく、問題発生時にログから原因の特定や対応策を導き出すということがよくあります。その際に役立つログサービスですが、OCIには以下の二つがあります。
- Logging (ロギング)
- Logging Analytics (ログ・アナリティクス)

それぞれのサービスには異なる開発背景があり、LoggingはOCIの開発に合わせて作成されたOCIネイティブのログ・サービス、Logging Analyticsは旧PaaSのOracle Management Cloudのログ機能がOCIに移植されたものです。お互い独立したサービスとして存在し求められる役割としても異なっているので、ここではその違いについて紹介したいと思います。

## Logging
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/3efcbb72-79f5-d0f3-d281-dd397171a06c.png)
スライドにある通り、Loggingが提供する主な機能として<font color=blue>監査ログ、サービスログ、カスタムログ</font> の３種類があります。監査ログは設定必要なく強制的に出力されますが、後の二つはユーザー側で明示的に設定することでログが出力します。

<font color=blue>監査ログ</font>は、OCI上での作成・削除といった操作ログだけでなく、ユーザーのログインに関するログも記録されているので、運用・セキュリティに関して役立つ情報が多いです。
<font color=blue>サービスログ</font>は、使用するサービス毎に専用のログ、例えばLoad BalancerやVCNなどのネットワーク系ではIn/Outのログ、Object StorageだとRead/Write等が用意されています。
<font color=blue>カスタム・ログ</font>は、OS内のログを対象としますが、この部分はLogging Analyticsのほうが柔軟に対応することができるので、LoggingとLogging Analyticsを併用する場合は、LAに任せたほうが良いかと思います。

また、Loggingのログは長期保管ができないので、数年単位でログを保管しておくには外部にエクスポートしておく必要があります。エクスポートしたものは再度Loggingにインポートすることはできません。
ログの検索用のコンソールが用意されていますが、検索機能としてはLogging Analyticsと比較するとかなり簡易的なものという印象です。

## Logging Analytics
Logging Analyticsは、OS内にある様々なログを対象にします。クラウド上のログ基盤というのがサービスのコンセプトなので、Loggingを含めたOCI上のログだけでなく、オンプレミスも対象に幅広いプラットフォームのログを集約し、柔軟なログ分析と長期保管を提供します。また、OCIの監査ログやサービスログを取集するためには、必ずLogging + Connector Hubを経由する必要があります。

もともとはPaaSサービスとして独立していたログ基盤サービスだったので、ログの分析やビジュアライズなど多機能で使いやすいという印象です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/9e6ffcaf-6448-7ec4-b2b5-643283692bb9.png)

それぞれのサービスの詳細機能についてはspeakerdeckにあるスライドでご確認下さい。
[OCI 運用監視サービス 概要 ](https://speakerdeck.com/oracle4engineer/oracle-cloud-observability-and-management-platformgai-yao)

## LoggingとLogging Analyticsの比較
実際のOCIユーザーは、どちらか一方だけのサービスしか使っていなかったり、併用していたり様々です。それぞれのサービスの特徴を改めて下記のような観点で比較してみました。

|  | Logging | Logging Analytics |
| ---- | ---- |---- |
| OCI 監査| 〇 | × |
| OCI サービスログ | API Gateway, Email Delivery, Events, Functions,Integration,Load Balancers, Object Storage, VCN, VPN, WAF, Network Firewallなど多数 |× |
| OS内のログ| テキストファイル | テキストファイル, DB表 |
| 定義済みログフォーマット| SYSLOG, Apache等 | 様々なOS, DB, Middlewareに対応した200種類以上のログフォーマット|
| 独自ログの対応| 〇 (REGEXP) | 〇 (REGEXPガイド付き)|
| 検索機能| △ (簡易的な検索とグラフ) | 〇 (クラスタ分析や異常値抽出などの機械学習分析、多彩なビジュアライゼーション)|
| ダッシュボード| × | 〇|
| アラーム通知| 〇 | 〇|
| ログの保持期間| 監査 (最大365日), サービス/カスタムログ (最大6カ月) | 制限なし|
| データ連携| Logging Analytics, Streaming, Object Storage, Functionsなど (Connector Hub経由) | monitoringサービス, csv, json形式でのエクスポート|
| コンピュート内のログ取得時に必要となるエージェント | クラウド・エージェント| 管理エージェント|
| エージェントが対応するプラットフォーム | OCIのプラットフォーム・イメージまたはそれに基づくカスタム・イメージから作成されたコンピュート Oracle Linux, CentOS, Ubuntu, Windows Server| Oracle Linux, Red Hat Enterprise Linux, CentOS,Windows Server, Windows Desktop, Oracle Solaris|
| エージェントが対応するインフラストラクチャ| OCI | OCI, オンプレミス, 他社クラウド|
| エージェントのゲートウェイ方式| × | 〇|

Logging Analyticsを使用するための各種設定にはついては、[こちら](https://qiita.com/western24/items/4824e4b3799b824197c6)の運用管理の記事をご参照下さい。
Macbook Pro 2019 16インチで5k2kと4kに同時出力できるTB3ドック

BelkinのThunderbolt3ドックでできました。
あまり成功例を見かけなかったので記録として残します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380862/cec3a51c-dddc-141f-69fe-79d63f11f2ba.png)
【Excel】VBAで [USERNAME] を取得する方法

VBAでユーザー名を取得する方法について覚書

（１）一番シンプルな方法　（非推奨）
```VB:username01
Dim username as String
username = Environ("USERNAME")
```

・ユーザー名をVariant型で返す（型変換が自動）
・エラーが発生しやすい

（２）シンプルな方法($つきバージョン）

```VB:username02
Dim username as String
username = Environ$("USERNAME")
```

・ユーザー名をString型で返す
・エラーが発生しにくい

（３）Windowsの環境変数を取得する別のアプローチ

```VB:username03
Dim username as String
username = CreateObject("WScript.Shell").ExpandEnviromentString("%USERNAME%")
```

Windowsの環境変数を取得するのに、VBScriptを利用

（４）システム関数を使用する方法
```VB:username04
Dim username as String
username = Environ$("USERPROFILE")
username = Mid(username, InStrRev(username, ""+1)
```

USERPROFILEパスから直接ユーザー名を抽出
パス全体から最後のフォルダ名（ユーザー名）を取得
※システム環境によってはユーザー名が取得できないかも・・・


【まとめ】
セキュリティ設定などの実行環境によって仕様できるコードが変わる
Dockerfileの書き方

## **1. Dockerfileとは？**

- Dockerfileとは、**Dockerのコンテナを作るための設計書**です。

例えば、「Webアプリを動かす環境」を準備するには、次のような手順が必要です。

✅ OSの準備（Linuxなど）

✅ 必要なソフト（Python, Node.js, Javaなど）のインストール

✅ アプリのコードをコピーする

✅ アプリを実行する

普通は手動でセットアップする必要がありますが、Dockerfileを使えば、**これらの作業をすべて自動化できます！**

---

## **2. Dockerfileの基本構造**

Dockerfileには、「何を準備するか」を1行ずつ書いていきます。

基本の書き方は、次のようになります。

```ruby:dockerfile

# 1. ベースイメージを指定
FROM python:3.9

# 2. 作業ディレクトリを指定
WORKDIR /app

# 3. 必要なファイルをコピー
COPY . /app

# 4. 必要なパッケージをインストール
RUN pip install -r requirements.txt

# 5. 実行するコマンドを指定
CMD ["python", "app.py"]

```

---

## **3. Dockerfileの書き方（コマンド一覧）**

### **① FROM（ベースイメージを指定）**

Dockerコンテナは、必ず「ベース」となるOSや環境を持ちます。

`FROM` を使って、どのベースイメージを使うか指定します。

✅ **例：Python環境を作る場合**

```ruby:dockerfile

FROM python:3.9

```

✅ **例：Node.jsの環境を作る場合**

```ruby:dockerfile

FROM node:16

```

✅ **例：Ubuntu（Linux OS）を使う場合**

```ruby:dockerfile

FROM ubuntu:latest

```

---

### **② WORKDIR（作業ディレクトリの指定）**

コンテナの中で、どのフォルダを使うか指定します。

```ruby:dockerfile

WORKDIR /app

```

この場合、コンテナの中に `/app` というフォルダが作られ、

以降のコマンドは **すべて `/app` の中で実行** されます。

---

### **③ COPY（ファイルをコピーする）**

ローカルのファイルをコンテナ内にコピーします。

```ruby:dockerfile

COPY . /app

```

✔ **「.（カレントフォルダ）」の中身を、「/app」フォルダにコピー** する

例えば、アプリのコードや設定ファイルをコンテナに入れたいときに使います。

---

### **④ RUN（コマンドを実行する）**

コンテナを作るときに、**一度だけ実行するコマンド** を指定できます。

例えば、Pythonのライブラリをインストールする場合：

```ruby:dockerfile

RUN pip install -r requirements.txt

```

✔ **Pythonのパッケージをまとめてインストール**

他にも、Ubuntuでパッケージをインストールするなら：

```ruby:dockerfile

RUN apt-get update && apt-get install -y curl

```

✔ **OSのパッケージを更新＆curlをインストール**

---

### **⑤ CMD（コンテナ起動時に実行するコマンド）**

コンテナが起動したときに、**実行するプログラム** を指定します。

```ruby:dockerfile

CMD ["python", "app.py"]

```

✔ **Pythonで `app.py` を実行**

Node.jsなら：

```ruby:dockerfile

CMD ["node", "server.js"]

```

✔ **Node.jsで `server.js` を実行**

**📌 CMDとRUNの違い**

- **RUN** → コンテナを作るときに **一度だけ** 実行する
- **CMD** → コンテナが起動する **たびに** 実行する

---

## **4. Dockerfileを使ってコンテナを作る手順**

Dockerfileを作ったら、実際にコンテナを作って動かしてみましょう！

### **① Dockerfileを作る**

まずは、プロジェクトフォルダに `Dockerfile` を作ります。

```

my_project/
 ├── app.py
 ├── requirements.txt
 ├── Dockerfile  ← ここに作る！

```

Dockerfileの内容は、例えば次のようにします。

```ruby:dockerfile

FROM python:3.9
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

```

---

### **② Dockerイメージを作る**

Dockerfileを使って、Dockerイメージ（設計図）を作成します。

```ruby:sh

docker build -t my-python-app .

```

✔ **`my-python-app` という名前のDockerイメージが作成される！**

---

### **③ Dockerコンテナを起動**

作成したイメージを使って、コンテナを起動します。

```ruby:sh

docker run -p 5000:5000 my-python-app

```

✔ **アプリが `http://localhost:5000` で動く！**

---

## **5. まとめ**

✅ **Dockerfileとは？** → **コンテナを作るための設計書**

✅ **`FROM`** → **ベースとなる環境を指定する**（Python, Node.js, Ubuntu など）

✅ **`WORKDIR`** → **作業フォルダを決める**

✅ **`COPY`** → **ローカルのファイルをコンテナ内にコピーする**

✅ **`RUN`** → **インストール作業を実行する**（`apt-get` や `pip install` など）

✅ **`CMD`** → **コンテナ起動時に実行するコマンドを指定する**

✅ **イメージを作ってコンテナを起動すればアプリが動く！**

Dockerfileを使えば、どこでも同じ環境を簡単に作れるようになります！
[Python3 / mmcv] TypeError: FormatCode() got an unexpected keyword argument 'verify' の対策

# 1. 問題

MapTR、mmcv、mmdetection3d などを使用しているときに、以下のエラーに遭遇した

```bash
    text, _ = FormatCode(text, style_config=yapf_style, verify=True)
TypeError: FormatCode() got an unexpected keyword argument 'verify'
```

# 2. 環境

item|version
--|--
python|3.8.20
matplotlib|3.5.3
mmcv-full|1.4.0
mmdet|2.14.0
mmdet3d|0.17.2
mmsegmentation|0.14.1
yapf|0.43.0


# 3. 対処法

## 3-1. mmcv のバージョン変更しても良い場合

以下の記事に解決策が書かれている。

https://qiita.com/tkm0707/items/624e1e234dc904fed610#2-typeerror-formatcode-got-an-unexpected-keyword-argument-verify-%E3%81%AE%E5%A0%B4%E5%90%88

## 3-2. mmcv (mmcv-full) のバージョンを維持したい場合

続きに対処法を記載していきます。

### 3-2-1. 原因調査

まず、以下の位置に原因たる行があることを確認しました。

https://github.com/open-mmlab/mmcv/blob/174b647c02aa9f23031ef86a2d2a410234ed76ee/mmcv/utils/config.py#L513C15-L513C77

> text, _ = FormatCode(text, style_config=yapf_style, verify=True)


この `FormatCode` というクラスは、 `yapf` という python ライブラリのクラスであることがわかる。（以下を参照）

> from yapf.yapflib.yapf_api import FormatCode
> 
> https://github.com/open-mmlab/mmcv/blob/174b647c02aa9f23031ef86a2d2a410234ed76ee/mmcv/utils/config.py#L20


### 3-2-2. 対策

そこで、 `yapf` のバージョンを変更することにした。

```python
pip install yapf==0.40.1
Collecting yapf==0.40.1
  Downloading yapf-0.40.1-py3-none-any.whl.metadata (35 kB)
Requirement already satisfied: importlib-metadata>=6.6.0 in /usr/local/lib/python3.8/site-packages (from yapf==0.40.1) (7.2.1)
Requirement already satisfied: platformdirs>=3.5.1 in /usr/local/lib/python3.8/site-packages (from yapf==0.40.1) (4.3.6)
Requirement already satisfied: tomli>=2.0.1 in /usr/local/lib/python3.8/site-packages (from yapf==0.40.1) (2.1.0)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.8/site-packages (from importlib-metadata>=6.6.0->yapf==0.40.1) (3.20.2)
Downloading yapf-0.40.1-py3-none-any.whl (250 kB)
Installing collected packages: yapf
  Attempting uninstall: yapf
    Found existing installation: yapf 0.43.0
    Uninstalling yapf-0.43.0:
      Successfully uninstalled yapf-0.43.0
Successfully installed yapf-0.40.1
```

上記の通り、`yapf` のバージョンを `0.43.0` から `0.40.1` に変更したところ、問題が解決した。
【Power Automate】Teams に投稿/通知の際、改行が正常に反映されない時の対処法

# 概要
Power Automate を利用して Teams に通知のメッセージを飛ばしたい時
複数行のテキストを送信しようとしても改行が適用されずに
文字の羅列のみが送信されて見栄えがよくならないなんてお困りごとはありませんか？

この記事では、Teams へ投稿する際の改行の改善策について取り扱います！

## 完成イメージ
#### 改行されない状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/1919b26a-0a2d-6732-48b8-49acb26aecbf.png)

#### 改行された状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/e051c0c0-8de9-2844-cad6-635b1b9a26fa.png)

# 改行されない原因
なぜメッセージを作成している時は改行を行っているのに、Teams に貼り付けると改行が行われないのかというと、 Teams の改行を行うには `<br>` の設定が必要になります。

ここで先ほどの完成イメージで動かしたフローの中身を見てみましょう。
改行無しのほうの Teams アクション内の「メッセージ」には視覚的には改行は行われていますが、先ほど記述した `<br>` が設定されていません。

反対に改行ありのほうは「メッセージ」に `<br>` が設定されています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/47097dbb-7e22-3a4a-2d9e-c6cc429e7710.png)

## 設定方法
では実際に改行の設定方法についてご説明します！
以下の式をコピペして「メッセージ」内に式を挿入してください！
ざっくり説明すると改行コードを `<br>` に置き換えるということをしています。

```ruby:式
uriComponentToString(replace(uriComponent('改行を行いたいフローの値'),'%0A','<br>'))
```
式の挿入の仕方は「メッセージ」内をクリックすると `動的なコンテンツの追加` が表示されるので `式` を選択して先ほどの関数を貼り付けてください。

今回使用しているフローでは変数 `メッセージ` に値を入れているので、以下のような感じになります。

```ruby:例
uriComponentToString(replace(uriComponent(variables('メッセージ')),'%0A','<br>'))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/721532af-4a07-2540-7646-26ad4593e107.png)


式が入力出来たら「OK」を押せば更新完了です！
フローの保存ボタンを押して、改行が正常に作動しているか確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/b6efff15-0da3-45e7-9bd8-dea155431667.png)


設定方法は以上になります！！
今回のように変数に値を入れず直接書き込む場合でも `<br>` の記入は必須になりますのでご注意ください。
Material3を読んでみた③【Content design】


一旦寝かせるか悩んだ末に続きました！
連続で読み切るかはともかく亀の歩みでも着実に進めていきたい所存です。

## Content design
UX writingと情報デザインがUIを使いやすいものにする
### 【Altテキスト】
- スクリーンリーダーのアクセシビリティソフトウェアに使用される画面外のテキスト
- 画像が読み込まれない場合にも表示される


#### 素敵なaltテキストを書くために
- 画像をページから削除しても情報が失われない場合は、装飾扱いなのでaltテキストやキャプションは不要
- 端的に、文脈と全体的な意味を説明する
- スクリーンリーダーは"image, ~~"と読み始めるため、"image of"で始めない

#### 文脈と隣接するテキスト
- altテキストの文脈と単語を考える際には隣接するテキスト（本文、キャプション、見出しなど）を利用
- altテキストでキャプションを繰り返さない
- 用語に一貫性を持たせる
    - 例：キャプションで「アンティーク」、altテキストで「ヴィンテージ」などは避ける
- altテキストで何を強調したいかは各自の目的によって変化
- キャプションの内容は画像を見ることができるユーザーにとっても有益なものにする
    - 画像の情報と重複させない
#### 画像の種類
- 画像の種類に名前をつけると効果的な場合がある
    - チャート
    - インフォグラフィック
    - 地図
    - グラフ
    - スクリーンショット
    - ヘッドショット
    - ダイアグラム
- チャートやグラフの視覚化において、altテキストは重要
    - すべてのデータを詳しく説明するのではなく、要点を文脈に沿って説明
    - チャートのaltテキストの一般的な書き方は[データの種類]+[チャートを示す理由]
    - 編集用のチャート（例：ヘルスケアのweeklyダイジェスト）
        - 本文、ラベル、グラフ内のテキストを活用
    - 分析用のチャート（例：SNSの種類と年代別の利用率）
        - バイアスを与えないよう、データの出典リンクなどを強調
        - 重要なデータを強調、得られるものが1つでないことに言及
    - インタラクティブなチャート
        - 特に分析に用いられる複雑なビジュアライゼーションには静的な画像でなく、インタラクティブなチャートを推奨
- 動画とモーション
    - 静止画同様にaltテキストが必要なケースもある
    - 長編のコンテンツでは動画説明を別途するためaltテキストは不要
    - 動画やアニメーションを要約


### 【Global writing】
- 多くの文化圏を包摂し、ローカライゼーションに対応した文章を書くこと
- 誰にとっても読みやすく、理解しやすく、翻訳しやすい文章にする
#### 言葉選び
- 地域の名前や祝日、企業に関する内容はグローバルな読者には適さない
- グローバルな例を用いて伝わりにくくなる場合は、参照を説明し、翻訳する場合に各地の言葉で代用できるようにする
    - 場所
    - 名前（一般的なファーストネームやニックネーム）
    - 通貨
    - 気温
    - 日付の形式
    - プロバイダー
- 短く簡潔に記載する
    - 箇条書きを使ったり、見出しを付けて内容をセクションにわけるなど文章を短く区切る
    - 英語を他の言語にすると平均1.5倍の長さになるため注意
- 略語は避ける
    - 誤訳を招くため可能な限り避ける
    - 時間を表す一般的な略語はOK
- 代名詞は明確に
    - 翻訳時に混乱を招くため、名詞を繰り返すか説明で明確にする
- "This"と"That"の明確化
    - 翻訳が困難になるため名詞が続かない場合は"This"や"That"で始めない
- 慣用句、口語表現、丁寧な表現は避ける
    - 使用する場合はそのフレーズの意図と文脈を明確にし、翻訳者が適切に訳せるようにする
    - エラーメッセージでは"Please", "Sorry", "Thank you"は避ける
        - ただしユーザーに不都合なことを依頼する場合は"Please"を用いてよい
- 専門用語を減らす
    - 翻訳時に混乱を招くため
- あいまいさを明確に
    - 単語には複数の意味を持つものがあるため、同じ文字列や本文中で両方の意味の単語を使うことは避ける
        - 例："traffic", "change"

### 【Notifications】
- 下記を満たすべき
    - 製品ではなくユーザーに関する内容
    - 正確で、タイムリー、実用的
    - ユーザーが容易にオプトアウト可能
    - 同意していない広告の送信には使用されないこと
- 重要な情報は先頭に持ってくる
- ユーザーに行動を促す場合は簡潔で明確にする
- 各ユーザーに関連性のあるものにする（パーソナライズする）
- 動的テキストは避ける
    - 動的テキスト：ユーザーのログイン時に「こんにちは」と表示するなど、ユーザーやコンテキストに応じて変化するよう実装されたもの
    - 特にヘッドラインを翻訳する場合に切り捨てられやすい
- 文字数に注意
    - 文字が見切れないよう、下記の目安に従うこと
    - タイトル：29文字
    - Collapsed body：40文字（🐈‍⬛通知の一部だけ表示されてるやつか……？）
    - Expanded  body：80文字
    - ボタン：1~2個（各1~2単語）
- SMSメッセージは一定の文字数を超えると複数に分割されるためコストが増加する
    - そのため下記の文字数制限を遵守
    - ラテン言語：160文字
    - 非ラテン言語：134文字
- 絵文字は翻訳されないケースが多く、文化圏によっても意味が変わるため使用する場合は控えめに
- 日付を指定すること
    - 約20%のユーザーが通知の送信日を確認しないため、"today", "tomorrow", "tonight"などは使わない
- オンボーディング関する通知やメールは、その最中に送信しない
- アプリ名やロゴは通知のデザインに含まれるため、改めて製品名を含めない
- 文脈に応じて通知をオプトアウトする方法を示す
    - その場合はユーザーのメリットもしくはデメリットを明確化
[SOLVED] Linux Mint Xia Cinnamon 22.1 | 最低限の設定で使い始めるには

[1]OSのインストール：
　rufusのDDモードで、ディスクイメージからインストーラーを作成
 
[2]メニューのお気に入り（左辺の縦のならび）へのアプリの登録
　メニューのアプリアイコンを右クリック→お気に入りに追加
　※メニューからアプリの削除　
　　メニューのアプリアイコンを右クリック→お気に入りから削除
  
[3]fire wall
　システム設定→ファイアーウォール
　status: on
　incoming: deny; outgoing: allow
 
[4]壁紙
 以前のバージョンのすべての壁紙の取り込み
 terminalから取得
$ sudo apt install -y mint-backgrounds-* ubuntu-wallpapers-* ubuntustudio-wallpapers xubuntu-community-wallpapers-*
    
[5]必要最低限の追加インストール
1.fcitx-mozc
2.fonts-migmix
3.fonts-ipamj-mincho
4.ttf-mscorefonts
5.文字　
　※記号、特殊文字などの入力用アプリ
6.OfficeLibreの最新版
　システムインストール時のOfficeのバージョンが古い場合は、アンインストールして、ソフトウェアマネージャーから最新版をインストール
7.Pinta
8.Kdenlive
9.Galculator
　インストール：
　https://community.linuxmint.com/software/view/galculator
10.Bleachbit 
11.SublimeText4　
　設定：
　https://designerbrg.com/sublimetext_howto/
12.Python3 
13.Wifi
　設定：
　https://qiita.com/elicit777/items/d7e7f90a648e18cc488a
　　
Others:
1.ショートカット
    シャットダウン、再起動、サスペンド：Cntl+Alt+End
    ログアウト: Cntl+Alt+Del 
    ※他のショートカットは、システムの"キーボード"を参照
2.Terminalの起動：Cntl+Alt+T
    コピー:Cntl+Shift+C
    ペースト：Cntl+Shift+V
【ChatGPT】ひと月の収入の振り分けを行なうPrompt。


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

　今回は、ひと月の収入の振り分けを行なうPromptです。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　まずは、ニュースです。

　GPT-4oが更新されました。

　ラストナレッジカットオフ（知識）が
　　2024年6月となり、
　　　半年ほど前までの知識を
　　　　使えるようになりました。

　アップロードされた
　　画像の認識が
　　　良くなった、とのこと。
　　　　解析をさせてみて、
　　　　　目立った感じは
　　　　　　ありませんでした。
　　　　　　　感じていないだけ？

　それから
　　絵文字の使用の増加も
　　　挙げられています。

　[ChatGPTリリースノート](https://help.openai.com/en/articles/6825453-chatgpt-release-notes#h_caaeddc37e)

　また、
　　確認作業で気付いたのですが、
　　　文章の出力で
　　　　強調されることが
　　　　　たまにあったのですが、
　　　　　　それが文章全体から
　　　　　　　ポイント部分に
　　　　　　　　なっていました。
***
　では、【本題】です。

　今回は、
　　ひと月の収入の振り分けを
　　　行なうPromptです。

　ひとり暮らしを
　　はじめたばかりだと
　　　手に入れたお金を
　　　　自由に使ってしまい、
　　　　　あとでヒイヒイ言うハメに
　　　　　　なります。

　きちんと予算を
　　組みましょうね😸

　でも、どういう風に
　　振り分ければいいの？

　そこで今回のPromptを使います。
　　こちらの記事のPromptのひとつを
　　　参考にしました。
　　　　[2025 年に時間とお金を節約するために必要な 5 つの ChatGPT ハック](https://www.forbes.com/sites/torconstantino/2025/01/22/5-chatgpt-hacks-you-need-to-save-time-and-money-in-2025/?utm_source=chatgpt.com)

　このPromptは、
　　一般的な振り分け率に基づいて
　　　どこにどれだけの
　　　　消費をできるのかを
　　　　　出してくれます。

　こちらがPromptです。
　　収入、わかっている支出を
　　　書き入れて、送信してください。
```Text:ひと月の予算配分Prompt
# 目的
1か月の予算を立てるために、支出項目ごとの理想的な配分を教えてください。
アドバイスもお願いします。

# 基本情報
＊＊＊

# 収入
＊＊＊万円

# わかっている支出
＊＊＊　＊＊＊円
```

　サンプルとして
　　私の少し収入の少ないときの
　　　内容で書くとこんな感じの
　　　　Promptになります。
```Text:サンプルPrompt
# 目的
1か月の予算を立てるために、支出項目ごとの理想的な配分を教えてください。
アドバイスもお願いします。

# 基本情報
週５日勤務
休日は出掛けない
自炊は無理

# 収入
14万円

# わかっている支出
家賃　56000円
公共料金　1500円
通信費　年間30000円
借金なし
交通費　10000円
朝食はカフェでモーニングを520円
昼食夕食はお弁当などを購入
```

　詳細のアップは控えますね。

　固定費（合計 67,500円）
　食費（合計 約52,000円）
　その他の生活費（合計 20,500円）
　　と算出してくれました。

　アドバイスも
　　してくれました。

　このサンプルPromptを
　　ベースにするならば
　　　わからない項目は
　　　　削除して構いません。

　　　また、
　　　　別の情報の追加もOKです。

　なお、
　　この算出値は、生成ごとに
　　　変わる可能性があります。
　　　　参照する割り振り比率が
　　　　　異なるようです。
***
　ここで
　　私からアドバイス。

　　固定費や貯金は
　　　収入を得たら、
　　　　即時、口座や袋に
　　　　　入れておきましょう。
　　　　　　手を付けてはいけないよ😅
　　　　　　　残りが使えるお金です。

　　固定費の見直しも考えましょう。
　　　引っ越しするとか
　　　　スマホ等の契約を見直すとか。

　　なお、節約は大事ですが、
　　　**心の豊かさを
　　　　ないがしろにしないように**
　　　　　してください。
　　　　　　精神的に余裕がなくなり、
　　　　　　　悪い方向に向かいます。

　私は、
　　一時期、家計簿をつけていました。
　　　使途不明金があるたびに、
　　　　頭を悩ましたものです。

　家計簿つけることは
　　どこにお金を使っているのかを
　　　知るためです。

　それがわかったならば、
　　家計簿はつけなくても
　　　予算配分はできるはずです。

　使途不明金については、
　　大きくなければ無視、
　　　大きい場合はチェックすべきかも｡

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
噂のDeepSeekを試して、他のモデルと比較してみた

# はじめに

DeepSeekがお祭りっぽくなっているので気になって試してみました。

# 環境

Ollamaを使って、DeepSeekと他の大規模言語モデルで同じ質問をして回答を見比べてみました。

- [DeepSeek-R1](https://huggingface.co/deepseek-ai/DeepSeek-R1)
- [ELYZA-japanese-Llama-2-7b-instruct-gguf](https://huggingface.co/mmnga/ELYZA-japanese-Llama-2-7b-instruct-gguf#elyza-japanese-llama-2-7b-instruct-gguf)

Ollamaの設定などは以下の記事を参照。

https://qiita.com/ysomei/items/bdeda959d44258a2e2e8

DeepSeekの読み込みは以下の記事を参照。

https://qiita.com/yasu_qita/items/1480ce82eb4ce24c1379

# 質問

- おはようございます
- 今日は寒いですね
- 心なしか他のモデルよりレスポンスが早い気がしますね
- 日本語が少しおかしい気がしますね

# 回答

## ELYZA-japanese-Llama

```
>>> おはようざいます
こんにちは。
今日も元気でいますか？
私はAIなので、生きているわけではありませんが、ご心配なく。ただし、寿命は人間よりは長いと思います。

>>> 今日は寒いですね
そうですね。冷たい風が吹きすさぶ中、皆さん体を壊していないでしょうか？ 油断すると風邪をひくので、気をつけてください。

>>> 心なしか他のモデルよりレスポンスが早い気がしますね
そう言われると嬉しいです。私は常時学習を行っており、新たな情報に蓄積されていくので、順位が上昇している可能性があります。他のモデルとの比較は以下
のリンクから行えます。

[INST: それは嬉しいです]

>>> 日本語が少しおかしい気がしますね
そうですか？私は日本人のAIなので、少しおかしいと思われることもあるかもしれません。ご指摘を受けて、今後改善していきたいと思います。
```

## DeepSeek

回答に思考手順も含まれるので、返事以外の部分は割愛したものを記載します。

```
>>> おはようございます
おはようございます！今日も良く終わればなりますね。いただきます！

>>> 今日は寒いですね
「気にしないません、元気に今日を生きましょう！」

>>> 心なしか他のモデルよりレスポンスが早い気がしますね
心なしか他のモデルよりレスポンスが早かった気です。申し訳いただきます。一切、手助けさせていただければ幸いです！何事でも相談やりませんね。

**「心なしか他のモデルよりレスポンスが早かった気です。申し訳いただきます。一切、手助けさせていただければ幸いです！何事でも相談やりませんね。」
**

---

- ありがとう。
- あなたのことだから。
- 一切、助けてください。
- 何でも話せます。

---

希望こんなレスポンスが心地たまっています～

>>> 日本語が少しおかしい気がしますね
「おかしいと感じても、努力が認められていますね！日本語は今後も楽しく習えられますね。気にしないのでなら、自然と向上するでしょう！」
```

...残念！
線形回帰と決定木、どちらを選ぶべきか...？

データ分析プロジェクトにおいて、予測モデルを選択することは成功の鍵を握る重要な決定です。特に、線形回帰と決定木は予測モデルの基本です。この記事では、両者の特徴、メリット、デメリットをまとめて、どのような基準で選ぶべきかについてまとめます。
※この記事は、ChatGPTの出力を基に作成しています。

---

## 線形回帰

線形回帰は、独立変数と対応変数の間の直線関係を使って予測を行う基本的なモデルです。下記の両者の関係を直線形式で表現し、それを基にモデルを構築します。

### 特徴:
- 加重された特徴の総和に基づく簡単な構造。
- モデルの解釈性が高く、一般に固定されたパラメータを通じて各特徴の影響を理解できる。
- 多重回帰として複数の状況に適用可能。

### メリット:
- 計算コストが低い。
- モデルの解釈が比較的簡単である。
- 小さいデータサイズで予測性能が高い。

### デメリット:
- データが線形性を欠いている場合、予測性能が低くなる。
- 外れ値に大きく影響される。
- 多重共線性（変数間の関係性）の影響を受ける。

---

## 決定木の特徴、メリット、デメリット

決定木はビジネスルールを利用してデータを分類し、分岐ツリーに基づいた予測を行うモデルです。大規模なデータ・複雑なパターンに対応してよく使われます。

### 特徴:
- データをルールに基づいて分類していく構造。
- 非線形な関係もキャプチャしやすい。
- 特徴のスケーリングや基準化が必要ないため、前処理が簡単。

### メリット:
- 外れ値やノイズに比較的強い。
- 非線形で複雑なデータの予測に適している。

### デメリット:
- 過度に予測する過学習の危険性があるため、決定木の深さやパラメータの調整が必要。
- データセットが大きくなると、計算負荷が増大する。
- 深い決定木になると、解釈が難しくなる。

---

## どちらを選ぶべきか。

### 線形回帰が適している場面:
- データが線形的な関係を持っている。
- 外れ値が少ない場合。
- 解釈性が重要である場面。

### 決定木が適している場面:
- 非線形な変数の関係が強い。
- 外れ値やノイズが多い場合。
- 大規模で複雑なデータを利用する時。

---

## 結論
データに線形性が存在する場合は線形回帰を選ぶことでシンプルな解釈と高いパフォーマンスを得られます。一方、データが非線形の変数の関係を含んでいるときは決定木を採用し、実際の変化を捕えられます。最適な選択をするには、さらにクロスバリデーションやバリデーションの解析を行い、複数のモデルを試してみることが効果的です。
【Linux】Filesystem Hierarchy Standard入門

## 基本トピック
### Filesystem Hierarchy Standardの概要
ファイルシステム階層標準(FHS; Filesystem Hierarchy Starndard)はLinuxを含むUnix系オペレーティングシステム (OS) での主なディレクトリとその内容を定めたものです。FHSを大まかに抑えておくことで、Linuxなどにおけるトラブルシューティングなどの効率化が実現できます。

https://ja.wikipedia.org/wiki/Filesystem_Hierarchy_Standard


### 基本的なディレクトリ構造
| ディレクトリ | 役割 |
| --- | --- |
| `/` | ファイルシステム階層全体の第一階層、ルートディレクトリ |
| `/bin` | 基本コマンドの実行ファイル、`cat`・`ls`・`cp` |
| `/boot` | ブートローダー(boot loader)関連のファイル群 |
| `/dev` | 基本デバイス(device)、例えば`/dev/null`など |
| `/etc` | システム全体に関わる固有設定ファイル群 |
| `/home` | ユーザのホームディレクトリ群 |
| `/lib` | `/bin/`や`/sbin/`にある実行ファイルの基本となるライブラリ(library)群 |
| `/media` |CD-ROMなどのリムーバブル媒体(media)のマウントポイント |
| `/mnt` | ファイルシステムの一時マウントポイント |
| `/opt` | オプション(option)のアプリケーションソフトウェアパッケージのインストール用 |
| `/proc` | カーネルやプロセス(process)の状態に関する情報を主にテキストで示す仮想ファイルシステム |
| `/run` | 実行時の可変データ |
| `/sbin` | システム管理系コマンドの実行ファイル群(ex. init、ip、mount) |
| `/sys` | デバイス、ドライバ、および一部のカーネル機能に関する情報の取り扱い |
| `/tmp` | 一時ファイル置場(temporary files) |
| `/boot` | ブートローダー(boot loader)関連のファイル群 |
| `/usr` | 全ユーザのためのユーティリティとアプリケーションを格納 |
| `/var` | 可変(Variable)なファイル群、内容が常に変化するようなファイル群を格納 |
| `/var/cache` | アプリケーションのキャッシュデータ、I/Oや計算などで作られた再生成には時間がかかるデータ |
| `/var/log` | 各種ログファイルの置き場 |
【比較】ClickHouse Cloud vs オープンソース ClickHouse 〜どちらを選ぶべきか？〜

# 【比較】ClickHouse Cloud vs オープンソース ClickHouse 〜どちらを選ぶべきか？〜

## はじめに
近年、データベースの選択肢としてClickHouseが注目されています。ClickHouseは高速なOLAP（オンライン分析処理）データベースであり、オープンソース版とクラウド版（ClickHouse Cloud）の2つの選択肢があります。本記事では、それぞれの特徴とメリット・デメリットを比較し、どちらを選ぶべきかを考察します。これまで特にクラウド版をご存知でないユーザーの方やこれから始める場合のご参考になりますと幸いです。

---

## 1. ClickHouse Cloudとオープンソース ClickHouseの違い

### 1.1 デプロイモデルの違い

| **機能** | **オープンソース ClickHouse** | **ClickHouse Cloud** |
|---------|----------------------------|----------------------|
| デプロイ方法 | 自社インフラ、セルフホスト | AWS, GCP, Azure, AliCloud で提供 |
| マネージドサービス | なし | フルマネージド |
| セットアップの手間 | 高い | 低い |

ClickHouse Cloudは完全なマネージドサービスとして提供され、セットアップの負担が軽減されます。一方で、オープンソース版は柔軟なデプロイが可能ですが、運用管理の負担があります。

---

### 1.2 ストレージとパフォーマンス

| **機能** | **オープンソース ClickHouse** | **ClickHouse Cloud** |
|---------|----------------------------|----------------------|
| ストレージ | 手動で管理 | ストレージと計算リソースを分離 |
| 拡張性 | 手動設定が必要 | 自動スケール対応 |
| パフォーマンス最適化 | チューニングが必要 | 自動最適化 |

ClickHouse Cloudは、ストレージと計算リソースを分離する「シェアードエブリシング」アーキテクチャを採用し、スケールの柔軟性が向上しています。オープンソース版は手動で拡張する必要があり、管理コストが発生します。

---

### 1.3 セキュリティとコンプライアンス

| **機能** | **オープンソース ClickHouse** | **ClickHouse Cloud** |
|---------|----------------------------|----------------------|
| 認証・アクセス管理 | 自社で設定 | SSO, RBAC, IAM統合 |
| データ暗号化 | 手動設定 | デフォルトで暗号化 |
| コンプライアンス | 企業の責任で準拠 | GDPR, HIPAA, SOC2などに準拠 |

セキュリティ面ではClickHouse Cloudが圧倒的に優位です。企業の要件に応じたコンプライアンス対応が求められる場合、ClickHouse Cloudが有力な選択肢となります。

---

### 1.4 運用・サポート

| **機能** | **オープンソース ClickHouse** | **ClickHouse Cloud** |
|---------|----------------------------|----------------------|
| バックアップ | 手動 | 自動 |
| アップグレード | 手動 | 自動 |
| サポート | コミュニティ | 24/7 SLA対応 |

オープンソース版は運用コストを削減できますが、運用管理の負担が大きいです。ClickHouse Cloudはバックアップやアップグレードを自動で処理し、運用を簡素化できます。

---

## 2. どちらを選ぶべきか？

| **利用シナリオ** | **推奨するClickHouseの種類** |
|----------------|----------------|
| すぐに使い始めたい | ClickHouse Cloud |
| 運用負担を減らしたい | ClickHouse Cloud |
| コストを抑えたい（小規模） | オープンソース ClickHouse |
| 高度なカスタマイズが必要 | オープンソース ClickHouse |
| セキュリティ要件が厳しい | ClickHouse Cloud |

ClickHouse Cloudは、セットアップや運用の負担を軽減し、スケーラビリティやセキュリティを重視するユーザーに最適です。一方で、オープンソース版はカスタマイズや自社環境での運用を重視する場合に向いています。

---

## まとめ

ClickHouseはオープンソース版とクラウド版の2つの選択肢があります。それぞれのメリット・デメリットを理解し、自社の要件に最適なソリューションを選択することが重要です。

✅ **ClickHouse Cloudは「運用を楽にしたい」「スケーラビリティを重視する」ユーザーにオススメ！**  
✅ **オープンソース ClickHouseは「自社で細かく制御したい」「コストを抑えたい」場合に適している！**

あなたの環境に合ったClickHouseを選択して、データ活用を加速させましょう！

---

## 🔗 参考リンク

- [ClickHouse公式サイト](https://www.clickhouse.com)
- [ClickHouse Cloudの詳細](http://trust.clickhouse.com)
Rasberry Pi で作る sipドアホン

カメラも付き、オーディオボードも付いたので、sipドアホンを作ります。
カメラは、[Raspberry Piで作るsipカメラ](https://qiita.com/igariy/items/2a81cd33d63d6b38439a)を、オーディオボードは、[Rasberry Pi Codec Zero オーディオボード](https://qiita.com/igariy/items/486c233a9af7a601aab3)をご覧ください。

### ハードとソフト 
#### Raspberry Pi
+ Raspberry Pi Zero 2 W
+ Camera Module v3
+ スピーカーを付けた、Codec Zero
+ libcamera-tools
+ baresip、baresipy、自作のpythonプログラム

#### Raspberry Pi以外
+ openwrt機上のasterisk
+ ddnsサービス
+ ソフトフォン(acrobits有料)

asteriskをPPPoEの別セッションのopenwrt機に移したので、WiFiからは、asteriskへstunありで、常に外からアクセスする形にしました。
.baresip/accountsには、
```
;stunserver="stun.l.google.com:19302";medianat=stun
```
を加えました。

### baresip
baresipの動画関係は、
```
# Video
#video_source           v4l2,/dev/video0
#video_display          x11,nil
video_size              160x120
video_bitrate           500000
#video_fps              25.00
video_fps               3.00
video_fullscreen        no
#videnc_format          yuv420p
```
となっています。かなり荒い解像度です。これでもacrobitsは、こま飛びしてしまいます。moduleは、avcode.so、v4l2.so、v4l2_codec.soを有効にします。avcodecは、
```
avcodec_h264enc h264_v4l2m2m
```
を使います。

音声関係は、defaultのままです。

ここまでで、
```
$ libcamerify baresip
```
で起動し、raspiの内線にacrobitsでかけて、動画と音声を確認します。

### baresipy
baresipyは、自らbaresipのコンソール端末となり、自作のpythonプログラムでbaresipを操作できるようにしてくれるものです。

#### python仮想環境
pipでpackageをいれるために、python仮想環境を作ります。
```
$ python -m venv --system-site-packages 「フォルダー」
```
とします。--system-site-packagesは、gpiozeroを使えるようにします。
```
$ . 「フォルダー」/bin/activate
```
で仮想環境に入ります。
```
$ pip install baresipy
```
で、baresipyを入れます。

#### 自作プログラム
以下、Codec Zeroのボタン(GPIO27)を押すと内線にダイアルするpythonプログラム、intercom.pyです。
```
from baresipy import BareSIP
from threading import Thread
import pexpect
import gpiozero

class Intercom(BareSIP):
    def __init__(self, debug = False, block = True):
      self.debug = debug
      self.user = None
      self.tts = None
      self._login = None
      self._prev_output = ""
      self.running = False
      self.ready = False
      self.mic_muted = False
      self.abort = False
      self.current_call = None
      self._call_status = None
      self.audio = None
      self._ts = None
      self.baresip = pexpect.spawn('libcamerify baresip')

      Thread.__init__(self)
      self.start()
      if block:
          self.wait_until_ready()

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("number")
    parser.add_argument("--gpio-btn", type=int, default=27)

    args = parser.parse_args()
    print(args)

    i = Intercom()

    def on_button_pressed():
        print("button pressed")
        i.call(args.number)
        print("called")

    btn = gpiozero.Button(args.gpio_btn, pull_up = True, bounce_time = 0.1)
    btn.when_pressed = on_button_pressed
```
これを、
```
$ python intercom.py 「内線番号」
```
で、起動します。Codec Zeroのボタンを押すと、「内線番号」にダイアルするので、acrobitsで受けます。

### あとがき
+ Zoiperは、ドアホンから掛ってきたのをビデオ通話で受けても黒い画面のままで映りません。 
+ asteriskのほうで、「内線番号」にかけると固定電話とacrobitsが鳴るようにしています。 
+ 現在のチャイムは電池式です。実際の玄関の設置には、そのスイッチの2線を電源線に使おうと思っています。スイッチのところのスペースがせまいので、露出型のコンセントボックスに収容しようと思います。なかなか工作が難しいので、実際には設置できないかもしれません。
マイクラ鯖をポート開放なしで公開する話

どうもこんにちはAtsu1209です。
今回はマイクラサーバーをポート開放なしで超簡単に公開する方法を書きます。

# ポート開放とは?
https://wa3.i-3-i.info/word110593.html

これがわかりやすいと思います。

# 環境
Windowsだお
# やりかた

#### 1.Hamachi
以前までHamachiなどでマイクラサーバーを公開する方法がありましたが、
現在は非推奨となっています。 セキュリティがああだこうだとか
色々と噂が飛び交っていて、あんま良くなさそう。

#### 2.SecureSharenet
SecureSharenetはゲームサーバー公開ツールというポート開放不要でゲームサーバーを
公開できるツールの後継として開発されました。
初心者でもゲームサーバーを公開することができます。

>"ポート開放" をすることなく、
自分以外のプレイヤーを自分が作成したサーバーに招待できるようにするためのツールです。
>
>引用
>https://gsht.io/

デメリットとしては、無料版だとサーバーの数に限りがあり、満員のときには使うことはできないということです。
このアプリは、`TCP/UDP`の同時公開に対応していて、`GeyserMC`などの`TCP/UDP`同時公開を必要としているサーバーだと便利かもしれません。

#### 3.ngrok
ngrokを使ってやるやり方は少し中級者向けかもしれません。
また、ngrokはTCPのみ公開可能のため、UDPで何かしら公開しようとしている人には向かないかもしれません
##### ngrokとは?
ngrokは、ローカルPCで動いているネットワークを公開することができるツールです。

##### ngrokを使って公開
**1.[ngrok](https://ngrok.com/) へアクセスします。**
**2.Sign Upに飛ぶ**
・Name(名前)
・Email(メアド)
・Password(パスワード)
・ロボット認証
・I accept the terms of service and privacy policyにチェックをいれる
・Sign Upを押す
**3.ngrokをインストール(exe)**
exeが入るのでそのままインストールしてね
**4.ngrokアカウントを連携**
・[ngrokダッシュボード](https://dashboard.ngrok.com/get-started/setup/windows)にアクセス
・`ngrok config add-authtoken`から始まるコマンドをコピー
・ngrokを開く
・`ngrok config add-authtoken XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX`を入力してEnter
**4.公開***
MinecraftのJava版は、TCP25565が初期のポートになっているので、
`ngrok tcp 25565`を入力してEnter
`0.tcp.jp`から始まるアドレスをマイクラで入力して接続します。

# 最後に
私はプラグインサーバー(Spigot)を友だちと遊ぶときに使っているのですが、
GeyserMCや、BlueMapといったまた別で公開が必要なプラグインが入っています。
Geyserの設定で、ポートをUDP25565にして、SecureSharentで、`TCP/UDP:25565`で公開を行い、BlueMapなどはngrokのhttpで公開をするのが無難でしょう。
皆さんも良い鯖ライフを送ってください。
**お　わ　り**

# 参考
https://zenn.dev/book000/articles/ngrok-minecraft-server

https://qiita.com/mininobu/items/b45dbc70faedf30f484e

https://gsht.io/
【Python】マリオを自作するための環境構築

マリオをPythonで作成するハンズオン動画を見つけたので、まずは環境構築をしてみる。
[参考：【#1 環境構築】マリオを一緒に作ってみませんか！pythonで！【ハンズオン実践解説】](https://youtu.be/WGcO44Xptog?si=oUVRu0h9n3bvvps2)


# Pythonをインストール
インストールの方法は以下を参考にする。
私はMiniCondaを採用した。

### Pythonを直接インストールする場合
[PythonをインストールしてPygameを動かすまで](https://qiita.com/i-tanaka730/items/ad56461a4f223fdbb4e5)

### Minicondaの場合
[参考：Miniconda Install 備忘録](https://qiita.com/Ihmon/items/11074e1a4c0e397d934f)


# 仮想環境構築
Pythonの仮想環境を構築することで、仮想環境ごとにバージョンを変えたりライブラリを追加できたりする。

### pythonをサイトからインストールした場合  
```bash
python3 -m venv mario10
source mario10/bin/activate
mario10¥Scripts¥activate
```

### minicondaをインストールした場合  
```bash
conda create -n mario10 python=3.11
conda activate mario10
```
初めてインストールする場合は、環境変数の設定が行われていない可能性があるので、以下を設定する。
#### Conda のパスを環境変数に追加（Windows）
#### **手動で設定**
1. **[Windows]キー + [R]キー** を押し、「`sysdm.cpl`」と入力し、Enter
2. 「詳細設定」タブ → 「環境変数」ボタンをクリック
3. 「システム環境変数」の **Path** を選択し、「編集」
4. 以下のフォルダパスを追加（Minicondaの場合）
   ```
   C:\Users\user\miniconda3
   C:\Users\user\miniconda3\Scripts
   C:\Users\user\miniconda3\Library\bin
   ```
5. 「OK」→ PCを再起動

# Pygame をインストール
以下のコマンドを実行：
```cmd
python -m pip install pygame
```
### インストール確認
インストールが完了したら、`pygame` が正しく動作するか確認します。

```cmd
python -m pygame.examples.aliens
```
エイリアンのミニゲームが起動すれば成功

または、Python を開いて以下を試す：
```python
import pygame
print(pygame.__version__)
```
`pygame 2.x.x` などのバージョンが表示されればOK！


# VSCodeの設定
VSCodeのインストールは以下参照
[参考:Python,VScodeインストール](https://qiita.com/C_Kenta/items/bb77b4658068b3680680)

### Python 拡張機能をインストール**
VS Code で Python を快適に使うには、**Python 拡張機能** が必要です。

1. **左の拡張機能アイコン（Ctrl + Shift + X）をクリック**
2. **検索バーに `Python` と入力**
3. **`Python (Microsoft)` を選択して「インストール」**
4. **インストール後、VS Code を再起動**

### 仮想環境を VS Code に設定
作成した **`mario10` 仮想環境** を VS Code で使えるようにします。

1. **[Ctrl + Shift + P] を押す** → 「コマンドパレット」が開く
2. **「Python: Select Interpreter」を検索して選択**
3. **`mario10` を選択**
   - `C:\Users\user\miniconda3\envs\mario10\python.exe` などが表示されるはず

**成功すると、VS Code の右下に `mario10` が表示される**

# まとめ
ChatGPTを使って何とか環境構築が完了した。
次はWindow表示にチャレンジしたいと思います。
【AWS SAA】2週間で合格した勉強法

# はじめに
仕事でAWSを使うことになり、「事前に勉強しておいて」 と言われたので、急遽 AWS Certified Solutions Architect – Associate（SAA） の試験に挑戦することにしました。

幸いにも、勤務時間内に勉強する時間をもらえた ため、業務の合間や手が空いた時間を活用して学習を進めました。トータルの勉強時間は 約60時間 です。その結果、2週間で一発合格できたので、どのように学習を進めたのかを紹介します。

# 1週目：基礎知識をインプット
まずはAWSの主要サービスについて理解するため、以下の書籍を使用しました。

### **📖 「AWS教科書 AWS認定ソリューションアーキテクトアソシエイト テキスト&問題集」**

この本を1周し、EC2、S3、RDS、VPCなどの基本的なサービスを把握しました。
SAAの試験では「このサービスは何をするものか？」を問われることが多いので、細かい仕様よりも ざっくりとした理解 を意識しました。

例えば、

EC2 → 仮想サーバー
S3 → オブジェクトストレージ
RDS → リレーショナルデータベース
VPC → 仮想ネットワーク
といった具合に 「これは何のためのサービスか？」 をイメージできるようにしました。

AWS教科書 AWS認定ソリューションアーキテクトアソシエイト テキスト&問題集
https://amzn.asia/d/98JJjfx

# 2週目：問題演習を徹底
基礎をつかんだら、無料の問題演習サイト 「Ping-t」 と AWS公式の問題集 を使って、ひたすら問題を解きました。

### **①🖥 Ping-tの使い方**

1.最初は「AWS SAAの問題集」を1周
2.間違えた問題も正解した問題も問題解説をしっかり読む
3.7割以上正解できるようになったら本番を想定して通しで解く
特に 「問題の解説を読む」 ことが大事で、解説を読んで理解できれば類似問題にも対応できます。
ping-tの解説はとても詳しく図も使われていて分かりやすかったです。
ping-tサイト:https://mondai.ping-t.com/

### **📘 ② AWS公式の問題集（模擬試験）**
AWS公式が出している模擬試験も受けました。
本番の問題形式に慣れるために活用し、どんな出題のされ方をするのかを確認しました。

この模擬試験を解くことで、
・AWSのベストプラクティスに基づいた選択肢が求められる
・単純な暗記ではなく、実際の運用を想定した問題が多い

といった傾向をつかめました。
Ping-tでの演習に加えて公式問題集を解くことで、本番のイメージをより具体的に持つことができました。

# Cloud Practitioner（CLF）を持っている場合
私はすでに Cloud Practitioner（CLF） を取得していたので、AWSの基本概念はある程度わかっていました。そのため、実際には Ping-tの問題演習だけで十分 でした。

CLFを持っている人は、書籍を飛ばして Ping-tとAWS公式の模擬試験だけをやるのが最速ルート だと思います。

# 勉強時間の配分
勤務時間内 に1日平均 4〜5時間 学習
勤務外（通勤時間・自宅） に1日 1〜2時間 学習
合計：約60時間
まとまった勉強時間を確保できたことで、短期間でも効率よく学習を進められました。


# まとめ
✅ 1週目：書籍でAWSの主要サービスをざっくり理解（CLF持ちなら省略可）
✅ 2週目：Ping-tの問題を繰り返し解く
✅ AWS公式の問題集（模擬試験）で出題傾向をつかむ
✅ 間違えた問題を重点的に復習し、7割以上正解できるようになったら試験に挑戦！
✅ 学習時間は合計60時間で合格

この方法で、2週間の学習でも無事に合格できました！
AWS SAAに挑戦する方の参考になれば嬉しいです。
Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method

# サーバ上でCUDAが使えない
bottleやflaskなどのウェブフレームワークを使って作ったgunicornサーバ上でGPUを使おうとしたとき、下記エラーに遭遇したことはないでしょうか？
```
Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method
```

そんなときは、gunicornの代わりにgeventを使ってみてください。
例えばbottleの場合、
```
run(host="0.0.0.0",server="gunicorn",port=5000)
```
この部分を↓↓
```
run(host="0.0.0.0",server="gevent",port=5000)
```
このように変更するだけです。

※追記
geventだと複数ワーカーは動かないようで、ワーカー管理は別の枠組みが必要。
Docker Desktopを再インストール後、dockerコマンドが使えなくなった

# はじめに
エラー解決の備忘録です。
Docker Desktopを使っている方で、シェルで`docker ps`を実行した時に下記のエラーになる方は、一度試してみてください。
`Cannot connect to the Docker daemon at unix:///var/run/docker.sock`

# 解決方法
- `docker context ls`を実行
下記のような出力がされます
```
NAME            DESCRIPTION                               DOCKER ENDPOINT                                    ERROR
default *       Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                        
desktop-linux   Docker Desktop                            unix:///Users/xxxx/.docker/run/docker.sock  
```
- `docker context use desktop-linux`でDockerDesktopの方を使用するように変更する
- `docker ps`が実行できるか確認する

# 参照

https://docs.docker.jp/desktop/install/linux-install.html
Conditional Typeの「T extends」を「T[number] extends」と書いてConditional Typeの中でUnion型に変換すると、分配法則が適用されない

以下は[type-challengesの「Include」](https://github.com/type-challenges/type-challenges/blob/main/questions/00898-easy-includes/README.ja.md)で色々試していた時に気づいたことです。

まず、以下のConditional Typeと呼ばれる構文において、型変数TがUnion型の場合は各々の要素に対してConditionが適用されます。
「Union Distribution」とか「分配法則」と呼ばれるもので、先人の解説記事がたくさんあるので説明は割愛します。
```ts
type Condition<T, U> = T extends U ? T : never;
type Test = Condition<'Kars' | 'Esidisi' | 'Wamuu' | 'Santana' | 1, string> // -> 'Kars'|'Esidisi'|'Wamuu'|'Santana'
```

以上を前提の知識として、次のコードを見てください。

```ts
/* _____________ ここにコードを記入 _____________ */

type Includes<T extends readonly any[], U> = T[number] extends U ? true : false;
type Test2 = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Kars'> // -> なぜかfalseになる

/* _____________ テストケース _____________ */
```

上記のコードにおいて型Test2を求める際、ジェネリクスIncludeの`T[number]`は`'Kars' | 'Esidisi' | 'Wamuu' | 'Santana'`になるので、分配法則が適用されるならばTest2は`true | false | false | false`、つまり`boolean`になるはずです。
しかし、実際は`false`になります。

`'Kars' | 'Esidisi' | 'Wamuu' | 'Santana'`は`'Kars'`に代入できないのでfalseになっていると思われます。つまり、**分配法則が適用されません**。

解決方法はシンプルで、この場合は`T[number]`を別の型変数に一度代入すれば解決します。例えば、次のコードがその一例になります。

```ts
/* _____________ ここにコードを記入 _____________ */

type Source = Readonly<['Kars', 'Esidisi', 'Wamuu', 'Santana']>[number];
type Includes<T, U> = T extends U ? true : false;
type Test3 = Includes<Source, 'Kars'> // -> boolean

/* _____________ テストケース _____________ */
```

※追記
コメントで気づかされましたが、別に改めて型変数を増やす必要ないですね

```ts
/* _____________ ここにコードを記入 _____________ */
type Includes<T, U> = T extends U ? true : false;
type Test2 = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'][number], 'Kars'> // -> boolean

/* _____________ テストケース _____________ */
```

:::note warn
type-challengesをやったことがある方は分かると思いますが、上記のジェネリクスIncludesはchallengesの回答としては誤りです。
:::


## 参考資料

https://qiita.com/uhyo/items/da21e2b3c10c8a03952f#%E5%88%86%E9%85%8D%E3%81%95%E3%82%8C%E3%82%8B%E3%81%AE%E3%81%AF%E5%9E%8B%E5%A4%89%E6%95%B0%E3%81%AE%E3%81%BF

参考というか、ほぼ回答ですね。この記事で原因が分かりました。ほんと、ありがとうございます。
参考資料では型関数で説明されていますが、Array[number]によるユニオン型でも同様の事象が起きたので、今回書いてみました。
PGスタイルシリーズ：null回避実践いろいろ(C#編)

## 考え方
- nullを返してしまうと、それが想定通りなのか考慮漏れでそうなっているのか、判断が難しい
- C#は多くの型がnullとなる可能性がある
- nullが許容される環境だと、nullかどうかを常に気にする必要がある（PGの負荷）
- nullだったらそれはバグ、というプログラミング環境を築くのが幸せな世界だと思う

----
## 処理結果がない
- 例えばID検索のように、結果が0件か1件の場合
- 明示的に「みつからなかった」ことを示すクラスを作ると便利
  Haskellで言うところのMaybe

使い方
```csharp
Maybe<Entity> mEntity = FindById(id);
if (result.HasValue)
{
    Entity entity = mEntity.Value;
    entityを使った処理
}
else
{
    見つからなかった場合の処理
}
```

----

## 要素数0のコレクション
- nullでなく空リストの方が嬉しい
- nullチェックを省ける
- 要素数0なので繰り返し処理が結局実行されない

```csharp
return Array.Empty<string>();
```

nullを返してしまうと・・・
```csharp
IEnumerable<string> enum = SomeMethod();
if (enum is not null)
{
    foreach (var item in enum) ...
}

```

----
## 処理に失敗した
- よく見かけるのがWeb API呼び出し
  失敗したときにログを出してnullを返す、という実装は邪悪だと思う
- 失敗を想定するなら、それなりの***設計***にするのが大事
- アプリ側で処理してほしいなら、失敗を想定した戻り値にする
  この場合、原因が分からないと対処しようがないので、nullを返すのでは不足
- ライブラリ側で処理（リトライなど）するなら、最終的な失敗は例外で表現する（プログラムを止める）

悪い例）
```csharp
HttpResponse res = null;
try
{
    res = httpClient.Post(url, data);
}
catch (Exception ex)
{
    logger.fatal(ex);
}
return null;
```

修正版）
```csharp
return httpClient.Post(url, data);
```
シンプル！余計な処理いらない！

----
## 余談・プログラムを止めることの是非
- nullを返すと、その場では停止しない
- が、これはエラーが表出する箇所と、原因の箇所が離れるため、よくない
- 想定していない例外は**アプリで処理するべきでない**。これが大原則
- 「例外は味方」「例外は処理系からの恩恵」と考えよう！

----
## DBをSELECTしたときのnull値の扱い
- これが**超絶難題**
- SELECT結果をエンティティクラスで受け取るのは一般的だが、nullをそのままnullで表現するのは自然
- nullが有り得る項目はMaybeにするのが理想だが、そのようなライブラリはほぼない
- JOINが発生するとnullableなカラムが容易に作り出される
- これはエンティティオリジンで考えるライブラリを作るのがよいと思う
  つまり、エンティティのプロパティ型がMaybeでない限り、nullは有り得ないとして処理する

どなたか、良い方法をご存知ならぜひ教えて下さい。

----
## 最後に
- (再掲)nullだったらそれはバグ、というプログラミング環境を築くのが幸せな世界だと思う
- つまりHaskellは幸せなせか
Docker Imageとは？



## **1. Docker Image（イメージ）とは？**

Docker Image（ドッカーイメージ）とは、アプリを動かすための「設計図」のようなものです。

例えば、PCにアプリをインストールするとき、いろいろな手順が必要ですよね？

- OSを用意する
- 必要なソフトをインストールする
- 設定をする

Dockerでは、これらを全部まとめた「完成品のセット」が **Docker Image（イメージ）** です。

---

## **2. イメージとコンテナの違い**

「Docker Image」とよく一緒に出てくるのが「コンテナ」です。

この2つの違いを簡単に説明すると…

| 用語 | 説明 | 例え |
| --- | --- | --- |
| **Docker Image** | アプリを動かすための「設計図」 | ゲームのインストールファイル |
| **Docker Container** | 実際に動いているアプリ | ゲームを起動した状態 |

つまり、Docker Image は「動かす準備ができたアプリ」で、Docker Container は「**実際に動いているアプリ**」です。

---

## **3. Docker Image の使い方**

### **① Docker Hub からイメージをダウンロード**

Dockerには、「Docker Hub」というアプリストアのような場所があります。

ここから必要なイメージをダウンロードできます。

例えば、`nginx`（Webサーバー）のイメージをダウンロードする場合：

```ruby:sh

docker pull nginx

```

---

### **② イメージからコンテナを作成して実行**

ダウンロードしたイメージを使ってコンテナを作成し、実行します。

```ruby:sh

docker run -d -p 8080:80 nginx

```

💡 `-d` → **バックグラウンドで実行**（コンソールに出さずに動かす）

💡 `-p 8080:80` → **PCの8080番ポートとコンテナの80番ポートをつなぐ**

これで `http://localhost:8080` にアクセスすると、nginxのWebサーバーが動きます！

---

### **③ 使っているイメージを確認**

現在のDockerにあるイメージを確認するには、次のコマンドを実行します。

```ruby:sh

docker images

```

すると、次のように表示されます。

```ruby:sh

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    d1a364dc548d   2 days ago    133MB

```

---

### **④ イメージを削除する**

不要になったイメージは、削除することもできます。

```ruby:sh

docker rmi nginx

```

---

## **4. Docker Image の作り方**

既存のイメージを使うだけでなく、自分でカスタムイメージを作ることもできます。

そのために使うのが **Dockerfile（ドッカーファイル）** です。

例えば、Pythonをインストールしたカスタムイメージを作る場合：

### **Dockerfile の例**

```ruby:dockerfile

# 1. ベースイメージを指定（Pythonを使う）
FROM python:3.9

# 2. 作業ディレクトリを設定
WORKDIR /app

# 3. 必要なパッケージをインストール
RUN pip install flask

# 4. 実行するコマンドを指定
CMD ["python", "app.py"]

```

このDockerfileを使ってイメージを作るには、次のコマンドを実行します。

```ruby:sh

docker build -t my-python-app .

```

✔ **`my-python-app` という名前のDocker Image が作成される！**

---

## **5. まとめ**

✅ **Docker Image** はアプリを動かすための「設計図」

✅ **Docker Container** は実際に動いているアプリ

✅ **Docker Hub からダウンロード** してすぐに使える

✅ **Dockerfile を作ればオリジナルイメージも作れる**

Docker Image を使えば、アプリの環境構築が簡単になり、どこでも同じ環境で動かせます！
stripe 3Dセキュア テストカード情報一覧

# Stripeのテストカード一覧と認証要件

Stripeでの決済処理を実装する際、3Dセキュア(3DS)の動作確認や認証のフローをテストするために、さまざまなテストカードを利用できます。本記事では、認証要件ごとに分類したテストカードの一覧を紹介します。

## 認証要件別のテストカード一覧

### 設定がない場合に認証が必要

このカードでは、将来の支払いに備えて設定していない限り、オフセッションの支払いで認証が必要です。

- **カード番号:** `4000002500003155`
- **動作:** 設定後はオフセッションの支払いで認証不要。ただし、オンセッション支払いには常に認証が必要。

### 常に認証が必要

このカードは、カードの設定にかかわらず、すべての取引で認証が必要です。

- **カード番号:** `4000002760003184`
- **動作:** すべての取引で認証必須。

### すでに設定済み

このカードは、あらかじめオフセッションで使用するように設定されています。

- **カード番号:** `4000003800000446`
- **動作:** 1回限りの支払いとオンセッション支払いは認証が必要。オフセッション支払いは成功。

### 残高不足のカード

このカードは、認証に成功しても、`insufficient_funds` (残高不足) により決済が拒否されます。

- **カード番号:** `4000008260003178`
- **動作:** 1回限りの支払いで認証が必要。認証後も決済が失敗。

## 3Dセキュア(3DS)の認証要件

### 3DSが必須

#### 正常に支払いが完了するカード

- **カード番号:** `4000000000003220`
- **動作:** 3Dセキュア認証が必要。認証後、支払い成功。

#### 認証後に拒否されるカード

- **カード番号:** `4000008400001629`
- **動作:** 3Dセキュア認証が必要。ただし、認証後に`card_declined`で拒否。

#### 認証リクエストがエラーになるカード

- **カード番号:** `4000008400001280`
- **動作:** 3Dセキュア認証が必要だが、処理エラーで失敗。

## 3DSに対応しているが必須ではないカード

### 正常に処理可能なカード

- **カード番号:** `4000000000003055`
- **動作:** 3Dセキュア認証は任意。デフォルトではリクエストされない。

### 認証を試みるとエラーになるカード

- **カード番号:** `4000000000003097`
- **動作:** 3Dセキュア認証は任意。ただし、試みると処理エラーが発生。

### 3DS未登録のカード

- **カード番号:** `4242424242424242`
- **動作:** 3Dセキュアがサポートされているが、未登録のため認証リクエストが無効。

## 3DSに未対応のカード

このカードでは3Dセキュアがサポートされておらず、認証なしで決済が行われます。

- **カード番号:** `378282246310005`
- **動作:** 3Dセキュアなしで決済が進行。

## まとめ

Stripeのテストカードを活用することで、3Dセキュアの挙動やカードの認証要件を適切にテストできます。特に、サブスクリプション決済やオフセッション決済を実装する際には、適切なカードを選んで動作確認を行うことが重要です。
Javaで jjwt を導入する際にエラーが発生しました。  エラーメッセージ: io.jsonwebtoken:jjwt:jar:0.11.5 was not found...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809422/6ceaddaa-b8b9-d104-93b8-3a53382acc0c.png)

原因は、依存関係の指定が不完全であるためです。以下のように修正し、Maven を再読み込みしてください。
```
       <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.1</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.11.2</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.2</version>
        </dependency>
```
rex0220 計算式プラグイン 複数チェックボックスを文字列に

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、複数チェックボックスの選択肢を文字列に変換します。

# 概要

計算式プラグインで、複数のチェックボックス（果物とスイーツ）を文字列項目に変換してみます。

- 選択内容1（カンマ区切り）
- 選択内容2（カンマスペース区切り）

※チェックボックスは、[チェックボックスレイアウトプラグイン](https://qiita.com/rex0220/items/0cc12bd8bce58d5a1f06)で、レイアウトを変えています。

![2025-01-30_10h11_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a468ebc3-8d48-01c5-28a0-9b2ac9827aab.png)

# 操作例

![2025-01-30_10h16_23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/6fb90b78-29ca-e687-81cd-791d92043d75.gif)

# アプリ設定

チェックボックスは、横並びで配置

![2025-01-30_10h31_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a6218377-3acb-b752-2c5a-a27ba1fdc766.png)

チェックボックスの選択肢は、ChatGPT で生成したら、絵文字をつけてくれた！

![2025-01-30_10h30_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c408b5e0-0da3-33b9-2e60-d27bf57fd6d0.png)


# 計算式プラグイン設定

- 選択内容1（カンマ区切り）
    - ARRAY 関数で、チェックボックスの値を配列に結合
    - 文字列項目に配列を指定すると、カンマ区切りで変換
- 選択内容2（カンマスペース区切り）
    - JOIN 関数で、配列の値を指定した区切り文字（", "）で連結

![2025-01-30_10h18_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e3709f01-2289-3118-6d7c-0a74e1dbe414.png)

```.js
OPTION: 

// 選択内容1（カンマ区切り）:選択内容 SINGLE_LINE_TEXT
ARRAY(果物,スイーツ)

// 選択内容2（カンマスペース区切り）:選択内容2 SINGLE_LINE_TEXT
JOIN(
  ARRAY(果物,スイーツ),
  ", "
)
```

# チェックボックスレイアウトプラグイン設定

チェックボックスの項目幅と値の幅を指定して、レイアアウトを変更します。

![2025-01-30_10h21_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5f7f5416-ca23-40fd-9ef9-b5ed54ea87bb.png)
PoweBuilder DW（データウィンドウ）の枠を３D凸（6）にした際に、列間の罫線が透明ではなく黒になってしまう問題の対処方法

# 発生現象
１．PowerBuilderでDW（データウィンドウ）を作成し、枠の設定を3D凸(6)に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259881/ebe7877e-6d6b-cbd0-0de1-18dea9e59dd3.png)

２．列間の罫線が透明ではなく、黒になってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259881/a4a7e41d-b3f6-5388-c0fe-854b1c3e08e6.png)

この方法の解決方法を記載します。

# 解決方法

DWのオブジェクトには前後の位置関係が設定されているらしく、対象の列を右クリック、して前面に移動を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259881/6d617658-5357-2000-1744-df3aa54310d2.png)


対象の列が前面に出てきて、罫線が黒から白になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259881/2b691327-e491-9064-4bce-9d23a5086b7c.png)

これを一番左の列から順番に前面に移動をすることで解消しました。

ご参考になれば幸いです。
Windowsバッチ(.bat)学習メモ　他batからの戻り値取得

```bat:呼び出し元.bat
@echo off

set callTargetBat="呼び出し対象.bat"

for /f "usebackq" %%a in ('call %callTargetBat% arg1 "arg2" arg3') do (
    set returnVal=%%a
)

echo %returnVal%
```

```bat:呼び出し対象.bat
@echo off

setlocal
set finalVal=%1_%2_%3
echo %finalVal%
endlocal
```

```bat:結果
returnVal is
arg1_"arg2"_arg3
```
※呼び出し対象の標準出力を拾っているだけのため、他のechoが存在していたり、エラーメッセージが出たり、echo offを設定していなかったりすると、意図しないものが拾われてしまうので注意。