OmniAICreator/Qiita-1.07M huggingface dataset:
DeSmuMEでメモリ値を参照した時期待される値よりも大きな値が出る時の対応

DeSmuMEでLuaスクリプトやmemory searchを使用しメモリ値を監視している際、挙動はそれっぽいのに中身の値が大きな値が出てしまうことがあります。　それはおそらく型の問題である場合がほとんどです。　この記事では２種類の対処法を記します。

まずは以下のLuaスクリプトを咲かせて！ちびロボ！を起動した状態で動かしてください。
無い場合は画像をご覧ください。

```lua:wattage.lua
local function fn()
local W

W = memory.readdword(0x02383CD4)

gui.text(0,0,"W: "..W)

end


gui.register(fn)

```
ある程度ゲームを進め、パーク内に入ってエミュレーターを一時停止させてください。（画像の例はまあまあ進んでいる状態ですが、チュートリアルの状態でも大丈夫です。）

<img width="256" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673555/0434e774-3e62-3c3d-c8f4-093cd519c439.png">

なんだかバカでかい数字が出てきました。その挙動からちびロボ！のワッツ数（右上に表示されているやつ）であることは明らかですがそれにしても大きな数字です。


# float型で対応
非公式リファレンスの`memoryライブラリ`を確認すると、memory.readword()は数値型で受け取っていることが分かります。そこで以下のコードを使ってfloat型に変換をして表示をしてみます。float型の変換は以下の関数を用意して毎回呼び出すのがいいでしょう。

```lua: coodinate.lua
local function convf(addr)
local n,s,e,f = 0

n = memory.readdword(addr)
s = (-1)^bit.arshift(n,31)
e = bit.band(bit.arshift(n,23),0xFF) - 127
f = 1 + bit.band(n, 0x7FFFFF) / 0x800000
return s*f*2^e

end

function fn()
local W
W = convf(0x02383CD4)

gui.text(0,10,"W: "..W)

end


gui.register(fn)

```

出力結果として以下の図のようになりました。綺麗な数値になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673555/8a86b57a-56f0-fae3-3479-3506eb23732c.png)

有効桁数が多すぎて見にくい場合は、`gui.text(0,10,string.format("W:%07.3f",W))`など`string.format()`で文字列出力フォーマットを揃えるといいと思います。

# decimal型で対応
ニンテンドーDSではfloat型以外にも固定小数点型（整数部:20bit 小数部:12bit）に対応しており、ゲームの変数によってはそちらで計算されていることがあります。例えばNewスーパーマリオブラザーズを起動し、コースにいる時以下のコードを実行してください。

```lua: decimal.lua
function fn()
local X,Y
X = memory.readdwordsigned(0x0208AD20)
Y = memory.readdwordsigned(0x0208AD24)

gui.text(0,10,"X: "..X)
gui.text(0,20,"Y: "..Y)

end


gui.register(fn)
```
<img width="256" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673555/173ebac0-63ed-9300-72bb-7e28f9d6c38b.png">

それっぽい数値が表示されました。ここでゲームを再開しマリオを動かしてみてください。XY座標どちらもマリオの動きに合わせて増減しており、カメラもしくはマリオの座標が格納されていることが確信できます。それにしても値が大きいです。

ここのメモリを`memory viewer`で確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673555/e4037f36-5243-ab3b-b3b4-14c6b430a569.png)

選択しているものはY座標ですが、この時の下部`フロート{20.12}:`を確認するとなんだかそれっぽい数値が書いてあります。おそらくこの変数は固定小数点型で宣言されていると思われます。

この場合スケールを合わせればいいので0x1000で割ります。以下のコードがコード例です。

``` lua: decimal.lua
function fn()
local X,Y
X = memory.readdwordsigned(0x0208AD20)
Y = memory.readdwordsigned(0x0208AD24)

gui.text(0,10,"X: "..X/0x1000)
gui.text(0,20,"Y: "..Y/0x1000)

end


gui.register(fn)

```

<img width="256" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673555/f493e7b3-ca19-e7b6-bd96-5368d850007a.png">

とてもそれっぽくなりました。有効桁数が多すぎて見にくい場合は、`gui.text(0,10,string.format("X: %07.3f",X/0x1000))`など`string.format()`で文字列出力フォーマットを揃えるといいと思います。
vimでファイルツリーを使う方法

## ゴール

vimでNERDTreeというファイルツリーを使えるようにすること

## やること
vimにNERDtreeをインストールしてショートカット(Ctrl + n)でファイルツリーを出したり引っ込めたりできるようにすること

## そのためにやること
vimにプラグインをインストールするために
**vim-plug**
というプラグインマネージャをターミナルで下記のコマンドを実行してインストールする
```
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
```

## NERDTree(ファイルツリーのプラグイン)をインストールするための準備をする
Vimの設定ファイル（~/.vimrc）を下記コマンドをターミナルで実行し.vimrcを開きます。
```
vim ~/.vimrc
```
.vimrcに下記を記入する
```
call plug#begin('~/.vim/plugged')

Plug 'preservim/nerdtree'

call plug#end()

nmap <C-n> :NERDTreeToggle<CR>
```
:wq　で保存しvimを抜ける

## vimを起動してNERDTreeをインストールする
ターミナルで下記コマンドを入力しvimを起動する
```
vim
```
vimが起動したら下記を入力しNERDTree(プラグイン)をインストールする
```
:PlugInstall
```
## インストールできたか確認する
ターミナルで下記を入力しvimを起動する
```
vim
```
下記を入力しNERDTree(ファイルツリー)の表示/非表示の切り替えができるか確認する
```
Ctrl + n
```
## まとめ
1. プラグインをインストールするために必要なプラグインマネージャをインストールする
1. vimの設定ファイルに各種設定を記述する
1. vimの設定ファイルの情報を元にプラグインをインストールする
1. 動作確認をする

こんなイメージで良いのではないかと考えています。最後までお読みいただきありがとうございました。
コイカツスタジオVR（SteamVR）でキャラが近いと異様にカクついていたので解決した

# はじめに
<!-- 発端や概要を記載 -->
18歳未満はお断りと申し上げておきます。
スタジオ用VR化MODを使用しております。

