OmniAICreator/Qiita-1.07M huggingface dataset:
RaspiでNATルーターを構築する

## はじめに
Raspberry piでルーターを作ってみる


## raspberrypi imagerの使用
sdカードにイメージを書き込む

## sshの設定
sdカードに直接　→　sshからファイルを作成する
raspi-config →　sshのオン

## 無線の設定

### 無線のインターフェイス起動
以下を書きこむ
/etc/wpa_supplicant/wpa_supplicant.conf
country = JP



#rfkill unblock wifi
#ifconfig wlan0 up

## DNSの設定
/etc/dhcpcd.conf

interface wlan0
static domain_name_servers=172.24.2.51
 
### 無線の認証設定
/etc/wpa_supplicant/wpa_supplicant.conf
country = JP
network={
    ssid="media"
    psk="metro-cit"
}


## GUI起動設定
### パッケージインストール
apt-get -y update
apt-get -y install lightdm

### 
raspi-config
boot GUIを選択
interface →　VNCの選択


## 有線設定

### IP設定
/etc/dhcpcd.conf
interface eth0
static ip_address=192.168.0.254/24
static routers=0.0.0.0
static domain_name_servers=0.0.0.0

### IPマスカレード(NAT)の設定

sudo apt-get install iptables-persistent

/etc/rc.local

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE


exit 0



## DHCPサーバーの設定
### DHCPサーバーのインストール
sudo apt install -y isc-dhcp-server dnsmasq

### コンフィグの書き換え
nano /etc/dhcp/dhcpd.conf

#option domain-name "example.org"; #コメントアウトする
#option domain-name-servers ns1.example.org, ns2.example.org; #コメントアウトする

authoritative; #コメントアウトを外す

#追記
subnet 192.168.0.0 netmask 255.255.255.0 {
        range 192.168.0.100 192.168.0.199;
        option routers 192.168.0.254;
        option domain-name-servers 172.24.2.51;
        option broadcast-address 192.168.0.255;
        ignore declines;
}

### インターフェイスの設定
/etc/default/isc-dhcp-server

INTERFACESv4="eth0"


### サーバーの起動
sudo systemctl start isc-dhcp-server.service
sudo systemctl enable isc-dhcp-server.service
KVMのVM内ファイルの編集

kvmにおいて、仮想マシン内のファイルを編集したい場合がある


## 書式
```
virt-edit [--options] -d domname file [file ...]

virt-edit [--options] -a disk.img [-a disk.img ...] file [file ...]

virt-edit [-d domname|-a disk.img] file -e 'expr'

```

## コマンド使用例
```
virt-edit -d mydomain /boot/grub/grub.conf
virt-edit -d mydomain /etc/passwd
```

## Windows仮想マシンの場合
```
virt-edit -d mywindomain 'c:\autoexec.bat'
```




##### 参考文献
https://manpages.ubuntu.com/manpages/bionic/ja/man1/virt-edit.1.html
Why Programmers Should Write Blogs

# Introduction

The topic of writing blogs is often discussed among programmers, but it indeed has many benefits and also some misconceptions. In this blog post, I will briefly summarize the advantages of writing blogs and provide some suggestions.

# Benefits of Writing Blogs

## Deepening Understanding of Knowledge
Learning shouldn't be limited to input; it also requires output. Writing blogs is an excellent way to reinforce your understanding and mastery of knowledge.

## Enhancing Summarization and Documentation Skills
Writing blogs involves organizing and summarizing what you've learned. This helps improve your summarization skills and ability to document your work, which is beneficial for both yourself and others who read your blog.

## Providing Assistance
By documenting the problems you've encountered and their solutions, you can help others facing similar issues. Sharing knowledge and experiences contributes to collective growth.

## Boosting Your Profile
Having one or more high-quality blog posts can be a valuable asset when looking for jobs or during interviews. It showcases your technical abilities and experience.

## Increasing Visibility
Once your blog gains a certain amount of traffic and followers, it can enhance your personal visibility, opening up more job and collaboration opportunities.

# Misconceptions and Recommendations

## Writing Blogs Isn't Limited to Experts
You don't have to be an expert or a guru to write blogs. Beginners can also share their learning journey, study notes, and insights, contributing to the community.

## Don't Fear Criticism
Whether you are a guru or a beginner, online content can attract criticism. Don't be afraid; criticism is common. Don't give too much attention to negative comments.

## Embrace Feedback from Readers
If someone points out mistakes in your blog, it's a free learning opportunity. Accept feedback with humility and use it to improve your writing.

## Test and Provide Details
When writing blogs, make sure to test the code and technologies you mention. Include relevant information such as version numbers, enabling readers to reproduce your results in a similar environment.

## Attribute Sources
When referencing documents or literature, remember to give proper credit and cite the sources to show respect for the original authors and their work.

# Conclusion

Writing blogs is not only a means of self-expression but also a way to contribute to the programming community. By sharing your knowledge and experiences, you can inspire others and foster growth in the field.

Remember, persistence is key. Keep writing, and you will reap great rewards!
あなたのパスワードは安全ですか？

　こんにちは。ディマージシェアの技術担当です。今回は「パスワード」について書いてみようと思います。

# パスワードとは
　技術的な解説はgoogle先生にお任せします。誰でもわかる表現で端的に表すと、「操作者が本人であることを証明する文字列」です。多くの人は何を今更...と思うでしょう。言わずと知れた常識です。しかし、残念なことに、理屈を理解して理想的な運用できているユーザは残念ながらごく一部です。

# パスワードに関連するトラブル
　パスワードに関連するトラブルは主に2つあります。一つは他人に知られてしまうこと、もう一つは自分がわからなくなることです。ほとんどの人はこれらのトラブルを経験したことがあるのではないでしょうか。後者のトラブルに関しては自分がシステムを使えなくなるだけで済みますが、前者のトラブルは金銭的な被害が伴うことも多く、極めて危険です。特に、他人に知られてしまうトラブルが起こりやすいパスワードは「安全性の低いパスワード」と呼ばれていたりします。

# 安全なパスワードとは
　安全なパスワードは、「自分以外入力できない」パスワードと言い換えることができます。「1234」や「admin」のようなパスワードが危険であることは明白です。推測が容易であったり、総当たりで簡単にわかる性質のものは安全とは言えません。対して「*ZGr~6i/Du%w」のようなパスワードは安全です。

　使用するシステムによっては、パスワードの設定時に「12文字以上、英数字記号混在...」などの条件を満たさないと登録できない場合があります。使いやすさの観点からは少し不便ではありますが、不用意なパスワードを登録させない仕組みとして有効であることがわかっています。

# 安易なパスワードは狙われる
　インターネットで利用できるサービスのうち、パスワードが必要なサービスは必ず第三者から攻撃を受けます。その際、パスワードは「総当たり」で探そうとすると意外とコストがかかります。そのため、攻撃者はある程度方針を持って攻撃を仕掛けます。例えば「辞書に載ってるワード」「キーボードの並び」などです。他にも、「password list top 100」のようなキーワードでgoogle検索すると、頻繁に使われたパスワードのリストを入手することができます。そして不幸なことに、これらの攻撃でパスワードの突破に成功してしまうケースは後を絶ちません。

　攻撃者は安全なパスワードを設定しているユーザをそもそも相手にしようともしません。理由はパスワードを突破するのが大変というだけではありません。安全なパスワードを設定できるユーザはリテラシーが高い可能性が高く、仮にパスワードを突破できたとしても対価が期待できないためです。

　現実の世界で窃盗の被害に遭いやすい人、遭いにくい人と構図が似ています。例えば自転車であれば、鍵が2つ付いている自転車と、鍵のかかっていない自転車が並んでいれば、鍵のかかっていない方の自転車がなくなるのが常識です。ユーザの安易な行為に付け込まれるのは現実世界でもインターネットの世界でも同様です。

# 使いまわしたパスワードは流出する
　パスワードの入力が必要なシステム全てが善意に満ちているとは限りません。フィッシング詐欺などは典型ですが、時折、普通の通販を利用しただけにも関わらず、登録したIDとパスワードのセットがメール本文に平文で載ったまま送信されてくることがあります。システム運用者側に善人しかいないのであればよいのですが、盗まれてしまうケースも報告されています。
　パスワードを毎回違うものを設定していればこの類の流出はそんなに大きなリスクにはならないのですが、同じパスワードを別のところで使っている場合は注意が必要です。

# 誰かが見ているところでパスワードを入力しない
　これもパスワードが流出する典型です。パスワードを入力する瞬間を見られていたり、撮影されていたりすることでパスワードを盗まれることがあります。ちょっと手が込んでくると、キーロガーが仕掛けられていたり。
　インターネット経由でパスワードを盗むのはそこそこ大変ですが、物理的に狙われると意外と脆弱です。注意しましょう。

# ログインIDとパスワード欄を間違えたときはパスワードを変える
　よくあるIDとパスワードのセットを入力するフォームですが、稀にIDを入力する場所にパスワードを入れてしまうことがあります。この値はシステムにロギングされている可能性が高く、パスワードが見られてしまうリスクが高いです。
　入力されたパスワードそのものをロギングするようなシステムは詐欺以外ではあまり聞いたことがありませんが、「誰がログイン試行したのか」はログに残ることが多いです。ID入力欄にパスワードを間違えて入れてしまうと、ログにパスワードが露出してしまうことがあるのです。


