OmniAICreator/Qiita-1.07M huggingface dataset:
Cloudflare Spectrum で FTP サービスを保護する - Amazon Linux 2

## Cloudflare Spectrum とは
レイヤー３/４で提供している TCP/UDP サービスを DDoS 攻撃から保護すると同時に、オリジンをインターネットに晒すこと無く、Cloudflare が持つルーティングで効率良くコンテンツをお届けすることに最適なソリューション

## FTP サービスを Cloudflare Spectrum で保護してみる
1. 今回は Amazon Linux 2 をオリジンとした FTP を構築
2. FTP は vsftpd 3.0.2
3. Spectrum はパッシブモードでの FTP をサポート
4. Spectrum をご利用いただくには、Cloudflare アカウントチームへご連絡ください
5. Spectrum でご利用いただくサービスのドメインを、Cloudflare ポータルへ登録する必要があります

### AWS EC2 インバウンドルールの設定
EC2 のインバウンドルールで接続ポートとデータポートをオープンします

![Screenshot 2024-03-25 at 12.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/2a4639ce-a3bd-b850-f033-1f4e195af513.png)

*ハマったポイント
AWS では FTP デフォルトの 21 番がパッシブモードでデータポートに受け渡せない？ので、210 番をオープン

$ sudo yum install vsftpd
$ vi /etc/vsftpd/vsftpd.conf

### vsftpd の設定
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
allow_writeable_chroot=YES
ls_recurse_enable=YES
listen=YES
listen_ipv6=NO

pam_service_name=vsftpd
userlist_deny=NO
userlist_file=/etc/vsftpd/user_list
force_dot_files=YES
tcp_wrappers=NO
pasv_enable=YES

pasv_address=ftp.xxx.net
(ftp.xxx.net には Spectrum で設定したサブドメインを入力します)
pasv_addr_resolve=YES
pasv_promiscuous=YES

listen_port=210
pasv_min_port=20000
pasv_max_port=20020
port_enable=YES

### Spectrum の設定
![Screenshot 2024-03-25 at 12.48.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/9fa37972-36cc-b709-7e09-45b3d84b51f4.png)

接続ポートとデータポート、両方の設定を行います。
データポートは範囲指定可能

![Screenshot 2024-03-25 at 12.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/e77b11f7-3aeb-17d5-8084-dd866cce983e.png)


接続、Ingress、Egress が発生すると転送量など見ることができます。

オフィシャルドキュメントはこちら
https://developers.cloudflare.com/spectrum/about/ftp/
21番ポートでの実装で説明されていますが、環境によっていはハマるポイントでもあるようです


Windows Server IIS 編はこちら
https://qiita.com/dd_cloudflare/items/731b1dc9d3d98ceb41a5
Cloudflare Spectrum で FTP サービスを保護する - Windows Server IIS

## Cloudflare Spectrum とは
レイヤー３/４で提供している TCP/UDP サービスを DDoS 攻撃から保護すると同時に、オリジンをインターネットに晒すこと無く、Cloudflare が持つルーティングで効率良くコンテンツをお届けすることに最適なソリューション

## FTP サービスを Cloudflare Spectrum で保護してみる
1. 今回は Windows Server IIS をオリジンとした FTP を構築
2. FTP は IIS (Windows Server 2022)
3. Spectrum はパッシブモードでの FTP をサポート
4. Spectrum をご利用いただくには、Cloudflare アカウントチームへご連絡ください
5. Spectrum でご利用いただくサービスのドメインを、Cloudflare ポータルへ登録する必要があります

### AWS EC2 インバウンドルールの設定
EC2 のインバウンドルールで接続ポートとデータポートをオープンします

![Screenshot 2024-03-25 at 12.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/2a4639ce-a3bd-b850-f033-1f4e195af513.png)

*ハマったポイント
①　AWS では FTP デフォルトの 21 番がパッシブモードでデータポートに受け渡せない？ので、210 番をオープン
②　IIS の Configuration にて、Data Channel Security を Passive の通信に対して無効にしないとダメ

### Spectrum の設定

![Screenshot 2024-03-25 at 12.48.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/54b48d6e-642d-17cd-6d8f-8b09ef91f48f.png)

接続ポート（ここでは 210番）、そしてもう一つデータポート用の設定（私は 20000 - 20020を利用）でもします。
ポートの範囲指定可能。

### Windows Server で FTP を立ち上げる

Programs and Freature より、Turn Windows freatures on or off へ進んでください。
ここで重要なのは、FTP Extensiblity も同時に有効にすることです。
これを有効化しないと、ハマったポイント ② の Data Channel Security 機能の操作ができません。

![Screenshot 2024-03-27 at 17.33.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/aa90f274-c232-7908-f0ad-1657e72442cd.png)

### IIS で FTP の設定をしていく

![Screenshot Bindings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/06ab3bb1-e145-25ae-167b-35cbc140d44d.png)
ここでは ポートを指定します。21 ではなく、210 にしています。

![Screenshot 2024-03-27 at 13.58.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/2e08d83a-c051-7733-bcf6-1412b2750b84.png)
External IP Address of Firewall に Spectrum で設定したドメイン（例：ftp.example.com の IP アドレス）を入力

![Screenshot Inbound rules.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/19d824f3-2f9d-b67e-9865-0821097034fa.png)

Windows Defender Firewall with Advanced Security にて、Inbound Rules を接続ポート、データポート ともに設定する

その他、ユーザー作成や FTP フォルダの作成がありますが、ググっていただければすぐに参考となる手順が出てくると思います。

![Screenshot 2024-03-27 at 17.01.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/8108b6a3-c401-1680-3c20-37c55b932bad.png)

FTP の Configuration Editor で system.applicationHost/sites の配下にあります、
matchClientAddressForPasv を False に変更して、Apply します。
説明はこちら
https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/ftpserver/security/datachannelsecurity

この設定ができていないと、データポートを利用するフォルダへのアクセスで切断をくらいます。
Response: 	150 Opening BINARY mode data connection.
Response: 	550 The network connection was aborted by the local system. 
Error:        	Failed to retrieve directory listing

Configuration Editor なるものが諸々の詳細設定になっているのですね。
ハマっていた期間、Windows といえば「Registry」かと思っていましたが、そこに手を出さずに解決ができたのは幸いです。。。

### FTP Serviceを再起動して完了

FTP Service を再起動して、
エラー無く FTP クライアントから接続でき、データ転送を確認してください。


![Screenshot 2024-03-27 at 19.05.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442885/8d9d6e2b-27b5-217e-cae0-eab83d908a80.png)

転送がされて 30 - 60秒ほどのタイムラグがありますが、Spectrum 設定一覧でトラフィックが見れます
CSSのスペースの有無で子要素かが変わる

## 初めに
現在いろいろと勉強中です。
カリキュラムと同様に書いたつもりが、cssのスペースの有無で表示が変わってしまったので残しておきます。

## 本題
以下のコードです。&を使ってのコードはあまり見慣れていなかったのですが、
```
& .text {
        ～～～～～ // 何かしらのcssコード
        
        &.add { 
            ～～～～～～ // 何かしらのcssコード
        }
```
上記の` &.add `の部分ですが、ここにスペースが入るか（`& .add`）で意味が変わります。

スペースがない場合は元のhtmlタグで
```
<div class="text add">
    <p>~~~</p>
</div>
```
に対してのコードになります。

スペースがある場合は
```
<div class="text">
    <p class="add">~~~</p>
</div>
```
これに対してのコード。

スペース一つで全然違う意味になってしまうみたいです。
ほかにもいろいろな書き方できるみたいです。調べてみます。
【ChatGPT＋DALL-E3】ジェンガはムズい。


　どうも、カーブミラーです。

　今回は、ジェンガを描きます。“えっ？なんで？”となることでしょうね。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　ニュースは
　　ありませんので、
　　　本題にいきます。

　今回は、ジェンガです。

　まずは、
　　Google SGEに
　　　聞きますか。
***
***Google SGE***
ジェンガは、1983年にイギリスで発売されたバランスゲームです。スワヒリ語で「積み上げる」を意味し、54本の細長いブロックを互い違いに組み合わせた塔から、1本ずつ順番にブロックを抜いて、塔の上に積み上げていくゲームです。バランスを崩し塔が崩れたら負けとなります。﻿
***

　補足するならば、
　　ブロックを三つで一段を構成し、
　　　それが18段積み重なっています。

　これを
　　描画してもらおう
　　　というわけです。

　ところが
　　リトライや
　　　プロンプトの書き換えを
　　　　どんなにやっても
　　　　　ゲーム途中の状態しか
　　　　　　描画されません。

