OmniAICreator/Qiita-1.07M huggingface dataset:
AWS使って体育館予約自動化してみた

## はじめに
NTTテクノクロスの熊倉です。この記事は[NTTテクノクロス Advent Calendar 2024 シリーズ1](https://qiita.com/advent-calendar/2024/ntt-tx)の12日目の記事となっています。業務では主にAWSを扱っており、AWSサービスの試験やガイドラインの作成など実施しています。AWSは学び始めてまだ1年半くらいなので、温かい目で見ていただければ幸いです。

## きっかけ
毎週土曜日趣味でバドミントンをしており、体育館の予約を自分が担当していました。そのため、毎週以下のような作業が発生していました。

1. 体育館の空きを確認し、予約
2. LINEで日程調整
※「12/7(土)17-19」と送信し、参加できるなら:grin:、参加不可なら:joy:といった感じでリアクションしてもらう

3. メンバーが揃えば開催、揃わなければキャンセル

この作業を毎週実施するのが面倒だと思い、AWSを使ってどうにか自動化できないかと考えました。

## 予約する体育館について
- 3か月先の同一日まで予約可能
例：12月12日であれば、3月12日まで予約可能
⇒つまり、3か月先の予約開始のタイミングで予約すれば必ず予約できる
- 予約日の1か月の同一日までに現地で支払いが必要（未払いだとキャンセルされる）
⇒予約日1か月前までには開催可否を決定する必要がある

- 支払いの際には予約時に取得できる予約番号が必要

## 実現したいこと
①3か月後の土曜日を自動予約する
②予約番号をLINEからいつでも取得できる
③日程調整のLINEを自動送信する

## 作成したシステム

![gym-reserve.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879459/6d2ae5de-3a03-86e3-366a-d78298865402.png)

### ①予約処理
- 毎週朝9時にEventBridge Schedulerが予約処理のLambda関数を実行
    - EventBridge Scheduler：定期的なタスク実行を管理するサービス
    - Lambda：サーバーレスでプログラムを実行できるサービス
- 予約結果をSNSで熊倉の携帯のSMSに通知
    - 指定した登録先に通知を送るサービス
- 予約情報をDynamoDBに格納
    - DynamoDB：NoSQLデータベースサービス

Dynamoの中身は以下のようになっています。予約した情報（reserve-day, reserve-num, reserve-time）とこのレコードの有効期限（expireAt(TTL)）を格納しています。DynamoDB の TTL(Time to Live)機能により、expireAt カラムに格納されたエポック時間(例の場合、1735120800 = 2024年12月25日19時00分00秒)を過ぎるとレコードが自動削除されるように設定しています。
※レコード期限は予約日の日時にしています。

| reserve-day | reserve-num | reserve-time | expireAt(TTL) |
|:-:|:-:|:-:|:-:|
| 2024/12/25  | 1111222  | 17-19  | 1735120800  |

### ②予約番号取得
- LINE Botに対し、日付(YYYYMMDD)を送信するとMessaging APIに設定したAPI Gatewayが呼び出され、DynamoDBに格納されている予約番号を返すLambda関数が実行される
    - API Gateway：LINEとAWSシステムを連携させるための入口となるサービス

### ③日程調整LINE自動送信
- 毎週EventBridge Schedulerが5週間後の土曜日の予約情報を取得し、その情報から日程調整のLINEを自動送信するLambda関数を実行する

## 使用したもの
### AWS
Lambda関数のコードはpythonで作成し、予約処理のためのウェブスクレイピングにSeleniumを使用しました。Seleniumは現在Lambda関数で対応しているpythonのバージョンだと互換性の関係で使用できません。そのため、Seleniumが使用できるよう作成されたコンテナイメージからLambda関数を作成しました。

https://qiita.com/sugo/items/7edf86482dcd837e34de

### Messaging API
Messaging APIを使ってLINE公式アカウントのようなLINE Botを作成できます。Messaging APIはプランが3つあり、無料で使用することもできます。※ただし、月に送信できるメッセージ数が200通までとなっています。

https://developers.line.biz/ja/docs/messaging-api/overview/

## 料金
### AWS
- API Gateway
月4回ほどリクエストするので0.000000425×4＝0.000017 USD/月
- ECR
ストレージ料金がかかるため、0.1 USD/月

### Messaging API
- 無料

### 合計： 0.100017 USD/月 = 約15.14円/月
ほとんどのサービスが永年無料枠で利用できました。
超安い、、AWSすごい

## まとめ
今回作成したシステムによって、体育館の予約と日程調整の作業をほとんど自動化することができました。自分の作業は、自動送信されたLINEの投票結果を見て必要ならキャンセルするのみなので、毎週体育館を意識することはほとんどなくなりました。

## あとがき
自分の課題を解決するために何かを作ることは非常に楽しいですし、AWSの勉強にもなったので今後も何か日常や業務で課題があれば、AWSを使って解決していきたいなと思いました。

**明日のNTTテクノクロス Advent Calendar 2024は、 @krbr-775 さんの「VSCodeの拡張機能を自作した話」についての記事です。お楽しみに！**
rex0220 プラグイン カタカナ変換とカタカナチェック

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)と[項目検証プラグイン](https://qiita.com/rex0220/items/be20fd879f5e1bc9e035)で、カタカナ変換とカタカナチェックを行います。

# 概要

カタカナのみ入力させたい場合やカタカナと英数字のみ入力させたい場合に、文字列変換と文字列チェックを行います。

- カタカナ変換：　計算式プラグイン
    - 半角カタカナを全角カタカナに変換
    - ひらがなをカタカナに変換
- 文字列チェック：　項目検証プラグイン
    - 全角カタカナのみかチェック
    - 全角カタカナと英数字のみかチェック

![2024-12-05_10h26_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/fa6c4c52-a446-30ae-d1b6-a128ceb14cd5.png)


# 計算式プラグイン設定

計算式を設定する項目をその計算式内で参照する場合は、「循環参照を許可」をチェックします。

![2024-12-04_17h35_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f0e656b2-a388-4973-b197-0bbfd31687d8.png)

```.js
OPTION: 循環参照を許可

// カタカナ変換 SINGLE_LINE_TEXT (editable)
KATAKANA(JIS(カタカナ変換,"k"))

// カタカナ変換チェック SINGLE_LINE_TEXT (editable)
KATAKANA(JIS(カタカナ変換チェック,"k"))

// カタカナ英数字変換チェック SINGLE_LINE_TEXT (editable)
KATAKANA(JIS(カタカナ英数字変換チェック,"k"))
```

- JIS 関数：　半角文字を全角文字に変換
    - JIS(fieldcode [,"akmnst"])
    - "k": カナを変換
    - 例 JIS("ABﾁｪｯｸ","k") -> "ABチェック"
- KATAKANA関数：　全角かなを全角カナに変換
    - KATAKANA(fieldcode)
    - 例 KATAKANA("あいうえお") -> "アイウエオ"
- JIS 関数と KATAKANA関数の組合せ
    - 例 KATAKANA(JIS("あいうえおABﾁｪｯｸ","k")) -> "アイウエオABチェック"

# 項目検証プラグイン設定

カスタムチェックは、項目行の編集ボタンをクリックして、検証条件のダイアログを表示してエラーにする条件とエラーメッセージを設定します。

![2024-12-04_17h38_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a6b22df7-6f31-6811-2197-c527899ceda4.png)

![2024-12-04_17h38_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/dd053d34-5fd4-4876-c36c-c9aeb95f6849.png)

```.js
// カタカナチェック SINGLE_LINE_TEXT
 //* custom check-1:
TESTRE(カタカナチェック,"[^ァ-ンー]")
 //* message ja:
"全角カタカナのみ"

// カタカナ変換チェック SINGLE_LINE_TEXT
 //* custom check-1:
TESTRE(カタカナ変換チェック,"[^ァ-ンー]")
 //* message ja:
"全角カタカナのみ"

// カタカナ英数字チェック SINGLE_LINE_TEXT
 //* custom check-1:
TESTRE(カタカナ英数字チェック,"[^ァ-ンー０-９0-9Ａ-Ｚａ-ｚA-Za-z]")
 //* message ja:
"全角カタカナ、英数字のみ"

// カタカナ英数字変換チェック SINGLE_LINE_TEXT
 //* custom check-1:
TESTRE(カタカナ英数字変換チェック,"[^ァ-ンー０-９0-9Ａ-Ｚａ-ｚA-Za-z]")
 //* message ja:
"全角カタカナ、英数字のみ"
```

- TESTRE 関数：　文字列の検索(正規表現)で、文字の有無（true, false）を返します
    - TESTRE(fieldcode, pattern[, pattern])
    - "[^ァ-ンー]"：　カタカナ以外にマッチする正規表現のパターン
    - "[^ァ-ンー０-９0-9Ａ-Ｚａ-ｚA-Za-z]]"：　カタカナと英数字以外にマッチする正規表現のパターン
    - 例 TESTRE("アイウエオ", "[^ァ-ンー]") -> false
    - 例 TESTRE("アイウエオAB", "[^ァ-ンー]") -> true
    - 例 TESTRE("あいうえお", "[^ァ-ンー]") -> true
    - 例 TESTRE("アイウエオAB", "[^ァ-ンー０-９0-9Ａ-Ｚａ-ｚA-Za-z]") -> false
    - 例 TESTRE("アイウエオ%!@AB", "[^ァ-ンー０-９0-9Ａ-Ｚａ-ｚA-Za-z]") -> true
＜作成中＞ERPの概要、ERPとCRMの連携について、物流、在庫

## ERP（基幹システム）
・ERPは、販売・購買／在庫・生産・会計など一元管理する。経営効率を上げることを目的。
・SAPのERPはOdataに対応している。（ESBでプロトコル変換不要）
　→レガシーERPの場合、対応しておらず、ESBでOdate変換する必要がある。（その場合、ESBがODataプロバイダーとなる）
・ERPは、人・もの・金の動きを管理
【販売】顧客から注文を受ける⇒在庫引き当て⇒売上計上⇒仕訳
【購買】ものを購入⇒在庫増える・資産増える⇒支払い
【生産】ものを作る⇒在庫増える⇒会計
・前払いやデポジットもあるが、基本は注文⇒納品⇒請求⇒入金の流れ。（納品してから支払い。）
・売掛金は請求時点で発生し、入金受けると消込されて、売り上げになる。
・請求管理システムがインターネットバンクと繋がっており、入金があればSalesforceに連携されるケース。（SFで営業が売り上げになったか予実管理やダッシュボード確認のため。）
・仕訳＝勘定科目＋金額。
左）現金　100万、　右）借入金　100万
・ERPは、在庫管理システムや配送管理システムのようにリアルタイムに進捗や位置状況を把握するものではないので、あくまで日次などで在庫情報を同期する。Salesforce上で最新の在庫を見る場合は、在庫システムとシステム連携する必要がある。（もしくはCanvasなどで在庫システムの画面をSalesforceに埋め込む。その場合、在庫システムが改修可能で画面がある必要がある。）
・Salesforceは情報系。あくまでSoRはERPであり、業務としてみたいもの・運用として使う情報（処理状況や納品状況など）はSalesforceに持ってくる。財務などは一貫してERPのため、Salesforceの受注などはすべてERPに渡す。

↓ERPの概要を掴むためのキャッチアップ資料

https://www.youtube.com/watch?v=3f09OYEFZVs


https://youtu.be/Tltv91Zj-II?t=259


https://www.youtube.com/watch?v=0DbliySiwkE


↓Trailhead

https://trailhead.salesforce.com/ja/content/learn/modules/complex-b2b-implementations


↓模擬レビューボード（SalesforceとERPのIFあり。）

https://www.youtube.com/watch?v=JeRKgGj9HEk


↓本


https://www.amazon.co.jp/SAP%E6%8B%85%E5%BD%93%E8%80%85%E3%81%A8%E3%81%97%E3%81%A6%E6%B4%BB%E8%BA%8D%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE-ERP%E5%85%A5%E9%96%80-%E4%B9%85%E7%B1%B3%E6%AD%A3%E9%80%9A/dp/4798071358?source=ps-sl-shoppingads-lpcontext&ref_=fplfs&ref_=fplfs&psc=1&smid=AN1VRQENFRJN5


## 物流システム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450298/71edc273-89df-c95a-846d-f5bd7c206003.png)



https://www.plumsa.co.jp/column/3158/


https://www.siscloud.jp/logistics-it-cloud/wms/


https://it-trend.jp/physical_distribution_management/article/83-0002


https://smartf-nexta.com/archives/10531
API Best Practices ~ページングトークンなしでページネーションAPIを定義することは稀である

## ページングトークンなしでページネーションAPIを定義することは稀である

https://protobuf.dev/programming-guides/api/#define-pagination-api

ページネーションするAPIのベストプラクティスは、ページングトークン(next_page_tokenと呼ばれる)を使用することです。 

このページングトークンもprotoで定義し、任意の方法でシリアライズしたものを使用します。

この定義には多くのフィールドを含めることができますが、重要なのは柔軟性と安定性を確保できることです。
このトークンのフィールドは信頼できない入力として検証することを忘れないでください。


```protobuf
message FooQuery {
  // 悪い例： 最初と2回目のクエリの間にデータが変更された場合、結果を見逃してしまう可能性がある。 
  // 最終的に一貫性のあるストレージでは、古いデータが新しいデータの後に表示されることは珍しくない。 
  // また、オフセット/ページのアプローチはすべてソート順を前提にしているため、柔軟性が失われます。
  optional int64 max_timestamp_ms;
  optional int32 result_offset;
  optional int32 page_number;
  optional int32 page_size;

  // 良い例： You've got flexibility!
  // これを Response で返し、クライアントが次のクエリに設定します。
  optional string next_page_token;
}
```
FreeBSD12を使うために

# はじめに
この記事は、今年転職後、FreeBSDに関して必要であったことをメモとして残します。

# 必要なこと

現時点でのFreeBSDのバージョンは14.2-RELEASEです。しかし、業務のシステムとしてはバージョンアップができないこともあると思われます。

そういう時は、古いバージョンのISOファイルのダウンロードなど必要となってきます。そのほか必要なことを少しメモしておきます。

## ISOファイルのダウンロード

OSのダウンロードは、公式のダウンロードページの一番下にある「Past Release」をクリックします。

https://www.freebsd.org/where/

## pkgやports

pkgやportsも現時点でフェッチとかすると12では非対応のものとなり、動作しません。
12の時のパッケージは、subversionにあるため、とりあえず、subversionのインストールはしておくことが必要となります。

https://docs-archive.freebsd.org/doc/11.4-RELEASE/usr/local/share/doc/freebsd/ja_JP.eucJP/books/handbook/svn.html

https://wiki.freebsd.org/PortsSVN
Gitでよく使う便利なコマンド集

## はじめに
Gitを効率的に使いこなすために、自分が頻繁に利用する便利なコマンドをまとめました。これらのコマンドを習得することで、より円滑なバージョン管理ができます。

## 基本的な操作　
### リポジトリの初期化と複製
#### 新しいリポジトリを初期化
```bash
git init
```

#### リモートリポジトリを複製
```bash
git clone https://github.com/username/repository.git
```

### 変更の追跡と確認

#### 変更されたファイルの状態を確認
```bash
git status
```
#### 変更内容の詳細を表示
```bash
git diff
```
#### 変更をステージングエリアに追加
```bash
git add -A
```
#### 変更をコミット
```bash
git commit -m "コミットメッセージ"
```
### ブランチ操作
#### 新しいブランチを作成し、切り替える
```bash
git checkout -b new-branch
```
#### 既存のブランチに切り替える
```bash
git checkout branch-name
```
#### ブランチ一覧を表示
```bash
git branch
```
### ブランチのマージと削除
##3# 現在のブランチにother-branchをマージ
```bash
git merge other-branch
```
#### ブランチを削除
```bash
git branch -d branch-name
```
### リモートリポジトリとの連携
#### ローカルの変更をリモートにプッシュ
```bash
git push origin branch-name
```
#### リモートの変更をローカルに取り込む
```bash
git pull origin branch-name
```
### リモートブランチの管理
#### リモートブランチを表示
```bash
git branch -r
```
#### リモートブランチを削除
```bash
git push origin --delete branch-name
```
### 履歴の確認と操作
#### コミット履歴を表示
```bash
git log
```
#### 簡潔なコミット履歴を表示
```bash
git log --oneline
```
### コミットの修正と取り消し

#### 直前のコミットメッセージを修正
```bash
git commit --amend
```
#### 直前のコミットを取り消し（変更は保持）
```bash
git reset --soft HEAD^
```
## 高度な操作
#### 作業中の変更を一時保存
```bash
git stash
```
#### 非追跡ファイルもstashする
```bash
git stash -u 
```
#### 保存した変更を適用
```bash
git stash pop
```
#### 現在のブランチを他のブランチにリベース
```bash
git rebase other-branch
```
#### タグを作成
```bash
git tag v1.0.0
```
#### タグをプッシュ
```bash
git push origin v1.0.0
```

## おわりに
これらのコマンドを使いこなすことで、Gitを通じたプロジェクト管理がより効率的になります。状況に応じて適切なコマンドを使用して、開発を効率化しましょう！
レガシー言語解析には生成AIを使うことがベスト・プラクティスであることは間違いない

# レガシー言語を触る機会
私は基本的にマイグレーションしか経験ないです

# COBOL
基幹システムマイグレーションプロジェクトで触った言語
「これがCOBOLかぁ。。。まぁBASICだな」
という感想しかわかなかった。行番号ふっていてインデントあって読みやすい。
中学生の時にN88互換BASICよりウェルカムテューアンダーグランド入りした私にとっては、まさしく母体に戻ったような安心感があった。

当時は生成AIなどなかったのでNacaTransというツールを使わされていた記憶がある。
ただ当時のNacaTransちゃんは１つしかネスト対応しておらず、これらの対応を簡単な構文解析を使って複数ネスト対応した記憶がある。それをSVNでプッシュ？コミット？(時代を感じるね)してチームに使ってもらった。かなり感謝されて嬉しかった記憶がある。

>![Screenshot_20241205_081802_Comic Screen.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423236/930c7326-6397-5608-e6ab-c4240210b16b.jpeg)
ガーリッシュ ナンバー1 (電撃コミックスNEXT)
堂本 裕貴 (著), 渡航 (その他), ＱＰ：ｆｌａｐｐｅｒ（小原トメ太／さくら小春）

こればかりは当時参画していたプロジェクトの発注企業がそこそこのところで、もともとのコードが非常に可読性、保守性の高いものであったこと。**設計書が存在していたこと**から軽めの園芸系のバイトみたいな感じでこなせていた。

当時、お世話になっていた会社では他にも様々なことを身をもって教えていただいた。
* **競プロみたいなコードは全く歓迎されない**(学生あるある)
* 懇親会で酒に酔って社長に絡むと後日、滅茶苦茶怒られる
* 謝るのは仕事と割り切ればなんてことない
* 私の飲酒の適正ラインは強い酒(リキュール系)が強く感じなくところで止めること
* **Powershellは神ツール**

# RPG
これもマイグレーションで触った言語
「ﾅﾆｺﾚｲﾐﾜｶﾝﾅｲ」が最初の感想
なぜCOBOLのセクションで**設計書が存在していたこと**とかいう当たり前のことを太字にしていたのか、お察しのとおりである。
可読性に関しては無いに等しい、聞くところによると保守は画面に長尺の定規を当ててしているようだ。
メトロポリスの制作現場でディスプレイにペンで直書きして指示かいてたというりんたろう氏を彷彿とさせる職人技である。

https://tezukaosamu.net/jp/anime/129.html

「こんなもん人間が読めるわけねーだろ」
ということで、当時、並行して参画していたプロジェクトで生成AIを業務で使用していたので、そちらで説明を求めてみた。

# レガシー言語解析には生成AIを使うことがベスト・プラクティスであることは間違いない
理由は、
* 今の私はRPGという存在は知っているが内容は一切記憶していない
* こんなフワフワした内容が無いような記事を書いていることから察してほしい
* そんな私でも普通に業務遂行できたこと

ここからは少しチーム内政治的な話になるが、チーム内にRPGを専門としてる方がいて、あまりにも生成AIがツヨツヨすぎてその人の仕事を奪いかねないのか使用禁止例が出されてしまった。それなら私はプロジェクトを抜けたいと伝えた。
まさしくAIが仕事を奪ってしまう現場を目の辺りにした。仕事を失ったのは私であるというオチはつくが。

# 今はイケイケの言語も将来は必ずレガシーになる
未来の開発者のためにコードは可読性の良いわかりやすいものを書くように心がけよう。
特に生成AIで気に入っているのはCntr+I>/docのドキュメント作成である。使える人は積極的に使おうね。
SwiftGen入門：リソースを型安全に扱うためのツール

## はじめに
SwiftGenは、iOSアプリ開発においてリソース（画像、色、文字列など）を型安全に扱うためのツールです。この記事では、SwiftGenの基本的な使い方とセットアップ方法を解説します。
## SwiftGenとは
SwiftGenは、プロジェクト内のリソース（画像、色、フォント、ローカライズされた文字列など）に対してSwiftコードを自動生成し、タイプセーフな使用を可能にするCLIツールです。これにより、以下のメリットが得られます：
* タイポによるエラーの防止
* 存在しないリソースの使用を防止
* コード補完の恩恵

## セットアップ方法
#### 1. SwiftGenのインストール

SwiftGenは複数の方法でインストールできますが、ここではCocoaPodsを使用する方法を紹介します。（CocoaPodsの導入方法については[CocoaPods入門：iOSアプリ開発における依存関係管理ツール](https://qiita.com/dlxsmd/items/a6146b210be5cbc95464)をご参照ください。）

Podfileに以下の行を追加します：

```ruby
pod 'SwiftGen', '~> 6.0'
```

ターミナルで以下のコマンドを実行します：
```bash
pod install
```

#### 2. 設定ファイルの作成

プロジェクトのルートディレクトリで以下のコマンドを実行し、設定ファイルを作成します。

```bash
./Pods/SwiftGen/bin/swiftgen config init
```

作成されたswiftgen.ymlファイルを編集します。以下は例です:

```text
xcassets:
  inputs:
    - YourProject/Resources/Assets.xcassets
    - YourProject/Resources/Colors.xcassets
  outputs:
    templateName: swift5
    output: YourProject/Generated/Assets.swift

strings:
  inputs: YourProject/Resources/Localizable.strings
  outputs:
    templateName: structured-swift5
    output: YourProject/Generated/Strings.swift

fonts:
  inputs: YourProject/Resources/Fonts
  outputs:
    templateName: swift5
    output: YourProject/Generated/Fonts.swift
```

#### 3. コード生成の自動化

ビルド時に自動的にSwiftGenを実行するために、以下の手順を行います：

1. Xcodeでプロジェクトを開きます。
2. ターゲットの「Build Phases」タブを開きます。
3. 「+」ボタンをクリックし、「New Run Script Phase」を選択します。
4. 以下のスクリプトを追加します：
```bash
$PODS_ROOT/SwiftGen/bin/swiftgen config run --config $SRCROOT/swiftgen.yml
```
###### 使用例
SwiftGenを設定後、以下のように型安全にリソースにアクセスできます:
```swift

// 画像の使用
imageView.image = Asset.Assets.imgApple.image

// 色の使用
view.backgroundColor = Asset.Colors.backgroundColor.color

// ローカライズされた文字列の使用
label.text = L10n.sampleText1

// フォントの使用
label.font = FontFamily.ConcertOne.regular.font(size: 20)

```
## おわりに
ここまでSwiftGenの使い方を説明してきましたが、メリット・デメリットの話を詳しく書いていなかったので最後に紹介したいと思います。SwiftGenを使う上でのメリット・デメリットは以下の通りです:
#### メリット
* コードジェネレートするリソースを選択可能で、必要なものだけに絞れる
* ビルドが不要なため、コード生成が高速
* 設定ファイル(swiftgen.yml)ベースで、チーム内で同じルールを共有しやすい
* 差分を見てコード生成するため、不要な再生成を避けられる
* 生成先や生成元のパス、リソースの選択など設定が柔軟
* スネークケースの文字列をキャメルケースに変換してくれる
#### デメリット
* R.Swiftと比べて導入がやや面倒
* 日本語のドキュメントや説明が少ない
* Xibファイルからのコード生成に対応していない
* 最初のコード生成時、生成ファイルを手動でXcodeに追加する必要がある
* SwiftUI環境でのLocalizationのオーバーライドに標準では対応していない
* 現状Sendableに対応していないため、警告が出る可能性がある

SwiftGenを使用することで、リソースへのアクセスが型安全になり、開発効率が向上します。大規模なプロジェクトほどその恩恵は大きくなると思います。ぜひ、自身のプロジェクトに導入して、より安全で効率的なiOS開発を目指しましょう！
CocoaPods入門：iOSアプリ開発における依存関係管理ツール

## はじめに
CocoaPodsは、iOSアプリケーションの依存関係を管理するための人気のあるツールです。ライブラリやフレームワークを簡単にプロジェクトに追加でき、手動での設定を大幅に軽減します。本記事では、CocoaPodsの基本的な使い方とセットアップ方法について解説します。

## CocoaPodsとは
CocoaPodsは、iOSやmacOSアプリケーションに必要な外部ライブラリやフレームワークを簡単に管理するための依存関係管理ツールです。これを使用することで、ライブラリのバージョン管理や更新が容易になり、開発効率が向上します。
## CocoaPodsのインストール
CocoaPodsはRubyGemsを使用してインストールできます。以下の手順でインストールしてください。
ターミナルを開きます。
次のコマンドを実行してCocoaPodsをインストールします：
```bash
sudo gem install cocoapods
```
インストールが完了したら、次のコマンドでCocoaPodsが正しくインストールされたか確認します：
```bash
pod --version
```
## プロジェクトへのCocoaPodsの導入
Xcodeで新しいプロジェクトを作成するか、既存のプロジェクトを開きます。
プロジェクトフォルダに移動し、ターミナルで以下のコマンドを実行します：
```bash
cd /path/to/your/project
pod init
```
このコマンドにより、プロジェクト内にPodfileというファイルが生成されます。
Podfileの作成と編集
Podfileをテキストエディタで開きます。以下は基本的なPodfileの例です：
```ruby
platform :ios, '11.0'
use_frameworks!

target 'YourAppTarget' do
  pod 'Alamofire', '~> 5.4'
  pod 'SwiftyJSON', '~> 5.0'
end
```
platformはアプリケーションがサポートするiOSバージョンを指定します。
targetにはアプリケーションターゲット名を指定し、その中に必要なライブラリ（ポッド）を追加します。
編集が完了したら、ファイルを保存して閉じます。
ライブラリのインストール
ターミナルで以下のコマンドを実行し、Podfileに記述されたライブラリをインストールします：
```bash
pod install
```
インストールが完了したら、.xcworkspaceファイルが生成されます。このファイルを使用してXcodeでプロジェクトを開く必要があります。
```bash
open YourApp.xcworkspace
```
## CocoaPodsの更新とアンインストール
更新
既存のポッドを更新するには、次のコマンドを実行します：
```bash
pod update
```
アンインストール
特定のポッドをアンインストールするには、Podfileからそのポッドを削除し、次に以下のコマンドを実行します：
```bash
pod install
```
すべてのポッドをアンインストールしたい場合は、次のコマンドを実行します：
```bash
pod deintegrate
```
## おわりに
CocoaPodsは、iOSアプリ開発における依存関係管理を簡素化し、開発効率を向上させる強力なツールです。この記事では、その基本的な使い方とセットアップ方法について解説しました。これからはCocoaPodsを活用して、よりスムーズなアプリ開発を楽しんでください！
create-vite で生成される Vue + TypeScript プロジェクトを調査

## この記事の目的

## この記事の対象読者

## 前提

- node v22.11.0
- vite v6.0.1

## プロジェクトの自動生成

以下コマンドを実行｡

```zsh
npm create vite@6.0.1 {プロジェクト名} -- --template vue-ts
```

## 生成されたプロジェクトについて

### ディレクトリ構造

```
.
├── README.md // README.md
├── index.html // エントリーポイント
├── package.json
├── public
│   └── vite.svg
├── src
│   ├── App.vue // 自動生成されるコンポーネント
│   ├── assets
│   │   └── vue.svg
│   ├── components
│   │   └── HelloWorld.vue // 自動生成されるコンポーネント
│   ├── main.ts 
│   ├── style.css
│   └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

```

### Vue 周り

#### index.html

index.html の body 要素下には下記コードが実装されている｡

```html
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
```

script タグで main.ts を読み込んでいる｡

#### main.ts

main.ts では､下記コードが実装されており､ [アプリケーション API | Vue.js](https://ja.vuejs.org/api/application#app-mount) によると､ `createApp()` で作成されたアプリケーションインスタンスを index.html の id 属性値が `app` の div 要素にマウントしている｡
`createApp()` の第一引数は ルートコンポーネントを指定する｡
ここでいうと､ App.vue で定義されたコンポーネントのこと｡

```ts
createApp(App).mount('#app')
```

#### App.vue

下記のような実装で `HelloWorld` コンポーネントを `msg` の値に `Vite + Vue` を渡して呼び出している｡

```html
<HelloWorld msg="Vite + Vue" />
```

#### HelloWorld.vue

```vue
defineProps<{ msg: string }>()
```

で 親コンポーネント (App.vue) から `msg` の値を受け取り､

```vue
<h1>{{ msg }}</h1>
```

で表示している｡
`{{ 変数名 }}` はマスタッシュ構文と呼ばれるもので､ Vue ではこの構文を用いて引数の値を呼び出している｡

```vue
const count = ref(0)
```

このコードでは､ `ref()` 関数を用いて､初期値が 0 のリアクティブ変数 count を定義している｡
リアクティブ変数として定義されると､値の変更が監視され､値の変更が画面に反映される｡
下記コードでは､ ボタンをクリックすると count の値が 1 増え､このとき count がリアクティブ変数として定義されていることでクリックする度に count の値が画面上でも 1 増える｡

```vue
<button type="button" @click="count++">count is {{ count }}</button>
```

### その他

- `vite.config.ts`: Vite の設定が記載されている
- `tsconfig.json`､ `tsconfig.app.json`､ `tsconfig.node.json`: TypeScript の設定が記載されている

## 参考文献

- [Vue.js 公式ガイド](https://ja.vuejs.org/guide/introduction.html)
paizaラーニング問題集「いびつなひとりリバーシ（１ターン）」を解いてみた

▼問題

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_pincerattack_step6

▼考え方

この問題を解くために私が考えた内容1.～3.を以下に示します。

1. 題意よりプレイヤーは盤面の'!'のマスに石を置きます。そのマスの(y,x)を取得するための処理です。

2.～4.は以前私が解いたものと同じですので、以下にまとめてあります。

https://qiita.com/toytoy24/items/de6f92d7e0e6985b3fb0


▼コード
```py
############### 関数処理 ###############

# reversi_positions: 新しく石を置くことができる(y,x)を求める関数
def reversi_positions(dy, dx):

    # newpositions: 新しく石を置くことができる(y,x)を格納するリスト
    newpositions = []

    # tmp_y,tmp_x: 単位ベクトルを、Yから1つずつ拡大させるための変数
    tmp_y,tmp_x = Y+dy,X+dx

    # 考え方3.
    while (0 <= tmp_y <= H-1) and (0 <= tmp_x <= W-1) and (S[tmp_y][tmp_x] == "."):
        newpositions.append((tmp_y,tmp_x))
        tmp_y,tmp_x = tmp_y+dy,tmp_x+dx

    # 考え方4.
    return newpositions if (0 <= tmp_y <= H-1) and (0 <= tmp_x <= W-1) and (S[tmp_y][tmp_x] == "*") else []

# set_stones: 石を置き盤面を更新する関数
def set_stones():
    S[Y][X] = "*"
    
    # 考え方2.
    for dy, dx in (-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1):
        for y, x in reversi_positions(dy, dx):
            S[y][x] = "*"

############### メイン関数処理 ###############

H,W = map(int, input().split())
S = []

# 考え方1.
for j in range(H):
    
    tmp = list(input())
    if "!" in tmp:
        Y,X = j,tmp.index("!")

    S.append(tmp)

set_stones()

for s in S:
    print(*s, sep="")
```
Ubuntu Server 24.04でのプロキシー設定周りのメモ

## 要約

- サーバーセットアップ時のProxy Configurationは、どうやら`apt/apt.conf.d/90curtin-aptproxy`に書かれるだけっぽい。
- `add-apt-repository`コマンドは環境変数のhttp_proxyやhttps_proxyなどを使うらしいので、`~/.bashrc`もしくは`/etc/profile.d/proxy.sh`にて定義しよう。

## セットアップウィザード的な場面でのProxy Configuration

Proxy Configuration の画面で、「ホスト名(もしくはIPアドレス):ポート番号」としてプロキシーサーバー情報を入力します。
普通はみんな空欄にしておくのでしょうけれど、環境によってはプロキシーサーバーを越えないと外部のネットワークにつながらないので、入力することになるのですが、あの情報が実際にどう扱われているのか、説明がないのでよくわかりませんでした。

片っ端からファイルをviewで開いて確認してみたら、`apt/apt.conf.d/90curtin-aptproxy`というファイルに記述がありましたので、記入間違ったとか、環境が変わった時はこのファイルを確認してみてください。

## PHPのインストールで add-apt-repository がコケる

aptやapt-getはプロキシーを越えられるようになっても、`sudo add-apt-repository ppa:ondrej/php -y`が失敗します。

プロキシーサーバーを越えるのは全ユーザーに影響がある話なので、`/etc/profile.d/proxy.sh`というファイルを新規に作って、下記のような内容を記載します：

```sh
MY_PROXY_URL="http://prox.srv.world:3128"

HTTP_PROXY=$MY_PROXY_URL
HTTPS_PROXY=$MY_PROXY_URL
FTP_PROXY=$MY_PROXY_URL
http_proxy=$MY_PROXY_URL
https_proxy=$MY_PROXY_URL
ftp_proxy=$MY_PROXY_URL

export HTTP_PROXY HTTPS_PROXY FTP_PROXY http_proxy https_proxy ftp_proxy
```

そののち、現在接続中のシェルbashにおいてその環境変数を反映させるために `source /etc/profile.d/proxy.sh`を実行することで、環境変数にプロキシーの設定を載せることができます。
/etc/profile.d/ に作っておくことで、Ubuntu Server起動時に自動的に反映されるはずです。

引用：[Ubuntu 24\.04 : プロキシクライアントの設定 : Server World](https://www.server-world.info/query?os=Ubuntu_24.04&p=squid&f=2)

`printenv http_proxy` など実行して環境変数に書かれているのを確認してから、
`sudo -E add-apt-repository ppa:ondrej/php -y`を実行して、無事にリポジトリの追加が出来たのでした。`-E`オプションを付けて環境変数を引き継ぐのがポイントのようです。

PHPのインストール手順については、こちらを参考にしました：
[Ubuntu24\.04 phpをインストールする \| mebee](https://mebee.info/2024/06/25/post-93489/)
Clojureの基本構文 - 特殊フォームその３

![advent_calendar_2024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/f4cd8ce0-6352-a1d8-4cae-f39dd44f4def.png)

[*Advent Calendar 2024 Day 8*](https://qiita.com/advent-calendar/2024/clojure)

## 基本構文

3つの基本についてまとめています

1. リテラル
1. 関数の定義と呼び出し
1. 特殊フォーム

**3. 特殊フォーム** についてまとめています

今日は続きから書いていきます

### 2. 特殊フォーム

特殊フォーム（Special forms）は、Clojureコンパイラによって直接解釈されます

#### (fn name? [params* ] expr*)

`fn`はclojureで無名関数を定義する際に使うものです。
一時的に使う関数を簡単に定義したいときや、関数名を付ける必要がない場合に便利です。

特徴としては

- オーバーロード可能（複数のアリティに対応可能）
- 再帰（recurを用いた効率的な再帰処理）
- 可変長引数（& rest-param）

それぞれの例を書いてみます

**オーバーロード可能**

```clojure
(def overload-funciton
  (fn
    ([] "引数がない場合のデフォルト値")
    ([x] (str "引数が1つ: " x))
    ([x y] (str "引数が2つ: " x " と " y))))

(overload-funciton)                 ;; => "引数がない場合のデフォルト値"
(overload-funciton "Hello")         ;; => "引数が1つ: Hello"
(overload-funciton "Hello" "World") ;; => "引数が2つ: Hello と World"
```

ここでは引数の数によって別の動作をします

**再帰**

```clojure
(def factorial
  (fn [n]
    (letfn [(helper [acc n]
              (if (zero? n)
                acc
                (recur (* acc n) (dec n))))]
      (helper 1 n))))

(factorial 5) ;; => 120
```

`helper`という内部関数を定義し、内部で`recur`を使い、自己回帰を行っています


**可変長引数**

```clojure
(def sum
  (fn [& nums]
    (reduce + nums)))

(sum 1 2 3 4)   ;; => 10
(sum)           ;; => 0
(sum 10 20 30)  ;; => 60
```

`& nums`は任意の数の引数をリストとして受け取ります

これらを使いこなすことで柔軟に無名関数を使うことができます

#### (loop [binding*] expr*)

`let`に似て、バインディングを定義します。
しかし、`loop`は追加で再帰ポイントを設定します。

後述の`recur`を使ってこの再起ポイントに戻すことができます。

```clojure
(loop [n 5] ; 再帰ポイントを作成し、nに初期値5を設定
  (when (> n 0) ; nが0より大きい間ループ
    (println n) ; nを出力
    (recur (dec n)))) ; nを1減らして再帰ポイントに戻る

; 5
; 4
; 3
; 2
; 1
```

#### (recur expr*)

`recur`は現在の再起ポイントに戻ってそのバインディングを更新し、ループを続行します

注意点
- 引数を同じにする必要がある
- 末尾の位置で使用

```clojure
(loop [n 5] ; 再帰ポイントを作成し、nに初期値5を設定
  (when (> n 0) ; nが0より大きい間ループ
    (println n) ; nを出力
    (recur (dec n)))) ; nを1減らして再帰ポイントに戻る

; 5
; 4
; 3
; 2
; 1
```

通常の再帰関数ではスタックを消費しますが、
`recur`はループとして実行されるので、スタックオーバーフローを防ぐことができます

#### (try expr* catch-clause* finally-clause?)

```clojure
(try
  expr*            ; メインの式
  catch-clause*    ; 例外をキャッチするための処理
  finally-clause?) ; 最後に必ず実行される処理（オプション）
```

*catch-clause → (catch classname name expr)*
*finally-clause → (finally expr)*

- expr*
    - 評価される式
- catch-clause
    - 例外を処理するための部分
    - `classname`
        - キャッチする例外のクラス名
    - `name`
        - キャッチした例外がバインドされる変数名
    - `expr`
        - キャッチした例外を処理するための式
- finally-clause
    - オプションで指定できる
    - `try`ブロックを抜ける時に必ず実行される式



```clojure
(try
  (throw (Exception. "Exception occurred"))
  (catch Exception e
    (println "Exception caught"))
  (finally
    (println "This will always run")))

; Exception caught
; This will always run
```

https://clojure.org/reference/special_forms
Amazonから「SP-API Developer Profile Update」ってきた

# 届いたメール
> Hello,
> We have completed our assessment and have determined that you are not eligible for SP-API access at this time.


こんにちは、

評価を完了し、現時点では SP-API アクセスの資格がないことが判明しました。


# 結論
パブリックだからだめなのか？
プライベートならいけるのか？

…等調査と対応が必要。
ここからの巻き返しを頑張ります。
paizaラーニング問題集「リバーシの操作」の自分のコードを改善してみた

▼問題

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_pincerattack_step5

▼改善前の問題点とコード

8方向の処理がほぼ同じであるにも関わらず、すべて別で書いていた。コードの行数が増え、DRY (Don't Repeat Yourself) 原則に反していた。8方向とは、上下左右と、右上,右下,左上,左下の4方向です。

https://qiita.com/toytoy24/items/abddba4a89f75f654b52

▼改善後の考え方とコード、改善の成果

▽改善後の考え方

新しく考えた内容1.2.を以下に示します。

1. ほぼ同じ処理はまとめて書きます。8方向の単位ベクトルを1つずつ関数reversi_positionsに渡し、帰り値として、石を置くことができる(y,x)を受け取ります。

2. 単位ベクトルを、盤面内かつ石を置くことができる間、拡大させていきます。条件に合致する盤面内の(y,x)は、仮でリストnewpositionsに保存します。

3. 実際に盤面に石を置くことができる条件に合致した場合は、newpositionsを返します。合致しなかった場合は（石を置けないので）空を返します。条件とは、盤面内かつ、すでに置かれている石が存在することです。(Y,X)の石とすでに置かれている石で挟む必要があるからです。

▽改善の成果

・改善前がコードの行数が97だったのに対し、改善後は19にすることができました。

▽改善後のコード

```py
############### 関数処理 ###############

# reversi_positions: 新しく石を置くことができる(y,x)を求める関数
def reversi_positions(dy, dx):

    # newpositions: 新しく石を置くことができる(y,x)を格納するリスト
    newpositions = []

    # tmp_y,tmp_x: 単位ベクトルを、Yから1つずつ拡大させるための変数
    tmp_y,tmp_x = Y+dy,X+dx

    # 考え方2.
    while (0 <= tmp_y <= H-1) and (0 <= tmp_x <= W-1) and (S[tmp_y][tmp_x] == "."):
        newpositions.append((tmp_y,tmp_x))
        tmp_y,tmp_x = tmp_y+dy,tmp_x+dx

    # 考え方3.
    return newpositions if (0 <= tmp_y <= H-1) and (0 <= tmp_x <= W-1) and (S[tmp_y][tmp_x] == "*") else []

# set_stones: 石を置き盤面を更新する関数
def set_stones():
    S[Y][X] = "*"

    # 考え方1.
    for dy, dx in (-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1):
        for y, x in reversi_positions(dy, dx):
            S[y][x] = "*"

############### メイン関数処理 ###############

H,W,Y,X = map(int, input().split())
S = [list(input()) for _ in range(H)]

set_stones()

for s in S:
    print(*s, sep="")
```
Livewire:Javascriptでinput要素の値を設定してもNULLが渡されてしまう対策

## 概要
Javascriptでinput要素に値を設定する画面で、バリデーションエラー（必須項目なのに値未設定）が出るので調べてみました。(Livewire3.0使用)
## 対応策
値を設定した後でinputイベントをdispatchする必要がありそう。

## 経緯
・画面
`<input id="name" type="text">`

・Javascript
`document.getElementById('name').value = 'abc'
console.log(document.getElementById('name').value);`

・バリデーションルール
'name' => 'required'

・サーバー側での確認
`logger()->debug('$this:' . json_encode($this));`

といった設定で、console.logで値が設定されているけど、サーバー側に渡された要素を確認すると、name項目はNULLだった。

・調査
Javascriptで値設定せずに、画面上でname項目に値を手入力してsubmitするとバリデーションエラーは出ない。

・対応策
`document.getElementById('name').value = 'abc'
`document.getElementById('name').dispatchEvent(new Event('input'));`

これで、Javascriptで設定した値がサーバーに渡されました。
目的にたどり着くまでを可視化

# はじめに
株式会社うるるの田中です。
昨年のアドベントカレンダー以降、書こう書こうと思っていたのですが、書けないまま1年が経ってしまいました。

昨年は、組織的なことばかりをやっていたので、プログラミングから少し離れていました。
今年に入って、妻が新たな挑戦を始めたことをきっかけに、プライベートの状況が動き出しました。
その過程で、自身で作りたかったサービスをちょっとずつではありますがプログラミングしたり、妻のやりたいことのwebやIT的な部分ふくめて支援を行うようになりました。

いつも目的にたどりいつくまでの道筋を自分の中でどうやって考えているかみなさんに共有できればと思いました。

# 言語化はできないけど。。。
自慢ではないですが、ぼくは自分の頭の中を言語化するのがすごく不得意です。
また、何かしらの言語化フレームワークを使うことも不得意です。
なので、いつも心がけているのは図解化することです。
頭の中に存在視するものを図と見立てて、組み合わせていくことを考えるようにしています。
いわばパズルですね！

# 目的に向かうには道が必要
とはいえ、自分自身のボキャブラリもすくないので、色んな人の表現をかりながら明確にしていることが多いです。
今回は「売上の地図」(著者：池田 紀行)で使用されていた表現を参考にしてます。

:::note warn
あくまでも表現を借りているだけで「売上の地図」で説いている内容と違うものになっているので興味がある人はそちらを読んでみて下さい。
:::

物事の始まりを出発地点とした時に、目的地までの道のりを思い浮かべて下さい。
それは下記の図のように真っ直ぐ進めるものでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630048/2fbe1dfd-69df-1f16-e79e-ff8d5d52f2db.png)

そうではないと思います。
実際は、目的地につくまでの間には何かが待ち受けているはずです。
しかしそれらはわかりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630048/4e4a6588-76e4-49d6-fd70-53fb001c5f73.png)

こんな感じですね。
ここに向けて道筋を立てていくわけです。
もちろんその中で判断しないといけないものも出てくるかと思います。
図に表すとこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3630048/a3c8e4ff-18e6-258f-3157-3d089b088b34.png)

# 過程を整理していくことの大事さ
道を考えた時に、真っ直ぐではなくいろんな分岐が存在しているかもしれないということわかったあとに何をしなければならないのかというと、これらの可能性を可視化することをするということをやっていかなければななりません。
可視化をおこなうことで自分たちが目的地としている場所に向かって行けていることを確認するとともに、分岐が迫った時に判断を行うための準備をができるようになります。

この部分は、我々ITエンジニアに通ずる部分でもあり、我々はこの可視化の作業のことを「__要件定義__」や「__仕様設計__」と呼んでいるはずです。
また、通常の仕事においても段取りと言うものになると思います。

ぼくの妻が望んでいることとしては固定店舗型のお店を開くことです。
下記のようなことが必要になってきます。

* __店舗の確保__
    * 賃貸物件を探す
    * 契約交渉を行う
    * 内装工事を行う
* __営業許可に必要な条項__
    * 食品衛生責任者資格を取得する
    * 消防法に基づく設備を整備する
    * 営業許可申請を行う
* __資金確保__
    * 自己資金
    * 融資
    * 助成金
* __マーケティング環境準備__
    * Webサイトを開設する
    * SNSアカウントを開設する
    * チラシを作成する
etc...

箇条書きで書いていくとよくわからないのですが、これらは関連しており、先程の図に当てはめ全体感をイメージしながら進めています。
このイメージを持てていなかったらどうなっているかというと

* __そもそものやらなければならないことがわからない__
* __順を意識していないため後々無駄になるようなことをやってしまう__
* __それぞれは進んでいるが全体感としては全然進んでおらず目的地までが遠い__

# 最後に
「お店を開く」という目的としては明確になっていたのですが、そこにしか目が言っていない時期がありました。
その時は、最終的に必要である「店」という「箱」のことしか考えられていませんでした。

目的にたどり着くためには、全体像を把握し道筋を明確にする必要があります。
明確にしないままたどり着くこともできるかもしれませんが、たどり着くまでに多く時間を必要とすることの方が多いと思います。
整理し可視化をすることで効率的に道筋をたどり目的を達成することができます。

これは、ITエンジニアの日々の業務に通ずるものだと考えております。
みなさんはどうでしょうか？
目的は持たれているとおもいますが、その道筋まで考えることができていますか？

もし、できていないようであれば目的までの道筋を整理して可視化して見て下さい。
紙とペンで簡単な図解を描いてみるだけでも良いですし、ExcelやGoogleスプレッドシートなどのツールを活用するのも良いでしょう。
ご自身の目的に合ったツールを見つけて活用するが良いと思います。
きっと仕事やプライベートの目的の達成に役立つと思います。

次回は @n_matsunaga さんの投稿になります。
セキュリティに関する個人メモ

# MIMEタイプ
受け取ったデータの種類をブラウザが判断するための情報

# text/html
MIMEタイプの一種。受け取ったデータをHTMLと認識する。
受け取ったデータの中のscript要素（&lt;script>alert(1)&lt;/script>）を実行したい場合、text/htmlにする必要がある。

# XMLHttpRequest 
JavaScriptでHTTPリクエストを行うためのブラウザ標準のネイティブAPI。略語はXHR。XHRはAjax技術の基礎としてよく利用されている。

JSONデータの処理にも対応している。

XHRは現在非推奨で、HTTPリクエストの際にはFetchやaxiosを利用すべき。

### XHRが非推奨の理由
- コールバック関数がめっちゃネストする
- Promiseやasync/awaitに対応していない。
- 大きなデータでも一度に全てのデータをメモリに読み込まなくてはならない
- 符号化や圧縮されたレスポンスに対応できない

# Content-Typeヘッダー
HTTPリクエスト/HTTPレスポンスのどちらのヘッダーにも記載ができ、**ボディ部の形式**を通信先に伝えるためのもの。例えば、HTTPリクエストヘッダー`Content-Type: application/x-www-form-urlencoded;`を記述した場合、リクエストボディはURLエンコードされたフォームデータであることを意味する。
サーバーからのレスポンスのデータ形式を制限したりすることはできない。


# Acceptリクエストヘッダー
サーバーが返すデータの形式を指定するためのヘッダー。
`Accept: application/json`など。

サーバー側がクライアントのAcceptヘッダーを無視する場合もある。その場合、デフォルトの形式（例えばHTMLやJSON）でレスポンスが返される。

# WEB API
ブラウザが標準として提供している機能。setTimeoutなど

# REST API
API開発の際のアーキテクチャ（設計ルール）。プロトコルではない。
API開発アーキテクチャはGraphQLなどがある。
24/12/04 読書記録 ~ソフトウェアテストの教科書~

# 書籍
[【この1冊でよくわかる】 ソフトウェアテストの教科書](https://amzn.asia/d/6jSYRVM)

# 書籍を読む目的

 - [ ] 「品質」を理解する
 - [ ] 品質を担保できるテストを理解する

# Part3. テストドキュメントとモニタリング

## Chap09. テストドキュメントの作成

### 学び 📝

#### なぜテストドキュメントを作成するのか？

品質劣化を防ぐため。
テストが一定期間、複数チームによって進められ、担当者に変更があった場合、テストドキュメントがないとテストの目的や内容を担当者間で正確に伝達できない。

### Chap9 感想 :writing_hand_tone5:

自分が所属している組織は、スプレッドシートで管理を行っているが、目的、手順が曖昧になっていると感じる。かといって、本著に書かれている同じことはできている気がする。
こちらの章ではテストケースの具体例が記載されているので、また参考にすることはありそうだと感じた。
ムードボードをやってみたい

# はじめに

エンジニアの知人と雑談をしていたときにサイトを作る前に「ムードボードやってみたいね！」という話になったので、チャレンジしてみる。
デザインはやったことがなく初心者なので、間違っているところがあるかもしれない🔰

# ムードボードとは

>ムードボード（英：Mood Board）とはデザインラフの一種で、デザインのイメージやコンセプトを紙面やスクリーン上にまとめてコラージュし、分かりやすく視覚的に共有するための手法です。
引用元：https://blog.nijibox.jp/article/moodboard/

あくまで"視覚的な"デザインを整理するためにやるものだそう。分かりやすく整理したうえで、デザインの方向性の一貫性を保つために使われるのだろうと解釈した。
大変そうだけど、すごく楽しそう！

全体的な手順はChatGPTに聞いてみた。


## ムードボードのやり方

```ChatGPT
1. テーマを決める
　どのようなプロジェクトやアイデアのためにボードを作るのか、明確にします。
　テーマが決まると、集める素材やイメージが定まりやすくなります。

2. インスピレーションを集める
　雑誌、ウェブサイト（PinterestやUnsplashなど）、写真、色見本、テクスチャ、フォントなどから
　インスピレーションを集めます。目的やテーマに関連するビジュアルを集めるのがポイントです。

3. 素材を整理する
　集めた素材を見ながら、テーマとの関連性を考えながら選別します。
　これには無関係なものや、重複したものを排除するプロセスが含まれます。

4. レイアウトを考える
　ボードのレイアウトを思い描きます。
　どの素材をどの位置に配置するか、色のバランスを考えながら配置を決定します。
　デジタルで作成する場合は、ソフトウェア（CanvaやAdobe Illustratorなど）を使うと便利です。

5. ボードを作成する
　実際にボードを作成します。
　物理的なボードを使用する場合は、紙やボードに素材を貼り付けます。
　デジタルボードの場合は、選んだソフトウェアでレイアウトします。

6. フィードバックを得る
　完成したら、他の人に見てもらい、意見を聞くことでさらなる改善点を見つけることができます。

7. 完成
　最後に、必要に応じて調整を加え、ムードボードを完成させます。
```

この手順に沿って実際にやってみる

## テーマを決める
え、テーマって何だろう？いきなり難しいな・・・( ^)o(^ )

調べてみたところ、ムードボードを進めていくうえで
まずは
- デザインテーマ
- デザインコンセプト

の２つを決める必要があるとのこと。

デザインテーマは、主題のことで基本的に1つ設定する。
デザインコンセプトは、テーマに紐づく複数の要素を設定する。テーマを修飾するものという表現が非常にわかりやすかった。

今回は自分用のブログを構築したいので、テーマを「ブログ」とする。

### デザインコンセプト
メインテーマを決めたので、次はコンセプトを整理していく。

どうやらコンセプトの整理方法は、他社と比較して自社のプロダクトを整理するためのポジショニングマップやスライダー、マトリクス図など様々な手法があるらしい。

ふむふむ。
そしたらまずは比較したり図に表したりするために、どんなサイトにしたいか全体的なイメージを列挙する必要がありそう。

#### まずはサイトのイメージを列挙する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667288/42783d7a-bda7-3745-bdae-c54c1ebc9212.png)


とりあえず、こういうサイトがいいなというコンセプトを10個挙げてみた。ちょっと少ないかもだけど、初めてなので一旦これで良しとする。
このままだと抽象的すぎるので、具体的に言語化したほうがよさそう。

🤔🤔🤔

とりあえず1つ目に列挙した「洗練されている」の具体を考えてみた。
まだ手探り状態だけど、なんかサイトのイメージがわかりやすくなってきた気がする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667288/dc84e971-9d1e-42fc-46f2-5f368f95043c.png)


他のコンセプトも同じようにより具体的に言語化できるよう考えてみる。
（今更気づいたけど、Figmaのスティッキーを使うよりもマインドマップ使ったほうがやりやすかったかも。）

## まとめ
今回はデザインのテーマとコンセプトを複数列挙してみた。おそらく、デザインテーマとコンセプトは細かく議論して決めることがとても重要なんだろうなと思う。

こうして大体のテーマとコンセプトが定まったので、次は実際に参考となる資料を集めていきたいと思う。
この続きは明日のアドベントカレンダーの記事で公開しようと思う。

## 参考サイト
https://nobu-n.co.jp/column/design-concept-is-different-from-theme/

https://shirokuma-design.jp/difference-between-theme-and-concept/

https://sevendex.com/post/3830/
origin/mainを意識してgit fetch, git pullの違いを理解する

# はじめに
こんにちは、watnowの竹内です。GitHubユーザーの方なら必ず使ったことがあるといっていいほどよく使われる`git fetch`, `git pull`コマンドですが、結構なんとなく使ってませんか？GitHub初心者の私はGitHubを使う度にこのコマンドを呪文のように唱えていますが、何やってるのかわからないまま呪文唱えるのって結構いやですよね…。そこで今回、この呪文で何をやっているのか初心者なりにまとめてみました。

# 基本的なコマンド



# origin, origin/mainの違いってなに
`git fetch`, `git pull`の本格的な説明の前に必要な知識を学びます。

`git fetch`を使ったことのある人は見たことありますよね？
`git fetch origin`とか`git pull origin/develop`とかって使われ方をしている`origin`のことです。なんかどっちもブランチっぽい名前しとるけど俺作った記憶ねーよ！って毎回思ってました。
簡潔にいうと


`origin` -> リモートリポジトリ
`origin/main` -> `origin`(リモートブランチ)の`main`を追跡するブランチ

のことを指します。
少しわかりにくいかもですが図で表すとこんな感じです

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886829/ab2e9237-8719-66b1-6abf-511569b70635.jpeg">

リモートブランチを追跡するブランチとはどういうことでしょうか？

## リモート追跡ブランチ
図をみてもらうとわかりますが、リモート追跡ブランチはローカルリポジトリ内に存在するブランチの一種です。私たちは普段自分でやった作業を記録していくローカルブランチとみんなでやったことを統合していくリモートブランチを同期させていくことでチーム開発を可能にしています。この同期作業をなんかいい感じに手伝ってくれてるのがリモート追跡ブランチです。
この追跡ブランチが存在しなかった場合、リモートブランチの最新の状態の把握や差分の把握がかなりめんどくさくなります。

# `git fetch`と`git pull`
ここまでやってしまえば`git fetch`と`git pull`の説明は簡単です。
2つともローカルに情報をもってくるコマンドだということは皆さん知っていると思いますが、この2つのコマンドの違いはなんでしょうか？

答えは「ローカルのどこまで情報を持ってきているのか」です。
図を見ればわかる通り`git fetch`はリモート追跡ブランチに情報をもってきているのに対して`git pull`はローカルブランチまで情報をもってきます。

# チーム開発でよくあるケースを考える
## 他のメンバーのPRを手元で確認したいとき
1. 確認したいブランチがローカルにないとき
![7D8247F7-1DB2-49BD-A18E-9FF8E7373FC2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886829/cf0ce8bb-387b-a7e7-bc7e-59a5935960a6.jpeg)


    `git fetch`コマンドをつかう
    ```diff_git
    git fetch origin 
    git checkout origin/b
    ```
    `git fetch origin `でリモートの情報をリモート追跡ブランチにもってきます
    その後`git checkout origin/b`を実行することでリモート追跡ブランチにもってきた最新の情報をみることができます
    
    
    
1. 確認したいブランチがローカルにあるとき
![85B2243D-B8EA-4D33-A823-286E68BAD598.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3886829/e3fedb53-da38-599f-afbe-91eafb923b3b.jpeg)
    `git pull`コマンドをつかう
    ```
    git checkout b
    git pull origin b
    ```
    
## リモートにあるブランチで作業したいとき
    
    git fetch origin
    git checkout b
    

(補足)
    `checkout`を普段使っている人が、ここまでの解説を読むとこのコマンドでリモートにあるブランチをローカルにもってきて作業できることに違和感があるかもしれません。これまでの解説通りであればbブランチはまだローカルに存在していないためcheckoutできないのではないかという疑問がうまれます。`fetch`を実行した段階では新しいブランチの情報はリモート追跡ブランチまでしか反映されていません。
ただし`checkout`を実行した段階でgit が以下の操作を行ってくれます。
1. bブランチがローカルに存在しないことを察知し、ローカルにbブランチを生成
1. `b`と`origin/b`を紐付け
1. ローカルのbブランチに移動
このようにしてローカルのbブランチで作業することができます！

# さいごに
長い記事をここまで読んでくださりありがとうございました！
今回よく使われる`git fetch` `git pull`を少しだけ深掘りしましたが、「とりあえず`pull`しとこ」みたいな考えから少し抜け出せたような気がします。
関数型PG言語の話・Elmのさわりをご紹介


## 関数型PG言語とは
- オブジェクト指向言語のアンチテーゼとして生まれた・・・わけではない
- 歴史は古い
- 学術的な匂いがするのはHaskellのイメージが強いからだと思う

----
## Elmとは(1/2)
- いわゆる「フロントエンドフレームワーク」
- ブラウザで動作するUIの作成**しかできない**DSL
- 機能が極小

----
## Elmとは(2/2)
- 型及び参照透過性に厳格なツンデレ関数型PG言語
  **曖昧さを許さない**ので堅牢なプログラムが書ける
- Haskellに書き味が似ている

----
## Elmの特徴
- コンパイルすることでJavaScriptになる
- 厳格な型表現とパターンマッチ
　非常に重要な機能！
- 全てが関数なので共通化や処理分割が容易
  覚えなければならないことは案外少ない

----
## TEA（The Elm Architecture）(1/2)
- Model/view/updateの３本柱
- Model：画面を描画するのに必要な全てのデータ
  ただ１つの大きなデータになる
- view：ModelからHTMLを生成する関数
- update：ブラウザからのイベントを受けてModelを更新する関数


----
## TEA（The Elm Architecture）(2/2)
- たったこれだけ！本当にこれだけ
- 初期のReactに似ている
- Virtual DOMを使って描画（昨今はアンチVirtual DOMの風潮ある）
- ElmでできないことはJavaScriptで書いてElmと連携させる

---
## Elmの強みと弱み
- 強み：シンプルで覚えやすく、書き方に迷わない
- 強み：複雑なロジックを誤りなく書ける言語仕様
- 弱み：BlazorやVue、Reactのように豊富なUIコンポーネント群がない
- 弱み：情報が少なめ

--
## 最後に
- 関数型PG言語でWebアプリを書けるし、有用
- コンポーネント指向なフロントエンドフレームワークが主流な中、全く思想の異なるものに触れるのは面白いと思います！
キャリアブレイク中にやっている勉強② コンピューターサイエンス

今日もキャリアブレイク中に具体的にやっている勉強について書きます。その②は「コンピューターサイエンス(以下CS)」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100916/e3067d66-e0bf-93b8-aa8f-00c0269abda8.png)

# コンピューターサイエンス
自分は低レイヤーの知識はどちらかと言えば避けている方でした。ただ最近は考えが変わってきて、実際触れてみると低レイヤーを知ることが面白くなってきました。特にCSは、プログラマとしても抑えている方が絶対強いという話も聞くし、休みがあったらやってみたいと最初に思ったのがCSの勉強でした。

# CS50
[CS50:Introduction to Computer Science](https://pll.harvard.edu/course/cs50-introduction-computer-science)はハーバード大学が公開しているオンライン公開講座です。なんと無料で公開されていて、誰でも受講でき、かつ日本語字幕が付いています。しかも自動翻訳ではなくて有志が付けてくれているので、映画の字幕レベルで全くひっかかることなく視聴出来ます。素晴らしいー

# CS50の使い方
自分のやっている読書方法を始めてから[集中力が上がった](https://note.com/binnmti/n/n3e15323052ab)ので、記憶に定着しやすいかなと思い、メモを取りながら見ることにしました。この動画は資格も取れる（[esX](https://www.edx.org/learn/computer-science/harvard-university-cs50-s-introduction-to-computer-science)で登録して、$219を出して、問題の提出も必要）みたいですが、自分は価値を感じなかったのでやりませんでした。問題も1回だけ提出しましたが、簡単だったのでそれ以降はしてないです。

# Discordメモ
今回はキャリアブレイク用に作った自分専用Discordにメモしながら聞きました。Discordを選んだ理由は何となくが一番大きいですが、マークダウン表記が使えるし、後からでも編集できるし、チャンネルで分けられるので情報が混じらないし、結果的には最適だったと思っています。[興味がある人が居ればのぞいてもらえる](https://discord.gg/7MhrBqvF)のも良かったです。

# 実際のやり方
動画を見る。良い内容や気になることがあったら、一時停止して、メモる。コードに関しては実際にCS50が提供してくれる[Codespace](https://cs50.dev/)を使って写経です。結構頻繁に一時停止するので30分見るのに大体1時間、つまり2倍の時間をかけて見ています。無駄に時間をかけているかと思われるかもしれませんが、自分にはこのスタイルがとても合っているように感じます。

# ペース
ペースとしては基本は1日最大1時間にしています。色々あって30分ぐらいの時もあるので、11月では「[Week0 Scratch](https://cs50.jp/x/2021/week1/) 、[Week1 C](https://cs50.jp/x/2022/week1/)、[Week2 Arrays](https://cs50.jp/x/2021/week2/)」を見て、もうすぐWeek2が終わる所です。大体1week2時間なので、単純計算で12時間ぐらいかけて見ています。仕事なら大体20日稼働なので、少な目に感じるかもですが、それほど悪くないペースかなと思います。

# 2021と2022の違い
CS50jpは2021と2022があります（esXにはもっと最新もありますが、日本語はありません）。教えている年によって若干の違いはありますが内容はほぼ同じです。Week 0は気づかずに2021を見て、新しい方が良いかと思いWeek 1を2022で見たのですが、2022は生徒の質問が聞こえないというマイナスポイントがありました。そこでWeek 2で2021に戻しました。内容を補足するLabやProblem Setなども2021にしかないので、ずっと2021を見る方が良い気がします。

# 見ての感想
ハーバードの教授が教えるのできっとハイレベルな前提が必要と思っていたのですが、ものすごく丁寧に一歩一歩進んで行きます。決して簡単な話だけでもないですが、この進め方なら正直小学生の息子であっても見せたら分かるかもと思えるぐらいでした。CSを勉強したいと思っている人は誰でも絶対に見た方が良いと思います。プログラムの話も結構出てきますが、あくまでプログラムではなくCSを教えるのがこの講義です。

# まとめ
というわけで、キャリアブレイク中の勉強の1つとして毎日1時間CS50を学んでいますが、これは本当にめちゃくちゃ良いものを選んだと思っています。今後の自分の仕事に直接役に立つかは分かりませんが、プログラマとして血肉になっているのは強く感じます。
cscの作法 その540

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
FlatStyleを使え。


# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.Globalization;

class form1: Form {
	form1() {
		Text = "test";
		ClientSize = new Size(200, 300);
		Button btn1 = new Button();
		btn1.FlatStyle = FlatStyle.Flat;
		btn1.Location = new Point(30, 30);
		btn1.Text = "flat";
		btn1.Click += btn1_Click;
		Button btn2 = new Button();
		btn2.FlatStyle = FlatStyle.Popup;
		btn2.Location = new Point(30, 80);
		btn2.Text = "popup";
		btn2.Click += btn2_Click;
		Button btn3 = new Button();
		btn3.FlatStyle = FlatStyle.Standard;
		btn3.Location = new Point(30, 130);
		btn3.Text = "standard";
		btn3.Click += btn3_Click;
		Button btn4 = new Button();
		btn4.FlatStyle = FlatStyle.System;
		btn4.Location = new Point(30, 180);
		btn4.Text = "system";
		btn4.Click += btn4_Click;
		Controls.AddRange(new Control[] {
			btn1,
			btn2,
			btn3,
			btn4
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		MessageBox.Show("ok");
	}
	void btn2_Click(object sender, System.EventArgs e) {
		MessageBox.Show("ok");
	}
	void btn3_Click(object sender, System.EventArgs e) {
		MessageBox.Show("ok");
	}
	void btn4_Click(object sender, System.EventArgs e) {
		MessageBox.Show("ok");
	}
	[STAThread]
	public static void Main() {
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(false);
		Application.Run(new form1());
	}
}





```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6b3f138e-2da3-addd-87ce-26e5d30e270c.png)


以上
cscの作法 その539

# 概要
cscの作法、調べてみた。
素晴らしいアプリ見つけたので、やってみた。

# 参考にしたページ

https://qiita.com/kob58im/items/7129810d3237e65b424d

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/94e3cbb2-a607-e47e-ced4-d172ea28679d.png)


以上
2024年地域コミュニティ活動の振り返りと2025年に向けて

# 最初に
この記事はPower BI Advent Calender 2024の21日目の記事です。

https://qiita.com/advent-calendar/2024/powerbi


　佐賀県の小売業（和服業）で情シスをしています。

  2024年に活動した地域コミュニティ活動の報告と2025年に向けてを記事にします。

# 地域コミュニティ紹介
　佐賀県ローコードツール勉強会を運営しています。
 主に佐賀市近郊で活動を行っており、オンライン又はオフラインでの勉強会を実施しています。
 Power BI以外にも、Power AppsやPower Automateの勉強会も行っており、地域のITスキル向上・普及のため活動しています。

 
https://saga-hagakure.connpass.com/

 
## 2024年の地域コミュニティ活動

　
 ### 他の地域コミュニティ（JAWS-UG佐賀）参加と登壇
 県内でコミュニティ活動されているJAWS-UG佐賀に参加し、AWSのハンズオン体験と登壇を行ってます。
  
 

https://jawsug-saga.connpass.com/event/316251/

#### 登壇内容
　AWSの勉強会であることとMicrosoft Fabricの試用版がまだ使用可能だったので、Microsoft FabricにてAmazon S3に入っているファイル(CSV)を取り込み、加工・変換をSparkで行いPower BIにて可視化・分析をしてみたという内容を発表してます。
 　

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277732/7d093fda-de57-ddf0-10ca-57f93f920209.png)


Amazon S3への接続法はLearnを見ながら、AWSの経験がないのでIAMの設定部分で多少戸惑いました。

https://learn.microsoft.com/ja-jp/fabric/data-factory/connector-amazon-s3


　
CSVファイルの加工・変換についてはNotebookを使用しています。

https://learn.microsoft.com/ja-jp/fabric/data-engineering/how-to-use-notebook


#### 作成レポート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277732/4d446c8e-6432-17fb-8431-f3991427b54b.png)

  

　

 ### SAGA INNOVATORS TALK LIVEへ参加
  **愛**をテーマに、佐賀県で様々なことに挑戦しているイノベーターが登壇やディスカッションを行うイベントになります。
  
  その中の県内にてコミュニティ活動している人同士が座談会をする**SAGA Smart Community TV**に参加し、佐賀ローコードツール勉強会の紹介とPower Platform愛と郷土愛について強く語りました。
　 

 https://saga-innovators-talk-live.jp/
 
　
  
#### 作成レポート
コミュニティ紹介時にレポートを紹介、佐賀市のオープンデータの一つであるAIカメラによる人流データを使ってのレポート作成を行ったものをWebに公開して、コミュニティへの勧誘活動を行ってます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277732/5448bda4-fd5d-3402-4917-324a28d0fe03.png)

  
参照（佐賀市オープンデータ　人流センサーデータより）

https://odcs.bodik.jp/412015/












## 2025年に向けて
 #### Japan Power Platform Community Caravan

 新年早々、1月26日（日）にMicrosoft Base 佐賀にて「Japan Power Platform Community Caravan in 佐賀」を行います。

 興味がある方はぜひ参加をお願いします。 



 https://jppcc.connpass.com/event/339634/
 





 ### SAGA IT Community Day 2025 Winter
　
 2025年2月23日（日）に佐賀県内のコミュニティ同士が集まって、コミュニティイベントを行います。
   
 子供が遊べるスペースや遊具を用意しており、ファミリー枠も用意しているので興味がある方は参加をお願いします。

 https://sitcd.connpass.com/event/333840/

 私の担当は生成AIについてのセッションなのですが、Power BIのCopilotを動かす資金力がないため、Power AppsとPower AutomateのCopilotを使ったセッションになる予定です。

 https://sitcd.vercel.app/timetable
 
 

# まとめ
2024年は地域コミュニティ活動を行ったり県のリスキルプログラムに参加することで、県内で活動しているコミュニティとの繋がりをもてたり、県内企業同士の繋がり、オンラインでの繋がりも大事だが、地域コミュニティや地域企業との繋がりも大事だと改めて思いました。
WinGet が登場したのに、なぜ Scoop を使い続けているのか

最近、Windows のパッケージマネージャーとして WinGet を使うのが主流になってきている気がします。ただ、私の場合は WinGet と Scoop の両方を使い分けておりまして（本当はどっちかに絞りたいけど）。

そこで、なんでこんな使い方をしているのか、この機会に整理してみることにしました。

# 使い分けの基準

以下の条件にヒットしたアプリは WinGet で、それ以外は Scoop みたいに振り分けてます。

**条件**
　アプリ自体に自動更新機能がある → WinGet
**理由**
　自動更新後の資材が Scoop 以外のディレクトリに保存されるため
**例**
　 Chrome、Visual Studio Code、Postman、など。

以前までは、上記のアプリは Chocolatey でインストールしていましたが、WinGet が登場すると、ただ Microsoft 公式だからという理由でそちらに移行しました。

# WinGet ではなく、Scoop を使っている理由

あくまで個人の好みの問題ですが、Scoop を気に入っているポイントとしては以下の３つがあります。

## 1. 環境変数の PATH が荒れない

これは長年同じ PC でいろんな開発作業を行うと直面する課題と思っているのですが、 winget とかでいろんなツールをインストールすると、 PATH に登録されるパスが増えます。

そうなると、どのパスの実行ファイルが効いているのか判断がすぐできず、謎に古いバージョンを使っていたり、いちいち優先的に検索させたいパスを最初の方に持ってきたりする必要が出てきます。

ただ、これって winget のせいではなくて、 Windows で開発する上でしょうがなく我慢しなくてはいけないポイントです。
Linux では、`/usr/bin` 配下にインストールしたバイナリへのシンボリックリンクを貼るようにすれば、いちいち PATH を更新しなくてもいいんですよね。
特に update-alternatives とか使うと便利でして。

ただ、 Scoop では `~\scoop\shims` ディレクトリ配下を `/usr/bin` 的な使い方にしているので、 PATH が荒れないようにしてくれてます。これが地味なんですが、意外と開発者体験を上げてくれるんですよね。

## 2. バージョンが簡単に切り替えられる

例えば、Java の JDK 17 と JDK 21 の両方をインストールしている環境の場合、以下のようにコンソールの再起動なしで簡単に切り替えられます。

```powershell
# JDK17 と JDK 21 をインストール
scoop install java/temurin17-jdk java/temurin21-jdk

# 最後にインストールした temurin21-jdk に対して JAVA_HOME と PATH が設定されている
$env:JAVA_HOME; java -version
#=> C:\Users\nimzo6689\scoop\apps\temurin21-jdk\current
#=> openjdk version "21.0.5" 2024-10-15 LTS
#=> ...

# JDK 17 に切り替え
scoop reset temurin17-jdk

# JDK 17
$env:JAVA_HOME; java -version
#=> C:\Users\nimzo6689\scoop\apps\temurin17-jdk\current
#=> openjdk version "17.0.13" 2024-10-15 LTS
#=> ...
```

Java で書いてますが、 Node.js や PHP、 Go 辺りも同様です。ただ、 Python とかだと pyenv などの仮想環境でプロジェクト配下に python3.exe が入るのでグローバルの Python バージョンを切り替えようとしたことはないですね。

こういった言語のバージョンの切替って、その言語に特化したバージョン切替ツールを使うのがメジャーですが、JDK のバージョン管理ツールとして使用されることが多い SDKMAN! や jEnv は Windows には非対応なので、私の場合はここも Scoop でやっちゃつてます。言語特化型ではないバージョン切替ツールとして [asdf](https://asdf-vm.com/) がありますが、これも Windows は非対応なんですよね。（WSL では動く）

ただ、Scoop をバージョン切替ツールとして使う場合、上記のツールと比べるとちゃんとデメリットもあります。

JDK の場合で説明すると、まずプロジェクトで固有の JDK バージョンを指定したい場合に .sdkmanrc などでバージョン情報を共有できるファイルなどはないです。
次に、この `scoop reset` ですが、他の JDK を `scoop update` で更新した際に自動で上書きされます。そのため、JDK 21 を使っていて、 JDK 17 だけ更新したら、JAVA_HOME と PATH も JDK17 に向いてしまった、という状況になります。

ただ、現場で Java 使っていた時に 5 年ぐらいこの運用でやってましたが、そこまで困ったことにならなかったので、意識低いかもですがこれに定着しています。
※ WSL を使っていない時点でこの辺の意識は低くなりがち。でも、メモリには優しいよ！

## 3. アンインストールが楽

これは winget の愚痴になってしまいますが、 winget のアンインストールってなぜか安定していない印象があるんですよね。別に appwiz.cpl を開いて手動でアンインストールできるので、詰まったりはしないのですが。

あと、アンインストールするときに、設定情報も含めて根こそぎ削除したいときに、いちいちホームディレクトリや AppData 配下の設定ファイル、レジストリを削除する必要がなくて、 `scoop uninstall --purge <app>` で消せるのも中々ポイント高いです。（全部のアプリでそれができるってわけではないけども）

全アプリが `~\scoop\` にあるので、容量食っているアプリを特定するのも楽ですし、コマンドに頼らなくても手動で簡単に消せるのも、割と安心感が持てます。

# おわりに

以上、Scoop をまだ使い続けている理由でした。
まだ使ったことがない Windows ユーザの方は、よかったら使ってみてください。

https://scoop.sh/
数学弱者が波に挑戦してみる③

# はじめに

https://qiita.com/Riru1290/private/1083083415e217a41e33

上記の続きになります！

今回はトロコイド曲線でハイトマップを生成するところから。

# 数学のお時間
さあやってまいりました！数学弱者には苦痛でしかないお時間が！

前回少しトロコイド曲線、もといサイクロイド曲線についてお勉強したんですが、
トロコイド曲線といっても様々なものがあるので
今回は限りなく波に近いトロコイド曲線を作っていこうと思います！

## トロコイド曲線

x=周期
y=波の高さ
a=円の半径
b=円の中心から軌道を描く点までの距離
θ=円が転がった角度

x=aθ−bsinθ
𝑦=𝑎−𝑏cos𝜃

*a=1,b=1のグラフ
![トロコイド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941047/0d315e26-8f52-cbc3-0043-462a2958a724.png)


まあ、確かにこのままだと波ではない。

### y軸を反転
ので、`y軸を反転させる`

x=aθ−bsinθ
𝑦=`-`(𝑎−𝑏cos𝜃)

![Y軸反転トロコイド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941047/b8b548f9-7fe1-29a8-f949-987d113107fb.png)


おお、これだけでもだいぶ波。

### 正の数に

で、これをより扱いやすくするために曲線全体がピタッと正の数になるように
`y=0からy=曲線上の最も低い場所（例えばθが180ﾟである場所）までの距離を足す`

x=aθ−bsinθ
𝑦=-(𝑎−𝑏cos𝜃) `+ (𝑎−𝑏cos180ﾟ)`
↓
y=b(cos𝜃+1)

![高さ変更トロコイド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941047/88cb7453-8ea4-3fb9-8d65-c77bf6bf71f6.png)

### bを振幅として扱いたい

現段階で`yの取りうる値の範囲`は
cos𝜃の取りうる範囲が-1~1なので
b(-1+1)~b(1+1)　つまり
`0~2b`である
これを　b　を波の振幅として扱いたい~~らしい~~ので
`y=b(cos𝜃+1)-b`
↓
`y=bcos𝜃`
となる。

![振幅トロコイド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941047/05b082ba-2bc1-83db-1962-07d79d534cca.png)

### 一旦ここでまとめ
いらない工程があったような気もしたんですが、結論
"**波の高さ＝振幅cosθ**"

### 円の半径aと円の中心から軌道を描く点までの距離bの関係


今まで **a = b**での話をしてきたんですが
この2つの値の関係値によって波の形が異なってきます。

![トロコイド曲線.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941047/0c2986c6-3111-0f7a-3d41-601b69879149.gif)

波だなって感じられるのは**a>b**のとき
(今回はb >= 0とする)

### aとbをパラメータによって算出したい

`x=aθ−bsinθ`
`y=bcos𝜃`

今のところ波の式は上記のようになっているんですが
最終的には**具体的なパラメータによって算出できるようにしたい**
例：波長と波の尖り度合とかを渡したらその波が作り出せる


ってわけで、次にやることは参考サイトによれば
`bをaの割合で表したい`ということで

R = aに対する割合(0~1の値をとる尖り係数)
`b = aR`

とする

次にaとbをこの尖り係数Rと波長Lという
`2つのパラメータを使って表す`

`a = L/2π`
`b = R・L/2π`

ただ、ここで仮に
Lを2、Rを1、θをπとした時に

波長はそのまま2
最大の波高が2b=2/π≒0.636

つまり
波長：最大の波高 = 1：0.318

となるんですが、前々回波について調べた結果
現実の波は大体
`波長：最大の波高 = 1：0.142`
ってことがわかっています。
そう、現段階の式だと割合がリアルじゃないんです。

なので
`b = R・L/2π/2`
↓
`b = R・L/4π`

とすると大体それっぽい割合になる

整理すると

**`x=(L/2π)θ−(R・L/4π)sinθ`**
**`y=(R・L/4π)cos𝜃`**


### 位相
動かない波であれば

`x=(L/2π)θ−(R・L/4π)sinθ`
`y=(R・L/4π)cos𝜃`

でいいんですが、
動かしたい場合はxに移動距離を足さないといけません

移動距離は速度×時間

時間はtで表せばいいんですが
速度がちょっとわかりづらくて
`v = √(L/2π・g)`

Lが波長、gが重力です
理解は後にして
とりあえず最終の式を出す

**`x=(L/2π)θ−(R・L/4π)sinθ+√(L/2π・g)・t`**
**`y=(R・L/4π)cos𝜃`**

長い！！！！！！！！！

# 実装
さあ実装してみよう！
と、行きたいところなんですが。

**`x=(L/2π)θ−(R・L/4π)sinθ+√(L/2π・g)・t`**
**`y=(R・L/4π)cos𝜃`**

これは媒介変数表示であり、
xとyの値は互いに直接的に干渉しません。

つまり、時間がどう進もうが波の高さが変化しないんです。

しかも、媒介変数であるθをxで表すこともできないらしいので
ほんとにお手上げ。

え。どうしたらいいの？

で、一応解決策的なものはあるらしくて
それが
**θをニュートン法で探索する**

いや知らん。ニュートン法ってなんぞ。

疲れたので今日はここまで。
本当は適用＋頂点シェーダも使いたかったんですが、
思ったより理解に時間がかかってしまった...

次回はニュートン法を理解するところから始まる気がする
ってかなんか元々の目標から離れていってる気がするけど大丈夫なんだろうか


# 小話：有義波
波には尖りがあるという話を前回したんですが、
その「人間が尖っていると感じる波」は`有義波`ってのに含まれているらしい。

有義波とは、目に入った波全体のうち、1/3ぐらいの割合で含まれる
　「人が目で見て動いているなと認識できる波」です。らしいです。
　残りの2/3は小さすぎてどう動いているのか認識できないとのこと。

まあ、簡単に言えば
波の構成は　大きい波：小さい波 ＝ 1 : 2 ってこと「らしい」


#

開発環境
IDE:VisualStudio2022
使用言語:c/c++
使用ライブラリ:DirectXTex,DirectXMath etc.

関数グラフ作成サイト様
https://www.geogebra.org/graphing?lang=ja