OmniAICreator/Qiita-1.07M huggingface dataset:
413.0 Request Entity Too Largeが出た時のIIS設定

自分用のメモとして。

# 現象

ASP.NET Core MVCから、HttpClientを使って別のASP.NET Core APIとPOSTでHTTPS通信する際に次のエラーが起きた。
ファイルアップロードなどは行っておらず、1000個近いデータのリストをJSONでPOSTしている。

```
IIS 10.0 エラーの詳細 - 413.0 - Request Entity Too Large
```

**主なポイント**
- HttpClient使用
- HTTPS通信
- POST(JSON)
- ファイルアップロードはしていない

# 原因の分析

大量データの送信テスト中だったこともあり、エラー内容からも推察するに、この問題がリクエストデータ量が上限値を超えたことによって起きている可能性が高いと考え、いくつかの対策を実施して結果を見た。

# 結論

ApplicationHost.configに以下の設定をするとエラーが出なくなった。300kbが妥当かどうかは送信されるデータによる為、さらに検証が必要。

|項目|値|
|--------|--------|
| セクション | system.webServer/serverRuntime |
|場所|ApplicationHost.config|
|maxRequestEntityAllowed|307200 (300kb) (規定値=49152)|
|uploadReadAheadSize|307200 (300kb) (規定値=49152)|

# 変更しても変化がなかったプロパティ

## maxRequestLength (×)

|項目|値|
|--------|--------|
|セクション|system.web/httpRuntime|
|場所|Web.config|
|maxRequestLength|規定値=4096|
|変更した結果|規定値から最大値に変更しても変化なし。そもそも4096はkb指定であり、4MBは十分な値|

※そもそもこれはASP.NET（ASP.NET Coreではなく）の設定値だった。ASP.NET Coreでは`maxAllowedContentLength`を設定する。未だにSP.NETとCoreの情報が入り乱れており、大変…。

## maxAllowedContentLength (×)

|項目|値|
|--------|--------|
|セクション|system.webServer/security/requestFiltering
|場所|Web.config|
|requestLimits/maxAllowedContentLength|規定値=30000000|
|変更した結果|規定値から最大値に変更しても変化なし。そもそも規定で30MB近くあり、十分な値|

# 解説

|プロパティ|説明|
| - | - |
|maxRequestEntityAllowed| IISの設定値で、リクエストのエンティティボディの最大バイト数を指定します。これは、HTTPリクエストヘッダーを含まないPOSTデータのサイズを制限するための設定です。|
|uploadReadAheadSize|IISの設定値で、HTTP.sysがクライアントから読み取る、SSL接続で送られるリクエストエンティティボディの最大バイト数を指定します。これは主にSSL接続でのファイルアップロードサイズを制御します。|
|maxRequestLength|ASP.NET（ASP.NET Coreではなく）のweb.config設定で、HTTPリクエストの最大長を指定します。この長さはキロバイト単位で指定されます。これは、アップロードされるファイルの最大サイズを制御するためのものです。|
|maxAllowedContentLength| IISの設定値で、リクエストのコンテンツ（ボディ）の最大バイト数を指定します。これはHTTPリクエスト全体（ヘッダーとボディを含む）の最大サイズを制御します。|
初めてメンターをした新人研修の「どうしよう！終わらない！」な状況でしてみたこと

# 概要
弊社では、新人研修として仮想プロジェクトを実施しています。
平たく書くと、２〜３人１チームで、何か動くWebアプリを１ヶ月で作ろうという研修です。

突然こんな研修が始まってしまうと、特にプログラミング完全未経験の人が集まったチームでは「さてどう進めようか？」になってしまいます。

今回の記事では、そんなチームのメンターをしていく中で、「あと２週間！けど完成しそうにない！」に遭遇してしまった際に行ったワークについてざっくり書いていきます。

# 課題だったこと
そもそもこのチームの課題は、
- タスクの洗い出しが苦手で、全体の工程の中で今自分たちが何を終えていて何をしないといけないのかの把握が難しい
- その状況をメンターが伝えても、いまいちピンと来ていない様子

ということでした。

未経験なので、そうなってしまうこと自体は当たり前です。
ただそれでも時間は容赦なく過ぎていき、完成発表会はどんどん近づいてくるわけで。

口で伝えても伝わりにくいので、いっそ手を動かして実感してもらおう、ついでにスケジュールも立て直してもらおう、と思い、下のようなワークを実践してもらいました。

# ワークの内容
ざっくり以下の内容です。
1. 現状のプロダクトを、チームメンバーとメンターで一緒に動かしてみる
1. 動かした結果を元に、完成までに「何が足りていないか」「どんな機能を追加したいか」を、大小問わず洗い出していく
1. 各々が思う優先度で洗い出した結果を分類してみる
1. 全体の意思で分類の最終決定をする
1. 分類を元に、スケジュールを立て直してもらう

ちなみに今回はメンターが２人いたため、１人は進行役として、１人は実際にワークに参加しました。

## 1. 現状のプロダクトを、チームメンバーとメンターで動かしてみる
とりあえず開発環境で動かします。

- クリックできそうな部分は全部クリック
- 見た目もチェック
- 入力する部分は限界まで入力
- ~~壊せそうだなと思ったら壊す~~

そうして触りまくり、気になった箇所や動かなかったはメモ書きしていきます。

## 2. 完成までに「何が足りていないか」「どんな機能を追加したいか」を洗い出し
１で各々がメモ書きなり記憶なりで残したことを、とりあえず付箋に書き出していきます。
今回はページ数が少ないWebアプリだったので、画面ごとに書き出してもらいました。

洗い出しで出た内容は、例えば
- そもそもCSSがあたっていない
- ログアウトがログアウトになっていない
- （作ったのがメンバー紹介アプリだったので）自分自身の情報以外は編集できないようにしたい

などです。

## 3. 各々が思う優先度で洗い出した結果を分類してみる

ひとまず各々が１つ１つの付箋に対し、下の基準でアイコンをつけていきます。
- 仮面（またの名を米粒）・・・譲れない最低ラインで、完成発表会までに絶対仕上げるタスク
- 星（⭐️）・・・できれば完成発表会までにやりたいタスク
- ハート（♡）・・・ここまでできれば上等だよね、というタスク

※ アイコンの選択に深い意味はありません。

実際に書き出してみた結果がこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/bf621bb5-abb8-ce75-9918-3280ac87d4d7.png)


## 4. 全体で話し合い、分類の最終決定をする
3で各々が置いたアイコンについて、以下のルールで話し合いをします。
1. 仮面のアイコンが１つでも置いてある付箋→星が置いてある付箋→ハートがおいてある付箋、の順に確認していく
1. 置いたアイコンが全員一致した場合、その優先度で決定
1. 置いたアイコンが一致しなかった場合、なぜそう思うのかをそれぞれに確認し、最終決定をする

話し合いが終わった付箋は、全員が結果を把握できるように整理していきます。
今回は、ホワイトボードアプリに新しくスペースを作り（通称：国旗）、そこに置いていきました。

実際の結果がこちらです。
（現在は加筆が入り、青色のスペースの付箋が黄色や赤色に移動した様子です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/4a0b808d-1a3f-34e8-1d80-17d4e6d59d4b.png)

## 5. 分類を元にスケジュールを立て直してもらう
あとはスケジュールを立て直してもらうだけです。
基本的に、
赤色に置いたタスクを仕上げてもらって手動テスト→余裕があれば黄色からタスクを取り出してもらって手動テスト
の流れで進めてもらうように伝え、ワークは終わりです。

後でこっそり覗いてみたところ、付箋の数がワーク時よりさらに増えてました笑
出来上がったスケジュールがこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605286/1b02c1fd-427a-324d-d225-81b1afff5553.png)

# ワーク後の変化
このワークの前後で、新人たちがどんなふうに変わったかを観察してみました。
- 「何が足りていないか」の会話が生まれたり、それを元にタスクを作り出せるようになった
- スケジュールが超具体的になった
- タスクの粒度が細かくなったことで、出社時や退社前に誰がどのタスクをやるか、遅れているタスクをどう振り分けるか、の会話がしやすくなった

このワークの思わぬ副産物として、なぜかチーム内の会話が増えてました。

# おわりに
最終的に、動くものが出来上がり、無事に完成発表会を終えることができました。
当日の発表会を見ながら、「初めて授業参観を見に行く人ってこんな気持ちになるんだろうな」と思ったことを覚えています。

結論、未経験チームでは、兎にも角にも何らかの形で可視化して実感してもらうのが一番伝わりやすいなーと思いました。
Oracleでテーブルとカラムのコメント抽出

# はじめに
備忘録。以前PostgreSQLで記述しましたが、Oracleでも必要になったので作成。

WHEREにて、テーブル指定やコメント文字列指定ができる。

# SQL

```sql:Oracle
SELECT
    USER_TAB_COMMENTS.TABLE_NAME,
    USER_TAB_COMMENTS.COMMENTS,
    USER_COL_COMMENTS.COLUMN_NAME,
    USER_COL_COMMENTS.COMMENTS,
    USER_TAB_COLUMNS.DATA_TYPE,
    USER_TAB_COLUMNS.DATA_LENGTH,
    NVL2(USER_TAB_COLUMNS.DATA_PRECISION,
      USER_TAB_COLUMNS.DATA_PRECISION || ',' || USER_TAB_COLUMNS.DATA_SCALE, '') AS NUMERIC_LENGTH,
    USER_TAB_COLUMNS.NULLABLE
FROM USER_TAB_COMMENTS
LEFT JOIN USER_TAB_COLUMNS
    ON USER_TAB_COLUMNS.TABLE_NAME = USER_TAB_COMMENTS.TABLE_NAME
LEFT JOIN USER_COL_COMMENTS
    ON USER_COL_COMMENTS.TABLE_NAME = USER_TAB_COMMENTS.TABLE_NAME
    AND USER_COL_COMMENTS.COLUMN_NAME = USER_TAB_COLUMNS.COLUMN_NAME
WHERE USER_TAB_COMMENTS.TABLE_TYPE = 'TABLE'
/*    AND USER_TAB_COMMENTS.TABLE_NAME = 'table_name' */
/*    AND USER_TAB_COMMENTS.COMMENTS = 'table_comment' */
/*    AND USER_COL_COMMENTS.COLUMN_NAME = 'column_name' */
/*    AND USER_COL_COMMENTS.COMMENTS = 'column_comment' */
ORDER BY USER_TAB_COMMENTS.TABLE_NAME, USER_TAB_COLUMNS.COLUMN_ID;
```

