OmniAICreator/Qiita-1.07M huggingface dataset:
あなたの頑張りを応援する名言集

名言収集が趣味なので、日々努力するエンジニアを応援する名言を集めました。

# 成功につながる

## チェスキーは学習マシーンだ。成功する起業家は永遠の学習者なんだ。 

:::note info
引用：Airbnb Story
:::
「ハッカーと画家」の著者で、著名なベンチャーキャピタリストでもあるポールグラハムが、Airbnbで成功したCEOチェスキーを評したコメントです。

https://www.amazon.co.jp/Airbnb-Story-%E5%A4%A7%E8%83%86%E3%81%AA%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2%E3%82%92%E7%94%9F%E3%81%BF%E3%80%81%E5%9B%B0%E9%9B%A3%E3%82%92%E4%B9%97%E3%82%8A%E8%B6%8A%E3%81%88%E3%80%81%E8%B6%85%E4%BA%BA%E6%B0%97%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%92%E3%81%A4%E3%81%8F%E3%82%8B%E6%96%B9%E6%B3%95-%E3%83%AA%E3%83%BC%E3%83%BB%E3%82%AE%E3%83%A3%E3%83%A9%E3%82%AC%E3%83%BC/dp/4822255190/

## 経営は、教科書通りにやる。

:::note info
引用：「デューデリだん！」にて星野佳路さんが語った内容
:::

天才経営者と思われがちな星野さんですが、経営の基礎は本から仕入れており、努力の賜物だそうです。

https://newspicks.com/movie-series/72?movieId=1270


## 喋りのプロは、アヒルの水かきだ。

:::note info
引用：「”伝わる話し方”のコツ」にて語った内容にて水野太貴さんが語った内容
:::



「ゆる言語学ラジオ」で人気を博すパーソナリティの水野さん。澱みなく生み出す面白コンテンツが大人気です。
そんな水野さんはインプットの鬼として知られており、優雅に泳ぐアヒルの、見えない側面としての「水かき」の努力が重要と語りました。



https://youtu.be/-c0-kZz9UwU

# なぜ努力する？

## 誰かが、あなたの問題を全て解決してしまっています。
:::note info
引用：Head First Design Pattern
:::

デザインパターンを扱う書物史上、最も ~~ふざけた~~ くだけている一冊です。その冒頭、最初の文章が痺れます。
ほとんどの問題が、人類が獲得済みの叡智で解決できるはずです。
事前に知っていることが多ければ、対応できる幅を広げることができます。

https://www.amazon.co.jp/Head-First%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%E2%80%95%E9%A0%AD%E3%81%A8%E3%81%8B%E3%82%89%E3%81%A0%E3%81%A7%E8%A6%9A%E3%81%88%E3%82%8B%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%81%AE%E5%9F%BA%E6%9C%AC-Eric-Freeman/dp/4873119766

## 人間、大臣ぐらいなら後天的になれるポテンシャルがある

:::note info
引用：「コテンラジオ」吉田松陰編にて深井龍之介さんが語った内容
:::

人気の歴史系ポッドキャスト、コテンラジオの深井さんが「吉田松陰」の回で語った内容です。
吉田松陰が松下村塾を開いた村からは、その後の総理大臣・閣僚がボコボコ出てきます。
これは良質な環境や努力により、後天的に獲得できる能力が、成功に必要な要素の多く占めることを物語っているのではないでしょうか。

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


## 人は、それぞれが無能レベルまで昇進するから、一生が勉強


:::note info
引用：「世界で活躍する人は、どんな戦略思考をしているのか？」 
著者：塩野誠さん
:::

