OmniAICreator/Qiita-1.07M huggingface dataset:
【個人開発】Ruby on Railsで勇者一行を作って魔王を討伐したい！

# ドラクエは、好きですか？
このメンバーで魔王倒したいとか、勇者一行に混ざりたいな〜とか。
皆様も人生で一度は考えたことありますよね？そうですよね。
僕もそう思いました。思い立って旅立ちました。冒険ですね。

# 私は勇者ではありません
初めまして、あやたかといいます。
2022年10月からプログラミングスクールに通ってRubyを中心に学習。
転職活動の後、C#を扱うエンジニアとなりました。
この記事を書いてる時点で、エンジニア10日目です。赤ちゃんですね。

仕事とは別で個人で開発をしようと考え、アウトプットの一環として
開発備忘録的なものを書いていきます。

# 魔王討伐のパーティって楽しそう
常日頃考えています。妄想の日々ですね。
ですが、私も30年生きてきたいい大人なので現実では出来ない事は重々承知しています。
というわけで、せっかく学んだRubyとRailsで作ろうと思います。
現実的にどこまで出来るかとか分からないので、目標を段階的に見ていきます。

# 自分のキャラを育ててステータスを上げ、職業や二つ名をつけたい
もう考えてるだけで楽しいですね。
自分の好きな名前のキャラ作って育てて、戦士だの魔法使いだのに転職させて、
くそかっこいい二つ名とか異名をつける。俗にいう a.k.a ですね。
とりあえずはこれを作ります。なんかいけそうですよね。

# 開発環境や使用技術（予定）
この辺り途中で必要なら随時追加していきます。
型にハマらない開発をします、そもそも型がない。
◆バックエンド
・Ruby 3.1.2
・Ruby on Rails 7.0.8
◆フロントエンド
・HTML
・CSS
・JavaScript
◆データベース
・PostgreSQL
◆その他
・Git
・画像生成API

# Little Braver
急にどうしたん？てならないでくださいね。
作りたいサービスの名前を忘れてました。一番大事。
「Little Braver」です。
BUMPから来てます。

# 来週のLittle Braverは！？ 「すいません、実はもう進めちゃってるの…」
そうなんです、なんか勢いで環境構築とかテーブルとか作っちゃったんですよね。
で、後から記事書こ！ってなったのです。
なので、しばらくは思い出しながら書いていきます、内容薄くなります。
ちなみにユーザー登録、キャラの登録まで実装しました。
次は何しよ。

# 最後に
記事書くのハードル高いよね。他の記事見たらめちゃしっかりしてるし。
でも書き続けたら上手になるやろし、見やすく出来るやろし、
今は見出ししか出来へんけどマークダウンも出来るやろし。
その部分の成長も見守って頂けたら。

## ここまで読んでいただきありがとうございました。また次回！
IT用語に「ミニマムサクセス」はなさそうだが、あってもいい感じ

