OmniAICreator/Qiita-1.07M huggingface dataset:
useStateについて知る

## はじめに
前回の記事にてuseMemoについて解説する記事を投稿しましたが、記事内でusetateを使用していたためuseStateについても解説する必要があると思い、今回記事を執筆するに至りました。
私自身、学習する立場のものですので誤植や間違いがあると指摘していただければ幸いです。

## useStateとは
useStateとは関数コンポーネント内で状態を管理するためのhooksになります。
```js
const [state, setState] = useState(initialState);
```
useStateを用いる際には上記のような記述をします。定義した配列の最初の要素(ここではstate)が現在の状態、2番目の要素がstateを更新するための関数になっています。
initialStateはstateに格納される初期値となっています。
javascriptでは型推論されるので、initialStateがtrueやfalseの値であればstateの型はbooleanの型が当てはめられます。もちろん配列や文字列などその他の型も適用できます。

また、例ではstate,setStateとなっていますが、
```js
const [a, setA] = useState(initialState);
```
のように任意の変数名を使用しても問題ありません。しかし、公式が推奨する命名規則として「状態名＋set状態名」というセットで用いることが推奨されています。

## サンプル
以下にuseStateを用いた簡単なサンプルコンポーネントを示します。
```jsx
import React, { useState } from 'react';

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

  return (
    <div>
      <p>{count} 回押したよ</p>
      <button onClick={() => setCount(count + 1)}>
        押してね
      </button>
    </div>
  );
}

export default Counter;
```
ボタンを押すとjsx内の{count}が押した回数増えていくことが確認できると思います。

また
```diff_jsx
import React, { useState } from 'react';

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

  return (
    <div>
      <p>{count} 回押したよ</p>
- <button onClick={() => setCount(count + 1)}>
+ <button onClick={() => setCount(prevState => prevState + 1)}>
        押してね
      </button>
    </div>
  );
}

export default Counter;
```
のように現在の状態を示すstateをprevStateとして引数に取る関数を渡せます。

また以下のようにオブジェクトや配列を管理することもできます。
```jsx
const [person, setPerson] = useState({ name: 'Shinji', age: 16 });

setUser(prevUser => ({ ...prevUser, age: 17 }));
```

※setstateの呼び出しは非同期であるため、即刻更新したstateの値が反映されるわけではないので、値が更新されていないなど後工程で予期しない動作をすることがあるかもしれません。

### 参考文献
[useState - React] https://ja.react.dev/reference/react/useState
cloudflareを利用してwebアプリを公開したい!part1(Pagesセットアップ)

# はじめに
　次に作る自作アプリは一般利用してもらえるようにcloudflare PagesとWorkersを使って公開してみようと思いました。
 　ひとまずベースができるまでを記事にしてみようと思います。