メモ書き程度ですのでご了承ください。
めっちゃ困るなと思いつつ、なんかわからんけど解決したので、同じ境遇の方がいらっしゃればこの情報をお届けできれば幸いです。
qiitaの利用規約を途中まで流し読みしましたが、とくにだいじょぶそうだとおもいました。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [解決方法](#解決方法)
1. [顛末](#顛末)
1. [雑な当方環境](#当方環境)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#解決方法"></a>
# 解決方法　Steamを終了したうえでsteamapps.vrmanifestで起動する
#### ①起動中であれば、Steamを終了する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846945/2467fcd4-0c3d-e2c9-439d-5818035d82c0.png)


#### ②SteamVR自体を以下のファイルより実行する。
C:\Program Files (x86)\Steam\config\steamapps.vrmanifest
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846945/924f04a3-22f6-9bf4-cdc8-960ae63a7c7c.png)

その後スタジオ用VR化MODの手順通りに起動する。

---
弊害としてSteamVRのUIが1,2年前のものになります。懐かしい。
あとシーンのロードが早くなります。※当方環境比

<a id="#顛末"></a>
# 顛末
いつもどおりコイカツスタジオVRを楽しんでいたところ、知能低下中でもはっきりと異変を感じられました。
そう、VRコントローラで触れる(※触れません)ぐらいにキャラに近づくとやたらカクカクと重くなります。なんだこれは！この前はどうだったっけ？
それはさておきまあええかと、ひと段落ついて急に思考がクリアになった後、これを解決せねばとあるクオリティが劇的に下がることに気づきます。

modやHMDやPC等のバージョンアップ等々でバグったか？と思うも、
確か先週(24年6月上旬)では問題なく特に心当たり無いので、そんなわけあるかい！と犯人を探し始め、直近でSteamVRのアップデートがあった [SteamVR 2.6](https://store.steampowered.com/news/app/250820/view/4166472403275280922)ので、
原因絶対これじゃんと思いダウングレードしましたが解決せず。
絶望のさ中に見つけて適当に起動したsteamapps.vrmanifestでコイカツスタジオVRを開くと、なんか解決しておりました。ﾁｬﾝﾁｬﾝ。

SteamVRの起動方法で解決するので、やっぱSteamVRが問題だろと思うのですが、
まぁ他には何もわからないのでSteamVRやPico開発元にissue投げられませんでした。（訳※勇気が出ませんでした。）

<a id="#当方環境"></a>
# 雑な当方環境
PC：Windows10 i7-11700F NVIDIA GeForce RTX 3090
SteamVR 2.6.2
PICO Connect for PC 10.1.5 有線接続
HMD：Pico4 v5.9.2 PICO Connect 10.1.5
※PICO ConnectやPicoのOS等々は執筆時点最新にアップグレード済み。

<a id="#備考"></a>
# 備考
- Picoの場合コントローラのバインドがうんたらかんたらで操作できなくなりますが、（中指）
PC側でバインドの設定をこねこねすると治りました。
- 事象自体はデフォルトちかりんでもカクカクします。コイカツのFPSカウンターでは最大90のところ70前後と表示されてますが、体感20fpsぐらいです。
シーンやキャラに依存しません。
- 素敵なシーンやキャラ、コイカツに限らず情報発信いただいている皆様には日頃より恩恵を享受させていただいておりますので、感謝しております。
- 当方はエンジニアには該当しませんがご容赦ください。

<a id="#reference"></a>
# 参考文献（勝手に）
- [Qiita記事投稿用テンプレート](https://qiita.com/tkrtmy1031/items/80c292fab5d631c6d4ba)
- [SteamVR のダウングレード方法](https://sportsmeleap.tech/2019/03/26/get-multi-controller-steamvr-downgrade/#c5)
- [SteamDB](https://steamdb.info/app/250820/depots/)
Nerves Livebook + Delux で簡単Lチカ

## はじめに

前回の記事で Nerves を導入し、Lチカまで実装しました

https://qiita.com/RyoWakabayashi/items/8119260ceeea462d6b7b

実は Delux というモジュールを使うことで、更に簡単にLチカできたので記事に残します

:::note info
Delux は @mnishiguchi さんに教えてもらいました
:::

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/nerves_livebook/delux.livemd

## 環境

デバイス: Raspberry Pi 4

実行環境: Nerves Livebook

https://github.com/nerves-livebook/nerves_livebook

## 設定の確認

新しいノートブックを開き、以下のコードを実行します

```elixir
Application.get_env(:delux, :indicators)
```

すると、以下のような結果が返ってきます

```elixir
%{default: %{green: "ACT"}}
```

実は Nerves Livebook には最初から Delux がインストール済であり、しかも ACT の LED を使うように設定済になっているのです

Nerves Livebook の config ディレクトリーを見ると、デバイス毎に設定が用意されています

https://github.com/nerves-livebook/nerves_livebook/tree/main/config

Raspberry Pi 4 用の config を参照すると、先程確認した内容が記述されています

https://github.com/nerves-livebook/nerves_livebook/blob/main/config/rpi4.exs

```elixir
...

config :delux, indicators: %{default: %{green: "ACT"}}
```

この設定では、緑色を光らせるように指定した場合、 ACT の LED が光ります

## Lチカの実行

既にお膳立てされているため、以下のように実行するだけでLチカが実行できます

```elixir
:green # 色
|> Delux.Effects.blink(0.5) # 周波数
|> Delux.render()
```

![0_5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/66e54420-7eec-14f4-515e-f0b6698f0a21.gif)

周波数を 4 に変更すると以下のようになります

![4_0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/76bc252f-7c6d-3b7c-b8d4-005b95f33b8c.gif)

また、色に `:red` や `:blue` を指定すると光らなくなります

`:red` や `:blue` には LED を割り当てていないためです

## 状態の確認

以下のコードを実行すると、現在の LED の状態が確認できます

```elixir
Delux.info()
```

実行結果

```elixir
green at 4 Hz
```

## モールス信号

おまけとして、モールス信号で "SOS" を発信してみます

```elixir
:green # 色
|> Delux.Morse.encode("SOS", loop?: true) # モールス信号にしたい文字列、繰り返し
|> Delux.render()
```

![SOS.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/76721488-6829-d61e-1391-d1c17432d121.gif)

SOS は「・・・－－－・・・」（トントントンツーツーツートントントン）なので、確かにモールス信号になっています

https://x.com/MPD_bousai/status/1714778382964048235

## まとめ

Delux で簡単にLチカを実行できました

次は何をしたら良いか、オススメの工作キット等あれば教えてください
React入門：Hello World を出力する！

# Reactを環境構築してHello Worldする方法

## 事前準備
1. 任意のディレクトリに作業ディレクトリを作成。
2. VSCodeで作業フォルダを開く。

## 動作環境
- Node.js v20.13.1
- npx 10.5.2

## Reactプロジェクトを作成
1. VSCodeのターミナルを表示。
2. 以下のコマンドを実行：
    ```powershell
    npx create-react-app react-practice
    ```
3. 成功すると以下のように出力される：
    ```powershell
    Success! Created react-practice at C:\...\React\react-practice
    Inside that directory, you can run several commands:
    
      npm start
        Starts the development server.
    
      npm run build
        Bundles the app into static files for production.
    
      npm test
        Starts the test runner.
    
      npm run eject
        Removes this tool and copies build dependencies, configuration files
        and scripts into the app directory. If you do this, you can’t go back!
    
    We suggest that you begin by typing:
    
      cd react-practice
      npm start
    
    Happy hacking!
    ```

## Reactプロジェクトを実行
1. ターミナルで以下を実行：
    ```powershell
    cd react-practice
    npm start
    ```
2. ブラウザで `http://localhost:3000` にアクセス。

## Hello Worldを表示
1. `App.js` を以下のように編集：
    ```javascript
    import logo from './logo.svg';
    import './App.css';
    
    function App() {
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>Hello World!</p>
            <a!
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React
            </a>
          </header>
        </div>
      );
    }
    
    export default App;

    ```
## 結果
![Hello World出力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/0bd2888e-9948-b21b-4213-5ee5b4600401.png)
## 参考
[【VSCode】Reactを環境構築してHello Worldする方法](https://inakademac.com/react-hello-world/)
個人識別符号について調べてみました

前回の投稿に関連して、個人情報ネタです。

弊社新サービスで取り合う扱う、生体由来データの法的解釈に困っており
個人情報について調べております。

https://elaws.e-gov.go.jp/document?lawid=415AC0000000057

によれば、

第一章の第二条にこのような記述がされておりました。

* 氏名、生年月日等により、特定の個人を識別することができるもの
* （他の情報と容易に照合して、それにより特定の個人を識別することができるものを含む）
* 個人識別符号が含まれるもの

つまり「個人識別符号」とは、それ単発で「個人情報」となるほどに個人識別能力の高い符号（文字や番号、記号）であることがわかります。

それでは実際にどのようなデータが「個人識別符号」に該当するのか、調べてみました。

---

# 個人識別符号

https://elaws.e-gov.go.jp/document?lawid=415CO0000000507

こちらの 第一章, 第１条に、実に明確に定義が述べられていました。

長いので意訳すると以下のとおりでした。

1.　生体認証に利用可能な程度の、身体の特徴を変換したデータ
    イ　DNA
    ロ　顔の形状、容貌（顔認証）
    ハ　虹彩（虹彩認識）
    ニ　声紋（声紋認証）
    ホ　歩行の際の姿勢及び両腕の動作、歩幅その他の歩行の態様（歩行識別）
    ヘ　手の静脈の形状（静脈認証）
    ト　指紋又は掌紋（指紋認証）
2. パスポート番号
3. 年金番号
4. 免許証番号
5. 住民票コード
6. 個人番号（マイナンバー）
7. 各種保険証
    イ　国民健康保険法の被保険者証
    ロ　高齢者医療の被保険者証
    ハ　介護保険法の被保険者証
8.　その他。（上記と同レベル程度のスペックで、個人情報保護委員会規則で定める文字、番号、記号その他の符号）


ちなみに、８．のその他枠は、件の個情委の規則

https://www.ppc.go.jp/personalinfo/legal/guidelines_tsusoku/

の、規則第４条に定義があり、

1. いろんな種類の保険証
2. 出入国管理及び難民認定法に関するパスポートと、在留カード
3. 特別永住者証明書番号

の３種類が定義されておりました。

---

つい先日、日本でもSIMスワップ被害が顕在化してきた４〜５月の状況を受けて、
ここぞとばかりに政府は「携帯契約はマイナンバーカード＋チップ読み取りに一本化します」みたいな政策をだして来ました。
そうすると将来的に自動車免許証や、旧式保険証がどんどん使えなくなって来て、最後には個人識別符号としての効力を失なうかもしれません。

法律の更新については何もしらないド素人なので、５年後とかの将来にこのあたりの法律条文がどう変わるのか、それともかわらないのか、
予想がつきませんが、どうなっているか少し興味有ります。
COZEって知ってますか❓

題名の通り、COZEって知ってますか...❓
毎日のように生成AIの話題が流れる中、これを活用してChatbot作りたいなぁと思ったことありませんか❓
この前、とある勉強会に参加した際、COZEなるものを知ったので紹介します。

# COZEとは？
簡単にChatbotが作れるWebプラットフォームです。

https://www.coze.com/

プログラミング不要で無料で使うことができます。
COZEを使う前は、こういったプラットフォームで作成するものは使える生成AIが古いものでしたり、最新のものは課金が必要なイメージでした。
しかし、COZEはGPT-4oやGemini Proなども無料で使うことができます。
現時点で下記のものが無料で使うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/d5273898-f426-ecb8-dd1c-78eb5e3d848a.png)

COZEからLINEやSlackなどとも連携しているので作ったものをすぐにシェアできます！
登録方法等々はこちらのHPに詳細がありますので参考にどうぞ✨

https://trends.codecamp.jp/blogs/media/about-coze

## COZEでできること
個人的にすごいと思った内容です！

- Chatbotのプロンプトを自動で書いてくれる

これが一番すごいです...！皆さんも様々な生成AIを作成していく中でそのAIに期待する動作を決めるプロンプト、悩みながら書いたことありませんか❓
画像のように超超単純なプロンプトを右上のOptimazeに通すと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/81ace6f0-48f1-d89e-5ce0-a124ff16db9d.png)

このように自動で文章を作成してくれます。
書いた以上のものが大量にできてる...！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/7a7f250c-a6c3-dabc-1a49-da5531b1cdde.png)

最終的にはたった1文がこんな素敵なプロンプトになりました...！これならプロンプト作成が苦手な人でも使いやすいですね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/efac12c8-fab0-f380-c942-a4472122b7c9.png)

- プラグインを自動で選択してくれる

生成AIを活用している皆さんならイメージが付きやすいかと思いますが自分のしてほしいことをサポートしてくれるプラグインがたくさん出ています。
COZEでもプラグインがたくさんあるのですがこれを全部自動で選んでくれます。
右上の”A”を押すと...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/014d06df-6c6b-32b3-b0be-ebb12f5c0690.png)

このように大量のプラグインを勝手に選定してくれます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/cce6d03f-c617-5466-8857-db8645fe0a7c.png)

- 音声をつけることができる

これはちょっとした遊びですが音声をつけることができます。
生成したChatbotに音声を自動音声をつけるなんて遊びもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273072/a67e17fd-772b-dd1e-6c20-4850787f6d66.png)