# はじめに
ほぼほぼ1年前の2023年2月19日、その数日前に起きたJAXAの次期国産基幹ロケットH3初号機が2023年2月17日の発射シーケンス中に「フェールセーフ」して発射が中断した状況にかこつけて、[IT用語「フェールセーフ」について記事](https://qiita.com/mylifewithviolin/items/bd4fa6ca7551f9a62d11)を書いたので、今回のSLIM（スリム: Smart Lander for Investigating Moon）月面着陸成功をお祝いして、太陽電池が作動しない状況をめぐって報道されている「ミニマムサクセス」について確認してみました。

## 「ミニマムサクセス」
[goo辞書 ミニマムサクセス（minimum success） とは？](https://dictionary.goo.ne.jp/word/%E3%82%A8%E3%82%AD%E3%82%B9%E3%83%88%E3%83%A9%E3%82%B5%E3%82%AF%E3%82%BB%E3%82%B9/#jn-297419)
>主に宇宙科学の分野における、目標に対する達成基準の一。難易度により設定された三段階の基準のうち、第一段階にあたり、最低限の目標を達成すること。→フルサクセス →エキストラサクセス

## 「サクセスクライテリア」
[サクセスクライテリア（成功基準）とは？ 4つの宇宙開発事例で考える技術開発における成功と失敗- sorabatake](https://sorabatake.jp/32411/)

>JAXAが公開している「成功基準（サクセスクライテリア）作成ガイドライン」では、「成功基準とは、『ミッション目標に対する達成の度合いを計るための基準』である。」と定義しています。

## JAXA 成功基準（サクセスクライテリア）作成ガイドライン 
https://ssl.tksc.jaxa.jp/isas-rev/koubo-support-pages/kogata2019/document/BDB-08012D.pdf

>アウトプット目標のサクセスクライテリアとしては、フルサクセスの設定が基本であるが、必要に応じてミニマムサクセス、エクストラサクセスも設定することができる。サクセスレベルの目安は以下の通りである。
>
>① フルサクセス【必須】
予定していた要求を満たし、計画通りの成果を得ること。
>② ミニマムサクセス【任意】
挑戦的なミッション目標を設定するため、独立した複数ミッション機器を搭載する場合等では、その一部の機能喪失が生じた場合でもクリアできる最低限の目標として設定することができる。なお、過剰に保守的な目標にならないよう注意が必要である。
>③ エクストラサクセス【任意】
フルサクセスを達成した上で、さらにそれを上回る成果を得ること。ただし、単に目標を設定するだけではなく、上回る成果を得るために克服すべき課題とその対策を明らかにする必要がある。

## JAXA ミッション要求書作成ガイドライン
https://ssl.tksc.jaxa.jp/isas-rev/koubo-support-pages/kogata2019/document/BDB-09009A.pdf

# まとめ
今回のSLIM（スリム）月面着陸ミッションにおいては、太陽電池電源の喪失によりミッション時間が大幅に制限されるリスクがありますが、下記の基準には該当しているということですね。

>② ミニマムサクセス【任意】
>一部の機能喪失が生じた場合でもクリアできる最低限の目標として設定

業務システムのリリースにおいては、隠れたる瑕疵を除いては正常稼働が基本線なので、「ミニマムサクセス」のような段階的成功基準は一般的ではない気がしますが、あった方がよい気がしました。

例えば、直接は内容が異なりますが、ぎりぎり炎上状態を消化（消火）して納期に間に合ったとかは、これは結果的には全機能正常稼働であれば「フルサクセス」、納期遅延が基準書許容値以内ではあったがギリギリセーフは「ミニマムサクセス」とかですかね。

世界５ヵ国目の月面着陸おめでとうございます！:tada:


https://qiita.com/OzoraKobo/items/8e4d9225100e5f00c139
aws ubuntu  コマンドラインとssh 接続

#### aws
```bash 
ssh -i "key.pem" public_ip
```

#### [nvm](https://github.com/nvm-sh/nvm)

```bash 
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 14
node -v
npm -v
```

#### [postgresql](https://www.postgresql.org/download/linux/ubuntu/)

```bash 
apt-get install 'postgresql-*'
sudo su
\passwd postgres
```

#### [ssh-keygen](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)

```bash 
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
cat /home/ubuntu/.ssh/id_rsa.pub
```

#### git clone

```bash 
sudo mkdir project
sudo chown ubuntu project/
cd project
git clone ssh-link
```

#### vim

```bash 
vim file.type
a
ESC
:wq
```

#### postgres データベースのエクスポート data output

```bash 
pg_dump -h ip -p 5432 -U username db_name > db.sql
```

#### sftp アップロード　ファイル

```bash 
sftp -i key.pem ubuntu@ip
put db.sql
```

#### postgres データベースへのインポート data input

```bash 
sudo chown postgres /home/ubuntu/db.sql
su postgres
psql -d db_name -f db.sql
```

#### screen 後台でのタスク　ランニング

```bash 
screen -r
screen -s task_name #new task
CTRL a c
npm run prod
CTRL a n #next task
# CTRL a p #preview
```

:::note alert
password authentication failed for user "postgres"
::: 

:::note
su postgres
psql
ALTER USER postgres WITH PASSWORD 'password';
::: 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641430/12a1bbfa-f060-c1d8-9e9a-2670353dc8ef.png)

:::note alert
NO supported authentication methods available(server sent: publickey)
と
Server refused our key
::: 

[ec2-ppk-pem-conversion](https://repost.aws/ja/knowledge-center/ec2-ppk-pem-conversion)　と　[putty-private-key](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/putty.html#putty-private-key)

EC2 Instance Connect

```bash: SSH設定
vim /etc/ssh/sshd_config
```
:::note
PubkeyAuthentication yes
::: 

因みに、安全のために、PermitRootLogin　PasswordAuthentication　PermitEmptyPasswordsが禁止。

:::note
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
:::
荷重方向変位 第11章 薄肉曲りはりとばねの力学 基本例題11.09 P358「材料力学演習(20221021)」をsympyでやってみたい。

 # オリジナル

[基本例題11.09 P358](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=363)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
・ver0.1
```python
# ver0.1
# 基本例題11.09 解説 P358
from sympy import *

var('P,EI,l,a,θ,Q',real=True)
M   =-P*a*(1-sin(θ))+Q*a*cos(θ)
δBV =(1/EI*a**2*integrate(M*   cos(θ) ,(θ,0,pi/2) )) .expand()  ;print("#",δBV )
Q_ans=solve(δBV,Q)[0]                                             ;print("#",Q_ans)
δBH =1/EI*a**2*integrate(-M*(1-sin(θ)),(θ,0,pi/2) ).factor()    ;print("#",δBH )
δBH = δBH.subs({Q:Q_ans}).factor()                              #;print("#",δBH )
δBH =(δBH*(1*pi*EI)/(P*a**3*pi)).expand()*(P*a**3*pi/(1*pi*EI))  ;print("#",δBH )
# -P*a**3/(2*EI) + pi*Q*a**3/(4*EI)
# 2*P/pi
# a**3*(-8*P + 3*pi*P - 2*Q)/(4*EI)
# P*a**3*(-2 - 1/pi + 3*pi/4)/EI
```

# いつもの? sympyの実行環境と 参考のおすすめです。
(テンプレート)

https://qiita.com/mrrclb48z/items/00dd08b0317069be9342

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

#### 参考文献

~~＞一部に等分布荷重を受ける単純支持はり~~
~~＞JSME p89~~
　
~~＞単純支持ばり 7)~~
~~＞構造力学公式集 p136~~
垂直方向変位,水平方向変位 第11章 薄肉曲りはりとばねの力学 基本例題11.02 P352「材料力学演習(20221021)」をsympyでやってみたい。

・垂直方向変位,水平方向変位

# オリジナル
[基本例題11.02 P352](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=357)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
・ver0.1
```python
# ver0.1
# 基本例題11.02 解説 P351
from sympy import *

var('P,EI,l,a,θ,Q',real=True)
M   =-P*a*(1-sin(θ))+Q*a*cos(θ)
δBV =(1/EI*a**2*integrate(M*   cos(θ) ,(θ,0,pi/2) )) .expand()  ;print("#",δBV )
Q_ans=solve(δBV,Q)[0]                                             ;print("#",Q_ans)
δBH =1/EI*a**2*integrate(-M*(1-sin(θ)),(θ,0,pi/2) ).factor()    ;print("#",δBH )
δBH = δBH.subs({Q:Q_ans}).factor()                              #;print("#",δBH )
δBH =(δBH*(1*pi*EI)/(P*a**3*pi)).expand()*(P*a**3*pi/(1*pi*EI))  ;print("#",δBH )
# -P*a**3/(2*EI) + pi*Q*a**3/(4*EI)
# 2*P/pi
# a**3*(-8*P + 3*pi*P - 2*Q)/(4*EI)
# P*a**3*(-2 - 1/pi + 3*pi/4)/EI
```

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

#### 参考文献

~~＞一部に等分布荷重を受ける単純支持はり~~
~~＞JSME p89~~
　
~~＞単純支持ばり 7)~~
~~＞構造力学公式集 p136~~
方向変位 第11章 薄肉曲りはりとばねの力学 基本例題11.01 P350「材料力学演習(20221021)」をsympyでやってみたい。


・方向変位
 
 # オリジナル
[基本例題11.01 P350](http://zairikiweb.starfree.jp/zai_enshuh/zai_enshuh_ver.3.3.pdf#page=355)＜[「材料力学演習(20221021)一括(ver.3.3)」を勉強したい。#sympy](https://qiita.com/mrrclb48z/items/c3274daf5f7a99cfe027#%E4%BD%9C%E6%A5%AD%E4%B8%AD%E7%A7%81%E3%81%AE%E8%A7%A3%E7%AD%94sympy)
　　？？？タブレット等で、pdfを開く事ができないかも。？？？　
# sympyで
・ver0.1
```python
# ver0.1
# 基本例題11.01 解説 P350
from sympy import *

var('Pz,EI,l,a,θ',real=True)
M   =Pz*a*(1-sin(θ))
m   =   a*   cos(θ)
δDx=1/EI*a*integrate(M*m,(θ,0,pi/2) )
print("#",δDx)
# Pz*a**3/(2*EI)
```

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

# いつもと違うおすすめです。

#### 参考文献

~~＞一部に等分布荷重を受ける単純支持はり~~
~~＞JSME p89~~
　
~~＞単純支持ばり 7)~~
~~＞構造力学公式集 p136~~
Androidでレズビアン専用のマッチングアプリを作ってる件について

# 大学生がレズビアン専用のマッチングアプリを作ってる

これを作ってる経緯としては、自分がマッチングアプリを作っていた時に
レズビアンのマッチングアプリがないなと思ったからです。

とても単純な理由かもしれないですが、技術を極めるのにもいいのかなと思い作ってまーす。

リリースされたら、またQiitaに記事を出すのでぜひTwitterの方をフォローしてみてください！！

技術は
FlutterとFirebaseのみです
SPAアプリケーションにおけるOIDCフロー

とりあえず走り書きです。時間がある時にブラッシュアップします。

refresh_tokenをcookieに保存するのはセキュリティリスクがあるのでは？と考え、ではSPAアプリケーションでどうやってセキュアにaccess_tokenのrefreshをするのかを考えました。

### 認証

1. code_challenge, code_verifierの作成
2. 認証リクエスト
3. コールバック後、tokenリクエスト
4. id_tokenの検証
5. refresh_tokenをredisに保存し、session keyを発行
6. session_keyとaccess_tokenをcookieに保存
7. 画面を表示
8. 以後SPA

### アクセス時認可

1. サーバーサイドでaccess_tokenの有効性を確認
2. 無効な場合、token refreshフローへ
3. 画面を返す
4. 以後SPA

### 定期的認可

1. 一定の間隔(1時間？2時間？)でリロードする
2. アクセス時認可が走る

### token refresh フロー

1. cookieからsession_keyを取り出す
2. refresh_tokenをredisから取り出す
3. token refresh apiを叩く
4. 新しいrefresh_tokenをredisに保存して新しいsession_keyを取得
5. access_tokenとsession_keyをcookieに保存

全体として、このフローはセキュリティを確保しつつ、SPAでのUXを最適化するための適切なアプローチを示しています。ただし、実装する際には、セキュリティ設定（特にCookieのHttpOnly、Secure、SameSite属性）や、セキュリティベストプラクティスへの準拠を確実に行うことが重要です。また、トークンの有効期間やリフレッシュ戦略を適切に設計することで、セキュリティリスクをさらに低減することが可能です。

これがベストなのかはわかんないです。もっといい方法を知っている方がいたらコメントお願いします
「Java API」、「ライブラリ」、「パッケージ」とは…

# 「ライブラリ」
プログラムを作成する上での便利な機能群。(便利なプログラムの部品を沢山集めて、ひとまとめにしたファイルのこと。) 例：Maven
便利な機能を含む、フレームワーク、ユーティリティなどもライブラリという。

# 「Java API」
クラスライブラリ。Javaにあらかじめ添付されている多数のクラス群のこと。
JDK、フレームワーク(サーブレット、struts、spring)、ユーティリティ(ant/jmeter/poi)など。

# 「パッケージ」
一つの意味としてはjavaの名称(フォルダ階層)。
また別の意味で製品(JBoss、oracleDB)や、サービスのかたまりのこと。
ライブラリで集めたプログラムを、似た機能ごとにあつめたもの。
上記してる、フレームワーク、ユーティリティもパッケージ。
ウィンドウサイズ変更ソフト Sizer 4.0 の使い方

Sizer（読み方：サイザー）は無料で使える Windows 向けのソフトウェアです。Sizer を使うとウィンドウのサイズや位置を簡単に変えることができます。ここでは 18 歳の新人社員向けに Sizer 4.0 の使い方を紹介します。

## Sizer の目的
Sizer は以下のような目的で利用できます。

### スクリーンショットの撮影
マニュアル作成者が特定のサイズや解像度でスクリーンショットを撮影する場合、Sizerを使ってウィンドウを正確にそのサイズにリサイズすることができます。

### ウェブデザインやアプリのテスト
ウェブページやアプリが異なる画面サイズでどのように表示されるかをデザイナーが確認する際、Sizerを使ってウィンドウのサイズを変更してテストすることができます。

### マルチタスク作業
複数のアプリケーションやドキュメントを同時に開いて作業する場合、Sizerを使うと、各々のウィンドウを簡単に特定のサイズや位置に調整することができ、作業効率を向上させることができます。

## Sizer 4.0 のシステム要件
Sizer 4.0 は以下の環境で動作します

オペレーティングシステム：Windows 10, 11

ここでは Sizer 4.0 の zip 版を例にして、Windows 11 へのインストール方法を紹介します。

## Sizer 4.0  のインストール方法
### ダウンロード

Sizer 4.0 のダウンロードページにアクセスします。ページが表示されたら **sizer4_dev640.zip** のリンクをクリックします。

[https://www.brianapps.net/sizer4/](https://www.brianapps.net/sizer4/)

![01_officialsite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/e7b3bc3d-7c14-bf87-cc2f-e5ca657ef173.png)

### ファイルの展開
ダウンロードが完了したら、ZIP ファイルを右クリックし、コンテキストメニューから「**すべて展開**」をクリックします。

![11_download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/dca86717-603e-d838-7440-8720af99761c.png)

### 展開先フォルダの指定
ファイルの展開先を指定します。ここでは例として **C:\ProgramFiles\sizer4_dev640** というフォルダに展開します。

![21_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/ed30a661-a106-b21e-d604-4874741c8e92.png)

以上でインストール作業は終了です。

## Sizer の使い方
Sizer を使う時は **C:\ProgramFiles\sizer4_dev640\sizer.exe** を実行します。

![22_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/d812646f-7b64-9088-0e56-5b40da883216.png)

Sizer が起動すると、システムトレイにアイコンが表示されます。

![31_sizer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/11561e87-7424-f13d-97bf-4f2247c4946b.png)

適当なウィンドウの境界付近を右クリックすると、Sizerのツールチップが表示されます。ツールチップからサイズを選択すると、ウィンドウの大きさがそのサイズに変わります。

![32_sizer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/527ae39a-2181-be72-2e2e-a62772d63ea5.png)

システムトレイにある Sizer のアイコンを右クリックし、「Configure Sizer」を選択すると、設定ダイアログが表示されます。

![33_sizer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/18f95ff5-9d7a-cf29-1a04-75da47b57fe2.png)

設定ダイアログでは、新しいエントリを追加したり、既存のエントリを編集することができます。

![34_sizer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/259ed975-a9d9-ff0c-89cb-a9d8f507a069.png)

## まとめ

この記事では Sizer のインストール方法と使い方を説明しました。Sizer のようなツールは、特定のタスクを効率的に行うための補助的な役割を果たします。ウィンドウのサイズや位置の調整が頻繁に必要な作業を行う場合、このようなツールが非常に便利です。
Subversion（SVN）とは

# 【Subversionとは】
Subversionとは、「集中型バージョン管理システム」のこと。
昔からあるバージョン管理システムのCVSを使い易くしたのがSubversion。
全員で１つのリポジトリを共有して随時ここにコミットして格納していく。その為、ローカルリポジトリはない。
整合性が保たれていないとコミットしてはいけないというルールがある。

# 【特徴】
・複数のエンジニアがアクセス可能
Subversionは複数のエンジニアがアクセスできる構成を採用することで、より効率よくコード管理や開発が行える仕様になっている。
直接的にコード管理を行えるため複数のエンジニアで管理する際には利用しやすいのが特徴。
しかし複数でアクセスできることによるデメリットも存在するので注意は必要になる。

・より多くの機能が搭載されている
Subversionには複数のエンジニアで開発するにあたり、より利便性を高めるための機能がたくさん搭載されている。
例えば、他のエンジニアがリポジトリからデータの引出しや保存を行っている際に、自分のデータは他の自分用のディレクトリに保存されるなど競合しても勝手に上書きされない特徴も持ち合わせている。



# 【subversionの基本コマンド】
・リポジトリの複製：checkout
・コミット（リモートへの反映）：commit
・コミット内容の確認：cat
・ファイルの変更の取消：revert checkout
・ブランチの作成：copy
・ブランチの切り替え：switch

SVNではローカルリポジトリ/リモートリポジトリという概念がないためコミットすると即座にリモートに反映される。

（補足）
- バージョン管理システム：ソースコードなどの変更履歴を管理してくれるシステムのこと。

- バージョン管理システムの種類
・分散型：リモートリポジトリだけでなく、ローカルマシンのローカルリポジトリにもバージョンを保存できる。
　　　　　　メリットは、ブランチを活用できる。オンラインオフライン問わず複数人が並行して作業できる。
　　　　　　デメリットは、マージ作業にコストがかかる。
　　　　　　例）Git、Mercurial

・集中型：バージョンがリモートリポジトリに保存される。
　　　　　　メリットは、導入コストの低さ。
　　　　　　デメリットは、ローカルにコミットできないため、影響範囲が広い。
　　　　　　例）「Subversion」、「CVS」

- 整合性：物事に矛盾がなく、整っているという意味。
パワークエリで住所から都道府県のみを抽出する方法

# はじめに
- 住所が正しく<INS>都道府県から記載</INS>されている事が前提条件となります。
- 日本の住所における以下特徴をうまく活用します。
:::note info
特徴
- ほとんどの都道府県名は住所の先頭から"3文字"
- 3文字以外には"4文字"しか存在しない
- 4文字は「鹿児島県」「和歌山県」「神奈川県」の3県だけ
:::

# PowerQueryで対応する方法
- 多少冗長ですが、個人的に以下の方法が分かりやすいと考えています。
- M言語を書けなくてもクリック操作＆コピペで対応可能です。（一部書き換えは必要）

### 1．「条件列」を使用し、4文字で始まる県はそのまま表示させる。
列の追加 ＞ 条件列を押下後、画像の様に入力します。
※条件列を増やすには、「旬の追加」をクリックして下さい。
![PQ1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/1436ddda-65e0-5235-6553-5fd3ab32c4fd.jpeg)

「神奈川県」は抽出成功。
それ以外に該当する東京都と大阪府は、「その他」と表示されました。
![PQ2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/1677c278-2876-acba-0ee0-a9a8640691f1.jpeg)

このままでは使いものにならない為、修正を加えていきます。

### 2．住所の頭3文字を抽出する
まず、住所列を選択。
その後、抽出 ＞ 最初の文字をクリック。
カウント欄に、「3」を入力します。
![PQ3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/12a4d022-92cc-b56e-d30c-993f8e2f6280.jpeg)

結果、以下の様な結果が得られます。
但し、神奈川県も「神奈川」と3文字しか表示されていません。
ここで注目するのは数式の部分です。<INS>赤枠部分の数式だけをコピペ</INS>して下さい。
※ここでは数式を得たかっただけなので、適用したスキップにある挿入された最初の文字は✗で削除して下さい。
![PQ4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/62db433f-cee3-bc7a-4924-b1d70035ebb2.jpeg)
```
Text.Start([住所], 3)
```

https://learn.microsoft.com/ja-jp/powerquery-m/text-start

### 3．「条件列」の数式を修正する
次に数式バーにある数式を修正します。
"その他"を削除し・・・
![PQ5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/254beb33-9e9d-ae85-c783-fb74dbc10678.jpeg)

先程コピペした、Text.Start([住所], 3)に書き換えてください。
![PQ6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/2104e4b8-aa48-bc03-3c10-d7bb9d64f487.jpeg)

求めていた結果を得る事が出来ました👍
<br>
要は以下の数式をクリック＆コピペのみで作成した形です🤓
```
=if Text.StartsWith([住所], "鹿児島県") then "鹿児島県" else
 if Text.StartsWith([住所], "和歌山県") then "和歌山県" else
 if Text.StartsWith([住所], "神奈川県") then "神奈川県" else
 Text.Start([住所], 3)
```


# 【参考】Excel関数で対応する方法
## ①関数のネストによる方法
以下の数式で都道府県名のみを抽出する事が可能です。
```
=IF(MID(A2,4,1)="県",LEFT(A2,4),LEFT(A2,3))
```
![関数で都道府県抽出2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/cef761dc-8231-fb34-770e-a4aae3744466.jpeg)

※鉄板ネタの為、詳細説明は割愛します。
　住所の4番目の文字が”県”であれば<INS>4文字</INS>、
　それ以外の場合は<INS>3文字</INS>を表示させる事で都道府県を抽出しています。

## ②Excel APIを使用する方法
「住所の分割」機能を用いて①と同じ結果を得る事が可能です。
```
=WEBSERVICE("https://api.excelapi.org/post/address-separate?parts=1&address="&ENCODEURL(A2))
```
![Excel API.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758923/9e325a78-1d7a-4f32-3e95-62e4ae3fc956.jpeg)

※無料で使用可能ですが、1日1万件以上のアクセスが必要な場合は有料となります。
　アクセス制限が掛かるだけで一方的に課金される事はありませんのでご安心下さい。
　詳細は下記公式サイトをご参照下さい。
 
https://excelapi.org/docs/post/address-separate/

---

Excel関数のみで処理する方が手っ取り早いですが、外部データソースをPowerQueryで処理している場合など、PowerQueryのみで完結したい／関数での処理を挟みたくないといった場合に使える手法かと思います。

ご参考になれば幸いです😊
Servlet(サーブレット)とは

# 【Servletとは】
Servletとは、「Webサーバ上（バックエンド）で動く、Javaで書かれたプログラム」のこと。
サーバ上でウェブページなどを動的に生成したり、データ処理を行うために、Javaで作成されたプログラム及びその仕様。
業務用のWEBシステムを開発するときによく使われている。

# 【Servletの役割】
Servlet自体は、WEBページをはじめとし画面に関する処理はいっさい行わず、WEBブラウザからの要求に応えたり、送られてきたデータを処理したりする役割を担っている。
ServletはJavaプログラムなので、単独ではWEBアプリ作成するための機能が不十分。
その為「ホームページのファイル（JSP）」や「サーブレットコンテナ」と呼ばれる他のプログラムと連携する必要がある。

（補足）
 ・Webサーバ：ホームページやWebサービスを置いておくコンピュータ。
 ・動的なWEBページ：アクセスしたときの状況（ログインの有無など）に応じて異なる内容が表示されるWebページのこと。 例として、ユーザーが書き込むことで内容が増える掲示板サイトやブログ、表示内容がユーザーごとに違うショッピングサイトなどがある。※動的にWEBページを作成することで、WEBアプリを実現することが可能となる。


# 【ホームページのファイル（JSP）】
JSPとは、HTML内にJavaのコードを埋め込み、動的にWEBページを生成する技術のこと。HTMLファイルとJavaのプログラムが合体したような見た目のソースをしている。
ServletはWEBアプリ内部の処理を担当し、JSPは主にWEBページを担当している。
ServletとJSPが連携することで、動的にWEBページを作ることが可能になる。

～ServletとJSPの違い～
・Servletはがっつりプログラム。それに対して、JSPは基本的にはホームページのファイル（HTMLファイル）。
・処理が始まるときの手順が違う。JSPは処理が始まるときに、Servletに変化する工程が発生する。その為、実際に処理をしているときの姿は同じ（どちらもServlet）。


# 【サーブレットコンテナ】
例）Tomcat(トムチャット)、Glassfish（グラスフィッシュ）など…

ServletはJavaプログラムなので、実行環境が必要となる。その実行環境となるソフトウェアが「サーブレットコンテナ」である。
厳密に言うと、HTTPリクエストはサーブレットコンテナが受け取り、「サーブレットコンテナがServletに対して処理の命令を出す」流れとなる。



# 【特徴】
・ライフサイクル管理
(ライフサイクル：処理が始まってから終了するまでの一連の流れ)
通常は、一連の処理が完了したらそれまでに使ったデータを破棄してしまう。
しかし、Servletは一連の処理が終わっても、データを保持して再利用できるようにする。
そのため、最初の1回目は処理に時間がかかるが、2回目はデータを再利用するので処理が早くなる。
頻繁に不特定多数の処理を行う必要があるWEBアプリでは、データをできる限り共有して使いまわした方が効率がよくなるのである。

・マルチスレッド対応
（マルチスレッド；同時に複数の処理をすること。）
1つのプログラムを実行している間は、他のプログラムは実行中のプログラムが処理されるのを待つ必要になるが、
それだと、複数のユーザーから頻繁に同時にアクセスがあるWEBアプリでは、常に順番待ちになってしまい非常に効率が悪くなってしまう。
これを解消してくれるサーブレットは、複数の処理を同時に行うマルチスレッドに対応しているので、複数のユーザーからのアクセスでも効率良く処理を行うことができる。

・プラットフォーム非依存
Servletというよりは、Javaの特徴ではあるが、
Windows、Mac、Linuxなどコンピューターに依存することなく動作させることができる。



# 【サンプルのコード】
●サーブレットのコード
```HelloWorld.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
     response.setContentType(“text/html;charset=Shift_JIS”);
     PrintWriter out=response.getWriter();
     out.println(“<html><head>”);
     out.println(“<title>Hello, World!!</title>”);
     out.println(“</head><body>”);
     out.println(“<p>Hello,World!!</p>”);
     out.println(“</body></html>”);
  }
}
```

●JSPのコード
```HelloWorld.jsp
<html>
<head>
    <title>Hello, World!!</title>
</head>
<body>
    <% out.println(“<p>Hello,World!!</p>”); %>
</body>
</html>
```
阿部寛公式サイトは本当に高速なのか？

俳優の阿部寛公式サイトの表示速度が高速とよく言われてますが、Qiitaでも検証ではシミュレーション計測結果が大半を占めているため実際のデータで判定してみました。

今回はRUMではなく無料で公開されているCrUXにあるLoad Eventからデータを取ります。

## CrUXから見る阿部寛公式サイトのLoad Event

記事で参考にしているデータは下記から確認できます。

https://treo.sh/sitespeed/http://abehiroshi.la.coocan.jp?metricsMode=d&metricsZoom=75&metrics=ttfb%2Cfcp%2Clcp%2Ccls%2Cfid%2Cr%2Cfp%2Cdcl%2Col&latestMode=false

1年後に記事を読まれる方向けに、スクショも貼っておきます。

<details><summary>スクショを表示する（クリックで開きます）</summary>

![Site-speed-audit-for-abehiroshi-la-coocan-jp-in-Japan-Treo-sh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431047/7f244fe5-7266-3e58-602b-a32633f42169.png)

</details>

### 計測データ（2023年12月時点）

|  | グローバル | 国内 |
|:-:|:-:|:-:|
| 平均Load Event  | 3.4秒  | 3.3秒  |
| 2.5秒 <=  | p58  | p58.1  |

### データから見えるポイント

- CrUXでは海外アクセスは韓国と台湾でしたので、国内集計とほぼ変わらない数値。
- 42%のサイト訪問者は2.5秒以下でサイト表示ができていない。
- 1年前の平均は0.8秒で高速でした。1年を通じて段々と遅くなっており2023年9月以降は表示速度が悪化。
- 表示速度悪化と共にCore Web VitalsのLCPも悪化。
- Core Web VitalsのFIDは珍しくこの1年間も良好範囲内ではない。
- 6秒以上かかっているサイト訪問者は全体の2.2%。

表示速度の理想は2秒以内とも言われてますので、現状の平均表示時間からすると遅いです。つまりこの記事を執筆した時点では、阿部寛さんの公式サイトは高速とは言えません。

## dev.toと阿部寛さん公式サイト、どちらが高速？

2017年にこちらの記事が話題となりました。

https://qiita.com/naru0504/items/7d652681d698f6d88c4f

同じように今回はデータが遡れる2023年1月と12月の両サイトのLoad Eventを比較してみましょう。採用するのはグローバルの平均値です。

| サイト | 1月 | 12月 |
|:-:|:-:|:-:|
|  阿部寛公式サイト |  0.8秒 | 3.4秒  |
|  dev.to |3秒   |  2.9秒 |

阿部寛公式サイトは1月だと圧倒的な速さでしたが、12月の最新データではdev.toの数値を上回ってしまいました。

## シミュレーションではなく実際のデータを採用した理由

従来はPageSpeed Insights（Lighthouse）のスコア（表示速度ではない）で誤って判断されていたり、表示速度だとしてもWebPageTestなどのシミュレーションで判断されている場面はよく目にします。

https://qiita.com/skillsharejp/items/acc51ec062af43aa84c0

改善作業時はWebPageTestも有効で私も結構頼る部分はありますが、**ウェブサイトの表示速度はシミュレーションの値がサイト訪問者と同じであるということは一切ありません**。

ウェブサイト高速化をするとサイト訪問者にとって表示速度を改善した結果、**CVR改善や離脱率改善の効果は各社の事例として実際に出ています**。（例：WPO Stats）

https://wpostats.com/

一方で**何割のサイト訪問者が高速化の恩恵を受けられているのか**という部分はあまり注目されていません。

国内の大手企業向けウェブサイト高速化サービスの実例をCrUXで調べましたが、初期費用に50万～100万円近く払って更に月額で数万円単位の費用を払っていても、高速化の効果があるのは全体の半数以下にとどまる事例もありました。

**ウェブサイト高速化のゴールはシミュレーションだけではなく、実際にサイトを閲覧する訪問者が高速にサイトを表示できること**です。

:::note info
2024年以降のウェブサイト高速化のゴール設定を説明する記事を準備中です。
:::
CNLohr ch32v003fun

### RISC-V Toolchain のインストール

ツールチェーンとは
製品（典型的には他のコンピュータ用のプログラム、またはシステムプログラム）を製作するのに使われるプログラム（ツール）の集合体である。

homebrew-riscv ここを参考にします。
https://github.com/riscv-software-src/homebrew-riscv

homebrew は入っている気がしますので、
tapを取得します。
```cpp
$ brew tap riscv-software-src/riscv
```
![スクリーンショット 2023-07-15 16.00.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/bded7cee-cc86-bc1f-7625-b1cef29682fc.png)
ツールチェーンをビルドします。
```cpp
$ brew install riscv-tools
```
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/eb1e0a54-fa39-a910-4ec0-a4b6fc4d25ad.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/e2ae8f90-f5dd-54fd-ccc9-739d68d14c28.png)
Warning: Your Xcode (13.4) is outdated.
Please update to Xcode 14.2 (or delete it).
Xcode can be updated from the App Store.

Warningが出ていますがmacOS Ver 12.6 なのでXcode のバージョンが上げられないのですね。
![スクリーンショット 2023-07-15 17.51.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/20ad6b8e-cac1-1ae3-a8fb-aab339294540.png)
インストールが成功したかテストするようです。
```cpp
$ brew test riscv-tools
```
![スクリーンショット 2023-07-15 17.59.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/118697ee-63ee-f9f4-83a5-d4cac39f7d9c.png)
![スクリーンショット 2023-07-15 17.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/3f21b3cb-9402-ab3f-6fd8-34117e3afc90.png)
成功したの？(^^;
Advent of Code 2023 Day 18 Lavaduct Lagoon の解き方メモ

https://adventofcode.com/2023/day/18

Advent of Code 2023 Day 18 Lavaduct Lagoon ですが、回答にあたって、個人的にたいへん苦労したので、解き方や考え方のメモを残しておきたいと思います。

この問題はPart1、Part2ともに、次のように言い換えることができます。

「ある多角形が与えられるので、その辺上の格子点の数と、内部にある格子点の数を合計した数を求めなさい。」

**① 辺上の格子点の数**

これは問題文を正しく解釈すれば簡単に求めることができます。

**② 内部にある格子点の数**

難しいのはこちら。これを求めるにあたってはピックの定理を利用します。

```math
\displaylines{
多角形の面積 = 内部にある格子点 + 辺上にある格子点 \div 2 - 1 \\
\Leftrightarrow 内部にある格子点 = 多角形の面積 - 辺上にある格子点 \div2 + 1
}
```

先述したとおり、辺上にある格子点の数は計算済み。では多角形の面積はどのように求めればよいのかというと、shoelace formulaを利用します。多角形の頂点の座標が$(x1,y1),(x2,y2)\ldots(x_n,y_n)$とすると、その面積は以下の式により求めることができます。

```math
Area = \frac{1}{2}\left| \sum\limits_{i=1}^n (x_iy_{i+1} - x_{i+1}y_i) \right|
```

なお多角形の頂点の座標については、問題の入力を正しく解釈すれば簡単に求めることができるはずです。

**解答(Python)**

- [Part1](https://github.com/nekoTheShadow/adventofcode2023/blob/master/day18_01/main.py)
- [Part2](https://github.com/nekoTheShadow/adventofcode2023/blob/master/day18_02/main.py)

**参考文献**

- [ピックの定理](https://ja.wikipedia.org/wiki/%E3%83%94%E3%83%83%E3%82%AF%E3%81%AE%E5%AE%9A%E7%90%86)
- [Shoelace formula](https://en.wikipedia.org/wiki/Shoelace_formula)
Python開発におけるテストの基本

# Python開発におけるテストの基本
テストは、コードが期待通りに動作することを確認し、バグを早期に発見するために用いられる。
Pythonでは、`doctest`と`pytest`がよく使用されるテストフレームワークである。

## doctest

`doctest`は、ドキュメント文字列（docstring）内の例を実行して、期待される出力と実際の出力を比較することでテストを行う。

### doctestの使用例

```python
def add(a, b):
  """
  二つの数値を加算する。

  >>> add(2, 3)
  5
  >>> add(-1, 1)
  0
  """
  return a + b

if __name__ == "__main__":
  import doctest
  doctest.testmod()
```

このコードでは、`add`関数のdocstring内にテストケースを記述しており、`doctest.testmod()`を実行すると、これらの例がテストとして実行される。

## pytest

`pytest`は、より高度で柔軟なテストをサポートする外部ライブラリである。
`pytest`を使用すると、アサーションを直接書くことができ、多くの便利な機能が利用可能。

### pytestの例

まず`pytest`をインストールする。

```shell
pip install pytest
```

次に、テスト処理を書く。通常、テストは`test_`で始まる関数名を付ける。

```python
# test_example.py

def add(a, b):
    return a + b

def test_add():
  # 任意の判定を記載する
  assert add(2, 3) == 5
  assert add(-1, 1) == 0
```

このテストを実行するには、コマンドラインで以下を実行。

```shell
pytest test_example.py
```

`pytest`は、`test_add`関数内のアサーションを実行し、それらがTrueであることを確認する。Falseの場合、テストは失敗となる。
【JavaScript】オブジェクトの比較についてまとめてみた

# はじめに
業務でオブジェクトの比較を行うことがあって、等価演算子を使って実装したら思った動きになりませんでした。
下記のイメージになります。

```js
const objectCarA = {
    make : "Toyota",
    model : "Corolla",
    color : "red"
}
const objectCarB = {
    make : "Toyota",
    model : "Corolla",
    color : "red"
}
const isEqualCars = objectCarA === objectCarB

console.log(isEqualCars) // false (あれ、trueにならないの？)
```

先輩にその理由を教えてもらったので、ここにまとめます。


# 参照型（オブジェクト型）　基本型（プリミティブ型）
JavaScript のデータ型は、大きく２つに分けて 「基本型(プリミティブ型）」と「参照型（オブジェクト型）」があります。
この違いは変数に値を格納する方法です。
以下に詳細を記載していきます。

### 参照型（オブジェクト型）とは
参照型のデータで定義された変数は、その変数内に**アドレス(データの住所のようなもの)**を持ちます。
実データは、メモリ上に存在し、変数にはそのメモリのアドレスが格納されるというわけです。
なので、CarAとCarBを統合演算子で比較した際は、アドレスを比較していたのでfalseが返ってきたというわけですね。


具体的には次のようなデータ型があります。
- オブジェクト(object)
- 配列(array)
- 関数(function)


### 基本型（プリミティブ型）とは
基本型は、値を変数に直接格納します。なので、変数をそのまま統合演算子で比較しても、中身が同じであればtrueが返ります。

```js
const numberA = 10
const numberB = 10

const isEqualNumber = numberA === numberB

console.log(isEqualNumber) // true
```

# どう比較するか
Objectの比較を一からコードで対応しようとすると下記のような関数を作成する必要があります。

```js
function isEqualCars(obj1, obj2) {
    if (
        obj1.make  === obj2.make  &&
        obj1.model === obj2.model &&
        obj1.color === obj2.color
    ) {
        return true
    }
    return false
}

console.log("ObjectFunction: " + isEqualCars(objectCarA, objectCarB)) // true
```

ただ、この関数は、他のObjectには使えないですし、比較するたびにつどつど関数を作成するのは手間がかかります。

こういう問題はすでに誰かが解決してくれており、あるメソッドを使うことで一発で解決できます。

### lodashのisEqualを使おう
lodashというライブラリがあり、その中のisEqual関数をもちいれば、オブジェクトの比較が一発で行えます。
lodashには配列操作などの便利メソッドがたくさんあるそうなので、色々調べてみたいですね。

```js
const isEqualCars = isEqual(objectCarA, objectCarB)

console.log(isEqualCars) // true
```


# 参考記事
https://pg.brain-studio.com/00/a-js-variable-address.html

https://lodash.com/
Pythonにおけるstaticmethodとclassmethodについて

# Pythonにおけるstaticmethodとclassmethod

## staticmethodとは

`@staticmethod`は、静的メソッドを定義する。
静的メソッドとは、オブジェクトを作成せずに呼び出せるメソッドで、通常の関数と同様に使う事ができる。
対象のクラスに関わるメソッドであるため、クラス内に作っておいた方が可読性が上がる、という場合に使うとよい。

```python
class MyClass:
  def __init__(self):
    pass

  @staticmethod
  def static_method(arg):
    return arg

print(MyClass.static_method(1))  # 1
```

## classmethodとは

`@classmethod`は、クラスメソッドを定義する
クラスメソッドとは、staticmethod同様にオブジェクトを作成せずに呼び出せるメソッドで、第一引数にクラス自体が設定される。
オブジェクトの生成に関わる処理を行う関数として使うと良い。

```python
from datetime import datetime

class BetterDate:
  def __init__(self, year, month, day):
      self.year, self.month, self.day = year, month, day

  @classmethod
    def from_str(cls, datestr):
        year, month, day = map(int, datestr.split("-"))
        return cls(year, month, day)

today = datetime.today()
bd = BetterDate.from_str(today)
print(bd.year)
print(bd.month)
print(bd.day)
```
Python学習1日目～基本的な文法～

### 引数
引数は関数を呼び出すための値
~~つまり関数は引数がないと動かない~~
→引数なくても動く関数は存在するので、ここは間違い
コメント参照

### 戻り値
引数に呼び出された関数の実行結果の値

## キーワード引数と位置引数
関数の中に複数の引数がある場合、どちらを先に書くかというのが決まっており、位置引数から記載を始める
~~~python:test.py
print("Python",end="!")
~~~
ここでは[end]が引数名になるので、引数名がある引数＝**キーワード引数**となる
単純に値を渡すだけの引数は**位置引数**となる

## ブロックコメントとインラインコメント

~~~python:test.py
# これはブロックコメントです
print("Hello world")

print("Hello world")  # これはインラインコメントです
~~~
インラインコメントは処理の横に空白を2個開けて、書き始める。
ただしインラインコメントはそこまで推奨されないので注意。

どちらのコメントも**文末**までがコメント扱いとなる

## PEP8
Pythonにおける標準的なコーディングスタイル。
コーディングスタイルは「どんな見た目でコードを書くか」という意味合い。
基本はPEP8に従ってコーディングを行う

PEP8
https://pep8-ja.readthedocs.io/ja/latest/

## 型について
値の型が超重要ですよ。
型が合致していないと動かないプログラムばかりなので、自分が今どの型を扱っているのかは常に意識する

### int
整数。
上限なし。

### float
浮動小数点数。
64bitの上限あり。
→大体15桁程度

### str
文字列。

#### エスケープシークエンス
str型の場合、クォーテーションの間が文字列として扱われるため、

「`"I can't play the "guitar""`」

を表示したいときにエラーが発生する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680269/973773d5-d884-e07e-9892-77b99994cf3b.png)

そこで「\」を使うことで回避可能。

「`"I can't play the \"guitar\""`」
と書けばOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680269/b53d4252-adad-2fad-f242-85f3c8bc80da.png)

#### raw文字列
ぶっちゃけいちいちエスケープシーケンス使うのが面倒なので、raw文字列を使うことでも回避可能

~~~python:test.py
print(r"C:\users\myname\Desktop")
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680269/5a364a20-5b54-afa6-5fba-0e4ff9552b35.png)
RAID

RAIDは複数のドライブを1つの大きなディスクとして
サーバーへ見せることができる仕組み。

複数ドライブへ分散書き込みすることで
処理効率の向上、ドライブ障害でのデータ損失対策が可能。

ドライブ障害時のデータ復旧先には
ホットスペアディスクを使用する。（予備のディスク）
予備のディスクにデータを復旧することをリビルド（再構築）という。
昨今のストレージでは1本の容量がかなりデカいので、リビルドに時間かかる（丸一日とかもある。。）
DRAID6の場合は稼働しているドライブにスペア領域を確保するので、予備からのリビルドに比べ高速でリビルドが可能。

・RAID0(ストライピング)
2本のドライブに分散してデータを読み書きするため、処理効率が良い。
2本分の容量を使用することができる。
1本でも障害が起こると復旧することが困難。

・RAID1(ミラーリング)
2本のドライブに全く同じデータを書き込む。
片方のドライブに障害が起きても耐えることができる。

・RAID0+1(ストライピング+ミラーリング)
ストライビングしたドライブをミラーリングする。

・RAID6(ダブルパリティレイド)
複数のドライブに分散書き込みし、2ドライブにパリティデータを書き込む。
2本までのドライブ障害に耐えることができる。
障害時はパリティデータと正常データを使用してデータを復元する。
初iOS個人アプリリリースしました！


## 初の個人アプリ開発！！！
iOSアプリエンジニアになって１年半ちょいが経過しました。少し遅かったのですがついに個人アプリを開発した！！

## アプリの概要
![英語日記](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/55990b60-6d90-688b-009a-a6ff05815104.jpeg "apple store")

アプリとしては、英語日記！
私個人的に英語を勉強しておりまして、新井リオさんの[英語日記BOY]((https://www.amazon.co.jp/%E8%8B%B1%E8%AA%9E%E6%97%A5%E8%A8%98BOY-%E6%B5%B7%E5%A4%96%E3%81%A7%E5%A4%A2%E3%82%92%E5%8F%B6%E3%81%88%E3%82%8B%E8%8B%B1%E8%AA%9E%E5%8B%89%E5%BC%B7%E6%B3%95-%E6%96%B0%E4%BA%95%E3%83%AA%E3%82%AA/dp/4865282637 "英語日記BOY")の勉強法をもとにアプリ開発を行いました。
英単語暗記などの作業がどうしてもつまらなくて続きませんでした。この本を読んでこの勉強法だ！！！ってなったのがきっかけで、せっかくなら色んな人にこの勉強法を知ってもらえて、アプリ化できたら最高やなぁとか思った笑

## アプリ制作にかかった時間
平日仕事終わった後と土日の時間を使いました。大体2ヶ月くらい？で終わったと思う

## アプリの機能
・英語発話機能
・ワード検索
・英語発話読み上げスピード調整
・英語発話の声の高さ調整
・スピーキング練習

順に説明します！

## 英語発話機能・読み上げスピード・声の高さ調整機能
これは再生ボタンタップで英語を読んでくれます!
![hoge.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348250/db3e98c6-ad39-e878-1950-21a158d50824.jpeg)

コードを載せますー
```swift
import Foundation
import AVFAudio

class Speecher {
    
    static let shard = Speecher()
    private init() {}
    
    let defaultSpeedValue: Float = 0.5
    let defaultPitchValue: Float = 1.0
    
    var speechSynthesizer = AVSpeechSynthesizer()
    
    func speech(voiceText: String, speed: Float? = nil, pitch: Float? = nil) {
        let utterance = AVSpeechUtterance.init(string: voiceText)
        if let speed {
            utterance.rate = speed
        }
        if let pitch {
            utterance.pitchMultiplier = pitch
        }
        utterance.voice = AVSpeechSynthesisVoice.init(language: "en-US")
        speechSynthesizer.speak(utterance)
    }
}
```
これだけで発話機能を実装できるのいいですね！

## ワード検索機能
日記orオリジナル英作文を検索したいので、何か検索ワードにヒットしたらその日記だけ表示するようにしました。
```swift
fileprivate extension Array where Element == Diary {
    func filter(searchWord: String) -> [Diary] {
        return filter {
            guard let english = $0.english,
                  let japanese = $0.japanese,
                  let situation = $0.situation,
                  let wantToSay = $0.wantToSay,
                  let createdAt = $0.createdAt else {
                return false
            }
            let createdAtString = Date.dateToString(date: createdAt)
            return english.contains(searchWord) ||
            japanese.contains(searchWord) ||
            situation.contains(searchWord) ||
            wantToSay.contains(searchWord) ||
            createdAtString.contains(searchWord)
        }
    }
}
```
Arrayのextensionを作成して型をDiary型に限定しました。


## このアプリの一番使い勝手がいいなと思うとこと
最低限の英文法は勉強しないといけないと思いますが、そこからは自分がこんなことを言いたい！とかこの場合英語でなんて言えばいいんだろうみたいなことってたくさんあると思います。そんな時にこのアプリを使って、皆さんの英語の勉強が捗ってくれると嬉しいです。私個人的にも使用しています。
私は、独り言とかブツブツ言いながら、この時なんて言うのかな？ってをアプリにメモして、色々調べながら英語で文章を作ってから、オンライン英会話の先生にこの文章あってる？(is this sentence correct?)っていつも聞いています笑

## エンジニアってなって後3ヶ月で２年
後3ヶ月でもう２年になります。エンジニアは勉強することが多すぎて参っちゃう時があるのと、自分の成長がなかなか分からない時があります。皆さんは毎日どれくらい勉強していますか？
そろそろ勉強会とかに参加してみようかなとか思ってます。会社以外の方のレベル感とかも知りたいし、、

## 最後に
是非英語勉強している方、オンライン英会話を受講している方などにインストールしてほしい！
これからどんどんアプリリリースしていきます！
Sailboat Retrospective

## はじめに
私が所属するチームはふりかえりに学習マトリクスをよく使っています。たまには気分を変えたふりかえりを実施してみたいということで Sailboat Retrospective というものを試してみました。

## Sailboat Retrospective とは
自分たちを、ゴール地点の島を目指しているヨットの搭乗員に見立てふりかえりを行います。
早くゴールに向かうための追い風、ヨットの進みを遅くする錨、将来ヨットを座標させるかもしれない暗礁、旅を快適にする太陽、などの要素を1枚の絵にまとめていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/0e020f3e-b936-b4df-0ed6-7628e9ef6b2c.png)

|項目|記載する内容(注：個人の解釈です)|
|:--|:--|
|島|チームが目指すゴール地点。チームの目標やビジョン|
|太陽|チームにとって嬉しいこと、ポジティブな気分にさせること。開発に直接かかわらないことでもOK|
|追い風|チームをゴールに向けて前進させていること。目標に向けて駆り立てるもの|
|錨|チームの進みを遅くさせていること。技術やプロセスなどチームの妨げになること。|
|暗礁|チームが抱えるリスクや潜在的な落とし穴。今すぐではないけど、将来妨げになりそうなこと|

参考：https://miro.com/miroverse/sailboat-retrospective/

ちょうどチームでもmiroを使っていたので、このテンプレートを使って実践してみました。

## 進め方

太陽・追い風　→　錨・暗礁　→　TRYの決定　という順番で時間を区切って起票と議論をしました。
KPTに近い進め方ができるので、チームも受け入れやすかったように見えます。

## 実践してみての感想
* ふりかえりの雰囲気を明るくできる
    * 全員で1枚の絵に対してふりかえりをするからか、全体的にワイワイと進められました。
    * 私のチームではKPTや学習マトリクスは文字だけの堅い雰囲気になってしまいがちなので、フレームワークの変更は効果的でした。
* チームの問題点の洗い出しに効果的
    * 短期目線・長期目線での問題を別の枠にしているので、長期目線での課題が出やすかったです
    * 長期目線でのリスクについては1Sprintで解決できるものではないので、一定期間続けた方が効果的かもしれません
* 遊びすぎに注意
    * イラストを使っていると楽しいので、つい遊びすぎて終わらないということが無いようにしましょう

2Sprint回してみた状態はこんな感じです。アレンジとして座礁について短期・長期の2つを追加しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296651/4d0d68ec-03ad-945c-9083-072ded0868ff.png)

## まとめ

気分を変えたふりかえりで Sailboat Retrospective を試してみた結果、ワイワイとふりかえりができたうえに新しい発想が生まれやすかったです。
チームのふりかえりはやり方が固定されがちですが、時には大きく変えてみるのもいい刺激になりそうです。

## 参考サイト

- https://miro.com/miroverse/sailboat-retrospective/
- https://www.teamretro.com/retrospectives/sailboat-retrospective
ストレージのキャッシュメモリ

コントローラとホスト間、コントローラとディスク間のI/O処理をスムーズに行うための物理スペースよ。

・キャッシュメモリはバッファとして機能するため、ホストとディスクのデータ転送を同期する必要がない。

・ホストからの読み書きの対象となるデータが以前の処理で既にキャッシュに格納されていれば
　ディスクにアクセスする必要はない。

・書き込みキャッシュを使用している場合、ホストは以前の書き込み処理がディスクに書き込まれる前に
　皇族の書き込みコマンドを送信することができる。

・読み取り処理ではよく使用するデータはキャッシュ内のデータが使用され、ディスクから読むより高速に読み取ることができる。
ストレージ用コントローラ(CPUの)

ストレージ↔︎メモリ間転送するためのCPUにあるコントローラ。
※従来はストレージからチップセットを経由してメモリへデータを読み込む。

CPUからの指示を受けて接続された機器へデータを送信したりデータを受信したことをCPUに通知したりする。
(データ読み書きの制御は接続されているCPUが行う。)
メモリコントローラ

＊メモリコントローラ＊
CPU↔︎メモリへの読み書きはメモリコントローラを介して行われる。

・メモリコントローラ(LSI:高密度集積回路)
→メインメモリを介したデータ読み書きやDRAMのリフレッシュ等をするための回路。
従来はチップセットに搭載されていたが、今はCPUへの統合メモリコントローラが主流。
とにかくCPUからの命令でメモリコントローラを介して処理されるようね。

CPUからの指示を受けて接続された機器へデータを送信したりデータを受信したことをCPUに通知したりする。
(データ読み書きの制御は接続されているCPUが行う。)
LangChain "The model text-davinci-003 has been deprecated" に対応する

# 症状

以前、「LangChainをFastAPI経由でUnityで利用する」Pythonプログラムを書いて、Render.comで動かしていたのですが、気がついたら、以下のようなエラーが返るようになってしまいました。


> {"detail":"The model text-davinci-003 has been deprecated, learn more here: https://platform.openai.com/docs/deprecations}

要は、「モデルが古いからもう使えないよ」ということですね。これを解決しました。かなりハマったので、誰かのお役に立てれば。ただし、「LangChainをFastAPI経由でUnityで利用する」方法には触れていません。

# やったこと

コードを次のように修正しました。修正部分は強調してあります。

``` python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List

from fastapi import FastAPI
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter

from langchain.document_loaders import UnstructuredURLLoader
from langchain.llms import OpenAI

app = FastAPI()

items = []

# 学校のホームページのURL
urls = [
    "https://www.hogehoge.ac.jp/academy/",
    "https://www.hogehoge.ac.jp/campus/faq/",
    'https://www.hogehoge.ac.jp/academy/tokusyoku/',

]

loader = UnstructuredURLLoader(urls=urls)

text_splitter = CharacterTextSplitter(
    separator = "\n",
    chunk_size = 300,
    chunk_overlap = 0,
    length_function = len,
)

index = VectorstoreIndexCreator(
    vectorstore_cls=Chroma, # Default
    embedding = OpenAIEmbeddings(), # Default
    text_splitter=text_splitter,
).from_loaders([loader])

class Item(BaseModel):
    name: str
    description: str

@app.post("/items/")
def create_item(item: Item):
    items.append(item.dict())

    query = item.description + " 日本語で100文字以内で教えて"
    # answer = index.query(query)
    #### modelを追加 #####################
    llm = OpenAI(model_name="gpt-4")    # "gpt-3.5-turbo"でもOK
    answer = index.query(query, llm)
    #####################################

    
    return {"answer" : answer}


@app.get("/")
async def hello(query: str = None):  # queryパラメータはデフォルトでNone
    if query is None:
        return {"answer" : "こんにちは。ご質問をどうぞ。"}
    else:
        try:
            query = query + " 日本語で100文字以内で教えて"
            # answer = index.query(query)
            #### modelを追加 #####################
            llm = OpenAI(model_name="gpt-4")    # "gpt-3.5-turbo"でもOK
            answer = index.query(query, llm)
            #####################################
            answer = index.query(query, llm)
            return {"answer": answer}
        except Exception as e:
            # 例外発生時にカスタムエラーを発生させる
            raise HTTPException(status_code=500, detail=str(e))
```

Render.comで動かしています。

requirements.txtはこちら
```
fastapi
uvicorn
gunicorn
langchain==0.0.145
openai==0.27.8
chromadb==0.3.26
tiktoken==0.4.0
unstructured==0.7.10
```

ちなみにローカルで動かすとこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222292/dce18869-7b6f-14a5-badc-f959dc294830.png)

非常に雑ですみませんが、以上です。
CPU、メモリ、ストレージの関係

ストレージはCPUに比べ低速である。
読み書きのたびにCPUが待ち状態となるのは効率が悪い。
ストレージに比べ高速なメモリを仲介役とすることで効率よく処理を行なっている。
メモリ内のデータは定期的にストレージへ書き込まれる。

命令やデータはストレージからメモリにロードし、
CPUがメモリから読み込むことで処理を実行する。
ストレージへ保存する必要のあるデータは、メモリを経由してストレージへ保存される。

流れ
1.CPUがメモリから対象の命令(プログラムカウンタに格納されている番地にある)を命令レジスタへロードする。(フェッチする。)
2.プログラムカウンタの値を次の命令へのメモリアドレスへ更新する。
3.命令デコーダで命令を解読する
4.命令内容に従って、メモリ内のデータを汎用レジスタへロードしたり、命令の処理結果をメモリへ格納する。

・プログラムカウンタ
→次の命令があるメモリアドレスを格納する領域

・命令レジスタ
→メモリからロードした命令を一時的に格納する領域

・命令デコーダ
→命令を解読する命令解読装置

・汎用レジスタ
→データを一時的に格納する領域
SQLを復習する 〜その4〜

# 検索結果を加工する
SELECT文でのみSQLで取得した検索結果を並び替えたり、重複を削除するなど、加工することができる。

# 重複を削除する（DISTINCT）
`DISTINCT`を使用することで、結果表の中で内容が重複している行を削除して、表示できる。
データの種類を取得したい場合に役立つ。例えば、成績表に関するデータベースがから教科の種類を確認する場合、重複を削除せずに取得すると見づらくなってしまう。そこで`DISTINCT`を使用すると重複を削除し、教科の一覧を取得することができる。

```sql
SELECT  DISTINCT 列名 ・・・
FROM テーブル名
```

:::note warn
このDISTINCTは、ほかの修飾と異なり、SELECT文の最初に記述する必要がある。
:::

# 結果を並び替える（ORDER BY）
`ORDER BY`を使用することで、指定した列の値を基準として並び替えることができる。

SELECT文の最後に、並び替えの基準となる列名と並び順を指定する。

### 並び替えの指定
昇順・・・`ASC`
降順・・・`DESC`

ORDER BY句の初期値は昇順となるので、指定を省略すると昇順となる。
```sql
SELECT 列名・・・ FROM テーブル名
ORDER BY 列名 並び順
```

# 先頭から数行のみ取得（OFFSET・FETCH）
検索結果を並び替えた上で、その一部の行だけを取得したい場合に使用する。
ORDER BY句に続けて、OFFSET・FETCHをつけることで取得することができる。

:::note alert
MySQL、MariaDB、SQLiteではサポートされていないので注意
上記については別途記述
:::

```sql
SELECT 列名・・・ FROM テーブル名
ORDER BY 列名・・・
OFFSET 先頭から除外する行数 ROWS
(FETCH NEXT 取得行数 ROWS ONLY)
```


### MySQL、MariaDB、SQLiteで使用する場合
```sql
SELECT 列名・・・ FROM テーブル名
ORDER BY 列名 DESC LIMIT 3
```
`LIMIT`を使用することで取得したい行数を指定することができる。
【変数宣言】const, let, varの違いをわかりやすく解説する

# はじめに

現在フロントエンドの勉強に邁進しているのですが、実際実装するに当たって、序盤「変数宣言ってどれを定義すればいいの？」って悩む人は多いのではないでしょうか？自分は、`const` `let` `var`をどんな時に使っていいのかかなり悩んでしまいました。
そこで、今回は大きく3種類あるスコープ(`const` `let` `var`)の中で一体どれを使っていけばいいのか？を対比させながら解説できればと思います。皆さんの理解の一助になれれば幸いです。

# const,let,varの違い

変数宣言では、上記3種類のスコープが使われているのですが、使用用途は以下の通りです。

|スコープ|意味|再代入|再宣言|
|:-:|:--|:-:|:-:|
|const|constant(定数)|×|×|
|let|let(仮の値)|○|×|
|var|variable(変数)|○|○|

ここで再代入／再宣言とは、変数へ再度代入／宣言することをそれぞれ表しています。具体的な実装点は以下の通りになっています。

# 実装してみる
![スクリーンショット 2024-01-20 15.58.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661690/9464e096-9247-2501-7513-387cd5027af9.png)

実際にコードを書いてみると、それぞれのスコープに対して、`const`で宣言した変数では、再代入/再宣言でエラー、`let`で宣言した変数では、再宣言でエラーが出ていることがわかります。それに対して`var`は再代入/再宣言どちらも対応可能であることも確認できます。
しかし、`var`に関しては、再代入/再宣言両方できる利便性がある反面、大規模なシステムになった場合、全く別の部分で知らずに変数を宣言してしまうなど、影響範囲も少なくありません。そのことから、利用に関しては非推奨になっています。

# 最後に

今回は変数宣言について勉強しました。もともとプログラミングの入りがPHP,Rubyなどの動的型付け言語(インタプリタ言語)と呼ばれる型宣言しなくて良い言語から入っていたので、変数宣言なんてしなくていいだろうと思っていました。しかし、変数宣言を用いる静的型付け言語(コンパイラ言語)とは特性が大きく違うということがわかってから、これからも正しく使い分けていければなと思いました。
また、勉強していく中で躓きそうなポイントがあれば、言語問わず記事にしていこうと思います。
UE5備忘録:プレイヤーコントローラーとAIコントローラーの切り替え(Switching between Player Controller and AI Controller)

# 概要
Possesを使ってPlayer ControllerからAI Controllerへ、AI ControllerからPlayer Controllerへ操作のコントローラーを切り替える。
妙に行き詰ったので今後行き詰った人のためにも備忘録として残す。
もっといい方法があるかもしれない。

# やった事
PlayerCharacter側とAIContorller側でそれぞれ処理させる。プレイヤーが設定するPosses,UnpossesはPlayerController側で、Posses関数,Unposses関数を用いて行う。

## PlayerCharacter側の処理
コントローラーがUnpossesされた場合にイベントを走らせる。
やろうとしている事は
- __次のTickまで待つ__
- コントローラーが有効かを確認する
    - 有効な場合は何もしない
    - 有効でない場合はAIContollerを新規に作成する
    - 新規作成したAIContollerをPossesする


__Delay Until Next Tick__ を付けないとAI ControllerのPossesが間に合わずに機能しない。
新規作成するAIContollerはCharacterクラスのAIContollerClassを利用する。

![b1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680198/4b19f6ec-6fcb-26b4-96dc-1e9319a0abc5.png)


## AIContoller側の処理
AI ControllerはTickで走らせた中で、プレイヤーの制御が無くなった場合に一度だけPossesする。これだけ。
Tickイベント直後のbranchは別の処理を行っているだけなので気にせずに...
![b1_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680198/4d688923-7328-4ced-1659-0e1f1c8bd41c.png)

# 結果
Possesを使ってPlayer ControllerからAI Controllerへ、AI ControllerからPlayer Controllerへ操作のコントローラーを切り替えが出来た。

# あとがき
もっといい方法が見つかれば更新します。
AWS RecognitionでデータのExportとImportができるかどうか

個人的メモとして残しています。

## Import
Rekognition Custom Labels にてラベル付けしたデータセットの内容は、ListDatasetEntries API にて取得可能
（参考資料[1]）

用途に応じて、API のレスポンスを整形するなどで利用できる。
ListDatasetEntries API 実行時に必要となるデータセットの ARN は、対象プロジェクトに対して DescribeProjects API を実行することで確認可能。
（参考資料[2]）

### Import参考資料
[1] ListDatasetEntries
https://docs.aws.amazon.com/rekognition/latest/APIReference/API_ListDatasetEntries.html 
[2] DescribeProjects
https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DescribeProjects.html 

## Export
ローカル環境から S3 バケットにアップロードしたマニフェストファイルをインポートし、データセットを作成できる。
（ご参考資料[3]）

ローカル環境のデータを SageMaker Ground Truth 形式のマニフェストファイル形式にして、参考資料[4,5]を参照して形式を変換した上でインポート可能。

### Export参考資料
[3] Creating training and test datasets with images
https://docs.aws.amazon.com/rekognition/latest/customlabels-dg/md-create-dataset.html 
[4] Creating a manifest file
https://docs.aws.amazon.com/rekognition/latest/customlabels-dg/md-create-manifest-file.html 
[5] Converting other dataset formats to a manifest file
https://docs.aws.amazon.com/rekognition/latest/customlabels-dg/md-converting-to-sm-format.html
VSCodeでSpring Bootを利用してプロジェクトを新規作成する

# 初めに
新規参画したプロジェクトでSpring Bootを利用していたため、[クイックスタート](https://spring.pleiades.io/quickstart/)を参考にVSCodeでプロジェクトを新規に作成する

# クイックスタート
手順に従ってプロジェクトを開始する
(設定内容は画面から読み取れる設定を反映した)

## 新プロジェクト開始
Spring Bootで新しいプロジェクトを作成する。
→私はVSCodeで開発しているため、特に説明はなかったが拡張で以下を追加してプロジェクトの作成を実行した。
 * Spring Boot Extension Pack

 新規プロジェクトだと以下の画面が表示されるため、「Getting Started with Spring Boot in VS Code」を実行する。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616345/ac5cd035-be0b-f8c0-a3ff-733d49c71d41.png)

 「Create New Project」を押して初期設定
  * バージョン：3.2.2
  * 言語: Java
  * グループID: com.example
  * アーティファクトID: demo
  * パッケージングタイプ: jar
  * Javaバージョン: 17
  * 依存関係: "Spring Boot DevTools", "Spring Web"

  →上記の設定により以下のディレクトリが作成された
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616345/28b90011-f7ee-b33e-20e2-272640e1b93d.png)

## コード追加
Helloを出力するコードを追加する。
コードから以下が読み取れた。
* `@SpringBootApllication`: アプリケーションの開始宣言
* `@RestController`: エンドポイントの指定
* `@GetMapping`: pathを指定してマッピング
* `@RequestParam`: Requestのパラメータを指定

```
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
    public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
    }
    @GetMapping("/hello")
    public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
      return String.format("Hello %s!", name);
    }
}
```

## 実行
アプリケーションの実行
→ VSCodeでは以下から実行
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616345/b177725b-a22a-5f7f-90de-db0049042322.png)

 以下にアクセスしてHelloが出力されることを確認
 `http://localhost:8080/hello`
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616345/ea673d12-3a0a-93c7-dd46-fb55b361285d.png)


 
`@RequestParam`で`name`を宣言していたため、Requestのパラメータを指定すると出力文字が変更されることを確認
`http://localhost:8080/hello?name=spring`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616345/aaad85e6-cb5a-8697-25ad-d33ad16e1d4f.png)
試験 AZ-900: Microsoft Azure Fundamentals の学習方法

