OmniAICreator/Qiita-1.07M huggingface dataset:
🚀 リアルタイム文字起こし＋GPTで会議が変わる！？超便利デモを作ってみた

こんにちは！
最近、会議を10倍楽しくする（かもしれない）ツールを作ってみたので、ご紹介します！

# 🎙️ 何を作ったの？

簡単に言うと...

1. リアルタイムで会議の音声を文字に起こす
2. 文字起こしされたテキストをGPTにリアルタイムで送信
3. GPTが会議内容を要約したり、重要ポイントを抽出したりしてくれる

という、ちょっと賢い「会議アシスタント」を作っちゃいました！

# 👀 デモ動画

百聞は一見にしかず！ってことで、デモ動画をどうぞ！

https://x.com/aorblue/status/1836008345549095094

# 💡 GPTは何をしてくれるの？
GPTさんとはチャット形式で会話できるので、
現時点の文字起こしの内容に基づいて、リアルタイムに何でもお願いできちゃいます。

## 📝 要約作成
「今の議論を3行で要約して」
長々とした会話もコンパクトにまとめてくれます。

## 📊 表形式でのまとめ
「各部署の課題を表形式でまとめて」
情報を整理して見やすく表示してくれます。

## 🔀 Mermaid形式でのフロー図作成
「今の業務プロセスをMermaid形式でフロー図にして」
複雑な流れも視覚的に表現してくれます。

## 🤔 質問への回答
「この提案の問題点は何かな？」
客観的な視点でアドバイスをくれます。

GPTさんに頼めばなんでもやってくれる...!?

# 🛠️ どうやって作ったの？

下記記事でリアルタイムな音声認識の実装について、記載しています。

https://qiita.com/aorblue/items/00909c1c9f1dbe8cf829

上記アプリに今回リアルタイムなChatGPT機能を追加しました！

# 🎉 さいごに

リアルタイム文字起こし＋GPTチャットで、会議がもっと生産的で楽しくなる可能性を感じていただけたでしょうか？

下記から無料ダウンロードできるので、ぜひ試してみてください！

https://booth.pm/ja/items/4675430

「これって〇〇にも使えるんじゃない？」というアイデアがある方、ぜひコメントで教えてください！
一緒に「AI駆動型コミュニケーション」の未来を想像しましょう🚀
orangepi でテレビを見たい

# はじめに
パソコンとかスマホでテレビ、見たいですよね！！！

ネットで調べてみると、 ラズパイの情報はたくさんありますが、私が持ってる Orange Pi の情報は一切なかったです...(2024年9月現在)

なので、自分でやってみました！