　これは
　　DALL-E3が学習したのが
　　　ゲーム途中の状態だけだった
　　　　からなのだと思われます。

　あちこちの写真を
　　見ても、ゲームスタート状態は
　　　少ないですからね。

　さて、
　　どうしたらいいか……。
***
　とりあえず、
　　ゲームスタート状態の
　　　写真を探して、
　　　　それをChatGPTに
　　　　　解析してもらいました。

　ChatGPTは最初から
　　これをジェンガだと
　　　わかっていました。

　それで
　　プロンプトを
　　　作成してもらって
　　　　描画してもらったのですが、
　　　　　やはり、ダメ。

　それでも
　　プロンプトをイジって、
　　　なんとか出たのが、こちら。
![1711594111370.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/a1ab6960-cacb-8ff4-2795-29d56d41e431.jpeg)

　Promptも
　　アップしましょう。
```Text:ジェンガPrompt
An office desk setting with a clear view of a computer keyboard, mouse, and desk mat in the background. On the desk, there is a calendar and a boxed item. To the right, a shelf is filled with various items, creating a busy yet organized look. In the foreground, a perfectly stacked tower of Jenga blocks stands tall, with no missing pieces, conveying a sense of order and readiness.
```

　翻訳すると
　　こうです。
「背景にはコンピューターのキーボード、マウス、デスクマットがはっきり見えるオフィスデスクの設定です。デスクの上にはカレンダーと箱入りのアイテムがあります。右側にはさまざまなアイテムで満たされた棚があり、忙しいながらも整理された外観を作り出しています。前景には、欠けているピースのない、完璧に積み上げられたジェンガの塔がそびえ立っており、秩序と準備の感覚を伝えています。」

　なのですが、
　　これは、ガチャで描画できた
　　　だけのようです。

　その後、
　　同じPromptで
　　　何度かやってみたところ、
　　　　穴あきばかりでした。
***
　ジェンガを
　　ここまでやるのに、
　　　四つもセッションを
　　　　使いました。
　　　　　制限にも一度、
　　　　　　引っ掛かりました😅

　こういうことも
　　たぶんにあります。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
redoclyで作成したAPI仕様書からモックを作る

# はじめに
API仕様書を作成する手段としてよく使われるものに、以下があると思います。

- API Blueprint + aglio
- Swagger
- redocly
- Excel
- PDF

昨年「API Blueprint + aglio」で作られたAPI仕様書をredoclyで作り直しました。

作り直した理由は以下です。

- 「API Blueprint + aglio」の仕様書の記法が好きではなかった
- YAMLを使ったAPI仕様書がイケイケな雰囲気になっている
- 「API Blueprint + aglio」の場合は、API仕様書を作成して終わり
- 「リクエストパラメタ一覧を書く + JSONのサンプルを書く」という手間が煩わしい

作り直す中で、便利だった機能なので紹介しようと思います。

この記事を見てredoclyを選択するきっかけになっていただけたらと思います。

# 注意
この記事では

- redoclyの使い方
- stoplight studioの使い方

などは説明しません。
ご注意ください。


# 完成品

### OK

リクエスト
```bash
curl --request POST \
  --url http://localhost:4010/create \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: insomnia/8.6.1' \
  --data '{
        "title": "test",
        "content": "aaaa"
}'
```

レスポンス
```
{"result":true,"blog_id":1}
```

### NG

リクエスト
```bash
curl --request POST \
  --url http://localhost:4010/create \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: insomnia/8.6.1' \
  --data '{
}'
```

レスポンス
```
{"result":false,"error_messages":["ブログタイトルは必須です","ブログ本文は必須です"]}
```

# 手順

１．nodeをインストールします
参考：　https://zenn.dev/shichi18/articles/20230325-01-50eb75b9096004
（API仕様書の作成時に、使うことになると思います）

２．Dockerを使えるようにします。

３．API仕様書を準備します
API仕様書は以下にサンプルを置いておきます。
ソース：　https://github.com/JunyaSatou/prism

４．prismを起動します
```bash
docker compose up prism-sample
```


# さいごに
API仕様書は作って終わりではなく、API仕様書からモックを作れるので、
API仕様書の作成担当とAPIの実装担当が分かれている場合など、
クライアント側はAPIの実装を待たずして開発ができるので便利ですね。
DatabricksのGitフォルダー

先日、ReposのUIにアクセスしたらメッセージが表示されてました。

![Screenshot 2024-03-27 at 19.53.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/833ee1d8-a73a-eb67-2384-5eee039a1891.png)

> Gitフォルダがパブリックプレビューで利用できるようになりました。

気づいたらマニュアルも更新されていました。

https://docs.databricks.com/ja/repos/what-happened-repos.html

要はこれまではGit連携はReposフォルダ配下でしかできていなかったのが、ホームディレクトリ配下のフォルダでGit連携ができるようになったとのことです。

Gitフォルダーを作成してみます。設定方法は以前と変わりません。
![Screenshot 2024-03-27 at 19.54.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a43968c9-e541-1d76-6cf8-9bbc7bb89fa5.png)

ホームディレクトリ配下で連携されるようになりました！
![Screenshot 2024-03-27 at 19.54.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f947d4d2-0688-98f7-2b6d-0cdc39124a5a.png)

UIも変わってないですね。
![Screenshot 2024-03-27 at 19.54.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1491b465-5559-8d19-7e5c-cfc77e7fd98e.png)

行ったり来たりが削減されるので、是非ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
サーバー内のメールを読めるように変換する

メールが正常に受信出来ていない時に、メールサーバ内にあるメールを読みたいのに、いざ開いてみたら読めなかった時に読む方法。
```
iconv -f 変換前文字コード -t 変換先文字コード /path/to/before_convert_mail > /path/to/after_convert_mail.txt
```
変換前の文字コードは変換前のメールを開いてContent-Typeのcharsetを見れば良いのかなと。
読めない時はだいたいISO-2022-JPだと思うので、
```
iconv -f ISO-2022-JP -t UTF-8 /path/to/before_convert_mail > /path/to/after_convert_mail.txt
```
で大丈夫だと考えますが、念の為確認しましょう。
あと、変換して読んだファイルは削除しておきましょう。
エンジニアに転職するためにやったこと、気を付けるべきこと

## ごあいさつ
4月からエンジニアとして働くことに決まっている初心者です。
前の会社は新卒から6年間勤めていました。IT系とは全く異なる業種です。
IT系のエンジニアとして貢献したいという気持ちが強くなり、
ひとまず今しかできないことをやってみようと思い、転職しました。

なぜエンジニアになりたいのかなどは人それぞれと思うので割愛します。

今年で30歳になり、年齢的にかなりきついのは自覚していますが、頑張ります。

## やったこと
自分は転職するにあたり全体で約3.5か月かかり、内定は3社からいただきました。
転職の流れは以下の通りです。
①スクールで勉強（2.5か月）
②転職活動（1か月）

### ①スクールに通う
通ってよかったと思うのは以下の理由です。
- ポートフォリオが作成できた
- 勉強の習慣化ができた

スクールへ通うことにしたきっかけは転職エージェントへ相談したことです。
3社のエージェント（大手転職サイト2社、エンジニア転職サイト1社）から話を聞き、エンジニア転職サイトの方がスクールでのポートフォリオ作成を勧めてくださいました。

自分自身、一人で勉強を始めるには
- 何から勉強を始めればよいのか
- 学んだことは転職でのアピール材料になるのか（どうアピールすれば良いのか）

など不安が多く、あまり時間を無駄にできなかったのもあり、スクールを頼りました。

スクールのカリキュラム、サポートで良かった点はそれぞれ、
（1）カリキュラムを活かして、自分で考えたアプリを作れること
（2）メンターのサポートが手厚い

（1）については、
最初に基本事項を習った後に、自分で「こういうアプリが作りたい」を考えて作成に入ることで、
- なぜそのアプリを作ったのか
- どんなところを工夫したのか
を意識したアプリ作成になったと思います。
スクールによっては全員一律で同じアプリを作るところもあるみたいですが、
これは実際に転職でのアピールでも話す内容になるので、絶対必要だと思います。
（何より、自分で作った感がうれしい）

（2）については、
「質問ができる」という意味ではないです。詰まったところは自分で解決することが大前提として、「モチベーションの維持」という点で大変助かりました。
スクールでは最低でも週１回メンターの方と面談の時間があり、自分の取り組み方やポートフォリオに対しての現役エンジニア視点からのアドバイスがあり、客観的な基準で取り組むことができました。人に見てもらえるというのは個人的にはそれだけでモチベーションになると思います。

