OmniAICreator/Qiita-1.07M huggingface dataset:
実行中のファイルの「フォルダのパス」を取得する

### 経緯
配属先のプロジェクトにて、実行ファイル(exeを想定)と同じフォルダにdllとiniファイルを格納し、iniファイルに設定した内容を読み込んでdllを実行するという運用があり、iniファイルの格納先を正確に取得する方法を実現するために調べたことをメモとして記載しました。

### 参考にしたWebサイト
https://www.wabiapp.com/WabiSampleSource/windows/path_remove_file_spec.html


### コードのイメージ
配属先のプロジェクトにて作成したコードをもとに一部変えたものを以下に記載します。ポイントは「GetModuleFileName」と「PathRemoveFileSpec」の両メソッドの処理で、それぞれ以下を取得します。
・GetModuleFileName：現在実行中の実行ファイルのフルパスを取得
・PathRemoveFileSpec：末尾のファイル名だけを削除

例,実行中のファイルが「C:\aaa\bbb.exe」の場合以下のようになります。
・GetModuleFileName：「C:\aaa\bbb.exe」(実行ファイル名まで取得)
・PathRemoveFileSpec：「C:\aaa」(実行ファイルが格納されているフォルダを取得)

```
// ヘッダーインクルード
#include <windows.h>
#include <stdio.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

// 実際の処理
int main()
{
    TCHAR iniFileFolderPath[_MAX_PATH];
    memset(iniFileFolderPath, NULL, _countof(iniFileFolderPath));
    GetModuleFileName(NULL, iniFileFolderPath, _countof(iniFileFolderPath));
    PathRemoveFileSpec(iniFileFolderPath);
}
RoboCup Junior Rescue Simulation に出てみた

# Introduction
「受験でノード大会のエントリ逃したからRCJJ出られんわ」と以前言いました。

**あれはウソだ**。

もちろん、当時はそのつもりでいましたよ。

ということでRoboCup Junior Japan Open World League Rescue Simulationに出場してきました。これまで高1、高2とレスキューラインに参加してきたので初めての挑戦です。

きっかけは、年末に[WRS技術委員会](https://rcjjcospace.blogspot.com/2023/12/rcjj2024.html)の「全国統一で予選会するよ、エントリーは1月14日までね」という投稿を見たことでした。
これならエントリーできる、やるしかないと感じ、~~共テを放棄して~~コードを書き続けました。
今度こそ最後の大会。去年大敗した自分への弔い合戦のようなものです。もちろん、大学の内定を持った上での行いですよ。
これを書いている今、大会は始まっていません。さぁ、その結果や如何に。

# チーム紹介
チーム名は「**こんぶ畑**」です。
私と友人の計2人で構成されています。

ちなみにこの友人、ロボットやプログラミングとは全く縁のない運動部の人です。じゃあなぜ彼をチームに迎えたかというと、エントリーした2023年の年末の時点で受験が終わってたからです。WRSはエントリーに2人以上が必要でした。受験が終わっていない旧メンバーを誘うわけにもいかず彼に白羽の矢が立ったわけです。~~「卒業旅行に行こう」と騙って誘いました。~~
突然にも関わらず、私のワガママに付き合ってくれたことに感謝です。

# 競技紹介
レスキューシミュレーションは参加が3チームのみと超ド級のマイナーリーグです。簡単に競技の内容を紹介します。

まず他のリーグと大きく違うのは、**ロボットをシミュレーション上で動かす**ということです。つまりソフトウェアでの一本勝負です。
競技の内容はレスキューメイズとよく似ています。というかメイズを基に作られています。
* **迷路を進みながら壁に貼り付けられた被災者(画像)を探す**

というのがメインのシナリオです。
RCJJのホームページでは以下の様に紹介されています。
>![レスキューリーグ及び各競技紹介.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/cd0b5996-f1bc-ecfe-034e-e14283480de2.png)
>https://www.robocupjunior.jp/info.html より引用

特にメイズと違うのは
* ロボットは公式が用意したものにセンサーを付けたりしてカスタマイズする
* 坂やバンプがない。代わりに沼地がある
* 色の被災者やレスキューキットがない。代わりにハザードマップがある
    <img width="400" alt="photo" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/1e68b6b4-c79a-7eef-4330-60a2a3ad7dae.png">
* 壁の種類が多い
* マッピングの一致率によってポイントが付与される
* **GPS**やLiDARといったチートなセンサを標準で使える

といった部分でしょうか。

競技動画です。

https://drive.google.com/file/d/1_l0D9VXbPb2q3wobI7PMYHxYE4ZLXCem/view?usp=sharing

# 結果発表ーーー!!
![43f4f15027c28cfd62c016a4f6b10be6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/a19833dc-fa64-3d30-a56d-3e64797bc736.gif)
* 第2位 (3チーム中)
* ソフトウェア奨励賞
* 優秀プレゼンテーション賞

でした。

# 情報公開
個人的に、シミュレーションリーグでコードをオープンにすることは、実機リーグのそれとは持つ意味合いが少し違うのかなと思っています。たった1つのexeファイルが文字通り「全て」なんですから。とは言え、情報公開はRCJの国是のようなものなので公開することにしました。テクニカルドキュメントもあります。

[リンク (GitHub)](https://github.com/KOMBU-Batake)

ライセンスはAGPL3.0です。~~Visual Studioのテンプレートで一番上にあったので採用しました。~~

# 「チーム」であったのか
「全部1人で作った」「協力できなかった」というのが去年の後悔でした。

今年のメンバーは工学とは全く別の畑の人です。「今からプログラミングを押し付けるのは違う」と思い、プログラムにどの程度関与するかは本人に任せた上で「プレゼン賞、ソフトウェア奨励賞、スポンサー賞のどれかを取ろう」というのを共通の目標にしました。これらの賞はポスターとテクニカルドキュメント、エンジニアリングジャーナルによって審査されるのでこれなら無理のない範囲だと考えました。
他にも練習用ワールドの作成などを任せました。

結果としてプログラムは1人で全て書きましたが。

# レスキューライン経験者として
RCJJのHPにこんなスライドがあります。
>![レスキューリーグ及び各競技紹介 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2449798/9e192a6d-fcd2-ae2e-31a7-3f8dae7587ff.png)
>https://www.robocupjunior.jp/info.html より引用

これを見るにラインとシミュレーションの違いは
* 難易度
* 現実空間or仮想空間

だと言えそうです。  
実機とシミュレーションを比べるのはナンセンスだという話はさておき、両方を経験した人間としてどちらの難易度が高いかを考えてみます。

まず、初心者から見た難易度は圧倒的にラインの方が低いでしょう。LEGOに乗っかればハードは基本的に安全ですし、ソフトもスクラッチが使えます。そしてライントレースだけでもある程度点が取れます。
それに対してシミュレーションはPythonなど何かしらの言語を必要とします。さらに被災者の発見、つまり画像認識ができなければ得点はほとんどできません。

ですがそのギャップも成長とともに縮んでいくでしょう。最終的な難易度はラインの方が高くなると考えています。ハードウェアの存在も1つですが、ラインはいくらでも難しいコースを作れることが最大の理由です。

どちらも進む先は青天井だとも言ってしまえばそれまでですが。

つまり何が言いたいかといえば、**レスキューメイズの難易度高すぎ**。

# 最後に
今度こそ本当の最後です。年齢的に。それと同時に大学生活の始まりでもあります。大学では何をしようかな、今は学ロボ、鳥人間辺りに目を付けています。
新たな出会いに期待して。

👋

P.S.
大会を支えてくださったロボカップジュニア関係者の皆様に深く感謝申し上げます。
世界一流エンジニアの思考法　読了

RSGT2022 Keynoteの[牛尾さんの動画](https://www.youtube.com/watch?v=Yb95ZUW9SRg)がとても面白かった & 牛尾さんの考え方にとても興味をひかれ、『世界一流エンジニアの思考法』を購入しました。
内容がとても面白く一気に読んでしまったので、書籍の中で特に印象に残った内容を忘れないうちにアウトプットします。

# 書籍について
- 著者である[牛尾さんのnote](https://note.com/simplearchitect/n/n4d66bc3f9218) にまとめられています

# 印象に残った内容
## 基礎の理解に時間をかける
- 一流のエンジニアでも理解に時間をかける
- 理解できるまでじっくり時間をかけて学ぶこと
- 何も調べずに、そらで実現できるところを増やす

<感想>
書籍の中で一番感銘を受けました。プログラミングとは異なりますが、私はAWSやAzureの資格試験の学習を行う時、いつも模試から手を出して曖昧な理解のままぎりぎり合格し、実践の場面で初めて理解できるというサイクルを繰り返してきました。公式ドキュメントやBlackBeltなどの解説を流し見して、「座学はよく分からない！」と逃げていたのですが、きっとそれは基礎の理解をしようとしてこなかったのだと今となっては思います。
また今年も資格試験を受験するつもりですが、その際には基礎の理解に時間をかけようと思います。幸いにもクラウドの資格試験には受験日の期日は無いので。

## フォーカスする仕事は1つの仕事のみにする
マルチタスクは行わず、1つのことを完了することに集中する。そのために集中を阻害する要素を排除する。
- 例：他の作業で使っていたGoogle Chromeのタブを閉じる
- 例：Teamsをオフにする

メールの返信・Teamsのレスポンスは空いた時間にまとめて行うなど、集中する時間とルールを決める

<感想>
仕事しているときに、ついTeamsやメールの通知に気を取られ目移りしてしまってたことに気が付かされました。「いつも速やかに返信するのが美徳」という考えが私の根底にあったように思います。速やかなレスポンス自体はいい事だと思っています。ただし、本当に出さなければならない価値は何か？を考えてみると、いつも必ずしも正しいわけでは無いと感じています。

## 自分が幸せになることをやる
- 自分の人生を幸せにするための行動を主体的に決める
- 日本的な我慢のマインドが自分の中にあっても、それが自分を幸せにするものでなければやめてしまう

<感想>
数年前からもやもやっと自分の中で思っていたことを、この書籍に言語化してもらえました。仕事をする中で、同じような努力・我慢が必要な仕事でも、何となくモチベーションの差を感じていました。そのモチベーションの差は、その努力が自分の幸せにつながるかどうかを心の奥底で判断していたのだなと思います。
私は、今の仕事が幸せだと思うし、仕事で嫌なことがあれば変えていけばいいと思っています。ただし、それは嫌なことを全くやらないというわけでは無く、幸せになるための必要な努力を積極的に行うことだとも思います（書籍の中で牛尾さんの一日のスケジュールが載っており、「凄い…」と圧倒されました）

# 最後に
スクラムマスターとしてアジャイルな取り組みを実践しようとしている身としては考え方に共感する部分がとても多く、自分の考えがいつの間にか意図せずアンチパターンに踏み込んでいることにも気が付かされました。その意味では「メンバーの才能を開花させる技法」と同じように、時々読み返して自分の考え方を振り返る書籍にしたいと思います。

とてもいい書籍に出会えました。本書の著者である牛尾さんに、心から感謝いたします。
【DQチャンプ】Chromebook でゲームパッドをキーマップ（Panda Gamepad Pro 編）

## 親記事

https://qiita.com/gaming_clomebook/items/82dabb5b61d083e640e6

## 操作したいゲームと現状
ドラゴンクエスト　チャンピオンズ（以下、DQチャンプ）
https://www.dragonquest.jp/champ/
※ゲーム単体については、インストールや動作、タッチパッドによる操作には問題がない。そこで、ゲームパッドによる操作を可能にする Panda Gamepad Pro をどうぬ油脂帯が、初期設定を完了出来ていない

## 現在試している方法

以下のアプリを導入しようとしている

- Panda Gamepad Pro - Google Play のアプリ
https://play.google.com/store/apps/details?id=com.panda.gamepad&hl=ja&gl=US

## 現状の整理

https://pandagame.app/a に記載の方法でアクティベートしようとしているがいずれも進まない。

### Ⅰ Activate Directly (Android 11+ ONLY)

以下のエラーメッセージが出て進まない。

![Screenshot 2024-03-31 19.59.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759423/4b31ff5c-5855-92ba-551a-9803d9dbd69e.png)

手動でデーモンを起動したあとも、メッセージは変わっていないように見える。

CPUがAMDなので、libadb.so を導入する必要がある？

### Ⅱ Activation via Connecting to PC

ChromebookをWindows PCとUSBで繋いでも、何もダイアログなどが表示されない

以下の方法でワイヤレスデバッグを試みる？

<a href="https://scrapbox.io/satakebox/Chromebook%E3%81%A8PC%E3%82%92ADB%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B">ChromebookとPCをADB接続する - サタケ箱</a>

上記の手順でsshを起動しようとするが起動しない。

代わりに下記の方法も試すが、こちらも起動しないので現状手詰まり。

- Chromebookで動作するAndroidアプリにadbを接続する方法 #Android - Qiita
https://qiita.com/jiro-aqua/items/81c2a35225387c436f2f#adb%E3%81%AE%E3%81%A4%E3%81%AA%E3%81%8E%E6%96%B9%E5%85%AC%E5%BC%8F


### Ⅲ Activate via OTG Connecting to another phone

chromebook のUSBポートはOGTに非対応なためこの対処法は取れない。

## 状況整理

Ⅰ、Ⅱいずれかで対応をすすめたい
Ⅲについては当面は保留

## 関連するかもしれないリソースのメモ

- ChromeOS 向けアプリの作成を開始する  |  Android Developers
https://developer.android.com/topic/arc?hl=ja#setup
MacBook Air(M2チップ) ruby 3.2 rails 7でrailsアプリを作成

# 目的
macを買ったので環境構築をする


# 今回やること

今回の目標は以下の1つ。
* 環境構築！


# 環境
* MacBook Air(M2チップ)
* ruby 3.2
* rails 7


# いざ出陣

### 背景
使っていたwindows PCが、電源をつけても画面が真っ暗のままになりまして、
新しいPCを買いました。
開発を趣味にしようと思ってM2チップのMacBook Airを購入。

セットアップしようと思ったら、沼ってしまったので備忘録的なことを書きます

### 陥った状況

railsをgemでインストールしても`rails -v`でバージョンが表示されない。。
デフォルトで入っているrubyと、rbenvで入れたrubyのどちらを見ているか分からなくなり、
かつ途中の権限エラーをsudoつけて解消しようとしてたせいでユーザーの権限がよく分からなくなっていました。。

仕方がないので初期化して進めたら、とりあえずできました。

### インストール
以下を参考にインストールしました。

https://qiita.com/ngkr327/items/cc5b199abddaa6739ca7

### 思ったこと

正直sudoがいるか分からないところも付けたり、付けなかったりしていたので
今後は不用意に付けないようにします。

DBはMySQLを使いたかったが、rails7ではクライアントが何とかでできなかったので、
そちらは諦めてsqliteを使用。

# 余談
こんなくだらないことに7時間ほど時間を使った土日でした。
sudoでインストールは気をつけよう
Docker Desktopインストール後初回起動でUnexpected WSL errorが出たときに確認すること

# 環境
* OS：Windows

# エラー内容
Docker Desktopのインストール後、初回起動時以下エラーが発生。
![Docker Desktop - Unexpected WSL error](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3750246/cbdb7fe5-dde7-e80e-ec06-9806e21464e2.png)
`Docker Desktop - Unexpected WSL error`

# 確認すること
### 確認手順
1. タスクマネージャーを開く
1. パフォーマンスタブを開く
1. CPUのパフォーマンスを表示する

### 期待値
* 仮想化が有効になっていること

# 対処方法
[確認すること > 期待値](#期待値)に沿わない場合、BIOS設定で仮想化を有効にする。
BIOSの画面はPCにより違うため、各サポートを確認すること。

### 例）Lenovo製品の場合
[Lenovoサポート > Virtualization Technology (VT-X)を有効にするには](https://support.lenovo.com/jp/ja/solutions/ht500006-how-to-enable-virtualization-technology-on-lenovo-computers)を参照。

# その他の原因

仮想化が有効になっているにも関わらず、`Docker Desktop - Unexpected WSL error`が発生している場合は、他に原因があるため調べること。
* `Windowsの機能の有効化または無効化`が正しく設定できているか
* WSLの前提条件を満たしているか
* Dockerのバージョン起因ではないか

# 詳細
Dockerはバージョンによって内部でWSLを利用している。そして、WSLは内部でHyper-Vを利用している。Hyper-Vは仮想マシンを使うためのツールである。結果、BIOSで仮想化が無効化されている場合、Docker Desktopインストール後初回起動で`Unexpected WSL error`が発生する。
Duet AI in BigQuery を使ってみた

# タイトル
## はじめに
この記事は 2024/2/26 に行われた [color is【クラウドLT大会vol.7】](https://saison-coloris.connpass.com/event/308746/)の発表内容をベースに作成しています。

https://speakerdeck.com/yu_sa18/duet-ai-in-bigquery

## Duet AI in BigQuery とは
Duet AI とは Google Cloud や Google Workspace で Google の生成 AI モデルからの支援を受けることができる機能です。

https://cloud.google.com/duet-ai?hl=ja

Duet AI in BigQuery では、BigQueru のコンソール画面で SQL クエリの開発支援を受けることができます。

 - 自然言語から SQL クエリを作成する
 - エラーが発生している SQL クエリの補完を行う
 - 完成しているクエリを説明する

わたしの環境で、3つのうち上2つの機能が使えるようになりました。
この記事では Duet AI in BigQuery を使う上で気を付けた点などをまとめます。

### 有効化の方法
2024/2 時点でプレビュー状態となっており、使うには専用フォームに申し込み、有効化してもらう必要があります。
申し込みフォームは以下公式ドキュメントにリンクがあります。英語表記にするとフォームリンクが表示されました。

https://cloud.google.com/bigquery/docs/write-sql-duet-ai

## 規約について
前述の通りプレビュー状態のため、Duet AI in BigQuery では2つの規約が適用されています。
 - Service Specific Terms の Pre-GA Offerings Terms
 - ADDITIONAL TERMS FOR GENERATIVE AI PREVIEW PRODUCTS

https://cloud.google.com/terms/service-terms

https://cloud.google.com/trustedtester/aitos?hl=en

ADDITIONAL TERMS FOR GENERATIVE AI PREVIEW PRODUCTS にて、生成 AI が出力する結果を公開することが禁じられています。
なのでこの記事では公式ドキュメントで公開されている結果のみを使用します。

https://cloud.google.com/bigquery/docs/write-sql-duet-ai?hl=ja

## 機能について
### 自然言語から SQL クエリを作成する
先頭に '#' をつけて作成したいクエリの概要を書き Enter ボタンを押すと、Duet AI がクエリ案を提案してくれます。
提案を採用する場合は Tab キー、採用しない場合は他のキーを押します。

### エラーが発生している SQL クエリの補完を行う
クエリにエラーが発生していると赤波線が表示されます。
エラーが発生しているクエリのどこかで Enter ボタンを押すと、Duet AI が修正案を提案してくれます。
クエリ生成と同様、提案を採用する場合は Tab キーを押します。

## 気を付けたこと
使ってみて、BigQuery の特性をうまく利用したクエリを作るには指示の出し方に工夫がいると感じました。
### 例① 配列データのカラムを扱いたい場合
配列やネストされたカラムの中身を SELECT 文で取得したい場合、`UNNEST()` 関数を使います。

https://cloud.google.com/bigquery/docs/arrays?hl=ja

Duet AI に指示を出すとき、配列データのカラム名だけを指定すると、UNNEST を使わないクエリが生成されました。
公式ドキュメントに沿った表現で、取得したいカラムが配列データであり、展開してほしいことを示す必要がありました。
日本語ではうまくできなかったのですが、英語で `flat <カラム名> into a set of rows` という指示の出すと成功しました。

### 例② パーティション分割テーブルを使う場合
パーティション分割テーブルは、Where 句にパーティションキーとして使っているカラムを指定することで、クエリ実行時のパフォーマンスが向上します。

https://cloud.google.com/blog/ja/topics/developers-practitioners/bigquery-admin-reference-guide-storage

コンソール画面でパーティション分割テーブルの詳細タブよりクエリタブを開くと、Where 句にパーティションキーが指定された状態で開きます。

![image (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426544/ff8a22c1-3802-9441-b97a-17c958ee8d14.png)

それもあり、パーティション分割テーブルで絞り込みするような指示を出したとき、パーティションキーでの絞り込みを期待しましたが、生成された結果は別のカラムで絞り込みをしていました。
なので明示的にパーティションキーで絞り込むような指示を出す必要があります。

わたしが試したテーブルのパーティションキーは日付カラムだったのですが、生成されたクエリの絞り込みカラムも日付カラム・キーと同じ日付フォーマット（YYYY-MM-DD形式）を使っていました。
なので、Duet AI は指示した絞り込みの文字列よりデータ型を推測していそうでした。

以上です。どなたかの参考になれば幸いです。
arduinoで文字列から指定の文字で区切る方法

Arduinoで"abc,def,ghi,jk"などの文字列を,で区切って配列に入れる関数です。

```c
String cmds[7] = { "\n" }; 