# 下準備-gitとプロジェクト
　cloudflare Pagesでアプリケーションを新規作成する際、gitに接続して任意のリポジトリをデプロイすることが可能なようです。
 　というわけで、今回のプロジェクト用に事前にリポジトリを用意しました。
  　今回は勉強がてらNuxtを触ってみようと思うので、[公式ドキュメント](https://nuxt.com/docs/getting-started/installation)の手順に則って進めていきます。
   　プロジェクトを作成したらそれをgitのmainにpushして準備完了です。

# cloudflareにデプロイ
　ダッシュボードのWorkers & Pagesに移動し、アプリケーションの作成ボタンをクリックします。
 　Pagesのタブに移動してgitに接続をクリックします。
  　任意のgitリポジトリを選択し、セットアップの開始をクリックします。
   　プロジェクト名とプロダクションブランチを設定(大体デフォルトでOK。)したのち、ビルドの設定をしていきます。
    　フレームワークプリセットに使用するフレームワークを設定(今回はNuxt)。ビルドコマンドとビルド出力ディレクトリは特に理由が無ければデフォルトのままでOK。アドバンスドの項目も今回はデフォルトにします。環境変数だけ後々追加するかも。
     　設定が完了したら保存してデプロイをクリックします。
      　以下の画面が表示されたら完了。表示されたURLにアクセスして確認してみましょう。
       ![cloudflarePagesDep_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3808364/35b6ca19-7758-d1c5-5f39-04c8b3eb4070.jpeg)

# おわりに
　次回はWorkerの準備をしていきます。Rustを使っていこうと思うので手順がすこし不安ですが......頑張ります。
【PlatformIO】ESP32C3・ESP32S3系でSerialの出力ができない問題に対処する

# 問題
ESP32-C3・ESP32-S3系（M5Stamp S3やそれが内蔵されたM5Stack Dialなどを含む）で、`Serial`を使って文字出力などを行っても、受信側に何も届かない。

## 解決方法
`platformio.ini`で、以下の行を追記する。

```ini
build_flags = -DARDUINO_USB_CDC_ON_BOOT=1
```

記載例:
```ini
[env:m5stack-stamps3]
platform = espressif32
board = m5stack-stamps3
framework = arduino
monitor_speed = 115200
upload_speed = 1500000
build_flags = -DCORE_DEBUG_LEVEL=3 -DARDUINO_USB_CDC_ON_BOOT=1
```




## 詳細

ESP32-C3・ESP32-S3系は、UART経由でのプログラム書き込みに加え、USB-Serial変換無しにUSB経由（CDC）で、JTAGを用いてプログラム書き込みを行うこともできます。
デフォルトでは、Serial出力はUART経由になりますが、Serialの受信側がCDCで接続されていると、Serialで出力した内容は受信できません。
そこで、前述の設定を追記し、Serialの出力先をCDCにする必要があります。

ちなみに、`ESP32-S3-DevKitC-1`などはUART接続のUSB端子とCDC接続のUSB端子があり、UART側で接続すると無印のESP32と同様に取り扱うことができます。

## 参考文献

https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/
Vue.jsのインストールとセットアップ方法を比較：create-vue、Vite、Vue CLIの違いとは？

**はじめに**
vueを学習し始めて1年ほど経ったのでなんとなく使っていたインストール方法の違いを比較してみました。
本記事では、Vue.js プロジェクトを始めるための3つの一般的な方法、create-vue、Vite、Vue CLI を比較し、それぞれの特徴を紹介します。

**1. create-vue**

**特徴:**

* **公式推奨**: Vue.js チームが推奨する最新のツール
* **シンプルで高速**: Vite をベースにしており、高速な開発サーバーとモジュールバンドルを提供
* **最新の機能**: Composition API や TypeScript サポートなどをはじめ、Vue.js の最新の機能をサポート

**インストールとセットアップ:**

```bash
npm install -g create-vue
create-vue [プロジェクト名]
cd [プロジェクト名]
npm install
npm run dev
```

**2. Vite**

**特徴:**

* **高速な開発サーバー**: ES モジュールをネイティブにサポートし、ホットモジュールリプレースメント (HMR) を高速に実現
* **柔軟性**: Vue.js だけでなく、React や Preact などの他のフレームワークもサポート
* **プラグイン豊富**: 様々なプラグインが提供されており、機能を拡張可能

**インストールとセットアップ:**

```bash
npm install -g vite
vite create [プロジェクト名]
cd [プロジェクト名]
npm install
npm run dev
```

**3. Vue CLI**

**特徴:**

* **成熟したツール**: 長年開発され、多くの機能を備えている
* **UIベースのインターフェース**: コマンドラインだけでなく、GUI を通してプロジェクト設定が可能
* **豊富な機能**: webpack をベースに、ルーティング、ステート管理、テスト、ビルドなど、様々な機能を提供

**インストールとセットアップ:**

```bash
npm install -g @vue/cli
vue create [プロジェクト名]
cd [プロジェクト名]
npm run serve
```

**比較表:**

| 機能         | create-vue     | Vite           | Vue CLI           |
|--------------|----------------|----------------|-------------------|
| 公式推奨      | ○             |              |                   |
| 速度         | 非常に高速      | 非常に高速      | 比較的遅い         |
| 柔軟性       | 標準的な設定 | 高い            | 比較的低い         |
| 機能         | 最新機能       | プラグイン豊富 | 幅広い機能         |
| UI インターフェース | コマンドライン   | コマンドライン   | GUI あり           |

**参考:**

* [create-vue](https://create-vue.vuejs.org/)
* [Vite](https://vitejs.dev/)
* [Vue CLI](https://cli.vuejs.org/)

**補足:**

- 上記のコードは、npm を使用していますが、yarn や pnpm などのパッケージマネージャーでも同様に利用できます。
- 各ツールには、詳細なドキュメントが用意されているため、必要に応じてドキュメントを参照してください。

**まとめ:**

* それぞれのインストーラーは、独自のメリットとデメリットがあるため、プロジェクトの規模やその時のニーズに合わせて、最適なツールを選択する方がいいと感じました。
AzureVMにssh接続できなくなった

VMの再起動を行ったところssh接続が行えなくなりました。結論から言いますと、osのソフトウェアベースのファイアウォール（ufw）に引っかかっているようでした。

## 確認手順
### nsgの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2910804/074f0b08-23f9-0d79-5449-83b5e4932615.png)
許可されていることがわかります。そのためvm側の設定を確認しました。

### nmapで確認
nmapコマンドで確認したところ

```
PORT     STATE  SERVICE
80/tcp   closed http
443/tcp  closed https

```
22portがフィルターされてました。


   



### ファイアウォールの設定変更
下記コマンドでsshで使用するポートのファイアウォールを解除します。
```bash
sudo ufw allow 22/tcp
```

```
Starting Nmap 7.80 ( https://nmap.org ) at 2024-03-11 11:41 JST
Nmap scan report for 000.000.000.000
Host is up (0.0048s latency).

PORT   STATE SERVICE
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 1.20 seconds
```
以上の手順で再びVMに接続できました
EC2 に DockerとDocker compose をインストールする手順

ec2 にdockerをインストールする簡潔な手順をメモしたので公開しておきます。
(上からやってけばできるはずですが、現在もできるかの保証はしてません。)

なお、EC2 は Amazon linux2 で作成し、SSH 接続した状態を前提とします。

# install docker
```
sudo yum install -y docker          # dockerのインストール
sudo service docker start           # dockerの起動
sudo usermod -a -G docker ec2-user  # ec2-userをdockerグループに入れる。これでec2-userがdockerコマンドを実行できる
sudo docker info                    # dockerの起動確認
```

# install docker compose
```
sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version
```

# (Option) Linux setting
vm.max_map_countはEC2が停止すると、設定がなくなるかもしれないです。
```
sudo sysctl -w vm.max_map_count=262144
sudo swapoff -a
sudo sysctl -p
```

以上です。
もしも、何か間違っていたり、動かないようでしたらご連絡いただけますと幸いです。
Source Code Viewer PHP

# Source Code Viewer PHP

# 概要

・PHP + GeSHi で書かれた、ソースコードビューワー CGI を作りました。

・Linuxサーバー上の各種プロジェクトのソースコードを言語ごとにシンタックスハイライトの色分けで表示することが出来ます。

・一応検索も可能です。

-----------------------------------------------------
# 設置方法:

・まず、Apache2 ＋ PHP8 が稼働している Linuxサーバー環境があるものとします。

・例示として、このPHPプログラムを
  /var/www/html/pub/viewer/ 
  に展開してください。

・次に、閲覧させたい各種プロジェクトのルートディレクトリを設定します。
  例示として、
  /var/www/html/pub/Src/
  ディレクトリを作成して、その下に
    ＜プロジェクト名＞/＜プロジェクトのファイル（ディレクトリ含む）＞
  を配置します。
    ＜プロジェクト名＞　のディレクトリは、シンボリックリンクでも大丈夫です。

・設置したら、適当なブラウザでアクセスします。

-----------------------------------------------------
# 使い方:
・例示として、
  http://サイトURL/pub/viwer/v.php にアクセスします。


- 画面上に、以下のような表示が出ます。
 ===========================================
 □一覧  /プロジェクト名/サブディレクトリ/ファイル名/  ［ 検索窓 ］
 ===========================================
その下に、プロジェクト一覧が出ますので、クリックして辿ってください。

![view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28186/a633e71e-a966-f740-bf87-ce286e4f589d.png)


-----------------------
□一覧   ボタンの使い方
-----------------------

-   □   ・・・ プロジェクト一覧に戻ります。
-   一覧 ・・・ プロジェクト内のファイル一覧に戻ります。
-   /プロジェクト名/サブディレクトリ/ファイル名/ ・・・　どれかをクリックするとそのディレクトリに移動します。

   
-----------------------------------------------------
# その他の機能

・pandoc がLinuxにインストールされている場合は、
拡張子 .md のファイルのビューワーとしてpandoc が使われます。

・ソースコード表示時の行番号にはすべてアンカーが付いていますので、
Pukiwiki等に行番号のリンク先を貼ることによって、ポインタとして使用できます。

・githubに同じソースが存在していて、リンクが欲しい場合は、config.php の
  $git_url にgithubへのリンクURLを記述すると、そこへ参照するためのボタン
　が現れるようになっていますが、おそらく多少の調整等が必要かもしれません。


-----------------------------------------------------
# 単なるソースコードビューワーって、何がうれしいの？

・どのソースの何行目、というポインタがURLになるので、ブックマークやWiki等に貼りやすい。（メモ代わりになる）

・エディタで開く場合と違って、間違ってソースを触ってしまう心配がない

・エディタの場合、プログラムを閉じてしまうと大抵はどのソースを弄っていたのかの情報を忘れてしまうけれど、Webブラウザだと頑張れば保持したままに出来るし、エディタと併用しながらソースを追いかける用途には適している気がする・・・気がするだけだけどね。

・携帯端末からも閲覧できる。
（と言うか、Android用のSourceCodeViewerというアプリを最初使っていたのですが、携帯端末にソースを転送するのが面倒くさいのと、やっぱり使い勝手が悪いので、サーバーサイドに移行しました。）

・GitHubでもいいんじゃないか？？？
・---> GitHubだと、publicソースを全部見れるのはいいけれど、機能が多すぎて微妙にブラウジングには適さない（かも）個人の主観です。


-----------------------------------------------------
# ライセンス：

 GeSHi に全面的に依存しているので、 GeSHi のライセンスに準じます。

（このリポジトリは GeSHi を含んでいます）

なお、PHP8に対応するために、GeSHiのソースに僅か数行の修正を加えさせていただきました

# github

-   https://github.com/iruka-git/SourceViewerPHP
Pythonで数値計算を効率化する Part2

#### データ解析に役立つNumPyの基本操作

##### 1. CSVファイルの読み込みと保存

データ解析では、CSVファイルを読み込んで操作することがよくあります。
NumPyを使うと、これが簡単にできます。

```python
import numpy as np

# CSVファイルの読み込み
data = np.genfromtxt('data.csv', delimiter=',', skip_header=1)
print(data)

# 配列をCSVファイルに保存
np.savetxt('output.csv', data, delimiter=',')
```

##### 2. データのフィルタリング

大規模なデータセットから条件に合ったデータを抽出するのもNumPyで簡単に行えます。

```python
# サンプルデータ
data = np.array([
    [1, 100],
    [2, 200],
    [3, 300],
    [4, 400],
    [5, 500]
])

# 2列目の値が300以上の行を抽出
filtered_data = data[data[:, 1] >= 300]
print(filtered_data)
```

##### 3. 基本統計量の計算

NumPyを使うと、基本的な統計量を簡単に計算できます。

```python
# サンプルデータ
data = np.array([1, 2, 3, 4, 5])

# 平均
mean = np.mean(data)
print(f"平均: {mean}")

# 中央値
median = np.median(data)
print(f"中央値: {median}")

# 標準偏差
std = np.std(data)
print(f"標準偏差: {std}")
```

##### 4. 欠損値の処理

データ解析では、欠損値の処理が重要です。
NumPyを使って、欠損値を簡単に扱うことができます。

```python
# サンプルデータ（欠損値を含む）
data = np.array([1, 2, np.nan, 4, 5])

# 欠損値を含むデータの平均
mean_with_nan = np.nanmean(data)
print(f"欠損値を無視した平均: {mean_with_nan}")

# 欠損値を0で置換
data_without_nan = np.nan_to_num(data)
print(f"欠損値を0で置換: {data_without_nan}")
```

##### 5. データの正規化

データの正規化は、異なるスケールのデータを比較する際に役立ちます。

```python
# サンプルデータ
data = np.array([1, 2, 3, 4, 5])

# 最小-最大スケーリング
normalized_data = (data - np.min(data)) / (np.max(data) - np.min(data))
print(f"正規化データ: {normalized_data}")
```

##### 6. 行列演算

NumPyでは、行列の演算も簡単に行えます。

```python
# サンプルデータ
matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])

# 行列の積
product = np.dot(matrix1, matrix2)
print(f"行列の積:\n{product}")

# 要素ごとの積
elementwise_product = matrix1 * matrix2
print(f"要素ごとの積:\n{elementwise_product}")
```

以上

---
前回の記事

https://qiita.com/benjamin1gou/items/367bfb989491bdc6ddd3
Gitとは

# この記事を書くきっかけ
私はプログラミング初心者です。昨年から勉強を始めました。毎日少しずつ、技術書を読んだり、プログラムを書いたりして、3月にはじめてWebアプリをデプロイしました。具体的には、Pythonを利用してDjangoでWebアプリを開発しました。利用したサービスはPostgresql、Git（SourceTree）、GitHub、Nginx、Gunicorn、AWSなどです。

独自のアイディアを盛り込んだオリジナルのコードを書く努力をしましたが、GitやNginxなどのサービスとその設定方法はすべて書籍を参考にしました。そのため、それぞれのサービスへの理解に不安があります。そのサービスがどういうもので、どんなコマンドを使えばいいのかがわからなければ、トラブルが起きたときに対処できません。そこで、自分が利用したサービスを最低限でも理解したいと思い、記事にしました。今回はGitについて勉強したいと思います。

# Gitとは
私たちは日々ファイルにいろいろな変更を加えています。ファイルを新規作成したり、下書きしたり、修正したり、加筆したり。このように、変化を加えられたファイルの状態のことを「バージョン」と言います。同じファイルの複数のファイルの状態（バージョン）を持っておくことをバージョン管理といいます。少しずつ変化した状態のファイルの情報を全て記録しておくのですね。

Gitは、このバージョン管理システムの一つです。いつ、誰が、どこを、なぜ修正したのか等、コードの修正履歴を記録するためのサービスです。ファイルの変更をバージョンとして記録することで、記録した地点へいつでも戻れる仕組みを提供しています。記録した地点の間を自由に行き来できるのはとても便利です。

一言で言えば、Gitはプログラム開発の作業履歴を記録するツールです。

### Gitができること
- コードの変更を記録する （add, commit）
- 状態や変更箇所を確認する （log, diff）
- 前の状態を復活させる （reset, revert）
- 作業箇所を分岐する （branch, checkout）
- 作業結果を統合する （push, merge）

### Gitのいいところ
- 古いバージョンから新しいバージョンのファイルまで管理できること
- 簡単に前のバージョンに戻せること
- 複数のメンバーでファイルや変更履歴をスムーズに共有できること


# バージョン管理の基礎知識
- コミット
    - コミットとは、ユーザーが好きなタイミングで**ファイルの状態を記録する操作**のことです。その記録自体のことも「コミット」と呼びます。 この記録は「.git」という隠し領域に保存されます。
- リポジトリ（貯蔵庫）
    - コミットを貯めていく場所のことです。
    - リポジトリを作成する方法は、①リポジトリを新規作成するか、②既存のリポジトリをコピー（クローン）する2つの方法があります。
    - リポジトリには、ローカルリポジトリとリモートリポジトリがの２種類のリポジトリがあります。
        - ローカルリポジトリは、手元で使っているパソコンに作成する自分専用のリポジトリです。
        - リモートリポジトリは、インターネットなどのネットワークのサーバー内にあるリポジトリです。　複数人で作業する時に、各人のローカルリポジトリと同期をとるために使用します。
- プッシュ/プル
    - プッシュとは、コミットをローカルリポジトリからリモートリポジトリへ反映させることです。プッシュを行うことで、ローカルリポジトリ上のファイルや変更履歴が、リモートリポジトリへアップロードされます。
    - プルとは、リモートリポジトリのコミットを、ローカルリポジトリへ反映させることです。プルを行うことで、リモートリポジトリ上のファイルや変更履歴が、ローカルリポジトリへダウンロードされます。
- ブランチ
    - ブランチとは、変更履歴の流れを分岐させておくことです。アプリに新機能をつける作業のためのブランチを作っておけば、うまくいかなくなればブランチごと捨て、うまく行った場合はブランチを統合（マージ）することができます。
- クローン
    - リモートリポジトリからローカルリポジトリを作成することです。誰かが作ったリモートリポジトリから、それと連携するローカルリポジトリを作成して作業するときにこの作業を行います。
- コンフリクト（競合）
    - 複数人が同じファイルの同じ場所に変更を加えてしまうことです。　
- プルリクエスト
    - 共同開発者とブランチをマージしていいかを話し合うことです。分岐させて作成したファイルを統合させても問題がないかどうか、確認をするためのコミュニケーションゾーンです。
    
# Gitでよく使うコマンド（ざっくり）
**リポジトリの作成**
| コマンド | 内容 |
|:-|:-|
| git init | ローカルリポジトリを新規作成する  |

**コミットの作成**
| コマンド | 内容 |
|:-|:-|
| git add  |  ステージングエリアに仮登録する |
| git commit  |  コミットを作成する |
| git rm |  Git管理下のファイルやディレクトリを削除する　|

**状態の確認**
| コマンド | 内容 |
|:-|:-|
| git status  | ローカルリポジトリの状態を確認する  |
| git diff  | 各エリアの違い（差分）を確認する  |
| git log  |  コミットの履歴を確認する |

**状態の復元**
| コマンド | 内容 |
|:-|:-|
|  git checkout |  ワーキングディレクトリの変更を取り消す |
|  git reset |  ステージングエリアに追加した変更をワーキングディレクトリへ戻す |
# まとめ
Gitとは、変更した箇所やその情報を記録するためのサービス。一度変更しても前の状態に戻すことができる。複数人で開発するときに便利。シェルコマンドで操作する。
springのTransactionalでロールバックされないお話

springの `@Transactional` を使用するとメソッドの外に例外が伝播した際にロールバックしてくれます。
ただし（デフォルトでは）プロキシ経由の外部メソッド呼び出しのみが対象になるということで、所謂 `@Autowired` したインスタンスから呼び出すメソッドに `@Transactional` を付与する必要があります。
そこで以下のようなコードを組んだのですが、これは期待した通りの動きにはなりませんでした。

```java:間違っている例
@Service
class ServiceA {
  @Transactional
  public void updateEntities(List<EntityA> entities) {
    // 全ての要素に対して UPDATE を実行して欲しい
    // エラーが起きても後続は処理を続ける
    for (Entity entity : entities) {
      try {
        update(entity)
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  @Transactional
  private void update(EntityA entity) {
    int cnt = dao.updateRecord(entity);
    if (cnt != 1) {
      // 更新件数が 1 で無ければ例外を投げてロールバックしたい
      throw new RuntimeException();
    }
  }
}
```

別のクラスから `updateEntities()` を呼び出し「全要素に対して処理を行いつつ、1 要素に対して更新件数が 1 で無ければその要素はロールバックしたい」という処理です。
これのテストを記述して試してみたところ、`update()` が例外を投げてもコミットされており、ロールバックされていませんでした。

# 主に間違っている点としては 2 つ

### 1. 内部呼び出しを行なっている

冒頭にもさらっと記載した通り、`@Transactional` に働いてもらうにはデフォルトでは別のクラスから呼ばれている必要があります。
今回 `update()` は同一クラスの `updateEntities()` から呼び出されてしまっています。

### 2. 可視性が private になっている

可視性は public である必要があるそうです（6.0 以降は protected または package private も可能とのこと）。

# 別クラスに切り出して対処

要素のカタマリを操作するクラスと単一の要素を操作するクラスに分けてしまおうという発想です。
クラスを分けてしまえば外部呼び出しの形になるので期待通りの動作となります。
また、ドキュメントを読んだだけで試していませんが mode を aspectj に変更し、設定を修正すれば自己呼び出しも対応可能なようです。

```java
class ServiceA {
  public void updateEntities(List<EntityA> entities) {
    for (Entity entity : entities) {
      try {
        serviceB.update(entity)
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}

class ServiceB {
  @Transactional
  private void update(EntityA entity) {
    int cnt = dao.updateRecord(entity);
    if (cnt != 1) {
      throw new RuntimeException();
    }
  }
}
```

教訓：ドキュメントを読む

https://spring.pleiades.io/spring-framework/reference/data-access/transaction/declarative/annotations.html
Best Reiki Healing in Ghaziabad

Priya The Optimist is a well respected spiritual healer and life coach with nearly 20 years of experience.

She remembers that she possesses unique psychic talents and powers, and has had a strong spiritual inclination and natural talent since she was a youngster. She has consistently displayed empathy and readily establishes connections with others. Her early experiences reveal her innate ability to form deep connections with people and perceive and empathise with things that are beyond the ordinary.


With her exceptional psychic talents, she has assisted several individuals worldwide in overcoming significant challenges in their lives, resolving karmic obligations, attaining spiritual enlightenment, and more.


![WhatsApp-Image-2022-11-13-at-11.52.37-AM-300x300.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812817/1efc06f8-0285-dcca-4709-a8f0b6cbfebd.jpeg)
Contact Info
Ganga apartment, Abhay Khand 1, Krishna Colony, Abhay Khand, Kaushambi, Ghaziabad, Uttar Pradesh 201010
Mob:- 9811709225
 Website:- https://theoptimistpriya.com/
UEでのキャラクターを押し出す壁についての問題を考える

# 注意
現状ドキュメントが不足、もしくは投稿者が見つけられていないため情報がかなり不正確です。（そのため考えるとしています）
手っ取り早く表題の押し出す壁を実装したい場合は事の発端に貼ってある一番最初のツイートのスレッドを参考にしてください。  
# 環境
Unreal Engine 5.4.2
# 事の発端
TL上に気になるツイートが流れてきました
<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">CharacterMovementは静止しているとコリジョンが正しく認識しないってUdemyで聞いた。ホントかな？<br>UE5.3で試してみた。<br><br>ホントだ。ガタガタだな。 <a href="https://t.co/5qjy4bvFTU">pic.twitter.com/5qjy4bvFTU</a></p>&mdash; TARK🥷 (@LideTark) <a href="https://twitter.com/LideTark/status/1798194878201160170?ref_src=twsrc%5Etfw">June 5, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

実際に試すと動画の通りの動きになりました。
壁にPlayerが押される動きってゲームにあってもおかしくはないものなので驚きました。
原因はCharacterMovementへ実装されている床にめり込まないようにする機能が壁へ反応しているようです。
（多分ソースのResolvePenetrationの部分...？）
また、ツイート主の方がスレッドに乗せている対処法はCharacterMovementComponent内で移動する際に使用している関数をframe毎に呼び出し、CharacterMovement側で衝突判定を行っているものと考えられます。
# 対処法1
この当行に対して対処法を解説してくださっている方がいました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/UE5Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE5Study</a><br>正しさ…の話は一旦置いて、とりあえず何が起きているかを解説してみます。<br><br>まず前提として、Blockコリジョン物体をSweep無しで動かすと、Block対象に対しては埋まります(Overlapが発火)。Sweep有りで動かすと接した状態で静止します(Hitイベントが発火)。<br><br>では、この押し出し挙動は… <a href="https://t.co/sR435rIQMs">https://t.co/sR435rIQMs</a></p>&mdash; 恒吉星光 (@seiko_dev) <a href="https://twitter.com/seiko_dev/status/1798348013678821730?ref_src=twsrc%5Etfw">June 5, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
ツイートの中では

- 壁はSweep（つまり障害物があった場合はすり抜けずに止まる）で動かす
- Hit判定が出るように設定しておく
- Hit状態になったら衝突したことによって動けなかった分のベクトル量を求める
- 先ほど求めた分衝突したアクターと壁をOffsetで動かす、壁を動かす際はSweepで動かす

といった処理で疑似的に壁がアクターを押し出しているような動きを実装しています。（多分）
ただしツリー上でもおっしゃられているように条件によって無限ループが発生したりと中々複雑そうです。
実際解説されている実装で壁を動かすとキャラクターが後ろや横から衝突した際に無限ループでエラーになります。
（これを回避するのにHit時の壁のオフセット移動をなくす方法がありますが、キャラクターが壁に向かって動くと壁からキャラクターが離れないため今度は壁が動かなくなります。）
# 対処法２
これは現状プロジェクトには使えないと思いますがVersion5.4から追加されたMoverプラグインに入っているPhysicsMannyPawnを使用すると壁側に何も細工をしなくとも壁にアクターが埋もれなくなります。
これは新しく追加されたMover2.0によってSimulatePhysicsをONにしないとできなかった挙動が表現できるようになったおかげです。
詳しい解説は以下のalwei氏のブログを参考にしてください（なお5.4.2だとブログ内で紹介されているMoverBasePawnはありません。代わりにPhysicsMannyPawnを継承してクラスを作成すると楽です。MoverBaseに近いのはAnimatedMannyPawnです。）
https://unrealengine.hatenablog.com/entry/2024/03/31/180000

実際に壁で押してみました（右からPhysicsMannyPawn,AnimatedMannyPawn,従来のCharacterMovement)
![Test5_4-UnrealEditor2024-06-1018-20-49-ezgif.com-video-to-gif-converter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366802/947a571c-3c2c-93f3-1c35-e445113e13ad.gif)
PhysicsMannyPawnは期待通りの動きをしてくれています。

# まとめ
以上TARK氏のツイートとそれに対する反応の流れをまとめたような記事にもなってしまいましたが現状この問題に対しての対処法でした。
正解と呼べるものは小手先では実装できそうにありませんのでこれぐらいにしておきます。

# 他参考
CharacterMovementについて

https://qiita.com/haya_t/items/7e5a2ad7eaa6f67aecaa

Sweepについて

https://www.unrealengine.com/ja/blog/moving-physical-objects
github actions で OIDCでAWSを認証しようとしたらエラーがNot authorized to perform


## 概要
[この記事](https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-aws)を参考にgithub actions で OIDCでAWSを認証しようとしたら以下のエラー
```
Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentity
```

## 解決策
以下の部分が良くなかった

```
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
                }
```

IAMロールの**信頼されたエンティティ**を以下に修正

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::${AWSアカウント}:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:${githubリポジトリ}:*"
                }
            }
        }
    ]
}
```

## 最後に
このポリシー条件は、GitHub Actionsから送られたOIDCトークンの aud クレームが sts.amazonaws.com と等しい場合にのみ、sts:AssumeRoleWithWebIdentity アクションを許可するという意味です。これにより、トークンが確かにAWSのSTSを対象として発行されたものであることを確認しています。

aud クレームは、トークンが使用されるべき対象（オーディエンス）を示します。

それが異なっていた？
【Apache】「Invalid command 'SSLPassPhraseDialog', perhaps misspelled or defined by a module not included in the server configuration」への対応

## はじめに

WEBサーバ移行中に発生したApacheのエラーについて記載します。

## 環境

- Rocky Linux 9.4
- Apache 2.4.57

## エラー内容

設定ファイルの構文チェックの為`$ httpd -t`を実行したところ、以下のエラーが出ました。

```shell-session
AH00526: Syntax error on line 18 of /etc/httpd/conf.d/ssl.conf:
Invalid command 'SSLPassPhraseDialog', perhaps misspelled or defined by a module not included in the server configuration
```

:::note info
調べたところ、ApacheでSSL証明書を利用するためには`mod_ssl.so`モジュールをインストールする必要があるようです。
:::

`/etc/httpd/conf.d`以下に`ssl.conf`ファイルがなければ`mod_ssl.so`モジュールはインストールされていない状況です。

筆者の場合は、旧サーバから`ssl.conf`ファイルは移行していたのですが、`mod_ssl.so`モジュールはインストールしていませんでした。

### インストールの確認

現状ではインストールされていないので何も表示されません。

```shell-session
$ find /etc/httpd/modules/ -name mod_ssl.so
```

## mod_ssl.soモジュールのインストール

```shell-session
sudo dnf install mod_ssl
```

### インストールの確認

```shell-session
$ find /etc/httpd/modules/ -name mod_ssl.so
/etc/httpd/modules/mod_ssl.so
```

## おわりに

モジュールのインストールにより無事に`httpd -t`の構文チェックも通りました。

```shell-session
sudo httpd -t
Syntax OK
```

## 参考

https://qiita.com/marumasa/items/de2cbde0215fe8d20022

http://www.sewiki.net/detail/1/37/
「nginx: [warn] the "listen ... http2" directive is deprecated...」への対応

## はじめに

Nginxの設定ファイル確認時に出た警告と、その対応について書きます。

## 環境

- Rocky Linux 9.4
- Nginx 1.26.0

## 警告の内容

Nginx 1.25.1で`listen ... http2`ディレクティブが非推奨になり、`$ nginx -t`で設定ファイルを確認すると、以下のような警告が出ます。

```bash
$ sudo nginx -t
nginx: [warn] the "listen ... http2" directive is deprecated, use the "http2" directive instead in {confファイル名}:2
```

## 対処法

エラーメッセージの通り、`http2`ディレクティブを設定します。

```bash:修正前
server {
  listen 443 ssl http2;
  ...（後略）
}
```

```bash:修正後
server {
  listen 443 ssl;
  http2 on;
  ...（後略）
}
```

## おわりに

上記の修正で問題なく`$ nginx -t`が成功しました。

```bash
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

