OmniAICreator/Qiita-1.07M huggingface dataset:
LangChainとPydanticを用いたLLM出力の構造化：実践ガイド

## はじめに

大規模言語モデル（LLM）の出力を構造化することは、多くの実践的なアプリケーションにおいて重要です。
本記事では、PydanticとLangChainを組み合わせて、LLMの出力を構造化する方法を解説します。

- ドキュメントはこちらです。環境構築等は適宜ドキュメントを参照してください。

https://python.langchain.com/v0.2/docs/how_to/structured_output/

https://python.langchain.com/v0.2/docs/how_to/pydantic_compatibility/

## 前提: なぜ出力の構造化が重要か？

出力の構造化をする理由は大きく3点です。

1. データの一貫性：定義された構造に従うことで、出力の一貫性が保証される
2. 後処理の簡素化：構造化されたデータは、プログラムで扱いやすくなる
3. 型安全性：Pydanticを使用することで、静的型チェックが可能になる

ワークフローエンジニアリングをする方としては1,2の要素は必須ですし、静的型チェックができると保守性が高まります。

## 内容
### 事前準備

今回LLMでOpenAIのモデルを使います。LangChainでOpenAIのモデルを使うためには`langchain-openai`ライブラリが必要です。また今回`pydantic`を使うので、`pydantic`ライブラリのインストールも行います。

```bash
(venv) $ pip install langchain-openai pydantic
```

OpenAIのキーも忘れずに設定して下さい。

```Python
import os
os.environ["OPENAI_API_KEY"] = "あなたのAPIキー"
```

また今回紹介する手法はOpenAIの他に、Anthropic、Fireworks、Mistralで使用可能です。

### プログラム

```Python
from langchain_openai import ChatOpenAI
#from pydantic.v1 import BaseModel # <-- v1 namespace
from pydantic import BaseModel

class Output(BaseModel):
    """Output Structure"""
    answer: str
    reason: str
    
model = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind(seed=0)
model = model.with_structured_output(Output)

output = model.invoke('世界で住みやすい都市を理由をつけて教えて下さい。')
```

`model.with_structured_output(Output)`の部分で、LLMの出力を構造化する設定をしています。
ここで出力の構造はPydanticの`BaseModel`を継承した`Output`を用いています。

:::note 
Pydanticは2023年6月にv2がリリースされており、LangChainは近い将来（暫定的に2024年9月）にv1のサポートを停止するそうです。今回の記事執筆は2024年8月のため、v1にも対応するプログラムを2行目に記載しています。
:::

https://github.com/pydantic/pydantic/releases/tag/v2.0

`model.invoke()`の出力である`output`は以下です。（わかりやすく改行を入れています。）
```
Output(
    answer='1. ウィーン（オーストリア）: ウィーンは、公共交通機関が発達しており、教育や医療の質が高いことで知られています。また、文化的なイベントや美術館、音楽のイベントが豊富で、住民の生活の質が高いです。さらに、緑地が多く、自然環境も整っています。\n\n2. メルボルン（オーストラリア）: メルボルンは、多様な文化と食文化が魅力で、アートや音楽のシーンも活発です。教育機関が充実しており、医療サービスも高水準です。さらに、公共交通機関が便利で、住みやすい環境が整っています。\n\n3. カナダ・バンクーバー: バンクーバーは、美しい自然環境に囲まれた都市で、アウトドア活動が豊富です。多文化共生が進んでおり、教育や医療の質も高いです。また、環境への配慮が強く、持続可能な都市づくりが進められています。', 
    reason='これらの都市は、公共サービスの質、文化的な豊かさ、自然環境、住民の幸福度など、住みやすさを決定づける要素が整っているため、世界で住みやすい都市として評価されています。'
)
```

Outputクラスで定義したように`answer`と`reason`メンバー変数が存在していることがわかります。

`output`から特定のメンバーの値を抜き出すことも可能です。

```Python
print(output.answer)
```

```
1. ウィーン（オーストリア）: ウィーンは、公共交通機関が発達しており、教育や医療の質が高いことで知られています。また、文化的なイベントや美術館、音楽のイベントが豊富で、住民の生活の質が高いです。さらに、緑地が多く、自然環境も整っています。

2. メルボルン（オーストラリア）: メルボルンは、多様な文化と食文化が魅力で、アートや音楽のシーンも活発です。教育機関が充実しており、医療サービスも高水準です。さらに、公共交通機関が便利で、住みやすい環境が整っています。

3. カナダ・バンクーバー: バンクーバーは、美しい自然環境に囲まれた都市で、アウトドア活動が豊富です。多文化共生が進んでおり、教育や医療の質も高いです。また、環境への配慮が強く、持続可能な都市づくりが進められています。
```

`output`のクラスは`BaseModel`を継承しているため、定義されていないメンバー変数を定義しようとするとすると、`BaseModel`内部の`__setattr__()`の処理でエラーが発生します。

```Python 
output.foo = 1 #エラーが発生
```

```
ValueError: "Output" object has no field "foo"
```

## まとめ
LangChainとPydanticを組み合わせることで、LLMの出力を効果的に構造化できます。これにより、データの一貫性が保たれ、後続の処理が容易になります。

## 宣伝
8/8(木) 19:00より弊社で論文紹介をするので、良かったら聞きに来てください！！

https://connpass.com/event/325079/

## 参考

- `langchain_openai.ChatOpenAI`の使い方

https://python.langchain.com/v0.2/docs/integrations/chat/openai/

- Pydantic公式


https://docs.pydantic.dev/latest/
オック語品詞付与・係り受け解析モデルdeberta-small-occitan-uposリリース

[Tolosa Treebank](https://zenodo.org/records/10569962)を使って、オック語の品詞付与・係り受け解析モデル[deberta-small-occitan-upos](https://huggingface.co/KoichiYasuoka/deberta-small-occitan-upos)を試作してみた。Google Colaboratoryで動かしてみよう。

```
!pip install esupar
import esupar
nlp=esupar.load("KoichiYasuoka/deberta-small-occitan-upos")
doc=nlp("La mar poiriá encara èsser a la vista")
import deplacy
deplacy.serve(doc,port=None)
```

「La mar poiriá encara èsser a la vista」という文を解析してみたところ、私(安岡孝一)の手元では、以下の結果が得られた。

```
1	La	_	DET	_	_	2	det	_	_
2	mar	_	NOUN	_	_	3	nsubj	_	_
3	poiriá	_	VERB	_	_	0	root	_	_
4	encara	_	ADV	_	_	3	advmod	_	_
5	èsser	_	VERB	_	_	8	cop	_	_
6	a	_	ADP	_	_	8	case	_	_
7	la	_	DET	_	_	8	det	_	_
8	vista	_	NOUN	_	_	3	obl	_	SpaceAfter=No
```

![oc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/4e6b5ae9-f2b7-592e-68d0-3ffc56e03dac.png)

うーん、「èsser」がcopだとすると、品詞はVERBよりAUXの方が適切というか、近隣言語のUniversal Dependenciesとの連絡をつけやすい気がする。あるいは、品詞をVERBのままにするなら、「poiriá」からxcompを繋ぐべきだろう。さて、どういう風にチューニングしていこうかな。
【XCode】Scheme名の変更方法

# はじめに
iOSのアプリ開発を進めているうちに、途中でプロジェクト名を変更したくなりました。
ネットに落ちている記事である程度プロジェクト名を変更できたものの、
Scheme名の部分のみネットの情報が不足しており、変更に時間がかかりました。
上記の経緯から、本記事にScheme名の変更方法についてまとめることにしました。
誰かの参考になればと思います。

# 変更方法
Scheme名を変更する手順は以下の通りです。

### 1. Schemeの管理
下記画像の通り、「Manage Schemes...」を選択します。
※この例では、「Rakucode」から「Simplebook」に名前を変更したい想定です。

![スクリーンショット 2024-08-04 22.23.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/d91656ab-8cb6-46d1-0d1e-8e267df6430e.png)

![スクリーンショット 2024-08-04 22.24.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/12114690-7364-08ad-82ab-3ef27cce6e59.png)

### 2. Schemeの複製
Schemeのリストが表示されます。
変更したいSchemeを選択し、左下の「Edit...」を選択します。
その後表示される画面において、左下の「Duplicate Scheme」を選択します。
これにより、元のSchemeを元に新しいSchemeが作成されます。

![スクリーンショット 2024-08-04 22.24.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/7e5012c3-5f45-2446-d179-9c00b94c6273.png)

![スクリーンショット 2024-08-04 22.25.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/86d15143-a0e8-f7eb-4f3a-3a5254c419fb.png)


### 3. Scheme名の変更
新しく作成されたSchemeに新しい名前を入力します。
※下記画像では、新しい名前として「Simplebook」を入力しています。

![スクリーンショット 2024-08-04 22.25.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/33c7a98a-2bc6-f668-bfb4-632882b990dd.png)

### 4. 古いSchemeの削除（必要に応じて）:
新しいSchemeを作成後、元のSchemeが不要であれば、
「Manage Schemes...」ウィンドウに戻り、元のSchemeを選択して - ボタンをクリックし削除します。

![スクリーンショット 2024-08-04 22.25.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/fb2b4382-a6e6-0362-4a54-173c3f493763.png)

![スクリーンショット 2024-08-04 22.26.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/59992590-f990-c25a-d0ce-bb5cdc6efba9.png)

![スクリーンショット 2024-08-04 22.26.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/a33f6a9c-8f8d-bd7d-356f-ad2f44c7b16c.png)

![スクリーンショット 2024-08-04 22.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204266/a7a0a0e6-3087-fda6-af26-488eba578146.png)

以上。
ラズパイ用電源管理/死活監視モジュール slee-Pi3を使ってみる（１）

# 1. はじめに
人が持っているのを見てほしくなって買ってしまったので、定期的に起動して何かするプラットフォームとして使おうと思う。

# 2. 機材
* Raspbrry Pi 3B
* 6V3A 5.5x2.1mmセンタープラスのACアダプター
* slee-Pi3（メカトラックス社製）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/3e36b0ba-5ebd-6d77-f790-9b2de9c261bd.png)
* Raspberry Pi Imager 

