OmniAICreator/Qiita-1.07M huggingface dataset:
(シンセ先輩からもらった(ほぼ))TG-LPC11U35-501、Lチカで遊ぶ。


参考

https://akizukidenshi.com/catalog/g/g112144/


x 過去ログをみよ

x くわしくは、秋月のlpc11u35をみてね

x arduinoじゃないけど電子工作も含む?

目的
理系フリマで入手831　シンセ先輩：mbedおわつちゃつたしで安くゆづって貰った
11u35、5台
Lチカさせる


![o_coq357.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/19f4a315-43e1-1832-b468-760ca955fa5f.jpeg)

●組み立て後

![o_coq358.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/485e738a-f35d-bc0d-243b-713ef7c7e14b.jpeg)


結果

![o_coq359.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1962edba-31ce-0a65-27a1-a084600d0ed0.jpeg)


1.ログイン

![o_coq360.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/078ab05b-9b1e-9b92-a073-ffe52636c465.jpeg)

2.コンパイルする

![o_coq361.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/454d8325-7d02-6c0d-7b23-ab8628e24710.jpeg)

![o_coq362.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1a6a5272-5c50-1e6e-bff2-1f1dff525066.jpeg)



```c++

#include "mbed.h"

DigitalOut myled(LED1);

int main() {
  while(1) {
    myled = 1;
    wait(0.2);
    myled = 0;
    wait(0.2);
  }
}


```

3. USBさす、ISP押したまま、リセットする

4. けす、コピー、リセットする(ターゲット)


![o_coq363.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b7db10b1-3b33-5716-2750-f685f528cc67.jpeg)
ハードウェア故障(PC)の問い合わせがあった際のヒアリング

## はじめに

こんにちは、小磯と申します。

ヘルプデスクやサポートデスクの業務を行っていると、お客様（ユーザー）よりハードウェア故障の問い合わせが来ますが、見たままの1視点しか情報がありません。
1視点の情報で対応してしまうと間違った案内をしてしまい、クレームを受けるかもしれません。
何が原因なのかを特定するため、もう少し深掘りするためにお客様（ユーザー）へヒアリングする必要があります。

## 1.ネットワーク
ネットワークに繋がらない場合、以下のヒアリングを行います。
#### ①有線LAN
 - PCに正しく接続されているか。
 - 他のLANケーブルを挿して接続出来るか。
 - 他の方もネットワークに繋がらないか。
 - 離れた席(接続元が違うHUB)にあるLANケーブルを挿して接続出来るのか。
 - LANケーブルを挿した際、PCの差込口にあるランプはどうなっているか。
※PCには問題が無くNW機器で障害が発生している可能性があるため、接続元（島HUB・フロアHUB）の担当者へ確認してください。

#### ②無線LAN
 - 接続先のアンテナ名は合っているか。
 - 無線接続の無効・有効を行い、接続出来るか。
 - 接続先のアンテナ名を変えて接続できるのか。
※PCには問題が無くNW機器で障害が発生している可能性があるため、接続元（島HUB・フロアHUB）の担当者へ確認してください。

## 2.PC本体
PC本体に何らかの原因で起動しない場合、以下のヒアリングを行います。
#### ①本体の電源が入らない
 - 電源ケーブルが正しく接続されているか。
 - コンセントに正しく接続されているか。
 - ノートPCの場合は、バッテリー・電源ケーブルを外して1分後に接続し直してから電源は入るか。
 - PC本体のランプの状態はどうか。

#### ②OSが起動しない
 - 画面の状況はどうか。（DOS画面・ブルースクリーン）
ブルースクリーンの場合は、コードが記載されていると思うので控えておく。
 - 電源を落とし、電源ケーブルを抜き放電させた後に電源を入れたらOSは起動するか。
ノートPCの場合は、バッテリーも外した方がよいです。

#### ③モニターが映らない
 - PCに正しく接続されているか。
 - 他のモニターを挿して表示されるのか。
 - 出力画面設定はどうなっているのか。


## まとめ
協力いただくため、相手側に分かり易く案内し情報を引き出す必要があります。
五月雨式に一気に聞かず、相手のペースに合わせて1つずつ確認していきましょう。
問い合わせが来た際、ヒアリング内容を瞬時に案内することは難しいと思いますので、一覧表にして切り分けていくとよいと思います。

以上、小磯でした。
Go言語(Golang) "godoc"と"go doc"

### `go doc`と`godoc`の違い

**1.使用方法**:
   - `go doc`: コマンドラインで直接使用
   - `godoc`: ウェブサーバーを起動し、ブラウザで閲覧

**2.機能**:
   - `go doc`: シンプルなドキュメント表示
   - `godoc`: 詳細なドキュメント表示、ソースコードリンク、検索機能

**3.インストール**:
   - `go doc`: Go標準ツールチェーンに含まれる
   - `godoc`: Go標準ツールチェーンに含まれる

**4.用途**:
   - `go doc`: 素早い情報確認
   - `godoc`: 包括的なドキュメント閲覧

**5.出力形式**:
   - `go doc`: テキスト形式
   - `godoc`: HTML形式（ブラウザで表示）



### `go doc`の例

**1.パッケージのドキュメントを表示**:
```sh
go doc fmt
```

**2.特定の関数のドキュメントを表示**:
```sh
go doc fmt.Println
```

**3.特定の型のドキュメントを表示**:
```sh
go doc time.Time
```

### `godoc`の例

**1.ウェブサーバーを起動 (デフォルトポート6060)**:
```sh
godoc -http=:6060
```