# 参考
PostgreSQLはこちら
https://qiita.com/sasio/items/ad4c1cdd93011c5fb7b4
Office(Mac)のライセンス認証が「組織内の別のアカウントが既にサインインしています」エラーで通らないとき

## Microsoft公式の対処法
キーチェーンアプリで特定のキー項目を削除する。

> https://learn.microsoft.com/ja-jp/microsoft-365/troubleshoot/sign-in/sign-in-to-office-2016-for-mac-fail

## 上記でも直らない場合
キーチェンをクリアする。
**当然キーチェーンに保存した全てのパスワードがクリアされる**ので注意

手順は下記の通り
1. 全てのアプリを終了する
1. システム設定アプリのプロフィール画面で、AppleIDからサインアウトしておく
1. キーチェンアクセスを起動
1. 設定を開く（メニューでキーチェーンアクセス → 設定）
1. デフォルトキーチェーンをリセットをクリック
NS-CSC 第一回 WriteUp


# 1. Welcome ☆
問題文の中に書かれているフラグを入力すれば成功
```
flag{abcd}
```

# 2. よいしょ、よいしょ ☆☆
これはシーザー暗号で暗号化されています。
このサイトを使うとすぐにフラグを見つけることができます
```
flag{Caesar_Caesar_Caesar_Caesar}
```


# 3. つーとん、つーとん　☆☆
つーとんから連想されるのは、電信。
フラグはローマ字になるのでアルファベットのモールス信号で解読します。

```
flag(morse_code_morse_code_morse_code)
```


# 4. 氷を溶かすように　☆☆
氷を溶かす＝＞解凍する＝＞zipを解凍する
```
flag{d715e102-4869-749e-76d3-2e6435b5bd3e}
```

# 5. 認証はどこで？ ☆☆☆
ただのログインページに見えますが、どうでしょうか。
HTMLを見てみると次のコードがある事がわかります。

```js
function login() {
    const username = document.form.username.value;
    const password = document.form.password.value;
    console.log(username)
    console.log(password)

    if (username === "admin" && password === "admin123456") {
        alert(`Login successful \nflag: flag{eeecafba-11ad-3779-67b8-5c98f699490b}`);
    } else {
        alert("Login failed");
    }
}
```

if文でuserとpasswordを一致させて認証していることがわかります。

ログインページにadminとadmin123456を入力するとフラグがわかります

```
flag{eeecafba-11ad-3779-67b8-5c98f699490b}
```

# 6. ログインできますか ☆☆☆
またログインページです。一つ前の問題のようにHTMLを見てもなにもわかりません。
ログインページでアタックできる方法は色々ありますが、単純なのがSQLインジェクション

コードは次のようになっていて入力部分の内容を直接入力していることがわかります。

```js
try {
    const results = await db.query(`SELECT * FROM test where user='${req.body.name}' AND pass='${req.body.pass}';`)
    await db.end()
    console.log(results)
    if (results.length !== 0 ){
        res.status(200).json({ message: `ログインに成功しました。\nflag: ${process.env.FLAG}`});
    }else{
        res.status(401).json({message: `ログインに失敗しました`});
    }
} 
```

ユーザー名に
```
1'OR'1'='1'-- ; 
```
と入力するし、パスワードに適当な文字列を入れるとフラグ入手

```
flag{9362c960-388d-c9d4-db85-15705f47d602}
```

ちなみに、ユーザー名に入力すると以下のSQLクエリ文が生成でき、
```sql
SELECT * FROM test where user='1'OR'1'='1'-- ; ' AND pass='${req.body.pass}';
```
「-- ;」によってパスワードのAND文が無効化され、userの条件式は常にTrueになるのでログインできるという仕組みになります

# 7. 本当に消えてる？ ☆☆☆
Gitのレポジトリを使用した問題でした。

Gitはバージョン管理のソフトウェアで、一度コミットしてしまうと、
取り消しをしない限り消えないという仕様があります。
間違えて機密情報をのせてしまった場合、当該ファイルを消しても消えないのです。

問題に載せられていたgitレポジトリの2番めのコミットを見ると、flagが表示されます。

```
flag{8dd8ea2f-e76f-7d90-0d92-ed238abe5e3a}
```
Auroraってなに

## Auroraとは

:::note
AWSが提供するリレーショナルデータベースサービスの一つ
MySQLとPostgreSQLの互換性を持つ高性能で信頼性の高いデータベースエンジン
AWSのクラウドインフラストラクチャを活用
→スケーラブルで耐障害性のあるデータベースソリューションを提供
:::

## Auroraの特徴

- **ハイパフォーマンス**
高速なパフォーマンスを提供
データのストレージやレプリケーションの仕組みなど、内部的に最適化された技術を使用

- **スケーラビリティ**
データベースのスケーリングを簡単に行える
読み込みトラフィックの分散や自動的なストレージ拡張などの機能がある
→データベースの需要に応じて柔軟にスケールアップ、スケールダウンができる

- **耐障害性**
冗長性と耐障害性を重視して設計されている
複数のアベイラビリティーゾーンにデータを複製し、自動的にフェイルオーバーを行う
→高い可用性

- **バックアップと復元**
自動バックアップとポイントインタイムリカバリ（PITR）をサポート
データの定期的なバックアップを実施し、必要に応じて過去の状態にデータベースを復元できる
【ChatGPT無】入力文章の要点をまとめるPrompt（メールなどに）

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

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

　今回は、
　　よくあるメールの作成、
　　　ではなく、
　　　　届いたメールの内容を
　　　　　簡潔にまとめる
　　　　　　プロンプトです。

　　メールに限らないつもりです。

　　**でも、
　　　指示プロンプトについては、
　　　　「」で囲うことを
　　　　　忘れないでください。**
　　　　　　そのプロンプトを
　　　　　　　実行しようと
　　　　　　　　しますので。

　　後半では、
　　　先日の小説のあらすじを
　　　　読み込ませてみました。

```Text:文章の要点をまとめるPrompt
# 目的
入力される文章に、何が書かれているのかが知りたい。

# お願い
要点を簡潔にお願いします。
重要点があるならば、教えてください。
最後に、簡単なまとめをお願いします。

上記を理解できたならば、「はい」と答えて、待機してください。

理解できない場合は、不明点を指摘してください。
```

　下記では、
　　ふたつのメール内容を
　　　入力しています。

　ちなみに、
　　メールの骨子は
　　　ChatGPTさんに
　　　　お願いしました。