# 使用機材
- [OrangePi 3B 4GB](https://ja.aliexpress.com/item/1005005919873216.html)
- [PX-S1UD V2.0 (テレビチューナー)](https://amzn.asia/d/ivrVLJ1)
- [SCR3310V2.0 (B-CAS リーダー)](https://amzn.asia/d/do9xBhP)
- [(mini B-CAS を B-CAS に変換するアダプター)](https://amzn.asia/d/aOkgRfc)

## 前提
方法は忘れてしまいましたが、 OrangePi は SSD から起動できるようにしています

# 困った事等
参考にしたサイト：[Raspberry Pi 4 と docker-mirakurun-epgstation で録画サーバーを構築する (2023年2月版)](https://blog.ch3cooh.jp/entry/2023/02/25/174845#PX-S1UD-V20-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%8A%E3%83%BC%E3%81%AE%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

## 詰まったこと1: Docker
### 詰まった
`sudo apt install -y git docker docker-compose`
`docker -v`
ここで、dockerのバージョンが表示されない。docker-composeは表示された
### 解決策
[【簡単な4つの方法】UbuntuにDockerをインストールするには](https://kinsta.com/jp/blog/install-docker-ubuntu/#ubuntudocker-engine)
```shell
sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update

sudo apt install docker-ce docker-ce-cli containerd.io
sudo systemctl enable docker

sudo reboot
```

## 詰まったこと２：リーダーが上手く動いてない
### 詰まったこと
`curl -X PUT "http://orangepi-ip-address:40772/api/config/channels/scan"`
でスキャンが上手く行かない
```
channel: "24" (12/50) [24%] ...
-> 1 existing config found.
-> {"name":"テレビ朝日","type":"GR","channel":"24"}
# scan has skipped due to the "refresh = false" option because an existing config was found.
```
### 解決策
まずリーダーが認識されてるか確認する
`lsusb`

次に、B-CASが読み取れているか確認
`sudo pcsc_scan`
私は mini B-CAS が読み込まれてなかったのをこれで気づくことが出来ました！（なのでアダプターを購入した）

`curl -X PUT "orangepi-IP:40772/api/config/channels/scan?refresh=true"`

```terminal
channel: "27" (15/50) [30%] ...
-> 2 services found.
-> {"name":"ＮＨＫ総合","type":"GR","channel":"27","isDisabled":false}
```

# 結果
見られるようになりました！（さすがにテレビ画面は権利的に良くない気がするので...）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/7dc630bc-6fab-46ce-ea1d-012381b4a68c.png)
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/20bb3a77-4bff-853f-cdc6-1eb00877d0fb.png)


# 最後に
結果でも書いたように見られるようになりましたが、OrangePiのスペック的に480pでも偶に止まります...
ただ、録画された番組はサクサク見られるので、そのように運用すると良さそうです

また、エンコードも重いです。結構時間がかかります...

![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/3723f131-5618-a7f4-0163-0486f9a3ba3f.png)
RevenueCatが他のアプリケーションに与える影響と統合の可能性


アプリ開発において、サブスクリプション管理は重要な課題の一つです。ビジネスモデルとして、サブスクリプションは収益を安定化させ、ユーザーとの継続的な関係を築く手段です。しかし、その実装や管理は複雑です。ここで役立つのが、RevenueCatです。今回はRevenueCatが他のアプリケーションにどれだけ影響を与え、どのように統合できるかについてご紹介します。

## RevenueCatの強力なサブスクリプション管理機能
RevenueCatは、アプリにサブスクリプション管理を簡単に組み込むためのSDKとAPIを提供しています。このツールの最大の強みは、複雑なサブスクリプションシステムを数行のコードで実装できることです。特に、次のような面でアプリケーションに大きな影響を与えます。

## 効率的なサブスクリプション管理
App StoreやGoogle Play Storeでのサブスクリプション管理は手間がかかりますが、RevenueCatを使用することで、購入、キャンセル、復元などのサブスクリプションプロセスが自動化されます。これにより、開発者はビジネスロジックやユーザー体験に集中できるようになります。

### 収益の最大化
RevenueCatは、ユーザーのサブスクリプション状況をリアルタイムで追跡し、どのプランが最も収益を生むかを簡単に分析できます。これにより、アプリの収益性を最適化するためのデータ駆動型の意思決定が可能です。

### クロスプラットフォームサポート
RevenueCatはiOS、Androidなど複数のプラットフォームに対応しており、1つのコードベースで異なるストアのサブスクリプションを管理できます。これにより、プラットフォーム間の一貫性を確保しながら、開発リソースを節約できます。

### RevenueCatのアプリケーションへの適用例
では、どのようなアプリケーションにRevenueCatが役立つか見てみましょう。

1. **フィットネスアプリ**
フィットネスアプリは、無料版と有料版の両方を提供し、パーソナライズされたトレーニングプランや栄養ガイドへのアクセスを提供するサブスクリプションモデルが一般的です。RevenueCatを使用すると、サブスクリプションの管理が簡単になり、ユーザーがトライアル終了後に自動的に有料版へ移行できる機能もシンプルに実装できます。

2. **教育アプリ**
教育アプリでは、特定のコースや教材へのアクセスにサブスクリプションモデルを利用することが多いです。RevenueCatを利用することで、ユーザーの進捗に応じてプランを動的に変更したり、定期購読のキャンセルや休止を簡単に行えます。これにより、教育アプリのサブスクリプションの柔軟性が増し、ユーザーエクスペリエンスが向上します。

3. **メディアストリーミングアプリ**
音楽やビデオのストリーミングアプリにとって、ユーザーがどのプランを選択しているか、再生可能なコンテンツの制限を管理することは重要です。RevenueCatはこれらの機能を簡単に管理し、バックエンドの複雑な処理を代行します。さらに、ユーザーがデバイスを変えた場合も、プラットフォームを横断してサブスクリプションを維持できます。

### 他のツールとの統合
RevenueCatは他のツールとも柔軟に統合でき、アプリの成長をさらに加速させます。

### Slackとの統合
RevenueCatはSlackと連携して、サブスクリプションの更新や解約などのイベントをリアルタイムでチームに通知できます。これにより、問題が発生した場合、すぐに対応できる体制が整います。

### Segmentとの統合
RevenueCatのデータをSegmentに統合することで、ユーザーのサブスクリプション行動を他のデータと組み合わせてより深く分析できます。たとえば、サブスクリプションをキャンセルしたユーザーが、どのアクションを取った後に離脱したのかを追跡し、リテンション戦略を改善することが可能です。

### AmplitudeやMixpanelとの統合
サブスクリプションデータをAmplitudeやMixpanelに統合することで、ユーザーの行動分析がさらに強化されます。どの機能がプレミアムユーザーに人気があるかを把握し、新たなマネタイズ戦略を設計することができます。

## まとめ
RevenueCatは、サブスクリプションモデルを持つあらゆるアプリケーションにとって強力なツールです。シンプルな実装と、クロスプラットフォーム対応、他ツールとの統合により、ビジネスの成長を大きく促進します。私たちのように短期間で効果的なサブスクリプション管理を実現したいと考えている開発者には、ぜひRevenueCatの導入を検討してみてください。
Lambda関数からプライベートサブネットのリソースへアクセスする方法

今回は、Lambda関数からプライベートサブネット内のAWSリソースにアクセスする方法について解説します！
この内容は、実務でもよく使うシーンがあり、さらにAWS認定ソリューションアーキテクト アソシエイト (SAA)の試験範囲にも含まれていますので覚えたい内容です！
よく忘れてしまう内容なので自分なりにまとめました。

結論としては、Lambda関数からプライベートサブネット内のリソースにアクセスするには、Lambda関数にVPCアクセスの設定を行う必要があります。


**LambdaとVPCの関係**
Lambda関数は作成されると、自動的にLambda専用のセキュアなVPCに構成されます。このVPCからはインターネットやパブリックサブネット内のAWSリソースへはアクセスできますが、プライベートサブネット内のリソースには直接アクセスできません。


**プライベートサブネット内のリソースへアクセスするには?**
Lambda関数からプライベートサブネット内のリソースにアクセスさせたい場合、Lambda関数にVPCアクセスの設定を行います。この設定では、アクセスしたいリソースがあるVPCやサブネットを選択、Lambda関数に適切なセキュリティグループを設定します。


このVPCアクセスを設定すると、Lambda関数はENI（Elastic Network Interface）をサブネット毎に作成し、そのENIの間にプライベートサブネット内のAWSリソースにアクセスすることができます。


**注意点: Lambda関数とインターネットアクセス**
注意点として、Lambda関数にVPCアクセスを設定すると、インターネットへのアクセスができなくなるという点があります！！
この問題を解決するには、プライベートサブネットからインターネットへアクセスする際に使用するのと同様に、パブリックサブネットのNATゲートウェイまたはNATインスタンスを利用する必要があります。


**まとめ**
Lambda関数からプライベートサブネット内のリソースにアクセスするにはVPCアクセスの設定が必要です。
VPCアクセス設定を行うと、Lambda関数はプライベートサブネット内のリソースに接続できるENIを作成します。
インターネットアクセスが必要な場合はNATゲートウェイを使って解決します。
本番環境を仮想環境でも使えるようにする方法

仮想環境だとどうしてもインストールできなかったので本番環境にapt-getでインストールした後仮想環境で本番環境を使えるようにしました。

まずはapt-getでインストール
```
sudo apt-get update
sudo apt-get install python3-numpy python3-pandas
```
その後、仮想環境のディレクトリ内のpyvenv.cfgを編集します。
```
nano myenv/pyvenv.cfg
```

デフォルトではこの値がfalseになってるので、ここをtrueにしましょう。
```
include-system-site-packages = true
```

これ知らなかったんですけど、かなり便利だと思います。また一つ勉強になりました。
これからの時代に活躍するエンジニアになるために必要な要素📚


今回は日本CTO協会理事を務めるCTO今村さんの特別セミナーに参加してきました。そこで得たものを共有しつつ、ここで記事にすることで頭にこのマインドを刷り込みます。

## 1. **活躍するための習慣を身につける**
### ・周囲を巻き込む行動
- **技術記事の共有**
技術記事の共有はチームとのコミュニケーションで大切！！仲間のモチベーションの向上や開発のヒントになる。
→**チームで成長する　これ大事**

- **チームに馴染む**
**謙虚さ・尊敬・信頼**：人間関係の衝突はこれらのいずれかが欠けたときに起こる。リスペクトを忘れない。

### ・圧倒的なインプット・アウトプット
- 毎日1時間は何があっても勉強する
- 技術のトレンドを常にキャッチアップし続ける

### ・客観的に自分を観察する
- **例：コードレビュー**
  - 「このメソッドの制御フローは完全に間違っています。みんなが使っているABCパターンを使うべきです」
     **→**「この部分の制御フローがよくわからないのですが、ABCパターンを使うと読みやすくなるのでしょうか？」
- 自分の書いたコード **≠** 自分自身

### ・特許的な観点を意識する
- これまでの方法における「課題」は何だったのか
- その解決のために必要な技術や考え方は何か
- そのアイデアは既存の方法よりも優れているか？

日々の業務の中にイノベーションを生む機会はたくさんあります。毎プロジェクト、毎機能開発ごとに特許的な視点を持ちましょう。

### ・テクノロジーのトレンドを知る
- どんな技術にも**ライフサイクル**と呼ばれるものがある。
知らないから使わないじゃなくて、知ってるけどこの機能はこの技術のほうがいいから使わない。日々の技術のキャッチアップは大切！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664061/f6ecd8fd-ce62-adbd-e6a5-8e6e14d9977f.png)


### ・各分野のテクノロジーのロードマップを参考にする
- 各分野の技術トレンドを押さえ、日々の技術選定や新しいものを学ぶ際の参考にする

| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664061/044cd024-dc29-03fd-19d0-a26f1277e793.png" width=50%>  |  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664061/63278bce-9212-a25e-6086-57357e014f8d.png" width=25%> |






## 2. **高い開発生産性を実現し続ける**
### ・開発生産性を上げる
- 開発生産性とは、ソフトウェア開発におけるコードの品質やデリバリー速度・安定性などを指標化したもの
- 開発生産性を向上させることで、開発組織のスループットを高め、顧客・ユーザーへの提供価値を上げる

事業・プロダクトのKPI → プロダクトの品質、開発組織のスループット → **Four Keys**

**Four Keys**とは、DevOps Research and Assessment（DORA）チームが6年間の研究から確立した、ソフトウェアエンジニアリングチームのパフォーマンスを示す4つの指標です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664061/bb5a44f5-8e2d-5cb0-9330-efe36cb2ebc3.png)


## 3. **生成AIを活用して事業貢献を目指す**
### ・AIをエンジニアとして使いこなす
- 生成AIの利用・普及により、コードを書く難易度と工数は下がります。エンジニアとしては、より前後のプロセスを含む状況で付加価値を発揮する必要があります。特に、開発における上流プロセスへの理解が重要になります。また、すべてのプロセスで生成AIの活用が必須となります。

### AIを武器にする／プロダクトに生成AIを組み込む

- 生成AIの登場により、これまで工数がかかっていたことや技術的に難しかったことが簡単になりました。プロダクトに生成AIを組み込み、ユーザー体験をさらに向上させ、事業への貢献を目指します。

---

## 要約

1. **活躍するための習慣を身につける**
   - インプット、アウトプット、HRT（謙虚さ、尊敬、信頼）、技術的挑戦、技術トレンドを継続的にキャッチアップする

2. **高い開発生産性を実現し続ける**
   - Four Keysを活用し、開発者体験を改善・実現する

3. **生成AIを活用して事業貢献を目指す**
   - 生成AIの活用を前提に、エンジニアとしての仕事の幅を広げる
   - プロダクトに生成AIを取り入れ、新たなユーザー価値の提供を目指す

## 感想
やはり今のエンジニアはただものを作るというでけではなく、なにがユーザーにとって重要なのかを考えて作らなければならないことを改めて実感しました。このセミナーで学んだことを頭にい入れ習慣化させていくことで、そのプロダクトで何がしたいのかつまり、ユーザーに何を提供するのかを考え提案できるエンジニアになろうと思います。
if (!hoge)に使えるhogeはなに(JavaScript)

気になったので調べてみた

### こういうやつ

~~~
if (!hoge) {
.....
}
~~~

### そのときのhogeは
- false
- null
- undefined
- 空文字（長さが0の文字列のこと）
- NaN
- 数字の0（-0や-0.0などもOK）
- 0n
のどれかになる


### 最後に
真偽値に変換したとき、falseになる値をfalsyな値という。
今回の値はfalsyな値にあたる。
※trueになる値はtruthyな値という。
Excelで文字列の中から特定の文字より左側（手前まで）を抜き出す

## はじめに
業務で、タイトルに書いたことをやりたい場面がありました。
例えば、index.htmlという文字列から、"."より手前の文字列(index)を抜き出すということです。
残しておきます。

## 数式
数式はこんな感じです。
```
=LEFT(${参照セル},FIND("${文字}",${参照セル})-1)
```

例えば、A1セルに入力された文字列から、"."より手前の文字列を抜き出す場合はこうなります。
```
=LEFT(A1,FIND(".",A1)-1)
```

## 実行例
A1のセルに記載されたindex.htmlという文字列から"."より左側の文字列(index)を抜き出します。

A1セルには「index.html」という文字列が入力されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/2c81c45f-386b-4120-39b3-79b3d7c6bdb8.png)

A3セルに数式を入力してEnterを叩くと"index"が抽出されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/d6db4132-14e9-3da0-1395-8acb2eddec76.png)

"."が複数ある場合は、左から1番目の"."から左側を抽出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/aa4d40b0-47a3-1c4a-e670-95e13c165966.png)

