OmniAICreator/Qiita-1.07M huggingface dataset:
SlackでゲームUIの調整タスクをスピーディーに対応する管理方法

[QualiArts Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qualiarts)、8日目の記事です。
QualiArtsで開発ディレクターをしている、新見です。

# はじめに
ゲーム開発において、機能やUI/UXの改修は改修規模の大小に関わらず必ず発生するものです。その中でも、細かい調整タスクや日々発生するTODOタスクの管理方法には頭を悩ませることはよくあることだと思います。
一つ一つ全てのタスクをチケット化していますか？
細かいタスクを毎回チケット化することに時間をかけながらも、少し面倒臭いと感じることはありませんか？
特にUIの改修に関しては、実際にゲーム画面を見せながら指示する必要があることも多いので改修指示がされた画面の画像が必要であったりと、通常のタスクよりも管理方法が難しいと感じている方は多いのではないでしょうか。
本記事では、実際に[IDOLY PRIDE](https://idolypride.jp/game/)の開発の中で効果のあった、「ちょっとしたUIの調整タスクをスピーディーに対応する管理方法」について紹介をします。

# 前提
- タスクを管理するツールはSlackを利用します。
    - 弊社ではコミュニケーションツールとしてSlackを利用しているので、今回のタスク管理をする為だけにSlackを利用しているわけではありません。
- あくまでUIの調整タスクが対象です。
- 他の機能に影響を及ぼすような改修ではなく、影響範囲が小さくセルフチェックで完了できるようなタスクが対象です。
    - 端末の画面比によってはボタンの位置がずれている。タップ領域が狭い。etc... 
    - とはいえ、改修内容によってはちゃんと検証チームへ確認を依頼します。
- iphone、ipadを使うとよりスムーズにslackに投稿できます。（後述します)
- あくまで管理する側の身としてはやりやすく、うまくいっていたのではと感じているものです。
    - 実際に作業するエンジニアやデザイナーがどのように感じていたかは不明です。 
    - 実は不満がたくさんあった、、、とかであったらごめんなさい。

# 実際にタスク化から対応完了するまでの流れ
1. 対象画面に指示を記載してもらい、専用のチャンネルに投稿（デザイナー）
1. 担当者へスレッドにメンションを飛ばし、チャンネルへピン留めする（タスク管理者）
1. エンジニアが修正し、セルフチェック（エンジニア）
1. 投稿に「済」スタンプをおし、ピンを外して完了。（エンジニアorタスク管理者）

以上の流れで完了なので、とてもシンプルです。
![Web 1920 – 1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521209/9377859a-b2ea-169a-e514-2fb861bd7a71.jpeg)


# （おまけ）画像を簡単にslackに投稿する方法
実際にチームのデザイナーが画像をSlackに投稿していた方法を紹介します。
画面のスクショをとり、指示とセットでSlackに投稿をすればよいのですが、少し工夫することで、この作業も少し楽になります。もしかしたら、もっと良い方法があるかもしれません。iphone、ipad限定なので、android端末の方はごめんなさい。

1. AssistiveTouchを利用して画面のスクショを撮影
カスタマイズをして、タップでスクリーンショットを撮影できるように設定で変更します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521209/e892fb9a-a668-8af7-5168-4496cbab4a4b.jpeg" width="500">

2.撮影したスクショにその場で改修内容を記載
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521209/773e6dfa-20bb-dfe3-d293-f963756e05ed.jpeg" width="500">


3.共有でそのままslackへ投稿
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521209/0b2a6e18-4bb4-baf4-f491-8f43c3c02ef7.jpeg" width="500">


# まとめ
IDOLY PRIDEの開発ではサービスをリリースして1年以上たった今でも、この管理方法は継続しています。
今回の管理方法は特別な何かがあるわけではありませんが、個人的には特に以下のポイントがいいなと感じております。
- 他のタスク管理ツールのように、チケット化をすることに時間がかからない。
- Slackなので、何か疑問点があればそのままスレで質問を投げかけることができる
- ピン留めをすることで、残っているタスクは把握できる為、他タスク管理ツールと比較しても困る部分は特にない。

タスク管理の方法はチームやメンバーによって様々だと思いますし、そのチームに合った方法を選択するのが一番だと感じています。
この記事がゲーム開発のお役に少しでも立てれば幸いです。
CSM(Certified ScrumMaster)トレーニングを受けてきました

この記事はスタンバイ Advent Calendar 2022の15日目の記事です。

# はじめに
受けました、とは言ってもまだオフラインで参加できたころの話です。
トレーニングの内容を書き残す意図としては、私はスクラムマスターではないですが、

**スクラムマスターの考え方、目的を知ってもらうことで、各人の役割を明確にする。
なぜなら
スクラムチーム内に、スクラムマスターが何を考えているかわからない、
何を価値として活動しているかわらからないというメンバーがいるという状態を無くしたい。**

ということへの一助となればよいなと考えています

## CSMとは
https://www.odd-e.jp/ja/article_009_3/

最初に言われて印象的だったのが、
試験(だったかな？)とは言わないでトレーニングと言う、ということでした。
意図としては、筋トレと一緒で一回やったからといって筋肉がつく(スクラムマスターになれる)わけではなく、継続的に何回も繰り返しトレーニングをしていくことが大事だから。
という旨話されていました。

# 話さないこと
- スクラムの基礎知識
- 私が学んだこと、感じたこと
    - 体験がメインのトレーニングなので、体験したことから何を学ぶか感じ取るかは人に大きく依存するため、基本的に触れません。
    - ここでは、トレーニングの中で出てきた話を可能な限りそのまま端的に記載するだけです。
 

# トレーニングの進め方
<table>
<tbody>
<tr>
<th>講師</th>
<td>江端 一将さん</td>
<td>https://www.odd-e.jp/team_01/</td>
</tr>
<tr>
<th>参加人数</th>
<td>35人+1人(講師)</td>
<td>なお、私の回では自己紹介はしませんでした(禁止されているわけでは別にないです)。<br>
最終日まで名前も素性も知らずに進めていきました。</td>
</tr>
<tr>
<th>期間</th>
<td>3日間</td>
<td></td>
</tr>
<tr>
<th>時間</th>
<td>9:00~19:00</td>
<td>時間を延長するかどうかは受講者次第</td>
</tr>
<tr>
<th>その他</th>
<td>18:00~</td>
<td>クールダウン時間<br>
- レトロでネガティブな方向に考えが向くのを改善するため<br>
- ポジティブも必要</td>
</tr>
</tbody>
</table>

# トレーニングの内容
- スクラムマスターとしての基礎の基礎、初級の初級のトレーニング
    - トレーニングを受けたからといって、スクラムマスターが出来るかは当然わからない
    - 参考までに世界レベルでスクラムマスターのスタートラインは『組織のルールを一つでも改善したことがあること』

#  トレーニングを通して身につける力
- 論理を構築する力
    - 感情や経験では話さない
- 論理的に捉える力
- 効果を測る測定力

「大切なのは、出来ないことを嘆くのでのなく、出来ない課題を解決すること」
 
# お題
「スクラムをやっている人たちがなぜコミュニケーションを取っているか? 
コミュニケーションの+αは何か?」
- ただ話すだけではコミュニケーションとは言わない
- +αを提供するのがコミュニケーション

お題はクラスによって毎回変わります。
与えられたお題を、35人+1人(講師)で3日間考えていきます。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407041/715dfc21-3b57-fc06-192e-3464421199b4.jpeg">

※画像はイメージです

# スクラムマスターとして考えること
- 活動に対して評価するという考え方を持つ
    - 結果に対する指標
    - 活動に対する指標
        - 集団で活動する中での判断する尺度
- 活動を改善することを視点にする
- 集団が変わる提案をする
- 論理が構築された選択肢を出さないといけない
    - 出した選択肢が採用されないことは全く問題ない
- 論理を構築するためには、知識や情報が必要
- ScrumTeamが改善されるのが最重要
    - 3割→4割、4割→5割(チームが実現したいことを達成できる確率が、一歩でも進むことが大事)


# スクラムマスターの役割
- Developersの責任、役割
    - Scrum Teamの生産性を最大化する
- Product Owner責任、役割
    - Scrum TeamのROIを最大化する
- Scrum Materの責任、役割
    - Scrum Teamが実現したいことの確率を最大化する
    - Scrum Teamを守る
    - 組織を改善する

下の図は組織の中で、Scrum Teamが受けるチーム外からのあらゆる力に対して、Scrum Masterがチームを守ることのイメージです。
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407041/2117b8f4-3047-d5f3-3918-2921b0b24ce9.png">

# スクラムマスターの役割(時間的視点)
- Developersの視点
    - 短期
- Product Ownerの視点
    - 中期
- Scrum Masterの視点
    - 長期
        - 例えば、 Doneを満たすために法務部門の確認が必要で、それが障害になっているのであれば、法務の専門家をScrum Teamに加える(極端な例ですけど)。