# インターネットの世界を安全に生きるために
　インターネットの世界は予想以上に悪意に満ち溢れています。パスワードを適切に管理するのは身を守るための第一歩です。インターネットの世界を安全に楽しみましょう。

当社に興味を持たれた方は[HP](https://www.dimage.co.jp/)もご覧ください。
【CSS】CSS Maskingを使って、フェードアウトするUIを実現する。

## はじめに
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/cd09f7fb-580d-acd4-8c2a-70eaeb5e55dd.png)


みなさんは、CSS Maskingを使いこなせていますか？

CSS Maskingは、デザイン性の高いLPや特設サイト等ではよく使うかもしれませんが、
Webプロダクトだとちゃんと触る機会が多くないプロパティだと思います。

そのため、この記事ではWebプロダクトでも使えるCSS Maskingを使ったUIを紹介しながら
CSS Maskingについて解説します。


## CSS Maskingとは？
CSS Maskingとは、任意の形に要素を切り抜けるプロパティになります。

似たような任意の形に要素を切り抜ける`clip-path` プロパティとの違いは、SVGで任意の形に切り抜けるだけでなく、`mask-image`で任意の画像や透明度に応じた切り抜きが行えることにあります。

この記事では、`mask-image`に`linear-gradient`でグラデーションを使用することで、フェードアウトするUIを実現していきます。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/ee8cf6f2-fb1a-cb23-7a46-5380dc488a70.png)


## 完成系
今回は、↓こんな感じにフェードアウトするUIを作っていきます。
音楽系のサイト/アプリで、歌詞が、右から左へ流れているようなものをイメージして作成しました。
<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="NWOPeRd" data-editable="true" data-user="sp_degu" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/NWOPeRd">
  CSS Masking - Fade out UI</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## フェードアウトするUIをつくる
### 1. HTMLを実装する
早速、HTMLの実装からしていきましょう。

作りはとてもシンプルです。
`container` の中にアイコンと歌詞を入れている形になります。
`yrics-container`に `mask-image`プロパティを指定して、フェードアウトするUIを作っていきます。

```sample.html
<div class="container">
  <span class="material-symbols-outlined">music_note</span>
  <div class="lyrics-container">
    <p class="lyrics">さぁ、怖くはない　　不安はない　　私の夢は　　みんなの願い　　歌唄えば　　ココロ晴れる　　大丈夫よ　　私は最強〜♪</p>
  </div>
</div>
```

### 2. CSSを実装する
次にCSSを作っていきます。

`.container`は、スタイルをいい感じにするため、それっぽいデザインを当てています。

`.lyrics-container`では、`mask-image`に`linear-gradient(to right, transparent 3%, black 30%, black 70%, transparent 97%);`をあてることで、フェードアウトしているデザインにしています。

`.lyrics`では、アニメーションを追加して、歌詞が左から右へ流れるようにアニメーションさせています。

```sample.css
.container {
  aligin-items: center;
  border: 1px solid #FFFFFF;
  border-radius: 8px;
  background-color: rgba(255, 255, 255, .7);
  display: grid;
  gap: 4px;
  grid-template-columns: 24px minmax(0, 1fr);
  padding: 6px 12px;
  max-width: 300px;
  width: 100%;
}

.lyrics-container {
  color: #1C1B1F;
  mask-image: linear-gradient(to right, transparent 3%, black 30%, black 70%, transparent 97%);
  -webkit-mask-image: linear-gradient(to right, transparent 3%, black 30%, black 70%, transparent 97%);
  position: relative;
  white-space: nowrap;
}

.lyrics {
  animation: 12s linear 1s infinite lyrics-anime;
  margin: 0;
  position: absolute;
  width: fit-content;
  font-weight: 500;
}

@keyframes lyrics-anime {
  0% {
    left: 150%;
  }
  100% {
    left: -400%;
  }
}
```

## まとめ
この記事では、CSS Maskingを使って、フェードアウトするUIの作り方を解説しました。

UI上で、フェードイン/フェードアウトするだけで、モダンなデザインになることが多いです。
また、文章が多くなった時に、よく `...`で省略しますが、CSS Maskingを使って省略させてもいいかもしれません。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
深層学習モデルのメモリの内訳と算出方法

## またGPUメモリ足りないや...
深層学習初学者の自分は

上司「とりあえずこれ使ってください(16GBメモリくらいの弱マシン)」

と言われて、いざ自分なりにgithubクローンして深層学習を始めてみると
```
RuntimeError: CUDA out of memory. Tried to allocate 220.00 MiB (GPU 0; 15.78 GiB total capacity; 13.16 GiB already allocated; 201.44 MiB free; 14.44 GiB reserved in total by PyTorch
```
みたいなエラーが出てきて、
僕「あれ、上司がこれ使えって言ったくらいだから動くはずなのに...」
僕「cuda、docker周りの設定ミスったか？」
僕「いや、でも初学者だから何か知らないメモリ周りの設定間違えてるのか...」
などと悶々としていて、最終的に調べてみると

上司「ごめんごめんメモリ足りんわ。もっといいマシン使っていいよ」

となることが多かったのはいい思い出です。が、実際のところ **ある深層学習モデルをあるタスクについて動かすのには最低どれくらいメモリが必要なのか？** を見積もるのは最初の一番大事なタスクになるかと思います。マシンスペックが足りないだけの場合、時間が無駄になりますしね。[^1]

## 必要なメモリの見積もりかた
**僕は**学習に最低限必要なメモリの概算は典型的な設定において次のように見積もっています：
**```必要なGPUサイズ ≒ 4bytes × (モデルのパラメータ数)```
```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 + 8bytes × (optimizerの必要な記憶)```
```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 + 4bytes × (モデルのパラメータにおける勾配)```
```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 + 4bytes × (入力データをforwardする時に必要なメモリ) × (バッチサイズ)```
```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 + α(pythonカーネル、他ソフト系、計1〜2GB)```**

**```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 ≒ 4bytes × 4 × (モデルのパラメータ数)```
```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 + 4bytes × (入力データサイズ) × (バッチサイズ)```
```　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 + 2GB```**
注１）一時的にこれを超えるメモリが必要になる可能性はあります。
注2）自分の経験則です！forward計算時に必要なメモリはモデルのアーキテクチャによって異なるので（例えば「分岐構造があるか？」「CNN使ってるか？」等によってデータサイズと必要な演算結果保持に必要なメモリサイズの関係は変わります。）
注3)実際にはこれより少ないメモリでも動かせる可能があります。

どうして上の式で見積もれるのかを以下で解説していきます。

## 必要なメモリの内訳
深層学習で必要なメモリの内訳は以下となります：
1. **モデルの重み**
2. **Optimizerの状態**
3. **勾配**
4. **フォワード計算結果の保持**
5. **tempバッファ**
6. **関数用領域**

それぞれについて必要なデータはを以下で見ていきます。
##### 1. モデルの重み
≒ネットワークの重みパラメータのことです。数式だとよく```W```で表されるものですね。
- 4 bytes × パラメータ数

##### 2. Optimizer計算に必要な状態のメモリ
Optimizerのアルゴリズムにより、保持しなければいけないデータ数は変わります。
- 4 bytes × パラメータ数 × 2(AdamWの場合更新前後の2状態を記録する必要がある)

##### 3. 勾配
バックプロパゲーションに必要な数値の保持分です。
- 4 bytes × パラメータ数

##### 4. フォワード計算結果の保持
あるバッチ数モデルに計算させる際の入力データです。batchサイズ、シーケンス長、hidden stateの大きさによって変わる部分です。一番ボトルネックになる部分ですね。

##### 5. tempバッファ
複雑な計算などに必要な一時的なメモリ領域です。利用する側は特に気にする必要はないです。学習中などに一時的に使用率が上がってしまう原因でもあります。従って、使わなくなった変数などはメモリを解放することが望まれる部分です。

##### 6. 関数用領域
最後にbeamサーチなどのライブラリ・ソフトウェアが使う領域です。こちらも利用する側は気にする必要がないでしょう。(pythonカーネルとかもここですかね？)

従って、GPUメモリの内訳としては
- データやモデルアーキテクチャによらず必要なモデルパラメータのデータと、そこで保持する必要のある勾配データ部分
- あるbatchサイズだけ、データをモデルにforwardさせる時に保存するデータ＆行った演算(一般に「計算グラフ」と言ってる部分)のデータを保持する部分
が必要となります。

ただし、後者については利用したいモデルによって違ったりする&学習のボトルネックになる可能性が高いので(≒batchサイズはでかい方が大体学習がうまくいく)、必要なGPUを見積もる際には
1. batchサイズを1、データサイズも可能な限り小さくして動かしてみる。
2. 動くのであればbatch・データサイズをN倍にしてメモリ使用率を見ることで、maxどれくらいのbatch・データサイズが試せそうか調べる。
2. 動かないならそもそもそのマシンでは動かせないから他手段を考える。
というのが一番手っ取り早いと思います。