# 終わりに

COZEは非常に簡単に高品質なChatbotを生成できるプラットフォームです。
個人的にも遊び感覚でいろいろ触っていますが、ほんとにいろいろなことができて便利です！
まだまだ、コーディングなどはGPT-4oを使えるからと言って強いわけではなく、あくまで文章生成に特化していますがそれでも様々ことがこれ一つにギュっとまとめられています。
興味がある方はぜひ触ってみてください！
Node.jsのインストールコマンドメモ

Udemyのterraformの講座にて、アプリケーション構築の中のnode.jsのインストール方法が古くて講義の通りだと動かないため、下記手順でインストールした。

```
EC2ログイン

リポジトリの追加
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -

インストール
sudo yum install nodejs

node -v
-> v16.20.2
```
Kotlinを書くための基礎知識（条件分岐）

## はじめに
この記事は、アプリ開発未経験の筆者が使用言語であるKotlinについて学び、Androidアプリ開発を目指していくものになります。

[前回の記事](https://qiita.com/teyama3/items/deb423ae534c44dcf97e) では、変数や関数など、Kotlinの基礎知識を学びました。
今回はその続きの記事となります。

すべてのコードは [プレイグラウンド](https://developer.android.com/training/kotlinplayground?hl=ja) で試すことができますので、動作が気になったら実際にコピペしてやってみてください。


## 対象読者
* Androidエンジニアを目指している方(自分は目指しています！)
* Kotlinの基礎知識をサクッと学びたい方
* 変数や関数など、ある程度の用語は理解している方

## 条件
Kotlinでの条件分岐制御は `if/else` ステートメントを使います。
条件は、比較演算子を利用して `Boolean` で判定します。

### 比較演算子
* 等しい：`==`
* 等しくない：`!=`
* 未満：`<`
* より大きい：`>`
* 以上：`>=`
* 以下：`<=`

```kotlin:sample.kt
fun main() {
    val num = 100
    if (num % 2 == 0) {
        println("偶数です")
    } else {
        println("奇数です")
    }   
}
```

### whenを使って可読性アップ
`if/else` ステートメントは、`when` ステートメントを使うことで、より可読性が向上します。

```kotlin:IfElseSample.kt
fun main() {
    val num = 3
    if (num % 3 == 0 && num % 5 == 0) {
        println("fizzbuzz")
    } else if (num % 3 == 0) {
        println("fizz")
    } else if (num % 5 == 0) {
        println("buzz")
    } else {
        println("not covered")
    }   
}
```
上記を `when` を使って書き直すと、以下のようになります。

```kotlin:WhenSample.kt
fun main() {
    val num = 3
    when {
        num % 3 == 0 && num % 5 == 0 -> println("fizzbuzz")
        num % 3 == 0 -> println("fizz")
        num % 5 == 0 -> println("buzz")
        else -> println("not covered")
    }
}
```

### 条件分岐の結果を変数に代入する
変数宣言を行う際に、条件分岐の結果の値を代入することができます。

```kotlin:SetVarSample.kt
fun main() {
    val num = 3
    val answer = when {
        num % 3 == 0 && num % 5 == 0 -> "fizzbuzz"
        num % 3 == 0 -> "fizz"
        num % 5 == 0 -> "buzz"
        else -> "not covered"
    }
    println(answer)
}
```

このように、条件分岐と変数宣言を組み合わせて書くことができます。

## 次回予定
* nullとは
* null安全とは
* nullチェックの方法　など、学んでいけたらと思います。
HTMLとCSSのみで画像のアクセプト比を保持したまま、背景画像のスライドショーを実装する

# はじめに
背景画像のスライドショーを実装したいけど、画像のアクセプト比が歪んでしまったり、javascriptを必要とする場合があったので、HTMLとCSSだけで簡単に実装できるスライドショーの作り方を紹介します。
今回は、3枚の画像でスライドショーを実装しています。


# HTMLの記述
```Ruby:index.html.erb
<div class="slideshow">
    <div class="slideshow-image" style="background-image: url('<%= asset_path '画像の名前' %>');"></div>
    <div class="slideshow-image" style="background-image: url('<%= asset_path '画像の名前' %>');"></div>
    <div class="slideshow-image" style="background-image: url('<%= asset_path '画像の名前' %>');"></div>
</div>
```
こちらを任意の場所に挿入してください。

# CSSの記述
```css:index.scss

.slideshow {
  position: relative;
  height: 〇〇px;
  width: 〇〇px;
}

.slideshow-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  animation: slideshow 9s infinite;
  opacity: 0;
}

.slideshow-image:nth-child(1) {
  animation-delay: 0s;
}

.slideshow-image:nth-child(2) {
  animation-delay: 3s;
}

.slideshow-image:nth-child(3) {
  animation-delay: 6s;
}

@keyframes slideshow {
  0%    {opacity: 0; }
  11.1% {opacity: 1; }
  33.3% {opacity: 1; }
  44.4% {opacity: 0; }
  100%  {opacity: 0; }
}
```
こちらをcssに挿入してみましょう。
およそ3秒おきに画像が変わるスライドショーができていると思います。

# CSSの簡単な解説
```css:index.scss

.slideshow {
    position: relative; スライドショーの位置を設定
    height: 〇〇px;
    width: 〇〇px;
  }
  
  .slideshow-image {
    position: absolute; 各画像の位置を設定、親要素に対して絶対的な位置に配置
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-size: cover;
    background-position: center;
    animation: slideshow 9s infinite; 「slideshow」という名前のアニメーションを9秒間で無限に繰り返し
    opacity: 0;  各画像の初期透明度を設定、この場合完全透明
  }
  
  ↓アニメーションの開始時間の設定
  .slideshow-image:nth-child(1) {
    animation-delay: 0s; アニメーションをすぐに開始
  }
  
  .slideshow-image:nth-child(2) {
    animation-delay: 3s; アニメーションを3秒後に開始
  }
  
  .slideshow-image:nth-child(3) {
    animation-delay: 6s; アニメーションを6秒後に開始
  }
  
  ↓キーフレームの定義
  @keyframes slideshow {
    0%    {opacity: 0; } 
    11.1% {opacity: 1; }
    33.3% {opacity: 1; }
    44.4% {opacity: 0; }
    100%  {opacity: 0; }
  }
   0%(開始時)と100%(終了時)には透明度が0(完全に透明に設定)
   11.1%～33.3%の間は透明度が1(完全に不透明に設定)
   44.4%～終了までは、透明度が0(完全に透明に戻る)
```
これにより、各画像が順番に表示され、それぞれが3秒間表示された後に次の画像に切り替わるスライドショーが作成されます。今回設定した画像は3枚のため、全体のサイクル時間は9秒です。
細かな数値は調整してみてください。
※このスライドショーは無限に繰り返されます。
# おわりに
やってみてね^^
個人情報保護委員会に電凸してみた

# 経緯

（ぼかして書いてます、ご了承ください）

> 私「うちの会社で新規リリースするXXサービスで扱う、ユーザーから集める○○（とある生体由来のデータ）って個人情報になるんでしょうか？
あたらしい分野だから、前例なくてこまってるんですよ。
もし個人情報に該当するんだったら利用規約とか見直したいんですよね。」
>社外のアドバイザー的な人「それだったら個情委に相談するといいよ」

・・・こじょうい？？

> 社外のアドバイザー的な人「個人情報保護委員会のことだよ。わりとフランクに話聞いてくれるよ」
> 私「うーん。ほかに頼れるとこもないし、聞いてみるか」

---

# とりあえず書面で聞いてみた

https://www.ppc.go.jp/personalinfo/business_support/

個人情報委員会では「PPCビジネスサポートデスク」というサービスをされており


    1. 個社が検討中の新ビジネスモデルにおける個人情報、仮名加工情報、匿名加工情報等の適正かつ効果的な活用に関する相談
    2. 業界又は複数事業者が共通に抱える個人情報、仮名加工情報、匿名加工情報等の適正かつ効果的な活用に関する相談

について相談できます。

「新ビジネスモデル」に該当しそうなので、こちらの窓口に該当しそうです！


応募フォームに具体的な新ビジネスモデルの内容を書きながら
そしてフォームのエラーに苦戦しながら（※１）、格闘しながらなんとか送信すると
翌日電話がかかってきました

> 担当者「うちの担当ではありませんので、こちらの電話にかけてください」


おおぅ。マジか。了解やで。

※１ ... ﾔﾚﾊﾞﾜｶﾙ

---

# こちらの窓口に電凸

こちらの窓口とはこちらです。

https://www.ppc.go.jp/personalinfo/pipldial/

・・・どう見ても、一般の問い合わせ先なんですが。

一抹の不安を感じながらも「個人情報保護法の解釈」について回答してくれるらしいので電凸してみました！


> 私「うちの会社で新サービスで扱う、ユーザーから集める○○って生体データ、弊社の考えとしてはこれこれこういう理由（法律の解釈）で、個人情報に該当しないと考えているが、お間違いないでしょうか？（※２）」
> 担当者「わたくし共では、法解釈はできかねます」

・・・ほらみたことか！

※２ 法解釈の見解を聞くときは、自分の考えを明確にした上で、yesかnoで答えられる形式で聞けってばっちゃが言ってた。

---

# 電凸後半戦。

ここで「なんの成果も得られませんでした！」では、進撃の巨人が始まってしまうので（※３）
だいぶ食い下がって根掘り葉掘り聞いてみました（※４）ところによれば
どうやら以下のようなボーダーというかしきい値があるようでした。


* 個人情報に該当するかどうかは、やはり個人を特定できるかどうかが争点となる
* 「特定」のイメージは、「不特定多数の人間の情報が格納されたDBから、当該情報を使って特定の１人を探しだせるかどうか」というニュアンスでした。
* その新規サービスのユーザーを全員集めて、当該の生体データを使って誰のものかを特定できるなら、まあ個人情報じゃないの？　くらいなフランクな回答をいただきました。
* 補足として、その生体データが仮に単体で個人情報ではなかったとしても、「容易に参照できる他の情報（たとえば同じDBに格納されている情報）」と組み合わせると個人を特定できる場合で、そのデータの集合は個人情報となります。情報単体で個人情報であるかどうかは、システム全体ではあまり意味がないのです。

※３ １巻のオープニングの名ゼリフ
※４　担当者の方、その説はご対応ありがとうございました。

---

そんなこんなで電話でいろいろヒアリングした体験談でした。

なかなか法解釈って一意に解釈できなくて
事件→裁判→前例がおきないと線引きできないの（これ仕様バグだと思ってます）
なんですが、
そんななかご対応頂いた個情委の皆様、ありがとうございました。
【雑】Create Vuetifyしたらなんか変わってた

会社でVueを触ろうと思い、npm create vuetifyをしたら、前に触ったときと、変わっている部分があったため、雑に見比べてみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125193/9204c0bb-cc62-eccf-e6ba-64207b3774ef.png)
npm create vuetify ←   → npm create vuetify@latest 

以前Vue3を触ってみようと思い入れたときのままのバージョンで
npm create vutifyをしたほうは、
Vue: 3.2.13, vuetify, 3.0.0
今回latestで入れてみたら
Vue: 3.4.21, vuetify: 3.5.8

選択したのは、vue router, pinia, layout, TSでおんなじものを選択。（選択するときの表示もちょっと変わっていて、細かいなーとちょっと感心した）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125193/28b90464-ffce-a909-8fff-edee65209399.png)