## カラクリ
この数式はLEFT関数とFIND関数が組み合わさっています。

### LEFT関数
文字列の先頭から、指定する文字数までを抜き出す関数です。
↓A1セル(index.html)から3文字目まで抽出
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/7f4a37a0-ee68-06c3-17da-458ec5cbfbdd.png)

### FIND関数
文字列の中から、特定の文字が何番目に出てくるのかを教えてくれる関数です。
3つ目の引数は、「何文字目から探し始めるか？」を設定します。
↓A1セル(index.html)で"."は何文字目か。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/40f0793a-b506-8f8e-9fdc-b6f7725b699d.png)

### LEFT関数+FIND関数
もう1度式を見てみます。
```
=LEFT(A1,FIND(".",A1)-1)
```

LEFT関数の2番目の引数に"FIND(".",A1)-1"が入っています。

"FIND(".",A1)"の結果は6になります。
※FIND関数の3つ目の引数を省略すると暗黙的に1が入ります。

そこから-1することによって5となり、「指定した文字より手前まで」を抽出できます。
=LEFT(A1,5)

![AdobeStock_483074769.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3848705/077c5f0d-e7ac-9707-5b18-9fe537ff5b6a.jpeg)
oracle テーブル 権限 備忘録

Oracle 19c では、特定の表に対してのみユーザーに SELECT 権限を付与し、不要な権限を与えないように管理できます。以下にその手順をまとめます。

1. ユーザーの作成

まず、新しいユーザーを作成します。

CREATE USER user_name IDENTIFIED BY password;

2. 基本的な権限の付与

ユーザーがデータベースに接続できるようにするために、CONNECT 権限を付与します。

GRANT CONNECT TO user_name;

3. 特定の表に対して SELECT 権限を付与

ユーザーに特定の表に対する SELECT 権限を付与します。

GRANT SELECT ON schema_name.table_name TO user_name;

複数の表に対して権限を付与する場合、それぞれの表に対して個別に実行します。

GRANT SELECT ON schema_name.table_name1 TO user_name;
GRANT SELECT ON schema_name.table_name2 TO user_name;

4. ロールを使用して権限を管理（オプション）

複数のユーザーに同じ権限を付与したい場合は、ロールを作成し、そのロールに対して権限を付与する方法が便利です。

CREATE ROLE select_role;

GRANT SELECT ON schema_name.table_name1 TO select_role;
GRANT SELECT ON schema_name.table_name2 TO select_role;

GRANT select_role TO user_name;

これにより、権限の管理が簡単になり、複数のユーザーに対して一括で権限を付与できます。

5. ユーザーやロールの権限を取り消す

ユーザーの権限を取り消す

特定の表に対するユーザーの SELECT 権限を取り消すには、以下のコマンドを使用します。

REVOKE SELECT ON schema_name.table_name FROM user_name;

他の権限（INSERT, UPDATE, DELETE など）も取り消すことができます。

REVOKE INSERT ON schema_name.table_name FROM user_name;
REVOKE UPDATE ON schema_name.table_name FROM user_name;
REVOKE DELETE ON schema_name.table_name FROM user_name;

ロールの権限を取り消す

ロールに対する特定の権限を取り消す場合、以下のようにします。

REVOKE SELECT ON schema_name.table_name FROM select_role;

6. ユーザーやロールの削除

ユーザーの削除

ユーザーを削除し、そのユーザーが持つオブジェクトも一緒に削除するには、CASCADE オプションを使用します。

DROP USER user_name CASCADE;

オブジェクトを保持したい場合は、手動で処理した後、ユーザーを削除します。

DROP USER user_name;

ロールの削除

不要になったロールは以下のコマンドで削除できます。

DROP ROLE select_role;

7. ユーザーやロールの権限を変更

GRANT や REVOKE コマンドを使って、ユーザーやロールの権限を随時変更することができます。

ユーザーに UPDATE 権限を付与する場合：

GRANT UPDATE ON schema_name.table_name TO user_name;

ロールから INSERT 権限を取り消す場合：

REVOKE INSERT ON schema_name.table_name FROM select_role;


これらの手順を通じて、ユーザーやロールに対する権限を柔軟に管理し、特定の表へのアクセスのみを許可し、不要な権限を付与しないように制御できます。
react-markdownのcodeblockにコピーボタンを配置する話

前回、[react-markdownをカスタマイズしてコードをSyntaxHighlighterを適用する方法](https://qiita.com/wataru775/items/61db1371655897aea517)を書きました。
コードを表示するとクリップボードにコピーして利用することが多いと思いますのでコピーボタンを配置しておきます

# クリップボードにコピーを行う方法

はじめにクリップボードに文字列をコピーする方法を書いておきます。

```typescript
navigator.clipboard.writeText(code);
```

# コピーボタンを設置する

次にコピーボタンを配置します。

今回は一番単純な方法でCodeBlockに直接書き込む方法を取ります

```typescript
const copyToClipboard = (code: string) => {
    navigator.clipboard.writeText(code);
};
 
return (
    <div style={{ position: 'relative' }}>
        <span style={{ position: 'absolute', top: '10px', right: '16px' }}>
            <button onClick={() => copyToClipboard(children)}>Copy</button>
        </span>
        <SyntaxHighlighter
            style={atomDark}
            language={lang}
        >
            {String(children).replace(/\n$/, '')}
        </SyntaxHighlighter>
    </div>
);
```
これによりコードの右上にコピーボタンが配置されました

# 終いに
　ReactMarkdownで表示したコードスタイルにコピーボタンを配置しました

デザイン的にボタン！設置とダサいですが
マウスオーバーするとボタンを表示させたり、
ボタンを押下すると数秒間「Copied … 」とか表示させるとか

色々できます

カスタマイズしてもっと楽しみましょう

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

https://www.mmpp.org/archives/3270
正規表現で省略するcharの分岐

自分、訳あってコンパイラの空白文字の比較コードを書いていたらこう思いました。
これ、正規表現で省略できるぞと。
他の部分で正規表現を多用していたため気付きました。
## Before
この場合は、空白かどうかを判定します。
```cs
namespace Sample{
    public class Sample{
        public static bool isEmpty(char code){
            switch(code){
                case '\t':
                case '\r':
                case '\n':
                case ' ':
                    return true;
                default:
                    return false;
            }
        }
    }
}
```
## After
```cs
using System.Text.RegularExpressions;
namespace Sample{
    public class Sample{
        public static bool isEmpty(char code){
            return Regex.IsMatch(code.ToString(),"\\s")
        }
    }
}
```
## 説明
まず、`char`の引数を`ToString`しているため1文字なので、`^\\s$`のような配慮は必要ありません。
`\\s`は正規表現では空白の意味ですのでこれで判定可能です。
## 応用
これ、意外と応用できます。
- `\\d`を使うことでその文字が数字かを判定する
- `[A-Z]`を使うことでその文字が大文字ASCIIかを判定する
- `[ABC]`を使うことでその文字がA,B,Cのどれかかを判定する
詳細については他記事をご参照ください。
一文字の正規表現を使えばいいですが、正規表現の`\`は`\\`と書くことを注意しておいてください。
【Mac/ブラウザ版】Figmaで新たにフォントを追加する方法

# はじめに
FigmaにはデフォルトでGoogleフォントが搭載されていますが、別のフォントを使用する場合はそのフォントをPCにインストールし、Figmaデザインファイルからアクセスする必要があります。

フォントの追加に少し手こずったので、備忘録としてまとめました。

# 1. フォントをダウンロードする
まずは使用したいフォントを公式サイトからダウンロードし、PCにインストールします。
例えば、SF Proであれば以下のリンクからダウンロードできます。

https://developer.apple.com/fonts/

ダウンロードが完了したかどうかを確認するには、デフォルトアプリの「Font Book」を使用します。「Font Book」は、Finder > アプリケーション > Font Bookで見つけることができます。

![スクリーンショット 2024-09-18 19.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/682c82fe-6c65-40d9-1c6a-cdaebd31f270.png)

無事にダウンロードが確認できたら、次に進みます。

# 2. Figmaフォントインストーラーのインストール
次に、Figmaフォントインストーラーをインストールします。
ブラウザでFigmaを使用している場合、このフォントインストーラーが必要です。（これを知らずに手こずりました）

以下のページからフォントインストーラーを選択してダウンロードします。

https://www.figma.com/ja-jp/downloads/


# 3. ブラウザ版Figmaでのフォント利用
インストールが完了したら、ブラウザで開いているFigmaのファイルを再読み込みします。これで、フォントを使用できるようになります。

Figmaデザインファイル内でテキストを選択または新しく作成し、右サイドバーの「Text」タブを開きます。

追加したフォント名で検索するか、「Installed by you」でフィルタリングすると、自分がインストールしたフォントを確認できます。

![スクリーンショット 2024-09-18 19.12.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/f675d57c-5fb1-4f19-5cb0-905a6650ddeb.png)

 # 参考
- [Figmaデザインへのフォントの追加](https://help.figma.com/hc/ja/articles/360039956894-Figma)
- [教え子さんに備忘録：おすすめ日本語フリーフォントと、figmaブラウザ版でフリーフォントを使う方法](https://note.com/hoxai/n/ne0c70d1421bb)
【GORM】Modelメソッドにはポインタ型の構造体を渡そう

一般的にCRUDする分には、Modelメソッドに値型の構造体を渡しても動作はします。
```go
if err := db.Debug().
    Model(User{}).
    Where("id = ?", 1).
    Updates(User{Age: 30}).Error; err != nil {
	fmt.Println("error:", err)
}
```
## 発生するエラー
しかし、Hooksを設定している状態で、Modelメソッドに値型の構造体を渡すと、以下のようなエラーが出力されます。
```
invalid value, should be pointer to struct or slice
```

## Hooksとは
特定のテーブルに対して作成、取得、更新、削除の操作を行う前後に自動的に呼び出される関数のことです。
参考: https://gorm.io/ja_JP/docs/hooks.html

## エラーが発生するコード例
```go
func dbInit() *gorm.DB {
	dsn := "root:@tcp(127.0.0.1:3306)/verify_db?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println("gorm open error:", err)
	}
	return db
}