## 参考

https://www.f5.com/ja_jp/company/blog/nginx/nginx-plus-r30-released
Javaで「switch文を使った条件分岐」の動作を確認してみた

# 概要

Javaで「switch文を使った条件分岐」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/if/index4.html

# 実装

以下のファイルを作成しました。
```JSample4_1.java
class JSample4_1{
  public static void main(String[] args){
    int[] classcode = {1,3,2};
    String[] name = {"鈴木","本田","遠藤"};

    for (int i = 0; i < 3; i++){
      System.out.print(name[i] + "さんは");

      switch(classcode[i]){
        case 1:
          System.out.println("Aクラスです");
          break;
        case 2:
          System.out.println("Bクラスです");
          break;
        case 3:
          System.out.println("Cクラスです");
      }
    }
  }
}
```

```
$ javac JSample4_1.java 
$ java JSample4_1 
鈴木さんはAクラスです
本田さんはCクラスです
遠藤さんはBクラスです
```

# まとめ

何かの役に立てばと。
【Python】【Selenium4】「'WebDriver' objects has no attribute 'find_element_by_name'」エラーが出た時の解消法

## 背景
以下を実行した

```
$ python {ファイル名}.py
```

すると

```
Traceback (most recent call last):
  File "/〜/sele-tu.py", line 11, in <module>
    search_box = driver.find_element_by_name('q') #ページ上の要素の取得
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'WebDriver' object has no attribute 'find_element_by_name'
```
おや…？