# はじめに
職場で Azure を触るようになり、 Azure の基礎の網羅的な理解のため AZ-900 試験を受験することにしました。
無事に合格できたため、本記事で学習した内容を投稿します。

# 試験 AZ-900: Microsoft Azure Fundamentals とは
Azure の学習の出発点に位置付けられている最も基本的な資格です。
試験費用は
詳細は下記のマイクロソフト社のサイトをご参照ください。

https://learn.microsoft.com/ja-jp/credentials/certifications/exams/az-900/

# 学習方法概要
試験に向けて学習した内容は以下の 3 つです。

1\. Microsoft Learn で Azure の概要を掴む
2\. 参考書を 1 周して AZ-900 の概要を掴む
3\. Udemy で模試を受講する

# 1. Microsoft Learn で Azure の概要を掴む
Microsoft Learn とはマイクロソフト社が提供している自社製品・サービスの学習サイトです。

Microsoft Learn では AZ-900 に関する以下 3 つのラーニングパスを提供しています。
Azure の経験がほとんどない方だととっつきにくい面もあるので、あまり深追いはせず、さらっと概要を掴むだけでよいと思います。

また、学習目安としては 6 時間程度となっており、それなりのボリュームなので試験が迫っている人はここはスキップしても OK です。
（私の場合、気になった用語について調べながら進めたため、 10 時間程かかりました。）