```Text:プロンプト実行結果
ChatGPT
はい





User
見返り美人 様

お世話になっております。
（株）アカネ商店の稲荷又八です。
先日は大変お世話になりました。

このメールは、先日のお礼を申し上げるためにお送りしております。

こちらが気付かなかった点を指摘していただけたことは、本当に有難く思いました。

若輩者ではございますが、これからも忌憚のない意見を賜りたく存じます。

改めて、ご協力いただきありがとうございました。今後とも何かお力になれることがありましたら、どうぞお気軽にお知らせください。

何かご不明な点や追加のご要望がございましたら、お知らせください。よろしくお願いいたします。

敬具
　稲荷又八



ChatGPT
要点：

・メールを送っている人は、アカネ商店の稲荷又八という人物。
・メールは先日のお礼を述べるために送られている。
・受け取った人からの指摘に感謝し、今後も意見を求める旨を伝えている。
・お力になれることがあれば連絡を求めている。

まとめ：
稲荷又八は、アカネ商店の代表者であり、先日のお礼を伝えるためにメールを送った。彼は受け取った人からの指摘に感謝しており、今後も意見を求めている。また、彼はお力になれることがあれば連絡を待っていると述べている。





User
見返り美人 様

お世話になっております。
（株）アカネ商店の稲荷又八です。

次回、御社へのプレゼンを行なうにあたり、以下の手続きで行ないたいと考えております。

（プレゼンの流れ）

何か気付かれたことがあれば、ひと言いただけたら、ありがたいと思っております。
もちろん、こちらでもチームで検討しておりますが。

よろしくお願いいたします。

敬具
　稲荷又八



ChatGPT
要点：

・メールを送っている人は、アカネ商店の稲荷又八という人物。
・メールは次回のプレゼンに関する手続きを伝えるために送られている。
・プレゼンの流れについて触れており、気付かれたことがあればひと言伝えるよう依頼している。

まとめ：
稲荷又八は、アカネ商店の代表者であり、次回のプレゼンに関する手続きを伝えるためにメールを送った。彼はプレゼンの流れについて触れ、受け取った人からの意見や気付きを求めている。
```
***
[【ChatGPT無】質疑応答Promptで小説を書こうとしたが喧々諤々……久しぶりに続けたら](https://qiita.com/kabumira/items/0f55e83df2ff18721093)
　で作られた
　　小説のあらすじを
　　　読み込ませてみました。

　ここは、
　　コードブロックではなく、
　　　引用で書き出します。

>要点：
>- タイトルは「異世界転生 〜魔法陣に巻き込まれた40歳サラリーマンの冒険物語〜」。
>- 第1章では、佐藤八郎太が通勤中に魔法陣の光景を目撃し、彼と四人の高校生が異世界へ転生する。
>- 第2章では、彼らがナーロッパ風の異世界に迷い込む。
>- 第3章では、彼らが冒険者としての登録を行い、修行や準備を始める。
>- 第4章では、彼らが王都への脱出を目指し、追っ手や自身の力量の不安と戦う。
>- 次回予告では、第5章で王都の闇と闘うことが示唆されている。
>
>まとめ：
「異世界転生 〜魔法陣に巻き込まれた40歳サラリーマンの冒険物語〜」は、佐藤八郎太と高校生たちが魔法陣によって異世界へ転生し、冒険者として生き抜く物語です。彼らは異世界での修行や準備を通じて成長し、王都への脱出を目指します。次回では王都の闇との戦いが展開されるようです。

***
　どうでしょうか。

　メールの内容って、
　　意外と長たらしいですよね。

　読む側は、
　　余計な時間を
　　　減らしたいのに
　　　　中身が、挨拶と
　　　　　助長な文章ばかり。

　そんなの、読んでいられないよ！
　　という人の役に立てば、
　　　うれしい……かな。

　まぁ、
　　コピペする手間が
　　　必要なんですけどねw
***
　実は、
　　ChatGPTの書籍が
　　　出てきたあたりから、
　　　　夢想していることが
　　　　　あります。

　人間←→人間（直接会話）が
　　テレワーク化で、
　　　人間と人間のあいだに
　　　　パソコンという機械が
　　　　　入るようになりました。

　そこに、
　　ChatGPTのような
　　　生成AIが入るようになる。

　人間←→生成AI←→人間
　　という構図に
　　　なっていく気がします。

　つまり、
　　人間が何か汚い言葉を
　　　使ったとしても、
　　　　生成AIが直して、
　　　　　相手に当たり障りない
　　　　　　言葉が送られる。

　相手も汚い言葉を吐き出すけれど、
　　生成AIが直してしまう。

　あるいは、
　　助長なメールなんかを
　　　要件だけにしてくれて、
　　　　生成AIにひと言
　　　　　言うだけで、
　　　　　　助長な返信が
　　　　　　　送られる。

　そのうち、
　　マスク型生成AIが
　　　売られるようになり、
　　　　そんな風にやり取りする
　　　　　ようになったりして。

　でも、
　　よくよくまわりを見渡すと
　　　スマホをずっと見続け、
　　　　イヤホンで会話が
　　　　　できている。

　ChatGPTの
　　iPhoneアプリも
　　　音声入力が
　　　　違和感なく、
　　　　　使われています。

　とすると、
　　そうしたことが、
　　　ふつうになっていくのかも
　　　　しれませんね。

　早くAndroid版アプリが
　　出て欲しいカーブミラーでした。

　その前に、パソコンが欲しいわw
【今更誰得】PC-G850VS 常用対数以外の対数を計算できるようにする


## 導入
PC-G850VSには常用対数を計算するためのLOG関数と自然対数を計算するためのLN関数がありますが底が10,$e$以外の対数を計算することはできません
基礎数学の授業で検算するために実装していきます。

## 技術
学校で習ったので底の変換公式を使っていきます
底の変換公式
※a≠1,a>0,b>0,c≠1,c>0とする。
$$\log_a b=\frac{\log_c b}{\log_c a}$$
ここでは常用対数で計算できるようにするためc=10とする。

## ソースコード
```basic
10PRINT "calc any base logarithm
20INPUT "base:",A
30WHILE ((A=1) OR  (A<=0))
40PRINT "base must be !=1 and >0"
50INPUT "base:",A
60WEND
70INPUT "antilogarithm:",B
80PRINT LOG B/ LOG A
```
底に1とか負の数を入れてくる人には正義の鉄拳を下します。

基礎数学 教科書
https://www.amazon.co.jp/dp/447703315X/

PCG850VS
https://www.amazon.co.jp/dp/B00FVRAN5E
買いましょう
ソースコードを１行増やすのは登山の山が１ｍ高くなるのと同じか？と思った話

適切にインターフェイス設計して、適切にオブジェクト指向プログラミングをしていると、１クラスあたりのファイルがだいたい50～300行程度になることが多いという体感があります。ごくまれに1000行を超える大きいソースファイルを作ってしまうこともあるのですが、そのようなクラスはC#の`DateTime`とか`List<T>`のような**名は体を表す**強力な機能になっていることも多いです。または設計ミス。

ここで、**ソースコードの１行は登る山の標高が１ｍあがる**のと同じようなものなんじゃないかなとふと思ったのがこのポエムです。では私たちが山を登る＝ソースコードを１行ずつ読むのはいつでしょうか？**保守のタイミング**です。

* 50行のソースコードは50mの山（というか丘）、かんたんに保守できる
* 300行のソースコードは300mの山、ハイキングのような気持ち
* 500行のソースコードは500mの山、まだギリ低登山らしいです。半日で終わらせましょう
* 1000行のソースコードは1000mの山、一日かけて挑戦するレベルです。１日で下山＝定時で帰宅できるでしょうか？遭難しないように気を付けてください。
* 3776行のソースコードは3776mの山、というか富士山を登るレベルの難易度。挑戦はせめて１年に１回以下にしたい（**正月は勘弁して！**）

なお、ユニットテストがないのは**登山道が存在しない**のと同じ意味になります。つまり、その山は登るべきではないし、登るときは覚悟が必要になります。

5000行や10000行のソースコードの保守は専用チームが結成される数週間レベルの登山＝保守になるでしょう。しかもこの手のソースコードはだいたいユニットテストがありません。登れと命令されてしまった場合、もしかすると遭難して帰れず（**デスマーチ**）、遺体で発見（**退職を決意**）されるかもしれません。

# まとめ
プログラミングばかりして運動不足の私たちは、**いかに山の高さを削るか**を努力していきたいものですね。~~登山クラスタの人には怒られるかもしれないけど~~
DDDに登場する値オブジェクトとエンティティについて簡単にまとめてみた

チームでドメイン駆動設計(以下DDD)に取り組んでおり、開発や勉強会を通して知見を高めています。DDDでは様々な概念が登場する為、理解に苦労することも多いです。この記事ではDDDの基本概念である値オブジェクトとエンティティについて、他の方に分かりやすく説明できるようにまとめてみたいと思います。

記事を書くにあたり参考にした文献がこちら。大変分かりやすく書いてあるので、DDDに興味がある方はぜひ一読されることをおすすめします。
[ドメイン駆動設計入門](https://www.shoeisha.co.jp/book/detail/9784798150727)

## 値オブジェクト
システム上に登場する概念を値オブジェクトとして定義したもの。概念というのは例えばユーザー情報を登録する処理で例えばユーザーの住所などが挙げられますが、この住所が1つの概念になります。値オブジェクトにするメリットは以下の2つが挙げられます。

・ロジック(ビジネスルール)の散在を防ぐ(結果として、コードの変更がしやすくなる)
・値オブジェクト自身が仕様書になる(コードの理解がしやすい)

住所は郵便番号・都道府県といった要素から構成されますが、そのビジネスルールをロジックとして記載する必要があります。値オブジェクトを切るとそういったビジネスルールを散在させることなく、値オブジェクト自身にまとめることができます。またそうすることで、値オブジェクトを見るだけでその概念の仕様書にもなるので、コードを見た時に理解がしやすいのも特徴として挙げられます。
では値オブジェクトに切り出す基準は何なのかと考えた時、下記2点を軸に切り出すか検討すると良さそうです。

・ルールが存在しているか(住所は郵便番号・都道府県などから構成される)
・単体で取り扱いたいか(郵便番号や都道府県で別々のルールが存在する場合)

住所は郵便番号・都道府県などから構成されるというルールがあります。また単体で取り扱いたいかについては、郵便番号や都道府県で別々のルールが存在するかを考えると良さそうです。例えば郵便番号では、3桁の数字（都道府県を表す市外局番）と4桁の数字（町域や番地を表す局番）から構成されるというルールがある為、別の値オブジェクトとして切り出すのも有りかもしれません。

## エンティティ
値オブジェクトの性質の反対の性質を持つのがエンティティと呼ばれるものです。値オブジェクトは属性によって識別されるのに対し、エンティティでは同一性によって識別されます。例えば上記で解説した値オブジェクトである住所は郵便番号・都道府県といった属性から構成されます。これらの属性の中身を変えた場合、異なる住所として認識されます。エンティティの例として代表格と言われるのが、ユーザー自身でしょう。ユーザーを表すにあたり住所もそうですし、年齢・体重・身長など様々な属性から構成されますが、これらの属性の中身が変わったからといって、そのユーザーが別のユーザーとして認識されることは普通に考えてあり得ません。この点が値オブジェクトとエンティティの大きな違いでしょう。値オブジェクトの時と同様、エンティティに切り出す基準は何なのかと考えた時、下記を軸に切り出すか検討すると良さそうです。

・ ライフサイクルが存在し、そこに連続性が存在するか

ユーザーはシステムを使用するにあたり、利用者によって作成されます。そしてシステムを利用していく内に、利用者にとってこのシステムはもう不要だなと感じ、退会(削除)することもあるかと思います。こうした作成されて、月日が経ち削除されるという流れこそがライフサイクルが存在し、連続性のある概念だと言えます。こうして見ると、値オブジェクトとエンティティは異なる性質を持つことが明白になったかと思いますが、どちらも切り出すことで得たいメリットに本質的に変わりはありません。

## 終わりに
DDDの基本概念である値オブジェクトとエンティティについて紹介しましたが、これ以外にもService・Repository・Factoryなど様々な概念が存在します。機会があればそれらの概念も紹介する記事を書きたいなと思っています。
mailchimp-marketing-rubyでMailchimpのAPIを叩いてみる

Mailchimpでは様々な情報がAPIで取得できるようになっています。

https://mailchimp.com/developer/marketing/api/

データ分析基盤との連携をする際、AWSでは[Amazon AppFlow](https://docs.aws.amazon.com/appflow/latest/userguide/connectors-mailchimp.html) を利用したり、Treasure Dataでは[Mailchimp Export Integration](https://docs.treasuredata.com/display/public/INT/Mailchimp+Export+Integration)を利用することなどが可能ですが、取得できるのは一部の情報のみで、それ以外は自分で取得する必要があります。

その際、RubyであればMailchimpMarketingRubyを使うことで、APIを楽に利用することができます。

https://github.com/mailchimp/mailchimp-marketing-ruby

## 実際にサンプルを叩いてみる

まず、こんな感じに`Gemfile`を編集します。dotenvはAPIキーを取得するために使います。

```ruby:Gemfile
source "https://rubygems.org"

gem 'dotenv'
gem 'MailchimpMarketing', :git => 'https://github.com/mailchimp/mailchimp-marketing-ruby.git'
```

次に.envを編集します。
MAILCHIMP_SERVER_PREFIXはAPI_KEYの-の後の文字を入れるだけで基本はOKみたいです。

```:.env
MAILCHIMP_API_KEY = 'xxxxxxxxxx-xxx'
MAILCHIMP_SERVER_PREFIX = 'xxx'
```

ではこんな感じのスクリプトを書いて実際にAPIを叩いてみます。
今回はサンプルとして [/lists](https://mailchimp.com/developer/marketing/api/lists/) を叩いてみます。


```ruby:main.rb
require 'dotenv'
require 'MailchimpMarketing'

Dotenv.load

client = MailchimpMarketing::Client.new()
client.set_config({
  :api_key => ENV['MAILCHIMP_API_KEY'],
  :server => ENV['MAILCHIMP_SERVER_PREFIX']
})

response = client.campaigns.list('count': 10)
puts response["campaigns"]
```

`bundle install`をした後、`ruby main.rb`を実行すると、APIを叩いた結果を得ることができます。

他のAPIの利用方法も [README](https://github.com/mailchimp/mailchimp-marketing-ruby#api-endpoints)にまとまっているため、そちらを元にとりたい情報をまとめることができます。
また、一度に取れる情報は最大千件までですが、大半のAPIでは下記のようにoffsetパラメータを利用することで１００１件目移行も取得ができるので、取得に困ることはなさそうです。

```ruby
client.campaigns.list('count': 1000, offset: 1000) # 0スタートなので１００１件目から取りたい場合は1000で良い
```

## まとめ

自分でAPIをガリガリ書くのは若干面倒ですが、Mailchimpは公式でラッパーが用意されており、非常に助かります。
[node.js](https://github.com/mailchimp/mailchimp-marketing-node)、[PHP](https://github.com/mailchimp/mailchimp-marketing-php)、[Python](https://github.com/mailchimp/mailchimp-marketing-python)実装もあり、幅広い言語で提供されておりお好みで選ぶことができるので必要になった際は是非お試しください。
Salesforce でページに特定の条件でメッセージや画像を表示させる方法

こんにちは
本橋孝昭です



今回はSalesforceで
ページにメッセージや画像を表示させる方法をご紹介します


今回の内容は動画でも紹介しています

https://www.youtube.com/watch?v=N-LL1kW767w&t=325s

<iframe width="560" height="315" src="https://www.youtube.com/embed/N-LL1kW767w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

![Salesforceページメッセージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/dcead3c5-a9c1-3233-aa94-72f25c77a444.png)



こちらを使用すれば例えば
・メール項目が空欄の場合、「メールを記載してください」と表示させたり
・退職フラグに☑がある場合、大きく退職済みと伝えたり

などが可能です

ぜひ皆さんもこのSalesforceのページからメッセージを表示させてみてください

## ステップ１　Lightningページを編集

## ステップ２　Lightningページから「リッチテキスト」コンポーネントをドラッグ＆ドロップ　でもっていく

##  ステップ3 リッチテキストのメッセージや表示条件を設定し保存


これで設定が完了です

![完成００２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/909f665c-afeb-b81b-b1e4-27f40a87d1ac.png)


## 番外編　静的リソース作成で画像も表示

なお、リッチテキスト内で画像を使用する際は、あらかじめ
・静的リソース
を作成します
静的リソース作成方法はこちらです


## ステップ１　
設定→静的リソース　から静的リソースを作成。作成する際にリッチテキストに表示させたい画像を添付

## ステップ２
作成された静的リソースから「ファイルを表示」をクリック
表示された画像から右クリックを行い
「画像をコピー」をクリックしリンクを取得


## ステップ3
リッチテキスト内にステップ２で作成したリンクを貼り付けする
#05 ArcGIS Proで緯度経度のCSVからポイントデータを作る際に気を付けること

### 緯度経度のフィールドを気を付ける
ArcGIS Proで緯度経度が入ったCSVからポイントデータを作りたいときに気を付けることですが、
ジオプロセシングツールのXY テーブル → ポイント (XY Table To Point) (データ管理)のXフィールドには経度（lng）を、Yフィールドには緯度（lat）を入れること。


### ArcGIS Proの翻訳ミスで緯度経度が逆
日本語の翻訳？が間違っていて、説明では逆になっているので注意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727169/154951a5-4460-71ab-0b39-9434e0b3f09f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727169/e0a8a0e4-3e52-64ba-d9ed-121b9472d507.png)

ただし、HP上のヘルプでは正しく記載がなされている。
https://pro.arcgis.com/ja/pro-app/latest/tool-reference/data-management/xy-table-to-point.htm
データベースのバックアップをターミナルから行う方法

# シェルスクリプトのファイルを作成
ターミナルからSSH接続した状態で、まずはバックアップファイルの保存先のフォルダをわかりやすい適当なディレクトリ(プロジェクトフォルダのルートとか)に作る

```terminal
mkdir /sql_backup
```

わかりやすい適当なディレクトリ(プロジェクトフォルダのルートとか)にシェルスクリプト用ファイルを作成
```terminal
vi sql_backup.sh
```

シェルスクリプト内容は以下の様にする。
```terminal
#!/bin/bash
username="データベースのユーザ名"
password="データベースのパスワード"

database_name="データベース名"
table_name="テーブル名"

backup_dir="/sql_backup"
backup_file="$backup_dir/backup_$(date +'%Y%m%d_%H%M%S').sql"

mysqldump -u $username -p$password $database_name $table_name > $backup_file
```

保存できたら、このファイルの権限をファイルの所有者または管理者権限（root）がこのコマンドを実行できるように変更する。
```terminal
chmod +x sql_backup.sh
```

# シェルスクリプトの実行
実行するには、先ほどのシェルスクリプトのファイルがあるディレトリで以下を実行するだけです。

```terminal
./sql_backup.sh
```

実行すれば、/sql_backupフォルダにバックアップファイルが作成されます。
サービス運用時、Rails Console等にCSV等大量のデータを入れる方法

こんにちは、[Doorkel](https://doorkel.com/)でエンジニアをやっております、ヒガシと申します。

# 本記事の概要
rails consoleなど、CLI経由で大量のデータを使う方法

# 背景
サービスを運用している際、できれば管理画面などで行いたいが機能実装しきれておらず、渋々rails consoleなどのCLI経由で大量のデータを扱う業務が発生することがあるかと思います。

データ量が少量であれば単にシェルにコピペすれば済みますが、CSVデータを元に大量にデータを追加する場合などではコピペミスのリスクやシェル側で何かしらの問題が起きて正しくデータを追加できずに困るケースがあります。

# 考えられる対策と課題
いくつか方法が考えられます。
1. サービス内にファイルアップロード機能(ActiveStorage等)があればそれでアップロード、そのファイルをCLI内で参照する
1. 頑張ってバッチを書いてシェルのリダイレクト等を使う
1. どこかpublicな場所に置く

1は該当機能の導線やファイルの特定などの楽さ、削除の容易さなどによって選ばれるかと思います。今回私が直面したケースだと、アップロードのUXが煩雑で、削除も面倒なので選びませんでした。

2は、実行するバッチが完成していればOKですがCLIで実行しつつ挙動を確認して進めたい、、などがあると選びづらい選択肢になります。

結果、3を選んだのですがホスティング先が重要です。gistは削除忘れ時にリスクになりうるし、s3やgcsなども事前に設定してないとなかなか面倒です。

# 対応方法: http-server + ngrokが楽だった
nodeのhttp-serverを使うと、特定のフォルダの静的ファイルをPC内にホスティングできます。

ngrokは、ローカル環境をPublicにアクセスできるようにするサービスで、http-serverでホスティングしている静的ファイルをPublicアクセスできるようになります。

下記のように、CLI上で使いたいファイルが入ったディレクトリでそれぞれのアプリケーションを実行することでホスティングできます。

publicになるため、URLを知られると当然漏洩のリスクがありますがCLI上でファイルをダウンロードする一瞬だけ公開であれば比較的低リスクでしょう。

```shell
$ http-server
Starting up http-server, serving ./

http-server version: 14.1.1

http-server settings:
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  http://127.0.0.1:8081
  http://192.168.1.15:8081
Hit CTRL-C to stop the server
```

```shell
$ ngrok http 8081
Account                       xxx
Update                        update available (version 2.3.41, Ctrl-U to update)
Version                       2.3.35
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://ngrok-url.app -> http://localhost:8081
Forwarding                    https://ngrok-url.app -> http://localhost:8081

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
```

# 使い方
上記http-serverとngrokを実行しておきつつ、下記の様にCLI(rails console)上でファイルを取得して実行します。

```
sample_json_str = URI.open('http://ngrok-url.app/sample.json').read
sample = JSON.parse(sample_json_str)
```

# まとめ
そもそも、console上で大量のデータを扱うようなリスクの高い作業は避けるべきですが、とはいえやらないといけないタイミングもあります。

多用しないよう気をつけつつ、比較的セキュアに作業しましょう。
[Docker] OpenFaceの起動から実行

# 概要
DockerでOpenFaceを実行する際にコマンドでの実行時に少し詰まったため補足も兼ねて記事にしました。

インストールから実行までの一通りの手順は[こちら](https://zenn.dev/nek0n0mimi/articles/e296473f1980f7)の記事が分かりやすく説明されています。　大変お世話になりました!

# 動作環境
・Windows10
・Ubuntu
・Docker Desktop for Windows

# 実行手順
Dockerのインストール・OpenFaceフォルダのダウンロードが完了した前提で、起動から実行までの手順になります。

### Docker起動
1. Docker Desktopを起動する。

2. コンテナに入るためのPowerShell __(以後PS1)__ を起動し以下を実行

       docker run -it --rm algebr/openface:latest

3. コンテナIDを確認するためもう一つのPowerShell __(以後PS2)__ を起動し以下を実行

       docker ps

4. 以下の表示がされればコンテナ作成が成功しています。

       CONTAINER ID  IMAGE                   COMMAND      CREATED             STATUS         PORTS     NAMES
       f01b14e154ff  algebr/openface:latest  "/bin/bash"  About a minute ago  Up 15 seconds            gracious_wright

### 実行
1. PS2でOpenFaceのインストールでダウンロードしたフォルダまで移動
2. PS2でdocker cpコマンドでファイルをローカルのパスにコピーする

       docker cp ./samples/sample1.jpg "実行中のCONTAINER ID":/home/openface-build

3. PS1で以下を実行 ( ここでは画像を解析するためFaceLandmarkImgを実行 )

       ./build/bin/FaceLandmarkImg -f sample1.jpg

    ※動画の場合はFaceLandmarkVid と FaceLandmarkVidMultiがありますが、FaceLandmarkVidMultiの方がエラーなく実行できます。

4. 結果は成功時に生成されるprocessedディレクトリに保存されます。

       root@f01b14e154ff:/home/openface-build# ls
       CMakeLists.txt  build  cmake  exe  lib  multi_face.avi  processed  sample1.jpg

# 参考資料

OpenFaceインストール・実行（Docker）
https://zenn.dev/nek0n0mimi/articles/e296473f1980f7

OpenFaceを試しに触れてみる
https://qiita.com/Nahuel/items/da1f71f817ec3a4d6674
個人的に便利だと思ったPhpStormショートカットキー

## ショートカットキー

- `Shift`, `Shift` [どこでも検索](https://pleiades.io/help/phpstorm/searching-everywhere.html)
- `option` + `Enter` [インテンションアクションの表示](https://pleiades.io/help/phpstorm/intention-actions.html)
- `Command` + `B` 定義元へジャンプ
- `Command` + `E` 最近使用したファイルを表示
  - `Command` + `E` 続けて入力すると編集済みのみ表示
- `Command` + `Shift` + `E` 最近開いた場所を開く
  - `Command` + `Shift` + `E` 続けて入力すると編集済みのみ表示
- `Command` + `7` 構造ビュー
- `Command` + `F12` 構造ビューポップアップ
- `Command` + `↑` ナビゲーションバーファイルジャンプ
- `Command` + `L` 行ジャンプ
- `Command` + `Shitt` + `V` クリップボードから貼り付け
- `Command` + `Shift` + `Enter` [ステートメント補完](https://pleiades.io/help/phpstorm/auto-completing-code.html#statements_completion)
- `control` + `G` 同じ単語の選択
- `option`, `option` + `↑`, `↓` [矩形選択](https://pleiades.io/help/phpstorm/multicursor.html)
- `Command` + `2` [ブックマークツール表示]()
- F3 ブックマーク登録/解除
  - `option` + `F3` ニーモニックブックマーク
- `Command` + `Shift` + `C` 絶対パスコピー
- `Command` + `Shift` + `option` + `C` 相対パスコピー
  - クラス名やメソッド名にカーソルを置いて実行すると名前空間をコピー

## 感想

ファイルパスコピーが大変なんじゃ

## 参考

https://pleiades.io/help/phpstorm/getting-started.html

https://pleiades.io/help/phpstorm/mastering-keyboard-shortcuts.html
PowerAutomateのExcelOnlineアクションで502エラーが発生

# 状況
とあるPowerAutomateクラウドフローにてそれまで問題なく動いていたExcelOnlineのアクションの箇所で急にエラーが発生した。
再試行を7回ほど繰り返した上で下記のようなエラーを吐いて終了していた。

    {
      "error": {
        "code": 502,
        "source": "japan-xxx.azure-apim.net",
        "clientRequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx",
        "message": "The response is not in a JSON format.",
        "innerError": "\"Service failed with unhandled exception of type Microsoft.ServiceFabric.Services.Communication.ServiceException\""
      }
    }

動いていた時から特にアクションに変更は加えていない。
502（Bad Gateway）エラーなので、Microsoftサーバー側のエラーであり、おそらくこちらから何もできないであろうと考えていた。

# 顛末
ことの顛末としては翌朝には何もしていないが特に問題なく動いていた。
フォーラムにも同日同様の書き込みがあり、そこでも時間が経てば解決したと書き込まれていた。
https://powerusers.microsoft.com/t5/General-Power-Automate/502-Bad-Gateway-Issue-in-Run-Script-Excel-Online-Business/m-p/2221388
Twitterのリンクをアプリで開くのが失敗する原因

とあるサイトを開発していたところ、Twitterのリンクをアプリで開くのが失敗するという問題が発生したので、それについて共有します。

## 環境

- Google Pixel 6
- OS：Android 13（ビルドTQ3A.230605.010）
- Twitterアプリ：v9.95.0-beta.2（安定版でも同様の問題が起こるようです）

## 問題の概要

突然ですが、次の2つのリンクを見てください。

PCのブラウザーでは、どちらも正しく私のTwitterアカウントのプロフィールが表示されます。

しかし、Twitterアプリがインストールされたスマホでは、［リンクA］は正しくアプリが開くものの、［リンクB］はアプリが一瞬だけ開いてすぐに閉じてしまいます。

:::note info
［リンクA］をTwitterアプリで開いたあと、**アプリを終了してから**［リンクB］を開いてみてください。
:::

- [リンクA](https://twitter.com/keita_roboin)
- [リンクB](https://twitter.com/keita_roboin/)

## 原因

原因は単純で、URLの末尾のスラッシュの有無です。先程のリンクは、次のようになっていました。

- リンクA：[https://twitter.com/keita_roboin](https://twitter.com/keita_roboin)
- リンクB：[https://twitter.com/keita_roboin/](https://twitter.com/keita_roboin/)

正しくアプリが開くリンクの末尾にはスラッシュがなく、アプリがすぐに閉じてしまうリンクの末尾にはスラッシュがあります。

URLは末尾のスラッシュの有無に関係なく同じWebページが表示されることが多いですし、実際にTwitterのWebクライアントもそうなっています。

また、Instagramのアプリはスラッシュの有無に関わらず正しく開くため、てっきりTwitterアプリでもスラッシュの有無は関係ないのかと思っていたのですが、どうやら違うようです。

## まとめ

この記事では、リンクの末尾にスラッシュがあるとTwitterのアプリで開くのが失敗する問題について紹介しました。

アプリによってはスラッシュの有無に関係なくリンクを開けますが、Twitterアプリではスラッシュがあると一瞬開いてすぐに閉じてしまうことに注意しましょう。
Next.jsをVSCodeでデバッグ中に出る Could not read source map の解決法

VSCodeでNext.jsのプロジェクトをデバッグ中、下記のエラーが出ます。

```
Could not read source map 
ENOENT: no such file or directory
```
![スクリーンショット 2023-06-30 102759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249097/e6226098-e692-8304-d548-3f68f7fa6c86.png)


これを解決するには .vscode/launch.json の設定を以下（変更前 → 変更後）のように設定します。


```json:launch.json(変更前)
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Next.js Client",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
    }
  ]
}
```


```json:launch.json(変更後)
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Next.js Client",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "resolveSourceMapLocations": [
        "${workspaceFolder}/**",
        "!**/node_modules/**"
      ]
    }
  ]
}
```


```json
      "resolveSourceMapLocations": [
        "${workspaceFolder}/**",
        "!**/node_modules/**"
      ]
```
によって明示的にSourcemapを探しに行く範囲を定義しているようですね。
```"!**/node_modules/**"```でnode_modulesディレクトリを探す範囲から除外しているのが良いのだろうかと思って

```json
      "resolveSourceMapLocations": [
        "!**/node_modules/**"
      ]
```

と書き直してlaunchすると、やはり Could not read source map は出なくなりましたので、そういうことのようです。
PythonでPowerPointからノートを取り出す

PowerPointのノート部分に書き込んだテキストを取り出して音声作成ツールにインポートするファイルを作りたく、方法を探していたら、Pythonでできそうだったので、やってみました。

実行環境：
Windows10（会社PC）
Python 3.10.11(Microsoft Storeからインストール)

やったことは以下になります。

#### 1．専用のPython実行環境作り
軽い環境でやりたかったので仮想環境を作成
※以降自分でつけた仮想環境名を「env_pptx」としてコマンド記載しています
```
cd [環境置き場]
python3 -m venv env_pptx
```
これで、環境置き場にenv_pptxというフォルダができて、個別にPython環境が作れるようになります。

#### 2．python-pptxのインストール
仮想環境の中で以下実行
「Successfully installed」が出てくればOK
```
cd [環境置き場]\env_pptx\Scripts
activate.bat
pip install python-pptx
```

#### 3．コード作成と実行
まずは、参考サイトに習いつつ、コードを実行したところエラーに・・・
```
Traceback (most recent call last):
  File "C:\pptx_env\lib\site-packages\pptx\compat\__init__.py", line 10, in <module>
    Container = collections.abc.Container
AttributeError: module 'collections' has no attribute 'abc'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\pptx_env\Scripts\test.py", line 1, in <module>
    import pptx
  File "C:\pptx_env\lib\site-packages\pptx\__init__.py", line 14, in <module>
    from pptx.api import Presentation  # noqa
  File "C:\pptx_env\lib\site-packages\pptx\api.py", line 15, in <module>
    from .package import Package
  File "C:\pptx_env\lib\site-packages\pptx\package.py", line 6, in <module>
    from pptx.opc.package import OpcPackage
  File "C:\pptx_env\lib\site-packages\pptx\opc\package.py", line 11, in <module>
    from pptx.compat import is_string, Mapping
  File "C:\pptx_env\lib\site-packages\pptx\compat\__init__.py", line 14, in <module>
    Container = collections.Container
AttributeError: module 'collections' has no attribute 'Container'
```
しかし、よく見るとcollectionsにabcがないと言っていたので、「import collections.abc」を入れたところエラー解消。
後は、標準出力をファイル書き込みにしたり、読み込みファイルを引数で取れるようにして、最終的には以下のコードを作成しました。
```python:test.py
import sys
import os
import collections.abc
import pptx

args = sys.argv
in_pptx= args[1]
out_dir = args[2]

prs = pptx.Presentation(in_pptx)
pptx_name = os.path.basename(in_pptx)
out_file = out_dir + "\\" + os.path.splitext(pptx_name)[0] + ".txt"

with open(out_file, 'w', encoding='UTF-8') as f: 
    for i, sld in enumerate(prs.slides, start=1):
        if i != 1:
            f.write('\n@@div@@\n') #ツールインポート用のページ区切り文字を挿入
        f.write(sld.notes_slide.notes_text_frame.text)
```
読み込む引数のエラー処理は入れる必要がありますが、ひとまず、
* 各ページのノートに「ノートコメントXページ目」と記載した5ページのPPTXファイルを準備（C:\test.pptx）
* 出力先フォルダを準備（C:\out_dir）
* 以下のコマンドで実行
python.exe test.py C:\test.pptx C:\out_dir

で以下のようなテキストファイルが出力できました。

```text:test.txt
ノートコメント１ページ目
@@div@@
ノートコメント２ページ目
@@div@@
ノートコメント３ページ目
@@div@@
ノートコメント４ページ目
@@div@@
ノートコメント５ページ目
```
これで少し作業がはかどるかも？

参考サイト
---
https://python-pptx.readthedocs.io/en/latest/
https://www.relief.jp/docs/python-pptx-extract-text-notes.html
MFC CWinApp::GetProfileStringの使い方

# 定義

アプリケーションのレジストリまたは.INI ファイル内の指定されたセクション内のエントリに関連付けられている文字列を取得できるらしい
```c++
CString GetProfileString(
    LPCTSTR lpszSection,
    LPCTSTR lpszEntry,
    LPCTSTR lpszDefault = NULL);
```
日本語で書くと、
```c++
CString GetProfileString(
    エントリがあるセクションを指定する NULL で終わる文字列へのポインター,
    文字列を取得するエントリを含む null で終わる文字列,
    初期化ファイルでエントリが見つからない場合のやつ);
```

# 使用例
実例のほうがわかりやすいので、まず設定ファイル

```ini:hoge.ini
...(略)

[Hoge sample]
Hoge data01 = test1
Hoge data02 = test2
Hoge data03 = test3
.

...(略)
```
ここにある文字列を取得できるみたい

```c++:hoge.cpp
CString Section = "Hoge sample";
CString Entry;
Cstring str;

//　Whileとかforで適当にループしてi++
//　Entryに文字列いれて
Entry.Format("Hoge data%02d", i+1);
//　iniファイルから文字列探してきてstrに入れる
str = AfxGetApp()->GetProfileString(Section, Entry, NULL);

// test1 test2 test3がstrに入ってくる
//　取得した文字列を利用できる
```
ターミナルからデータベースへ接続する方法

# データベースへ接続する
ターミナルからSSH接続した状態からスタート。
どこのディレクトリからでもいいので

```terminal
$ mysql -u your_username -p
```

パスワードを聞かれるので、入力する。

# データベースの特定のテーブルのレコードを確認する
以下のコマンドで、テータベース一覧を表示させる。
```terminal
mysql> SHOW DATABASES;
```

以下のコマンドで、特定のデータベースに切り替える
```terminal
mysql> USE データベース名;
```

以下のコマンドで、テーブル一覧を表示させる
```terminal
mysql> SHOW TABLES;
```

以下のコマンドで、特定のテーブルのレコード全件を表示させる
```terminal
mysql> SELECT * FROM テーブル名;
```

レコード件数が多いテーブルの場合、ターミナルだと全件は表示できなかったりする。そんな時は、以下で10件だけ取得することもできる。

```terminal
mysql> SELECT * FROM テーブル名 LIMIT 10;
```

# 特定のカラムで昇順、降順に表示させる
昇順で上位10件取得
```terminal
mysql> SELECT * FROM テーブル名 ORDER BY カラム名 ASC LIMIT 10;
```

降順で上位10件を取得
```terminal
mysql> SELECT * FROM テーブル名 ORDER BY カラム名 DESC LIMIT 10;
```
Docker を基本からまとめてみた【コンテナ】

## PORTとは？
インターネットで広く使われているTCPIPというプロトコルで使われている用語の１つ
```
//-p によって、ホストマシンのポートをコンテナのポートに紐付ける
docker container run -p [ホスト側のポート]:[コンテナ側のポート][イメージ]

sample : docker container run -p 3000:80 --rm nginx
```
## Dockerネットワークとは？
コンテナ同士の通信を簡単にしたり、不要なコンテナ同士の通信を防ぐために隔離する
```
//ネットワークの一覧を表示する
docker network ls
```
## ブリッジネットワークとは？
コンテナ同士の通信を橋渡しする橋のような役割をする

```
//ネットワークの詳細情報を表示する
docker network inspect[ネットワーク]

//新しいネットワークを作成する
docker network create[ネットワーク]

//指定したネットワークに接続したコンテナを起動する
docker container run --network[ネットワーク][イメージ]
```



## 参考サイト
[初心者OK！Docker入門＋応用：ゼロからでも実務で使えるスキルが身に付ける
](https://itplusjp.udemy.com/course/ok-docker/learn/lecture/36661966#overview)
AWS不要なリソースの削除を対応したのお話

# はじめに

こんにちは。IT業界15年、Web系10年のアラフォーです。

以前エンジニアの仕事を中心にやって来たが、現在スペシャリストとチーム長として働いてます。
昨年の10月から、プロダクトソリューション部に異動し、現在SREチームでSREの取り組みを頑張っています。

SREの施策の一環として、インフラコストの削減を取り組んでいます。
当初、一つAWSのアカウント上で、月額10000ドル超えている状態から、現在月額約3000ドル未満になりました。
対応した内容はほぼ不要なリソースを削除しただけですが、コスト削減する際に、確認観点としてご参考になれば幸いです。

# 前提
弊社のサービスでは、現在すでに IaC (Infrastructure as Code)を導入しましたが、以前IaCという概念がなかったので、インフラの構築は全てコンソール上で手動で構築してました。
システムリニューアル後、リソースがそのまま残され、無駄なコストが課金されてしまった。
当初のインフラ担当者が既に離任したので、残されたリソースをそもそも削除できるか確認できないため、リソースの利用状況を確認しながらコスト削減を実施しました。

全ての内容ではないが、対応した時の確認観点を重点的にピックアップし、共有させていただきます。

# 確認観点

### VPC
* 不要なNATゲートウェイが存在しているか否か
* 不要なVPCエンドポイントが存在しているか否か

### EC2
* 不要なインスタンスがあるか否か
* 不要なLoad Balancerが残ってるか否か
* スケールダウン(イン)できるインスタンスが存在しているか否か
* 夜間や休日に停止可能なインスタンスあるか否か
* 不要なEIPが残っているか否か
* 不要なEBSスナップショットがあるか否か

### RDS
* 不要なインスタンスが存在しているか否か
* スケールダウン(イン)できるインスタンスが存在しているか否か
* 夜間や休日に停止可能なインスタンスがあるか否か
* 不要なスナップショットがあるか否か
* バックアップの世代数が適切かどうか

### ElastiCache
* 不要なバックアップあるか否か
* スケールダウン(イン)できるインスタンスが存在しているか否か

### OpenSearch
* スケールダウン(イン)できるインスタンスが存在しているか否か

### S3
* 不要なバケットが存在しているか否か
* ログ系、ライフサイクルなど設定しているか否か
* 不要なバージョニングをしているか否か
* 適切なストレージクラスを選択できているか否か

### Cloudwatch
* ログの保持期間の設定が適切か否か
* 不要なダッシュボードが存在しているか否か
* 不要なアラームが存在しているか否か
* 使ってないリージョンが課金されるか否か

### Route53
* 不要なHostedZoneが存在しているか否か

### EventBridge
* 不要なイベント存在しているか否か

### ECS
* タスクのスペック適切になっているか否か

上記の内容を見ると、当たり前の事しかやってないと思いますが、当初、IaC化していないとの事と、担当者が既に離任しているので、リソースの状況を確認し、情報を整理し、他の部署と連携を取りながらコスト削減を実施しました。すごく苦労しました。
こういったゴミ掃除やコスト削減を今後楽に対応できるように、どうすれば良いかのを改めて考えてみました。

# 対策
### 環境毎、アカウントを分ける

今回対応したアカウントは、開発環境、検証環境、及び実際にお客様にサービスを提供している本番環境、全て同じのアカウントに構築された。
そのために、今回不要なリソースを削除した時に、そのリソースはどの環境のリソース、削除しても本当に大丈夫かとの確認が少し苦労しました。
もし、環境毎、アカウントを分けていれば、本番環境以外の対応は誤削除してもお客様への影響がないため、対応のスピードが速くなり、判断ももっとシンプルになると思います。

### IaC化
冒頭でも伝えましたが、当初まだIaC化の概念が導入されていないため、全て手動対応で構築された。そのため、削除対応した時も、全て手動で行なって、かなり大変な作業になっています。
IaC化することで、リソースの変更をコード上で確認できますし、削除の対応もかなり楽になります。

### タグ付け
タグ機能をうまく運用すれば、リソースをカテゴライズし、機能毎分類できます。
また、コストを確認する際に、タグで絞る事ができ、機能毎、どれぐらい料金かかるのも把握しやすくなります。

### 世代管理を適切に
今回の対象アカウントはかなり長く運用しているので、5年前以上のログやバックアップも残っているし、おそらく、そのログやバックアップも全然使われていない。
もし、最初に世代管理を設定していれば、バックアップの料金もかなり抑えられるし、わざわざゴミ掃除を対応しなくても済みます。

### 定期的に棚卸し
手動でバックアップしたRDSスナップショットやEC2スナップショットなど、自分で削除しないと、ずっと課金され続けてしまうので、定期的に確認し、不要なバックアップを削除しましょう。

### 検知の仕組みを導入
AWSコスト異常検出(AWS Cost Anomaly Detection)を導入することで、意図していない利用料の増加を早めに検知することができます。
また、AWS Budgetsを設定することで、AWS利用料金をモニタリングし、予算超えてしまったら通知され、早めに対策を打つことができます。

### マインド
自分にとって、一番重要なのは、マインドです。
仕組み上で検知や防ぐ事ができると思いますが、もし最初に構築する際に、過剰なスペックをしないように、一時的に検証で立てたリソースを忘れず削除するように、世代管理をきちんと考えるようにすれば、そもそもこういったゴミ掃除の対応は不要になるかもしれませんね！

# 最後
今回のAWSコスト削減の対応は、ほぼ不要なリソースの削除を対応しただけですが、意外とそのまま放置してしまったら、無駄に課金され続けてしまうので、きちんと意識しましょう！
AWSコスト削減する際に、ご参考になれば幸いでございます。
アマチュア無線の免許について - アマチュア無線のはじめかた

## この文章について

ある経緯で、アマチュア無線を始めることにしました。経緯については気が向いたら書くかもしれません。

本記事は以下の内容を含みます。

- 免許の種類と取り方、おすすめの免許

他に、気が向いたら書こうかなと思っている内容もありますが、これはまた後日。

- 周波数帯（いわゆるバンド）ごとの特徴
- 初めての機材選び
- 無線機以外に必要なもの
- JARLという組織について
- アマチュア無線の楽しみ方

なお、筆者は本記事執筆時点で従免（後述）の申請中段階のため、電波を発射できません。開局準備を進めている途中ですが、その過程にもおそらくこれからアマチュア無線を始める方にとって役に立つ情報があるはずだと思い、記事化します。と言いつつ半分自分用の備忘録です。
では早速本題へ進みます。

## 免許の種類と取り方、おすすめの免許

アマチュア無線局として電波を発射するためには免許が必要です。免許なく電波を発射すると法律により罰せられます。理由は、免許試験を取られる方ならその過程で勉強するはずなので割愛します。

### 2種類の免許

アマチュア無線使用に関係する免許には大きくわけて以下の2種類あり、**開局（電波を出す）には両方必要です**。

1. 無線従事者免許（従免）
    いわゆる「従免」と呼ばれる免許資格で、4級アマチュア無線技士〜1級アマチュア無線技士の4種別があります。免許されると、「免許証」が発行されるので、無線局運用時は必ず携帯しましょう。ただし、従免だけではまだ電波の発射はできません。
1. 無線局免許（局免）
    いわゆる「局免」と呼ばれる免許で、「従免」を持っている技士が「無線設備」を用意の上総務省に申請して得ます。無線設備の仕様等の情報を記載して申請し、開局基準を満たしている場合免許されます。免許されると「免許状」が発行されるので、無線設備の設置場所もしくは常置場所に保管しましょう。免許状にはコールサイン（無線局ごとに割り当てられる呼出符号）が記載されています。

なお、免許の取得順序は現時点で「従免」→「局免」と順番に取る必要があり、それぞれ申請から1ヶ月程度のリードタイムがあります。そのため開局にはトータルで最低2ヶ月程度のリードタイムが必要です。ただし、2023年9月25日以降は制度が変更になり、「従免」と「局免」の申請を同時にできるようになるとのことです（[ソース](https://www.tele.soumu.go.jp/j/others/amateur/dojishinsei/index.htm)）。

### アマチュア無線技士資格の4種別

「従免」には4つの種別があり、以下のようにそれぞれ許可される操作範囲、難易度、受験方法が異なります。

*※ 免責事項: 初心者向けに概略を解説することを趣旨とする本記事では操作範囲の詳細や正確性を保証しないので、正確な情報が必要な場合は必ず総務省の公開情報及び電波法令を参照してください。*

| 種別 | 操作範囲の概略 |
| --- | --- |
| 第一級アマチュア無線技士（略称: 1アマ） | アマチュア無線局としてのすべての操作 |
| 第二級アマチュア無線技士（略称: 2アマ） | 送信出力上限200W |
| 第三級アマチュア無線技士（略称: 3アマ） | 送信出力50W（ただし8〜18MHzは使用NG） |
| 第四級アマチュア無線技士（略称: 4アマ） | 〜8MHz, 21MHz〜30MHzは上限10W, 30MHz〜は上限20W, モールス信号はNG |

要は、大出力（=他の人に迷惑かけやすい）の操作をするには、より高度な技師資格を取得する必要があります。
3級、4級あたりは操作範囲が細かくてややこしいんですが、（技適マークのある）「4アマ用の市販無線機」とか「3アマ用の市販無線機」を買えばそもそもNG操作ができない仕様になっているのでご安心ください。

### これから資格を取る初心者におすすめなのは3アマ

アマチュア無線技士資格は、ステップを踏まなくても飛び級的に受験できます。極端な話、いきなり1級受験も可能なのですが、これから資格を取る方におすすめなのは4級を飛ばして**3級**の受験です。
理由は、以下のとおりです。

1. **受験方法の気軽さ**
    4級と3級は地域のCBTテストセンター（パソコン教室みたいな施設）でサクッと受験して帰ってこれます。申込みもオンラインですぐできるので、受験の手続きがとても簡単です。
1. **試験難易度の差があまりない**
    4級になくて3級にある試験範囲の差分は、国際法規とモールス符号だけです。これらもそんなに難しいものではないので、後述するメリットを享受するためにほんの少しだけ頑張って飛び級してしまうのが吉。
1. **操作範囲の拡大により選べる無線機が増えるメリット**
    残念ながら、今はこれから始めるアマチュア無線家にとってさほど良い時代ではありません。簡単に言うと、初心者におすすめできる無線機がとても少ないです（個人の見解です）。これが4級となると、元々少ない無線機の選択肢が送信出力の制限により更に狭まってしまうため、機材選びが難しくなってしまいます。少しでも制限を緩和するために、50W機まで選択可能な3級の取得がおすすめです。*機材選びについてはまた後日気が向いたら記事を書こうと思っています。*

### 受験方法

1級と2級については、受験方法が3級以下と異なる上にあまり調査していないのでここでは説明しません。

一般人が3級, 4級の従免を取るには大きく分けて2つの方法があるようです。1つ目は1〜2日の期間の「養成課程を修了する」方法、2つめは国家試験に合格する方法です。自動車運転免許の「自動車学校通い」と「一発試験」の違いみたいなものですね。

アマチュア無線の場合、国家試験（一発試験）に合格するのは難しくないので、こちらがおすすめです。試験内容も、常識的なモラルと高校物理程度の工学の知識があればさほど苦労しないです。ひたすら過去問を解くだけで合格できると思います。国家試験と言っても、実際には「Webで受験予約」し、地域のテストセンターでパソコンに向かって「CBT方式のテストを受ける」ぐらいの気軽さです。私はこの方法で受験しました。受験当日以外はすべてオンラインで予約→結果通知まで完結します。

「養成課程を修了する」方法は経験がないのでわからないのですが、おそらく「重要なポイント」をしっかりと教えてくれるので事前知識が少なくても取りやすい方法なのではないかと想像しています。ただ、この方法だと飛び級受験ができないとかだったと思うので注意が必要です。

## まとめ

読んでくださってありがとうございます。Web系の人（筆者自身もそう）がほしいようなアマチュア無線の入門情報が乏しいなと思ったのでとりあえず書いてみました。気が向いたら他のトピックについても書きます。
HumanActivityRecognitionImplement-Transformer1

論文のトレースを行った試行録。  

対象は以下の論文。  
「Inertial-Measurement-Unit-Based Novel Human Activity Recognition Algorithm Using Conformer」  

https://www.mdpi.com/1424-8220/22/10/3932  

論文の概要をまとめたものがこちら  

https://qiita.com/NakagawaRen/items/c2576ea4aa679d4416ba  

論文の趣旨はConformerだが、今回は副次的に実装されていたTransformerを実装する。  

なお、データ拡張については今回は行わず、次回以降の課題とする。  

4.2.2節によれば「inertial-based human activity recogniton with transformers」についてdim=256に変更したのみだという。

「inertial-based human activity recogniton with transformers」でのハイパーパラメータは以下。  
|params|d|L|head|Dropout rate|
|------|-|-|----|------------|
|value |64|6 |8 |     0.1    |

隠れ層の次元が64から256に変えるということは元の次元より大きくしたほうが良いということだろう。  

論文は以下。  

https://ieeexplore.ieee.org/document/9393889  

論文について概要をまとめたものがこちら  

https://qiita.com/NakagawaRen/items/c47ed3fce2f954b5612a  

以下のソースコードを参考に実装を行う。  

https://github.com/yolish/har-with-imu-transformer/tree/main

Conv.backboneでは入力チャネル数から出力チャネル数へカーネルサイズ1の畳み込みで変換を行っている。 
その際に活性化関数GERUに通す。この操作を4回行う。  
カーネルサイズ1の為、周辺のコンテキストは含んでいない。  
これはシーケンスの要素ごとの変換を線形、非線形を1セットにして計4回行っている。 
点単位畳み込み層と呼ぶらしい。ViTのハイブリッドモデルでも用いられている。 

コードで表すと以下のようになる。  
```python
class ConvBackbone(nn.Module):
    def __init__(self,input_ch,transformer_ch,):
        self.input_proj = nn.Sequential(nn.Conv1d(input_ch, transformer_ch, 1), nn.GELU(),
                                        nn.Conv1d(transformer_ch, transformer_ch, 1), nn.GELU(),
                                        nn.Conv1d(transformer_ch, transformer_ch, 1), nn.GELU(),
                                        nn.Conv1d(transformer_ch, transformer_ch, 1), nn.GELU())
        
    def forward(self,x):
        x = self.input_proj(x)
        return x
```





実装結果について。  
今回Optunaの探索区間・条件を以下のように設定した。  

- Epoch=10の場合におけるACCスコアが最も高いハイパーパラメータを探す  
- それぞれ離散的な値を設定し、場合の数は72000通りで探索回数は1000回

| 探索区間     | hidden_ch    | depth    | heads    | mlp_dim   | dropout    | emb_dropout | batch_size |
|--------------|--------------|----------|----------|------------|------------|-------------|------------|
| Min          | 3            | 3        | 3        | 256        | 0.01       | 0.01        | 16         |
| Max          | 15           | 8        | 10       | 2048       | 0.8        | 0.8         | 512        |


探索結果、最良のACCは0.9187573356807514であり、ハイパーパラメータは以下の様になった。
| パラメータ     | hidden_ch    | depth    | heads    | mlp_dim   | dropout    | emb_dropout | batch_size |
|--------------|--------------|----------|----------|------------|------------|-------------|------------|
| 値             | 15           | 3        | 3        | 1024       | 0.01       | 0.01        | 64         |

Optunaによって得られたハイパーパラメータを元に再度スクラッチから学習させた。  
結果、37EPOCHでEarly Stoppingし、ACC=0.91でローカルでの最良スコア0.89を更新した。  

今後の課題・展望としては、  

- dimを変更する埋め込み層の実装
- Optunaの探索条件を実際の学習と同じものにする（Early Stopping等）
- 学習計画（Warmup等）の実装
- データ拡張の実装
- コードのリファクタリング
 
を考えている。
【ワイ記法】プロンプトすらロクに考えずに、AIに技術記事を生成させる方法【関西型言語】

# 技術記事を書くのは大変

ワイ「ChatGPTが記事を書いてくれたらいいのにな・・・」
ワイ「でも、プロンプトを考えるのも大変・・・」
ワイ「要はワイ記法ってどんな書き方なのか、自分でもよく分かってないし・・・」
ワイ「それを言語化できないと、ChatGPTに命令できないし・・・」

# プロンプト自体も、ChatGPTに考えてもらおう

ワイ「せや、ChatGPTにこうお願いすればええんや」

![スクリーンショット 2023-06-30 9.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/e17c8d07-14e1-1af9-7f9c-6b5f39f2d24d.png)

ワイ「自分で自分のことを『彼』って言ってて草」
 
# ChatGPTの解答

![スクリーンショット 2023-06-30 9.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/8226baf0-aa64-d3f5-6023-4e9f18bc2615.png)

ワイ「お、なんか冒頭の部分が英語になってて読まれへん」
ワイ「翻訳してみよか」

> 【翻訳抜粋】
> 目に見える内容から山太郎の文体の特筆すべき特徴をいくつか挙げてみよう：

ワイ「**山太郎**って誰やねん」
ワイ「まぁ、ええわ」
ワイ「とにかく、ワイ記法の特徴をまとめてくれたな」
ワイ「大したもんや」


# その書き方で記事を書いてもらう

ワイ「ほな、その書き方で何か記事を書いてもらってみよか」
ワイ「記事のネタは何にしよか」
ワイ「あっ、せや」

>　ふわせぐ「全部 Store にブチ込めば Props のバケツリレーしなくて済みませんか」

ワイ「↑こんなことを後輩くんから質問されてたんやった」
ワイ「記事に書いて欲しいって言うてたわ」
ワイ「じゃあ、このテーマで行こか」

# ChatGPTに執筆依頼

![スクリーンショット 2023-06-30 9.49.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/12856efe-c0d8-97ce-a4d1-0951c99c8f3d.png)


# できた

![スクリーンショット 2023-06-30 9.50.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/5ad1b913-b171-a1ee-71bb-efa5897fd8e8.png)
![スクリーンショット 2023-06-30 9.50.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/b046a4fe-d289-deba-7d72-50f2a70d6a43.png)

ワイ「普通に分かりやすっ」

娘「すご〜い！」
**娘「これでもう、パパ要らないね！」**

**〜完〜**


# 完成した記事はこちら

けっこう分かりやすい記事が生成されました。
ぜひ読んでみてください！

[全部 Store にブチ込めば Props のバケツリレーしなくて済みませんか？](https://qiita.com/Yametaro/items/b5afec7b8e38208c68fb)
FormCheckApp

# FormCheckApp 仕様書

## 概要
FormCheckAppは、一般のユーザーが自身の筋トレのフォームをチェックし、プロのフォームとの違いやスピードを視覚的に確認するためのアプリである。AR技術を活用し、解剖学的なポイントの可視化により、ユーザーは正しいフォームに近づくことができる。

## ターゲットユーザー
一般のユーザーであり、トレーニングのフォームに改善を求める人々を対象とする。

## 主な機能
- プロのフォームの可視化と解剖学的なポイントの表示
    - プロのフォームをARを使用して可視化する。
    - 関節位置や軸、筋肉の活動、ボディラインなどの解剖学的なポイントを表示する。
    - ユーザーは自分のフォームとプロのフォームを比較し、視覚的なフィードバックを受ける。
    - 手首、肘、肩などの関節の位置を強調して表示する。関節はフォームにおいて重要な役割を果たすため、正確な位置をユーザーに示すことで、フォームの改善に役立つ。
    - 体の軸や重心の位置を表示する。体の軸は姿勢やバランスに影響を与えるため、適切な位置を示すことで、ユーザーのフォームの安定性や姿勢の改善をサポートする。
    - 特定の筋肉の活動を表示する。例えば、背筋や腹筋などの筋肉が適切に活動しているかを示すことで、ユーザーがフォームの正確性と筋肉の適切な使い方を理解できる。
    - ユーザーのボディラインを強調して表示する。これにより、フォームの全体的なバランスやアライメントを視覚的に確認できる。
    - 骨盤の傾きや背骨のカーブなど、関連する解剖学的な構造を表示することで、フォームの正確性と身体のバランスに対する理解を深めることができる。
- ユーザーのフォームとプロのフォームの一致度の評価と視覚化
    - ユーザーのフォームとプロのフォームの一致度を計算し、評価する。
    - 一致度の値を表示し、線の色やマーカーの変化などで視覚的に一致度を示す。
    - ユーザーはフォームの改善を追跡し、プロのフォームに近づけることを確認できる。
- 骨格や身体的特徴に基づく個別化機能の導入
    - ユーザーの骨格や身体的特徴を入力し、個別化されたフォーム修正ポイントやアドバイスを提供する。
    - ユーザーは個別化されたフィードバックを受けて、効果的なフォーム改善を行う。
- スタートポジションの音声案内
    - ユーザーに正しいスタートポジションに移動するように音声案内を提供する。
    - 適切な姿勢や位置を維持するための指示やアラートを提供する。
- フォーム改善のフィードバックと履歴
    - ユーザーはフォームの改善に関する個別のフィードバックを受けることができる。
    - 履歴を保存し、ユーザーのフォーム改善の進歩を追跡する。
    - フィードバックや進歩の可視化を通じて、ユーザーのモチベーションをサポートする。
- ユーザープロファイルの作成とカスタム設定
    - ユーザーは自身のプロファイルを作成し、骨格や身体的特徴、制約などの情報を入力する。
- 専門家へのコンサルテーション機能
    - ユーザーは専門家とのコンサルテーションやアドバイスの提供を受けることができる。
- ユーザー教育と解説
    - ユーザーにフォームの重要性や解剖学的なポイントについての教育を提供する。
- ユーザーインターフェースのシンプルさと使いやすさ
    - アプリの操作性やユーザーインターフェースのシンプルさに重点を置く。
- ユーザーフィードバックの収集
    - アプリを使うユーザーからのフィードバックを積極的に収集し、機能や使いやすさの改善に反映させる。

ユースケース
---
**トレーニングセッションの開始**
ユーザーはジムでアプリを起動し、動画撮影モードに入る。

**フォームチェックの実行**
アプリはユーザーに正しいスタートポジションに移動するように音声案内を提供する。
ユーザーは音声案内に従ってスタートポジションに移動し、動作を行い、フォームをチェックする。

**フォームの可視化と一致度の確認**
プロのフォームに基づいて、関節位置、軸、筋肉の活動、ボディライン、関連する解剖学的な構造をAR上に表示する。
ユーザーのフォームとプロのフォームの一致度を計算し、一致度の値や線の色などを視覚的に表示する。

**結果の表示とフィードバック**
ユーザーは一致度の結果やフォームの改善に対するフィードバックを確認する。

使用技術とツール
---
- iPhone（iOSプラットフォーム）
- AR技術による解剖学的なポイントの可視化
- プロの体にセンサーを装着して位置情報を取得する（具体的なセンサーについては追加の要件定義が必要）
- 機械学習によるフォーム解析

ユーザーインターフェース要件
---
- 動画撮影画面：トレーニングセッションの開始とフォームの撮影ができるインターフェース
- AR出力画面：ユーザーのフォームとプロのフォームをARで表示し、解剖学的なポイントを強調して視覚的に確認できるインターフェース
- 一致度の結果やフィードバックを表示するインターフェース

データの保存とバックエンド要件
---
- 撮影データとフォーム正解率の保存
- ユーザー情報や機械学習モデルの管理（具体的な要件については追加の詳細が必要）

# 開発検討事項

## システムアーキテクチャの設計
- アプリの機能や要件に基づいたシステムアーキテクチャの設計を行う。

## ユーザープロファイルとカスタム設定
- ユーザープロファイルの作成とカスタム設定に関する詳細を検討する。

## スタートポジションの音声案内
- ユーザーに正しいスタートポジションに移動するように音声案内を提供する仕組みを検討する。

## フォーム改善のフィードバックと履歴
- ユーザーがフォームの改善に関する個別のフィードバックを受ける仕組みを検討する。
- 履歴を保存し、ユーザーのフォーム改善の進歩を追跡する方法を検討する。

## 専門家へのコンサルテーション機能
- ユーザーが専門家とのコンサルテーションやアドバイスの提供を受ける仕組みを検討する。

## ユーザー教育と解説
- ユーザーにフォームの重要性や解剖学的なポイントについての教育を提供する仕組みを検討する。

## ユーザーフィードバックの収集
- ユーザーからのフィードバックを積極的に収集するための仕組みを検討する。
全部 Store にブチ込めば Props のバケツリレーしなくて済みませんか？

※100パーセントChatGPTで生成した記事です。


# とある休日

娘「パパ」

ワイ「なんや？娘ちゃん」

娘「あのね、お友達が」
娘「全ての状態を Store にブチ込めば Props のバケツリレーをしなくて良いって言ってたんだけど、それって本当にそうなの？」

ワイ「そうなんや」
ワイ「全ての状態を Store にブチ込めば確かに Props のバケツリレーをしなくて済むやろうけど、それがベストの解答かはちょっと考えてみる必要があるな」

娘「え？なんで？」

ワイ「それを説明するためには、まず状態管理ライブラリについて理解する必要があるんや」
ワイ「例えば、React の世界では Redux, Recoil, Jotai などの状態管理ライブラリがあって、これらは全ての状態を Store に保持することでコンポーネント間の状態の共有を容易にするんや」
ワイ「だけど、これらのライブラリに依存したコンポーネントを作った場合、そのコンポーネントの再利用性は低くなる。また、そのコンポーネントを使う場合はその状態管理ライブラリも一緒に使う必要があるから、使いづらくなる可能性があるんや」




```tsx
// Reduxに依存したボタンコンポーネント
import { useDispatch } from 'react-redux';
import { actionCreator } from './actions';

const ButtonWithRedux: React.FC = () => {
  const dispatch = useDispatch();

  return (
    <button onClick={() => dispatch(actionCreator())}>Click me!</button>
  );
};

```


ワイ「↑これは Redux に依存したボタンコンポーネントの例や。このコンポーネントを使うためには Redux の設定も必要になるし、他のプロジェクトで再利用するのも難しいやろうな」

娘「なるほど、そういうことだったんだ」

ワイ「そや。だからこそ、コンポーネントには「ボタンが押されたら何をするか」という関数をpropsで渡す方が、再利用性が高く使いやすいと言われてるんや」




```tsx
// propsで関数を渡すボタンコンポーネント
interface ButtonProps {
  onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ onClick }) => {
  return <button onClick={onClick}>Click me!</button>;
};
```


ワイ「↑これは props で関数を渡すボタンコンポーネントの例や。このコンポーネントはどんな状態管理ライブラリを使っているプロジェクトでも再利用することができるんや」

娘「そうなんだ、勉強になるわ」

ワイ「ただ、全てを props で渡す設計にすると、「Props のバケツリレー」問題に直面するかもしれんな。これは、親コンポーネントから子コンポーネント、さらにその子コンポーネントへと、props を伝えていくのが面倒になるという問題や」
ワイ「それを解決するために、状態管理ライブラリを用いて状態を Store に保持し、それを必要なコンポーネントで直接利用するという方法もあるんや」
ワイ「ただ、先ほども話したように、全ての状態を Store に持たせるとコンポーネントの再利用性が低くなるから、どの状態を Store に持たせるべきかは設計の段階でよく考える必要があるんや」

娘「なるほど、全部 Store にブチ込むのは簡単そうだけど、それだと再利用性が低くなるし、どうするかは設計の段階でよく考える必要があるんだね」

ワイ「せやな。だから、「全部 Store にブチ込めば Props のバケツリレーしなくて済む」というのは一理あるけど、それがベストの解答かというと、必ずしもそうではないんや」

娘「わかった、ありがとうパパ！」

ワイ「おお、ええで！」

# 追記

この記事は、全て**ChatGPT**で生成した実験記事です。
生成方法は以下の記事で解説しています。

[【ワイ記法】プロンプトすら考えずに、AIに技術記事を生成させる方法【関西型言語】](https://qiita.com/Yametaro/items/52ab0303860483120775)
AppIconの自動生成

# はじめに
AppIconの設定で、assets上にiphoneの端末サイズを考慮して10種類以上のサイズを用意する必要があったのですが、Xcode14になってから1つのサイズだけしか入力できないようになっていました。

今まで![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485517/e0e76e75-9d79-8419-dba5-49a22a27d927.png)

Xcode14![スクリーンショット 2023-06-30 9.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485517/c5ed4e7f-fe8f-00b2-7729-ae47cf73d423.png)

# AppIconの自動生成
どうもXcode14からは1024x1024ピクセルのアイコン1つを入れるだけでよくなったそうです。Xcode側で自動的にサイズを調整してくれるようになったようなので、全部のサイズを用意しなくて良くなったみたいです。これは手間が省けて朗報ですね！