# auto importってなんぞや
一番最初に違和感を感じたのはこれら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125193/0d297fda-83a8-ed1d-c9bd-1572308827ca.png)

なんかComponentsフォルダにファイルを作成すると、npm run devをしたときに、自動的にcomponents.d.tsにそのコンポーネントを書いてくれたりなんやかんやしてくれて、わざわざImportを書かなくても、コンポーネントが使えるようになっているらしい
[unplugin-vue-componentsとunplugin-auto-importでimportの自動化](https://reffect.co.jp/vue/unplugin-import)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125193/79bc3683-113a-8860-f802-ec03ece648e3.png)

あんまりよくわかってないし、それによる悪影響がないのか気になる

# ほかにもちらちら変わってる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125193/7fbec3c0-d898-7dd5-bbf4-e60b370db9d1.png)

まだlayoutsのつかいかたすら良くわかってないのに、、、
AppBarはComponentなのかlayoutなのかはっきりしてほしい
Viewsフォルダなくなってるし

# ベストプラクティスを教えてくれ！！！

ggrks
JSDocコメントちゃんと書いていこう！

みなさんはコメントと言われてどんなものを想像するでしょうか？
```typescript
// ここにコメントを残します

/*
 * 複数業だとこんな感じ
 * コメントを残します
 */
```

上記のようにコメントを残すことは多いと思います。
ただ、コメントを残すのではなくコーディングのヒントになるものを残せるのがベストです！
なので「JSDocコメント」について復習も兼ねてまとめてみました！

:::note
読んでくれた人が明日からJSDocコメント書いてみようと思えるようになることを目指した記事です！
:::

## JSDocコメントってなに？
JSDocコメントとは関数や変数の宣言前に記載するコメントです。
`@type`や`@param`を記述します！

```typescript
/**
 * @type {boolean}
 * @param {string} name
 */
```

## JSDocコメントの種類
JSDocコメントには先にあげた`@type`や`@param`以外にたくさんあります！
よく使われるものを紹介します！

|JSDocの種類|コメントの意味|
|--|--|
|`@type`|値の型や説明を記述する|
|`@param`|関数の引数の説明を記述する|
|`@returns`|関数の戻り値を記述する|
|`@see`|資料を示し、合わせて確認してほしいものを示す|
|`@author`|開発者の名前を記載する時に利用|
|`@deprecated`|非推奨であることを示すもの|
|`@function`|メソッドの定義であることを示す|

- `@see`は、具体的に言うとライブラリのリンクなどがコメントに記載されることが多い印象
- `@author`は役割分担の記録としても利用される
- `@deprecated`はあまり見る機会がないですが、利用してほしくない関数に利用するものでリファクタリングの際に利用する
- `@function`はメソッド、具体的にはアロー関数式で関数を書く場合に利用することが多い

## JSDocコメントを書くと何が良いのか？
特に良いと思えるのは以下の点です。
- コンテキストの理解につながる
- コードヒントが表示されてドキュメントの替わりになる

### コンテキストの理解につながる
JSDocで適切にコメントが書かれていることはコンテキスト（背景）の理解につがなります。

過去の開発はどのような判断でどのようなコードが書かれたのかが適切にコメントが残されていることによって理解が早まり、誤った設計や実装をしなくて済む手掛かりになると考えています。

### コードヒントが表示されてドキュメントの替わりになる
vscodeなどのエディターでJSDocを記述してあると、コードヒントとしてポップアップが表示されるなどコードを書くときの手助けになってくれます！

例えば下記のようにコメントを書いたとします。
```typescript
/**
  * カウントの数値を取得します。
  * @return {number} カウントの数値
  */
```

定義した関数の部分をホバーすると画像のようなポップアップが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/0b4246f2-bb1e-c8da-f61a-961a0a978f08.png)

:::note alert
コメントをいただいて気がつきましたが、
APIドキュメントとしてのコメントとソースコードに対するコメントを切り分けておかないとコーディングの邪魔になってしまう可能性もあります…。

コメントする時は、コード内にすべきかドキュメントファイルとして切り分けて別で管理するかチーム内でコミュニケーションをとってください！
:::

## 【まとめ】JSDocコメントについて
ここまで読んでくださった方はきっと明日からJSDocコメントを書いてくれると思います！

プロジェクトでは人の入れ替わりは常です。
わかりやすい、丁寧なコメントを残していきましょう！

:::note
適切でわかりやすいコメントを残すことは、後の開発生産性に大きく影響を与えると考えています！
:::

コメントを書くとファイルのコード量が増える。というのも事実です。
ただ、今だとファイルを圧縮する方法はいくらでもあります。

:::note warn
コメントを書かずして、後の開発者に0からコードリーディングさせるのはあまりにも非効率なのでコードヒントが表示される状態にしておける方がメリットなのではないかと考えています。
:::

コメントには皆さんもご存知の通り「why not」が書かれていることが重要です。

https://twitter.com/t_wada/status/904916106153828352?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E904916106153828352%7Ctwgr%5E79663a0f0366a1c03a0fe2639c45b1f49b77d0b1%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fembed.zenn.studio%2Ftweetzenn-embedded__93256c6c0f0eb

もちろんコメントを書くまでもなく綺麗で明瞭なコードを書けることが望ましいですが、さまざまな理由からそうできない場合も存在すると思います。

:::note
丁寧なコメントが残すことで、後の開発者により良い実装を依頼できるメッセージにもなると思います！
:::