どうやらSeleniumがVer.3 → 4 に上がる際に使えなくなった模様。

以下で解決しました。


## 変更前
```
search_box = driver.find_element_by_name('q') #ページ上の要素の取得
```

# 引数にまとめて書くやり方に統一される

## 変更後
```
from selenium.webdriver.common.by import By
search_box = driver.find_element(By.NAME, "q")
```

これでOK
codeigniter4　画面によってLocaleを変更する

日本語と英語のお問い合わせが必要だったので調査しました。
Localeを変更したいControllerのinitControllerに以下を追記

$language = \Config\Services::language();
$language->setLocale("en"); //英語

これで
app\Language\en\Validation.phpを見に行ってくれます。
Vue.jsのディレクトリ構成について

## ディレクトリ構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/e5e8319a-4ae1-977e-a5e9-82c7bdff4edc.png)

## node_modules
プロジェクトにインストールされたnpmパッケージが格納されるディレクトリ。

## public
静的なファイルが入るディレクトリ。

## src
ソースコードが入るメインのディレクトリ。

## assets
画像やスタイルシートなどのリソースファイルを格納するディレクトリ。

## components
再利用可能なUI部品（コンポーネント）を格納するためのディレクトリ。

## router
シングルページアプリケーションでのルーティングを管理するディレクトリ。