# スクラムマスターの発言
- 「とりあえず」「一旦」「まず」等言っていいのは、Developersだけ
    - スクラムマスターは、論理を構築して、綿密に考えた戦略のもと選択肢等を発言しなければならな
いから。
        - ちなみにトレーニング中は、上記言葉を発すると即座に発言権を失いました。
- 主語は必ず「私たち」
    - 海外のスクラムマスターは意地でも「We」を使う人もいるらしい
- 言葉の選定に注意を払う
    - 相手の言葉に合わせることが大事
    - スクラムマスターにマウンティングは不要
 

# まとめ
トレーニングの内容にも記載したのですが、CSMトレーニングを受けたからと言って、スクラムマスターになれるわけではなく、あくまで入口に立っただけかと思います。
そこからの継続的なトレーニング、とりわけ論理を構築するために勉強しつづけて知識や情報を習得することが大事かと考えますので、スクラムマスターを目指すのであれば、日々の鍛錬を欠かさず、出来ない課題を解決する活動をし続けることが、近づける道なのかもしれません。
Loomについての初歩的な知識

# ジャンル
　画面録画、画面キャプチャーアプリ

# プラットホーム

1. デスクトップ版
    - Windows
    - Chorme拡張機能 (Edgeでも利用可)
    - Mac
1. モバイル版
    - iOs
    - Andoroid

# 料金

1. Starter (無料)
    - 最大50人のクリエイター
    - 最大25本のビデオ
    - 一回の録画可能時間　5分まで
    - インスタント編集
    - 無制限の文字起こし
    - プライバシー管理
    - 視聴者インサイト
1. Business ($12.5/月)
    - 無制限の参加者
    - 無制限のビデオ
    - 無制限の録画時間
    - 最大50人のクリエイター
    - パスワードで保護された動画
    - 動画のアップロード
1. Enterprise (問い合わせ)
    - 無制限のメンバー
    - 無制限のビデオ
    - 無制限の録画時間
    - SSOおよびSCIM
    - 高度なコンテンツプライバシー
    - カスタムデータ保護ポリシー
    - アクティビティログのエクスポート
    - セルスフォースの統合

https://www.loom.com/pricing#compare-plans

# 概要
　Loomは、ビジネス用のビデオ録画、共有ソフトウエアを提供する企業です。2015年、カリフォルニア州サンフランシスコでVinay Hiremath、Shahed Khan、Joe Thomasによって設立されました。
　2016年6月に、Chrome拡張機能、2018年8月にデスクトップ向けをリリースし、その後iOS、Android向けアプリがリリースされました。

# 基本機能
　Loomは動画を録画し、それを共有します。メニューは日本語化されていません。

## ビデオを録画する
　操作は、デスクトップ版では録画対象をデスクトップかウィンドウか選択するところがうまく動きませんでした。Chrome拡張機能版の方が使いやすいかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/85019130-627f-c307-bca8-12f3681e1d23.png)
　録画は、カメラの映像をカメオで表示させることもでき、画面上に書き込みすることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/3368bee4-e3ce-01b8-e2ce-94c16787f8d0.png)

# 動画の管理
　録画した動画はLoomのサーバーに送られ、編集や文字起こし、尺を修正、サムネイルの修正、動画の管理などはブラウザで行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f8bdf9d0-6354-7af0-00ca-b884a4919428.png)
　共有は、URLリンクを使うか、LinkedIn, TwitterやFacebook, Gmailなどに送ることができます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a1a8d5df-1ac3-3766-dbba-b9fbb25e374a.png"/>

# セキュリティ
　簡単に映像の共有ができてしまうので、セキュリティについて心配になります。
　初期値は "Share to <チーム名>" となっており、同じチームでも視聴できません。このスイッチをONにすると、チーム内のメンバーが視聴できるようになります。
　しかし、動画へのリンクを知っている場合、誰でも視聴できてしまいます。動画へのリンクへのアクセスは、3段階から選択できます。初期値が **"Anyone with the link can view"** なので注意が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/2e49445f-e193-baf8-367f-ec59c35c77c1.png)
　Libraryにはprivate folderとteam folderが作成できます。teams folderに動画を移動すると、Post状態になり、チーム内小メンバーは閲覧できる湯になります。また、フォルダーには Private と Public が選択できます。Public となっているフォルダー野中の動画は、リンクを知っている外部からの閲覧が可能になります。
　Publicになっていても、Unshareになっているとフォルダー内の動画は視聴できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f8f652b9-1db5-745b-f6f1-2287e8caca4f.png)
　視聴できる動画は、初期状態ではダウンロードも可能です。ダウンロードを許可しない場合は設定変更が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/6a304967-6d14-38c2-e457-d1629d0a28ff.png)

　**Private、Public、Shre、Unshare、Post、Unpost** の動作を説明しているところが見つけにくいと思いますが、公開しない動画を扱う場合は確認しておいてください。

　各種権限についての説明は、以下をご覧ください。

https://techffee.com/loom-for-team-8150/

