OmniAICreator/Qiita-1.07M huggingface dataset:
DevRelとは？？？ #2

Voicy で SRE してます。
[#1](https://qiita.com/penguin425/items/05ccfd1619a07db69fc3) の続きで、日本的 DevRel について調べたことを書きたいと思います。
あくまで、調べた範囲なので、そのあたりはご容赦ください。

## 日本的 DevRel とは
日本的なDevRelは、海外、特にアメリカで生まれた DevRel の概念が日本独自の文脈で解釈され、変化したものです。

## 特徴
- マーケティング・広報色が強い: 欧米では開発者との技術的な交流やコミュニティ育成に重点が置かれることが多いのに対し、日本では製品・サービスの認知度向上や採用活動など、マーケティング・広報的な要素が強い傾向があります。
- イベント運営に注力: 開発者向けのイベントや勉強会を頻繁に開催し、参加者との交流を通じて関係構築を図るケースが多いです。
- コミュニティマネージャー的な役割: オンラインコミュニティの運営や、開発者からの問い合わせ対応など、コミュニティマネージャー的な役割を担うことも多いです。
- 技術力よりもコミュニケーション能力重視: 深い技術的な知識よりも、開発者と円滑にコミュニケーションを取れる能力が重視される傾向があります。

## 背景
このような日本的な DevRel が生まれた背景には、以下のような要因が考えられます。

- IT人材不足: 日本では慢性的なIT人材不足が課題となっており、優秀な開発者を確保するために、DevRel が採用活動の一環として位置づけられるケースが多いです。
- 開発者コミュニティの未成熟: 欧米に比べて、日本の開発者コミュニティは規模が小さく、未成熟な部分があります。そのため、企業が積極的にコミュニティ育成に取り組む必要があります。
- 文化的な違い: 日本では、欧米に比べて、直接的なコミュニケーションよりも間接的なコミュニケーションを重視する傾向があります。そのため、イベントなどを通じて交流する機会が重要視されます。

## 課題
日本的な DevRel は、マーケティング・広報色が強いあまり、本来の目的である開発者との長期的な関係構築がおろそかになっているという指摘もあります。また、イベント運営に偏っているため、オンラインでの情報発信やサポート体制が不足しているという課題も抱えています。

## 今後の展望
近年、日本でもDevRelの重要性に対する認識が高まり、海外の事例を参考にしながら、より本質的な活動に取り組む企業が増えてきています。今後は、開発者との双方向のコミュニケーションを重視し、長期的な信頼関係を構築していくことが重要になるでしょう。

## 補足
DevRel は比較的新しい概念であり、まだ明確な定義や活動内容が確立されているわけではありません。そのため、企業や担当者によって解釈や取り組み方が異なる場合があります。

## というのが・・・
日本的な文脈の DevRel のあり方のようです。
賛否両論あるかと思いますが、発展途上の分野なので個人的には色々と議論があってよいとは思います。

## 参照
- [日本におけるDevRelとは何なのか、現状と課題と今後](https://blog.kushii.net/archives/2024/10/13/205852)
- [DevRel/Japan CONFERENCE 2024](https://devrel.tokyo/japan-2024/)
- [ヤフーの「DevRel」って何する人？ 社内外クリエイターの熱量をつなぐ取り組みの全貌](https://seleck.cc/1490)

## 宣伝
Voicy では voi-chord というエンジニアでやっている音声番組があります。
その中で、「エンジニアイベント運営の裏側！」ということで、対談番組を収録しましたので、是非ご聴取ください！

https://r.voicy.jp/jpVEOJaDmJ6

https://r.voicy.jp/v2mvepkAKrG
【個人メモ】Ruby on Rails チュートリアル 第7章

Ruby on Railsチュートリアルで学んだ内容を個人的なメモとして簡単にまとめたものです

# 個人メモ
- debugメソッドとparams変数を用いてページにデバッグ情報を表示できる
- Railsの３つの環境
test環境、debelopment環境、production環境がある
- resources :users
REST機能を実装するために必要な一文
名前付きルーティングとUsersリソースで必要になる全てのアクションを有効にすることができる
- params[:id]でidに対応したデータを取得することができる
- debuggerメソッド
ターミナルにrdbg（Ruby debugger）プロンプトが表示される
バグが発生した際、怪しい箇所に差し込めばシステムの状態を調査できる
- Gravatarでユーザー画像とメールアドレスを関連づけることができる
- form_withメソッドを用いることでユーザー登録フォームが作成できる
- Srtong Parameters
必須パラメータと許可済みパラメータを指定すること
これにより許可していない属性をparamsハッシュに紛れ込ませることが不可能になる
- privateキーワード
特定のメソッドを外部から使えないようにする
- errors.full_messagesオブジェクト
エラーメッセージの配列を持つ
- any?メソッド
オブジェクトが空ならtrue
- pluralize
英語専用のテキストヘルパー
- status: :unprocessable_entity
HTTPステータスコード422 Unprocessable Entity
Rubyの基本（変数/型/条件分岐/メソッド/クラス等）

# Ruby

サイトではなく、Webアプリケーションを作るための言語として、日本人によって作られた「楽しさ」を重視した言語

- `puts` など、命令を出すものを **メソッド（関数）** といい、複数の処理を1つにまとめたもの
- メソッドに渡す値を **引数** という

## 変数と定数

### 変数
- 変数：値を変えることが可能（代入できるもの）
  - 変数名の1文字目は、小文字のアルファベットか `_`（アンダースコア）のみが使用可能
  - 数字で始まる変数名はNG

### 定数
- 定数：値を変えることができないもの
  - 定数の始まりは大文字で、 `_` で区切る（スネークケース）

---

## 型変換

文字列や数値をそれぞれの方に変換し、組み合わせることができる
| 型変換方法 | 説明 |
| --- | --- |
| `.to_s` | 整数→文字列 |
| `.to_i` | 文字列→整数 |

上記の方法を使うと煩わしい場合があるため、**変数展開**や**文字列展開**（"#{word}"）が便利
**ダブルクォーテーションで囲った場合のみ**機能し、どんな型も変換できる

```ruby
name = "太郎"
weight = 60
puts "#{name}さんの体重は#{weight * 2}kgです" 
# 出力: 太郎さんの体重は120kgです
# 入力は {} （波括弧）、出力は [] （角括弧）
```
---
### 👉🏻 if条件分岐</aside>

`==`   ：　一致
`!＝`：　不一致
`!`　：　否定
`&&`  ：　どちらも正しければ
`||`  ：　どちらかが正しければ

---
### 👉🏻 while
指定した条件式が真（true）の間、繰り返し実行

```ruby
while 条件　do
    処理
end
```

---
### 👉🏻 for
範囲内を**順に**繰り返す
```ruby
for 変数 in(範囲,ハッシュ,配列) do
    処理
end
```

---
### 👉🏻 rand
ランダムで数字を出力
ゲーム内のサイコロをイメージすると分かりやすい

無限ループが発生した場合、Ctrl＋Cで強制終了

---
### 👉🏻 each
要素を順に取り出す
```ruby
(ハッシュ等).each do |変数|
    処理
end
```

break：強制終了

---
### 👉🏻 メソッド
複数の処理を１つにまとめて扱いやすくしたもの

**length**

文字列型に使用すると文字数を数えてくれる

```ruby
puts "Qiita".length
# 出力: 5
```


### **reverse**
文字列を逆に表示

```ruby
puts "Qiita".reverse
# 出力: atiiQ
```


**include?**

引数に指定した文字列が含まれているかどうかを調べる

```ruby
puts "Qiitaでアウトプット".include?("Qiita")
# 出力: true
# 含まれていない場合はfalseが出力
```

**methods**

使用可能なメソッドを一覧で表示できる

```ruby
puts "Qiitaでアウトプット".methods
# 出力: encode
#　　　 encode!
#　　　 include?
#　　　 %
#　　　 *
#　　　 +
#　　　 count
#　　　 partition
#　　　 sum
```

**def**

オリジナルのメソッドを作れる！

```ruby
def メソッド名(引数)
	処理(戻り値)
end
```

例

```ruby
def greeting(name)
  "Hello, #{name}!"  # この行のnameは、引数で渡すname
end
puts greeting('John')  # 'John'を引数として渡す

# 出力: Hello, John!
```

```ruby
def greeting(name)
  return "Hello, #{name}!"
  "Good morning, #{name}!"
end
puts greeting('John')

# 出力: Hello, John!
```

重複する場合は後者が返されるが、returnを追加すれば、returnが返される

---
### 👉🏻 シンボル　:シンボル

`：コロン`で定義したものを、シンボルと言う
文字列とは違い、シンボルは不変で、プログラム内で1つだけのインスタンスを持つため、
同じ名前のシンボルは常に同じオブジェクトIDを持つ
この特性が、シンボルの処理が高速である理由の一つ

- .object_id(メソッド)

オブジェクト固有の**id(割り振られた整数)を取り出す**ことができる

```ruby
# 文字列オブジェクト
dog1 = "犬"
dog2 = "犬"

# シンボルオブジェクト
dog3 = :犬
dog4 = :犬

puts dog1.object_id
puts dog2.object_id
puts dog3.object_id
puts dog4.object_id
```

実行したとすると、以下のような結果になる

```ruby
<文字列オブジェクトの場合>
70292126869460
70292126869440
<シンボルオブジェクトの場合>
1058268
1058268
```

整数管理しているため、処理が高速で、検索などに向いている


つまり他のデータとは**重複しない**ことが保証されており、
このように**「同じものが複数あると困るもの」**を扱う時にシンボルが使われる。

---
### 👉🏻 class

class内は、メソッドを集約したようなもの(設計図)
class内のメソッドを**インスタンスメソッド**という

- クラス　　　：設計図
- メソッド　　：設計図の内容
- インスタンス：設計で作られるもの

インスタンス名　= 　[クラス名.new] 　：　代入
インスタンス名.メソッド名(引数)　　　：　呼び出し

- `.class`  ：　どのクラスに属するか調べることができる
- `.join()`  ：　()内の文字を、文字の間に入れる
- `self.メソッド(引数)`　：　.newは不要で、クラスメソッドとして1行で呼び出すことができる

---
### 👉🏻 『クラスの継承』

親クラスから継承することで、子クラス内で再度定義（メソッド）する必要がない
＝可読性が高いコードになる！！

継承すべきか迷った時は、『AはBの一種である(is-a)』が成立するかで考える
例えば・・・ バスは車の一種である
　　　　　　 猫は動物の一種である

`オーバーライド`：子クラスで親クラスの上書きができる

子クラスのメソッド内に「super」と書くと、親クラスの同名メソッドを取り出すことができる

`.superclass`で親クラスを調べることができる
DevRelとは？？？ #1

Voicy で SRE してます。
今日は、最近議論が盛んな DevRel に関して、少し気になったので調べてみました。
あくまで、調べた範囲なので、そのあたりはご容赦ください。

## そもそもの DevRel とは
DevRel とは Developer Relations の略で、直訳すると「開発者との関係」という意味です。
簡単に言うと、企業が外部の開発者と良好な関係を築くための活動 全般を指します。

## 目的
DevRel の目的は、企業と開発者の双方にとってメリットのある関係を築くことです。企業側は、開発者に自社製品・サービスを知ってもらい、利用・貢献を促すことで、ビジネスの成長を目指します。一方、開発者側は、企業から情報やサポートを得ることで、開発効率やスキル向上を期待できます。

## 具体的な活動内容
DevRel の活動内容は多岐に渡り、企業や製品・サービスによって異なりますが、代表的なものとしては以下のようなものがあります。
- 情報発信: ブログ記事、技術ドキュメント、サンプルコードなどを提供することで、開発者に役立つ情報を発信します。
- コミュニティ活動: 開発者向けのイベントや勉強会を開催したり、オンラインコミュニティを運営したりすることで、開発者同士の交流を促進します。
- サポート: 開発者からの質問や要望に対応することで、製品・サービスの利用を支援します。
- フィードバック収集: 開発者から製品・サービスに対するフィードバックを収集し、改善に活かします。
- 広報活動: メディアへの露出や講演などを通じて、企業や製品・サービスの認知度向上を図ります。

## DevRel の重要性
近年、DevRel の重要性が高まっている背景には、以下の要因が挙げられます。
- オープンソースソフトウェアの普及: 多くのソフトウェアがオープンソース化され、開発者コミュニティの影響力が拡大しています。
- クラウドサービスの普及: クラウドサービスの利用が当たり前になり、開発者がサービスを選択する際に、開発者向けのサポート体制が重視されるようになっています。
- 開発者不足: IT 人材の不足が深刻化しており、優秀な開発者を確保するために、DevRel が重要な役割を担っています。

## DevRel の事例
多くの企業が DevRel に取り組んでいますが、代表的な事例としては以下のようなものがあります。
- Google: Google Developers を通じて、開発者向けのドキュメント、ツール、イベントなどを提供しています。
- Microsoft: Microsoft Learn や Azure のドキュメントなどを通じて、開発者向けの情報を提供しています。
- Amazon: AWS のドキュメントや AWS re:Invent などのイベントを通じて、開発者向けの情報を提供しています。

## まとめ
DevRel は、企業が外部の開発者と良好な関係を築くための活動です。開発者に対して情報発信やサポートを行うことで、企業は製品・サービスの利用促進や開発者コミュニティの活性化を図ることができます。

## というのが・・・
元々の DevRel 文脈で言われていて、欧米などでの DevRel のあり方のようです。
次回は、日本的 DevRel について書いてみたいと思います。

## 参照
- [開発者の心をつかむ「DevRel」とは？ 活動を成功させる「4つのC」と、企業事例を徹底解説](https://seleck.cc/devrel)
- [「DevRel」ってなんだろう？](https://thinkit.co.jp/article/19462)
- [「DevRelとは何か、そして今日からどうすればいいのか？」](https://qiita.com/e99h2121/items/a4cfb73416457b1a5c32)

## 宣伝
Voicy では voi-chord というエンジニアでやっている音声番組があります。
その中で、「エンジニアイベント運営の裏側！」ということで、対談番組を収録しましたので、是非ご聴取ください！

https://r.voicy.jp/jpVEOJaDmJ6

https://r.voicy.jp/v2mvepkAKrG
LPIC 201 未経験が12日で合格

# はじめに
LPIC 201を受けました。
勉強開始から12日で合格しました。

# 学習目的
資格を取りつつLinuxの知識を身に付けること。

# 試験結果
LPIC201
今回の得点：740/800点
合格ライン：500/800点
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771776/3a95c47e-3124-a6b4-8e83-051f0be66d97.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771776/767d8217-0d90-868c-d0ae-c94ff71c429c.png)



# 学習前の知識
201を受験する4か月前にLPIC level1を取得しましたが、コマンドなどの知識はかなり抜けているように感じました。


# 学習時間
日数 : 12日
時間 : 約60時間

連休を利用して短期集中で学習しました。
予定があって勉強がほとんどできない日もありましたが、1日大体6時間ほど勉強しました。

# 学習教材
* [Ping-t](https://mondai.ping-t.com/g/question_subjects)
* [Linux教科書 LPIC レベル2 スピードマスター問題集](https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC%E3%83%AC%E3%83%99%E3%83%AB2-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version4-5%E5%AF%BE%E5%BF%9C-%E6%9C%89%E9%99%90%E4%BC%9A%E7%A4%BE%E3%83%8A%E3%83%AC%E3%83%83%E3%82%B8%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3/dp/4798151238/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=)

Ping-tはweb問題集でスピードマスターは紙の問題集です。
LPIC level1の試験勉強の際もこちらの教材を使用しました。
私は参考書を読むよりも問題集を解く方が身につくタイプなので、問題集タイプの教材を使用しています。

## 選んだ理由

### [Ping-t](https://mondai.ping-t.com/g/question_subjects)

評判が高く、この問題集の学習のみで合格できるほど問題が網羅されています。
実際にLPIC level1の試験を受けてみて、ping-tで学習した内容がかなり出題されていたので今回もこちらを使用しました。


### [Linux教科書 LPIC レベル2 スピードマスター問題集](https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC%E3%83%AC%E3%83%99%E3%83%AB2-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version4-5%E5%AF%BE%E5%BF%9C-%E6%9C%89%E9%99%90%E4%BC%9A%E7%A4%BE%E3%83%8A%E3%83%AC%E3%83%83%E3%82%B8%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3/dp/4798151238/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=)

こちらもLPIC level1の試験対策で使用した教材で、問題の的中率も高いと感じたことから今回も使用しました。

# 学習方法
### 1. Ping-tの「最強WEB問題集」を全問正解する。

初めて解く問題は問題文を読んだらすぐに正解を表示して解説を読む。
↓
次の日にもう一度解く。解けなかったら更に次の日に解く。

といったやり方で進めて「未出題」、「ミス(最後に問題を解いたときに不正解だった問題)」がなくなるまで問題を解きました。

1周目は考えてもわからないのですぐに答えを表示して、どうしてその答えになるのか理解しようとしました。解説を読んでもわからない場合はping-tのAIアシスタント機能を使って質問しました。
例えば以下のように質問していました。
「ルーティングテーブルとは？要点をまとめて5行で教えて」
「ip addr add 192.168.1.1 dev eth0と同じことができるコマンドを教えて」
AIに質問することは以下の2つのメリットがありました。
・要点をまとめて回答してもらえる。
・どうやって検索したらいいかわからない内容を質問できる。

### 2. Ping-tの模擬試験を周回する。
Ping-tには「模擬試験」というモードがあって演習問題60題を90分で解くことができます。
模擬試験は↓のように出題順を選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771776/7e1e924b-6405-2463-5cf6-81c4a7c1c29c.png)
この機能を使って出題日時が古い問題をひたすら解きました。
短期間で学習しようとするとどうしても最初の頃に解いた問題を忘れてしまうので、そこをカバーするために出題日時が古い問題優先で解きました。
また、記述式の問題にも対処できるように、選択肢をなるべく見ないで解くようにしました。
最終的に模擬試験は10回ほどやって出題日時が一番古い問題でも4日以内に解いている状態にしました。

### 3. 出題率が高い問題優先でスピードマスターの問題を解く。
Ping-tの問題がほとんど解けるようになってから最後の仕上げとして学習しました。

以下の順に学習しました。
模擬演習→★3の問題→間違えた問題をもう一回解く→★2の問題

Ping-tだけでも範囲は網羅できていると考えて出題率が高い問題を最優先で解きました。
★1の問題は解きませんでした。

# 試験
1択まで絞れた問題 7割
2択まで絞れた問題 2割
それ以下の問題    1割

理解できていたつもりでも問題の問われ方が変わると解けないという問題が何問かあるように感じました。

# 反省
ping-tのAIアシスタント機能など生成AIを使って理解を深めるように学習しましたが、それでも理解しきれないところはあると感じました。
また、AIに質問することに時間を割きすぎたので、ある程度質問して理解できなかったところは見切りをつけて暗記をしてしまう方が時間の無駄を省けたと思います。
今回は9割以上得点できたので、もう少し早めに受験してもよかったと感じました。
第二回チーム開発

今回はアプレンティスの課題で第二回チーム開発を行ったので、実装の過程や感想をまとめていこうと思います。

## テーマ
今回、私たちに与えられたテーマは
**「ワクワクするものを開発せよ」**
になります。
こちらをチームメンバー4人で作成します！

## 完成プロダクト
兎にも角にも、まずは完成したプロダクトを紹介します！
今回はメンバー全員がゲームに興味があるということだったので、
ノベルゲームを作成することにしました。

しかし、お題はワクワクするものだったので、今までにないようなノベルゲームを作成したく、
**「ヒロインが逆再生で話しかけてくる**という仕掛けを用意しました。

逆再生の音声を読み取って、適切な回答を答えるというゲーム性が
今までになく、ワクワクするものになるのではないかと私たちは考えました。

**ホーム画面**
![スクリーンショット 2024-09-22 14.34.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774215/af599dbf-086a-b4db-5f47-d2f98966465f.png)

**本編**
シナリオパート
![スクリーンショット 2024-10-31 16.07.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774215/b340edf8-a1d1-5d6c-32eb-248c2510c859.png)


問題パート
![スクリーンショット 2024-10-31 16.05.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774215/4f0f7396-f6f2-13fa-154e-9a93372f7817.png)


ここで逆再生音声が流れて、プレイヤーが適切な選択肢を選びます。
回答によってシナリオが変化していくという流れ。

**チュートリアル**
![スクリーンショット 2024-10-31 16.04.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774215/043781ce-813d-ccd1-4c3c-c84215ace52f.png)


本編に入る前の練習モード
最初から逆再生を聞き取ることは難しいと感じたため、チュートリアルで練習することで
さらにゲームを楽しめると考えた。
**設定画面**
![スクリーンショット 2024-10-31 16.05.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774215/e630ef74-f019-63df-e8c5-7f7b8beab866.png)


音量調節、会話の速度調整
完成品は以上です。

## 使用技術
・HTML/CSS
・JavaScript
・PHP/Laravel
・MySQL

## 機能
・画像、テキストの表示
・BGM再生
・BGMの音量調整
・逆再生音声の再生
・テキスト表示の速度調整、スキップ機能
・音声を繰り返し聞ける
・セーブ機能
・選択肢の正誤判定し物語を進める

機能としてはストレスなく、ノベルゲームが遊べるように設計しました。

## こだわりポイント
今回作成したプロダクトはゲームであるため、今後の多くの追加機能に備え、オブジェクト指向を意識した設計を行いました。
これにより、新しいシナリオやキャラクターの追加も容易に行える柔軟な構造を実現しました。


## チームでの動き
今回、前回の反省を踏まえて行動を見直し、チームのルールを以下のように改善しました：

**1:要件定義とタスク分解**
GitHubのIssuesやProjectsを活用し、タスク管理を徹底しました。これにより進捗が明確になり、効率的な作業が可能になりました。

**2:ボイスチャットの活用**
毎晩チーム会を行い、現状確認やタスク分担を円滑に実施しました。

**3:議事録の作成**
会議内容を記録することでチーム間での認識の相違が起きないようにしました。

**4:デザインの参考**
複数のノベルゲームを参考にデザインを強化することで、デザインに関しては知識が少ない私たちにもクオリティの高いプロダクトに仕上がったと思います。
これらの改善により、チーム開発のクオリティが向上しました。


## 個人的に良かった点
・他の人がやりたがらないタスクを率先して引き受けた。
・毎日チーム会を行ったことで、お互いの日々の進捗、実装した機能に相違がないかを逐一確認することができた。
・デザインはいくつかのノベルゲームを参考にしたことによって、デザイナーがいなくても、ゲームとして違和感のないUI、UXにすることができた。

 ## 個人的な反省点
 ・素直すぎるがゆえに、自己主張が弱いとチームメンバーからのフィードバックがあった。

## まとめ
第二回は、チーム全体の技術力向上と円滑なコミュニケーションにより、第一回を上回るクオリティに仕上がったと思います。
今後もこのチームメンバーと一緒に学習を継続していきたいです。
RaspberryPi PicoをUSB接続の温度センサーにして定期的に温度を測定するプログラムをつくる

# あらすじ
[以前作ったコード](https://qiita.com/pinkych24/items/6761255531ddd089560b)をchatGPT o1-previewに書き直してもらったらずいぶんよくなったので改めて記事を作成した。どうもinput()ではなく sys.stdin.readline()でコマンドを読み取ると良いらしい。素人にはinput関数がどうやってserialのバッファを取得してるのかが分からなかったので、こういう大して難しくなさそうなのに地味でマイナーすぎてぐぐっても解決策がみつからない類の問題をサクッと解決してくれるchatGPT様には足を向けて寝られない。あと4oよりo1-preの方が明らかに頭がいい。

## RaspberryPiPico側のコード
今回は基板に内臓されている温度センサーの値を取得してるけどGPIOピンからセンサーの値を取得したりモーター等を動かしたりすることもできる。1分に1回程度動作する環境制御機器を想定しているのでレスポンスの速さは確かめていない。
```main.py
import machine
import utime
import sys

def read_temperature():
    sensor_temp = machine.ADC(4)
    reading = sensor_temp.read_u16()
    voltage = reading * 3.3 / 65535
    temperature = 27 - (voltage - 0.706) / 0.001721
    return temperature

print("Waiting for commands...")

while True:
    # コマンドをブロッキングで読み取る
    command = sys.stdin.readline().strip()
    if command == "GET_TEMP":
        temp = read_temperature()
        sys.stdout.write("Temperature: {:.2f} C\n".format(temp))
    else:
        sys.stdout.write("Unknown command.\n")

```

## PC側のコード
最初にVender IDとProduct IDでPico基板を探している。デバイスの名前や説明を編集できれば一番いいのだけれどその機能がMicroPythonに実装されてるのか分からなかった。とりあえずPico側に名を名乗らせるコマンドを追加すれば対応できると思う。
```get_temp.py
import serial
import serial.tools.list_ports
import time

def find_pico_port(vid=0x2E8A, pid=0x0005):
    ports = list(serial.tools.list_ports.comports())
    for port in ports:
        if (port.vid, port.pid) == (vid, pid):
            return port.device
    return None

def main():
    pico_port = find_pico_port()
    if pico_port is None:
        print("Raspberry Pi Picoが見つかりませんでした。")
        return

    print(f"Raspberry Pi Picoが{pico_port}で見つかりました。")

    # シリアルポートを開く
    ser = serial.Serial(pico_port, baudrate=115200, timeout=1)
    time.sleep(0.1)  # デバイスの準備待ち

    # 入力バッファをクリア
    ser.reset_input_buffer()

    try:
        # 2秒ごとに温度を取得するループ
        while True:
            # コマンドを送信
            ser.write(b'GET_TEMP\n')

            # 応答を読み取る
            response = ser.readline().decode('utf-8', errors='ignore').strip()
            print(f"受信した温度データ: {response}")

            # 2秒間待機
            time.sleep(2)
    except serial.SerialException as e:
        print(f"シリアル通信でエラーが発生しました:\n {e}")
    except KeyboardInterrupt:
        pass
    finally:
        print("\n温度取得を終了します。")
        ser.close()

if __name__ == "__main__":
    main()


```


## 動作テスト
Windows機のThonnyで実行するとこんな感じ
``` shell
>>> %Run MicroPython_USB_CDC_Host.py
Raspberry Pi PicoがCOM12で見つかりました。
受信した温度データ: Temperature: 17.68 C
受信した温度データ: Temperature: 17.21 C
受信した温度データ: Temperature: 16.75 C
受信した温度データ: Temperature: 17.21 C

温度取得を終了します。
>>> 
```

動作中にUSBケーブルを抜くとこんな感じ
```shell
>>> %Run MicroPython_USB_CDC_Host.py
Raspberry Pi PicoがCOM12で見つかりました。
受信した温度データ: Temperature: 17.68 C
受信した温度データ: Temperature: 17.21 C
受信した温度データ: Temperature: 17.21 C
シリアル通信でエラーが発生しました:
 WriteFile failed (PermissionError(13, 'デバイスがコマンドを認識できません。', None, 22))

温度取得を終了します。
>>> 
```

とりあえずAIに頼めばいい感じのデモコードを作ってくれる時代になってしまったので簡単な作例を公開する意義が薄くなった気はするけど以前作ったやつがあんまりにもあんまりなので今回は公開する。
Learn Next.js chapter 1やってみた

Qiitaで初めての記事です。内容は[Lean Next.js](https://nextjs.org/learn/dashboard-app/getting-started)の分からない箇所を中心に写経していくだけです。なので、すべての要素を拾うわけでもないし、英語を都合のいいように翻訳していたりもします。

## 1.Getting Started
### 新しいプロジェクトを作る
まずは、パッケージマネージャーをインストールする。`pnpm`は`pnm`の上位互換らしい？

**npm vs pnpm**  [参考](https://qiita.com/ryoma_itngineer/items/8b0fda6a76fb04dccc32)
1. ディスク使用量とインストール速度
2. 依存関係の解決
3. ワークスペースのサポート
4.  パフォーマンス  

```
npm install -g pnpm
```

npxでプロジェクトを作成する。
- `npx` :  `install`+`run`+`uninstall`を一度に行う
- `nextjs-dashboard` : プロジェクトの名前。変えるの忘れた。
- `example` : URLを指定してひな形を利用できるみたい。
```
npx create-next-app@latest nextjs-dashboard --example "https://github.com/vercel/next-learn/tree/main/dashboard/starter-example" --use-pnpm
```

**フォルダ構造**
- `/app` すべてのルート、コンポーネント、ロジックが含まれる。ここで一番作業するらしい
- `/app/lib`再利用可能なユーティリティ関数やデータ・フェッチ関数など、アプリケーションで使用される関数が含まれる
- `/app/ui`アプリケーションのすべてのUIコンポーネントが含まれる
- `/public`画像などの静的な要素を含む
- `ConfigFiles` このLearnでは触らんらしい。

**place holder**
`app/lib/placeholder-data.ts`にプレースホルダーデータを用意してくれてるとのこと。カスタマーデータやら請求データやらが設置されていた。
> プレースホルダー：プログラミングやデータベースにおいて、ある値や情報を後で入力するために一時的に置いておくための記号や変数。プログラムで動的に変更されるデータの表示箇所。

**TypeScript**
`.ts`や`.tsx`などのファイル。「型」という要素が重要らしい。例えば、`/app/lib/definitions.ts`には、invoicesテーブルの方が定められている。このおかげで、誤ったデータを渡すのを防ぐことだできる。
```ts:/app/lib/definitions.ts
export type Invoice = {
  id: string;
  customer_id: string;
  amount: number;
  date: string;
  // In TypeScript, this is called a string union type.
  // It means that the "status" property can only be one of the two strings: 'pending' or 'paid'.
  status: 'pending' | 'paid';
};
```

**deveropment serverを動かす**
Q. `i`をインストール???なんこれ 
A. このコマンドを実行すると、`pnpm`は`package.json`ファイルを読み込み、指定されたすべての依存関係をプロジェクトにインストールします。
```terminal:Terminal
pnpm i
```
dev serverを起動
```terminal:Terminal
pnpm dev
```
すると以下のように出力される
```terminal:Terminal
> next dev --turbo

  ▲ Next.js 15.0.0 (turbo)
  - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 16.8s
```
このタイミングで、http://localhost:3000 にアクセスすると...
![{7F60C00D-D117-43F1-A787-7AA5AB430A9C}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3923538/05d0c7e8-f6ed-c6ad-91b8-993efa1d4abb.png)
へんな画面が登場する。`Vercel`？によって、デプロイされているみたいです。

---
### これでチャプター1は終了  
次回は、CSS Stylingについていろいろする。
StringをCharにしたら処理速度が倍になった

Stringを甘く見ていてめっちゃハマってしまったので戒めに残しておく
この問題 https://atcoder.jp/contests/abc375/tasks/abc375_c

## 解答コード

``` diff_kotlin
fun main(){
    val n = readln().toInt()
-    var pre: MutableList<List<String>> = mutableListOf()
-    var next: Array<Array<String>> = Array(n){Array(n){""}}
+    var pre: MutableList<List<Char>> = mutableListOf()
+    var next: Array<Array<Char>> = Array(n){Array(n){'.'}}
    repeat(n) {
        pre.add(
-            (readln().map { it.toString() })
+            (readln().toList())
        )
    }

    for(x in 1 .. n) {
        for (y in 1 .. n) {
            val convNum = minOf(x,y,n+1-x,n+1-y) % 4 // 変換回数
            var (i,j) = listOf(y, x)
            repeat(convNum) {
                val tmp = i
                i = n+1-j
                j = tmp
            }
            next[y-1][x-1] = pre[i-1][j-1]
        }
    }
    println(next.map{it.joinToString("")}.joinToString("\n"))
}
```

## 実行時間
[TLE](https://atcoder.jp/contests/abc375/submissions/59293019)  3048ms
[AC](https://atcoder.jp/contests/abc375/submissions/59293153)  1741ms

倍近い時間がかかっている！

## 学び

Javaの文字列は不変オブジェクトで、**文字列の内容を変更するたびに新しいインスタンスが生成される**のでC/C++の感覚で扱うと痛い目を見るらしい[^1]

StringがCharより重いという感覚は勿論あったが、そうはいっても文字数次第で大差ないだろうくらいの感覚だったのでアルゴリズムを疑い続けてめっちゃハマってしまった

[^1]: ChatGPT様ありがとう！！
JavaScriptの基礎入門

# 1. 変数の宣言
JavaScriptでは、以下の3つの方法で変数を宣言します。

var：古い方法で、現在はあまり推奨されません（再代入・再宣言が可能）。
let：再代入可能だが再宣言は不可。
const：再代入・再宣言が不可。
javascript
```javascript
let name = "JavaScript";  // letを使った変数宣言
const version = "ES6";     // 定数の宣言
name = "JS";               // letの再代入は可能
```
# 2. データ型
JavaScriptには以下の主なデータ型があります：

プリミティブ型：string、number、boolean、undefined、null
オブジェクト型：オブジェクト、配列、関数など
```javascript
let text = "Hello, JavaScript";  // string
let num = 42;                    // number
let isActive = true;             // boolean
let nothing = null;              // null
let unknown;                     // undefined
```

# 3. 条件分岐
if-else文
```javascript
let score = 85;
if (score >= 90) {
    console.log("Excellent!");
} else if (score >= 60) {
    console.log("Good Job!");
} else {
    console.log("Keep Trying.");
}
```

switch文
```javascript
let day = 3;
switch (day) {
    case 1:
        console.log("Monday");
        break;
    case 2:
        console.log("Tuesday");
        break;
    default:
        console.log("Unknown day");
}
```

# 4. ループ

forループ
```javascript
for (let i = 0; i < 5; i++) {
    console.log(i);
}
whileループ
javascript
コードをコピーする
let i = 0;
while (i < 5) {
    console.log(i);
    i++;
}
```

# 5. 関数
関数の定義
```javascript
function greet(name) {
    return `Hello, ${name}!`;
}
console.log(greet("Alice"));
```

アロー関数
```javascript
const greet = (name) => `Hello, ${name}!`;
console.log(greet("Alice"));
```

6. 配列とオブジェクト
配列
```javascript
let fruits = ["apple", "banana", "cherry"];
console.log(fruits[0]);  // apple
オブジェクト
javascript
コードをコピーする
let person = {
    name: "Alice",
    age: 25,
};
console.log(person.name);  // Alice
```

7. イベントハンドリング
Webページでのイベント処理が簡単にできます。

```javascript
document.getElementById("myButton").addEventListener("click", () => {
    alert("Button clicked!");
});
```

8. 非同期処理 (Async/Await)
非同期処理を簡潔に書くためのasync / await。

```javascript
async function fetchData() {
    let response = await fetch("https://api.example.com/data");
    let data = await response.json();
    console.log(data);
}
```

9. DOM操作
JavaScriptを使ってHTMLを操作することができます。

```javascript
document.getElementById("myElement").textContent = "Hello, DOM!";
```

10. エラー処理
JavaScriptではtry-catchでエラーを処理します。

```javascript
try {
    let result = someFunction();
} catch (error) {
    console.error("An error occurred:", error);
}
```

**まとめ**
JavaScriptは、基本的なプログラミングだけでなく、フロントエンドやバックエンド、モバイルアプリ開発など幅広い分野で使える汎用的な言語です。これらの基礎を押さえた上で、より高度なトピック（ES6以降の新機能、非同期処理、モジュール管理など）を学ぶと良いでしょう。


Javascript応用文法についての記事はこちらで公開しています

https://qiita.com/y-t0910/items/123d5701b6c96670c96f

次のステップ
JavaScriptをさらに学びたい場合、以下のリソースが役立ちます：

JavaScript公式ドキュメント (MDN Web Docs)
JavaScriptチュートリアル

**最後までよんでいただきありがとうございます。
毎日更新していますので、@y-t0910をフォロー,いいねしていただけると嬉しいです！**
AWSの開発環境構築手順：ALB編

# ALBとは？

ChatGPTに質問しました。

> Q:ALBに関して5行程度で教えてください。

> A:
AWSのALB（Application Load Balancer）は、アプリケーション層（レイヤー7）で動作する負荷分散サービスです。
リクエストの内容に基づいてトラフィックを振り分けるため、パスベースやホストベースのルーティングが可能です。
例えば、特定のURLやHTTPヘッダーに応じて異なるサーバー群に振り分けることで、柔軟なトラフィック管理ができます。
また、複数のAZ（アベイラビリティゾーン）にまたがる高可用性も備えており、HTTPSなどのセキュアな接続もサポートします。

EC2編で少し言及したELBの一種です。
今回はHTTPS対応しますが、SSL/TLSサーバー証明書の取得手順は別の記事に記載します。

# 作業内容

## ロードバランサーを作成

EC2>ロードバランシング>ロードバランサーと進み、[ロードバランサーの作成]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/66479ed9-fc25-7b51-532a-946a2818c426.png)
<br>

「ロードバランサータイプ」でALBの[作成]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/ad49ab17-2acb-5814-24b4-2e84ad90d0c3.png)
<br>

「ロードバランサー名」を入力する
※本記事ではproject-dev-alb

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/4659960c-824b-7fa8-ea28-404c966a5f30.png)
<br>

「ネットワークマッピング」で下記入力
- 「VPC」でproject-dev-vpcを選択
- 「アベイラビリティーゾーン」でap-northeast-1a, ap-northeast-1cにチェックを入れる
- サブネットがそれぞれpublicを選択していることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/0e041dc5-d2e5-e535-dca7-4a2c7df07200.png)
<br>

「セキュリティグループ」でproject-dev-alb-sgを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/9ad57999-19c9-3504-7864-f351d4c603c6.png)
<br>

[ターゲットグループの作成]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/40ed7b51-9774-1544-e6d5-348e63cc9135.png)
<br>

- 「ターゲットタイプの選択」でインスタンスが選択されていることを確認
- 「ターゲットグループ名」にproject-dev-tgを入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/c54f3f12-8c66-cf5d-6f0c-d0d75c7b4f53.png)
<br>

「VPC」でproject-dev-vpcを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/e4c8c332-066e-6c65-248e-0e8fbd41e4a0.png)
<br>

[次へ]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/e54562b4-d3de-351f-c1bd-f467a91dd7d3.png)
<br>

project-dev-ec2にチェックを入れて、[保留中として以下を含める]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/34b96318-355d-5adb-4834-234cb780da7d.png)
<br>

「ターゲット」に追加されていることを確認して[ターゲットグループの作成]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/f956346e-154f-394e-f605-2eb120b7da89.png)
<br>