世界で活躍するコンサルタントの塩野誠さんの言葉です。
（もし今が安寧だったとしても）環境に甘えず、努力し続けることの重要性を説いています。
塩野さんは一週間のニュースを振り返るポッドキャストコンテンツ「[ニュース小噺](https://podcasts.apple.com/jp/podcast/news-connect-%E3%81%82%E3%81%AA%E3%81%9F%E3%81%A8%E7%B5%8C%E6%B8%88%E3%82%92%E3%81%A4%E3%81%AA%E3%81%905%E5%88%86%E9%96%93/id1608666340)」に出演されており、人気を博しています。



https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E3%81%A7%E6%B4%BB%E8%BA%8D%E3%81%99%E3%82%8B%E4%BA%BA%E3%81%AF%E3%80%81%E3%81%A9%E3%82%93%E3%81%AA%E6%88%A6%E7%95%A5%E6%80%9D%E8%80%83%E3%82%92%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8B-%E5%A1%A9%E9%87%8E-%E8%AA%A0/dp/404600925X


# 「才能ない」を言い訳にしない！

## 才のともしきや、学ぶ事の晩(おそ)きや、暇のなきやによりて、思いくずおれて、止(とどま)ることなかれ。

:::note info
引用元：うひ山ぶみ
著者：本居宣長
:::

簡単に訳すと、「才能がない、学ぶのが遅かった、暇がない、と言って落ち込んで、止まってはいけない。」となります。
江戸時代屈指の国学者となった宣長ですが、国学に励み始めたのは27歳だったようです。



# でも、体調が第一

## 良い食事をして、よく眠り、体に良くないものは取らない。

:::note info
引用元： 記事「ピーター・ウタカが語る日本とＪリーグ。」にて、ピーター・ウタカ選手が語った内容
:::

サッカーJリーグの得点王も獲得したFWのピーターウタカ選手。
投稿日現在、39歳にして得点ランキング上位につける鉄人です。
その衰えないプロフェッショナルの秘訣は、体にいいことを、当たり前にすることから。
継続するための前提として、体調を整えましょう。

https://sportiva.shueisha.co.jp/clm/football/jleague_other/2022/07/27/post_111/
【個人開発】国ごとに課金アイテムの値段を変えたら収益が上がった

# はじめに
少し前、個人開発のアプリで課金アイテムの値段を国ごと変えてみました。

# やったこと
具体的には、課金アイテムがよく売れている国と石油王の国（笑）で、買い切りアイテムの価格を1.99ドルから2.99ドルに上げてみました。

# 結果
すると、思いの外これまでと同じくらい購入してもらえて、収益を上げることに成功しました😆

# おわりに
簡単に試せるので、収益を上げたいと思っている方にはおすすめです！
この記事が参考になった思った方はいいね・フォローしていただけると励みになります☺️
自然言語処理の歴史をドラゴンボールに例えてみる

# 初めに
社内向け及び勉強会向けに生成AI周りの資料を作成したので、SpeakerDeckに公開するとともに、いくつかのトピックについてはこちらで補足解説していきます。
趣味の範囲で機械学習周りを学んでいるため、説明に誤りがあればご指摘ください。

# 自然言語処理の進化
下記のサーベイ論文を基に4つの段階に分類し、各時代の特徴からドラゴンボールの時代に例えてみます。
A Survey of Large Language Models [[Xin Zhao et al., arXiv:2303.18223](https://arxiv.org/abs/2303.18223)]

**・SLM(Statistical Language Models)　：統計的言語モデル**
**・NLM(Neural Language Models)　　：ニューラル言語モデル**
**・PLM(Pre-trained Language Models)：事前学習済みモデル**
**・LLM(Large language models)　　　：大規模言語モデル**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2816440/c27c26e9-6bb9-1d12-63b4-484ab6724032.png)

## SLM：統計的言語モデル(~2010年付近)
時代的には~2010年までの時代として分類されており、単語の発生頻度などの確率統計を用いたモデルが主流。

モデル例としては、N-Gram言語モデルなど。

**ドラゴンボールに例えると**
人の知識がメインとなっているため、桃白白(タオパイパイ)やヤムチャが活躍していた時代に似ている
<font color="Blue">⇒少年編～ピッコロ大魔王編</font>

## NLM：ニューラル言語モデル(2010~2018)
発表用スライドでも説明しているような分散表現が導入され、ベクトルでの処理が行われるようになる。
そして、ニューラルネットワークの技術を用いた時代へと変化していき、自然言語処理関連の参考書の序盤に出てくるRNN(Recurrent Neural Network)やLSTM(Long Short Term Memory)が登場してくる。
最終的に2017年にGoogleによってTransformerと呼ばれるAttention機構を最大限に生かしたモデルが発表され、次の時代へと移り変わっていく。
このTransformerは、今となっては多くのモデルに組み込まれており、自然言語処理の枠に留まらず、画像や音声モデルなどにも転用されている。最新のモデルには、大抵どこかしらでtransformerが組み入れられており、時代の重要な分水嶺のような気がする。

モデル例としては、Word2vecやELMoなどが挙げられる。

**ドラゴンボールに例えると**
ニューラルネットワークが注目され、transformerという象徴的な技術の存在で終止符を迎える一連の流れは、ドラゴンボールにおけるサイヤ人の襲来とスーパーサイヤ人への覚醒に例えられる
<font color="Blue">⇒サイヤ人編～フリーザ編</font>

**余談**
この時代(正確にはtransformer以後)にELMoというLSTMをベースにしたモデルが発表される。
これを機にセサミストリートのキャラクター名をモデルに付ける流れが発生する。
ELMoとは全身赤い主要キャラクターだが、色合いからして界王拳10倍といったところか、、

## PLM：事前学習済みモデル(2018~2020)
徐々に時代の間隔が狭くなってきているが、現在の大規模言語モデルへの助走期間のような時代。
Transformerをベースとしたモデルが続々と発表され、まるでトランスフォーマーのバーゲンセール状態に。
ELMoによって、文書(単語)を右から左へ学習していく形から、前後の単語からの双方向学習が提案されたが、
上述の通りELMoはLSTMがベースとなっていたが、Transformerベースに転用したのがBERTになる。
自然言語処理のモデル性能を測る上では、いくつかのベンチマークテストが存在する。
その中のSQuADと呼ばれる、Wikipediaの内容から出題される言語テストにおいて、BERTが人間の回答結果を上回る結果をだす。

この時代の序盤モデルの特徴は2段階でモデルを変更する点になる。(GPT-1など)
・Pre-training
　大規模なトレーニングデータで学習をさせ、汎用的なモデルを作成する
　⇒とりあえず英語を喋れる人を赤ん坊から育て上げるイメージ
・Fine-tuning
　各タスクに特化した出力を出せるように、モデルの最終層を変更する
　⇒英語が分かる人に、法律などの専門文章を追加でトレーニングさせ、専門家を育て上げるイメージ

**ドラゴンボールに例えると**
人が作ったモデルが人間の性能を超える時代になってきた。
<font color="Blue">⇒人造人間・セル編</font>

## LLM：大規模言語モデル(2020~)
Scaling lawなどの研究によって、モデルを適切に大きくすることで性能はべき乗で向上することが分かっていた。
このような先行研究などから、モデルのパラメータや学習データが急激に増大し、性能も向上する。
性能が向上する一方で、人との対話の中では適切ではない回答を占めることが出てきた。
これは、LLMの抱えるHallucination(幻覚)と呼ばれる課題とは異なり、看護師は女性として回答してしまうなどのジェンダーの偏りや、爆弾の作成方法などの有害な回答をしてしまう部分である。
人との対話を目指す中では、適切な回答と有害な回答を分離させる仕組みが必要となってきた。そこで、Instruct GPTと呼ばれる、強化学習を用いて人との対話に適切な回答をするような強化学習が実施されるようになる。
その結果、ChatGPTに代表されるような対話に特化したモデルやサービスが発表されてきた。

**ドラゴンボールに例えると**
性能としてはすごい物となったが、なんでも回答できるが故に、悪い回答も出すようになってきた。
そのため、良い回答と悪い回答を分離してやる必要が出てきた。
<font color="Blue">⇒魔人ブウ編</font>

**直近**
ChatGPTの登場や自然言語以外にも画像生成や動画生成のサービスなどが登場しており、今までの仕事のあり方や、人とシステムの関係性などの見直しが迫られており、創造的破壊の時代へと入りつつある。
<font color="Blue">⇒破壊神ビルス編</font>

# FULL資料
<script async class="speakerdeck-embed" data-id="2ba6a9e4a5f743f5a958168856732216" data-ratio="1.77777777777778" src="//speakerdeck.com/assets/embed.js"></script>
Azure にインストールした postfix を SMTP でテストする

「Azure で postfix のインストールを試す」
https://qiita.com/nanbuwks/items/38b54aaf8c3ecfdbb3cc
「Azure/Ubuntu にインストールした postfix / dovecot を Maildir 対応にする」
https://qiita.com/nanbuwks/items/10e6dd1224ce0c3f76af

で設定した postfix は、 SMTP サーバとして動いています。
今回は telnet を使って SMTP でメールを送ってみます。

本来では、ここまでの設定で外部から SMTP 接続を受け付けるのですが、Azure では 標準の SMTP ポートであるポート25 の通信ができないようになっているので、サーバに ssh でログインし、サーバから localhost を指定して接続します。


# 環境


 - Ubuntu 22.04
 - Postfix

#  操作

あらかじめ、 ssh でサーバにログオンしておきます。
ポート25で localhost にアクセスします。

```
$ telnet localhost 25
```
postfix より返答が還ってきます。
```
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net ESMTP Postfix (Ubuntu)
```
HELOコマンドで自分のホスト名を送ります。ここのホスト名は適当でも通ります。
```
HELO localhost
```
250 が返答として返ってきます。
```
250 test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net
```
後ろに付いているホスト名は接続してきたホスト名を逆引きした名前です。
さて、MAIL コマンドで送信手順を開始します。
```
MAIL FROM:azureuser
```
ステータスコード250が返ってきます。200番台が正常終了のコードです。
```
250 2.1.0 Ok
```
相手先を指定します。
```
RCPT TO:example 
```
ステータスコード250が返ってきます。
```
250 2.1.5 Ok
```
DATAコマンドで本文送信します。
```
DATA
```
以下のように返事が返ってくるので
```
354 End data with <CR><LF>.<CR><LF>
```
メール本文を入力します。ピリオドだけの行があると終了します。
```
Hello SMTP by telnet.
.
```
メールが受け付けられました。
```
250 2.0.0 Ok: queued as 9D4C63F4AF
```
SMTPセッションを終了します。
```
QUIT
```
サーバから以下のような返事が返ってきて接続が閉じられます。
```
221 2.0.0 Bye
Connection closed by foreign host.
```
# メール確認

example ユーザでメールが届いているかどうか確認します。

```
$ mail
"/home/example/Maildir": 5 messages 5 unread
>U   1 Ubuntu                               10/634   
 U   2 Ubuntu                               10/632   
 U   3 Ubuntu                               10/634   
 U   4 Ubuntu                               10/634   
 U   5 azureuser@test-azu                   11/679   
? 5
Return-Path: <azureuser@test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net>
X-Original-To: example
Delivered-To: example@test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net
Received: from localhost (localhost [127.0.0.1])
	by test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net (Postfix) with SMTP id 9D4C63F4AF
	for <example>; Sun,  9 Jul 2023 14:16:07 +0000 (UTC)
Message-Id: <20230709141613.9D4C63F4AF@test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net>
Date: Sun,  9 Jul 2023 14:16:07 +0000 (UTC)
From: azureuser@test-azure-gen.ugx1l5hl2pbu5oitg4vrqao0jd.phxx.internal.cloudapp.net

Hello SMTP by telnet.
? q
Saved 1 message in /home/example/mbox
Held 4 messages in /home/example/Maildir

```

無事届いているようです。
Visual Studio Code + PlatformIO + Arduino 環境で CH32V003 のLチカ

## はじめに
Visual Studio Code + PlatformIO + Arduino 環境で CH32V003J4M6 を使用したLチカを試してみました。
事前に↓参考にしてpio-ch32をインストールしておきます。
PlatformIO にpio-ch32をインストール
https://qiita.com/masashi_214/items/2bbd60ff88e8143e8cf0
## 新しいプロジェクトの作成
蟻アイコンのHOMEを表示させます。
![スクリーンショット 2023-07-09 21.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/92b3eeb2-8e39-599c-4b2c-4097127e80fa.png)

プロジェクトウイザードで
名前[Lchika]、BOARD[CH32V003J4M6]、フレームワーク[Arduino]を指定します。
![スクリーンショット 2023-07-09 21.38.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/bdc38170-8bdc-8786-8fce-5faaf3013555.png)

src内にmain.cppという雛形のファイルが出来上がります。
![スクリーンショット 2023-07-09 21.38.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/4287a48d-8d15-508c-2e06-5ee010779d76.png)

Lチカプログラム
D4は使っても良いですが、以降Uploadができなくなります。
![スクリーンショット 2023-07-09 23.18.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/35f5905e-d2f4-5131-a184-6d68ae755f64.png)

```cpp
#include <Arduino.h>

void setup() {
  pinMode(C1, OUTPUT);
  pinMode(C2, OUTPUT);
  pinMode(C4, OUTPUT);
//  pinMode(D4, OUTPUT); // D4 を使用する（OUTPUT)に設定すると、SWIOとして使えなくなる
}
void loop() {
  digitalWrite(C1, HIGH);
  digitalWrite(C2, LOW);
  digitalWrite(C4, LOW);
 // digitalWrite(D4, LOW);
  delay(100);
  digitalWrite(C1, LOW);
  digitalWrite(C2, HIGH);
  digitalWrite(C4, LOW);
 // digitalWrite(D4, LOW);
  delay(100);
  digitalWrite(C1, LOW);
  digitalWrite(C2, LOW);
  digitalWrite(C4, HIGH);
 // digitalWrite(D4, LOW);
  delay(100);
  digitalWrite(C1, LOW);
  digitalWrite(C2, LOW);
  digitalWrite(C4, LOW);
//  digitalWrite(D4, HIGH);
  delay(100);
}  
```
### uploadできなくなった場合の対処

WCH-LinkUtilityを使用して、Target -> Clear All Code Flash-By Power off を実行すると、CH32V003J4M6 が初期化されますので、再度uploadができるようになります。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/f859a55e-4b9c-df27-0e7d-d197cbc51472.png)
WindowsUpdate後にNASへのアクセスが重くなったので設定変更した

# NASが重たくなったので設定変更した
Windows10 で QNAP のNASストレージを使用しています
設定からウイルスと脅威の防止を開きリアルタイム保護をオフにするとアクセスが高速になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104691/c19fb30f-7143-d5d2-dfeb-0ccb93bbeaca.png)

