OmniAICreator/Qiita-1.07M huggingface dataset:
Nextjs レンダリングについて整理してみた

# 目次
- SSG(データ付き)
- SSR
- SSG + CSF(データなし)

# 用語
*First Contentful Paint (FCP)
→ウェブページの最初の要素が表示されるまでの時間を測定
*Largest Contentful Paint (LCP)
→ページの読み込み中に表示される最も大きな要素が表示されるまでの時間を測定
*Time To First Byte(TTFB)
→ウェブページのリクエストから最初の応答が返るまでの時間
*hydrate
→HTMLとJSの紐付け
*CSR
→クライアントサイドレンダリング


### SSG(Static Site Generation)
---
静的サイト生成
概要
事前にウェブページを生成し、静的な形式で提供

![スクリーンショット 2023-07-04 14.25.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675254/5501fe02-9cc9-08e0-377f-9f729ef4cb66.png)
1. user request
1. vercelからHTML, jsonデータのレスポンス
1. jsのレスポンス
1. ユーザに表示完了
1. hydrate(htmlとjsの紐付け)
1. ユーザが操作可能になる

### SSR(Server Side Rendering)
---
サーバーサイドレンダリング
概要
サーバーで「データ取得」「HTMLレンダリング」を行う

![スクリーンショット 2023-07-04 14.47.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675254/8ee0136e-844e-16ad-d190-394c8c4bc041.png)

1. user request
1. vercelのlambdaが走りデータをデータベースから取得&HTMLレンダリング
1. HTMLをブラウザでparseし、ブラウザで表示
1. 以下省略

### SSG+CSF(Client Side Fetching)
---
概要
SSGとクライアントでのfetchを合わせた形(staticデータなし)
- 一つ目のSSGでの静的jsonデータはなしでクライアントでデータをフェッチ
![スクリーンショット 2023-07-04 15.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675254/a418acdb-5d3f-a1c5-1066-344fe0945fa5.png)



1. user request
1. 同様にSSGで静的なHTML、JSを取得&hydrate
    - ここでFCPをユーザに表示
1. Interactiveでユーザが操作可能になってからデータフェッチ
- CSFの特徴として他二つのレンダリングと違い、FCPとLCPのタイミングが分かれる。
vsftp + FileZila でファイルを送れない

## 状態
- FileZilaでファイルを送ろうとするとこんな感じのエラーが出てくる
```
レスポンス:    550 Permission denied.
エラー:    致命的なファイル転送エラー
```
![Screenshot 2023-07-04 14.46.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084346/f5dd65d8-7475-675e-d092-a2c4aec4e878.png)

## 解決策

```
sudo vi /etc/vsftpd.conf
```
write_enable=YESのコメントを外す
```
write_enable=YES
```
Azure OpenAI Serviceのラーニングパスまとめメモ

Azure OpenAI ServiceのMicrosoft Learning Pathが公開されているのでまとめメモです（2023/7/3時点）。最初のモジュール以外はまだ日本語化されていないので現時点では英語で取り組む必要があります。Azure OpenAI Serviceをまだ使用したことがない人が演習を交えながらできることを理解するのにちょうどよい内容になっています。

https://azure.microsoft.com/en-us/blog/explore-the-benefits-of-azure-openai-service-with-microsoft-learn/

