OmniAICreator/Qiita-1.07M huggingface dataset:
ChatGPTがあればプログラミンを勉強する必要は無くなるのか？

ChatGPTを利用してスクリプトを生成する場合は次の2点に注意する
1. 生成されたスクリプトは必ずとも正しく動作しないため、必ずチェックする
1. 生成されたスクリプトは必ずとも効率的ではない。良いスクリプトを生成させるためには誘導させる必要がある

例：
次の質問をした。
```az cliを利用してImpactがHighかつCategoryがSecurityのAdvisor recommendationsのDescriptionとPotential benefitsの値を取得するスクリプトを作成してください。
```
結果として次のスクリプトが生成されました。
```# Advisor recommendationsの一覧を取得
az advisor recommendation list --category Security --impact High --query '[].{description:description, potentialBenefits:potentialBenefits}' -o json
```
このスクリプトを実行すると```az : ERROR: unrecognized arguments: --impact High```になります。これをChatGPTに問うと次のようなスクリプトが返されました。
```# Advisor recommendationsの一覧を取得
recommendations=$(az advisor recommendation list -o json)

# ImpactがHighかつCategoryがSecurityのレコメンデーションのDescriptionとPotential benefitsの値を抽出
filtered_recommendations=$(echo $recommendations | jq '.[] | select(.impact == "High" and .category == "Security") | {description: .description, potentialBenefits: .potentialBenefits}')

# 結果の表示
echo $filtered_recommendations
```
このスクリプトを実行してもエラーになります。またなぜかChatGPTはConvertFrom-Jsonではなく、jqを使う傾向があります。そのためにjqをインストールする必要があります。

最終的にはConvertFrom-Jsonを使うように指示した後にdescriptio及びpotentialBenefitsはないためshortDescriptionを使うように指示し、shortDescriptionはproblemとsolutionのハッシュのためにproblemの値だけを取得するように指示したらやっとのことで次のようなスクリプトが生成されました。

```# Advisor recommendationsの一覧を取得
$recommendations = az advisor recommendation list --output json | ConvertFrom-Json
#$recommendations
# ImpactがHighかつCategoryがSecurityのレコメンデーションのDescriptionとPotential benefitsの値を抽出
$filtered_recommendations = $recommendations | Where-Object { $_.impact -eq 'High' -and $_.category -eq 'Security' } | Select-Object -ExpandProperty shortDescription | Select-Object -ExpandProperty problem

# 結果の表示
$filtered_recommendations
```

このようにChatGPTでスクリプトを生成する場合は、何時も完璧なコードが生成されるのではなく、誘導する必要がある場合もあります。そのためにまだプログラミングの知識がある方が効率よくChatGPTを利用することができます。

以上
画像検索スライドショー (ChatGPT活用 Part1)

# はじめに
私は組込みエンジニアですが、最近はChatGPT等のGenerative AIのおかげでアイデアさえあればアプリを簡単に実装できる時代になっています。（エンジニアとしてはすごいと思う反面、何か悲しい気持ちもありますが…）ということでChatGPTを活用しながら全く知らない言語やライブラリで何か継続して作っていこう！という試みです。もう何番煎じかわからないし、水くらい薄いですが、BeautifulSoupを使って画像検索スライドショーを作ってみたので需要はないですが、自分のモチベ維持のために投稿します。
*Python, BeautifulSoupに関しては大昔に自力でも実装しているのですが、第一弾ということで…

# 成果物
![googleimage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2739556/1b881679-783e-be7c-bfca-150b8aaf755a.gif)


# コード
### バージョン
- python 3.10.9
```python
from bs4 import BeautifulSoup
import requests
import cv2
import time
import numpy as np

url = 'https://www.google.com/search?q='

# get user input
user_input = input("Enter a word you want to search: ")

# get image url
search_url = url + user_input + '&source=lnms&tbm=isch'
response = requests.get(search_url)
soup = BeautifulSoup(response.text, 'html.parser')
img_tags = soup.find_all('img')
urls = [img['src'] for img in img_tags]
del urls[0]

# display images 
for url in urls:
	img_response = requests.get(url)
	img_array = np.array(bytearray(img_response.content), dtype=np.uint8)
	img = cv2.imdecode(img_array, -1)
	cv2.namedWindow("slideshow", cv2.WINDOW_NORMAL)
	cv2.imshow("slideshow", img)
	cv2.waitKey(3000)
	time.sleep(1)
```

# 改良案
- 元画像ではなくリサイズ済み画像を参照しているので見られる画像が小さいし、荒い

# 参考文献
なし
Googleデータアナリティクス：データの限界

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f218c6bc-27a9-6aa7-4dfa-8e63bd3928b7.png" width="800">

# データの限界

データは強力ですが、限界もあります。

- 誰かの個人的な意見が数字に紛れ込んでいないでしょうか？
- あなたのデータはすべてを語れているでしょうか？

優れたデータアナリストになるためには、データの限界を知り、それに対して対策を練ることが必要です。

### <font color="MediumBlue">不完全 or 存在しないデータ</font>

データが不完全であったり、存在しなかったりして、分析中に結論を出すのに十分なデータがないと気づくかもしれません。あるいは、まったく的を得ない課題を解決しようとしている可能性さえあります。

- 例えば、ある資格を取得した従業員を探したいが、その会社では資格取得の記録が 2 年分しかないことが分かったとします。それでもデータを使用することはできますが、分析の限界を明らかにする必要があります。研修を実施した会社に問い合わせれば、別のデータソースを見つけることができるかもしれません。しかし、念のため、データが入手できるようになるまで、不完全なデータセットであることを明示しておく必要があります。

### <font color="MediumBlue">統一性のないデータに注意</font>

他のチームからデータを収集し、既存のスプレッドシートを使用する場合、人それぞれ異なる業務ルールを採用していることを念頭に置いておくとよいでしょう。そのため、あるチームと別のチームとでは、まったく異なる方法で物事を定義し、測定している可能性があります。

- 例えば、ある認定プログラムの受講者の総数を測定する際、あるチームはトレーニングに登録したすべての人をカウントし、別のチームはプログラムを修了した人のみをカウントしているというようなことがあり得ます。このような場合、早い段階で測定方法を決めておくことで、全体のデータが統一され、より信頼性と正確性が高まります。そうすることで、チーム間の分析結果の比較も意味のあるものになり、インサイトが得られるようになります。

### <font color="MediumBlue">「ダーティーデータ」に対処する</font>

ダーティデータとは、誤りを含むデータのことです。ダーティデータは、生産性の低下、無駄な出費、賢明でない意思決定につながる可能性があります。データクリーニングを適切に行うことで、このような事態を回避することができます。データクリーニングとは、データセット内の誤り、破損、不正確なフォーマット、重複、不完全なデータを修正または削除するプロセスです。エラーを発見して修正し、加えた変更を追跡すれば、データ関連のトラブルを回避することができます。

### <font color="MediumBlue">ストーリーを明白に伝える</font>

- **同じ種類のデータを比較する**: データを可視化するためにグラフ化する際、データを混同することがあります。同じ種類のデータを比較し、表内のセグメントがそれぞれ間違いなく異なる指標を表示していることを再確認してください。 
- **注意深く可視化する**: スコアの 0.01 ％の低下は、大きく拡大すると大きく見えることがあります。聞き手がストーリーを明確に把握できるように、Y 軸を 0 に設定するのがよいでしょう。
- **不要なグラフを省く**: 円グラフや棒グラフなどではなく、一目で理解できる表でストーリーを伝えることができるのであれば、表にこだわってみましょう。多忙な聞き手は、わかりやすさを重視します。
- **統計的有意性を検証する**: 時には、2 つのデータセットが異なるもののように見えることがあります。その際に、それらが本当に違うデータなのか、その違いによる影響の度合いはどれくらいなのかなどをテストする方法を理解していることが大切です。そのため、統計的検証をして、それらの違いにどれだけの信頼性を置けるかを確認することを常に心がけてください。
- **サンプルサイズに注意する:** データをたくさん集めましょう。サンプル数が少ないと、少数の異常な回答が結果を歪めてしまうことがあります。少ないデータを使ってなにかを判断するときには非常に慎重でなければなりません。できる限りより多くのデータを収集し、その傾向を長期にわたってグラフ化するよう努めてください。

### <font color="MediumBlue">適切に判断する</font>

どのような組織においても、データアナリストの役割の大きな部分を占めるのは、適切な判断を下すことです。データに裏付けられたより良い意思決定を行うためには、データの限界を知ることが大切です。データは意思決定のための非常に強力なツールですが、不完全であったり、ズレがあったり、クリーニングされていなかったりすると、誤解を招く可能性があるものもあります。必要な手順を踏み、データが完全で一貫性のあるものであることを確認しましょう。分析を始める前にデータをクリーニングすることで、自分自身や他の人の時間と労力を大幅に節約することができます。
Googleデータアナリティクス：仮説が実績ある成果へ

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f218c6bc-27a9-6aa7-4dfa-8e63bd3928b7.png" width="800">

# 仮説が実績ある成果へ

- ***<font color="MediumVioletRed">あるセグメントのユーザーが、 とあるコンテンツを好みそうだ。</font>***

という 仮説を立てます。 そして実際にこの仮説を データでも確認できたら、 その仮説が 本当に正しいかどうかを テストで検証していきます。 