type User struct {
	ID           uint
	Name         string
	Email        *string
	Age          uint8
	Birthday     *time.Time `gorm:"type:date"`
	MemberNumber *string
	ActivatedAt  *time.Time
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

func (u *User) BeforeSave(tx *gorm.DB) (err error) {
	fmt.Println("BeforeSave run")
	return
}

func main() {
    db := dbInit()
    
	if err := db.Debug().
		Model(User{}). // 値型の構造体だとエラー
		Where("id = ?", 1).
		Update("age", 20).Error; err != nil {
		fmt.Println("query error:", err)
	}
}
```
このコードを実行すると、以下のようにエラーが発生します。
```shell
% go run main.go
query error: invalid value, should be pointer to struct or slice
```
`User`構造体に定義した`BeforeSave`メソッドが呼び出される前に、エラーで処理が中断されてしまいます。

## 解決方法
```go
if err := db.Debug().
	Model(&User{}). // ポインタ型の構造体に変更
	Where("id = ?", 1).
	Update("age", 20).Error; err != nil {
	fmt.Println("query error:", err)
}
```
基本的には、Modelメソッドにはポインタ型の構造体を渡すようにしましょう。
event.preventDefault(); とは？フォーム送信時のページリロードを防ぐ方法

## はじめに
こんにちは、未経験からエンジニア転職を目指しているものです。
オンラインスクールで本格的に学習して4ヶ月目に入りました。勉強し始めの頃の自分が疑問に思っていたことを整理してみようと思い記事を書いております。HTML,CSS,JSを使用しログインフォームを作成した時に、`event.preventDefault();`を学びました。なぜこの記述が必要なのか疑問に思い、整理してみました。

## 作成したログインフォーム
まずは作成したログインフォームを紹介いたします。

![スクリーンショット 2024-09-18 18.59.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3846051/4a2d77d6-c5df-165f-8e75-5f3ac0405d22.png)


## event.preventDefault(); とは？
`event.preventDefault();` は、JavaScriptでイベントが発生したときに、そのデフォルトの動作をキャンセル（防ぐ）ためのメソッドです。

例えば、フォームを送信すると通常ブラウザはそのデータをサーバーに送信し、ページをリロードします。しかし、このデフォルトの動作が必ずしも望ましいとは限りません。`event.preventDefault();` を使うことで、このリロード動作を止め、JavaScriptによる独自の処理を実行できます。

## なぜ event.preventDefault(); を使うのか？
主に次のような理由で使われます：

**1. ページの再読み込みを防ぐ**
フォームが送信されると、ページはリロードされます。しかし、再読み込みされると、ユーザーが入力した情報や、JavaScriptで保持している一時的なデータが失われてしまいます。`event.preventDefault();` を使うことで、ページの再読み込みを防ぎ、ユーザーの操作をスムーズにできます。

**2. カスタム処理を実行する**
フォーム送信時に特定の処理（例えば、入力データをサーバーに送信する、バリデーションを行う、ローカルにデータを保存するなど）を行いたい場合、デフォルトの送信動作を防ぐことで、JavaScriptで必要な処理を実行できます。



## 具体的な例
**例1: 通常のフォーム送信**
まず、`event.preventDefault();` を使わない場合のフォーム送信を見てみます。

```html
<form id="login-form">
        <input
          type="email"
          id="email"
          class="storage"
          placeholder="name@company.com"
          required
        />
        <div class="password">password</div>
        <input type="password" id="password" class="storage" required />
        <button type="submit" class="submit">Sign in</button>
      </form>
```
```js
const loginForm = document.getElementById("login-form");

  loginForm.addEventListener("submit", (event) => {

    const email = emailInput.value;
    const password = passwordInput.value;

    console.log("サインイン処理を実行: ", email, password);
    });
```

この場合、フォームが送信されるとページが再読み込みされ、コンソールに結果が表示されない可能性があります。

**例2: event.preventDefault(); を使ったフォーム送信**
次に、`event.preventDefault();` を使ってフォーム送信を見てみます。

```html
<form id="login-form">
        <input
          type="email"
          id="email"
          class="storage"
          placeholder="name@company.com"
          required
        />
        <div class="password">password</div>
        <input type="password" id="password" class="storage" required />
        <button type="submit" class="submit">Sign in</button>
      </form>
```
```js
 const loginForm = document.getElementById("login-form");

loginForm.addEventListener("submit", (event) => {
    event.preventDefault(); // フォームのデフォルトの送信動作をキャンセル

    const email = emailInput.value;
    const password = passwordInput.value;

    console.log("サインイン処理を実行: ", email, password);
    });
```

このコードでは、フォームが送信されてもページがリロードされることはなく、console.log() によってサインイン処理を実行します。（例：サーバーに送信）

## まとめ
`event.preventDefault();` は、デフォルトのフォーム送信動作を防ぎ、より柔軟にフォーム送信を処理するために便利なメソッドです。これを活用することで、スムーズなユーザー体験を提供できるだけでなく、フォーム送信時にJavaScriptでカスタム処理を実行することも可能になります。


最後までご覧いただき本当にありがとうございました！！
AIを使ってYoutuberになる為に

ふと、ある日こんなことを考えた

> 動画投稿なんて恥ずかしくてしていなかったが、AIを化身として動画投稿すれば、身バレしないし好きな表現ができそう..!

そして、AIであることはなるべく視聴者にバレたくない。というのは、自分自身動画コンテンツを見るときに、映像がAIだと思うと、求心力に影響があると思うからだ。特に、Vlogのようなストーリー性、一貫性を消費するコンテンツにおいては相手がAIであることを理解した上で関心を持つ人はまだ少ないだろう。

> （目の前にいる友人を差し置いて、スマホに映る一度もあったことのないインフルエンサーのコンテンツをみる現代人は、AIにすぐ慣れると思うが）

おそらく、現時点で投稿者を唯一の人間たらしめるのは、フォロワー数とコンテンツの内容だ。同じ顔の人が、ある程度のフォロワーを持っていれば、まだ、人間だと思ってくれる気がする。

ただ、更に生成AIの質が上がり、そのコンテンツが溢れると、そのきっかけとなるサービスのリリースを起点に人間判定されると思う。
言いたいこととしては、今ならまだ人間のふりができそうだ、ということだ。

### 必要な用件
- 同じ人を動画の主人公にすることができる
- 話している口の動きと音声が一致している必要がある

### 調べたサービス

- [Describe](#Describe) AI動画編集ソフト
- Runway

### Describe

Describe は動画を編集するサービスだったので今回は利用しなかった。
このサービスに動画をアップロードすると、文字起こしをしてくれる。その生成された文字起こしを編集することで動画が編集できる。例えば、削除すればカットになる。AIの機能としては、文字の追加がある。喋る文章を追加すると、スピーカーの認証を求められる。内容は声で声明文を読み上げたものを提出するもので、審査に通るとそのスピーカーから話す内容を新たに生成することができる。よくある、ひろゆきボイスAIみたいなもののイメージです。

### Runway

このサービスでは、text, image, video から, それぞれを生成できる。今回は text + image To video で利用した。
被写体のイメージを置いて、そのシーンからtext で指定した動きをさせることができる。 [公式サイトのサンプル](https://help.runwayml.com/hc/en-us/articles/30266515017875-Creating-with-Gen-3-Alpha)
私は一人の被写体を利用して長時間の動画を作りたかった。このサービスでは一度に10秒の動画しか生成できない為、

0. 画像を用意する
1. 画像から動画を作る
2. 動画の最後のシーンを新たな写真入力として1に戻る

というのを繰り返して、長時間の動画を生成しようとした。

### やってみた感想

動画を作る中で以下の難点を感じた
- 意図通りにシーンを動かせない
- 物理に反した動きをよくする
- 再生成すればいつか直るがその前に利用制限に引っかかる (今回の検証は3時間ほど行ったが、それだけでBasic プランの 4/5 程度 (500token) 使ってしまった)

前の[ホリエモン級のクオリティ](https://romptn.com/article/44268)はどのように再現できるのだろうか。
(本当にAIなのだろうか..?)

十分なデータを入力できるインターフェースが提供されていること、被写体の十分なデータを用意することが、AIの動画生成のコツなのかもしれない。

ホリエモンの動画を見た時の衝撃を思い出すと、逆に、AIで作った動画だと言って、実写をあげるのもインパクトを残せるかもしれない。
motoを使用したDynamoDBのトランザクション処理でThe "SET" section can only be used once in an update expressionが発生した時の対処

以下のような、オペレーションがUpdateのDynamoDB書き込み処理があるとします。

```python:sample.py
import boto3
from boto3.dynamodb.types import TypeSerializer

client = boto3.client("dynamodb")
serializer = TypeSerializer()

options = {
    "TransactItems": [
        {
            "Update": {
                "TableName": "test-table",
                "Key": {"pk": serializer.serialize("test")},
                "UpdateExpression": "SET test = :test",
                "ExpressionAttributeValues": {":test": serializer.serialize("xxx")},
            }
        }
    ]
}

client.transact_write_items(**options)
```

motoでDynamoDBをモック化し、上記ソースコードのテストを実行すると・・・

```
The "SET" section can only be used once in an update expression
```

エラーが出ました。
ちなみにオペレーションがPut、Deleteの時は特にエラーが出ませんでした。


# 解消法
motoのバージョンを5.0.11以上にアップデートする。

# 参考
https://github.com/getmoto/moto/issues/7817

https://github.com/getmoto/moto/issues/7726
CloudFront FunctionsのKeyValueStoreを使ってBasic認証

CloudFront Functionsに追加されたKeyValueStoreのKeyにユーザー名、Valueにパスワードを保存しておいて複数のBasic認証ユーザーを作成して認証できるようにしたコードの共有です。

CloudFront Functionsの関数を作ったら「Associated KeyValueStore」で作成したKeyValueStoreを関連づけてから関数を下記のように書けばOKです。

```Javascript
import cf from 'cloudfront';

// This fails if there is no key value store associated with the function
const kvsHandle = cf.kvs();

async function handler(event) {
    var request = event.request;
    var headers = request.headers;
    var unautherized = {
            statusCode: 401,
            statusDescription: "Unauthorized",
            headers: { "www-authenticate": { value: "Basic" } }
        };

    if ( typeof headers.authorization === "undefined" ){
        console.log("Authorization header is not found!")
        return unautherized
    } else {
        var val = headers.authorization.value;
        val = val.replace('Basic ','');
        var decoded = atob(val);
        var values = decoded.split(":");
        var username = values[0];
        var password = values[1];
        var correctPassword = "Not found"
        try {
            correctPassword = await kvsHandle.get(username);
        } catch (err) {
            console.log(`Key ${username}: ${err}`);
        }
        if ( "Not found" != correctPassword && correctPassword == password ){
            console.log("Authorized!")
            return request;
        }
    }
    console.log("Unauthorized!")
    return unautherized;
}
```

以上です。
「UNIXという考え方」を読んでプログラミング時に参考になった箇所

[「UNIXという考え方」](https://www.amazon.co.jp/UNIX%E3%81%A8%E3%81%84%E3%81%86%E8%80%83%E3%81%88%E6%96%B9%E2%80%95%E3%81%9D%E3%81%AE%E8%A8%AD%E8%A8%88%E6%80%9D%E6%83%B3%E3%81%A8%E5%93%B2%E5%AD%A6-Mike-Gancarz/dp/4274064069)を読んで参考になった箇所（特にコードを書く上で）を紹介する。

# スモールイズビューティフル
プログラムを書くときは小さく書き始め、それを小さいままで保つという考え方。
例えばファイルAとファイルBにコピーするというプログラムを書く場合、以下の手順が必要になる。
>1. ユーザーにコピーする元のファイル名を訪ねる
>2. ファイルがあるかどうかをチェックする
>3. ファイルがなければ、それをユーザーに通知する
>4. ユーザーにコピー先のファイル名を尋ねる
>5. ファイルがあるかどうかをチェックする
>6. ファイルがあれば、ユーザーにそれを上書きするかどうか尋ねる
>7. 元ファイルを開く
>8. 元ファイルが空だったらそれをユーザー通知し、プログラムを終了する
>9. コピー先のファイルを開く
>10. データをコピー元のファイルからコピー先のファイルにコピーする
>11. 元ファイルを閉じる
>12. コピー先のファイルを閉じる

この手順を見ると実際にコピーを行っているのは手順10になり、他の手順はファイルの存在チェックなどの補助的な役割になる。
実際にプログラムを書くときはこれらの手順1つずつをメソッドとして切り出すのが望ましい。例えば手順2のファイルの存在チェックや手順7のファイルを開く動作は他にも流用する可能性が大いに考えられると思う。
自分はこの手順1～12をまとめて1つのメソッドとして作ってしまい、過去に保守が苦しくなった経験がある。。
手順12だけが不要な別処理が必要になった場合に手順1～11をまた別メソッドとして書き、似たような記述があちこちにある状態を作ってしまった。
この経験からもプログラムは小さく書き、そのプログラムを組み合わせるのが最も良いと実感した。

# 効率より移植性
効率と移植性（例えばコードが簡潔だと移植性が高い）は多くの場合、トレードオフの関係にある。
優先するのは移植性と著者は断言している。
移植性を優先する理由はハードウェアにある。ハードウェアは年々性能が高くなっており、ソフトウェア側で処理速度をわずかに速くしようとする努力以上にハードウェアの進歩によって処理は速くなる。
似たような話で「達人に学ぶdb設計徹底指南書」にも正規化とクエリの実行速度の関係を思い出した。正規化をするほどクエリは遅くなるがこの本でも正規化を
できるところまで行うことを主張していた。
プログラムにしろDBにしろやはり保守性（移植性）を最重要するべきということを学んだ。

# 独自技術症候群を避ける
プログラマは自分にしか書けない芸術的な難易度の高いプログラムを書くことに自分の価値を見出すべきではないという考えを著者は主張している。
自分も難しいプログラムを書いたときに達成感を得てしまうことがあるので、ハッとさせられる内容だった。
個人の経験としても頭を悩ませながら書いたプログラムは、他人からすると読みにくいのはもちろん未来の自分もすぐに理解できず困ることが多々ある。
今後、独自技術に価値を見出さずに誰でもすぐに読めるコードを書くことを一層意識しようと思う。そのために上記でも述べた「スモールイズビューティフル」などを意識する必要がある。

# 最後に
この本は他にもそもそもUNIXは歴史上どのような使われ方をしてきたか、ここでは紹介していないUNIXの思想、他のOSとの比較などが書かれているため、非常に面白くためになりエンジニアとして知っていて損はない内容である。
[Diagram] 開発に用いる図と表

# 一覧
|||
|:--|:--|
|DFD|業務を構成する処理とその間で受け渡されるデータの流れを3つ要素(プロセス、源泉と吸収、データストア)およびデータフローを表現|
|CRUDマトリクス|どのデータ(エンティティ)が、どのプロセス(機能)でCreate、Read、Update、Deleteを表現|
|状態遷移図|時間の経過や状況のへかに応じて状態が変わるシステムの動作を表現|
|ペネリット図|並行動作する機能同士の同期を表現することができる図式化手法<br>トランジション(事象)、プレース(状態)、トークン(印)で表現する|
|UML||
|クラス図|クラスの仕様と、クラス間の静的な関係を表現|
|シーケンス図|オブジェクト間の相互作用を時間軸に沿って表現|
|アクティビティ図|オブジェクトの振る舞いを表現|
|コミュニケーション図|オブジェクトがどのようにコラボレーションするかを表現|
|||
|||
|||
|||
|||






# 参考リンク
- [令和2秋46_アクティティ図](https://www.ap-siken.com/kakomon/02_aki/q46.html)
- [令和元秋46_ペネリット図](https://www.ap-siken.com/kakomon/01_aki/q46.html)
OpsRamp - ダッシュボードを共有する方法

本記事では、OpsRampで作成したダッシュボードをほかのユーザーに共有する方法について説明します。

# 概要
OpsRampでは、作成したダッシュボードをほかのユーザーに共有することが可能です。ダッシュボードは、同テナント内のすべてユーザーまたは任意のロールを指定し特定のユーザーに共有することができます。

# 設定方法
ダッシュボードの共有は、対象ダッシュボード右の三点リーダーのShareから可能です。
![dashboard-share1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/b5222e0f-3f27-6f74-4d47-6304bb22cd25.png)
- ロールを指定した特定ユーザーへ共有
SHARE TOにROLESを選択し、任意のロールを選択します。
![dashboard-share2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/a9e6091b-b44f-a4c9-4660-7a4d950785e4.png)

- すべてのユーザーへ共有
SHARE TOにALL USERSを選択します。
![dashboard-share3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/eee6fd65-8eb4-06a8-9481-ef46a79de478.png)


---------------------------------------
[<img width = 250 height = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344939/111de30a-4d33-aa33-5c7d-83d9015093e6.png">](https://www.vistanet.jp/knowledge-base/)
【Amazon Connect Customer Profiles】顧客情報を手作業作成とフローでの自動登録をやってみた

## 本記事の内容
- 手作業での顧客情報作成
- フローでの顧客情報自動作成
- 項目の注意点

## はじめに
Customer Profilesは、Amazon Connect（コールセンターサービス）で使用できる顧客情報の集約サービスです。
本記事では、顧客情報の手作業作成とフローでの自動登録方法について記載しています。
顧客情報は外部データからの取り込みも可能ですが、こちらについては別記事として投稿予定です。

なお、顧客情報を作成後の受電時の挙動などは以下の記事に記載しています。

https://qiita.com/oho-kiyotaka/items/d5c82e5fd727d26b2844

## 本記事の注意点
本記事では以下のように使い分けをしています。
- Customer Profiles：サービスの名称
- 顧客情報：Customer Profilesに登録する顧客データ

## 手作業での顧客情報作成
手作業での顧客情報作成は、Amazon Connectの「エージェントWorkspace」で行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717693/c7c25226-821f-54e6-d228-8737b89ddc81.png)

「+プロファイル」をクリックすると以下のような画面に遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717693/98107713-ed7c-604c-5f89-47f67c256298.png)


上記の画面で名や性、性別などを登録します。
※各項目の注意点は、下部の「項目の注意点」に記載しています。

## フローでの顧客情報自動作成
本記事ではコンタクトフロー上で作成する方法を記載しています。
「お客様のプロフィール」ブロックを使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717693/5be96a81-6831-6f21-48dc-a5ddd27c8da4.png)
今回は上記の画面キャプチャのように「お客様のプロフィール」を2つ使用しました。
1つ目の「お客様のプロフィール」ブロックでは、プロフィールの取得を実施しています。
「何も見つかりませんでした」（該当する顧客情報がなかった）の分岐の後ろに、2つ目の「お客様のプロフィール」ブロックを設定し、プロファイル（顧客情報）を作成を行っています。
以下に設定を載せています。

#### 1つ目の「お客様のプロフィール」設定
アクションを選択では「プロファイルの取得」を選択します。
検索識別子は以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717693/5dcb5766-8937-681d-55c2-b7fb124791f7.png)
顧客の電話番号を基に、登録されている顧客情報から一致する顧客情報を取得します。


#### 2つ目の「お客様のプロフィール」
アクションを選択では「プロファイルの作成」を選択します。
リクエストフィールドやフィールド値をリクエストでは以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3717693/35befde8-d712-690c-d923-bb0570f687e7.png)

このブロックで、顧客情報の「電話番号」に顧客の電話番号を格納し、顧客情報を自動作成することができます。
顧客情報には、「携帯電話番号」の項目もあるので「070,080,090」の時は「携帯電話番号」項目に顧客の電話番号を登録、それ以外の番号の時は「電話番号」に登録するなども可能です。
※どの電話番号項目（「電話番号」や「携帯電話番号」）に登録しても、次回以降の着信時の検索にはヒットします。


## 項目の注意点
日本仕様になっていないため、いくつかの項目は注意が必要です。
- 名前
    - 性・名と項目が分かれていますが、顧客情報を表示する際は「名・性」の順になるため注意が必要です
    - 以下のような対応方法があります
        - 「名」にフルネームを登録する
        - 「性」に名前を、「名」に苗字を登録する
    - 「名」は必須項目のため注意が必要です
- 性別
    - 選択項目の「男性」または「女性」を選択すると、「MALE」や「FEMALE」と表示されてしまいます
    - そのため、日本語表記にしたい場合は「その他(具体的に記入してください)」を選択し、「その他の性別」に男や女などを記載する必要があります
- 追加情報
    - こちらはフリーテキストとなっています
    - 上限は1000文字です
- 住所（「郵送先住所」、「請求先住所」、「配送先住所」、「その他の住所」）
    - 名前同様、「番地」や「市町村」などを記入しても、表示が英語順になってしまいます
    - 対処法としては、「番地」に郵便番号を登録、「アパート/マンション名、部屋番号など」に都道府県以下の住所を登録することで、日本の住所表記にすることが可能です
    - ※住所を登録する際、「市町村」が必須項目となってしまうため、半角スペースや全角スペースを記入することでエラーを回避しています
    - 「市町村」に文字列をいれると、住所の末尾に文字列が入ることになります
- アカウント番号
    - 最初の登録時に記入する必要があります
    - 別の記事で紹介するマージの機能を使用することで編集は可能ですが、手作業での修正が不可となっています

【参考ドキュメント】
[標準プロファイルの定義](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/standard-profile-definition.html)


## まとめ
顧客情報の項目は英語表記や必須項目に注意することが多々あるで、今後日本への対応を強化してもらいたいなと感じました。
本記事で使用した「お客様のプロフィール」の「プロファイルの取得」を利用することで、エージェントとの通話の前に「○○さま、いつもお世話になっております。」というようなプロンプトを組むことも可能でした。
SwiftUI で applicationDidEnterBackground 相当の処理を実行する方法

iOS アプリ開発では、アプリがバックグラウンドに入ったり、フォアグラウンドに戻ったりするタイミングで特定の処理を実行する必要がよくあります。従来の UIKit では、applicationDidEnterBackground(_:) などの UIApplicationDelegate メソッドを使って処理を実行していましたが、SwiftUI ではどうすればよいでしょうか？

SwiftUI では、ScenePhase というライフサイクル管理機能を使うのが一般的です。この記事では、ScenePhase を使って、アプリがバックグラウンドに移行するタイミングで処理を実行する方法を紹介します。

ScenePhase とは？

ScenePhase は、アプリケーションの現在のライフサイクル状態を表す環境値です。以下の3つの状態を持っています。

	•	.active: アプリがフォアグラウンドでアクティブな状態
	•	.inactive: アプリがフォアグラウンドだが、非アクティブな状態（例えば、電話の着信などで一時停止）
	•	.background: アプリがバックグラウンドで実行されている状態
 実装例

以下に、ScenePhase を使ってアプリのライフサイクル状態を監視し、バックグラウンドに入ったときに処理を実行する方法を示します。

```demo.swift
import SwiftUI
struct MyApp: App {
    @StateObject var userManager = UserManager() // ユーザー管理オブジェクト
    @Environment(\.scenePhase) var scenePhase   // ScenePhase の監視

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(userManager)  // 環境オブジェクトとして注入
        }
        .onChange(of: scenePhase) { newPhase in
            if newPhase == .background {
                // アプリがバックグラウンドに入ったときの処理
                print("アプリがバックグラウンドに入りました")
                userManager.saveData()  // 例: ユーザーデータを保存する
            } else if newPhase == .active {
                // アプリがフォアグラウンドに戻ったときの処理
                print("アプリがアクティブになりました")
            } else if newPhase == .inactive {
                // アプリが一時停止状態になったときの処理
                print("アプリが非アクティブになりました")
            }
        }
    }
}
```
コードのポイント

	1.	@Environment(\.scenePhase): scenePhase は SwiftUI の環境値で、アプリケーションの現在のライフサイクル状態を示します。@Environment を使ってこれを監視します。
	2.	.onChange(of:perform:): scenePhase の値が変わったときに、この修飾子を使って状態に応じた処理を実行します。例えば、.background 状態に入ったときにはデータ保存を行います。
	3.	userManager.saveData(): アプリがバックグラウンドに入る際に、必要なデータを保存するなどの処理を行います。

バックグラウンドでの処理の注意点

バックグラウンドに移行する際に行う処理にはいくつかの注意点があります。iOS では、バックグラウンドで実行できる処理には制限があり、長時間の処理はできません。例えば、データ保存などは迅速に行う必要があります。

終わりに

SwiftUI では、従来の UIApplicationDelegate メソッドを使わずに、ScenePhase を活用してアプリのライフサイクルに応じた処理を簡単に実装できます。特に、バックグラウンドへの移行時の処理はよく使われるため、ぜひ ScenePhase を活用してみてください。
GO言語のgo-echartsパッケージを使って横棒グラフを出力する方法

# はじめに

go-echarts

https://github.com/go-echarts/go-echarts


を使ってチャートを出力するシリーズの３つ目の記事です。

１つ目は、

https://qiita.com/twsnmp/items/c0bb1b6b8dd18132dfb6

です。

今回は、横棒グラフの出力方法です。

go-echartsのGitHubにあるサンプルプログラムを、そのまま実行すると縦棒グラフ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/56afe1c8-e94b-ed4d-9f37-d95c87e78bd9.png)

が表示されます。

これを１行追加するだけで、横棒グラフにできるという、お話です。


# 横棒グラフの出力

横棒グラフは、

```go
package main