また、勉強の習慣化についてはひとまず「毎日コードに触れる」を目標にしていました。
勉強時間は大体ですが、仕事の日は2-4時間、休みの日は8-10時間ほど勉強していました。

### ②転職活動
こちらは上記でスクールに通うのをおすすめしていただいたエージェントの方と進めていきました。
およそ１か月間で活動を終わらせにかかったので、正直かなり急いで対応してもらいました。

自分の転職活動の流れは
⓪勉強
①履歴書、職務経歴書作成（エージェントの方が添削してくれます）
②書類選考
③模擬面接（2回）
④面接（会社により1~2回程度）
⑤内定
という流れでした。

後述しますが、ここは気をつければよかったと思うことがあります。

活用したのがエンジニア向けの転職サイトだったので、エンジニアからどう見られるかを意識して
書類の添削、模擬面接や各企業担当の方と話をさせてくれたのは良かったです。


## 気をつければよかったこと
こちらについては主に転職活動についての話です。
勉強や転職活動を優先したあまり、企業研究が疎かになりました。

気を付けるべきと感じたのは
- いつまでに内定がほしいのか（≒いつ会社に退職を伝えるのか）
- そのためにはどれくらいの転職活動の期間が必要なのか

自分は退職交渉の期間を忘れていて、それに気づいて急いで転職活動に移りました。
（自己責任ですが、エージェントの人にも気づいてほしかった…）

書類選考に出す企業はエージェントの方が選んでくださるのですが、
時間がなかったのと、会社を選べるほどの立場（未経験、年齢から）ではなかったので、とりあえず全部出すことにしました。

結果論ですが、ここでもう少し吟味するべきだったかもしれません。
書類選考通過後、面接の日程が決まってからようやくその企業のことを調べ始めたのですが、
その企業が何をやっている会社なのか、どんなものを作っているのかなど（当然ですが）全然違いました。「この企業はちょっと違うな」となっても面接日程は決まっていて、リミットの時間がある中ではよくなかったと思います。

これも当然の話ですが、
- 面接日が決まればその時間は拘束される（貴重な面接可能時間が埋まっていく＝ほかの企業の面接は組めない）
- 内定後は内定承諾期間が設定される（いつまでも内定承諾を待ってくれるわけではない）
という点も改めて注意です。

最終的には自分が納得いく企業を選ぶことができましたが、それでもやっぱりここの企業の選考も待てたらなとか思うところもありました。

## 終わりに
長々書いてしまいましたが、他にも感じたことなどあった気がします。駄文ですみません。
はじめての転職活動ですべてうまくいくことなんて無いと思うので、ひとまず決めた会社で技術を磨きます。（幸いにも早くから開発に入れそうなところではあるので。）

家族のことや年収（めっちゃ下がりますが）などそこまで気にすることが多くないうちにチャレンジ出来て良かったと思います。

今後は技術の記事を書けたらいいなと思います。
ありがとうございました。
基本設計書

```
基本設計書作成ツール
draw.io-20.8.16-windows-installer.exe    2024/3/28 時点
便利です
draw.io検索ダウンロード

-----------------------------------------------------------
基本設計書内容

〇項目レイアウト
初期表示
サイズ
色
形状


〇アクション
ボタン押下
リンククリック
プルダウン選択


〇画面遷移
遷移元

遷移先


〇データインプット、アウトプット

インプット

アウトプット


CSV
帳票



===========================================
実参考例
△表紙シート
タイトル
日付
△機能概要シート
概要
　要件定義機能から転記
画面遷移
　遷移元画面一覧
　遷移先画面一覧
△画面シート
　画面イメージ
　画面項目
　　ボタン群
　　　アクション記載
　　項目
　　　DBテーブル
　　　DBカラム
△処理概要シート
　初期表示
　アクション詳細
　エラー処理詳細
△表題シート
共通内容記載のため
　システム名
　資料名
　題名名
　作成者
　作成日
　バージョン





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

 draw.io  使用方法メモ


 １　四角ダブルクリックで文字入力可能
 ２　四角の線と中身は色設定可能
 ３　メニューからテーブル自由行と列を選択可能、便利です。
 ４　四角内部の文字は左寄せ設定可能。
 ５　オブジェクト選択して、左揃え可能。
 ６　エクセルようなシート増える可能、ここはページ１，ページ２の感じ、便利です。
 ７　四角は角の場合、一番右上の点を引くと、四角の周りの角度調整可能です、便利です。
 ８　色選択時、左の四角色選択で便利です。
カウントアップ機能の実装

# 1. pages/practice/01.tsxのreturnで返すjsxを以下に置き換えてください。

    <div className="mx-auto mt-10 max-w-4xl">
      <div className="flex justify-center">
        <div>
          <h2 className="mb-4 text-center text-6xl">{count}</h2>
          <Button label="カウントアップ" variant="primary" />
        </div>
      </div>
    </div>

# 2. useStateで管理されたButtonのonClickイベントの実装

- [ ] ButtonにonClick属性を追加してください。
- [ ] state変数を定義してください。変数名は"count", セッター関数はsetCountとします。
- [ ] 追加したonClick属性にsetCount内でcountを1追加する関数を設定してください。

※注意点
- state変数は必ず関数コンポーネントの定義内かつ、returnより前で宣言してください。
- onClick属性で指定するのは実行する関数の「コールバック関数」です。コールバック関数は関数定義として記述します。
- state変数は「const [name, setName] = useState(初期値)」のように指定します。nameや初期値の部分は適切な文字列に適宜修正してください。

# 3. onClickイベント内の関数定義をreturnの外に書き出す

#2 で正しく実装を行うと、ButtonコンポーネントのonClickイベントには以下のようなコールバック関数が定義されます。

`setCount( count + 1 )`

つまり、Buttonコンポーネント全体は以下のようになります。
```
          <Button
            onClick={() => setCount(setCount( count + 1 ))}
            label="カウントアップ"
            variant="primary"
          />
```
【お題】
- [ ] onClickイベント内の関数定義をreturnの上部（state変数宣言の下）に書き出してください。

※注意点
- 関数はアロー関数で定義してください。
- 関数を代入する変数は、「onClickCountUp」としてください。

# 4. onClickCountUpの修正
onClickCountUpの関数定義部分を正しく記載すると、以下のようになります。
`const onClickCountUp = setCount(count + 1)`

しかしこれでは、onClickCountUp内で複数のsetCount関数を実行しても、一番したの文しか実行されません。

- [ ] 関数定義の部分を以下に書き直してください。

修正前
```
  const onClickCountUp = () => {
    setCount(count + 1);
  };
```

修正後
```
  const onClickCountUp = () => {
    setCount((prevState) => prevState + 1);
  };
```
シェルスクリプトでGithub Release から最新版をダウンロードする

# はじめに

同じものはたくさんあるけれど、自分で手軽に利用したかったので作ってみた。
実際は curl と jq を呼んでいるだけ。
ファイル名の先頭一致で抽出しているので、似たファイル名が存在していると目的のファイルを取得できない可能性がある。

例はいつものお世話になっている yuru7 さんのフォントをダウンロード

# コード

```bash
#!/bin/bash