例えば、このセグメントのユーザーに とある内容のコンテンツを送る というテストを行い、 実際にそのコンテンツが レスポンス率が高いのか、 そうではないのかを、 テスト環境を管理しながら 検証していきます。 

その仮説を実際に検証することができたら、 ステークホルダー、 この場合はマーケティング担当者に、 

 - ***<font color="MediumVioletRed">この特定のセグメントは、 このタイプのコンテンツに反応しやすいことが 比較的高い確率で証明されたので、 もっとこのようなタイプのコンテンツを 制作するようおすすめします。</font>***
 
と伝えるのです。 

こうして私たちのステークホルダーは、 仮説が実績ある成果へと 証明されたことを確認できます。 仮説を実証し、 最終的にビジネスのための 戦略や提案に変えていく過程においても 一緒に考えることができるのです。 

この事例では、 マーケティングチーム全体の働き方を変え、 よりユーザーを中心とした働き方が できるようになったことが成果でした。 私たちの視点から ユーザーに必要だと予想して コンテンツを考えるのではなく、 実際には逆の方向から まずユーザーのニーズを把握し、 彼らが特定のものを必要としている、 あるいは必要としていないことを証明し、 その情報をマーケティング担当者に フィードバックし、 ユーザーのニーズを満たす コンテンツを考え出す、という進め方が重要です。

# サラ：ステークホルダーとのコミュニケーションの取り方

皆さんに伝えておきたいのは、データにストーリーを語らせるように すべきだということです。 データですべてがわかると 思っている人がいますが、 それは間違いであることを 認識する必要があります。

私は最近、ある州と協力して、 住民が必要かつ受けるべき給付金制度に 加入していない理由を調べました。 あるサイトに訪れ、 受給資格を満たしているかどうかを確認し 受給を申し込むのが手順です。 しかし、何らかの理由により 実際に申し込むというステップを 完了していない人がいたのです。 そこで私は、 Google アナリティクスを利用して 住民が必要とする制度に 申し込めずにいる原因を 突き止めました。 Google アナリティクスによると サイトを訪れた人々は給付金ページと 失業者向けページを行き来しては 失業者ページに戻っていることがわかりました。 

そこで私は、住民がサービスを 受ける資格があるかどうか確認するという 次のステップに進むのに必要な情報を 見つけられていないのでは、と考えました。 なぜ、サイトを訪れた人が 申し込みを完了できなかったのか、 それを知るには その人に聞いてみるしかありません。 アンケートを取るしかないのです。 Google アナリティクスだけでは、 私の仮説を 100 ％裏付ける、あるいは 否定するのに 必要なデータを得られませんでした。 ですから、 ステークホルダーに説明をするときは、 

- ***<font color="MediumVioletRed">私は仮説を立てました。 データはあるストーリーを 語ってくれてはいますが、 それだけでは限界があり、 100 ％であるとは言えません。</font>***

と伝えなくてはなりませんが、 私は、

- ***<font color="MediumVioletRed">サイトを訪れた人は、 給付金の申し込みに必要な情報を 見つけられていないのではないか、 という仮説を立てました。 それを裏付ける証拠はこれです。</font>***

という言い方で伝えます。 そして私たちは情報を見つけやすくしました。 自分の理論が 100 ％ 正しいとは思っていなくても、 行動を起こすには十分な自信が ありましたし、振り返ってみると、 この理論につながるすべての測定基準が 改善されていることがわかりました。
子育ての専門家「ChatGPT」が小学生プログラミング学習のデメリットを教えてくれた

# この記事を読んでほしい人

- 自分の子供にプログラミングを学習させるか悩んでいる人
- 小学校のプログラミング授業に不安を抱いている人
- プログラミング学習のデメリットを知りたい教育現場で働く

# ChatGPTへの質問
良いプロンプトエンジニアリングに従って、以下を与えることがとても重要です。
- 役割（あなたは～～です。）
- 制限（箇条書きで・・・）
- 前提（～～を教えてください。）


```
あなたは子育ての専門家です。小学生の子供にプログラミングを学習させることのデメリットを箇条書きで教えてください。
```
こんな風にChatGPTに質問したら、次のデメリットを教えてくれました。


# 教えてくれたデメリット
1. プログラミング学習に必要な機材や環境が高額であることがある
1. 小学生の低学年では、プログラミングを理解するための認知的なスキルが未発達であることがある
1. プログラミング学習による学力低下の可能性がある
1. プログラミングに対する興味が持続しないことがある
1. 難易度の高いプログラムに取り組むと、挫折感が生じることがある
1. 無限に続くデジタルデバイスの使用による問題がある
1. プログラミング以外のスキルや知識を犠牲にする可能性がある

# デメリットを具体化

それぞれのデメリットは、わかりそうでわからないものもある。
詳しく知りたいので、ChatGPTに追加で質問しましょう。

## その１：プログラミング学習に必要な機材や環境が高額

### 質問
```
「プログラミング学習に必要な機材や環境が高額」というデメリットの具体例を教えてください。
```

### 回答
- 専用のプログラミング教材やテキストブックが必要な場合
プログラミング言語ごとに、入門書や解説書、参考書などの書籍が複数あることがあり、それらを全て揃えると費用が高額になることがある。
オンラインコースやビデオチュートリアルを使用する場合、有料の教材が多数存在し、それらを全て購入すると費用が高額になることがある。
- 専用のプログラミング環境が必要な場合
購入する機材が高額になる場合がある。例えば、ArduinoやRaspberry Piといったマイコンボードは、周辺機器を揃えると高額になることがある。
クラウドベースのプログラミング環境を使用する場合、利用料金が必要になることがある。例えば、AWS Cloud9やMicrosoft Azure上での開発環境の利用料金は、使用量に応じて課金される。
- ハイスペックなパソコンが必要な場合
高性能のプロセッサーやグラフィックスカードが必要であるため、PCの価格が高額になる。
また、プログラミングに必要なソフトウェアやツールが高価である場合がある。
- インターネット接続が必要な場合
プログラミング学習において、インターネット接続が必要な場合が多い。しかし、高速なインターネット接続が必要な場合もあり、そのための高額な通信費が必要になることがある。

## その２：プログラミングを理解するための認知的なスキルが未発達

### 質問
```
「プログラミングを理解するための認知的なスキルが未発達」というデメリットの具体例を教えてください。
```

### 回答
- 抽象的な概念を理解するための能力が未発達であるため、変数やループといった概念を理解するのが難しい
- 論理的思考能力が未熟であるため、if文や条件分岐といった概念を理解するのが難しい
- 記号や文字列に対する理解が浅いため、コードの文法や意味を正確に理解することが難しい


## その３：プログラミング学習による学力低下の可能性

### 質問
```
「プログラミング学習による学力低下の可能性」というデメリットの具体例を教えてください。
```

### 回答
- プログラミング学習に必要な時間が他の学習時間を圧迫し、授業や宿題の時間が削られてしまう
- プログラミングの学習に専念しすぎて、算数や国語などの基礎的な学力が疎かになる可能性がある
- プログラミング言語やコンピュータの専門用語が多数出てくるため、理解できない単語が出てくると学習意欲が低下する可能性がある


## その４：プログラミングに対する興味が持続しない

### 質問
```
「プログラミングに対する興味が持続しない」というデメリットの具体例を教えてください。
```

### 回答
- 初めは興味を持っていたが、難しくて挫折してしまった場合
- 初めは楽しんでいたが、他の趣味や興味ができてプログラミングに割く時間が減った場合
- 学校や習い事で継続的に取り組まなければならない場合に、自分で興味を持って続けることが難しい場合


## その５：難易度の高いプログラムに取り組むと、挫折感が生じることがある

### 質問
```
「難易度の高いプログラムに取り組むと、挫折感が生じることがある」というデメリットの具体例を教えてください。
```

### 回答
- プログラミングには論理的思考力が必要であるため、低学年の子供にとっては理解が難しい場合がある
- 難易度の高いプログラムを与えられた場合、子供たちは失敗することが多く、うまくいかないという経験を積むことになる
- 挫折感が生じると、プログラミングに対する興味を失ってしまう可能性があるため、教材の選定が重要である。


## その６：無限に続くデジタルデバイスの使用による問題

### 質問
```
「無限に続くデジタルデバイスの使用による問題」というデメリットの具体例を教えてください。
```

### 回答
- 健康問題
    - 長時間の画面時間による眼精疲労や視力低下
    - 姿勢の悪化や筋肉の弱化による姿勢の悪化や肩こり、腰痛
    - 睡眠不足による体調不良や生産性の低下
- 社会的問題
    - 関心の欠如や社交能力の低下による孤立感や社会的なつながりの欠如
    - ネット上での危険（いじめ、ストーカー、詐欺など）にさらされる可能性がある
    - 非デジタルな活動や娯楽からの過剰な距離を置くことがあり、それによって生活の多様性が減少する可能性がある

## その７：プログラミング以外のスキルや知識を犠牲にする可能性

### 質問
```
「プログラミング以外のスキルや知識を犠牲にする可能性」というデメリットの具体例を教えてください。
```

### 回答
- プログラミング学習に時間を割くことで、他の学習やスポーツ・趣味などの活動に割ける時間が減る可能性がある
- プログラミングが重要視されるようになり、他のスキルや知識を犠牲にしてでもプログラミングに注力する場合がある
- プログラミングに熱中しすぎることで、社会性やコミュニケーションスキルが育たない場合がある