//-------------------------------------------------------
//概要：dataの文字を区切って配列に入れる
//引数：data=区切りたい文字列　delimiter=区切り文字　dst=区切った文字を入れる配列
//戻り値：配列の数
//-------------------------------------------------------
int split(String data, char delimiter, String* dst) {
  int index = 0;
  int arraySize = (sizeof(data)) / sizeof((data[0]));
  int datalength = data.length();

  for (int i = 0; i < datalength; i++) {
    char tmp = data.charAt(i);
    if (tmp == delimiter) {
      index++;
      if (index > (arraySize - 1)) return -1;
    } else dst[index] += tmp;
  }
  return (index + 1);
}


void setup() {
  String Data = "abc,def,ghi,jk"
  Serial.begin(19200);  // シリアル通信速度設定
  int index = split(Data, ',', cmds);
  for(int i=0;i < index;i++){
    Serial.println(cmds[i]);
  }
}

```
結果
abc
def
ghi
jk
ChromebookでのDebian12へのアップグレードで参考にしたサイト

どうもChromebookのLinuxコンテナに関して、いつもDebianのアップグレードは失敗する。

標準機能でアップグレードしようとすると、Gitを消されたうえで復旧が難しくなる。コマンドからアップグレードしたらGitも正常にインストールできるようになりました。

https://qiita.com/DaikichiDaze/items/d7f2495ff7e395763edd

# 環境
- HP Elite c1030 13.5 Chromebook
- ChromeOS Version 122.0.6261.137 (Official Build) (64-bit)
- Debian 11

# 参考にした記事
実際にこの記事手順で更新できました。
https://bitwalk.blogspot.com/2023/12/linux-chromebook.html
【Nextjs × microCMS × QiitaAPI】高校生が春休みに念願の個人ブログを開設

# はじめに
今回はNextjsとmicroCMSを使って個人ブログを簡単に作ってみたので紹介します！
個人的にブログを作りたい気持ちがめちゃくちゃあったので、もしそういう方がいたら参考になると幸いです！

# 紹介
こんな感じでかっこいいブログが完成しました！！
<br />

![スクリーンショット 2024-03-31 164033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554025/a68c25ae-5608-0fb0-9fca-09294d8b00be.png)

![スクリーンショット 2024-03-31 164048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554025/34f13e58-7735-9b5e-9037-ef601e8f054c.png)

![スクリーンショット 2024-03-31 164114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554025/38fe76e3-4dcd-301b-27af-b2ee8b2df74a.png)

### 機能
- microCMSからブログ記事を取得して表示する
- Qiitaの記事を表示
- ブログ記事の場合は詳細ページを表示、Qiita記事の場合はそのリンクへ飛ぶことができる

### 使用技術一覧
- Next.js
- microCMS
- Qiita API
- tailwindcss
- daisyUI
- firebase(ホスティング先)
- jest
- react-testing-library
- github actions(CI/CD)

# 技術紹介
今回の開発で初めて触れた技術について紹介したいと思います

### microCMS
microCMSとは？？
> microCMSはAPIベースの日本製ヘッドレスCMSです。
快適な管理画面により、開発・運用コストを大きく削減することで、ビジネスを加速させます。
>
>公式サイトより引用

僕の言葉でご説明させていただくと、**ブログのコンテンツを管理できるシステム**です。

こちら少し見にくいかもしれませんが(クリックすると大きく見れるはずです)、自分でAPIを作ることでブログのコンテンツ管理を非常に簡単に行うことが可能です。
![スクリーンショット 2024-03-31 164745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554025/bd0b117d-89fa-ccd5-4818-2128670f27de.png)

使い方はいたってシンプルです。

1. プロジェクトを作る
　　　↓
2. APIを作る
　　　↓
3. microCMS公式のsdkを利用してデータを取得する
<br/>

少し情報は古いような気がしていますが、こちらとても参考になりました。

https://blog.microcms.io/microcms-next-jamstack-blog/

### daisyUI
daisyUIはtailwindcssをベースに作られたUIライブラリです。
僕の作ったブログのような画面がとてつもなく簡単にできてしまいます。UI構築を煩わしく感じている人にはうってつけです！作っていてすごく楽しいライブラリです。ぜひとも体験してほしいです！

https://daisyui.com/

### QiitaAPi
正直ドキュメントを見ても使い方がわかりにくかったです。なのでchatgptなどを駆使して使ってみました。

僕はこのような感じで取得しました。headersに認証情報を書けばよいみたいです。
```ts
  const res = await fetch(
    //?per_page= というクエリをつけると取得記事数を制限できる
    `https://qiita.com/api/v2/users/ユーザーID/items?`,
    {
      method: "GET",
      headers: {
        Authorization: `Bearer ${process.env.QIITA_API_TOKEN}`,
        "Content-Type": "application/json",
      },
      //これでSSRでデータ取得が可能
      cache: "no-store",
    }
  );