import (
	"math/rand"
	"os"

	"github.com/go-echarts/go-echarts/v2/charts"
	"github.com/go-echarts/go-echarts/v2/opts"
)

// generate random data for bar chart
func generateBarItems() []opts.BarData {
	items := make([]opts.BarData, 0)
	for i := 0; i < 7; i++ {
		items = append(items, opts.BarData{Value: rand.Intn(300)})
	}
	return items
}

func main() {
	// create a new bar instance
	bar := charts.NewBar()
	// set some global options like Title/Legend/ToolTip or anything else
	bar.SetGlobalOptions(
		charts.WithTitleOpts(opts.Title{
			Title:    "My first bar chart generated by go-echarts",
			Subtitle: "It's extremely easy to use, right?",
		}),
		charts.WithLegendOpts(opts.Legend{Show: opts.Bool(false)}),
	)

	// Put data into instance
	bar.SetXAxis([]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}).
		AddSeries("Category A", generateBarItems()).
		AddSeries("Category B", generateBarItems())
	// X <-> Y
	bar.XYReversal()
	// Where the magic happens
	f, _ := os.Create("hbar.html")
	bar.Render(f)
}
```

で出力できます。結果は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/0a31bd73-dcb6-dc93-d1a3-70f43d2b0a0a.png)

です。

サンプルのコードから変更したのは、

```go
// X <-> Y
	bar.XYReversal()