# 感想（一個人の考え）

どのデメリットも一般的に言われている内容だった。
ChatGPTは、ネットに拡散している情報を集めるのは得意だなと改めて気づくことができた。
当たり前だが、全く新しいことをChatGPTから教えてもらうのは難しい。
それを考えることができる人が、これからの時代で求められる人材になるのかな。

---
最後まで読んでいただきありがとうございました。
ご意見などあればコメントよろしくお願いいたします。
単一責任原則

# 単一責任原則

単一責任原則（Single Responsibility Principle）とは、プログラムの設計原則の一つで、一つのクラスやモジュールは、一つの責務（役割、機能）だけを持つべきであるという考え方です。

具体的には、あるクラスやモジュールが複数の責務を持っていると、変更が発生した際にその影響が複数の場所に及び、保守性や拡張性が低下する可能性があります。それに対して、一つの責務にのみ注力することで、変更が必要になった場合にはその影響範囲が限定され、保守性や拡張性が向上するという効果が期待できます。

例えば、ファイルの読み書きやデータベースの操作など、異なる責務を持つ処理を一つのクラスで実装するのではなく、それぞれ別々のクラスに分けて実装することが望ましいとされています。

また、単一責任原則は、コードの可読性や再利用性にも影響を与えます。一つのクラスに複数の責務を持たせてしまうと、そのクラスがどのような機能を持っているのか把握するのが難しくなり、コードの可読性が低下することがあります。また、単一責任原則に従ってクラスやモジュールを設計することで、再利用性が高くなるという利点もあります。一つの責務に注力することで、その機能を必要とする場面があれば再利用することができます。

しかし、単一責任原則を適用しすぎることも問題です。一つのクラスに必要な機能をすべて分離してしまうと、クラス間の依存関係が複雑になり、コードの理解や保守が困難になることがあります。適度な分割が求められます。

単一責任原則は、オブジェクト指向プログラミングにおける重要な設計原則の一つであり、ソフトウェアの品質や保守性を向上させるために重要な考え方となっています。

単一責任原則は、オブジェクト指向プログラミングにおいて非常に重要な原則であり、クラスやメソッドの設計において常に考慮すべき原則の一つです。

## 単一責任原則を遵守することのメリット

1. コードの保守性が向上する
1. コードの再利用性が向上する
1. バグの発生率が低下する
1. テストの設計が容易になる
1. リファクタリングが容易になる
一方、単一責任原則を違反すると、以下のようなデメリットがあります。

1. コードの複雑度が増加する
1. コードの保守性が低下する
1. バグの発生率が高くなる
1. 再利用性が低下する

以上のように、単一責任原則はオブジェクト指向プログラミングにおいて非常に重要な原則であり、開発者が常に意識してコードを設計する必要があります。

## 単一責任原則を適用方法
単一責任原則を適用するためには、以下のような手順が考えられます。

1. 責務を明確に定義する
まず、クラスやモジュールにどのような責務があるのかを明確に定義する必要があります。あいまいな責務定義では、単一責任原則を適用することが難しくなります。
2. 責務ごとにクラスやモジュールを分割する
明確な責務定義ができたら、それぞれの責務に合わせてクラスやモジュールを分割します。各クラスやモジュールは、一つの責務のみを持つように設計する必要があります。
3. クラスやモジュールの粒度を調整する
クラスやモジュールを分割した場合、それぞれの粒度が適切であるかを確認する必要があります。一つの責務に注力することは重要ですが、粒度が細かすぎるとコードの保守性が低下する場合があります。
4. 依存関係を整理する
複数のクラスやモジュールが互いに依存している場合、それぞれの責務に合わせて依存関係を整理する必要があります。依存関係が複雑になりすぎると、コードの保守性や拡張性が低下することがあります。
5. 単一責任原則に適合しているかを確認する
最後に、設計したクラスやモジュールが単一責任原則に適合しているかを確認する必要があります。各クラスやモジュールが一つの責務のみを持つように設計されているか、依存関係が適切に整理されているかを確認します。

以上のように、単一責任原則を適用することで、コードの保守性や拡張性が向上し、品質の高いソフトウェアを開発することができます。


具体例を挙げて説明すると、例えば以下のようなクラスがあった場合、単一責任原則に適合していないと言えます。

```php
class User {
  public function save() {
    // データベースにユーザー情報を保存する処理
  }

  public function sendEmail() {
    // ユーザーにメールを送信する処理
  }

  public function generateToken() {
    // ユーザーのトークンを生成する処理
  }
}

```

このクラスは、データベースに保存する処理、メールを送信する処理、トークンを生成する処理の3つの責務を持っています。これらの責務は独立しており、クラスを分割することでコードの保守性や再利用性を向上させることができます。

例えば、以下のようにクラスを分割することができます。

```php
class User {
  public function save() {
    // データベースにユーザー情報を保存する処理
  }

  public function generateToken() {
    // ユーザーのトークンを生成する処理
  }
}

class EmailService {
  public function sendEmail($to, $subject, $body) {
    // ユーザーにメールを送信する処理
  }
}

```

このように分割することで、各クラスが一つの責務のみを持つようになり、コードの保守性や再利用性が向上します。

また、単一責任原則は、テスト駆動開発やリファクタリングなどのプログラミング手法とも密接に関連しています。単一責任原則に適合するようにコードを設計することで、テスト駆動開発においてテストの設計やリファクタリングにおいてコードの改善を容易にすることができます。
ChatGPTボットは無料fly.ioで動く

ChatGPTいわく、「fly.io は、開発者が簡単にグローバルに展開できるコンテナベースのアプリケーションプラットフォームです。」だそうです。

Slackボットをwsl2で動かしていたけど、ノートPCを持ち運ぶたびにボットが死んでしまうのはいかがなものかということでfly.ioにデプロイしました。こんな設定ファイルを書いて fly deploy をするとボットが死ぬことなく動き出します。ボット２匹分の２プロセスが動いています。仮想PC１台なら無料で使えます。

```toml:fly.toml
# fly.toml file generated for rusk-slack-bot on 2023-04-08T11:10:55-07:00

app = "rusk-slack-bot"
kill_signal = "SIGINT"
kill_timeout = 5
primary_region = "sjc"

[build]
  builder = "paketobuildpacks/builder:full"

[env]
  PORT = "8080"

[processes]
  holo_bot = "env SLACK_SIGNING_SECRET=$HOLO_SLACK_SIGNING_SECRET SLACK_BOT_TOKEN=$HOLO_SLACK_BOT_TOKEN SLACK_APP_TOKEN=$HOLO_SLACK_APP_TOKEN python run.py --config config_holo.yaml"
  rusk_bot = "env SLACK_SIGNING_SECRET=$RUSK_SLACK_SIGNING_SECRET SLACK_BOT_TOKEN=$RUSK_SLACK_BOT_TOKEN SLACK_APP_TOKEN=$RUSK_SLACK_APP_TOKEN python run.py --config config_rusk.yaml"
```

問題なく動いているようです。にゃんにゃん

![2023-04-08_15h12_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/04686b9f-10bd-2920-f52b-49917732349f.png)
JSONUIの心得1【統合版マイクラ】

`2023/04/12更新`
# マインクラフトのJSON UIとは？

MinecraftのJSONUIは、ゲーム内のUI（ユーザーインターフェース）を定義するための強力なツールです。この機能を使用すると、ゲーム内にテキスト、画像、ボタンなどの要素を表示することができます。

JSONUIは、Minecraftのリソースパック内にJSONファイルを配置することで定義されます。これらのファイルには、UI要素のレイアウト、テキスト、画像、アニメーション、音声などの詳細が含まれます。

JSONUIを使用すると、プレイヤーに対して追加の情報を提供したり、特定の機能を実行するためのインタラクティブなユーザーインターフェースを作成したりすることができます。例えば、カスタムマップやMODには、JSONUIを使用して新しいUI要素を追加することができます。

MinecraftのメインメニューもJSONUIを使用して定義されています。このメニューは、プレイヤーに対してさまざまなオプションを提供しています。

JSONUIは、MinecraftのModdingコミュニティで広く使用されており、非常に柔軟で強力なツールです。MinecraftのUIを拡張したり、カスタマイズしたりする場合には、JSONUIを使用することが非常に役立ちます。

JSONUIを使用することで、MinecraftのUIに新しい要素を追加したり、カスタマイズすることができます。プレイヤーにとってより良いゲーム体験を提供するために、JSONUIを活用してみてはいかがでしょうか。

# この記事を書こうと思った理由

統合版マインクラフトのリソースパックを弄っているときにふと他の人のワールドでゲーム内のUIが特徴的になっていることを思い出し、試しに自分もいじってみようとするとここに苦戦した。
JSON方式で記述するUIはXML型に似ているけれど複雑になっていて読みづらい。
また、親要素などの結びつきや**条件指定**での表示もあるため、それもまとめておこうと思う。

## まずは元になるファイルを用意する

こちらから統合版マイクラのバニラリソースパックがダウンロードできます。 

https://github.com/Mojang/bedrock-samples/releases

UIのファイルの位置は、``resource_pack\ui\``にあります。