## 経緯
2023/7/2 のWindowsUpdate後に急にNASが重たくなり1枚の画像を開くのに５～１０秒かかるようになった
色々検索したがどれも解決には至らなかった
2023/7/9 以下のサイトを参考にリアルタイム保護をオフにし解決した
[https://www.ubackup.com/jp/articles/windows-10-file-copy-slow.html](https://www.ubackup.com/jp/articles/windows-10-file-copy-slow.html)

元々リアルタイム保護をオフにしていたが WindowsUpdate の際に設定が変更されたがその事に気が付かなかった

## 注意事項など
リアルタイムの保護をオフにすることでセキュリティ上の問題があるかもしれないので社用PCなどではリアルタイム保護をオフにすべきではない
プライベートPCであってもセキュリティを考慮し各自で判断すべき
Elixir Image でヒストグラム平坦化（明るさ調整）

## はじめに

以前、 [evision](https://github.com/cocoa-xu/evision) でヒストグラム平坦化を実行しました

https://qiita.com/RyoWakabayashi/items/bcd5d5940711e4480467

[Image](https://github.com/elixir-image/image) にも 0.23.0 時点で `Image.autolevel` と `Image.normalize` によるヒストグラム平坦化が実装されていたのですが、 0.35.0 で `Image.equalize` に統合されました

今回は Livebook で Image によるヒストグラム平坦化を実行、視覚化します

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/vix/equalize.livemd

## セットアップ

必要なモジュールをインストールします

```elixir
Mix.install([
  {:image, "~> 0.35"},
  {:kino, "~> 0.9"}
])
```

- [Image](https://github.com/elixir-image/image): 画像処理 
- [Kino](https://github.com/livebook-dev/kino): Livebook の UI/UX

## 画像の準備

"/home/livebook/vix/dark.jpg" のパスに以下の画像が保存されているものとします

![dark.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/75d87f3b-2b37-69d5-5320-c7e33df89c80.jpeg)

暗くて何が写っているか見えませんね

この画像を `Image.open` で開きます

```elixir
dark_image = Image.open!("/home/livebook/vix/dark.jpg")
```

## ヒストグラム平坦化

ヒストグラム平坦化を実行し、結果を並べて表示します

```elixir
[
  dark_image,
  Image.equalize!(dark_image),
  Image.equalize!(dark_image, :each),
  Image.equalize!(dark_image, :luminance)
]
|> Kino.Layout.grid(columns: 2)
```

![スクリーンショット 2023-07-10 9.44.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/27f2858f-3942-a3f8-4d33-4393c774440c.png)

- 左上: 元画像
- 右上: デフォルト（第2引数 bands = `:all` ）で実行した結果
- 左下: bands = `:each` で実行した結果
- 右下: bands = `:luminance` で実行した結果

右上、右下では明るさが補正され、何を写っているか分かるようになりました

第2引数 bands の値については以下を参照

https://hexdocs.pm/image/Image.html#equalize/2

:all では最も暗いところが真っ黒、最も明るいところが真っ白になるよう、色の値を引き伸ばします

:each は RGB 毎に値を平坦化します（今回の例ではほとんど効果がありませんでした）

:luminance は輝度だけを平坦化します

## まとめ

これで暗い画像や明るすぎる画像も見やすく加工できますね
Laravelでアプリケーションの名前を変更する方法

アプリケーション名は.envファイルに設定します。

.envは環境設定のファイルになります。

## アプリケーション名の変更

早速アプリケーション名の変更方法を紹介します。

> .env
> 

```php
APP_NAME=Laravel
・
・
・
```

`.env`には色々設定はありますが`APP_NAME=Laravel`の箇所がアプリケーション名になります。

デフォルトだと`Laravel`になっていると思うのでこの`Laravel`の文字を設定したいアプリケーション名に変えるだけで変更できます。

## アプリの設定はどこの箇所で読み込んでいるの？

> config > app.php
> 

```php
/*
    |--------------------------------------------------------------------------
    | Application Name
    |--------------------------------------------------------------------------
    |
    | This value is the name of your application. This value is used when the
    | framework needs to place the application's name in a notification or
    | any other location as required by the application or its packages.
    |
    */

    'name' => env('APP_NAME', 'Laravel'),
```

結論configフォルダのapp.phpで読み込んでいます。

コードにも`Application Name`と表示されているのでかなり分かりやすいと思います。場所がわからない人は`Ctrl+F`などで調べると良いと思います。

### 説明

コードの説明も一応しときます。

こちらのコードは連想配列で書かれており

キーが`’name’`で

バリューの方で`env()`というヘルパ関数が使用されています。

`env()`というヘルパ関数を使用して先ほど設定した.envファイルを参照して第一引数で`APP_NAME`と書かれているのですがこちらに先ほど.envに記載したアプリケーション名が入ります。

`APP_NAME`が空の場合は第二引数にある`Laravel`がアプリケーション名になります。
GASでGmailの新着をチェックし、指定の件名のメールが来ていたらSlackに通知する簡単なプログラムを書いた

## はじめに
掲題の小さなプログラムを書いてみました。
Amazonで置き配指定で商品を注文した際、ヤマトのセールスドライバーが荷物を届けてくれると、登録したメールアドレスにヤマトから配達完了メールが届くので、これを検知してスマホに通知->荷物を取りに行く。これを実現したかった、というのが今回のプログラム作成の動機です。

## 使用技術
* Google App Script (GAS)
* Slack Incoming Webhook

## 作成したプログラム
作成したのは、下記１ファイルだけの小さなプログラムです。

```js
function myFunction() {
    const threads = GmailApp.search('{subject:(お荷物お届け完了のお知らせ) subject:(配達完了:ご注文商品の配達が完了しました。)}');
    let unreadMailExists = false;
    // 未読メッセージがあるかチェック
    for (thread of threads) {
        if (thread.isUnread()) {
            unreadMailExists = true;
            // 既読に更新する
            GmailApp.markThreadRead(thread);
        }
    }
    if (unreadMailExists) {
        // Slackで配達完了したことを通知
        sendSlack("荷物届いたよ！");
    }
}

function sendSlack(slackText) {
    const userProperties = PropertiesService.getScriptProperties();
    const webhookUrl = userProperties.getProperty('webhook_url');

    const jsonData =
    {
        "text": slackText,
        "link_names": 1,
        "username": "荷物配達完了"
    };

    const payload = JSON.stringify(jsonData);

    const options =
    {
        "method": "post",
        "contentType": "application/json",
        "payload": payload
    };

    // リクエスト
    UrlFetchApp.fetch(webhookUrl, options);
}
```

### 簡単に解説
* ヤマトの配達が完了すると、「お荷物お届け完了のお知らせ」という件名のメールが届くので、この件名で未読のメールがあれば通知対象とする。（既読なら荷物が届いたことに気づいているので、未読を対象とする）
※(追記)ヤマト以外(日本郵便など)の場合は、Amazonから「配達完了:ご注文商品の配達が完了しました。」の件名のメールが届くことがわかり、件名の条件は複数件にしています。
* 通知対象のメールは既読に更新する。（既読にしておかないと、次に動いたときにまた通知されてしまうため）
* プログラム以外に、SlackとGASで下記の設定を行っています
* Slackの設定
    * 任意のワークスペースを作成する
    * Slackのアプリケーションページから `incoming-webhooks`を追加・設定する。
    * <a href="https://qiita.com/ik-fib/items/b4a502d173a22b3947a0" target="_blank">こちら</a> 参考
* GASの設定
    * 任意のスタンドアロンプロジェクトを作成
    * GASの左メニュー上から３つ目の「トリガー」で時間主導型・10分単位のトリガーを設定
![スクリーンショット 2023-07-09 201703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519408/6d58fea6-aa9e-54b3-32af-28d356d99c11.png)
    * GASの左メニュー上から５つ目の「プロジェクトの設定」->「スクリプト プロパティ」で `webhook_url`のキー目でwebhook url を設定。（こうすることで、`userProperties.getProperty('webhook_url')`で設定値を読み込める）
* SlackやGASの設定や通知まわりのプログラムは、<a href="https://note.com/lssa/n/nac5fed56bd06" target="_blank">こちら</a> 参考。

## 動作確認
荷物の配達が完了していると、下記のメッセージがSlackに通知されます。
![スクリーンショット 2023-07-09 140223.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519408/e8834013-91c5-696d-02c8-f78c7f086e46.png)

リアルタイムではないですが・・下記の流れで荷物の配達完了がわかるようになりました。

1. ヤマトのセールスドライバーが配達完了すると、Gmailに配達完了の旨のメールが届く
1. 10分間隔のトリガーで今回作成したGASプログラムが起動
1. Gmailに未読の配達完了メールがあったらSlackに通知
1. スマホのSlackアプリでプッシュ通知をONにしているので、メッセージが通知されると、プッシュ通知され、スマートウォッチが鳴る
1. 荷物が届いたことに気づき、玄関に荷物を取りに行く

## おわりに
簡単なプログラムですが、これを作ったことで、荷物まだ来てないかなーって何度もメールチェックする手間を減らせたのが良かったです。
あとは、Gmailに新着メール届いたらGAS起動するようにしてリアルタイム検知できればカッコイイけど、そこまで厳密なのは求めていない+GASの実行数が多くなりそう・・なので、10分間隔トリガーに落ち着きました。
また何かちょっとしたプログラムをGASで作ってみたいなと思いました。
useEffectの使い方

使い方に悩んだuseEffectを、個人的にまとめてみました！
誰かの役に立てれば嬉しいです。:relaxed:
※公式さんはこちら[useEffect](https://react.dev/reference/react/useEffect)

---

### useEffectとは？
- Reactコンポーネントに存在する副作用関数を、特定のタイミングで実行する**関数**である

---

### 構文

**`useEffect(setup, dependencies?)`**

**setup**

- コンポーネントがDOMに追加されると、ReactはuseEffectに渡された第一引数を実行する（SPAのような動きと言われている理由・・・？）
  
    
- 再レンダリングされるたび・コンポーネントがDOMから削除されたとき、古い値を使用してクリーンアップ関数を実行する
    - 次に新しい値を使用してセットアップ関数を実行

**dependencies**

- 指定することで、リアクティブの値が依存関係として正しくしているかどうかが検証される
- 省略するとコンポーネントが再レンダリングされるたびにエフェクトが再実行される

---

### 注意事項

- **クライアント上でのみ実行される**
    - サーバー レンダリング中には実行されない

- **useEffectで、関数コンポーネント内で副作用を実行することができるようになる**
    - 副作用のない関数、ある関数とは？
        
        例①：JSXあるいはTSXからUIを構築する処理＝DOMの書き換え操作、イベント処理etc
        
        例②：サーバー通信(APIコール)
        
        例③：以下のような、同じ入力で同じ出力を返却しないもの
        

```tsx
// 副作用がない関数
function double(x: number) :number {
	return 2 * x;
}
```

```tsx
// 副作用がある関数
let num = 0;
// グローバル変数numを参照し、それを増加させて返す関数
function add(x: number): void {
	num = num + x;
}
```

- 第二引数に設定したstateを第一引数で更新しない＝無限ループになるため
    - 必要な場合は条件分岐で制御をかけること

- Promiseを直接指定しないこと（？）
    - **`useEffect`** に直接 **`async`** 関数を渡すと、非同期処理を待てない
    - 代わりに、非同期処理をuseEffectのコールバック関数内で行う必要がある
        - コールバック関数：他の関数を引数として渡す関数のこと（オブジェクトなので可能）

---

### 実行順序

1. useStateの更新関数等によって関数の値が書き換える
2. 画面を再レンダリングする
3. 2で変更がある場合、DOMを書き換える
4. useEffectの第一引数に渡した処理を実行する

---

### 実行タイミング

- **第二引数に何も指定しない場合**
    
    **レンダリング(Mounting, Updating, Unmounting)毎**に実行します。
    
    つまり、コンポーネント内で値が変わり、再レンダリングされるような場合には再レンダリング毎に実行します。
    
- **第二引数に空の配列を指定した場合**
    
    初回レンダリング時のみ実行されます。
    
- **第二引数の配列に1つ以上の値が指定されている場合**
    
    渡された値がレンダリング前後で変更がなければ処理をスキップし、再レンダリング後に変更していれば実行します。
    

---

### クリーンアップについて

- クリーンアップとは：
    - **コンポーネントが消失されたときに実行される**
- **クリーンアップを設定しないと、コンポーネントが消失しても、バックグラウンドで動き続けてしまう可能性がある**
    - 戻り値として設定する

```tsx
useEffect(() => {
    return () => {
      // クリーンアップ関数実行
    };

  }, [time]);
```

- 記載例
    - intervalを設定して、クリーンアップのところでclearする

```tsx
useEffect(() => {
    let interval = null;
    interval = window.setInterval(() => {
      console.log("interval called");
      setTime((prev) => prev + 1);
    }, 1000);
    return () => {
      window.clearInterval(interval);
    };
  }, []);
```
PL/pgSQLのRAISEメッセージをリダイレクトを使用してファイル出力する方法

キーワード：PL/pgSQL,RAISE,NOTICE,標準出力,リダイレクトできない

PL/pgSQLのRAISEメッセージは、普通にリダイレクトを使用してもファイルに出力されません。
この問題に対する対処方法を説明します。

# １．結論

標準エラー出力を対象にリダイレクトします。

例1：

    psql -U postgres -f foo.sql 2> foo.log

例2：

    psql -U postgres -f foo.sql > foo.log 2>&1

# ２．環境

・OS：Windows
・コンソール：コマンドプロンプト
・DB：PostgreSQL 14.7

# ３．解説

標準出力には以下の2種類があります。
・標準出力（非エラー）
・標準エラー出力

PL/pgSQLのRAISEメッセージは、この内「標準エラー出力」に分類されており、標準出力（非エラー）のリダイレクト対象になりません。

# ４．実行例

## SQLファイル「foo.sql」

~~~sql
SET CLIENT_ENCODING TO 'UTF8';

DO $$
declare
begin
  RAISE NOTICE 'test message.';
end;
$$ language plpgsql;
~~~

## ４．１．標準出力（非エラー）を対象にリダイレクトした場合
### コマンド

    psql -U postgres -f foo.sql > foo.log

### 実行結果（コンソール）
RAISEメッセージがリダイレクトされず、コンソールに出力されます。

    psql:foo.sql:8: NOTICE:  test message.

### 実行結果（出力ファイル「foo.log」）
SET実行ログ等がリダイレクトされます。

    SET
    DO

## ４．２．標準エラー出力を対象にリダイレクトした場合
### コマンド

    psql -U postgres -f foo.sql 2> foo.log

### 実行結果（コンソール）
SET実行ログ等がリダイレクトされず、コンソールに出力されます。

    SET
    DO

### 実行結果（出力ファイル「foo.log」）
RAISEメッセージがリダイレクトされます。

    psql:foo.sql:8: NOTICE:  test message.

### 補足

標準出力（非エラー）、標準エラー出力の両方をリダイレクトしたい場合は、以下の方法を取る。

    psql -U postgres -f foo.sql > foo.log 2>&1
リファクタリングしても壊れないテストコード

# はじめに
本記事は、私が最近読んだ著書 [「単体テストの考え方/使い方」](https://amzn.asia/d/eW1YZay)で紹介されている、リファクタリングに強いテストを書くためにはどうするべきか、という記述について簡単にまとめたものです。ここで紹介する内容以外にも多くの素晴らしい情報が詰まった本なので、是非皆様も読んでみてください！

https://amzn.asia/d/eW1YZay

## リファクタリングへの耐性
**まず、本書において作者は、テストの目的とはバグを起こすことなく、新しい機能の追加やリファクタリングを行えるようにすることだと述べています。** そこで、テストコードが備えるべき要件の一つとして、リファクタリングへの耐性を挙げています。

> 参考：良い単体テストを構成する４本の柱
> 1. バグに対する保護
> 2. リファクタリングへの耐性
> 3. 迅速なフィードバック
> 4. 保守のしやすさ

**リファクタリングへの耐性とは、テストが失敗することなく、コードのリファクタリングが行えるかどうかを示す指標です。** 例えば、リファクタリングを行った結果、テスト対象の機能的な振る舞いは変わっていないのに関わらず、テストが失敗するようになった場合、そのテストコードは耐性が低いということになります。

## 偽陽性
**このように、テストコードが意図通りに動いているのに関わらず、テストが失敗することを「偽陽性」と言います。** リファクタリング耐性の高いコードを作成するためには、この偽陽性に対して注意を払わなければなりません。例を挙げると、メソッドの引数を増やしたことによってテストがコンパイルエラーを起こすようになった、というのも偽陽性に含まれます。

**偽陽性が増すと、テストコードの信頼性が損なわれていきます。** 正しく振る舞っているはずなのに、テストが失敗するケースが増えると、リファクタリング時に発生したバグが無視されるようになったり、あるいはリファクタリング自体を敬遠するようになってしまいます。

## 対策
**テストコードから偽陽性を取り除くためには、テスト対象の内部的な実装から切り離す必要があります。** つまり、コードを呼び出す側にとって意味ある実行結果のみを確認し、内部でどのような処理が行われるかは検証しないようにします。

**設計が正しくなされている場合、これはほぼパブリックメソッドと一致します。** 逆に言えば、プライベートメソッドの検証は一切すべきではないということです。プライベートメソッドを検証してしまうと、テストが実装の詳細と結びついてしまい、壊れやすいテストとなってしまうからです。

もし、パブリックメソッドからの検証が困難であるほどプライベートメソッドの実装が複雑になっている場合、プライベートメソッドの一部をクラスに切り出すなど、何かしらの設計変更が必要かもしれません。

## まとめ
**リファクタリング耐性の高いテストコードを書くためには、実装の詳細(プライベートメソッド)を検証せず、パブリックメソッドを通じて、利用側の期待する振る舞いのみを検証するようにしましょう。**
DjangoのCustomUserModelでログインができないバグを解消した

# DjangoでCustomUserModelを定義後、ログインの時のis_validができなかった
nameというフィールドを持った単純なCustomUserというモデルをAbstractUserを継承することで定義しました。

```py
class CustomUser(AbstractUser):
    name = models.CharField(max_length=30)
    groups = models.ManyToManyField(
        'auth.Group',
        related_name='custom_user_set',
        blank=True,
        help_text='The groups this user belongs to.'
    )
    user_permissions = models.ManyToManyField(
        'auth.Permission',
        related_name='custom_user_set',
        blank=True,
        help_text='Specific permissions for this user.'
    )
```

サインアップ(form.save)は実行できアカウントが作れることを確認後、ログインするためのLoginForm.is_valid()がFalseになってしまいログインができなくなっていました。

## 解決策
### CustomUserを作成したら
- アプリ名/backends.pyの作成
- settigns.pyのAUTHENTICATION_BACKENDSの記載
が必要でした。

#### アプリ名/backends.pyの作成
--- 
BaseBackendというのを継承してauthenticateを作成したCustomUserモデルに適した形に定義する必要がありました。
```py
from django.contrib.auth.backends import BaseBackend
from .models import CustomUser

class CustomUserBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = CustomUser.objects.get(username=username)
        except CustomUser.DoesNotExist:
            return None

        if user.check_password(password):
            return user

        return None
```
#### settings.pyの書き換え
先ほど適用させたbackendの情報をsettings.pyに記載して読み込んでもらう必要がありました。
```py
# autheticationをカスタムユーザーモデルに適応させる
AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'polls.backends.CustomUserBackend',  # カスタムユーザーモデルのバックエンドを指定
]
```

これで私のプログラムは正しくis_valid()でTrueが返ってくるようになりましたので参考になれば幸いです。
Elixir Image で射影変換（台形補正）

## はじめに

Elixir Image にバージョン 0.28.0 で射影変換（台形補正）の機能が追加されました

以前の記事では Evision の形式に変換してから Evision で台形補正し、 Image に戻す、というようなことをしていましたが、その必要はなくなりました

https://qiita.com/RyoWakabayashi/items/34de2207bcf8d745a01a

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/vix/warp_perspective.livemd

## セットアップ

台形補正を行う場合、 [Nx](https://github.com/elixir-nx/nx/tree/main/nx#readme) が必要になるため、一緒にインストールしておきます

```elixir
Mix.install([
  {:image, "~> 0.35"},
  {:nx, "~> 0.5"},
  {:req, "~> 0.3"},
  {:kino, "~> 0.9"}
])
```

## 画像の準備

適当な画像をダウンロードします

```elixir
ryo_img =
  "https://www.elixirconf.eu/assets/images/ryo-wakabayashi.png"
  |> Req.get!()
  |> Map.get(:body)
  |> Image.from_binary!()
```

![筆者近影](https://www.elixirconf.eu/assets/images/ryo-wakabayashi.png)

射影変換の効果がわかりやすいようにテキストを用意します

```elixir
text_image =
  Image.Text.text!(
    "Hello, Livebook!",
    font_weight: 600,
    text_fill_color: :blue
  )
```

![スクリーンショット 2023-07-09 22.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e52d43e5-af13-7f95-dec7-143904b94ad2.png)

テキストを画像に重ねます

```elixir
composed_image =
  ryo_img
  |> Image.compose!(text_image, x: 100, y: 450)
  |> Image.compose!(text_image, x: 100, y: 500)
  |> Image.compose!(text_image, x: 100, y: 550)
```

![スクリーンショット 2023-07-09 22.05.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/51117e6f-8bb4-5f19-f333-86bb3ad4141d.png)

## 実行

`Image.warp_perspective` で射影変換を実行します

- 第1引数: 変換対象の画像
- 第2引数: 変換前の四角形の各頂点座標
- 第3引数: 変換後の長方形の各頂点座標
- 第4引数: オプション

注意点としては、第3引数は任意の四角形ではなく、長方形でなければいけません

本来は台形補正に使う目的なので、変換前の画像で斜めに写っているものを長方形に補正する想定だからです

今回はわざと台形に歪ませるので、変換前の四角形を左右にはみ出させています

```elixir
source =
  [
    {-900, 0},
    {0, 600},
    {1500, 0},
    {600, 600}
  ]

destination =
  [
    {0, 250},
    {0, 600},
    {600, 250},
    {600, 600}
  ]

Image.warp_perspective!(composed_image, source, destination, background: :blue)
```

![スクリーンショット 2023-07-09 22.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/5d04c99e-bc70-adc6-19da-e7361a2e082a.png)

確かに台形に変換できました

オプションで `background: :blue` を指定したため、背景が青くなっています

## まとめ

Elixir の画像処理まわりは今まさに発展途上なので、どんどん機能が追加されていきますね
【オススメのQiita記事をピックアップ】ChatGPTの分かりやすい記事5選！

## オススメのQiita記事をピックアップ！
コチラでは、2023年7月時点でのQiitaのオススメ記事をご紹介させていただきます。
今回は…「ChatGPT関連のオススメQiita記事5選」ということで、ChatGPTをテーマにお届けします。

個人的なオススメの選考基準は、下記の通りです。
- よくある悩みや課題を解決してくれる（汎用性の高さ）
- 非エンジニアの方にも、それほど難しい知識が必要なく読むことができる
- 流用や横展開がしやすい（拡張性の高さ）

※トピックスの内容によっては、上記の選考基準を逸脱する可能性もありますが、その場合は分かりやすく掲示をさせて頂きます。

私自身が読んでためになった！と感じた記事を、独断と偏見でご紹介させて頂きます。

## ChatGPT関連のオススメQiita記事5選
### ①[「ChatGPT先生のお陰でネットワークスペシャリストに合格した話」](https://qiita.com/namn1125/items/048eb17fd5e8f802660a)

ChatGPTを勉強の相棒としてフル活用！

専門用語や概念的な理解にChatGPTを活用して、見事ネットワークスペシャリストに合格した著者の方の体験談です。

実践・経験が伴わないなかで、どれだけ専門書を読んでも頭には入ってこない。そんな悩みの解決策として、ChatGPTが活躍しています。

https://qiita.com/namn1125/items/048eb17fd5e8f802660a

### ②[「ChatGPT公式プラグイン「Code interpreter」の使い方や活用方法を徹底解説」](https://qiita.com/ot12/items/32d0ac8a10f00ec12881)

話題のプライグイン「Code interpreter」の使い方です。ChatGPT上でPythonを使ったコードの実行や、ファイルのアップロード／ダウンロードができると話題の「Code interpreter」について、仕様や機能をざっと理解することができます。

「Code interpreter」で何ができるのか、一通り把握したい方にオススメです。

https://qiita.com/ot12/items/32d0ac8a10f00ec12881

### ③[「【ChatGPT】黒歴史ブログの文章を生成した」](https://qiita.com/neriumezui/items/5ab61b8c848f48c8a207)

文章の特徴を覚えさせて文章を生成！

過去の「黒歴史ブログ」の文章を読ませて、文章の特徴を覚えさせる。そして、自動で文章を生成できるように作り込み、最終的にはDiscordのAPIを使って、Discordへ出力しています。

https://qiita.com/neriumezui/items/5ab61b8c848f48c8a207

### ④[「VoicyやYoutubeのリンクを入力して、OpenAI APIを使用して内容を要約するアプリを作ってみよう！」](https://qiita.com/cardene/items/9415a1fbf7274b411ce6)

【難易度高めです】OpenAiのAPIを使った音声のテキスト化！

Pythonの知識が少し必要なので、ちょっと難易度は高めです。しかし、Voicyの音声を題材とするなど、手を動かして挑戦してみたい！と思いました。

https://qiita.com/cardene/items/9415a1fbf7274b411ce6

### ⑤[「え？まだRPA使ってるの？ ChatGPTの課題と解決アプローチから学ぶ 生成系AIを活用したRPA 自動化の未来」](https://qiita.com/ManabuTech/items/719829ecf15c39cc0735)

RPA/DX系のSEが本業の私も、大変参考になりました。生成系AIを活用した自動化の未来について、3つの具体例を挙げながら解説しています。

https://qiita.com/ManabuTech/items/719829ecf15c39cc0735
クラウドサービスのセキュリティガイド

クラウドサービスを使った開発を進める上で、アプリのセキュリティについては対策をしなくてはならないと考える人は多いですが、クラウドサービスそのものに対する対策は意外と意識されていなかったりします。
そこで、クラウドサービスのセキュリティって、何をすればよいのかを書いていこうと思います。

## ベストプラクティスセキュリティガイド
参考できるとして、Center for Internet Security（CIS.）という団体が無料で配布している `CISベンチマーク` というものがあります。
参考リンク：https://www.cisecurity.org/

これは、様々な製品などのベストプラクティスセキュリティガイドとなっており、主なクラウドプロバイダでは以下のサービス向けのCISベンチマークが配布されています。
* Alibaba Cloud
* Amazon Web Services
* Google Cloud Computing Platform
* Google Workspace
* IBM Cloud Foundations
* Microsoft 365
* Microsoft Azure
* Microsoft Dynamics 365 Power Platform
* Oracle Cloud Infrastructure

実際にどのようなことが記載されているのか`CIS Amazon Web Services Foundations v1.2.0`をもとに抜粋すると、
1. Identity and Access Management (アカウントやアクセス権限管理に関すること)
2. Logging（ログの設定）
3. Monitoring（監視メトリクス）
4. Networking（network設定）

のカテゴリでそれぞれどのようなことに気をつけなければいけないのかのプラクティスが記載されています。
基本的な項目ではあるものの、CIS Benchmark自体はガイドであり組織のポリシーや優先度などに合わせて判断してよいのではないでしょうか。

各クラウドサービスでも通知機能などのサポート機能が提供されていたりしますので利用するクラウドサービスに合わせて対応したり、セキュリティ向けSaaSや製品などでもCISベンチマークに対応しているものが数多くありますので、状況に合わせて選択肢がいろいろあります。
JetpackCompose無限に点滅するアニメーションの実装方法

今回は繰り返すアニメーションについて調べてみました。

点滅のアニメーションをさせたいわけではなく、どちらかと言うと繰り返す方法を探していました。


サンプルコードです

```.kt
val infiniteTransition = rememberInfiniteTransition()
val alpha by infiniteTransition.animateFloat(
    initialValue = 0f,
    targetValue = 1f,
    animationSpec = infiniteRepeatable(
        animation = keyframes {
            durationMillis = 500
        },
        repeatMode = RepeatMode.Reverse
    )
)
Surface(
    shape = MaterialTheme.shapes.small
) {
    Spacer(
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
            .background(Color(0xFF666666).copy(alpha = alpha))
    )
}
```

`repeatMode = RepeatMode.Reverse`こちらが繰り返す処理の設定です。

アニメーションの方は`initialValue = 0f`で透明から`targetValue = 1f`表示へと変化します。
`durationMillis = 500`でアニメーションする時間を設定してます。

作成したアニメーションは`background`の`alpha`に設定します。
![Videotogif (4).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/edb86796-9f0b-3cb9-e173-8373d8b2f67f.gif)


以上です。
Bottle 静的ファイルに遷移するルーティングの書き方

## pyファイルの書き方
```Python
# /<filename> にアクセスしたら、accessHtml関数が呼ばれる
@route('/<filename>')
def accessHtml(filename):
    # 静的ファイルを呼び出す
    return static_file(filename, root='./')

# ↓webサーバーを起動する
if __name__ == "__main__":
    # テスト用のサーバをlocalhost:8080で起動する
    # reloader=Trueにより、ソースを書き換えると自動的に再起動される
    run(host='localhost', port=8080, reloader=True, debug=True)
```

## htmlファイルの書き方
```HTML
<a href="./移動したいファイル名">テスト</a>
```


## 参考サイト
https://www.denzow.me/entry/2017/09/07/111137
TypeScript で Kotlin っぽいコードを書きたいから NPM ライブラリを作ってみた

# TypeScript の気になる点

TypeScript で「配列内の偶数だけ合計する」という処理を書こうとすると、次のようなコードになると思います。
私は、この例で少し読みにくく感じる点があると思います。（※個人的意見です）

```typescript:実装 (1)
const sumOfEvenNums = sum(
    [1, 2, 3, 4, 5].filter((num) => num % 2 === 0)
)
```

```typescript:実装 (2)
const  evenNums = [1, 2, 3, 4, 5].filter((num) => num % 2 === 0)
const sumOfEvenNums = sum(evenNums)
```

実装 (1) は、処理順序は次のようになっていると思います。
1. `[1, 2, ...]` というリストを定義する
2. `filter` で偶数を取り出す
3. `sum` で合計する

しかし、実際のコードの順序が 3 → 1 → 2 になっていて、**処理とコードの順序が一致していません**。

実装 (2) は、`evenNums` という**無駄な一時変数**が定義されています。`evenNums` が後で使用されるか分からないので、`evenNums` を覚えて置く必要があります。もし、後で出てこなかったら覚え損です。

# Kotlin のスコープ関数

上記で挙げた気になる点を解決するのが、プログラミング言語 Kotlin の**スコープ関数**（Scope functions） です。簡単に言うと、スコープ関数は、あるオブジェクトに対して**一時的なスコープを作りだす関数**です。

例えば、上記の処理「配列内の偶数だけ合計する」は、スコープ関数 `let` を使うと次のような感じになります。
**処理とコードの順序も一致**しており、**説明変数もラムダ式 `{ ... }` 内にだけで有効**です。

```kotlin
val sumOfEvenNums = listOf(1, 2, 3, 4, 5) // 数値のリスト
    .filter { num -> num % 2 == 0 } // 偶数のみをフィルタリング
    .let { evenNums -> sum(evenNums) } // フィルタリング結果の合計をする
```

# NPM パッケージ `tslin`

https://www.npmjs.com/package/@rakiya/tslin

TypeScript で使えるスコープ関数のパッケージ `tslin` を作りました。
TS + Kotlin で `tslin` です。

## インストール

次のコマンドでインストールできます。

```
npm install @rakiya/tslin
```

## 追加したスコープ関数などの拡張メソッド

スコープ関数も含めて 8 つのメソッドを追加しました。詳しくは、[Kotlin のドキュメント](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/)を読めば使用法がわかると思います。

- Object （全てのオブジェクトで使用可能）
    - `Object.let<T, R>(block: (_: T) => R): R`
    - `Object.also<T>(block: (_: T) => void): T`
    - `Object.takeIf<T>(predicate: (_: T) => boolean): T | undefined`
    - `Object.takeUnless<T>(predicate: (_: T) => boolean): T | undefined`
- Array （配列で使用可能）
    - `Array.isEmpty(): boolean`
    - `Array.isNotEmpty(): boolean`
    - `Array.indices(): Array<number>`
    - `Array.lastIndex(): number`

## 追加したメソッドの解説

### let

例で説明した通り、オブジェクトを加工した結果を返すスコープ関数です。

```typescript
"abc".let((str) => str.toUpperCase()) // ABC
```

### also

処理をメソッドチェーンの間に挟むためのスコープ関数です。
ラムダ式の処理をした後に、受け取ったオブジェクトをそのまま返します。

```typescript
[1, 2, 3, 4, 5]
    .filter((num) => num % 2 === 0) // [2, 4]
    .also((nums) => console.log(nums)) // [2, 4]
    .indexOf(2) // 0
```

### takeIf

`filter` のオブジェクトバージョンです。ラムダ式が `true` のときオブジェクトを返します。`false` のときは `undefined` を返します。

```typescript
"2".takeIf((num) => num % 2 === 0) // 2
"1".takeIf((num) => num % 2 === 0) // undefined
```

### takeUnless

`takeif` の逆の挙動をします。`true` のとき `undefine`、`false` のときオブジェクトをそのまま返します

```typescript
"2".takeIf((num) => num % 2 === 0) // undefined
"1".takeIf((num) => num % 2 === 0) // 1
```

# 感想

NPM パッケージを公開したのが初めてなので結構苦労しました。
TypeScript も Kotlin も好きな言語なので、今後 TypeScript を使っていて気になる点があったらアップデートしていきたいと思います。
[リサーチ・メモ] JAR, WAR, EAR の違い

## 背景
仕事でJARファイルを使用したが、聞いたことのあるWARやEARとの違いが
説明できない為、メモとして纏める。

## JAR（Java Archive）
 JARファイルは、Javaアプリケーションやライブラリのパッケージングに使用されます。JARファイルは、Javaバイトコード、リソースファイル、設定ファイルなどを1つのアーカイブにまとめます。これにより、複数のクラスやリソースを単一のファイルとして配布することができます。主にJava SE（Standard Edition）アプリケーションや独立したJavaライブラリに使用されます。

### 作成方法
仕事だとeclipseで下記を実施
1.パッケージ化するプロジェクトを右クリック
2.実行からMaveninstall
3.target配下にjarファイルが作成される

別の方法
1.eclipseでパッケージ化するプロジェクトを右クリック
2.Exportからjavaのjarファイルを選択
3.項目やエクスポート先等を選択し、作成

### 利用方法
他のjavaプロジェクトでライブラリとして利用

## WAR（Web Archive）
WARファイルは、Java Webアプリケーションのパッケージングに使用されます。WARファイルには、ウェブアプリケーションのJavaクラス、静的リソース（HTML、CSS、JavaScriptなど）、構成ファイル、ライブラリなどが含まれます。これにより、ウェブアプリケーションを単一のファイルとしてデプロイおよび配布することができます。主にJava EE（Enterprise Edition）アプリケーションサーバーで実行されるウェブアプリケーションに使用されます。

### 作成方法
1.eclipseでパッケージ化するプロジェクトを右クリック
2.Exportからwebのwarファイルを選択
3.エクスポート対象のリソースや出力先のファイル名を指定し作成

### 利用方法
Java サーブレットコンテナにデプロイ


## EAR（Enterprise Archive）
EARファイルは、Java Enterpriseアプリケーションのパッケージングに使用されます。EARファイルには、複数のモジュール（WARファイル、EJB（Enterprise JavaBeans）JARファイルなど）とそれらの構成情報が含まれます。これにより、Java EEアプリケーションを1つのアーカイブとしてパッケージングし、デプロイおよび配布することができます。主にJava EEアプリケーションサーバーで実行されるエンタープライズアプリケーションに使用されます。

### 作成方法
1.eclipseでパッケージ化するプロジェクトを右クリック
2.ExportからjavaEEのearファイルを選択
3.エクスポート対象のリソースや出力先のファイル名を指定し作成

### 利用方法
Java EE アプリケーションサーバーにデプロイ

## まとめ
形式の違いは、パッケージングの対象や使用目的によって異なる
JARファイル：単一のJavaアプリケーションやライブラリをパッケージ化
WARファイル：Webアプリケーションをパッケージ化
EARファイル：複数のJavaEEコンポーネントを包括的にパッケージ化し、エンタープライズアプリケーションをデプロイする
【Rails】ユーザー退会機能（物理削除）

# 論理削除とは
**論理削除のメリット**
・データを完全に削除せず、復元や再利用が容易
・削除されたデータの履歴や関連情報を保持しやすくなる
・データを誤って削除した場合でも、バックアップや復元を介して元に戻すことができる

**論理削除のデメリット**
・データベース内に論理削除されたデータが残るため、データベースの容量が増える可能性がある
・削除されたデータに対するクエリや検索処理に追加の条件を設定する必要がある
・データの一貫性を保つために、論理削除されたデータに対してもアクセス制御やバリデーションを適用する必要がある

# 物理削除とは
**物理削除のメリット**
・データベースからデータが完全に削除されるため、データベースの容量を節約できる
・削除されたデータを誤って復元する心配がないため、データのセキュリティを向上させることができる

**物理削除のデメリット**
・削除したデータの履歴や関連情報が完全に失われるため、復元や再利用が難しい
・誤って削除した場合はバックアップや復元の手段を用意する必要がある


# コントローラ編集
users_controller.rbにdestroyアクション追加。
```ruby
class UsersController < ApplicationController
  before_action :set_user, :only => [:show, :destroy]

  def destroy
    @user = User.find(params[:id]) 
    @user.destroy
    flash[:notice] = 'ユーザーを削除しました。'
    redirect_to root_path
  end

  private
  def set_user
    @user = User.find_by(:id => params[:id])
  end
end
```

# モデル編集
user.rbにdependent => :destroyを追加することで、退会したユーザに紐づく投稿も削除される。
```ruby
has_many :posts, :dependent => :destroy
# 投稿したデータも削除する

has_many :comments, :dependent => :destroy
# 退会ユーザーに紐づくコメントも削除する場合
```
# ルーティング編集
routes.rbにdestroyアクション追加。
```ruby
resources :users, only: [:show, :destroy]
```

# ビュー編集
退会ボタン作成。
```ruby
<%= link_to "退会",user_path(current_user.id), class: "destroy-user", method: :delete, "data-confirm" => "本当に退会しますか？" %>
```
【Rails】Devise Token Auth使用時のNoMethodError (undefined method `downcase' for nil:NilClass)解消法

## 状況
Devise Token Authの設定に以下の項目を追加したところログイン時に`NoMethodError (undefined method `downcase' for nil:NilClass)`となりました。

```rb:devise_token_auth.rb
DeviseTokenAuth.setup do |config|

  config.headers_names = { "access-token": "access-token",
                           client: "client",
                           expiry: "expiry",
                           uid: "uid",
                           "token-type": "token-type" }

end
```

## 解消法

以下のように`authorization: "authorization"`を追記することで解消しました。

```rb:devise_token_auth.rb
DeviseTokenAuth.setup do |config|

  config.headers_names = { "access-token": "access-token",
                           client: "client",
                           expiry: "expires",
                           uid: "uid",
                           "token-type": "token-type",
                           authorization: "authorization" }

end
```

## 参考

https://github.com/lynndylanhurley/devise_token_auth/issues/1540
Laravel MixとTailwindcssのインストール方法

現在、下記の本を参考にしてLaravelの学習をしており、その中で気づいた点を備忘録として残しておこうと思います。

【参考にした本はこちら↓】
プロフェッショナルWebプログラミング　久保田賢二郎 他著
![laravel本.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/a63531a7-536b-aec1-5cc0-1ec081c3bf23.png)


【備忘録としてのページ範囲】
143ページ～152ページまでについて備忘録として記載します。

## 事前準備(必要なもの)
Node.js

## Laravel Mixとは？
Laravel Mixとは『フロント側の開発を簡単に構築できるライブラリ』のこと。このライブラリをnpmでインストールするとサクッとフロント画面のデザインができてしまうすごいツールです。

公式サイト↓
URL:https://laravel-mix.com/docs/6.0/installation

## Tailwindcssとは？
Bootstrapやfoundationと同じCSSフレームワークの一つで、特にカスタマイズ性に優れていることが特徴です。そのため、近年では多くのシステム開発で受け入れられています。

## Laravel Mixの導入方法
では、さっそくLaravel Moxをnpmを使って順番に沿ってインストールしてみましょう。

### npm installを実行して必要なパッケージをインストールする

```
npm install
```

### Laravel Mixをインストールする
```
npm install laravel-mix --save-dev
```

#### Laravel Mixインストール前のpackage.jsonの中身
![Laravel-mixインストール前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/496c90b3-7ee0-82bd-824a-2f4bc66e0d45.png)


#### Laravel Mixインストール直後のpackage.jsonの中身
![Laravel-mixインストール後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/65628517-b5d8-830f-b094-d29746a1336c.png)

#### webpack.mix.jsを作成して、Mixの構成を記述する
ルートディレクトリにJSファイル『webpack.mix.js』を作成して、下記の内容を追加します。

参考にしたLaravel Mixに関するサイトはこちら↓
URL：https://github.com/laravel/vite-plugin/blob/main/UPGRADE.md

```webpack.mix.js
const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);
```

#### package.jsonの"script"タグを編集する

参考にしたサイトはこちら↓
URL:https://github.com/laravel/vite-plugin/blob/main/UPGRADE.md

##### 更新前
```package.json
  "scripts": {
     "dev": "vite",
     "build": "vite build"
  }
```

##### 更新後
```package.json
  "scripts": {
     "dev": "npm run development",
     "development": "mix",
     "watch": "mix watch",
     "watch-poll": "mix watch -- --watch-options-poll=1000",
     "hot": "mix watch --hot",
     "prod": "npm run production",
     "production": "mix --production"
  }
```

## Tailwindcssの導入方法
#### tailwindcssを導入するためのコマンドを実行

さて、最後にtailwind CSSをnpmを使ってインストールしてみましょう

```
npm install -D tailwindcss
npx tailwindcss init
```

以上です。

お疲れさまでした。
仮想環境へのVirtual Box/Vagrantのインストールで躓いたところ(仮想化のネスト)

# はじめに
仮想環境にCICD環境をインストールしていく過程で、Virtual Box/Vagrantのインストールをしていたところ、色々と躓いてしまいましたので、その対応をこちらに記載してまいります。


# 目次
1. [仮想化のネスト](#Chapter1)
1. [ルートディスクの容量不足](#Chapter2)
1. [Add VirtualBox repo fileでのエラー](#Chapter3)

<a id="Chapter1"></a>
# 仮想化のネスト

仮想環境にCICD環境をインストールしていく過程で、Virtual Box/Vagrantのインストールをしていたところ、CPU has to support Intel VT-x or AMD-Vというエラーが発生いたしました。
こちらはCPUのIntel VT-xが有効化されていないことと、仮想化のネストができていなことが原因でした。
まずはBiosを立ち上げ、Intel Virtualization TechnologyとIntel VT-d FeatureをEnableにします。
そして以下のサイト様に記載がある通り、仮想化のネストを実施いたしました。（というかこんなサイト様があるなら、最初から見ておけばよかったなんて思いました・・・）


<a id="Chapter2"></a>
# ルートディスクの容量不足

仮想化のネスト対応が終わり、またansible playbookを実行しましたところ、今度はrootスペースが足りないよといった警告が出てまいりました。
本の記載に則り、ちゃんと50GB確保しているはずなのですが、なぜかうまくいきません。
試しにdf -hコマンドで容量をチェックしてみましたところ、しっかりと50GB存在しているように見受けられました。
仕方ありませんので50GBから60GBに拡張してみることにいたしました。

~~拡張方法は以下のサイト様を参考にさせていただきました。~~
~~https://qiita.com/iaoiui/items/acbe36fad349572b3a16~~
~~まずはlvdisplayコマンドで論理ボリュームの情報を確認いたします。~~
~~論理ボリュームのパスは上記コマンドの実行結果の中から、LV Pathに記載の /dev/centos/root　であることが判明いたしましたので、こちらに対して容量を追加いたします。~~
~~以下のコマンドを実行することで論理ボリュームの拡張ができます。~~

~~```~~
~~lvextend -L +10G /dev/centos/root~~
~~```~~
~~ダメでした。~~


そもそも仮想マシンで使える容量の限界があるように見えたので、次に試したのが以下のサイト様となります。
https://atmarkit.itmedia.co.jp/ait/articles/0909/18/news119.html
こちらのサイト様でご紹介されている、Hyper Vのディスクの編集から、拡張で容量を177GB（元が127でしたので+50GBとなります）に変更いたしました。
この状態で再度CentOSのインストールから/の割り当てを拡張することにいたします。
CentOSのインストール時に、パーティションを手動で設定とし、無事に/を50GBから60GBに変更することができました。自動で設定させてしまうと、50GBで設定されてしまいますので、手動で設定するようご注意ください。

この状態で再度playbookを実行してみますと、第一関門は突破することができました。

<a id="Chapter3"></a>
# Add VirtualBox repo fileでのエラー

次に私の前に立ちはだかって参りましたのは、TASK [virtualbox:Add VirtualBox repo file]でのエラーでした。こちらについては、Ansibleが提示してくださるエラーの内容から何もヒントが得られませんでした。
そこでVirtualBoxのリポジトリを設定する方法をGoogle先生とお勉強いたしました。
調べる中で気になったのは、リポジトリの設定にはOracleのpublic keyが必要となるよとの情報です。

こちらが参考にさせていただいたサイト様達です。
https://linuxmining.com/install-virtualbox-6-1-on-centos-8-rhel-8/
https://hrkworks.com/it/vm/vbox01/

まずはwgetコマンドが必要となりますので、以下を実行いたしました。

```shell
yum -y install wget
yum -y update
reboot
```

次にOracleのpublic keyを取得いたします。

```shell
wget http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc
```

ここまで完了したところで、本に記載されておりますplaybookを実行いたしました。
でも結果は同じでしたので、他に問題があるようです。
プロダクト開発におけるMTGの情報管理は映像議事録がいいと思った理由

# はじめに

レコロクを使う機会があり、映像議事録は個人的に新しい体験だなと思ったので記事化。
これまで音声データからの自動文字起こしのサービスはいくつか使ったことがあるのですが、その文字起こしとウェブ会議映像の録画データが紐付き、特定の会話が何分に行われていたのかがすぐにわかるという点がユニークなポイントでした。

▼レコロクについて

https://recoroku.com/

▼使うきっかけになった取材

https://zine.qiita.com/interview/202306-recoroku/

## 前提
私はQiita株式会社でマーケティングやセールスに従事しており、Qiitaをはじめとしたプロダクト開発に際してはビジネスサイドの観点としてレビューや議論する立場として関わっています。
本記事はプロダクト開発に関する情報管理や情報共有に関する内容に言及しているため、普段のコミュニケーションの流れなどを簡単にまとめると以下のようなイメージです

1. プロダクト開発MTGにて要件や詳細の議論
1. 各職能組織に情報共有

# プロダクト開発におけるMTGの情報管理は映像議事録がいいと思った理由
普段は基本的にはMTGの議事録をQiita Teamというドキュメントツールで作成し、情報を記録、共有をしていますが、レコロクを試してみて、映像議事録のほうがいいかもと思った理由は以下などがありました。

1. SlackのようなURLベースで共有ができるので楽
1. 議事録が自動で残るので議論に集中できる
1. 映像があるのでビジュアルも一緒に共有できるため認識の齟齬が起こりにくい

## SlackのようなURLベースで共有ができるので楽
>1. 各職能組織に情報共有

上述したように機能開発の方針が決まると、MTGに参加していないメンバー向けに議論において決定した以下などの情報を共有します。

- どのような方針、仕様、見た目になったのか
- おおよそのリリーススケジュール

これらの内容を共有するさいに、議事録のURLを共有はするのですが、どこを見ておいてほしいのかなど伝えたい内容を改めて要約して朝会などの定例MTGの議事録に記載するためちょっとした二度手間になってしまっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427308/b9ab1617-e211-51ce-7bad-6f9919c68dc6.png)

画像赤枠内のような感じで、ここ共有したい！というポイントをリンクベースで共有することができます

## 議事録が自動で残るので議論に集中できる
ここはシンプルで議事録をツールに任せることで、これまでだとどうしても議事録を取るメンバーが議事録と議論で脳内シェアが半分ずつになってしまっていた部分が、より議論に集中できるようになりました。

## 映像があるのでビジュアルも一緒に共有できるため認識の齟齬が起こりにくい
MTGの内容にもよりますが、プロダクト開発におけるMTGではUIのイメージ含めた議論をすることが多々あり、Figmaなどを画面共有しながら議論することがよくあります。
こういった議論の模様はスクリーンショットや議事録ツールへの埋め込みなどを用いて表現っしていました。
ただ、MTGの最中にこういったイメージも見たい、というように複数のパターンを実際にデザイナーに手を動かしてもらいながら確認、議論するというシーンも頻繁に発生していますが、それらをすべて表現することは難しいです。
映像があれば、上記のように特定の箇所をリンク共有して、その周辺の録画データからどういった流れでこの結論に至ったのかというプロセスまで確認できるため、MTGに参加していないメンバーにもスムーズに情報が共有できました。
結論を共有するときによく質問として挙がってくるような以下なども同時に解消できた印象があります。

- 他のデザインパターンは検討したのか
- 結論はわかったがどのようなプロセスでそこに至ったのか

# まとめ
各組織、各プロダクトでさまざまな情報管理や情報共有の方法があると思いますが、多職種が議論に関わり、それぞれ共有するといったやり方で開発している方々にはレコロクは非常に便利なのではないかと思います。

個人的には、インタビューや記事の取材、原稿作成などにも使うのも面白いなと思います。
RubyでAtCoder ABC309(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC309のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Nine
https://atcoder.jp/contests/abc309/tasks/abc309_a
```ruby:a-309.rb
a, b = gets.split.map(&:to_i)
puts b - a == 1 && a % 3 != 0  ? "Yes" : "No"
```

# B - Rotate
https://atcoder.jp/contests/abc309/tasks/abc309_b
```ruby:b-309.rb
n = gets.to_i
array = Array.new(n){ gets.chomp }

ans = array.map(&:dup)
1.upto(n - 1) do |i|
  ans[0][i] = array[0][i - 1]
  ans[i][n - 1] = array[i - 1][n - 1]
end

0.upto(n - 2) do |i|
  ans[i][0] = array[i + 1][0]
  ans[n - 1][i] = array[n - 1][i + 1]
end
ans.each{ puts _1 }
```
## 解説
（他の方の提出結果を参考にしました）

`dup`メソッドを使ってオブジェクトの内容をクローンする必要があるみたいです（元の`array`も変わってしまうため）。

# C - Medicine
https://atcoder.jp/contests/abc309/tasks/abc309_c
```ruby:c-309.rb
n, k = gets.split.map(&:to_i)

hash = Hash.new(0)
sum = 0
n.times do
  a, b = gets.split.map(&:to_i)
  hash[a + 1] += b
  sum += b
end

if sum <= k
  puts 1
  exit
end

hash.sort.each do |key, val|
  sum -= val
  if sum <= k
    puts key
    exit
  end
end
```
## 解説
連想配列`hash`に薬の情報を保持させておき、`sum`として錠剤の数の総和をもたせておきます。そして、`key`(日数)でソートした`hash`について`sum`から`val`(錠剤の数)を引き、`sum`が`k`以下であれば対応するkey(日数)を出力してループを抜けることで解くことができます。なお、1日目スタートであるため`key`の値は元の値よりも1多い値としています。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
ChatGPTのゆるい活用記録

# はじめに
個人的なChatGPT活用方法についてまとめます。
ChatGPT関連の記事はすでに多く出ているので、備忘・記録として書きます。
「プロンプトエンジニアリング」など込み入った話には触れずゆるく使っていきます。

※ ChatGPTの回答画像は全文を掲載していない可能性があります
※ 記事用に生成されたコードの検証はしていません。


# 前提条件
## ChatGPT Plus(GPT-4) を使う
GPT-3.5と比較して回答の精度が段違いです。
$20/月掛かりますが、それ以上の価値があるので課金しておきましょう。

## プログラミングでの活用に限定する
キリがないので、プログラミングでの活用に限定しています。

# 気を付けること
- 質問に機密情報やキー情報を含めないようにする
    - ChatGPTに限ったことではありませんが、アカウント流出もあるので必ずマスクしましょう。
    - https://gigazine.net/news/20230621-chatgpt-accounts-dark-web-marketplaces/
- 自分で真偽が判断できない情報を鵜呑みにしない
    - あくまで「それっぽい回答」をしてくれるだけ
    - 自身でファクトチェックをするか、判断できる領域で活用しましょう

# 基本的な使い方

## 条件を箇条書きで指定する

箇条書きで条件を指定すると期待する結果を得られやすいです。

例
```
Javaでとあるフォルダからファイルツリーを出力するプログラムを書いて下さい。
- for文はなるべく使わないでください
- なるべくStreamAPIやLambdaを利用して下さい
- 引数はファイルパスを受け取って下さい
- 例外が発生した場合は、上位にスローして下さい
```

## レビュアーになった気持ちで指摘をしていく

一回で期待する回答が得られることは少ないので、質問を繰り返してブラッシュアップしていきます。
レビューで人間に指摘するようにしていくと、上手く修正していってくれます。

### Q1
> Javaで1から10の値を合計する関数を作って下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/1ac79ece-5681-5ee2-c869-08165795daab.png)

### Q2
> for 文を使わないでください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/ecea8e64-3a23-8ab8-99c6-7a57b2675ae2.png)

### Q3
> LambdaやStreamAPIでできませんか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/844ea847-69e8-c025-7f7d-ac75c4c349f9.png)


# 活用方法

## 欲しいメソッドやクラスを作ってもらう
メソッドコメントを質問として渡すを良い感じになります。

### 質問例
> ```
> Goで以下のメソッドを作って。
> 
> # 内容
> - UTCをJSTに変換する
> - 入力値、出力値は文字列「yyyyMMddhhmmss」とする
> 
> # 入力値
> UTC時間
> 
> # 出力値
> JST時間
> ```

```
package main

import (
	"fmt"
	"time"
)

func convertUtcToJst(utcTime string) (string, error) {
	// UTC時間の文字列をtime.Timeにパース
	layout := "20060102150405"
	utc, err := time.Parse(layout, utcTime)
	if err != nil {
		return "", err
	}

	// UTCをJSTに変換
	jst := utc.In(time.FixedZone("JST", 9*60*60))

	// JST時間を文字列にフォーマット
	jstTime := jst.Format(layout)

	return jstTime, nil
}

func main() {
	// Example usage
	utcTime := "20230709103000"
	jstTime, err := convertUtcToJst(utcTime)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Println("UTC time:", utcTime)
	fmt.Println("JST time:", jstTime)
}

```

## メソッド名や変数名をつけてもらう
### 質問例

> ○○をするメソッドの名称を考えて下さい。

> ○○をするメソッドの名称で△△というのは自然ですか？

といった質問をすると使いやすいです。



## メソッドをブラッシュアップしてもらう

### 質問例
> 以下のコードを書きましたが、間違いや改善できる点があれば指摘して下さい

## クラスの配置箇所の相談

### 質問例
> クリーンアーキテクチャでSpring/Javaの実装をしています。
> Controllerでのみ利用する定数定義はどこに格納するのが良いですか？
> 定数は複数のControllerで利用されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/012d8f5f-61fe-a6f9-7372-6521854e5d0e.png)



## テストデータやダミーデータの生成
> 架空のアイドルユニット名をいくつか考えて下さい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3294382/10eb3587-cb8b-140c-e989-363e25b6dba6.png)


## 経験の無い/浅い言語でのプログラミング
生成した言語を微修正していけば、知らない言語でも結構実装できてしまいます。
ただし、精通している言語とあまりにかけ離れた文法のものは真偽の判断ができないため、難しいです。

あまりに構文の違うものだと厳しいと思いますが、１つ得意な言語があれば
# 終わりに
雑然とした記事なので、まとめることは特にありません。。。
また思いついた(or 思い出した)内容があれば追記していきます。