```

の行を追加して、X軸とY軸を入れ替えただけです。

ただし凡例がタイトルに重なって見にくいので、

```go
charts.WithLegendOpts(opts.Legend{Show: opts.Bool(false)}),
```

の行も追加しています。
見守り番犬システムの運用（TWE-LITEによる見守り⑤インターホン機能）

# １．はじめに
遠隔地に住む祖母の暮らしを見守るため、家に設置した各種センサーの情報をモニタする取り組みを行っておりましたので、主として備忘のためここにまとめます。

モノワイヤレス株式会社の[**「TWE-Lite（トワイライト）」**](https://mono-wireless.com/jp/products/twelite/index.html)を使用してセンサ情報を収集し、親機であるRaspberryPiへ各種情報を記録する仕組みです。

https://mono-wireless.com/jp/products/twelite/index.html

# ２．インターフォン機能
`古い家屋にも後付け可能、工事不要のインターフォンを設置！`
　ドアベルとして設置した「押しボタン」を押すと、室内にチャイムを鳴らすことが可能となります。

![⑩インターフォン機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2944244/4e9c8f6c-ef1c-6b03-aaf1-7f7ff0539ae6.png)

→[**ブルーパル（BLUE PAL ）**](https://mono-wireless.com/jp/products/twelite-pal/BnR/index.html)と接続した**スイッチ**を、[**PAL専用ケース（MW-PAL-CAS-0）**](https://mono-wireless.com/jp/products/twelite-pal/cases/index.html)に格納して設置する。

https://mono-wireless.com/jp/products/twelite-pal/BnR/index.html

https://mono-wireless.com/jp/products/twelite-pal/cases/index.html

# ３．ハードウェア実装
| 区分| 名前 | 説明 |
|:-----------|------------:|:------------:|
| 親機       | Raspberry Pi 4 Model B|	親機となって、センサー情報を記録・発信する本体|
||MONOSTICK|センサー情報を受信するデバイス。「App_PAL」をインストールしておくこと|
| 子機       | BLUE PAL（MW-B-PAL-P）        |情報を送信する無線装置。別途、コイン型電池（CR2032）が必要|
|          |PAL専用ケース（MW-PAL-CAS-0）|インターフォン装置を格納するケース           |
| 　       | タクトスイッチ       |押すとオン、離すとオフになるスイッチ。[**せんごくネット通販**](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=4ALY-L5MU)で購入     |
|その他|Bluetoothスピーカー|あらかじめ Raspberry Piと接続しておくこと|

### ①BLUE PALとスイッチを接続します
PAL専用ケースに穴を開けて、タクトスイッチが通るようにします。BLUE PALのピン２つ（ピン番号14,15）とスイッチを銅線をハンダ付けします。
![マージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2944244/9f33c69a-2b61-b2f2-e4ba-2d1d1136dcf1.jpeg)

### ②ケースにスイッチ部品を収納する
PAL専用ケースにスイッチ部品を収納し、屋外に設置するためホットボンドでシールします。
![DSC_0338.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2944244/25cba43f-34fc-2579-b87a-9d0a2681a2da.jpeg)

# ４．ソフトウェア実装
```python:Pal_Script.py
from apppal import AppPAL
import subprocess