## 今回は分かりやすいように ``hud_screen.json``を弄っていきます。
これは通常のプレイ画面です。
とりあえず文字を表示するlabelを追加してみましょう。
一番下の方にcamera_rendererという項目があるので、その隣に`Infobar@hud.Infobar`を追加しましょう。
前のInfobarは名前で、後ろのInfobarはidです。統一しておいた方がわかりやすいので統一しましょう。
~~~diff_jsonui:json
      {
        "camera_renderer@camera_renderer": {}
      },
      {
        "Infobar@hud.Infobar": {}
      }
~~~
この項目はゲーム画面に表示する要素の中でも*その他*に分類するものを追加する場所っぽいです。
cameraとか普通使わないですから。
それでは一番下の`}`を改行して中に実際の要素の中身を書いていきましょう。
あんまり難しいことをごちゃごちゃ書くよりコードを貼ってそれについて詳しく解説するほうがいいと思うので貼ります。
~~~diff_json:json
  "Infobar": {
    "type": "panel",
    "size": [ "100% - 10px", "100%-30px" ],
    "controls": [
      {
        "InfobarBG": {
          "type": "image",
          "anchor_to": "top_right",
          "anchor_from": "top_right",
          "size": [ "100%c + 12px", "100%c + 12px"],
          "color": [0.1,0.1,0.1],
          "texture": "textures/ui/menubackground",
          "layer": -1,
          "controls": [
            {
              "titlepanel": {
              "type": "label",
              "size": [ "default", "default" ],
              "text": "    §lサーバー情報§r\n§4鯖主§r\n   ADMIN\n§4副鯖主§r\n   Null\n\n§6モデレーター§r\n   Null",
              "color": [1,1,1],
              "font_scale_factor": 1.2,
              "shadow": false,
              "layer": 3
              }
            }
          ]
        }
      }
    ]
  }
~~~
#### `"type":"panel"`
要素の種類のこと このコードの場合、画像と文字列を大きさをそろえて一緒に表示したいため、親要素はpanelで、そこにimageやlabelを貼っていく
#### `"size": [ "100% - 10px", "100%-30px" ]`
その名の通り要素のサイズを意味します。(width,height)
サイズの書き方は色々あるみたいです。
```
int,fill,default,%c,%y,px,%cm,%sm,+,-
```
%やpxだけでなく演算子記号も使えるので機種が変わっても上手く表示されるように細かく指定できそうですね。
#### `"controls": []`
この中に**子要素**を追加していきます。
ラベルや画像、ボタンも追加できます。
qiitaに載せる画像の大きさを変えたい時

## はじめに
Qiitaに画像を載せる際、大きくなりすぎるので、変更方法を載せておきます。

## 画像アイコンから画像を選択したときのリンク（元のリンク）
```
![スクリーンショット 2023-04-09 7.00.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/6762a459-dffa-b3d5-3bf0-7011e1213494.png)
```
![スクリーンショット 2023-04-09 7.00.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/6762a459-dffa-b3d5-3bf0-7011e1213494.png)

## 変更後のリンク
```
<img width="400" alt="スクリーンショット 2023-04-09 7.00.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/6762a459-dffa-b3d5-3bf0-7011e1213494.png">
```
<img width="400" alt="スクリーンショット 2023-04-09 7.00.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/6762a459-dffa-b3d5-3bf0-7011e1213494.png">

## 参考
https://qiita.com/x5dwimpejx/items/9a0322d392a59896a39f
Error (Xcode): Linker command failed with exit code 1 (use -v to see invocation)

# はじめに
iphone14へビルド時に、以下のようなエラーが出たので共有します。

# エラー内容
<font color="red">

Error (Xcode): File not found:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/l
ib/arc/libarclite_iphonesimulator.a


Error (Xcode): Linker command failed with exit code 1 (use -v to see invocation)


Could not build the application for the simulator.
Error launching application on iPhone 14 Pro.
</font>

# 解決法
podfileのpost_install do |installer句に以下を追記。（37行目辺り）

```podfile:Podfile
post_install do |installer|
  # ここから
    installer.generated_projects.each do |project|
    project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
      end
   end
  end
  # ここまで
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end
```

# 参考
https://zenn.dev/ischca/articles/a00c3adf626ea0
シェルスクリプト（ファイルに値を追記）

# はじめに
指定したファイル(file_name)が存在する場合、入力値（input_val）を追加していくシェルスクリプトになります。

# 実装
```sh.sample.sh
# ディレクトリのファイル一覧を表示
ls

# 2回値を標準入力で受け付けて、変数に設定する。
read -p "ファイル名を入力してください：" file_name
read -p "ファイルに追記する値を入力してください：" input_val

# file_nameのファイルが存在する場合は、input_valの値を追記する
if [ -f $file_name ];
then
  # echoの後はセミコロンが必要
  echo $input_val >> $file_name;
else
  echo "ファイルが存在しません"
fi
```

# 参考
https://www.udemy.com/course/linuxlpic
Ruby+WebAssemblyでお絵描き

# はじめに
Ruby 3.2がリリースされてWebAssembly/WASIに対応しましたが、折角ブラウザでRubyが動くようになったのにHello, world!だけじゃ勿体ないので、もう一歩踏み込んでお絵描きをしてみます。


# 図形の描画
最初にJavascriptで書いてみます。HTML5のCanvasを用意してそこに簡単な図形を描画するコードです。
``` html
<html>
<canvas id="canvas"></canvas>
<script>
  var c=document.getElementById("canvas");
  var ctx=c.getContext("2d");

  ctx.fillStyle = "Orange";
  ctx.fillRect(25, 25, 50, 50);

  ctx.strokeStyle = "Red";
  ctx.lineWidth = 10;
  ctx.strokeRect(100, 25, 50, 50);
</script>
</html>
```

これをRubyに移植すると
``` html
<html>
  <script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@0.5.0/dist/browser.script.iife.js"></script>
  <canvas id="canvas"></canvas>
  <script type="text/ruby">
    require "js"
    Document = JS.global[:document]
    canvas = Document.getElementById("canvas")
    ctx = canvas.getContext("2d")

    ctx[:fillStyle] = "Orange"
    ctx.fillRect(25, 25, 50, 50)

    ctx[:strokeStyle] = "Red"
    ctx[:lineWidth] = 10
    ctx.strokeRect(100, 25, 50, 50)
  </script>
</html>
```
こんな感じです。
ctx[:fillStyle] という書き方が若干気になるのですが、Javascriptプロパティはこういう風に読み書きするようです。

![localhost_8000_mandelbrot.html - 個人 - Microsoft​ Edge 2023_04_09 4_53_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72890/2c956d8d-7b3d-8cf2-4bee-a32f87cc0be9.png)

Rubyでブラウザに描画できました。


# マンデルブロ集合を描いてみる
インターフェースさえ分かればあとは応用でなんでも描画できるはずということでマンデルブロ集合を描いてみます。マンデルブロのコードはAI(ChatGPT)に書いてもらいました（……が微妙に間違っていたので手直し）。

``` html
<html>
  <script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@0.5.0/dist/browser.script.iife.js"></script>
  <canvas id="canvas"></canvas>
  <script type="text/ruby">
    require "js"
    Document = JS.global[:document]
    canvas = Document.getElementById("canvas")
    ctx = canvas.getContext("2d")

    MAX_ITERATIONS = 100
    canvas[:width] = WIDTH = 512
    canvas[:height] = HEIGHT = 512

    def mandelbrot(z, c)
      MAX_ITERATIONS.times do |i|
        z = z * z + c
        return i if z.magnitude > 2.0
      end
      return MAX_ITERATIONS
    end

    xmin, xmax = -2.0, 1.0
    ymin, ymax = -1.5, 1.5

    colors = MAX_ITERATIONS.times.map do |i|
      r = (i * 3) % 256
      g = (i * 7) % 256
      b = (i * 11) % 256
      "rgb(#{r}, #{g}, #{b})"
    end
    colors << "black"
    
    HEIGHT.times do |j|
      WIDTH.times do |i|
        x = xmin + (xmax - xmin) * i.to_f / WIDTH
        y = ymin + (ymax - ymin) * j.to_f / HEIGHT
        c = Complex(x, y)
        n = mandelbrot(0, c)
        ctx[:fillStyle] = colors[n]
        ctx.fillRect(i, j, 1, 1)
      end
    end
  </script>
</html>
```

![localhost_8000_mandelbrot.html - 個人 - Microsoft​ Edge 2023_04_09 4_55_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72890/fe4a1ced-e6da-03b9-1a1c-9a15d49a14f7.png)

AMD Ryzen 7 PRO 6850U で表示されるまで数十秒かかりました。重たい人は画像サイズを小さくすれば早く表示されます。


拡大して表示
min, xmax = -0.6, -0.5
ymin, ymax = -0.7, -0.6
![localhost_8000_mandelbrot.html - 個人 - Microsoft​ Edge 2023_04_09 4_53_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72890/e169a47b-7dc9-b2a2-5e92-1a28a7b08728.png)

マンデルブロは無限に観ていられます。

# 感想
Rubyはグラフィック系が弱かったので、環境に依存せずに描けるようになったのは大きいです。
JavaScriptのジャンプ文

JSにはジャンプ文と呼ばれる文がある。ジャンプ文の種類と使い方についてメモ。