## views
ルートとなるVueコンポーネントを格納するディレクトリ。
通常、ページごとに1つのVueコンポーネントを持つ。

## App.vue
Vueアプリのトップレベルコンポーネント。

## main.js
Vue.jsの起動場所となるファイル。
このファイルにはVueインスタンスを作成し、ルーターやストア、アプリケーション全体の設定を行うコードが含まれている。

## index.html
Vue.jsアプリケーションのエントリーポイントとなるファイル。
このファイルはブラウザに直接読み込まれ、Vue.jsアプリケーションのルートとなる要素を定義し、必要なスクリプトやスタイルシートを読み込む。

## package-lock.json
npm install時のパッケージ情報（バージョン等）を保持するファイル

## package.json
 npmコマンドや依存するnpmモジュールを管理するファイル
右も左もわからない人のためのZod（ゾット）入門

フロントエンド界隈で「Zod」という言葉を耳にする機会が増えたと思っています。

なんとなく検証するテストコードなのはわかっています。

ただ、当然書けないしそもそも何か全くわかっていなかったので知識の更新のためにメモとして残します。

:::note info
この記事は、3分ぐらいで「Zodってなに？」を説明するための記事です。
:::

## Zod（ゾット）ってなに？

Zodの目的は「重複した型宣言を排除すること」だそうです。

正直よく分かりませんが…スキーマ宣言および検証ライブラリです。

:::note info
例えばAPI経由で送られてくるデータやコード状に管理されるグローバルメニューのリンク集のようなデータの正しさを保証するために利用されるケースが多い印象です。
:::

https://zod.dev/

もう少し理解を深めたかったのでチュートリアルをやってみたいと思います！

https://www.totaltypescript.com/tutorials/zod


## Zodチュートリアルをやってみる
Githubのページに行き`git clone`しようと思ったらCodespacesが立ち上がる仕様だったので立ち上げてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/2816173f-d42a-e54c-7645-fae8a7d3ab1c.png)

Codespaceを立ち上げると下記のような表示がブラウザに表示されると思います！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/2dccf79b-7377-877c-537c-de92c48d87bf.png)

:::note info
[Codespaces](https://github.co.jp/features/codespaces)はGithubの提供するクラウドで開発環境を構築できるものです！
:::

### `npm run exercis`を実行してチュートリアルの開始
コマンドを実行するとエクササイズのリストがコマンドラインに表示されるので矢印キーで操作してEnterします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/d6afba43-cc3c-13f8-25d3-7a4bd66286e3.png)

Enterを押すとZodによるバリデートが実行されてコマンドラインにエラーが表示されるので修正していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/3a1d6e10-164e-8f4c-f4d7-1c9e73c52935.png)

どこをどのように直せば良いのか見当もつかないので用意してくれている`01-number.solution.ts`を確認して下記を追加しました。

```diff_javascript
+ const numberParser = z.number();

export const toString = (num: unknown) => {
+ const parsed = numberParser.parse(num);
-  return String(num);
+  return String(parsed);
};
```

修正したら無事テストが通ったようです。


## Zod（ゾット）まとめ
APIの場合どのようなデータ形式で返ってくるか不透明だとエラーの原因になることもあるのでZodを使って検証することでデータの正しさを保証できるのは良いと思いました。

:::note alert
すべてを検証するのはやりすぎなこともあります。
チェックするということはそれだけzodによる検証コードを書くことになります…。
当然メンテナンスも必要になってきますので、必要最低限にできることが望ましいです。
:::

フレームワークが用意しているコンポーネントなどすでに十分な型のチェックが行われているものまで検証することはないと思うので過度に導入してしまわないように私も注意したいと思います。
WoocommerceのWebhook

# 概要
WoocommerceのWebhookを使うことがあったので
その記録です。

# 設定
## 設定ページ
woocommerce→「設定」→「高度な設定」→
青の文字で小さく「Webhook」と書かれているのでクリックする。

## Webhookの追加
「Webhookを追加」ボタンを押すと
設定画面に移動します。

## Webhookの設定
![スクリーンショット 2024-06-10 17.34.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966688/2c162778-7617-f51d-ee41-a22d7ccadbf9.png)

名前：好きな名前で大丈夫です。
ステータス：有効にすると送信されます。
トピック：送信するトリガーを選べます。(例：注文作成時)
配信URL：Webhookを送信する先のURLを入力します。
秘密鍵：自動生成されます。

項目を全て埋めて「保存」を押せば
登録完了です。