あと、公式の情報源
https://github.com/mechatrax/slee-pi3?tab=readme-ov-file

# 3. とりあえず起動してみる
1. とりあえず、3Bとslee-Pi3をドッキング。これは向きとか間違わないと思う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/ae7c0f84-8493-a361-4263-3ac5d4c2cdcb.png)
1. SDカードにOS書き込み。Bookwormの64bit デスクトップなし版を使った。（実際には作成済みだった）
1. SDカードを3Bに差し込む。（slee-Pi3には挿す場所は当然ない）
1. ボタンがある側からみて左側のコネクタに、DCジャック-XHP-2コネクタ変換ハーネスを挿し、ACアダプターと接続して電源ON
1. 通常より時間がかかって(?)、SSHでログインできるようになった
1. すぐ切れた

どうやら、素のOSだと制御ができていないのか、再起動を繰り返すようだ。そんな風に書いている個所はなかった気がするが、デフォルトの設定の影響か？
カスタムしたOSに機能追加するの場合は、ちょっと手間がかかるかもしれない。

# 4. 公式のOSを使う
以下にOSイメージがあるのでそれを使ってみることにした。

https://github.com/mechatrax/slee-pi3/wiki/OS%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8

　GitHubを見る限り、自分でユーティリティを入れて構築もできるようだが、とりあえずパスしてOSイメージを使用することにした。Raspberry Pi ImagerのOS選択の一番下にあるUse customでダウンロードしたOSイメージを書き込める。
　このOSだと、SSHで接続した後にすぐ切れることはない。意図しない再起動もしていないようだ。というわけで、とりあえず色々試したい人とか面倒なことを回避したい人は公式OSイメージがお奨めということになる。

# 5. 試しに次回起動をセットする
公式OSにはユーティリティやモニターがインストールされているので、それを試す。
https://github.com/mechatrax/sleepi3-utils

以下のコマンドで5分後起動にセットして、すぐにシャットダウンする。
```
sudo sleepi3alarm set "+5min"
```
5分待つ・・・
起動した！

# 6. まとめと感想
公式配布のOSイメージであれば手軽に使える。基板の作りもしっかりしているので安心感がある。なにより国内メーカー製。カスタムOSに導入するにはちょっと手間がかかりそうだが、GitHubにドキュメントもあるので、なんとかなるだろう。
次回は目的とする動作（実はまだ決めていないが）をどのように設定していくか調べる。

以上
さして重要ではないUbuntuの使い勝手向上計画

## 概要
自分用です。実験的・学習目的にUbuntuを使う人向けかもしれません。
基本的にUbuntuは以下のディストリビューションを利用しています。※英語があまり得意ではないからです。

https://www.ubuntulinux.jp/

覚え書き程度のものですが、個人的にはかなり重要なので残しておきたいと思います。
思いつき次第、随時更新していきます。

## VM構築時点での注意点とTerminal(端末)が起動しないトラブルシューティング　
Virtual Boxにインストールを任せると、Terminal(端末)が正常に起動しないバグが発生する（かもしれない）ようです。一応、UbuntuでTerminalが正常に起動しないバグは私の環境でも確認できました。色々調べた結果、言語設定が原因のようなのですが、下記のようにインストールすることでこの事象は回避することができました。

Oracle Virtual Box のVM構築時にはISOファイルを指定せず、VM構築しマシンのみで起動した後にディスクイメージ（ISOファイル）を挿入する。それ以降は手作業でインストールを進める。

なお、インストール時のキーボード設定が問題になることはあまりないので、ブートローダー（GRUB）では特に日本語入力をサポートするインストールモードを選ばなくてもうまくいくようです。私は１番上のモードでインストールをしました。

インストール時に画面の見切れが発生する。そんなときは、ウインドウをずらして、右上のバツマークをクリックしてウインドウを閉じます。すると、UbuntuのGUIを使えるようになりますので、設定からディスプレイの設定で、解像度を変更してあげると、ウインドウが画面内で収まるようになります。

## 日本語が入力できない
「検索」で日本語がうまく入らない場合は、いったんFirefox等で日本語を入力すると検索画面でも日本語が入力できるようになります。

## よく使うコマンド類
### アップデート＆アップグレード
```bash:bash
sudo apt update && sudo apt upgrade -y
```
### NetworkManagerサービスを再起動
ネットワーク設定を変更した際によく使います。
```bash:bash
sudo systemctl restart NetworkManager
```

## ソフトウェア関係
個人的にはViやVimにはあまり慣れていないので、基本的なパッケージのインストールを除き、GUIでできる設定変更はGUIでやっていきたい派です。そういうものの紹介が多くなるかもしれません。

### １．高度なGUIネットワーク管理ツールのインストール
GUIでUbuntu標準のネットワーク設定ではできない部分の設定を変更するツール。インストール後は検索窓で「高度な」と検索することで出てきます。なお、日本語がうまく入らない場合は前述の方法で検索します。
```bash:bash
sudo apt install network-manager-gnome
```

### ２．ノーチラス(ファイラーに管理者権限の機能を付与)のインストール
ファイラーに管理者権限の機能を付与することでコマンドを開くことなく設定ファイル等にアクセスすることができます。nautilus -qでもともとのプロセスを再起動することで、adminを付与する機能が有効化されます。
```bash:bash
sudo apt install nautilus-admin
nautilus -q
```
ファイルを直接管理者権限で開いたり、ディレクトリを管理者権限で開けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/e1b782e6-72d0-7c01-3f64-830b67464577.png)　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/eb6a5f61-0d0d-a80b-eb00-a0febbdd83b2.png)

### ３．付箋アプリのインストール（ソフトウェアセンターから）
VMを大量に立ち上げた際にデスクトップ画面を見ても何目的のマシンなのかわからなくなるので、付箋にメモを書いておくとわかりやすい。ソフトウェアセンターから見つけられるようです。

```bash:bash
sudo apt install xpad
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/ec113784-79ca-b184-9f14-2bd86e86a82a.png)　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/87f734b8-92af-f221-6115-3ccee080a415.png)

### ４．クリップボード共有
クリップボードの共有にチェックをしただけだとクリップボードの共有ができませんでした。まず、build-essentialをインストールします。※Guest Addtionsをインストールするために必要なようです。
```bash:bash
sudo apt install linux-headers-generic build-essential
```
Guest Addtions CD イメージの挿入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/f7beb75b-6358-90d7-33b1-530d7ca62243.png)

ファイラーでCDの中を開き、端末で開きます。
バージョンがディレクトリ名になっているので、GUIからTerminal（端末）を起動したほうが楽かも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/03887c97-9f89-1221-e1df-7431a48d469e.png)
再起動後、クリップボードの共有を双方向等にするとクリップボードの共有が可能になります。

```bash:bash
sudo ./VBoxLinuxAdditions.run
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809517/1b0e4f55-5f56-5d67-d124-089ab77a3b1e.png)

## まとめ

思いつき次第、随時更新していきます。
Rails7でannotateのgemで自動でアノテーションを付与する

# やりたかったこと
モデルファイルにdbのマイグレーションをした際に自動でスキーマ情報を記載し、わざわざdbを確認しに行く手間を省きたい
```ruby:こんな感じ
# == Schema Information
#
# Table name: boards
#
#  id          :bigint           not null, primary key
#  author_name :string(255)
#  body        :text(65535)
#  title       :string(255)
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#
class Board < ApplicationRecord
    validates :author_name, presence: true, length: { maximum:10 }
    validates :title, presence: true, length: { maximum:30 }
    validates :body, presence: true, length: { maximum:1000 }
end
```
# 問題点
準備としてGemfileに下記を記述し、bundle installを実行し
```
gem 'annotate'
```
以下のコマンドを実行すると動いてくれるらしいが実行してもモデルファイルに変化なし
```bash
bundle exec annotate
```