コメントを書く理由の1番は後の開発者にコンテキストを伝えることにあると思います。
私もわかりやすいコメントが記述できるように改めて意識していきます！
WSL2ディレクトリ　コマンドプロンプト　アクセス方法

## WSL2上のubuntuで作成したディレクトリにコマンドプロンプトからアクセスする方法

# 背景
* asdfを使用してnode.jsをインストールする際にWSL2上のubuntuのディレクトリにアクセスしようとした際に少しはまってしまったため記事にしようと考えた。

# アクセスする方法は２通りある

```:１コマンドプロンプト上で下記コマンドを実行する
ubuntu
```
2windowsの検索窓にubuntuと入力をする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/41b015c8-b52b-a559-e540-d6681d7ede29.png)

1,2どちらでもWSL2のUbuntuを起動させることができる。


## 参考にした記事
[Windows11 WSL2 Ubuntu の超基本的な使い方]
⇒https://note.com/hiro20180901/n/neb8fdd56f961
DeSmuMEで組み込まれているLua用API　非公式リファレンス　～stateライブラリ～ 

この記事はニンテンドーDS向けエミュレータの一つである「DeSmuME」（以降Desmume）のLua用APIの非公式日本語リファレンスです。今回はstateライブラリについてのリファレンスです。

:::note warn
このリファレンスは非公式の日本語リファレンスです。そもそも英語のリファレンスも公式のリファレンスもありません。
さらに詳細の仕様を確認したい場合はDesmumeのソースコードを参照することを推奨します。
→https://github.com/TASEmulators/desmume/blob/master/desmume/src/lua-engine.cpp
:::

---

`savestate.create()`
ステートセーブを行い`userdata`型で戻す

<details><summary>引数</summary>

第一引数
`int`型　スロット番号（ファイル生成あり）
1~10
`userdata`型　ファイル生成なし　lua完結


</details>

<details><summary>戻り値</summary>

`object`型

</details>

``` lua: example.lua
local state1,state2

state1 = savestate.create()
state2 = savestate.create()

savestate.save(state1)
emu.frameadvance()
emu.frameadvance()
emu.frameadvance()
savestate.save(state2)
emu.frameadvance()
emu.frameadvance()
savestate.load(state2)
emu.frameadvance()
emu.frameadvance()
savestate.load(state1)
```

---

`savestate.save()`
第一引数にステートセーブを行う

<details><summary>引数</summary>

第一引数
`int`型　スロット番号（ファイル生成あり）
1~10
`userdata`型　ファイル生成なし　lua完結

:::note info
第二引数にオプションがありますが、コメントアウトになっておりTODOとなっているので実装待ち
:::


</details>

<details><summary>戻り値</summary>

無し nil

</details>

``` lua: example.lua
local state

state = savestate.create(2)

savestate.save(state)
```

``` lua: example.lua
savestate.save(2)

--上のコードと同じ動き
```


---

`savestate.load()`
第一引数のスロットをステートロードする

<details><summary>引数</summary>

第一引数
`int`型　スロット番号（ファイル生成あり）
1~10
`userdata`型　ファイル生成なし　lua完結

:::note info
第二引数にオプションがありますが、コメントアウトになっておりTODOとなっているので実装待ち
:::

</details>

<details><summary>戻り値</summary>

無し nil

</details>

``` lua: example.lua
savestate.load(2)
```

---

`savestate.verify()`が用意しようとしている痕跡あり。
代替名も用意しようとしている痕跡あり。
エラーバーつきのレーダーチャートを作成する

## 背景
エクセルではレーダーチャートにエラーバーを含めることができません。
この記事では、エラーバー付きのレーダーチャートをpython(matplotlib)で描画する方法を紹介します。

## 動作環境
- Windows11
- Ubuntu 22.04.3 LTS (WSL2)
(Google Colabでも動作することを確認しています)

## サンプルコード
#### エラーバー付きレーダープロットを描画
このプログラムにより、レーダープロットの各頂点にエラーバーを持ったグラフを作成できます。
実際にこのコードを使用する場合は、手持ちのデータを「label_list, value_list, error_list」に入れてプログラムを実行しましょう。目盛りの値など、パラメータを調整したい場合は、「#パラメータの指定」以下の値から変更できます。パラメータとレーダーチャートの対応は図中に示しています。
```python
import matplotlib.pyplot as plt
import numpy as np

#ラベル、プロットする値、エラーバーを入力
label_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
value_list = [0.90, 0.85, 0.75, 0.80, 0.95, 0.70, 0.85, 0.88]
error_list =  [0.09, 0.1, 0.05, 0.20, 0.02, 0.020, 0.045, 0.1]
line_color = "blue"

#パラメータの指定

#リスト先頭の値のレーダープロット上の位置( "N", "NW", "W", "SW", "S", "SE", "E", "NE")
#Eだと、先頭の値が一番右(東)になる
theta_zero_location = "E"

#目盛りを入力
rgrids = [0, 0.25, 0.50, 0.75, 1]
#目盛り位置の角度
rgrids_angle = 75
#外枠の描画位置を入力
border_value = 1.05
#レーダーチャート中心の値を入力
center_value = 0

###################################################################################

#レーダーチャートの始点と終点をつなげるために、各リストの最後に最初の値を入れる
angle_list = [n / float(len(label_list)) * 2 * np.pi for n in range(len(label_list))]
angle_list.append(angle_list[0])
value_list.append(value_list[0])
error_list.append(error_list[0])

# レーダーチャートのフォーマットを作成
fig, ax = plt.subplots(1, 1, subplot_kw=dict(projection='polar'))
ax.set_rgrids([]) #目盛り線を削除
ax.spines['polar'].set_visible(False) #外枠線を削除
for grid_value in rgrids:
    grid_values = [grid_value] * (len(label_list)+1)
    ax.plot(angle_list, grid_values, '--',color="gray",  linewidth=0.5) #目盛り線を再描画
ax.plot(angle_list, [border_value] * (len(label_list)+1), '-',color="k",  linewidth=1) #外枠線を再描画
for t in rgrids:
    ax.text(x=np.pi * (rgrids_angle/180), y=t, s=t)
ax.set_rlim([center_value, border_value])

# レーダーチャートにプロット
ax.errorbar(angle_list, value_list, error_list,fmt='-o', linewidth=1, capsize=5,c=line_color)
ax.set_xticks(angle_list[:-1],label_list )
ax.set_theta_zero_location(theta_zero_location)
```
![変数との対応.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602355/3ea77264-e764-2a14-e97c-7f257ec695ce.png)



#### (おまけ)描画形式の変更
上記プログラムの「#レーダーチャートにプロット」を以下のように書き換えることで、エラーバーではない形式で誤差範囲を示すことができます。
```python
# レーダーチャートにプロット
top_value_list = [acc+ye for acc,ye in zip(value_list,error_list)]
bottom_value_list = [acc-ye for acc,ye in zip(value_list,error_list)]
ax.plot(angle_list, value_list, linewidth=1, linestyle='-',c=line_color)
ax.plot(angle_list, top_value_list, linewidth=0.5, linestyle='-',c='grey')
ax.plot(angle_list, bottom_value_list, linewidth=0.5, linestyle='-',c='grey')
ax.fill_between(angle_list,top_value_list,color=line_color,alpha=0.1)
ax.fill_between(angle_list,bottom_value_list,color='w')
ax.set_xticks(angle_list[:-1],label_list )
ax.set_theta_zero_location(theta_zero_location)
```
![output2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2602355/61302ead-d2fb-251d-693e-6e47ce87e3f5.png)


## 参考文献

https://analytics-note.xyz/programming/matplotlib-radar-chart/
【UE5】Unity で言うプレハブを作ったら静的ではないエラーが出た

# はじめに
Unity で言うプレハブを UE5 で作り、それを設置したかったが、よくわからないエラーが出たのでメモを残す。
ちなみにプレハブのことを UE5 ではブループリントクラスって言うらしい。

# エラー

```
AttachTo: 
'/Game/Maps/UEDPIE_0_SimpleMap.SimpleMap:
PersistentLevel.SM_Cube_bottom_Blueprint_C_UAID_xx_00.StaticMeshActor_UAID_xx_00' 
は静的  (in blueprint "SM_Cube_bottom_Blueprint") ではありません。

静的である 
'/Game/Maps/UEDPIE_0_SimpleMap.SimpleMap:
PersistentLevel.StaticMeshActor_UAID_xx_00_GEN_VARIABLE_StaticMeshActor_CAT_UAID_xx_00.StaticMeshComponent0' 
を親子付けすることはできません。中止します。
```

# 解決

どうやらスタティックメッシュ使ってるときは、アクタをスタティックに変更してあげないといけないらしい。

ブループリントクラス内のコンポーネント内にあるオブジェクトを選択し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/917bbdfc-48f8-a062-c3e6-fb53f87f764a.png)

可動性をスタティックにする必要があったみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/6c68522a-3e1e-3498-880f-57e9143c996d.png)

これで無事このエラーは解決できた。


# 参考

https://dev.epicgames.com/documentation/ja-jp/unreal-engine/unreal-engine-for-unity-developers?application_version=5.0