```

https://qiita.com/api/v2/docs

# 躓いたところ
- apiを作るのか関数を作るのか
nextjsでは簡単にAPIを作ることも可能ですが、apiを叩くとjson形式で返すようにしており、.json()をいちいちする必要があるなどの理由から正直恩恵を感じることが出来ませんでした。
qiitaAPIからデータ取得する際に取得記事数の制限をかけられるようにapiを作ったのが原因かもしれません。apiがあるのにその中間にapiを作るとはどういうこっちゃ！と自分は思ってしまいました。
<br />

- microCMSのクライアント作成
詳しくはこちらをご覧ください

https://qiita.com/shunii/items/fa8aeb07a8064a64361c

- レンダリング方法
最初のうちはCSRを使ってしまっていて、やたらと処理が遅くなるということがありました。まだ使い方も慣れていなかったので今後どしどし使っていこうと思います。

# 終わりに
daisyUIのおかげもあってUIはサクサク完成していくし、microCMSも割と使いやすかったので開発していてすごく楽しかったです！みなさんもぜひ個人ブログを作ってみてください！！

理想の個人ブログ開発はつづく、、、、
次回「SEOを意識したJamstack構成のブログを作ってみた」
お楽しみに～～😊

# 🔥JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
気になる方はぜひHPからライン登録お願いします！
https://projisou.jp
![jisou-banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/217ea52d-8130-3266-0619-990fa968408a.png)

# ✨About Me✨
友達になってくれよな(きらん)
- X(Twitter)

https://twitter.com/shunii_hack
Azure CLI コマンドの出力をフィルタリングする

## はじめに

Azure CLI コマンドの出力は JSON 形式で返されるため、そのままでは読みづらいことがあります。本記事では、Azure CLI の出力をフィルタリングして必要な情報だけを的確に取得する方法を紹介します。

## \--query オプションを使用する方法

Azure CLI の --query オプションを使用すると、JMESPath クエリ言語を用いて出力結果をフィルタリングできます。

例えば、特定のリソースグループ内の仮想マシンの一覧を表示する際に、名前と OS のみを取得したい場合は以下のようにします。

```bash
az vm list -g myResourceGroup --query "[].{Name:name, OS:storageProfile.osDisk.osType}" -o table

