OmniAICreator/Qiita-1.07M huggingface dataset:
AWS認定資格を全冠取得するための費用を計算してみた(2024年9月1日現在)

## はじめに
インフラ業界ではクラウドを利用した業務が昨今当たり前のように存在する今日この頃。
クラウドエンジニアになれば、やはり知識量のTOPを目指したいと目標を持ちますよね！
そこでAWSに特化した、AWS認定資格で全冠を目指した場合に、どのくらいの費用がかかるか気になったので計算してみようと思いました。
現在(2024年9月時点)では、AWS認定資格は全部で12個存在しています。
この12個の認定を全て取得した際の費用を計算してみます。

AWS認定資格の詳細は以下公式URLから御参照ください。
https://aws.amazon.com/jp/certification/


## AWS認定資格全冠で得られるメリット／デメリット
計算する前に、メリット／デメリットについて考えてみたいと思います。
一般的には以下のような事が言えるかと思います。
　＜メリット＞
　・AWS社より「AWS All Certifications Engineers」として表彰※1され
　　「AWS JAPAN APN ブログ」で世界に発表されます。(公式に認定者として認められる。)
　・AWSのテクノロジーを正しく理解し、髙い基礎技術力を持っていることを証明できる。
　・AWSのサービスを全て学んだという高い自己承認が得られる。(自信がつく)
　・AWSのベース知識があるため、実務をスムーズに進められるようになる。