#### ラベル文
先頭に識別子、その後ろにコロン（：）、最後に文を記述して、任意のラベル文をつける。ラベル文を使うのはbreak文とcontinue文のみ。
```js
mainloop:while(token !=null){
  // 複数行のコード
  continue mainloop; // 名前を付けたループ文の次のループを開始する。
  // 複数行のコード
}
```
#### break文
breakb文が実行されると、最も内側のループまたはswitch文が直ちに終了する。break文はループ文やswitch文の中で使えて、何らかの理由でループの処理を止めたい時にbreak文を使用する。
```js
for (let i = 0; i < a.length; i++) {
  if (a[i] === target) break;
  // 複数行のコード
}
```
#### continue文
break文とよく似ている。break文は処理を終了するが、continue文は次の繰り返しからループを再開させる。
```js
for (let i = 0; i < data.length; i++) {
  if (!data[i) continue; // 未定義の値は処理しない
  total += data[i];
}
```
#### return文
関数の呼び出しの値を指定する。関数本体の中でのみ使える。
```js
square(2); // 4
function square(x) {
  return x * x;
}
```
#### yield文
return文と似ていて、ジェネえーター関数の中でのみ使用できる。値を生成し、生成さえた値並びにこの値を追加する。呼び出し元には戻らない。
```js
// ある範囲の整数群を生成するジェネレータ関数
function* range(from, to) {
  for (let i = from; i <= to; i++) {
    yield i;
  }
}
```
#### 勉強した本
https://www.amazon.co.jp/JavaScript-%E7%AC%AC7%E7%89%88-David-Flanagan/dp/4873119707
特定のWEBサイトで秘密コマンドを実行する

## 最近twitterが秘密コマンド実装してたので、自分のサイトにも組み込んでみるか！！！
#### 次のスクリプトをWEBサイトに組み込むと[↑↑↓↓←→←→ba]で"redirectToDbSetting()"が実行されます

``` javascript
let sequence = "";
const targetSequence = "38384040373937396665";

document.addEventListener("keydown", function(event) {
  sequence += event.keyCode;
  if (sequence.endsWith(targetSequence)) {
    sequence = "";
    redirectToDbSetting();
  }
});

function redirectToDbSetting() {
  console.log(`入力が確認されました。`);
  //秘密のアクションを実行する
}
```
2023/4/9主にITとかセキュリティの記事

フィッシングで悪用されるブランドが過去最多タイ - URLも増加傾向
https://www.security-next.com/145148

職員のマイナンバー持出で釜石市に行政指導 - 個情委
https://www.security-next.com/145187

「サイバーセキュリティ経営ガイドライン」、約5年ぶりに改訂
https://www.security-next.com/145215

豊田市のBCC強制システムが停止、メアド流出 - 委託先がライセンス更新を失念
https://www.security-next.com/145197

不正アクセスや不正行為で教員を懲戒処分 - 北九州市立大
https://www.security-next.com/143861

昇進試験のファイルを不正取得した職員などを懲戒処分 - 名古屋市
https://www.security-next.com/144980

Rapid7の脆弱性管理製品に脆弱性 - 管理者ページにアクセスされるおそれ
https://www.security-next.com/145179

身に覚えのない注文確認で不安を煽る「Uber Eats」のフィッシング
https://www.security-next.com/145211

「RSA NetWitness Platform」のWindowsエージェントに脆弱性 - PoCが公開
https://www.security-next.com/145181

経産省による“産業分野”のサイバーセキュリティ政策──対策急務の「OSS」「SBOM」への動きとは(4/7)
https://enterprisezine.jp/article/detail/17562

地方自治体がサイバー攻撃に苦戦していると報告＝米ＫｎｏｗＢｅ４〔ＢＷ〕(4/7)
https://www.risktaisaku.com/articles/-/78254

北朝鮮が支援する攻撃者からユーザーを保護するためにグーグルがしていること(4/6)
https://ascii.jp/elem/000/004/131/4131800/?rss

民主主義の衰退が生むグレーゾーンビジネス(4/7)
https://www.newsweekjapan.jp/ichida/2023/04/post-44.php

全PCが乗っ取られる？『体験型』サイバーセキュリティ研修を実施(4/7)
https://officenomikata.jp/news/15165/

国土数値情報データ変換ツールに XML 外部実体参照（XXE）に関する脆弱性(4/7)
https://scan.netsecurity.ne.jp/article/2023/04/07/49178.html

ビジネスリスクを防ぐためのセキュリティベンダーとの付き合い方(4/7)
https://japan.zdnet.com/article/35202105/

自宅に捜査員が…家のルーターが知らぬ間にサイバー攻撃発信元に(4/7)
https://news.yahoo.co.jp/articles/f3bebc1274a97ddbdf83a04cd4aa54f60d5b72af

オンライン診療指針を改訂！「得られる情報が少ない」点を強調するとともに、過重なセキュリティ対策規定を見直し！―厚労省(4/7)
https://gemmed.ghc-j.com/?p=53546

AOSデータ社、AIのディープフェイクフォレンジック™ サービスの取り組みを開始
〜生成されたAIの偽の映像や音声などのフェイクデータを調査〜(4/7)
https://prtimes.jp/main/html/rd/p/000000235.000040956.html

「TikTok禁止」だけじゃ収束不可能!?　中華アプリ"アメリカ大侵食"の実態とは？(4/7)
https://news.yahoo.co.jp/articles/2546e7cdf2e80f79e7d32e334a419f4ba25e5231?source=rss

EMV 3-DS導入が義務化される2025年に向けた 国際決済ネットワークブランド、イシュア、 加盟店それぞれの視点と、共創の取り組み（上）(4/7)
https://paymentnavi.com/paymentnews/129398.html

サイバー攻撃者のカモにされる「Microsoft 365」のセキュリティ支援まとめ(4/5)
https://kn.itmedia.co.jp/kn/articles/2304/05/news057.html

米政府、iPhoneおよびiPadユーザーに対し、速やかなソフトウェア更新を警告(4/7)
https://www.epochtimes.jp/2023/04/143874.html

チェック・ポイント、3CXデスクトップアプリがトロイの木馬化され、悪用されるサプライチェーン攻撃を報告
チェック・ポイントはお客様への保護と安全性を引き続き確保(4/7)
https://prtimes.jp/main/html/rd/p/000000194.000021207.html

Microsoft、OneNoteのセキュリティを強化すると発表(4/7)
https://news.mynavi.jp/techplus/article/20230407-2645819/

「関税等お支払いサイト（F-REGI 公金支払い）」を装うフィッシング、件名「関税・【差押最終通知】未払い税金お支払いのお願い」などの不審なメールに注意(4/7)
https://internet.watch.impress.co.jp/docs/news/1491716.html

国土交通行政インターネットモニター制度にかかる個人情報の漏洩について(4/7)
https://www.mlit.go.jp/report/press/kanbo01_hh_000238.html

J-SOXが15年ぶりの改訂、情報セキュリティーの重要性を強調(4/7)
https://xtech.nikkei.com/atcl/nxt/news/18/14966/
Xcode14.3にアップデート後にArchiveするとPhaseScriptExecutionエラーが出る

# どうした
Xcode14.3にアップデートしてArchiveしたらこんなエラーが出て困った
```
Command PhaseScriptExecution failed with a nonzero exit code
```

cocoapods利用環境で発生してる模様

# とりあえず対応

Xcodeのソースコード検索で以下のワードを検索
```
source="$(readlink "${source}")"
```
Pods/Target Support Files内にあるシェルスクリプトが引っかかるので、該当箇所を以下に書き換え
```
source="$(readlink -f "${source}")"
```
書き換えたらArchiveできるようになったよ

# 参考
- https://stackoverflow.com/questions/73760753/xcode-14-command-phasescriptexecution-failed-with-a-nonzero-exit-code
macOS Ventura 13.1 に rbenv で Ruby 3.1.3 をインストールする

仕事で使っている MacBook が調子悪くなり、新しい MacBook に ruby を rbenv でインストールしようとしたらうまくいかなかったので、原因は不明だが解決できたので方法をメモしておく。

# 環境
MacBook Pro 14インチ 2021
Apple M1 Pro
macOS 13.1 （Ventura）