https://zenn.dev/daichi_gamedev/books/unreal-engine-tutorial/viewer/editor-actor-setting
PythonスクリプトからPowerShellスクリプトを実行したときPauseコマンドをスキップして停止しないようにする

# 前提
以下の記事の続きです。

https://qiita.com/barleytea/items/f9febcd383f75a7e8596

PythonスクリプトからPowerShellを実行した際、PowerShellスクリプトにあるpauseコマンドレットで処理が止まってしまう。処理を止めたくないのならpauseを削除すればよいのだがPythonスクリプトからではなくPowerShellスクリプトを直接実行する場合はpauseで止まってほしい。Pythonスクリプトから実行した場合のみpauseをスキップできないか考えた。

# PowerShellの処理
pauseコマンドレットを3つ用意する。3回文字入力をすると処理が終了する。
``` ps1
pause
pause
pause
```

# Pythonの処理
2通りの処理を用意する。pauseコマンドレットをスキップできるのは(2)の場合。
(1)単にpowershellコマンドを実行する
(2)echoコマンドをパイプラインでpowershellコマンドに渡す
　エコーコマンドで指定する文字列は任意

``` b.py
import subprocess

ps_file = 'C:\\PyWork\\a.ps1'

print('(1)')
ps_cmd = 'powershell -ExecutionPolicy RemoteSigned -File'
cmd = subprocess.run(ps_cmd + ' ' + ps_file)

print('(2)')
ps_cmd = 'powershell -Command echo "PYTHON" | powershell -ExecutionPolicy RemoteSigned -File'
cmd = subprocess.run(ps_cmd + ' ' + ps_file)

print('(3)')
ps_cmd = 'powershell -Command Write-Host y | powershell -ExecutionPolicy RemoteSigned -File'
cmd = subprocess.run(ps_cmd + ' ' + ps_file)
```

# 実行結果
(1)エンターキーを3回押さないと処理が完了しない
(2)エンターキーを押さなくても自動で処理が完了する
``` 
C:\PyWork> python b.py
(1)
続行するには、Enter キーを押してください...: 
続行するには、Enter キーを押してください...: 
続行するには、Enter キーを押してください...: 
(2)
続行するには、Enter キーを押してください...: PYTHON
続行するには、Enter キーを押してください...:
続行するには、Enter キーを押してください...:
(3)
y
続行するには、Enter キーを押してください...: 
続行するには、Enter キーを押してください...:
続行するには、Enter キーを押してください...:
```
LangchainのVersion上げたらAOAIの読み込みができなくなった

# 現象

LangchainのVersion上げたらエラーでた
`langchain-core (0.1.8-> 0.1.19)`
エラーメッセージ
```
ImportError: cannot import name '_signature' from 'langchain_community.chat_models.baichuan' (/usr/local/lib/python3.12/site-packages/langchain_community/chat_models/baichuan.py)
```

# 対応方法
0.1.8では下記の記述だったが、
`from langchain.chat_models import AzureChatOpenAI`


あるバージョンから別ライブラリ`langchain_openai`に書き出されていて、そこから引っ張ってくる必要があるらしい。
https://pypi.org/project/langchain-openai/
そして、コード内の記述は次のように切り替える必要がある。
`langchain_openai.llms.azure.AzureOpenAI`
Optparseの使い方について

# 概要

今回は、Rubyの標準機能である「Optparse」の説明になります。

公式ドキュメントは以下になります。

https://docs.ruby-lang.org/ja/latest/library/optparse.html


# Optparseとは？

rubyファイルを実行するときに、コマンドでオプションを指定することができるようにします。より正確に記述をすると「オプション解析をよしなに実施してくれる便利な機能」ということです。

実際の使用例を以下に用意しました。

# 使い方

サンプルコードは以下になります。

```sample.rb

# optparseが使用できるようにrequireします
require 'optparse'

opt = OptionParser.new

# ショートオプションとロングオプションの設定
# 使用するオプションを「-p または -option」という名前に設定します
# どちらかだけ(-pのみ)の設定でも問題ありません
# また、オプションの説明文も追加できます（なくても問題ありません）
opt.on('-p', '--option', '文字入力ができます') { |v| p v }

# コマンドラインに入力した文字を解析（パース）します
# 今のままの場合「-p」という文字も入力した文字が保管されているARGVに入っているため、"-p"をARGVの中から除外します
opt.parse!(ARGV)

# -pのあとに入力した文字を配列の形で出力します
p ARGV
# -pのあとに入力したものをこのような形で一つのずつ出力できます
puts ARGV[1]
# もし、-pのあとに複数 文字をインプットした場合はこのような形で出力できます
puts ARGV[2]
```

以下のコマンドで実行できますので、皆様のPCで実行してみてください。

```
ruby sample.rb --option test 
```
```
# オプションのあとに複数の文字をインプットすることもできます
ruby sample.rb -p test1 test2
```

# 補足

以下のコマンドを実施して optionの中に「-p」[--option]、そして説明文が含まれていることを確認できます。
```
# -h はデフォルトで使用できるヘルプオプション
ruby sample.rb -h
```

結果 以下のような表示がコンソールに表示されると思います。
```
Usage: test [options]
    -p, --option                     文字入力ができます
````
正規表現メモーその１

個人的「質はともかく継続する」１２日目です

## 正規表現メモ

メモとしてgithub上に残しておいた正規表現メモです。
良く忘れるし、githubの方は全然見なくなっていたので
こちらにお引越しします。

### 用語

__メタ文字__
特別な意味のある文字

__リテラル__
ふつうの文字

__パターン__
演算子のこと

__接頭辞・Prefix__
文字の頭につける値

__接尾辞・Suffix__
文字の後ろにつける値

__部分文字列・Substring__
文字の間につける値

__完全一致__
完全に一致する

__部分一致__
一部分だけ一致する

__前方一致__
前方に一致する

__後方一致__
後方に一致する

### アンカー

文字位置にマッチする

|moji|mean|
|----|----|
|^|行頭|
|$|行末|
|¥A|テキストの先頭|
|¥z|テキストの終端|
|¥b|文字列の間|
|¥B|文字列以外|

### エスケープシーケンス

バックスラッシュを頭につけて特殊文字を表す

|moji|mean|
|----|----|
|¥t|タブ|
|¥n|改行|
|¥s|スペース|
|¥000|8進ASCII|
|¥x00|16進ASCII|
|¥d|¥[0-9¥]|
|¥D|¥[^0-9¥]|
|¥w|¥[A-Za-z0-9¥]|

### キャプチャ

正規表現に¥(¥)をつかうと、その部分に連番が振られて、
変数のように取り出す事ができる。
＊エンジンやプログラム言語によって変数にできたり使えなかったりする。

```reg
2021/10/23
この文字列の数字部分を以下のようにキャプチャする
(¥d{4})(¥d{2})(¥d{2})
前から順に以下のようになる
$1 = 2021
$2 = 10
$3 = 23
これを使って置換することができる
----------------------------
検索 (¥d{4})(¥d{2})(¥d{2})
----------------------------
置換 $3,$1,$2
----------------------------
結果 23/2021/10
```
【2024マラソン05】EOMONTH関数が使えない時に、DATE関数で月末の日時を出す方法

# 何これ？
弊社で使っているノーコードツール「CELF」で、幾つか主要な関数が使えなかったので、調べた対処法を自分用の備忘録も兼ねてまとめます。

# 誰向け？
- CELFを使っていて、EOMONTH関数が使えなくて困った人
- 諸事情により、ExcelでEOMONTHが使えない人

# 解決策
``` 書き方
=date(year(today()),month(today()),0)
```
date関数はそれぞれ、年月日の数字をいれると、それに応じた日付を出してくれる関数です。
日付欄に0を入れると、先月末の数字になります。
なかなか便利なのが、閏年の三月に上記の関数を入れると、ちゃんと2/29になります。

非常にあっさりした分量の記事ですが、自分が覚えたばかりのことを書いてまとめるのもいいですね。
htmlを動的に追加された要素でも関数が効くようにする方法・jqueryとvanilla js

# jqueryなら
```javascript
    $(document).on('click', '.js-delete', function() {
        // クリックされたボタンの最も近い親の<table>を削除
        $(this).closest('table').remove();
    });
```

# vanilla jsなら

### DOMNodeInsertedは非推奨とのご指摘をいただいたので再度
短い！ありがとうございます。

```javascript
document.addEventListener('click', ({ target }) => {
  if (target.closest('.js-delete')) {
    target.closest('table').remove();
  }
});
```

### observerを使う方法

```javascript
// ページ読み込み時に実行される関数
document.addEventListener('DOMContentLoaded', function() {
  // クリック時のイベントリスナーを設定
  addDeleteEventListener(document);
});

// 新しい要素が追加されたときに実行される関数
function handleNewElement(mutationsList) {
  mutationsList.forEach(function(mutation) {
    if (mutation.type === 'childList') {
      // 追加された要素にイベントリスナーを設定
      mutation.addedNodes.forEach(function(node) {
        if (node.nodeType === Node.ELEMENT_NODE) {
          addDeleteEventListener(node);
        }
      });
    }
  });
}