if __name__ == '__main__':
	while True:
        if PAL.ReadSensorData():# データがあるかどうかの確認
            Data = PAL.GetDataDict()# あったら辞書を取得する
            print(Data)			# 標準出力
           
            ★★インターフォンが押された場合の処理★★
            if Data['EndDeviceSID']=='デバイスID':
                if Data['DIO']==3:
                    #スピーカーからインターフォンの音声ファイルを再生する
                    subprocess.Popen(["/usr/bin/aplay","/home/pi/sound/interphone.wav"])
```
# ５．考察
大きめのノックや呼びかけで事が足りてしまうので、未だにインターフォンがないお家ってありますよね。そんな場合でも手軽な電子工作一つで、インターフォンが完成するんだから便利なものです。
今回は省略しましたが、データベースに登録してグラフに出力させれば、遠隔でも来客が分かるようになります。

## ６．工事完成
これまで作ってきた各機能で、遠隔地の祖母見守りシステムの構築は終了となります。たまに不具合が発生するので、その際は祖母邸に訪問して調整を行ったりしています。
実際のところはシステムに頼る見守りより、現地に赴いてお喋りするのが、何よりの見守りになっているのかもしれません。
DevOpsエンジニア、始めました。(1)


## はじめに  

開発経験のないクラウド(インフラ、運用)エンジニアの筆者が軽率にDevOpsエンジニアを目指し、学んだことを自分なりの備忘録にまとめ、シリーズ記事にしていきます。  

## そもそもDevOpsとはなんぞや

開発チームと運用チーム間で連携・協力を行い、ガンガンリリースを回し迅速に信頼性が高いソフトウェアを提供していこうという考え方を元にする手法。   

##  具体的には？  

DevOpsにおいて、各チームが取り組むとみんなが幸せになれる事例
  
### 開発チーム  

1. 継続的インテグレーション（CI）の実践  
2. 品質・セキュリティ・パフォーマンスを考慮したコードを実装
3. 運用チームとの緊密な連携  
など  

### 運用チーム  

1. オペレーション作業の自動化の推進  
2. インフラのコード化(IaC)  
3. スケーラビリティと可用性の確保(いつでもデリバリーできる環境作り)  
4. 開発チームとの緊密な連携  
など  

### 共通  

1. 継続的デリバリー（CD）の実践  
2. 共有知識の育成  
など

## まとめ

DevOpsにおいて、互いの役割の観点での配慮が必要というのが理解できました。  
調べれば調べるほどDevOpsエンジニアへのハードルが高くなってきてドキドキしていますが  
めげずに引き続き取り掛かっていこうと思います。  
次回はDevOpsエンジニアを目指すにあたって必要な分野の知識を掘り下げていきたいと思います。
constexpr virtual 関数におけるMSVCのバグ

C++20から、仮想関数に`constexpr`を指定することができるようになりました。

https://cpprefjp.github.io/lang/cpp20/allow_virtual_function_calls_in_constant_expressions.html

そこで、`constexpr virtual`関数を使ってコードを書いていたのですが、gccとclangではコンパイルが通るのに、MSVCではコンパイルエラーになるという現象に悩まされていました。色々と検証した結果、`constexpr virtual`関数からメンバ変数にアクセスするとMSVCでだけ定数として評価できないようです。
再現コードは以下になります。
```cpp
struct base
{
    constexpr virtual int value() const = 0;
};

struct derived : public base
{
    constexpr int value() const override { return m_val;}
    int m_val = 42;
};
```
https://godbolt.org/z/6z5Y8doqa

Visual StudioのDeveloper Communityで検索した結果、これは報告済みのバグで、現在(2024/9/18)でも修正されていません。

https://developercommunity.visualstudio.com/t/error-C2131-when-calling-constexpr-virtu/10727589

上記のDeveloper Communityにもあるように、関数ポインタを通して呼び出すことによって、`constexpr`関数を使うことができるのですが、煩雑極まりないので早く修正されてほしいです。
【VMware ESXi】OSのバージョンアップデート方法について【コマンド】

### VMware ESXiのバージョンアップデート

```:
#VMwareのバージョン確認
vmware -l

#メンテナンスモードの確認
esxcli system maintenanceMode get

#メンテナンスモードの有効化
esxcli system maintenancemode set --enable true

#メンテナンスモードの無効化
esxcli system maintenanceMode set --enable false

#===================================#
#  ソフトウェアプロファイルの確認   #
#===================================#

esxcli software source profile list -d /vmfs/volumes/<Volume_Label>/VMware-ESXi-6.7.0-8169922-depot.zip

#===================================#
#	ドライランの実行	    #
#===================================#

esxcli software profile update --dry-run --depot=/vmfs/volumes/<Volume_Label>/VMware-ESXi-6.7.0-8169922-depot.zip --profile=ESXi-6.7.0-8169922-standard

#===================================#
#	アップデート実行	    #
#===================================#

#esxkr10
esxcli software profile update -d /vmfs/volumes/<Volume_Label>/VMware-ESXi-6.7.0-8169922-depot.zip -p ESXi-6.7.0-8169922-standard

#再起動
reboot

#VMwareのバージョン確認
vmware -l