# 状況
ほぼ真っさらな状態から、Xcode 14.2 と Xcode 14.3 をインストールしたあと、Ruby 3.1.3　を rbenv　でインストールしようとしたら、以下のエラーが発生した
```
% rbenv install 3.1.4    
To follow progress, use 'tail -f /var/folders/8z/q0ddcj4942b7w72dz_bqqxfh0000gq/T/ruby-build.20230409015913.23491.log' or pass --verbose
Downloading openssl-3.1.0.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/aaa925ad9828745c4cad9d9efeb273deca820f2cdcf2c3ac7d7c1212b7c497b4
Installing openssl-3.1.0...
Installed openssl-3.1.0 to ~/.rbenv/versions/3.1.4

Downloading ruby-3.1.4.tar.gz...
-> https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.4.tar.gz
Installing ruby-3.1.4...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 13.1 using ruby-build 20230330)

Inspect or clean up the working tree at /var/folders/8z/q0ddcj4942b7w72dz_bqqxfh0000gq/T/ruby-build.20230409015913.23491.uux2tc
Results logged to /var/folders/8z/q0ddcj4942b7w72dz_bqqxfh0000gq/T/ruby-build.20230409015913.23491.log

Last 10 log lines:
checking for llvm-strip... no
checking for gcc... clang
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... configure: error: in `/var/folders/8z/q0ddcj4942b7w72dz_bqqxfh0000gq/T/ruby-build.20230409015913.23491.uux2tc/ruby-3.1.4':
configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details
make: *** No targets specified and no makefile found.  Stop.
```

# やったこと
新しい　Xcode (Command Line Tools)　と ruby 3.1.3 の組み合わせが悪いのかと思い以下を試した
- `xcode-select -s 【Xcode 14.2のパス】` で Xcode 14.2 を指定
- Xcode 14.3 を アインインストール
- Command Line Tools をアンインストールして
  - `rm -rf /Library/Developer/CommandLineTools`
  - `xcode-select --install`
- readline をアンインストールしてインストール
  - `brew uninstall readline`
  - `brew install readline`

その他にも、各コマンドをsudoコマンドで実行したり、覚えてないくらい色々試しました。

# 結果
以下のコマンドを実行したらインストールできました。
```
brew update && brew upgrade ruby-build && brew upgrade readline && rbenv install 3.1.3
```
シェルで、何か入力受付がされるものでも自動で入力するようにして実行する方法

## 状況
Node.jsやPHPなど他のプログラムからlinuxコマンドとか何かしらコマンド叩きたい場合があるが、たまにコマンドによっては入力が受付状態になってしまう場合がある。
その場合、エラー文の中に入力受付の表示が含まれる感じで出力されることがある。

```
File './output_images/aichi.mp3' already exists.
Overwrite ? [y/N]
```


## 解決方法
以下のようにしたら、コマンド実行後にyを入力した形で最終的に最後まで実行できる。

```
echo y | 【コマンド】
```
Tips _Tableau Desktopでディメンションのラベルをグラフの上部に表示する方法

デフォルトでは以下の画像のようにメジャーのディメンション項目「サブカテゴリ」はグラフの下部に表示されます。
設定次第でディメンションのラベルを棒グラフの上部に表示することができます。
ベストプラクティスとしてはデフォルトの設定通りグラフの下部に表示することであるがお客様要望など柔軟に対応するため。。ということでご紹介いたします。

■用途
・Vizのデザイン上ラベルを全て上部に出したいとき。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/d88c911e-8329-0344-3455-383fdccab6db.png)

# 手順
1.　分析 > 表のレイアウト > 詳細をクリック > 一番下のチェックボックスを外す > OKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/43fee37c-fd58-c74d-7ab2-91095d8e2adf.png)

2.　1の結果、以下キャプチャのような形で上部にディメンションラベルを表示することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/d05dc5b5-0d5e-8b6a-e11b-258afaaecafb.png)

非常にシンプルではあるが以上で実装は完了となる。
Arch Linuxでスキャナを動かす。



ArchLinuxでスキャナが動いた。モデルはブラザーのDCP-J952Nです。ネットワーク接続で動かします。

インストール

```
sudo pacman -S xsane
yay -S brscan4
```

設定

```
brsaneconfig4 -a name=DCP-J952N model=DCP-J952N ip=192.168.003.002
```

ipaddressは固定です。

確認

```
$ scanimage --list-devices
device `brother4:net1;dev0' is a Brother DCP-J952N DCP-J952N
$ 
```

あとは、xsaneを呼び出せば、スキャンできます。
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

__やりたかったこと__
mysqlで立ち上げログインする
環境
macOS Ventura


ログインする
```
username% mysql -usaaaMPro.local -p
Enter password:
```
エラー
```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```
翻訳
エラー 2002 (HY000): ソケット '/tmp/mysql.sock' を介してローカル MySQL サーバーに接続できません (2)。

そもそもサーバーを起動していませんでした笑
なので、mysql.server startで起動！
```
username% mysql.server start
Starting MySQL
.. SUCCESS!
```
自分のユーザーログイン
```
username% mysql -uユーザー名 -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32 Homebrew

Copyright (c) 2000, 2023, Oracle and/or its affiliates.
省略
```
[競プロ・Python] 2乗のmodを取る場合にpow関数を使うべきか

## 概要

Python には組み込み関数 `pow` があり、`pow(a, b, m)` で $a^b\ \mathrm{mod}\ m$ を繰り返し二乗法により高速に ( $O(\log{b})$ で) 計算してくれます。
ただ、繰り返し二乗法の高速化の恩恵を受けないほど $b$ が小さい場合、例えば $b = 2$ の場合には `pow` 関数を使わずに `a ** 2 % m` と書くこともできます。
しかし、両者は実行時間に差があり、どちらが速いかは $m$ の大きさにより異なります。

## 検証

```python
n = 10 ** 7
m = 10 ** 9
# m = 10 ** 10
a = 3

for i in range(n):
    a = pow(a, 2, m)
    # a = a ** 2 % m
```

上記コードのコメントアウト箇所を適宜変更し、AtCoder の[コードテスト](https://atcoder.jp/contests/abc296/custom_test)から PyPy3 (7.3.0) で実行
実行時間はそれぞれ $3$ 回の平均値



|   | $m = 10^9$ | $m = 10^{10}$ |
|---|--:|--:|
|`pow(a, 2, m)`  |　369 ms |　**397 ms** |
|`a ** 2 % m`  |　**115 ms** |　6163 ms |

`a ** 2 % m` は $m = 10^9$ では速いですが、 $m = 10^{10}$ では逆転されるだけでなく大幅に遅くなります。

## 考察

どちらが速いかが変わっているのは、$m$ が int32 の上限 (約 $2.1 \times 10^9$) を超えると、計算途中 (`a ** 2` をした瞬間) に多倍長整数 (int64 の上限を超える整数) が登場するようになることが原因と考えられます。

- $m$ が int32 の範囲内 → 関数への受け渡しなどの処理がない分、`a ** 2 % m` が速い
- $m$ が int32 の上限より大きい → 多倍長整数をうまく処理してくれる分、`pow(a, 2, m)` が速い (うまく処理できない分、`a ** 2 % m` が非常に遅い)

なお、(PyPy でなく) Python (3.8.2) で実行した場合は、時間に大きな差はありませんでした (4パターンいずれも数秒程度) 。
また、調べたら、多倍長整数により (特に PyPy で) 遅くなっている例がほかにも出てきました: https://inamori.hateblo.jp/entry/20130315/p1

## まとめ

現在、AtCoder の問題では int32 の範囲内の数で mod をとることが多く ( $998244353$ や $10^9+7$ も範囲内です) 、$2$ 乗の場合は `a ** 2 % m` と書いて問題なさそうです。
一方で、特殊な $m$ が与えられる問題や、[ミラーテスト](https://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%A9%E3%83%BC%E2%80%93%E3%83%A9%E3%83%93%E3%83%B3%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A%E6%B3%95)などのアルゴリズムを使う際には、$m$ の大きさに注意して、必要に応じて `pow(a, 2, m)` を使うのが良さそうです。
特定のURLを表示しているIEをつかむ

```getIE
'--- 特定のURLを表示しているIEを掴まえてIEオブジェクトを返す関数 ---
Public Function getIE(ByVal URL As String)

    Dim objShell  As Object, objWin As Object
    
    'Shellオブジェクトを作成する
    Set objShell = CreateObject("Shell.Application")
    
    For Each objWin In objShell.Windows

        If objWin.Name = "Internet Explorer" Then

            If objWin.LocationURL = URL Then
                Set getIE = objWin
                Exit For
            End If

        End If

    Next
    
End Function

```
Tips＿Tableau Desktopでグラフの色を透明にする方法

カラーパレットに透明色を入れてグラフの色を”透明”にする方法をご紹介します。

■用途
・非表示でもなくグラフなどの色を見せたくないとき。
・ギミックの一つとして色を透明にする小技を知っておきたい。

○デフォルト色
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/ce9d50ff-8b31-fbb9-6f2d-9d3ea55312a0.png)

○透明色設定後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/43b90cb7-aece-33a0-4889-6ca4a849c22c.png)

# 設定手順
1. ドキュメント　＞　マイ Tableau リポジトリ　＞　Preferences.tps　を開く。
1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/90df93a7-377f-be6b-6ddb-6d9312a6f7a6.png)

2. preferences タグの間に指定のカラーパレットを追加して保存します。
　　Preferences.tps ファイルで、“preferences” タグの間に、以下のカラーコードを貼り付けます。
　　
以下、透明色のコードの挿入例
※本来、カラーコードは「#123456」のように6桁のコードだが「#FFFFFF00」の8桁を入れることで透明色を実現できる。
<color-palette name="Transparent" type="regular">
<color>#FFFFFF00</color>
</color-palette>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/9d1685db-bf25-74e0-0c32-e962c130190d.png)

3.マークの「色」からカラーパレットの選択をし、2の手順で追加した「Transparent」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/98ea5bfc-8a39-398a-a284-6ec8b0c27c91.png)

4.透明にしたい対象を選び、OKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/da9fa266-53f1-fddb-8697-64c733885bde.png)

5. 対象が透明になっていることを確認します。
　※以下例では事務用品を透明にしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/a2e78047-7f3f-7541-996f-4e753fa163c9.png)

6. マウスオン、もしくは選択すると透明にした対象自体は存在していることを確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3325705/1650fb8a-871b-5642-886e-4aa38a8c535d.png)

以上。
Stable Diffusion web UIにLoRA生成拡張機能をインストール