// Mutation Observer を作成してイベントリスナーを設定
const observer = new MutationObserver(handleNewElement);
const observerConfig = {
  childList: true, // 子ノードの変更を監視
  subtree: true // 子孫ノードも監視
};

// イベントリスナーを追加する関数
function addDeleteEventListener(target) {
  const deleteButtons = target.querySelectorAll('.js-delete');
  deleteButtons.forEach(function(button) {
    button.addEventListener('click', function() {
      const table = button.closest('table');
      if (table) {
        table.remove();
      }
    });
  });
}

// ルート要素を監視対象に設定
observer.observe(document.documentElement, observerConfig);
```


#### 以下は非推奨だけど念の為

```javascript



// ページ読み込み時に実行される関数
document.addEventListener('DOMContentLoaded', handleDeleteButtons);

// 新しい要素が追加されたときに実行される関数
document.addEventListener('DOMNodeInserted', handleDeleteButtons);

// 削除ボタンのイベントリスナーを設定する関数
function handleDeleteButtons(event) {
  const target = event.target;
  if (target.matches('.js-delete') || target.closest('.js-delete')) {
    target.closest('.js-delete').addEventListener('click', function() {
      this.closest('table').remove();
    });
  }
}

```


動的に追加された場合の処理を考えるとjqueryのコードの短さは神。
JavaScriptにおけるvarとletの違い

JavaScriptには変数を宣言するためのキーワードとして`var`、`let`、`const`の3つがあります。
特に`var`と`let`の違いは混乱を招きやすいポイントです。
本記事では、`var`と`let`の違いを明らかにし、なぜ`let`が推奨されるのかを解説します。

## varとletの基本的な違い
### スコープの違い
`var`は関数スコープを持ちます。関数内で定義された変数は関数全体でアクセス可能です。
一方、`let`はブロックスコープを持ち、ブロック（if文やfor文など）内で定義された変数はそのブロック内でのみアクセス可能です。
```
function scopeExample() {
    if (true) {
        var x = 10;
        let y = 20;
    }
    console.log(x); // 10 (関数スコープなのでアクセス可能)
    console.log(y); // ReferenceError: y is not defined (ブロックスコープなのでアクセス不可)
}
scopeExample();
```

### 再宣言の違い
`var`は同じスコープ内で再宣言が可能ですが、`let`は再宣言が不可能です。
```
var x = 1;
var x = 2; // 問題なく再宣言できる
console.log(x); // 2

let y = 1;
let y = 2; // SyntaxError: Identifier 'y' has already been declared
```
### 変数の巻き上げ（ホイスティング）
`var`は変数の宣言が巻き上げられるため、宣言前に使用することが可能です。ただし、初期化は巻き上げられないので、未初期化の状態になります。
`let`は変数の宣言が巻き上げられず、宣言前に使用するとエラーになります。
```
console.log(x); // undefined
var x = 10;
console.log(x); // 10

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
console.log(y); // 10
```
## なぜ`let`が推奨されるのか
### 意図しないバグを防ぐ
`var`の関数スコープとブロック外でのアクセス可能性は、意図しないバグを引き起こしやすいです。
`let`のブロックスコープにより、変数の使用範囲をより明確に限定できるため、予期しない動作を防ぐことができます。
### コードの可読性とメンテナンス性
`let`を使用することで、変数がどこで使用されるのかが明確になります。これにより、コードの可読性が向上し、他の開発者や将来の自分にとっても理解しやすくなります。また、スコープが明確であるため、メンテナンスも容易になります。

### より厳密なエラーチェック
`let`は再宣言を許さず、宣言前の使用もエラーとなるため、コードの品質を高めるための厳密なエラーチェックが可能です。これにより、潜在的なバグを早期に発見しやすくなります。

## まとめ
`var`と`let`の違いを理解することは、JavaScriptの変数管理において非常に重要です。

`let`を使用することで、スコープの明確化、意図しないバグの防止、コードの可読性とメンテナンス性の向上、より厳密なエラーチェックが可能になります。
これらの理由から、JavaScriptにおいては`let`が推奨されています。

今後のプロジェクトでは、意識的にletを使用することで、より堅牢で読みやすいコードを書くことを目指しましょう。
Iceberg カタログの概要・前提条件と、各種カタログの比較

# この記事について

毎週木曜の朝に開催している #データエンジニアRadio 第16回のネタとして、Oreilly から発売された Apache Iceberg - The Definitive Guide の第5章の前半部分を要約したものです。

:::note warn
この形式で書かれている部分は、私の感想・コメントなどです。
:::

本文は逐語訳ではなく、細かい点を端折っているところもあるので、細かい部分も正確に知りたい方は原書をお読みください！

## 本

https://www.amazon.co.jp/dp/1098148622

### Respect

この本が発売される前の時点で、Iceberg カタログの情報をここまでまとめていた[べりんぐさん](https://x.com/_Bassari)まじすごい。

https://t.co/d6fDbDNVMj


## データエンジニアRadio

https://qiita.com/IQ_Bocchi/items/d38db751388b10870ab2


# 要約

この章では、複数のユーザーが読み書きをする状況下で一貫性を担保するのに欠かせない Iceberg カタログについて以下を見ていく。

- カタログの一般的な要求事項と、本番でカタログを使うための更なる要求事項
- 異なるカタログの実装とそのメリデメ、カタログ活用のための Spark の設定方法
- カタログの移行を検討するべき状況
- カタログを移行する方法
- 
:::note warn
このページで翻訳したのは、最初の２つだけです。
後半の２つは・・・そのうちやるかも。
:::

## Iceberg Catalog の前提条件

Iceberg は、以下のような機能の実装を要求するカタログインターフェースを提供する。

- 既存のテーブルの一覧を表示する
- テーブルを作成する
- テーブルを削除する
- テーブルが存在するかどうかを確認する
- テーブルをリネームする

インターフェースなので、様々な実装がある。
たとえば Hive メタストア、AWS Glue、Hadoop の ファイルシステムカタログなど。

インターフェースで定義された関数を実装していることに加え、Iceberg カタログとして機能するためにカタログに求められる主要な事項として、**テーブルのパスを、現在の状態とともにメタデータファイルとマッピングできること**が挙げられる。

上記は一般的な要求事項であり、このマッピングをどのように実装しているかはカタログごとに異なる。

### 各種のカタログの実装方法の違い

たとえばファイルシステムをカタログとして利用する場合、テーブルのメタデータフォルダに version-hint.text というファイルがあり、そこに現在のメタデータファイルのバージョン番号が書き込まれる。 Hive メタストアをカタログとして使う場合、 Hive メタストアのテーブルエントリに `location` というプロパティがあり、現在のメタデータファイルのロケーションを示す。

上記はカタログを Iceberg カタログ として使用する最低限の要求事項だが、カタログとして使えるかどうかと、オススメできるかどうかは別問題である。

単に使えるかどうかとオススメできるかどうかの区別は、複数のジョブが同じテーブルに同時に書き込みを行なった際に失われるデータがないかどうかによる。

開発や検証目的であればこの要件は必要ではないが、本番でデータが失われると大問題である。

:::note warn
開発・検証でこの要件が不要なわけではないだろう。。。
（許容度が本番に比べたらまだ高いというだけで。。。）
:::

### 本番でカタログを使うときの要求事項

本番で Iceberg カタログを使うときの最も大切な要求事項は、現在のメタデータのポインタを更新する際のアトミックなオペレーションをサポートすることだ。この要求事項は、以下を保証するためにある。

- 同じ時間に同じテーブルにアクセスしているすべての読み手・書き手は、そのテーブルの同じ状態を見ていること

- 同時に書き込もうとする処理が２つある場合に、ふたつめの処理が最初の処理による変更を上書きしないこと（上書きが起きると、データの消失が起きてしまう）

## カタログの比較

このセクションでは、そこそこ人気のあるカタログを、以下の観点で見ていく。

- テーブルのパスとテーブルの現在のメタデータファイルのロケーションをどのように紐づけるか
- メリデメ
- そのカタログを使うべきう状況

:::note warn
原書ではそれぞれのカタログの特徴が文章で書いてありますが、そのまま訳してもおもしろくないというか長いしお互いの比較もしづらいので、ここでは表にまとめてみました。
本文中で見ると字がかなり小さくて見づらいと思いますので、適宜ダウンロード・拡大するなどしてご覧ください。
:::

どーん！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/6c607e6f-944c-4861-be2a-956d9101dea3.png)

:::note warn
原書では、各種のカタログを使うための Spark の設定方法も書いてあるが、こちらでは紙面の都合上割愛。
:::

他にもカタログとして使えるものはある（インメモリ、DynamoDB、Snowflakeなど）が、きりがないので代表的なものを挙げた次第。
前述の Icebergカタログの要求事項を満たしている限り、なんでも Iceberg カタログとして機能することができる。

# 最後に

まとめは以上です。

ここまで記事をお読みいただき、ありがとうございました！
せっかく読んだことだし、この本の翻訳プロジェクトが発足した際にはぜひ参加したいです。

Iceberg コミュニティの皆様、よろしくお願いいたします。

あと データエンジニアRadio もぜひ聞いてみてください！
毎週木曜日の朝8:00〜8:40に、Twitter の Space でやっています。

Twitter やっていない人も、以下のアーカイブから録音を聴くことができます。

https://qiita.com/IQ_Bocchi/items/d38db751388b10870ab2
Rubyでデザインパターン (3) TemplateMethodパターン

## この記事は何
デザインパターンについて、Rubyでどのような使い方ができるかをまとめた記事です。
デザインパターン自体の解説は詳しく行いません。

## TemplateMethodパターンとは
TemplateMethodパターンとは、スーパークラスで処理の枠組みを定め、その一部をサブクラスで具体的に実装するデザインパターンです。

https://qiita.com/shoheiyokoyama/items/c2ce16b4f492cd014d50

詳しくはこちらをご覧ください。

## Rubyでのコード例
スーパークラスで手続きの流れを実装し、サブクラスで手続きの処理で呼び出しているメソッドの定義を行なっていきます。

```rb
class SuperClass
  def template_method
    method1
    method2
    method3
  end

  private

  def method1
    fail NotImplementedError
  end

  def method2
    fail NotImplementedError
  end

  def method3
    fail NotImplementedError
  end
  