function download_gh_release() {
  echo Download $2 from github: $1
  curl -sLO $(curl -s https://api.github.com/repos/$1/releases/latest | jq -r '.assets[] | select(.name | startswith("'"$2"'")) | .browser_download_url')
}

download_gh_release yuru7/moralerspace MoralerspaceNF
```
作成してみたいアプリを考える

## はじめに
なぜ、作成してみたいアプリを考えたかというと、
早くもやる気がなくなって・・・。目標を明確にしないと続かないなと思い。雑ではありますが作ってみることに。
（自分しか見ないし、綺麗に書くことに時間を掛けたくはない）


## 最低限のイメージを図で作成してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781864/17c5417f-58ab-d329-3562-a051bd2b1758.png)
＊フォーマットなんてありゃしないし、Webアプリなのにスマホっぽい

以上で最低限の「大喜利アプリ」としての動作はするかなの気持ち。

## 今後の進め方
- 静的に作成（サクッと）
- 動的にできるよう（DBとかもここで考える）

## 追加したい機能
- ログイン
- ユーザ種別(管理者、特別、一般) 
- 投票
- 部屋を作って特定ユーザで出来る別モード
- その他もろもろ

## 終わりに
ぼんやりと作成したいものが頭にあったが、書き出すことで現実味が出た。ちゃんと書き方を学びながら仕様書？は作成した方がいいのかも知れないが、今回の目的の主ではないため後悔していない。
作りながらもっといい画面や、追加機能については考えながら楽しみながら作成したい。
矢をを改造？したい!!!!

## 矢の飛ばしたい!!

### はじめに
--------------------------------------
皆さんは、
「矢をコマンドで飛ばしたい」
「矢は一定のダメージしか与えられない」
など思ったことありますか？

**この記事は、矢関連のコマンドを詳しく教えよう!!** という記事になります

-------------------

### ダメージ量を変えるコマンドは簡単！
ダメージ量を変えるときに使うコマンドは、
#### /summon
コマンドだけです!!
まあ厳密に言えば、最後にNBTという値を指定するだけ。
先にコマンドを教えます
/summon arrow ~ ~ ~ {damage:10d}
この一つのコマンドだけでダメージが10に増やせました!!
最後の d を忘れずに
damage:10dのところを好きな値に変えることでダメージ量をかえられます。

-------------
### 矢を飛ばしたい!!
矢を飛ばすために使うコマンドは５つあります。
チャット欄でのコマンドではできないので、コマンドブロックを用意しましょう

execute as @a at @s anchored eyes run summon arrow ^ ^ ^1 {Tags:["arrow"],life:1000s}

execute as @a at @s rotated as @s positioned 0.0 0.0 0.0 run summon armor_stand ^ ^ ^2 {Tags:["Motion"],Marker:1b,Invisible:1b}

execute as @e[tag=arrow] run data modify entity @s Motion set from entity @e[tag=Motion,limit=1] Pos

kill @e[tag=Motion]

tag @e[tag=arrow] remove shot_arrow

この五つのコマンドです。

始めの矢を召喚するコマンドに damage:10d
を追加するとダメージが10の矢を召喚できます。
Prismaでリレーションされたレコードの有無を条件にデータ抽出したい場合の解決策

## Prismaとは
Prismaとは型安全なデータアクセスを提供するTypeScriptベースのORMです。
https://www.prisma.io/

## やりたかったこと
以下のER図ようなテーブル構成があり、**「タグAが紐づいている」**、または **「全く紐づけがない」** アイテムを抽出する必要がありました。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2221418/9165e0f0-8ee1-09c0-153b-1976591735df.png)


**「タグID Aが紐づいている」** という条件はsomeを使用することで実現できます。
```js
where: {
    {
        tagsOnItems: {
            some: {
                tagId: 'A'
            }
        }
    },
}
```

しかし **「全く紐づけがない」** という条件が問題でした。  
Prismaは[オブジェクト型での条件式](https://www.prisma.io/docs/orm/prisma-client/queries/filtering-and-sorting)にexists句やsumの結果による判定を組み込むことができません。以下のようなリレーションにnullを指定する書式にも対応していません。

```js
where: {
    {
        tagsOnItems: null
    },
}
```

## 解決策
Prismaにはネガティブなリレーション判定プロパティは[none](https://www.prisma.io/docs/orm/reference/prisma-client-reference#none)しか用意されていないので、noneを使用して以下のように **「紐づけ対象が存在しない」** という条件を構築しました。

```js
where: {
    tagsOnItems: {
        none: {
            itemId: {
                not: ''
            }
         }
     }
}
```

Prismaでは条件の中にカレントアイテムのitemIdを明示的に指定することはできないので、itemIdで紐づいたtagsOnItemsに対して```itemId: {not: ''}``` (*)とすることで、 **「カレントアイテムのitemIdが設定されているレコード」** を絞り込むことができます。  
その絞り込まれたレコードに対してnoneを指定することで **「カレントのアイテムIDを持つレコードが存在しない」**＝**「紐づけ対象が存在しない」** という条件を実現しました。

※ itemIdはNOT NULLなので型制約によってitemId: {not: null}という条件が使用できません。そのため空文字を指定しています。

## 完成形
前述の各条件をORで内包することによって、**「タグID Aが紐づいている」**、または **「全く紐づけがない」** アイテムを抽出することができました。
```js
where: {
    OR: [
        {
            tagsOnItems: {
                some: {
                    itemId: 'A'
                }
            }
        },
        {
            tagsOnItems: {
                none: {
                    itemId: {
                        not: ''
                    }
                }
            }
        }
    ]
}
```
[Laravel] Windowsで文字化けしないCSVのエクスポート機能を作ろうとしたら、意外と詰まった話

# はじめに
個人でシステム開発の仕事をしています。
管理画面を開発しているときに、Windowsのエクセルでも文字化けしないようなCSVインポート機能を実装しようとしたんですが、
SJIS変換してもBOMをつけてもなかなか解決できなかったので、その解決方法を備忘録として残しておこうと思います。

## 開発環境
- php 8.2
- laravel 10
- docker

# やりたいこと
header_1 | header_2 | header_2|
------ | ------ | ------
body_a1 | body_a2 | body_a3|
body_b1 | body_b2 | body_b3|

上のようなCSVをエクスポートし、macでもwindowsでも文字化けせずにCSVを表示したい。

:::note info
- windowsではexcelで開くことを想定しています。
- headerはソース内で定義し、bodyはMySQLから持ってきた値です。
:::

# 試したこと
## SJIS-winに変換（うまくいかなかった）
まずは、単純にUTF-8をSJISに変換しました。

```php
mb_convert_encoding($text, 'SJIS-win', 'UTF-8');
```


しかし、エクスポートしたCSVを開くと、カタカナの濁音が　`?`　となっていまいました。

:::note info
具体的には「はばぱハバパ」のように濁音と半濁音のひらがなカタカナの文字列があったときに
「はばぱハハ?パ」と表記されてしました。
:::

## BOMの追加（うまくいかなかった）
BOM付きのUTF-8にすることで、ExcelがUTF-8で開いてくれると思い、
fopenした直後くらいに以下の一文を追加しましたがうまく行かず。

```
fwrite($handle, pack('C*', 0xEF, 0xBB, 0xBF));
```

:::note info
0xEF, 0xBB, 0xBF はUTF-8のBOM表す3バイトのシーケンスで、CSVがUTF-8エンコーディングであることを示しています。
:::

## 正規化 + SJIS-winに変換（うまくいった）
Unicodeで正規化して、正規化されたものをSJISに変換してうまくいきました。


```php
use Normalizer;

Normalizer::normalize($field, Normalizer::FORM_C);
return mb_convert_encoding($normalizedField, 'SJIS-win', 'auto');
```

:::note info
Normalizer::FORM_C で異なる方法の文字エンコードを統一した方法に正準合成します。
https://www.php.net/manual/ja/class.normalizer.php
:::

データ取得先の MySQL が `utf8mb4` で `utf-8` の拡張表現なのが影響していました。
そのため、正規化してSJIS変換でうまくいきました。

以下にサンプルコードを記述します。

## サンプルコード

- 前提
    - TestDataというモデルからbodyのデータを取得することを想定しています。
```php
    public function exportCsv(Request $request)
    {
        // データを取得
        $query = TestData::query();

        // CSVヘッダー
        $headers = ['ID', '名前', 'テストデータ1', 'テストデータ2', '作成日時', '更新日時'];
        $headers = array_map(function ($header) {
            return mb_convert_encoding($header, 'SJIS-win', 'UTF-8');
        }, $headers);
        $callback = function() use ($query, $headers) {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, $headers);

            // データを一行ずつ書き込む
            foreach ($query->cursor() as $row) {
                $csvData = [
                    $row->id,
                    $row->user_name,
                    $row->test_data_1,
                    $row->test_data_2,
                    $row->created_at,
                    $row->updated_at,
                ];

                // 各行のデータをShift-JISに変換して出力
                $csvData = array_map(function ($field) {
                    $normalizedField = Normalizer::normalize($field, Normalizer::FORM_C);
                    return mb_convert_encoding($normalizedField, 'SJIS-win', 'auto');
                }, $csvData);

                fputcsv($handle, $csvData);
            }
            fclose($handle);
        };

        $fileName = 'test_data_' . date('Ymd') . '.csv';

        return new StreamedResponse($callback, 200, [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => "attachment; filename=\"$fileName\"",
        ]);
    }
```

# 最後に
同じWindowsでも使っているExcelのバージョンなどによっても文字化けする/しないがあるので、文字コードの管理は難しいですね。
wslで、最小のカーネルをコンパイル その28

# 概要
wslで、kernel.elfのコンパイル、やってみた。
さらに、上のkernel見つけたので、コンパイルしてみた。
フロッピーイメージが、できる。
qemuで、起動してみた。
GUIが動く。フロッピーから読める。素晴らしい。

# 参考にしたページ

https://github.com/m-star18/HariboooteOS


# 手順

# コンパイル

```
cd git
git clone https://github.com/m-star18/HariboooteOS.git
ls
cd HariboteOS
make

