OmniAICreator/Qiita-1.07M huggingface dataset:
EC2 instance をインターネットに繋ぐ

AWS の EC2 instance からインターネットに繋ぐのにハマったのでメモ。

# 概要
AWS の EC2 instance からインターネットに繋ぎたい。以下の要請がある。
- 複数のインスタンスを立てるかもしれない。その時のためになるべく少ない個数の public IPv4 アドレスを利用したい
- Web サービスは立てないので、EC2 instance に public IPv4 アドレスが紐づいている必要はない
- インターネットに繋ぐには何らかの形で public IPv4 アドレスを 1 個以上要する

# 完成図
VPC の中に以下のようなものができる。
![スクリーンショット 2024-09-22 17.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67404/632df6cf-bbf7-55fe-e9e3-93cf38caf651.png)
図からわかりにくいが、`koba-nat-gateway` が `subnet-for-internet-access` (pubilc な方の subnet) に関連づけられていることに注意。これによって 2 個の subnet の間のつながりが生まれる。

# 作るもの
全体の構造から順に説明する。構築する際は順番に従うこと。

- subnet 2 個 (1 番目)
  - 図の `subnet-for-internet-access`: インターネットへの接続を司る。Internet Gateway に接続する。また NAT Gateway もこの中に作る。大きさは 11 ホスト (CIDR block を /28 で設定する、5 ホスト予約されるので $2^{32-28}-5=11$) でよい。/29 (3 ホスト) が可能だったらそれでも良かったかもしれない (検証不能)
  - 図の `subnet-for-priv-dev`: 外に漏れたらまずいことをやる。インターネットに繋ぎたい時は NAT Gateway にリクエストを送信する
- route table 2 個 (3 番目)
  - 図の `rtb-public-dev-subnet-into-internet`: Explicit subnet associations を `subnet-for-internet-access` にし、「全て (0.0.0.0/0) のターゲットを Internet Gateway に繋げ」という指示を与える
  - 図の `rtb-public-dev-subnet-into-internet`: Explicit subnet associations を `subnet-for-priv-dev` にし、「全て (0.0.0.0/0) のターゲットを NAT Gateway に繋げ」という指示を与える
- NAT Gateway (2 番目)
   - Elastic IP Address を持つ。必然的に public subnet (Internet Gateway につながっている subnet) に作る必要があり、そうでないところに作るのはナンセンスである

# ハマったポイント
## public subnet と private subnet の違い
subnet そのものに public/private の設定項目があるわけではない。Internet Gateway につながっているものを public subnet と呼ぶ。

## 一つの subnet でできないのか?
多分できない。
ラズパイPico でNeoPixelを光らせる

ラズパイPico でNeoPixelのLEDを光らせよう

## NeoPixelの説明

NeoPixel は WS2811 と言うマイコンで制御された、フルカラーのLEDです。
電源のプラス、マイナスと信号線の3本で、制御します。
さらに、複数個 NeoPixelを接続できるように、信号線の出力があり、合計4本の足が出ています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665435/057dc29a-e259-b27b-9450-b9440a743895.png" width="50%">

4本の足はそれぞれ、左から3番目が1番長い足となるようにして、左から「4 DIN:入力」、「3 VDD:+（プラス）」、「1 GND:-（マイナス）」、「2 DO:出力」です。

NeoPixel が1個の場合は、「2 DO:出力」は使いません。複数個 NeoPixel をつないだときは、「2 DO:出力」を、次の NeoPixelの「4 DIN:入力」につなぎます。

こちらも参考にしてください：

マイコン内蔵RGBLED 5mm PL9823-F5：
https://akizukidenshi.com/catalog/g/g108411/

マイコン内蔵RGBLED 8mm PL9823-F8：
https://akizukidenshi.com/catalog/g/g108412/

## 準備：NeoPixel を GND、GPIO22、5V に接続

「1 GND:-（マイナス）」をGNDに、
「4 DIN:入力」をGPIO 22番に、
「3 VDD:+（プラス）」を5Vに接続します。

![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665435/565de5ce-3436-4e29-bb85-3aaa3be0c6d9.png)


## プログラム

Raspberry Pi Pico W で動作を確認しました。
W 無しの Raspberry Pi Pico では、「色化け」が起きて、点灯はするものの、変な色で点灯してしまいました。

```Python
from machine import Pin
from neopixel import NeoPixel
import time

# GRB を RGB に変換する関数
#   Red:赤、Green:緑、Blue:青
#   各色の明るさを 0 ～ 255 で指定
def rgb(r, g, b):
    return (g, r, b)

# ここからはじまり
pin = Pin(22, Pin.OUT)      # GPIO 22 番に NeoPixel の信号を出力する
np = NeoPixel(pin, 1)       # pinの先には、NeoPixelが 1 個接続されている
for i in range(4):          # 4回くりかえす
    np[0] = rgb(255, 0, 0)  # 0番の NeoPixel を「赤」にする
    np.write()              # NeoPixel にデータを書き込む
    time.sleep(1)           # 1秒待つ
    np[0] = rgb(0, 255, 0)  # 0番の NeoPixel を「緑」にする
    np.write()
    time.sleep(1)
    np[0] = rgb(0, 0, 255)  # 0番の NeoPixel を「青」にする
    np.write()
    time.sleep(1)
np[0] = rgb(0, 0, 0)        # 0番の NeoPixel を消す
np.write()

```
atcoder372のA問題

## 問題
- 英小文字および . からなる文字列 S が与えられます。 S から . を全て削除した文字列を求めてください
## わからなかった点
 - 特定の削除方法
 - chatGPTに聞く
### 特定の削除方法
 ```
C++で入力された文字列から特定の文字、
たとえば.をすべて削除するには、
標準ライブラリのstd::stringを使ってループ処理や
erase-removeイディオムを使う方法があります。
以下にその方法を説明します。

```
```
#include <iostream>
#include <string>
#include <algorithm>  // std::remove

int main() {
    std::string input;

    // ユーザーから入力を受け取る
    std::cout << "文字列を入力してください: ";
    std::getline(std::cin, input);

    // '.' を削除
    input.erase(std::remove(input.begin(), input.end(), '.'), input.end());

    // 結果を表示
    std::cout << "After removal: " << input << std::endl;

    return 0;
}

```

## 回答を元に作成し、実行

- stdを削除
```
#include <bits/stdc++.h>
using namespace std;
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using ll = long long;
using P = pair<int,int>;
    
    int main() {
      string input;
    
      // ユーザーから入力を受け取る
      getline(cin, input);
    
      // '.' を削除
      input.erase(remove(input.begin(), input.end(), '.'), input.end());
    
      cout << input << endl;
      return 0;
}
```
 - コンパイルし、実行
 ```
 tomo@tomonao-pc:~/atcoder$ ./program
.test..
test
tomo@tomonao-pc:~/atcoder$ 
```

### 学んだこと
 - getline(std::cin, input) は、ユーザーが入力した全体の文字列（空白や改行も含む）を取得するために使用
 - removeで.を文字列から削除し、eraseメソッドでそれを完全削除
install pyenv/python systemwide on Rocky 9.4

# initial setting for linux

## useradd

```
sudo useradd <name>
sudo passwd <name>
```

# install pyenv

## download

https://github.com/pyenv/pyenv

```
sudo su -
cd /usr/local
```

dependencies
```
dnf install gcc make patch zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel
```

https://github.com/pyenv/pyenv/wiki#suggested-build-environment

```
dnf install git
git clone https://github.com/pyenv/pyenv.git pyenv
```

## set login profile

```shell:/etc/profile.d/pyenv.sh
echo 'export PYENV_ROOT="/usr/local/pyenv"' >> /etc/profile.d/pyenv.sh
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> /etc/profile.d/pyenv.sh
echo 'eval "$(pyenv init - --no-rehash)"' >> /etc/profile.d/pyenv.sh
```

--no-rehashは次のブログを参考に追記した

https://home.hirosaki-u.ac.jp/heroic-2020/970/

## check

再ログインする
```
exec -l $SHELL
pyenv -v
```

# install python for system

## dependencies

https://github.com/pyenv/pyenv/wiki#suggested-build-environment

```
dnf install gcc make patch zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel
```

## python

```
pyenv install --list
pyenv install 3.9.
```

これで3.9.Xの候補一覧が出る

```
pyenv install 3.9.20
pyenv global 3.9.20
```

## check

一般ユーザにて

```
exec -l $SHELL
python -V
```

→3.9.20となる
git の過去のコミットのメールアドレスを修正

## 目的
git の過去のコミットのメールアドレスを修正

## 手順
タグ名は維持しつつ、コミットのメールアドレスだけ変更する。
```
git filter-branch --env-filter '
CORRECT_NAME="Your Name"
CORRECT_EMAIL="xxx@xxx.com"

export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
' --tag-name-filter cat -- --branches --tags
```

すでに push していた場合、上書きするには、--force オプション必要。
```
git push origin main --force 
```

今後のコミットのメールアドレスも変更しておく。
```
git config --global user.name "Your Name"
git config --global user.email "xxx@xxx.com"
```
【個人開発】自分だけのベストアルバム一覧を作れるサービスを開発しました

### 概要
今まで聴いてきた音楽の中から「自分だけのベスト10」をアルバムアートを表示しつつ一覧にできるサービスを作成しました。

個人的に使うだけなのでリンクは特に掲載しません。