　※1:・表彰されるにはAWS Partner Network (APN) に参加している企業に属している
　　　　必要があります。(https://aws.amazon.com/jp/partners/)
　　　・表彰が毎年必ずあるかどうかは確定していません。毎年、都度のアナウンスで
　　　　開催が確定されます。(2024年の例：https://aws.amazon.com/jp/blogs/psa/2024-japan-aws-all-certifications-engineers-criteria/)
　　　・全冠の対象資格がどれになるかについても、上記発表段階で確定されます。

　＜デメリット＞
　・過度な期待を周りから受け、実務での空回りが発生するかも。
 　　(実務経験の少ない方にありがち)
　・やった感で、燃え尽きる可能性がある。　
　　※上記2つのデメリットは、現場の先輩や上司でフォローはできると考えています。
　・とにかく受験料が掛かる。

## AWS認定資格の種類と受験料(2024年9月現在受験できる物)
以下12種類が現時点で存在しています。これを全て合格できれば全冠となります。
受験料につては、昨今円安の影響もありかなり値上げされ高額になってきています。
また、下記”★”印箇所の認定資格は現在ベータ版で提供されていますので、
本試験となるまでは10,000円で受験できますが、割引バウチャーがベータ試験で利用できるか不明なので、今回の計算では通常価格での計算とします。

**Foundational(初級) 15,000 円**
　AWS Certified Cloud Practitioner
　AWS Certified AI Practitioner ★

**Associate (中級) 20,000 円**
　AWS Certified SysOps Administrator - Associate
　AWS Certified Developer - Associate
　AWS Certified Solutions Architect - Associate
　AWS Certified Data Engineer - Associate 
　AWS Certified Machine Learning Engineer – Associate　★

**Professional (上級) 40,000 円**
　AWS Certified Solutions Architect - Professional
　AWS Certified DevOps Engineer - Professional 

**Specialty (専門) 40,000 円**
　AWS Certified Advanced Networking - Specialty 
　AWS Certified Machine Learning - Specialty 
　AWS Certified Security - Specialty

上記を全て計算すると、
以下のように単純計算で33万円です、が、

Foundational(初級)　　15,000 円　×　2認定 ＝30,000円
Associate (中級)　　　20,000 円　×　5認定 ＝100,000円
Professional (上級)　　40,000 円　×　2認定 ＝80,000円
Specialty (専門)　　　40,000 円　×　3認定 ＝120,000円
－－－－－－－－－－－－－－－－－－－－－－－－－－－－
　　　　　　　　　　　　　　　　　　総額　330,000円


しかしながらAWS認定資格は、試験に合格すると、どの認定資格でも利用できる受験料
半額バウチャーが貰えます。
初回をFoundationalから順番に受験していくと以下のようになります。
（下記の例は全てストレート合格前提ですので、途中で不合格をたたき出してしまうと、
一旦半額バウチャーが無くなるので、次の受験料は1回全額出費となります。）

Foundational(初級)　15,000 円　×　1認定 ＝15,000円　※1つ目は普通に通常料金を払い受験
Foundational(初級)　7,500 円　×　1認定 ＝7,500円　※前の合格時の半額バウチャー利用
Associate (中級)　　10,000 円　×　5認定 ＝50,000円　※前の合格時の半額バウチャー利用
Professional (上級)　20,000 円　×　2認定 ＝40,000円　※前の合格時の半額バウチャー利用
Specialty (専門)　　20,000 円　×　3認定 ＝60,000円　※前の合格時の半額バウチャー利用
－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
　　　　　　　　　　　　　　　　　総額　172,500円

## まとめ
結果、2024年の現在は全冠取得すると、**総額172,500円**必要とわかりました。
会社によっては、受験費用の補助が出る会社さんもあると思いますが、
本当に自腹で支払いをされている方は、合格時の半額バウチャーがあったとしても
結構な高額となりますので、計画的に受験を進めていく必要があります。

ただ、昨今AWSを利用した業務は沢山存在していると思いますので、多少の出費が
あったとしても、メリットは大きいと個人的には考えます。
もしも、ハードルがあるとしたら、全冠取得のための勉強時間の確保とモチベーション維持をどのように保っていくかという問題の方が、かなりハードルが高いと推測します。
勉強の仕方等についてはQiitaにも沢山投稿があるので、是非確認していただければと思います。
PosrgresでのUUID,RLSの設定+外部キー設定

## UUIDの設定
UUIDは、一意の識別子を生成するために広く使用されます。特に、複数のシステム間でデータを同期したり、複数のテーブル間で一意性を保つために有効です。PostgreSQLでは、UUIDをサポートしており、テーブルの主キーや他のカラムに使用することができます。






![napkin-selection (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690843/685df009-cb5d-213a-d10f-a90a447074ab.png)


1. UUIDの設定
UUIDデータ型を使用するためには、PostgreSQLのuuid-ossp拡張機能を有効にする必要があります。

```sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
```
これで、uuid_generate_v4()関数を使用して、UUIDを生成することができるようになります。


2. テーブルでUUIDを使用
例えば、先ほどの商品テーブルでUUIDを主キーとして使用する場合、以下のように設定します。

```sql
CREATE TABLE 商品 (
    商品ID UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    商品名 VARCHAR(255) NOT NULL,
    数量 INTEGER NOT NULL CHECK (数量 >= 0),
    所有者 TEXT,
    カテゴリ VARCHAR(255)
);
```
ここで、商品IDはUUID型であり、デフォルトでuuid_generate_v4()関数を使って自動的に生成されます。

## RLS（Row Level Security）の設定
RLSを使用すると、特定のユーザーがアクセスできる行を制限することができます。これにより、データベース全体に対するアクセス制御を細かく管理することが可能になります。

1. RLSを有効にする
まず、RLSを有効にするテーブルを指定します。ここでは、商品テーブルに対してRLSを有効にします。

```sql
ALTER TABLE 商品 ENABLE ROW LEVEL SECURITY;
```
2. ポリシーの作成
次に、特定のユーザーがどの行にアクセスできるかを定義するポリシーを作成します。例えば、ユーザーが自身が所有する商品のみを閲覧できるようにするには、以下のように設定します。

```sql
CREATE POLICY 商品閲覧ポリシー ON 商品
    FOR SELECT
    USING (所有者 = current_user);
```
このポリシーでは、所有者が現在のデータベースユーザーと一致する行のみが選択（SELECT）できるように制限しています。



## 外部キー設定
1. ユーザー認証 テーブルの作成
まず、ユーザーのログイン情報を保存するためのユーザー認証テーブルを作成します。このテーブルには、ユーザー名(ユーザー名)とパスワード(パスワード)を保存します。

```sql
CREATE TABLE ユーザー認証 (
    ID SERIAL PRIMARY KEY,
    ユーザー名 VARCHAR(255) UNIQUE NOT NULL,
    パスワード VARCHAR(255) NOT NULL
);
```
2. 商品 テーブルの作成
次に、Todoリストの各項目を保存する商品テーブルを作成します。ここでは、所有者カラムを追加し、このカラムをユーザー認証テーブルのユーザー名カラムと連携させます。

```sql
CREATE TABLE 商品 (
    商品名 VARCHAR(255) NOT NULL,
    数量 INTEGER NOT NULL CHECK (数量 >= 0),
    所有者 TEXT,
    ID UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    カテゴリ VARCHAR(255)
);
```
3. テーブルの連携 (FOREIGN KEY 制約の設定)
商品テーブルの所有者カラムをユーザー認証テーブルのユーザー名カラムに連携させるため、FOREIGN KEY制約を設定します。

```sql
ALTER TABLE 商品
ADD CONSTRAINT fk_所有者
FOREIGN KEY (所有者) REFERENCES ユーザー認証(ユーザー名);
```
4. データの挿入と動作確認
次に、各テーブルにデータを挿入し、設定した外部キー制約が正しく機能するか確認します。

4.1 正常なデータの挿入
まず、ユーザー認証テーブルにユーザー情報を挿入します。

```sql
INSERT INTO ユーザー認証 (ユーザー名, パスワード) VALUES
('佐藤', 'secure_password_hash_for_sato'),
('田中', 'secure_password_hash_for_tanaka');
```
次に、商品テーブルに関連するデータを挿入します。

```sql
INSERT INTO 商品 (商品名, 数量, 所有者, ID, カテゴリ) 
VALUES ('サンプル商品', 10, '佐藤', gen_random_uuid(), '家電');
```
wingetでアプリケーションインストール時に0x8a15000fエラーが発生しアプリケーションのインストールができない

# 概要
本記事では下記のスクリーンショットのようにwingetでアプリケーションインストール時に 0x8a15000f エラーが発生しアプリケーションのインストールができない場合の対処について説明をいたします。

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/90b6d200-6cf8-e034-1580-ad84d1d05d18.png)


# 対処手順
本事象はwingetのバージョンが古い場合に発生します。
下記いずれかの手順にてwingetのバージョンアップを行うことで事象への対処が可能です。

## バージョンアップ方法その１（推奨）
下記リンクを開き、Microsoft ストア経由でインストールを行います。

 [アプリ インストーラー - Microsoft Apps](https://apps.microsoft.com/detail/9nblggh4nns1?rtc=1&hl=ja-jp&gl=JP)

※ ストアアプリで検索してもヒットしないようです。

## バージョンアップ方法その２
ポリシーで制限されているなどの理由でストアアプリが利用できない場合は、github よりパッケージを入手しアップデートを行います。

下記 Microsoft 社員による blogの[Microsoft.DesktopAppInstaller のパッケージがない場合]が参考になるかと思います。

 [winget を用いた Microsoft Store アプリのオフライン ダウンロードについて (正式版が公開となりました) | Microsoft Japan Windows Technology Support Blog](https://jpwinsup.github.io/blog/2024/06/10/UserInterfaceAndApps/winget-store-download/#)

ただしダウンロードする際には blog 内のリンクからではなく下記より最新のバージョン（Latest）のパッケージ(Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle)をダウロードするようにしてください。

 [Releases · microsoft/winget-cli · GitHub](https://github.com/microsoft/winget-cli/releases)

 ![スクリーンショット 2024-09-01 194053.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1833876/16952f42-be7e-d7c9-b4fe-d25185cbe87f.png)


## バージョンの確認方法

下記にてwingetのバージョンの確認が可能です。

```

winget -v

```
# 有効でなかった対処策

下記のソースのリセット並びにソースの更新では改善がしませんでした。

```
winget source reset --force
winget source update
```
# Azure CLI インストール時に本事象が発生した場合

スクリーンショットを見ていただくとわかると思うのですが、本事象はAzure CLI を winget にてインストールしようとした際に確認された事象です。

Azure CLI のインストールでは winget のアップデートをしたのみでは、[アーカイブを展開しています]の表示のまましばらくまたされインストールは完了するものの、実際に使用すると
pythonのdllが不足しているとのエラーが使用できませんでした。

2024年9月2日時点ではインストール時バージョン 2.61.0 以下のものでないとインストールができない模様です。
もし Azure CLI のインストール時に本事象が発生した場合には下記のようにバージョンを指定してインストールを行ってみてください。

バージョン 2.61.0 を指定した場合

```
winget install -e --id Microsoft.AzureCLI -v 2.61.0
```
devise_token_authを用いたユーザー登録・ログインの実装

開発時にハマった際、参考にさせていただいた記事をまとめました。


## 意図せずomniathへリダイレクトする減少について解決につながった記事。

https://qiita.com/HeppokoNeet/items/bb70fce97d47b9f09a5a

## redirect_urlが指定したページにリダイレクトしない現象の解決に役立った記事

https://footlog-blog.net/posts/20220103-the-event-of-no-redirection-by-resetting-the-password-of-devise_token_auth/

## railsの機能でリダイレクト弾かれた際に参考にした記事

https://qiita.com/kuma_0319/items/ed65fe44238c3e40f774

## メール認証機能
confirmed_atがレスポンスに入ってないのでuserモデルから追加するように設定。
ログイン時にconfirmed_atの有無をチェック。有る場合のみlocalstrageにトークン等を保存してログイン状態を保持できるようにした。

https://zenn.dev/shogo_matsumoto/articles/c6485b39c5f621
EZ-USB FX2の開発

EZ-USB FX2は2003年くらいに発売されてメーカーの開発環境のコンパイラーはKeilのものでした。

フリーのSDCCでも開発する人がでてきて、当初はgcc2でしたが、3,4と移り変わってきました。

現在のplatformioのSDCCはgcc4です。

それぞれ微妙に仕様が違いビルドが通らないものがたくさんあります。

現在gcc4のSDCCで開発するのであれば、以下のレポジトリをベースにするのがよさそうです

https://github.com/djmuhlestein/fx2lib

このレポジトリはgmakeでのビルドになります。

SDCCはビルドされたバイナリを提供しているのでそれを使うか、platformioでインストールされたtoolchainにパスを通して使うのがいいです。

Cypressはinfineonに買収されて、SDKがぐでぐでになっていました。
aws-sdk CostExplorerのgetCostAndUsage関数のパラメーターについてのメモ

## 概要

aws-sdkのCostExplorerのgetCostAndUsage関数のパラメーターについてのメモを記載する。

### Granularity

このキーはコスト算出粒度を指定する。
下記のように指定できる。

| 指定値 | 粒度 |
| --- | --- |
| DAILY | 指定期間内のコストを日毎に算出 |
| MONTHLY | 指定期間内のコストを月ごとに算出 |
| HOURLY | 指定期間内のコストを1時間ごとに算出 |

例えば2024-01-01〜2024-01-31の期間を指定した場合下記の様になる。

- DAILY：2024-01-01のコスト、2024-01-02のコスト・・・のように31日分の情報が個々に配列に入って返却
- MONTHLY：2024-01-01〜2024-01-31は2024年1月の一ヶ月以内のコストなので当該期間内のコストの合計が一つ返却
- HOURLY：2024-01-01 00:00:00〜01:00:00のコスト、2024-01-01 10:00:00〜02:00:00のコスト・・・のようにコストが1時間ごとに分割され配列に入り返却

### Metrics

このキーは返す情報の内容を指定している。
下記に一部を記載する。

| 指定値 | 内容 |
| --- | --- |
| UnblendedCost | 割引やプロモーションが適用される前のコスト<br>実際に請求される料金 |
| BlendedCost | 複数のアカウントやリージョンにまたがるコストの平均 |
| UsageQuantity | 使用量の合計値で例えば、EC2インスタンスの使用時間やS3のストレージ使用量など |

## 参考文献

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CostExplorer.html#getCostAndUsage-property
初学者のためのJavaの学習方法/内容に関して

# Qiitaに書く内容を尽きたところで
隔週更新していくとなると、ネタも尽きてくる。そのため、少人数ではあるものの、議論する機会があったので、今一度Javaを学ぶにあたってどんな感じで学んでいけばいいのかを考えてみた。

# 学ぶ内容
最初、自分が発表するにあたり、以下の項目に関して紹介すれば、初心者（初学者）がJavaをわかるようになるのではないかと思っていた。
1. 変数/class/intefrface
1. 配列/List/Map
1. for文/拡張for文
1. if文

これに加えて、enumやstream、三項演算子を加えておいた。ただし、番号が附番していない項目に関しては補助的な項目として必須の学習項目から外した。

# 実際に議論してわかったこと

実際に話してみて、足りないといわれた項目は以下。

1. getter/setter
1. アノテーション

上記の２つに関しては追加しておいたほうがよいのではないかと言われた。確かにわかっておいたほうがいいかもなって思う項目ではあるが。

# 今週から書く記事として

以下の項目に関して記載をしていこうと思う。

1. 変数/class/intefrface
1. 配列/List/Map
1. for文/拡張for文
1. if文
1. getter/setter
1. アノテーション

以上
【Next.js + Typescript】ブログサイトを個人開発

# はじめに
今回はじめてNext.jsを使用したアプリの開発をしました。
今まではReactとViteという組み合わせで作成することが多かったので、Next.jsに慣れておらず、苦戦しながらもなんとか作成をすることができました。
開発したアプリの詳細とNext.jsを使ってみた所感を共有したいと思います。

# アプリのご紹介
### 概要
Qiita と MicroCMS の API を利用してブログや記事を掲載するサイトです。

### 使用している技術スタック
```
- 環境
Next.js: v14.2.6
firebase: 10.13.0

- 言語
typescript: 5.3.3

- ライブラリ
react: 18.2.0
react-hook-form: 7.52.2
react-markdown: 9.0.1
react-dom: 18.2.0

- CSS
tailwindcss: 3.4.10
daisyui: 4.12.10

- Test
testing-library/jest-dom: 6.1.5
testing-library/react: 14.1.2
types/jest: 29.5.11

```

# 実装機能

### トップ画面
Qiitaに 掲載中の記事とmicroCMSで作成したブログ記事をAPIで取得してきて抽出してきた中から4記事を表示させています。
<img width="5000" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/d576356c-c1a7-1d53-975d-b8e9fc351992.png">

### Qiita記事
各記事に配置している「詳細を見る」ボタンを押すと、Qiitaに掲載中の記事へ直接遷移します。

<img width="5000" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/9324bb7c-37bf-b428-aa70-8dac7a5f661f.gif">
<br>

### ブログ記事
各記事に配置している「詳細を見る」ボタンを押すと、microCMS上で投稿したブログ記事をAPIで取得して画面へ表示します。


<img width="5000" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/dd4238f9-42b3-0fba-399c-1f42db96fd2d.gif">



# 反省点
Next.js14を使用してアプリを作成してみましたが、appルーターでのディレクトリ構成を考えるのが少し難しく感じました。
appルーター配下にフォルダを作成し、そこにpage.tsxを作成することでルーティング設定ができるのですが、ページが増えてきたり同じようなページがある場合はどうすればベストな構成にできるのかがわかっておらずappの中のディレクトリを無駄に作成してしまった感じです。
その部分を次のアプリ作成までに整理して、学んだことを活かしていきたいと思います。

# さいごに
Next.jsを使用できることでReactを使ってクライアントサイド中心のアプリを作成している以上に作れるアプリの幅が増えると思っています。
実際に大規模で複雑なアプリにも使用されることがあるようなので、次はNext.jsのいいところをもっと活かせるようなアプリを作成してみたいと思います。


# JISOUのメンバー募集中！

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

https://projisou.jp/
Error: Cannot deploy a web framework の解決法


# はじめに

Next.jsのアプリをfirebaseでデプロイする際に下記のエラーが出ました。

```
Error: Cannot deploy a web framework from source 
because the experiment webframeworks is not enabled. 
```
訳：webframeworksが有効化されていないからソースからwebframeworkをデプロイできません。


# 事象の経緯
Next.jsのアプリをfirebaseでデプロイする際にこちらの記事を参考にしました。

https://qiita.com/Sicut_study/items/1eab452008c5d1d1ca56


この記事にあるように`firebase init` をすると以下の質問が出てくるはずなのですが、今は仕様が変わったのか質問が出てきませんでした。
```
=== Hosting Setup
? Do you want to use a web framework? (experimental) (y/N) 
```

そしてfirebase.jsonのsourceに"."を設定したのですが、認識されず今回のエラーが出てしまいました。

エラー内容を見ていると原因としては web frameworksが有効化になっていないことなので、有効にすることでエラーを解消します。


# 解決方法
`firebase init`でセッティングが終わった後に、以下のコマンドを実行します。

```
firebase experiments:enable webframeworks
```

こうすることでwebframeworksを有効化することができ、firebaseデプロイ時に必要はfirebase-toolsを使用することもできるようになります。

確認してみると、以下のようにfirebase-framework-toolsのReadMeにもwebframeworkが認識されるのを有効化するためにこのコマンドが記載されていました。
![スクリーンショット 2024-09-01 14.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825671/7c5fa8ab-9aa6-fc69-6b64-32f29b2633d0.png)

# おまけ
ちなみに私は混乱してしまったのですが、firebase-tools とfirebase-framework-toolsは別のものを指します。
通常であればfirebaseデプロイのステップで以下のコマンドを実行し、firebase-toolsをインストールし有効化することでfirebaseのサービスが利用可能になります。
```
npm install -g firebase-tools
```

ただし、Next.jsではこのインストールだけではfirebase-toolsが使えずデプロイに問題が出てきます。
その時にfirebase-framework-toolsというweb frameworksを有効化することでNext.jsでもFirebaseのサービスや機能を使用することが可能になります。
firebase-framework-toolsは特定のフレームワークサポートのための拡張機能的なもののようです。


# おわりに
Next.jsアプリをfirebase利用してデプロイする手順はいくつか紹介されているのですが、
こういうエラーが出た時の対処情報が上記の記事以外に見つけることができなかったため共有させていただきます！参考になれば幸いです。
Slackのデフォルトのフォントが変わってしまったのでSlackのフォントを元に戻したい！

最近、Slackのフォントが変わりましたね。自分は前のフォントの方が良かったので元に戻す方法を残しておきます。

# 結論
Slackの適当なチャンネルに `/slackfont Lato` と打ち込み送信する。

```test:メッセージで送信するコマンド(コピペ用)
/slackfont Lato
```

デフォルトに戻すときは `/slackfont`と送信する。

※ 変わらない場合は、フォントをインストールしてください。

# 解説

Slackのデスクトップクライアントでは、 `/slackfont <font name>` でフォントを `<font name>` に変えることができます。

フォントはシステムにインストールされてると安心なので、元々のフォントを探してきてインストールします。

Slackの元々のフォントは [Lato](https://fonts.google.com/specimen/Lato) っぽいので、Google Fontから落としてきてインストールしましょう。

フォントをインストールしたら、Slackを再起動し、上記のコマンドを入力することで、おなじみの見た目が戻ってきます。

> https://fonts.google.com/specimen/Lato
> Slackでお馴染みのフォントです。角に若干の丸みがあるのが特徴で、太字にして見出しやクリエイティブに使っても味わいがあるし、小さいサイズでも見やすいのでUIにも使いやすいと思います。RegularとBoldの中間がないのが唯一の欠点...。
>
> [_おすすめのGoogleフォントをまとめる会 | Zenn_](https://zenn.dev/catnose99/scraps/3c38a6fec1bff583c18c) より

# 参考
https://zenn.dev/catnose99/scraps/3c38a6fec1bff583c18c

https://ascii.jp/elem/000/004/125/4125801/
Android Studioで便利なショートカット

# はじめに
今回はAndroidStudioで開発している中で効率的に作業を進めるためにショートカットについて、よく使っているものや使いたいと思っているけど忘れてしまっているもの、それを調べた際に使えそうだと思った他のショートカットなどを一覧にしてあとで見返せるように自分用のショートカット一覧作成しようと思います。

# ショートカット一覧

|ショートカット|説明|
|:---|:---|
|shift２回押し|全体検索|
|command + shift + F|フォルダーを指定して検索|
|command + z|ひとつ前に戻す|
|command + shift + Z|ひとつ後に戻す|
|command + shift + backspace|最後に編集した所に移動|
|command + option + L|指定した範囲のコードをフォーマット|
|command + D|カーソルがある行をすぐ下に複製|
|option + command + [|コードブロックの始まりに移動|
|option + command + ]|コードブロックの終わりに移動|
|shift + fn + F6|カーソルのある変数などをリネーム|
|control + option + O|不要なインポートの削除|
Voltaを使ってNode.jsやnpmのバージョンをpackage.jsonに記載する方法

## 概要

Node.jsのバージョン管理ツールであるVoltaを使ってNode.jsやnpmのバージョンをpackage.jsonに記載する方法を簡単にまとめる。

## 方法

### Node.jsのバージョンを記載

下記コマンドを実行

```terminal
volta pin node
```

### npmのバージョンを記載

下記コマンドを実行

```terminal
volta pin npm
```

## メモ

ちなみに、Voltaが入っており、package.jsonにNode.jsやnpmのバージョン情報が記載されていた場合、そのディレクトリに移動したときにVoltaがよしなにバージョンを変更してくれるらしい。
AWS CDKでの TypeError: type of argument sources must be a sequence エラーの解決方法

## はじめに

AWS CDKを使用していると、次のようなエラーに遭遇することがあります：

```
TypeError: type of argument sources must be a sequence; got jsii._reference_map.InterfaceDynamicProxy instead
```

エラーの原因と解決策について詳しく説明します。

## エラーの原因

このエラーは主に、CDKコンストラクトに渡すパラメータの型が正しくない場合に発生します。具体的には、`sources`引数に期待される型（シーケンス型、例えばリストや配列）ではなく、単一のオブジェクトが渡されている場合に起こります。

## 解決策

### 1. パラメータをリストで囲む

最も一般的な解決策は、`sources`パラメータを角括弧`[]`で囲み、リストにすることです。

**修正前：**

```python
my_construct = SomeConstruct(self, "MyConstruct",
    sources=s3.Bucket(self, "MyBucket")
)
```

**修正後：**

```python
my_construct = SomeConstruct(self, "MyConstruct",
    sources=[s3.Bucket(self, "MyBucket")]
)
```

### 2. CDKのバージョンを確認

使用しているCDKのバージョンが最新であることを確認してください。古いバージョンを使用している場合、型の不一致が発生する可能性があります。

```bash
npm list -g aws-cdk
```

必要に応じて、最新版にアップデートしてください：

```bash
npm update -g aws-cdk
```

### 3. ドキュメントの確認

該当するCDKコンストラクトのドキュメントを確認し、`sources`パラメータの正しい使用方法を確認することも重要です。AWS CDKの公式ドキュメントや、使用しているコンストラクトの具体的なAPIリファレンスを参照してください。

## まとめ

AWS CDKでの `TypeError: type of argument sources must be a sequence` エラーは、主にパラメータの渡し方の問題です。多くの場合、単一のオブジェクトをリストで囲むことで解決できます。また、CDKのバージョンが最新であることを確認し、必要に応じてドキュメントを参照することで、このような問題を回避できます。

エラーメッセージが難解に見えても、落ち着いて原因を分析し、適切な対処を行うことで、スムーズにAWS CDKの開発を進めることができます。

## 参考リンク

- [AWS CDK 公式ドキュメント](https://docs.aws.amazon.com/cdk/latest/guide/home.html)
- [AWS CDK API リファレンス](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html)
serverless framework ローカル開発環境だけでテストする（モック使用）

## 概要

serverless frameworkにてローカル開発環境に閉じてテストが行えるようにするまでの方法をまとめる。
下記で紹介したローカル開発環境でのテスト方法は手軽だが、モックを使っていないのでテストだとしてもaws-sdkを使って実際にリクエストが飛んでしまっている。
今回はデプロイ内容的に実際にリクエストが飛んでも問題は無いがモックを使ったものも学んでおきたいのでその方法を記載する。

## 前提

下記の内容が完了していること

https://qiita.com/miriwo/items/bf274fa6af25a396f05d

また、下記のモックを使わないテストも実施していることが望ましい

https://qiita.com/miriwo/items/d4aee0c6dc020e134145

## 方法

- aws-cost-notifyディレクトリで下記を実行して必要なパッケージをローカル開発環境向けにインストール

    ```terminal
    npm install --save-dev jest aws-sdk-mock
    ```

- aws-cost-notifyディレクトリ直下にhandler.test.jsというファイルを作成し、下記のように記載

    ```aws-cost-notify/handler.test.js
    const AWSMock = require('aws-sdk-mock');
    const { notify } = require('./handler');
    
    
    AWSMock.mock('CostExplorer', 'getCostAndUsage', (params, callback) => {
      callback(null, { ResultsByTime: [] });
    });
    
    test('notify function', async () => {
      const event = { source: 'aws.cost', 'detail-type': 'AWS Cost and Usage Report', detail: { key1: 'value1' } }; // lambdaトリガー時のイベントを指定
      const result = await notify(event); // 関数の実行
      // 結果の評価
      expect(result.statusCode).toBe(200);
      expect(JSON.parse(result.body)).toEqual({ "message": "コスト通知が正常に処理されました" });
    });
    
    AWSMock.restore('CostExplorer'); // モックの解除
    ```

- package.jsonを開きscriptsのtestを下記のように書き換え

    ```aws-cost-notify/package.json
    "scripts": {
      "test": "jest"
    },
    ```

- 下記を実行して上記で定義したテストを実行

    ```terminal
    npm test
    ```

- 下記のようにPASSと出たら完了

    ```terminal
     PASS  ./handler.test.js
      ✓ notify function (937 ms)
    
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        2.297 s, estimated 3 s
    ```
ステップbyステップでローカルLLMを構築する(Ollama + Elyza-7B)

# サマリー

- ローカルLLMをMac mini M1で試しました。
- Ollama使うと爆速で構築できますね。（時間はほぼ、モデルのダウンロード時間くらい 30分程度？）
- Ollamaの公式のインストール手順では、llama3が使える手順が示されます。llama3.1で日本語も問題なくいけますが、流石にElyzaのほうが賢い回答がきます。

# はじめに

- どれくらい簡単にローカルLLMを構築できるのか？知りたいと思ってやってみました。

# 実行結果

1. [Ollamaのサイト](https://ollama.ai/)(公式)からMac用をダウロード(zip)し、解凍してできる.appをappフォルダに放りむ。
2. Macのアプリケーションフォルダから、Ollama.appを実行
3. ターミナルで、以下実行
    ```bash
    % ollama run llama3.1
    (中略)
    writing manifest 
    success 
    >>>
    ```
4. “>>>”にプロンプトを入力(llama3.1実行結果）
    ```bash
    >>> だれがまどまぎで一番かわいいですか？
    答えは難しいです。各キャラクターの人気は違います。人によって好みが異なるようです。
    
    >>> 主観的でいいので教えてください。
    それは私的事前設定ではありません。ただ、一般的に人気の高い「まどかちゃん」と「しずくちゃん」の2人が挙げられます。
    
    * 「まどかちゃん」は、可愛らしい容姿とキャラクターの純粋さで心をつかんでいます。彼女の笑顔がかわいくて、人気が高いようです。
    * 「しずくちゃん」は、大きな胸元やおどけたキャラクターによって男性向けのコミックを思わせることもありますが、可愛らしくてかわいいと
    も言われます。
    
    しかし、「まどかちゃん」と「しずくちゃん」の人気は、ある程度主観的です。人それぞれの好みや印象が違う可能性があるので、個人によって
    異なります。
    
    ```    
5. モデルファイルをダウンロード
    Hugging Face から、「Llama-3-ELYZA-JP-8B-q4_k_m.gguf」をダウンロードしてカレントフォルダに格納　https://huggingface.co/elyza/Llama-3-ELYZA-JP-8B-GGUF/tree/main

6. Modefile作成
    「Modelfile」という名前のファイルをカレントフォルダに作成    
    ```yaml
    FROM ./Llama-3-ELYZA-JP-8B-q4_k_m.gguf
    TEMPLATE """{{ if .System }}
system

    
    {{ .System }}
{{ end }}{{ if .Prompt }}
user

    
    {{ .Prompt }}
{{ end }}
assistant

    
    {{ .Response }}
"""
    PARAMETER stop "
"
    PARAMETER stop "
"
    PARAMETER stop "
"
    PARAMETER stop "<|reserved_special_token"
    ```
    

7. Ollamaモデルの作成

    ```bash
    % ollama create elyza:jp8b -f Modelfile
    ```
1. モデルの実行   
    ```bash
    ollama run elyza:jp8b
    
    ```
2. 実行結果(elza)
    ```bash
    >>> だれがまどまぎで一番かわいいですか？
    ... 
    マギレコのマドマギキャラについては、好みや印象は人それぞれなので、誰が一番かわいいかは主観的な意見です。
    
    >>> 主観的でいいので教えてください。
    マドマギキャラと言えば、個性溢れる女の子たちがたくさんいますが、私のAIとしての感覚では、百千鳥の「エミリア」さんが一番かわいいです
    。
    
    可愛さ満点で、表情も仕草も全てがたまらない、非の打ち所がありません。
    
    ```
    

# 終わりに

- 24/9/1の時点では、Ollama公式に沿ってインストールしただけで、llama3使えた。
- llma3でも日本語もいけるが、elzaのほうが答えは洗練されている。

# 参考

https://qiita.com/s3kzk/items/3cebb8d306fb46cabe9f?utm_source=Qiita+ニュース&utm_campaign=79f624725c-Qiita_newsletter_625_07_03_2024&utm_medium=email&utm_term=0_e44feaa081-79f624725c-35082673

https://note.com/npaka/n/ndadbae6c6be5

https://ollama.com/download
FFmpeg で keyframe でカットする方法

- 対象のストリームの `codec` を `copy` に設定
- `-ss` を入力オプション (`-i` の前) として使用
- `-ss` に設定する時刻を
  キーフレームと同じ (か、次の frame までの間の) timestamp に設定
- `-to` に設定する時刻を `keyframe` と同じ timestamp に設定 (後述)

## 公式ドキュメント `-ss <位置>` の説明

[ffmpeg Documentation]

### 要約

- キーフレームを重要視する場合は、入力オプション (`-i` の前) として使用
- `seek point` と `position` との間のセグメントの扱いについてはこちらのまとめを参照:
  - [FFmpeg でカット編集する際、カット位置のズレまたは再エンコードどちらかが必ず発生 #ffmpeg - Qiita]
- 出力オプションとして `-ss` を設定すると再エンコードされます

### 原文の和訳

> 入力オプション (`-i` の前) として使用すると、この入力ファイル内で `position` を検索します。
> ほとんどの形式では正確に seek することができないため、
> ffmpeg は `position`の前に最も近い `seek point` まで seek することに注意してください。
> トランスコーディングと -accurate_seek が有効になっている場合 (デフォルト)、
> `seek point` と `position` の間のこの余分なセグメントは decode されて破棄されます。
> stream の `copy` を実行する場合、
> または `-noaccurate_seek` が使用される場合、
> stream は保持されます。
> 
> 出力オプション (出力 URL の前) として使用すると、
> decode しますが、timestamp がその `position` に達するまで入力を破棄します。
> `position` は `time duration` の形式でなければなりません。
> [ffmpeg-utils(1) マニュアルの (ffmpeg-utils) `time duration` セクション] を参照してください。

## FFmpeg wiki の説明

[Seeking – FFmpeg]

### 出力オプションとして `-ss` を設定すると再エンコードされます

> Here, the input is decoded(and discarded) until it reaches the position indicated by `-ss`.


### 入力と出力両方に `-ss` を設定する意味なし

動作はするが用途不明

> Semantically valid, but mostly useless.

## `-to` に設定する時刻を `keyframe` と同じ timestamp に設定する方法

説明が長くなるので概要のみ記載、1度に行うには何らかのプログラムによる自動化が必要

1. まず FFmpeg でカット対象動画ファイルの PTS time を 0 から振り直し
   (PTS time が 0 から始まっていない場合があるため)
1. FFprobe で `keyframe` の PTS time 一覧を取得
1. 一覧の中からカットしたい位置の `keyframe` の PTS time を選択して `-to` に設定

[ffmpeg Documentation]: https://www.ffmpeg.org/ffmpeg-all.html
[FFmpeg でカット編集する際、カット位置のズレまたは再エンコードどちらかが必ず発生 #ffmpeg - Qiita]: https://qiita.com/road-master/items/eef4d1396d00f01fcd0d
[ffmpeg-utils(1) マニュアルの (ffmpeg-utils) `time duration` セクション]: https://www.ffmpeg.org/ffmpeg-utils.html#time-duration-syntax
[Seeking – FFmpeg]: https://trac.ffmpeg.org/wiki/Seeking
AndroidStudioのUIをマテリアルデザインベースのUIへ変更する方法

# はじめに
Androidエンジニアにはより親和性の高いマテリアルデザインですが、AndroidStudioにもマテリアルデザインを適用できることはご存知でしょうか？
実はプラグインを使用することでAndroidStudioのUI自体をマテリアルデザインベースへ変更することが可能です。
今回はこの便利なプラグインに関してご紹介したいと思います。

# Material Theme UIの導入
導入方法は簡単で、`Settings > plugins` より`Material Theme UI`と検索し、インストールするだけで使用できるようになります。

![スクリーンショット 2024-09-01 17.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/1dc9bbd3-6ffd-6c90-8136-dbe52e42eeba.png)

同じようなのたくさんありますが、一番上のものをインストールしてもらえれば問題ないです。

インストールし、IDEを再度立ち上げるとプラグインが適用されている状態です。
プラグインの導入が完了するとSettingsにMaterial Theme UIという設定項目が追加されます。

![スクリーンショット 2024-09-01 17.19.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/4942820d-01ca-e06c-d6a8-d49f83dd69dc.png)

ここから適用するMaterial Themeに関して細かく設定が可能です。

![スクリーンショット 2024-09-01 17.23.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/e1072035-5ca9-6f2d-9fac-49ccd4262c45.png)

上記項目の通り各種UIの設定やアクセントカラーなど細かく調整ができますが、もしそこまでこだわりがないという方には、ThemeSelectorよりベースにするThemeを選択してもらうだけでいい感じに設定が可能です。

上記Themeを選択して適用するだけでもだいぶ見やすくなりますので、是非一度試していただいてご自身のこだわりが詰まったIDEに調整してもらえればと思います。

# さいごに
もう9月ですね、今月乗り切れば落ち着くので気合い入れていきます💪
Git｜作業ブランチ名を常にターミナルへ表示したい（Mac）

# はじめに

エンジニアのみなさま、日々の学習本当にお疲れ様です！
また本記事まで足を運んでいただき本当に感謝です。
約2分程度で読めるので最後まで読んでもらえると幸いです。

=======================================================

開発中に作業ブランチを確認するとき、毎回『git branch』コマンドを入力して確認してませんか？ちなみに私はずっと入力してました...w
業務効率を上げるために何か良いものはないかと探していたときに **『Oh My Zsh』** に出会いました。

![スクリーンショット 2024-09-01 16.59.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/6c1d4f86-f11e-4897-7b08-2d20328f75b3.png)

遊び心のあるフレームワークで個人的にとても好きですw
今回はこのフレームワークを活用して作業ブランチ名を常に表示させるための手順をご紹介したいと思います！

# こんな形で表示されます

![スクリーンショット 2024-09-01 16.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/a950292c-1fe2-f7b2-6fe2-7ec64207daef.png)

# さっと見たい人向け

:::note info
#### 前提
- Macの設定手順になります
- Gitバージョンはv2.4.11以上を推奨してます
- インストールは『curlコマンド』の操作になります
:::


:::note warn
以下、手順①のコマンドを実行すると、Oh My Zsh がインストールされます。
zshrcファイルの設定内容が **削除** されて **Oh My Zsh の内容** に切り替わります。
そのため、手順①実行前にzshrcファイル内容のバックアップを必ず取りましょう。
:::


### 手順①：ターミナルで以下コマンドを実行する

```terminal:ターミナル
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
```

### 手順②：zshrcファイルを開く

```terminal:ターミナル
vi ~/.zshrc
```

### 手順③：ターミナルへの表示方法を設定する

```zsh:zsh
i //insertモードに切り替え
```
zshrcファイル内の ``ZSH_THEME="robbyrussell"`` が対象のコードになります。
デフォルトが ``robbyrussell`` になります。お好みに合わせて表示方法を変更してください。

### 手順④：zshrcファイルを閉じて設定内容を反映する

```zsh:zsh
esc + :wq + enter //insertモードを解除しzshrcファイルを閉じる ※『＋』は押下しない
source ~/.zshrc //zshrcファイルの設定内容を反映する
```
# もう少しだけ説明

**手順①** を実行すると、以下内容がzshrcファイルに反映されます。
コメントアウトされている項目に関しては今回の設定では関係ない箇所になるため、活性されているコードを見るだけでOKです。
※全文英語でしたがDeepLを使って日本語に翻訳しております。
　文章の読みづらさはご容赦ください...！
![スクリーンショット 2024-09-01 13.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/7724f696-9e73-88cb-6ce6-c3f8b7045ece.png)

作業ブランチ名をターミナルに表示させるための設定項目は``ZSH_THEME="robbyrussell"``になります。このままの状態で利用すると以下の表示になります。

![スクリーンショット 2024-09-01 16.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/ebc48969-704d-1859-dd9d-df869a1b1763.png)

``ZSH_THEME="agnoster"``にすると以下の表示になります。

![スクリーンショット 2024-09-01 16.36.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/cfe3232d-1032-5e73-f59d-ba5f03e55f1e.png)

この設定だけで作業ブランチが常に表示される様になります。『git branch』コマンドを入力せずとも安心して開発が進められそうですね！リモートブランチへの誤爆の心配も軽減されそうですw

ちなみにZSH_THEMEは上記以外にもたくさん用意されています。自分好みのものを見つけて設定してみてくださいね。

https://github.com/ohmyzsh/ohmyzsh/wiki/Themes

# おまけ

『Oh My Zsh』にはテーマの設定以外に、各言語の補完機能がついてます。
Gitに関して言えばエイリアスの設定がされていたりします。
気になる方は以下内容も合わせて確認してみてください！

https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/git


# さいごに

唐突ですが、弊社のご紹介もさせてください。

▼ コーポレートサイト

https://prum.jp/

▼ Wantedly求人

https://www.wantedly.com/projects/626662

弊社メンバーは学習した内容を日々Qiitaの記事にアウトプットしております。
弊社にご興味のある方、まずは求人を見てみてください！
ご応募お待ちしておりますー！

### 最後までご覧いただき、ありがとうございました！
pythonでjsonファイルをread/writeする際の備忘録

pythonでjsonファイルをread/writeする際の備忘録

write

```py: write.py
import json 
# Data to be written
dictionary = {
    "input": [
        [
            111,
            222,
            333,
        ]
    ]
}
 
# Serializing json
json_object = json.dumps(dictionary, indent=4)
 
# Writing to sample.json
with open("sample.json", "w") as outfile:
    outfile.write(json_object)
```

```sh
$ python write.py
$ cat sample.json 
{
    "input": [
        [
            111,
            222,
            333
        ]
    ]
}                                          
```

read

```py:read.py
import json

json_open = open('test.json', 'r')
json_load = json.load(json_open)
print(json_load)
```

```json:test.json
{
        "input" :       [
                [
                111     ,
                112     ,
                113     ,
                114     ,
                115     ,
                116     ,
                117
                ]
        ]
}
```

```sh
$ python read.py
{'input': [[111, 112, 113, 114, 115, 116, 117]]}
```

# 参考

https://qiita.com/t4t5u0/items/530d3eb7453aa8ad8abf

https://qiita.com/soiSource/items/53990fca06fb9ba1d8a7

https://www.geeksforgeeks.org/reading-and-writing-json-to-a-file-in-python/
GitLab PackageRegistryのMavenリポジトリをcurlコマンドで操作する

# はじめに
確認バージョン: GitLab Community Edition 15.3.1

# 1. Mavenパッケージのアップロード方法
JARファイルとPOMファイルをセットでアップロードします。

### 事前準備
GitLabのプロジェクト画面左側のSettings→Deploy Tokensから、api権限を持つトークンを作成します。

### JARファイルのアップロード
例: 

* 対象ファイル: mypkg-1.2.3.jar
* GitLabプロジェクトID: 63
* MavenグループID: foo.bar
* MavenアーティファクトID: mypkg
* トークンの値: glpat-1234567890abcdef123

```sh
curl --header "PRIVATE-TOKEN: glpat-1234567890abcdef123" --upload-file mypkg-1.2.3.jar \
"https://gitlab.example.com/api/v4/projects/63/packages/maven/foo/bar/mypkg/1.2.3/mypkg-1.2.3.jar"
```

### POMファイルのアップロード
JARファイルに含まれるPOMファイルを抽出し、JARファイルと同じ場所にアップロードします。

例: mypkg-1.2.3.jarに含まれるpom.xmlをアップロード

```sh
curl --header "PRIVATE-TOKEN: glpat-1234567890abcdef123" --upload-file <(unzip -p mypkg-1.2.3 META-INF/maven/foo.bar/mypkg/pom.xml) \
"https://gitlab.example.com/api/v4/projects/63/packages/maven/foo/bar/mypkg/1.2.3/mypkg-1.2.3.pom"
```

# 2. Mavenパッケージのダウンロード方法
### 事前準備
GitLabのプロジェクト画面左側のSettings→Deploy Tokensから、read_api権限を持つトークンを作成します。

## JARファイルのダウンロード
例:

```sh
curl -LO --header "PRIVATE-TOKEN: glpat-1234567890abcdef123" \
"https://gitlab.example.com/api/v4/projects/63/packages/maven/foo/bar/mypkg/1.2.3/mypkg-1.2.3.jar"
```

# 参考
* [Maven API](https://docs.gitlab.com/ee/api/packages/maven.html)
朝活してみたけど…健康とのバランスが大事だと感じた話

# はじめに
***「9時には就寝し、朝は3時に起きて勉強をして、7時には出社する」***

私が参加しているコミュニティー[JISOU](https://qiita.com/organizations/jisou)には、そんなような生活をしているエンジニアがいます。この習慣に近い形で1週間過ごしてみましたので、その結果をご紹介します。



:::note warn
警告
こちらの記事は、医学的根拠は全くありません。あくまでも私が体験した内容を記事にしております。
:::

# 1週間早寝早起き生活の開始
## きっかけ
最近の朝活ブームに影響され、<font color="Red">***「朝活=意識高い」***</font>という単純な理由で始めました。さらに「早起きは三文の得」とも言いますし、何か良いことがあるかも、と軽い気持ちで挑戦しました。

## 内容
流石に最初に挙げたような生活は難しいので、次のようなスケジュールで1週間過ごしました

- 11時までに就寝、朝は6時に起床
- 朝の8時まで勉強する

元の内容と比べるとかなり緩やかなスケジュールです。睡眠時間は6時間以上確保しています。普段は日付を超えてから就寝することが多いので、少し早めに寝るだけでも大きな変化です。起床時間も通常は8時前なので、かなり早く感じました。

## 経過
最初の2日ほどは次のような効果を感じました。

- 勉強が捗る
- 気分もスッキリする

朝活の恩恵で、その日1日が充実したものになりました。

<font color="Red">***異変を感じ始めたのは3日目からです。***</font>
次のような症状を感じました。
- 猛烈な頭痛
- 倦怠感

4日目以降は、無理やり朝に起きて勉強するだけになってしまいました。もはや何のために早起きしているのか分からなくなりました。

## 結果
実際に朝活の効果を感じたのは最初の2日間だけでした。その後は効果を感じられず、勉強の効率も向上しませんでした。さらに、その後2週間ほど体調を崩してしまい、この間は勉強の効率が著しく低下し、勉強時間も減少してしまいました。

さらにその後2週間ほど体調を崩してしまいました。この2週間は普段より勉強の効率がものすごく悪くなりました。勉強時間も少なくなってしまいました。

## 失敗の原因
今回の1週間早寝早起き生活は、総じて失敗に終わりました。その原因を考えると、いくつかの要素が挙げられます。

まず、体調不良の一因として、急激な生活習慣の変更が挙げられます。1ヶ月程度の期間をかけ、徐々に生活リズムを整えるなどの方法が良かったかもしれません。いきなり生活習慣を大幅に変えてしまったことで、身体がその変化に対応しきれなかったのだと思います。

さらに、朝活の時間に「何をやるか」を事前に決めていなかったことも問題でした。特に体調を崩してからは、朝の時間を有効に使うための計画が曖昧で、考えるのに多くの時間を費やしてしまいました。その結果、効率が悪くなり、ストレスも増してしまいました。

今思えば、あらかじめルーティンを決めておくことが大切だったと感じます。下記の記事で紹介されているように、朝活の内容をルーティン化することで、スムーズに行動でき、時間を無駄にせずに済むはずです

https://note.com/ryou0312/n/n0de9cb495a97

# 1週間早寝早起き生活での気づき
1週間早寝早起き生活を通して私は3つのことに気がつきました。

- ***自分に合った生活リズムを見つけることの大切さ*** 
- ***健康は全てにおいて基礎となる***
- ***無理は禁物***

人それぞれ、最適な睡眠時間や活動時間は異なります。誰かの成功体験を盲目的に真似るのではなく、自分自身の体と心の声を聞き、自分に合った生活リズムを見つけることが重要です。健康がなければ、どんな目標も達成できません。どれだけ効率的に時間を使い、努力を重ねても、健康を失ってしまっては意味がありません。

また、短期的な成果を求めて無理なスケジュールを組んだり、睡眠時間を削ったりすることは、長期的にはマイナスになる可能性が高いです。私のように体調を崩してしまっては元も子もありません。

<font color="Red">***朝早く起きて勉強することが目的ではないのです。あくまでの効率よく勉強するための手段に過ぎないのです。***</font>

# 最後に
今回の1週間の早寝早起き生活は、私にとって貴重な経験となりました。人によっては、「たった1週間いつもより早く起きただけでは？」と思われるかもしれません。しかし、自分の体調は自分にしか分かりません。短期間で目に見える成果は得られませんでしたが、健康の大切さや自分に合った生活リズムの重要性を改めて認識することができました。

朝活に一定の効果があったことは事実ですので、無理のない範囲で少しずつ続けていこうと思います。
[2024年最新]Google Cloud 認定資格をオンライン（リモート）受験しました！体験記

2024年9月1日にGoogleCloud認定資格のCloud Digital Leaderに合格しましたので試験までのフローを記載したいと思います。
順番等、若干間違っているかもしれないので予めご了承ください
**※2025年追記あり**

# 試験の申込の流れ
## Webassessorアカウント作成
以下のサイトから
https://webassessor.com/wa.do?page=createAccount&branding=GOOGLECLOUD

:::note alert
警告
名前、住所など提示する運転免許証、マイナンバーカードなどと表記ゆれ（□丁目〇番地△と□ー〇ー△）がないように気を付けてください。
**照会できない場合、受験できません！**
:::
- *2025.3.16上記の表現を**警告**に変更*

## 試験の申込
試験の申込タブ　＞　Google Cloud 認定試験 - 日本語　＞　該当の試験をクリック　＞　遠隔プロクター　＞　今すぐ購入　＞　日付・時間選択　＞　応募するボタン　でクレジットカードを選択し支払う

:::note warn
72時間以上、試験まで猶予があれば変更にお金が掛からないはずです...（ご自身でお確かめください）
:::


# 事前の準備
:::note warn
セットアップに時間がかかるので前日までに準備しておいたほうがいいと思います。
:::
- 専用ブラウザのインストール
- 生体認証登録
- ファイアウォールの設定（必要があれば）

# 試験当日の流れ
### 机の上
- ノートパソコン＋LogicoolのWebカメラ（C270)+ マウス
- 顔写真付き身分証
- スマートフォン

事前に**スマホ**、**身分証**が机上にあってもよいという情報があったので、その情報を信じてそれらを机の上に置いておきました。（あってもOKでした。後で片づけるタイミング有）
腕時計、ネックレス、飲み物はNGでした。

### 専用ブラウザの起動
アセスメントタブ＞予定されている試験＞実行の[？]の印のところが試験10分前に[受験する]へ変更され、事前準備でインストールした専用ブラウザが起動されました。

英語のポップアップで「Chromeが起動しています。Closeしてもよろしいでしょうか？」のような（意訳）が出てきていたので、Closeを押下するも...

何も変わらずポップアップが消えずでかなりテンパりました。何回かポップアップが起動していたので、**連打してみる**と次の画面に行きました。

### 生体認証と同意事項
事前準備と同様なPCのカメラを使用した生体認証登録を行い、手順に沿って同意事項にチェックを入れ進めていきました。

### 試験官の待ち時間
試験官を待っていますみたいな感じのメッセージが出てかなり待たされました。（10分強くらい？）
画面には「ゲームをしてもいいし、のんびりしてもいいです」みたいなのが表示されていた気がします。

WEBカメラが光った状態でActiveになっていましたが、まだスマホとか使って勉強してもいいと思います。待ち時間用にブラウザ版[PingPong](https://qiita.com/ist-ka-u/items/4044e775d1873e9bc4f9)ゲームが用意されていました。

緊張していてゲームのスコアは最高スコア19でした...

### スマホで部屋の環境の撮影と身分証の撮影
[部屋の環境の撮影]と[身分証の撮影]のフローになります。
**スマホを使用して**ブラウザに表示されるQRコードを読みこむ（またurl直打ちする）と専用サイトへ遷移しブラウザ内のカメラでカメラが起動し以下の項目を撮影しました。
- 前面
- 背面
- 左右
- 机を真上から
- 机の四隅の撮影
- 身分証の確認

私は運転免許証を使用しました。念のためマイナンバーカードも用意しましたが使用しませんでした。

### webカメラで身分証の撮影
左にチャットUIと右に自分のカメラの様子が分かるUIを含む画面に遷移します。
これ移行やりとりがチャットになります。（日本語）

PCのカメラを通した身分証の撮影を求められましたが、**解像度が足りず**チャットで「自身のスマートフォンアプリで身分証を撮影してカメラに見せてください」と言われたので、言われた通りスマホで撮影した画像をPCのカメラに映しました。見えにくかったのか、このやり取りが**3回くらい**私の場合はありました。

チャットはすべて日本語でしたが、botのように定型文の日本語しかチャットが送られていなかったので相手は日本人ではないと思います。

### スマホを手の届かないところへ退避
「スマホを試験エリアから削除してください。その様子私に見えるように映してください。」的なことを言われたので、外付けのWebカメラを持ちながらスマホを後ろにぶん投げた様子が映るように撮影しました。「みえましたか？」とチャット送ると「はい」と来てチャットが続きます。

### テストの開始
「これからテスト開始します。退出できませんがトイレとかいきたいですか？行きたい場合は5分以内でかえってきてください」みたいなことをチャットで聞かれたので、ちょうどトイレ行きたかったので「トイレ行きます」チャットで言って、試験官に戻り次第伝えました。

特に上記の時間は試験の時間に含まれておらず、きっちり1時間半試験時間は用意されていました。

# 試験

試験の問題毎に後で見直すチェックボックスがあり、試験提出前にチェックをつけたものを[レビューボタン]から一覧でみることができました。

**[提出ボタン]** を押すとすぐに提出されてしまうようなので、提出ボタンには注意してください

試験体験談は[こちら](https://qiita.com/asarashi/items/30a7f7e740d1e853597a)

# 試験後
試験終了後すぐに暫定的な合否がわかるようになっており、アンケートの調査がありましたが昼過ぎでお腹がすいていたので私はスキップしました

後日改めて、メールで合格の通知が送られてきました。
OBS起動後に自動でテキストソースのテキストを更新する

# 動機

- ローカルファイルの分析結果をOBSのテキストソースに自動反映させたい
- [OBSスクリプトを書いてみる #Lua - Qiita](https://qiita.com/natmark/items/66bf793253aa2d4b151d) を参考に、Luaを使えば実現できそう

# 方法1

OBSのフロントエンドの読み込み終了イベントに、テキストソースを更新するコールバックを登録します。

```sol1.lua
local TARGET_TEXT_SOURCE_NAME = "TestText"

function script_load(settings)
	obslua.obs_frontend_add_event_callback(on_event)
end

function on_event(event)
    -- https://github.com/obsproject/obs-studio/blob/release/30.2/UI/window-basic-main.cpp#L2526-L2529
    if event == obslua.OBS_FRONTEND_EVENT_FINISHED_LOADING then
        update_text()

        obslua.obs_frontend_remove_event_callback(on_event)
    end
end

function update_text()
    local source = obslua.obs_get_source_by_name(TARGET_TEXT_SOURCE_NAME)
    if source ~= nil then
        local settings = obslua.obs_data_create()
        obslua.obs_data_set_string(settings, "text", get_text())
        obslua.obs_source_update(source, settings)
        obslua.obs_data_release(settings)
        obslua.obs_source_release(source)
    end
end

-- 解説用のサンプル処理
function get_text()
    local text = ""
    -- = を含む行を逆順にtextに追加していく
    for line in io.popen([[type "C:\mylog.log" | sort /r]]):lines() do
        if line:find("=") then
            text = text .. line .. "\n"
        end
    end
    return text
end
```

`OBS_FRONTEND_EVENT_FINISHED_LOADING` イベントを使用しない場合、 `script_load` 内でテキストソースを更新することはできません。名前からも分かるように、`OBS_FRONTEND_EVENT_FINISHED_LOADING` イベントが発行される前はソースが読み込まれていないため、編集できません。

# 方法2

スケジューラやBatファイルなどを用いて、OBSの起動前にテキスト整形スクリプトを実行し、OBS側でテキストソースの「ファイルから読み取り（Read from file）」機能を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186959/d459c5a1-fa9d-3ef4-9e90-bfd37cf62104.png)

上記の画像では `C:\mylog.log` を選択していますが、このファイルを更新すると、OBSは起動中であっても自動的に再読み込みしてくれます。Luaに慣れていない場合は、この方法をおすすめします。
初めてLaravel環境構築(Windows + WSL + Docker + Sail)を行う前に知っておくべきこと3つ


Laravelの環境構築を(Windows + WSL + Docker + Sail)で行う際に、
いくつかの問題で時間を要しました。

同じ方法で環境構築を行う初学者のために、
あらかじめ知っておくべき重要なポイントを3点紹介します。

なお、環境構築手順は以下の公式ドキュメントを参照しています。

https://laravel.com/docs/11.x#sail-on-windows



# 1. Bashを実行可能なWSL2の構築が必要

Sailを使用して環境構築を行うためには、
WSL(Windows Subsystem for Linux)2でbashを実行可能なディストリビューションが必要です。

:::note warn
コマンドプロンプトやPowerShellでは実行できません。
:::


現在のwslディストリビューションは以下のコマンドで調べることができます。

```
>wsl -l
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu (既定)
docker-desktop-data
docker-desktop
```

私の場合はWSLにdocker-desktopが設定されていたため、
プロジェクト作成に必要な要素が不足していました。

また、Ubuntuに関しても追加でcurlなどのインストールが必要となるため、
公式の「1コマンドで簡単にセットアップ！」を過信しないほうが良いかもしれません。





# 2. php artisan 関連のコマンドが './vendor/bin/sail artisan' に変わる

公式ドキュメントのSail on Windowsを採用する場合、
php部分が全て './vendor/bin/sail' となります。

特にSailを使用していない記事などを参照すると、
php artisan コマンドが過半数のため注意が必要です。

:::note warn
GPTを使用する場合も'php artisan'が最初に掲示されるため、注意が必要です。
:::

基本的なコマンドは以下のようになります。
``` commands.txt
# Docker起動
./vendor/bin/sail up -d

# mysql接続
./vendor/bin/sail mysql

# 対話モード起動
./vendor/bin/sail artisan tinker

# マイグレート
./vendor/bin/sail artisan migrate

# シード実行
./vendor/bin/sail artisan db:seed

# マイグレート&データ生成やり直し
./vendor/bin/sail artisan migrate:fresh --seed

# テンプレ
./vendor/bin/sail

```

毎回全てを入力するのは手間だったので、
自分の場合は上記のようなcommands.txtを作成し、
よく使うコマンドを実行していました。

# 3. サンプルページの表示にもマイグレーションが必要
大抵のフレームワークでは、
プロジェクトを作成するとすぐにサンプルページを表示できますが、
Laravelの場合はDockerコンテナの起動後にマイグレーションの実行が必要となります。

```
# マイグレート
./vendor/bin/sail artisan migrate
```

マイグレーションを行わないと、
データベースにサンプルページ用のデータが投入されないため、
localhostへのアクセス時にMySQLエラーが発生します。

私はここで「Dockerまわりで設定失敗したのかな？」という路線から
かなり時間を浪費しました。

# おわりに
現在アプレンティスの6期生として参加しています。

カリキュラムにLaravelが含まれるため、
今後の参加者も同じ課題に直面する可能性があると思いますので、
参考になれば幸いです。

https://apprentice.jp/lp
VBAでedgeのhistoryファイルから閲覧履歴を取り出す

## edgeの履歴が取りたい
　※ファイルをインストールしないで、無理くりデータを読み出す方法です。

　もともとedgeの履歴を取りたかったのですが、
 
 ```:Historyファイル場所
 C:\Users\●ユーザー名●\AppData\Local\Microsoft\Edge\User Data\Default\History
 ```
 　履歴が保存されているHistoryファイルは メモ帳で開くと冒頭に
 SQLite format 3 ...

 　と記載されており、SQLiteなので、しかるべきODBCドライバーもしくは.dllファイルをインストールして見ることができます。
```:この程度の正確性でよければ
ttps://tryhackme.com/r/room/iosanalysishttps://tryhackme.com/P
```
　私が試したのは、会社の制限でこれらができないときに、文字化けと戦いながら閲覧履歴の一部を見る方法です。
　なお、手動でとりあえず中身が見たいなら、[Wordのファイル修復コンバーター](https://qiita.com/harryyuni/items/7172efe01fc061337bd0)でも同じような結果が得られます。

 ## マクロで読み出す場合

```vba:Historyを書き出す
Sub history()
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Dim textStream As Object
    Set textStream = fso.OpenTextFile("C:\Users\●ユーザー名●\AppData\Local\Microsoft\Edge\User Data\Default\History",1,False)
    Dim s_i As Byte
        For s_i = 0 To 200
            textStream.SkipLine
        Next s_i
    Dim regEx As Object
    Set regEx = CreateObject("VBScript.RegExp")
    regEx.Pattern = "https?://[\w!?/+\-_~=;.,*&@#$%()'[\]]+"
    regEx.IgnoreCase = True
    regEx.Global = True
    
    Dim textLine As String
    Dim matches As Object
    Dim match As Object
    
     Do Until textStream.AtEndOfStream
        textLine = ""
        textLine = textStream.readLine
            If InStr(textLine, "test.com") > 0 Then
                Set matches = regEx.Execute(textLine)
                    For Each match In matches
                        Debug.Print textStream.Line
                        Debug.Print match
                    Next match
            End If
            If textStream.Line = 500 Then Exit Do
     Loop
    textStream.Close
End Sub
    
    
```
## 詳細

　私はパソコンではあまり検索しないのに６年使ったＰＣで１万行ありましたので、199行しか出力できないイミディエイトウインドウには荷の重い仕事です。最初、固まったのかと思いました。
 　履歴ファイルは行が多いのでinstrで該当サイトだけ出力しましょう。どうも、最後に開いたサイトは223か224行目辺りに来ることが多く、100行目辺りまではフォーマットがそれ以降と異なりエラーが頻出したので、201行目スタートにしています。例では500行までにしていますが、行も区切った方がよいと思います。


　どうやら、SQLiteはUTF-8という話なので、CreateObject("ADODB.Stream")
 でCharsetをUTF-8にすればいけると思ったのですが、全くとりだせませんでした。
　なぜtextstreamなら部分的に文字化けしながらも取り出せるのかは謎です。
  誤ってwriteしてHistoryファイルを壊さないよう、最初はHistoryファイルをデスクトップなどにコピーしてコードを作るのがよいと思います。
Julia 小ネタ集

Juliaという言語がなかなか楽しいのですが、新しく触れる言語かつ解説もそこまで多くないため、つまづくところが多いです。
そこで初心者の備忘録として、トライアンドエラーで得た知識を書いていきます。内容は思いつき次第更新で。より良いやり方や認識間違いなどの突っ込み大歓迎です。

## Plots 複数ヒストグラムの幅を揃えたい

### 事象

```julia
using Plots

data1 = rand(100) .+ 2
data2 = rand(100) .* 3 .+ 1

plt = plot()
histogram!(plt, data1, alpha=0.3, bins=20)
histogram!(plt, data2, alpha=0.3, bins=20)
```

![graph1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617561/1aabd33f-7776-d9e3-50ca-8684a9533577.png)

matplotlibでもありがちだけど、分散や最大最小値が異なる二つの分布を重ねると棒の幅などが揃わず、コレジャナイ感満載のヒストグラムができやすい。

### 解決策

StatsBaseのfit関数を使う。
あらかじめPkgからadd StatsBaseしておく。
```julia
using Plots
using StatsBase

data1 = rand(100) .+ 2
data2 = rand(100) .* 3 .+ 1

hist1 = fit(Histogram, data1, 0:0.2:5)
hist2 = fit(Histogram, data2, 0:0.2:5)

plt = plot()
plot!(hist1, alpha=0.3)
plot!(hist2, alpha=0.3)
```

fitの第1引数はHistogram固定。第3引数にヒストグラムの最小値:差分:最大値を指定する。
これでhist1, hist2は度数分布表になるので、これをplotやplot!に放り込んでやる。

![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617561/e6929282-6456-1a92-39ad-86a8702a41e0.png)

### より良い方法

…と書いたところ、別に新たなパッケージを導入せずとも、binsにRangeを指定することでのぞみのグラフが得られるとコメントいただきました（ありがとうございます）。

```julia
using Plots

data1 = rand(100) .+ 2
data2 = rand(100) .* 3 .+ 1

plt = plot()
histogram!(plt, data1, alpha=0.3, bins=1:0.2:4)
histogram!(plt, data2, alpha=0.3, bins=1:0.2:4)
```

こっちの方がずっとスッキリ。

## 予定
- Plotのforを使った重ね書き
- Vectorを重ねてMatrixを作るときのお作法
- XLSXやCSV,Encode周り
- 型の扱い
- 入れておきたいパッケージ
[baserCMS][baserCMS Toggle Debug] デバッグモードを簡単に切り替えられるVSCode用拡張機能


baserCMSのデバッグモードを簡単に切り替えられるVisual Studio Code用拡張機能を作成しました。4系版と5系版の両方に対応しています。

- [Visual Studio Code Marketplace](https://marketplace.visualstudio.com/items?itemName=fuchigam1.basercms-debug-toggle)
- [github](https://github.com/fuchigam1/basercms-debug-toggle)

![sc_basercms-toggle-debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26110/88b8c425-a131-8ade-54d9-abb6a51e29b2.png "sc_basercms-toggle-debug.png")



## 想定している対象者

- baserCMSを用いて開発、制作を行っている方
- デバッグモードの切り替えを頻繁に行う方


## どうして作ったの？

baserCMSのデバッグモードの切り替えをもっと簡単にしたいと思い、この拡張機能を作りました。
通常、デバッグモードは設定ファイルを手動で編集して切り替えますが、その手間を省きたいと考えたからです。
（管理画面からも切り替え可能ですが、より手早く行いたい方におすすめ）

- baserCMS4系
	- app/Config/install.php 内の ```Configure::write('debug', 0);```
- baserCMS5系
	- config/.env 内の ```export DEBUG="false"```


### デバッグモードってなに？

baserCMSのデバッグモードは、開発やトラブルシューティングの際に役立つ機能です。
本番環境ではオフにするのが一般的です。
オンにすることで詳細なエラーメッセージやログが表示され、問題解決がスムーズになります。
開発時には主に以下の動作が変わります。

- 詳細なログ情報が生成される
- 一部のキャッシュ（ビューキャッシュやDBキャッシュ）が無効化される


## 参考記事

初めてのことが多く、いろいろな情報に助けられました。ありがとうございました。

- https://code.visualstudio.com/api/working-with-extensions/publishing-extension
- https://qiita.com/tkts_knr/items/92a15a9fe7475418b333
- https://dev.classmethod.jp/articles/easy-vs-code-extension-development/
- https://tercel-tech.hatenablog.com/entry/2024/03/07/233436


## 感想など

工夫したのは、現在のモードを表示させておくことですぐ確認できるようにしたことです。
プロジェクトを開いた直後に反映というのができなくって、一旦諦めちゃいました。
コマンド1回叩く必要があるのが改善点なのでそのうち、といったところです。
後からVRM化したモデルの Humanoid Avatar を作成する方法

VRM規格は神！でも．．．Unityでは Humanoid Avatar じゃないんだ．．．

# 目的
Blender や Unity から VRM化したモデルの Humanoid Avatar を作成する方法


### 前提条件

1. ヒューマノイドのモデルをVRM形式でUnityにimportしている
1. VRM0系を入れている (VRM1系では未確認)
1. Unity 2022.3.10f1 (他は未確認)

### 方法

1.Unityのシーン上にモデルを用意する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/61290e94-406d-fc50-e3cf-8fc76e64f264.png)

2.UniHumanoid に含まれる　Humanoid を Animator がある Component にアタッチする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/517ca020-4c85-0d2d-f2b5-01fe80fb691f.png)

3.Create UnityEngine.Avatar を実行

4.UnityHumanoid に含まれる BoneMappiing を VRM Humanoid Description がある Component にアタッチする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/bef99737-9844-8d08-c62e-c874edba3a27.png)


5.Create Avatar を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/fcbbf4a5-549e-f08a-124c-a43d7091088c.png)

左下のように Avatar Description が生成される．(このときに Humanoid で作成した Avatar を Override しないように注意する．)

この Avatar Description を本体のモデルの Avatar Description と入れ替える．

### デモ
![VRM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353403/e518dc07-a9d6-8927-f64c-5cd19258af14.gif)

# 使用したモデル(1番重要)

Noesisの一夜さん(嫁)です!

https://booth.pm/ja/items/4077433

### 参考

https://vrm.dev/en/univrm/humanoid/meshutility_humanoid/
u-blox USB-NORA-W2で始めるAWS IoT ExpressLink - Raspberry Pi pico と連携

前回の記事では、u-bloxのモジュールをPCから操作しました。

https://qiita.com/sparkgene/items/78516382882cbc3e8cb2

この記事では、実際のユースケースのように、別のマイコンから利用する方法を試してみます。

![IMG_8225.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36184/37faf3e9-afad-4661-977c-f79fadcfd33e.jpeg)

結線は以下のようにしています
|u-blox USB-NORA-W2 | Raspberry Pi pico |
| ----- | ----|
| TX(GPIO43)|UART0RX(GP1)|
| RX(GPIO44)|UART0TX(GP0)|

Raspberry Pi picoはMicroPythonが使えるように[ファームウエア](https://www.raspberrypi.com/documentation/microcontrollers/micropython.html)を書き込んでいます。

VS Codeでコーディングしていますが、[MicroPico](https://github.com/paulober/MicroPico)の拡張機能を入れると試すのが楽でした。

いかがプログラムです。

```python
from machine import UART
import json
import time

uart = UART(0, 115200)


def send_command(cmd: str):
    print(f"SEND: {cmd}")
    uart.write(f"{cmd}\r")

    recieve_result()


def recieve_result():
    time.sleep(0.5)
    rxData = bytes()
    while uart.any() > 0:
        rxData += uart.read(1)

    print(rxData.decode('utf-8'))


print("Start!")

# 
send_command("AT")

send_command("AT+CONF? Version")

send_command("AT+CONNECT")

send_command("AT+CONF Topic1=ublox/data")

for i in range(5):
    msg = {"message": f"Hello World! {i}"}
    send_command(f"AT+SEND1 " + json.dumps(msg))
    time.sleep(1)

```

やっていることは単純で、MQTTの接続を行った後、メッセージをpublishしています。

AWS IoT Coreのマネージメントコンソールに以下のようなメッセージが届きました。

```json
{
  "message": "Hello World! 4"
}
```

こうやってみるとホストマイコンの方は、少ない実装でクラウドと接続できることが確認できたかなと思います。

MQTTにsubscribeするプログラムを書く場合に、頻繁に `AT+GET` で監視する必要があるかというと、ExpressLinkにはEvent Pinの仕様もあります。このPinはハードウエアのモジュールによって変わりますが、[USB-NORA-W2の場合は、GPIO11](https://content.u-blox.com/sites/default/files/NORA-W2_DataSheet_UBX-21046925.pdf)に割り当てられているようです。このPinをホストマイコン側と接続することで、ホストマイコンの通知すべきイベントが発生したら、PinはHighになります。イベントキューが空になると、Lowになります。

ホストマイコンはこの信号を検出したら、どんなイベントがあるかを`AT+EVENT?`のコマンドで確認し、必要な処理を行うことで、イベントドリブンな実装を行うことができます。

https://docs.aws.amazon.com/iot-expresslink/v1.2/programmersguide/elpg-event-handling.html
Sentryでエラー監視を始めてから良かったこと

# はじめに
社内プロジェクトでSentryをインストールしていたものの、入れていただけで有効活用はできていなかった。

そこで、テックブログなどを参考に他社のSentry運用方法を調べて、それを自社プロジェクトに落とし込み、実際に運用を始めてみた。

今回はエラー監視をやってみて良かったことをまとめてみた。

# 運用開始前の印象
- **面倒くさそう・・・**
- いっぱいエラーが来て、他の業務が圧迫されたらやだな

# 良かったこと
- システムの理解につながった
→ユーザーがどういう使い方をしているのかがわかった！運用を続けると否応にも頻度の多いエラーとその原因がわかってくるので、より**全体を見た対処法**を考えられるようになる！
- ユーザーの問い合わせに自信を持って答えられる
→常に監視をしていて問題が起きたらすぐ対処できる体制ですと答えることで、ユーザーからの**信頼**につながった！
- 続けるごとに確実にエラーが減っていくので、ユーザーからの問い合わせ頻度が減り、保守コストが下がる。


# 継続したらこんなことに気づきました
- 意外と発生するエラーは偏っている
→全体の２割の機能を８割のユーザーが使っている、とどこかで聞いたことがあるが、発生するエラーは意外と偏りがあり、**一つ修正するだけで多くのエラー発生を修正する**ことにつながった。

# おわりに
何かと面倒になりやすい保守業務ですが、Sentryでエラー監視を初めると、**エラーを効率よく潰すことが業務量の削減につながる**ので、保守業務に前向きに考えて取り組むことができるようになった。

仕様決定段階で、例外を発生させないように色々なケースを想定したり、（この辺りは、エラー監視を通してエラーの発生傾向を掴んでいたことがいい経験になった）
設計段階では、最小限の手間で複数のエラーに対処できるように、共通化を意識したりとか。

手を動かすだけのエンジニアにならないために、必要な思考回路が身についていったと思います。