```

# エラーでるので、対応。

```
sudo apt install nasm

sudo apt install mtools
```

# qemuで、起動。
Qeum Luncharで、haribooote.imgを起動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c8360d60-c23e-4900-f5eb-29a7b4dead09.png)

![スクリーンショット 2024-03-28 101422.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1b370c36-5f60-2071-42f0-8fd00df8ffad.png)



以上。
Flutter iOS Privacy Manifest対応(Flutter 3.19対応含む)

# Privacy Manifest対応するために必要な事

- Flutter 3.19対応
    - Deprecated imperative apply of Flutter's Gradle plugins
        - Gradle周りの書き方を変更する必要があります
- 各種ライブラリアップデート
    - だいたい最新のverにあげないといけないです
- Android APIレベル 34 対応
    - 一部SDKで求められます
    - 合わせてJava17対応も必要です
        - AndroidStudioはいい感じにしてくれるがCI(Bitrise)は対応必要
- FlutterのiOSプロジェクト自体のPrivacyManifest対応をする
    - 対応内容に関しては審査提出時のメールに記載の内容を確認する


# Flutter 3.19対応

※3.19.3にアプデしたものを元に書いています

## Deprecated imperative apply of Flutter's Gradle plugins

> Deprecated imperative apply of Flutter's Gradle plugins | Flutter
https://docs.flutter.dev/release/breaking-changes/flutter-gradle-plugin-apply

上記の公式のドキュメントを参考に修正します。

上記との差分に関して記載します。

### oss-licenses-pluginを使用している場合

```android/app/build.gradle
plugins {
    id "com.google.android.gms.oss-licenses-plugin"
}

// 削除
// apply plugin: 'com.google.android.gms.oss-licenses-plugin'
```

```android/settings.gradle
plugins {
    id "com.google.android.gms.oss-licenses-plugin" version "0.10.6" apply false
}
```

※android/build.gradleのbuildscriptは全部削除

### $kotlin version で　errorが出た場合

下記の記述は不要なので消してください(Kotlin 1.4.0以降は不要)

```
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
```

# 各種ライブラリアップデート

Flutter, iOS のライブラリに関しては特に問題なし

## Android

### jackson

verを上げたらエラーになったので一旦最新にはしない

```
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.3'
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3'
```

# Android APIレベル 34 対応

targetSdkとcompileSdkを34にして、各種javaのversionを17に変更

```android/app/build.gradle
android {
    compileSdk 34

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_17.toString()
    }
    
    defaultConfig {
        targetSdk 34
    }
}
```

※targetSdkとcompileSdkにversionがついていましたが34から省略するっぽい
※AndroidStudioはjavaのversion変更をいい感じにしてくれるが、CIはしてくれないので注意

## Bitrise java 17 対応

Stacks & Machines が Xcode15.3の場合、defaultのjavaのversionは11なのでStepで17を設定する必要があります。

Set Java Version のStepを追加しInput variables の java version を 17 にします。

このStepを FlutterBuild の前に実行します

## FlutterのiOSプロジェクト自体のPrivacyManifest対応をする

対応内容に関しては審査提出時のメールに記載の内容を確認する

PrivacyInfo.xcprivacyを作成し対応する

# 以上で、対応は終了です

# おまけ

## Gradleのversionは8系にするとエラーになるので注意

Android APIレベル を34にするとGradle8.4以上にしないといけなそうに書いてあったのですが、7系のままでもいまのところえらーにはならなかったです。逆に8系にするとFlutterのライブラリでnamespaceの記述がなくエラーになることが多いので注意。

## use_build_context_synchronously

自分の場合はdart analyzeでuse_build_context_synchronouslyが有効になったので無効にしました。
M5stack StampS3を秋月で買ったのでLチカして遊ぶ。(ESP32-S3)


目的
StampS3で遊ぶ

![o_coq003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7602d84f-2d2c-9abf-14e1-9978e9aeba1e.jpeg)


ボードのインストール

![o_cop99e.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d9bee39f-78ad-f4e9-b342-da75bcb62d4b.jpeg)

![o_cop99d.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f1c2b450-c532-d70d-55f4-c541f6512de4.jpeg)

プログラム

GPIO_Blink_1_M5S3

```c++