https://learn.microsoft.com/ja-jp/training/paths/microsoft-azure-fundamentals-describe-cloud-concepts/

https://learn.microsoft.com/ja-jp/training/paths/azure-fundamentals-describe-azure-architecture-services/

https://learn.microsoft.com/ja-jp/training/paths/describe-azure-management-governance/

# 2. 参考書を 1 周して AZ-900 の概要を掴む
AZ-900 の参考書は幾つか出ていますが、自身に合ったものを 1 冊やればいいと思います。
私はたまたま近くの本屋にあった以下の本を購入して学習しました。

[合格対策 Microsoft認定 AZ-900：Microsoft Azure Fundamentalsテキスト＆問題集](https://www.amazon.co.jp/%E5%90%88%E6%A0%BC%E5%AF%BE%E7%AD%96-Microsoft%E8%AA%8D%E5%AE%9A-AZ-900%EF%BC%9AMicrosoft-Azure-Fundamentals%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%EF%BC%86%E5%95%8F%E9%A1%8C%E9%9B%86/dp/4865943463/ref=asc_df_4865943463/?tag=jpgo-22&linkCode=df0&hvadid=622955539433&hvpos=&hvnetw=g&hvrand=17761340092511106693&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009309&hvtargid=pla-1943895111001&psc=1&mcid=6b6d80abcddc3019932156b529046e3f&th=1&psc=1)

# 3. Udemy で模試を受講する
私はコースの評価点や評価数から判断して、下記のコースを受講しましたが、他のコースでも OK です。
模試の問題を 9 割くらい解けるように仕上げたら、本番の試験を受験して問題ないと思います。

https://www.udemy.com/course/az900-azure/
MavenでSpringBootを使ったライブラリjarを作成する方法

SpringBootを使ってライブラリ（jar）を作る際、Mavenで単純に作成するとBOOT-INF配下にclassファイルが配置されるため他のJavaから参照できない。
他のjarと同様にトップフォルダにclassが配置されるようにする対応。

## pom.xmlを変更する
pom.xmlに通常のjarファイルを作成する設定を追記する。
```
	<build>
		<plugins>
            <!-- 他のplugin情報 -->
            ・・・
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<executions>
					<execution>
						<!-- 他のプロジェクトから参照するため通常JARを作成-->
						<id>create-jar</id>
						<phase>package</phase>
						<goals>
							<goal>jar</goal>
						</goals>
						<configuration>
							<classifier>library</classifier>
						</configuration>
					</execution>
				</executions>
			</plugin>
        </plugins>
	</build>
```

上記の設定でBOOT-INF配下にclassファイルが配置されたjarと、他のプロジェクトから参照可能なjar（～-library.jar）が作成できるようになる。

## Mavenのコマンドでjarファイルを作成する
以下のコマンドにてjarを作成する。（cursorのターミナルで実行）
```
./mvnw.cmd clean package
```
正常終了すると「.../target」フォルダ配下にjarファイルが作成される。