end

class SubClass < SuperClass
  private
  
  def method1
    puts 'sub class method1'
  end

  def method2
    puts 'sub class method2'
  end

  def method3
    puts 'sub class method3'
  end
end

SubClass.new.template_method
```

```:出力結果
sub class method1
sub class method2
sub class method3
```

## どのような時に使えるか
処理の流れを共通化し、処理の内容をカスタマイズ可能な形を実現したい場合などに有効です。
例えば以下のようなコードはTemplateMethodパターンを用いることで再利用性の高いコードにすることができます。

```rb
# レポートの生成プロセスを定義するスーパークラス
class ReportGenerator
  def generate_report
    gather_data
    format_report
    print_report
  end

  private

  def gather_data
    fail NotImplementedError
  end

  def format_report
    fail NotImplementedError
  end

  def print_report
    fail NotImplementedError
  end
end

# 特定のデータを収集し、レポートをフォーマットするサブクラス
class SalesReportGenerator < ReportGenerator
  private

  def gather_data
    puts 'Gathering sales data...'
    @data = 'Sales Data'
  end

  def format_report
    puts 'Formatting sales report...'
    @formatted_report = "Formatted: #{@data}"
  end

  def print_report
    puts 'Printing sales report...'
    puts @formatted_report
  end
end

class InventoryReportGenerator < ReportGenerator
  private

  def gather_data
    puts 'Gathering inventory data...'
    @data = 'Inventory Data'
  end

  def format_report
    puts 'Formatting inventory report...'
    @formatted_report = "Formatted: #{@data}"
  end

  def print_report
    puts 'Printing inventory report...'
    puts @formatted_report
  end
end

# サブクラスを利用してレポートを生成
SalesReportGenerator.new.generate_report
InventoryReportGenerator.new.generate_report
```

```:出力結果
Gathering sales data...
Formatting sales report...
Printing sales report...
Formatted: Sales Data
Gathering inventory data...
Formatting inventory report...
Printing inventory report...
Formatted: Inventory Data
```
[Python]YouTube Data API v3で自分の登録チャンネルのリストを取得する

YouTube Data APIの「Python クリックスタート」のとおりにしたらつまづいたのでメモを残す

# 環境
wsl
```
>wsl --version
WSL バージョン: 2.2.4.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.61
MSRDC バージョン: 1.2.5326
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26091.1-240325-1447.ge-release
Windows バージョン: 10.0.22631.3737
```

Python
```
$ python --version
Python 3.10.12
```

# 手順

ここに書かれている通りに勧める。

https://developers.google.com/youtube/v3/quickstart/python?hl=ja
* 登録チャンネルリストの取得ではAPIキーは不要なのでAPIキーに関することはスルーする


実行するとエラーが発生する
```Python
$ python example.py
Traceback (most recent call last):
  File "sample.py", line 41, in <module>
    main()
  File "sample.py", line 29, in main
    credentials = flow.run_console()
AttributeError: 'InstalledAppFlow' object has no attribute 'run_console'
```

クイックスタートでインストールしたモジュールは最新のバージョンでは```run_console```がないらしい
```
pip install --upgrade google-api-python-client
pip install --upgrade google-auth-oauthlib google-auth-httplib2
```

https://stackoverflow.com/questions/75602866/google-oauth-attributeerror-installedappflow-object-has-no-attribute-run-co

https://github.com/xyou365/AutoRclone/issues/101#issuecomment-1795530261

このバージョンで解決するらしい
```
google-api-python-client==1.7.2
google-auth==2.14.1
google-auth-httplib2==0.0.3
google-auth-oauthlib==0.4.1
```

上記バージョンのモジュールをインストールすることでサンプルコードは実行できるようになった

# 最新バージョンを使用するためには
~~run_console()は Google によって非推奨になっているらしいが、それならどう解決するべきか~~

run_local_server()を使用するのが正解っぽい
とりあえずモジュールを最新にする
```Bash
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
```

run_console()をrun_local_server()にして実行するとエラーが発生する
```Python
Traceback (most recent call last):
  File "/mnt/c/Users/satoshi/Projects/Youtube/get-my-subscription-list.py", line 41, in <module>
    main()
  File "/mnt/c/Users/satoshi/Projects/Youtube/get-my-subscription-list.py", line 29, in main
    credentials = flow.run_local_server()
  File "/mnt/c/Users/satoshi/Projects/Youtube/.venv/lib/python3.10/site-packages/google_auth_oauthlib/flow.py", line 444, in run_local_server
    webbrowser.get(browser).open(auth_url, new=1, autoraise=True)
  File "/usr/lib/python3.10/webbrowser.py", line 65, in get
    raise Error("could not locate runnable browser")
webbrowser.Error: could not locate runnable browser
```
これはWebブラウザを開こうとして失敗したということらしい。wslでbrowser.get()は機能しないのかもしれない。なのでrun_local_server()の引数に```open_browser=False```を渡すと
```
Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=314104985852-8oqdcunjkim2bfijomq2ilp6g00qukfv.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&state=bWv3M7G4HLjuCVYxvFPEPqAsOsdx8r&access_type=offline
```
となるのでクリックするとブラウザが開き認証ができるようになる
TypeScriptつよつよになりたいんじゃ

## はじめに
TypeScriptでのコーディング能力を向上させたいという目的で取り組んだことを書きます。

## バイブル「サバイバルTypeScript」

TypeScript界隈では知らない人はいない優良サイトです。
「あれ、これってどういう書き方だっけ...？」ってなったらすぐにここで調べています。
何よりPlayGroundをこのサイトで知ることができてインプット➡アウトプットのサイクルがものすごく早くなりました。
とにかくコード書いて試してみるのが一番ですよね。

https://typescriptbook.jp/

## PRレビュー会

自分で実装したコードを言語化して人に説明できないと話にならん！と思い強制アウトプットの機会を作りました。
チームメンバーにも希望者がいれば発表してもらっています。
トピックとしては主に2つに分かれます。
1. ***開発仕様も含めたソースコード全体を説明してフィードバックをもらう***
人に説明できるようソースコードを改めてチェックしながら発表準備をしている内に
「ここ書き方変だな、修正しよう」とか「いまやっとここの仕様完全に理解したわ」ってなるのでとても効果的です。
1. ***コーディングで迷った部分についてみんなで議論する***
1.よりも細かい技術的なところをあーだこーだ言いながら進めます。
配列メソッドの効果的な使い方や例外処理の実装についてなど、誰かがテーマを持ち込んで話していきます。
普段はあまりこのような時間が取れずめったに聞くことのない先輩社員の考え方を知れる機会にもなってとても勉強になっています。

## セルフレビュー
PRレビュー会以外にも何かできないかな～と思って調べているとこんな記事がでてきました。

https://konifar-zatsu.hatenadiary.jp/entry/2024/05/30/194846

私は当たり前のことが当たり前にできていなかったのでとても参考になりました。
特に以下の文が自分に刺さりました。
> Pull Request は自分の作品 というつもりで仕上げることを意識するのが大事

この考え方だけで自分のPullRequestへの愛着が200倍になりました。
最近は迷った点や理解しづらいコードにPRコメントを残すようにしています。
レビュワーとしての経験ももっと積んでいきたいですね。

## おわりに

ふとした瞬間に「自分、成長してるな」って感じるときがあって嬉しい反面、「やっぱ実力不足だな」って思うこともあります。
まだまだ取り組みはじめたばかり、コッカラッス！
プライベートIPの規則(RFC1918)に関する備忘

# 背景
- AWS Advanced Networking Specialtyの勉強をしているときにRFC1918という聞き慣れない言葉が出てきたので備忘

# RFC1918とは
- プライベートIPのCIDR範囲に関する規約
- クラスA-Cまで分かれている
    - クラスA：10.0.0.0~10.255.255.255(10.0.0.0/8)
    - クラスB:172.16.0.0～172.31.255.255(172.16.0.0/12)
    - クラスC：192.168.0.0~192.168.255.255(192.168.0.0/16)

何かあればまた追記