/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(1, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(1, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(1, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}


```
任意のプロファイルを指定してWindowsTerminalを開く

```settings.json
"name": "cmd.exe"
```

として登録してあるプロファイルを開くなら、

```posh
wt.exe --profile "cmd.exe"
```

ショートカットとしてタスクバーに登録すれば、任意のプロファイルがワンクリックで開けるようになる。
RHEL7 ELSのサポート対象に関して

# RHEL7のELS期間中のサポート内容に変更があります。
詳細は、RH社のサイト内で公開されています。
こちらをご確認頂くのが良いです。
- https://access.redhat.com/ja/articles/7038376

## 前提
ELS期間中に修正パッケージをご希望される場合、ELS-addon の追加購入が必要です。

# RHEL6 までの ELS の違い
RHEL6までのELS では、期間中のサポート対象は〜、という記載があったかと思いますが、
RHEL7では、【 Red Hat Enterprise Linux 7 Extended Lifecycle Support の<font color="red">除外対象</font> 】 となっています。<font color="red">※RHEL7 ELS サポート対象外の機能が明記されています。</font>
RHEL7で、ELSを予定されている場合、内容を確認されることをオススメいたします。

## RHEL7 ELS 対象外(抜粋)
詳細は、https://access.redhat.com/ja/articles/7038376 をご確認ください。
- Red Hat Enterprise Linux for Real Time
- ネットワーク機能仮想化 (NFV)
- Red Hat Enterprise Linux Extras チャネル
- Red Hat Enterprise Linux Supplementary リポジトリー
- Red Hat Software Collections (RHSCL)
- OpenJDK メンテナンス
    - OpenJDK 11 のメンテナンスは 2024 年 10 月に終了します。
    - OpenJDK 8 のメンテナンスは 2026 年 11 月に終了します。

# RHEL7 メンテナンスフェーズ終了とELSへの移行
あわせて、ELSへの移行についての情報も公開されています
- https://access.redhat.com/ja/articles/7029425

RHEL7のメンテナンスが2024年6月末 ということで、時間的な猶予はない状況ではありますが、
こちらの内容もご確認されることをオススメします。
レポートの保存ボタンがグレーアウトしている



+ [レポートを保存できないユーザーがいます。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A7LtHSAV)

:::note
ユーザーがレポートを「個人用カスタム レポート」フォルダーに保存すると、同じレポートを編集できるようになります。レポートをパブリック フォルダーに保存すると、編集できなくなります。したがって、レポートが「個人用カスタム レポート」以外のフォルダーに保存されている場合、このレポートを変更するたびに新しいレポートを作成する必要があります。
 

レポート フォルダーの読み取り/書き込み設定により、ユーザーはレポートをそのフォルダーに保存できます。ただし、フォルダー内のレポートを編集できるわけではありません。混乱するのはわかります。
 

残念ながら、パブリック フォルダー内のレポートを編集できるのは、「パブリック レポートの管理」権限を持つユーザーのみです。 Professional Edition を使用しているため、システム管理者プロファイルのみがこの権限を持っていると思います。ちなみに、EE/UE では柔軟性がなくなりました。
:::

+ [公開レポートの管理権限](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A7SywSAF)

:::note
レポート フォルダーの作成中に、[このフォルダーは次のユーザーのみがアクセスできます] オプションを選択し、希望する役割、役割、および部下を選択します。これにより、選択された役割のみがフォルダーにアクセスできるようになり、役割と部下のみがフォルダーの可視性を制御します。
:::

"Manage Public Reports" permission がいる？

プロファイルには権限を設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/95e7d770-a452-d7bc-d121-682471b1e39f.png)

フォルダーもロールで権限を与えているのですが...

管理部というロール。　このロールの下に総務ぼロールがある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fb16e3e2-d4e8-0ac3-8dc9-e1934c932cc3.png)

 試しに公開グループを作って設定したら保存ができるようになりました。今までは別名で保存しかできなかったですね。

 何が違うんだろう。
[Vuetify3]ボタンにtooltipもdialogも両方とも設定したい時

```package.json
{
  "dependencies": {
    "vue": "^3.4.15",
    "vuetify": "^3.5.9"
  }
}
```

dialogのactivatorもtooltipのactivatorも、どちらも同じコンポーネントのv-bindとして渡したい......という状況の解決方法。
こんな感じにしたら動いたっす。

```HogeComponentParent.vue
<v-dialog>
  <template #activator="{ props: dialogActivator }">
    <v-tooltip text="hello, tooltip">
      <template #activator="{ props: tooltipActivator }">
        <HogeComponent
        　　　　// mergePropsを使って二つのpropsを合成するのがポイント
          v-bind="mergeProps(tooltipActivator, dialogActivator)"
        />
      </template>
    </v-tooltip>
  </template>
  <template #default>
    <v-sheet class="pa-4">
      <p>hello, dialog</p>
    </v-sheet>
  </template>
</v-dialog>
```

参考

mergeProps()
https://ja.vuejs.org/api/render-function#mergeprops
Vite + TypeScript + Sass + GitHub Pagesで簡単デプロイ

初投稿です！
自己紹介ページを持っておりませんでしたので、復習がてらVite, TypeScript, Sass, GitHubPagesでサクッと公開してみましたので、
メモの意味も込めてまとめてみました。
こちらにソースコードも載せております。

https://github.com/kanbaru-github/suzuki-hiroaki-static

# 手順

### 1.以下のコマンドでViteのプロジェクトを作成→使用技術を聞かれるので好みのものを選択
```
npm create vite@latest
```

https://vitejs.dev/guide/

### 2.下記のコマンドでsass導入
```
npm install -D sass
```

### 3.GitHubPages自動化ライブラリを導入
```
npm install gh-pages --save-dev
```

### 4.package.jsonにスクリプトを追加
```
   "scripts": {
     "dev": "vite",
     "build": "tsc && vite build",
+    "deploy": "gh-pages -d dist",
     "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
     "preview": "vite preview"
   },
```

### 5.viteの設定ファイルでbaseを設定
```
import { defineConfig } from 'vite'

export default defineConfig({
  base: '/product-name/',
})
```
### 6.GitHubでリポジトリを作成& git push

### 7.GitHubPagesの設定画面でBranchを編集
[![Image from Gyazo](https://i.gyazo.com/252481888e53f72eceecc15db452f578.png)](https://gyazo.com/252481888e53f72eceecc15db452f578)

### 8. デプロイを実行
```
npm run build
npm run deploy
```

### 7.Actionsタブで成功が確認できれば完了です。
あとは好みに合わせてvite.config.jsやディレクトリ構造などを変更してみてください。

## CodeRabbit導入
導入手順に従えば問題ございません。
設定はGUIでも行うことはできますが、私はyamlファイルで設定いたしました。
こちらのファイルも上記のGitHubにあげました、ソースコードより確認が可能です。

https://coderabbit.ai/
宛先NAT/送信元NATをLANでやってみた

宛先NAT/送信元NATをLANで実施する
スタティックNAT

# 結果
送信元NATはできた。
宛先NATはやらなかった。LAN内のサービスをインターネットに公開する機会はなかなかない。LAN内でNATして送信先IPを隠したいって機会もなかなかないから。


# 宛先NAT 前提知識
宛先IPアドレスが変わる

⚫︎いつ使うのか
サービスを作ってネットに公開した時に、アクセスしたい誰かのために設定する。
•自分の作ったLAN内でサーバを公開して外からアクセスできるようにさせるとき。WANからLAN宛の通信が届いた時など。
•設定するインターフェースはインターネット側。ルーターによるかも

⚫︎実現方法
•Wan側にNAT descriptar設定
•natテーブルに公開したいサーバのローカルIPと接続を許可させたいグローバルIPを記載
※外から誰かが通信できるようにするために設定する

# 送信元NAT(ローカルで検証)
送信元IPアドレスが変わる
⚫︎いつ使うのか
•プライベートIPからグローバルIPに通信する時。家のLANからYouTube見る時とか。
•プライベートIPとグローバルIPは通信できないので、宛先も送信元もグローバルIPアドレスに変換する
•設定するインターフェースはlan側かな？やってないからわからない

⚫︎実現方法
•LAN側にNAT descriptar設定
•natテーブルにローカル送信元IPとwanに割り当てられているグローバルIPを対応させる
※発信元が外と通信するために設定する


## NW環境
           WAN    LAN
[Win11]-----[RTX830]-----[Win10]
送信元wan win11 → 宛先lan win10
やったことまとめてて思ったが、wanからlanに送信元natってあんまりないよね。ローカルでやってるからなんかよくわからんことになったな。

### 送信元NATの設定(static)
○RTX830
•ipアドレスの設定
wanのifの設定
ip lan2 address 172.16.1.1/24
lanのifの設定
ip lan1 address 192.168.1.101/24
•NATの設定
宛先が接続しているifのlanに設定
ip lan1 nat descriptor 1
nat descriptor type 1 nat
nat descriptor address 
lanの空いているipを選択。使われているIPと被ると変換されるipがlan内のipと重複するので空いてるipを選択した
outer 1 192.168.1.50 nat descriptor address 
wanの送信元ipを指定
inner 1 172.16.50
変換するipを指定
nat descriptor static 1 1 192.168.1.50=172.16.1.50 1

○Win11 経路設定
スタティックでwanのインターフェース指定
デフォルトゲートウェイ指定でもよい

○Win10 経路設定
スタティックでlanのインターフェース指定
デフォルトゲートウェイ指定でもよい

#### ログ
wiresharkでlanの宛先端末で確認。source ipが192.168.1.50になっていてpingも成功していた


#### 疑問に思ったこと
CLIでwanのインターフェースにIPアドレスを振る時にlan2を指定した。""の中の値。wanかと思ってた。show configだとla2にip指定されていたけど、GUIだとwanのipが指定されていたので設定は正しいと確認できた。
例
ip "lan2" address 192.168.10.1/24


○NATの仕組み
https://www.infraexpert.com/study/ip11.html
https://wa3.i-3-i.info/diff977network.html#:~:text=%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AB%E5%90%AB%E3%81%BE%E3%82%8C%E3%82%8B%E3%81%A9%E3%81%AEIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B%E3%81%8B%E3%81%8C%E9%81%95%E3%81%84%E3%81%BE%E3%81%99%E3%80%82,%E9%80%81%E4%BF%A1%E5%85%83NAT%E3%81%AF%E9%80%81%E4%BF%A1%E5%85%83IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8BNAT%E3%81%A7%E3%81%99%E3%80%82%20%E5%AE%9B%E5%85%88NAT%E3%81%AF%E5%AE%9B%E5%85%88IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8BNAT%E3%81%A7%E3%81%99%E3%80%82


○RTX830仕様
https://network.yamaha.com/products/routers/rtx830/index

○RTX830 Nat設定方法
https://network.yamaha.com/setting/router_firewall/security/lan_side/static_nat


○RTX830 Telnet有効化
https://www.rtpro.yamaha.co.jp/RT/manual/rt-common/setup/telnetd_host.html

○RTX830 LANとWANに固定IPアドレスを振る

○パソコンに経路追加
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/route_ws2008
【conda環境】コマンド一つでユーザ追加から環境構築までやりたい

# はじめに
新しく研究室に加わる人に対して、作業環境をセットアップするのは、これまで私の役割でした。研究室という環境上、この作業を繰り返していました。

しかし、このプロセスはいくつかの問題を抱えています。例えば、管理者権限を設定する必要があったり、環境変数の設定方法を忘れてしまい、毎回調べ直さなければならなかったりと、煩雑です。そこで、このセットアッププロセスを自動化することにしました。これにより、私が卒業した後も、このノウハウが残り、後輩たちの負担が軽減されると思います。特に新しいメンバーが加わるタイミングでは、この自動化ツールが大きな役割を果たすと確信しています。

# コード

以下に示すスクリプトは、Ubuntu環境下で新規ユーザーに対してMinicondaをインストールし、Jupyter Notebookを利用可能にするものです。スクリプトの詳細な説明はコード内コメントをご参照ください。なお、Minicondaで管理されるパッケージのインストールは、個々のニーズに応じて行ってください。

あと使用時はリダイレクトに管理者権限が必要なため、sudoで実行するようにしてください。

```sh:setup_env.sh
# Usage: bash setup_env.sh 新規ユーザ名 パスワード
# Description: 新規ユーザのホームディレクトリにMinicondaをインストールし、Jupyter Notebookを使えるようにする
# 注意: このスクリプトは、Ubuntu でのみ動作確認しています

#!/bin/bash

# 新規ユーザ名を引数として受け取る
new_user=$1
password=$2

# ホストIPアドレスの設定
# 自動で先頭のIPアドレスを取得しているので、jupyterlabなどのコマンドがうまく使えないときは、
# .bashrcなどを確認すること
host_ip=$(hostname -I | cut -d ' ' -f 1)

# ユーザを作成
sudo useradd -m -s /bin/bash $new_user

# パスワードの設定
echo "$new_user:$password" | sudo chpasswd

# ユーザのホームディレクトリ変数
user_home="/home/$new_user"

# パッケージ類のインストール
sudo apt update && sudo apt upgrade -y
sudo apt install -y git vim wget

# Minicondaインストーラーのダウンロード
sudo wget https://repo.anaconda.com/miniconda/Miniconda3-py310_23.11.0-2-Linux-x86_64.sh -O $user_home/miniconda.sh

# Minicondaのインストール (ユーザー権限で実行)
sudo -u $new_user bash $user_home/miniconda.sh -b -p $user_home/miniconda

# 環境変数PATHの設定をユーザーの.bashrcに追加
echo "export PATH=\"$user_home/miniconda/bin:\$PATH\"" >> $user_home/.bashrc

# Miniconda環境内でJupyter Notebookをインストール
sudo -u $new_user bash -c "source $user_home/miniconda/bin/activate && conda install -y jupyter"

# よく使うパッケージはインストールしておく
sudo -u $new_user bash -c "$user_home/miniconda/bin/pip install numpy matplotlib pandas lightgbm scikit-learn"

# 新規ユーザーの.bashrcにaliasを追加
# 空白なしのコマンドでipアドレス付きでjupyterを起動できるようにする
# つまり、リモートデスクトップなどを使う必要がなく、自分のPCのブラウザからアクセスできるようにする
echo "alias jupyterlab='jupyter lab --ip=$host_ip'" >> $user_home/.bashrc
echo "alias jupyternotebook='jupyter notebook --ip=$host_ip'" >> $user_home/.bashrc

# Miniconda環境を有効化するためのコマンドを.bashrcに追加
echo "source $user_home/miniconda/bin/activate" >> $user_home/.bashrc

echo "$new_userの開発環境のセットアップが完了しました。"
```

## Gist

一応、Gistの方でも公開しました。

[https://gist.github.com/sugimochi97/657906ad7244360fe316d7d638cb9c34](https://gist.github.com/sugimochi97/657906ad7244360fe316d7d638cb9c34)
NestJSの基本的なインストール方法

# はじめに
この記事では、Node.jsのエンタープライズレベルのフレームワークであるNestJSの基本的なインストール方法とその使い方について説明します。この記事は、NestJSの初心者やNode.jsで新しいプロジェクトを始めようと考えている開発者に向けて書かれています。

# TL;DL
- NestJSはNode.jsのための効率的なフレームワークです
- 基本的なインストールはnpmを通じて行うことができます
- 新しいプロジェクトの作成もCLIコマンドで簡単に実行可能

# 前提
- Node.jsがインストールされていること
- npmが利用可能であること

# 詳細
NestJSの基本的なセットアップ方法をステップバイステップで解説します。

## 1. NestJSのインストール
NestJSの基本的なセットアップ方法をステップバイステップで解説します。

```bash:bash
npm i -g @nestjs/cli
```

## 2. 新しいプロジェクトの作成
次に、以下のコマンドで新しいプロジェクトを作成します。

```bash:bash
nest new project-name
```

project-nameは自分のプロジェクト名に置き換えてください。

## 3. プロジェクトの起動
プロジェクトフォルダ内で以下のコマンドを実行し、アプリケーションを起動します。

```bash:bash
nest new project-name
```
ブラウザで http://localhost:3000 にアクセスし、NestJSアプリケーションが起動していることを確認します。

# まとめ
これで、NestJSのインストールと新しいプロジェクトの作成方法について学びました。NestJSは、TypeScriptに基づいた堅牢なサーバーサイドアプリケーションを構築するための強力なツールです。今回学んだ知識を活用して、さまざまなアプリケーションを開発してみてください。

# 参考文献
- [NestJS公式ドキュメント](https://nestjs.com/)
Raspberry Pi OS 2024-03-15 Release-note 翻訳

（追記：2024/07/05に、Raspberry Pi OS 2024-07-04 がリリースされています）
https://qiita.com/utaani/items/fe15135f26f884cdd540
 
 https://downloads.raspberrypi.com/raspios_armhf/release_notes.txt

2024-03-15:   
  * 他のオーディオデバイスが接続または切断されてもオーディオストリームは中断されなくなった
  * Orca をインストールするためのキーボード ショートカットはパスワードの入力を待たなくなり、サイレントに失敗するのではなく時計の同期を待つようになった
  * Orca スクリーン リーダーは、さまざまな小さなバグ修正が追加されたバージョン 45 に更新
  * 廃止された fbturbo ビデオ ドライバーが削除
  * バグ修正 - 保存されたディスプレイ解像度設定が X で再ロードされない問題
  * Raspberry Pi ファームウェア 6e0ae774407d68659b50cfbeb9f493ed16718866
  * Linux カーネル 6.6.20 - 6f16847710cc0502450788b9f12f0a14d3429668
CSVデータを読み替え表に従って読み替える

# 目的

あるCSVデータを読み替え表に従って、読み替えたい
データが読み替え表にすべて存在する場合は読み替えるが、存在しない場合は読み替えずそのままとする
データの第一列ごと(宅1→宅2→宅3)に読み替える。

参考画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/2dca41e9-f1b5-e6ed-41d3-abc7e0f125ad.png)  

# コード  

``` grouping.py  

import os
import pandas as pd

# import csv

groupcsv = "./settingCsv/読み替え表.csv"
targetcsv = "./settingCsv/注文リスト.csv"

# read file by pandas
gp_pd = pd.read_csv(groupcsv)
tt_pd = pd.read_csv(targetcsv)
gp_pd_count = gp_pd['料理セット'].value_counts()

# output csv

outputcsv = "./targetFolder/test.csv"

# main

## duplicate delete list make
tt_NoDup = tt_pd.drop_duplicates(subset=['宅番'])
gp_NoDup = gp_pd.drop_duplicates(subset=['料理セット'])

for index1, tablelist in tt_NoDup.iterrows():
    # 宅番ごとのデータを取り出す
    targettable = tt_pd.query('宅番 == @tablelist.宅番')
    targettable_tmp = targettable.copy(deep=True) 
    # グルーピング用のリストを取り出す
    for list,count in gp_pd_count.items():
        gp_list = gp_pd.query('料理セット == @list')
        # グルーピング用のリストを1つずつ(中華セット1→中華セット2...)グルーピングできるか確認する
        for index2,gp in enumerate(gp_list.iterrows()):
            targettable_check = targettable_tmp.query('注文料理 == @gp[1][1]')
            if not targettable_check.empty:
                targettable_tmp.drop(targettable_tmp[targettable_tmp['注文料理'] == gp[1][1]].index, inplace=True)
                if index2 == (len(gp_list) - 1):
                    targettable_1column = targettable['宅番'][:-1]
                    targettable_tmp2 = {'宅番':targettable_1column.iloc[-1],'注文料理':gp[1][0]}
                    targettable_tmp = pd.concat([targettable_tmp, pd.DataFrame([targettable_tmp2])], ignore_index=True)
                    targettable = targettable_tmp.copy(deep=True) 
            else:
                targettable_tmp = targettable.copy(deep=True) 
                break
    if index1 == 0:
        targettable.to_csv(outputcsv, index = False)
    else:
        targettable.to_csv(outputcsv, index = False, mode='a', header=False)



```  


``` 注文リスト.csv  

宅番,注文料理
宅1,天ぷら
宅1,とんかつ
宅1,親子丼
宅1,肉じゃが
宅1,カルビ
宅1,ミスジ
宅1,牛タン
宅1,ラーメン
宅2,ラタトゥイユ
宅2,キャロットラペ
宅2,酢豚
宅2,ラーメン
宅2,青椒肉絲
宅2,八宝菜
宅2,ご飯
宅3,棒棒鶏
宅3,八宝菜
宅3,天ぷら

```  

``` 読み替え表.csv  

料理セット,料理
日本食セット2,天ぷら
日本食セット2,とんかつ
日本食セット2,味噌汁
日本食セット1,親子丼
日本食セット1,肉じゃが
中華セット3,ラーメン
中華セット3,青椒肉絲
中華セット2,麻婆豆腐
中華セット2,回鍋肉
中華セット1,棒棒鶏
中華セット1,八宝菜
焼肉セット2,サーロイン
焼肉セット2,ホルモン
焼肉セット1,カルビ
焼肉セット1,ミスジ
焼肉セット1,牛タン
フランス料理セット1,ラタトゥイユ
フランス料理セット1,キャロットラペ

```  
# 出力データ

``` test.csv  

宅番,注文料理
宅1,天ぷら
宅1,とんかつ
宅1,ラーメン
宅1,焼肉セット1
宅1,日本食セット1
宅2,酢豚
宅2,八宝菜
宅2,ご飯
宅2,中華セット3
宅2,フランス料理セット1
宅3,天ぷら
宅3,中華セット1

``` 

# その他

データベースやほかのライブラリを使えばこんなに深い階層にならないと思います。
直した方がよいですが、一旦このままとします。
インパクト×FinTech　エンジニア勉強会

株式会社Figuroutが主催するFinTech関連技術の勉強会を開催します
2024/04/03(水)
19:00 〜 21:00
https://figuraout001.connpass.com/event/313955/

インパクト×フィンテックの領域において、 勉強会(LT)と交流会を通して知識の幅を広げることを目的としたイベントです。 
以下のようなテーマに触れる予定です

企業価値を評価するモデルづくり
開示情報（XBRL）のデータ化の取り組みのポイント
機関投資家の保持銘柄リストを活用したデータサイエンス
技術領域： GCP/AWS/React/Nextjs/graphQL/Hasura/PostgreSQL/docker/CloudSQL/python/xbrl
※内容は予告なく変更になる可能性があります）

こんなエンジニアにおすすめ
インパクト領域、金融、資本主義の課題に興味がある、 WEBエンジニア（バックエンド、フロントエンド）・データサイエンティスト・デザイナーの方。
初心者の方も大歓迎です

タイムスケジュール
19:00〜19:05	オープニング	
19:05〜19:15	自己紹介	
19:15〜20:15	LT+ディスカッション	10分×3~5本を想定
20:15〜20:20	Q&A	
20:20〜20:25	交流会案内	
20:25〜20:55	交流会		
21:00	        閉会	

https://figuraout001.connpass.com/event/313955/
Flutter 〜TextFieldとコントローラー〜

●TextFieldウィジェットのパラメータ
・decoration
→InputDecorationウイジェットを指定する。InputDecorationでデザインなどを調整する。

・contoroller
入力された値をプログラムの中で使用する際に使用。
サンプルではTextEditingControllerウィジェットを指定。
ボタンを押すとコンソール内に入力された値を出力する。

●InputDecorationウィジェットのパラメータ
・border
→枠線の指定。OutlineInputBorder()を指定している。

・labelText
→テキストボックス自体のタイトル

・hintText
→テキストボックス内のヒント情報。「名前を入力してください」など。

・errorText
→文字列が多いときなどのエラー時に表示する。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743467/68bb604c-d75f-dd4a-627c-80874e3451cd.png" width=50%>



```
import 'package:flutter/material.dart';

void main() {
  // テキストフィールドの入力内容を管理するコントローラーを作成します。
  final controller = TextEditingController();

  // テキストフィールドウィジェットの定義です。
  final textField = TextField(
    decoration: InputDecoration(
      // 外枠を囲むためのデコレーション設定。
      border: OutlineInputBorder(),
      // テキストフィールド上部に表示されるラベルテキスト。
      labelText: 'labelText',
      // テキストフィールド内に表示されるヒントテキスト。
      hintText: 'hintText',
      // 入力エラー時に表示されるエラーテキスト。
      errorText: 'errorText',
    ),
    // このテキストフィールドの入力内容を管理するコントローラー。
    controller: controller,
  );

  // ボタンが押された時に実行される関数です。テキストフィールドの内容をデバッグコンソールに出力します。
  xxxx() {
    debugPrint(controller.text);
  }

  // エレベーテッドボタンウィジェットの定義。ボタンが押された時の処理としてxxxx関数を指定します。
  final button = ElevatedButton(onPressed: xxxx, child: Text('ボタン'));
  
  // アプリケーションのUI定義を行うMaterialAppウィジェットです。
  final app = MaterialApp(
    home: Scaffold(
      // Scaffoldウィジェットを使用して、基本的なマテリアルデザインのレイアウトを提供します。
      body: Center(
        // Columnウィジェットを使用して、ボタンとテキストフィールドを垂直に並べます。
        child: Column(mainAxisSize: MainAxisSize.min, children: [
          // テキストフィールドの幅を300ピクセルに設定するためのコンテナウィジェット。
          Container(
            width: 300,
            child: textField,
          ),
          // 定義したボタンウィジェット。
          button,
        ]),
      ),
    ),
  );

  // Flutterアプリケーションを起動し、appウィジェットをルートウィジェットとして設定します。
  runApp(app);
}

```
SpringBootでログ出力の基礎

# この記事はこれの続きです

https://qiita.com/waokitsune/items/098fbfa874175faad474

# 概要

**SpringBootでログ出力をやったことないから、まず何をどうしたらいいか分からない** という状態向けです。

* SpringBootの標準的な機能を使う。
* 最小限のコード。

という基礎的な内容です。

# logback-spring.xml作成

logback-spring.xmlとは『ログ出力先』『ログフォーマット』などが書かれた **ログ設定ファイル** です。
これを **特定の場所に置くと** SpringBootが勝手にログ機能を用意してくれます。

下記のように作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2299c111-9b64-4aae-f790-551664f3c94b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8726abd8-b67a-cf85-9fbb-899143409e1a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/21cd00fc-cf3b-cc14-df42-c1d74e3a6105.png)

```xml:logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE logback>
<configuration>
	
	<!-- INFO以上のレベルのログは『FILE』という名前の設定でログ出力。 -->
	<root level="INFO">
        <appender-ref ref="FILE" />
    </root>
    
    <!-- ↓『FILE』という名前の設定はこう。 -->
    <!-- 一定の規則にしたがってログファイルを切替（ローリング）。 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		
		<!-- 時間でログファイルを切替。 -->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			
			<!-- ログ出力先フォルダーとログファイル名。 -->
			<!-- ログファイル名に日時情報を埋め込みたい時は %d{yyyyMMdd} を使う。 -->
			<!-- この設定の場合、日単位でログファイルが切り替わる。 -->
            <fileNamePattern>C:\Neko\Log\%d{yyyyMMdd}.log</fileNamePattern>
            
            <!-- ログファイル保存日数。 -->
            <maxHistory>30</maxHistory>
            
        </rollingPolicy>
		
        <encoder>
			<!-- ログフォーマット。 -->
			<!-- 『%』のあとの『-24』は『24文字でスペース埋め』という意味。 -->
			<!-- スペース埋めによって縦揃えができるので、人が読みやすいログにできる。 -->
            <pattern>%-24d{yyyy-MM-dd HH:mm:ss.SSS},%-6level,%-36thread,%-70logger{36},%msg%n</pattern>
        </encoder>
        
    </appender>
    
</configuration>
```

# Controllerクラス


```java:DemoController.java
package com.example.demo;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class DemoController {

	
	private final Logger log = LoggerFactory.getLogger(this.getClass());
	
	
	@GetMapping("/")
	public String getIndex(Model model) {
		
		
		log.info("ログ出力にゃん");
		log.info("ログ出力にゃんにゃん");
		log.warn("うわーん");
		log.error("やばい！");
		
		
		return "/index";
		
		
	}
	
	
}
```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e69eee46-5e67-e4f5-f41c-caea3de2cba8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8f5feeb4-a73b-70e6-a65c-57105a841669.png)


# 構成

赤枠が追加 or 変更になったファイルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/393c3aa0-99ba-8218-7162-c2845101ef1f.png)

# この記事の続き

https://qiita.com/waokitsune/items/6f7d8c87e330c3c4f054

# 参考サイトさん

https://qiita.com/Masahiro_Uemura1234/items/61a25ce4aa815a9922d6

https://b1san-blog.com/post/spring/spring-log/

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
Spring Boot v3.1.10
JAVAで現在時刻を文字列にフォーマット（変換）

# やり方

```java:
String now_1_ = DateTimeFormatter.ofPattern("yyyy/MM/dd_HH:mm:ss.SSS").format(LocalDateTime.now());
System.out.println(now_1_);

String now_2_ = DateTimeFormatter.ofPattern("yyyy年MM月dd日（E曜日） HH時mm分ss秒SSS").format(LocalDateTime.now());
System.out.println(now_2_);
```

# 参考サイトさん

https://qiita.com/t_t238/items/5db1c6ca131a61ebd6ae

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ef9f034b-f65c-0075-6e44-2c8f9366a64b.png)

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
JAVA 17.0.8.1
JAVAのコードでJAVAのバージョン取得

# やり方

```java:
String java_version_ = System.getProperty("java.version");
System.out.println(java_version_);
```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f7a0fc4e-f92e-549e-fae5-3caa82e5ecdf.png)


# バージョン

Microsoft Windows [Version 10.0.19045.4170]
JAVA 17.0.8.1