```

このコマンドの詳細は以下の通りです。

- `az vm list -g myResourceGroup`: 指定したリソースグループ内の仮想マシンの一覧を取得するコマンド
- `-query "[].{Name:name, OS:storageProfile.osDisk.osType}"`: 出力結果をフィルタリングするための JMESPath クエリ
    - `[]`: 配列内の各要素に対してクエリを適用
    - `{Name:name, OS:storageProfile.osDisk.osType}`: 取得したい属性 (名前と OS の種類) を指定
- `o table`: 出力形式をテーブル形式に指定

出力例:

```
Name       OS
---------  --------
linux-vm1  Linux
linux-vm2  Linux
windows-vm Windows

```

## jq コマンドを使用する方法

jq は JSON 形式のデータを処理するためのコマンドラインツールです。Azure CLI の出力は JSON 形式なので、パイプで jq に渡すことでフィルタリングできます。

例えば、リソースグループ内の仮想マシン名だけを取得したい場合は以下のようにします。

```bash
az vm list -g myResourceGroup | jq '.[].name'

```

このコマンドの詳細は以下の通りです。

- `az vm list -g myResourceGroup`: 指定したリソースグループ内の仮想マシンの一覧を取得するコマンド
- `| jq '.[].name'`: Azure CLI の出力を jq にパイプで渡し、JSON データをフィルタリング
    - `.`: JSON データのルート要素を表す
    - `[]`: 配列内の各要素に対して処理を適用
    - `name`: 取得したい属性 (仮想マシン名) を指定

出力例:

```json
"linux-vm1"
"linux-vm2"
"windows-vm"

```

### jq の -r オプション

デフォルトでは、`jq` は JSON 形式で出力を生成するため、文字列値はダブルクォーテーション (`"`) で囲まれます。しかし、`-r` (または `--raw-output`) オプションを使用すると、`jq` は出力からダブルクォーテーションを取り除き、生の文字列値だけを返します。

例えば、先ほどの例に `-r` オプションを追加すると:

```bash
az vm list -g myResourceGroup | jq -r '.[].name'

```

出力は次のようになります:

```
linux-vm1
linux-vm2
windows-vm

```

この出力では、仮想マシン名がダブルクォーテーションなしで表示されています。`-r` オプションは、`jq` の出力を他のコマンドやスクリプトに渡す場合に特に便利です。

## その他の例

- 特定のリソースグループ内のストレージアカウント名とアカウントの種類を取得する

```bash
az storage account list -g myResourceGroup --query "[].{Name:name, Type:sku.name}"

```

- `az storage account list -g myResourceGroup`: 指定したリソースグループ内のストレージアカウントの一覧を取得するコマンド
- `-query "[].{Name:name, Type:sku.name}"`: 出力結果をフィルタリングするための JMESPath クエリ。名前 (name) とアカウントの種類 (sku.name) を取得

出力例:

```json
[
  {
    "Name": "mystorageaccount1",
    "Type": "Standard_LRS"
  },
  {
    "Name": "mystorageaccount2",
    "Type": "Standard_GRS"
  }
]

```

- 特定のリソースグループ内のパブリック IP アドレスの IP アドレスのみ取得する

```bash
az network public-ip list -g myResourceGroup | jq -r '.[].ipAddress'

```

- `az network public-ip list -g myResourceGroup`: 指定したリソースグループ内のパブリック IP アドレスの一覧を取得するコマンド
- `| jq -r '.[].ipAddress'`: Azure CLI の出力を jq にパイプで渡し、JSON データをフィルタリング
    - `r`: jq の出力を生の文字列 (raw output) として表示

出力例:

```
20.43.122.47
52.143.90.218

```

## まとめ

Azure CLI の --query オプションと jq コマンドを適切に使い分けることで、出力結果を柔軟にフィルタリングできます。また、コマンドにリソースグループを指定することで、特定のリソースグループ内のリソースに対して操作を行うことができます。`jq` の `-r` オプションを使用すると、JSON 形式ではなく生の文字列値として出力を取得できます。これにより、必要な情報だけを的確に取得することが可能になります。是非、Azure CLI でのリソース管理にお役立てください。

## 参考記事