実際に使用しているキャプチャも最後まで載せたいところですが、アルバムアートは著作権的にアウトだと思いますので、途中までになります。
![3capture.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877267/c1d21ae9-4f28-8a70-4144-dd66f73c498d.gif)


実際にはこのあとアルバム一覧が表示→アルバムを選択したらアルバムアートが一覧で表示できます。

### 開発背景
友人とよく「◯◯ベスト10」というような話をします。ゲームだったり映画だったり…
それぞれの好きなものがわかりますし、色んな視点を聞くことができるので個人的にはすごく楽しい話題だと思っています。
この話をするときに視覚的な情報も一緒にあるとよりイメージつきますし、「それ知ってる！」みたいな話が広がると思い開発してみました。

あとは単純に勉強の意味もあります。
業務で主にフロントまわりを担当していますが、社内で使用しているシステムはレガシーなものばかりなので新しい技術を身に着けていくためにも、こういった手を動かす学習が習慣的に必要と思いました。
今回の開発のおかげで、これまでゲームとかで時間を潰していましたが、プログラムを触る時間のほうが圧倒的に多くなりました。

### サービスの概要
あなただけのベスト10を作れます。
アーティストを検索して選択、それだけ。
一覧を画像共有することができます。
……本当にこれだけです。シンプルですね。

### 開発言語
フロントエンド
- HTML
- CSS
- JavaScript
- jQuery 

バックエンド
- PHP