| モジュール | 概要 | モジュールの目的 |
|:-|:-|:-|
| [Azure OpenAI Service で作業を開始する](https://learn.microsoft.com/ja-jp/training/modules/get-started-openai/)（43分） | このモジュールでは、Azure OpenAI Service ソリューションの構築を始めるためのスキルについてエンジニアに説明します。 | Azure OpenAI Service リソースを作成し、Azure OpenAI の基本モデルの種類を理解します。Azure OpenAI Studio、コンソール、または REST API を使って基本モデルをデプロイし、Studio のプレイグラウンドでそれをテストします。プロンプトの入力候補を生成し、モデルのパラメーターの管理を始めます。|
| [Build natural language solutions with Azure OpenAI Service](https://learn.microsoft.com/en-us/training/modules/build-language-solution-azure-openai/)（57分） | このモジュールでは、Azure OpenAI Serviceと統合したアプリケーションの構築を始めるためのスキルについてエンジニアに説明します。 | Azure OpenAI Serviceを独自のアプリケーションへの統合します。アプリケーションで利用可能な様々なエンドポイントの違いを理解します。REST APIと言語固有のSDKを使用してプロンプトに対するコンプリ―ションを生成します。|
| [Apply prompt engineering with Azure OpenAI Service](https://learn.microsoft.com/en-us/training/modules/apply-prompt-engineering-azure-openai/) （63分）| Azure OpenAIのプロンプトエンジニアリングは自然言語処理モデルのプロンプトを設計する技術です。このプロセスにより応答の制度と関連性が向上しモデルのパフォーマンスが最適化されます。 | Azure OpenAIモデルのパフォーマンスを最適化するためのプロンプトエンジニアリングの概念とその役割を理解する。AIモデルをよりよく利用するためのプロンプトの設計と最適化の方法を知る。明確な指示を含み出力構成を要求し、文脈的なコンテンツを使用してモデルの応答の質を向上させます。 |
| [Generate images with Azure OpenAI Service](https://learn.microsoft.com/en-us/training/modules/generate-images-azure-openai/)（50分） | Azure OpenAI ServiceにはDALL-Eモデルが含まれており、自然言語のプロンプトに基づいてオリジナルの画像を生成するために使用できます。 | Azure OpenAI ServiceにおけるDALL-Eの機能を説明します。Azure OpenAI StudioでDALL-Eプレイグラウンドを使用します。Azure OpenAI RESTインターフェースを使用してDALL-E画像生成をアプリに統合します。|
| [Generate code with Azure OpenAI Service](https://learn.microsoft.com/en-us/training/modules/generate-code-azure-openai/)（38分） | このモジュールはエンジニアがAzure OpenAI Serviceを使ってコードを生成し、改善する方法を紹介します。| 自然言語プロンプトを使ってコードを書きます。ユニットテストを構築しAIモデルを使って複雑なコードを理解します。既存のコードに対しコメントとドキュメントを生成します。|
【ServiceNowow】GlideOAuthClientを使用してトークンを取得する際の小ネタ（ProfileIDについて）

### はじめに
GlideOAuthClientを使用して外部連携先システムのトークンを取得する処理を作成していた際、ProfileIDを指定する方法について少し調査をしたので、小ネタではありますが情報をまとめます。

### GlideOAuthClientを使用してトークンを取得する方法
アクセストークンとリフレッシュトークンを取得するスクリプトは以下のKBを参考に作成できます。

https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0791131


### ProfileIDを指定する・・・
上記KBの４行目にProfileIDを指定するように記載されています。
これはOAuth Entity ProfileのSysIDを指します。

画面を見てのとおりOAuth Entity Profileは複数登録することができるので、その場合はIDを指定する必要がある、ということです。

IDを指定しない場合（KBの4行目を丸々書かない場合）は「Is default」が「true」になっているプロファイルを参照します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/14ec0d3d-ffb3-9a05-c979-f35836955df9.png)

### 「Is default」の制御
OAuth Entity Profileに「Is default」が「true」であるレコードを複数行作成しようとしたところ、下図のようにエラーとなるよう制御が入っていました。
「Is default」が「true」になるレコードは最大１つになるよう制御されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/aada5d68-f2e1-7f36-abd4-16dbba166f5f.png)


ちなみに「Is default」をすべて「false」にすることも可能でした。
この場合は、想定外のエラーが出る可能性があるのでKBのとおりにProfileIDのSysIDを指定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/6c06d1d5-049e-40cb-5287-58ecff9d5493.png)


### 終わりに
トークンの取得処理を実装する場合は、どのプロファイルの「Is default」がtrueになっているか、またはどのプロファイルを使用したいのか把握しておく必要があることがわかりました。
備忘録：m1 MacBookAirを再起動したらrubyのversionがシステムのもので固定されてrbenv localで動かせなくなり、rails sが効かなくなった件

## なぜかrails sが効かない。PC再起動までは動いていたので、rails gemがないはずもない。
```
kishimotokohei@MacBook-Air-3 narou-osusume-cloud9 % rails s
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.
```

## railsプロジェクト内でrubyのバージョンを確認
```
kishimotokohei@MacBook-Air-3 narou-osusume-cloud9 % ruby -v
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin21]
```

あれ？バージョン違うな。と、ここでrbenv localしてもバージョン変わらず。

## どのrubyを使っているかを確認→システムのだった。
```
kishimotokohei@MacBook-Air-3 narou-osusume-cloud9 % which ruby
/usr/bin/ruby
```

## zshrcを再読み込みし、rubyのパスを確認。rbenvの方のパスを見に行っていることを確認
```
kishimotokohei@MacBook-Air-3 ~ % source ~/.zshrc 
kishimotokohei@MacBook-Air-3 ~ % which ruby
/opt/homebrew/opt/rbenv/shims/ruby
```

## バージョンを確認
```
kishimotokohei@MacBook-Air-3 narou-osusume-cloud9 % ruby -v
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [arm64-darwin21]
```

## rails s→動いた！よかったよかった。
```
kishimotokohei@MacBook-Air-3 narou-osusume-cloud9 % rails s
=> Booting Puma
=> Rails 7.0.4.2 application starting in development 
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.5 (ruby 3.2.1-p31) ("Birdie's Version")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 2454
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
```
［メモ用］AmazonLinux2023でRubyをインストールする


AWSを学習している段階でEC2のAMIとしてAmazonLinux2を選択する方が多いと思います。
実際にネット上の記事もAmazonLinux2に関する記事が多いです。
ただ、2023年からAmazonLinux2023が一般公開され、今後はこちらが主流になりそうなので、今回AmazonLinux2023でRubyの環境構築をしてみました。

※今回の記事は自分のメモ用です。
※インスタンスの選択やSSH接続等については触れません。

# 1. はじめに
AmazonLinux2023を選択してRubyをインストールしたい方は「t3.micro」は選択しない方が無難です。
無料枠なので使いたい気持ちもよくわかりますが、何度か試した結果Rubyのインストールが安定しません。
これは後で後述しますが、絶対にできないわけではないのでこちらの選択は自己責任でお願いします。
また、AmazonLinux2023でも「yum」は使えます。
fedoraベースなので本来は「dnf」を使用すべきですが、こちらはよしなに変換してくれるみたいです。
もちろん「dnf」も使用可能です。
なお、本記事では「yum」を使用します。

# 2. 最初にアップデート
EC2にSSHでログインしたらまずはアップデートを行います。
```sh
sudo yum update
```

# 3. 必要なプラグインをインストール
Rubyをインストールする前に必要なプラグインをインストールします。
もしかしたら不要なものもあるかもしれませんが、主要なプラグインなのでインストールしておきます。
必要に応じて削除してください。（例えばmysql関連は人によっては不要です）
```sh
sudo yum -y install git make gcc-c++ patch openssl-devel libyaml-devel libffi-devel libicu-devel libxml2 libxslt libxml2-devel libxslt-devel zlib-devel readline-devel ImageMagick ImageMagick-devel mysql mysql-server mysql-devel
```

# 4. Node.js & yarn をインストール
```sh
curl -sL https://rpm.nodesource.com/setup_14.x | sudo bash -
```
```sh
sudo yum -y install nodejs
```
```sh
curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
```
```sh
sudo yum -y install yarn
```

# 5. rbenvをインストール
```sh
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
```
```sh
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
```
```sh
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
```
```sh
source .bash_profile
```

# 6. ruby-buildをインストール
```sh
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

# 7. Rubyをインストール（t3.small以上の方向け）
先に伝えたように、こちらはt3.small以上を選択した方向けです。
t3.microを選択した方は次に進んで下さい。
```sh
rbenv install -v 3.2.2
```
```sh
rbenv global 3.2.2
```

# 8. Rubyをインストール（t3.microの方向け）
t3.microだと何がダメなのか？
結論
<b>/tmpディレクトリの容量不足でエラーが起こる</b>
ということで解決策です。
```sh
TMPDIR="${PWD}/tmp" rbenv install -v 3.2.2
```
```sh
rbenv global 3.2.2
```

現在の作業ディレクトリにある "tmp" フォルダを一時ディレクトリとして指定することで容量不足を解決できます。

# 9. 最後に
今回は自分のメモ用なので詳細は書けませんでしたが、これの解決に本当に時間を要したので誰かの救いになったら嬉しいです。
HackerOneで脆弱性報告してから、報奨金を受け取るまでの流れ

# はじめに
HackerOne経由でSlackに脆弱性報告しました。
その報奨金を得たので備忘録として。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/348b2cf4-e289-66a4-7f37-1a77fc51539a.png)


# 報告した脆弱性の概要
偽のURLに飛ばせる（フィッシング）に悪用できる脆弱性
CVSS評価値は大体Lowくらい。

このprofile urlをクリックすると、何も確認画面が表示され無いため
うっかりさんを任意の悪性URL(画像では`evil.example.com`)に誘導できるというもの
（実URLがどこにも表示されないので避けようがない）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/8a0814a7-3be3-bc45-3c50-8a30f45fd306.png" width="50%">

実際の設定内容は、evilに飛ばすようになっている。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/eaad866e-759e-bbd5-026e-658365bc771a.png" width="100%">

2023年7月4日時点では、確認プロンプトが立ち上がるため攻撃は不能に成っています。



# 基本的な手順
- 脆弱性を報告する（DeepL翻訳を使う）
- 脆弱性の認定をされるまで待つ
- 認定されたらメールが飛んでくる
    - 「脆弱性認定されたけど、まだ誰にも言わないでね！」と言う趣旨のメールが飛んでくる。
    - ※お金をもらえる代わりの守秘義務なので守りましょう
- W-8BENを書く
    - 税に関するやつです。
    - 前述したメールを受信すると書けるようになります。
    - [解説サイト](https://jp.cpb.bank/faq/about-w-8ben)が有るので参考にしつつ書きます。
- 振込先口座を設定します。
- 振り込まれるまで静かに待ちます
    - 課題チケットに「解決したよ！ありがとう！」っていうメッセージが飛んできます。
    - それが来たら大体次の週くらいまでには振り込まれてます。
 
# 振込周りの設定
解決したよメッセージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/13c982b0-fab4-11a9-099a-554ddfb52a1e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/851779b6-09af-e6c2-bc12-dcbd68424ee5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/aa7912e4-aeac-9014-4ec8-d697f1e630ab.png)

# 最後に
脆弱性報告してお金を稼ごう。
でも雑所得になると思うので税務署への申請（確定申告）は忘れずにしないといけないよね。
自動でやってくれると良いんだけどなぁ。
マイナンバーカードでもっと便利になって欲しい。
チャレンジレスポンス

# チャレンジレスポンス認証
* サーバが送信したチャレンジデータに対し、```アクセスを行うクライアントが取り決めた規則に基づいてレスポンスデータを生成し、それをサーバが確認する```方法。双方で保存してあるパスワードはそのまま使わないため安全性が高い。
# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8

* チャレンジ&レスポンス方式とは、パスワードの認証に用いられる方式のひとつで、サーバーから送られてくる暗号鍵（チャレンジ）を受け取り、それに演算処理を組み合わせたデータ（レスポンス）を返すことによって暗証を行う方式のことである。```主にワンタイムパスワードの手法として用いられる```。
チャレンジ&レスポンス方式においては、はじめにサーバーがクライアントに対して「チャレンジ」と呼ばれる値を送る。チャレンジを受け取ったクライアントは、チャレンジの値にそれぞれ保有しているパスワードを掛け合わせて演算処理を行い、その結果として生成されたハッシュ値を「レスポンス」として返す。サーバーは、クライアントから返ってきた値をサーバーが自ら生成したレスポンスと照合し、ふたつのレスポンスの値が一致していれば認証を通す。
チャレンジとして送られてくる値は毎回ランダムな値で変更される。そのため、生成されるレスポンスの値も毎回異なる。そのため、チャレンジ&レスポンス方式にはチャレンジやレスポンスが盗聴されたとしても認証上の致命的な問題が生じないという利点がある。
# 出典
https://www.sophia-it.com/content/%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%26%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E6%96%B9%E5%BC%8F#:~:text=%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%26%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E6%96%B9%E5%BC%8F%E3%81%A8%E3%81%AF%E3%80%81,%E3%81%98%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E5%88%A9%E7%82%B9%E3%81%8C%E3%81%82%E3%82%8B%E3%80%82

# 欠点
メールで受信するワンタイムパスワードが狙われる
その日、そのタイミングでしか使うことのできないワンタイムパスワードは、メールやSMSで通知する仕組みが主流でした。しかし、パソコンやスマートフォンをウイルスに感染させることで、メールやSMSが受信する情報まで盗み取る被害が発生しています。
2013年にインターネットバンキングの不正送金による被害額が増加したのは、ウェブメールに送信されたワンタイムパスワードが漏洩していることが原因だと考えられています。
ユーザーとオンラインサービスとの通信の間に入り込み情報を盗み取るこの手法は、```中間者攻撃とも呼ばれ、独立行政法人情報処理推進機構ではその危険性を指摘```しています。
# 出典
https://www.secioss.co.jp/%E3%83%AF%E3%83%B3%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%8C%E5%8D%B1%E9%99%BA%E3%81%AA3%E3%81%A4%E3%81%AE%E7%90%86%E7%94%B1%E3%80%82%E5%8A%B9%E6%9E%9C%E7%9A%84/#:~:text=%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%A7%E5%8F%97%E4%BF%A1%E3%81%99%E3%82%8B,%E6%8C%87%E6%91%98%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82
IBM Db2 コマンド集

# コマンド集

インスタンスの一覧を確認します。
```db2ilist```
現在のインスタンスを確認します。                  
```db2 get instance```  
「TESTDB」というデータベースを作成します。      
```db2 create db TESTDB```    
データベースの一覧を確認します。
```db2 list db directory``` 
「TESTDB」というデータベースに接続します。    
```db2 connect to TESTDB```    
「TEST_TABLE」というテーブルを作成します。 
```db2 create table TEST_TABLE (MYNUMBER CHAR(12) NOT NULL, MYNAME CHAR(100))```
テーブルの一覧を確認します。                         
```db2 list tables```           

「TEST_TABLE」というテーブルを削除します。
```db2 drop table TEST_TABLE```  
テーブルの一覧を確認します。
```db2 list tables```
「TESTDB」というデータベースから切断します。              
```db2 terminate```   
「TESTDB」というデータベースを削除します。            
```db2 drop DB TESTDB```   
データベースの一覧を確認します。        
```db2 list db directory```       


インスタンスの一覧を確認します。
```db2ilist``` 
インスタンスを停止します。       
```db2stop```  
「DB2」というインスタンスを削除します。       
```db2idrop DB2```
インスタンスの一覧を確認します。   
```db2ilist``` 
「DB2」というインスタンスを作成します。       
```db2icrt DB2```
インスタンスの一覧を確認します。    
```db2ilist```     
インスタンスを起動します。  
```db2start```       


## 参考サイト
・[Windows Server 2019にIBM Db2 Community Edition（v11.5）のインストール](https://note.com/w2i/n/n00e3b7e25422)
・[Windows版 IBM Db2 Community Edition（v11.5）を使ったデータベースを作成](https://note.com/w2i/n/n992b50d917f4)
・[DB2 設定方法](https://www.microlab.jp/xcutedoc/documents/sup_db/DB2.htm)
・[DB2の環境構築手順をコマンド単位で丁寧に書いてみる](https://qiita.com/bython/items/5d1a73c718ae08edb797)
売上予測と自動でレポートを作成するwebアプリを作りました

![sales_forecast_report_top_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490834/ddb1bad6-7adb-fde6-96da-bb76f9ed6902.png)

ExcelデータとGmailアドレスを使って、売上予測のレポートを自動で作成をしてくれます。


![send_sales_forecast_report_gmail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490834/7ff84386-f3cf-33b8-5123-356ca1bdbbce.png)
完成したレポートはgmailに届きます。
　　





![florian-olivo-4hbJ-eymZ1o-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490834/7fa7f6b2-e3d0-6673-942d-e43741a166b9.jpeg)


【使用技術】
Python,Flask,HTML,CSS,Heroku
　



【主な機能】
レポート作成、売上予測、gmail送信、業務自動化
　


【どこまで作ったのか？】
1人で作りました。

　
![maranda-vandergriff-7aakZdIl4vg-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490834/98253e7a-5cdd-bf8e-3b24-2d82fce56918.jpeg)

【こだわったポイント】
飲食業や小売業など土日に売上がある業種の売上を正確に予測するため、データを日付でキーとするのではなく、曜日ごとにキーとしてデータを結合しました。

　
　

【苦労したポイント】
WEBアプリをどこから作ればいいのかわからなくなり苦労しました。

　
　
【苦労したポイントの改善】
漠然とした考えで作るのではなく、アプリに必要なことを書き出して簡単にできることから順番に実装していきました。

　

　

![absolutvision-82TpEld0_e4-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490834/3c748267-92a7-f7ad-ea96-8a8bd9289b9d.jpeg)

　

　

【作ろうと思ったきっかけ】
SFが好きでAIに興味があり、それをきっかけにアプリを作りました。
売上予測にした理由は今までしてきたアルバイトの現場が業務効率と自動化するにはどのようなことが必要か考えたことがきっかけです。

　
　
【足りないと自覚している機能】
ユーザーが自由に選択できる機能が少なく、柔軟性に欠ける点です。
例えば、棒グラフから円グラフへの変更や、グラフを増やすなどの設定が難しく、ユーザーの選択の自由度を高めることが課題です。

　
　
【今後の対応方法】
ユーザーがどのようにサービスを使うのか客観的に考え、それに対応した機能を実施したり、コードの修正を行うことです。
ログのプレースホルダとパラメータをバインドさせるツールを作ってみた(VBA)

パラメータをプレースホルダにバインドさせるツール
実際に実行前後のスクショを見て貰うとどういったモノなのか理解が早い

実行前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/add9c3a1-5b5f-476b-3386-4faa797b26e3.png)

実行後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384409/449efcbd-5885-1cf3-59bb-94183a64c1a6.png)

B1セルのSQLにB2セルの内容を順にバインドしていき、結果をB3セルに出力する。
エクセルは適当に作成してもらって、実行ボタンは追加してもしなくてもいい。

```vb:VBA
Dim sql As String
Dim param As String
Dim bracketRight As Integer
Dim bracketLeft As Integer
Dim result As String

Sub SQL生成()

    '値の取得
    sql = Range("B1").Value 'SQL
    param = Range("B2").Value 'パラメータ

    '行頭行末の空白をトリム
    param = Trim(param)

    '入力チェック
    question = InStr(sql, "?")
    If question = 0 Then
        MsgBox "SQLに「？」が含まれていません。"
        End
    End If

    bracketRight = InStr(param, "[")
    bracketLeft = InStr(param, "]")
    If bracketRight = 0 Or bracketLeft = 0 Then
        MsgBox "パラメータが[]で囲われていません。"
    End If

    '[]を削除
    param = Mid(param, bracketRight + 1, bracketLeft - bracketRight -1)

    '配列にして格納
    sqlList = Split(sql, "?") '「?」区切り
    paramList = Split(param, ", ") '「, 」区切り

    'SQLとパラメータ数一致のチェック
    If UBound(sqlList) -1 <> UBound(paramList) Then 'メモ：SQLはパラメータより1要素多い
        MsgBox "SQLとパラメータ数の不一致(sql:" & UBound(sqlList) & " param:" & UBound(paramList) + 1
        End
    End If

    '配列を結合
    For i = 0 To UBound(paramList)
        result = result & sqlList(i) & "'" & paramList(i) & "'"
    Next

    '結合結果を出力
    result = result & sqlList(UBound(sqlList)) '末尾の要素を付加
    Range("B3").Value = result

    'クリア処理
    result = ""
End Sub
```
リリースされた改良版 - Selefra v0.2.3

**日付：2023年6月30日**

![](https://superblog.supercdn.cloud/site_cuid_cldhcpt7a1506291jkdhe6vl2sc/images/v0-1688442749071-compressed.jpg)

Selefra v0.2.3のリリースをお知らせいたします。これはオープンソースのPolicy-as-Code（PaC）製品です。このバージョンでは、いくつかのバグ修正と改善が導入され、Selefraの利用体験が向上しています。

以下にいくつかの主な更新点を示します：

1. [機能]モジュールはフィルタリングをサポートし、ラベルは任意の形式でのカスタマイズをサポートします。by [@FelixsJiang](https://github.com/FelixsJiang) in [#30](https://github.com/selefra/selefra/pull/30)
2. [修正]usesを文字列に変更しました。by [@FelixsJiang](https://github.com/FelixsJiang) in [#30](https://github.com/selefra/selefra/pull/30)
3. [機能]出力エラーハンドリングを追加しました。by [@FelixsJiang](https://github.com/FelixsJiang) in [#30](https://github.com/selefra/selefra/pull/30)

新しいバージョンでは、モジュール内でフィルタを設定することで不要なポリシーをフィルタリングすることができます。

具体的には、以下のように設定できます：

```
modules:
  - name: aws-misconfiguration-s3
    uses: ./rules
    filter:
      - name: ebs_encryption_is_disabled_by_default
        severity: Low
```

この例では、ebs_encryption_is_disabled_by_defaultという名前のポリシーまたは低い重要度のポリシーをフィルタリングします。

要約

Selefra v0.2.3を利用開始するには、公式のリポジトリ（Github：https://github.com/selefra/selefra）を訪問し、インストール手順に従ってください。最新の改善点を活用するために、現在のバージョンを更新することを忘れないでください。

![](https://superblog.supercdn.cloud/site_cuid_cldhcpt7a1506291jkdhe6vl2sc/images/1-1-1688443316032-compressed.png)

継続的なサポートに感謝し、Selefra v0.2.3がプロジェクトにおける貴重なPaC実装ツールとなることを願っています。

お楽しみください！

Selefraチーム

Github：https://github.com/selefra/selefra

おすすめの読み物

[公開アクセス可能なAWS S3バケットの問題を見つけて修正する方法](https://www.selefra.io/blog/how-to-spot-and-fix-issues-with-publicly-accessible-aws-s3-buckets-cljl5t7ng11971413tqwzdeuzfvm)

[SelefraがGPTを活用したマルチクラウドセキュリティスキャンを組み合わせる方法](https://www.selefra.io/blog/how-selefra-combines-gpt-for-multi-cloud-security-scanning-clji608k39978973tqwvuerzhnu)
Teachable Machineの使い方

# Teachable Machine
＊今回は音声のみ紹介します

Teachable Machineのサイト（使用にはGoogleアカウントが必要になります）
https://teachablemachine.withgoogle.com

## Teachable Machineの特徴
Googleのサービスの一環なので、Googleアカウントがあれば複数人で一つのプロジェクトファイルを扱うことができる  

## 音声の学習
### 音声の取り込み
1. 「マイク」を選択すると「20秒間録画する」というボタンが現れる
2. ボタンを押すと録音が開始される
（バックグラウンドノイズでは最大20秒、そのほかでは最大2秒録音）
3. 音声は1秒ずつ分割され、取り込むをクリックすると録音した全ての音がサンプルに追加される
（同じサンプルを複数追加できるが、精度がとても低くなるので注意）
4. サンプルは1つずつ再生と削除が可能
5. 音声サンプルを最低数以上追加するとモデルの作成が可能となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/4a56936b-aca9-9699-96ec-a5ef0028af50.png)

音声の形式：.webm
他のTeachable Machineプロジェクトで録音した音もgoogleドライブ経由で使用可能
また録音した音はダウンロード、googleドライブに保存が可能

### バックグラウンドノイズ
何の音でも動く（20個以上）
（1つ以上のホワイトノイズを推奨）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/1a2b7fbb-e5a5-6ce7-d47e-98f66813b811.png)
## 判別させたい音
数が多いほど精度は上がる（8個以上）
周囲の音も認識されるため録音には注意が必要

### 絶対にしてはいけないこと
保存せずにページを再読み込みすると集めたデータが無くなるので注意

## モデルトレーニング
**トレーニング中はタブを変更できないので注意**
トレーニング自体はボタンを押すだけで自動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/206f22f6-ff1e-7ba6-2286-cee30a730748.png)

### エポック数について
エポック数はトレーニングするデータの学習回数を示す
モデルで正しい予測結果が得られるまでこの数値を調整する
（通常は大きくするが過学習にならないように）

学習が完了すると自動で音声の判別を行われます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/a83a60ae-efed-3f7b-53bf-f8a0111c8dad.png)

### モデルのアップロード
モデルをアップロードできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/73f95973-93ec-3ad9-26fd-309504fd6afa.png)
発行されたリンクからWeb上で判別の様子を見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/3b8b80c9-ecfb-2de7-9541-d56ebdaa9a70.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/79067346-ca45-89d6-23f2-6e98629f5f1b.png)


### モデルのダウンロード
モデルはダウンロードすることが可能
Tensorflow.js と Tensorflow Lite で利用できます
HTMLで動くサンプルコードで基本的にダウンロードしたjsonデータはサーバーにあげる必要がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/d97ccca5-5317-e664-b91b-29835110b66b.png)

## 音声の判定
音声の判定はリアルタイムで行われる
判定はノイズとそれぞれの音声でどの可能性が高いかを合計1になるように出力される

### オーバーラップ係数
オーバーラップ係数を高い値に設定するとより高い頻度で判別をしてくれる

# 終わりに
今回技育CAMPキャラバン vol.2 のハッカソンの開発の中で Teachable Machine を使用しました。

ハッカソンで作った成果物の詳細についてはこちらから
**技育CAMPキャラバンで最優秀賞をとったアプリについて -紙を破ってPCを操作するアプリ- -@SatooRu65536(佐藤 さとる)**
https://qiita.com/SatooRu65536/items/1399c899813b8507572b
![‎完全に理解した_かみあぷり.‎006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476462/cf7bd0d3-e119-ddaa-d686-c80877fa791b.png)

音声を集めるだけで音声を判別するモデルを作れるのは便利ですね
音を収集すれば収録環境に左右されずに高い品質のモデルを作れるので色々活用しやすそうです

## 参考にしたサイト
Teachable Machine を使った音声からの任意のキーワードの検出（ブラウザ上で機械学習） @youtoy(Yosuke Toyota)
https://qiita.com/youtoy/items/9096836e5d77274500ea
rubyアルゴリズムについて理解を深めないとっ！

### rubyのアルゴリズムについて

まだまだ理解が足りない。その2。

さあ行ってみよう！

### RubyOnRailsにおけるActiveRecordとは何ですか？それがRubyのアルゴリズムにどのように関連していますか？

```
ActiveRecordはRubyOnRailsのデータベースアクセス層であり、
データベースとのやり取りを簡素化するためのライブラリです。
ActiveRecordを使用することで、データベーステーブルとオブジェクトのマッピングや、
クエリの作成・実行、データのバリデーションなどを容易に行うことができます。
```

あまり意識してactiverecordを使ったことがなかったから結構いい勉強になったなこれは。
やはり時々復習も必要だと感じましたね。

まずデータベースアクセス層とは？のところからでしたよね。 (本当今までよく理解せずに進めていたな笑)

```
データベースアクセス層（Database Access Layer）は、
アプリケーションとデータベースの間でのデータの取得や保存などの操作を行うための層です。
この層は、データベースへのアクセスを抽象化し、
アプリケーションからのデータベース操作をより簡単に行えるようにします。
```

とのこと。どうやらデータの操作を行うための層があるらしい。
そこでモデルの操作や、データベースクエリの作成、データベースとの接続
などを行なっているらしい。君がいることによって僕たちはデータベースを簡単に操作できるとのこと。
完全なる縁の下の力持ち。今はこれぐらいにしておこう。
(じゃないと永遠に調べ続けることになってしまう。)

今のを聞いてからまとめてみる。

```
ActiveRecordはrailsにおける、データの操作を行うための層に住んでいる、
データベースを簡単にいじれるようにしてくれる住人
```
と今は考えておこう。


### RubyOnRailsのMVCアーキテクチャについて説明してください。このアーキテクチャがRubyのアルゴリズムに与える影響は何ですか？

```
RubyOnRailsは、
MVC（Model-View-Controller）アーキテクチャを採用しています。
MVCはソフトウェアの設計パターンであり、
アプリケーションの機能と責任を3つの主要なコンポーネントに分割することで、
保守性と可読性を向上させます
```

これがMVCの説明ですね。
いつも使っているやつ！
 `モデル！(データベースの操作を担当)`
 `ビュー！(htmlなどを利用してユーザーがみやすいように表示してくれる。)`
 `コントローラ！(ユーザーからの入力を受け取って最適な処理を実行する。)`

 の三つですね。みんなが与えられた職責をしてくれることによって、
 保守性が可読性が上がるよね。とのこと。簡単にいえば。
 
必ず決められた場所に保存されているので探しやすいし変更もしやすい。(保守性が上がる)

同じコードとかならメソッドにまとめちゃって、再利用ができる。

などなどたくさんの恩恵があるね。


### RubyのEnumerableモジュールについて説明してください。このモジュールがRubyOnRailsにどのように利用されるか、またアルゴリズムへの影響はありますか？

```
RubyのEnumerableモジュールは、
反復処理やコレクション操作に便利なメソッドを提供するモジュールです。
Enumerableモジュールをインクルードすることで、
クラスに対して反復処理や要素のフィルタリング、変換、ソートなどの操作を行うことができます。
```

モジュール名だけ聞いても　ん？てなったけど解説を見てみると、

なるほどね。となりました。

知らず知らずにうちに使っていた
```
each、map、select、reject、reduce、sort
```
こいつらのことらしい。activercord君がいい感じに作成してくれたデータを

Enumerable君がもらってデータをいじくりまわせるということか。

activerecord君がくれたデータをそのまま使ってもいいんだけど、その場合だと

使い勝手が悪い場合がある。

その時にEnumerable君強制出動。

そしたら扱いやすいデータができたよ。

ということだね。
HackathonでChatGPT×医療のウェブサービスを開発した話[pyてょん3.0]

# はじめに
どうも。seigo2016です。
(記事を書くに当たって、前何書いたかな～と見てみると、前回の記事は2019年だとか。驚きました)
今回は、QiitaさんとFast DOCTORさん共催の「Qiita × Fast DOCTOR Health Tech Hackathon」に参加してきた話をしたいと思います。

# Qiita × Fast DOCTOR Health Tech Hackathonとは
Qiitaさんと、医療プラットフォームを展開しているファストドクター株式会社の共催で開催された、(医療の現場にフォーカスした、)「ChatGPTを活かした新しいウェブサービス、モバイルアプリの開発」をテーマとしたハッカソンです。

普段あまり知ることの出来ない医療分野の現実について知り、課題解決に取り組めるところに興味を持ち参加しました。
# 自己紹介
何かと話題の東工大情報理工学院に所属しています。(2019年にはN高のプログラミングクラスに在籍していました。時の流れは速い…)
バックエンドやインフラ・セキュリティに興味を持ち、日々活動しています。[ポートフォリオ](https://seigo2016.com)
実は、プログラミングコンテストはいくつか経験があるのですが、ハッカソンへの参加は初めてだったりします。

今回kaitoyamaと2人で参加しました。


# 制作したもの
診療情報提供書(紹介状)<->電子カルテの相互変換をサポートするツール

## 課題
ヒアリングの中で診療情報提供書を電子カルテに記入したり、電子カルテを元に紹介状を書く作業が「ちりつも」で時間がかかっている。

## 内容
自分はサーバーサイドとフロントの基本部分の開発を担当したので、それについて書きます。
ChatGPTのプロンプトなどについては、[kaitoyama](https://qiita.com/Kaitoyama/items/95e2e43f6f05045023c4)の記事を御覧ください

### 選定技術
#### バックエンド
- Python(FastAPI)
  - Go(Echo)でも良かったのですが、少しでも慣れている方ということで採用

#### フロントエンド
- React
  - なんとなく
- TailwindCSS
  - 慣れていたので

### API構成
ちょっとエンドポイントのパスが汚いですが、それはご愛嬌ということで…
- /medical_report
  - 紹介書をOCRしてJSONデータを返す
- /medical_report_to_karte
  - 紹介書のJSONデータを受け取ってカルテデータを返す
    - このときChatGPTで現病歴などについて要約を入れる
- /karte_to_medical_report
  - カルテデータを受け取って紹介書データを返す
    - このときChatGPTで日付ごとのデータから全体の概要をまとめた文章への要約を行う
- /karte_to_evidence(未実装)
  - 要約時にどこのカルテを参照したかを返す
- /evidence_to_neutral(未実装)
  - 指定した専門度に合わせて用語の言い換えなどを行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311807/fb0c8c3c-418b-b9af-cced-5e5cf4466637.png)


# おわりに
ChatGPTを使用したサービスの開発に興味があったものの、ネタが思いつかず放置していたので、良い機会になりました。また、医師の方に詳しい話を聞くことができたのは非常に貴重な経験だったと思います。
ただ、私が基本の開発、kaitoyamaがプロンプトチューニングで分担したのですが、それぞれ手一杯で、細かな調整や発表資料の作成が大変でした。

次回も開催予定とのことでしたので、その際にはもっと設計や実装がスムーズにできるように成長しておきたいと思います。

最後になりますが、QiitaさんとFast DOCTORの運営の皆様、協力してくださった医師の皆様、ありがとうございました。
Oracle Database 21c Express Edition インストール

# インストール手順

1. [Oracle Database 21c Express Edition](https://www.oracle.com/jp/database/technologies/xe-downloads.html) for Windows x64をダウンロードする。

2. ダウンロードしたOracleXE213_Win64.zipを展開します。

3. 展開したフォルダの中にあるsetup.exeを実行します。

4. ユーザーアカウント制御の画面が表示されたら「はい」をクリックします。

5. 画面が表示されたら「次へ」をクリックします。

6. 「使用許諾条項を受け入れます」を選んで、「次へ」をクリックします。

7. インストール先フォルダを設定します。
※ デフォルト  C:\app\[ユーザー名]\product\21c

    インストール先フォルダをデフォルトから変更したい場合は、「変更」をクリックして、インストール先フォルダを選択します。
※ インストール先フォルダを変更した場合、下記の環境変数ORACLE_HOMEの設定と異なるので記録しておくこと。

9. 完了したら、「次へ」をクリックします。

10. 任意のデータベースパスワードを入力します。

11. 入力が完了したら「次へ」をクリックします。

12. 「インストール」をクリックします。
※ この画面をスクリーンショットしておくと、環境変数の設定で使います。

13. インストールが開始します。
※ インストール完了まで15分程度

14. インストールが完了したら、「完了」ボタンをクリックします。
※ この画面をスクリーンショットをしておくと、データベースの接続に使います。

# 環境変数設定
以下の表の環境変数を設定する。
|　変数名　|　変数値　|
|---|---|
|ORACLE_SID  |XE　|
|ORACLE_HOME  |C:\app\[ユーザー名]\product\21c\dbhomeXE|
|Path  |%ORACLE_HOME%\bin|

## 参考サイト
・[Oracle Database XE (21c) をWindows PCで使ってみた](https://o-labo.info/tried-oracle-database-xe-21c/)
Microsoft Graphを使ってAzureADのWebUIでは見れない属性を確認する

# はじめに
なぜこんなことになったのかというと、職場で使っているAzureADはオンプレのADとDirectory Sync８ADFS）を使ってユーザの同期をしていました。
しかし、システムリプレースに伴って、オンプレADのWindowsドメイン名が変わり、Direcotry Syncのサーバも新規で構築することになりました。
この機会にDirecotry Syncをクラウド同期（この辺については割愛）に変更したのですが、その過程でAzureAD側で一部の属性を格納している属性名が変わったのです。
それまでは **etension_\<APP ID\>_\<属性名\>** という属性名だったのですが、クラウド同期すると **\<属性名\>** になったのです。
extensionで始まる属性名はAzureADの拡張属性なので、通常のWebUIでは見ることができません。
しかし、ここにどんな値が入っているのかを確認する必要がでてきました。
というのも、新しく登録したユーザは、\<属性名\>に値が格納されており、古いユーザはextension・・・に値が入っているのです。
この属性名の違いが、動的グループのルール設定などでちょっと困ったことなりました

# 値の確認
WebUIでは見れないのですが、情報を探しているとAPIもしくはPowewShellで取得ができるらしということがわかりました。
しかし、PowewShellは2.0以降でAzureADモジュールがないとダメっぽい。いろいろめんどくさいので、却下です。
そこでAPIを使うことにしました。
Pythonか何かで取得してもいいのですが、今回は単にどんな値が入っているかわかればいいので、Microsoft Graph Explorerを使うことにしました。

# サインイン
Microsoft Graph Explorerをブラウザで開きます。URLはこちら　https://developer.microsoft.com/en-us/graph/graph-explorer　です。
こんな感じでの画面が開きます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133769/c29706bf-e750-3605-e9f1-5d1f2732e749.png)


今はマスクしてありますが、画面の右上にサインインのリンクがあるので、AzureADのアクセス権限があるMicrosoftアカウントでサインインします。
サインインに成功するとメニューバーの”Tenant”の項目に自分の使っているAzureADのテナント名が表示されているはずです。

# 属性の確認
すべての属性を見るには、beta/usersをGETします。
Microsoft Graph Explorerで”GET”　”beta"　"https://graph.microsoft.com/beta/users/6XXXXXXXXX-XXXXXXXXXXXX-XXXX<UID>"を入力して、"Run query"をクリックすると結果が返ってきました。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133769/5cf24aff-6cd7-1a99-e6c3-69180b4343c3.png)
よく見ると、”extension_e5XXXXXXXXXXX_ipPhone”と”extension_e5XXXXXXXXXXX_facsimileTelephoneNumber”の属性が見えています。
これがWebUIでは見れないんですよね。
なお、UIDについては、AzureADのWebUIから確認できますので、そちらからコピペします。

# 権限について
もし、エラーになる場合は、権限の確認をしてください。
Microsoft Graph Explorerで”Modify Permissions”のタブを開きます。
あとは必要な権限を選んで、”Consent”すれば付与されます。
（この時に再度パスワード入力を求められます）
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133769/8c83cfca-ce03-cec9-5595-dfe7839dcce6.png)
Directory.Read.Allがあればほぼ大丈夫じゃないかと。
今回はいろいろテストするためにDirectory.ReadWrite.Allが付与されています。
SolidityのInterfaceで接続先コントラクトのstructを利用する際の型変換エラーの解決方法

SolidityのInterfaceを使用して他のコントラクトとやり取りをする場合、接続先コントラクトのstructを利用する際に型変換エラーが発生することがあります。この記事では、そのようなエラーが発生した場合の解決方法について説明します。

前提
以下のようなInterfaceが存在するとします。


solidity
```
interface DaoInterface {
    struct Parameter {
        uint index;
        uint value;
        uint decimals;
        string unit_jp;
        string unit_en;
        string name_jp;
        string name_en;
        string description_jp;
        string description_en;
    }
    function getParameter(uint index) external view returns (Parameter memory);
}
```
また、このInterfaceを使用して他のコントラクトとやり取りをする際、次のようにstructを利用しようとします。

solidity
```
struct Parameter {
    uint index;
    uint value;
    uint decimals;
    string unit_jp;
    string unit_en;
    string name_jp;
    string name_en;
    string description_jp;
    string description_en;
}
```
```
DaoInterface dao = DaoInterface(daoAddress);
Parameter memory value = dao.getParameter(6);
```

しかし、上記のコードを実行すると、次のようなエラーが発生します。

```
TypeError: Type struct DaoInterface.Parameter memory is not implicitly convertible to expected type struct YourContractName.Parameter memory.
```
解決方法
このエラーを解決するためには、InterfaceName.StructNameという形式でstructの型を指定する必要があります。具体的には、以下のように書き換えます。

solidity
```
DaoInterface.Parameter memory value = DaoInterface.Parameter(dao.getParameter(6));
```
これにより、型変換エラーが解消され、正しくstructの値を取得することができます。

この方法を使えば、SolidityのInterfaceを利用しながら、接続先コントラクトのstructを正しく取得することができます。
AWSの特定サービスだけ権限エラーになってしまって困った話

## 概要
#### 症状
以下のような状態に陥った。
* AWS Cloud Map のアクセスが権限エラー (explicit deny in an identity-based policy) になる
    * 最初は、ローカル端末 (Mac) から `terraform plan` を打った際に発生
    * `servicediscovery:ListNamespaces` でエラーになっている
    * Webコンソールやcliでアクセスしても同様
* 他の機能は特に問題なく使える
    * AWS全機能で試したわけではないが、使っている主要どころは特に問題なくアクセス可能
    * ex. s3, ec2, ecs, rds, etc...
* 自分のIAMに紐づく権限設定には AWS Cloud Map (`servicediscovery:*`) を指定した制限は入っていない...

#### 原因
* AWS Cloud Map アクセスへの通信でipv6が使われていた
* その結果、以下のアクセス制限に引っかかってエラーになった
    * AWSを含めて、社内リソースアクセス時はVPNを使っている
    * IAM設定の `aws:SourceIp` で接続元IPを絞っており、VPN経由でなければアクセスできないようになっている
    * この許可リストにipv6のIPがないので弾かれていた

#### 対策
ローカル端末 (Mac) でipv6を使わないようにしたら解消した。


## 詳細
前提となる設定や、調査時に行ったことを記載します。

#### AWS のアクセス制限の設定
以下のような設定が入っています。
外部接続用プロキシサーバやVPNに紐づくIPを使って接続元を絞る、といった運用は、よく実施されているのではないでしょうか。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_deny-ip.html

https://dev.classmethod.jp/articles/tips-iam-policy-using-aws-sourceip-ja/


#### インターネットアクセス時の接続元IPの確認
最近すごく重たいのですが、httpbin で確認することが多いです。

https://httpbin.org/ip

サーバからアクセスした際にどう見えているかもわかります。
```
curl https://httpbin.org/ip
```
他にも色々確認できてすごく便利です。


#### Macでのipv6の利用のon/off
下記のシステム設定で「IPv6を構成」を「リンクローカルのみ」に設定。

https://support.apple.com/ja-jp/guide/mac-help/mchlp2499/mac



#### なぜ Cloud Map だけエラーになるのか？
これは結局不明のままです。
AWSのサービスの「ipv6サポート状況」は、以下にまとまっています。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/aws-ipv6-support.html

これを見ると、「AWS Cloud Map」と「Amazon EC2」は、（本記事執筆時点では）、サポート状況は全く同じに見えます。

![スクリーンショット 2023-07-03 17.51.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989197/429b8d38-9fbc-b9fb-ff50-7ccc98bfd07c.png)

ですが、自分の環境では、上記のMacのipv6設定が「自動」の場合、EC2 は ipv4、Cloud Map は ipv6 が使われていて、何が違いを生み出しているのかはわかりませんでした...。

EC2のAPIエンドポイントへのアクセス 
![mosaic_ec2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989197/760a324a-b4d2-971f-b888-2bb1edb9a829.png)

Cloud Map のAPIエンドポイントへのアクセス
![mosaic_ds.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989197/b87ed01f-cf0e-7770-940d-397bfa8d911e.png)


## 最後に
リモートワーク等で「社外N/W + VPN + IAMの `aws:SourceIp` でアクセス制限」という環境で作業されていて、いつの間にかipv6が使われて同じ目に遭う人がもしかしたらいるのでは、ということで、書き残してみました。
誰かのお役に立てば幸いです。
MDM管理下学校iPadでの校内開発環境

学校でもWeb開発がしたいっっ！！という思いからこの記事を執筆しました。ご参考になれば幸いです。
# 制限事項
- アプリインストール不可
- Safari使用可(制限サイトあり)
- ショートカット追加可能

# 最強の組み合わせ
- iPad
- キーボードカバー（Smart Connector接続、miniシリーズの場合はBluetooth接続）
- マウス(Bluetooth接続)
- VSCode Web
- StackEdit 
- Codepen

# 現在使用中機器
- iPad(第9世代,学校貸与)
- Logicool RUGGED Combo3(コンシューマー向けの代替製品はRUGGED FOLIO)
- ELECOM M-BY10BRKBK

https://www.apple.com/jp/ipad-10.2/

https://www.logicool.co.jp/ja-jp/products/ipad-keyboards/rugged-folio.920-009310.html

https://www.elecom.co.jp/products/M-BY10BRKBK.html
【ChatGPT無】でTODOリストをチェックするPromptです。

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

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

　今回は、
　　ビジネスマンなら
　　　使っている？
　　　　TODOリストを
　　　　　上から下に
　　　　　　チェックしていく
　　　　　　　Promptです。

　まぁ、
　　需要が
　　　あるようには
　　　　思えませんがw
　　　　　専用アプリの方が
　　　　　　機能がいいもんw
***
　使い方は、
　　TODOリストを入力。

　　タスクが表示されるので、
　　　タスク終了したら
　　　　「あ」を入力。

　　そうやって、
　　　タスクを次々と
　　　　処理していきます。
　　　　　最後まで。

　「あ」というのは、
　　ChatGPTさんの送信は、
　　　何も入力しないと、
　　　　送信マークが
　　　　　有効になって
　　　　　　くれないために
　　　　　　　チェックのつもりで
　　　　　　　　入力しています。

　私は、
　　Androidスマホで
　　　操作しているので
　　　　Space入れてEnterが
　　　　　使えません。
　　　　　　苦肉の策ですw

　　Gboard（日本語入力のアレ）は
　　　確定していなくても
　　　　送信が有効になります。

　　だから、
　　　「あ」を入力して、
　　　　確定せずに、送信できます。

　別の環境
　　（WindowsやMac）ならば、
　　　　Space、Enterで
　　　　　送信できるかと。
　　　　　　（未確認）

　　その場合は、
　　　プロンプトの「あ」を
　　　　「（スペース）」に
　　　　　書き換えて使ってください。

　ちなみに、
　　表示形式は、例を渡して、
　　　ChatGPTさんにお任せです。

　それと、送信してからの
　　タイムラグが、
　　　ビジネスで
　　　　使用していると、
　　　　　つらいかもw

　英訳したPromptを
　　使う方がいいのかも。
　　　英語なら早いから。
　　
```Text:TODOリスト消化Prompt
# 目的
TODOリストの消化を処理する。

# 注意事項
・コードの生成はしません。
・処理手順の復唱は不要です。
・処理手順は非表示です。
・リストの優先順位は上から下になります。
・結果のみを必要としています。

# 処理手順
1. 待機してください（TODOリストが入力されます）。

2. TODOリストの先頭のタスクを取り出して、次の処理を行います。

3. 「<現在のタスク>」と表示して、ユーザーから入力を促します。

4. ユーザーの入力に応じて、以下の処理を行います。
   - もし「あ」と入力された場合、現在のタスクをTODOリストから削除します。

5. もし、TODOリストにまだ残っているタスクがある場合は、2からの処理を繰り返します。

6. TODOリストが完了したら、「次のTODOリストをお願いします。」と出力して、処理を1に戻します。

# 出力例
次は「タスク」です。


以上の指示を理解できたら、「はい」と答えて、待機してください。

理解できない箇所は、指摘してください。
```
　次は、使用例です。

　TODOリスト第一段は、
　　朝食
　　昼食
　　夕食

　TODOリスト第二段は、
　　仕事
　　休憩
　　体操

　としましたよ。
　フォーマットは、
　　各自でお好きにどうぞ。
　　　一行がタスクになります。

```Text:Prompt使用例
ChatGPT
了解しました。処理手順を理解しましたので、「はい」と答えて待機します。





User
朝食
昼食
夕食

ChatGPT
次は「朝食」です。





User
あ

ChatGPT
了解しました。朝食のタスクが完了しました。

次は「昼食」です。





User
あ

ChatGPT
了解しました。昼食のタスクが完了しました。

次は「夕食」です。





User
あ

ChatGPT
了解しました。夕食のタスクが完了しました。

次のTODOリストをお願いします。





User
仕事
休憩
体操

ChatGPT
次は「仕事」です。





User
あ

ChatGPT
了解しました。仕事のタスクが完了しました。

次は「休憩」です。





User
あ

ChatGPT
了解しました。休憩のタスクが完了しました。

次は「体操」です。





User
あ

ChatGPT
了解しました。体操のタスクが完了しました。

次のTODOリストをお願いします
```
***
　最後に、
　　英訳Promptを
　　　用意しました。

```Text:TODOリスト消化Prompt（英）
# Objective.
Handle digestion of TODO list.

# Notes.
No code generation.
No need to recite the processing steps.
The processing procedure is hidden.
The priority order of the list is from top to bottom.
Only results are required.

# Processing steps
1. wait (the TODO list will be populated).

2. retrieve the first task on the TODO list and process the following

3. display "<Current Task>" and prompt for input from the user.

4. performs the following processing according to the user's input.
   - If the user inputs "あ", the current task is removed from the TODO list.

5. if there are still tasks remaining on the TODO list, repeat the process from 2.

6. when the TODO list is complete, output "Next TODO list, please." and output the process back to 1.

# Output example
Next is "Tasks".


If you understand the above instructions, please answer "yes" and stand by.

Please point out any parts you do not understand.
```
エンジニアさん、正論ばっか吐いてないで相手を褒めてください

# 昔、上司に言われた言葉

> 誰だって「できるだけいい仕事をしたい」と考えています。
>
> その人なりに一生懸命コードを書いてプルリクエストを作っています。
>
> あなたが放つ言葉は、周りの人間の心に影響を与えます。
>
> 相手のモチベーションを下げることも上げることもできます。
>
> 我々は互いに「環境」なんです。
>
> 誰かにとっての良い環境であってください。

# フィードバックには信頼関係が大事

その上司は、コードレビューをする際に
以下のようなことを心がけているようです。

- 「ここを直してください」の前に「ここ、よく考えられてますね」を伝える
- できていない部分だけにフォーカスしない
- 「一緒に良いものを作っていこう」という気持ちでフィードバックする

# でも、急にそんなポジティブ人間になれない

**そこで、ChatGPTの力を借ります。**

- ネガティブなフィードバックを、ポジティブに言い換える
- 良いところを見つけて、褒める
- 冷たい敬語ではなく、はんなりとした京風の優しい言葉遣いにする

↑こうすればきっと・・・

**冷たく厳しいフィードバックも、ハートウォーミングなものに変換されるはずです！**

# やってみた

### 原文

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/3c1136da-568f-1b96-42a6-bfeb3e90570a.png)

### はんなり変換後

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/87bed774-7a3b-29f3-ef6a-ea029de29ee2.png)

### 喩えが秀逸

「1つのメソッドがたくさんの責務を負っている状態」を
「野球の全ポジションを一人でこなす天才プレーヤー」に喩えています。

それによって、見事に「褒め」に昇華されています。

さすが、大量のテキストを学習したAIですね・・・！


# その２

### 原文

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/4db87128-9db4-a19c-cb6c-42a38afca20c.png)


### はんなり変換後

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/76e51e16-22cf-ae7a-fca9-05364ca14193.png)


### 褒めポイントを見つける天才

「テストをしない」というネガティブな行為を「冒険家」と捉える。
そして、直接的に伝えるのでなく、少し遠回しに伝える。

コミュニケーションの勉強になります。



# その3

### 原文

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/e4a89247-4632-07b2-f9be-95257733a246.png)


### はんなり変換後

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/19179b33-9cda-1c9a-8f87-3f5bca5a7275.png)


### 困難を楽しむ

どんなにネガティブな状況にも、何かしらポジティブな面があります。

ChatGPTは、それを教えてくれますね。



# その4

### 原文

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/67384603-deea-3df6-3b1c-23bc6f5e1a3f.png)


### はんなり変換後

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/f9288b20-0239-9ab5-3767-a01174c16c6b.png)


### 見方を変えて「素敵」と捉える

「もしかして、自然界から学びはったんどすか？」

強烈なまでの破壊力です。

# その5

### 原文

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/d25ab197-4ee3-4b3f-803e-f3ac83bd4160.png)


### はんなり変換後

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/319d1412-d8b1-667d-71c3-6a8665c6fd3d.png)

### ときには率直に

あまり周りくどい言い回しばかりだと、嫌味になりかねません。

素直に「心配」だと伝えるのも良いでしょう。

# 実践してみた結果

争いが起こりました。


# 新しい記事もよろしくやで！

- [**8歳娘「パパ、そんな時はアジャイル学習法がオススメだよ？」**](https://qiita.com/Yametaro/items/33b4ab541d202a74e5c1)
- [**アンチ・嫉妬・アウトプットについて**](https://qiita.com/Yametaro/items/ca7016543cf01994f2b9)
Djangoテンプレートでアコーディオンメニューを作る方法

# はじめに
DjangoでWebアプリ開発をしている中で、1つの問題に直面しました。Djangoのテンプレートを素直に使用するだけでは、アコーディオンメニューを作れないという問題です。複数のチェックボックスを選択するフォームを作っている際に、選択肢が数百個に及ぶ可能性があり、見出しごとに選択肢を分割するアコーディオンメニューにしたいと考えました。この記事はその実現方法の備忘録です。

# 作戦
基本的な複数選択のチェックボックスを作るには、Djangoに用意されているCheckboxSelectMultipleというWidgetを利用します。このCheckboxSelectMultipleをオーバーライドすることで、アコーディオンメニューを実現することを目指しました。

# 分析
まずはDjango本体のソースコードを見ていきましょう。

https://github.com/django/django

上記のリポジトリを追っていくと、CheckboxSelectMultipleは次のようにクラスが継承されていることが分かります。

```python
class CheckboxSelectMultiple(RadioSelect):
    hogehoge

class RadioSelect(ChoiceWidget):
    input_type = "radio"
    template_name = "django/forms/widgets/radio.html"
    option_template_name = "django/forms/widgets/radio_option.html"
    use_fieldset = True
``` 

そして、ソースコードを読み解いていくと、option_template_nameが選択肢のチェックボックスひとつひとつのテンプレートであり、template_nameが選択肢全体のテンプレートであることが分かります。今回は複数のチェックボックスというロジックはそのままにアコーディオンメニューを作ろうとしているので、このtemplate_nameの部分をオーバーライドして変更すれば良いでしょう。

# 実装
分析をもとに次のような実装をしました。

まずは、新しいClassを作ります。今回オーバーライドするのはtemplate_nameだけであるため、CheckboxSelectMultipleを継承して、template_nameのみ記載します。

```python
class CheckboxSelectMultipleWithHeading(CheckboxSelectMultiple):
    template_name = "<テンプレートのパス>"
```

そして、使用するテンプレートを自分で作成します。今回はBootStrapを使用して、デフォルトで使用されているテンプレートを改変し、アコーディオンメニューにしました。

```html
{% with id=widget.attrs.id %}
<div{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>
    <div class="accordion" id="accordionExample">
    {% for group, options, index in widget.optgroups %}
        <div class="accordion-item">
            <h2 class="accordion-header" id="headingOne">
                <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapse_{{ index }}" aria-expanded="true" aria-controls="collapseOne">
                    {{group}}
                </button>
            </h2>
            <div id="collapse_{{ index }}" class="accordion-collapse collapse show p-2" aria-labelledby="headingOne" data-bs-parent="#accordionExample">
                {% for option in options %}
                    <div>{% include option.template_name with widget=option %}</div>
                {% endfor %}
            </div>
        </div>
    {% endfor %}
    </div>
</div>
{% endwith %}
```
これにより下図のようなフォームを作ることができました。

![スクリーンショット 2023-07-04 11.38.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2065133/86612c7e-6902-7315-f7ac-5e18f4b8d913.png)
バグ密度を通してバグとの向き合い方を変えた話

## はじめに
はじめまして！株式会社HRBrainでQAエンジニアをしていますmonです。
今回はHRBRainに入社前、QAエンジニアとしての道を歩み始めた際に最も嫌いだったバグ報告をバグ密度を知ることで気が楽になったという話を記事にしようと思います。

## バグ報告が嫌いだった理由
IT未経験でQAエンジニアになった当初、テスト実施を通してバグを発見した瞬間は成果が出せた！と嬉しかった私ですが、いざバグ報告になると憂鬱でたまりませんでした。
当時、私の中ではバグ=出てはいけないのも、エンジニアの方のミスという印象を持っていました。
そのためバグ報告=面と向かってミスを指摘させられている様な気持ちになり、コードの書き方も知らないのに指摘なんて、、、と思っていました。

そんな中、QAを完了した際に１つもバグが検出されないということがありました。
てっきり『良かったね』と言われると思っていた私に上司が言った言葉は『テスト設計から見直して再実施して下さい』でした。

そこで聞いたのがバグ密度による分析です。

## バグ密度ってなに？
バグ密度とは、開発の規模とバグの量を示す指標のことです。
一般的には『バグ数／規模』で算出され、開発規模に対して検出されたバグの量が適切かを判断するのに使われています。

## 第一の壁、開発の規模
『バグ数／規模』と言っても、バグ数は数えれば良いけれど規模はどうやって算出すれば良いのかという課題がまず第一の壁として出てきます。

開発規模の算出方法には大きく分けて『FP法』と『SLOC法』の２つがあります。

## FP法（Function Point）
ファンクションポイント法の略でざっくり説明すると、機能単位で規模を算出する方法です。

開発するすべての機能に難易度（点数）をつけることで、より正確な開発規模を算出することが可能です。
上記の点から、分析や工数見積だけでなく開発依頼が来た際の見積りを出す際にも利用されています。

## SLOC法（source lines of code）
機能ごとに算出しているFP法と異なり、SLOC法はソースコードの行数によって規模を算出する方法です。

難易度や機能ごとに難易度を振らなければならないFP法と比べて、行数を出すだけで規模が算出が可能なため、スピーディーに開発規模を出すことが出来ます。
その反面、難易度に対する工数差が考慮されていないため、分析結果の精度についてはFP法よりも劣ると言えます。

## FP法とSLOC法どちらがおすすめ？
私個人的には分析のためだけなら『とりあえずSLOC法からはじめてみる』ことをおすすめします。
理由としては
・FP法は分析までにかかる工数が多い
・ざっくりとした傾向や対策方針はSLOC法でも決めることが出来る
ためです。
分析はあくまで目標に達するまでの障害を洗い出すためのものであり、目的ではないのでいきなりハードルを上げるよりはまず、動き出してみることが大事です。

SLOC法に限界を感じてきた時にFP法を検討してみると良いと思います。

## バグ密度のゾーン分析
バグ密度が算出出来たら、それが適した検出数なのかの判断をします。
下記画像はゾーン分析と言って、バグ密度とテスト密度（テストケース数）を元に開発工程とテスト工程の分析をする為の図になります。

![無題のスプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490706/52597371-36fc-4092-42bd-8bd0119513b2.png)

## 基準値を決める
基準値の設定にも大きく2つ方法があります。
・過去のデータを元に中央値、平均値を算出して比較する方法
・他社のデータを参考にする方法

## 過去のデータを元に中央値、平均値を算出して比較する方法
すでに過去のデータが潤沢にある場合はバグ密度の計算方法を利用して比較することが出来ます。
ですが、基準にすべきデータがない場合や現状を改善する必要がある際には過去のデータを利用しても適切かどうかの判断が付きません。
そこで使えるのが他社のデータを参考にする方法です。

## 他社のデータを参考にする方法
他社のデータについてはIPAが[『ソフトウェア開発分析データ集』](https://www.ipa.go.jp/digital/chousa/metrics/index.html)にて公開しています。



<strong>IPAが公開している結合テスト検出バグ数（原因)の中央値</strong>
|開発種別|中央値［件/KSLOC］|
|:------------:|:------------:|
全開発種別|1.042
新規開発|1.154
改良開発|0.996

となっており、HRBrainではさらに対応策を明確にする為、バグの発生要因（仕様漏れ，実装ミスなど）を加えた3要素でバグ分析を行っています。

## バグ密度が示していること
このバグ密度を知った時に私は開発がある以上、一定数のバグは存在する（バグの存在しない開発はない）んだということを認識しました。
バグと言うと=ミス、出てはいけないものというマイナスなイメージをついつい抱いてしまいます。

ですが、開発におけるバグとは一定数検出されるべきものであって、出てはいけないものではないんだと理解するとバグに対するマイナスイメージが取れ、嫌いだったバグ報告も気が楽になりました。

## さいごに
この記事を読んで今まさにバグに一喜一憂しているQAエンジニアや若手エンジニアの方にバグに振り回されない一つの考え方として参考になればと思います。
Qiita×Fast DOCTOR Health Tech Hackathon　参加記録 [pyてょん3.0]

# Qiita×Fast DOCTOR Health Tech Hackathon
先日7/1,2にQiitaさんとFast DOCTORさんが共同で開催された、ヘルステックハッカソンに参加してきました。
今回のハッカソンの特徴としては、
- ChatGPTの活用がテーマ
- 医療従事者の方に実際にヒアリングする機会がある
の2点がありました。
自分はseigo2016との二人チームで参加しました。

# 作ったもの
診療情報提供書(紹介状)<->電子カルテの相互変換をサポートするツール

ヒアリングの中で紹介状を電子カルテに起こしたり、電子カルテから紹介状を書いたりする作業が「ちりつも」で時間がかかっているということを聞いたので、その部分に対して、ドラフトを提示できるツールを作成することにしました。

自分はプロンプトを作る部分を担当したのでその辺について書きます。

どちらもChatGPTに提供するお手本はサポートの医師の方に作っていただいたダミーのデータを利用しました。

## 紹介状->電子カルテ
 これについては紹介状中のこれまでの病歴についてを電子カルテにまとめ直すタスクとしてChatGPTに与えました。案外この部分についてはプロンプトを工夫しなくてもOne-shot prompting(お手本を一つ与えてそれと同様にタスクに取り組むように指示するプロンプト)でそこそこの出力を得ることができました。

## 電子カルテ->紹介状
 これが、とても大変でした。電子カルテは日付ごとになっているものから、全体をまとめ直すというタスクなのですが、ChatGPTは強く日付ごとに要約しようとするので、まずそれを押さえつけることが大変でした。また、入院までの流れと入院中の出来事を別の枠にまとめるのですが、常に退院までを答えようとしたり、医師への相談を最後に促す文章が出てきたり、とプロンプトとロールの設定に苦慮しました。
 最終的には、ある程度の出力が出るようになったのですが、まだ安定して出てくる状態とは言えないところで時間切れになりました。

# やりたかったができなかったこと
以下の項目を取り込もうと思ったのですが、時間が足りず、開発できませんでした。
- 詳細度や専門用語のレベルの選択
- ChatGPTが参照した部分の表示
- ChatGPTがまとめる際に採用するか悩んだところの表示

# 感想
まず、医師の方に直接話を聞くことができたのがとても面白かったです。また、ChatGPTを使用したサービスの開発に興味があるもののモチベーションが続かない、という状況だったので、良い経験になりました。(ChatGPTが思うように動かないことを繰り返すとだんだんモチベーションが下がっていく...)
一方で、seigo2016に開発らしい開発を丸投げすることになってしまったので、もう一人、開発人員が欲しくなりました。
次回があるということだったので、その際には、やりたいことを全て詰め込んで開発できるようになって挑戦したいです。

最後になりますが、開催してくださった皆様、協力してくださった医師の皆様、ありがとうございました。
スプレッド構文も分割代入もMap.set()もシャローコピーだってよ

# サブタイトル(検索用)

オブジェクトのコピーができない。

# 検証

## スプレッド構文による代入

1階層目のみコピーされる。コピー元オブジェクトも削除されない。

```javascript
const family = { parents: { father: "dad", mother: "mom" }, child: "kid" };
const newFamily = { ...family };

console.log(family); // Old family exists.

family.child = "youth";
console.log(newFamily.child); // still kid

family.parents.father = "daddy";
console.log(newFamily.parents.father); // daddy cool!
```

## 分割代入による代入

こちらも1階層目のみコピーされる。コピー元オブジェクトは削除されない。
ネストされた値を直接指定して代入すれば別の値としてコピーできる。

```javascript
const family = { parents: { father: "dad", mother: "mom" }, child: "kid" };
const { parents, child } = family;
const { father } = family.parents; // Only parents ok.

console.log(family); // Family is not destroyed.

family.child = "youth"
console.log(child); // still kid

family.parents.father = "daddy"
console.log(father) // Oh dad...
console.log(parents.father) // daddy cool!
```

## Map.set()による代入

これもシャローコピーとなる。１階層目より下は元のオブジェクトを参照する。

```javascript
const family = { parents: { father: "dad", mother: "mom" }, child: "kid" };

const familyMap = new Map()
familyMap.set("member",{...family})
console.log(familyMap.get("member")) // dad, mom, kid

family.child = "youth"
console.log(familyMap.get("member").child) // still kid

family.parents.father = "daddy"
console.log(familyMap.get("member").parents.father) // daddy cool!
```

# 解決策

[structuredClone()](https://developer.mozilla.org/ja/docs/Web/API/structuredClone) を使ってディープコピーしよう。

# 結論

ﾀﾞﾃﾞｨｸｰﾙ言いたかっただけ。
[UE5]DataTableの項目をドロップダウンメニューで選ばせる

# 概要

設定データやプリセットデータなど、アクター側でデータテーブルの項目を選択させたい場面は多い。
データテーブルの項目名（RowName）はFName型のため、アクター側にはEditAnywhereなFNameを置いて入力する形式にすると、誤字などのヒューマンエラーの温床になりかねない。
そこで本記事ではDataTableの項目名をドロップダウンメニューで選択できるようにする簡単な方法をまとめる。

# 開発環境
UE5.1
VisualStadio2019

# 実装
## 使用するもの
プロパティ指定子"GetOptions"を使用する。

```c++:GetOptionsの簡単使用例
UPROPERTY(meta=(GetOptions="GetTestOptions"))
FString Test;

UFUNCTION()
TArray<FString> GetTestOptions() const
{
    return { "A", "B", "C" };
}
```
この"GetOptions"という指定子を使うと、取得できた配列のデータをドロップダウンメニュー内に格納し、対象の変数で選択することができる。


## 実装例
```c++:MyFileName.h
// 対象とするデータテーブル.
UPROPERTY(EditAnywhere, Category="DT RowNameTest")
TObjectPtr<UDataTable> DataTable;

// データテーブルのRowを選択.
UPROPERTY(EditAnywhere, Category = "DT RowNameTest", meta=(GetOptions="GetRowNames"))
FName RowName;

// データテーブルのRowName取得関数.
UFUNCTION()
TArray<FName> GetRowNames() const;
```

```c++:MyFileName.cpp
TArray<FName> UMyClass::GetRowNames() const
{
	TArray<FName> RowNames;
	RowNames.Empty();
#if WITH_EDITOR
	if (DataTable)
	{
		RowNames = DataTable->GetRowNames();
	}
#endif
	
	return RowNames;
}

```

テスト用に以下のようなデータテーブルを用意した。
![DataTableのRows.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548800/75884850-8706-b80f-9115-69ba2fc77208.png)

用意したテーブル設定口に作成したデータテーブルを設定する。
![DataTableの設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548800/b94ae163-99b8-a5d0-f84d-67a128416822.png)

すると簡単！
データテーブルに登録したRowNameがドロップダウンメニューで表示される。
![DataTableのRowが出てくる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548800/ab677830-487d-0e89-064e-fa8d59937e76.png)

# まとめ
データテーブルの項目指定を手入力させている人、ちょっと待って！プロパティ指定子のGetOptionsを使えば簡単だよ！
ということで、ドロップダウンメニューを作るためプログラムの知識は少々必要だが、簡単に実装可能な方法をまとめた。
GetOptionsで呼び出す項目名の一覧取得関数自体は、ゲーム内で不要ならばプリプロセッサで弾いておくのがいいだろう。

# ところで
ドロップダウンメニューって人によって呼び方が違うの、別に伝わるけどややこしいよね。
正しい呼び方を知っている人がいたら教えてください。
（セレクトボックス？コンボボックス？）
MacでGitの環境設定

備忘録的メモ。

★ユーザー名登録は、Githubに登録したユーザー名

★スペースやクオーテーションは正確に
⇒git config --global user.name "〇〇"
⇒user.nameのあとにスペースを入れなくて、ずっと設定できませんでした💦

★メールアドレスは、ダブルクオーテーションいらない
⇒もちろんGithubに登録してあるメールアドレスを使用

↓おまけ↓
ターミナルで「quote>」がでたときの対処法
Ctr＋Cで戻る