- [JMESPath クエリを使用して Azure CLI コマンドの出力に対してクエリを実行する方法](https://docs.microsoft.com/ja-jp/cli/azure/query-azure-cli)
- [jq Manual (development version) | jq](https://stedolan.github.io/jq/manual/)
- [Azure CLI の概要](https://docs.microsoft.com/ja-jp/cli/azure/get-started-with-azure-cli)
pyenvとpoetryを活用したPython開発環境の構築

## ゴール(はじめに)：
Windows Subsystem for Linux (WSL) 内でのPython開発環境を構築する方法を紹介します。特に、バージョン管理システムの`pyenv`とパッケージ管理ツールの`poetry`を使用することで、プロジェクトごとに異なるPythonのバージョンと依存関係を簡単に管理できるようになることを目指します。


## やってみた結果
この方法を用いることで、異なるプロジェクト間でのPythonのバージョンの衝突を避けつつ、必要な依存関係を正確に管理できるようになります。結果として、開発の効率性が大幅に向上し、複数のプロジェクトを同時に進行させる際のストレスが軽減されました。

## 開発環境
- Windows 10または11
- Windows Subsystem for Linux (WSL2推奨)

## 事前準備
1. **WSLの有効化とセットアップ**：WindowsにWSLをインストールし、UbuntuなどのLinuxディストリビューションをセットアップします。


## やったこと
以下の手順でWSL内にPython開発環境を構築します。

### pyenvのインストール

1. 必要な依存関係のインストール：
    ```bash
    sudo apt update; sudo apt install build-essential libssl-dev zlib1g-dev \
    libbz2-dev libreadline-dev libsqlite3-dev curl \
    libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
    ```
2. `pyenv`のインストールスクリプトを実行：
    ```bash
    curl https://pyenv.run | bash
    ```

### pyenvの設定

1. bashの設定ファイルにpyenvの初期化コマンドを追加：
    ```bash
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
    echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(pyenv init -)"' >> ~/.bashrc
    ```
2. シェルを再起動して、設定を有効化します。

### Pythonのバージョン管理

1. 利用可能なPythonバージョンをリストアップ：
    ```bash
    pyenv install --list
    ```
2. 必要なバージョンをインストールし、プロジェクト用に設定：
    ```bash
    pyenv install 3.10
    ```

### poetryのインストール

1. `poetry`の公式インストールスクリプトを実行：
    ```bash
    curl -sSL https://install.python-poetry.org | python3 -
    ```

### プロジェクトの依存関係管理
1. 新しいプロジェクトの作成：
    ```bash
    mkdir myproject && cd myproject
    ```
2. `poetry`を使用して新しいプロジェクトを初期化：
    ```bash
    poetry init
    ```

## 関連ツールの紹介

今回は使用していませんが、`pipx`や`pipenv`など他のツールを使うことも検討してみてください。

## 参考文献
- [Pythonのパッケージ管理ベストプラクティス](https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64)
- [pyenv公式ドキュメント](https://github.com/pyenv/pyenv)
- [poetry公式ドキュメント](https://python-poetry.org/docs/)

## おわりに

WSL内で`pyenv`と`poetry`を使ったPython開発環境を構築する方法を紹介しました。これらのツールは、プロジェクトのPythonバージョンと依存関係を簡単に管理できるようにすることで、開発プロセスを大きく助けてくれます。
AWS CloudFormationを使ってALBアクセスログの自動収集を設定する方法


## はじめに

アプリケーションの運用において、ログの収集・分析は不可欠です。
特にAWSのApplication Load Balancer（ALB）を使用している場合、アクセスログを有効にすることで、トラフィックパターンの分析、パフォーマンスの監視、セキュリティの強化などが可能になります。
この記事では、AWS CloudFormationを使用して、ALBのアクセスログを効率的に収集・保存するための設定を自動化する方法を紹介します。

## 前提条件
この手順を実施する前に、次の条件が満たされている必要があります。
 - ALB（Application Load Balancer）が設定され、動作している
 - AWS CLIがインストールされ、適切に設定されている（AWS CLIの場合）

## 作成リソース

- S3バケット: ALBのアクセスログを保存します
- S3バケットポリシー: ALBからのログファイルの書き込みを許可します

## CloudFormationテンプレート

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Template to create S3 bucket for ALB Access Logs and enable logging

Resources:
  AccessLogsBucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      AccessControl: LogDeliveryWrite
      BucketName: !Join [ "-", [ "alblog", !Ref "AWS::AccountId" ] ]

  BucketPolicy:
    Type: 'AWS::S3::BucketPolicy'
    Properties:
      Bucket: !Ref AccessLogsBucket
      PolicyDocument:
        Statement:
          - Action: 's3:PutObject'
            Effect: Allow
            Resource: !Sub 'arn:aws:s3:::${AccessLogsBucket}/*'
            Principal:
              Service: 'elasticloadbalancing.amazonaws.com'
          - Action: 's3:GetBucketAcl'
            Effect: Allow
            Resource: !GetAtt AccessLogsBucket.Arn
            Principal:
              Service: 'elasticloadbalancing.amazonaws.com'
```

## デプロイ方法（AWSマネージメントコンソールの場合）
1. CloudFormationで、保存した`alb-access-logs.yml`ファイルをアップロードします
2. 待つ

## デプロイ方法（AWS CLIの場合）

1. 上記のテンプレートを`alb-access-logs.yml`として保存します
2. AWS CLIを使用して、以下のコマンドでCloudFormationスタックをデプロイします

```bash
aws cloudformation create-stack --stack-name alb-access-logs-stack --template-body file://alb-access-logs.yml --capabilities CAPABILITY_IAM
```

## アクセスログ有効化
参考文献
https://dev.classmethod.jp/articles/alb_accesslog_enable/

## デプロイ後の確認

- S3バケットが正しく作成されたことを確認します
- S3バケットポリシーが適用され、ALBからのログがバケットに保存されていることを確認します

## まとめ

CloudFormationを使用することで、ALBのアクセスログ収集・保存設定を効率的に自動化できます。
この方法により、アプリケーションの監視とセキュリティが強化され、運用の効率性が向上します。
AndroidStudioのプラグインを使用してJSONをKotlinのデータクラスに一瞬で変換する

AndroidStudioのプラグインを使用する事があまりなかったのですが、便利な機能があるので最近調べています。

APIのレスポンスデータを参考にデータクラス実装するのは単純作業なので、面倒ですよね。

AndroidStudioのプラグインを使用してJsonをKotlinのデータクラスに一瞬で変換してみようと思います。

# 変換方法
プラグインの入れ方はこちらを参考にしてください。

https://qiita.com/yuta317/items/4599276d5b2e58250364

こちらを使用します

https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-

![スクリーンショット 2024-03-31 17.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/27f855d3-73a6-eaef-953b-e5735452e9ff.png)

こちらをインストールいたします。

# 使用方法

![スクリーンショット 2024-03-31 18.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/42f5e310-ae53-e6db-f78c-42da2deaca67.png)

普段クラスを作成するときと同じで右クリックをすると画像のようなものが増えてます。

画像のような画面が表示されるので、変換するJSONを入力します。

![スクリーンショット 2024-03-31 18.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/f6517096-1a3b-b2f7-cb14-1ddd24c2ef94.png)

 Class Nameに作成するデータクラス名を入力します。

 Advancedをクリックすると詳細設定ができます。

![スクリーンショット 2024-03-31 18.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/eda03b73-1bc5-8d0c-b283-5a92d0c4c9ef.png)

 
![スクリーンショット 2024-03-31 18.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/2fd1b318-adb4-5b99-3daf-c8b46645c774.png)

今回は`@Keep`　`@Serializable`　の設定しています。

出来上がったデータクラスはこちらです。

```User.kt
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import androidx.annotation.Keep

@Keep
@Serializable
data class User(
    @SerialName("member")
    val member: Boolean,
    @SerialName("user_id")
    val userId: Int,
    @SerialName("user_name")
    val userName: String
)
```

簡単に作成できました！
PostgreSQLのコマンド一覧

# 接続前
| 内容             | コマンド                 |
| ---------------- | -------------------- |
| サーバステータス表示 | pg_isready|
| サーバ起動 | pg_ctl start -D /usr/local/var/postgres |
| サーバ停止 | pg_ctl stop -D /usr/local/var/postgres |
| データベース一覧表示| psql -l |
| データベース接続 | psql -d (DB_NAME) -U (USER_NAME) -h (HOST_NAME) |

# データベース
| 内容             | コマンド                 |
| ---------------- | -------------------- |
| 抜ける | \q | 
| データベース一覧表示 | \l | 
| 他のデータベースに接続 | \c (DB_NAME) | 
| テーブル一覧表示(sequence含む) | \d | 
| テーブル一覧表示(sequence含まない) | \dt | 
| スキーマ一覧表示 | \dn | 
| スキーマ詳細表示 | \d (TABLE_NAME) | 
| アクセス権限表示 | \z | 
| ユーザ一覧表示 | \du | 
| スキーマからテーブル情報取得 | \dt (テーブル名).* | 

# テーブル操作
| 内容             | コマンド                 |
| ---------------- | -------------------- |
|データ一覧| select * from (TABLE_NAME);|

# 参考

https://dev.classmethod.jp/articles/postgresql-organize-command/

https://qiita.com/poccariswet/items/9c75da7b626f31d8abac
Aurora Limitless Database 概要

# これは何？

AWS re:Invent 2023で発表されたAuroraの新機能「Amazon Aurora Limitless Database 」を使う側の目線でご紹介します。



# Amazon Auroraとは？
- AWSが開発した独自のRDBエンジンで、RDSのひとつ
2種類の互換DBを選択可能
-- MySQL
-- PostgreSQL
- 高機能高性能
通常の5倍のパフォーマンス
最大128TBのストレージ
最大15台のリードレプリカ
マルチAZでデータ保存し高い耐障害性


## Limitless Databaseとは？
「AWS re:Invent 2023」で発表されたAurora Postgrersの新機能

- 既存のProvisioned、ServerlessV1、ServerlessV2に加えた4つ目の新たな稼働方式
-- 書き込み性能をスケールアウト／スケールインすることができる
-- 1秒あたり数百万件の書き込みトランザクションに対応
-- ペタバイト単位のデータを管理できる

※一般には利用不可
公式ドキュメントも未公開

### 従来方式との違い
スケールアウト、アケールアップが無停止で可能となる。

-- 書き込み性能のスケールアウト／スケールインが無停止でできる
-- 数百万/秒のトランザクションを処理できる
-- 従来の10倍以上のペタバイト単位のデータを管理できる

さらに、1つのエンドポイントで利用可能！

従来は書き込み用と読み取り用でエンドポイントが分かれていたが、１つのエンドポイントでオートスケーリングできるように改善されました。

- 従来の稼働方式
-- 従来はアプリ側でエンドポイントの使い分けが必要
-- 読み込みはスケールアップ、スケールアウトどちらにも対応していましたが、スケールアウトは読み取り専用のリーダーエンドポイントのみが対応
-- 書き込みはスケールアウトができず、ライターエンドポイントに対するスケールアップのみ対応

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/f7bc70de-34f5-6049-b102-0043e4b06fe6.png)


- 今回のLimitless Database
-- アプリ側は使い分け不要になり、１つのエンドポイントに接続するだけです。
-- 新たに追加されたLimitless Database用の1つのエンドポイントで読み書きどちらもスケールアウト、スケールアップにマルチAZで対応
従来のエンドポイントも残っており、合計３つのエンドポイントが利用できます。移行時の互換性のために残しているのではないでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/446f77ba-aa5e-38a4-a1da-70d2f5865811.png)



### 分散管理「シャーディング」
データを「シャード」という単位で分割管理する仕組み

複数のシャード（ノード）に分散してデータを書き込みすることでスケールアウトを実現
シャードは通常、ユーザが管理するのは難しいがLimitless Databaseにより完全マネージド化


使い方（インスタンス作成）
クラスターにシャードグループを追加する方式

従来通りコンソールまたはAPIでAuroraクラスターを作成
DBシャードグループ（Limitless Database）を追加
Auroraキャパシティユニット(ACU)の最大値を選択可能
既存のクラスターにも追加できると推測

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/1e4e4ca9-ac14-5b40-6567-f0bd511835e7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520895/d0ab5de5-8c66-5e24-ba65-a9698083b8cd.png)


## ユースケース
大規模なトランザクションで有効

- 1秒あたり数百万の書き込みトランザクションを処理し、ペタバイト単位のデータを管理できるため、今までAuroraで対応できなかった大規模なデータベースワークロードを１つのデータベースで利用可能
- 逆に小さすぎるワークロードではシャーディング等のオーバーヘッドで適さない可能性あり
- これだけの高機能であるため、現行のAurora Serverlessよりも高単価となり、性能特性と費用対効果で使い分けることになる

## まとめ
Amazon Aurora Limitless Databaseは、AWSで今まで対応できなかった大規模なワークロードのRDBに対応できるようになりました。
テーブル作成DDLへのシャーディング設定等、使う上での考慮事項は多々ありそうです。
【Python】class構文解説！！

# はじめに
「class」は、Pythonを勉強する上で必ず押さえて欲しい内容になります。
classは試験や開発で必要になる知識です。概念が難しいのでしっかりと理解してください。

## classとは
結論から言うと、オブジェクト（もの）の内容を定義しておくものです。別の言い方で「ひな形」です。
今回使用するのは、Userというオブジェクトの定義です。
中身は、「挨拶」と「年齢を表示」という単純なものです。

## メソッドとは
classの中で処理をまとめているもの。関数になります。

## インスタンス化とは
classに対してデータを格納すること。つまり、classを使用する為の準備。

## 実際のコード
以下のコードはclassの内容です。
例1. `class_1.py`(userの情報を取得する。)
```python
class User:
    user_type = None
    
    def __init__(self, name, age, address):
        """初期化をするメソッド"""
        self.name = name
        self.age = age
        self.address = address
    
    def age_view(self):
        """年齢を表示するメソッド"""
        print(f'{self.name}さんの年齢は{self.age}です。')
    
    def name_hello(self):
        """挨拶をするメソッド"""
        print(f'{self.name}さんこんにちは！！')
```
以下のコードがクラスを使用するコードになります。

`user.py`
```python
from class_1 import User

user1 = User("大谷", "30", "アメリカ") # インスタンス化

print(type(user1))

print(user1.name)
user1.age_view() # 年齢表示のメソッドを呼び出す。
user1.name_hello() # 挨拶メソッドを呼び出す。
```

## 実行した結果(例1)
```
<class 'class_1.User'>
大谷
大谷さんの年齢は30です。
大谷さんこんにちは！！
```

例2. `class2.py`(数値を渡して処理を行うクラス)
```python
class Calculator:
    def __init__(self, number, number_1):
        """初期化メソッド"""
        self.number = number
        self.number_1 = number_1

    def total(self):
        """numberの合計を求めるプログラム"""
        sum_lst = [i for i in range(self.number + 1)]
        ans = sum(sum_lst)
        print(f'1から{self.number}を全て足した合計は-> {ans}')
    
    def add(self):
        return self.number + self.number_1
    
    def even(self):
        """偶数を求めるプログラム"""
        even_lst = [i for i in range(self.number) if i % 2 == 0]
        return even_lst 
```

実際に呼び出す為のプログラム`caluculator.py`

```python
from class_2 import Calculator
total = Calculator(10, 100)

total.total()
print(total.add()) # 合計を求める
print(*total.even()) # 偶数を求める
```
## 実行した結果(例2)
```
1から10を全て足した合計は-> 55
110
0 2 4 6 8
```
macが重い。文字入力・ライブ変換が遅い。WindowServerのCPU占有率がおかしい

ある日から少しずつ遅くなり、文字入力がとてつもなく遅くなってしまった。

## 現象の整理
- 特に重いプロセスを実行しているわけでもないのに、突然ファンが高回転になる。当然、本体も熱い状態
- ことえり日本語入力が遅くなる。特にライブ変換が遅くなる
- SlackやChromeが極端に遅い。反応も悪い
- Venturaにアップグレードしたあたりから、この現象が生じるようになった
- 特に外部ディスプレイに接続するとこの問題が酷くなる
- 再起動すると改善するが、数時間後に悪化し始める

周りに同一の現象を持った人がおらず、直すの苦労しましたので、メモとして残しておきます。

## 状況
 - 13-inch, 2020, MacBook Pro
 - 2.3GHz Corei7, 32GB RAM
 - Ventura 13.6.6

```
$ uname -a
Darwin macookpro2020.local 22.6.0 Darwin Kernel Version 22.6.0: Mon Feb 19 19:48:53 PST 2024; root:xnu-8796.141.3.704.6~1/RELEASE_X86_64 x86_64
```
4年前のx86のmacとはいえ、スペックに問題があるとは思えない。

## topコマンドやActivityMonitorで原因を調べる
```bash
$ top
```
ActivityMonitorの方が使いやすいかなという気がしますが、どちらでもいいです。



## WindowServerのCPU占有率がおかしい
```
PID   COMMAND      %CPU TIME     #TH   #WQ  #PORT MEM    PURG   CMPRS PGRP PPID STATE    BOOSTS         %CPU_ME %CPU_OTHRS UID  FAULTS   COW
6975  WindowServer 80.9 09:08.73 16    7    1678  587M   91M    0B    6975 1    sleeping *0[1]          3.59132 0.50891    88   873826+  1982
```
(数字は当時のイメージです。)

やたらWindowServerというプロセスがCPUをくっているようでした。
ウィンドウ描画を行うプロセスですので、外部ディスプレイ入力時に問題が酷くなる点などと因果関係が濃厚になってきました。
また、ことえりのライブ変換入力は、WindowServerの状況によっては入力が遅くなるという情報もRidditでちらほら見かけました。

## 試したこと

### macOSの透明効果をオフにする
「システム環境設定」→「アクセシビリティ」→「ディスプレイ」

`Reduce transparency(透明度を下げる)`のチェックをオン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247444/4843db26-0acc-3d8c-ea6f-d8e970572773.png)

### Mission Controlの自動配置をオフにする
「システム環境設定」→「デスクトップとドック」→「Mission Control」
`Automatically rearrange Spaces based on most recent use`のチェックをオフ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247444/a4df5a0b-e4c5-34da-4f45-166253bcc73f.png)

### デスクトップ上に配置しているファイルやフォルダを別の場所に移動する
そのままの意味です。

環境的にはこれが一番効果がありました。
デスクトップに多数の動画ファイルを配置していたことが問題だった模様。

### TimeMachineをオフ（または時間指定に）
TimeMachineEditorで深夜帯にバックアップ時刻を指定しました。

https://tclementdev.com/timemachineeditor/


## 終わりに
なおってよかった。
良い機会だったので、`launchd` に登録されていたよくわからないplistを削除しまくりました。
「システム環境設定」→「全般」→「ログインアイテム」も見ておくと良さそうです。

### 余談
`Thomas CLEMENT` という謎のLoginItemが表示されており、なんだこれ？と思ったら、 `TimeMachineEditor`の作者さんの名前だそうです。
署名が彼の名前のため、この表示になっていたとのこと。

(Thanks Mr.Clement, I salute you for your great work.
オフライン環境でDockerイメージを展開(RENAT)

インターネットから切り離された環境へDockerイメージを転送し起動したときの手順を記載。

### 1. Dockerイメージの保存
インターネットに接続している別の環境で、RENATのDockerイメージをダウンロードし、それをファイルとして保存。

```bash:インターネット接続環境のサーバで実施
docker pull bachng/renat:latest
docker save bachng/renat:latest > renat_latest.tar
```
### 2. Dockerイメージの転送

```bash:インターネット接続環境のサーバで実施
# scp [オプション] [ローカルファイルのパス] [ユーザー名]@[リモートホストのアドレス]:[リモートでのパス]
scp renat_latest.tar user@192.168.1.100:/home/user/
```
### 3. Dockerイメージのロード

```bash:インターネット接続環境できないサーバ側で実施
docker load < renat_latest.tar
```
### 4. Dockerコンテナ(RENATの場合)実行

```bash:インターネット接続環境できないサーバ側で実施
docker run --rm -d --privileged -v /opt/renat:/opt/renat -p 8185:80 -p 10022:22 --name renat bachng/renat:latest
```
Doma2を使ってみる(その１)

# Doma2を使ってみる(その１)

## ライブラリ概要
Doma 2はJava 8+向けのデータベースアクセスフレームワークです。Domaにはさまざまな強みがあります。

## 特徴
- SQLマッパー型
- 2-way SQL
- Kotlinサポート
- コンパイル時にアノテーションプロセッサーを使用して、ソースコードを検証および生成します。
- 型安全なCriteria APIを提供します。
- 他のライブラリに依存しません。


### SQLマッパー型
データベースのテーブルとプログラムのクラスを直接対応付けることができます。  
また、SQLは別途テキストファイルに書くことが多い
#### メリット
- 学習コストが低い
  - SQLを知っていれば利用することができる
#### デメリット
- 誰でも扱える結果、共通化されないことが多い
#### 選定理由
- 開発者を選ばずとりあえず DB アクセスをして動くものを作りたい場合に採用される

### 2-way SQL
SQL単体でも、プログラムからでも実行できる
```sql
select * from t_product where id = /* id */'1'
```
#### メリット
- SQLを直接書くことができるため、SQLのパフォーマンスを最大限に引き出すことが可能です。
- SQLファイルとJavaのコードが一致するため、保守性が高まります。
- SQLの結果をJavaのオブジェクトにマッピングする機能があります

#### デメリット
- SQLを直接書くため、SQLに詳しくないと使いこなすのが難しいかもしれません。
- データベースの種類によっては、SQLの書き方を変える必要があるかもしれません。
- ORMフレームワークと比べると、機能が少ないかもしれません。

### Kotlinサポート
Kotlin1.4.0以降をサポート  
Kotlinを利用した場合のベストプラクティスの書き方がある

### コンパイル時にアノテーションプロセッサーを使用して、ソースコードを検証および生成します。
Doma はコンパイル時に Pluggable Annotation Processing API を使用します。

### 型安全なCriteria APIを提供します。
JPAの機能の一部であるCriteriaAPIを提供している。
Kotlinの場合は、Kotlin固有のCriteriaAPIを利用する。

## まとめ
Doma2は2way sqlがあるおかげで、誰でもDBアクセスが簡単にできる点が評価されているみたい
Doma2から2way sqlだけ切り出して他のORMを利用している人もいるので、2way sqlがあるだけでDoma2を採用するのはよくなさそう。
実際にDoma2を利用してみて良さそうな点を考えたい


## 参考サイト
- https://doma.readthedocs.io/ja/latest/getting-started/
- https://casual-tech-note.hatenablog.com/entry/2019/03/17/212855
- https://www.slideshare.net/masatoshitada7/java-or-jsug
- https://www.tuyano.com/index2?id=5767409591910400
FirstPersonControllerアセットを使用したPlayerの視点を外部から操作すると「視点がガクッとなる」問題の原因

カットシーン等を作っていると、

「カットシーン後にプレイヤーを位置移動(テレポート)＆**視点を任意の方向に指定したい**」
といった場面が出てくると思います。

その際に視点を任意の方向に指定しようと「PlayerCameraRoot」にx座標をセットすると
マウスを操作出来るようになった最初の段階で「ガクッ」としないでしょうか？

```C#:FirstPersonController.cs
private void CameraRotation() 
		{
			// if there is an input
			if (_input.look.sqrMagnitude >= _threshold)
			{
				//Don't multiply mouse input by Time.deltaTime
				float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime;

				_cinemachineTargetPitch += _input.look.y * RotationSpeed * deltaTimeMultiplier;
				_rotationVelocity = _input.look.x * RotationSpeed * deltaTimeMultiplier;

                // clamp our pitch rotation
                _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);

                // Update Cinemachine camera target pitch
                CinemachineCameraTarget.transform.localRotation = Quaternion.Euler(_cinemachineTargetPitch, 0.0f, 0.0f);

                // rotate the player left and right
                transform.Rotate(Vector3.up * _rotationVelocity);
			}
		}
```

結論から申し上げると

**・_cinemachineTargetPitch変数が前の視点情報のままで計算
・CinemachineCameraTarget.transform.localRotationでセット**

となっている為、
カットシーン後等のマウスが効き始めた直後に前の視点情報で計算された値が
localRotationにセットされて「視点がガクッとなる」という問題が発生します。
RakutenAI-7BでのFew-Shot Promptingによる日本語品詞付与

[一昨日の記事](https://qiita.com/KoichiYasuoka/items/c180d901649dbac43532)の続きだが、<a href="https://huggingface.co/Rakuten/RakutenAI-7B">RakutenAI-7B</a>は<a href="https://huggingface.co/tokyotech-llm/Swallow-MS-7b-v0.1">Swallow-MS-7b-v0.1</a>と同様のMistralモデルなのだが、トークナイザの出来がかなり違う。これがどういう問題を引き起こすか、国語研短単位でのUPOS (Universal Part-Of-Speech)品詞付与をFew-Shot Promptingで挑戦してみよう。5つの例文は、[この記事と全く同じもの](https://qiita.com/KoichiYasuoka/items/b604dbe94db2207d9aa1)を選んだ。

```
>>> class TextUPOSList(list):
...   __str__=lambda self:"\n".join("###text:"+"".join(t for t,u in s)+"\n###UPOS:"+"|".join(t+"_"+u for t,u in s) for s in self)+"\n"
...
>>> ex=TextUPOSList()
>>> ex.append([("一","NUM"),("直線","NOUN"),("に","ADP"),("伸びる","VERB"),("電撃","NOUN"),("を","ADP"),("放ち","VERB"),("、","PUNCT"),("電撃","NOUN"),("ダメージ","NOUN"),("を","ADP"),("与える","VERB"),("。","PUNCT")])
>>> ex.append([("色々","ADV"),("と","ADP"),("面白い","ADJ"),("メニュー","NOUN"),("の","ADP"),("ある","VERB"),("店","NOUN"),("。","PUNCT")])
>>> ex.append([("しかも","CCONJ"),("、","PUNCT"),("ここ","PRON"),("は","ADP"),("コース","NOUN"),("が","ADP"),("リーズナブル","ADJ"),("な","AUX"),("の","SCONJ"),("です","AUX"),("。","PUNCT")])
>>> ex.append([("彼","PRON"),("は","ADP"),("コンピュータ","NOUN"),("を","ADP"),("個人","NOUN"),("の","ADP"),("持ち物","NOUN"),("に","ADP"),("し","VERB"),("まし","AUX"),("た","AUX"),("。","PUNCT")])
>>> ex.append([("2007","NUM"),("年","NOUN"),("9","NUM"),("月","NOUN"),("現在","ADV"),("、","PUNCT"),("以下","NOUN"),("の","ADP"),("メーカー","NOUN"),("から","ADP"),("対応","NOUN"),("製品","NOUN"),("が","ADP"),("発売","VERB"),("さ","AUX"),("れ","AUX"),("て","SCONJ"),("いる","VERB"),("。","PUNCT")])
>>> from transformers import pipeline
>>> tgn=pipeline("text-generation","Rakuten/RakutenAI-7B",max_new_tokens=128)
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜け_VERB|ると_ADP|雪国_NOUN|であった_AUX|。_PUNCT
```

『雪国』の冒頭文に品詞付与させてみたところ、RakutenAI-7Bは「`抜ける_VERB|と_ADP|雪国_NOUN|で_AUX|あっ_AUX|た_AUX`」が正しくトークナイズできなかった。この結果「`ると_ADP`」という怪しい単語が現れたり「`であった_AUX`」が1語になってしまったりしている。もう一度やってみよう。

```
>>> print("\n".join(tgn(str(ex)+"###text:国境の長いトンネルを抜けると雪国であった。\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:国境の長いトンネルを抜けると雪国であった。
###UPOS:国境_NOUN|の_ADP|長い_ADJ|トンネル_NOUN|を_ADP|抜け_VERB|ると_ADP|雪国_NOUN|であった_AUX|。_PUNCT
```

どうやら同じ結果だ。ならば「予想に反して品詞付与の精度がイマイチ」という文はどうだろう。

```
>>> print("\n".join(tgn(str(ex)+"###text:予想に反して品詞付与の精度がイマイチ\n###UPOS:")[0]["generated_text"].split("\n")[len(ex)*2:len(ex)*2+2]))
###text:予想に反して品詞付与の精度がイマイチ
###UPOS:予想_NOUN|に反_ADP|して_ADP|品詞_NOUN|付与_VERB|の精度_NOUN|がイマイチ_ADV|。_PUNCT
```

残念ながら「`予想_NOUN`」と「`品詞_NOUN`」以外は全て間違っている。単語の切れ目を完全に無視していて、日本語における言語処理としては話にならない。形態素解析というものを、ちゃんと学ばずにトークナイザを作ってしまったのだろう。残念だ。
Go言語でブロックチェーンのシステムを作成する（その２）

## はじめに
前回は、ブロックチェーンについてまとめましたが、今回から実際にGo言語で実装していきます。

- 前回の記事

https://qiita.com/jun_11/items/a1adf93ba02292321b25

- バージョン
  - Go 1.22.0

## 実装
### イメージ図
下の図のようなイメージで実装していきます。

<img width="300" alt="ブロックチェーン1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676504/00462db0-78fd-a073-690e-cde54bc96776.png">

- prev hash
  - 前のブロックの情報
- timestamp
  - 生成の時間
- nonce
  - nonceの計算結果
- transactions
  - 取引履歴
- Pool
  - 取引情報が入る

上の図から新しいブロックが作られたとき、下の図のようになり、新しいブロックのprev hashには前のブロックの情報が入ります。また、Poolに溜まっていた取引情報が新しいブロックのtransactionsに入り、Poolの中は空になります。

<img width="600" alt="ブロックチェーン2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676504/bb0ad399-3d61-1134-2910-054fc889f08d.png">

### Blockの作成
まずは、Blockの作成をしていきます。

```golang
type Block struct {
	nonce        int
	previousHash [32]byte
	timestamp    int64
	transactions []string
}

func NewBlock(nonce int, previousHash [32]byte) *Block {
	b := new(Block)
	b.timestamp = time.Now().UnixNano()
	b.nonce = nonce
	b.previousHash = previousHash
	return b
}
```

Blockは、nonce、previousHash、timestamp、transactionsでstructを定義します。
NewBlockでは、nonceとpreviousHashを引数にとって、Blockを作成しています。

### Blockchainの作成
次に、Blockchainの作成をしていきます。

```golang
type Blockchain struct {
	transactionPool []string
	chain           []*Block
}

func NewBlockchain() *Blockchain {
    b := &Block{}
	bc := new(Blockchain)
	bc.CreateBlock(0, b.Hash())
	return bc
}

func (bc *Blockchain) CreateBlock(nonce int, previousHash [32]byte) *Block {
	b := NewBlock(nonce, previousHash)
	bc.chain = append(bc.chain, b)
	return b
}
```

Blockchainは、transactionPool、chainでstructを定義します。
NewBlockchainでは、Blockchainを新しく作成し、CreateBlockを呼んで一番最初のBlockを作成して、Blockchainを返しています。CreateBlockを呼ぶときの引数には、前のBlockが存在していないので、とりあえずnonceに0、previousHashには空のBlockを作っておいて、そのBlockのハッシュを入れています。b.Hash()については後で実装します。
CreateBlockでは、Blockを作成した後、そのBlockのポインタをBlockchainのchainに入れています。

### Blockのハッシュを実装
次に、Blockのハッシュを実装していきます。
```golang
func (b *Block) Hash() [32]byte {
	m, _ := json.Marshal(b)
	return sha256.Sum256([]byte(m))
}

func (b *Block) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		Timestamp    int64    `json:"timestamp"`
		Nonce        int      `json:"nonce"`
		PreviousHash [32]byte `json:"previous_hash"`
		Transactions []string `json:"transactions"`
	}{
		Timestamp:    b.timestamp,
		Nonce:        b.nonce,
		PreviousHash: b.previousHash,
		Transactions: b.transactions,
	})
}

func (bc *Blockchain) LastBlock() *Block {
	return bc.chain[len(bc.chain)-1]
}
```
Hashでは、BlockをJSON形式に変換して、それをハッシュの文字列に変換しています。
Blockのstructのフィールド名が小文字から始まっていますが、フィールド名が小文字だとプライベートなフィールドとして認識されてしまい、うまくマッピングできていません。そこでMarshalJSONでは、大文字に変えてjson.Marshalをするようにしています。
LastBlockでは、previousHashに前のBlockのハッシュを入れたいので、どのBlockが最後のBlockかを返しています。

## おわりに
今回は、Block、Blockchainの作成、hashの実装をしていきました。
次回は、transactionsの実装をしていきます。

次の記事

https://qiita.com/jun_11/items/61adfc340792cdb2af08

# 参考

https://www.udemy.com/course/go-blockchain/?couponCode=ACCAGE0923
rviz_satelliteでrviz2にNavSatFixトピックの地図を表示

# はじめに

ROS2 Iron環境でrviz_satelliteのデモを動かしNavSatFixの経度緯度のマップ画像をrviz2に表示させる

https://github.com/nobleo/rviz_satellite

# インストール

```bash
sudo apt install ros-iron-rviz-satellite
```

# demo の実行


```bash
ros2 launch rviz_satellite demo.launch.xml
```

rviz2設定ファイルが読み込まれないので、こちらからrviz2設定ファイルをダウンロードしてきて直接rviz2コマンドで実行

https://github.com/nobleo/rviz_satellite/blob/ros2/demo/demo.rviz

```bash
rviz2 -d demo.rviz
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/b7fe52d6-5563-9f07-eb38-5fe1845a8fde.png)


マップを表示させるサイトを変更する場合　
`AerialMap`の`Object URL`を変更
TomTom, Mapboxはトークンが必要

OpenStreetMap: https://tile.openstreetmap.org/{z}/{x}/{y}.png
TomTom: https://api.tomtom.com/map/1/tile/basic/main/{z}/{x}/{y}.png?tileSize=512&key=[TOKEN]
Mapbox: https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/256/{z}/{x}/{y}?access_token=[TOKEN]

### Google Mapの表示

Object URL "http://mt0.google.com/vt/lyrs=y&hl=en&x={x}&y={y}&z={z}&s=Ga"

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/fc3df923-f493-cf85-35b1-fd40fc1b915b.png)


# 参考

https://medium.com/@hitlx916/visualize-the-gnss-messages-by-rviz-plugin-ros-42a2f0675939

https://gis-dictionary.com/qgisdechiriinchizunadonotilewohyoujisuruhouhou/

https://drawtrail.net/map-tile-summary/
git pullする前にbranchを切った場合の対処法

GitHubを使うにあたって、branchを新しく切る際、初心者であればremote branchの更新を忘れて古いままbranchを切ってしまうことはよくあると思います。
その際に、あれ、このbranchにはこのコードがあるはずなのにない！ってなることがありますよね。自分はよくやっちゃいます笑

そんな時には、以下の手順を踏んでもらえればすぐ更新されると思います。
# 前提条件
今回は以下の条件で話を進めます。
・今回branchを切る元となっているbranch名：develop
・今回切るbranch名：feature/add-sample
・branchを切った後に最新化していない状態なので、今いるbranchはfeature/add-sampleとします。

# 実行手順
1. developブランチに戻ります
    ```
    git checkout(もしくはswitch) develop
    ```
2. branchの状態をremoteのdevelopの最新状態にする
    ```
    git pull
    ```
3. もう一度feature/add-sampleに戻ります
    ```
    git checkout(もしくはswitch) feature/add-sample
    ```
4. developブランチへの更新をfeature/add-sampleに反映させます
    これによって、rebaseしつつ、反映させることができます。
    もし、切ったbranch側で変更が加えられており、差分がdevelopとかぶっている場合は、rebaseを行い、変更履歴を整えましょう
    ```
    git pull --rebase develop
    ```

ちなみに、developの更新をfeature/add-sampleにmergeするやり方ありますが、それでは変更履歴が壊れてしまうため、お勧めしません。
やるなら、rebaseを使いましょう
「AWSってAmazonなんだ～」からはじめた、クラウドプラクティショナー受験

#### AWS Certified Cloud Practitioner（CLF-C02）

AWSをまったく知らなかった私が、
「AWS認定 クラウドプラクティショナー（AWS Certified Cloud Practitioner（CLF-C02）」
を受験するまでに行ったことをこちらにまとめます。

この勉強法によって、ただの資格勉強の知識だけでなく**AWSを利用する上での ”基本”を身に付けることができました。** 
その結果、後の資格（SAA,DBS）にも２週間ほどの勉強で合格！
資格勉強だけでなく今後のAWS知識に繋げていきたい方へ、おすすめの方法です。

<details><summary>「CLF-C02」ってなに？</summary>

「CLF」＝「AWS Certified Cloud Practitioner」（試験名）
「C02」＝「バージョン２」（試験バージョン）
のことです。
試験バージョンは、改定によって変わっていきます。
試験内容が変わりますので、ここの確認は必須です。
</details>

<details><summary>私がクラウドプラクティショナーを受験したきっかけ</summary>

社内の勉強会で「Docker(コンテナ技術)」を学んだとき、初めてECSをはじめとしたAWSサービスに触れました。
このときにAWSって面白いなあと思ったことがきっかけで、いろんなものを構築してみたいと思い、勉強を始めました。

そこではじめの一歩として、クラウドプラクティショナーを受験することにしました。
クラウドプラクティショナーでは、**AWSの基本かつ常に重要とされる知識**が多く出題されます。AWSの知識をつけるはじめの勉強にぴったりです。
</details>

## 勉強したこと
AWSの基本を身に付ける勉強法として行ったことは、以下のとおりです。

1. AWS公式「はじめてのクラウド」を視聴する　＜3時間＞
1. マネジメントコンソールを見る(触る)　＜10分＞
1. AWS公式「模擬試験」を受ける　＜30分＞
1. **AWS公式「Essentials」を受ける**　＜15時間＞☆
1. **各サービスを覚える**　＜3時間＞☆
1. AWS公式「模擬試験」を受ける　＜30分＞

＜＞：所要時間
　☆：個人的おすすめの方法

***

### AWS公式「はじめてのクラウド」を視聴する ＜3時間＞
「構築にクラウドを使うとどんなことが良いのか」について、分かりやすく教えていただける動画が公開されています。
クラウドを使うメリットを大まかに知ることができるので、初めて触る方にとてもおすすめです。

### マネジメントコンソールを見る(触る) ＜10分＞
ちょっとだけ、是非マネジメントコンソール(AWS Manegement Console)を触ってみて欲しいです。
どのようにAWSサービスを使っていくのかをイメージしやすくなります。

### AWS公式「模擬試験」を受ける ＜30分＞
Skillbuilderにて
「AWS Certified Cloud Practitioner Official Practice Question Set (CLF-C02- Japanese)」という模擬試験が公開されています（20問のみ）
本格的な勉強をする前に、どのような問題が出題されるのかを経験しておくことをおすすめします。

### AWS公式「Essentials」を受ける ＜15時間＞☆
Skillbuilderにて
「AWS Cloud Practitioner Essentials (Japanese) (Na) 日本語実写版」
というe-learningが公開されています。（動画版もあります）
クラウドプラクティショナー試験にでてくるサービスについて、細かく解説してくれています。

ここで、**個人的おすすめの方法**があります！

:::note info
AWSサービスのアーキテクチャアイコンも軽く覚えておく
:::

各AWSのサービスには「アーキテクチャアイコン」があります。主に構築のアーキテクチャ図に使われるものです。
このアーキテクチャアイコンはピクトグラムのように、**見た目でどんなサービスなのか分かる**ようになっています。

例えば「Amazon Athena」は、S3内をクエリで探すことができるサービスです。
このAmazon Athenaのアーキテクチャアイコンはこちらです。

　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747814/efb727d6-6fc8-835e-d058-58c6155094e6.png)
　　Amazon Athena

S3を虫眼鏡で見ているようなイラストになっています。

　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3747814/a073e436-c838-f438-0c50-8f49890228c9.png)
　　　　　S3