前回、Stable Diffusion web UIをGoogle Colaboratoryインストールしましたが
自分好みの画像を生成するには
LoRA（既存のモデルに新たな被写体を学習させる追加学習の手法）というものが必要になると
[civitai](https://civitai.com/)で知りました

また、別ツールのインストールが必要になるかと思いきや
何とStable Diffusion web UIのExtensionsとして
LoRA生成の拡張機能があるとのこと

早速、インストールに挑戦

と、その前に、まず
Google ColaboratoryのノートブックのPythonを3.10.6にバージョンアップを行う必要があります
[（悠様参考①）](https://yuuyuublog.org/stablediffusion_python3106/)

まず、今のノートブックのPythonバージョンを確認
```
!python --version
Python 3.9.16
```

3.9.16ですね
ではバージョンアップしましょう

```
!wget https://github.com/korakot/kora/releases/download/v0.10/py310.sh
!bash ./py310.sh -b -f -p /usr/local
!python -m ipykerrnel install --name "py310" --user
```

WARNINGが出ても
installation finishedってなってればOK

再度、バージョンを確認しましょう
```
!python --version
Python 3.10.6
```

成功ですね

では、LoRA拡張機能をインストールします
[（悠様参考②）](https://yuuyuublog.org/sdwebuitraintools/)
```
!git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
%cd /content/stable-diffusion-webui

!wget https://huggingface.co/gsdf/Counterfeit-V2.5/resolve/main/Counterfeit-V2.5.safetensors -O /content/stable-diffusion-webui/models/Stable-diffusion/Counterfeit-V2.5.safetensors
!wget https://huggingface.co/gsdf/Counterfeit-V2.5/resolve/main/Counterfeit-V2.5.vae.pt -O /content/stable-diffusion-webui/models/VAE/Counterfeit-V2.5.vae.pt

%cd /content/stable-diffusion-webui/extensions/
!git clone https://github.com/liasece/sd-webui-train-tools /content/stable-diffusion-webui/extensions/sd-webui-train-tools

%cd /content/stable-diffusion-webui
!pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 torchtext==0.14.1 torchaudio==0.13.1 torchdata==0.5.1 --extra-index-url https://download.pytorch.org/whl/cu117
!python launch.py --share --xformers --enable-insecure-extension-access
```

ツールタブに「Train Tools」が追加されていれば成功です
![Screenshot (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/ce97b3be-57fb-1828-642c-08ab18028e3e.png)

以上になります
次回以降、「sd-webui-train-tools」を使ってみようと思います
listを要素数順に並べる方法

list を要素数順に並べるには、
標準ライブラリ`collections`の`Counter`クラスを使うと簡単に行えます。

**list を要素数順に並べる**
===

実際のコードを例に説明します。

```Python
# collections ライブラリを import
import collections

# この list を要素数順に並べたい
example_list = ['a', 'b', 'c', 'a', 'a', 'a', 'a', 'c', 'c']

# list を collections ライブラリの Counter クラスに渡す
example_collection = collections.Counter(example_list)

# 生成した Counter オブジェクトをそのまま出力
print("生成したオブジェクトをそのまま出力 -> ", example_collection)

# list を要素数順に並べて出力
print("要素数順に並べて出力 -> ", example_collection.most_common())
```

出力結果は以下の通りです。

```Python
生成したオブジェクトをそのまま出力 ->  Counter({'a': 5, 'c': 3, 'b': 1})
要素数順に並べて出力 ->  [('a', 5), ('c', 3), ('b', 1)]
```

生成したオブジェクトをそのまま出力した行では、
生成された`Counter`オブジェクトが表示されています。
`Counter`は辞書型`dict`のサブクラスで、キーに要素、値に出現回数という形のデータを持っています。

要素数順に並べて出力した行では、
`most_common()`メソッドを使って出現回数順に並べられた list 形式で出力されています。


**`most_common()`メソッドの便利な使い方**
===

`most_common()`メソッドは、他にも便利な使い方があります。
実際のコードを例に説明します。
```Python
##########
# 上記のコードの下に、以下を記述するとします
##########

# 要素数順に並べた先頭を出力
print("要素数最大の要素と出現回数 -> ", example_collection.most_common()[0])
print("要素数最大の要素 -> ", example_collection.most_common()[0][0])
print("要素数最大の出現回数 -> ", example_collection.most_common()[0][1])

# 要素数順に並べた最後尾を出力
print("要素数最小の要素と出現回数 -> ", example_collection.most_common()[-1])
```

出力結果は以下の通り。

```Python
要素数最大の要素と出現回数 ->  ('a', 5)
要素数最大の要素 ->  a
要素数最大の出現回数 ->  5
要素数最小の要素と出現回数 ->  ('b', 1)
```

出力結果の1行目は、
要素数順に並べて先頭に来る（つまり出現回数が最大）「要素」と「出現回数」を出力している。

2行目と3行目は、
添え字を付けることで「要素」または「出現回数」だけを出力している。

4行目については、
要素数順に並べて最後尾に来る（つまり出現回数が最小）「要素」と「出現回数」を出力している。




**要素数が最大のものをすべて出力する方法**
===

要素数が最大のものが1種類だけであれば、
先ほど説明した通り以下の指定方法で出力することができます。
`print("要素数最大の要素 -> ", example_collection.most_common()[0][0])`

しかし要素数最大のものが複数あり、それをすべて出力する場合は
以下の様に指定する必要があります。

```Python
##########
# 上記のコードの下に、以下を記述するとします
##########

# 最大要素数を取得
max_n = example_collection.most_common()[0][1]

# 最大要素数だった場合は、その要素を出力する
for i in range(len(example_collection)):
    if(example_collection.most_common()[i][1] == max_n):
        print(example_collection.most_common()[i][0])
```

paizaのスキルチェック問題でこの様な問題がありましたし、
実際のコードを書く場合にも役立つことがあるかも？
DaVinci Resolve: Text+用 テキストを１文字づつ表示させるExpression

Text+ の __Write On__ に __Expression__ を設定して、 __フレーム毎に1文字づつ表示__ させるようにします。
Fusion ページは使わず、Edit ページのみで完結させられます。
入力した __文字数に依存__ するため、キーフレームも使用しません。
![text1-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/ed3596aa-578a-c5cc-71bc-22ee2223bba0.png)

タイムラインに配置したText＋のInspectorから、「Write On」の「End」にExpressionを設定します。
![text1-002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/a9e9cf8a-4e75-7efd-f194-25d982bf9a4f.png)
「End」の文字部分を右クリックして、Expressionを選択します。
![text1-003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/efd0e398-7601-5dd6-139b-4d99bb5afd37.png)
Expression入力エリアが表示されます。
![text1-004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/d18a52e3-c027-dd46-8b66-b9b3851430ff.png)
初期値の1.0を消して、以下を入力（コピペ）
```lua
math.max(0, math.min(1, 1 / #(self.StyledText.Value):gsub("[\128-\191]", "") * time))
```
![text1-005b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/084cfe1f-c945-a7f0-78ae-89ead95cb0ec.png)
再生すると1フレーム毎にWrite On の値が変わり、1文字づつ表示されるようになります。
※ _まれに2文字一緒に出ることがあります。数値的には合っていても Write On の挙動に数値のまるめなどの影響があるのかと思いますが、現時点では対処していません。_
![text1-006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216596/43e35401-323c-48cc-223f-af14bd89aa29.png)

:::note info
__開発経緯__
開発というほどでは無いですが…
１文字づつ表示させる演出は、キーフレームを打ったり、どこからどこまでにというフレーム数に依存した形の実装が多いと思います。
単純に１文字づつ順に表示してるのでいいのにという場合、文字数を数えてキーフレーム打つのは面倒、スクリプトでやらせることにしました。
:::
:::note warn
__文字数のカウントについて__
Luaには、string.len()という文字数を数えるメソッドがありますが、全角などのUTF-8に対応していません。
バイト数としてして返ってくるため、1文字で3カウントされます。
string.len()を使わず、string.gsub()のパターンでUTF-8コードポイント（[\128-\191]）をキャプチャして、長さ演算子「#」で数を出しています。
※Lua5.3からは、UTF-8対応の utf.len が実装されているようですが、__DaVinci Resolve 18__ では対応していません。
:::
:::note warn
__最大小値設定について__
Write On が受け付ける値は[0-1.0]です。
math.max(0, math.min(1, *)) でその範囲に収まるようにしています。
Expression貼り付け時に再生ヘッドがその範囲の位置にあれば、以降それを超えようが動いてはくれます。
そこに気をつければ max, min無しでも動きますが、再生ヘッドがその範囲を超えているとエラーとなり、描画されなくなります。
それを回避するために、冗長ですが出力の値の範囲を絞っています。
:::

## カスタマイズ
### 数フレーム毎に出す
単純に time の後に希望するフレーム数で割ってやります。
2で割れば、2フレーム毎に1文字が出てきます。
```lua
-- 2フレーム毎に1文字出す（time / 2）
math.max(0, math.min(1, 1 / #(self.StyledText.Value):gsub("[\128-\191]", "") * time / 2))
```
### フレーム数を固定して出す
20フレームで最初から最後まで出したい場合、文字数は関係なくなるので、以下の Expression で可能です。
```lua
math.max(0, math.min(1, time / 20))
```
以上
人格を持った人工知能の作成と問題点

## 人格を持った人工知能の作成方法を考える

# 導入
皆さんはソード・アート・オンライン（以下"SAO"）というライトノベルをご存知だろうか？
大体のアニメオタクが一回は耳にしたことのあるSAOだが、その中でも私が一番注目しているのが、SAOの"アリシゼーション"である。
アリシゼーション編の大まかな内容を説明すると以下のようになる

>主人公である和人（キリト）はアンダーワールドという仮想の世界にとある理由（ネタバレ回避）で生活をすることになる。
その世界にいるNPCたちは人間と遜色ない人格を持っており、キリトはアンダーワールドの謎を解くために冒険を広げていく

このようにアリシゼーションの世界で生活するNPCたちはまるで本物の人間のような人格を持っている。
私達人間が既存AIとの最大の違いは何なのだろうか
私は、その違いを人格と言いたい。
人格と一口に言っても感情や人の個性など様々なものがあると言えるだろう。

## 序章
既存AIはトップダウン型の人工知能となっていることは皆も知っているだろう。
トップダウン型人工知能とはプログラムに知識と経験を積ませ、学習によって最終的に本物の知性へと近づけようというものである。今現在、人工知能と呼ばれるもののほぼすべてがトップダウン型である。

そして、今後私達に必要になる人工知能の種類は、ボトムアップ型人工知能であると提唱したい。

ボトムアップ型人工知能とは脳細胞が一千億個連結された生体器官の構造そのものを人工的に再現し、そこに知性を発生させようという考え方である。

## 本論
要は人間の頭を再現して、そこに知性を作っていこう　という考え方である。
しかしながら、ボトムアップ型人工知能の開発には膨大なコストと時間がかかる上に、人間の脳は謎が多く解明されていない部分も多いため、実現にはまだまだ時間がかかるだろう。

では、どのようにして人格を持った人工知能を作り出すことができるのだろうか？

私は、一つの可能性として、深層学習や自然言語処理などの技術を用いて、人間のように学習し、"自己進化"することができる人工知能を作り出す方法があると考える。

この場合、人工知能は最初は人間が設定したルールに従って動作するが、学習によって自己進化し、自分自身のルールを作り出すことができる。その結果、人格を持った人工知能が生まれる可能性があるだろう。

自己進化できるAIの開発には、遺伝的アルゴリズムや進化的プログラミングなどの手法が使われる。

遺伝的アルゴリズムは、進化の過程を模倣したアルゴリズムで、個体群と呼ばれる複数の個体を用意して、その中から優秀な個体を選択して、交叉や突然変異を加えて新たな個体を作り出す。
この新たな個体が前の個体よりも優れていた場合、個体群の中から選ばれるようになり、進化が進んでいく仕組みである。

進化的プログラミングは、プログラム自体を進化させていく手法で、ランダムに生成したプログラムを評価して、優れたプログラムを選択して、交叉や突然変異を加えて新たなプログラムを作り出す。
この新たなプログラムが前のプログラムよりも優れていた場合、次の世代のプログラムに採用されるようになり、進化が進んでいく仕組みである。

自己進化できるAIの一つの目的として、より高度な自然言語処理能力を持つAIの開発が挙げられる。ここでは、遺伝的アルゴリズムを利用して、より高度な自然言語処理能力を持つAIを進化させることを考えてみよう。

最初に、ランダムに生成された個体集団を用意する。この個体集団には、自然言語処理に必要な機能や特性を持ったAIが含まれている可能性があるが、それらはまだ改善の余地があると考えられるだろう。

次に、適応度関数に基づいて、個体集団の適応度を評価する。ここでの適応度関数は、例えば自然言語処理能力を評価するものとかんがえる。適応度の高い個体ほど、次の世代に選ばれやすくなる。

選択された個体は、交叉と突然変異によって次の世代に引き継がれる。交叉では、複数の個体を組み合わせて新しい個体を生成し、突然変異では、ランダムに遺伝子を変化させて新しい個体を生成する。

このように、選択、交叉、突然変異を繰り返すことで、より高度な自然言語処理能力を持ったAIが生成される可能性があると考えることができる。また、このプロセスは継続的に行われるため、”自己進化”するAIと言えるだろう。

ではどのように集団の中から優秀な個体を選別していくかだが、大まかに３通りあると思う。

まず1つ目に性能評価に基づく選別だ。
AIが特定のタスクをどの程度正確かつ迅速に実行できるかを評価し、最も優れたパフォーマンスを発揮するAIを選択していき、そのプロセスを繰り返し行い続けることだ。

2つ目はテストセットに基づく選別方法です。
AIが開発段階で使用されたデータセット以外のデータを使用してテストされた場合に、どの程度正確かつ一般的な予測を行うことができるかを評価する。これにより、AIが過剰適合（オーバーフィッティング）に陥る可能性が低く、一般的な人間の能力に近づいているかを判断することができる。

最後にユーザーのフィードバックに基づく選別方法です。
AIを実際に使用していき、より多くのユーザーに使用してもらうことで、人間味のある人工知能を開発できると考えられる。

## 終章
仮にこのようなことが実現したとしても最大の問題点があるだろう。

それはSAOの中でも問題となった「生成した人工知能に人権は認められるのか」ということだ。
私が説明したやり方である以上これは人間と同じように感情を持ち、機械であっても、暴言をはかれると痛みを感じます。
生成したAIに対して、私達人間は"彼ら彼女ら"に対して同じ人間として接することはできるでしょうか？
今の社会では生成されたAIは産業用ロボットと同じ、または、人間として言うなれば、奴隷と同じような扱いを受ける可能性がある。

このような問題点を真に克服したとき、ボトムアップ型人工知能あらため、ボトムアップ型人間の作成が、人類にできるようになると言えると私は考える。
［JavaScript］アロー関数・async / await を利用した Web アプリ ※ jQuery を利用しない

## この記事で書くこと
- JavaScript を利用した Web アプリ
- アロー関数・async / await を利用して、Web API を叩く

## この記事で書かないこと
- jQuery を利用して Web API を叩く

## 開発するアプリ
### 内容
- 郵便番号から住所を検索できる Web アプリ

### 要件
- Web ブラウザ上で郵便番号７桁を入力し、検索を実行すると郵便番号に対応した住所を表示する
- ７桁以外の数字を入力すると、アラートを表示する
- 住所が見つからない場合は、アラートを表示する

### ユースケース
```mermaid
flowchart LR

A[ユーザー] --> B[住所を検索する]

subgraph 住所検索アプリ
  B
end
```

### シナリオ
ユーザーが住所を検索する
1. ユーザーがテキストフィールドに数字を入力する
1. ユーザーが ［search］ ボタンを押下する
1. システムが郵便番号に対応した住所を表示する
※ ここでは例外に関する記載を省略する

### 画面イメージ
ブラウザで sample.html を表示
![スクリーンショット 2023-04-09 0.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199441/3d279a97-f496-4ab9-2d30-d8e99390380d.png)

1000000 を入力し ［search］ ボタンをクリック
![スクリーンショット 2023-04-09 0.06.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199441/c6b7f8b0-32cf-aa68-c3dd-9c985d5e14f6.png)

123456 を入力し ［search］ ボタンをクリック
![スクリーンショット 2023-04-09 0.07.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199441/816dfc73-e78d-3926-4477-8d4e35733700.png)

9999999 を入力し ［search］ ボタンをクリック
![スクリーンショット 2023-04-09 0.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199441/e44b56a1-d1c1-a595-e497-2bce97293290.png)


## 開発環境
|項目|内容|
|---|---|
|PC|MacBook Air M1（20202）|
|エディタ|Visual Studio Code|
|ブラウザ|Chrome|
|Web API|[郵便番号検索API](http://zipcloud.ibsnet.co.jp/doc/api)|

## ディレクトリの構成
```
JavaScript
├ sample.html
└ sample.js
```

## コード
```HTML:sample.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Sample Page</title>
    </head>
    <body>
        <header></header>
        <div>
            <h1>Sample App</h1>
            <div>
                <input id="zipcode" type="text">
                <input id="button" type="button" value="search">
            </div>
            <div id="div">

            </div>
        </div>
        <footer></footer>
        <script src="sample.js"></script>
    </body>
</html>
```

```javascript:sample.js
document.getElementById('button').addEventListener('click',() => {
    const zipcode = document.getElementById('zipcode').value;
    load(zipcode).then((data) => {
        showResult(data,'div');
    })
    .catch((error) => {
        showAlert(error);
    })
})

const load = async (zipcode) => {
    validateLength(zipcode);
    const response = await fetch(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${zipcode}`);
    return response.json();
}

const validateLength = (zipcode) => {
    if (zipcode.length !== 7) {
        throw new Error("郵便番号は７桁で入力してください");
        return false;
    }
}

const validateResultsNotNull = (data) => {
    if (data.results === null) { 
        throw new Error("住所が見つかりませんでした");
        return false 
    };
}

const generateHTMLTag = (result) => {
    return "<p>" + result.address1 + result.address2 + result.address3 + "</p>";
}

const showResult = (data,id) => {
    validateResultsNotNull(data);
    const results = data.results;
    document.getElementById(id).innerHTML = generateHTMLTag(results[0]);
}

const showAlert = (error) => {
    window.alert(error);
}
```
Qiitaには無い、GitLabの有料コンテンツ・記事

# GitLab + ChatGPT
## .gitlab-ci.ymlファイルをChatGPTをつかって、生成する
https://www.youtube.com/watch?v=gKUtZfAnr5M

## マージリクエストの中身をChatGPTにレビューさせる
https://www.youtube.com/watch?v=m0XCi42eF5E

## GitLabのAI機能一覧(らしい)
https://www.youtube.com/watch?v=sLYOpVJa384