# まとめ
すごく簡単にWebhookを登録することができました。
本家の[ドキュメント](https://woocommerce.com/document/webhooks/)もぜひ読んでみてください！
Bun の使い方

[Bun](https://bun.sh/)の使い方です。


## Ubuntu 24.04 にインストール

```bash
sudo snap install bun-js
```

バージョンの確認

```text
$ bun --version
1.1.12
```

## TypeScript のプログラムを走らせる

プログラム

```ts:index.tsx
const server = Bun.serve({
  port: 3000,
  fetch(request) {
    return new Response("Bun へようこそ!");
  },
});

console.log(`Listening on localhost:${server.port}`);
```

Bun で実行

```bash
bun run index.tsx
```

クライアントで接続

```bash
http http://localhost:3000
```

実行結果

```text
$ http http://localhost:3000
HTTP/1.1 200 OK
Content-Length: 20
Date: Mon, 10 Jun 2024 08:39:03 GMT
content-type: text/plain;charset=utf-8

Bun へようこそ!
```

## JavaScript のプログラムを走らせる

プログラム

```js:http.js
export default {
  port: 3000,
  fetch(request) {
    return new Response("皆さん　こんにちは!")
  },
}
```

Bun で実行

```bash
bun run http.js
```

クライアントで接続

```bash
http http://localhost:3000
```

実行結果

```text
$ http http://localhost:3000
HTTP/1.1 200 OK
Content-Length: 28
Date: Mon, 10 Jun 2024 08:41:40 GMT
content-type: text/plain;charset=utf-8

皆さん　こんにちは!
```
XunziALLMは「不入虎穴不得虎子」をどうトークナイズするのか

『[Overview of EvaHan2024: The First International Evaluation on Ancient Chinese Sentence Segmentation and Punctuation](https://aclanthology.org/2024.lt4hala-1.27)』を横目に、[XunziALLM](https://github.com/Xunzi-LLM-of-Chinese-classics/XunziALLM)のトークナイザを試してみた。Google Colaboratoryだと、こんな感じ。

```
!pip install transformers tiktoken
!test -d Xunzi-Qwen || env GIT_LFS_SKIP_SMUDGE=1 git clone --depth=1 https://www.modelscope.cn/Xunzillm4cc/Xunzi-Qwen.git
from transformers import AutoTokenizer
tkz=AutoTokenizer.from_pretrained("Xunzi-Qwen",trust_remote_code=True)
print(tkz.convert_ids_to_tokens(tkz("不入虎穴不得虎子")["input_ids"]))
```

「不入虎穴不得虎子」を[Xunzi-Qwen-7B](https://modelscope.cn/models/Xunzillm4cc/Xunzi-Qwen/summary)でトークナイズしてみたところ、私(安岡孝一)の手元では以下の結果になった。

```
[b'\xe4\xb8\x8d', b'\xe5\x85\xa5', b'\xe8\x99\x8e', b'\xe7\xa9\xb4', b'\xe4\xb8\x8d\xe5\xbe\x97', b'\xe8\x99\x8e', b'\xe5\xad\x90']
```

素のUTF-8なので読みにくいが、「不」「入」「虎」「穴」「不得」「虎」「子」とトークナイズされているようだ。うーん、「不」「入」と「不得」でトークナイズの粒度が違うのは、かなり使いにくいなぁ。
ubuntu core 24がどうたらな件

Linuxでガンダムのリゼロのようなやつは作れないかとcopilotに聞いたところ、難しいとの反応が
帰ってきたので、組み込みLinuxの話しへ移動する。組み込みLinuxと言えば、前にデスクトップパソコンでお世話になったubuntuがあったので、ubuntu coreの話しまですんなりと進むに至る。

copilotの紹介は以下の通りであった。

Ubuntu Core 24は、Ubuntuの24.04 LTS（Noble Numbat）を基盤とした最新のリリースで、12年間の長期サポートを提供する、厳格に隔離されたオペレーティングシステムです1。IoTデバイスメーカー向けに新しい工場インストールシステムを提供し、AIoT対応のGPUサポートや、LandscapeおよびMicrosoft Azure IoT Edgeによるデバイス管理統合機能が特徴です2。

主な新機能は以下の通りです:

改善されたGPU統合: ハードウェア互換性を高め、リソース利用を最適化します。
Landscapeによるデバイス管理: 効率的なデバイス管理、セキュリティ、アップデートを実現します。
Azure IoT Edgeとのエッジおよびクラウド統合: Ubuntu CoreデバイスをAzureクラウドとシームレスに統合します。
新しいROS統合: ロボティクス開発者向けに、Robot Operating System（ROS）との本番環境での統合を提供します。
新しいドキュメントとドキュメント構造: ユーザーがより簡単に情報を見つけられるように改善されています。
Ubuntu Core 24は、Linux Kernel 6.8とsystemd 2.55を含む最新の機能をバンドルし、snapdの最新機能も全て含まれています。これには、動的なカーネルブートパラメータ、ジャーナルログのクォータグループ制限、オフラインリモデリングなどがあります1。

6月10日時点
TypeSpecで出力先のフォルダ名などを変更する設定

[TypeSpec](https://typespec.io/)を利用してOpenAPIの仕様書を作成すると、デフォルトでは`tsp-output/@typespec/openapi3/openapi.yaml`のパスにファイルが出力されます。

これを任意のフォルダ（例えば`swagger/spec.yaml`）へ出力するように設定を変更する方法をまとめます。

最終的には設定ファイルを以下のように記述しました。

```yaml:tspconfig.yaml
emit:
  - "@typespec/openapi3"

options:
  "@typespec/openapi3":
    emitter-output-dir: "{output-dir}"
    output-file: "{service-name}.{version}.spec.yaml"

output-dir: "{project-root}/openapi"
```

## 設定の変更
TypeSpecの設定は`tspconfig.yaml`に記載するか、CLIでのコンパイル実行時にフラグを指定することで変更できます。この記事では前者の`tspconfig.yaml`に記載する方法で説明したいと思います。

https://typespec.io/docs/handbook/configuration#typespec-configuration-options

`tspconfig.yaml`ファイルは、コンパイル時のエントリーポイントのパスに存在するものか、最も近い親フォルダに存在するものが参照されるようです。

https://typespec.io/docs/handbook/configuration#configuration-file

## 出力フォルダを設定
デフォルトではファイルは`{output-dir}/{emitter-name}`というパスで出力されます。

https://typespec.io/docs/handbook/configuration#configuring-output-directory

Emitterというのは、TypeSpecで記述した仕様の**出力フォーマットのようなもの**と私は認識しています。互換性があるものであれば、1つの記述でOpenAPIの仕様で出力したり、gRPCのProtobufで出力したりと出し分けられるようです。

今回想定しているユースケースはOpneAPIの仕様のみの出力なので、出力フォルダをemitter名を含まない`openapi`フォルダとすることにします。

### output-dirの設定
`tspconfig.yaml`に以下のように追記します。

```diff_yaml:tspconfig.yaml
emit:
  - "@typespec/openapi3"

+ output-dir: "{project-root}/openapi"
```

ここで`{project-root}`は組み込み変数で、`tspconfig.yaml`ファイルのあるフォルダのパスを参照します。

ちなみに、`output-dir`は**絶対パス**にする必要があり、`output-dir: "./swagger"`などには設定できません。

これで`openapi/@typespec/openapi3/openapi.yaml`にファイルが出力されるようになりました。

### emitter-nameの設定
上記の設定では出力フォルダにまだemitter名のパスが残っているため、emitter名を省略するように設定します。

```diff_yaml:tspconfig.yaml
emit:
  - "@typespec/openapi3"

+ options:
+   "@typespec/openapi3":
+     emitter-output-dir: "{output-dir}"

output-dir: "{project-root}/swagger"
```

ここでは、OpneAPIの仕様書を出力する`@typespec/openapi3`のエミッターのオプションとして、出力先に大元の`output-dir`をそのまま指定しています。

この設定により、`swagger/openapi.yaml`に出力されるようになりました。

## 出力ファイル名を設定
次に出力されるファイル名が`spec.yaml`となるように設定を変更します。

```diff_yaml:tspconfig.yaml
emit:
  - "@typespec/openapi3"

options:
  "@typespec/openapi3":
    emitter-output-dir: "{output-dir}"
+   output-file: "{service-name}.{version}.spec.yaml"

output-dir: "{project-root}/openapi"
```

ファイル名は、デフォルト値が`{service-name}.{version}.openapi.yaml`という形式なようです。なので、それを踏襲して最後の`openapi.yaml`の部分のみ`spec.yaml`へと変更しています。

https://typespec.io/docs/next/emitters/openapi3/reference/emitter#output-file

これにより目的としていた`openapi/spec.yaml`への出力ができるようになりました。
PowerShellで大文字と小文字が異なるキーを持つJSONを取り扱う

2024年6月現在、PowerShellのConvertFrom-Jsonに大文字と小文字のみが異なるキーを持つJSONを読み込ませるとエラーが発生します。

下記例ではfoo と Foo　がキーとなるJsonをシリアライズしようとしている。

```PowerShell:PowerShellで下記のようなfooとFooがキーとなるjsonをシリアライズしようとするとエラーとなる
# here-string で文字列を変数jsonに
$json = @"
{
    "foo": "bar",
    "Foo": "bar"
}
"@

$json | ConvertFrom-Json
```

## 今回試している環境

- Windows 11 23H2
- Windows PowerShell 5.1.22621.3672
- PowerShell 7.5.0-preview.2

### Windows PowerShell のケース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/4682dcee-b7e9-db49-f322-3a00fb7e8de3.png)

### PowerShell 7 のケース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/5b19fb6b-4ebc-b190-74f9-361e51a972ca.png)

## 事象について

[RFC 8259 - The JavaScript Object Notation (JSON) Data Interchange Format](https://datatracker.ietf.org/doc/html/rfc8259)

JSONフォーマットについては、RFC 8259で文書がありますが、こちらのRFCでは大文字小文字を区別する仕様となっていますが、PowerShellのConvertFrom-Jsonコマンドレットをオプションを指定せずに実行すると、PSCustomObjectが出力されますが、PSCustomObjectのプロパティ名は大文字区別を区別しない仕様となっているため、齟齬が発生してエラーとなるようです。

```powershell
# 下記のようにfooとFooが混在したpscustomobjectを作成しようとしてもエラーになる
$obj = New-Object -TypeName PSObject
$obj | Add-Member -MemberType NoteProperty -Name 'foo' -Value 'bar'
$obj | Add-Member -MemberType NoteProperty -Name 'Foo' -Value 'bar'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/40ef5b26-3ae5-ab07-bfe9-5d6a7901e730.png)

## PowerShell 7での対応方法について

- [ConvertFrom-Json does not handles same keys with different case (but JSON is case sensitive)
#3705](https://github.com/PowerShell/PowerShell/issues/3705)

PowerShellのgithubに上記のissueがあり、`-AsHashTable`オプションを利用する回避策が紹介されています。

`-AsHashTable`オプションを利用する事でPSCustomObjectではなく、HashTableで出力されエラーになりません。

```PowerShell:-AsHashTableオプションを利用(Windows PowerShellでは利用不可）
# here-string で文字列を変数jsonに
$json = @"
{
    "foo": "bar",
    "Foo": "bar"
}
"@

# AsHashTableオプションはWindows PowerShellでは利用できない
$json | ConvertFrom-Json -AsHashTable
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/184ebdda-4395-818e-c5fd-58842199b0a9.png)

## Windows PowerShellでの対応方法について

https://github.com/PowerShell/PowerShell/issues/3705#issuecomment-350022987

issueにはWindows PowerShellでは.Net Frameworkで提供されている、System.Web.Script.Serialization.JavaScriptSerializerクラスを利用して回避する方法が紹介されていました。

[JavaScriptSerializer クラス](https://learn.microsoft.com/ja-jp/dotnet/api/system.web.script.serialization.javascriptserializer?view=netframework-4.8.1&redirectedfrom=MSDN)

```powershell
$json = @"
{
    "foo": "bar",
    "Foo": "bar"
}
"@

Add-Type -AssemblyName System.Web.Extensions
$obj = (New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer -Property @{MaxJsonLength=67108864}).DeserializeObject($json)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/8799b6e1-27ea-8d18-799d-730a319691ba.png)

JavaScriptSerializerクラスを利用してhashテーブルが取得できました。

## 総評

ConvertFrom-JsonがデフォルトだとPSCusotmObjectで出力するため、その制約からエラーになっていてなかなかつらい感じですね。

この制約はPSCustomOBjectではなくHashTableで出力する事にて回避できますが、ひと手間かかりますね。
Angular でインターフェイスを作ってみました。

インターフェイス？って言葉が出てきました。が、まだ私にはイメージできていません。Angular で何かするために必要なのだろうというレベルなのですが、とりあえずやってみて理解しようというスタンスで試してみます。

今回の記事だけではなく、もう少し先まで進んでから理解できると思っています。
実はデータ型？って言葉もよくわからず、なんとなくで使っています。
今時点はご了承ください。

#### １．インターフェイスを作成します。
##### １－１．新しい汎用インターフェイスを作成するコマンドを実行します。
・コマンドプロンプトで以下のコマンドを実行します。
`ng generate interface encyclopedia`

（アウトプット）
![5-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798951/2004f4a0-b80b-6b09-340c-8382b1a128f4.png)
##### １－２．app ディレクトリの直下に encyclopedia.ts が追加されています。
・エクスプローラで以下のディレクトリを参照します。
`C:\Users\user\Angular\monotoneboy\src\app`

（アウトプット）
![1-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798951/ce19d8e1-668b-0f32-2848-71d913a337b9.png)
#### ２．プログラムを更新します。
##### ２－１．encyclopedia.ts にデータ型を定義します。
・以下のファイルを更新します。
`C:\Users\user\Angular\monotoneboy\src\app\encyclopedia.ts`

``` diff
+ export interface Encyclopedia {
+   id: number;
+   name: string;
+ }
```
##### ２－２．app.component.ts に encyclopedia インターフェイスをインポートします。
・app.component.ts に以下を設定します。
``` diff
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HeaderComponent } from './header/header.component';
+ import { Encyclopedia } from './encyclopedia';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, HeaderComponent],
template: `
  <main>
    <app-header></app-header>
  </main>
`
})
export class AppComponent {
}
```
##### ２－３．app.component.ts にサンプルデータを作成します。
・app.component.ts に以下を設定します。
``` diff
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HeaderComponent } from './header/header.component';
import { Encyclopedia } from './encyclopedia';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, HeaderComponent],
template: `
  <main>
    <app-header></app-header>
  </main>
`
})
export class AppComponent {
+  encyclopedia: Encyclopedia = {
+    id: 999,
+    name: 'Test Name',
+  };
}
```
（アウトプット）
![2-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798951/5d4531b7-97ec-aac1-0dcf-6363ad591041.png)

:::note info
ここで新たに表示されるものはありません。エラーにならないこと確認します。
:::

エラーになっていないので、今日のところはここまでです。
【備忘録】`grep`コマンドでファイルパスを表示する/しない

# 環境
* Ubuntu 22.04.4 LTS
* grep 3.7

# はじめに
`grep`コマンドでファイルパスを表示する/しないオプションを探すのに手間取ったので、備忘録としてファイルパスがどのようなときに表示されるか表示されないかを記載します。

# 前提
`target`ディレクトリの中に`bar.txt`と`foo.txt`があります。

```
$ tree target
target
├── bar.txt
└── foo.txt