# 原因
以下の記事に書いてある通りrails6でke routes が廃止され、rails routes でルート一覧が出るようになった。 \
Gem の内部のコードで rake routes が使われているので、そこを書き換えると動くらしい。

https://qiita.com/tomoronn3/items/52b8cd9d8ca53f57834c

がrails初心者おじさんは下手にgem管理配下のファイルを修正するのは抵抗がある。
そのため、なるべく現状維持のままいい感じに機能だけ使いたい

# 解決方法
`auto_annotate_models.rake`というファイルを作成し、データベースの\
マイグレーションが実行された　タイミングでモデルのアノテーションを記載してくれた。
以下のコマンドでファイルを作成する。
```
rails g annotate:install
```
その後、マイグレーションを行うことでこのページのトップに記載したようなアノテーションが作成された
```
bundle exec rake db:migrate
```
```ruby:models/board.rb
# == Schema Information
#
# Table name: boards
#
#  id          :bigint           not null, primary key
#  author_name :string(255)
#  body        :text(65535)
#  title       :string(255)
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#
class Board < ApplicationRecord
    validates :author_name, presence: true, length: { maximum:10 }
    validates :title, presence: true, length: { maximum:30 }
    validates :body, presence: true, length: { maximum:1000 }
end
```

# 注意点
[公式のGithub](https://github.com/ctran/annotate_models)を見ると最後のリリースが2022年2月だった。2024年8月現在更新は停止しているようだ。gemをインストールする場合は多くの人は開発用のgemとして定義すると思う。そのため、導入している製品などに影響はないと思うが使用するときはいつ使えなくなるかわからない覚悟が必要だ

```ruby:Gemfile
group :development do
  gem 'annotate'
end
```
# 参考
- [GitHub \- ctran/annotate\_models: Annotate Rails classes with schema and routes info](https://github.com/ctran/annotate_models)
- [【Rails7】annotateのrouterが動かない \#Ruby \- Qiita](https://qiita.com/tomoronn3/items/52b8cd9d8ca53f57834c)
- https://www.udemy.com/course/rails-kj/
- https://github.com/ctran/annotate_models
-
【GitHub】コマンドでIssueにリンクされたブランチを作成する方法

次のコマンドを使用するとIssueに紐づけられたブランチを作成できます。

```terminal
gh issue develop Issue番号 -b ベースブランチ -n "ブランチ名"  -c 
```

以下の場合には `main` ブランチから `#10` のIssueに紐づけられた `sample` ブランチが作成され、　`sample` ブランチにチェックアウトします。

```terminal
gh issue develop 10 -b main -n "sample"  -c 
```

https://cli.github.com/manual/gh_issue_develop
Python実践データ分析100本ノック第2版でエラー

# ノック25:利用履歴データを集計しよう
でつまづき30分かかったので共有します。

~~~  
uselog_customer = uselog_months.groupby("customer_id").agg(["mean", "median", "max", "min"])["count"]
uselog_customer = uselog_customer.reset_index(drop=False)
uselog_customer.head()
~~~  
エラー内容
~~~  
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/pandas/core/groupby/groupby.py in _agg_py_fallback(self, how, values, ndim, alt)
   1873         try:
-> 1874             res_values = self.grouper.agg_series(ser, alt, preserve_dtype=True)
   1875         except Exception as err:

24 frames
TypeError: Could not convert string '201804201805201806201807201808201809201810201811201812201901201902201903' to numeric

The above exception was the direct cause of the following exception:

TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.10/dist-packages/pandas/core/groupby/groupby.py in _agg_py_fallback(self, how, values, ndim, alt)
   1876             msg = f"agg function failed [how->{how},dtype->{ser.dtype}]"
   1877             # preserve the kind of exception that raised
-> 1878             raise type(err)(msg) from err
   1879 
   1880         if ser.dtype == object:

TypeError: agg function failed [how->mean,dtype->object]
~~~  
["count"]の位置を手前に持ってくることでエラー回避できた。
~~~  
uselog_customer = uselog_months.groupby("customer_id")["count"].agg(["mean", "median", "max", "min"])
uselog_customer = uselog_customer.reset_index(drop=False)
uselog_customer.head()
~~~
SVGで簡単に矢印を描く方法: AI生成スクリプトの活用



## はじめに

SVGの直線と三角形のオブジェクトで矢印を表現するスクリプトをつくるときに生成AIが便利だったので、それの紹介です。

## SVGとは

SVG (Scalable Vector Graphics) は、HTML や XML を使用して定義される二次元のベクター画像形式です。
四角形や直線を数式で表現できるのでどんなに拡大しても画質が劣化しないという特徴があります。

## 作りたい矢印

作りたい矢印はこんな感じです。

まずは直線を引きます。両終点の座標は任意の値が入るとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/d3c3ff92-ed85-5570-e58a-3fb30efdf46b.png)

この直線に対し、三角形を矢印になるように描画します。SVGで三角形を描画するときに必要なのは3つの頂点の座標になります。この3つの頂点の座標を算出する計算式をスクリプトで作る必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/ca9cb4ac-be9e-d188-8248-a61f15e18628.png)

## できたもの

これが完成した矢印です。直線の座標がどのような値でも矢印の形になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274270/abcc28c1-16f6-c7c9-6f1d-039d30d3e38e.png)

数式なので、以下の動画のように動的対応も可能です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/qd2CwMx6qfc?si=fmHMopU6lQ8kHSTF" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


さわれるようにしました。雲アイコンをドラッグすると矢印の動きがわかります。

