OmniAICreator/Qiita-1.07M huggingface dataset:
【時短術】私がこれから使うショートカット①(Mac + VSCode)


## はじめに
現状、案件に対して多くの時間の消費が必要。
項目としては
コードを調べる時間
設計する時間
設計によって詰まってしまう時間
コード入力する時間
コードによるエラーで詰まってしまう時間

ここの入力に対しての時間を削るために私の知識が浅い部分である「エディタによるショートカット」を全く知らない。
この部分を補填して、作業時間の全体を向上させることが目的です。

## 🦁<INS>**結論**</INS>🦁
時間短縮に繋がりそうなショートカットはいくつもあった。
これをこれから使って、入力（修正、選択など）のスピードを上げて、クライアントの方に喜ばれるように技術を、身につける🦁

## <INS>**ショートカット一覧**</INS>

## <INS>**複数選択**</INS>
「cmd + d」

単語選択（「double click 」  or  「opt + click」）して 「cmd + d」
→からの特定の同じ単語をスキップ（大文字のものなどをスキップしたい）
***  

## <INS>**複数選択からのスキップ**</INS>
「cmd + D」→「cmd + K」ここがスキップ操作→「cmd + D」

複数選択して途中の特定の同じ単語をスキップ（大文字のものなどをスキップしたい）
単語選択（「double click 」  or  「opt + click」）して 「cmd + D」→「cmd + K」
***  

## <INS>**ファイル内の同じ単語を全選択**</INS>
「cmd + shift + L」

単語選択（「double click 」  or  「opt + click」）して「cmd + L」
***  

## <INS>**VS Codeのサイドバーの切替**</INS>
「cmd + B」

サイドバーの開閉に使える。
***  

## <INS>**ファイル検索**</INS>
「cmd + P」

ファイル名を入力することで検索できる。
探す時間を削減できる。
***  

## <INS>**ファイル内の単語検索**</INS>
「cmd + F」

「cmd + F」で特定したい単語を絞り込める。
***  

## <INS>**全ファイル（ディレクトリ内）単語検索**</INS>
「cmd + shift + F」

ファイル名を検索できる。
探す時間を削減できる。
***  

## <INS>**フォーマット整形**</INS>
「shift + opt + F」

選択してるファイルのズレてるインデントなどを修正してくれる。
***  

## <INS>**ターミナル開閉**</INS>
「cmd + J」

ターミナルの開閉ができる。
いちいちマウスで動かすより早い。
***  

## <INS>**別タブで開く**</INS>
「cmd + click」

基本は右側に追加されて2画面になる。
いちいちマウスで動かすより早い。

## まとめ✍️
まだまだ知らないことがいっぱいある。
できることをやって時間を短くして、より効率の良い技術を身につけていく。