**2.カスタムポートでウェブサーバーを起動**:
```sh
godoc -http=:8080
```
[AWS #24] Amazon Cloud Front

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
こんにちは
今回はネットワークサービス分野である **<font color="c00000">「Amazon Cloud Front」</font>** について紹介したいと思います。
:rolling_eyes: CloudをFront（正面、前）?　どんなサービスなんでしょうか
:upside_down: 世界中に約**600**箇所以上ある **「エッジロケーション」** を使い、<font color="c00000">**最も低いレイテンシー**</font>でコンテンツを配信できる<font color="c00000"> **「コンテンツ配信ネットワークサービス」**</font>になります。特徴も踏まえて見ていきましょう。

## Cloud Frontの特徴
・**キャッシュによる低レイテンシー配信**
・**ユーザーの近くからの低レイテンシー配信**
・**安全性の高いセキュリティ**

### キャッシュによる低レイテンシー配信
仮にCloud Frontを使用していないとします。 **S3（Simple Strogae Service）** から直接、または**ELB（Elastic Load Balancing）** 経由のEC2からWebコンテンツ配信をしているユーザーがいたとしましょう。アクセスしたいユーザーはその都度、**オリジナルコンテンツ**にアクセスします。

色々な理由があります。**距離が離れている…**　コンテンツのサイズが**大きく負荷がかかっている…** など。

その影響で配信に遅延が発生している場合、コンテンツを閲覧している全てのユーザにも<font color="c00000">**同じような遅延が発生**</font>します。

### ユーザーの近くからの低レイテンシー配信
Cloud Frontは<font color="c00000">**世界中にエッジサーバーを持つ**</font>ため、あらゆる場所からのアクセスにも**柔軟に対応**することができます。

図のように一例ですが、東京リージョンにEC2でアプリケーションを作成した場合でも、**CloudFront**をしようすることで「エッジサーバー」にキャッシュを持たせることができます。それにより、海外ユーザーにも**低レイテンシー**でアプリケーションを利用してもらうことが可能です。
![AWS24_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/bd4f17f6-ee8f-bb8f-85fb-332cc614f152.png)


### 安全性の高いセキュリティ
Cloud Frontは、セキュリティ面でも優れた<font color="c00000"> **CDN（Contents Delivery Network）**</font>サービスとなっています。なので安心して使用することが可能です。

さらに、AWS利用者が使用している**ドメインの証明書**を使用することができ、ユーザーからHTTPSのアクセスを受けることでデータを**保護することが可能**です。

## おわりに
今回のちょっとしたまとめになります。

:::note info
Cloud Frontは <font color="c00000">**セキュリティ面に優れた**</font>サービス
:::
:::note info
エッジロケーションにキャッシュを持つことで <font color="c00000">**低レイテンシー配信**</font>を実現する
:::
:::note info
世界中にエッジサーバーを持つ　→　 <font color="c00000">**あらゆる場所からのアクセスにも柔軟に対応する**</font>
:::

Cloud Frontは世界中に沢山あるエッジロケーションを使って、最も低いレイテンシーでコンテンツを配信できるサービスということがわかりました。

最後までお読みいただきありがとうございました！
>>日頃より活用している参考書です。
>> **「参考書」**
[AWS認定クラウドプラクティショナー改定第3版](https://x.gd/19i6N)
>
> **「AWS公式サイト」**
[Amazon CloudFront とは何ですか?](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html)
>
> **「参考元」**
[【初心者必見】Amazon CloudFrontについて](https://www.ctc-g.co.jp/solutions/cloud/column/article/26.html)
>
> **「Youtube」**
[Amazon CloudFront](https://www.youtube.com/watch?v=JAAq_an68HU)
キャッシュ機能の差でActiveStorageではなくCarrierwaveを使うことにした

## これは何？
railsのファイル管理機能で、ActiveStorage vs Carrierwave論争はよく聞く。

> [Ruby on Rails】ActiveStorageの概要とその利点、弱点](https://zenn.dev/s17w09/articles/d91b274b2f2116)
> [ActiveStorage vs CarrierWave](https://qiita.com/w5966qzh/items/510d4c2a3829524b2e64)
> [画像管理をActiveStorageからCarrierWaveへ乗り換えた話](https://tech.dely.jp/entry/2019/12/22/145733)
> [Catch allルーティングとActive Storage](https://qiita.com/jkr_2255/items/60d4e5859a711258f97c)

プレビュー機能の実装にはCarrierwaveのキャッシュ機能が必要だったので、備忘録として記述する。

## 要件
### 開発アプリケーション概要
- 管理サイトとエンドユーザ画面のあるwebアプリケーション
- 管理サイトでコンテンツの編集を行い、エンドユーザサイトで閲覧することができる

### 開発機能概要
- 管理サイトのコンテンツ編集画面において、プレビューを行いたい
- 画面の左半分が入力部分、右半分をプレビュー部分とし、エンドユーザサイトと同じ見た目で入力をリアルタイム判定したい


### 実装方法
- エンドユーザサイトのviewをコンポーネント化し、管理サイトの編集画面の右半分に埋め込む
- 左側の入力部分のform内の値が更新されるたびにformの内容をpreview更新用エンドポイントに送信してturboの描画内容を返却させ、その返却値でまるっと右側のエリアを更新

この際、ActiveStorageではキャッシュ機能が存在していないため、未保存の画像を呼び出すことはできない。
故に入力部分で画像を選択しても、プレビュー部分には表示されない。

一方でCarierwaveにはキャッシュ機能が存在しているので、未保存であっても選択した画像をプレビュー部分に表示することができる。
フェルミ推定

最近、エンジニアとして自己啓発本を読んだりする中で、`フェルミ推定`という言葉を初めて目にしました。  
少し調べると、私はたまに無意識？にやっていたことでした。  
例えば、そば屋さんに行って、繁盛していると
- 土日の昼の客数はこのくらい
- 一人当たりの客単価はこのくらい
- 平日は客数少ないだろう
- 従業員は3名いるから

結果！そんなに儲けてないやん！
ってな具合に、仮説（推定の数）などを当てはめて
計算する。
に似ているなと思いました。

[こちら](https://qiita.com/PoodleMaster/items/cc648e4b500273ea3348)の記事で勉強させていただきました。

# フェルミ推定とは
1. コンサル業界でよく聞く（使われる）
2. 限られた情報から、合理的に（荒く）スピーディーに見積りを行う方法

# フェルミ推定を使用する理由
1. 例えば戦略を立てる場合などに、あらゆるデータを収集できるとはまれで、そのような状態においても論理的、合理的に推定する必要がある場合に有効
2. 推定したことの根拠を一般的な数値、または推定した数値を用いて論理的に説明できる

# フェルミ推定のやり方

<span style="font-size: 200%; color: red;">**コンビニの年間売上高は？**</span>
こちらを例として考えてみます。

## Step1 前提確認
コンビニと言っても、世界全体なのか日本のことなのか分かりません。  
また、年間売上と言ってもいつのものか分かりません。
上記のような曖昧な箇所を確認できる部分は、確認します。確認できないことは前提を考えます（前提を作る）。

ここでは、  
<font color="red">日本のコンビニの2023年度の年間売上高</font>という前提にします。

## Step2 アプローチ設定
土台となる計算式を立てていきます。
1. 日本人1人が1日にコンビニでの購入金額
2. コンビニを利用する日本人の人口
3. 日本人が、コンビニに行く年間日数 

## Step3 モデル化
Step2で設定した式に数を推定し計算する

>1. 日本人1人が1日にコンビニでの購入金額  

700円

>2. コンビニを利用する日本人の人口

日本の総人口を1.2億人として、そのうち70%がコンビニを利用すると仮定します。
1.2 * 0.7 ≒ 8,000万人

>3. 日本人が、コンビニに行く年間日数 

週平均4回と仮定。≒年間200日。

## Step4 計算
実際に計算します。

700円 × 200日 × 8,000万人 ＝ 11.2兆円

## Step5 現実性検証

結果の妥当性を確認
DockerでRailsとMySQLの開発環境を構築する方法

## はじめに
今回、Rails 7とMySQL 8.0の開発環境を構築する際にDockerを使用してみました。環境構築の手順を具体的に説明しながら、注意点やエラー解決の方法についての説明していきます。

## 必要なファイルの作成
まずは、以下のコマンドを使用して、必要なファイルを作成します。
```
touch Dockerfile docker-compose.yml Gemfile Gemfile.lock entrypoint.sh
```
このコマンドは、zshシェルを使用している場合にファイルを5つ一度に作成するためのものです。

## Dockerfileの設定
次に、Dockerfileの内容を以下のように記述します。
```
# Rubyの公式イメージを使用
FROM ruby:3.2.5
ARG RUBYGEMS_VERSION=3.3.20

# 作業ディレクトリを指定
WORKDIR /myapp

# ホストのGemfileをコンテナ内にコピー
COPY Gemfile Gemfile.lock /myapp/

# bundle installを実行
RUN bundle install

# アプリケーションコードをコンテナ内にコピー
COPY . /myapp/

# entrypoint.shをコンテナ内にコピーし、実行権限を付与
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh

# コンテナ起動時にentrypoint.shを実行
ENTRYPOINT ["/usr/bin/entrypoint.sh"]

# コンテナ起動時に実行するコマンドを指定
CMD ["rails", "server", "-b", "0.0.0.0"]
```

## docker-compose.ymlの設定
次に、docker-compose.ymlファイルを以下のように設定します。
```
version: "3"
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mydatabase
    volumes:
      - mysql_volume:/var/lib/mysql
    ports:
      - "3306:3306"
    command: --default-authentication-plugin=mysql_native_password

  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    stdin_open: true
    tty: true
    depends_on:
      - db

volumes:
  mysql_volume:
```

## Gemfileの設定
次に、Gemfileをファイルを以下のように設定します。
```
source 'https://rubygems.org'
gem 'rails', '~> 7.0.0'
```
## entrypoint.shの設定
次に、entrypoint.shをファイルを以下のように設定します。
```
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

## Railsプロジェクトの作成
以下のコマンドでRailsプロジェクトを作成します。
```
docker-compose run web rails new . --force --no-deps --database=mysql --css=tailwind --skip-jbuilder --skip-action-mailbox --skip-action-mailer --skip-test
```
### オプションの説明
* --database=mysql: MySQLを使用するために指定します
* --css=tailwind: Tailwind CSSを使用する設定が自動で行われます
* --skip-*: 必要のない機能をスキップします

## MySQLの設定
config/database.ymlを以下のように編集します。
```
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test
```

## データベースの作成
次のコマンドでデータベースを作成します。
```
docker compose run web rails db:create
```

## コンテナの起動
最後に、コンテナを起動させます。
```
docker compose up -d
```
ブラウザで`http://localhost:3000/`にアクセスし、Railsの初期画面が表示されれば成功です。

## 注意点
何度か試しているとキャッシュが残っていてうまく起動しないことがあります。
対処法①
以下のコマンドでdockerを再起動してみる
```
docker compose down -v
docker compose up -d
```
対処法②
volumes内のすべてのファイルとフォルダを強制的に削除する
```
docker-compose down
sudo rm -rf ./db/mysql/volumes/*
docker-compose up
```

## 参考文献
https://musclecoding.com/rails7-mysql8-docker/#index_id2

## まとめ
私自身何度もエラーを出してしまい試行錯誤しながら環境構築しました。環境構築が完了した後もこの記事を書くために数回環境構築をしなおしてちゃんと動くか確認してみました。この記事が環境構築で困っている人の助けになれば嬉しいです。
ライブラリ・パッケージ・モジュールについてまとめた備忘録

# 前置き
こんにちは！
今回は掲題にも書いているライブラリ・パッケージ・モジュールについてまとめました。

いまいち、この辺の言葉ってパッとイメージがしずらく人によって定義があやふやなので
今回備忘録を兼ねて記事としてまとめました。

# モジュールって何？
:::note warn
**注意**
前提としてIT用語に出てくるモジュールについてです。
モジュールという言葉自体は様々な業界で使われており、業界によって意味が変化します！
:::

**結論**

**「部品」** です！
要するにハードウェアやソフトウェアなど媒体に対して付属する部品や機能のことを指します！
下記に例をあげます！

```
例 <ハードウェア>
スマートフォンにはカメラが付いています
付いているカメラは**カメラモジュール**です

Q. カメラモジュールのメリットとは？
A. 製品を0から作る必要がない！
A. 別の製品にも組み込みができる！(PCや他デバイスなど)
A. 目的に合わせて変更可能！(4Kカメラなどデバイスの応じて変更可能)
```

```
例 <ソフトウェア>
Webサイトなどには様々な機能が付いています。例えばログイン機能です。
このログイン機能はログイン機能モジュールです！
このモジュールはWebサイトを構成する要素の1つです！

Q. ログイン機能モジュールのメリットは？
A. ソフトを0から作る必要がない
A. 別のソフトに組み込みができる！
A. 目的に合わせて変更可能！(セキュリティに合わせてログインに縛りをかけるなど)
```

# パッケージって何？

**結論**

**「モジュールをひとまとまりにしたもの」** です！
イメージでは **「フォルダ」** です！
先程説明したモジュールをファイルとして捉えて一つのフォルダにまとめるようなもんです。
例えとして、イメージしやすいようゲームを取り上げます。

```
例 <ゲーム販売>

ゲーム販売では最新ゲームソフトや最新ゲームハードが発売されるとパッケージ売りが行われます。
例えばPS5が発売された時をイメージしてください。

販売時のパッケージ商品として「ゲーム機本体・コントローラ・ゲームソフト．．etc」のように
販売されているのを見たことあると思います。

このひとまとまりがパッケージです！
ゲーム機本体や、コントローラ、ソフトはモジュールという扱いになります。
```

要は下記画像です。
ゲーム機本体と一緒にスパイダーマン2が付いてきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/1ef308d8-6a9a-61f8-2820-1e5bbe977399.png)



```
例 続き パターン2

パッケージは複数のパッケージをまとめて定義ができます。
パッケージと定義してまとめられたまとまりをモジュールとして呼ぶこともできます！

先程のゲーム販売を例にします。
{A/Bは個別パッケージ商品、CはA/B商品をまとめ買いできるパッケージ商品です！}

パッケージA:モジュール →「ゲーム機本体・コントローラ・ゲームソフト」
パッケージB:モジュール →「マイク付きヘッドセット・コントローラー・外付けHDD」
パッケージC:モジュール →「パッケージA・パッケージB」

```
要は下記画像です。

ゲーム機本体とコントローラーがついてくる箱A
ヘッドセットとかもろもろ付属品などついてくる箱B
それぞれをモジュールとして捉えて
この2つの箱同時買いすることをパッケージCとする的なイメージです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/df7ba0f4-96a2-a622-ee0b-6df43702fa7a.png)

# ライブラリって何？

**結論**

**「図書館」** です！
要はモジュールやパッケージを詰め合わせたものです。

部品単体やパッケージなどがめちゃ入っている集合体だったり、
場所をイメージしてもらえればOKです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/2e5e67ac-883f-e920-1016-a13aea802d07.png)

以上です、お疲れ様でした。

学習の参考になれば幸いです。
(調査中)tomcat の設定が反映されない？

Tomcatのserver.xmlで指定した設定が反映されていないように感じる場合、いくつかの原因が考えられます。以下に主な理由を挙げます。

### 1. 設定のキャッシュ:

Tomcatは再起動しないと、server.xmlの設定が反映されません。設定を変更した後、Tomcatを再起動することを確認してください。
### 2. 他の設定ファイルの影響:

server.xml以外にcontext.xmlやweb.xmlなど、特定の設定をオーバーライドする設定ファイルが存在する場合があります。ただし、maxConnectionsのようなコネクションに関する設定は通常server.xmlに設定されます。
また、confディレクトリ内にCatalina/localhost/ディレクトリなどがある場合、その中のファイルが個別のWebアプリケーションの設定を上書きしている可能性もあります。
### 3. 環境変数やシステムプロパティ:

環境変数やJavaシステムプロパティがserver.xmlの設定をオーバーライドしている可能性があります。例えば、CATALINA_OPTSやJAVA_OPTSに設定されている内容が影響することがあります。
### 4. 複数のConnector設定:

server.xmlに複数の<Connector>要素が定義されている場合、異なるポート番号でリスンしているものの設定が影響を与えることがあります。正しいConnectorに設定を適用しているか確認してください。
### 5. 他のネットワーク関連の設定:

OSやファイアウォール、ロードバランサーなどのネットワーク関連の設定がTomcatに影響を与えている可能性も考えられます。これらが原因で、期待したコネクション数が制限されることがあります。

以上を確認しても解決しない場合は、設定内容やログファイルを確認し、問題の原因をさらに調査する必要があります。
Laravel8 新規作成したプロジェクトのMySQLにログインする方法

# 前提
以下のコマンドを実行し、Laravel8のプロジェクトを作成していること
```
composer create-project laravel/laravel {プロジェクト名} "8.*" --prefer-dist
```

# MySQLのサーバー起動
```
$ sudo mysql.server start
```

# ログインコマンド実行
```
$ sudo mysql -u {ユーザ名} -h {ホスト名} -p
```
.env の初期値から特に変更していないため、ユーザ名は「root」ホスト名は「localhost」を指定
正しいパスワードを入力するとログインに成功する
```
$ sudo mysql -u root -h localhost -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.1.0 Homebrew

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

# エラーが発生した場合

- 参考
    - https://qiita.com/Yusuke_Hoirta/items/5d1157115d5c45687ce0
    - https://qiita.com/hondy12345/items/d32ed749fb49e9da7de6
pythonのloggingモジュールの設定方法まとめ(py, ini, json)

# 概要
pythonのloggingモジュールを使うと`print()`よりも詳細なログ出力ができる。
タイムスタンプを付加できたり、ログファイルを出力できたりいろいろと嬉しいことがある。
loggingの設定方法がいくつかあるのでまとめる。

# .pyファイル
loggingモジュールをインポートしてそのまま定義する方法。
エディタのコード補完が効くので個人的にはこの方法が好き。
```py
from logging import getLogger, Formatter, DEBUG
from logging.handlers import RotatingFileHandler

# フォーマット
fmt = '%(asctime)s %(name)s:%(lineno)s %(funcName)s [%(levelname)s] %(message)s'
datefmt = '%Y-%m-%d %H:%M:%S'
formatter = Formatter(fmt, datefmt)

# ハンドラ
handler = RotatingFileHandler('./log/py_logger.log', maxBytes=1000000, backupCount=3)
handler.setFormatter(formatter)

# ロガー定義
logger = getLogger(__name__)
logger.setLevel(DEBUG)
logger.addHandler(handler)
```

# .iniファイル
`logging.config.fileConfig()`を使って.iniファイルを読み込む方法。
```py
from logging import config, getLogger

config.fileConfig('./logging.ini')
logger = getLogger('ini_logger') # 適宜変更する。
```
```ini
[loggers]
keys=root,ini_logger

[handlers]
keys=fileHandler

[formatters]
keys=fileFormatter

[logger_root]
level=DEBUG
handlers=fileHandler

[logger_ini_logger]
level=DEBUG
handlers=fileHandler
qualname=ini_logger
propagate=0

[handler_fileHandler]
class=handlers.RotatingFileHandler
level=INFO
formatter=fileFormatter
args=('./log/ini_logger.log', 'a', 1000000, 3)

[formatter_fileFormatter]
format=%(asctime)s %(name)s:%(lineno)s %(funcName)s [%(levelname)s] %(message)s
datefmt=%Y-%m-%d %H:%M:%S

```

# .jsonファイル
`logging.config.dictConfig()`を使って.jsonファイルを読み込む方法。
```py
import json
from logging import config, getLogger

with open('./logging.json', 'r') as f:
    config.dictConfig(json.load(f))
logger = getLogger('json_logger') # 適宜変更する。
```
```json
{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters": {
        "fileFormatter": {
            "format": "%(asctime)s %(name)s:%(lineno)s %(funcName)s [%(levelname)s]: %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        }
    },

    "handlers": {
        "fileHandler": {
            "class": "logging.handlers.RotatingFileHandler",
            "level": "INFO",
            "formatter": "fileFormatter",
            "filename": "./log/json_logger.log",
            "maxBytes": 1000000,
            "backupCount": 3
        }
    },

    "loggers": {
        "json_logger": {
            "level": "DEBUG",
            "handlers": ["fileHandler"],
            "propagate": false
        }
    },

    "root": {
        "level": "INFO"
    }
}

```
Go言語(Golang)  Goroutine記述例


```go
package main

import "fmt"

// producer関数は、0から9までの整数をfirstチャネルに送信します
func producer(first chan int) {
	defer close(first) // 関数が終了する前にチャネルを閉じる
	for i := 0; i < 10; i++ {
		first <- i // チャネルに整数を送信
	}
}

// multi2関数は、firstチャネルから受信した整数を2倍にしてsecondチャネルに送信します
func multi2(first chan int, second chan int) {
	defer close(second) // 関数が終了する前にチャネルを閉じる
	for i := range first { // firstチャネルから値を受信し、チャネルが閉じられるまでループ
		second <- i * 2 // 受信した整数を2倍にしてsecondチャネルに送信
	}
}

// multi4関数は、secondチャネルから受信した整数を4倍にしてthirdチャネルに送信します
func multi4(second chan int, third chan int) {
	defer close(third) // 関数が終了する前にチャネルを閉じる
	for i := range second { // secondチャネルから値を受信し、チャネルが閉じられるまでループ
		third <- i * 4 // 受信した整数を4倍にしてthirdチャネルに送信
	}
}

func main() {
	// チャネルを作成
	first := make(chan int)
	second := make(chan int)
	third := make(chan int)

	// goroutineを使って非同期に関数を実行
	go producer(first)
	go multi2(first, second)
	go multi4(second, third)

	// thirdチャネルから値を受信し、チャネルが閉じられるまでループして結果を表示
	for result := range third {
		fmt.Println(result) // thirdチャネルから受信した値を表示
	}
}
```

### 解説

1. **パッケージ宣言**:
   ```go
   package main
   ```
   - `main`パッケージは、Goプログラムのエントリーポイントです。

2. **インポート宣言**:
   ```go
   import "fmt"
   ```
   - 標準ライブラリの`fmt`パッケージをインポートします。これを使用してコンソールに出力します。

3. **producer関数**:
   ```go
   func producer(first chan int) {
       defer close(first)
       for i := 0; i < 10; i++ {
           first <- i
       }
   }
   ```
   - `first`チャネルに0から9までの整数を送信する関数です。
   - `defer close(first)`は、関数が終了する直前に`first`チャネルを閉じることを保証します。
   - `first <- i`は`i`の値を`first`チャネルに送信します。

4. **multi2関数**:
   ```go
   func multi2(first chan int, second chan int) {
       defer close(second)
       for i := range first {
           second <- i * 2
       }
   }
   ```
   - `first`チャネルから受信した値を2倍にして`second`チャネルに送信する関数です。
   - `for i := range first`は、`first`チャネルが閉じられるまで値を受信し続けます。

5. **multi4関数**:
   ```go
   func multi4(second chan int, third chan int) {
       defer close(third)
       for i := range second {
           third <- i * 4
       }
   }
   ```
   - `second`チャネルから受信した値を4倍にして`third`チャネルに送信する関数です。
   - `for i := range second`は、`second`チャネルが閉じられるまで値を受信し続けます。

6. **main関数**:
   ```go
   func main() {
       first := make(chan int)
       second := make(chan int)
       third := make(chan int)

       go producer(first)
       go multi2(first, second)
       go multi4(second, third)

       for result := range third {
           fmt.Println(result)
       }
   }
   ```
   - `main`関数はプログラムのエントリーポイントです。
   - `make(chan int)`でチャネルを作成します。
   - `go`キーワードを用いて、goroutineとして`producer`、`multi2`、`multi4`関数を非同期に実行します。
   - `for result := range third`で`third`チャネルから値を受信し、チャネルが閉じられるまで値を表示し続けます。

このコードは、複数のgoroutineとチャネルを使用してデータをパイプライン処理する例です。それぞれのステージ（`producer`、`multi2`、`multi4`）は独立して動作し、チャネルを介してデータを受け渡します。
AWSのLambdaとAPI Gatewayでプロキシ統合てhtmlを表示しようとしたら文字化けした

AWSでLambdaとAPI GatewayのRest APIを用いてサーバーレスでWebサイトを作ろうとしたところ、日本語のhtmlを表示しようとしたときに文字化けしてしまった。
このとき、API Gatewayの設定でLambdaのプロキシ統合は有効にしていて、Lambdaのソースコードはざっくりとは下記の通り。
```python
def lambda_handler(event, context):
    html = """\
<h1>日本語を含むhtml</h1>
<p>あいうえおかきくけこ</p>
"""
    return {
        "statusCode": 200,
        "headers": {
            "Content-Type": "text/html"
        },
        "body": html
    }
```
調べてみると、プロキシ統合を有効にしない場合ではAPI Gatewayの設定で「Content-Typeをapplication/json;charset=UTF-8にする」ことにより日本語が使えるようになるらしいので、これに習い、プロキシ統合は有効のままでソースコードを下記のように修正した。
```python
def lambda_handler(event, context):
    html = """\
<h1>日本語を含むhtml</h1>
<p>あいうえおかきくけこ</p>
"""
    return {
        "statusCode": 200,
        "headers": {
            "Content-Type": "text/html; charset=UTF-8"
        },
        "body": html
    }
```
`text/html`の後に`charset=UTF-8`を追加した。これで再度確認したところ、無事日本語を文字化け無しで表示することができた。
教師なし学習の実践

# 教師なし学習とは
回帰や分類問題における学習は説明変数と目的変数のデータの組が与えられており、このような学習方法を**教師あり学習**といいます。しかし、すべてのデータに目的変数のデータが与えられているわけではなく、そのような場合には**教師なし学習**を行います。

ここでは、教師なし学習の中のアルゴリズムとして**主成分分析**を扱ってみましょう！

# 主成分分析
主成分分析は、データの多数ある特徴の中から重要な特徴を取り出す手法です。(数学的な言葉を使えば、特徴量ベクトルの変換を行ったときに、そのノルムが最も大きくなるような基底を探すということで、固有空間への射影を行なったのちに次元圧縮をすることに対応します。)

Irisのデータセットを用いて実際に主成分分析してみます。
まず、pythonを用いてデータセットの中身を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675830/b4118801-7356-3ff0-af74-5a91da1c92f3.png)

因みに、Irisとは「あやめの花」のことです。本データセットは以下の特徴量で構成されています。
　・sepal length：がく片の長さ
　・sepal width：がく片の幅
　・petal length：花弁の長さ
　・petal width：花弁の幅

最終列のlabelは教師ラベル（あやめの種類）のことで0,1,2のいずれかの値となります。

４次元の特徴量を、主成分分析によって２次元に圧縮してみます。
以下の図がその結果です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675830/e543c23f-44d0-bc98-6432-efdc55ee7898.png)

色が同じデータは同じ種類のあやめであることを示しています。
横軸が第1主成分、縦軸が第2主成分となっており、軸ラベルの括弧の中の数字は、その主成分がどれだけデータの特徴を表しているかを示す割合です(寄与率といいます)。このことから、あやめのデータは2つの主成分で 95パーセント以上の特徴を表せていることがわかります。また、同じ種類のあやめは、グラフ上で似た座標に集まっていることも確認できることから、「2つの主成分によって、あやめの種類は概ね推定できる」ということがわかります。

以上より、主成分分析は煩雑な多次元データから、データの特徴を表す本質を抽出することができるアルゴリズムだということがわかりました！

# 主成分分析の理論
主成分分析とは、
あるデータの行列$X$が与えられたとき、
$||X\phi_{1}||$を最大にする$\phi_{1}\in R^{N}$、
$\phi_{1}\$と直交して$||X\phi_{2}||$を最大にする$\phi_{2}\in R^{N}$、
・・・、
$\phi_{p}\$と直交して$||X\phi_{p}||$を最大にする$\phi_{p}\in R^{N}$を求める操作です。

ここで、$||X\phi_{i}||=1$と仮定しておきます。

まず、$\phi_{1}\$に対する最適化問題は、以下のように表されます。

```math

\max ||X\phi_{1}||^2 \qquad subject \, to \quad ||\phi_{1}||=1
```

上記の式をラグランジュの未定定数法で解くと　

```math
(X^T X)\phi_{1} = \gamma_1 \phi_{1}
```

という式が得られます。これは、$X^T X$の固有ベクトルが$\phi_{1}$であることを表しています。そして、対応する固有値$\gamma_1$は、最適化問題の解となります。
つまり、$\phi_{1}$が第１主成分です。

次に、$\phi_{2}\$に対する最適化問題は、以下のように表されます。

```math
\displaylines{

\max ||X\phi_{2}||^2  \\
\qquad subject \, to \quad ||\phi_{2}||=1 \quad , \quad \phi_{1}^T \phi_{2} =0

}
```

この問題に対しても、ラグランジュの未定条数法を適用し、

```math
(X^T X)\phi_{2} = \gamma_2 \phi_{2}
```

が求まります。また、$X^T X$が対称行列なので、その固有ベクトルである$\phi_{1}$、$\phi_{2}$は直交します。従って$\phi_{2}$が第2主成分です。

これを一般の$i=1,2,...,p$に適応すれば、第$p$主成分までが求まります。

# 確率分布から見る話
主成分分析を、確率分布から生成されるアルゴリズムとみると、
これは、潜在変数がガウス分布に従う行列分解モデルの最尤推定結果としてみることもできます。このように主成分分析をみると、モデルに沿ったデータ生成を行えるようになります。次回はこの辺りの話（確率的主成分分析）をしてみようかなと思います。
EC2インスタンスへのSSH接続手順

## アジェンダ
このガイドでは、AWS EC2インスタンスにSSH接続する手順をまとめています。VPC作成、サブネット設定、インターネットゲートウェイのアタッチなど、事前準備について簡単にまとめます。

## 手順

### 1. VPCの作成
- AWSコンソールからVPCサービスを選択し、「VPCを作成」をクリック。
- 名前を指定し、IPv4 CIDRブロック（例: `10.0.0.0/16`）を入力してVPCを作成。

### 2. サブネットの作成
- 作成したVPCの中でサブネットを設定します。
- 「サブネットを作成」をクリックし、サブネット名、VPC、アベイラビリティゾーン、IPv4 CIDRブロック（例: `10.0.1.0/24`）を指定。

### 3. インターネットゲートウェイの作成とアタッチ
- インターネットゲートウェイを作成して、VPCにアタッチします。
- サブネットのルートテーブルに0.0.0.0/0 → インターネットゲートウェイのルートを追加し、インターネットアクセスを許可。

### 4. EC2インスタンスの作成
- 作成したVPCとサブネットを選択し、EC2インスタンスを起動。
- セキュリティグループでポート22（SSH）を許可。必要に応じて、ポート80（HTTP）も開放。
- 起動後にインスタンスへパブリックIPが割り当てられます。

### 5. SSH接続の設定
- ローカルで、インスタンス作成時にダウンロードしたキーペア（`.pem`ファイル）を使用してSSH接続します。
```bash
ssh -i "your-key.pem" ec2-user@your-ec2-public-ip
```

例: キーペアが`test-key.pem`、パブリックIPが`13.235.246.234`の場合:
```bash
ssh -i "test-key.pem" ubuntu@13.235.246.234
```

## 参考
- [パブリックなIPアドレスを経由してEC2インスタンスへSSH接続するポイントをまとめてみた | DevelopersIO](https://dev.classmethod.jp/articles/ssh-connection-is-available/)
- [AWS EC2 Nginxを使ってWebサイトホスティング](https://zenn.dev/nakam_aws/articles/1ccd870200ff59)
【エラー対処】Homebrewインストール時の Warning: /opt/homebrew/bin is not in your PATH.

## 「パスが通っていないよ」と言われる
[Homebrew公式サイト](https://brew.sh/ja/)からインストールコマンドをコピーし、ターミナル上でペースト＆実行してみたところ、以下のようなメッセージが。
```terminal
Warning: /opt/homebrew/bin is not in your PATH.
  Instructions on how to configure your shell for Homebrew
  can be found in the 'Next steps' section below.
==> Installation successful!
```
インストール自体は成功したようですが、「パスが通っていないよ」とWarningが出ています。
```terminal
$ brew -v
zsh: command not found: brew
```
当然、brewコマンドは使えません。

## 解決方法
① .zshrcを開く（bashの場合は.bashrc）
```terminal
$ vi ~/.zshrc
```
② 開いたファイルに以下のコードを追加・保存して閉じる
```vim
export PATH=/opt/homebrew/bin:$PATH
```
③ 設定を反映する
```terminal
$ source ~/.zshrc
```

## 確認
これでパスを通すことができたので、再度バージョン確認のコマンドをたたいてみます。
```terminal
$ brew -v
Homebrew 4.3.18
```
無事、brewコマンドが使えるようになりました。
Azure OpenAI Serviceで PTU がデプロイできるようになっている件について

# Azure OpenAI Service の PTU って？

PTUを使用すると自分だけのGPUを予約すること処理能力やパフォーマンスを安定化させることができます。

https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/provisioned-throughput

# PTU の何ができるようになったの？

これまでは Microsoft の営業さんに使いたいよー！と伝えて承認を得られてからでないと使えなかったのですが、誰でも使えるようになりました！

https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/provisioned-migration

# 驚くべき金額

誰でもデプロイできるようになったものの、恐ろしい金額がかかるようです。
デプロイする際は計画的にしないと痛い目にあいそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232184/dc413089-c7d0-0e8e-2d5e-49129d33fc04.png)

# 意図するデプロイを防ぐには?

デプロイの種類を Provisioned managed の場合デプロイをできなくするような、Azure Policy のルールを設定できるようです。
Microsoftのサポートチームのブログで紹介されてましたー。

https://jpaiblog.github.io/blog/2024/08/29/AzureOpenAIService-Provisioned-Deployment/
【Shell】変数が空または未定義の場合のデフォルト値を設定する方法

`:-`を使用して空文字か未定義の場合のデフォルト値を設定できます。

```zsh
hoge=Hello
foo=""

echo ${hoge:-exist}
# Hello
echo ${foo:-empty}
# empty
echo ${bar:-undefined}
# undefined
```

変数が定義されていない場合のみデフォルト値とする場合には`-`を使用します。

```zsh
hoge=Hello
foo=""

echo ${hoge-exist}
# Hello
echo ${foo-empty}
#
echo ${bar-undefined}
# undefined
```
Typescript - Type error: No Index Signature with a Parameter of Type String の対処法

# エラーの再現例
以下のコードは、UserEntryインターフェースを使用して、ユーザーエントリーの必須フィールドがすべて存在するかどうかをチェックしようとしています。しかし、TypeScriptはエラーを投げます。
```typescript:example.ts
interface UserEntry {
  id: number;
  name: string;
  sex: "male" | "female";
}

const entry: UserEntry = {
  id: 1,
  name: "太郎",
  sex: "male"
}

const errors: string[] = [];
const requiredFields = [
  "id",
  "name",
  "sex"
];

requiredFields.forEach(field) => {
  if (!entry[field]) {  // エラー: 型 'UserEntry' には文字列インデックス シグネチャがありません
    console.log(`Missing value for ${field}.`)
  }
});
```
# なぜエラーが発生するのか？
entry[field]のように動的にオブジェクトのプロパティにアクセスしようとする場合、TypeScriptはそのオブジェクトの型定義に文字列インデックスシグネチャがないとエラーを発生させます。UserEntryインターフェースは静的に定義されているため、動的な文字列キーでアクセスできないのです。

# 解決方法①：keyof UserEntry
このエラーを解決するために、requiredFields配列の型を正確に指定する必要があります。keyof型演算子を使用して、UserEntryのキーを型として指定することで、TypeScriptに対して安全なアクセスを保証します。
```diff_typescript:example.ts
interface UserEntry {
  id: number;
  name: string;
  sex: "male" | "female";
}

const entry: UserEntry = {
  id: 1,
  name: "太郎",
  sex: "male"
}

const errors: string[] = [];
- const requiredFields = [
+ const requiredFields: (keyof UserEntry)[] = [
  "id",
  "name",
  "sex"
];

requiredFields.forEach(field) => {
  if (!entry[field]) {
    console.log(`Missing value for ${field}.`)
  }
});
```
keyof UserEntryは、"id" | "name" | "sex"のユニオン型を生成します。これにより、requiredFields配列の各要素がUserEntryのキーであることが保証され、entry[field]のような動的アクセスが安全になります。

# 解決方法②：as const
credit to: @sugoroku_y さん
as const は、TypeScript において、コンパイラに requiredFields 配列を変更不可の定数値として扱うように指示する型アサーションです。これにより、配列内の各要素はリテラル型として扱われ、より一般的な string 型ではなくなります。

```diff_typescript:example.ts
interface UserEntry {
  id: number;
  name: string;
  sex: "male" | "female";
}

const entry: UserEntry = {
  id: 1,
  name: "太郎",
  sex: "male"
}

const errors: string[] = [];
const requiredFields = [
  "id",
  "name",
  "sex"
- ];
+ ] as const;

requiredFields.forEach(field) => {
  if (!entry[field]) {
    console.log(`Missing value for ${field}.`)
  }
});
```

### 1. as const なし：
```typescript
const requiredFields = ["id", "name", "sex"]; // 推論される型は string[]
```
もし requiredFields が単なる string[] の場合、TypeScript はエラーを出します。なぜなら、field が entry に実際に存在するキーであることを保証できないからです。

### 2. as const あり：
```typescript
const requiredFields = ["id", "name", "sex"] as const; // 推論される型は readonly ["id", "name", "sex"]
```


しかし、as const を使うと、TypeScript は field が必ず entry に存在するキーの1つ（"id"、"name"、"sex" のいずれか）であることを認識します。このため、as const を使用すると型エラーを回避し、安全にインデックスアクセスができるようになります。

# まとめ
TypeScriptでは、動的にオブジェクトのプロパティにアクセスする場合、型の安全性を確保するためにkeyofやインデックスシグネチャを適切に使用することが重要です。このアプローチにより、エラーを防ぎつつ、堅牢でメンテナンス性の高いコードを書くことができます。

as const を使うことで配列がリテラル型を持つタプルとして扱われ、entry に安全にインデックスアクセスできるため、型エラーを防ぐことができるということです。
SPF / DKIM / DMARC について

# はじめに
メール機能を実装するに当たって調べたことを学びにするために記事にしました。
不足な点や誤りがありましたら教えていただけますと幸いです。

# SPF / DKIM / DMARC とは
SPF、DKIM、DMARCは、メール送信時にドメインの正当性を確認し、不正なメールの拡散を防ぐ技術です。

# SPF / DKIM / DMARCは2024年2月から対応必須に
1日あたりGmailアカウントにメールを5000件以上送る場合になりますが
Googleの[メール送信者のガイドライン](https://support.google.com/a/answer/81126?sjid=4068263634946002854-AP&visit_id=638608821577899881-602638179&rd=1)が更新され、SPF / DKIM / DMARC のそれぞれを認証設定する必要がある旨が記載されています。
これまでSPF / DKIM だけでしたが2024年2月から新たに DMARC も必須設定となりました。


## SPF（Sender Policy Framework）

![how-spf-works.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/3764c31c-0c2e-cbf8-bd0b-f0ef25a5699f.jpeg)
[引用元](https://lolipop.jp/media/what-is-an-spf-record/)

#### 説明
SPFは、送信元のIPアドレスがそのドメインのメールを送信する権限があるかどうかを確認する仕組みです。送信者のドメインのDNSに設定されることで、受信側はこのドメインの許可されたメールサーバーを確認できます。

#### 設定方法
1. ドメインのDNS設定画面にアクセス
2. TXTレコードを追加
3. レコードにSPFポリシーを記述（例: v=spf1 ip4:192.0.2.0/24 -all）
4. 設定を保存し、DNSの反映を待つ

## DKIM（DomainKeys Identified Mail）

![eyecatch-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/575175dd-e1bc-832c-abfe-c24516a18d42.png)
[引用元](https://sendgrid.kke.co.jp/blog/?p=2044)

#### 説明
DKIMは、送信ドメインに公開鍵を使用してメールに署名し、受信側でその署名を検証することによりメールの改ざんを防ぎます。

#### 設定方法
1. メールサーバーでDKIMをサポートしていることを確認
2. 公開鍵を生成し、ドメインのDNSにTXTレコードとして設定
3. メールヘッダにDKIM署名を追加するようメールサーバーを設定

## DMARC（Domain-based Message Authentication, Reporting & Conformance）

![DMARC-1024x570.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/a0df3bf9-7ab2-60d4-2d9b-7188b5bcb2bf.png)
[引用元](https://baremail.jp/blog/2022/05/09/2490/)

#### 説明
DMARCは、SPFやDKIMを組み合わせて、メールの送信元を検証し、ポリシーに基づいて受信するメールの処理を決定します。さらに、送信メールの検証結果に関するレポートをドメイン管理者に提供します。

#### 設定方法
1. ドメインのDNS設定画面にアクセス
2. TXTレコードを追加
3. レコードにDMARCポリシーを記述（例: v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com）
4. DMARCポリシーを適用して、報告メールアドレスを設定
M1macにVirtualBoxをインストールしたいです

### 結論
1. FinderのApplicationsタブからターミナルアプリを右クリックしGetInfoをクリック

2. Generalからopen rosettaのチェックマークをつける
2. 以下をターミナルから実行
```
brew install --cask virtualbox
```


### 私が詰まったところから解決まで
私はターミナルからHomebrewでインストールしました
```
brew install --cask virtualbox
```

ですがここでエラー。エラー内容を確認するとarchitectureが違うらしいです。

![Screenshot 2024-09-02 at 22.32.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876433/b11453e4-bb6d-d73c-1a91-e34e026a8119.png)

現在のアーキテクチャはarm。
エラー文見る感じVirtualBoxをインストールするにはintelである必要がありそうです
```
uname -m  // arm64
```

ここで神資料発見
rosettaを使用してターミナルを開くとアーキテクチャがintelのものになるらしいです
```
uname -m  // x86_64
```
こうなればインストールが成功します。
```
brew install --cask virtualbox
```

### rosettaとは
>Rosettaとは特定のアーキテクチャのプログラムコードを持つバイナリを、別のアーキテクチャに適宜変換することでバイナリの互換性を維持するAppleの技術。

Rosettaを使えば、Apple シリコンを搭載した Mac でも、Intel プロセッサ搭載 Mac 用に開発されたアプリを使えるようになるらしいです

#### 追記

インストールはできましたがkali linuxの構築もアーキテクチャ関連で無理そうだったので諦めてUTMにて構築しました
個人開発を振り返るよ (まとめ)

# はじめに
この記事では、私が個人開発した「Digital Time Capsule」というWebアプリケーションについて紹介します。このアプリケーションは、ユーザーが将来の自分にメッセージを残すことができるサービスです。  
転職に失敗して時間が有り余っていたので、勉強を兼ねて作ってみました。なのでこれはポートフォリオ用にモダンな技術を使ってWebアプリを作りたかっただけのプロジェクトです。転職できたらサ終すると思います。無料プランでずっと動かしていたら申し訳ないので。

https://digitaltimecapsule-webapp.vercel.app/

![chrome-capture-2024-9-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876441/e4d5a1dd-a5ab-cd10-6c17-ceb8827c74e3.gif)


## 使用技術と選定基準

### フロントエンドフレームワーク: Next.js 14 (App Router)
Next.js 14のApp Routerを使用しました。モダンなフレームワークで、特にコード分割やサーバーサイドレンダリング（SSR）が簡単に実装できることが魅力でした。

### 認証: NextAuth
認証にはNextAuthを選びました。NextAuthは複数の認証プロバイダー(GoogleとかGithubとかとか)を簡単に統合できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3876441/90f8ea36-8bd3-2563-6978-17a2a7a9e28f.png)


### データベース: Supabase
データベースにはSupabaseを使用しました。無料プランがあるため、開発初期の段階でコストを抑えつつ、PostgreSQLベースのデータベースを利用できる点が良いと思いました。ただし、Supabaseの無料プランは1週間しか持たないため、長期的な運用には不向きです。

### ORM: Prisma
Prismaは、データベースとのやり取りを簡単にし、型安全なクエリを実現するために選びました。モダンな開発環境において、データベース操作をより直感的に行える点が大きな魅力です。

### ホスティング: Vercel
ホスティングにはVercelを採用しました。VercelはNext.jsの開発元であり、無料プランでもシームレスなデプロイメントを提供してくれます。しかし、Vercelのクーロンジョブ（VercelJob）は無料プランだと1日1回しか動かせない制約があり、これに気づかず設定していた際に、デプロイエラーに悩まされました。また、vercel.jsonで1日に2回以上のCron設定を行ったために、Vercelのデプロイエラーの前にGitHubのCDで止まることがあり、かなり時間を無駄にしました。😢

### UI: chadcn/ui & TailwindCSS
UIにはchadcn/uiを使用し、スタイリングにはTailwindCSSを採用しました。これらの技術はモダンであり、無料で利用できることから選定しました。シンプルでレスポンシブなデザインを効率的に作成できるため、開発速度が向上しました。

### AI: Claude 3.5(Artifacts) ChatGPT-4o
フロントのデザイン周りはClaudeくんで作成しました。
バグ修正や分からないことはCursorエディタにChatGPT-4oのAPIを5ドル分買って余ってたので使いました。

## おわりに
「Digital Time Capsule」Webアプリケーションの開発は、最新のモダンな技術を組み合わせで、いい勉強になりました。これらの技術選定は、無料プランがあることを基準に行いましたが、SupabaseやVercelの制約により、長期的な運用においては課題が残ることが分かりました。特に、VercelのクーロンジョブやSupabaseの無料期間については、今後のプロジェクトでの注意点として記憶に残りそうです。

質問やフィードバックがありましたら、ぜひコメントでお知らせください！

あと雇っていただける方いませんか。。。🙇
スキルシートです。。
https://taterunakayama.github.io/skill-sheet/

https://github.com/TateruNakayama
https://x.com/nakayamaaa011
SIGSEGV

iOSアプリの開発をしていると、クラッシュしたときにを見かけます。これはどういう意味なのでしょうか？

# SIGSEGVとは

**SIGSEGV**（"Segmentation Violation"の略）は、アプリが不正なメモリアクセスを行ったときにオペレーティングシステムから送られるシグナルです。具体的には、アプリがアクセスしてはいけないメモリ領域にアクセスしようとした場合に発生します。例えば、NULLポインタの参照や、メモリが確保されていない領域に書き込みを行おうとしたときです。このようなエラーが発生したときにクラッシュさせないと、システム全体の安定性が脅かされ、さらに深刻な問題（例えばデータの破壊やセキュリティの脆弱性）が引き起こされる可能性があります。そこでシステムはアプリを即座に停止させて、システムの健全性を維持しようとします。

iOSアプリの開発中に見かける似たようなエラーのキーワードとして、EXE_BAD_ACCESSやKERN_INVALID_ADDRESS、SIGNAL 11やSegmentation Fault: 11があります。EXE_BAD_ACCESSは、メモリアクセスが許可されていない場所に行われたことを示します。KERN_INVALID_ADDRESSは、カーネル（オペレーティングシステムの核心部分）から発生するエラーで、無効なアドレスにアクセスしようとした際に返されます。SIGNAL 11は、Unix系システムにおけるシグナル番号11を示します。この番号は「Segmentation Fault」を意味し、プログラムが無効なメモリアクセスを行ったことを知らせます。たとえば、NULLポインタの参照、未初期化のポインタの使用、メモリの範囲外へのアクセスなどが原因となります。いずれもSIGSEGVと同様に、メモリ管理の問題に関連しています。

SIGSEGVが不正なメモリアクセスを示すのに対して、SIGABRT（"Abort"の略）は、アプリが異常な状態に陥った場合に自身で停止を要求するシグナルです。通常、SIGABRTはアプリ内で意図的に呼び出されることはなく、標準ライブラリのアサート関数によってエラーが検出された場合などに発生します。SIGABRTが発生すると、通常はコアダンプ（メモリの内容をファイルに保存）が生成され、デバッグに役立ちます。

アプリがクラッシュした場合、エラーログ（クラッシュログ）は問題の原因を特定するための重要な手がかりを提供します。ログは通常、デバイスのシステムログに保存されます。iOSの場合、これらのログは「Console」アプリやXcodeを使用して確認することができます。ログには、クラッシュが発生したスレッド、クラッシュした関数やファイルの行番号、スタックトレースなどの情報が含まれています。これらの情報を解析することで、どのコードが問題を引き起こしたかを突き止めることができます。

# シンボリケーション
iOSアプリをFlutterで開発している場合、クラッシュが起きたときにスタックトレースの一部が「???」となっていることがあります。これはシンボル情報が欠けているためです。

シンボリケーションとは、クラッシュログのメモリアドレスを人間が読める形式、つまりシンボル（関数名やファイル名、行番号）に変換するプロセスです。デバッグシンボルが含まれていないビルド（例えば、リリースビルド）ではこの情報が欠落しているため、シンボリケーションが不可能となり、アドレスが「???」として表示されることになります。シンボリケーションは、クラッシュの原因を特定するために不可欠です。

ちなみに、アドレスが0xで始まる理由は、16進数で表現されているからです。0xは16進数を示すプレフィックスで、メモリのアドレスを効率的に表現するために使用されて。
Go言語(Golang) Goroutine記述例

```go
package main

import (
	"fmt"
	"sync"
)

// producer関数は整数チャンネルに整数を送信します。
func producer(ch chan int, i int) {
    // チャンネルにi * 2を送信
	ch <- i * 2
}

// consumer関数はチャンネルから受信した整数を処理し、WaitGroupのDoneメソッドを呼び出してカウントを減らします。
func consumer(ch chan int, wg *sync.WaitGroup) {
    // チャンネルから受信した整数を処理
	for i := range ch {
		fmt.Println("process", i*1000)
		wg.Done()
	}
}

func main() {
	// WaitGroupを初期化
	var wg sync.WaitGroup
    // 整数チャンネルを作成
	ch := make(chan int)

	// 10個のプロデューサーゴルーチンを起動
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go producer(ch, i)
	}

    // コンシューマーゴルーチンを起動
	go consumer(ch, &wg)
    // すべてのプロデューサーが終了するまで待機
	wg.Wait()
    // チャンネルを閉じる
	close(ch)
}
```


### プログラムの流れ

1. **WaitGroupの初期化**
   ```go
   var wg sync.WaitGroup
   ```
   `sync.WaitGroup`を使って、複数のゴルーチンの終了を待つためのカウンタを作成します。

2. **チャンネルの作成**
   ```go
   ch := make(chan int)
   ```
   整数を送受信するためのチャンネルを作成します。

3. **プロデューサーゴルーチンの起動**
   ```go
   for i := 0; i < 10; i++ {
       wg.Add(1)
       go producer(ch, i)
   }
   ```
   10個のプロデューサーゴルーチンを起動します。各ゴルーチンは`producer`関数を実行し、`i * 2`の値をチャンネルに送信します。

4. **コンシューマーゴルーチンの起動**
   ```go
   go consumer(ch, &wg)
   ```
   1つのコンシューマーゴルーチンを起動します。`consumer`関数はチャンネルから整数を受信し、それを処理します。

5. **プロデューサーの終了待機**
   ```go
   wg.Wait()
   ```
   すべてのプロデューサーゴルーチンが終了するのを待ちます。

6. **チャンネルのクローズ**
   ```go
   close(ch)
   ```
   チャンネルを閉じます。これにより、`consumer`関数の`range`ループが終了します。

### 出力の詳細

各プロデューサーゴルーチンは、以下のように`i * 2`の値をチャンネルに送信します：

- `i = 0`の場合、送信値は`0 * 2 = 0`
- `i = 1`の場合、送信値は`1 * 2 = 2`
- `i = 2`の場合、送信値は`2 * 2 = 4`
- `...`
- `i = 9`の場合、送信値は`9 * 2 = 18`

コンシューマーゴルーチンは、これらの値を受信し、`i * 1000`を計算して表示します。したがって、出力は以下のようになります：

- `0 * 1000 = 0`
- `2 * 1000 = 2000`
- `4 * 1000 = 4000`
- `...`
- `18 * 1000 = 18000`

出力順はゴルーチンの実行順によるため、必ずしも順番通り（0, 2, 4, ... 18）にはなりませんが、出力される値は以下となる。

```plaintext
process 0
process 2000
process 4000
process 6000
process 8000
process 10000
process 12000
process 14000
process 16000
process 18000
```

### 注意点

- プログラムは、プロデューサーが`ch`に値を送信した後すぐに`Done`を呼び出しているため、`wg.Wait`が終了した時点で`ch`にまだ値が残っている可能性があり、`close(ch)`が早すぎる問題があります。
- `consumer`側で`wg.Done`を呼び出すべきでなく、プロデューサー側で呼び出すべきです。また、`ch`を閉じるタイミングも見直す必要があります。
Jenkinsでbash: ./download.sh: 許可がありませんというエラーが出てビルド失敗した

# はじめに
業務でJenkinsを使用してCI/CDの管理を行っているのですが、たまに遭遇するエラーで詰まったため備忘メモとして残します。

# どんなとき
Jenkinsサーバーでビルド実行を行った際

# どんなエラーが出たのか
```
bash: ./download.sh: 許可がありません
```
許可が無い=権限だなと思いJenkinsサーバーに入ってファイルの権限を確認。
すると、実行権限が無かったので、```chmod```コマンドを実行してdownload.shの実行権限を付与しました。
いつもはこの対応で解消していたのですが、今回は再度ビルドを実行しても変化せずでした。

# 解決方法

以下のコマンドを実行し、commit＆pushすることで権限を変えることができ、無事ビルドが通るようになりました。

```
git update-index --add --chmod=+x download.sh
```

## 原因
ビルド実行時にgitを使用して指定したブランチの最新のソースをクローンし、設定したコマンドを実行させていたのですが、
push元の自分の環境のdownload.shを確認したところ、ファイルの所有者にしか実行権限が無いように設定されており、その権限状態のソースを毎回クローンして持ってきていたために当該エラーが出てしまっていました。

最初にリポジトリを作成した際に権限が不十分な状態でgitに上げてしまったために、後で困ることになりました。
今後は注意したいと思います。

# さいごに
同じようなエラーが出て困っている人の参考になれば幸いです。

# 参考

https://qiita.com/satotka/items/29f1483f8921d2ecfeab
データを活用して健康とウェルネスの旅を最適化する

現代のデジタル時代において、テクノロジーは個人の健康、[栄養](https://forums.botanicalgarden.ubc.ca/proxy.php?link=https://greycicada.com/category/nutrition/)、そして[フィットネス](https://left.engr.usu.edu/chanview?f=&url=https://greycicada.com/category/fitness/)において重要な役割を果たしています。ワークアウトの追跡、食事のモニタリング、またはウェルネスに対する気配り、データはあなたの最良の味方となります。ここでは、テクノロジーを活用して健康の旅を向上させる方法を紹介します。

### **1. アプリを使った栄養摂取の追跡**

健康と栄養のアプリの台頭により、食べ物の追跡がこれまで以上に簡単になりました。Apps like MyFitnessPalやCronometerなどのアプリは、1日のカロリー摂取量、マクロ栄養素の分布、さらには微量栄養素のレベルまで詳細な洞察を提供します。これらのツールは食習慣を理解し、健康目標を達成するために調整するのに役立ちます。

### **2. フィットネスモニタリングのためのウェアラブルテクノロジー**

Fitbit、Garmin、Appleなどの有力ブランドのデバイスを含むウェアラブルテクノロジーは、フィットネスのアプローチ方法を革新しました。これらのデバイスは歩数だけでなく、心拍数、睡眠パターン、ストレスレベルまでモニタリングします。このデータを分析することで、ワークアウトや回復期間を微調整し、パフォーマンスを向上させることができます。

### **3. AIと機械学習を活用した個別化された健康推奨**

AIと機械学習は個別化された健康ケアの最前線にあります。Platforms like [Persona Nutrition](https://imodules.uwaterloo.ca/controls/login/sts.ashx?gid=2&returnUrl=https://greycicada.com/why-persona-vitamins-are-tailored-just-for-you/) は、健康データとライフスタイルの選択を分析し、あなたの特定のニーズに合わせた個別化されたビタミンパックを提供します。これにより、サプリメントの選択の推測作業が省かれ、体が必要とするものを正確に摂取できます。

### **4. テクノロジーとウェルネスの統合：マインドフルネスと瞑想アプリ**

精神的なウェルビーイングは身体的健康と同じくらい重要です。HeadspaceやCalmなどのアプリは、テクノロジーを活用してユーザーを瞑想とマインドフルネスの演習を導きます。これらのアプリはストレスを軽減し、集中力を高め、全体的な精神的な健康を促進します。これらを日常生活に取り入れることで、バランスの取れたウェルネスアプローチを築くことができます。

### **5. データ駆動のフィットネス意思決定**

フィットネス愛好家にとって、データは改善の鍵です。StravaやTrainingPeaksなどのプラットフォームは、ワークアウトに関する詳細な分析を提供します。これらのツールを活用することで、強み、弱み、改善の余地を特定し、最適な結果を得るためにトレーニング計画を調整することができます。マラソンのトレーニングをしているか、単に体調を整えているかに関わらず、このデータを活用することが重要です。

## **結論**

テクノロジーを取り入れて健康とウェルネスの旅を向上させることは、前例のない利点を提供します。栄養摂取の追跡、フィットネスモニタリングのウェアラブルテクノロジーの活用、AIによる個別化された健康推奨の受け取り、そして精神的ウェルビーイングのためのマインドフルネスアプリの統合を通じて、データ駆動のアプローチはあなたに情報を提供し、的確な決定を支援します。今日利用可能なデジタルツールを活用して、健康の改善に取り組んでください。
DMARC「p=reject」 設定後の変化

# はじめに

**DMARCポリシーをp=rejectに変更**しました。DMARCに取り組もうとしたきっかけや、取組の経緯は、以下のブログに書いてます。

https://qiita.com/akihiro_suto/items/8f65b36c83a754f88578

# DMARCとは

そもそもDMARCとはって話はいろいろな人がいろいろな記事をあげてくれているので割愛します。このへんの記事や、Youtubeがわかりやすいです。

https://www.proofpoint.com/jp/threat-reference/dmarc

https://youtu.be/Agh8mxfEJYk?si=eomVvM5JWXbED-uJ

# DMARC「p=reject」設定後の変化

DMARCは認証されていないor認証が不十分なメールを受信側のメールサーバーで検疫or削除してもらうことができる設定です。ポリシーをquarantine （検疫）以上にしておけば、非正規なメールが送信先ユーザーのメールボックスに届きにくくなります。

弊テナントではDMARCポリシーを設定する前は、弊社ドメインになりすましたと思われるメールが **1日10,000通前後** 送信されていることが観測されていました。

**それが、DMARCポリシーをp=quarantine以上に設定1週間ほど経つと、なんと、なりすましメールそのものが劇的になくなったのです。（図を参照）**

この図でいうと、8/8以降ですね。不審なメール送信そのものがすくなく、棒グラフがほとんどなくなっていることがわかります。

![画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/70f29a02-1b8e-631d-d07c-500b488e14cd.jpeg)

DMARCのポリシーが設定されているため、不審なメールが送信されたとしても、ユーザーに届きにくくなっているのですが、DNSレコードにDMARCポリシーが入っていることを確認した攻撃者が、おそらくIPレピュテーションの低下を恐れて、弊社ドメインをなりすましメールに使うことをやめてくれたようで、1日に100通もないくらいまで減りました。

https://sendgrid.kke.co.jp/blog/?p=2115

# メールは攻撃の起点になっている

インシデントの多くがメール起点とよく耳にします。DMARCを設定するだけで、自社ドメインになりすましたメール送信がこんなにも減るならば、社会貢献という意味でも、必須の取り組みだなと感じます。

# 目に見える取り組みだから楽しいよ😇

DMARCは解析ツールを導入していれば、常に可視化レポートを見ながら、正規なメールなのに認証がされていないと思われるメールを探し、業務部門と連携しSPFやDKIMを設定していく。数日後にレポートを見ると、不審なメールが少し減ってる。その繰り返しです。情シスのお仕事で、目に見えて成果が出ていく仕事って少ない気がしており、振り返ってみれば楽しい仕事でした。

# まとめ

まだ、DMARCに取り組めていない人、ポリシーをnoneにしたけどその先何もしていない組織は、ぜひ前向きに取り組んでほしーな！
【備忘録】TPlinkを使用していて "L2TP/IPsec VPN" に繋げなかった

TPlink v6プラスやDS-Liteで接続時はVPNパススルーが利用できない

TPlinkを使用していて、L2TP/IPsec VPN に繋げなかった。

会社のVPNとか。

以下を参考にルーターを買い替えた、数カ月前の備忘録。

*   知らずに損をした、Wi-Fiルーターの罠
    <https://note.com/cba_log/n/n11c48614bc4b>

*   10G回線契約したら L2TP/IPsec VPN に繋げなくなった話
    <https://jun-networks.hatenablog.com/entry/2024/04/25/212151>

L2TP/IPsec VPN 使わないなら、全然OKなルーターと思う。

仕事に支障が出たので交換した過去。
URL からクエリ文字列を取り除く

# やりたいこと

URL からクエリ文字列を取り除きたい。

# 方法

この記事では [URI](https://docs.ruby-lang.org/ja/latest/class/URI.html) オブジェクトを利用した方法を紹介する。もちろん正規表現などでも可能。

```rb
require 'uri'

url = 'http://yoyonest.jp/view/item/000000047948?category_page_id=ct26'
URI(url).tap { _1.query = nil }.to_s
#=> "http://yoyonest.jp/view/item/000000047948"

# URI は
# [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
# という構成要素からなる。
# 必要に応じて、あるいは必要はないが僕のように潔癖な人は fragment も取り除くとよい。
url = 'http://yoyonest.jp/view/item/000000047948?category_page_id=ct26#:~:text=%E3%83%9E%E3%82%A6%E3%83%AB'
URI(url).tap { _1.query =  nil }.to_s
#=> "http://yoyonest.jp/view/item/000000047948#:~:text=%E3%83%9E%E3%82%A6%E3%83%AB"
URI(url).tap { _1.query = _1.fragment = nil }.to_s
#=> "http://yoyonest.jp/view/item/000000047948"
```

# バージョン情報

```shell-session
$ ruby -v
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23]

$ gem list | egrep "^uri"
uri (default: 0.13.0)
```

# 参考

- [class URI::Generic (Ruby 3.3 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/class/URI=3a=3aGeneric.html)
【AWS認定合格記】AWS クラウドプラクティショナー(CLF-C01)

## はじめに
:::note warn
受験は今から1年以上も前のことになるので、今の試験(CLF-C02)とは試験内容は異なりますが、当時の勉強方法などの備忘録を記載しています。
:::


軽く自己紹介すると、、
◆学部卒(非情報系)
◆新卒でSIerに入社し、3年目。
◆取得資格
| 資格名 | 取得日 |
|:-----------|:-----------|
| 基本情報技術者 | 2021年11月  |
| AWS クラウドプラクティショナー | 2023年2月 |
| AWS ソリューションアーキテクトアソシエイト | 2023年7月 |
| AWS ソリューションアーキテクトプロフェッショナル | 2024年3月 |
| AWS デベロッパーアソシエイト | 2024年3月 |
| AWS sysOps Administrator アソシエイト | 2024年4月 |


:::note info
sysOpsAdministratorアソシエイトを取得するまでは、業務ではAWSに携わったことはありませんでした。
:::



## 勉強方法
使用した問題集は、**Udmeyのみ**でした。

 https://www.udemy.com/course/aws-4260/?couponCode=SKILLS4SALEJP

個人的なUdemyの使い方は以下。
　①まずは、問題に目を通してみる。
　②分からないワードを調べる。
　③答えを見てなぜその答えなのか、解説を読む。分からないところは調べる。
　④全ての問題で①〜③を行う。
　⑤実際に答えを見ずに解けるか確認する。


:::note info
私が受験した時期はCLF-C01でしたが、今はCLF-C02にバージョンアップしており、添付のudemyはC02に途中で対応したようです。
:::


## 勉強期間
合格までに要した期間は**約2週間**。

平日：約3時間〜4時間
休日：約7時間~9時間

ざっくりの計算で**約70時間ほど**でした。



## 試験当日

| 時間 | 流れ |
|:-----------|:-----------|
| 15:00 | 試験開始|
| 16:00 | 試験終了|
| 翌朝　5:30 | 合格通知メール届く|　


試験は100分間ですが、1時間ほどで解き終わりました。

試験終了後の感覚としては、Udemyで解いた問題と似た問題が多く(半分以上)、少し手応えはありました。
ただ、当日中に合格メールが来るかと思っていたので、なかなかメールが来なくて夜はあまり眠れませんでした。

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

## モチベーションの保ち方
当時、入社1年目のほぼ終わりで、何か目に見える強みが欲しいと思っていました。
ちょうどその頃、社内でAWSの資格をみんなで取ろう！みたいな運動があり、その流れでみんなと一緒に勉強して取りました。
周りに勉強している人がいると、頑張ろうと思えました。


## 受験〜合格しての所感
### 記念すべき初のAWS資格取得。やった〜！

世間の評価的にも簡単だと言われているCLFですが、やっぱり合格は嬉しかったです。

:::note info
クラウドプラクティショナーは問題の範囲が狭く、当日もひっかけ問題はなかったので、Udemy等で勉強してれば基本的には合格できると感じました。
:::
《Mac標準》 ISOイメージファイルからブータブルUSBを作成する方法

:::note
Macの標準機能で可能
追加のアプリやライブラリは不要！
:::

#### USBメモリをUSBポートに挿入し、ターミナルから以下のコマンドを実行する。

```terminal
# 1. 接続されているディスク一覧を出力、対象USBの/dev/diskXXを特定する
diskutil list

# 2. 対象USBをMS-DOS形式で初期化する
diskutil eraseDisk MS-DOS UNTITLED /dev/diskXX

# 3. フォーマットするとマウントされるのでアンマウントする
diskutil unmountDisk /dev/diskXX

# 4. ddコマンドを使用してISOイメージをディスクに書き込む
sudo dd if=./xxxxxx.iso of=/dev/diskXX bs=1m

# 5. 書き込みが終わったら、USBメモリを取り出す
diskutil eject /dev/diskXX
```


#### 実行例

```terminal:実行例（ubuntu_24.04 インストールUSBの作成）
~ % diskutil list
（一部省略）

/dev/disk6 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *31.0 GB    disk6
   1:             Windows_FAT_32 NO NAME                 31.0 GB    disk6s1



~ % diskutil eraseDisk MS-DOS UNTITLED /dev/disk6
Started erase on disk6
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk6s2 as MS-DOS (FAT) with name UNTITLED
512 bytes per physical sector
/dev/rdisk6s2: 60063040 sectors in 1876970 FAT32 clusters (16384 bytes/cluster)
bps=512 spc=32 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=60092416 bspf=14664 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk6

~ % diskutil unmountDisk /dev/disk6
Unmount of all volumes on disk6 was successful

~ % ls -s ubuntu-24.04-desktop-amd64.iso
11942688 ubuntu-24.04-desktop-amd64.iso

~ % sudo dd if=./ubuntu-24.04-desktop-amd64.iso of=/dev/disk6 bs=1m
Password:
5831+1 records in
5831+1 records out
6114656256 bytes transferred in 546.737826 secs (11183891 bytes/sec)

~ % diskutil eject /dev/disk6
Disk /dev/disk6 ejected
```


<br>　 

## おまけ

#### macOSインストーラから、インストールUSBを作成する方法

フォーマット済みのUSBをMacに挿して、以下のコマンドを実行する。
（16GBのUSBでほぼ足りる）

```terminal
# インストーラのファイル名を確認
ls /Applications/Install*.app

sudo /Applications/Install\ macOS\ XXXX.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume
```

#### 実行例

```terminal
~ % ls /Applications/Install*.app
/Applications/Install macOS Ventura.app:
Contents

# VenturaのインストールUSBを作成
sudo /Applications/Install\ macOS\ Sonoma.app/Contents/Resources/createinstallmedia --volume /Volumes/MyUSB
```

#### Macでブートディスクを選択する方法

1. Macの電源を入れ、すぐに Option(Alt)キー を押し続ける
1. 起動可能なボリュームが暗い画面に表示されたら、Optionキーを離す
1. インストーラ（ブータブルUSB）を選択する
[備忘] react-router-dom vs .htaccess 404 not found

React初心者のわたし。ドキドキで本番環境へビルド。意外と動作するのでほっと胸をなでおろしていた。
ところがURL直打ちやリロードをすると404 not foundが返される。

解決した方法をときメモ。

まず、`.htaccess` ファイルで設定したリダイレクトがどのように機能しているのかを深く理解するために、以下のポイントを振り返る。

### 1. **リダイレクトの仕組み**

```
# すべてのリクエストをindex.htmlにリダイレクトする
# ただし、既存のファイルやディレクトリへのアクセスはそのまま許可
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [L]
```

今回は上記の設定で解決した。`.htaccess` ファイルに記述した設定は、URLリクエストの処理に影響を与える。設定内容としては、`index.html` にリダイレクトする条件が書かれている。これはリクエストがサーバーに到達する際の処理であり、クライアントサイドのルーティング（React Routerなど）とは異なる動作をする。

### 2. **リクエストとサーバーの役割**

- **最初のリクエスト（初期アクセス）**: たとえば、ユーザーが `http://192.168.1.xxx/test` というURLにアクセスすると、ApacheサーバーはそのURLに対応するファイルを探しにいく。
- **ファイルが存在しない場合**: `/test` に対応するファイルやディレクトリが存在しないときに、`.htaccess` の設定が適用される。今回の場合だと、`RewriteCond %{REQUEST_FILENAME} !-f` と `RewriteCond %{REQUEST_FILENAME} !-d` がマッチし、`RewriteRule ^ index.html [L]` により、リクエストは `index.html` にルーティングされる。

### 3. **リダイレクトと表示の違い**

- **リダイレクト**: `RewriteRule ^ index.html [L]` の設定は、サーバーがリクエストを処理する方法で、存在しないファイルやディレクトリへのリクエストが `index.html` で応答されるようになるが、クライアントサイドでの表示やルーティングには影響しない。
- **クライアントサイドのルーティング**: `index.html` が読み込まれた後、React Router が実際のページの表示を管理する。`index.html` がブラウザに表示されると、React Router がURLに基づいて適切なコンポーネントをレンダリングしてくれる。便利。

### 4. **リロードとブラウザの動作**

- **直接アクセス**: ユーザーが `/test` というURLにアクセスすると、サーバーは `.htaccess` 設定に従い `index.html` を返す。
- **リロード**: ブラウザでページをリロードしても、サーバーは再び `index.html` を返し、その後、React Router がURLに基づいて適切なコンポーネントを表示する。このおかげでユーザーがリロードしても、`/test` の内容が維持されるしくみ。

### 5. **まとめ**

- `.htaccess` で設定したリダイレクトは、URLに対するリクエストの処理をサーバーサイドで制御するもので、リクエストに対して `index.html` を返すことが目的となる。
- リダイレクトといっても、なんでもかんでも`index.html` が表示されるわけではなく、React アプリケーションがその後のルーティングを制御してくれて正しいコンポーネント（例: `/test`）を表示してくれる。

React初心者のわたしを絶望の淵から助けてくれたのは `.htaccess` だった。結果的にはうれしいけど、検証中はブラウザキャッシュのせいで無駄に時間を使ってしまって苦労した・・・。おしまい。