0 directories, 2 files
```

```plain:target/bar.txt
alice
bob
chris
```

```plain:target/foo.txt
dave
eve
alice
```


# 動作確認

## ファイル名を表示する/しないオプションを使わない

### 1個のファイルを指定

```
$ grep -e "lic" target/bar.txt
alice
```

ファイルパスは表示されない。

### 複数のファイルを指定

```
$ grep -e "lic" target/bar.txt target/foo.txt
target/bar.txt:alice
target/foo.txt:alice
```

ファイルパスは表示される。

### ディレクトリを指定

```
$ grep --recursive -e "lic" target/
target/bar.txt:alice
target/foo.txt:alice
```

ファイルパスは表示される。

## ファイルパスを表示する/しないオプションを使う

### 常にファイルパスを表示する


```
$ grep --with-filename -e "lic" target/bar.txt
target/bar.txt:alice
```


```
-H, --with-filename
    Print the file name for each match.  This is the default when there is more than one file to search.  This is a GNU extension.
```

### 常にファイルパスを表示しない

```
$ grep --no-filename -e "lic" target/bar.txt target/foo.txt
alice
alice
```

```
-h, --no-filename
    Suppress the prefixing of file names on output.  This is the default when there is only one file (or only standard input) to search.
```


## ファイルパスのみを表示する

### マッチするファイルを表示する

```
$ grep --files-with-match --recursive -e "bob" target
target/bar.txt
```

```
-l, --files-with-matches
    Suppress normal output; instead print the name of each input file from which output would normally have been printed.  Scanning each input file stops upon first match.
```


### マッチしないファイルを表示する

```
$ grep --files-without-match --recursive -e "bob" target
target/foo.txt
```

```
-L, --files-without-match
    Suppress normal output; instead print the name of each input file from which no output would normally have been printed.