***  
## 参考にした記事📕
[プログラミング始めるなら必須のショートカットキー72選](https://youtu.be/wf-8HkfMckM?si=TZ0yVhBGpt4mRd5G)
アヒル駆動のセキュリティ教育 SecDuck製作記録 ~プリント基板編~

## ハードウェア構成
アヒル本体は**3Dプリント**されたボディに**電子部品**が内蔵された構成になっています
また、それらの電子部品を**プリント基板**上にまとめています
※3/2の展示時にはプリント基板の発注が間に合わなかったため、ユニバーサル基板という汎用的な基板の上に実装してあります


## プリント基板の設計

### 使用した部品一覧
- [Raspberry Pi 3A+](https://www.raspberrypi.com/products/raspberry-pi-3-model-a-plus/)
- [スピーカー](https://akizukidenshi.com/catalog/g/gP-16600/)
    [DIP化キット](https://akizukidenshi.com/catalog/g/g105363/)を通してRaspberry Piとつなげます
- [USBマイク](https://www.amazon.co.jp/gp/product/B073QPLKRN)
    直接Raspberry Piとつなげます
- コントローラー
    Raspberry PiのGPIOピンから入出力を行います
    - [LEDスイッチ](https://akizukidenshi.com/catalog/g/gP-02009/)
    - [ボリューム](https://akizukidenshi.com/catalog/g/gP-14827/)
        音量調整に使います
    - [ADコンバータ](https://akizukidenshi.com/catalog/g/gI-09485/)
        ボリュームの絞り(アナログ値)をデジタル値に変換してからRaspberry Piに伝えます

### なぜプリント基板を使うのか
コントローラーはもともと↓の画像のようにユニバーサル基板に各パーツをはんだ付けすることで実装していました
![PXL_20240229_192826786.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699597/d9aafab0-fdfc-53c2-e953-6012048a435d.jpeg)

ですが「はんだ付けがめんどくさい」「上手にはんだ付けしないと正常に動作しない」といった問題に加えて「SecDuckをOSSにしたい」という気持ちもあり、プリント基板を設計、発注することにしました

注文した基板は2種類です
1. コントローラー基板
    LEDスイッチやボリュームが載っている基板です
1. ハブ基板
    コントローラー基板とRaspberry Piをつなぐほか、DIP化キットやADコンバータ、LEDの抵抗が載っています

### 自作パーツの作成
基板設計に用いたのはFritzingというソフトです。直感的なUIで初心者におすすめらしかったので選びました。
Fritzingではライブラリにもネットにもない部品は自分でデータを作る必要があります。今回LEDスイッチのデータ(Fritzing用のfzpzというファイルです)がなかったので、[YouTube](https://www.youtube.com/results?search_query=fritzing+custom+part++illustrator)の動画を参考にしてIllustratorで作成しました。

その中の一つの画像が↓で、LEDスイッチはLEDとスイッチがくっついた部品であるというようなことを表しています。

![Screenshot 2024-03-01 at 8.56.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699597/8dd5206f-b4a0-b019-5eba-09b4d61aceb7.png)

### 導線の配置
自作パーツを加えて各パーツを電気的につなげていきます

詳細は割愛しますが、画像のようにピンソケット越しに各パーツがつながっています

![Screenshot 2024-03-01 at 9.00.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699597/a8f4ff6e-5d2e-729b-fb5c-0bbc9a42931f.png)

### 部品の配置
次に実際に基板上のどこに部品を配置するかを決めます
コントローラー基板とハブ基板をそれぞれ下の図のように設計しました。
![Screenshot 2024-03-01 at 9.03.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699597/62d31d47-9c5a-8b8e-dbf8-50f7aff8d5fa.png)
![Screenshot 2024-03-01 at 9.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699597/735712bd-d61e-a39b-0e26-e13280814546.png)

黄色とオレンジの二色の線がありますが、この色は基板の表と裏を表しています。今回注文したのは両面基板なので、色の違う線は交差しても大丈夫ということになります。

同じ色が交差しないように配線を考えるのはパズルみたいで結構楽しい作業でした。

### 基板の発注
FusionPCBというところで製造を発注しました。
5枚ずつ計10枚と送料で3,500円くらいでしたが、半分以上は送料なのでたくさん発注すれば150円/枚くらいで作れそうです。

### 関連リンク

https://qiita.com/acta/items/7c38c278013df7bc8ba5

https://qiita.com/acta/items/94fd92a73d39bac7adfd
PlaywrightでのE2Eテストのテストケース管理方法

### はじめに

エンドツーエンド(E2E)テストは、アプリケーションのユーザーインターフェイスからデータベースとのやり取りまで、すべての層を通じて機能が正しく動作することを保証するために重要です。

このドキュメントでは、主に自分たちが行っているPlaywrightを使用したE2Eテストのケース管理方法について説明します。特に、テストケースを整理し、追跡するためのスプレッドシートの使用方法に焦点を当てます。

### テストケース管理のスプレッドシート構造

スプレッドシートは、テストケースを効率的に管理し、テストの計画及び実装の進行状況を追跡するのに役立ちます。ユースケースごとに個別のシートを作成し、以下のカラムを用意します。

#### カラム構造

- **グループ**: テストケースをグルーピングするためのカテゴリ。自動テストの実装時には、これがテストファイルの単位となります。
- **仕様**: テスト対象の仕様を記述します。これは「What」の部分に相当し、例えば「管理者は削除できる」や「ユーザーは削除できない」といった仕様が該当します。
- **方法**: 仕様をどのようにして確認するか、つまり「How」の部分を記述します。テストの手順や確認ポイントを具体的に書き出します。
- **実装予定**: テストコードを実装するか否かの判断を記録します。「あり」または「なし」で記入し、優先度の高いテストから順に着手できるようにします。
- **実装完了**: テストコードの実装が完了しているかどうかを「未」または「済み」で記録します。これにより、進捗管理が容易になります。

### テストケースの考え方

テストケースを考える際の順序は、まず「仕様」から始めます。具体的な機能や振る舞いについて明確にし、次にそれをどのようにグループ化するか（「グループ」）、そしてその仕様をどのように検証するか（「方法」）を考えます。このプロセスにより、テスト計画の明確化と効率的なテストケースの作成が可能になります。

### まとめ

Playwrightを使用したE2Eテストのケース管理にスプレッドシートを活用することで、テスト計画の透明性が向上し、テスト実装の優先順位付けが容易になります。テストケースのステータスを一目で把握できるように管理し、プロジェクトチーム全体でテスト進行状況を共有することが重要です。このドキュメントが、より効果的なテストケース管理に向けた参考となることを願います。
AI搭載のVsCode – Cursor エディタの Copilot + (プラス) とは何なのか

# Cursor エディタとは

ほとんどVsCodeだがAIが使いやすくなったエディタ
https://cursor.sh/

# 有効化

チャットウィンドウのMOREタブに設定があり、有効化出来る

2024/03/01 現在 BETA版で有料課金が必要

<img width="746" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/f5bef05d-5935-4cc3-8165-2647615e195d">

<img width="665" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/4e0733ee-ea3d-4b46-8163-05046789a8da">

# 動作

 
## 複数行の編集

### BEFORE

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/5530916a-bad0-4abd-bce6-2276e8632865)

### AFTER

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/c31f08c9-9266-4689-bcd1-aea5c77a426f)

## 複数行の編集 ( 要素の削除 )

### BEFORE

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/5c8231db-4744-4eae-8e38-4a8737e49271)

### AFTER

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/1c7225a6-68b2-4f11-9568-bf75a8fe9b91)



## 行の削除

削除すべき行を削除してくれる場合がある

### BEFORE

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/79a69c0a-dd02-4d41-ad69-1c8a03af7eee)

### AFTER

![image](https://github.com/YumaInaura/YumaInaura/assets/13635059/9e4b2014-f8d6-4249-8a80-0ca91937b30f)

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
Ajax/APIのわかりやすい図

完全honaki用

## Ajax/APIのわかりやすい図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/b08cd2a9-c68c-4c6c-8f69-e208f07d3850.png)

参考：https://qiita.com/minato-naka/items/9362ea5af5f823c95b0b
MailHogを使ってユーザーに招待メールを送信する

MailHogの動作確認をしたので、そのメモを残します。

まず、ターミナルを立ち上げ、「mailhog」を実行。


そして、アプリのメール送信画面に移動する。
![スクリーンショット 2023-05-02 10.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876907/1a402616-3a22-68b0-084b-6963b60e6d56.png)


相手のメールアドレスを入力。
例として、user@gmail.comと入力。
![スクリーンショット 2023-05-02 10.08.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876907/5249bb15-3413-4c25-dc92-c9a1288782b9.png)

「送信する」ボタンを押下したら、メールが完了したメッセージを表示させる。
![スクリーンショット 2023-05-02 10.09.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876907/5445ee38-7275-4adc-759a-ea2c6677f099.png)

localhost:8025にアクセスすることで、MailHogの画面を確認できる。
以下の写真から、user@gmail.com宛にメールが送信できていることが確認できた。
![スクリーンショット 2023-05-02 10.10.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876907/12aeebdf-c609-b320-205b-7e200d57a026.png)


ここで、リストをクリックすると詳細画面が確認できる。
メール内容が正しいことを確認できた。
ちなみに、このRULを踏むとグループに参加できるようにする予定です。
![スクリーンショット 2023-05-02 10.17.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2876907/2f0d36be-1a4c-157f-4d5d-d8c70c0b2992.png)
Doctype宣言の呼び出しショートカットキー

# Doctype宣言の呼び出しショートカットキー
Doctype宣言とは↓これのことです。
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
```
結論から言うと、**「!」を押してTabキーを押す。**
これだけです。簡単ですね。
NetBSDで74HC595を制御してみた

BCM5301XのGPIOドライバーは作りかけだったのでピン操作が出来るように書き足しました。

GPIOに接続された74HC595を制御してみます。

```:gpio.conf
# 74HC595
gpio0 4 set out
gpio0 6 set out
gpio0 7 set out
gpio0 8 set out
```

rc.confにgpio=YESを追加します。

```sh:led.sh
#!/bin/sh

#LED=01000000
LED=$1

SER=4
RCLK=6
SRCLK=7
SRCLR=8

reset() {
gpioctl -q gpio0 ${SRCLR} 0
gpioctl -q gpio0 ${SRCLR} 1
}

clock() {
gpioctl -q gpio0 ${SRCLK} 0
gpioctl -q gpio0 ${SRCLK} 1
}

reset

gpioctl -q gpio0 ${RCLK} 0

for COUNT in 1 2 3 4 5 6 7 8
do
VAL=`echo ${LED} | awk '{print substr($0,'${COUNT}',1)}'`
if [ "${VAL}" = "1" ] ; then
gpioctl -q gpio0 ${SER} 1
else
gpioctl -q gpio0 ${SER} 0
fi
clock
done

gpioctl -q gpio0 ${RCLK} 1
gpioctl -q gpio0 ${RCLK} 0
```

実行してみます。

```
# ./led.sh 00000100
```

猛牛さんのインジケーターが赤から白になりました。おそらく赤はOSが起動してないなどの致命的な状態を表しているのだと思いますが、猛牛さんのコーポレートカラーが赤なので、あまり緊迫感がありません。

BCM5301Xのドライバーは特殊な構成になっています。これはSOCのアーキテクチャからきているのかもしれません。ChipCommonA(cca)というデバイスにcomやgpioがぶら下がるようになっています。今の構成はccaにgpioが入っている形でconfig_found()でgpiobusを付けにいくとcomもprobeされてしまうので、ワークアラウンドを入れてあります。
JSONとHTML表示の両立

## 概要
Ajaxを用いた非同期通信でコメントを表示する機能の開発時、JSONレスポンスとHTML表示の両立に苦労したので記録として。
「json　画面　黒　配列　htlm　表示されない」などのワードで検索してもバシッと同じ状況の解決策が出てこず、何日もハマったのでどなたかの参考になれば。

## 結論
リクエストに対するレスポンスでJSOMとHTMLの両方をformatで明示する。

```
    def index
      @default_avatar_url = view_context.asset_path('default-avatar.png')
      @comment = @article.comments.new
      @comments = @article.comments.order(created_at: :desc)
      respond_to do |format|
        format.html # HTMLページとしてコメント一覧を表示
        format.json do # JSONレスポンスとしてコメントデータを返す
          comments_json = @comments.as_json(include: {
            user: {
              only: [:username, :display_name, :id], # 必要なユーザー情報を指定
              methods: :profile_image_url # プロフィール画像のURLを返すメソッド
            }
          })
    
          comments_json.each do |comment|
            comment["is_current_user"] = (comment["user"]["id"] == current_user.id)
          end
    
          render json: comments_json
        end
      end
    end
```

上記のコードはHTMLフォーマットのリクエストがあった場合、通常のHTMLページとしてコメント一覧を表示する。
JSONフォーマットのリクエストがあった場合、コメントデータをJSON形式で返す。
このような形式にすればHTMLの表示とJSONレスポンスによる動的なHTMLの生成を両立できる。

## 経緯
JSONレスポンスを取得して動的にHTMLを生成するページを作成しようとしたところ、真っ黒な画面に配列だけが表示されてしまう減少に直面。
特にエラーが発生しているわけでなく、失敗の原因が掴めないまま何日も解決できなかった

原因は「Railsはアクション名に対応するビューファイルに自動でレンダリングする＝どんなときでもHTML表示される」と思っていたこと。
当初はJSONレスポンスの記述さえ行っていればHTMLページが生成され、遷移すると思い込んでいた。

しかし、調べたところJSONレスポンスがある場合はHTMLの生成より優先されてしまい、JSONレスポンス内の配列データだけが渡ってしまうということだった。画面に配列だけが表示された原因はこれ。

そこで、上記のformatを記述してHTMLの生成とJSONレスポンスを両立するコードを明示。
HTML表示と動的なHTML生成を両立できた。
Too many query rows: 50001

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)


+ [HEAP_ALLOCATE](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Yw2Ee)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/16f99265-4b43-38ba-b2f0-36e0b1de888f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/21192d7d-64c8-d66f-2398-51147435766c.png)


:::note
Please check this article.

https://salesforce.stackexchange.com/questions/105609/system-limitexception-too-many-query-rows-50001-even-though-soql-has-limit-10
:::

# npsp:Too many query rows: 50001

Error is in expression '{!onNpspSettingsLoad}' in component <apex:page> in page npsp:stg_settingsmanager: (System Code)

Class.npsp.UTIL_MasterSchedulableHelper.setScheduledJobs: line 157, column 1

Class.npsp.STG_SettingsManager_CTRL.onNpspSettingsLoad: line 90, column 1

+ [NPSP Settings Not Loading](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000078SO1o)


# 「System.LimitException: dlrs:Too many query rows: 50001」というエラーが表示されるのはなぜですか

DLRS は通常、親の観点からクエリを実行し、指定された基準に一致するすべての子レコードを取得します。特定のバッチ内の親に平均 250 (50,000 / 200) の子があり、多くの DLRS ジョブが構成されている場合、または多数のカスケード ロールアップ (孫から親、祖父母へのロールアップ) がある場合、DLRS は合計で 50,000 を超える数を簡単に要求できます。指定されたトランザクションのレコード。

これがスケジュールされた計算または完全な計算バッチ ジョブ中に発生する場合は、宣言ルックアップ ロールアップ集計階層のカスタム設定でバッチ サイズを調整できます。デフォルトは 200 です。

# 未解決

+ [CRLP_RollupQueueable npsp:Too many query rows: 50001 on Opportunity rollup](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000GhJQq)
libboost_filesystem-vc143-mt-sgd-x64-1_84.lib を開くことができません。

libboost_filesystem-vc143-mt-sgd-x64-1_84.lib を開くことができません。
というコンパイルエラーが出て詰まったのですがなぜか解決したので備忘メモ。

boostをDL(https://www.boost.org/)して任意のディレクトリに解凍。

cd C:\Program Files\boost\boost_1_84_0\
./bootstrap.bat
./b2.exe variant=debug runtime-debugging=on runtime-link=static threading=multi

でboost_1_84_0\stage\libにlibboost_filesystem-vc143-mt-sgd-x64-1_84.libが生成された。

※./b2.exe をオプション無しで実行すると
　libboost_filesystem-vc143-mt-gd-x64-1_84.lib
　が生成されるだけだった。sはstaticのsか？

その後、リンカを追加してコンパイルすれば解決した。VSの場合、
構成プロパティ > リンカ― > 全般 > 追加のライブラリ ディレクトリ > "C:\Program Files\boost\boost_1_84_0\stage\lib" を追加する。
[mac] TimeMachine使用後に1password が起動しない件 [解決方法]

# 何が起こったのか
macOS でタイムマシンを使用後に、1password を起動しようとしたら、以下のように「1passwordはローカルアプリのデータベースでエラーを検出しました。support@1password.comまでご連絡ください。」とポップアップウィンドウが出て、1password が使えなくなった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/625951e6-4969-6653-046a-38797700aed0.png)

# どう解決したのか
素直にサポートへ英語でHELPしました。サポートから返信いただいた内容を元にどのように解決したのかを記します。

## 1. 非同期な1password データが存在するか確認する

ターミナルでコマンドを実行、出力されるテキストの中身を確認する
```
cd ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/Library/Application\ Support/1Password/Data &&
sqlite3 1password.sqlite "select uuid from item_overviews where local_edit_count > 0;" > ~/Desktop/unsynced_item_uuids.txt
```

もし、テキストファイルの中身が空でなければ、非同期な1password データが存在するということなので、サポートに連絡してください。（私は空だったので、以下の手順に進みました）

## 2. 不具合を起こしているローカルDBのバックアップを取り、削除する
```
cd ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/Library/Application\ Support/1Password/

# 7zip で圧縮ファイルとしてバックアップを取りました。7zipを導入してなければbrewで入れてください。
brew install p7zip
7z a Data_backup.7z Data

# ローカルDBを削除
rm -r Data
```

## 3. 1password を起動し直して、ログイン。お疲れ様でした。

# おわりに
今回の不具合はサポートに連絡する前に英語も含めてググったのですが、該当するものが見つからない状態でした。
仕方なくサポートに連絡したのですが、担当者の方が的確に解決方法を教えてくれたため、1往復のやりとりのみで終わりました。
とは言え、時差もあり、即時解決とはいかなかったので、後に同じ問題に直面する人へ向け、本記事を書きました。
誰かの助けになりますように。

（おわり）
MEN'S LEATHER JACKETS

Elevate Your Style with Men's Leather Jackets
![download (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3730538/5d6db04b-d32e-c123-01b8-63963bca5e3b.jpeg)

In the world of <a href="https://tobleo.com/product-category/mens-leather-jackets/"> men's fashion, leather jackets </a> stand as icons of style, rebellion, and rugged elegance. Whether you're aiming for a casual look or dressing up for a night out, a leather jacket is a versatile piece that has the power to transform any outfit. Here's why every man should consider adding a leather jacket to his wardrobe.

Timeless Fashion Statement

Leather jackets are more than just a piece of clothing; they're an investment in timeless style. From the classic biker jacket to the sleek cafe racer, there's a style for every personality. Each carries its own story, a nod to the past with a modern twist.

Durability and Comfort

Crafted from the finest materials, <a href="https://tobleo.com/product-category/mens-leather-jackets/"> men's leather jackets </a>are built to last. With proper care, they can withstand the test of time, often getting better with age. The natural material offers unparalleled comfort and warmth, making it perfect for any season.

Versatility

The beauty of a leather jacket lies in its versatility. Pair a bomber jacket with jeans and sneakers for a casual outing, or elevate your evening look with a slim-fit biker jacket over a crisp shirt. The options are endless, allowing you to express your personal style in various ways.

Wide Range of Options

Biker Jackets: Embrace your inner rebel with the classic asymmetrical zippers and bold lapels.

Bomber Jackets: Perfect for a relaxed, sporty look that works with virtually everything in your closet.

Cafe Racer Jackets: For those who prefer a cleaner, more streamlined look, the cafe racer is your go-to.

Field Jackets: A practical yet stylish option, offering more room for layering during colder months.

Care and Maintenance

Leather jackets require some care to maintain their appearance and longevity. Regular cleaning, conditioning, and proper storage will keep your jacket looking its best for years to come.

Conclusion

A men's leather jacket is more than an article of clothing—it's a statement. Whether you're going for an edgy, sophisticated, or casual look, there's a leather jacket out there for you. Explore the options, find your fit, and embrace the timeless appeal of leather.
スケーラビリティと結合度の関係

# まえがき

今回はスケーラビリティと結合度の関係性について考える。
一般的にこれらの間には、逆相関関係　トレードオフ関係がある傾向にある。
その理由を図解を通して考えていく。


# 密結合な場合
簡単のために２つのコンポーネントが密にべったりと結合した場合を考えよう。

<img width="500" alt="スクリーンショット (429).png (41.8 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/03/01/135213/aa014cb0-6cd1-4431-83a1-ba9dd33f38bc.png">

この場合、赤い領域の方だけをスケールアップするには、ブルーの方も自ずとスケールアップしないといけないことは容易に想像がつく。

同様に、スケールダウンする際にも同じである。
べったりとくっついた状態では、どちらかだけを拡大したり縮小したりは難しい。


# 疎結合な場合
では、結合が疎な場合にはどうであろうか？
結合が疎とは、下図のようにくっついていない状態のことを指す。

<img width="500" alt="スクリーンショット (439).png (71.6 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/03/01/135213/9aac31bc-91bf-4430-bd57-1e0ca0da7c8d.png">

この状態で、ブルーの方をスケールアップしようとしたら、赤い方は影響受けるだろうか？
もちろんくっついていないのだから、影響を受けずにいられる。

スケールダウンの場合にも同様である。
赤い方のみをスケールダウンさせたいって時には、密な結合の場合には
ブルーの方も一緒にスケールダウンさせなくてはならないが、
疎結合な場合にはブルーの方は影響を受けずに赤い方のみスケールダウンが可能である。

<img width="500" alt="スクリーンショット (440).png (63.9 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2024/03/01/135213/c21d7f4e-de3f-4926-b544-1ed28231b460.png">

以上のことから、一部の設計パターンを除いて
スケーラビリティと結合度はトレードオフ関係にあるといえる。

これは是非とも常識にしておきたい品質特性同士の関係性である。
ウェブアプリ開発のためのコーディングとシステム開発費用の相場

ウェブアプリ開発は、現代のビジネスにおいて不可欠な要素となっています。ビジネスの拡大やサービスの向上を実現するためには、効果的なコーディングとシステム開発が必要です。この記事では、「[コーディング と は](https://newwave-solutions.co.jp/web-coding/)」、そして「[web アプリ 開発](https://newwave-solutions.co.jp/web-app-development-guide/)」と「[システム 開発 費用 相場](https://newwave-solutions.co.jp/cost-of-engineer-per-month/)」に焦点を当てて、ウェブアプリ開発の重要性と費用の見積もりについて詳しく探ります。
![web-coding-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031688/be175ba2-4db1-6414-7675-fb5f6ba9b84d.jpeg)


1. コーディング と は

コーディングとは、プログラムやスクリプトを書くプロセスを指します。これは、ウェブアプリケーションやシステムの機能を実現するための鍵となるステップです。優れたコーディングは、アプリケーションの動作をスムーズかつ安定に保ち、将来の拡張性や保守性を確保します。プロのコーディングは、効率的で再利用可能なコードを作成し、開発プロセス全体を向上させることが期待されます。

2. web アプリ 開発

ウェブアプリ 開発は、オンラインプレゼンスを構築し、顧客とのインタラクションを向上させるための手段です。使いやすいユーザーインターフェース、セキュリティの確保、高いパフォーマンスなど、様々な要素が成功の鍵です。効果的な開発は、ビジネスの競争力を高め、新しい市場への進出を可能にします。

3. システム 開発 費用 相場

システム開発の費用は、プロジェクトの複雑さ、機能の要件、開発時間などによって異なります。一般的な相場を知ることは、プロジェクトの予算立てに重要です。システム開発には、コーディング、テスト、デプロイメント、メンテナンスなどのプロセスが含まれます。プロの開発者を雇用する場合は、そのスキルや経験も費用に影響を与えます。

ウェブアプリ開発とシステム開発の成功には、適切なコーディングと費用の適切な見積もりが欠かせません。これらの要素を理解し、プロジェクトに最適なアプローチを見つけることが、ビジネスの成果を最大化する鍵となります。




[Newwave Solutions Japan](https://newwave-solutions.co.jp/)は、多岐にわたるサービスを提供しており、技術分野で顧客の多様なニーズに応えています。経験豊富な専門家チームを擁し、効果的で柔軟なソリューションを提供することを自負しています。当社のサービスには、ウェブおよびモバイルアプリの開発、システムインフラのコンサルティング、ITプロジェクトの管理などが含まれます。

私たちは、深い業界理解と顧客の具体的な要件に基づいたカスタマイズされたソリューションを提供することで、お客様の満足をお約束します。同時に、サービスの品質向上と、テクノロジーの最先端を活用して、お客様が技術の急速な変化に常に適応できるよう努めています。
Excelで処理フローを書くだって？

### Excelで処理フローを書いている現場って結構あるよね
#### なんとかして楽をしたい...

めちゃくちゃ簡単なフローなら、これで自動的に作成できるはず。
```
Sub CreateDynamicFlowchart()
    Dim ws As Worksheet
    Set ws = ActiveSheet

    ' ステップと図形の種類を格納するコレクション
    Dim stepsAndShapes As Collection
    Set stepsAndShapes = New Collection

    ' ステップと図形の種類を1行で追加
    stepsAndShapes.Add Array("データを読み込む", msoShapeRectangle)
    stepsAndShapes.Add Array("データをチェック", msoShapeDiamond)
    stepsAndShapes.Add Array("DBに登録", msoShapeRectangle)

    Dim i As Integer
    Dim item As Variant
    Dim shape As Shape
    Dim lastShape As Shape
    Dim topPosition As Single
    Dim leftPosition As Single

    ' 図形の初期位置
    topPosition = 50
    leftPosition = 100

    For Each item In stepsAndShapes
        ' 指定された種類の図形を作成
        Set shape = ws.Shapes.AddShape(item(1), leftPosition, topPosition, 150, 50)
        shape.TextFrame2.TextRange.Text = item(0)
        shape.Line.Weight = 2
        
        ' 矢印付き直線で前のシェイプと現在のシェイプをつなぐ
        If Not lastShape Is Nothing Then
            Dim connector As Shape
            Set connector = ws.Shapes.AddConnector(msoConnectorStraight, 0, 0, 100, 100)
            With connector
                .Line.EndArrowheadStyle = msoArrowheadTriangle
                .Line.ForeColor.RGB = RGB(0, 0, 0)
                .Line.Weight = 2
                .ConnectorFormat.BeginConnect lastShape, 1
                .ConnectorFormat.EndConnect shape, 1
                .RerouteConnections
            End With
        End If
        
        ' 次のシェイプの位置を更新
        topPosition = topPosition + 100
        Set lastShape = shape
    Next item
End Sub


```

#### ほか 
分岐処理も簡単に書きたい....
SwiftのUIButtonのSF Symbol(SystemImage)のサイズを変更する方法

### こいつのサイズを簡単に変更したい
![スクリーンショット 2024-03-01 1.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/4f0bb92d-5924-a731-1d8d-33975b095b2f.png)

### 結論
![i0GRx.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/0e3a7588-8f4b-a3be-5c57-2fe24b2fc7b3.gif)


引用:https://stackoverflow.com/questions/60641048/change-a-sf-symbol-size-inside-a-uibutton


### 感想
調べ方が悪いのか、みんなコード上から変更する方法しか書いていなかった..。
何を今更な SATA m.2 adapter card を買ってみた

過日 m.2 まわりを調べてたときにウチにある m.2 の素性も調べてそれが sata の m.2 だことが分かりました。 

のはいいんですけど最初期の仕様なのでソイツを storage にしてくれる adapter card なんて国内じゃなくてももう出回ってない訳で、…　ひとつだけ見つけたは見つけたけど買うのは賭けだよね aliex じゃ。 ww

ええーい、ポチッ。

　　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3729329/404fe05e-6efb-c94c-1742-99fdcdb9a43b.jpeg" width=75%>


最近は早くなったね aliex、1 週間で届いたよ。 一応 boot できるとは謳ってある（上部 switch 切り替えがある）んだけど、さて ？ 

本当は pci 版が欲しかったんだけどまあ無理だよねそもそもな感。 手近なところで開発用端末に挿してみました。

<br />
わーお、boot 項目に出てきた、これで今や骨董な m.2 が無駄にならなくて済みそう。 もう 1 枚買っておこうかな。 いやでも sata m.2 はこれ 1 枚しか持ってないからたぶん無駄になる気が …

今日は このくらいで。
Dialog と Popover API

2024年2月時点でPopover APIがFirefox以外のブラウザに対応しHTMLのみでポップオーバーコンテンツが表示されるようになりました。

## ポップオーバーコンテンツとは

> ポップオーバー要素は、呼び出し／制御要素（すなわち <button> または <input type="button"> に popovertarget 属性が付いたもの）、または HTMLElement.showPopover() の呼び出しによって開かれるまで、display: none で非表示になっています。
開かれると、ポップオーバー要素は、最上位レイヤー内の他のすべての要素の上に現れ、親要素の position や overflow のスタイル付けの影響を受けません。

[Mdn popover](https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/popover)

つまりCSSの`z-index`を指定せずともコンテンツの上位に表示されるという仕様のようです。
簡単なデモを作成してみました、JavaScriptを書かずとも**モーダルのようなもの**が表示されます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ExJxNvV" data-user="makoto-ogata" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/makoto-ogata/pen/ExJxNvV">
  Untitled</a> by Makoto Ogata (<a href="https://codepen.io/makoto-ogata">@makoto-ogata</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

簡単にできるといってもPopover APIを使ってdivタグをモーダルの様に見せるのはあまりよろしくなく、その場合はdialogタグを使うほうが良いとされています。

## モーダルと非モーダル
Mdnによりますと、こう書かれています。

- モーダルというのは、ポップオーバーが示されている間、ページの残りの部分は、ポップオーバーが何らかのアクションを起こすまで（例えば、重要な選択がなされるまで）、反応しないようにレンダリングされるということです。
- 非モーダルというのは、ポップオーバーが表示されている間も、ページの残りの部分が反応するようにするということです。


Popover APIは非モーダルで、dialogタグはモーダルです。
> モーダルダイアログはユーザーを遮って何かしらの行動を要求するものである。これはユーザーの注意を重要な情報に向けてもらうことが必要な場合には適している。

記事最後の参考にした記事「**モーダルと非モーダルダイアログ：用いるべき場合とそうでない場合**」のサブタイトルにもなっています。
つまり非モーダルである以上、モーダルウィンドウとして実装するのはあまりおすすめはしないという事です。
- ただDialogとPopover APIを併用はできる
- もちろん内容にもよる

では用途としてはどんな事に使えるのか？
トースト通知であったりコンテンツピッカーなどで使うと良いとされています。
CodePenなどで「Popover API」と検索するとサイドメニューの開閉などに使われていて、アイデアによっては様々な箇所で使われそうですね。



## 参考
https://developer.mozilla.org/ja/docs/Web/API/Popover_API

https://azukiazusa.dev/blog/popover-api/

https://zenn.dev/yusukehirao/articles/popover-api-and-attributes

https://u-site.jp/alertbox/modal-nonmodal-dialog

https://developer.chrome.com/blog/introducing-popover-api?hl=ja
【phpMyadmin】Failed to set session cookie. Maybe you are using HTTP instead of HTTPS to access phpMyAdmin.

## 経緯

Laravelで開発をする準備をしていました。
docker-compose.ymlファイルを編集し、DockerのphpMyAdminにログインしようとしたら、エラーでログインできませんでした。

## エラー内容

![スクリーンショット 2024-02-28 21.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459296/91ac19a9-203b-c35f-ebeb-0bf86269cde6.png)

:::note alert
Google翻訳
セッションCookieの設定に失敗しました。 phpMyAdmin へのアクセスに HTTPS ではなく HTTP を使用している可能性があります。
:::


## 対応

色々と調べて試したことをまとめていきます

- Googleの拡張機能を確認
まだエラー出でいる...

- Laravel Sailを起動する際に --ssl オプションを使用してHTTPSを有効にしてみる
まだエラー出でいる...

- Dockerを最新版にする
ログインできた！！



## さいごに
いかがだったでしょうか。

少しでも同じようなエラーが出た人の助けになれば幸いです。

他にもいろいろな記事を書いているのでぜひ読んでいただけたら嬉しいです。
ゲーム制作のススメ(1) ～ゲームエンジン編～

# はじめに
この記事では，『ゲームを作ってみたいけど，どんな方法で作ればいいのか分からない...』という人を対象に，ゲーム制作で役に立つゲームエンジンを紹介したいと思います！

# そもそもゲームエンジンとは？
[ゲームエンジン](https://ja.wikipedia.org/wiki/%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3)とはゲーム制作に役立つソフトウェアのうち，グラフィック，入力，音響，ネットワーク等の便利機能を網羅的に扱うことができるソフトウェアのことである．

つまり，キャラクターの絵が出せたり，敵を倒したときの音が鳴らせたり，キーボードで操作できるゲームを作れる[スゲーナスゴイデス](https://dic.pixiv.net/a/%E3%82%B9%E3%82%B2%E3%83%BC%E3%83%8A%E3%82%B9%E3%82%B4%E3%82%A4%E3%83%87%E3%82%B9%E3%81%AE%E3%83%88%E3%83%A9%E3%83%B3%E3%83%97)って感じのソフトウェアということ．

ゲームを作ってみたいという人はゲームエンジンを使ってみるのがおすすめ！

# どんなゲームエンジンがあるの？
広く知られているかつ使用しやすいゲームエンジンとして，Unity，Unreal Engine，Godot，などがあります．

これらのゲームエンジンの得意なことや動作するPCスペックはそれぞれ異なるので一つずつ簡単に解説します．

また，紹介するゲームエンジン以外にも色々あります．
- [ティラノビルダー](https://b.tyrano.jp/): ノベルゲームを制作するのに向いている
- [GameMaker Studio 2](https://gamemaker.io/ja-JP): 2Dゲームに特化している
- [Defold](https://defold.com/)
- [Open 3D Engine](https://o3de.org/)
- [Construct 3](https://www.construct.net/en)
- [Clickteam Fusion 2.5](https://www.clickteam.jp/product/clickteam-fusion-2-5)
- [PlayCanvas](https://playcanvas.jp/features/)

これらのゲームエンジンは特定の機能に特化した物やマイナーあるいはデータ収集に苦労するであろうという理由のため本筋から省きました．
目的によっては下記のゲームエンジンより優れていることがありますのでチェックしてみてください．

以下メインテーマです．

- ## [Unity](https://unity.com/ja)

| 初心者おすすめ度 | 使用料金 | 使用するプログラミング言語 |
|:-:|:-:|:-:|
| ★★★★★  | 無料(条件あり)  | C#  |

- [過去12か月の収益が10万米ドル以下であれば無料で使える](https://unity.com/ja/pricing#plans-student-and-hobbyist)(2024年2月現在)

とても有名！2Dゲームも，3Dゲームも，どちらも作れる．
ゲーム制作に必要となる各種素材(絵，3Dモデル，音)は[Unity Asset Store](https://assetstore.unity.com/ja?locale=ja-JP)で手に入れることができ，無料の素材も豊富である．

作成するゲームの規模によるが，そこまで動作不可が大きいわけではない．
公式チュートリアルやいろんなサイトで使用方法が調べられるので，初心者でも形のあるものが作成しやすい．

また，有名なゲームエンジンなので日本人の使用者が多く，日本語でトラブルの解決がしやすい．

- ## [Unreal Engine 5](https://www.unrealengine.com/ja/)

| 初心者おすすめ度 | 使用料金 | 使用言語 |
|:-:|:-:|:-:|
| ★★★★☆  | 無料(条件あり)  | C++  |

- [Unreal Engineを用いた作品のライフタイム総収入が100万米ドルを超える場合は5%のロイヤリティを支払う必要がある](https://www.unrealengine.com/ja/license)(2024年2月現在)

こちらも有名なゲームエンジンである．2Dと3Dどちらも表現できるが，3Dに長けたゲームエンジンであり，美麗なグラフィックを得意とする．
 [Unreal Engineマーケットプレイス](https://www.unrealengine.com/marketplace/ja/store)を活用すればゲーム制作のための素材を手に入れることが可能である．

動作負荷が大きく，グラフィックボードを搭載した[ちょびりんき](https://www.nintendo.co.jp/n02/dmg/b86j/hamugo04/index.html)なPCでなければ動作は難しい．
このゲームエンジンも日本で多くの人が使用しているため，日本語でトラブル解決がしやすい．

- ## [Godot Engine](https://godotengine.org/)
| 初心者おすすめ度 | 使用料金 | 使用言語 |
|:-:|:-:|:-:|
| ★★★★☆  | 無料  | GDScript または C#, C++  |

日本での知名度はいまひとつだが，海外での使用例が多いゲームエンジンである．
使用料金は一切かからず，2Dと3Dのどちらも扱うことができる．
[公式のドキュメント](https://docs.godotengine.org/en/stable/)は内容が充実しており初学者でも利用しやすくなっている．

また，Godot Engineは動作が軽く，グラフィック機能の強いPCが必須とならない点がほかのゲームエンジンと比べて優れている．
Godot Engine独自のプログラミング言語であるGDScriptを採用しており，Pythonをベースとした言語で初心者でも多言語の経験者でも取っかかりやすい．
他にもC#やC++でのコーディングがサポートされている．

余談ですが，筆者はこのゲームエンジンを使って次のゲームを作ろうと考えています．
理由はGodot Engineに詳しくなりたいからです．
未知のソフトウェアは使ってみたくなりますよね．

# まとめ
近年のゲーム制作は汎用かつ無料という素晴らしきゲームエンジンが登場したおかげでハードルが下がり続けています．
このビッグウェーブに乗らない手はない！
みんなでたくさんゲームを制作しましょう．

次はライブラリについて書けたらいいな，まだ経験値が足りないので1年後とかに書けたらいいな～．
アルゴリズム事始め②

アルゴリズムを学習し始めたものの、まだまだなんとなくで進んでいる人のチラシの裏です。

[読んでる本]
アルゴリズムとデータ構造

1はここ↓
https://qiita.com/biscorio/items/918060343eeab6c4570f

## 動的計画法
課題を部分にわけて、それぞれを選んだ時、選ばなかった時について考えていく方法。

#### ナップサック問題
かばんの中身にモノを入れよう、ただし貴重品をたくさん入れつつX㎏は超えるな、みたいなやつ。
荷物1 10kg(価値10),荷物2 5kg(価値20),荷物3 13kg(価値5),荷物4 6kg(価値9)とあった時、価値が最大になるようにしつつ、20㎏以内に収めるにはどう組み合わせると良いか、みたいなこと。

#### 考え方
選んだ時、選ばない時を考える。
荷物1を選んだ時、価値10 / 重さ10kgになる。
荷物2を選んだ時、荷物1を選んでいたら価値30 / 重さ15kgになる。
これを、表に埋めていく。
ここでは重さを横軸、選択する荷物を縦にして、それぞれ選んだ場合に価値がどうなるかを見ている。(選ばなかったら0なので気にしなくてOK)
|i/w | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ... | 20 |
|:-----------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
| -(0)  | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A(1)  | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |10| 10 | 10 | 10 | 10 | 0 |
| B(2) | 0 | 0 | 0 | 0 | 0 | 20 |20 |20 |20 |20 |30 |30 |30 |30 |30 |30 |
| C(3)  | 0 | 0 | 0 | 0 | 0 | 20 |20 |20 |20 |20 |30 |30 |43 |43 |43 |43 |
| D(4)  | 0 | 0 | 0 | 0 | 0 | 20 |26 |26 |26 |26 |36 |36 |49 |49 |49 |49 |

## 貪欲法
とりあえず、後先考えずにその場の最善を取り続ける方法。

:::note info 
この方法は、現時点での最適を考えるので、そもそもの問題構成に「良い性質(※)」がないと成立しなかったりする。
:::


#### 課題パターン1：コイン問題
支払いに使うコインを最小にするにはどうするか、というやつ。
500円、100円、50円、10円、5円、1円があるとして、例えば2431円をどうやって支払うか、みたいなこと。

#### 考え方
とりあえず、後先考えなくて良いので、500円で払えるだけ払う。
残った分は、また後先考えずに100円で払えるだけ払う。
これを他のコインでも繰り返す。
どの順序でコインを選択するかが大事。

:::note info 
※良い性質：コイン問題は、実はコインが1円、4円、5円みたいになっていると貪欲法で解けなくなる。8円出すのに5+1+1+1より、4+4の方が少なくて済む。
:::

#### 区間スケジューリング問題
できるだけたくさん仕事ができるようにスケジュールを組む、という課題。
仕事Aは13:00~13:30、仕事Bは13:20～14:00、仕事Cは13:30～14:00、となっていた時、一番たくさん仕事ができる組み合わせを考える。

#### 考え方
仕事というがその実、開始-終了で区切られた「区間」の選択になる。
用意されている区間をどの順序で選択する(しない)かが大事。
終わり時間でソートして、一番早く終わるもの(仕事A)はとりあえず選んでしまう。
仕事Aと、Aと重なるもの(仕事B)を除いて、同じことを繰り返す。
区間の問題は終わり時間でソートするのが良いらしい。
curlコマンドで Azure OpenAI Service の tts-1 を使って音声合成して whisper による音声認識も行う

## 概要
Azure OpenAI Service を使った「音声合成（Text to speech）」と「音声認識（Speech to text）」の話です。

それらを curlコマンドで扱います（※ 自分が試している環境は Mac です）。

処理の流れとしては、[Azure OpenAI Service の tts-1](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models#text-to-speech-preview) を使った音声合成を行い、音声ファイルを得ます。そして、tts-1 で得た音声ファイルを [Azure OpenAI Service の whisper](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models#whisper-preview) を使った音声認識でテキスト化します。

## 事前準備（※ 詳細は省略）
今回の curlコマンドを実行するために、Azure OpenAI Service のモデルのデプロイ（※ モデルは、tts-1 と whisper の 2種）を行っておいてください。
※ 記事執筆時点だとモデルを利用可能なリージョンが限定的だと思いますので、そのリージョンの情報は[公式情報で確認](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/concepts/models)して進めてください

そしてこの後に API経由でモデルを使うため、以下の情報も用意しておいてください。

- エンドポイント
- デプロイ名
- APIキー

## curlコマンドで API を使う
### tts-1 による音声合成
まずは、音声合成です。コマンドは、「[公式情報](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/text-to-speech-quickstart?tabs=command-line#rest-api)」と「[JBS Tech Blog の記事](https://blog.jbs.co.jp/entry/2024/02/19/113914)」を参考にしました。

以下が実際のコマンドになります。APIバージョンは「2024-02-15-preview」を指定しています。【エンドポイント】・【デプロイ名】・【APIキー】 の 3箇所は、ご自身の環境のものを指定してください。

```bash
curl '【エンドポイント】/openai/deployments/【デプロイ名】/audio/speech?api-version=2024-02-15-preview' \
 -H "api-key: 【APIキー】" \
 -H "Content-Type: application/json" \
 -d '{
    "model": "tts-1",
    "input": "I am excited to try text to speech.",
    "voice": "alloy"
}' --output speech.mp3
```

コマンドの実行結果は、以下のとおりです。ここで得られた speech.mp3 をプレイヤーで再生し、音声が再生されるのを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/bf0b9fd1-fe22-3c49-13c0-07ab83e70556.png)

### whisper による音声認識
今度は音声認識です。その入力には、先ほど音声合成で作ったファイルを使います。
コマンドは、「[公式情報](https://learn.microsoft.com/ja-jp/azure/ai-services/openai/whisper-quickstart?tabs=command-line%2Cpython&pivots=rest-api#rest-api)」を参考にしました。

以下が実際のコマンドです。先ほどと同様、APIバージョンは「2024-02-15-preview」を指定しています。【エンドポイント】・【デプロイ名】・【APIキー】 の 3箇所は、ご自身の環境のものを指定してください。

```bash
curl '【エンドポイント】/openai/deployments/【デプロイ名】/audio/transcriptions?api-version=2024-02-15-preview' \
 -H "api-key: 【APIキー】" \
 -H "Content-Type: multipart/form-data" \
 -F file="@./speech.mp3"
```

コマンドの実行結果は、以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9ca44b51-22a6-2816-bef4-d5af7639f415.png)

音声合成の時に入力した「"I am excited to try text to speech."」という内容が得られているのが確認できました（ハイフンの有無が微妙に違っていますが...）。

音声合成で作成したノイズなどがない音声なので、音声認識の結果もきれいに得られた形かと思います。
iOS で AppleID の個人情報が開かない

# はじめに
iPhone の設定で AppleID は開くが、その先の `個人情報` がグレーになり、開かないというケースについて悩んでいる人がいたので、原因と解決策をまとます。以下の写真のようなケースです

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/950402df-449f-d051-03f1-64bdbac14fa8.jpeg"/>


:::note info
そもそも AppleID 自体がグレーになっていて開かない場合についても取り上げます
:::

# AppleIDが開かない

AppleID がグレーになり開かない理由は、スクリーンタイムの中で規制されているからです

設定 > スクリーンタイム > コンテンツとプライバシーの制限 > アカウント変更

が`許可しない`になっている場合開かないので、許可してください

# AppleID のその先がグレーになって開けない

開けない理由は2つケースに分けられます

1. ネット接続がない
1. WiFi に接続していない & モバイル通信 で `設定` がオフになっている

## ネット接続がない

- WiFi がオフになっている
- モバイル通信 がオフになっている

この 2 つの条件が揃っていると、ネットに接続できず、開けません

## モバイル通信 で `設定` がオフになっている

設定 > モバイル通信

で画面下部にそれぞれのアプリのモバイルデータ通信についての設定項目があります

この設定で、`設定`アプリが オフ になっているかつ、WiFi がオフになっている場合、設定アプリがネット通信できないため、開けません

# 終わりに

今回は身近な人が困っていて、Apple の質問の中でこの結果に至った方を見受けられなかったのでまとめました
【1年後の1年前は今日ではない！】Go でうるう年に落ちるテストがあった話

# 概要

本日は2024はうるう年で2月29日が追加され、1年が366日ある年です。
そんな2024/02/29に落ちるテストがあっておもしろかったので共有です

# テスト概要

ユーザーの会員期限の再アクティベートのテスト。一度会員になって失効して再度会員になったときに正常に有効化できるか、というような旨のてすとです。

1. 失効期限を今日から1年後にする
1. 失効期限を1年前に戻す
1. 期限が切れていることを期待する
1. 再度アクティベートする

という流れの3でうるう年の今日だけ有効期限が切れなくなっていました。

# 原因

Golang でうるう年2/29の１年後を取得すると、翌年の2025年は2/29 がないので3/1 に繰り上げされ、１年後の１年前が今日じゃなくて翌日になっていたため！

例: 

**1/ 失効期限を今日から1年後にする**
→　2025年に2/29 はないので3/1

**2/ 失効期限を1年前に戻す**
→　2025年3/1 だったので2024 3/1 になる

**3/ 期限が切れていることを期待する**

Now() = 2029 2/29 なので< 2024/ 3/1
会員期限は迎えていない!閏年に救われている!
↓
失敗

# 対応

1年足すのをやめて日数を足すようにした

# PlayGround での確認


``` go 
// You can edit this code!
// Click here and start typing.
package main

import (
	"fmt"
	"time"
)

func main() {
	// 普通に考えて1年後にすすめて1年前にもどしたらその日に戻る
	t := time.Date(2023, 2, 28, 0, 0, 0, 0, time.UTC)
	fmt.Printf("初期状態: %s\n", t)
	tAdd1year := t.AddDate(1, 0, 0)
	fmt.Printf("1年後: %s\n", tAdd1year)
	fmt.Printf("1年後の1年前: %s\n", tAdd1year.AddDate(-1, 0, 0))

	println("===============")
	// うるう年2/29は例外！
	t = time.Date(2024, 2, 29, 0, 0, 0, 0, time.UTC) // 閏年の2/29
	fmt.Printf("初期状態: %s\n", t)
	tAdd1year = t.AddDate(1, 0, 0)
	fmt.Printf("1年後: %s\n", tAdd1year)
	fmt.Printf("1年後の1年前: %s\n", tAdd1year.AddDate(-1, 0, 0)) // 3/1になっている
}
```

ref: https://go.dev/play/p/f4z9CXbIi8d

memo:
1ヶ月増減はセーフ
12ヶ月増減はアウト
365日増減はセーフ
AD認証とSSO認証

### AD認証とは

**AD** とは「Active Directory」の略称でマイクロソフト社から提供されている機能であり、ユーザーアカウントや端末情報を管理することが可能なメカニズム。
部署や役職といったユーザーの「属性」でアクセス制御が可能なため、ユーザーごとに個別で制御を設定する必要がない。
→つまり、いくつかの権限グループを作り、そこに各ユーザーアカウントをいれていくイメージ。そのため、各ユーザーに権限をつける手間が省ける。

### SSO認証とは
**SSO** とは、ユーザーが複数のアプリケーションやサービスに対して1回の認証でアクセスできるようにする仕組みのこと。
ユーザーが1回ログインすると、他の関連するシステムやアプリケーションに再認証なしでアクセスできるようにする。これにより、ユーザーエクスペリエンスが向上し、パスワードの維持が簡素化される。


### まとめ
・AD認証は、ユーザーがWindowsネットワークにログインする際に使用されるMicrosoftの認証メカニズムのこと。

・SSO認証とは、1回のログインで複数のアプリケーションやサービスにアクセスできる仕組みのこと。

[参考サイト]
・[AD（Active Directory）連携によるシングルサインオン（SSO）について](https://biz.techvan.co.jp/tech-microsoft/blog/contents/activedirectory_singlesignon.html#:~:text=%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%A8%A9%E9%99%90%E3%81%8C%E3%81%82%E3%82%8B%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC,%E3%81%A0%E3%81%A8%E3%81%84%E3%81%88%E3%82%8B%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%80%82])
・https://codezine.jp/article/detail/4212
【JavaScript】オブジェクトをJSON文字列に変換する方法

`JSON.stringify()`を使用することでオブジェクトや値をJSON文字列に変換します。

```js
const jsonObject = {
    name: "Sample",
    age: 20
}
const jsonString = JSON.stringify(jsonObject)

console.log(jsonString) // {"name": "Sample","age": 20}
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
activerecord.ja.ymlファイルの便利さ

## はじめに
　Railsで簡単な掲示板サイトを作っていた時に、ページ（今回はプロフィール画面）のカラムが期待通りに表示されておらず、なかなか原因が分からなかった事がありました。
## 環境
ruby 3.14
rails 7.0.3.1
## 目次
事例
activerecord.ja.ymlファイル
別の方法
まとめ

## 事例
　Railsで簡単な掲示板サイトを作っていた時に、profileページが期待通りに表示されませんでした。

![qiita1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/8a8764e4-651a-7673-9c44-ea758a58d44d.png)

メールアドレスや氏名がちゃんと表示されているにも関わらず、アバターだけがAvatarと英語表記になってしまっています。

profiles/edit.html.erb
```
<div class="mb-3">
  <%= form.label :last_name %>
  <%= form.text_field :last_name, class: 'form-control' %>
</div>
<div class="mb-3">
  <%= form.label :first_name %>
  <%= form.text_field :first_name, class: 'form-control' %>
</div>
<div>
 <%= form.label :avatar %>
  <%= form.file_field :avatar, class: "form-control", accept: 'image/*' %>
  <%= form.hidden_field :avatar_cache %>
</div>
```


form_withの書き方が間違っているのか、しかし他のカラムはしっかり表示されているのになぜ…。

## activerecord.ja.ymlファイル

<strong>i18n</strong>というgemがあります。Railsではデフォルトで入っている、様々な言語に対応するためのものですね。

これを用いるのに必要なファイルが、ja.ymlファイルとactiverecord.ja.ymlファイル。

今回関わってくるのは後者のactiverecord.ja.ymlファイル。
このファイルは「このテーブルのこのカラムは〇〇と表記してね」とカスタマイズすることが出来る大変便利な機能ですが、この機能のありがたさが当時はあまりピンと来ておらず、「とりあえず書くのが決まり」と解釈していました。

今回edit.html.erbで書いた<strong>:avatar</strong>は、Userテーブルのavatarというカラム。


config/locales/activerecord.ja.ymlファイルを確認してみる。

![qiita1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/f414be26-c32c-e80e-9e19-4f54a4da67df.png)

他のカラムは登録されているのだが、今回はavatarはまだ登録されていない。

早速登録してみましょう

![qiita1-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/337ef071-b283-27d2-5873-7033bb4405a9.png)

これでUserテーブルのカラムであるavatarに”アバター”と名前をつける事で、逐一form_withを使う時に、〇〇とか書かなくても大丈夫なようになった。

ブラウザの方も確認してみると、

![qiita1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/feb0de36-5e40-a233-393b-e05aa33b2d84.png)

無事解決。

ちなみに開発者ツールを使うと次のような構成になっているのが分かる。

activerecord.ja.ymlファイルに記述しない場合
![qiita1-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/befa94e3-dd07-f9e2-eca0-e7b7e368ca91.png)

activerecord.ja.ymlファイルに記述しない場合
![qiita1-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/097f719f-d7da-5f89-921f-9063a3490074.png)


## 別の方法

i18nにコードを追加しない場合は、以下の画像2行目のように表示させたい言葉、つまり"アバター"と書いてしまうのもあり。
![qiita1-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726578/3e342919-e30c-b62e-b400-1ea07b6e74db.png)
しかしながら、i18nを利用すれば、後々コードが膨大になった後で修正する際には便利。

## まとめ

サイトを作り始めの時は、activerecord.ja.ymlファイルやja.ymlファイルに記述するのは手間ですが、数箇所form_withを使う状況になることもあり得るので、活用してしまった方が便利。

　<strong>「システムテストをして、実装が正確に行われているかを判断する場合」ではテストに通らない原因となるので</strong>、詰まった際にはactiverecord.ja.ymlへのコードの書き忘れも念頭においた方が良いかもしれません。
構成要素を持つ型 Part.1

構成要素を持つ型 Part.1
class編
---
クラスとは同じような処理を集めた箱のようなものです！
クラスの中には変数や関数などの処理がまとめて記述されます！
使用するにはクラスの外からクラスにアクセスするためのインスタンスを作成する必要があります！
基本的にクラス名は、アッパーキャメルケースで記述します
アッパーキャメルケースとは 単語の先頭と単語間の区切りの最初の文字を大文字にする ことです！
例 SampleClass

サンプルプログラム1
```
//クラスを定義
class SampleClass {

    //定数の定義
    let a = "まっちゃんの髪"
    let b = "浜ちゃんのしわ"
 
}
 
 //クラスの定数を参照
print(SampleClass().a) 
print(SampleClass().b)
```
実行結果:
```
まっちゃんの髪
浜ちゃんのしわ
```
インスタンスは'クラス名()'で生成できます！
上記だと'SampleClass()'を指します！

クラスの変数にアクセスするには'クラス名().変数名'で、そのクラスの変数にアクセスすることができます!
ですが一般的に上記のようにインスタンスをクラス（）のように使用する方法は使用されません！！

クラスのインスタンスは、以下のようにインスタンスを変数や定数に代入してから使用する方法が一般的です！
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇

サンプルプログラム2
```
// クラスを定義
class SampleClass {

 // 定義
 let a = "まっちゃんの髪"
 let b = "浜ちゃんのしわ"
 
}

// インスタンスを作成
let c = SampleClass()

// クラスの定数を参照
print(c.a)
print(c.b)
```
実行結果:
```
まっちゃんの髪
浜ちゃんのしわ
```
基本的にクラスのインスタンスを生成して使用するには、上記のような方法となります！

最後にイメージしやすいように
```
class Automobile {

    var maker = "TOYOTA"
    var name = "カムリ"
    var doorCount = 4
    var fuelcapacity = 50 // リットル
    var displacement = ２５００ // cc
}

// インスタンス化
let myCar = Automobile()

print(myCar.maker)
print(myCar.name)
print(myCar.doorCount)
print(myCar.fuelcapacity)
print(myCar.displacement)
```
実行結果:
```
TOYOTA
カムリ
4
50
２５００
```
今回は以上です
次回は構成要素を持つ型 Part.2 struct編です！
【解決済み】KubernetesにMetalLBをインストールしたが「ensure CRDs are installed first」のエラーが出てIPAddressPoolのリソースを作成できない

# はじめに

おうちKubernetesの設定をしている時、本エラーにハマったので共有のために記事を残しておきます。

# 環境

Kubectl Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Kubernetes Version: v1.28.7
CNI: Calico

# 作業手順

[Kustomizeを利用したMetal LBのインストール手順に従って](https://metallb.universe.tf/installation/#installation-with-kustomize)、以下のKustomizationファイルを作成した。

```:kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: metallb-system

resources:
  - github.com/metallb/metallb/config/native?ref=v0.14.3
  - ipaddresspool.yaml
```

```:ipaddresspool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metallb-system
spec:
  addresses:
  - 192.168.11.200-192.168.11.250
```


このKustomizationファイルを`kustomize apply -k ./metallb`で適用しようと試みたが、MetalLB公式のマニフェストのリソースが全て`Created`になった後、IPAddressPoolのリソースだけが

> error: resource mapping not found for name: "default" namespace: "metallb-system" from "./metallb/ipaddresspool.yaml": no matches for kind "IPAddressPool" in version "metallb.io/v1beta1"
ensure CRDs are installed first

のエラーによって作成されませんでした😢

# 原因

わかりませんでした（解決はしたので詳細は後述）

「ensure CRDs are installed first（CRDを先にインストールしろよ）」などと言われている割には、`kubectl get crds`でカスタムリソース定義を確認すればIPAddressPoolは既にインストール済みですし、どん詰まりでした。

# 解決方法

`kubectl apply`の後、10分ほど待ってから再度`kubectl apply`を試してみたところ、今度はエラーが出ずIpAddressPoolを作成することができました。

よくわからない・・・（詳細をご存じの方はTwitterでもこちらの記事のコメントでも、ご連絡いただけると嬉しいです）
pdfにコンパイル？できないトラブルシューティング


LaTeXを導入しようと思い、

https://qiita.com/passive-radio/items/623c9a35e86b6666b89e#2-vscode%E3%81%AE%E5%B0%8E%E5%85%A5-%E3%81%99%E3%81%A7%E3%81%ABvscode%E3%81%8C%E5%85%A5%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E4%BA%BA%E3%81%AF%E6%AC%A1%E7%AB%A0%E3%81%B8

↑こちらの記事を参照し、
"3. VSCode に LaTeX 環境を整備"
まで進んだのですが、

test.tex の作成が終われば、Ctrl + @ を同時に押して VSCode 上にコマンドプロンプトを表示させ、

cmd
lualatex test.tex
と打って実行します。

というところで挫折。


そこで、
https://qiita.com/alpaca-honke/items/f30a2d04eedaa3c36a21#%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96%E6%8B%A1%E5%BC%B5
①上記の記事のsettings.jsonをコピペ

https://qiita.com/alpaca-honke/items/f30a2d04eedaa3c36a21#%E5%BF%85%E8%A6%81%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
②上記の記事の「2023.05.10追記」よりlualatex-mathをインストール

以上①、②を実施したところ無事pdfが出てきてくれました…！


以上の記事の著者の方々にお礼申し上げます。
おわり


(2024/03/01追記)
①の記事のURLが間違っていたので修正しました。申し訳ありません。
新しいサービスを作り、古いサービスを優しく殺すお話

# はじめに
私は製造業の現場作業員です。
現場作業員には、手続きが色々とあります。手続きの数だけ担当窓口があり、窓口の数だけ謎ルールがあり、謎ルールの数だけお作法があります。
でもようやく、少しづつ、複写伝票がFAXになり、メールになり、オンラインフォームになり、電子承認が取り入れられたりしています。デジタル化万歳。
さて、これを「せーのっ」と3月31日→4月1日に切り替えができるのか？
できないとしたらどうすればいいのか？なポエムです。
# 移行したところで新サービスの普及には時間がかかる
便利な新サービスを作ったからといって、全ての利用者が一斉に新サービスへ切り替えて便利に活用してくれる、は幻想です。そんなわけない。
* 新サービスの存在が認知されない（告知を見ない）
* 見ても理解しない
* 先輩に聞いたら複写伝票を渡された
* 〇〇課は電子承認を採用してない

やらない理由はいくらでも出てくるのです。これを慎重に、丁寧に、1つ残らず摘み取っていくのが新サービスへの移行なのです。
# 当面の間、新旧両方のサービスをサポートする消耗戦になる
もちろん新サービスのサポートや不慣れな利用者への問い合わせに対応しなくてはなりません。
もちろん旧サービスのサポートは全く減りません。だって利用者がわんさか居るので。
この覚悟と根性がないまま、新サービス開始を告知してはいけません。気力か体力のどちらか、もしくは両方が削られます。
# 小さく初めて大きく育てる
人も設備もアプリもサーバも最初は不具合だらけです。そういうものです。
テスト環境でどれだけテストしても、〇〇営業所から来たデータだけが順番通りに並ばないと思ったら時計がズレてたなんてことは極まれに良くあります。「5分前行動実践中」などという謎キャンペーンが所長の思い付きで即時実行されてしまうのが営業所です。（NTPサーバのことは一瞬忘れてください）
伝票100件当たりの問い合わせ数が少ない部門や、技術的にレベルの高いナイスな問い合わせをしてきた人をメモしておきましょう。そういう部門や人にレターを書き、お願いだから（カナリアになって）新システムのテストに協力してくれ、あなたは王国の危機を救う勇者（カナリア）なのだと持ち上げて新サービスを試してもらいましょう。
私はテスト中の新サービスから出てきたデータを旧サービスに手動で転記して、何食わぬ顔で処理を走らせるという姑息な手をよく使います。これも小さく始めている（そしてカナリアが協力してくれる）から実現できるのです。
# さあ育てよう
立ち上がりの不具合を一通り経験し、レベルを上げ、装備を揃えたら新サービスの正式開始をアナウンスしましょう。カナリア部署が協力してくれた事例をPRに使うのも良い方法です
* 告知
* 新サービスのサポート
* 旧サービスのサポート

これを同時並行で走らせます。気力と体力を十分に養いましょう。新サービス利用者の「便利になったよ」のフィードバックが貰えたら大喜びしましょう。アンケートの初期値を☆5にしておくのも良い方法です。寝れる時に寝ましょう。
# 寝れる時に寝るためには
告知で
* 新旧両サービスが並行している点
* 新サービスは順調に利用者が増えている点

をPRしましょう。具体的には、「旧サービスのサポートを段階的に縮小する」宣言が必要です。1日は24時間しかありませんし、あなたの身体は１つしかないのですから。
段階的に縮小する方法は
* 曜日で区切る（毎週〇曜日は旧サービスのサポートはお休みします）
* 時間で区切る（旧サービスのサポートは15時以降は翌日対応になります）
* 件数で区切る（現在受付番号〇〇番まで対応しています）

これらを上手く組み合わせて、新サービスへの移行を促進していきましょう。
# 広げた風呂敷の畳み方
新旧サービスの平行稼働、大変お疲れ様です。
利用者をカウントして、新サービスの利用者が51%を越えたら大々的に勝利宣言をしましょう。旧サービスのサポートを一気に縮小しましょう。EOS（End Of Service）を示しましょう。旧サービスの利用者さんに、重い腰を上げてもらいましょう。ここを非情にやらないとズルズルと撤退戦を続けることになります。偉い人からクレームがきても「過半数が既に利用していますので」と押し切れます。私はこれを「51％戦略」と呼んでいます。
# おわりに
技術的な話でもなんでもないポエムを読んでくれてありがとうございます。
私は「良い回答は良い質問が作る」と信じて、「社内ヘルプデスクのヘルプデスク」を勝手に作って活動をしています。利用者からも情シスからも奇異な目でみられていますが、デジタルで職場が愉快になったらいいなと思って活動しています。qiita記事にできるほど気の利いたことが言えない時は、Xやブログに色々書いています。Xをフォローしてくれるととても嬉しいです。
https://twitter.com/1RRhcSB6HSUu9hF
それではまた。愉快に行き当たって楽しくばったりお過ごしください。
バリデーションチェック時のnullと空文字との違い

Spring Bootを使用して以下のようなバリデーションを想定します。
nullと空文字それぞれで挙動を確認します。

```java
public class SampleRequest {
    @NotBlank(message = "空白です")
    @Size(max = 10, min = 10, message = "10桁で入力してください")
    @Positive(message = "正の数を入力してください")
    private String number;
}
```

```java
@RestController
@RequestMapping("/api/v1")
public class SampleController {
    @PostMapping(value = "/hello")
    public String post(@RequestBody @Validated SampleRequest request) {
        return "hello";
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<List> handleError(MethodArgumentNotValidException exception) {
        List<String> messages = exception.getBindingResult().getFieldErrors().stream().map(FieldError::getDefaultMessage).toList();
        return ResponseEntity.badRequest().body(messages);
    }
}
```
### nullの場合
nullをPOSTした場合は以下のレスポンスが返ってきます。
``` :response
["空白です"]
```
これにより以下のことがわかります。
- nullの場合は`@NotBlank`にひっかかります。
- nullの場合は対象が存在しないため、`@Size`、`@Positive`で検証されません。

### 空文字の場合
空文字をPOSTした場合は以下のレスポンスが返ってきます。
``` :response
["空白です","10桁で入力してください","正の数を入力してください"]
```
これにより以下のことがわかります。
- 空文字の場合は`@NotBlank`にひっかかります。
- 空文字の場合はサイズ0の文字列として扱われるため、`@Size`、`@Positive`でもひっかかります。

<br>
バリデーション時にnullと空文字それぞれで挙動は異なることがわかりました。
pgAdmin 4使用時　列が追加できず、カラムに鍵マークがついた

# はじめに
pgAdmin 4を使用してPostgreSQLのテーブルにカラムを追加しようとした際に直面したトラブルに関する記事です。
テーブル作成した後、カラムに値を追加できなくなりました。

# 現象
bookというテーブルを作成しました。idをint,titleをchar,authorをchar,priceをint,4つのカラムを作成しました。
![スクリーンショット 2024-02-29 23.10.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657759/d700da14-5d21-08de-aba2-e8eecf874efc.png)

作成したテーブルを確認して見てみると、カラムに鍵マークがつきました。
さらに画像左上の「三+」がグレーになってしまい、列が追加できませんでした。
![スクリーンショット 2024-02-29 22.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657759/e9717521-f7c4-93f7-49ef-c131327e621a.png)

# 対処方法
私の場合は、サンプルのテーブルなので、一回削除し、もう一度作成し直しました。後からプライマリーキー設定する方法もあると思います。今回は省略します。
今回は、idを主キーに設定しました。Primary key?のところクリック　青くなります。
![スクリーンショット 2024-02-29 22.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657759/6b0ce71d-d703-1b00-ee23-730f3e2e4f86.png)

# 結果
プライマリキーを設定した後に「三+」がグレーだったのが、黒になり、列の追加、カラムの追加できるようになりました！
![スクリーンショット 2024-02-29 22.32.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657759/b9a8cc78-dd93-da00-3362-9f478361b962.png)

~~# 原因~~
~~[公式](https://www.postgresql.jp/docs/9.2/ddl-constraints.html)には、下記のことが書いてあります。私の場合、「リレーショナルデータベース理論では、全てのテーブルにプライマリキーが1つ必要とされています。」これを無視して作成していたのが、原因だと思われます。~~

~~「プライマリキーの設定が推奨される理由」は、また調べて記事にしたいと思います！~~
コメント頂いたので、修正しました。



```
1つのテーブルは最大1つのプライマリキーを持つことができます。 
（一意性制約および非NULL制約には個数の制限はありません。
機能的には同じものですが、プライマリキーとして識別される制約は1つのみです。） 
リレーショナルデータベース理論では、全てのテーブルにプライマリキーが1つ必要とされています。 
この規則はPostgreSQLでは強制されませんが、たいていの場合はこれに従うことが推奨されます。
```

# 原因
[公式](https://www.postgresql.jp/docs/15/ddl-constraints.html)には、下記のことが書いてあります。私の場合、主キーに対する理解不足が原因だと思われます。


```
主キーは文書化、および、クライアントアプリケーションの両方の面で役に立ちます。 例えば、行値の変更が可能なGUIアプリケーションが行を一意的に特定するためには、 おそらくテーブルの主キーを知る必要があります。 他にも主キーが宣言されているときにデータベースシステムがそれを利用する場面がいくつかあります。 例えば、外部キーがそのテーブルを参照するとき、主キーがデフォルトの対象列となります。
```