- 先ほどのロードバランサーの作成画面に戻り、更新ボタンを押して、project-dev-tgを選択する
- 「プロトコル」をHTTPSにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/89b80141-5b30-cc7c-ee49-6b04e13c46eb.png)
<br>

[ロードバランサーの作成]を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/48c49466-a08b-167f-6bde-124420b94d3d.png)

※余談
この段階で、EC2>ターゲットグループ>project-dev-tgと開くと、ヘルスチェックに失敗しているが、
Nginxをインスタンスに設定すれば解消するはずなので問題なし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/b58ba6c1-3c83-2e38-e092-74304ffbaf2a.png)
<br>
Githubのリポジトリを要約してChatGPTが内容を認識できるようにするスクリプト

# はじめに
ChatGPTにリポジトリの中身を理解してもらうためのツールを作成してました。コードの要約を作ってマークダウンファイルに出力します。このマークダウンファイルをカスタムGPTに読み込ませると、リポジトリの使い方やアプリケーションの作り方などをChatGPTが答えてくれるようになります。

# リポジトリ
このスクリプトは [こちら](https://github.com/takurot/RepoSumm) で公開されています。

# カスタムGPTの事例
要約結果を活用するサンプルとして、[Graphai](https://github.com/receptron/graphai)というリポジトリに対してこのスクリプトで要約作成し、カスタムGPTを生成しました。 [GraphaiのカスタムGPT](https://chatgpt.com/g/g-5HCO0kb8k-graphai) からご覧いただけます。

# 目的

このスクリプトの目的は、ChatGPTがリポジトリの全体像を迅速に把握できるよう、各ファイルの要点を自動的に生成し、リポジトリ内容を簡潔にまとめることです。生成されたMarkdownファイルを確認することで、リポジトリの構造や各ファイルの役割をChatGPTが理解できるようになります。

# スクリプトの機能

- **リポジトリ内のファイルを再帰的に探索**し、対象のファイルを収集
- 各ファイルを**ChatGPT APIで要約**し、内容のポイントを抽出
- 各ファイルごとの要約を**Markdown形式で出力**

# 環境

このスクリプトの実行には以下の環境が必要です：

- Python 3.x
- OpenAIのPythonクライアントライブラリのインストール
  ```bash
  pip install openai argparse
  ```

また、OpenAI APIキーを取得し、スクリプトに適用する必要があります。APIキーは OPENAI_API_KEY の環境変数に設定してください。

# スクリプトの使い方

## 1. スクリプトの準備

スクリプトを任意のフォルダに配置し、実行可能な状態にします。

## 2. コマンドライン引数でリポジトリパスを指定

このスクリプトは、コマンドライン引数で対象リポジトリのパスを指定する仕様になっています。`argparse`ライブラリを使用し、ユーザーがリポジトリのパスを引数として渡せるように設定されています。

```bash
python summarize_repo.py /path/to/your/repository
```

## 3. スクリプトの実行と結果の確認

指定したリポジトリ内のファイルを再帰的に探索し、ファイルの要約が `repo_summary.md` にMarkdown形式で出力されます。このファイルには各ファイルの相対パスと、ChatGPTが生成した要約がまとめられています。ファイル数が多いと時間がかかります。

## 4. 生成ファイルの活用

生成された `repo_summary.md` は、ChatGPTがプロジェクトの概要を把握してカスタムGPTとして使うために利用できます。例えば[GraphaiのカスタムGPT](https://chatgpt.com/g/g-5HCO0kb8k-graphai)のように、リポジトリを解析するモデルを作成し、プロジェクトの要点をクイックアクセスできる環境を構築することも可能です。

# 注意点

- **APIのコスト**: ChatGPT APIの利用にはコストが発生します。大規模なリポジトリを要約する際には、API使用量が多くなる可能性があるため、注意が必要です。
  
- **要約内容の確認**: AIによる要約のため、内容が完全に正確とは限りません。必要に応じて手動で修正・補足することをお勧めします。

# まとめ

このスクリプトは、ChatGPT APIを活用してリポジトリ内のファイルを効率的に要約し、プロジェクトの概要を素早く理解できるようにする強力なツールです。特に新しいコードベースに迅速にキャッチアップする必要がある場合に有用です。
GameAnalyticsの導入メモ

Unityに導入の前提

* 公式ドキュメントは古かったりする。リソースを含む設定は導入後Unity内のWindow-GameAnalyticsのセッティングでログインして対応
* GameAnalytics.EnableAdvertisingIdTracking(true/false)というのがあって、これがGAIDの収集許可。イニシャライズ前に実行して設定する
* サポートのメールは意外とレスポンスが良かった
Mailing listから探るSPF, DKIM, DMARCの対応状況(2024年10月)

# はじめに
SPF, DKIM, DMARCの可視化について以下に記載しました。

https://qiita.com/matsuhira/items/e1c5e5b068561e4c6bdb

ここでは、実際に受信したMailing Listのメールから、現時点の対応状況を見てみます。対象とするMailing Listは4つです。
# Mailing List #1
* dkim-pass, dmarc=pass, spf=pass
* <font color="maroon">dkim=fail</font>, dkim-pass, dmarc=pass, spf=pass
* <font color="maroon">dkim=fail</font>, dkim-pass, spf=pass
* <font color="maroon">dkim=fail</font>, dkim=pass, <font color="maroon">dmarc=fail</font>, spf=pass
* dkim=pass, spf=pass
* dkim=pass, <font color="maroon">dmarc=fail</font>, spf=pass
* <font color="maroon">dkim=none</font>, dkim=pass, <font color="maroon">dmarc=none</font>, dmarc=pass, spf=pass
* <font color="maroon">dkim=fail</font>, <font color="maroon">dkim=none</font>, dkim=pass, <font color="maroon">dmarc=none</font>, dmarc=pass, spf=pass
* <font color="maroon">dkim=none</font>, dkim=pass, <font color="maroon">dmarc=fail</font>, <font color="maroon">dmarc=none</font>, dmarc=pass, spf=pass

# Mailing List #2
* dkim=pass, dmarc=pass, spf=pass
* dkim=pass, <font color="maroon">dmarc=none</font>, spf=pass
* dkim=pass, <font color="maroon">dmarc=fail</font>, dmarc=pass, spf=pass
* <font color="maroon">dkim=none</font>, dmarc=pass, spf=pass
* dmarc=pass, spf=pass
* dkim=pass, <font color="maroon">dmarc=fail</font>, dmarc=pass, <font color="maroon">spf=neutral</font>, spf=pass
* <font color="maroon">dkim=none</font>, <font color="maroon">dmarc=fail</font>, dmarc=pass, spf=pass

# Mailing List #3
* <font color="maroon">dkim=fail</font>, dkim=pass, dmarc=pass, spf=pass
* <font color="maroon">dkim=fail</font>, <font color="maroon">dkim=none</font>, dkim=pass, <font color="maroon">dmarc=none</font>, dmarc=pass, spf=pass
* dkim=pass, dmarc=pass, spf=pass

# Mailing List #4
* <font color="maroon">dkim=fail</font>, <font color="maroon">dkim=none</font>, <font color="maroon">dmarc=none</font>, spf=pass
* spf=pass
* <font color="maroon">dkim=fail</font>, <font color="maroon">dmarc=fail</font>, spf=pass
* <font color="maroon">dkim=fail</font>, dkim=pass, <font color="maroon">dmarc=fail</font>, spf=pass
* <font color="maroon">dkim=fail</font>, <font color="maroon">dkim=none</font>, <font color="maroon">dmarc=fail</font>, <font color="maroon">dmarc=none</font>, spf=pass
* dkim=pass, dmarc=pass, spf=pass
* <font color="maroon">dkim=fail</font>, spf=pass
* <font color="maroon">dkim=none</font>, sof=pass
MySQL client is not connected　がターミナルに表示されたら

`MySQL client is not connected`がターミナルに表示されたら速度系の問題！

私は単体テストコードをしていた時、異常系テストでうまくいったりいかなかったりの現象が起きていました。
例えば以下のコード
```spec/models/xxx_spec.rb
    item = FactoryBot.create(:item, user: user)
```
このコードの中には画像が含まれている為処理に時間が掛かり、その処理の前に下のコードを読んでしまいエラーが出ていました。

これを解決するコード
```config/environments/test.rb
config.active_job.queue_adapter = :inline #最終行endの上に追記
```
この**active_job**は途中で重い処理があったら、それが終わってから次のコードを読んでね、という命令を出してくれる。

このせいで丸2日止まっていました。
やっと次に進める！！！！
ありがとうございます！！
EC-CUBE基本設定メールアドレスのパスワードに使えない記号

EC-CUBE基本設定に設定するメールアドレスのパスワードに使用した記号が原因でメール送信エラーになる現象をテストしました
# テスト環境
サーバー：MacOS Sequoia
EC-CUBEバージョン：4.2.3
phpバージョン：8.1.29
メールサーバー：CoNohaレンタルサーバー

# 使用できない記号
`/`　スラッシュ（フェイタルエラー発生）
`#`　ハッシュ（フェイタルエラー発生）
`)`　右かっこ（フェイタルエラー発生）
`+`　プラス（エラーは発生しないがメール送信されない）
# 使用できる記号
`~`　チルダ
`.`　ドット
`(`　左かっこ
`@`　アットマーク
`-`　ハイフン
`_`　アンダーバー
`*`　アスタリスク
`!`　エクスクラメーション
`$`　ドル
`%`　％
`&`　アンド
`|`　パイプ
`:`　コロン
`;`　セミコロン
`<`　小なり
`>`　大なり
`=`　イコール
`^`　ハット
`(`　左かっこ
# 未検証の記号
`,`　カンマ
メールサーバー（ConoHa）の仕様でメールアドレスパスワードに使えないため未検証
# 原因

```:.env
###> symfony/mailer ###
MAILER_DSN=smtp://[メールアドレス]:[パスワード]@[メールサーバー]:[ポート番号]?auth_mode=plain
###< symfony/mailer ###
```
インストール時に設定したメール設定のメールアドレス、パスワード、メールサーバー、ポート番号が`root/.env` に書き込まれるため、パスワードの記号がプログラムコードとして読み取られてしまいエラーが発生するようですね。
# 参考記事
https://s-pro4.com/page-331.html
[Axx]x86_64によるHello Worldの実行テスト。assembled [linux]


axxによる、x86_64linuxシステムの、hello worldのテストです。

#### 試験環境

Archlinux　terminal


#### AXXファイル

```hello.axx
MOV EAX,e   ::  0xb8,e,e>>8,e>>16,e>>24
MOV EDI,e   ::  0xbf,e,e>>8,e>>16,e>>24
MOVQ ESI,e::  0x48,0xbe,e,e>>8,e>>16,e>>24,e>>32,e>>40,e>>48,e>>56
MOV EDX,e   ::  0xba,e,e>>8,e>>16,e>>24
SYSCALL     ::  0xf,0x5
DB e        ::  e
```

#### hello world 本体

```hello.s
section .text
.export _start,len
        .org 0x401000
_start:
        mov     edx, 0
        mov     eax, 1      ; sys_write (01)
        mov     edi, 1      ; stdout    (01)
        mov     edx, len:    ; length    (13)
        movq     esi, msg    ; address
        syscall
        mov     edi, 0      ; return 0
        mov     eax, 60     ; sys_exit
        syscall
msg:     .ascii      "hello, world\n"
len:     .equ     $$ - msg
_end:
```

#### アセンブル

```
$ axx.py hello.axx hello.s -o hello.bin  
hello.s 5         mov     edx, 0  0xba 0x00 0x00 0x00 0x00
hello.s 6         mov     eax, 1      ; sys_write (01)  0xb8 0x01 0x00 0x00 0x00
hello.s 7         mov     edi, 1      ; stdout    (01)  0xbf 0x01 0x00 0x00 0x00
hello.s 8         mov     edx, len:    ; length    (13)  0xba 0x0d 0x00 0x00 0x00
hello.s 9         movq    esi, msg    ; address  0x48 0xbe 0x2c 0x10 0x40 0x00 0x00 0x00 0x00 0x00
hello.s 10         syscall  0x0f 0x05
hello.s 11         mov     edi, 0      ; return 0  0xbf 0x00 0x00 0x00 0x00
hello.s 12         mov     eax, 60     ; sys_exit  0xb8 0x3c 0x00 0x00 0x00
hello.s 13         syscall  0x0f 0x05
 0x68 0x65 0x6c 0x6c 0x6f 0x2c 0x20 0x77 0x6f 0x72 0x6c 0x64 0x0a
```

#### rawバイナリファイルから、実行形式ELFへの変換

これが役に立ちました。
bin2elf

・https://gist.github.com/tangrs/4030336


```
bin2elf.sh hello.bin hello.exe 0x401000
```

プログラム実行のデフォルトエントリは0x401000なので。

#### 実行

```
$ ./hello.exe                            
hello, world
$
```

動きました。

axxのリンカ（ldとのインターフェース）を作ろうとしていますが、ELFの構造は複雑で、リロケータブルELFを作るのが難しいです。

#### Happy Halloween.

![Ga9lqbLXEAAPvws.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315399/ad631c29-e1d4-1b2b-2d58-667156619f3b.jpeg)
ゲームプログラマのための設計：高階関数

[ゲームプログラマのための設計シリーズ](https://qiita.com/kobitnex/items/93397d985682c806884c)：実装詳細編の記事です。

# 概要
* C++での高階関数の実装法を比較
* 一緒に状態を受け取らなくていいなら関数ポインタ
* 実装を隠す必要がないならテンプレート

# 本文
高階関数とは、関数を引数or戻り値に持つ関数の事です。
C++の実装方法は大きく分けて３パターン考えられるので紹介＆比較してみます。

※これを使うと何がうれしいのかは↓
https://qiita.com/kobitnex/items/0f04bcd58fb8887a4ab7


## 関数ポインタによる実装
```cpp
// 関数ポインタ
void HighFunc0(float (*argFunc)(int))
{
	const float val = argFunc(0);
}
```

ポイント：
* 良くも悪くも、関数以外の余分な状態はついてこない
* それゆえキャプチャありのラムダ式などは渡せない

```cpp
void test()
{
    // キャプチャなしのラムダ式なら、関数ポインタに暗黙変換される
	HighFunc0([](int) {return 0.f; });
}
```

※関数ポインタと似たものに、__関数型__ というものがあります。
戻り値には使えず引数にのみ使えますが、結局関数ポインタ扱いされるようです。
```cpp
using FuncType = float(int);    // 関数型
using FuncPtr = float (*)(int); // 関数ポインタ型
```

## std::functionによる実装
std::functionとは、関数のように呼び出せるものをなんでも格納できるクラスです。
```cpp
#include <functional>

void test()
{
	int(*funcPtr)(float);					// 関数ポインタ
	auto lambda = [](int) {return 0.f; };	// ラムダ式
	struct S
	{
		float operator()(int) { return 0.f; }
	} functor;								// operator()を持つクラスのインスタンス

	// みんな()をつけて呼び出し可能
	const float val0 = funcPtr(0);  // (簡略化のため初期化してないので未定義動作)
	const float val1 = lambda(0);
	const float val2 = functor(0);

	// std::functionに格納可能
	std::function<float(int)> func;
	func = funcPtr;
	func = lambda;
	func = functor;
}

```

std::functionの見過ごせないデメリットとして、代入時にメモリ確保が走る可能性があるということが挙げられます。動的メモリ確保をしないfunctionの実装はいろいろ公開されているので、ぜひ取り入れてみてください。
https://blog.toylogic.co.jp/programmer/3364.html
https://zenn.dev/suuta/articles/c4c47e8626d5aa
が、動的確保を避けるということは受け取れるインスタンスのサイズに制限が発生するということでもあります。

ポイント：
* 良くも悪くも、一緒に状態を受け取る
* std::functionでは動的メモリ確保が生じることがある
* 動的メモリ確保を回避する独自実装は可能だが、受け取れるインスタンスのサイズに制約ができる
* std::function::operator()の呼び出しは仮想関数コールより高コスト

## テンプレートによる実装
テンプレートを用いても、関数のように呼び出せるものすべてを受けるコードを書くことができます。

```cpp
// Funcはintをとりfloatを返す関数
template<typename Func>
void HighFunc1(Func&& func)
{
	const float val = func(0);
}
```
関数のシグネチャからFuncに何を渡したらよいかはっきりしない問題がありましたが、C++20のConceptにより欠点を解消することができるようになりました。コンパイラにもよりますが、間違った型を渡したときのエラー文も以前よりわかりやすくなっているはずです。
```cpp
template<typename Func>
requires std::is_invocable_r_v<float,Func,int> // Funcとはintをとりfloatを返す関数（っぽいやつ）であるという制約
void HighFunc2(Func&& func)
{
	const float val = func(0);
}
```
ちなみに、それ以前はデフォルト引数でお茶を濁していました。
```cpp
template<typename Func = float(int)>
void HighFunc4(Func&& func)
```

ポイント：
* 良くも悪くも、一緒に状態を受け取る
* インスタンスのサイズに制約なく受け取れる
* テンプレートなので、実体化する側のコードから実装を隠すことができない

※余談：キャプチャありのラムダを返したい場合はテンプレートではなく、戻り値型推論を使うことになります。
```cpp
// 「引数をaと足した結果を返す関数」を返す関数
auto retAddFunc(int a)
{
    // ラムダ式はそれぞれ固有の型を持つので推論するしかない
	return [a](int b) { return a + b; };
}
```

## まとめ
| | 関数ポインタ | std::function（的なもの） | テンプレート |
|:-:|:-:|:-:|:-:|
| 受け取れる状態のサイズ | なし | 動的メモリ確保or有限 | 無限 |
| 実装の隠蔽 |可 | 可  | 不可  |
| 呼び出しにかかるオーバーヘッド | 低 | 高 | 低 |

1. 状態を受け取る必要がないなら関数ポインタ
2. 実装を隠す必要がないならテンプレート
3. どちらでもない場合、std::function（的なもの） 

という感じで判断するのが良いかと思います。
ESXiに入っている各VMの状態を取得するシェルスクリプト

## はじめに
このスクリプトは、指定したESXiホスト上の全てのVMの電源状態をチェックし、一定期間電源がオフのVMをリスト化するものです。長期間電源がオフのVMを識別し、別のリストへ移動する際に役立ちます。

### スクリプトの内容
・ESXiホストにSSHで接続し、全てのVMのリストを取得。
・各VMの電源状態をチェックし、「電源オフ」のVMをリストに追加。
・指定した日数(ここでは1ヶ月)経過した電源オフのVMを別のリストに移動。

### 各処理の流れ
**1．CSVファイルの作成**：list.csvとvms_list.csvが存在しない場合、自動で作成されます。
**2．VMリストの取得**：SSH経由でESXiホストからVMリストを取得し、各VMの情報を配列に格納します。
**３．電源状態のチェック**：
電源オフのVMはlsit.csvに保存され、電源オンに戻ったVMはリストから削除されます。
**４．1ヶ月経過チェック**：list.csv内の各VMの最終電源オフ日から1ヶ月経過した場合、vms_list.csvに移動され、元のCSVから削除されます。

```
#!/bin/bash

# ESXiホストの情報
ESXI_USER="○○○○"
ESXI_HOST="○○○○"
POWER_STATUS_CSV="list.csv"
COPY_LIST_CSV="vms_list.csv"
TODAY=$(date +%Y-%m-%d)

# CSVファイルがなければ作成
touch "$POWER_STATUS_CSV"
touch "$COPY_LIST_CSV"

# すべてのVMのリストを取得
VM_LIST=$(ssh "$ESXI_USER@$ESXI_HOST" "vim-cmd vmsvc/getallvms")

# VMリストを配列に格納
mapfile -t VM_ARRAY < <(echo "$VM_LIST" | tail -n +2)

# VM電源状態の確認
echo "Checking VMs..."

for line in "${VM_ARRAY[@]}"; do
    # VMのIDと名前を抽出
    VM_ID=$(echo "$line" | awk '{print $1}')
    VM_NAME=$(echo "$line" | awk '{print $2}')

    # 空行や無効なIDをスキップ
    if [[ -z "$VM_ID" || "$VM_ID" =~ [^0-9] ]]; then
        continue
    fi

    # VMの電源状態を取得
    POWER_STATE=$(ssh "$ESXI_USER@$ESXI_HOST" "vim-cmd vmsvc/power.getstate $VM_ID" | grep -Eo '(Powered on|Powered off)' | tr -d '[:space:]')

    # 電源オフのVMを処理
    if [[ "$POWER_STATE" == "Poweredoff" ]]; then
        # 既にvm_power_status.csvにあるか確認
        if ! grep -q "^$VM_NAME," "$POWER_STATUS_CSV"; then
            # なければ新規に追加
            echo "$VM_NAME,$TODAY" >> "$POWER_STATUS_CSV"
            echo "Added $VM_NAME to $POWER_STATUS_CSV"
        fi
    else
        # 電源オンならvm_power_status.csvから削除
        if grep -q "^$VM_NAME," "$POWER_STATUS_CSV"; then
            sed -i "/^$VM_NAME,/d" "$POWER_STATUS_CSV"
            echo "Removed $VM_NAME from $POWER_STATUS_CSV (powered on)"
        fi
    fi
done

# 1か月経過したVMをチェック
while IFS=, read -r vm_name date; do
    # 日付の差を計算
    diff_days=$(( ( $(date -d "$TODAY" +%s) - $(date -d "$date" +%s) ) / 86400 ))

    if [ "$diff_days" -ge 30 ]; then
        # 1か月経過したらvmcopy_list.csvに追加し、vm_power_status.csvから削除
        echo "$vm_name" >> "$COPY_LIST_CSV"
        sed -i "/^$vm_name,/d" "$POWER_STATUS_CSV"
        echo "Moved $vm_name to $COPY_LIST_CSV after 1 month of being powered off"
    fi
done < "$POWER_STATUS_CSV"
```

### 実行結果
```
Checking VMs...
Added VM1 to list.csv
Added VM2 to list.csv
Removed VM3 from list.csv (powered on)
```
上記の出力では、VM1とVM2が電源オフのためlist.csvに追加され、VM3が電源オンに戻ったためlist.csvから削除されたことがわかります。

list.csvには電源オフのVM1とVM2が、日付と共に記録されています。
```
list.csv:
VM1,2024-10-31
VM2,2024-10-31
```

このcsvの記録から1ヶ月が経過すると、vms_list.csvにVM名が記述されます．

記述された後は、以下の事を行います。
https://qiita.com/c0a21013ef/items/9d5eacee52581ba38f01


:::note warn
注意事項
このスクリプトを定期的に実行するには、.serviceファイルと.timerファイルを各自で設定する必要があります。.serviceファイルでスクリプトの起動方法を指定し、.timerファイルで実行スケジュールを設定することで、systemdによる自動実行が可能となります。
中間テーブルをの応用

テーブルAとテーブルBがN対Nのリレーションを持つ場合、**中間テーブル (ABテーブル)** を用意して効率的に検索する方法をご紹介します。これにより、テーブルAからテーブルB、またはその逆方向に検索することができます。

### 1. テーブル構造の定義

まず、3つのテーブル構造は以下のようになります：

#### テーブルA
- `a_id` (主キー)
- `a_name` (データ属性)

#### テーブルB
- `b_id` (主キー)
- `b_name` (データ属性)

#### 中間テーブルAB
- `a_id` (テーブルAの外部キー)
- `b_id` (テーブルBの外部キー)

### 2. テーブルの関連図
N対Nのリレーション構造は次のように表せます：

```
 Aテーブル               ABテーブル                Bテーブル
+----------+       +--------------+        +----------+
| a_id     | <-->  | a_id         | <-->   | b_id     |
| a_name   |       | b_id         |        | b_name   |
+----------+       +--------------+        +----------+
```

### 3. 検索クエリ例

#### 例1: テーブルAに関連するテーブルBのレコードを検索

特定の`a_id`に関連する`B`テーブルのデータを取得する場合、以下のクエリを使用します。

```sql
SELECT B.b_name
FROM B
JOIN AB ON B.b_id = AB.b_id
JOIN A ON A.a_id = AB.a_id
WHERE A.a_id = '指定のa_id';
```

#### 例2: テーブルBに関連するテーブルAのレコードを検索

特定の`b_id`に関連する`A`テーブルのデータを取得する場合、以下のクエリを使用します。

```sql
SELECT A.a_name
FROM A
JOIN AB ON A.a_id = AB.a_id
JOIN B ON B.b_id = AB.b_id
WHERE B.b_id = '指定のb_id';
```

### 4. インデックスの活用

検索を効率化するために、中間テーブル`AB`には`a_id`と`b_id`の両方にインデックスを作成することが推奨されます。これにより、JOIN操作が高速化され、N対Nのリレーションを効率的に検索できます。

```sql
CREATE INDEX idx_ab_a_id ON AB(a_id);
CREATE INDEX idx_ab_b_id ON AB(b_id);
```

この構造を利用することで、AとBのN対Nリレーションを持つデータを効率的に検索できるようになります。
![対応していない形式のファイルです。]()
Last Epoch のオフラインキャラクタを複製するツール

## Last Epoch というゲームについて

https://store.steampowered.com/app/899770/Last_Epoch/?l=japanese

Last Epoch は、タイムトラベル、エキサイティングなダンジョン探索、夢中になれるキャラクターのカスタマイズ、そして無限のリプレイ性を組み合わせて、ベテランにも初心者にも同様に楽しめるアクション RPG を作成します。エテラの過去の世界を旅し、暗黒帝国、怒り狂う神々、そして手つかずの荒野に立ち向かい、ヴォイドから時間を守る方法を見つけてください。

主な特長
15 のマスタリークラス
5 つの強力なクラスの 1 つとして冒険に乗り出し、旅を通じて、より特殊な能力とビルド オプションのロックを解除する独自のマスタリー クラスに昇格します。

100以上のスキルツリー
すべてのスキルには独自の拡張ツリーがあり、プレイスタイルを制御、変更、強化することができます。スケルトンを射手に変えたり、稲妻をチェーンライトニングに変えたり、蛇を攻撃させて蛇を召喚して一緒に戦わせたりしましょう！

レアで強力な戦利品を狩る
完璧に作り上げることができる魔法のアイテムで武器庫を満たし、強力なユニークなアイテムやセットアイテムでビルドのルールを変更し、Last Epoch の深くランダム化された戦利品システムを使用して、次のアップグレードを常に目前に置いておきます。

やりがいのあるクラフトシステム
あなたが持っているアイテムはあなたのものです！ Last Epoch のコミュニティで尊敬されているクラフト システムを使用すると、堅牢で決定的なアップグレード メカニズムを備え、キャラクターのパワーの進行を制御できます。

過去を明らかにし、未来を再構築する
さまざまな時間の瞬間に移動し、エテラの世界に存在する多くの派閥や秘密を発見し、タイムラインを新しい方向に設定するために戦います。

無限のリプレイ性
カスタマイズできる豊富なクラスとスキル、奥深いゲーム システム、ランダム化された戦利品、継続的な開発を備えた Last Epoch は、今後何年も戻ってくることになるゲームです。

学ぶのは簡単、マスターするのは難しい
私たちは、すぐに戦いに参加できるようにし、多くのゲーム内リソースを提供することで、新規プレイヤーとベテラン プレイヤーが同様にゲームプレイを親しみやすいものにすることに尽力しています。だまされないでください。エテラには、戦闘と構築の熟練を必要とする多くの危険があなたを待っています。

ゼロペイツーウィン
Last Epoch では、リアルマネーを使用できることでゲームプレイの利点が提供されることはありません。私たちはすべてのプレイヤーにとって公平な環境を作り出すことを信じています。


## インストール方法

[https://github.com/nuget-tools/le-tools/releases/latest](https://github.com/nuget-tools/le-tools/releases/latest) から le-tools.exe をダウンロードします。

https://github.com/nuget-tools/le-tools/releases/latest

## le-tools.exe を起動

起動すると、以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/adbfb224-66e7-2394-bac4-5482a52741ef.png)

## キャラ複製

左側のリストからキャラ名を選択して「キャラ複製」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/6de7e47b-6dad-47ef-e89c-d36a6425c00a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/0b4e3488-1dcb-e1c4-81ff-122d6a536dde.png)

「SENTINEL-01」という名前で「SENTINEL-00-D」キャラが複製されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/5cd59cb6-8624-6b53-a77e-3a5d5b35b5c3.png)

## キャラ名変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/00d8c746-1b6a-81e2-ba14-76916f822136.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/4cb77910-67ca-7d96-2904-ad8e994e0a6b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/5cc0e3ac-8648-6f19-3978-4d12a09baf7b.png)

## 「タッチ」

「タッチ」ボタンをクリックすると、画面上では何も変わりませんが、Last Epoch を立ち上げてオフラインにログインすると、キャラ一覧が名前の降順で表示されます。
キャラクターのセーブファイルのタイムスタンプを変更しています。

# 最後に

もし、不明な点やバグがありましたらコメントでお知らせください。
【AWS】LocalStack環境を構築して動作確認する

# はじめに
<!-- 発端や概要を記載 -->
こんにちは、shutamoです。

情報発信の練習と備忘録を兼ねて投稿してみます。
まだまだ未熟者なので、間違っていることがあれば指摘してください！
# 目次
<!-- タイトルとアンカー名を編集 -->
1. [LocalStackとは](#Chapter1)
1. [環境準備](#Chapter2)
1. [LocalStack環境構築](#Chapter3)
1. [AWSサービスを使うための準備](#Chapter4)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# LocalStackとは
AWSをローカル環境でシミュレートできるツールです。
そのため料金などを気にすることなくAWSのサービスを気軽に確認が可能です。

LocalStackには無料版(Community)と有料版(Pro)があります。主な違いは下記の通りです。

・利用可能なAWSサービスの違い
・無料版ではリソースが永続化されない（LocalStackを再起動すると既存のリソースが削除される。）

利用可能なサービスは[こちらのページ](https://docs.localstack.cloud/user-guide/aws/feature-coverage/)を参照してください。一覧で(Pro)と記載のサービスは有料版でのみ利用可能です。

<a id="#Chapter2"></a>
# 環境準備
Windowsを想定しています。

<a id="#Chapter3"></a>
# LocalStack環境構築
まずDockerがインストールされている必要があります。まだの人は[インストールしておいてください。](https://docs.docker.com/get-started/get-docker/)

### [公式サイト](https://docs.localstack.cloud/getting-started/installation/#docker-compose)のDocker-Composeでの起動手順を参考に起動します。

#### 1.任意のディレクトリにdocker-compose.ymlを作成する。

#### 2.作成したdocker-compose.ymlに下記内容を記載する。
```yml:docker-compose.yml
version: "3.8"

services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Gateway
      - "127.0.0.1:4510-4559:4510-4559"  # external services port range
    environment:
      # LocalStack configuration: https://docs.localstack.cloud/references/configuration/
      - DEBUG=${DEBUG:-0}
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

```

#### 3.ymlファイルがあるディレクトリに移動し次のコマンドを実行しコンテナを起動する。
```bat
docker-compose up -d
```
以上でLocalStackのサーバーが起動されました。

<a id="#Chapter4"></a>
# AWSサービスを使うための準備

#### 1.AWS CLIを[インストールする。](https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/install-windows.html)

#### 2.正しくインストールされたか確認のため以下のコマンドを実行してバージョン情報を取得する。
```bat
aws --version
```

#### 3.動作確認として、awscliを利用してLocalStackにアクセスする。
cliからLocalStackにアクセスするためにはまずcredentialsを設定する必要があります。その際、credentialsの設定値は任意で問題ありません。

設定コマンド
```bat
aws configure --profile localstack
```
このように設定してみました
```
AWS Access Key ID [None]: test
AWS Secret Access Key [None]: test
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

### バケットの作成をしてみる
```
# 作成コマンド
aws s3 mb s3://[任意の名前] --endpoint-url=http://localhost:4566 --profile localstack

# 実行結果
make_bucket: [任意の名前]
```

削除したい場合は下記コマンドで削除できます。
```
aws s3 rb s3://[削除したいバケット名] --force --endpoint-url=http://localhost:4566 --profile localstack
```
--forceはバケット内のオブジェクトも一緒に削除するときに書く

S3バケット一覧取得
```
aws s3 ls --endpoint-url=http://localhost:4566 --profile localstack
```

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html

以上です。
Unityパッケージをローカル化する

## なんでそんなことするの？

クラウドサービス「Box」のAPIをUnityで利用する必要がありましたが、このAPIには`Box`という名前空間が含まれています。一方で、Unityの`Visual Effect Graph`パッケージ内の`VFXUIDebug.cs`には`UnityEngine.UIElements.Box`が使用されており、この二つが名前空間の競合を引き起こしてしまいました。

そこで、競合を解消するために`VFXGraph`パッケージのコードを編集する必要がありました。しかし、`Library`フォルダ内のパッケージはGitで共有されず、またUnityのアップデートで上書きされる可能性もあります。そこで、`VFXGraph`パッケージをローカル化し、競合を解消する方法を取ることにしました。

正直パッケージ側で競合しないようになんとかしてほしい( ；∀；)

## Unityパッケージのローカル化手順

### 1. Library/PackageCache から Packages フォルダにコピー
まず、競合が発生している `Visual Effect Graph` パッケージを `Library/PackageCache` フォルダから `Packages` フォルダにコピーします。これにより、Unityは`Packages`フォルダ内のパッケージを優先して参照するようになります。

### 2. 競合の解消とコードのカスタマイズ
次に、コピーしたパッケージのコード内で競合を解消するための編集を行います。具体的には、`VFXUIDebug.cs`内で`UnityEngine.UIElements.Box`を明示的に指定して競合を回避します。編集が完了したら、Unityを再コンパイルすることで修正が適用されます。

## ローカルパッケージのメリットと注意点

### メリット

- **直接編集が可能**  
  パッケージ内のコードをプロジェクトに合わせて直接編集できるため、細かな調整や競合の解消が可能です

- **アップデートで上書きされない**  
  パッケージがローカルにあるため、Unityのアップデートで勝手に上書きされる心配がなくなります

### 注意点

- **更新管理の手間**  
  ローカルパッケージは手動で更新する必要があるため、Unity公式の最新バージョンがリリースされた際には、手動で再度パッケージを取得・編集する必要があります

## まとめ

Unity標準パッケージをローカル化することで、プロジェクトに合わせた競合解消や独自のカスタマイズが可能になります。この方法は、特に外部ライブラリとUnityの名前空間が競合する場合や、パッケージの一部を調整したい場合に有効です。