```
RDSにスナップショットのdumpファイルをインポート

とあるシステムのステージング環境のDBをいじっていた、ある日—。

show tables;
\>> Empty set (0.00 sec)

## スナップショット復元
1. AWS RDS コンソールから「スナップショット」>「アクション」>「復元」

2. 立ち上がったスナップショットDBのインスタンスを選択し、変更を行う
   - 「認証情報管理」>「AWS Secrets Manager で管理」を選択し、保存
   - 必要に応じて正しいセキュリティグループを当てる（もともとのRDSに当ててるやつと同じにするとか）
3. Secrets ManagerからスナップショットDBのユーザー名とパスワードを確認

## スナップショットDBの中身をエクスポート

Secrets Managerから確認できる、スナップショットDBのユーザー名とパスワードを使って、DBの中身をエクスポートします。

指定するDB名ですが、RDSのコンソールでは「-」みたいに表示されてDB名が分からないかもしれませんが、おそらくスナップショットを取った時点でDB名も引き継いでいるはずなのでそれと同じものになると思います。
もしそれすら忘れてしまったら、MySQLにログインしてデータベース一覧を確認しましょう。
~~~bash
# ログイン
mysql -h スナップショットのエンドポイント -u ユーザー名 -p
~~~
~~~sql
SHOW DATABASES;
~~~

エクスポートを実行します。

~~~bash
mysqldump -h スナップショットのエンドポイント -u ユーザー名 -p DB名 > dump.sql --set-gtid-purged=OFF
~~~

`dump.sql`というファイルが生成されます。この中にデータを復元させるためのSQLコマンドがたくさん入ってます。実際に覗いてみると分かりやすいので見てみてください。

## 別のRDSにインポート

私はcdkでRDSを定義していたため、cdkでRDSを再生成しました。
とにかく、インポート先のDBを用意します。

そしてそこに、先ほどの`dump.sql`を読み込ませてデータをインポートします。

そして本来なら以下の方法でインポートできるはず。
~~~bash
# よく見るやり方
mysql -h インポート先のDBエンドポイント -u ユーザー名 -p DB名 < dump.sql
~~~

しかし、私の場合は以下の権限エラーが起こりました。
~~~bash
ERROR 1227 (42000) at line 14: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
~~~
このエラーに関しては調べたらたくさん記事が出てきて、
例えばdumpファイルから`DEFINER`を消すとか、
ファイルの冒頭にある`SET`3行をコメントアウトするとか、
`mysqldump`実行時に`--set-gtid-purged=OFF`を入れる（今回は上記ですでに入れている）
などをすれば解消されるとのことでしたが、解消されず。

よくわかりませんが、外から実行できないなら一旦中に入って直接実行させてみようということで、インポート先のDBにログインしちゃいます。
（root権限があるユーザーである前提）
~~~bash
# mysqlログイン
mysql -h インポート先のDBエンドポイント -u ユーザー名 -p
~~~
データベースを作成（なければ）
~~~sql
CREATE DATABASE `DB名`;
~~~
データベースを指定
~~~sql
USE DB名;
~~~
そして`SOURCE`コマンドでdumpファイルの中身を実行させます。
~~~sql
SOURCE /home/ec2-user/dump.sql;
~~~
これだとうまくいきました。

言うまでも無いですが上記コマンドのdumpファイルのパスは`pwd`とかで確認すれば良いです。（もちろんmysqlからログアウトした状態で）
~~~bash
pwd dump.sql
> /home/ec2-user
~~~

## なぜmysqlにログインしてからSOURCEコマンドじゃないとできないのか

claudeに聞いてみた

1. `mysql -h <エンドポイント> -u <ユーザー名> -p <DB名> < dump.sql`
この方法では、MySQLクライアントにdump.sqlファイルの内容が直接渡されます。このとき、ファイル内のSQLコマンドが順次実行されますが、SQLコマンドの中に権限不足のものがあると、エラーが発生してしまいます。

2. `SOURCE /home/ec2-user/dump.sql;`
この方法では、MySQLクライアントにログイン後、SOURCEコマンドを使ってdump.sqlファイルを読み込んでいます。この場合、ファイル内のSQLコマンドはMySQLサーバー側で実行されるため、クライアント側の権限とは別に、MySQLユーザーアカウントの権限が適用されます。

つまり、1の方法ではMySQLクライアントプロセスの権限でSQLコマンドが実行されるのに対し、2の方法ではMySQLサーバープロセスの権限でSQLコマンドが実行されるためです。

エラーメッセージから、使用しているMySQLユーザーアカウントにSUPERまたはSYSTEM_VARIABLES_ADMIN権限がないということがわかります。__SOURCEコマンドを使った2の方法ではこの権限は必要ない__ ため、エラーが発生しませんでした。

一般的に、SQLスクリプトをインポートする際は、SOURCEコマンドを使う方が安全です。ただし、本番環境ではスーパーユーザー権限を持つユーザーを使用するのは避けるべきです。代わりに、必要最小限の権限を持つアプリケーション専用のユーザーを作成し、そのユーザーでデータベースにアクセスすることをお勧めします。

だそうです。
Pythonを使ってCaesar Cipher （シーザ暗号）を生成する

### この記事の目的は、Caesar Cipher（シーザー暗号）をどのようにPythonを使って書くかを説明したい。暗号理論上、もっともシンプルで、広く知られた暗号の一つである。決まった文字数分のアルファベットをシフトして暗号化を行う。

#### まず、alphabet全26文字をリストにする。
![Screenshot 2024-06-10 at 16.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/e2cee003-47d0-6c74-ae1b-db742c284adf.png)

#### 次に、関数を定義する。
![Screenshot 2024-06-10 at 16.28.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/a08af3f4-10b1-e6a3-cee3-fcaf9ac02140.png)

start_text: 暗号化または復号化したいテキスト。
shift_amount: シフトする量。
cipher_direction: "encode"（暗号化）または "decode"（復号化）を指定する文字列。

#### 初期化
![Screenshot 2024-06-10 at 16.30.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/25a8b8a6-aae5-998f-e39c-962877df609b.png)
結果の文字列を格納するための変数、"endtext"を空文字で初期化します。

#### シフト方向の調整
![Screenshot 2024-06-10 at 16.30.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/ced2b676-abc0-6c71-4d9b-c94d1b32093f.png)

cipher_direction が "decode" の場合、シフト量を負の値にします。これにより、文字が逆方向にシフトされて復号化されます。

#### 文字の処理
![Screenshot 2024-06-10 at 16.31.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/d1a1369d-7cbb-a635-8df1-c0f73a552082.png)

start_text 内の各文字 char を順に処理します。
文字が alphabet に含まれている場合、その文字の位置を取得し、シフト量を加算（または減算）した新しい位置の文字を end_text に追加します。
文字が alphabet に含まれていない場合、そのまま end_text に追加します。
alphabet は事前に定義されているアルファベットのリストである必要があります。

#### 結果の表示
![Screenshot 2024-06-10 at 16.32.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/9617ba28-e28f-1601-c9e4-68ace4748319.png)

暗号化または、複合化の結果を表示します。

#### ロゴの表示
![Screenshot 2024-06-10 at 16.33.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/a7b4fa20-536d-1368-960b-841a6a84d4da.png)

art モジュールから logo をインポートし、表示します。この部分はシーザー暗号の動作には直接関係ありませんが、プログラムの見た目を良くするために追加されています。

以下が、"alphabet"を含んだ完全なコード例です。
![Screenshot 2024-06-10 at 16.35.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/02b90153-4fbf-2b36-789a-baeacd5e49f3.png)

以上の画像のコードを使ったら、以下の画像が表示されます。

![Screenshot 2024-06-10 at 16.35.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/8364e19d-70d4-a8af-4871-557decd7c0f9.png)

今回は、japanを入力し、3文字ずつ"encode”して、文字列を移そう。この場合、mdsdqがresultとして表示された。つまり、encodeは、各文字列をユーザが指定した文字の数だけアルファベットを一定の法則に基づいて変換することになる。

![Screenshot 2024-06-10 at 16.38.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/fecc3426-9940-2025-307a-5a850d136397.png)

次に、hanshinと入力し、5文字ずつ"decode"して、文字列を移そう。この場合、cvincdiがresultとして表示された。つまり、decodeは、各文字列をユーザが指定した文字の数だけアルファベットを一定の法則に基づいて変換することになる。
![Screenshot 2024-06-10 at 16.41.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/510c3aab-f07e-d9a7-0937-9109f61ad849.png)

![Screenshot 2024-06-10 at 16.42.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518583/9d7b0d23-13af-9093-e7b7-f786b6af6366.png)
そして、今回はnoと選択したので、このプログラムは終了した。皆さんもこのプログラムコードを参考にしながら、シーザー暗号を生成したらいかがでしょうか。

以下の記事を参考にして、この記事を書くためのプログラムコードを作成しました。
https://medium.com/paul-zhao-projects/python-100-projects-in-100-days-learning-journal-979d9500c868
病み上がり

先々週の日曜日、39.6℃というガッツリな風邪をひいてしまいダウンしていました。
…まあ、ダウンしていたのはその1日だけで翌日には熱も症状も消え回復していたのですが…。
長引くようなら病院で検査してもらおうと思っていただけに、翌日は病院見送り。ただ もしコロナやインフルだった場合を考えて1週間の自主隔離をしていました。（今の隔離期間は5日と症状軽快から24時間でいいらしい。）
決して勉強が面倒だったとかそういうことでは…。
…
……
………
隔離中も症状が無いので勉強はできる状態なのですが、いかんせん家の中となると集中できず勉強が身につかないので避けています。
言い訳と言われればぐうの音も出ません。ぐう…。

---
前回までのエラーが解決しました。
[[解決済み]Target class [] does not exist.](https://qiita.com/suzukidog/items/a28e219f3be2a0d61b8d#%E8%A7%A3%E6%B1%BA20240610)

エラーを解消できた時ガッツポーズしたいくらい嬉しかったです。
周りの目が無ければやったこともないシャドーボクシングを披露していたかもしれません。

---
Qiitaの通知設定がよくわからない。
というのも、前回の記事にひとつコメントをいただいたのだが兄に言われるまで気が付かなかった。
メールにもサイト内にも通知されませんでした。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798584/cb0b3bdc-443b-2081-6be2-8bf96f0caf2b.png" alt="SCR-20240610-oqme.png" width=50%/>
> コメントをいただいたのは2024/05/31

メールの迷惑メール設定をしているわけでも、通知設定のオンオフでもなさそう。
ちなみに通知設定は「週間サマリー」「Organization週間サマリー」「ストック一覧」以外全てオンにしています。
謎だー！