## この見積もりより小さいGPUメモリでも動かせる可能性がある

以上、GPUメモリの内訳を説明しましたが、 現在pytorchやdeepspeedなどのフレームワークではGPUを節約して実際のGPUサイズより大きいサイズのモデルを扱ったり、計算時間を短くするための工夫が様々提案・実装されています。なので、理解が深まって「GPUたりんな〜」というときは[hugging face](https://huggingface.co/docs/transformers/perf_train_gpu_one)や[pytorch](https://lightning.ai/docs/pytorch/stable/accelerators/gpu_intermediate.html)のドキュメントを読むことをお勧めします（、というか自分が読まなきゃいけないと感じてる）。

キーワード：Gradiant Accumulation、Gradient Checkpointing、不動小数点型の変更、ZeRO、マルチGPU、マルチノードにおける並列化手法

[^1]:(P.S. 本当は小さいデータセット作ってから検証進めてれば、メモリ不足であることはすぐ検証できたんですけどね笑。初学者の自分にはその発想すら思いついてませんでした。同じ悩みを持つ人が少しでも減ることを祈ります！)
Laravel のメール送信テストに Mailtrap を利用する

とある Laravel リポジトリのローカル開発環境で何故かメールが送信できず、設定の確認のため env.local 見てみると、Mailtrap というサービスを利用している模様。

サービス上でダミーのSMTPサーバーが用意され、それを使ってメールを送信すると画面上で送信したメールの内容を確認出来るという感じ。初めて見聞きしたサービスのため、使い方を調査した結果をメモ。
（※調査後、メールは無事にテスト出来ました。こういうのは README.md に残してて欲しい…）

# Mailtrap 公式サイト

https://mailtrap.io/

<br><br>

## アカウント作成

トップページ右上にある 「[Sign Up](https://mailtrap.io/register/signup)」ボタンをクリック。
Google, GitHub, Office 365 アカウントのいずれか、もしくはEメールにてアカウントが作成可能です。

Eメールだと**そのアドレスが利用可能かどうかの確認のためのメールが送信され、そのメールのリンクをクリックするという一手間が発生します**ので、可能であれば Google, GitHub, Office365 アカウントでの利用をオススメします。（大した手間ではないですけど…）

![createaccount.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/becfae8c-17d7-feaa-9bc6-3c858a065afc.png)


<br><br>

## ダミー SMTP サーバー情報を取得する

![mailtrap_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/df475bcb-7578-8fa6-55d5-b739fd0f3d63.png)

ログイン後、左メニューにある Email Testing リンクをクリック、もしくは画面中央あたりの Email Testing の「Start Testing」ボタンをクリック。（※画像赤枠のいずれか）

<br><br><br><br>

![myinboxdetail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/e1164dd6-6edb-15bc-7956-f1817235be50.png)


### 1. SMTP Settings タブををクリック

Email Address, Auto Foward, Manual Forward, Access Rights タブも気になるところですが、有料プランでないと使えないっぽいのでスルーしましょう

### 2. Integrations セレクトボックスで、Laravel 7+ を選択

色々な言語、フレームワークに対応しているようですが、PHPだけ謎の充実

### 3. copy ボタンをクリックして、クリップボードに .env の情報を保存

※画像にある僕のアカウントのSMTP情報は、Credentials を既に破棄しているので利用できませんよ！

<br><br><br>

## .env に登録

mailtrap からコピーした情報を、.env に貼り付ける。
既にパラメータが存在している場合は上書きしましょう。

```.env
MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
```

<br><br>

## Laravel キャッシュはしつこいので、念のためクリアしておく

```bash
php artisan config:clear
```

<br>

## Laravel でメール送信。結果が Mailtrap に記録される

### 雑な Laravel サンプルコード

```php
Mail::from('xxxxxxxxx@gmail.com')
    ->to('xxxxxxxxxx@gmail.com')
    ->send('テストメールだよ');
```

### Mailtrap 画面

正常にメールが送信されていれば、My Inbox 内の赤枠部分に表示されます。

![send.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/31e54c73-3fd8-dbac-112a-3cd9fca5d61b.png)

<br><br>

## フリーアカウントの注意事項

- 1時間に 100 通までしか送信できない
- InBox に 50 通までしか保存できない

一斉送信などの機能テストだとすぐ制限に引っ掛かりそうですが、通常の１通ずつ送るような機能テストだとおそらく問題になることはないかな、と感じました。

制限に引っかかるような使い方をされる場合は、MailHog コンテナを利用するといいと思います。
XcodeでiOSアプリのビルドをすると　Could not find module 'xxxxxxxxx' for target 'x86_64-apple-ios-simulator';　が発生する

# 状況
- Intel CPUのMacで作ったプロジェクトをApple CPUのMacでビルドした時にエラーが発生
- 今回はFrameworkをサブプロジェクトとして作成、取り込んだ（たぶん本体だけでも同じこと起こると思われる）

# エラーの内容
- 「x86_64（Intel CPU）のシミュレータを対象にしたモジュールがないぞ！」
- 作ったFramework（もしくは本体）はarm64（Apple CPU）でビルドしたけど、シミュレータはx86_64（Intel CPU）が起動した状態

# 対処
- 今回はFramework側の「Build Settings」->「Build Active Architecture Only」を"No"に変更して再ビルド
- 本体のプロジェクトも同様に"No"に設定されていることを確認
- 「Build Active Architecture Only」は、自分のMac（Intel or Apple）に合ったアーキテクチャ（x86_64 or arm64）のみビルドするか否かの設定
- Apple CPUだけでビルド、実行するときはarm64だけで良いはずだけど、なぜかシミュレータはx84_64が起動するため、両方作るように"No"を設定するしかない状況

![スクリーンショット 2023-05-22 9.34.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198158/6952440b-81b4-d8c6-3e15-4eac0df41acd.png)
Rocky9へのOpenpyxlのインストール[備忘録]

パッケージマネージャであるdnfを利用して、pipツールをインストールする。
```
>sudo dnf install python3-pip
```

インストールした、pipを利用して、Openpyxlをインストールする。
```
>sudo pip3 install openpyxl
```

インストールが完了したら、Pythonスクリプトにおいて、import文にて利用できる。
```
import openpyxl
```
「第一級関数」←どのへんが第一級なんだ？？

# 第一級関数とは
JavaScriptやPythonを学習していると、「第一級関数」というワードに遭遇することがよくあります。
ざっくりとした意味を説明すると、「第一級関数」とは、**単なる値として扱われる関数**を意味します。
例えば、JavaScriptでは関数を変数に格納できます。
```js
// 変数に関数を格納できる
const add = function(x, y){
    return x + y;
}

console.log(add(1, 2)); // 3と表示される
```
さらに、関数の引数に他の関数を取ることも可能です。これは一般的にコールバック関数と呼ばれます。
```js
function helloGoodbye(text) {
    text();
    console.log('さようなら');
}

function hello(){
    console.log('こんにちは');
}

// 関数の引数に関数をとる
helloGoodbye(hello) 
// こんにちは
// さようなら
```

この他にも関数を結果として返すことができたり、データ構造に格納できたりといった特性があります。

そんな第一級関数ですが、学習中の自分にとっては、先述のような機能がまとめて「第一級」と表現されていることが疑問でした。

関数を値として扱うことのどこが「第一級」なんだ。。？

![](https://storage.googleapis.com/zenn-user-upload/78674fd83f2f-20230521.png)

個人的に、言葉の意味と内容に繋がりを感じる方が、内容の記憶がしやすい質なので語源を調べました。


# 第一級関数の本質
どうやら「第一級」とは「**言語の全ての特性を自由に利用できる**」という点を指しているようです。

そもそも第一級関数とは、1960年代にコンピュータ科学者であるクリストファー・ストラッチーによって導入された表現で、「第一級の市民（functions as first-class citizens）」とも呼ばれています。

冒頭でも触れた通り、第一級関数は変数に代入できたり、関数の引数にできたり、さまざまな言語の特性を自由に利用できます。

その点を指して「第一級の市民」と表現するあたり、クリストファー・ストラッチーもなかなかブラックですね。

## おわりに
今回はJavaScriptの学習中に気になった「第一級関数」について深掘ってみました。
それぞれの概念が持つ意味を理解することで、より深くプログラミング言語を理解できます。
次に「第一級関数」を見かけた時は、ぜひその背後にある概念と考え方を思い出してみてください。
Scikit-Learnを使った欠損値補間と特徴量スケーリング

こんにちは！今日は、Scikit-Learnの`SimpleImputer`と`StandardScaler`を使ったデータの前処理について解説します。

## SimpleImputerでの欠損値補間

まず、`SimpleImputer`クラスを使って欠損値（NaN）を補間する方法について見ていきましょう。

```python
from sklearn.impute import SimpleImputer
import numpy as np
import pandas as pd

# サンプルのデータフレームを作成
df = pd.DataFrame({
    'A': [1, np.nan, 3, 4, 5],
    'B': [np.nan, 2, 3, 4, 5],
    'C': [1, 2, 3, np.nan, 5]
})

# SimpleImputerのインスタンスを作成
imputer = SimpleImputer(strategy='mean')

# 欠損値を補間
df_imputed = imputer.fit_transform(df)
```

これにより、欠損値がそれぞれの列の平均値で補間されます。

StandardScalerを使った特徴量スケーリング
次に、StandardScalerを使用して特徴量のスケーリングを行います。特徴量スケーリングは、各特徴量が平均0, 分散1となるようにデータを変換することです。これにより、様々な機械学習モデルのパフォーマンスが向上することがあります。

```python
from sklearn.preprocessing import StandardScaler

# StandardScalerのインスタンスを作成
scaler = StandardScaler()

# 特徴量のスケーリングを行う
df_scaled = scaler.fit_transform(df_imputed)
```

以上のように、Scikit-LearnのSimpleImputerとStandardScalerを使うことで、データの前処理を簡単に行うことができます。

これらの手法を実際のデータに適用する際は、データの分析と理解を深めるために各ステップでのデータの変化を観察することを強く推奨します。データ科学者としてのスキルを向上させるためには、ツールを使うことだけでなく、その背後にあるプロセスを理解することが重要です。

以上、ご覧いただきありがとうございました！
Windows11 + WSL2 + ghコマンドでexec: "xdg-open,x-www-browser,www-browser,wslview": executable file not found in $PATH　エラーが出る時

# 症状
Windows11 + WSL2 (Ubuntus 22.04)で`gh browse`を実行しようとしたときに、以下のエラーがでてブラウザが起動しない
```
exec: "xdg-open,x-www-browser,www-browser,wslview": executable file not found in $PATH
```

# スペック
- Ubuntu 22.04
- Windows11
- Github CLI v2.29.0

# 解決方法
```
sudo add-apt-repository ppa:wslutilities/wslu
sudo apt update
sudo apt install wslu
```

## 参照
- [Windowsで至高のターミナル生活を求めて（番外編：ArchLinux on WSL2）](https://www.asobou.co.jp/blog/web/archilinux-on-wsl2)
- [wslu Wiki](https://wslutiliti.es/wslu/install.html)
【PHP】PDO：「query」と「prepare/bindValue/execute」の使い分け①

## 初めに

- PHP/Mysqlを使用して１年ほど
- Symfony：ORM(doctorin)やLaravelを半年ずつほど

## 概要

PHPでDBを操作する際によくSQL文を記載して簡単に「query」する方法と

```php
$member = $db->query('SELECT * FROM user');
```

条件値を後から動的に「prepare/bindValue/execute」で設定する方法がありますが

```php
$stmt = $pdo->prepare("SELECT * FROM user WHERE id=:id");

$stmt->bindValue(':id', $id, PDO::hogehoge);

$stmt->execute();
```

各関数がどのような処理をしているのか理解しないで使用していました。。

①ではなぜ使い分ける必要があるのかにフォーカスを当てて確認したいと思います

## 1. ２通りのクエリ方法について

静的なSQL文を使用する機会や、SQL文を動的変えたい場合があると思います。

各用途ではどのようになっているのか、簡単に調べてみました。

:::note info
SQL文が静的→「query」を使用
SQL文が動的→「prepare/bindValue/execute」を使用
:::

上記から、「**動的**」＝SQL文に「**変動値**」が入るかで使い分けているイメージになります。

## 2. 使い分ける理由について

PHPの記述上、「query」でも変数を使用した動的なSQLが書けます。

```php
$sql = "SELECT * FROM user WHERE name='$name'";
$pdo->query($sql);
```

上記SQL文でプログラムは動きますが、推奨しない理由がありました。

:::note info
SQL文の中に変動値が入る場合、PHPの変数を直接連結してしまうと「**SQLインジェクション攻撃**」により悪意のあるSQLが実行されてしまう可能性がある。[参照リンク](https://blog.senseshare.jp/query-prepare.html)
:::

要するに、情報流出のリスクといった感じで解釈しています。

上記から「**プレースホルダ**」という仕組みを使い「**SQLインジェクション攻撃**」を防ぐクエリ方法が「**prepare/bindValue/execute**」になります。
※プレースホルダにも静的/動的がありますが説明の関係上省略しています。

ざっくりとした仕組みのイメージ

:::note info
「**PDO**」
　　**↳**「**プレースホルダ**」
　　　　　　　**↳**「**prepare/bindValue/execute**」
:::

「**prepare/bindValue/execute**」を使用した簡単な記述例

```php
$stmt = $pdo->prepare("SELECT * FROM user WHERE id=:id");

$stmt->bindValue(':id', $id, PDO::hogehoge);

$stmt->execute();
```

## まとめ

- 「**query**」でも動的クエリはできるけど「**prepare/bindValue/execute**」を使った方が良い。
- 実作業でも「変動値」があるSQL文がほとんどなので覚えた方が書きやすい。
- 書き方でどのようなリスクがあるのかは保守の観点やPGとして必要な感覚だと思うのでアンテナを張っていきたいです。
【PHP】配列操作処理における処理速度とメモリ使用量の参考

## はじめに
私は現在の携わる案件においてPHPを利用しています。
プログラムが動作する環境のデータ量に依存してパフォーマンスに課題が発生することが多く、
メモリー不足エラー「Fatal error: Allowed memory size of 〜」を目にすることが多いです。

課題改善をすべく、多量のデータ（要素）を扱うにあたり配列操作処理に観点を向け、
改善できることがないか調査を行ったところ、新しい学びがあったので本記事にまとめていきたいと思います。

## 本記事で扱う配列操作について
私の業務に実際に利用される頻度が高いものと今回の調査で学んだものを検証します。
1. foreach
1. array_＊＊＊関数(array_sumなど)
1. [ジェネレータ](https://www.php.net/manual/ja/language.generators.overview.php)→ **new**

## 検証
※今回は配列操作にあたり1~10万までの数字を要素とする配列を扱うものとします。
※例として全ての要素を足してみます。

### 1.foreach
```php
<?php

$start = microtime(true);
$start_memory = memory_get_usage();

function create_array() {
    $new_array = array();
    for ($i = 0; $i <= 100000; $i++) {
        $new_array[] = $i;
    };
    return $new_array;
};

$sum_num = 0;

foreach (create_array() as $key => $value) {
    $sum_num += $value;
};

$exec_time = microtime(true) - $start;
$used_memory = (memory_get_peak_usage() - $start_memory) / (1024 * 1024);

echo "処理時間:{$exec_time}s" . "\n";
echo "メモリ使用量:{$used_memory}MB" . "\n";

?>
```
- 処理時間:0.015480995178223s
- メモリ使用量:4.0039825439453MB

### 2.array_＊＊＊関数(array_sumなど)
```php
<?php

$start = microtime(true);
$start_memory = memory_get_usage();

function create_array() {
    $new_array = array();
    for ($i = 0; $i <= 100000; $i++) {
        $new_array[] = $i;
    };
    return $new_array;
};

$sum_num = array_sum(create_array());

$exec_time = microtime(true) - $start;
$used_memory = (memory_get_peak_usage() - $start_memory) / (1024 * 1024);

echo "処理時間:{$exec_time}s" . "\n";
echo "メモリ使用量:{$used_memory}MB" . "\n";

?>
```
- 処理時間:0.012201070785522s
- メモリ使用量:4.0039825439453MB

### 3.ジェネレータ
```php
<?php

$start = microtime(true);
$start_memory = memory_get_usage();

function create_array() { 
    for ($i = 0; $i <= 100000; $i++) {
        yield $i;
    }
};

$sum_num = 0;

foreach (create_array() as $key => $value) {
    $sum_num += $value;
};

$exec_time = microtime(true) - $start;
$used_memory = (memory_get_peak_usage() - $start_memory) / (1024 * 1024);

echo "処理時間:{$exec_time}s" . "\n";
echo "メモリ使用量:{$used_memory}MB" . "\n";

?>
```
- 処理時間:0.010108947753906s
- メモリ使用量:0.035301208496094MB

## まとめ
検証結果に多少の前後はあると思いますが、処理結果は以下のようになりました。
|処理|処理時間|メモリ使用量|
|---|---|---|
|foreach|0.015480995178223s|4.0039825439453MB|
|array_sum|0.012201070785522s|4.0039825439453MB|
|ジェネレータ|0.010108947753906s|0.035301208496094MB|

- 処理時間
    - ジェネレータ > array_sum > forearch
- メモリ使用量
    - ジェネレータ > array_sum = forearch

今のところ具体的な使用方法は思いつきませんが、
イメージとしては配列要素の順序吐き出しのようなものと思うので
CSVファイルなど大きい要素数を扱う機能において改善できるか検討してみようと思います。
MySQLのint型での誤解

## はじめに

`int(n)`という、int型にするときのカッコ内の数字の意味を誤解していました。
そして調べていくうちに、そもそも非推奨となっていることを知りました。
同じように誤解している方の目に止まればいいなと思います。

実行環境：mysql : 8.0.33

## int(n)は、n桁の整数という意味ではない　　

たとえば int(3) だと、-999〜999 が有効な範囲になると思っていました。
しかし実際には10000を入れてもちゃんと10000を取り出せます。

```sql
mysql> CREATE TABLE int_check1 (id int(3));
mysql> INSERT INTO int_check1 VALUES (10000);
mysql> SELECT * FROM int_check1;
+-------+
| id    |
+-------+
| 10000 |
+-------+
```

## int(n)は、nに何を指定しようとも有効範囲は変わらない

まず n = 3 の場合を、int型に格納できる最大数と最小数の境界で確認します。

```sql
mysql> INSERT INTO int_check2 VALUES (2147483647);
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO int_check2 VALUES (2147483648);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> INSERT INTO int_check2 VALUES (-2147483648);
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO int_check2 VALUES (-2147483649);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> SELECT * FROM int_check2;
+-------------+
| id          |
+-------------+
|       10000 |
|  2147483647 |
| -2147483648 |
+-------------+
```
:::note
MySQLでのintの有効範囲は -2147483648 〜 2147483647 です。
:::

このようにnが小さい場合でも、int型としての限界まで格納できます。


### nが有効桁数オーバーでも問題ない

次に、新しくデータ型を int(20) としたカラムを持つテーブルを作成して確認してみます。

```sql
mysql> CREATE TABLE int_check3 (id int(20));

mysql> INSERT INTO int_check3 VALUES (2147483647);
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO int_check3 VALUES (2147483648);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> SELECT * FROM int_check3;
+------------+
| id         |
+------------+
| 2147483647 |
+------------+
```

MySQLでのintの最大有効桁数は10桁です。
それをオーバーする20を指定しても問題なく、挙動は int(3) と変わりません。

## int(n)のnは、表示幅を指定している

新しくデータ型を int(3)、int(15) としたカラムを持つテーブルを作成して確認してみます。
MySQLでの表示の際に、自動でゼロフィルされるようにオプションとしてZEROFILL指定をします。

```sql
mysql> CREATE TABLE int_check4 (
    ->    id1 int(3) ZEROFILL,
    ->    id2 int(15) ZEROFILL
    -> );

mysql> INSERT INTO int_check4 
    -> VALUES (12, 12), 
    ->        (123, 123), 
    ->        (1234, 1234),
    ->        (2147483647, 2147483647);

mysql> SELECT * FROM int_check4;
+------------+-----------------+
| id1        | id2             |
+------------+-----------------+
|        012 | 000000000000012 |
|        123 | 000000000000123 |
|       1234 | 000000000001234 |
| 2147483647 | 000002147483647 |
+------------+-----------------+
```
このようにZEROFILLを使うと、表示幅を指定した影響が確認できます。

## 留意点

この件を調べる過程で公式ドキュメント[^1] [^2] を読み学んだ中で、上記に関連した内容を記載します。

**int(n)という表示幅指定と、ZEROFILL属性は非推奨になっており、今後サポートされなくなる。**

今回の誤解原因である機能は、近い将来に無くなるようです。
表示幅指定の機能削除はあくまで整数データ型のみですが、そもそも小数データ型の場合の (n) は、ちゃんと（表示幅ではない）桁数に関係しているようです。
MySQLで小数のデータ型を扱ったことがなかったので、そういった違いに気付きませんでした。
さらに同じ小数データ型でも、floatやdoubleなどの種類によっても意味が変わるようです。

一応、int(n)の表示幅の指定はアプリケーション側でも利用されているようなので、ZEROFILL属性を持たせなくても指定に意味があったみたいです。

しかし完全にint(n)の機能は削除されるので、今後は使わないのが正解なのでしょう。

**表示幅は、`LPAD()`関数を使えば、あとからでも指定できます！**




[^1]: https://dev.mysql.com/doc/refman/8.0/ja/numeric-type-syntax.html
[^2]: https://dev.mysql.com/doc/refman/8.0/ja/numeric-type-attributes.html
2023/5/22主にITとかセキュリティの記事

BRC-20とは？ビットコインのトークン規格がもたらす可能性と課題(5/20)
https://coinpost.jp/?p=459652

生成AIの課題　利用と規制のルール急げ(5/19)
https://www.nishinippon.co.jp/item/n/1089608/

攻撃を受けるAI　ブームの裏で広がるセキュリティーリスク(5/20)
https://news.yahoo.co.jp/articles/6cf97ebd656a5c13ce0933a469654d56b5a8773a?source=rss

無効な Google アカウントに関するポリシーを更新しました(5/19)
https://japan.googleblog.com/2023/05/GoogleAccount.html

Googleが2年間まったく使われなかった場合にアカウントを削除すると発表！ログインするだけで回避。対象には削除前に複数のメール通知(5/20)
https://s-max.jp/archives/1823453.html

ChatGPTで注目される生成系AI--有用だがリスクも、企業や学生のスタンスは？(5/20)
https://japan.cnet.com/article/35203938/

アップル、従業員のChatGPT利用制限か＝報道(5/20)
https://coinpost.jp/?p=461383

【ハワイ旅行者向け】公共USB利用によるジュースジャッキングに注意(5/20)
https://news.nicovideo.jp/watch/nw12605452

最高約270万円、OpenAIがChatGPTのバグハンティングに懸賞金(5/20)
https://news.yahoo.co.jp/articles/4324022aa01a3ec960fa0898be0111de039c46c6?source=rss

Apple、Apple Watchを利用したMacのロック解除でログインできない問題や再起動後のBluetoothキーボードの接続が遅い問題などを修正した「macOS 13.4 Ventura (22F66)」をリリース。(5/19)
https://applech2.com/archives/20230519-macos-13-4-ventura-build-22f63-now-available.html

盛岡市中央卸売市場になりすまし外部へメール　サーバー攻撃受けて件数や被害を確認中　公式ホームページを閉鎖(5/20)
https://news.yahoo.co.jp/articles/e44aff64d05362e422d979eeb1f474d41bfaa4e7

黒塗りの個人情報が一時閲覧可能状態に　本港区エリア利活用のＨＰ公開めぐり知事陳謝　鹿児島(5/19)
https://www.fnn.jp/articles/-/530679

「トロイの木馬に感染しています」　福岡県大牟田市でパソコンのサポート詐欺未遂事件が発生(5/18)
https://www.nishinippon.co.jp/item/n/1089494/

ラザルス　ジェフ・ホワイト著
北朝鮮ハッカーの実態描く(5/20)
https://www.nikkei.com/article/DGKKZO71147720Z10C23A5MY6000/

「サイトの利用料が未払いに…」ニセ電話詐欺で佐賀市の30代男性が280万円被害　佐賀南署発表(5/20)
https://news.yahoo.co.jp/articles/31e2aaa6ac46b5f665c43c1a1bee06a246927279?source=rss

サイバー攻撃か 県警が捜査　G7サミット開催の広島市ホームページで通信障害(5/20)
https://news.yahoo.co.jp/articles/1d9d8f21874a78d6d5e16ea61f35aa283fa67487?source=rss

北朝鮮ハッカー集団は暗号資産を盗み、国民は種イモを盗む(5/20)
https://news.nicovideo.jp/watch/nw12603173
SQLインジェクションとは

# SQLインジェクションとは
SQLインジェクションとは***第三者がSQLコマンドを悪用してのDBへ不正にアクセスし、情報を改ざんしたりするサイバー攻撃***のことです。

# 対策
対策は以下のやり方があるみたいです。

|対策|
|-|
|SQL文の組み立ては全てプレースホルダで実装する{
|SQL文の組み立てを文字列連結により行う場合は、エスケープ処理等を行うデータベースエンジンのAPIを用いて、SQL文のリテラルを正しく構成する。|
|ウェブアプリケーションに渡されるパラメータにSQL文を直接指定しない。|
|エラーメッセージをそのままブラウザに表示しない。|
|データベースアカウントに適切な権限を与える。|

> 引用　https://www.jbsvc.co.jp/useful/security/sql-injection.html#:~:text=SQL%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%AF%E3%80%81%E7%AC%AC,%E3%81%95%E3%82%8C%E3%82%8B%E3%82%B1%E3%83%BC%E3%82%B9%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

# SQLインジェクションの実演
こちらの動画のハッキングを紹介されていたのでよかったら見てください。

https://www.youtube.com/watch?v=DFAB7nYGQAQ

# SQLインジェクションを扱っているUdemy

https://www.udemy.com/course/backend-tutorial/

# N + 1問題
DBで同じ問題で扱われます。よかったら目を通しておいてください。

https://qiita.com/Hashimoto-Noriaki/items/00107984dc6fbd929f7f



# 資料

https://www.jbsvc.co.jp/useful/security/sql-injection.html#:~:text=SQL%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%AF%E3%80%81%E7%AC%AC,%E3%81%95%E3%82%8C%E3%82%8B%E3%82%B1%E3%83%BC%E3%82%B9%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

https://railsguides.jp/security.html#sql%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3

https://www.youtube.com/watch?v=TFCQ2_gPQes
Flutterの学習でお世話になった・おすすめのサイト一覧

## Flutterとは
モバイル開発用のDartというプログラミング言語のフレームワークになります。
一番の特徴は一つのソースコードでiOSとAndroid両方向けに開発することができます。
クロスプラットフォーム開発を実現できるフレームワークとしては、Flutter以外にもReact Nativeが有名で、弊社でもモバイルアプリ開発ではReact Nativeを主に利用しています。

最近ではモバイル開発以外にもWebアプリ、Mac / Windowsのデスクトップアプリにも対応しており、JavaScript（TypeScript）一強だったフロントエンド開発に新しい選択肢が出てきました。

そんなFlutterを学習する時に自分がお世話になったサイトや、これから学習を始める人におすすめしたいサイトを紹介します。

## サイト一覧
#### 1. まずは公式ドキュメント
学習を始めるならまずは公式を見るべきかなと思います。
ありがたいことに日本語翻訳した専用のサイトもあります。
チュートリアルでアプリを作るので一通りやってみることをお勧めします。

https://flutter.ctrnost.com/

#### 2. Dart入門
Flutterあくまでもフレームワークなので、元となってる言語のDartの基礎的な内容も学習した方が良いかと思います。
Qiitaでまとめてくださってる方がいました。

https://qiita.com/teradonburi/items/913fb8c311b9f2bdb1dd

#### 3. Riverpodの学習におすすめ！
Flutterの状態管理で使われるRiverpodの学習ができます。
自分もこちらの本で学習しました、とても分かりやすくておすすめです。

https://zenn.dev/riscait/books/flutter-riverpod-practical-introduction

#### 3. Flutter大学さんのZenn・Qiitaの記事や本
こちらは「Flutter大学」というコミュニティが提供している本で、Flutterの環境構築から基礎的な内容まで分かり易く説明してくれます。
またYoutubeにも動画がたくさんありますので、おすすめです。

https://zenn.dev/kboy/books/ca6a9c93fd23f3

https://flutteruniv.com/

#### 4.Flutter OsakaさんのYoutube
こちらは「Flutter Osaka」というコミュニティのYoutubeから見ることができます。
リンクに貼っている動画はFlutterの書き方や基礎的な内容には触れませんが、実践的なスマホアプリの開発とSupabaseの使い方を学習することができます。
その他にもYoutubeの別の動画でハンズオン形式の講義がありますので、一通り見てみるのをおすすめします！

https://www.youtube.com/live/5nDzDEsqcIU?feature=share

https://flutter-osaka.netlify.app/

#### 5. 株式会社ゆめみさんの研修課題
株式会社ゆめみさんのFlutterの研修課題がQiitaに公開されてました。
こちらも環境構築から始めますので、初学者の方も取り組める内容となってます。

https://qiita.com/blendthink/items/c2d6bdc4ebb8bbe8f666


## その他学習するためにしたこと
#### 1. 自分でアプリを1から作ってみる
正直これが一番学習になります。
日常で使えそうなアプリや面白そうなアプリ、もしくは考え付かなかったら有名なアプリを真似てみるのもありです。
ちなみに自分はTwitterを完全に再現したアプリを作りながら学習しました。

サーバーからデータを取得するためにAPIの連携方法を調べてみたり、開発が進むにつれて規模が大きくなってきたのでアーキテクチャーについて学習してみたり、状態管理ツールを導入してみたりと調べつつ作っていきます。
ただ現在はTwitter APIが有料化したので今では難しいです...やるなら別のアプリが良いかもしれないですね。

アプリを作る過程でわからない事とか技術的に難しい事に対して自分で調べながら進めていくのが効率的で頭に入りやすいです。

#### 2. Flutterの講義資料を作る
一通り学習したらアウトプットとして講義資料を作ってみるのをおすすめします。
自分は社内向けに講義資料を作りました。
他の人に教えるためにFlutterの概念や知識を言語化する必要があるため、曖昧だったところの理解が深まります。
講義資料という形じゃなくても、QiitaとかZennに投稿するのでも全然良いです。

#### 3. React Nativeとの違いを知る
同じクロスプラットフォーム開発のReact Nativeとの違いやメリット・デメリットを知るのも良いかと思います。
パフォーマンス面ではFlutterの方が優れてるかもしれませんが、作るアプリや一緒に開発するメンバーによってはFlutterよりReact Nativeの方が最適な時もあります。
両者の違いを理解して最適な技術選定ができるようになっておくと良いかと思います。
脆弱性とそのリスク

## 脆弱性：vulnerabilityとは

コンピューターシステムやソフトウェアにおいての、セキュリティ上の欠陥や弱点のこと

### 原因

・ソフトウェアの設計上の欠陥
・プログラミングエラー
・セキュリティポリシーの不備など

### 脆弱性によるリスク


- システムへの不正アクセス
攻撃者が脆弱性を利用し、システムやネットワークに不正に侵入できる
→データの盗み見、改ざん、削除などをされる可能性がある

- サービスの停止や妨害
脆弱性を悪用する攻撃をされると、システムやアプリケーションがクラッシュしたり、正常な動作を妨害されたりすることがある
→サービスの提供が中断される可能性がある

- 機密情報の漏洩
攻撃者は機密情報（パスワード、個人情報、営業秘密など）を入手する可能性があり、漏洩された情報は、不正利用や詐欺行為に悪用されるかもしれない
virsh-install時にpermission deniedとなる場合

kvmにおいてvirsh-installを行った場合、permission deniedが出力される場合がある

```
インストールを完了できません: '内部エラー: process exited while connecting to monitor: 2016-05-05T08:57:02.803493Z
qemu-system-x86_64: -drive file=/var/lib/libvirt/images/winxp.raw,format=raw,if=none,id=drive-ide0-0-0:
Could not open '/var/lib/libvirt/images/winxp.raw': Permission denied'
```

## isoをrootディレクトリに置いてはいけない
ubuntuならば、一般ユーザーを作成して、その配下にisoを配置しなければならない。


## QEMUの設定
/etc/libvirt/qemu.confを、以下のように３行編集する。
```
#       user = "qemu"   # A user named "qemu"
#       user = "+0"     # Super user (uid=0)
#       user = "100"    # A user named "100" or a user with uid=100
#
user = "ユーザー名"　←「ユーザー名」は普段使う一般ユーザーのユーザー名に変える。

# The group for QEMU processes run by the system instance. It can be
# specified in a similar way to user.
group="libvirt"　←グループをlibvirtに変える。

# Whether libvirt should dynamically change file ownership
# to match the configured user/group above. Defaults to 1.
# Set to 0 to disable file ownership changes.
dynamic_ownership = 1　←コメントアウトを解除。
...
```

## libvirtの設定
```
# nano /etc/libvirt/libvirtd.conf
```
```
...
unix_sock_group = "libvirt"
...
unix_sock_ro_perms = "0777"  # set to 0770 to deny non-group libvirt users
...
unix_sock_rw_perms = "0770"
...
auth_unix_ro = "none"
...
auth_unix_rw = "none"
...
```

ユーザー周りの権限も設定
```
sudo usermod -G -a kvm "username"
sudo usermod -G -a libvirtd "username"
```


libvirtdデーモンを起動する。
```
# systemctl start libvirtd.service
# systemctl enable libvirtd.service
```



##### 参考サイト
https://www.archlinux.site/2016/05/virt-managerroot.html
https://www.dedoimedo.com/computers/kvm-permission-denied.html
MySQLコンテナ内で日本語が入力できない

## 動作環境
- Windows11
- Docker version 20.10.23

## 詰まったこと

データベースの学習のためにDockerにてMySQL環境を構築しました。ところが、コンテナに入った状態でコマンドライン上に日本語を入力してエンターを押すと、入力した日本語が消えるといった事象に出くわしました。日本語のサンプルデータを扱えなくて困りました。。


## 解決策

もともとは`compose.yml`でイメージを指定して環境構築していましたが、ビルド時にパッケージをインストールする処理が必要になるので`Dockerfile`も用意します。

ポイントは以下の通りです。
1. イメージに`mysql:8.0-debian`を指定
    `apt-get`コマンド（APTパッケージ管理システム）を使用するには、ベースイメージに`Debian`や`Ubuntu`を指定する必要があります。
    `mysql:8.0`では`apt-get`が使えず、ビルド中にエラーになります。

2. `locales-all`のインストールコマンドを記述
    ロケールとは国・地域等によって違うタイムゾーンや書式等をシステムに伝える機能です。
    ロケールを日本語化するためにパッケージのインストールが必要です。

3. 環境変数`LANG`に`ja_JP.UTF-8`を設定
    これで実際にコンテナ内のロケールが日本語化されます。

```Dockerfile
FROM mysql:8.0-debian

RUN apt-get update \
    && apt-get install -y \
        locales-all \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \

ENV TZ=Asia/Tokyo
ENV LANG ja_JP.UTF-8
```

`compose.yml`の内容です。

```yml
version: "3.9"

services:
  db:
    build:
      context: .
      dockerfile: ./docker/db/Dockerfile
    restart: always
    ports:
      - 3306:3306
    env_file:
      - ./docker/db/.env
    volumes:
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/init.sql:/docker-entrypoint-initdb.d/init.sql
```

ディレクトリ構成も載せておきます。

```
.
├── .gitignore
├── compose.yml
└── docker
    └── db
        ├── .env
        ├── Dockerfile
        ├── data
        │   └── .gitkeep
        ├── init.sql
        └── my.cnf
```

## あとがき
学習環境として利用していたので、コマンドやファイル等、今回の件と関係ないものも色々ありますがご了承ください。
間違っている部分やアドバイス等がありましたら、ご教授いただけますと幸いです。
AWRスナップショットからリアルタイムSQL監視レポートの取得とイベントを仕掛けて特定SQL IDを監視対象とする方法

実行計画のどの部分が遅いか分析するために役立つリアルタイムSQL監視ですが、11gR2まではメモリ上からなくなってしまうとリストから消えてしまい取得し直し。また、シリアル実行で実行時間が短いSQLの場合はmonitorヒント句が必要でした。
ここでは、12cより使用可能なAWRからのリアルタイムSQL監視レポートの取得方法と、ヒント句を使わず特定SQL IDのみmonitor指定する方法について記載します。

# 1. AWRからのリアルタイムSQL監視レポートの取得方法
前提として対象SQLのSQLIDはわかっているものとします

1.dba_hist_reportsから該当のSQLのレポートが取得されているか確認

```
ALTER SESSION SET NLS_DATE_FORMAT='YYYY/MM/DD HH24:MI:SS';
SELECT snap_id,report_id,period_start_time
FROM 
    dba_hist_reports 
WHERE 
    component_name = 'sqlmonitor' 
    AND period_start_time BETWEEN To_date('2023/05/18 00:00:00','YYYY/MM/DD HH24:MI:SS') AND To_date('2023/05/20 05:00:00','YYYY/MM/DD HH24:MI:SS') 
    --key1にはSQLIDを指定します
    AND key1='bk95v91hn3dps'
ORDER BY 1
;


   SNAP_ID  REPORT_ID PERIOD_START_TIME
---------- ---------- -------------------
       954       8886 2023/05/18 01:21:29
       955       8894 2023/05/18 02:21:30
       956       8904 2023/05/18 03:21:31
       957       8913 2023/05/18 04:21:01

```



2.DBMS_AUTO_REPORT.REPORT_REPOSITORY_DETAILにreportidを指定してリアルタイムSQL監視レポートを出力する

```
set pages 0 linesize 32767 trimspool on trim on long 1000000 longchunksize 10000000

--dbms_auto_report.report_repository_detailの
--第１引数にはREPORT_IDを指定
--第２引数にはレポートのタイプ、'XML'、'TEXT'、'HTML'、'EM'または'ACTIVE'を指定（デフォルトはXML）。'EM'または'ACTIVE'の場合はアクティブなHTMLレポートになります
select dbms_auto_report.report_repository_detail(8886, 'TEXT') report from dual;
```

# 2. イベントを仕掛けて特定のSQLIDを監視対象として指定する

リアルタイムSQL監視のモニタリングされる条件
・並列実行
・少なくとも5秒のI/OまたはCPU時間のリソース消費
・MONITORヒント句が付与されている

このため、実行時間が短いシリアル実行のSQLについては、MONITORヒント句を利用することが多いのですが、いつもヒント句を入れられるわけではありません。
その場合の方法としてイベントを仕掛けて特定のSQLIDを監視対象として指定する方法があります。

```
ALTER SYSTEM SET EVENTS 'sql_monitor [sql:my sql_id] force=true';
```

# 参考
How To Get Historical SQL Monitor Report For SQL Statements (Doc ID 2555350.1)

Real-Time SQL Monitoring: a MUST for SQL Tuning
https://blogs.oracle.com/coretec/post/oracle-database-real-time-sql-monitoring-one-of-the-most-important-tools#8
Spring InitialzrでSpringBootのプロジェクトを5分で作成する

## Spring Initialzrの公式ページにアクセス（00:10）

https://start.spring.io/

## 任意のビルドツールや言語、バージョンを選択（01:30）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035894/34137ce6-8ff3-1d9e-6339-8b1c533fb2e9.png)

## その他、追加したいプラグインがある場合は、下記ボタンから追加（02:30）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035894/efb128de-e915-210a-03cd-45501f580229.png)

* 今回は下記のプラグインを追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035894/2c64d0ee-eb8f-144a-a5ab-ae84e9f8e006.png)

## 下部のGENERATEをクリック（03:00）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035894/c0ffce26-e83c-71df-49d2-3017571f037a.png)

数秒でzipファイルがダウンロードされます。

## zipを解凍して、任意のフォルダに配置する（04:00）

## Intellijやeclipceから解凍したファイルを開く（04:30）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035894/c04fa859-beb3-1dd8-c7bc-51591db63c83.png)


## ビルドが成功すれば準備完了（05:00）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035894/8e0b5365-2258-1244-d673-f15bffcb091c.png)
React クラスコンポーネントのアンチパターン【初心者向け解説】

Reactを使って開発を進める際、特定の方法が問題を引き起こす可能性があることを理解することは重要です。
これらは「アンチパターン」と呼ばれ、避けるべきプラクティスを示しています。
今回は、Reactのクラスコンポーネントに関連したアンチパターンをいくつか紹介します。

## 1. 不要なStateを持つ

Reactのクラスコンポーネントにおいて、propsから直接導出できる値をステートとして保持することは避けるべきです。ステートは通常、時間経過に伴って変更が発生するデータを表現するためのものです。

**アンチパターン:**

```javascript
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: this.props.name,
    };
  }

  //...
}
```

## 2. 直接ステートを変更する

Reactのステートは、`this.setState()`メソッドを通じて間接的に変更するべきです。これはReactがステートの変更を追跡し、再レンダリングを行うために必要です。

**アンチパターン:**

```javascript
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  incrementCount() {
    this.state.count += 1; // 間違い！
  }

  //...
}
```

## 3. ライフサイクルメソッドの誤用

ライフサイクルメソッドは特定のタイミングで実行されるものですが、それぞれが持つ特性を理解せずに使用すると予期しない問題を引き起こすことがあります。たとえば、`componentDidUpdate`内でステートを更新する場合、無限ループを引き起こす可能性があります。

**アンチパターン:**

```javascript
class MyComponent extends React.Component {
  //...

  componentDidUpdate() {
    this.setState({ count: this.state.count + 1 }); // 間違い！
  }

  //...
}
```

## まとめ

これらのアンチパターンは、Reactのクラスコンポーネントを使用する際に避けるべき一部の点を示しています。これらを理解し、適切なパターンを採用することで、バグの少ない、保守性の高いコードを書くことができます。
Android PageObjectデザインパターンについて - ページ部

# 概要
本記事は、デザインパターンの一種である"PageObject"パターンを紹介します。
おそらく、以下の二部に分かれますと思います。
　・ページ部
　・シナリオ部

また、今回使用する言語はKotlinを想定しています。

# PageObjectとは？
Seleniumの公式docを貼り付けておくのでそちらを参照してみてください
↓↓
https://www.selenium.dev/ja/documentation/test_practices/encouraged/page_object_models/

一応自分なりに解説してみると...。
アプリケーションは様々な画面から構成されていますよね。
例えばショッピングサイトでは、ログイン画面、ユーザー情報画面、商品画面など...。
挙げれば果てしないですが、とにかく様々な画面で構成されています。

PageObjectでは、それらの各ページを1つのオブジェクトとして捉えるのです。
今の段階では、何言ってるのやら...という感じかもしれませんがコードを読めばある程度は想像できます。
また、PageObjectは以下の2つのファイルに分かれます。
・ページ部
・シナリオ部

各部がどういった役割なのかは下に記載します。

# 考え方
今回は、お試しなので簡単なログイン画面にPageObjectを適用しステップバイステップで考えてみましょう。
① ファイルを用意する
以下2つのファイルを用意してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355973/d1b7bdcd-7bbf-7abe-ecd4-a365a5323c66.png)

★LoginPageOperations(ページ部)
　　→　ログインページで行えるユーザー操作をカプセル化して記載します。例えば、ログインするためにユーザーは必ずパスワードを入力しますし、その後にログインボタンを押しますよね。
そういったユーザーが行う処理を記載します。

★LoginPageTests(シナリオ部)
　　→　LoginPageOperationファイルにて用意した処理を呼んでテストシナリオを記載するファイルです。
後でコードで解説するためサラッとですが、ページ部から処理を呼んでユーザーが行う操作をシナリオ化します。

2. LoginPageOperationsを記載する
``` Kotlin
class LoginPageOperations {
    /**
     * Emailアドレス入力機能
     * @param email セットするEmailアドレス
     * @return LoginPageオブジェクト
     */
    fun setEmail(email: String) : LoginPageOperations{
        Espresso.onView(ViewMatchers.withId(R.id.edittext_email)).perform(
            ViewActions.replaceText(email)
        )
        return this
    }

    /**
     * Password入力機能
     * @param password セットするパスワード
     * @return LoginPageオブジェクト
     */
    fun setPassword(password: String) : LoginPageOperations{
        Espresso.onView(ViewMatchers.withId(R.id.edittext_password)).perform(
            ViewActions.replaceText(password)
        )
        return this
    }

    /**
     * ログイン機能
     *
     * 本テストは事前にEmail及びPasswordがセットされていることが前提である。
     * そのため、必ずテスト関数 : setEmail() & テスト関数 : setPassword()をコールすること
     *
     * @return LoginPageオブジェクト
     */
    fun login() : LoginPageOperations{
        //ログインボタン押下
        Espresso.onView(ViewMatchers.withId(R.id.LoginButton))
            .perform(ViewActions.click())
        return this
    }
}
```
ここで注目してほしい点があります。
* メソッドの分け方
上記のコード内には
setEmail => Emailアドレスのセット処理
setPassword => パスワードのセット処理
login => ログイン処理
上記3つの処理がありますね。
これは、ユーザーが行える操作単位に分割したものです。
ユーザーがログインする為には、メールアドレスのセット→パスワードのセット→ログイン実行の3ステップが必要なわけです。
これらをシナリオ側から呼ぶことでテストを実行していきます。

* 各メソッドの戻り値
戻り値を見てみると全て
```kotlin
return this
```
としていますよね。これはメソッドチェーンというものを行うためです。
後のシナリオコードを読めば分かりますが非常に可読性が優れています。
後で詳しく記載しますが、以下のようにシナリオコードを書けます。
```kotlin
loginPageOperation
    .setEmail("メアド")
    .setPassword("パスワード")
    .login()
```
メアドセット→パスワードセット→ログインを順番でやっていることが分かりますよね。
こういった書き方が出来るのがPageObjectの特徴でもあります。
ここでページ部については完成ですね。
次は、シナリオ部になります。
ページ部で書いたコードを呼んでテストを行っていきます！
【Delphi】配列 VS リスト 処理速度対決

https://qiita.com/rait0/items/14e71ebd8ae26b13bbab

上記記事のDelphi版です。

# 知りたいと思った理由
最近Delphiに入門したため。

# 環境
- Rad Studio 11.3
- Windows 10
- VCLアプリケーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3441187/d483b2cc-3c4f-4745-bb8c-f37af3d3eb99.png)

# 条件
- 1億回の書込と読込を計測
- 計測は5回平均
- 読込は、forとforeach(for in)それぞれ計測

# 結果(ms)
|| リスト | 配列 | 差分(リスト-配列)|
|:-:|:-:|:-:|:-:|
|書込| 2:430  | 0:216  | 2:224  |
|For読込| 0:234  | 0:197  | 0:037  |
|Foreach読込| 0:376  | 0:278  | 0:098  |


# 所感
リストの読み込みが、意外と高速だと思いました。
Delphiの書き方がおかしかったら、ご指摘ください。

# 次回
- Delphiで良く見かけるデータセットも計測
- TDictionaryを加えて、コレクションからの検索も計測

# 使用したソースコード
```pascal:検証ソース
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    const TestCount = 100000000;  // 1億回試行
    procedure WriteLog(const aStartTime: TTime; const aEndTime: TTime; const aMsg:string);
  public
    { Public 宣言 }
  end;

var
 Form1 : TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  arrayTestData : Array Of Integer;
  startTime : TTime;
  endTime : TTime;
begin

  { Array }
  { 準備 }
  System.SetLength(arrayTestData, TForm1.TestCount);

  { 書き込み }
  startTime := System.SysUtils.Time();
  for var i := System.Low(arrayTestData) to System.High(arrayTestData) do
    arrayTestData[i] := i;
  endTime := System.SysUtils.Time();
  Self.WriteLog(startTime, endTime, '書込時間 array');

  { 読み込み(for) }
  startTime := System.SysUtils.Time();
  for var i := System.Low(arrayTestData) to System.High(arrayTestData) do
    var _ := arrayTestData[i];
  endTime := System.SysUtils.Time();
  Self.WriteLog(startTime, endTime, '読込時間(for) array');

  { 読み込み(foreach) }
  startTime := System.SysUtils.Time();
  for var d in arrayTestData do
    var _ := d;
  endTime := System.SysUtils.Time();
  Self.WriteLog(startTime, endTime, '読込時間(foreach) array');

  { List }
  { 準備 }
  var listTestData := TList<Integer>.Create();

  { 書き込み }
  for var i := 0 to TForm1.TestCount - 1 do // LowとHigh使えない？
    listTestData.Add(i);
  endTime := System.SysUtils.Time();
  Self.WriteLog(startTime, endTime, '書込時間 list');

  { 読み込み(for) }
  startTime := System.SysUtils.Time();
  for var i := 0 to listTestData.Count - 1  do // LowとHigh使えない？
    var _ := listTestData[i];
  endTime := System.SysUtils.Time();
  Self.WriteLog(startTime, endTime, '読込時間(for) list');

  { 読み込み(foreach) }
  startTime := System.SysUtils.Time();
  for var d in listTestData do
    var _ := d;
  endTime := System.SysUtils.Time();
  Self.WriteLog(startTime, endTime, '読込時間(foreach) list');


end;

procedure TForm1.WriteLog(const aStartTime: TTime; const aEndTime: TTime; const aMsg:string);
begin
  var durationTime := FormatDateTime('hh:nn:ss:zzz', aEndTime - aStartTime);
  Memo1.Lines.Add(Format('%d件 %s | %s',[TForm1.TestCount, aMsg, durationTime]));
end;

end.

```

以上
【備忘録】ファイルやフォルダあれこれ

# はじめに
T4exf63です。
新しい現場に行くと一番最初に困ることランキング1位の

<b><font color="Red">『ファイルやフォルダのディレクトリがわからない問題！』</font></b>

「〇〇に保存しといて」と言われたのにそんなディレクトリ見つからない！とか
「××ってフォルダに作っといて」と言われたら××ファイルが何十個もある！とか
果ては、現場の人なのにディレクトリ構成を知らないせいでいじっていいディレクトリがわからない

などなどディレクトリ絡みで苦しめられたこと皆さんあるはずです。

そうならない様に個人的によく使うディレクトリ絡みのコマンドをメモしておきます。


# 本題
今回は2つです。
・配下のディレクトリを調べるコマンド
・ファイル容量を見るコマンド

## ・配下のディレクトリを調べるコマンド
・windowsの場合１

```cmd
tree >aaaaa.txt
```
・windowsの場合２
```cmd
dir /s /b /ad >bbbbb.txt
```
※基本的にどちらでも大差ないが、体感だとtreeコマンドの方が処理が早いし、容量も小さい
dirコマンドはフルパスで欲しいとき使うといい（フルパスだから加工するとき楽）

・Linuxの場合
```linux
find / -type d >ccccc.txt
```

## ・ファイル容量を見れるコマンド
・windowsの場合
```linux
dir /s
```
※結構時間かかるから裏で動かす方がよさそう
また、ファイル数も一緒に出してくれる

・Linuxの場合
```linux
du -sh
```



# おわりに
私は緊張しいなんで新天地に行っていろいろ立て込んでいると、こう言う簡単なコマンドやオプションほど忘れてしまって咄嗟に出ないんですよね。
そしてインターネットで調べようにも、来てすぐだとインターネットが使えなかったり前に見たサイトが消えててわかりづらいサイトしか残ってなかったり・・・。
もっと、いろいろ書いた方が良いんでしょうが、パっと思い出したのが２つだけだったので簡素な内容となってます。
（使えそうなコマンドとか思い出したら追加するかも？）
便利なコマンドを知っていたら教えてください。

記：2023年5月21日
【Linux】ファイルの差分を取得する方法


## はじめに

以下のような2つのファイルがある場合に内容を比較して変更箇所のみ取得する方法について記載します。  

```old.txt
変更なし
変更なし
変更なし

```

```new.txt
変更なし
変更なし
変更あり
追加
追加
追加

```

## `diff`コマンド

`diff`コマンドを使用して次のように実行することで変更箇所のみ取得できます。  

```terminal
$ diff --old-line-format='' --unchanged-line-format='' --new-line-format='%L' old.txt new.txt
変更あり
追加
追加
追加
```

- `--old-line-format`
  1番目のファイルだけにある行の出力に使用するフォーマットを設定する。  
- `--unchanged-line-format`  
  両方のファイルに共通な行の出力に使用するフォーマットを設定する。  
- `--new-line-format`  
  2番目のファイルだけにある行の出力に使用するフォーマットを設定する。  
- `%L`  
  行頭などに何もつけず1行ずつ出力する。
  `+%L`とすると以下のようになります。  

  ```terminal
  $ diff --old-line-format='' --unchanged-line-format='' --new-line-format='+%L' old.txt new.txt
  +変更あり
  +追加
  +追加
  +追加
  ```

  また`%l`とすると以下のようになります。  

  ```terminal
  $ diff --old-line-format='' --unchanged-line-format='' --new-line-format='%l' old.txt new.txt
  変更あり追加追加追加
  ```

## `comm`コマンド

`comm`コマンドを使用して次のように実行しても変更箇所のみ取得できます。

```terminal
$ comm -13 old.txt new.txt
変更あり
追加
追加
追加
```

- `-13`  
  `old.txt`のみに含まれる行と両方のファイルに含まれる行を出力しないようにする。  
  すなわち変更や追加があった行のみ出力する。  

ただしファイルが`sort`されていない正しく比較できず以下のようなエラーが出力されます。  

```terminal
comm: file 2 is not in sorted order
comm: input is not in sorted order
```

これを出力させないようにするには`sort`してから`comm`するか`sort`する必要のない場合には以下のようにオプションを付けます。

```terminal
comm --nocheck-order old.txt new.txt
```