# 何に使うか
　私としては、このアプリを課金して使う必要性は感じませんでした。無料枠でちょっとした動画を作成したい時に録画し、その後ダウンロードして、共有はYoutubeでやればいいように思います。
　動画のやり取りを頻繁に行うようであれば、ビデオメールのような使い方があるかもしれません。ただし、ビデオメッセージのサービスとしては、[BombBomp](https://bombbomb.com/)などもあります。
ふりかえりの手法を実践してみる　～Shooting Star～

## はじめに

前回の記事から1年以上経過してしまいましたが、ふりかえりの手法を実践してみた記事を復活させます。

(前回の記事は[こちら](https://qiita.com/msts_on/items/d296fa36ca42bef057fe))

今回は「Shooting Star」を実践してみたので、こちらの手法について書いてみたいと思います!

この記事はTDCソフト株式会社Advent Calendarの10日目です。
https://qiita.com/advent-calendar/2022/tdc

## Shooting Starとは？

Shooting Starはふりかえりの対象期間について、どんな期間だったかを「天気」で表します。天気の表し方は人それぞれ自由です。
その後にチーム全員の天気を更に良くするためにはどうしたらいいか？という観点でカイゼンのためのアイデアを出していきます。

## 参考にした書籍・サイト

tweeeety@メルカリさんの書いた[こちらの note 記事](https://note.com/tweeeety/n/n663300735460)を参考させていただきました。

## どのように進めたか

先ほどの記事を参考に以下のように進めました。時間は5人で進めたときの時間ですので、もしこちらを参考にする場合はご自身のチームに合わせて時間を調整してください

1. 今日のふりかえりの説明｜5～10分
簡単に手法と流れについて説明します。
2. 天気描き｜5分
Weatherボードという天気を書くボードを用意して、メンバーごとに対象期間がどうだったか天気の絵を描いてもらいます。
3. 天気の共有｜10分
それぞれなぜその天気を書いたのか簡単に説明して共有してもらいます。(1人MAX2分)
4. みんなの天気を良くするアイデア出し｜10分
天気を書くときより多めに時間を確保して、少しでもみんなの天気を良くできそうだと思ったアイデアをどんどん出していきます。
5. アイデアの共有｜10分
どんなアイデアを書いたか簡単に説明していきます。
6. 実際に取り組むアイデアを決定する｜15分
決め方は自由ですが、誰かの意見を採用するのではなく、チーム全員の総意で決めましょう。どうしても意見が合わないときは「[ドット投票](https://www.ourfutures.net/session_methods/dot_voting)」等を採用してアイデアを選定するのもありです。

## 事前準備

オンラインホワイトボードツールである Miro を用いて行いました。
天気を描くWeatherボードとアイデアを出すstarfishボードを用意しました。
天気を描くエリアは個人単位で書けるようにして、starfishボードはチームで共通で5つの要素を書くエリアを用意しました。
(詳しくは戦術のnote記事をご覧ください)

## 実際のふりかえりボード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298729/dc5be068-8072-88af-410f-1ba4cf7bb82e.png)
こちらは9人で実施したときのWeatherボードですが、よく見ると天気じゃないものも...？

## なぜ Shooting Star をやってみようと思ったか？

### 1. 他にはあまりなかった絵を描くふりかえりだったから

これまでいくつかのふりかえり手法を実際にやってみましたが、付箋に出来事など文字を書いてそれを共有するというのがスタンダードな形でした。出来事の共有に「絵を描く」というのが他のふりかえり手法にはない独特なポイントだと思い、純粋に面白そうだなと思いやってみることにしました！

### 2. 楽しそうな雰囲気を作りやすそうだった

1の内容と重複してしまいますが、「絵を描く」ということがこのふりかえりに楽しさを生み出してくれそうな予感がしました。
私はふりかえりをファシリテートするとき、「楽しい」「明るい雰囲気」を作ることを心掛けています。
そういう意味でこのふりかえりはその楽しくて明るい雰囲気が作りやすそうだなと思ったのも選んだ理由です。

## Shooting Starをやってみた感想

### 1.  絵を手書きで書くからメンバーの個性が出て楽しい！

進め方に明記しませんでしたが、私のチームでやったときは天気を手書きで書いてくださいとルールを設けていました。
理由は大きく2つあって、1つは絵文字等よりも手書きの方が天気を柔軟に表現しやすいのと、もう1つが絵に個性が出て面白いからです。
絵に自信がない人でも、天気くらいだとそこまでハードルの高さを感じずに描けますし、みんなの描いた絵からコミュニケーションが生まれて楽しい雰囲気になります。
例えば、すごい晴れているのに同時に土砂降りの雨が降っている絵を描いている人がいて「何があった！！」とみんながツッコんだり、太陽や雲などに表情を描く人もいて、「この天気かわいいね」など自然と何気ない会話を生み出すことができました。

### 2. 準備が簡単(ホワイトボードなど書けるものがあれば出来てしまう)

やること自体かなりシンプルですし、準備するものもホワイトボートや紙そしてペンといった書くものがあれば始めることができるのも大きな利点でした。
ファシリテーターの準備も少なく済みますし、説明自体も「その期間についてどうだったか天気を書いて表してください！​​​​​​」と「全員の天気を良くするには何ができるでしょう？」というシンプルな問いかけで進めることもでき、大きな混乱もなくふりかえりを進めることができました。

### 3.「自分」ではなく「みんな」の天気を良くするアイデアを出すところ

カイゼンの視点が個人ではなくチームにちゃんと向けられているところも良いポイントだと思いました。
例えば自分自身が晴れを書いたとしても、他メンバーが雨や曇りだった場合はその人たちの天気も晴れにするにはどうすればいいだろう？と考えることもできます。
また、いい天気を次の期間もいい天気のままであり続けるためのアイデアを考えることも重要です。
何もせずにいい天気(状態)が続く訳ではありませんし、いい天気を作り出すことができた要因をふりかえってそれを更に良くするアイデアを出すこともとても重要なので、その辺は意識して声掛けをしました。

## まとめ・最後に

Shooting Starは楽しい雰囲気で進められるふりかえりだと思います。
なかなか普段絵を描く機会自体少ないですし、そういう点からもすごく楽しめるふりかえりじゃないかな？と感じています。
また、毎日のふりかえりもすごく使いやすいのでは？と思っています。天気が毎日違うようにメンバーがそれぞれ感じることも毎日違うはずなので、そんな毎日の状況を知りやすくするという意味でもこのふりかえりは使いやすいなと感じました。
Why NFT Marketplace is an excellent choice for business startups

Incredibly lucrative enterprises in the cryptocurrency sector have attracted a sizable fan base. Many young firms are motivated by it to launch in the cryptocurrency sector. However, not all of them achieve the anticipated success rate. They frequently make mistakes since they don't know how to choose the finest business idea

In order to prevent this, I'm going to discuss a great business concept called the NFT marketplace, which enables you to realize your goals in an effective manner.

**NFT Marketplace: What is it? Why did you begin it?**

The NFT market is currently popular and has made a positive impression on plenty of business people. It enables users to transform digital works of art, music, gaming assets, and even real estate into non-fungible tokens (NFTs) and trade them.

The platform's owner will receive a portion of each NFT sale as a commission fee in the form of cryptocurrency. Additionally, the platform's owner will take a set amount of cryptocurrency as a charge for each NFT that is minted.

Given this, we can conclude that the NFT marketplace is among the best business concepts.

In a particular time frame, a lot of us will suffer. Regardless of the situation, you will attract the proper things and receive a good chance at your door. Therefore, this is the ideal time to choose the NFT marketplace as your business idea and establish a bigger presence there.

I hope you now have a basic understanding of the NFT market. But once you decide to launch an NFT Marketplace, you'll have a lot of questions about how it will be developed.

Don’t worry guys!!

You should check out my fantastic blog post on [how to build an NFT marketplace](https://www.coinsclone.com/how-to-build-an-nft-marketplace/). Referring to this post will clear up all the misunderstanding and assist you in building an excellent NFT marketplace in hassle-free way
if,else練習問題

# 問題
Aさんは普段土日が休みの仕事に就いており、
休みの日は遅くまで寝ていたいと考えています。
そこでAさんのために「その日が遅くまで寝ていられるかどうか」
を判断する、sleep_inメソッドを実装しよう。

第一引数の値では「平日かどうか」
第二引数の値では「休暇かどうか」
をtrueまたはfalseを用いて以下のように表します。

第一引数がtrue（平日である）または、
第二引数がtrue（休暇である）の場合はtrue

第一引数がfalse（平日でない）または、
第二引数がtrue（休暇である）の場合はtrue

第一引数がtrue（平日である）または、
第二引数がfalse（休暇でない）の場合はfalse

第一引数がfalse（平日でない）または、
第二引数がfalse（休暇でない）の場合はtrue

#### 雛形
```
def sleep_in(is_weekday, is_vacation)
  # ここに条件式を実装する
end
```

呼び出し例
sleep_in(false, false)
sleep_in(true, false) → false
sleep_in(false, true) → true


# 解答
```
def sleep_in(is_weekday, is_vacation)
  if is_weekday == true && is_vacation != true
    puts 'false'
  else
    puts 'true'
  end
end
```

# 模範解答
```
def sleep_in(is_weekday, is_vacation)
  if (is_weekday != true) || (is_vacation == true)
    puts true
  else
    puts false
  end
end
```


# 解説
第1引数は平日かどうかで判定し
第2引数は休暇かどうかで判定する。

「平日ではない」もしくは「平日だが休暇である」　→ true
「平日であり、休暇でもない」　→ false

　　　　　　　　　　　↓

「平日ではない」または「休暇である」場合に→true
条件式は、平日　|　|　休暇と記述する。
Py-Featで顔検出と表情認識やーる（Python 3.9、Windows 10）

# はじめに
Py-Featで顔検出と表情認識やっていきまーす

https://py-feat.org/pages/intro.html

# 開発環境
- Windows 10 PC
- Python 3.9

# 導入

1．py-featをインストールします

pip install py-feat

2．下記プログラムを実行します。画像から一つの顔を検出します。

~~~single_face_detection.py
from feat import Detector
import numpy as np
import cv2

detector = Detector(
    face_model="retinaface",
    landmark_model="mobilefacenet",
    au_model='jaanet', # ['svm', 'logistic', 'jaanet']
    emotion_model="resmasknet",
)

# single_face_prediction = detector.detect_image("single_face.jpg")
single_face_prediction = detector.detect_image("single_face.jpg", outputFname = "output.csv")

print(single_face_prediction.facebox)
print(single_face_prediction.aus)
print(single_face_prediction.emotions)
print(single_face_prediction.facepose) # (in degrees)
# figs = single_face_prediction.plot_detections(poses=True)
figs = single_face_prediction.plot_detections(faces='aus', muscles=True)
print(len(figs)) # 1

figs[0].canvas.draw()
image = np.array(figs[0].canvas.renderer.buffer_rgba())
# image = np.array(figs[0].canvas.renderer._renderer)
image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)

cv2.imshow("image", image)
cv2.waitKey(0)
~~~

3．顔検出結果の矩形
|FaceRectX|FaceRectY|FaceRectWidth|FaceRectHeight|FaceScore|
|:--|:--|:--|:--|:--|
|162.010315|120.175117|137.789398|202.156555|0.998934|

4．ランドマークの予測結果

|AU01|AU02|AU04|AU06|AU07|AU10|AU12|AU14|AU15|AU17|AU23|AU24|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|
|0.634789|0.963166|0.001228|0.847978|0.823023|0.06328|0.995102|0.212514|0.034145|0.00111|0.00223|0.000003|

5．表情認識結果
|anger|disgust|fear|happiness|sadness|surprise|neutral|
|:--|:--|:--|:--|:--|:--|:--|
|0.000574|0.000032|0.001309|0.972357|0.000069|0.025577|0.000082|

6．顔向き
|Pitch|Roll|Yaw|
|:--|:--|:--|
|3.200458|-3.116152|5.953827|

7．結果をプロットした画像
![output.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/226ef48c-8041-26c0-c5ee-061c096ce222.jpeg)

8．その他

detector.detect_imageの引数にoutputFnameを指定すると結果をcsvで保存できます。

figs = single_face_prediction.plot_detections(faces='aus', muscles=True)はエラーが出ました。
**IndexError: index 15 is out of bounds for axis 0 with size 12**

au_modelがsvmのときはエラーが出ました。モデルがダウンロードできないようです。
**urllib.error.HTTPError: HTTP Error 404: Not Found**

ここにモデルリストがあります。

https://github.com/cosanlab/py-feat/blob/main/feat/resources/model_list.json

- https://github.com/cosanlab/py-feat/releases/download/v0.1/svm_568.joblib
- https://github.com/cosanlab/py-feat/releases/download/v0.1/Logistic_520.joblib
が見つからないようです


お疲れ様でした
Node-REDでChatGPTを試す

今話題の `ChatGPT` をNode-RED（enebular）でサクッと試してみました。

## 1. パレットの追加
パレットの追加から `node-red-contrib-simple-chatgpt` を検索します。
出てきたやつをインストール。

![s100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154355/0c276b9c-7c94-0104-5cef-31ac0770f4a6.png)

## 2. シークレットキーを取得する
下記URLにアクセスし、アカウント設定してシークレットキーを生成してください。
https://beta.openai.com/docs/quickstart/build-your-application

![s101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154355/2f40349a-a28e-41d1-8c2a-dcabc4a65ecf.png)

## 3. simple-chatgptを設定する
simple-chatgptをドラッグアンドドロップして、先ほど取得したシークレットキーを適応します。

![s102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154355/3c17b0ea-c16f-1d0d-91c2-1959f9dc1dc7.png)

あとはpayloadに適当なメッセージを設定すれば、こんな風に返答が返ってきます。

![s103.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154355/def65775-484e-733f-464f-4573001e1cdd.png)

## まとめ
AIの進化が素晴らしいですね。Node-REDだと簡単に試すことができるので、幅が広がりますね。
数 Steps で手軽に脆弱性対策をする方法

## はじめに

こちらの記事は「[Snykを使って開発者セキュリティにまつわる記事を投稿しよう！ by Snyk Advent Calendar 2022](https://qiita.com/advent-calendar/2022/snyk)」の 6 日目の記事として投稿しています。

[私(@changeworlds)](https://twitter.com/changeworlds)からは、Snyk を使うことで、数 Steps で脆弱性対策をする具体的な方法についてご紹介いたします。

脆弱性対策というと企業に所属している人なら所属先のアプリケーション/サービス/プロダクトに対して、年次/Q 毎など定期的に脆弱性診断をしてもらっているかと思います。

しかし、本来問題というのは一定期間寝かせておいてから取り除くのではなく、気づいたときに取り除くものです。

とはいえ脆弱性診断を commit/push 毎にするというのは至難の業です。

そこで、登場するのが数 Steps で手軽に脆弱性対策を行える [Snyk](https://go.snyk.io/jp.html) です。

https://go.snyk.io/jp.html

https://go.snyk.io/jp.html にアクセス後、 [ログイン/無料トライアル] をクリックして、アカウントを登録し、GitHub リポジトリと連携する設定してみましょう。

なんとこれだけで以下のメリットを享受できます！！

### **登録した GitHub リポジトリに対して自動解析してくれる**

便利ですね。

たったこれだけで、勝手に GitHub リポジトリのコードを読み込んで、勝手に解析し、勝手に修正のための Pull Request を出してくれます。また、連携した GitHub リポジトリに Pull Request を出すと、変更されたコードの中に脆弱性がないか勝手にチェックしてくれます。

勝手にチェックしてくれる脆弱性としては、ソースコードとライブラリがあります。

ソースコードの場合は、ソースコードで問題があったり、脆弱性があったりする書き方をしていると指摘をしてくれます。

指摘を無視(Ignore)することもできますし、指摘をしてくれる際は同時に他の人はどのように修正しているのか？といった sample を提示してくれるので、「どう直せばいいかわからないな…」といったときに助かるかと思います。

ライブラリの場合は、利用しているバージョンに脆弱性がある場合にその脆弱性を解消するためにどのバージョンまで上げないといけないかを指摘してくれます。というか、勝手に Pull Request を送ってくれます。

ここまでの機能は

* アカウントを作る
* GitHub リポジトリと連携する

だけで行える脆弱性対策ですが、ここからもう数 Steps 追加することで、さらに脆弱性対策をする方法をお伝えします。

* アカウントを作る
* GitHub リポジトリと連携する

だけでよいので、とても簡単な反面、この指摘をもらうためには、Pull Request なり、GitHub に push する必要があります。

でも、push や Pull Request を出す前にローカルで脆弱性があるかどうかわかった方がより品質を高められますよね？

それをできるようにするのが次にご紹介する [Snyk Code Checker](https://snyk.io/code-checker/) になります。

Snyk Code Checker は IDE のプラグインとして利用可能で、コードをスキャンし、問題点を検出するツールです。これを使うことで、コーディング中に脆弱性対策をしたコードに直接修正できるので品質とセキュリティの高いコーディングができるというわけです。

## Snyk Code Checker

* アカウントを作る
* GitHub リポジトリと連携する

ほどではないですが、使い方は簡単です。

事前に Snyk のアカウントを作成していると思うので、Snyk の画面の下にある [Integration] > [IDE plugins] から利用している IDE を選択してください。
※ 本記事では Visual Studio Code を前提に説明します。

別ウィンドウ(本記事では Visual Studio Code の Marketplace)が開くので、[Install] をクリックします。

すると、先ほど選択した IDE(本記事では Visual Studio Code)のプラグインインストール画面が表示されるので Install をクリックします。
![IDE install](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104744/aac5f90c-197b-3a9a-f8d3-e77e7cd04bd7.png)

Visual Studio Code の場合、Snyk にログインするように表示されるので、Trust wordspace and connect ボタンをクリックします。
![Trust wordspace and connect](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104744/f285dfd2-7428-b7af-e414-7a59e650585e.png)

すると、ブラウザで認証画面が表示されるので、Authenticate をクリックします。
![Authenticate](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104744/40bfa185-ffbd-c2dd-9e66-31957d7f6668.png)

認証に成功すると Snyk のプラグインが IDE(本記事では Visual Studio Code)で自動的に実行されます。

デフォルト設定だと、ファイルを保存すると自動的にスキャンが実行されます。

* アカウントを作る[他手順で実行済]
* Snyk の画面の下にある [Integration] > [IDE plugins] から利用している IDE を選択する
* 別ウィンドウ(Visual Studio Code の Marketplace)が開くので、[Install] をクリック
* IDE で Install をクリック
* Visual Studio Code の場合、Snyk にログインするように表示されるので、ボタンをクリック
* ブラウザで認証画面が表示されるので、Authenticate をクリック

追加 5step でローカルで脆弱性対策を行ったコーディングができるようになります。

## おわりに

今回 Snyk でコードの品質を向上させる流れを紹介しました。

Snyk は脆弱性以外にもコードの品質を向上させるためのツールとしても利用する事ができます。Snyk を利用することでコーディング段階からコードの品質、サービスの品質を向上させることができます。
WindowsからRaspbery PiにRDPで接続できなくなった話

# 現象

Raspbery Pi OSへのWindowsからのRDP接続。ついさっきまで普通にできていたのに、突然、なぜかログアウトしたあと二度とログインできなくなった。

ログインダイアログは表示されていて、usernameとpasswordを入力すると、まあまあ長い時間、青い画面のまま。そしてその後、画面の左上に下記の内容の Connection Log ウィンドウが現れる。

```
connecting to sesman ip 127.0.0.1 port 3350
sesman connect ok
sending login info to session manager, please wait...
login successful for display 10
started connecting
connection problem, giving up
some problem
```

`/var/log/xrdp-sesman.log` を調べてみると、下記のエラーメッセージが記録されていた。

```
[ERROR] sesman_data_in: scp_process_msg failed
[ERROR] sesman_main_loop: trans_check_wait_objs failed, removing trans
```

# 解決

Googleで検索して、いろいろ試してみたが、何をやってもダメ。
しかし結局以下の方法で解決できた。

`sudo raspi-config` を実行して 1. System Options → S5 Boot / Auto Login → B1 Console を選択し、rebootする。すると、Windowsから無事RDP接続ができるようになった。

そして、その後は B3 Desktop に戻しても大丈夫。

理由はわからん！
Cやアセンブラで終了ステータスを返す

# はじめに
必要最低限の環境変数やコードを調べ、今後の土台とする。

# 環境
Windows 11 Pro (64bit)
Visual Studio Community 2022

# MASM32 SDK

https://www.masm32.com/

http://takeda-toshiya.my.coocan.jp/msdos/

## ソースなど

```dev16.bat
@echo off
path %path%;D:\masm32\bin
path %path%;D:\etc\msdos\binary\i86_x64
cmd
```

```ret.asm
comment *
ml /c ret.asm
link16 /t ret;
*
.model tiny
.code
	org	0100h
start:
	mov	ax, 4c2ah
	int	21h
end start
```

## 実行例

```
D:\Projects\etc\MASM32>ml /c ret.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

 Assembling: ret.asm

D:\Projects\etc\MASM32>link16 /t ret;

Microsoft (R) Segmented Executable Linker  Version 5.60.339 Dec  5 1994
Copyright (C) Microsoft Corp 1984-1993.  All rights reserved.

LINK : warning L4045: name of output file is 'ret.com'

D:\Projects\etc\MASM32>msdos ret

D:\Projects\etc\MASM32>echo %errorlevel%
42

D:\Projects\etc\MASM32>certutil ret.com
    b8 2a 4c cd 21                                     .*L.!
CertUtil: -dump コマンドは正常に完了しました。

D:\Projects\etc\MASM32>
```

# VC++

## ソースなど

```devc.bat
@echo off
path %path%;D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx64\x86
set lib=%lib%;D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\lib\x86
set lib=%lib%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86
set lib=%lib%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86
cmd
```

```retc.c
/*
cl /MD retc.c
*/
int main(int argc, char *argv[])
{
	return argc;
}
```

## 実行例

```
D:\Projects\msvc>cl /MD retc.c
Microsoft(R) C/C++ Optimizing Compiler Version 19.34.31935 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

retc.c
Microsoft (R) Incremental Linker Version 14.34.31935.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:retc.exe
retc.obj

D:\Projects\msvc>retc a b c

D:\Projects\msvc>echo %errorlevel%
4

D:\Projects\msvc>
```

# MASM (x86)

## ソースなど

```devasm.bat
@echo off
path %path%;D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\Hostx64\x86
set lib=%lib%;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86
cmd
```

```reta.asm
comment *
ml /c reta.asm
link /subsystem:console reta
*
includelib kernel32
.model flat
ExitProcess proto stdcall :dword

.code
start proc c
	invoke	ExitProcess, 42
start endp
end start
```

## 実行例

```
D:\Projects\msvc>ml /c reta.asm
Microsoft (R) Macro Assembler Version 14.34.31935.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: reta.asm

D:\Projects\msvc>link /subsystem:console reta
Microsoft (R) Incremental Linker Version 14.34.31935.0
Copyright (C) Microsoft Corporation.  All rights reserved.


D:\Projects\msvc>reta

D:\Projects\msvc>echo %errorlevel%
42

D:\Projects\msvc>
```
Docker環境のLaravel 9 + VITEでハマったこと

# はじめに
Docker環境でLaravel9のbreezeを使用した時にcss, jsの参照問題で地味にハマったのでその解決法の共有です。


## 環境
Docker環境と構成: [リポジトリ](https://github.com/hellomyzn/docker_laravel)
- PHP
- Nginx
- Node
- Mysql
- Mysql(test db)
- PHP My Admin
- Ngrock
- Schemaspy
- Schemaspy Server(Nginx)

それぞれのVersion
- PHP: 8.1.13
- Laravel: 9.42.2
- Composer: 1.10.26
- Node: 16.18.1


## 前提
- Dockerを使用してLaravel環境を構築している。
- Breezeをインストールしている。
- Nodeサーバーではnpm run devをしている状態。

## 現象
下記の画像のようにcssとjsの参照がうまくできていませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184733/56831d2b-5fdb-c0d4-b44d-ac400fea43c9.png)

エラー内容
```
Failed to load resource: net::ERR_EMPTY_RESPONSE
```

## 原因
- Laravel9からビルドツールが`Laravel Mix`から`Vite`への変更があった。
- ブラウザからNodeサーバーにアクセスするため、Nodeサーバーの`5173`ポートを公開する必要がある。
- Viteのネットワーク経由のアクセスを設定していない。

## 解決方法
### Nodeサーバーの5173ポートを公開
自分の環境では下記のように追加
```dockerfile: Node Dockerfile
  node:
    container_name: node
    build: ./infra/node
    ports:
      - 5173:5173 //追加
    tty: true
    volumes:
      - ./backend:/work
    working_dir: /work
```

`http://localhost:5173/`で下記のようになっていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184733/7c2e61ea-9e72-c6b9-7baf-02328ebc4103.png)


### Viteの設定
`vite.config.js`でネットワーク経由のアクセスを設定する。

```js:vite.config.js
export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
    ],
// ここから追加
    server: {
        host: true,
        hmr: {
            host: 'localhost',
        },
    },
});
```
変更後に`npm run dev` をすると`Network`のところにURLが設定されていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184733/a52980f9-cfbf-8d87-987f-13cf9bb4161a.png)

このNetworkのIPアドレスはDocker Networkで設定されているもので下記のコマンドで確認できます。
```
# ネットワークの名前を検索
$ docker network ls

# ネットワークの詳細を表示
$ docker network inspect NETWORK_NAME
```


### ブラウザで確認
`http://localhost:8080/login`にアクセスすると下記のようになっていればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184733/715c05cf-6bfa-fcdd-6165-7d96f7987152.png)

### 参考
- [【超入門】20分でLaravel開発環境を爆速構築するDockerハンズオン](https://qiita.com/ucan-lab/items/56c9dc3cf2e6762672f4)
文系卒未経験の新人SEが現地作業のとき意識してること3つ


## はじめに
現場に入ってから４か月になりましたが、
なかなか毎日悪戦苦闘しながらしごとをする毎日です。

文系卒未経験の新人が配属されることになった現場は、
なんと現地作業盛りだくさんでした！

私のいう現地作業とは、
エンドユーザー様のオフィスに訪問し現地で製品の説明や作業をおこなうことです。
現地作業では取り扱っている製品への理解はもちろん、
エンドユーザー様に説明するなどの対人スキルも必要とされます。

これは自分にとってかなりハードルが高く、
最初はもっと単純なドキュメント作成などが多いのかなと思っていたので
実際の業務とのギャップに驚く日々でした。

そんな中で右も左もわからないなりについてくために
現地作業のときにまずこれだけは意識しよう！としている三つのポイントを紹介します。

## ①わからないことをそのままにしない
当たり前のことですが、まずはこれに尽きます。
わからないことをそのままにしてためていたら、
いつか同じような作業をするときそのツケを払うのは未来の自分です。

余裕がなかったりして即時に解決できなくても、
何がわからなかったかメモするなど、何かしらに残しておくことで
思い出すきっかけになります。
上司の空いた時間にササっと質問できたりするので、
やはりメモしておくことは大事だと思います。

「わからないことがなんなのかわからない」状態が
私は一番つらいなと思うので、わからないことを言語化できるよう日々頑張っています。

## ②手順通りの作業では考えない
これは現場の上司に教えていただいたものです。
最初は意味が分からなくて困惑しました。。

これは訳すと、「作業中考えなくていい手順を事前に用意できるようにする」ということです。
手順を用意しているのに作業中に考えたり迷ったりするのは
その手順を理解できてない、もしくは用意してきた手順が不十分だったからです。

現地での作業を円滑に行うためには、手順があるか聞くなり事前の検証をするなり、
はっきりとした手順をあらかじめ用意しておくことが大事です。
手順を準備することで自分の自信につながりますし、安心して作業に臨むことができます。


## ③顔に出さない
これがなかなか難しいです。
実際現地作業に行ってトラブルが起きたとき、原因を自分で切り分けして問題解決にあたります。
このとき私の心の中は「やばい」でいっぱいです。
まだ自分に自信がないため、トラブルが起きても起きなくても
作業が無事終わるまでどうしてもあせったり不安になったりして慌ててしまうことが多々あります。
しかし、エンドユーザー様を前にしてそのようなふるまいはよくありません。
相手に不安を抱かせるようなふるまいは、現地作業の際は厳禁です。
どんなに心の中が嵐でも顔には出さないよう、女優になったつもりで対応を心がけています。

# おわりに
実際に文字に起こしてみて、
意識しようとしてるだけでできてないこともたくさんあるなあとあらためて振り返ることができました。
今後もできていないことをできるように、日々頑張りたいと思います。
ここまで閲覧いただきありがとうございました。
Serverless Frameworkを使ってLambda + API Gateway + DynamoDBの環境を構築してみる

## 目次
1. Serverlessのインストール
2. サービスの作成
3. サービスをデプロイしてみる
4. API Gatewayの設定
5. DynamoDBの設定
6. まとめ

## 1. Serverless Frameworkのインストール
Serverlessはnpmのパッケージとして公開されているため、ターミナルより以下を打つとグローバルにインストールされる。
```shell
$ npm install -g serverless
```

正しくインストールできているか<span style="color: #6c737b"><span style="color: #1453c6">serverless --version</span>と打って以下の表示になっているかどうかで確認できる。
```shell
$ serverless --version
Framework Core: 2.72.3 (local)
Plugin: 5.5.4
SDK: 4.3.2
```
## サービスの作成

Serverlessではサービスという単位で実行環境を構築しているらしい。
    
 そして実際にサービスを構築するためには以下をターミナルで打てば良い。
 ```shell
 $ serverless create --template aws-nodejs --name my-special-service --path my-special-service
 ```
    
 すると以下のようなディレクトリ群が作成される。
 ```
 - my-special-service
     - .gitignore
     - handler.js
     - serverless.yml
```
ここで、グローバル（自分の場合だと/usr/local/lib/）にserverlessを置いた状態だとエラーが起きることがあるため、
    my-special-service階層でもう一度serverlessをインストールする。
```shell
$ cd my-special-service
 ```
```shell
$ npm install serverless
```
すると以下のようなディレクトリ群が作成される。
 ```
 - my-special-service
     - .serverless
     - node_modules
     - .gitignore
     - handler.js
     - package-lock.json
     - package.json
     - serverless.yml
```
    
以下にそれぞれのファイルの詳細を記載する。

### .serverless
serverlessライブラリ群。基本いじることがないと思う。
    
### serveless.yml
サービス全体の設定を行うためのファイル。
ここを書き換えることでそれぞれの環境構築が可能になる。
    
### hander.js
Lambdaで実行する関数をここに記載していく。
    
### package.json/package-lock.json/.gitignore
省略
    
## サービスをデプロイしてみる
ここで作成したサービスをプロバイダー上へデプロイしてみる。
デプロイするためには以下をターミナル上で打てば良い。

```shell
$ serverless deploy -v 
```

-vオプションを付けるとverboseというモードでデプロイが実施され、途中経過がターミナル上で確認できる。

ここまででLambdaの関数を構築・デプロイまで完了したので、プロバイダーのLambdaの関数画面から確認すると良い。

## API Gatewayの設定
    
API Gatewayを設定するためには以下をserverless.ymlに加える。
```
# Lambdaのイベントトリガーを設定
events:
# トリガーとしてAPIGatewayを構築
  - http:
    path: sample/test # リソースを指定
    method: post # メソッドを指定
    integration: lambda # 統合サービスをLambdaにする
```
一旦デプロイするために以下をターミナルに打つ。
```shell
$ serverless deploy -v 
```
ここまででAPI Gatewayを構築・デプロイまでが完了したので、プロバイダーのLambdaの関数画面から確認すると良い。
    
## DynamoDBの設定
```
# リソースの構築
resources:
  Resources:
    # DynamoDBの構築
    DynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        # キーの型を指定
        AttributeDefinitions:
          -
            AttributeName: id
            AttributeType: S
            -
            AttributeName: name
            AttributeType: S
```
ここまででDynamoDBを構築・デプロイまでが完了したので、プロバイダーのDynamoDBの画面から確認すると良い。

## 参考文献
- https://serverless.co.jp/blog/25/
- https://qiita.com/t_okkan/items/546330b5f4da720c71a7
Pleasanterで簡単なTODOリストを作ってみる

本記事は、[OSSのノーコード・ローコード開発ツール「プリザンター」 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pleasanter) の6日目の記事です。

# 前置き
[こちら](https://qiita.com/Implem/items/f47b37c2ab561b5cf356)の記事より、TODOリストとか簡単にできそうかなと思い作ってみました。

# TODOリストの仕様
特に期限などの管理は想定せず、タスクの完了・未着手を管理するだけ単純なものを考えてみました。

ざっくり仕様
・Pleasanterにタスクを登録
・一覧画面上のボタンを押すことでタスク完了にする
・完了後は未着手に戻すこともできる

ポイントは、一覧画面でポチポチっと完了にしていく操作イメージ。

# 実装画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/e30504e1-a6ea-f8de-29a3-72cbbca911a6.png)
「完了にする」ボタンをクリックすることで、ステータスが完了になるようにします。前述のとおり、単純に終わったか・終わっていないか、を管理するだけにしたいので、ステータスは、「未着手」と「完了」だけにします。

また、ボタンは少し手を入れてて、ステータスに応じて、「完了にする」「完了を戻す」と表示名を切り替えます。

# 実装

### ボタン配置：サーバスクリプト

ステータスの値に応じてボタンの表示を切り替えるようにします。

```javascript
try {
    let label;
    if (model.Status === 100){
        label = '完了にする';
    }else{
        label = '完了を戻す';
    }
    let html = `
<button data-id="${model.ResultId}" 
class="todo-check button button-icon ui-button ui-corner-all ui-widget applied" 
type="button" >${label}</button>
    `;
    columns.ClassA.RawText = html;
} catch (e) {
    // エラーログ出力
    context.Log(e.stack);
}

```

### TODO処理：スクリプト
レコードのIDからApiでGet→Updateしています。特に難しいことは無いと思います。
```javascript
//ボタンクリックイベント
$(document).on('click', '.todo-check', function (event) {
    // レコードのIDをコンソールに出力
    ToDo($(this).data('id'));
    // 編集画面が開かないようにイベントの伝搬を停止
    event.stopImmediatePropagation();
});

//メイン処理
const ToDo = async(id) => {
    //Apiでレコード情報を取得します。
    let res = await ApiGet(id);
    let value;
    //取得結果のステータスの値より、更新すべきステータスを判定します。
    if(res.length > 0){
        if(res[0].Status !== 900){
            value = 900;
        }else{
            value = 100;
        }    
    }
    //Apiでレコード情報を更新します。
    await ApiUpdate(id, value);
    console.log(res);
}

//Apiでレコード情報を取得
const ApiGet = async (id) => {
    let res;
    await $p.apiGet({
        id: id,
        done: function (data) {
            res = data.Response.Data;
        }
    });
    return res;
}

//Apiでレコード情報のステータスを更新
const ApiUpdate = async (id,value) => {
    let res;
    await $p.apiUpdate({
        id: id,
        data: {
            ApiVersion: 1.1,
            Status: value
        },    
        done: function (data) {
            //処理が終わったら画面をリロード
            location.reload();
            res = data;
        }
    });
    return res;
}
```

# 使い方など
[ビュー](https://pleasanter.org/manual/table-management-view)に未着手のものだけ表示するようにしておくと、より使いやすくなるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/a334242b-7f96-22ab-6a76-0012ae9a59a5.png)
↓↓「完了にする」ボタンをクリックすると、どんどんレコードが消えていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/ac02d32c-8123-43b1-a956-4ef57935f813.png)

# 余談
ちなみに、詳細画面であれば[プロセス](https://pleasanter.org/manual/process)でノーコードで簡単に作成できたりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922382/799350c1-14ea-21cd-aff7-d69d23d68920.png)
#### 余談の余談
プロセスに「一括処理を許可」というのがありますが、これは一覧画面でプロセスを「一括処理」するためのものであり、今回の要件とはちょっとズレるかなと思ってこのような個別スクリプトでの処理としました。ただ、今後のアップデートで、同じことがノーコードでできるようになるかも知れませんね。
Zapierを使ってQiitaに投稿したらMattermostに通知を飛ばす

せっかくQiita使い始めたので、記事を書いたら社内のMattermostにも通知を飛ばしてアピールしよう！
と思って試してみました。

- mattermost.comの情報
https://developers.mattermost.com/integrate/zapier-integration/

# やったこと
## MattermostでOAuth2.0を有効にする
`システムコンソール`→`統合機能管理`
で
`OAuth2.0サービスプロバイダーを有効にする`を`有効`にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985470/d1bf2f50-8347-0d59-580d-5b50c798219f.png)


## MattermostでOAuth 2.0アプリケーションの登録
`統合機能`に`OAuth 2.0アプリケーション`の選択が出てくるので、[ここの情報](https://developers.mattermost.com/integrate/zapier-integration/)を参考に新規で登録する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985470/9e555fa2-3a60-9db5-ac87-0c5f2abaea01.png)

## Zapierの設定
Zapierのアカウント登録をし、`RSS`→`Mattermost`で新規作成する。
詳細省いちゃいますが、上記で追加したOAuth2.0アプリケーションのクライアントIDとクライアントの秘密鍵を入力しつつ下記のような感じで登録。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985470/6b67e8ae-11d6-fb50-e6d7-2d016effaefd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985470/b556cd50-a1cf-4ca7-d278-75c30e90c839.png)

以上で終了。
Zapierは他にも色々なサービス間での連動を簡単に構築できそうで活用の幅が広そうです！

※きっとこの記事も通知されるはず・・（笑）
[VSCode] Pythonのisort拡張機能がいつの間にか使えなくなってた話

VSCodeでPythonのisort拡張機能が使えなくなってしまったのはしばらく前のこと。こんな感じのエラーが出て使えなくなっていました。

![isort-error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982972/13ad4be5-3c06-7673-252e-d2afb0011edc.png)

それほど致命的ではなかったので、特に理由を追求することなくしばらく放っておいたのですが、ふと思い立ってクラッシュの理由を調べてみました。原因はあっけなくわかりまして、単に開発環境のPythonバージョンが古すぎただけでした。

> This extension is supported for all actively supported versions of the python language (i.e., python >= 3.7).

https://marketplace.visualstudio.com/items?itemName=ms-python.isort


とりあえず拡張機能をdisableしました。Pythonバージョンが上がったら有効化しようと思います。
paiza.ioでelixir その120

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
活性化関数tanhをグラフ化せよ。

# サンプルコード

```


IO.puts """
<!doctype html>
<html>
<head>
<style type="text/css">
* {
  margin: 0;
  padding: 0;
  border: 0;
}
body {
  background: #fdd;
  font: 30px sans-serif;
}
</style>
</head>
<body>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<div id='chart'></div>
<textarea id="koko0"> 
"""
for i <- 0..100 do 
    a = :math.exp(((i - 50) / 5))
	b = :math.exp(-1 * ((i - 50) / 5))
	v = (a - b) / (a + b)
    IO.puts(v)
    IO.puts ","
end
IO.puts """
</textarea>
<script type="text/javascript">
google.load("visualization", "1", {
    packages: ["corechart"]
});
var x0 = document.getElementById('koko0').value;
var x = x0.split(",");
var res = [['x', 'tanh'],];
for (var i = 0; i < 100; i++)
{
    res.push([i, x[i] / 1]);
}
google.setOnLoadCallback(function() {
    var data = google.visualization.arrayToDataTable(res);    
    var options = {
        title: '活性化関数',
        hAxis: {
            title: 'x'
        },
        vAxis: {
            title: 'y'
        }
    };    
    var chart = new google.visualization.LineChart(document.getElementById('chart'));
    chart.draw(data, options);
});
</script>
</body>
</html>
"""


```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0ecb359e-55f4-5eb9-a311-c9f5ce2871dd.png)


# 成果物

https://paiza.io/projects/wbOp1FRo_3B54CqSYCUAIA?language=elixir


以上。
svelte/storeについてのまとめ - 後編

# はじめに

svelte/storeについてのまとめを作りたかった
今回は`derivered` `custom` `binding`について

# 使ったもの

* Vite + Svelte + Typescript
* skelton

# 前回(writable, Auto-subscribe, readable)

https://qiita.com/doyaseizin/items/774dda71a18fd3a61f58

# derivered

`store`されている値が変化した時に一緒に変化させるメソッド。
`computed`みたいな感じ？
公式では時計と、所要時間という風に使ってました。

![deliver.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/b1b87dd1-da90-409e-b398-aaef70e006ee.gif)


```typescript
// src/store.ts
import { readable, derived } from 'svelte/store';

export const count = readable(0, (set) => {
  let c = 1
  const interval = setInterval(() => {
    set(c);
    c++
  }, 1000);

  return function stop() {
    clearInterval(interval);
  };
});

export const double = derived(
  count,
  $count => $count * 2
)
```


```vue
<script lang="ts">
	import { count, double } from "../../store";
</script>

<div>現在: {$count}</div>
<div>２倍: {$double}</div>
```

# custom

`store`をカスタマイズすることができ、自前のメソッド等を`store`に持たせることができる。
`store`の使い方が固定されている場合はカスタマイズした方が再利用性が高くなりそう。

![custom.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/fcdfa349-08c1-a7cc-4a26-790f7082ccc6.gif)


```typescript
// src/store.ts

import { writable } from 'svelte/store';

function createCount() {
  const { subscribe, set, update } = writable(0);

  return {
    subscribe,
    increment: () => update(n => n + 1),
    decrement: () => update(n => n - 1),
    reset: () => set(0)
  };
}

export const count = createCount();
```

```vue
// src/Home.svelte
<script>
  import { count } from "./store"
</script>

<div>
  The count is {$count}
</div>

<button class="btn btn-filled-surface" on:click={count.increment}>+</button>
<button class="btn btn-filled-surface" on:click={count.decrement}>-</button>
<button class="btn btn-filled-surface" on:click={count.reset}>reset</button>
```

# binding

`store`が書き込み可能な状態(`subscribe`や、`Auto-subscribe`)の時は、
他の変数と同じように`bind`が使えます。
`input`の要素を変えてみます。

![binding.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/9945fed3-d4ea-6daa-f466-ebfe81c56fde.gif)


```typescript
// src/store.ts
import { writable } from 'svelte/store';

export const text = writable('');
```

```vue
// src/Home.svelte
<script>
  import { text } from './store';
</script>

<label for="text">
  <label for="text">
    <span>テキスト</span>
    <input type="text" id="text" bind:value={$text} minlength="2" required>
  </label>
</label>

<button class="btn btn-filled-surface" on:click={() => $text += 'こんにちは。'}>こんにちは。</button>
<button class="btn btn-filled-surface" on:click={() => $text = ''}>リセット</button>

<style>
  input {
    width: 245px;
  }
  button {
    margin-top: 10px;
  }
</style>
```

コードがかなり減りそうです。
[Discord.js] DiscordBotにGPT-3を(API利用で)組み込む

# 動機

巷で話題のChatGPTで利用されているモデルについて、OpenAIのAPIから叩けることを知りました。
LINEでやり取りできるようにする記事を読んで自分でもなにかやってみたいなと思ったので、なずなさんおなじみのDiscordBotへ、機能追加の形で取り組むことにしました。

作業していたブランチとそのPRは以下です。
https://github.com/na2na-p/2na2-Discord/pull/157

# 準備

- OpenAIのAPI Key発行
割愛します。

# 作業

## Slash Commandの登録
```ts
const command: commandSetType = {
	name: 'gpt3',
	description: 'おしゃべりAIです。予告なく使えなくなる場合があります。',
	options: [
		{
			type: 3,
			name: 'prompt',
			description: 'AIに入力する文章です。',
			required: true,
		},
	],
};

// 別ファイルでcommandSetTypeを定義しています。下記のとおりです。
// export type commandSetType = Omit<ChatInputApplicationCommandData, 'name'> & {
//	name: Lowercase<string>;
// };
```

## Slash Command検知した際の処理
```ts
private async interactionHook(interaction: Readonly<ChatInputCommandInteraction>): Promise<boolean> {
	if (interaction.commandName === 'gpt３') {
        // 3秒以上かかるので必要
		interaction.deferReply();
		const prompt = interaction.options.getString('prompt', true);
        // fetchGpt3{prompt: string}を受け取って文字列を返す関数
		const completions = await fetchGpt3({ prompt });
		console.log(completions);
		interaction.editReply(completions);
		return true;
	} else {
		return false;
	}
}
```

## fetchする関数
```ts
import ENDPOINTS from '@/constants/ENDPOINTS.js';
// configはAPIキー等を持っています。
import { config } from '@/config/index.js';
import GPT3_MODELS from '@/constants/GPT3_MODELS.js';

// https://api.openai.com/v1/completions に飛ばします
const COMPLETION_ENDPOINT = `${ENDPOINTS.OPEN_AI}/completions`;

// 0~1
const TEMPERATURE = 0.9;
// 2048 or 4000
const MAX_TOKENS = 4000;

/**
 * @see https://beta.openai.com/docs/api-reference/completions/create
 */
async function fetchGpt3({ prompt }: {prompt: string}): Promise<string> {
	const options = {
		model: GPT3_MODELS.davinci,
		max_tokens: MAX_TOKENS,
		temperature: TEMPERATURE,
		prompt,
	};

	const response = await fetch(COMPLETION_ENDPOINT, {
		method: 'POST',
		headers: {
			'Content-Type': 'application/json',
			'Authorization': `Bearer ${config.openAiApiKey}`,
		},
		body: JSON.stringify(options),
	});

	const results = await response.json();
	try {
		// results.choicesの中からランダムに返す
        // エラー(tokensが長過ぎる等)の場合にresults.choicesは帰ってこないのでtry-catchしてます
		const randomIndex = Math.floor(Math.random() * results.choices.length);
		return results.choices[randomIndex].text;
	} catch (e) {
		return results.message;
	}
}

export default fetchGpt3;
```

# まとめ

かなーり雑ですが、フェッチする箇所だけ取り出して使いまわしが効くような書き方をしたつもりです。おもちゃとしての性能が非常に高く、作業時間は少しでしたが満足です。
AWS認定 DVA-C01に合格しました（2022/12/03）

## はじめに

2022/12/03にAWSのデベロッパー試験`AWS DVA-C01`に合格したので、使った教材や出題内容について書きます。
時期がちょうどだったので、ちゃっかりアドベントカレンダーにも便乗させてもらってます。


## 受験結果

ガッツリ勉強したのは2週間くらいでしたが、無事合格できました。
![スクリーンショット 2022-12-05 16.43.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119757/bf37de35-8301-0533-6d51-72ae47f49e74.png)


## 受験前の経験・知識など

* 新卒3年目のデータサイエンティスト
* 技術系の研修が無かったので、勉強も兼ねて個人で作りたいものを作っている
    * 例）[自分のためだけの新着お笑いライブ通知Botを作りました](https://qiita.com/oddgai/items/b37b98b6721c3a375fac)
* AWS系の業務経験はあまりない
    * 日常的にSQL（RedShift）とS3は使うが、管理者ではないので権限設定などはよくわからない
* 1年前に`SAA-C02`を取得したので、AWS全体のざっくりとした知識はある


## 使った教材

基本的には、**Tech Stockを解きつつ、不安な/間違った部分をポケットスタディで読む**という流れで勉強しました。

- [Tech Stock（AWS WEB問題集、旧小岩）](https://techstock.jp/)
    - 1周目の正解率は50~60%ほどで、間違った問題や不安な内容はポケットスタディで確認しながら取り組みました
    - 2周目は1周目で間違った問題を中心に取り組みました
    - 前日に受けた本試験モードでは930点（95%）でした

- [ポケットスタディ AWS認定デベロッパーアソシエイト](https://www.shuwasystem.co.jp/book/9784798063409.html)
    - 2021年3月に出たものなのでたまに古い情報もありますが、試験範囲がよくまとまってると思います
    - 「セキュリティ」「開発」などの章に分かれてサービス内容がまとまっていて、各章末に確認問題があります
    - 章末問題は実際の試験とやや乖離してる気はしますが、「本の内容がちゃんと頭に入ってるか？」を確認するには良い問題だと思います
    - 最後の章の本試験想定問題集は、体感ですが実際の試験に近い内容・難易度な気がします
    - 試験前日の夜に不安な部分を一通り読んで問題を解いて、「よし、大丈夫だな」と安心して眠れました

- AWS公式教材
    - [AWS Certified Developer - Associate Official Practice Question Set (DVA-C01 - Japanese)](https://explore.skillbuilder.aws/learn/course/12521/)
        - 20問の公式模試

- 参考までに）[コードで学ぶAWS入門](https://tomomano.github.io/learn-aws-by-coding/)
    - 東大の講義資料として使われている（いた？）教材で、AWSの主要なサービスを解説しつつ、EC2やサーバーレス（Lambda, DynamoDB, S3）に関するハンズオンができます
    - 試験対策というよりは興味本位で、本格的な勉強を始める前に一通り触りましたが、特にサーバーレスの部分はかなり試験に役立ちました


## 出題内容

ざっくり、以下のような出題でした。

* 30%：Tech Stockとほぼ同じ問題
* 70%：Tech Stockにはなかったが、Tech Stockやポケットスタディの内容を押さえておけば解ける問題

座学だけでも十分合格はできますが、実際にハンズオンなどをやるとイメージがついて解きやすくなると思います。実際、ハンズオンをしたサーバーレスに関する内容はあんまり座学で勉強せずに合格レベルに達せたと思います。


## 感想

SAAとMLSに続いて合格できてよかったです。次はSAPに挑戦しよう・・・
また、いくつか個人で作りたいアプリがあって、だいたいサーバーレスで済みそうなのがわかったのも収穫でした。
今はパルデア地方の探索で忙しいので、落ち着いたらちゃんとスケジュール立てて作ろうと思います。
[小ネタ] MySQLのAUTO_INCREMENTは勝手にテーブルのデータの最大値から始まる

## MySQL の AUTO_INCREMENT

突然ですが、**MySQLには他DBMSにあるシーケンスという種類のオブジェクトはありません。** [マニュアルを探しても本当にありません。](https://dev.mysql.com/doc/refman/8.0/ja/)

その代わりテーブルのカラムに `AUTO_INCREMENT` を指定してテーブル固有の勝手に増えるIDを実現することが可能です。下記が例です。

```sql
CREATE TABLE `hogehoge` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
);
```

```sql
INSERT INTO hogehoge VALUES ();
INSERT INTO hogehoge VALUES ();
INSERT INTO hogehoge VALUES ();

-- => 3
SELECT MAX(id) FROM hogehoge;
```

## AUTO_INCREMENTはコンフリクトするか？

ここで、本題ですが、前述の状態の `id = 3` まで進んだテーブルの定義（DDL）をバックアップすると下記のようなDDLを [`mysqldump`](https://dev.mysql.com/doc/refman/8.0/ja/mysqldump.html) 氏が作成してくれます。

```sql
CREATE TABLE `hogehoge` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=4;
```

`AUTO_INCREMENT=4` でシーケンスを初期値 `4` にしてくれているようですね。この状態で新規INSERTすると `4` からINSERTされます。

```sql
INSERT INTO hogehoge VALUES ();

-- => 4
SELECT MAX(id) FROM hogehoge;
```

ただ、システムバックアップあるあるですが、バックアップ取得の際に、1. 上記のバックアップDDL発行と 2. バックアップDML（INSERT文）の取得の発行のタイミングが異なると、上記の `AUTO_INCREMENT=4` に反して、下記のようなバックアップが取得されてしまいます。

```sql
INSERT INTO hogehoge VALUES (1);
INSERT INTO hogehoge VALUES (2);
INSERT INTO hogehoge VALUES (3);
INSERT INTO hogehoge VALUES (4); -- あっ……
INSERT INTO hogehoge VALUES (5); -- あっ！
```

どうやら、DDLからDMLのバックアップの隙間に新規データが2件挿入されたようですね。

「これってテーブル側のシーケンスが `=4` の状態なのに、次にINSERTでコンフリクトするじゃん！」

と思ってしまいますが、そこはMySQL、 **ちゃんとテーブルの最大値の次に大きい値を採番して勝手に回避してくれます**。

試しに大きな値(`100`)を挿入して

```sql
INSERT INTO hogehoge VALUES (100);

-- => 100
SELECT MAX(id) FROM hogehoge;
```

再び自動採番させてみれば `101` が来るので、MySQLが勝手にテーブルの最大値を参照してINSERTのコンフリクトを回避していることが分かります。

```sql
INSERT INTO hogehoge VALUES ();

-- => 101
SELECT MAX(id) FROM hogehoge;
```

## AUTO_INCREMENT は過去に戻るか？

逆に `100` `101` を消して再度、 `INSERT` するとどうなるのでしょうか？

```sql
DELETE FROM hogehoge WHERE id >= 100;

INSERT INTO hogehoge VALUES ();

-- => 102
SELECT MAX(id) FROM hogehoge;
```

**一度進んだシーケンスは戻りません。** まあ戻ったりしたら、DELETEしたデータを戻した際にコンフリクトするので妥当な仕様でしょう。


## まとめ

- `AUTO_INCREMENT` は勝手にテーブルのデータの最大値から始まり、コンフリクトしない
-  一度進んだシーケンスは戻らない
今話題のChatGPTにPythonデスクトップアプリ作らせてみた

## 1. はじめに

はいどうも、[myjlab advent calender 2022](https://qiita.com/advent-calendar/2022/myjlab) 6日目を担当する3年の [yoshiki495](https://github.com/yoshiki495) です。

5日目担当 [阿左見さん](https://qiita.com/ren_180) の [無料で使える！ render.comとは？](https://qiita.com/ren_180/items/d82b371783e638b6c3d7) をサンドイッチしての2日目になります。

過去にHeroku使って無料でデプロイしたアプリたちを思い出してとても悲しい気持ちです。

余談は置いておいて、

先日、OpenAIからChatGPTという名の対話型言語モデルが発表されましたね。

こんな感じで多くの著名人が話題に取り上げています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">chatGPTは雨描いて，って言って出てくるからプログラミング実習とかアレだわ． <a href="https://t.co/nSetPWe5PD">pic.twitter.com/nSetPWe5PD</a></p>&mdash; 落合陽一 Yoichi OCHIAI (@ochyai) <a href="https://twitter.com/ochyai/status/1599606597567016960?ref_src=twsrc%5Etfw">December 5, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

いやついにここまで来たかと感動しますね。

そんなわけで今回はこのChatGPTにPythonデスクトップアプリを作らせることができるか検証していこうと思います。

ではどうぞ。

## 2. 検証

### まずは作り方を聞いてみる

![スクリーンショット 2022-12-05 15.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2298551/21fa4ced-e2b7-2f7b-42a6-cf0eaee5c3c0.png)
良い感じですね。

箇条書きで補足もあってわかりやすい。

### 実際に作ってもらう

今回はtkinterとPyInstallerを使ってアプリケーションを作ってもらいたいと思います。
![スクリーンショット 2022-12-05 15.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2298551/c01106b0-4c5d-2340-7866-48d0c36d7714.png)

良い感じですね。

コメントもしてくれてありがたい。

### テスト

あとは言われた通りに作成するだけです。

するとPythonファイルと同じ階層のdistフォルダ内このようなアイコンが作成されます。

![スクリーンショット 2022-12-05 16.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2298551/2d7061aa-039a-3b5f-bcab-47a0bee1f109.png)

これをクリックすると、デスクトップにPythonプログラムに記述した通りのウィンドウが表示されます。

![スクリーンショット 2022-12-05 16.18.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2298551/a2ff0c67-fac3-3dfa-4031-806186cb491e.png)

正常系ですね。つまり結果は成功です。

### 補足

ちなみに自分はM1のMacを使っているのでpipコマンドを使用すると当たり前に `zsh: command not found: pip` というエラーが出力されます。

こういう場合、ChatGPTに聞いてみるとどうなるでしょうか。
![スクリーンショット 2022-12-05 16.36.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2298551/fc5b26ef-1328-ea33-39ac-c079dcbb0aa3.png)

とのことです。

あながち間違ってはないですが、

M1のMacを使うなら順当にpip3コマンドを使いましょうね。

## 3. おわりに

これにて検証一旦終了です。

結果は成功。

いやChatGPT凄いですね。

上手く使いこなせば開発が加速度的に進みそうです。

みなさんも是非。これにて。