```
PostgreSQLが動かなくなった

# 経緯

色々作業したあとにローカルサーバーにおいてあるPHPファイルを開こうとすると、
```txt
Error:SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?
```

なんじゃこのエラー...
軽く見た感じサーバーが止まってるっぽい？再びPostgreSQLを起動しようとすると、

```sh
Job for postgresql.service failed because the control process exited with error code.
See "systemctl status postgresql.service" and "journalctl -xe" for details.
```

と言われたのでおとなしく`journalctl -xe`を実行すると、Hintのところに

```sh
HINT:  Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
```

ポートがかぶってる？...
いろいろしてもなかなか治らず途方に暮れてました。

# したこと
まずはポート`5432`が使用中かを確かめる。

```sh
$ ps aux | grep 5432

root        1424  0.0  0.0  10388  1072 pts/3    S+   16:43   0:00 grep --color=auto 5432
```

うーん...別に使ってなさそう？
再起動もしたりしたけど相変わらず原因はわからず。
`systemctl restart postgresql`も実行してみたけど同じ結果、`stop`からの`start`でも変わらず。
ネットで調べていると前回のプロセスが残っているとか書いてあったけどなかったしなぁ...

# 原因
さっきの出力でもう一つ見落としていた、`HINT:  Future log output will appear in directory "log".`
エラーログをみてみることに。
`postgres`でコマンドにログインして、`ls data/log`を実行してみるとエラーログがあった。
これを開いてみると一番下のところに、
```txt
2024-09-18 16:32:03.411 JST [1413] LOG:  invalid connection type "IPv6"
2024-09-18 16:32:03.411 JST [1413] CONTEXT:  line 93 of configuration file "/var/lib/pgsql/data/pg_hba.conf"
2024-09-18 16:32:03.411 JST [1413] FATAL:  could not load pg_hba.conf
2024-09-18 16:32:03.412 JST [1413] LOG:  database system is shut down
```

これは`pg_hba.conf`ファイルをうまく読み込めていない？...
実際に`pg_hba.conf`ファイルを開いてみると、
```conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
#local   all             all                                     scram-sha-256
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
#host    all             all             127.0.0.1/32            scram-sha-256
 IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local   replication     all                                     trust
#host    replication     all             127.0.0.1/32            trust
#host    replication     all             ::1/128                 trust
```

あ...9行目のIPv6 ~のところのコメントアウトはずれてる。
コメントアウトして再び読み込んでみると、うまくできた!!!

いつのまにか間違えてコメントアウトを外していたみたいです。
ずっとコマンド上のエラーばかり見ていたから気づかなかった...

みなさんもしっかりとエラーログを見るようにしましょう笑
AWSのリソースをコード化する上で検討すべきTerraformのディレクトリ構造

# Terraformのベストなディレクトリ構造とは
これは非常に悩ましい内容だと思います。
まず私の場合は、Terraformの事を相談出来る相手がおらんとです・・・ｗ
調べても調べてもどれがベストなのかは出てこず、
とりあえずシンプルな構成とモジュール構成の大きく分けて２通りだろうということは分かりました。

基礎中の基礎を学びたかったり、Terraformを触ってみたいといった方は
シンプル構成で良いのではないかと思います。
私もまずはコードの書き方を学ぶ必要があるのと、エンターキー１つでリソースが作成されていく気持ち良さを体験するためにシンプル構成でやりました。

下記に実際私が作ったものと類似した構成を記述します。

# 具体的なディレクトリ案
１．シンプルな構成　
簡単にかけるが流用性が低い
```
project/
├──envs
　　 ├──prd/
        ├── main.tf
        ├── variables.tf
        ├── outputs.tf
        └── provider.tf
　　 ├── dev/
        ├── main.tf
        ├── variables.tf
        ├── outputs.tf
        └── provider.tf
```

２．環境ごとにデプロイする構成

enviroment配下のmain.tfが大きくなりがちで、影響が出やすい
```
project/
├── main.tf
├── variables.tf
├── outputs.tf
├── provider.tf
└── enviroment
    ├── prd/
    ├── dev/
    ├── staging/
└── modules/
    ├── network/
    │   ├── main.tf
    │   ├── variables.tf
    │   └── outputs.tf
    ├── ec2/
    │   ├── main.tf
    │   ├── variables.tf
    │   └── outputs.tf
    └── security_group/
        ├── main.tf
        ├── variables.tf
        └── outputs.tf
```

３．リソースごとにデプロイする構成

最良か・・・？だが、環境によって違いが多ければproject配下のルートディレクトリにmain.tfを置かないでその配下に置く必要があるか
```
project/
├── provider.tf
└── resources
    ├── ec2/
    |    ├── prd/ 
    |    │   ├── main.tf
    │    ├── variables.tf
    |    │   └── outputs.tf
    |    │    ├── project1/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf          
    |    │    ├── project2/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf  
    |    ├── dev/
    |    │   ├── main.tf
    |    │   ├── variables.tf
    |    │   └── outputs.tf
    |    │    ├── project1/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf      
    |    │    ├── project2/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf  
    ├── network/
    |    ├── prd/ 
    |    │   ├── main.tf
    |    │   ├── variables.tf
    |    │   └── outputs.tf
    |    │    ├── project1/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf          
    |    │    ├── project2/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf          
    |    ├── dev/
    |    │   ├── main.tf
    |    │   ├── variables.tf
    |    │   └── outputs.tf
    |    │    ├── project1/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf      
    |    │    ├── project2/
    |    │         ├── main.tf
    |    │         ├── variables.tf
    |    │         └── outputs.tf  
```
:::note info
３のリソースごとの構成はあまり見かけないかも知れませんが、
main.tfに大量に書き込まないためデプロイがデストロが早いのと、
多人数で作業する時のstateファイルのデグレが起きないなど、メリットが多いとのこと。
:::

# 感想
右も左も分からないので、まず出来るところから作っていって要件を意識して変更していくしかないと思ったんですよね。
会社によって規模も違いますし、どれくらい構成の変更やdestroyが必要かも分からないので、非常に難しいところです。



ではまた。
高校生のプログラミング

:::note warn
この文章は、あくまで私見です。
私自身もこの意見が絶対的に正しいとは思っていません。
なので、意見補足があれば、ぜひコメントにておっしゃってください。
:::

ここでは、高校生がプログラミングをするにあたり、私が常々重要であると考えていることを記していきます。
高校生と書きましたが、ものによっては社会人も当てはまるでしょう。
私がやってしまった失敗をもとに書いておりますが、反論等ありましたら是非コメントにて。

# プログラミングスクールを当てにするな
いきなりすごいのが来ましたね（自分で言うな）
まぁ、通うなとは言ってません。詳細を書いていきます。

みなさん、プログラミングスクールについてどういうイメージをお持ちでしょうか？
よくみるプログラミングの広告では、「独学はダメ！」とよく言ってるので、やっぱりスクールに通ったほうがいいのかなぁなどと思っていませんか？
まぁ結論から言って、私は独学をお勧めします。

プログラミングスクールは非常に費用が高いです。あなたにやる気があれば独学でも一週間でマスターできることを、莫大な資金を費やしてまで短縮する必要はあるのでしょうか？　プログラミングを学ぶのにそこまで緊急性がありますか？

もちろん、やる気が全然ないという方はスクールに行ったほうがいいかもしれません。しかし、それはあくまで親の視点であります。

ここで話していることで重要なのは、生徒側がどうしたいかです。生徒側にやる気があれば、わざわざスクールになぞ行く必要性は全くありません。「質問ができるから便利！」という声もありますが、これはすこしおかしいと思っています。
まず、プログラミングにおいて、質問の必要性がそこまであるか、ということです。現代は情報化社会、ほとんどの情報は探せば出てきます。金をかけてまで質問をする必要性はあるのでしょうか。例外は確かにあります。質問の内容がある程度高度な場合です。Pythonでいうと、llvmliteの使い方がわからない！などですね。そのような場合は探しても出てこないことが多いので、金をかけて質問するのもありでしょう。（llvmliteは英語のドキュメントがしっかりしてるので探せばきちんと出てきますが）

どうでもいいのですが、個人的にプログラミングスクールの広告は大嫌いです。

# 安易な気持ちでプログラマを目指すな
実務でのプログラミングはコミュニケーション能力が大事です。また、実務経験がなければ大した案件も受けることはできませんし、そこまで能力が評価されるようなシステムでは現状ありません。
プログラマに夢を見ているなら、それは捨てましょう。
どうしてもプログラマになりたいなら、まずはどこかの小さな会社で社畜のごとく働きましょう。その間は給料も大して高くありません。
社会に出たらいいことある、なんてそんなことはないですよ。社会は厳しいです。親の庇護を受けている間が最も楽で楽しい時間です。親の庇護から離れると、いろいろなことができるようにはなりますが、それ以上につらいことが多いです。

# 高校生の間はプログラミングでは稼げない
これが今までの中で最も重要なポイントです。
`高校生　プログラミング　稼ぐ`と調べるといろいろ出てきますが、あれはほとんど嘘です。実際のところ、高校生である間プログラミングで稼ぐことは**不可能**です。可能性は少しもありません。０です。いくら技術があっても高校生に依頼なんて来ません。
とはいえ、嘘をつけば可能です。「私は大学生です！」といえばいくらかは仕事は貰えるでしょう。嘘をついてまで金を稼ぎたい方はやってみてください。

# おわりに
以上、私の意見でした。どうだったでしょうか？
私としては、３番目の「高校生の間はプログラミングでは稼げない」はもっと周知されるべきだと思っています。