このように**関係のあるサービス**が描いてあったりするので、
サービス名を聞かれて分からなくなっても、アーキテクチャアイコンを思い出すことで試験の時に答える選択肢を狭めることができました。

マネージドコンソールからサービスを利用する時にも役立ったりします。

### 各サービスを覚える ＜3時間＞☆
こちらも**個人的おすすめの方法**です！

:::note info
試験範囲内のサービスを覚える
:::
Readnessで学んだ以外にも試験範囲となっているサービスがあるかと思います。
そのようなサービスも試験にでる可能性は大いにあります。
試験本番で「初めて見た…」とならないよう、一通り見ておくこと大切です。

試験範囲は、以下に載っています。（CLF-C02）

https://d1.awsstatic.com/ja_JP/training-and-certification/docs-cloud-practitioner/AWS-Certified-Cloud-Practitioner_Exam-Guide.pdf

### AWS公式「模擬試験」を受ける ＜30分＞
一通りの勉強が終わったので、もう一度模擬試験を受けてみましょう！

### その他
模擬試験は解けば解くほど効果が感じられます！
AWS公式の模擬試験が全問正解できた後、他の学習サイトにて模擬試験を受けてみるのもおすすめです。

## まとめ
今後AWSを触っていくうえで必要な基本知識を、クラウドプラクティショナーの受験を通して学んでいきました。
その結果、試験合格はもちろん、AWSサービスを利用していくはじめの一歩としてとても効果を感じられたインプット法でした。

AWSに触れるはじめの目標に、クラウドプラクティショナーの資格取得、いかがでしょうか！