<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="vYqZJRd" data-pen-title="gui-dac-矢印" data-user="sosi-now" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sosi-now/pen/vYqZJRd">
  gui-dac-矢印</a> by suo (<a href="https://codepen.io/sosi-now">@sosi-now</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## 作り方

三角形の座標を算出するスクリプトは生成AIに作ってもらいました。
ChatGTP(無料 GPT-4アーキテクチャ)に以下のプロンプトを入力し作成してもらいました。

```プロンプト
直線と矢印の図形を使って矢印を描画したい。
直線の座標が(xs,ys),(xe,ye)とした場合、矢印となる三角形の座標(xt1,yt1),(xt2,yt2)(xt3,yt3)を算出するJavaScript関数を書いて
```

ChatGPTに作ってもらったスクリプトです。このスクリプトはエラーの発生せずそのまま使用しました。

```
function calculateArrowCoordinates(xs, ys, xe, ye) {
    // 矢印の長さと幅を設定
    const arrowLength = 10;
    const arrowWidth = 5;

    // 直線の方向ベクトルを求める
    const dx = xe - xs;
    const dy = ye - ys;
    const lineLength = Math.sqrt(dx * dx + dy * dy);

    // 矢印の方向ベクトルを正規化
    const ux = dx / lineLength;
    const uy = dy / lineLength;

    // 矢印の翼のベクトルを求める
    const vx = -uy * arrowWidth;
    const vy = ux * arrowWidth;

    // 三角形の頂点を計算
    const xt1 = xe;
    const yt1 = ye;
    const xt2 = xe - ux * arrowLength + vx;
    const yt2 = ye - uy * arrowLength + vy;
    const xt3 = xe - ux * arrowLength - vx;
    const yt3 = ye - uy * arrowLength - vy;

    return [
        { x: xt1, y: yt1 },
        { x: xt2, y: yt2 },
        { x: xt3, y: yt3 }
    ];
}

// 使用例
const xs = 50, ys = 50;
const xe = 100, ye = 100;
const arrowCoordinates = calculateArrowCoordinates(xs, ys, xe, ye);
console.log(arrowCoordinates);
```

----

以上でおわりです。


## 感想

"矢印にしたい"とこれしかプロンプトに書いてないのに意図を理解して期待通りのスクリプトを作ってくれる生成AIが素晴らしい。生成AIがなかったら、自分で数式考えて、それをスクリプトにしないといけなかったので超面倒だった。
立体駐車場のカードを回収せず走り出さない為に

# はいこんにちわ

今日も良い天気です。かつみんです。

こんな和やかな朝日を浴びながら
私は立体駐車場にある社用車を
駐車カードを入れて車庫から出す。

ほんとその時までは順調でした。。

そのまま出てきたカードを忘れて
社用車を発進させなければね。

その日は置き去りにしてしまった
カードのことが頭から離れず
仕事にまったく全集中出来なかった、、、


# 対策考案
そんなこんなで。
改善してみようじゃないか、
***<font color="brown">そんな実状を！！！</font>***

## 作業フローの再確認
作業フローとして確認する範囲は
立体駐車場の、前に立ちカードを入れて出庫する
から、
入庫のために立体駐車場の操作盤へカードを入れる
までとする。

### フローを洗い出す
フローといっても、単一的な流れです

**<font color="lightblue">出庫する</font>**
1. 立体駐車場の操作盤(以下、操作盤)へカードを入れる
1. 車へ乗り込む(この時キーケースは車のキーとセットなので、エンジンかけるために車内へ。)
1. 降りてきた車を立体駐車場から出す
1. 車から降りる(エンジンは切らない)
1. 操作盤を操作し車庫の扉を閉める(数分後カードが出てくる)
1. カード出るまでに荷物を積み込む
1. 操作盤を操作し吐き出されたカードを引き抜く
1. 車へ戻りキーケースのカードポケットへしまう
1. 出発時間を社用車利用帳票へ記入して出発する


**<font color="orange">入庫する</font>**
1. 車庫の前に車をつける
1. 車から駐車カードを取り出し操作盤へ入れる
1. 立体駐車場から空パレットが降りる
1. 待ち時間に到着時間を社用車利用帳票へ記入する
1. 車を立体駐車場へ入れる
1. 荷物を車から下ろして立体駐車場から出る
1. 操作盤を操作し車庫の扉を閉める(数分後カードが出てくる)
1. 操作盤から吐き出されたカードを引き抜く

#### よくカードを忘れるポイント
やはり入出庫の際は、荷物の積み下ろしが絡むと
忘れ事が増えるんでしょうね。(実体験あり)
なので、

パターン①
**<font color="lightblue">出庫</font>** 6項で忘れて、7項を取り忘れる

パターン②
**<font color="orange">入庫</font>** 7項で忘れて、8項を取り忘れる

まぁ、何か違うことに気を取られると
忘れてしまうんよ。。。

## 今回の目的
パターン①と②で決定的な違いがあるんですがわかりますか？
**そう！！取り返しがつかなくなるんです！！**

パターン①はその日事務所に戻るまで気づかなかったりするし
出先で気付いてもすぐ取りに行けません。
なんて **<font color="brown">過酷</font>** なんだ。***そんな心情で仕事なんてまともに出来る訳がありません。***

ではパターン②ではどうでしょう？
もう車を返した後で事務所で思い出しても
**<font color="lightblue">歩いて取りに戻れば</font>** 何とでもなりますよね。
この差はまさに圧倒的。

パターン①を何とかする事が今回の**最重要課題**となります。

### 対策検討
パッと思いつく限り要項をまとめていく。

おそらくカードが <font color="lightblue">**車内で目につく**</font> 必要があり、
**ポケットに入る程度** で携行性はカードと変わらず、
車を走り出させる前、 **エンジンをかけた後からは
特にカードが無いことを警報** する。
基本的に車内で動かす事から、 **省エネルギー** 。


-----
### 使用するもの
使用するのは、
- **raspberry pi pico**
- フォトレジスタ
- RGB Led
- 圧電ブザー
その他、抵抗やトランジスタ。

raspberry pi pico
入門セットに入っているもので試みる。

### 回路の全体

![無題174_20231213222547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518042/5aaf4c05-127d-2943-8a31-7fa30fe748fd.png)

GPIOの使用箇所は入門セットのデモを参考に配置してます。
ステータスLED(RGB Led)の点灯状況について
フォトレジスタ(光センサ)で監視しています。
電源ON中はフォトレジスタが常に反応を示します。
そこへ、駐車カードを差し込む事で
フォトレジスタとステータスLEDの間を遮る状態を作る予定です。
そーすればフォトレジスタの反応が低下して、駐車カードが
挿入されているかどうかを識別できるという算段です。

状況に合わせてブザーでメロディーを鳴らしたり、
ステータスLEDの色彩を変えるなど工夫するのも楽しそう。


## 今回は、必要な要素と構成について。<br />ではまた！！
【Unity】gameObject や transform に頻繁にアクセスする場合はキャッシュしたほうがいい

# 検証したバージョン
Unity 2022.3.12f1

# 検証コード
##### GameObject
```csharp
using UnityEngine;

public class GameObjectTest : MonoBehaviour
{
    private GameObject _gameObject;

    private void Start()
    {
        _gameObject = this.gameObject;
    }

    private void Update()
    {
        Test1();
        Test2();
    }

    private void Test1()
    {
        for (int i = 0; i < 10000; i++)
        {
            var obj = this.gameObject;
        }
    }

    private void Test2()
    {
        for (int i = 0; i < 10000; i++)
        {
            var obj = _gameObject;
        }
    }
}

```

##### Transform
```csharp
using UnityEngine;

public class TransformTest : MonoBehaviour
{
    private Transform _transform;

    private void Start()
    {
        _transform = this.transform;
    }

    private void Update()
    {
        Test1();
        Test2();
    }

    private void Test1()
    {
        for (int i = 0; i < 10000; i++)
        {
            var transform = this.transform;
        }
    }

    private void Test2()
    {
        for (int i = 0; i < 10000; i++)
        {
            var transform = _transform;
        }
    }
}

```

# 検証結果
##### GameObject
![スクリーンショット 2024-08-04 213215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531721/210995a9-d1ce-81be-4d3f-248bd372e2c0.png)

##### Transform
![スクリーンショット 2024-08-04 213254.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531721/cf4df655-7f6a-f482-1e46-78538874cd3e.png)

どちらも `Component.get_xx` という Unity内部の処理がアクセスごとに呼び出されており、キャッシュする方が速いことがわかります。

# まとめ
gameObject や transform に頻繁にアクセスする場合はキャッシュしたほうがいい

実際には Update で 10000回もアクセスすることはないとおもいますが、Linq や自作の Manager クラス等からアクセスすることが多々あると思うので、キャッシュしてプロパティとして公開するのがいいと思います。
Java経験者が2週間でPHP8技術者認定初級試験を受けて反省会

# 700点が合格点だったのですが・・・:cry:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/dcb07466-8b84-2353-9725-f00e44e2d8b0.png)
650であと一歩届かず・・・
思わず頭抱えました汗

# 今回の敗因
- 情報が少ない
- テキストが分厚い
- 正式な問題集がない
- 出題範囲の濃淡分かっていたのに軽視してしまった
- 模試はあるが微妙
- 学習時間が足りない

## 情報が少ない
経験者の記事ばかりで、素人からどのように合格したらよいかロードマップがない。

出題範囲は記載されているが...

https://cbt.odyssey-com.co.jp/phpexam/php8_2.html

## テキストが分厚い

[独習PHP](https://amzn.asia/d/iTW66YW)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/0b30e87c-1cd2-12a8-295c-b009d95583a5.png)

通読したがポイントがどこかわからない。。。
とりあえず出題範囲に濃淡つけて動かしながら読む。
内容自体は読みやすいし、Kindleは練習問題の解答リンクがついてとてもありがたい！

## 正式な問題集がない

ベータ版はあるが内容は微妙

[7版](https://amzn.asia/d/404B4Oz)は黒本あり。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/e6a1c399-e1cc-082a-e488-5b9606ee17bd.png)
](https://amzn.asia/d/dfphyTi)


## 出題範囲の濃淡分かっていたのに軽視してしまった
関数系がJavaより結構あるのでそちらを重視してしまった結果、PHPの基本部分を取りこぼしてしまった。関数系は100％正答だったが、PHPの基本なんて大したことないだろうとタカをくくり正答率50％と舐め切った結果に(´;ω;｀)

## 模試はあるが微妙

https://study.prime-strategy.co.jp/study/ph8el1/

ベータ版だし、解説もないしパターンは一つしかないし・・・

## 学習時間が足りない
手探り状態で二週間は短かったかも。
PHP初学者は余裕みて一か月は欲しい。

# 対策と最適な勉強法
:::note info
体系的に学べる教材がない以上、
7版の黒本で学ぶのがセオリー。
PHP8系との違いについては独習PHPで拾う！
:::

:::note info
PHPの基本や基本文法中心に、Javaとの大きな違いをよく確認する！
:::
Azureのfreeプランでnodeアプリをホストする際に容量不足になった場合の対処方法

AzureWebAppsのフリープランで試しにホストする際、node.jsアプリだと度々デプロイに失敗します😥
その時、フリープランは1GBのストレージしかなく、デプロイ時にあげたzipファイルサイズやら、展開後のファイルサイズやら、node_modulesのサイズやらで容易に上限に達してしまいます、、(remixアプリをあげたときの所感です)
わざわざリソースを作り直すのも面倒なので、以下の手順でクリーニングを行って対処しました

:::note info
1. Azure Web Appsの高度なツールに接続する
2. bash接続を選び、`npm cache clean -force`を実行する
:::

上記によりストレージ内のnpmキャッシュがクリアされ、容量に余裕が出ると思います
検証はしていませんが`~/site/wwwroot`配下を`rm -r`することでも容量を削減でき、再度デプロイできるんじゃあないかと思います
~~時間がとれなかったので記事作成ちょっと手抜きしました~~
Laravelでcompact関数を使う意味

## はじめに
最近Laravelの学習を始めたのですが、コントローラからビューへ変数を受け渡す時によく使うcompact関数の具体的な働きがわからなかったので調べました。

## compact関数とは
引数で指定した変数名をキーとして、その変数の値を値とする連想配列を作成します。
Laravel独自のものでなく、PHPの組み込み関数です。
Laravelでは、コードをより簡潔で読みやすくするために使用されることが多いようです。

https://www.php.net/manual/ja/function.compact.php

## 具体的な動き
```php
<?php
$bikes = ['Cannondale', 'Cervélo', 'Colnago'];
print_r(compact('bikes'));
  // ['bikes' => ['Cannondale', 'Cervélo', 'Colnago']]
```
このように、`compact('bikes')`とすると、`$bikes`という変数が存在する場合にその変数をキー`'bikes'`として連想配列に変換します。

## Laravelでの使用例
```php:compact関数を使用しない場合
class ExampleController extends Controller
{
    public function show() {
        $name = 'Richard CARAPAZ';
        $team = 'EF Education - EasyPost';
        $bike = 'Cannondale';
        
        return view('example', ['name' => $name, 'team' => $team, 'bike' => $bike]);
    }
}
```

```php:compact関数を使用する場合
class ExampleController extends Controller
{
    public function show() {
        $name = 'Richard CARAPAZ';
        $team = 'EF Education - EasyPost';
        $bike = 'Cannondale';
        
        return view('example', compact('name', 'team', 'bike'));
    }
}
```
このように、compact関数を使うことでコードが簡潔になり読みやすくなります。
また、渡す変数が増えた場合でもリストを追加するだけで済むため、メンテナンス性も向上します。

## おわりに
Laravelにおいて、compact関数にはコードの可読性や保守性を高めるという重要な役割があることを知りました。
今後はそのことも意識しながら利用していこうと思います。
Security Hubのアラートメール おすすめ振り分け方法

## はじめに
Security Hubからのアラートを皆さんはどのように確認していますか？
今回は、Security Hubのアラートをメールで配信している場合の、おすすめの振り分け方法を共有します。

## Security Hubのアラート
Security Hubでは、GuardDutyやInspector、CIS Benchmark等のセキュリティ標準をはじめとしたセキュリティ製品のアラートを集約管理することができます。

Security Hub はセキュリティコントロールに対してチェックを行い、検出結果をアラートとして発出します。

検出結果はセキュリティイベントとして、EventBridgeと連携し、SNSを利用したアラートメール等の発報や、LambdaやRunCommand を利用した自動修復アクションの設定が可能です。

今回は、Security Hub → EventBridge → SNSでアラートをEmailで通知するケースにおいて、メールのおすすめの振り分け方法について共有します。

## Security Hubのアラート内容
### アラートの形式
Security Hubでは、デフォルトでAWS Security Finding形式を使用して検出結果が記載されています。

>Security Hub は、AWS Security Finding 形式 (ASFF) と呼ばれる標準検出結果形式を使用して検出結果を取得します。これにより、無数の情報源からの検出結果を複数の形式で管理する必要がなくなります。また、Security Hub はプロバイダー全体にわたり結果を関連付け、結果を優先順位付けします。

このアラートは分量が多く、形式を熟知していないと即時には読みとけないため、緊急度が高いアラートなのか、低いアラートなのかをフォルダレベルで分けることが有効になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/bef1f9e7-5d01-a25e-ade9-4de380039023.png)

### アラートの重要度
Security Hubにおいて、アラートに対する緊急度は「重要度」という項目から確認することができます。

> Security Hub コントロールに割り当てられる重要度は、コントロールの重要性を特定します。コントロールの重要度は、[Critical] (重要)、[High] (高)、[Medium] (中)、[Low] (低) または [Informational] (情報) のいずれかです。


以下の記事にも記載していますが、アラートの重要度に応じてどのような対応をするのかあらかじめ決めておくことをおすすめします。

https://qiita.com/utsunomiya_ff/items/8b2d2bb83bee949af184

メールの受信フォルダもアラートの重要度ごとに作成することをおすすめします。
重要度に応じてフォルダを作成することで、アラートに対してどのような対応が必要かわかったうえでアラートの内容を確認するため、その後の作業の効率化を期待できます。

### メールの振り分け方法
アラートメールの振り分けは、以下のルールで重要度ごとにそれぞれ設定することをおすすめします。
基本的には、本文中のLabelから重要度を振り分けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115411/a991a839-c87f-cb95-fc9c-6e6ca6017248.png)


なお、今回は重要度が重要・高・中・低のみを振り分ける設定としています。

また、Organizationsを利用する等で複数のアカウントのSecurity Hubを統合している場合、「"awsAccountId":"アカウントID"」を本文の条件に追加してください。

## おわりに
Security Hubのアラートメールの振り分け方法でした。
私のプロジェクトでは約30アカウントのSecurity Hubを統合しているため、アラートメールの振り分けがかなり重要となっているため、今回ナレッジとして共有しました。
是非参考にしていただければと思います。
【備忘録】WindowsでPythonコマンドを実行するとMicrosoft Storeを開く問題の解決方法


# 概要

PowerShellなどにおいて`python`コマンドを実行した際に`Python`が実行されずMicrosoft Storeが開くという問題が起きた．
この問題を解決し，正しく`Python`が実行されるようにする．

# 状況
## インストール時の手順
1. 公式のPythonインストーラ（python-3.12.4-amd64.exe）をダウンロード
2. ユーザ権限，add pathにチェックを付けPythonをインストール

## パスなどの確認
powershell，コマンドプロンプトでpythonコマンドを実行したが，どちらもmicrosoft storeを開いた．システムの環境変数のユーザの環境変数において，pythonのパスが追加されたことを確認．詳細は以下の通り．

```
ユーザの環境変数 → Path

C:\Users\<ユーザー名>\AppData\Local\Programs\Python\Python312\Scripts\
C:\Users\<ユーザー名>\AppData\Local\Programs\Python\Python312\
C:\Users\<ユーザー名>\AppData\Local\Programs\Python\Launcher\
C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps
...
```
先に述べると，一番下の`C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps`の部分が今回の問題の原因に関わっていた．


# 解決手順

## 原因

まず，この問題の原因として，pythonコマンドを実行した際，
`C:\Users\<ユーザー名>\AppData\Local\Programs\Python\PythonXX\python.exe`
ではなく
`C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps\python.exe`および
`C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps\python3.exe`の方の`python.exe`が実行されていたためである．
パスの順序的には`C:\Users\<ユーザー名>\AppData\Local\Programs\Python\PythonXX\python.exe`の方がMicrosoftのものよりも上にあったが，Microsoftのものが優先されて呼び出されていたらしい（これの原因は不明）．



## 方針
### ステップ1: Windowsの環境変数を確認

**状況**において既に環境変数を確認してあるが，一応，確認・追加の方法を記載する．

1. システムの環境変数 → 環境変数 → <ユーザ名>のユーザ環境変数．
2. Pathの中に公式インストーラでインストールしたPythonのディレクトリがリストに含まれていることを確認する．
     例: `C:\Users\<ユーザー名>\AppData\Local\Programs\Python\PythonXX\` および `C:\Users\<ユーザー名>\AppData\Local\Programs\Python\PythonXX\Scripts\`
   - 含まれていない場合は、「新規」ボタンをクリックして上記のパスを追加．

### ステップ2: Microsoft Store版のPythonショートカットを削除
`C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps` ディレクトリにあるPythonのショートカットが原因で問題が発生している．このパスを消してもよいが，影響の範囲が大きくなるため，`python.exe`，`python3.exe`のみを削除する．手順を以下に示す．

#### **管理者権限でコマンドプロンプトを使用して削除**:
   - Windowsの検索バーに「cmd」と入力し、「管理者として実行」を選択します。
   - 以下のコマンドを入力してファイルを削除します。
     ```cmd
     del C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps\python.exe
     del C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps\python3.exe
     ```

これでもしもできなかった場合は，以下を行い，ファイルの権限を変えることで削除できるようにする．

1. **エクスプローラーを開く**:
   - `C:\Users\<ユーザー名>\AppData\Local\Microsoft\WindowsApps` に移動．
   <br>

2. **ファイルの所有権を変更**: 
   - 削除したいショートカットファイル（`python.exe` および `python3.exe`）を右クリックして「プロパティ」を選択．
   - 「セキュリティ」タブに移動し，「詳細設定」ボタンをクリック．
   - 「所有者:」セクションの「変更」リンクをクリックし、自分のユーザーアカウントを選択して「OK」をクリック．
   - 「所有者をサブコンテナとオブジェクトに置き換える」チェックボックスをオンにし、「適用」をクリック．
    <br>

3. **アクセス許可を変更**:
   - 「セキュリティ」タブに戻り、「編集」をクリック．
   - 自分のユーザーアカウントを選択し、「フルコントロール」のチェックボックスをオン．
   - 「適用」および「OK」をクリックして変更を保存．


### Pythonの動作確認
コマンドプロンプトまたはPowerShellを再起動し、以下のコマンドを実行してPythonが正しく動作するか確認．
```cmd
> python --version
Python 3.12.4
```
できた．
クラウドコンピューティングとは？

今回はクラウドコンピューティングについて学習したので、学んだことをアウトプットしていこうと思います！
## クラウドコンピューティングとは
クラウドコンピューティングとは、インターネットを通じてデータストレージ、コンピューティングパワー、ネットワーキング、アプリケーションなどのコンピューティングリソースを提供するサービスのことです。クラウドサービスは、ユーザーが物理的なハードウェアを所有せずに、必要なときに必要なだけのリソースを利用できるようにすることで、多くの利点をもたらすことができます。

## クラウドコンピューティングの利点
- 1.コスト効率：
初期投資が不要で、利用した分だけの料金を支払う「従量課金制」が一般的です。これにより、企業はインフラストラクチャに対するコストを大幅に削減できます。


- 2.スケーラビリティ:
必要に応じてリソースを簡単にスケールアップまたはスケールダウンできます。急なトラフィック増加やプロジェクトの拡大に柔軟に対応できます。


- 3.柔軟性とアクセス性:
インターネット接続があれば、どこからでもアクセスできるため、リモートワークやグローバルなチームに最適です。

- 4.信頼性とバックアップ:
クラウドサービスプロバイダーは、高い可用性とデータの冗長性を提供します。データのバックアップや災害復旧が容易に行えます。

- 5.自動アップデート:
ソフトウェアやハードウェアのアップデートが自動的に行われるため、ユーザーは常に最新の技術を利用できます。

## クラウドサービスの種類
クラウドサービスは主に以下の3種類に分類されます：

- 1.IaaS (Infrastructure as a Service):
基本的なインフラストラクチャ（仮想サーバー、ストレージ、ネットワーキング）を提供します。ユーザーはオペレーティングシステムやアプリケーションの管理を行います。


- 2.PaaS (Platform as a Service):
アプリケーション開発やデプロイに必要なプラットフォーム（開発ツール、データベース管理システムなど）を提供します。ユーザーはアプリケーションの開発と管理に集中できます。

- 3.SaaS (Software as a Service):
完成されたソフトウェアアプリケーションをインターネット経由で提供します。ユーザーはアプリケーションのインストールやメンテナンスを気にすることなく利用できます。

## まとめ
クラウドコンピューティングは、コスト効率、スケーラビリティ、柔軟性、信頼性、自動アップデートなど、多くの利点を提供します。企業や個人がより効率的にITリソースを利用できるようにし、ビジネスの成長を支援します。適切なクラウドサービスプロバイダーとセキュリティ対策を選ぶことで、安心してクラウドの利点を受けることができます。
python3 -m pip install の失敗例 - ヘッダファイルがない-

`python3 -m pip install パッケージ名` で
ヘッダファイルがなくて、build に失敗する事例があった。
それへの対処事例を記す。

## 発端
あるリポジトリのinstall 作業の中で、上記のパッケージをインストールしようとしたところ、ソースコードからのビルドのなかで、ヘッダファイルがないとしてビルドに失敗、pip の実行にも失敗した。
そこで以下のようにして解決した。

## 解決手順
- whlファイルの中身をみてみよう
```
python3 -m pip download パッケージ名
```
を実行した。

そうすると パッケージ名-バージョン情報.whl
が入手できる。

その中でソースコードのtar.gz ファイルをtar zxvf *.tar.gz で展開しました。

やはり、その中に問題のヘッダファイルがありませんでした。

pypi のパッケージ名 のサイトを確認しました。
その中にgithub のリポジトリ情報がありました。
そこから該当のヘッダファイルを見つけました。
そのヘッダファイルを、cppのソースコードから見た適切なフォルダにコピーしました。

その後
```
python3 -m pip install .
```
を実行しました。
その結果installに成功しました。
```
$ python3
>>> import パッケージ名
>>>
```
でimport が無事行われていることを確認できました。

## 結局
```
git clone 該当のモジュールのgit
python3 -m pip install .
```

するのと、ほとんど同じになってしまっている。

## TODO
PyPI上のパッケージの作者に連絡して、対応をお願いすること。
nanoの使い方

# はじめに
Linuxの端末上でファイルの編集作業を行う際、コマンドラインで動作するエディターを使用する必要があります。Linux上で使えるエディターは多くありますが、初めて使用する方は``nano``を使うのが良いでしょう。
以下では``nano``の使い方を、ごく簡単に説明します。

# 使い方
ここでは``nano``を使って``hello.f90``というプログラムを書いてみましょう。
コマンドプロンプト上で以下を実行します。
```
nano hello.f90
```
すると以下のような画面が現れます。
![nano_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837941/2a5f96ec-3d4c-cd4a-1cfc-7be56020f980.png)
マウスは使用できませんが、文字の入力は通常のエディターと同様にすれば良く、カーソルの移動には矢印のコマンドを使用すれば良いでしょう。
``nano``の操作に必要なコマンドは画面の下に表示されています（``^``はコントロールキーを意味しています）。

例えば以下のようなプログラムを書きます。
```bash
program main
implicit none
write(*,*)'Hello World!'
end program
```

書いたプログラムを保存したい場合はコントロールと``x``を同時に押します（終了のコマンド）。すると以下のように画面の下にバッファーを保存するかどうかを尋ねるプロンプトが現れます。
![nano_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837941/584ab160-fad2-7cdf-e642-1b6d6e9a8438.png)
保存する場合には``y``を入力します。すると以下のように保存先を聞かれますので、ファイル名を変更しない場合にはそのまま``Enter``を、変更する場合には新しいファイル名を入力します。
![nano_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837941/f68eeef9-b325-627c-6a7e-bc670ba71052.png)

# まとめ
簡単ですが、これだけで最低限のファイルの編集操作は可能です。その他の機能は``nano``の画面下に現れるキーを自分で実行してみて何が起こるのか試してみると良いでしょう。私は``vim`` (``vim``)を使用していますが、``emacs``も多くの方が使用されていると思います。[Visual Studio Code](https://code.visualstudio.com/)もリモート端末からの接続方法も含めて使い方を覚えるとそちらの方が便利かもしれません。
SwiftUIでプロジェクト作成直後にPreviewがエラーで表示できない

2024年5月ごろから私用端末でSwiftUIでPreview機能が全然機能しなかった。プロジェクト作成直後にも関わらずエラーで表示できない

発生したエラーや何を試したかをいちいち記録していたわけではないが、HumanReadableSwiftError()やらでWaiting for Preview...でXCodeのbuildがビルドが止まっている

そこでClean Build FolderやDerived Dataの削除、XCodeの削除やMacの再起動、ビルドする端末を変えるなどありとあらゆる方法を試してみたが結局解決できず痺れを切らして個人開発プロジェクトのFlutterへの移行を検討した

VSCodeでFlutterの最新版を落としてプロジェクト作成してからiOS Simulatorの起動を試す。その際Simulatorが立ち上がるのが遅かったので、シミュレーターを呼び出す目的のためだけにXCodeで該当プロジェクトのビルドを走らせたところ何故かうまくアプリがビルドできていたしPreviewも走っていた

なにを言っているのか分からないと思うが私も分からない

いかんせんこのエラーに関して情報量が少ないし開発が進まなくてストレスがマッハだったので、一応同じような現象にハマった人に共有

#
まとめ
・Flutterで一度ビルドが走るか試してみよう


https://forums.developer.apple.com/forums/thread/690766
https://qiita.com/AkkeyLab/items/e26b38de8a0d68014aa1
https://forums.developer.apple.com/forums/thread/664227
https://forums.developer.apple.com/forums/thread/748204
[Slidev] ワンクリックで要素の非表示と別要素の表示を行う方法

## この記事が役立つかもしれない人

* クリックで要素の非表示と表示を同時に行いたい人
* 表示を切り替えた際の表示位置を調整したい人
* クリック操作による表示変更も含めてエクスポートしたい人


## 手順
### ワンクリックで要素の非表示と表示を行えるようにする

```md: slides.md
---
layout: default
---

# 表示切り替えのテスト

<div v-click.hide>

## 内容 A

- `v-click.hide` の付いた要素内にある要素はクリックすると隠れます

</div>

<div v-after>

## 内容 B

- 内容 A の非表示と同時に現れます
- `v-after` は一つ前にある `v-click` が発動したのをトリガーとして表示を行います

</div>

```

![slidev-click1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/109f8c64-49bb-9f22-b292-4b2335d014d1.gif)

ワンクリックでの要素の非表示と表示を達成できました！
内容 B 上部の余白については、このあと対応していきます！

#### 詳細

重要なのは `div` 要素に付いているディレクティブ `v-click.hide` と `v-after` です。

`v-click.hide` の付いた要素はクリックすることで隠れます。これはクリックで表示させる `v-click` の派生ディレクティブです。

`v-after` は一つ前の `v-click` がトリガーされた時に表示されます。これは `v-click.hide` の場合でもトリガーされます。


### 余白を作らずに `v-after` の要素を表示する

先ほど確認した通り、`v-after` で表示させた要素は上に余白を残して表示されています。
これは `v-click.hide` で隠れた `div` 要素が隠れただけ (`opacity: 0;`) で存在しているために起こります。そのため "`v-after` の付いた要素" が "見えないが存在している要素" の下に出現することで余白が生まれてしまいます。

対応としては `v-click.hide` の要素を隠す CSS クラスを改造して非表示にした要素を無効化します。

```md: slides.md
---
layout: default
---

# 表示切り替えのテスト

<div v-click.hide>

## 内容 A

- `v-click.hide` の付いた要素内にある要素はクリックすると隠れます

</div>

<div v-after>

## 内容 B

- 内容 A の非表示と同時に現れます
- `v-after` は一つ前にある `v-click` が発動したのをトリガーとして表示を行います

</div>

<!-- ここから下を追加しただけ -->

<style>
.slidev-vclick-hidden {
  display: none;
}
</style>
```

![slidev-click2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/3b455112-7d24-58dd-1733-58c98fe61fda.gif)

#### 詳細

要素が非表示になると Slidev が自動で `slidev-vclick-hidden` というクラスを付与します。
上記の Markdown では、そのクラスを利用して `display: none;` で表示を無効化しています。

### クリック操作の内容も含めてエクスポートする

Slidev には作成したスライドを pdf などでエクスポートする機能が備わっています。
しかしスライドをデフォルトでエクスポートするとクリック等の操作を終えた最後の状態のスライドしかエクスポートされません。

:::note warn
<details><summary>デフォルトの実行例</summary>

```bash
yarn run slidev export 
```

![slidev-export1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/89a72a21-7b62-eeb6-8f1b-ea4405f4801a.png)

</details>
:::

そこでクリック操作も含んだ状態でエクスポートされるようにオプションを渡します。

```bash: オプションを渡した実行例
yarn run slidev export --with-clicks
```

![slidev-export2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/b3d1ec94-9bcf-0f27-9c1d-cfa0d15fbe62.png)

:::note 
<details><summary>npm を使用している場合</summary>

`npm run export` でエクスポートが可能です。
クリック操作も含めたい場合は`package.json` を編集します。

```diff_json: package.json (一部抜粋)
  "scripts": {
    "build": "slidev build",
    "dev": "slidev --open",
+   "export": "slidev export --with-clicks"
  }
```

この編集後に `npm run export` を行うとクリック操作も含まれたエクスポートが作成されます。

</details>

:::


これですべての内容が含まれるスライドをエクスポートすることができました。
この記事が役に立ったら 🩷 を頂けると嬉しいです！

## 参考記事

https://sli.dev/guide/animations
time

import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

class WeekRange {
    private LocalDate startDate;
    private LocalDate endDate;
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

    public WeekRange(LocalDate startDate, LocalDate endDate) {
        this.startDate = startDate;
        this.endDate = endDate;
    }

    public LocalDate getStartDate() {
        return startDate;
    }

    public LocalDate getEndDate() {
        return endDate;
    }

    @Override
    public String toString() {
        return "WeekRange{" +
                "startDate=" + startDate.format(formatter) +
                ", endDate=" + endDate.format(formatter) +
                '}';
    }
}

public class WeekRangeCalculator {

    public static List<WeekRange> getWeekRanges(String start, String end) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate startDate = LocalDate.parse(start, formatter);
        LocalDate endDate = LocalDate.parse(end, formatter);

        List<WeekRange> weekRanges = new ArrayList<>();

        // 找到第一个开始日期的周一
        LocalDate currentStart = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        // 找到最后一个结束日期的周日
        LocalDate finalEnd = endDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));

        while (!currentStart.isAfter(finalEnd)) {
            LocalDate currentEnd = currentStart.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
            weekRanges.add(new WeekRange(currentStart, currentEnd));

            // 下一个周的开始日期
            currentStart = currentStart.plusWeeks(1);
        }

        return weekRanges;
    }

    public static void main(String[] args) {
        String start = "20260801";
        String end = "20260831";
        List<WeekRange> weekRanges = getWeekRanges(start, end);

        for (WeekRange range : weekRanges) {
            System.out.println(range);
        }
    }
}
EditTextを活性化する５つの方法


# はじめに
今回この記事を書こうと思ったきっかけは、 EditTextがある条件の時に使えなくなるケースがあり 他Viewと同じようにenabledを操作して簡単に不具合を治せると思っていたところ　上手くいかず。その際に調べたところいくつか出てきたのでそれを記事にしていこうと思います。

この記事では、５つそれぞれの使い方と一言メモ的なものを残しておこうと思います。

# enabled
活性・非活性を切り替える

単純に使用させない時などに使う
```
EditText.enabled = true
```
```
<EditText ...
        android:enable="true">
```
# clickable
click可能不能を切り替える

clickイベントを使用するときに切り替える
```
EditText.clickable = true
```
```
<EditText ...
        android:clickable="true">
```

# cursorVisible
カーソルの表示・非表示を切り替える

視覚的にEditTextが使用できる状態であることを表せる

```
EditText.cursorVisible = true
```
```
<EditText ...
        android:cursorVisible="true">
```


# focusable
EditTextのフォーカス可能・不可能を切り替える

上書きやコピペなどをさせたくない時に使う
```
EditText.focusable = true
```
```
<EditText ...
        android:focusable="true">
```

# focusableInTouchMode
Viewをタッチすることでフォーカス可能・不可能を切り替える

今回の不具合はこれを追加したら治った
**FOCUSABLE_AUTO**をしているするとclick可能な時だけフォーカス可能にできる


```
EditText.focusableInTouchMode = true
```
```
<EditText ...
        android:focusableInTouchMode="true">
```


# 参考
https://stackoverflow.com/questions/3928711/how-to-make-edittext-not-editable-through-xml-in-android


https://tomorrowkey-2.hatenadiary.org/entry/20091012/1255334049

https://qiita.com/yasukotelin/items/c2b3c6d9e410c9a67d1c

https://android.suzu-sd.com/2020/10/android_focus_touchmode/#focusableInTouchMode
【React+Typescript+Vite】 デジタル名刺アプリを作成

# はじめに

React学習の一つとしてデジタル名刺アプリを作成しました。

前回作成した学習記録アプリよりもレベルアップしたことは、React Routerを用いて複数ページを作成していることと、バッチ処理を用いてデータ管理を行なっていることです。

# 作成したアプリ
![Video.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/a7f63420-6676-9560-3efb-f1c0c47a4fe0.gif)



### 概要

学習した時間や学習した内容を簡単に記録できるアプリ

### 使用言語・ライブラリ

Typescript, React

### DB

Supabase

### テスト

Jest

React-testing-library

### その他

Firebase

Github

React Router

## 実装機能
### Homeページ
こちらから名刺登録ページと登録された名刺を検索するページへ遷移できます。
![スクリーンショット 2024-08-04 10.25.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/9e93733d-0211-97a4-d221-73545f2d9133.png)

### 新規登録ページ
新しく名刺を作成することができます。
![スクリーンショット 2024-08-04 10.20.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/12484dcb-d5cc-2710-24c0-15bbe028351a.png)

### 名刺検索ページ
名刺を作成するときに登録したidで登録済みの名刺を検索できます。
![スクリーンショット 2024-08-04 10.26.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/637efcb1-9156-0ba5-af51-7dcbd20d6166.png)

### 検索された名刺
検索結果の名刺が画面に表示されます。
![スクリーンショット 2024-08-04 10.26.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/af0ca361-70ba-9e8e-f98e-cbbaac400ea1.png)


# 大変だったこと

こちらのエラー記事にも書いたのですが、バッチファイルを作成してテーブルの削除を一括で行う設定をする時が大変でした。

https://qiita.com/acu8/items/1a4d0d243adb06ccb9af


というのも、エラーがどうして発生しているかはわかっていても、どこをどう直せば問題が解決するか調べてもあまり情報が出てきませんでした。

AIを使ったりしても解決できないときは、何が原因になっていてエラー解決にどういう選択肢があるのかを一度冷静になって整理をしてから進めることが大切だと実感しました。

# 今回の開発で得た気づき

今回は初めてReact Routerを実装して複数ページを作成しました。React Routerについてはインプット教材で学んだ時にとても難しく感じましたが、実際に今の最新版であるv6を使ってみると意外とシンプルに実装ができたので難しいイメージが変わりました。

また、少し前まではエラーが出てすぐに解決できないと落ち込んで数時間放置してしまったりしていましたが、今はエラーが出ても数時間は何度も色々な方向性で解決策を考えてトライできるようになってきました。筋トレと同じような感じでエラー解決筋的なものが強化されてきたのかもしれません。


# おわりに
今回開発を進めていて思ったのは、前まで難しいと感じて時間がかかっていた工程がサクサク進めることができるようになっていることでした。苦手だったテストやデプロイも何度もやっていくうちに慣れるし、こうしたらいいのでは？と自分で考えらえるようになってきました。
JISOUの提供してくれる工程通りに開発を進めるのはこのアプリが最後です。次回からは自分で全て考えてアプリ作成をしていくので、別の新しい壁にぶつかると思いますが、今までのアウトプット経験を活かして一つ一つ解決をしていきたいと思います。
次のアプリを作成したら記事にする予定です。最後まで読んでいただきありがとうございました！

# JISOUのメンバー募集中！

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
実践的なカリキュラムで、あなたのエンジニアとしてのキャリアを最短で飛躍させましょう！
興味のある方は、ぜひホームページからお気軽にカウンセリングをお申し込みください！
▼▼▼

https://projisou.jp/
休み明けに自己嫌悪感が強くなってしまう人へ

# いつもの日曜日
21時ごろの日曜日。
辛い。もやもやする。
今週も何もできなかった。時間はあるのに。
やればいいのに。なんで目の前のやらないといけないこともできないんだろう
しょーもな。
だからいつまでたっても何も成し遂げられんやん。
のくせして理想だけ高い、口先だけ野郎やん

# 記事作成経緯
・・・みたいなことを毎週繰り返して、辛い、しんどい。
連鎖的にいろんな自分を責める理由が見つかって、自分自身への嫌悪感が強くなり、
何もしたくない。全てから逃げ出したい。みたいなことが自分はよくありました。

よくあることではあったものの直近、すごく感情が沈むことが多くなり、
この状況はよくないなーと思い、自分の感情を整理し始めました。

比較的最近は整理して試していた結果、気持ちが楽にはなってきたので、
以降では考えたことや取り組んだことをメモしていこうと思います。
目新しいことは無く、完全な個人的な主観ですが、同じようなことで苦しんでる人の助けになれば幸いです

# 整理
気持ちが落ち着いてるタイミングで改めて自分を見返したときに、下記が気になりました
* 何もできてないけど、誰かが困っているわけではない
* 誰かに責められているわけでもない
* 過去の失敗を連鎖的に思い出す
* 自分自身が一番の敵になっている
* 小さなことでも「やった」という事実があると気持ちが楽になる
* やりたくないけどやらないといけない作業は実はやってみるとそんなに時間がかからない
* (何かやってたとしても)自分が前に進んでいる気がしない

# 対策
上記を踏まえて、下記を意識的に取り組むようにしました
* 他人や想像上の自分と比較しない。過去の自分と比較する
* 積極的に小さくタスク化する
* タスクが消化されたことを見える化する
* 意識的に自分をほめる
* 現状の改善や将来については休みの前日の夜か休みの1日目に考える

## 他人や想像上の自分と比較しない。過去の自分と比較する
作業の始まりなどに、きらびやかな理想と比較することはモチベーションとして価値があると思うのですが、
振り返りにおいて、すごく危険だと思います。
もちろん、悔しさに変えエネルギーに変えられる気持ちの余裕があるのならその比較に価値はあるとは思います。
でも自分を責める理由になるだけならいらないです。

かつ、詳細はおいておいたとして、きらびやかに見えるのは「今の自分にできないから」を理由に持っていることがあると思います。
できた時に褒めることはあっても、できないことを否定する必要はありません。
できないことが今まで通りの自分です。

理想ほどでなくても、
先週の自分がやってなかったことをとりくんだならほめたっていい！

## 積極的に小さくタスク化する
なんとなく「アプリを作る」みたいな大きな粒度感のやることだけを抱えていると達成が難しく、できなかったことだけが目に付いて、自分を責める理由になりがちです。
「アイデアを5分間だけブレストする」とか「本を買う」とか、とりあえずできることで一旦いいです。

何か作成しないといけない資料があるけど、作る気が起きないとかの場合
「資料を開く」「資料のファイル作成する(中身空)」とかでもいいです。
だいたい、そのタスクが終わったとして、そのまま何もしないことはないです。資料作成につながる何か作業が連動して実施されます

## タスクが消化されたことを見える化する
自分は、普段のタスク管理にnotionを使っています。
ページ内で未着手のタスクと本日完了済みのタスクが表示できるものを用意して、自分が実施したことを見えるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812194/9ead5c6c-209e-cb02-de58-69a7066afc35.png)

また、日曜日とかは、完了したことを後から追加で書くこともあります。
何かやったことがなかったけ？
別に今日やらなくてよかったけどやったことはなかったけ？
小さいことでも書くように心がけるように最近意識し始めました。

自分の中でチェックマークをつけて「完了」に変わることが
頑張った自分の認識となり、精神的に救われました。
自分の場合は、何をやったかという質より何かをやった自分を気にしている印象があります。
なので、なんとかしてチェックマークを付けて「完了」に増やせるものをつくろうとしています。
タスク管理という目的に対しての行動からは少し外れますが、気持ちを前向きにするため、私がすべきことだとおもっています。

## 意識的に自分をほめる
落ち込んでいる時は特にですが、タスクの完了など何か理由を探して、自分で自分をほめたほうがいいです。
自分がほめる言葉を否定することが見つかっても、ほめたほうがいいです。
あと周りに人がいないなら口にだしたほうがいいです。
天才か？
つよつよ！
やば、、すごすぎる
効果を感じなくてもすべきです。
何度かやってると「確かに・・！」とか調子乗り始めるので。
自分が自分にとっての敵である必要はないので、意識的に自分の味方をしてあげましょう。

あと毎日5分とかでもいいのでできる「やったほうがいいこと」を習慣化するだけでもほめる理由が作れます。

## 現状の改善や将来については休みの前日の夜か休みの1日目に考える
往々にして、振り返りは自分を責める理由になりがちです。
○○をすべきだった。××はよくない。
といった改善はもちろん必要ではあるのですが、休みの最終日にすべきではないです。

やたらと無敵感のある休みの前日の夜や休みの1日目がおすすめです。
だいたいそういう時は趣味にとりくみがちですが、「辛い日曜日」を避けるために、時間をつくったほうが精神衛生的にいいです。

# 最後に
なんでこんなに自分に敵意が強いんだろうとは思いつつも、
昔からの性格なので、ときおり向き合うようにはしようと思います。

また、気持ちを整理したことや上記を取り組んだことで深く沈む日は減った気がしています。

今の所気持ちが沈んでしまってから浮き上がる方法はあまりないので、
沈まないために休みの最終日以外での事前の工夫を考えていこうと思いました。
FlutterでGoogleMapを表示する

## はじめに
表題通り、FlutterでGoogleMapを表示する。

## 準備
GCPでGoogleMapsを有効化し、APIキーを発行する必要があります。
Maps SDK for AndroidでAPIキーを発行します。
![スクリーンショット 2024-08-04 18.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/1d16c530-f95d-f704-db33-e69a2083d2bf.png)

## プログラム改修
プロジェクト設定後取得したAPIキーを設定します。

・Androidの設定

```xml:android/app/src/main/AndroidManifest.xml
<manifest ...
  <application ...
    <meta-data
      android:name="com.google.android.geo.API_KEY"
      android:value="YOUR_API_KEY"/>
  </application>
</manifest>

```

・iOSの設定

```swift:ios/Runner/AppDelegate.swift
import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("YOUR_API_KEY") // ここにAPIキーを設定する
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
```

```ruby:Podfile
platform :ios, '14.0' // 14.0以上に設定

target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  target 'RunnerTests' do
    inherit! :search_paths
  end
  pod 'GoogleMaps' # ここに追加
end

```

:::note info
iosのplatformは14以上に設定しておく必要があります。
:::


## ソースコード

```dart:lib/main.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MapSample(),
    );
  }
}

class MapSample extends StatefulWidget {
  @override
  State<MapSample> createState() => MapSampleState();
}

class MapSampleState extends State<MapSample> {
  GoogleMapController? mapController;

  final LatLng _center = const LatLng(35.681236, 139.767125); // 東京駅の緯度経度

  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Google Maps Example'),
        backgroundColor: Colors.green[700],
      ),
      body: GoogleMap(
        onMapCreated: _onMapCreated,
        initialCameraPosition: CameraPosition(
          target: _center,
          zoom: 11.0,
        ),
        markers: {
          Marker(
            markerId: MarkerId('marker_1'),
            position: _center,
          ),
        },
      ),
    );
  }
}

```

## 実行
flutter runで実行します。GoogleMapが表示されるようになりました。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/397a7997-6e36-1262-af8b-9998243102ed.png">