その他
- Spotify API
- composer
- [spotify-web-api-php](https://github.com/jwilsson/spotify-web-api-php)

 環境
 - Docker


### 良かった点
なるべくわかりやすく直感的に操作できるような画面設計にしました。
シンプルにするということは単純に情報を絞ればそれでいい、というわけではなく
「必要な情報はなにか？」ということを整理したうえでないと達成できないということを学べた気がしています。
あとはAPIで一度に取得できる楽曲情報件数がMAX50件だったので、全曲取得できるように工夫できた点は良かったと思います。
先にも挙げてましたが、プログラムを触る時間が習慣化できたのは非常に良い収穫でした。

### 反省点
実装に入っていく前に機能を詳細に決めきらないまま進行してしまったことです。あとからこの機能があったほうがいいな、と気づいて追加して……みたいなことがよくありました

### 今後
今後はReactに移行することを目標としたいと思います。
当初勉強しながらReactで実装しようと思っていたのですが、いきなりあれこれ手を出しながら勉強は効率悪いと感じたので、まずは自分の使える技術で実装→移行という形にしました。
いずれはゲームや映画といったジャンルにも展開できていけたらと思っています。


今回初めてQiitaに投稿しました。
今後も学んだことをアウトプットしていきたいと思います。
正規表現

## Basic Regular Expression

```
/abc/
```

In JS, regexes are strings that begin and end with /
The simplest regexes simply match a particular substring
The above regular expression matches any string containing "abc"
● Matches: "abc", "abcdef", "defabc", ".=.abc.=.", ...
● Doesn't match: "fedcba", "ab c", "PHP", ...



## Wildcards, Case sensitivity

A . matches any character except a \n line break
● /.ax../ matches "Faxes", "Jaxes", "Taxes", "maxie", etc.

A trailing i at the end of a regex (after the closing /) signifies a case-insensitive
match
● /cal/i matches "Pascal", "California", "GCal", etc.


## Quantifiers: *, +, ?


* means 0 or more occurrences
● /abc*/ matches "ab", "abc", "abcc", "abccc", ...
● /a(bc)*/ matches "a", "abc", "abcbc", "abcbcbc", ...
● /a.*a/ matches "aa", "aba", "a8qa", "a!?xyz__9a", ...
+ means 1 or more occurrences
● /Hi!+ there/ matches "Hi! there", "Hi!!! there!", ...
● /a(bc)+/ matches "abc", "abcbc", "abcbcbc", ...
? means 0 or 1 occurrences
● /a(bc)?/ matches only "a" or "abc"

## Character ranges: [start-end]

Inside a character set, specify a range of characters with -
● /[a-z]/ matches any lowercase letter
● /[a-zA-Z0-9]/ matches any lowercase or uppercase letter or digit
Inside a character set, - must be escaped to be matched
● /[+\-]?[0-9]+/ matches an optional + or -, followed by at least one digit
Salesforce 認定Platformデベロッパー 受験レポート

## 1. 受験の経緯
8月末に取得したアプリケーションビルダーの認定取得に引き続きデベロッパー認定の学習を継続しました。

## 2. 学習方法
### ①過去問 
[Salesforce 認定Platformデベロッパー】試験対策：第215問（TysonBlog）
](https://tysonblog-whitelabel.com/category/salesforce/salesforce-developper1 "TysonBlog")
　試験対策は過去問を中心に進めました。コンテンツはアプリケーションビルダー認定の時と同じです。
　序盤の設問では解説のところに公式ドキュメント(②)の該当ページへのリンクが貼られていて、そのページを読み込む流れで進めました。
　また、設問に登場する分からないキーワードについても公式ドキュメントの該当箇所を探して確認しました。
　2週目に再利用できるようにExcelに設問、キーワードと参考URLを整理しました(↓)。
　結局、学習時間が十分に取れず第170問までしかできませんでしたが、試験直前の復習では役に立ちました。

 ![スクリーンショット 2024-09-22 165222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875094/3e9a8074-3745-c3ef-89d5-4e2fe28f69b5.png)

### ②公式ドキュメント
[Developer Documentation (Salesforce)](https://developer.salesforce.com/docs "Salesforce")
　過去問で登場したキーワードについて検索し、該当ページを読み込みました。
　特にApexトリガーの種類、標準コントローラー、ガバナ制約、apexタグ、Apexクラス、Testクラス、DML、SOQL/SOSLなど、メソッド名や属性名、シンタックスなど細かいレベルで問われましたので、該当ページを一通り確認しておくと良かったと思います。
　
## 3. 試験結果

　受験日　：2024年9月22日(日)
　所要時間：57分（105分）
　結果　　：合格

| セクション  | 正答率 |
|:-----------|:------------:|
| Developer Fundamentals（デベロッパーの基本）| 71%        |
| Process Automation and Logic（プロセスの自動化とロジック）| 72%        |
| User Interface（ユーザインターフェース）| 60%        |
| Testing, Debugging, and Deployment（テスト、デバッグ、リリース）| 76%        |

## 4. まとめ
　アプリケーションビルダーよりは試験対策をしたつもりでしたが正答率は平均して低い結果となりました。
　デベロッパーは出題範囲がわりと限られていますが必要知識の粒度が細かいので、単純に消化した過去問の種類とドキュメントの確認範囲、記憶量が正答率に繋がると思います。
　「User Interface（ユーザインターフェース）」の正答率が60%と特に低いですが、
過去問にこのカテゴリの問題があまり見なかったのでそれが影響したのだと思います。

次回はアーキテクトロールの認定を受験しようと思いますが、
内容は高度になるのでしっかり試験対策をして臨みたいたいです。
local.propertiesの使い方(Android)

local.propertiesの使い方忘備録

## local.properties
local.propertiesにAPIキーなどの情報を追加する。
```local.properties
hoge=HogeHoge
```

## appレベルのbuild.gradle
buildConfigを有効にする。

```app/build.gradle.kts
android {
    buildFeatures {
        buildConfig = true
    }
}
```

local.propertiesから情報を取ってくるコードを追加する。

```app/build.gradle.kts
import java.util.Properties

android {
    defaultConfig {
        // 既存のコード

        val localProperties = Properties()
        localProperties.load(rootProject.file("local.properties").inputStream())
        buildConfigField("String", "hoge", "\"${localProperties.getProperty("hoge")}\"" 
    }
}        
```
build.gradle.ktsに追加ができたら、一度アプリをビルドする。
ビルドすることでBuildConfig.javaが更新されてプロパティの値を利用できるようになる。

## コード内での利用
`BuildConfig.{プロパティ名}`でコード内で利用できる。
```MainActivity.kt
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello ${BuildConfig.hoge}!",
        modifier = modifier
    )
}
```
[Makefile]PCに保存されている環境変数を.envファイルにすべて入れて作成する

## Makefile

```Makefile
# デフォルトのターゲット
.PHONY: all
all: create-env-file

# 環境変数を.envファイルにエクスポート
.PHONY: create-env-file
create-env-file:
	@echo "Creating .env file from current environment variables..."
	@printenv | grep -v '^_' | sed 's/=.*//g' | sed 's/^/export /' > .env.temp
	@while read line; do \
		var_name=$$(echo $$line | cut -d' ' -f2); \
		var_value=$$(printenv $$var_name); \
		echo "$$var_name=$$var_value" >> .env; \
	done < .env.temp
	@rm .env.temp
	@echo "Created .env file with $(shell wc -l < .env) environment variables."

# .envファイルの内容を表示（セキュリティ上重要な情報は表示しないよう注意）
.PHONY: show-env-file
show-env-file:
	@echo "Contents of .env file (excluding sensitive information):"
	@grep -vE 'KEY|TOKEN|PASSWORD|SECRET' .env || true

# .envファイルを削除
.PHONY: clean
clean:
	@echo "Removing .env file..."
	@rm -f .env
	@echo ".env file removed."

# ヘルプメッセージを表示
.PHONY: help
help:
	@echo "Available targets:"
	@echo "  create-env-file : Create .env file from current environment variables"
	@echo "  show-env-file   : Show contents of .env file (excluding sensitive information)"
	@echo "  clean           : Remove .env file"
	@echo "  help            : Show this help message"
```

## 説明

このMakefileは、環境変数の管理を支援するためのツールです。主な機能は以下の通りです：

1. 現在の環境変数から.envファイルを作成
2. 作成された.envファイルの内容を確認（機密情報を除く）
3. .envファイルの削除
4. 使用可能なコマンドの一覧表示

## 使用可能なコマンド

### 現在の環境変数から.envファイルを作成
```
make create-env-file
```
このコマンドは、現在のシェルセッションの環境変数を取得し、.envファイルに保存します。これにより、プロジェクトの環境設定を簡単に再現できます。

### 作成された.envファイルの内容を確認する（機密情報を除く）
```
make show-env-file
```
このコマンドは、.envファイルの内容を表示します。ただし、セキュリティ上重要な情報（キー、トークン、パスワード、シークレットなど）は表示されません。

### .envファイルを削除
```
make clean
```
このコマンドは、作成された.envファイルを安全に削除します。

### ヘルプメッセージを表示
```
make help
```
このコマンドは、利用可能なすべてのmakeターゲットとその簡単な説明を表示します。

## 注意事項

- このMakefileを使用する際は、セキュリティに注意してください。.envファイルには機密情報が含まれる可能性があるため、適切に管理してください。
- `show-env-file`コマンドは機密情報を表示しないよう設計されていますが、完全な保証はありません。表示される情報には注意してください。
- .envファイルをバージョン管理システム（Git等）にコミットしないよう注意してください。
Dictionaryに対するFirstOrNull

# 0. はじめに
[Freeradical](https://www.freeradical.jp)の中の人、[yamarah](https://qiita.com/yamarah)です。
`Dictionary`に対して`FirstOrDefault`すると、一致がない場合に`KeyVaulePair(default, default)`が得られます。ちょっと困る場合があるよね、という話です。

# 1. どういった場合に困る
`FirstOrDefault`で困るのは`Dictionary`に、`Key`もしくは`Vaule`が`Default`値の要素を含む場合です。
`int`で`0`や、`string`で`null`を許容している場合など。
これらの場合に、含まれている要素なのか検索ヒットなしかの区別がつきません。
```C#
Dictionary<int, string?> dic = new() { { 0, null } };
var pair1 = dic.First();
var pair2 = dic.FirstOrDefault(_ => false);

// 以下はTrueになる
Console.WriteLine(pair1.Key == pair2.Key && pair1.Value == pair2.Value);
```
もちろん、それぞれの状況に応じて回避方法はあるでしょう。
しかし、毎度回避方法を探るのではなく、ただ単純に`FirstOrNull`が欲しいのです。

# 2. 作ってみた
ということで、作りました。
```C#
static class CollectionExtensions
{
    public static KeyValuePair<TKey, TValue>? FirstOrNull<TKey, TValue>(this IDictionary<TKey, TValue> source, Func<KeyValuePair<TKey, TValue>, bool> predicate) where TKey : notnull
    {
        foreach(var pair in source)
        {
            if (predicate(pair)) return pair;
        }
        return null;
    }
}
```
これならば、
```C#
Dictionary<int, string?> dic = new() { { 0, null } };
var pair = dic.FirstOrNull(_ => false);
Console.WriteLine(pair is null); // True
```
となり、満足です。
[Unity]学生プランで最初に出てくるロゴは消せる

　Unityのビルドしたプロジェクトデータはデフォルトでは起動時に以下のようなロゴが表示され、これは無料のPersonalプランでは削除することができません。
 　しかし、学生プランに登録することでこれを削除することができます。
  ![UnitySplash.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799491/e9dcb6bc-7f92-97bf-1f74-7c3e606a11b3.gif)
  
　学生プラン登録後、[Edit]>[Project Settings]>[Player]>[Splash Image]>[Show Splash Screen]と進み、チェックボックスを外すことで、ビルド時にロゴが表示されなくなります。
 ![スクリーンショット 2024-09-22 165647.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799491/090551ef-f48b-9872-2407-5a776ac1e273.png)

　学生プランは以下のURLから登録できます。
https://unity.com/ja/products/unity-student
## 余談
　Unityの学生プランの登録手順は度々変更されているらしく、ネット上の情報にも古いものが数多くあります。
 　2024年9月現在では、Unity公式が以下のページで紹介している手順で登録ができます。
  https://unity3d.jp/education/unity-student-plan/
仮想化（ハイパーバイザー型、ホストOS型）の違いに終止符を

# 記事によって記載が異なり、違いが分からん

ハイパーバイザー型の説明は、根本的な箇所が記事によって異なるケースがある。
以下2つの『ハイパーバイザー型』の説明では、
「ハイパーバイザー」がホストOSの上にない説明と、ある説明がある。

<img width="300" alt="ハードに直接乗っている" src="https://camo.qiitausercontent.com/190be7aa6b4ae7466229f69b118b7c194807f3aa/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313230393831342f61393737653334352d376162342d396631372d336634662d3331636239373336633533612e706e67">
<img width="400" alt="ホストOSの上に乗っている" src="https://academy.gmocloud.com/wp/wp-content/uploads/2021/12/vps-hv-container-03.png">

参考：
[【勉強用】仮想化３種についてまとめてみた](https://qiita.com/dogabon20/items/765ed50a0aa3822d34dc)
[VPSはどんな技術で動くの？ハイパーバイザー型とコンテナ型の違いを解説](https://academy.gmocloud.com/wp/vps/20211228/13893)

#### あ ～ も  う  め  ち  ゃ  く  ち  ゃ だ よ
<img width="400" alt="ホストOSの上に乗っている" src="https://www.softbank.jp/biz/function/dynamicmedia/deliver/dm-aid--baa33197-4359-421a-9812-5d3df9cdb97b/img-hypervisor-20200715-02.gif?preferwebp=true&quality=100&width=2000">

参考：
[ハイパーバイザーとは](https://www.softbank.jp/biz/blog/business/articles/202007/hypervisor/)


# なぜこうも違うのか
結論としては、「ハイパーバイザー型が時間とともにタイプ1とタイプ2に区分別けされ、その後タイプ2がホストOS型と呼ばれハイパーバイザー型とは完全に別物と考えられるようになったためカオス状態となっている」が答えだと思われる。つまりハイパーバイザー型とホストOS型の解釈は
```
・ハイパーバイザー型（タイプ1、タイプ2）
・ハイパーバイザー型（タイプ2）、ホストOS型（元はハイパーバイザー型の"タイプ1"）
```
の2通りがあり、それぞれの解説者がそれぞれの解釈で説明しているせいだと思われる。
以下に詳しく記載する。

# ハイパーバイザー型とはそもそも何なのか
直訳すると「超すごい管理者」となる。
これはVirtualBoxのような仮想化アプリと考えていいと思う。
この「超すごい管理者」がハードウェアに直接居座っているのか、ホストOS上にいるのかという違いで、実はハイパーバイザー型は2タイプ存在している。

・ハードウェア上で動作する「タイプ1」
・ハードウェア上のホストOS上で動作する「タイプ2」
>ここで、タイプ2ってホストOS型のことじゃね…？と思った人は勘が鋭い。

ここからは完全に私の推理ですが、これらを踏まえ恐らく以下のような用語変化があったのだと想像できる。

##### 初期の概念 
「ハイパーバイザー」という用語が生まれた初期は、「物理マシン上で仮想マシンを管理するソフトウェア」を指す程度であり、タイプ1とタイプ2なんて区分すらなかったのではと考えられる。
```php:第一形態
・ハイパーバイザー型（仮想マシン作れるすごいやつ程度の認識）
```
##### 中期の概念 
仮想化技術が進化するにつれて、異なる動作方式（直接ハードウェア上で動作するか、ホストOS上で動作するか）を区別する必要が生じ、タイプ1とタイプ2に分類されたと予想。
```php:第二形態
・ハイパーバイザー型
   >タイプ1（ハードウェア上で直接動作）
   >タイプ2（ハードウェア上のホストOS上で動作）
```
##### 後期の概念 
その中でもタイプ2はホストOS上で動作することから、「タイプ2だけ異質だし"ホストOS型"って感じでジャンルごと別けて考えた方が良くね？」となり、別個に認識されるようになっていったと予想。
```php:最終形態
・ハイパーバイザー型（元々はタイプ1であり、ハードウェア上で直接動作）
・ホストOS型（元々はハイパーバイザー型のタイプ2）
```
<details><summary>Q:なぜタイプ1ではなくタイプ2がハイパーバイザー型から追い出されたのか</summary>
A:分かりません。
</details>

# 結論
ハイパーバイザー型の説明がごちゃごちゃしている理由は、ホストOS型について「ハイパーバイザー型とは完全に異なるもの！」と考える派閥と、「ハイパーバイザー型の派生なんだから"ハイパーバイザー型のタイプ1"と説明するべき！」派閥がいるからと私は理解しました。

つまり、試験に受かりたいだけの人は
・ハイパーバイザー型（ハードウェア上で直接動作するもの）
・ホストOS型（ホストOS上で1つのアプリとして動作するもの）
・コンテナ型（勉強中…）
という認識で全く問題ないと思われる。ややこしいね。

間違っていたらコメントいただけると幸いです。



# 参考文献

Wikiにも「狭義においては、Type 2はハイパーバイザには含まれない。」とあるので、上記の過程は正しいか分からないが、最終的な結論は合っていると考えている。
参考：https://ja.wikipedia.org/wiki/%E3%83%8F%E3%82%A4%E3%83%91%E3%83%BC%E3%83%90%E3%82%A4%E3%82%B6

これも勉強になった
https://www.softbank.jp/biz/blog/business/articles/202007/hypervisor/
Node-RED Windows

ラズパイで動いたのでWindowsにも入れた

# 環境
Node-RED v4.0.3
Node.js v20.17.0
Windows_NT 10.0.22631 x64 LE

# Node.js
Node.jsをインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/939c3c1f-f4ee-6d01-a43e-6e1ffab455f1.png)

# Node-RED
Node-REDをインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/1ea81aaa-ec30-acff-e662-a4fb80e82850.png)
ラズパイの時同様にインストール完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/1f2c86d4-c69a-1b12-cba7-b2741119df28.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/ac982680-9717-74df-1baf-c101d6b703a1.png)
# 動作確認
ラズパイの時同様タイムスタンプで動いているのを確認した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3852763/1a4dc3f0-b091-c8cd-cf58-c689d9ea19cf.png)


# 参考にした書籍・URL
https://qiita.com/HiguchiTakahiro/items/3c024c79e5f463936ecc
https://www.kohgakusha.co.jp/books/detail/978-4-7775-2249-1
ForwardAgent を使って、EC2 から Github に ssh接続でpushしたい。

## 目的
ForwardAgent を使って、手元から Github にSSH接続するための設定を、EC2 でも使えるようにする。
※ VsCode の Remote SSH でもやりたかったが、うまくいかなかった。

## 環境
Windows WSL2(ubuntu)
EC2(ubuntu)

## 手順
(1)
[GithubにSSH接続する手順](https://qiita.com/ShiroatoHiro/items/72788d7f5935d165019f) を参考に、手元の WSL2(ubuntu) から Github に SSH接続できるようにしておく。

(2)
EC2 に接続するときの設定ファイルを作成する。
```C:\Users\{YourUserName}\\.ssh\config
Host MyHost
    HostName xxx.xxx.xxx.xxx
    User ubuntu
    IdentityFile ~/.ssh/xxx.pem
    LocalForward 3000 localhost:3000
    LocalForward 8080 localhost:8080
    ForwardAgent yes
```

(3)
WSL2 のホームディレクトリは、通常のホームディレクトリと異なるので、両方から使えるようにコピペしておく。
下記のコマンドを適当に使う。

```ubunu
cp /mnt/c/Users/{YourUserName}/.ssh/config ~/.ssh/config 
cp /mnt/c/Users/{YourUserName}/.ssh/xxx.pem ~/.ssh/xxx.pem
```
```
cp ~/.ssh/config /mnt/c/Users/{YourUserName}/.ssh/config 
cp ~/.ssh/xxx.pem /mnt/c/Users/{YourUserName}/.ssh/xxx.pem
```

(4)
VsCodeのRemote SSH を使ってEC2にアクセスする。
EC2 で下記のコマンドが成功しないので、Github へ SSH 接続ができない。
```
$ ssh-add -l
$ ssh -T git@github.com
```

(5)
回避策として、WSL2 から下記を実行して、EC2 にアクセスする。
```
$ eval "$(ssh-agent -s)"
$ printenv | grep SSH_
SSH_AUTH_SOCK=xxx
SSH_AGENT_PID=xxx
$ ssh-add ~/.ssh/id_ed25519
$ ssh-add -l
```
※ [GithubにSSH接続する手順](https://qiita.com/ShiroatoHiro/items/72788d7f5935d165019f) によって、SSHエージェントにすでに登録されていれば、上記を実行する必要はない。
```
$ ssh MyHost
```
下記によって、EC2 から Github へ接続できることが確認できた。
```
$ ssh-add -l
$ ssh -T git@github.com
```
VsCode の Remote SSH だとうまくいかなかったので、私はいつも、push のときは WSL2 からアクセスしたターミナルを使っている。
AWS:Webサーバ構築

# Webサーバの構築

## 知識
EC2(elastic compute cloud):仮想サーバ

インスタンス：EC2からたてられたサーバ

AMI(amazon machine image)あみ：
インスタンス軌道に必要な情報が入ったOSのイメージ
AMI→インスタンス
AMIがあるため、自分でOSをいれなくていい

インスタンスタイプ：サーバーのスペック
m5.xlarge
m:インスタンスファミリー
5:インスタンス世代
xlarge:インスタンスサイズ


ストレージ：
- EBS(elastick block store)
永続的に保存
- インスタンスストア
一時的なストレージ
無料

## 操作 EC2インスタンスの設置
1. AMIの選択
1. インスタンスタイプ
1. ネットワークの選択
1. ストレージの追加
1. セキュリティグループの設定
1. SSHキーペアの設定
→後でダウンロードしなおすことはできないのでなくさない！


ネットワーク
自動割り当てパブリックIP：
グローバルIPアドレスをつけるかどうか

キャパシティ予約：
事前にリソースを確保
EC2インスタンスの実行の有無にかかわらず料金発生する


##  操作　Apacheをインストール
1. SSHでログイン（※Tera Term5でログイン）ログアウトはexit
1. Apacheインストール(先にyumでupdateしておく：sudo yum update)

・apacheインストール
```
sudo yum -y install httpd
```
httpdはapacheを構成する実行ファイル


・起動
```
sudo systemctl start httpd.service
```

・ステータス確認
```
sudo systemctl status httpd.service
```

・apacheが自動起動するように設定(サーバーが起動したらApacheも自動起動)
```
sudo systemctl enable httpd.service
```

・自動起動設定されてるか確認
```
sudo systemctl is-enabled httpd.service
```

## FWの設定
AWSではセキュリティグループ＝FW
・インバウンドの80ポートを開ける
・ブラウザにパブリックIPv4アドレスを貼り付けアクセスする

## 固定IPアドレスの設定
EC2インスタンスのパブリックIPは、起動、停止で別のIPアドレスが動的に割り当てられる
Elastic IP：IPアドレスを固定する

※Elastic IPアドレスは場合によって課金される
インスタンスに紐づけていないとき
インスタンスが停止しているとき
↓
アクション＞
アドレスの関連付けの解除＞
アドレスの開放

これをすると課金されない
スクラムの成功とは何を指すのか

## はじめに
スクラム開発における成功とは何だろう
そもそもPJTとは期限があるが、前例はないものである
前例がないものに対して「ウォーターフォールじゃなくてアジャイルでよかった」と断定できるだろうか
既存のウォーターフォールの進み具合が悪く、アジャイルに開発した場合は効果を実感しやすい
元々アジャイルで開発した場合はいかがだろうか
開発サイド、発注サイドとしてもこの成功体験を積めない限りは、本質的にアジャイル開発はできないと考えている
今回は、スクラム開発の成功について思考し、スクラムマスターとして活かせるノウハウを積もうと思う

## スクラムの成功例(開発T)
スクラムはチームの雰囲気を重要視するフレームワークである
少人数で迅速に開発を行うため、一致団結となり前進する
それぞれがタスクの進捗状況を理解し合い、取り残されることがないよう前進する
疑問や困難があればすぐに相談し、障害をできる限り取り除いた状態で開発できる環境
そのために各々仕様を理解するために事業側に相談を出し、
相談を受けたらすぐに親身になって解決できる環境が理想である
タスクを細分化し、各々担当するため、成果物ができるたびに達成感を覚えることができる

## スクラムの成功例(事業T)
目的→目標まで定まっているが、過程が決まっていない要望
目標達成できれば良いが、UI/UX周り等、言語化しにくい部分の要望は出しきれない
そのような状態だが要望を出し、擦り合わせながら作れるシステムが理想
顧客に直接関わり、ROIを強く求めるようなシステムの場合、変化しやすいスクラムには向かない
先にROIを出す場合、ROIありきの改修となる
その場合は、柔軟に変更をするスクラムは向いておらず、ROIすらも変えたくなる
後にROIを出す場合、システムありきのROIになる
それはあくまで結果論であり、ROIを達成できても事業へのインパクトは大きくない
あくまで社内の改善のため、スクラムは向いているシステムである
us配列 chromebook のvs codeで日本語入力と英語入力切り替えに対応する方法

## ctrl + spaceはvscode上では、chromeos側のショートカットが効かない。
chrome bookでは、デフォルトで、US配列のキーボードを使用している場合、`ctrl + space`で半角全角の入力切替を行います。
しかし、vscodeを開いている状態だと、このキーショートカットがvscode側で独占されてしまい、chromebook側の全角半角の入力切替として検知されなくなってしまいます。

## 解決策 新たなショートカットを紐づける
`ctrl + 検索キー + S`でchrome bookのショートカットキー一覧を表示する事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300617/8ae1c9cf-a3ed-0ffe-4b17-f2f5e0bf4694.png)

「入力方法切り替え」的な感じで検索して頂くと、該当するショートカットが表示されます。
カーソル重ねると鉛筆マークが出てくるので、そこを押してショートカットキーの追加を行います。

僕は、`検索キー + space`にしました。
検索キーはchromeos独自なものなので、他のアプリ等に占領されることは無いですからね。


## 最後に
chromebookでus配列のキーボードを使用して、vscodeでcodeを書く環境がこれで整いました。
chromebook + us配列キーボードで何か困っている部分がありましたら、お気軽にお尋ねください。
良いchromebook Lifeを！！
知ってた？vscodeでダミーテキストを爆速で用意する

先日vscodeで簡単にダミーテキストを生成する方法を知りました…。
ちょっとしたダミーテキストがほしいと思った時に便利です！

:::note
ダミーテキストは英語のみになるので日本語にしたい場合は。別のプラグインを利用するなどの工夫が必要です！
:::

## vscodeでダミーテキストを生成する方法
vscodeで`lorem`と打ち込んで`tab`を押すと英語のダミーテキストを出すことができます！

```html
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Maiores, incidunt. Nemo pariatur numquam iusto nulla unde doloribus perspiciatis esse? Tenetur est non neque repellat ut necessitatibus impedit eligendi, possimus delectus!</p>
```

`lorem`の後に数字を続けることで生成する文字列の文字数を指定することができます！

`lorem20`と打ち込むと下記の文字列が表示されます！

```html
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere, blanditiis alias. Quaerat odio, deserunt rem ut corrupti cupiditate dolorem tempora.
```

タグを生成してその中にダミーテキストを入れることも可能です！

`p*5>lorem20`

```html
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere, blanditiis alias. Quaerat odio, deserunt rem ut corrupti cupiditate dolorem tempora.</p>
<p>Architecto illum alias nulla, nostrum suscipit at? Laudantium officiis laboriosam enim maxime molestiae? Aperiam facilis laudantium quo! Itaque, quis fugit.</p>
<p>Ut, nesciunt minima repudiandae nam sint modi autem similique. Voluptates quod asperiores debitis necessitatibus tempora dignissimos ab soluta, doloribus laudantium.</p>
<p>Ducimus quae, tenetur distinctio laborum aliquam suscipit illo perspiciatis? Voluptatibus atque quisquam praesentium aut! Ipsam saepe ipsa eaque magni id.</p>
<p>Quis saepe commodi, doloribus incidunt nobis at excepturi magnam cum vero culpa deserunt sunt autem architecto, nesciunt velit non a?</p>
```

英語だけになりますが、これだけのダミーテキストを生成するのは意外に大変だと思います！
少しのテクニックで時間を節約できると思うのでぜひ覚えておいてください！
Promise JavaScript

## Terminology

- CallStack
- Task queue
- Promise


## 関数実行順番

実行順番について勘違いしていたのでまとめる



1. orderExecutor 呼ばれてCallStack に入る
2. orderExecutorがCallStackから出る
3. thenがTask queueに入る
4. `console.log('2')`呼ばれてCallStack に入る
5. `console.log('2')`がCallStackから出る
6. CallStackがEmptyなったのでthenがTask queueからCallStackに入る
7. thenが実行される

```javascript:promise.js

function orderExecutor(resolve, reject) {
    console.log('1'); // 1
    resolve('3');
}
let orderPizza = new Promise(orderExecutor);
orderPizza.then(function (value) {
    console.log(value); // 3
});
console.log('2'); // 2

// 1, 2, 3
```

## Reference 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth

https://www.youtube.com/watch?v=eiC58R16hb8&t=518s
【応用情報技術者試験】21.ビジネスインダストリ

自分用メモです。

## 1. ビジネスシステム

### XBRL
- 財務報告用の情報の作成・流通・利用ができるように標準化した規約であり，適用業務パッケージやプラットフォームに依存せずに財務情報の利用が可能となる。

### IoTがもたらす効果
|用語|説明|
|---|---|
|監視 | 機械の温度や振動データをセンサーで集めて，インターネットを経由してクラウドシステム上のサーバに蓄積する。|
|制御 | 機械に対して，保守員が遠隔地の保守センターからインターネットを経由して，機器の電源のオン・オフなどの操作命令を送信する。|
|最適化 | クラウドシステム上に常時収集されている機械の稼働情報を基に，機械の故障検知時に，保守員が故障部位を分析して特定する。|
|自律化 | クラウドサービスを介して，機械同土が互いの状態を常時監視・分析し，人手を介すことなく目標に合わせた協調動作を自動で行う。|

### デジタルツイン
- デジタル空間に現実世界と同等な世界を，様々なセンサーで収集したデータを用いて構築し，現実世界では実施できないようなシミュレーションを行うこと
- 各種センサーを取り付けた航空機のエンジンから飛行中に収集したデータを分析し，仮想空間に構築したエンジンのモデルに反映してシミュレーションを行うことによって，各パーツの消耗状況や交換時期を正確に予測できるようになる。このように産業機器などにIoT技術を活用し，現実世界や物理的現象をリアルタイムに仮想空間で忠実に再現することを表したものはどれか。

### サイバーフィジカルシステム（CPS）
- 現実世界の都市の構造や活動状況のデータによって仮想世界を構築し，災害の発生や時間軸を自由に操作して，現実世界では実現できないシミュレーションを行う。
- 現実世界のデータを収集し，仮想世界で分析・加工して，現実世界側にリアルタイムにフィードバックすることによって，付加価値を創造する仕組み

### EDINET（Electronic Disclosure for Investors' Network）
- 金融庁が行政サービスの一環として提供している，金融商品取引法に基づく有価証券報告書等の開示書類に関する電子開示システム

### スマートグリッド
- 通信と情報処理技術によって，発電と電力消費を総合的に制御し，再生可能エネルギーの活用，安定的な電力供給，最適な需給調整を図るシステム

### VICS（Vehicle Information and Communication System：道路交通情報通信システム）
- 道路上に設置したビーコン又はFM多重放送から情報を受信し，渋滞情報，事故情報，工事情報などを表示するシステム


## 2. エンジニアリングシステム

### 生産方式
|用語|説明|
|---|---|
|かんばん方式|中間在庫を極力減らすために，生産ラインにおいて，後工程が必要とする部品を自工程で生産できるように，必要な部品だけを前工程から調達する。|
|リーン生産方式||
|セル生産方式|部品の組立てから完成検査まで，ほとんどの工程を1人又は数人で作業する。|

### MRP
- 製品の基準生産計画を基に，部品の手配数量を算出する。

### PDM（Product Data Management）
- 図面・部品構成データ，仕様書データなどの設計及び開発の段階で発生する情報を一元管理することによって，設計業務及び開発業務の効率を向上させる。


## 3. e-ビジネス

### RFID
- 極小の集積回路にアンテナを組み合わせたもので電子荷札に利用され，無線自動認識技術によって対象の識別や位置確認などができる。
- 汚れに強く，梱(こん)包の外からも記録された情報を読むことができる。

### BtoC
- バーチャルモール

### アグリゲーションサービス
- 分散的に存在する事業者，個人や機能への一括的なアクセスを顧客に提供し，比較，まとめ，統一的な制御，最適な組合せなどワンストップでのサービス提供を可能にするサービス

### ロングテール
- インターネットショッピングで売上の全体に対して，あまり売れない商品の売上合計の占める割合が無視できない割合になっていることを指すもの

### クラウドソーシング
- 発注者がインターネット上で発注対象の業務内容や発注条件を告知し，受注者を募集する。

### EDI
- ネットワークを介して，商取引のためのデータをコンピュータ(端末を含む)間で標準的な規約に基づいて交換することである。

|規約|規定されるべきもの|
|---|---|
|情報伝達規約|伝送制御手順|
|情報表現規約|メッセージの形式|
|業務運用規約|システムの運用時間|
|取引基本規約|企業間の取引の契約内容|

情報銀行
- 事業者が，個人との契約などに基づき個人情報を預託され，当該個人の指示又は指定した条件に基づき，データを他の事業者に提供できるようにする取組


4. 民生機器

エッジコンピューティング
- 演算処理のリソースをセンサー端末の近傍に置くことによって，アプリケーション処理の低遅延化や通信トラフィックの最適化を行う。

### センサー端末
|用語|説明|
|---|---|
|ジャイロセンサー|機体を常に水平に保つ姿勢制御のために使われるセンサー|


## 5. 産業機器

### スマートファクトリー
|用語|説明|
|---|---|
|マシンビジョン|従来の人間の目視検査を自動化し，検査効率を向上させる。|
setup Ubuntu 22.04 as vagrant Host OS

# TL;DR

* install Ubuntu 22.04 (Host OS)
* install AMD Radeon Graphics Driver (for Ryzen 9 9900X)
* install VirtualBox
* vagrant install
* add Rocky Linux 9 (Guest OS)

## Hardware

* CPU:Ryzen 9 9900X (ZEN 5 Gen.)
* M/B:Gigabyte B650E AORUS ELITE X AX ICE
* GPU: None (AMD Radeon Graphics with CPU)

# install Ubuntu 22.04 (Host OS)

Desktop imageを取得してインストール実行した。

https://releases.ubuntu.com/jammy/

## apt update

```
sudo su -
apt update
apt list --upgradable
apt upgrade
```

## firewalld

```
ufw status
```

→inactive

```
ip addr
```

→今回はホストOSに向けた同一スイッチからのSSH接続用に開けるので、enp7s0のinetをメモする

SSHとHTTPだけ開けておく場合はこんな感じ
```
ufw enable

ufw default deny
ufw allow from 192.168.1.0/24 to any port 22
ufw allow from 192.168.1.0/24 to any port 80

ufw reload
```

https://qiita.com/RyoMa_0923/items/681f86196997bea236f0

## openssh

```
apt install openssh-server
```

# install AMD Radeon Graphics Driver (for Ryzen 9 9900X)

https://www.amd.com/en/support/download/linux-drivers.html

```
wget https://repo.radeon.com/amdgpu-install/6.1.3/ubuntu/jammy/amdgpu-install_6.1.60103-1_all.deb
dpkg -i ./amdgpu-install_6.1.60103-1_all.deb
```

# VirtualBox

## prepare

```
apt install build-essential
apt install gcc-12
```

gcc-12を入れるのはエラー回避のため

https://qiita.com/kawamo55/items/99abe4fe8bb260075b55


## install

ダウンロードページ

https://www.oracle.com/virtualization/technologies/vm/downloads/virtualbox-downloads.html

```
wget https://download.virtualbox.org/virtualbox/7.0.20/virtualbox-7.0_7.0.20-163906~Ubuntu~jammy_amd64.deb
apt install ./virtualbox-7.0_7.0.20-163906~Ubuntu~jammy_amd64.deb
/sbin/vboxconfig
```

# vagrant

## install

https://developer.hashicorp.com/vagrant/install

```
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vagrant
```

## rocky linux 9 VM

https://portal.cloud.hashicorp.com/vagrant/discover?query=rocky

```
mkdir -p vms/rocky9
cd vms/rocky9
vagrant box add bento/rockylinux-9

vagrant init bento/rockylinux-9 --box-version 202407.23.0
vagrant up
vagrant ssh
```
Oracle Database Vaultを導入するメリットは？

Oracle Database Vaultを導入するメリットは、主にセキュリティとコンプライアンスの強化にあります。以下に主要な利点を挙げます。

**1. アクセス制御の強化:**
- 特定のデータや機能に対するアクセスを、DBA（データベース管理者）を含むユーザーでも制限可能です。これにより、システム内部の特権ユーザーによる不正なデータアクセスを防ぎます。

**2. コンプライアンス対応:**
- 多くの業界で要求されるデータ保護やプライバシー関連の法令（例: GDPR、PCI DSS、SOX法）への準拠を支援します。機密データへのアクセスを厳格に管理することで、監査やセキュリティの基準に適合しやすくなります。

**3. 特権ユーザーの制限:**
- 特権を持つDBAや開発者などが、必要以上にデータにアクセスすることを防ぎます。業務に関連しない操作を制限することで、内部からの脅威に対するセキュリティを高めます。

**4. リアルタイム監査とアラート:**
- 誰が、どのデータにアクセスしようとしたかをリアルタイムで監視し、異常な操作や不正なアクセス試行に対してアラートを出すことが可能です。

**5. データ分離:**
- アプリケーションやユーザーがアクセスできるデータを厳密に分離することができます。これにより、必要なデータのみをユーザーに公開し、余計な情報が見えないように制御できます。

**6. 最小限のシステム変更で導入可能:**
- Oracle Database Vaultは、既存のOracle Databaseに組み込む形で導入可能なため、大規模なシステム変更を伴わずにセキュリティ強化を実現できます。

このように、Oracle Database Vaultは、内部からの脅威に対する防御を強化し、コンプライアンス要件を満たすための効果的なソリューションです。
Material UIの無料テンプレートであるDashboardを実装する方法


初投稿です。Dashboardの実装に大変苦労したため、備忘録として作成しました。

## はじめに

この記事はMaterial UIのインストールから無料テンプレートであるDashboardを実装するまでの手順を書いたものです。
また、この方法は2024年9月22日時点においての実装方法です。今後実装方法が変わり、本記事のやり方では実装できなくなる可能性があることをご了承ください。
それでは、始めていきます。


## Material UIのインストール

以下のコードを順番に実行します。


```
npm install @mui/material @emotion/react @emotion/styled
npm install @fontsource/roboto
npm install @mui/icons-material
```
<br />


## プロジェクトの下準備

Material UIの公式サイトにあるサンプルプロジェクトを実装します。サンプルは[Example projects](https://mui.com/material-ui/getting-started/example-projects/) にある「Reactアプリを作成する」のJavaScriptバージョンを使用します。
まず、https://github.com/mui/material-ui/tree/master/examples/material-ui-cra/src に存在する4つのファイルのコードをコピペしていきます。ProTip.jsとtheme.jsは自分でファイルを作る必要があります。
<br />


## テンプレートの実装

次に、https://github.com/mui/material-ui/tree/v6.1.1/docs/data/material/getting-started/templates/dashboard へアクセスし、「.(ドット)キー」を押します。すると以下のような画面になるかと思います。

![MaterialUIPrev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891997/2606fcb9-11d5-740d-c88c-dfedaee2c628.png)
<br />
<br />

そこから「dashboard」と書かれているものを探し、右クリックすると、「ダウンロード」と書かれている項目があるかと思います。

![MaterialUIPrev2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891997/755c10fb-03de-7b8a-1b50-472ebe76d2d1.png)
<br />
<br />

そこから「ダウンロード」をクリックし、ファイルをダウンロードしてください。保存先は「src」フォルダです。
すると様々なエラーが表示されると思います。次はこのエラーを直していきます。
<br />


## エラーの修正

### shared-themeのダウンロード

まず最初のエラーは「shared-themeが見当たらないよ」というエラーなのでこれを直します。
先ほどdashboardをダウンロードしたときと同じように、「shared-theme」と書かれているものを探し、ダウンロードします。保存の場所も同じく「src」フォルダです。
<br />


### 必要なパッケージのインストール

次は「必要なパッケージが入っていない」というエラーなのでこれを直します。dashboardのreadmeに書かれているパッケージをインストールします。事前にインストールしたものも混ざっていますが、念のため全部インストールしときましょう。

```
npm install @mui/material @mui/icons-material @emotion/styled @emotion/react @mui/x-charts
```
<br />
そのほか、インストールが必要なパッケージとそのコードです。

```
npm install dayjs @mui/x-date-pickers @mui/x-data-grid @mui/x-tree-view
```
<br />

これでパッケージが足りない系のエラーは消えたかと思います。
後は私が遭遇したエラーを以下に記します。
<br />

## その他のエラー

### LocalizationProviderが解決されない

対処方法：`dashboard/components/CustomDatePicker.js`の8行目にある行を度書き直したら直りました。もしくは、一度インポート元である`node_modules/@mui/x-date-pickers/LocalizationProvider`を開いたから直ったのかもしれません。正直このエラーは私もよく分かりませんでした。
<br />


### import { animated }のエラー

対処方法：animatedをインポートするコードを以下のように書き換えると治りました。

```
import { animated } from '@react-spring/web';
```
<br />

## 参考
Material UI 公式サイト
https://mui.com/material-ui/getting-started/
インストール方法
https://mui.com/material-ui/getting-started/installation/
使い方
https://mui.com/material-ui/getting-started/usage/
プロジェクトの作成
https://mui.com/material-ui/getting-started/example-projects/
テンプレート一覧
https://mui.com/material-ui/getting-started/templates/
ESP32 WROVER CAMで画像識別ST7735バウンディングボックス

ESP32 WROVER CAMで画像データを収集します。EdgeImpulseにてアノテーションを行い画像モデルを作成します。今回は試験的に数十件だけグー、チョキ、パーの画像を撮ります。作成した画像モデルを元にESP32 WROVER CAMにて画像識別を行うテストです。テスト中は撮影画像をリアルタイムでLCD ST7735に映し画像識別に反応したらバウンディングボックスを黄色で表示させます。

![wrover_edgeimpulse_ST7735.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/efdb58f6-5682-2ecd-9eed-6497a37ac8ce.png)



* 前回はテスト中の画像をブラウザで表示しました。

https://qiita.com/hassy131/items/fa726793a987c9f1db93

ソースコードピックアップ
# #include
* ST7735を使用するためにTFT_eSPI.hを使う
* グーチョキパーのモデル　esp32_pachokigu_inferencing.h
```c++
#include <Arduino.h>
#include <TFT_eSPI.h> // TFTディスプレイを制御するライブラリ
#include <SPI.h>
#include <esp32_pachokigu_inferencing.h>  // Edge Impulse推論用にパーチョキグーのモデル
#include "edge-impulse-sdk/dsp/image/image.hpp" 
#include "esp_camera.h" // ESP32カメラを制御するためのライブラリ
```
# TFT_eSPI.h関連
* TFT_eSPI\User_Setup_Select.hの修正
```c++
<User_Setup.h> //アンコメント
```
* user_setup.hの修正
```c++
#define ST7735_DRIVER
...
//接続時のGPIOをを指定
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS   15  
#define TFT_DC   12 
#define TFT_RST  33 

```
# バウンディングボックス
void loop()の中で、
```c++
....
  bool bb_found = result.bounding_boxes[0].value > 0; // 最初のバウンディングボックスが見つかったかをチェック

  for (size_t ix = 0; ix < result.bounding_boxes_count; ix++) { // バウンディングボックスの数だけループ
    auto bb = result.bounding_boxes[ix]; // バウンディングボックスを取得
    if (bb.value == 0) { // 値が0ならスキップ
      continue; // 次のループに進む
    }

    /* Create Coordinates and Size for Bounding Boxes */
    x = bb.x; // X座標を設定
    y = bb.y; // Y座標を設定
    w = bb.width * 6; // 幅を6倍にスケーリング
    h = bb.height * 5; // 高さを5倍にスケーリング

    /* Checking Sizes */
    ei_printf("BB Coord [ x: %u, y: %u, width: %u, height: %u ]\n",  bb.x, bb.y, bb.width, bb.height); // バウンディングボックスのサイズをシリアル出力

    /* Draw Bounding Boxes in Display */
    tft.drawRect(x, y, w, h, TFT_GREEN); // バウンディングボックスを緑で描画
    tft.setCursor(x, y); // カーソル位置をバウンディングボックスの位置に設定
    tft.setTextColor(TFT_GREEN); // テキスト色を緑に設定
    tft.setTextFont(4); // テキストフォントを4に設定
    tft.println(bb.label); // ラベルを表示
  }
....
```
# 結果
guと出て黄色のバウンディングボックスが出ています。学習データが少ないのでもっと多くする必要があります。WROVERでは役不足かも知れません。
![20240811_200556 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806156/26a94531-9b0a-08b5-27bc-d5e7bd3ef30d.gif)
ESP32: GATT通信でLチカ

スケッチ例を参考にしました。

## プログラム

```text:GATT_LED.ino
// ---------------------------------------------------------------
/*
	GATT_LED.ino

						Sep/22/2024
*/
// ---------------------------------------------------------------
#include <ArduinoBLE.h>

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Bluetooth® Low Energy LED Service

// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

#define LED_BUILTIN 13
const int ledPin = LED_BUILTIN; // pin to use for the LED

int icount = 0;
// ---------------------------------------------------------------
void setup() {
	Serial.begin(115200);
	while (!Serial);

	pinMode(ledPin, OUTPUT);

	if (!BLE.begin()) {
		Serial.println("starting Bluetooth® Low Energy module failed!");

		while (1);
	}

	BLE.setLocalName("GATT-LED");
	BLE.setAdvertisedService(ledService);

	ledService.addCharacteristic(switchCharacteristic);

	BLE.addService(ledService);

	switchCharacteristic.writeValue(0);

	BLE.advertise();

	Serial.println("BLE LED Peripheral");
}

// ---------------------------------------------------------------
void loop() {
	Serial.print("*** loop *** ");
	Serial.println(icount);
	icount++;
	delay(1000);
	// listen for Bluetooth® Low Energy peripherals to connect:
	BLEDevice central = BLE.central();

	// if a central is connected to peripheral:
	if (central) {
		Serial.print("Connected to central: ");
		// print the central's MAC address:
		Serial.println(central.address());

		// while the central is still connected to peripheral:
		while (central.connected()) {
			// if the remote device wrote to the characteristic,
			// use the value to control the LED:
			if (switchCharacteristic.written()) {
				Serial.println(switchCharacteristic.value());
				if (switchCharacteristic.value()) {	 // any value other than 0
					Serial.println("LED on");
					digitalWrite(ledPin, HIGH);				 // will turn the LED on
				} else {															// a 0 value
					Serial.println(F("LED off"));
					digitalWrite(ledPin, LOW);					// will turn the LED off
				}
			}
		}

		// when the central disconnects, print it out:
		Serial.print(F("Disconnected from central: "));
		Serial.println(central.address());
	}
}

// ---------------------------------------------------------------
```

## Arduino IDE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/fb0d4920-9823-aba0-b09d-7b200c2282f8.png)

## Android の LightBlue から信号を送信

LED を ON にする
![led_on.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4d33ff26-c1e4-ce98-5d2a-da5f32b57784.png)

LED を OFF にする
![led_off.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/9420aabc-bd0f-72e8-7b44-676652b3e4c7.png)
[Common Frame] 共通フレーム

# 企画プロセス

# 要件定義プロセス

# 参考リンク
- [令和2秋62_企画](https://www.ap-siken.com/kakomon/02_aki/q62.html)
- [令和元秋65_要件定義](https://www.ap-siken.com/kakomon/01_aki/q65.html)
EVM(Earned Value Management)とは。何が嬉しいのか

## EVMとは
- プロジェクトを管理する時に、タスクの完了率だけじゃなく、予算の消化率も管理すること

## 何が嬉しいのか
- 予算を常に把握できる
    - 「タスクの完了率は遅れてるけど、予算は余っているので、人員を追加しましょう」みたいな話がノータイムでできる

## 何が嬉しくないのか
- タスクの完了率だけじゃなく、予算の消化率も計算するので、以下のデメリットが生まれる
    - 予算消化率の計算作業が手間
        - 自動化するにしても、自動化を確立するまでが手間
    - 予算を厳密に管理しなくていい時は、ノイズの情報になる

## 用語
### PV(Planed Value)
- ある時点でかかっているはずの費用(予定)
    - 「どのタスクにいくらかかるか」を事前に割り当ててあるので、「その時点で完了しているはずのタスク」も費用から計算できる
    - ITのプロジェクトだと、「費用=人件費」と考えると理解しやすい

### EV(Earned Value)
- ある時点で完了したタスク(実績)から、求めた費用(予定)
    - 「今日の時点でタスクAまで終わっている。タスクAに割り当てた予算は1万円だから、今日の時点で1万円費用がかかっているはずだ」という風に求める

### AC(Actual Cost)
- ある時点でかかっている費用(実績)

### SV(Schedule Variance)
- スケジュール不一致
    - 「スケジュールが予定より進んでいる or 遅れている」がわかる数値
- EV - PVで求める
- SV > 0 なら予定より進んでいる
- SV < 0 なら予定より遅れている

#### 私がつまづいたところ
- 仮にEVとPVで差があっても、タスクあたりの予算見積もりが間違っていただけの場合、スケジュールの指標にはならないのでは？
    - SVの考え方はタスクに紐づいた予算が正確であることを前提として、予算を比較することで、タスク完了率の予定と実績を比べる考え方なので

#### つまづきが解消された理由(勘違いしていたところ)
- EVはあくまで「プロジェクト開始時(PV決定時)」に、タスクに割り当てた予算をもとに計算するもの
    - 「このタスクに思ったより予算がかかった」という事態は、反映されない
    - その事態はACに反映される

### CV(Cost Variance)
- 費用不一致
    - 「費用が予定よりかかっている or かかっていない」がわかる数値
- EV - ACで求める
- CV > 0なら予定よりかかっていない
- CV < 0なら予定よりかかっている

### SPI(Schedule performance index)
- スケジュールパフォーマンス指標
    - 「スケジュールが予定より進んでいる or 遅れている」がわかる数値
- EV / PVで求める
- SPI > 0なら予定より進んでいる
- SPI < 0なら予定より遅れている
- SVとの使い分け方は分からない

### CPI(Cost performance index)
- 費用パフォーマンス指標
    - 「費用が予定よりかかっている or かかっていない」がわかる数値
- EV / ACで求める
- CPI < 0なら予定よりかかっている
- CPI > 0なら予定よりかかっていない
- CVとの使い分け方は分からない

## 運用の例

### 想定するプロジェクト
- プロジェクト期間は1/1~1/30
- 作業者はAさん1人
- タスクはタスク1~タスク30まである
    - つまり1日につき、1タスク終わる予定
- 1日の費用(Aさんの人件費)は1万円
    - つまり1つのタスクにつき、1万円の費用がかかる予定
- 残業代は、時間内労働と同じ人件費がかかる
    - 1日分の残業をしたら、1万円の人件費がかかる

### 1/15時点での、タスク完了率・予算消化率の判断
- タスク10まで終わっているとする
- Aさんは1日分残業したとする

#### PV
- 15万円
    - タスク15まで進んでいる予定なので

#### EV
- 10万円
    - タスク10まで終わっているので

#### AC
- 16万円
    - Aさんは15日の時間内労働と、1日分の残業をしたので

#### SV
- 10(EV) - 15(PV) = -5
    - 予定より遅れている

#### CV
- 10(EV) - 16(AC) = -6
    - 予定より費用がかかっている

#### SPI
- 10(EV) / 15(PV) = 0.67
    - 予定より遅れている

#### CPI
- 10(EV) / 16(AC) = 0.63
    - 予定より費用がかかっている

1/15時点での予算と、1/15時点で完了したタスクに割り当てられた予算を比較して、
スケジュールが予定通りどうかを判断するのが、ややこしいポイントだなと思いました
(予算を起点にしているのに、スケジュールの判断に直結しているのは、結局タスクの完了率)

タスク完了率・予算・実際かかった費用・時間軸の4つを材料に、進捗率と予算消化率を判断するのが、EVMの肝なんだと思いました

## 再結論
- タスクの完了率だけじゃなく、予算の管理もするのがEVM
    - 一般的なプロジェクト管理は、「1/15までにタスク10まで終わりました」だけを管理する
    - でもEVMは予算消化率も管理する
- 厳密に予算を管理する、受託の案件とかだと、便利かもしれないと思った
- 逆に、細かく人月あたりの予算を管理してない自社サービスの社内案件とかだと、過剰かもしれないと思った

## 参考文献
- https://backlog.com/ja/blog/what-is-evm/
- https://www.m-keiei.jp/musashinocolumn/evm
[Review]

# 一覧
|名称|詳細|
|:--|:--|
|ウォークスルー|レビュー対象（成果物）の作成者が説明者になるレビュー|
|インスペクション|レビュー対象（成果物）の作成者以外はモデレータとして会議進行を行うレビュー<br>公式なチェックシートにより記録・分析する|
|パスアラウンド|レビュー対象（成果物）を複数のレビュアーが個別にレビュー|

# 参考リンク
- [令和元秋48_インスペクション](https://www.ap-siken.com/kakomon/01_aki/q48.html)
- [令和2秋49_ウォークスルー](https://www.ap-siken.com/kakomon/02_aki/q58.html)
SAP Continuous Influence for SAP S/4HANA Cloud Public Editionの概要について

# 概要
受託開発企業で働くfussasyといいます。普段は、SAP BTP（PaaS）上でSAP Fioriアプリケーション開発をしています。最近のSAP S/4HANA導入において、SAP S/4HANA Cloud Public Editionを選択される場面が多くなってきているように思えます。その中で、クラウド製品に対して、顧客が直接改善を提案可能なサービスがSAP社より提供されているとのことなので、情報整理をさせていただきました。

# SAP Continuous Influenceの特徴について
![スクリーンショット 2024-09-21 230327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1727556/e18c983a-be77-04a6-b324-b736ef771151.png)
### SAP Continuous Influenceの説明ドキュメント
**【SAP Continuous Influence for SAP S/4HANA Cloud Public Edition】**

https://pages.community.sap.com/topics/s4hana-cloud/continuous-influence

**【PDFドキュメント：SAP Continuous Influence for SAP S/4HANA Cloud Public Edition】**
https://help.sap.com/doc/fdd65c04def84724871f70fbdce9446b/1.0/en-US/SAP_Customer_Influence_for_SAP_S4HANA_Cloud_User_Documentation.pdf

### SAP Continuous Influenceの特徴

SAP Continuous Influenceは、SAP製品の開発プロセスに顧客が継続的に参加し、改善提案を直接開発チームに届けることができるプログラムです。従来のSAP Customer Influenceプログラムが特定のプロジェクトやリリースにおける改善提案に焦点を当てていたのに対し、Continuous Influenceは製品ライフサイクル全体を通して顧客の声を取り入れることを目指しています。主な特徴については、以下の通りです。

- 継続的な改善提案：顧客はいつでも、製品に関する改善提案をSAP Continuous Influenceポータルを通じて提出できます。
- 直接的なフィードバック：提案は直接開発チームに届き、評価・検討されます。
- 透明性：提案のステータスや進捗状況はポータル上で確認でき、顧客は開発プロセスへの関与を実感できます。
- コミュニティ：顧客同士が意見交換や投票を通じて、提案の優先順位付けや改善内容の具体化に貢献できます。

SAP Continuous Influenceは、顧客の声を製品開発に反映させることで、顧客満足度の向上と製品の競争力強化を目指しています。顧客は、自らのニーズや要望を直接開発チームに伝え、製品の進化に貢献できる貴重な機会を得ることができます。SAP S/4HANA Cloudなどのクラウド製品では、Continuous Influenceを通じて顧客の声を迅速に取り入れ、継続的な機能改善や新機能開発につなげることが重要視されています。



# SAP Continuous Influenceのメリット・デメリットと費用について
SAP Continuous InfluenceはSAP S/4HANA Cloudなどのクラウド製品を対象としています。
### SAP Continuous Influenceのメリット・デメリット
- メリット
・顧客の声を製品開発に直接反映できる。
・製品に対する愛着やロイヤリティが高まる。
・製品改善のスピードが向上する。
・顧客満足度が向上する。

- デメリット
・提案が必ずしも採用されるとは限らない。
・提案内容によっては時間がかかる場合がある。
・顧客側の積極的な参加が必要。

### SAP Continuous Influenceの費用
SAP Continuous Influenceの利用は、原則無料です。ただし、一部の機能やサービスについては、追加料金が発生する場合もあります。

# SAP Continuous Influenceのユースケースについて
SAP Continuous Influenceを利用する機会のうち、代表的なものを以下に挙げます。
- 特定機能の改善提案
既存機能の使い勝手向上：特定画面のUI改善、操作手順の簡素化、エラーメッセージの分かりやすさ向上など。
新機能の追加要望： 特定業務に対応する機能の追加、レポート出力項目の拡充、外部システムとの連携機能強化など。

- 業務プロセス改善提案
特定業務フローの効率化：承認プロセスの簡素化、データ入力作業の自動化、業務関連情報の可視化向上など。
新しい業務シナリオへの対応：法改正や市場変化に対応するための機能追加や業務フロー変更など。

- その他提案
パフォーマンス改善：システム処理速度の向上、大量データ処理時の安定性向上など。
セキュリティ強化：アクセス制御の強化、脆弱性対策など。
ユーザビリティ向上：多言語対応、アクセシビリティ向上など。

例えば、SAP S/4HANA Cloudであれば、請求書処理の自動化機能改善、在庫管理画面のUI改善、新しい会計基準への対応といったものが考えられます。

# おわりに
SAP Continuous Influenceは、顧客とSAPが共に製品を進化させていくための強力なツールです。顧客は積極的に活用することで、自社の業務効率向上や競争力強化に貢献することができます。
私自身は直接的に利用する機会は少ない気もしますが、SAPシステム導入のお仕事をしている以上、SAPが提供するサービスについては各々しっかりと把握しておきたいものですね。
【備忘録】SIGNATE Cup 2024に参加してみた

## 目次
[0.結論](#0-結論)
[1.コンペティション概要](#1-コンペティション概要)
[2.前処理](#2-前処理)
[3.モデリング](#3-モデリング)
[4.おわりに](#4-おわりに)

### 0. 結論
[SIGNATE Cup2024](https://signate.jp/competitions/1376)に参加。
順位：558 位 / 1,226人投稿
なかなか順位を上げることができなかったものの、AIコンペ完走することができ、多くの学びがあった。

### 1. コンペティション概要
旅行会社の保有する顧客データ（属性や志向、営業担当との接触履歴等）を元に、旅行パッケージの成約率を予測するモデルを構築するコンペティション。

### 2. 前処理
|特徴量|処理概要|Nan値埋め|
|:-|:-|:-|
| Age<br>(顧客の年齢) |①漢数字を数字に変換<br>②全角の数字を半角に変換<br>③〇代は〇5に変換（例.20代→25、10代のみ18に変換）|平均値(整数)|
| DurationOfPitch<br>(営業担当者による顧客への売り込み時間)|①分数を秒数へ変換（例.5→300）|平均値(整数)|
| Gender<br>(顧客の性別)|①表記ゆれの修正（例.fe male→female）|-|
| NumberOfFollowups<br>(セールストーク後に営業担当者が行ったフォローアップの合計数)|①外れ値処理(3桁値を100で割って1桁にする)（例.500→5）|平均値(整数)| 
| ProductPitched<br>(営業担当者による商品の売り込み)|①名寄せ処理（例.klng→king）|-|
| NumberOfTrips<br>(顧客の年間旅行数)|①年での回数に修正（例.「年に1回→1」|平均値(整数)|
| Designation<br>(現在の組織における顧客の指定)|①名寄せ処理（例.m@nager→manager）|-|
| MonthlyIncome<br>(顧客の月収)|①文字列値含め数値型(int)に修正（例.月収30万円→300000）|平均値(整数)|
| customer_info<br>(顧客の情報のメモ(婚姻状況や車の有無、旅行の子どもの同伴の有無について記載されている))|①区切り文字の統一化<br>②婚姻状況、車の有無、子供の人数に分割||

上記前処理における名寄せ処理について以下にサンプルを記載する。
```Python:
!pip install Levenshtein
from Levenshtein import ratio, distance

def find_closest_word_and_similarity_1(word, correct_words):
    if correct_words.size > 0:
        # 各単語とのLevenshtein類似度を計算
        similarities = [ratio(word, correct_word) for correct_word in correct_words]
        # 最大類似度の単語とその類似度を返す
        return correct_words[np.argmax(similarities)]
    else:
        return word

df1_test = pd.DataFrame({"word":["appli","banana","lennon","grap","おざなり"]})
df2_true = pd.DataFrame({"target":["grape", "apple", "banana", "lemon","なおざり"]})
df1_test['closest_word'] = df1_test['word'].apply(lambda x: find_closest_word_and_similarity_1(x, df2_true['target'].values))
```
上記スクリプトでは編集距離(Levenshtein Distance)を用い、正解の語句群へ誤字が含まれる語句群を参照することで誤字を訂正することとしています。

編集距離(Levenshtein Distance)については以下の記事が詳しいので、必要に応じてご確認下さい。
[編集距離(Levenshtein Distance)の計算方法・計算量を考える](https://qiita.com/sinchir0/items/02697cae7f960356eaba)


### 3. モデリング
モデリングには以下の６個及びそれらの出力を平均したものを利用しました。

①Random Forest
②AdaBoost
③Gradient Boosting
④XGBoost
⑤CatBoost
⑥LightGBM

平均して良い結果が出ていたのはCatBoostです。
しかし、木系のモデルでは分類に間違っていたサンプルに対して、出力平均を用いた結果では分類に成功していることもあり、アンサンブルの効果を実感しました。

また、本コンペの検討点の一つとして、不均衡データ(購入無：2992、購入有：497)の取り扱いが挙げられます。
今回は以下の記事を参考に対策としてアンダーサンプリング＋バギングを実施しました。
[機械学習の課題: 不均衡データへのアンダーサンプリング解決策](https://www.salesanalytics.co.jp/column/no00364/)

具体的にはモデリングの際に(購入無：497、購入有：497)のように多数クラスのサンプル数を少なく選定し、さらに選定の際にはランダム抽出を行なっています。
上記、アンダーサンプリング＋バギングを行うことで、識別境界がロバストとなることが今回の学びです。

### 4. おわりに
初めてAIコンペに参加してみました。

完走はできたものの、結果は振るわず。。。というものでした。

しかしながら、技術的な部分での学びは多く次回以降のコンペに対しても精力的に取り組みたいです！！

また、データ探索についても行なったので、他データを用いて同様のデータ探索を行なってみたいと思います。

長い文章を最後までお読みいただき、ありがとうございました！！