OmniAICreator/Qiita-1.07M huggingface dataset:
【コピペで簡単】スプレッドシートをCSVにしてGitHubへプッシュする

# はじめに
スプレッドシート上に羅列されたデータがあり、それをCSVに変換してGitHubへあげたかったので作りました

# 必要なもの
GitHubのアクセストークン(リポジトリ操作権限を持たせること)
GitHub上のリポジトリ(最初のコミットをしておき、画像の部分を覚えておく)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/d7c5723f-d945-9575-5d38-fbf0e1edf62b.png)

# 手順
1. スプレッドシートを作成する

1. データを入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/01df7c29-d952-725a-c87d-6ad02408dddf.png)

1. Apps Scriptを作成する
↓画像のボタンをクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/8876bed4-045f-927e-85ed-7c7dc83a9f4f.png)
するとこんな感じの画面になる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/5eebb430-c32c-5117-db40-24927535d230.png)
中身は全て消しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/320f27b9-63b5-b76a-948a-9102a6ce1cd4.png)

1. コードをコピペする
下記リンクから
https://github.com/OR-Sasaki/MasterdataPresenter/blob/main/masterdata_presenter.gs
このコピーマークを押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/808038b7-4c1a-0dbf-6865-83c91b564537.png)
中にペーストする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/f4299ac6-6ef9-63d0-53fe-9036b7df3e60.png)

1. 設定する
画像の設定ボタンを押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/2b130420-75bd-91b1-0b14-ca9a78a84316.png)
下にスクロールすると画像のような設定項目がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/1115173d-8332-bb4d-6363-e2d75101ccd1.png)
「スクリプトプロパティを追加」ボタンを押して、「GITHUB_TOKEN」と「REPOSITORY_NAME」というプロパティを追加する
:warning: 保存ボタンを押すのを忘れない
GITHUB_TOKEN => "必要なもの"で用意したアクセストークン
REPOSITORY_NAME => "必要なもの"で用意したリポジトリの赤線部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/29671c96-d8c8-95d8-b6c7-22a9db269617.png)

1.インポートする
スプレッドシートをリロードするとボタンが現れる(すぐには表示されないので、リロードしてから10秒ぐらい待つ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/20649d67-268d-dd8f-f917-ca788792957f.png)
マスタインポート => 実行ボタンを押すとインポートが開始される
認証を求められた場合は承諾する
分からない人は以下参照
https://tonari-it.com/gas-script-approval/
GitHubで確認するとcsv下にプッシュされていることが分かる

# 補足
コードの上の方に設定項目を用意しています
|項目|説明|
|---|---|
|useDirectory|ルートディレクトリを設定するか|
|directoryName|ルートディレクトリの名前|
|doSplice|インポートしない行を設定するか(説明のための行など)|
|spliceStartAt|インポートしない行のはじめの位置。1行目から0, 1, 2と数える|
|spliceEndAt|インポートしない行の終わりの位置|

# 参考
https://int128.hatenablog.com/entry/2017/09/05/161641
https://tonari-it.com/gas-script-approval/
ゼロから作るdeep learning 〜学習をスムーズに進めるためのメモ〜

**ゼロから作るdeep learning**を勉強しています。


ここでは、頻出用語の説明と、理解が難しかった部分の要約を載せています。特に機械学習・深層学習に全く触れてなくてなにもかもこれから始めるという人はぜひこの記事を読んで活用していただけたらと思います。

# コード上での頻出用語　

### __init__
・・・初期化を行うメソッド。別名**コンストラクタ**とも呼ばれる。パラメータの重みの初期値などを設定する際にこの初期値を用いる。　

### hidden_size 
・・・隠れ層（全結合）のニューロンの数　

### output_size 
・・・出力層（全結合）のニューロンの数

### iters_num 
・・・勾配法による更新の回数。繰り返し(iteration)の回数のことである。例えば、更新の回数を10000回に設定すると、訓練データに対し損失関数の計算が行われ、その都度(1万回)勾配法よるパラメータの更新が行われる。



### gradient
・・・勾配。主に損失関数を求めるための数値微分(numerical_gradient)と誤差逆伝播法(gradient)の関数を作成する際に使う。``grads``と略されることも多いので注意が必要。


### optimizer
・・・最適化。効率良く勾配を求めるアルゴリズムを設定する際に使用する変数。SGD、AdaGrad、Adamなどを実装する際には、この変数に格納する。　

### Batch
・・・バッチ。主に1度の学習で使用する学習データのまとまりのことである。この1度で使用される学習データの個数をバッチサイズという。

### epoch(iter_per_epoch)
・・・単位の一つ。全ての学習データを使い切った際にカウントされる単位である。例えば、50000個のデータを使用する時、500個のバッチで学習を行った場合、最大で``(50000÷500 = )100``回、損失関数の訂正が行われる。この時、100回＝1エポックとなる。

### forward
・・・順伝播を行う関数。誤差逆伝播法(5章)の学習で頻出。　

### backward
・・・逆伝播を行う関数。　











# 頻出ではないが、抑えておくべき用語
### weight decay 
・・・荷重減衰。学習の過程において、大きな重みを持つことに対してペナルティを課すこと絵、過学習を抑制するためのもの。　

### weight_init_std 
・・・初期化の際の重みの標準偏差。　

### conv_param 
・・・畳み込み層のハイパーパラメータ。終盤から頻出。
ゴミクサ

# ゴミクサ

# 目次

- 作品の目的　
- 用意するもの
- 作品の説明　　　
- 手順
-コード
- 追加したい機能

# 作品の目的
毎日のゴミ捨ての際に今日何ゴミだろう？となる時が多々あります。(特にビンや缶、乾電池など)
そんな時に今日何のゴミかを捨てればいいのか教えてくれると助かると思い作りました。



# 用意するもの
- アレクサeco
- Raspberry Pi

# 作品の説明
#### Alexaから朝起きたらゴミの日だよ！ってお知らせしてくれる装置を作ります！

# 手順
➀シェルスクリプトでアプリを作ります。


➁トリガーをどうするか考えます。

　まず考えられるのは時間です。
　指定した時間になると勝手に喋れるようにします。

　問題は起きる時間が同じではない可能性があることです。


➂そこで毎朝行っている「アレクサ、行ってきます」という言葉をトリガーにします。


➃NodeREDを使ってRaspberry Piに信号を送ります。


➄呼び出し先のシェルスクリプトを作ります。


➅何度も言われるのは面倒なので、時間指定と1日に1度だけ言うようにします。


これで行ってきます！とアレクサに言うたびにゴミの日をリマインダーしてもらえます!




# コード
```
#!/bin/bash

cd `dirname $0`

# 曜日の取得
# 月:1 火:2 水:3 木:4 金:5 土:6　日:7
day_of_the_week=`date +%w`

flag=`.flag`

if [ $flag = `date +%Y%m%d` ]; then
	exit
fi

if [ `date +%H%M` -gt 900 ]; then	# 9:00以上なら実行しない
	exit
fi
if [ `date +%H%M` -lt 600 ]; then	# 6:00より前なら実行しない
	exit
fi

if [ $day_of_the_week -eq 1 ]; then 	#月
	echo "今日出せるゴミはありません。">/dev/null
elif [ $day_of_the_week -eq 2 ]; then	#火
	echo "今日出せるゴミは、燃えるごみ、びん、かん、新聞紙、段ボール" >/opt/nodered/alexa_speak.txt
elif [ $day_of_the_week -eq 3 ]; then	#水
	echo "今日出せるゴミは、生ゴミです。" >/opt/nodered/alexa_speak.txt
elif [ $day_of_the_week -eq 4 ]; then	#木
	echo "今日出せるゴミはありません。" >/opt/nodered/alexa_speak.txt
elif [ $day_of_the_week -eq 5 ]; then	#金
	echo "今日出せるゴミは、ペットボトル、プラスチックです。">/dev/null
elif [ $day_of_the_week -eq 6 ]; then	#土
	echo "今日出せるゴミは、生ゴミ、乾電池です。" >/opt/nodered/alexa_speak.txt
elif [ $day_of_the_week -eq 7 ]; then	#日
	echo "今日出せるゴミはありません。">/dev/null

fi

date +%Y%m%d >daily.flag
```


# 追加したい機能
- 朝だけ人感センサーで反応して喋りかける機能を追加したい
- ゴミ箱に距離センサーと重量センサーをつけ、そんなにゴミが溜まっていない時は通知がならないようにしたい
OCI Oracle Linux 初期設定

リリースバージョン表示
```
cat /etc/oracle-release
```
現在のシステム・ロケールとキーマップの確認
```
localectl
```
システム日時・タイムゾーンの確認
```
timedatectl
```

### ロケール
使用可能なすべてのロケールの確認
```
localectl list-locales
```
ja_JP.UTF-8がない場合、それをインストール
```
yum install glibc-langpack-ja
```
ロケールをja_JP.UTF-8に設定
```
localectl set-locale LANG=ja_JP.UTF-8
```
ロケールの確認
```
cat /etc/locale.conf
```

### キーマップ
X11 LayoutとVC Keymapの設定（以下の両方が必要）
```
localectl set-keymap jp106
localectl set-keymap jp-OADG109A
```

### タイムゾーン
```
timedatectl set-timezone Asia/Tokyo
```

### 開発ツールセット
```
yum groupinstall 'Development Tools'
```
今更ながらRubyKaigi2023 ライブビューイングを振り返り

# はじめに

人生で初めてRubyKaigi2023に参加しました

![video_kaigi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/1767d3c1-e9ac-9927-1982-6332c492eaaa.png)

オフライン参加ということで、会社の会議室からライブビューイングしました
予め参加者メンバーで見たいセッションを決めておいて、大きな画面で視聴して、個別見たいセッションがあれば
手元のPCで見るみたいな事をしました

焦ったのは、英語のセッションでは翻訳がなかった事で、同時翻訳か翻訳機能があると思いこんでいたので
当日、スライドと雰囲気でカバーしました

# 一部セッション内容

朝から夕方まで視聴したのですが、自分がわかった範囲の感想を書きます

## 基調講演 Rubyの生みの親であるまつもとゆきひろ(Matz)氏

#### 内容をざっくり書くと・・・
名前の重要性
Rubyという名前を付けた日が、Rubyの誕生日
他の名前ではなく、Rubyという名前だったから、ここまで使いたいと思ってもらえたはず
初期には、認知も機能も少ない状態で利用したいと思うサービス、ソフトウェアになるためには、名前の影響は大きい

基本構成の重要性
RubyKaigi2023時点でのRubyの最新バージョンは`3.2.2`
最古のバージョン`0.49`を見直したところ、基本的な構成は現在と変わっていなくて、ポリシーも維持されている

Rubyの歴史、Rubyの広がり、モチベーション・メンタル、人とのつながりなど、大事なことを話されていました

## The Resurrection of the Fast Parallel Test Runner（Koichi ITOさん）

<script async class="speakerdeck-embed" data-id="e05090616b8b42cb8c76589382b76d2d" data-ratio="1.78343949044586" src="//speakerdeck.com/assets/embed.js"></script>

#### 内容をざっくり書くと・・・
1日は24時間で、みんなに平等に与えられている
機械も同じで秒数にすると `86400秒`

リリースするためには、テスト・デプロイというCIを回すけど、CIにかかる時間が長いと1日にリリースできる回数が少なくなってしまう
解決方法は、お金をかけて、性能の高いマシンで回すのが初手の方法
次はテストを並列に動かしてテスト時間を短縮させる方法

テストのライブラリは複数あって、それぞれの良いところ・もう少しな所を１つ１つ説明
test-queueのメンテナンスをすることになって、そのお話
途中から時間が足りなくなり駆け足になりました

#### 感想
テスト時間がかかるとそれだけリリースできる機会が減ってしまうのは、確かにと思いました
1日の業務の中でリリースできる機会が少なることを意識したほうがよくて、コードのテストは必要なので改善できる方法はないか？という話だったと思います
自分ができる範囲でいくとテストを書く時に、必要以上のデータを用意させていないかなどを気をつけたいと思いました

# さいごに

貴重な時間とお金を投資してくれた会社に感謝してます

自分の力不足ですが、英語で何言っているの？ってところが多かったです
翻訳機能があったけど、日本語>英語:ok: 、 英語>日本語:ng:
スライドの内容でカバーだけど、内容も英語だったので、英語読めたらいいなと思いました

Rubyの深い部分のセッションや、こういう機能があるんですよといった
業務ではあまり触れないようなところの説明を聞けたのは楽しかったです

そしてRubyを利用しているサービスやRubyに触れている人が大勢いることを知れたこともよかったことです

以上になります
GPUとCPUの処理速度の違い


GPUとCPUの処理速度を比較する一つの方法は、大量の行列計算（例えば、行列の乗算）を実行し、それぞれの実行時間を計測することです。そのため以下に、実行時間を計測するPythonコードを示します。

私はGoogle Colaboをここでは使用しています。

```
import torch
import time

# 行列のサイズを設定します
for size in range(1000, 11000, 1000):
  
  a = torch.randn([size, size])
  b = torch.randn([size, size])

  # CPUでの計算
  start_time = time.time()
  c = torch.matmul(a, b)
  end_time = time.time()
  cpu_time = end_time - start_time
  print('Size: {}, CPUによる処理時間: {:.4f}秒'.format(size, cpu_time))

  # GPUでの計算
  a = a.to('cuda')
  b = b.to('cuda')

  start_time = time.time()
  c = torch.matmul(a, b)
  torch.cuda.synchronize() # すべてのCUDAカーネルが完了するまで待つ
  end_time = time.time()
  gpu_time = end_time - start_time
  print('Size: {}, GPUによる処理時間: {:.4f}秒'.format(size, gpu_time))


```

結果は以下の通りです。

Size: 1000, CPUによる処理時間: 0.0248秒
Size: 1000, GPUによる処理時間: 0.0009秒
Size: 2000, CPUによる処理時間: 0.2079秒
Size: 2000, GPUによる処理時間: 0.0060秒
Size: 3000, CPUによる処理時間: 0.6982秒
Size: 3000, GPUによる処理時間: 0.0193秒
Size: 4000, CPUによる処理時間: 1.6222秒
Size: 4000, GPUによる処理時間: 0.0456秒
Size: 5000, CPUによる処理時間: 4.2262秒
Size: 5000, GPUによる処理時間: 0.0879秒
Size: 6000, CPUによる処理時間: 5.3194秒
Size: 6000, GPUによる処理時間: 0.1467秒
Size: 7000, CPUによる処理時間: 9.5572秒
Size: 7000, GPUによる処理時間: 0.2131秒
Size: 8000, CPUによる処理時間: 13.5594秒
Size: 8000, GPUによる処理時間: 0.2957秒
Size: 9000, CPUによる処理時間: 19.6224秒
Size: 9000, GPUによる処理時間: 0.4059秒
Size: 10000, CPUによる処理時間: 26.2983秒
Size: 10000, GPUによる処理時間: 0.5396秒

グラフにすると以下の通りです。
![スクリーンショット (119).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2587191/c7e45ce7-4748-9379-bdd6-4fe92439da84.png)


この結果から、GPUがCPUに比べて大幅に高速であることが明確に理解出来ました。特に行列のサイズが大きくなるにつれて、パフォーマンスの差が顕著に確認出来ました。
Pythonで画像データに地理座標系を与えるのに使えそうな記事まとめ

# はじめに
今所属する部署では、頻繁に地理データを活用する。部署の一人が、デイリースクラムで「Python等のプログラムを用いて衛星画像に座標をつけるやり方知りませんか？」と質問をし、その際に自分で調べてみた。今後使う可能性も高いし、地理データをいじるのは好きなのでtips的にまとめてみた。

# 見つけた記事
・[ArcPy で画像処理をしてみよう ～その１：ラスタオブジェクトとプロパティ](https://blog.esrij.com/2013/03/01/arcpy-e459/)(個人ブログ)
・[【GIS】Pythonでラスタ画像上の任意地点の値を拾う](https://qiita.com/KI_333/items/189e3f2df86d2a4cdf68)（Qiita）
・[GISデータ(ラスター・ベクター)をPythonで処理する](https://qiita.com/kudap10/items/2a024695b963f51b1353)(Qiita)
・[地理情報をPythonで扱う](https://zenn.dev/sre_holdings/articles/4ff923a73e7e5a)(Zenn)
・[GIS実習オープン教材 ~ラスターデータの読み込み~](https://gis-oer.github.io/gitbook/book/materials/python/07/07.html)

# オチ
結局[gdal_translate](https://gdal.org/programs/gdal_translate.html)でTIFFファイルにして、解決したそうな.. 個人的にはnetCDFを扱ったりする上でもpythonを使うので、プログラム上の処理がいいと思う。（GISだとファイル管理が面倒なので..笑）
AWS認定試験の更新戦略を、自分の状況を踏まえて整理してみる。

# 前置き

この記事は、表題の通り、筆者の状況や価値観に基づいたもので、ある意味ポエムです。前提条件などは人によってかなり異なると思います。
ただ、AWS資格試験の更新に関して他の人はどうしているのだろう？と思ってる方が、ある程度はいると想像し、一つの例として参考になればと思って記事にしました。

# 主題

AWS資格試験は、３年間の有効期間があります。ある程度保持している資格数が増えてくると有効期間を踏まえて保持戦略を練らねばいけなくなります。この記事は筆者がそれを整理した記録です。

# 保持資格と現時点での有効期限

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866006/ff45049e-0ac1-e666-3ed6-22755ef656f1.png)

# 自分の現状など

- 会社の業務ではAWS使うものの、最近の部署移動によって濃度は薄くなった。
- 幸いにもAWS知識が活きる副業をやらせて頂いている。
- 副業は続けたいのである程度はAWSの知識はキープしたい。
- 自分の記憶力だと、それぞれの資格取得には、１～２か月の準備期間が欲しい（再取得だとしても）。
- 業務外時間が勉強ばかりというのは味気ないので避けたい。
- 副業を始めたという事もあり、以前ほど勉強時間が捻出できない。
- 趣味としてやってる機械学習系の事にも時間使いたい。
- 社内のAWS資格新規取得キャンペーン（報奨金あり）が必ずある訳ではない。

# 整理ポイント

まず、今後どうするかを考える上でのポイントと基本姿勢を整理します

## AWS ALL Certifications Engineersを目指すかどうか

取得出来れば名誉である事は確実ですが、残る二つは`Advanced Networking - Specialty`と`SAP on AWS - Specialty`です。業務では関わりがほぼ無い領域です。前者は教養として知っておきたい部分もありますが、`Solutions Architect - Professional`の出題範囲を知っていれば十分かと思いました。後者は自分の業務的には教養としても必要性が希薄です。
今の状況では目指さなくていいかなという判断をしました。

## どの資格を保持するか

今保持している資格を維持するのも結構大変になる事が想定されます。状況は今後変わると思いますが、優先順位をつけておきたいと思います。

### 必須

`Solutions Architect - Professional`
`DevOps Engineer - Professional`

Professional資格という事で、この二つを持っているとAWS界隈で一定以上の知識と経験を持つ人と認識されるイメージがあります。副業においても資格保持必須では無いですが、保持しておかないと心苦しい感じです。
この２つを確保していれば`Associate`カテゴリ３資格と`Cloud Pactitioner`は更新されていくという意味でも優先順位が高い資格です。

### 個人的優先順位高

`Machine Learning - Specialty`

業務でも副業でもあまり関係は無いですが、自分の趣味分野という一点において優先順位高くします。

### 汎用性優先順位高

`Security - Specialty`

各資格試験それぞれにセキュリティ部分の範囲はありますが、セキュリティに関する要件を一通り知っておくのは重要だと思います。それらの管理や対応も重要です。知識をアップデートする価値は高いと思います。

### 優先順位中ほど

`Database - Specialty`

業務でもある程度は関係します。が、１度取る事で各種DBの存在を知れました。今の自分の状況ではこの領域の知識のアップデートは優先順位そんなに高くないかなと思いました。

### 優先順位低

`Data Analitics - Specialty`

業務では関係ない知識です。教養として１度取ったのは良かったと思っていますが、部署移動などで業務で関わりが発生しない限りはこの領域の知識アップデートは要らないかなと思いました。

### 考慮無し

`Associate`カテゴリ３資格
`Cloud Pactitioner`

必須に上げた２つの資格を保持していると自動的に更新されるので考察から外します。

# 結論

資格を取った時期も加味して以下のサイクルで回していこうと思っています。

## サイクル１年目
　６月頃：`Security ― Specialty`更新
１２月頃：`Solutions Architect - Professional`更新

## サイクル２年目
　６月頃：`Machine Learning - Specialty`更新
１２月頃：`DevOps Engineer - Professional`更新

## サイクル３年目
　６月頃：他の資格にも手を出す、休む、残るAWS資格取る（or更新）など気分と状況次第
１２月頃：他の資格にも手を出す、休む、残るAWS資格取る（or更新）など気分と状況次第



# ぼやき（ずん飯尾さんっぽく）

- あ～、`AWS ALL Certifications Engineers`が有効期限切れの資格がいくつかあっても申し込めるようにならないかな～（Specialty系はOKとか ）
- あ～、`SAP on AWS - Specialty`が`AWS ALL Certifications Engineers`に必要無くならないかな～
  ※3rdパーティーフォーカス資格というカテゴリ作っていいと思う。OracleとかCiscoとかWordPressとかAWSコラボの資格試験作れそうだし。
- あ～、AWS資格の有効期間が５年とかになったりしないかな～  
  ※AWSの機能強化速度がすごいの知ってるので無理目である事理解してます
- あ～、出題範囲が狭い更新専用の試験がリリースされないかな～
Sambaの設定ファイル「/etc/samba/smb.conf」　[global]セクションで使用される認証設定に関わる主な設定項目

●Sambaの設定ファイル「/etc/samba/smb.conf」には3つの特別なセクションである[global]、[homes]、[printers]セクションと、個々の共有の設定を行う任意の名前のセクションがあります。

●[global]セクションで使用される認証設定に関わる主な設定項目

・security=user|domain|ads　認証方法を設定する。
user→ユーザレベルでの認証
domain→NTドメインにおいてドメインコントローラーを使用し認証
ads→Active Directoryドメインにおいて、ドメインコントローラを使用し認証

・passdb backend=認証方式　Samba3.0以降、security=userの場合smbpasswd,tdbsam,ldapsamなどの認証方式を指定(複数可)

・smb passwd file=ファイル名　security=useの場合、smbpasswdでの認証を行う際のパスワードファイルの指定

・password server=NetBIOS名|IPアドレス　security=[ads|domain|server]の場合、認証を別のサーバで行う際のぱづわーどサーバ(認証サーバ)の指定
【PHP】「require」と「require_once」の使い分け


## 初めに

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

## 概要

PHPで外部ファイルを読み込むときに使用している「****require****」と「****require_once****」の使い分けを理解していないので調べてみました。

呼び出し元のファイルは「parent.php」として先に定義しておきます。

```php
//parent.php
$require = "Hello world";
$require_once = "Hello world";
```

## 1. ****require****について

そもそも「****require****」とは何かPHP公式ドキュメントを調べてみました。

:::note info
`require` は include とほぼ同じですが、失敗した場合に **`E_COMPILE_ERROR`** レベルの致命的なエラーも発生するという点が異なります。 つまり、スクリプトの処理がそこで止まってしまうということです。一方 include の場合は、警告 (**`E_WARNING`**) を発するもののスクリプトの処理は続行します。
:::


要するに、ファイル読み込みをする機能で、指定のファイルがない場合致命的なエラーによって処理が止まるよ！と解釈しています。
※includ については別途記事にしようと思います。

よく使用する「****require****」構文です。

```php
require 'parent.php';
echo $require . PHP_EOL; //出力結果はHello world
```

## 2. ****require_once**** について

1.では「****require****」について調べましたが、自分自身よく使用するのは「****require_once****」です、処理の内容について調べてみました。

:::note info
 `require_once` 式は require とほぼ同じ意味ですが、 ファイルがすでに読み込まれているかどうかを PHP がチェックするという点が異なります。 すでに読み込まれている場合はそのファイルを読み込みません。
:::

ファイルを読み込むという点では同じですが、「****require****」では複数回読み込み(定義を呼び出し)をすることが可能でしたが、「****require_once****」では一度ファイルを読み込んだものは二回目以降、読み込まないようです。

「****require_once****」

```php
require_once 'parent.php';
echo $require_once . PHP_EOL; //出力結果はHello world
```

二回目以降、読み込まない
→文言だけでは少しややこしいのでコードで見てみましょう。

```php
require 'parent.php';
echo $require . PHP_EOL; //出力結果はHello world

require_once 'parent.php';
echo $require_once . PHP_EOL; //出力結果はHello world

//変数の値を変更してみる
$require = 'text_change';
$require_once = 'text_change';

//requireでの読み込みなので、読み込み時 $require は Hello world の状態で呼び出される
require 'require.php';
echo $require . PHP_EOL; //出力結果はHello world

//require_onceでの読み込みなので、2回目は読み込まれず変数の値が変更されル
require_once 'require_once.php';
echo $require_once . PHP_EOL; //出力結果はtext_change
```

上記コードから呼び出し時の変数が初期値に戻っています。

## 3. ****require / require_once どちらを使うか？****

2.にて二回目以降の呼び出し結果を比較しましたが、普段はどちらを使用すればよいのか調べました。

関数の再定義や変数値の再代入が起こると想定外の結果が起こります、普段使用するのであれば、「****require_once****」の方がよさそうです。

## まとめ

- 「****require****」はソースコード中で実行されるたびに再度、読み込みを行う
- 関数やクラスは重複定義となるため、致命的エラーとなり処理が止まってしまう
- 変数は読み込んだ値に上書きされる

- 「****require_once****」はそのソースコード中で一度だけ読み込む
- 普段使用際は、関数やクラスの定義がある場合はこちらを使う
.bash_profileと環境変数PATHについて


### 概要

`.bash_profile`とは、UnixやUnix系のオペレーティングシステムで使用されるシェルスクリプトです。主にBashシェルで利用され、ユーザーのログイン時に実行される特別なファイルです。`.bash_profile`は、ユーザーの環境設定や起動時に必要なカスタムコマンドを定義するために使用されます。

環境変数`PATH`は、コマンドラインインターフェース（CLI）から実行されるプログラムを探すためのディレクトリパスを含む特殊な変数です。`PATH`は、システムがコマンドを見つけるための検索パスを提供し、ユーザーがカスタムコマンドやスクリプトを簡単に実行できるようにします。

### .bash_profileの役割

`.bash_profile`は、以下のような役割を果たします。

1. 環境変数の設定: `.bash_profile`は、シェルセッションの開始時に環境変数を設定するために使用されます。環境変数は、システムの動作やユーザー環境のカスタマイズに影響を与える重要な値を保持します。

2. エイリアスと関数の定義: `.bash_profile`は、エイリアスや関数を定義するための場所としても利用されます。エイリアスは、長いコマンドや一連のコマンドに対して短い名前を割り当てることができ、入力を簡略化するために使用されます。関数は、複数のコマンドや処理をまとめて実行するための方法として利用されます。

3. シェルの設定: `.bash_profile`は、プロンプトの外観や動作、デフォルトのエディタなど、シェルの設定に関する指示を含むこともあります。これにより、シェルの動作を個別のユーザーの好みに合わせてカスタマイズすることができます。

### 環境変数PATHの役割

`PATH`環境変数は、シェルがコマンドやプログラムを実行する際に検索するディレクトリのリストを保持します。システムは`PATH`の値に従ってディレクトリを順番に検索し、実行したいコマンドやプログラムが存在する場所を見つけます。

`PATH`の設定により、ユーザーはカスタムコマンドやユーティリティスクリプトをどこからでも実行できるようになります。ディレクトリが`PATH`に追加されると、そのディレクトリ内の実行可能ファイルがコマンドとして認識されるようになります。

例えば、`/usr/bin`や`/usr/local/bin`などの一般的なディレクトリは、多くのシステムコマンドが格納されている場所です。これらのディレクトリが`PATH`に含まれているため、ユーザーはターミナルから直接これらのコマンドを実行することができます。

### .bash_profileとPATHの設定方法

`.bash_profile`には、以下のような形式で環境変数`PATH`を設定することができます。

```bash
export PATH=/path/to/directory1:/path/to/directory2:$PATH
```

この例では、`/path/to/directory1`と`/path/to/directory2`が新たに`PATH`に追加されています。`$PATH`は既存の`PATH`の値を参照し、新しいディレクトリを追加することで既存の設定を保持します。

`export`キーワードは、変数を現在のシェル環境にエクスポートするために使用されます。これにより、設定した環境変数がシェルセッション内で他のプログラムやスクリプトから利用可能になります。

### まとめ

`.bash_profile`は、ユーザーの環境設定やカスタムコマンドの定義に使用される重要なシェルスクリプトです。環境変数`PATH`は、システムがコマンドやプログラムを検索するためのパスを保持する変数であり、ユーザーがカスタムコマンドを実行するために重要な役割を果たします。`.bash_profile`を使用して環境変数`PATH`を設定することで、ユーザーはシステム全体でのコマンドの利用性を向上させることができます。

この記事では、`.bash_profile`と環境変数`PATH`の役割や設定方法について解説しました。これらの基本的な概念を理解することで、より効率的なシェル環境の構築やカスタマイズが可能になります。
AWS SCS-C01取りました！！

こんにちは。yuzu_juiceです🥂
昨日合格した、SCS-C01を振り返ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086592/b01571ff-8460-391d-511c-8b3d2cfbb781.png)

# こんな資格
https://aws.amazon.com/jp/certification/certified-security-specialty/
※2023/7/11から、C02にバージョンアップするようです。

問題数はAssociate試験と変わらず65問、
試験時間は170分と、Associate試験より40分長かったです。
受験料は$300と、Associateの2倍の金額になります。これだけ高額だと、気合い入れて勉強しなければなりません……


# 勉強方法
- サンプル問題
一番初めに、サンプル問題を解きました。
ここで、9/10問正解できたので、勉強自体少なくてよいと判断し、2週間後に試験をセットしました。

- Black Belt
試験ガイドを見て、その中で知らないサービスについて、YouTubeで以下のBlack Beltを見ました。
    - Amazon Macie
    - AWS KMS
    - Amazon Inspector
    - AWS CloudHSM

Black Beltを見ることで、だいたいのサービスの雰囲気をつかむことができました。
特に、鍵管理周り(ローテーションとか、HSMとか)はあまり理解できていなかったのでやっておいて正解でした。

- 公式模擬試験
    - 無料なので、絶対に受けたほうがよいです。AWS Skill Builderから無料受験できます。

# 感想
Associate試験に比べ、試験範囲が狭いので勉強はしやすかったです。
しかしその分、各サービスについて、Associateより深い理解が必要になりました。
私にとって初のAWS specialty試験でしたが、難易度としてはAccosiate試験よりちょっと難しいかな？くらいの感覚でした。必要以上に心配する必要はなかったです。

# 得点
Associate試験は、720/1000点で合格ですが、Specialty試験は750点が合格ラインになります。
結果としては、771/1000点でした。ぎりぎりでしたが、合格できてよかったです👑
JavaScriptとDOM操作の基本

この記事ではJavaScriptを使ったDOM操作について解説します。DOM（Document Object Model）とは、HTMLのような文書の構造を表現するためのプログラミングインターフェースです。JavaScriptとの連携により、ウェブページの内容やスタイルの変更ができるようになります。

### 1. DOMとは？
ウェブページの内容はHTMLによって記述されています。しかし、このHTMLの内容をJavaScriptから操作するためには何らかの橋渡しが必要です。その役割を果たすのがDOMです。DOMによって、HTMLの各要素をオブジェクトとして扱うことができるようになり、JavaScriptからそのオブジェクトへアクセスして操作できるようになります。この記事ではDOM操作の基本的なものを例を挙げて紹介していきます。

### 2. DOM要素の取得方法
まず最初に、HTML要素の取得方法を見ていきましょう。

```javascript
const elementById = document.getElementById('myId'); // IDによる取得

const elementsByClass = document.getElementsByClassName('myClass'); // クラスによる取得

const elementsByTag = document.getElementsByTagName('div'); // タグによる取得

const elementBySelector = document.querySelector('#myId .myClass'); // CSSセレクタによる取得

const elementsBySelector = document.querySelectorAll('div.myClass'); // CSSセレクタによる取得（複数）
```

### 3. DOM要素の作成と追加
次は、新しいHTML要素の作成とそれをDOMに追加する方法です。

```javascript
const newElement = document.createElement('div'); // 新しいdiv要素を作成
newElement.textContent = '新規に作成した要素です。'; // 要素のテキストコンテンツを設定
```
このようにして作成した要素は、まだページ上には表示されません。要素をページ上に表示するためには、既存のDOM要素（この場合は'parent'要素）の子要素として追加する必要があります。

```javascript
const parentElement = document.getElementById('parent'); // 親要素を取得
parentElement.appendChild(newElement); // 新しい要素を親要素の子要素として追加
```

### 4. DOM要素の削除と置換
最後に、DOMから要素を削除する方法と、要素を別の要素に置き換える方法について見てみましょう。

```javascript
const elementToRemove = document.getElementById('remove-me'); // 削除する要素を取得
elementToRemove.parentNode.removeChild(elementToRemove); // 要素を削除

const elementToReplace = document.getElementById('replace-me'); // 置換する要素を取得
const replacementElement = document.createElement('div'); // 新しいdiv要素を作成
replacementElement.textContent = '置換された新しい要素です。'; // 要素のテキストコンテンツを設定
elementToReplace.parentNode.replaceChild(replacementElement, elementToReplace); // 要素を置換
```

### 5. イベントリスナーの使用
JavaScriptとDOM操作を組み合わせることで、ユーザーのアクション（クリック、スクロール、キー入力など）に反応する動的なページを作成することができます。これは「イベントリスナー」を使うことでできます。下のコードは、ボタンクリックに反応する基本的なイベントリスナーの設定例です。

```javascript
const button = document.getElementById('myButton'); // ボタン要素を取得

button.addEventListener('click', function() {
  alert('ボタンがクリックされました！');
}); // ボタンのクリックイベントに反応
```

このコードでは、ボタンがクリックされるとブラウザ上にアラートが表示されます。

以上、JavaScriptとDOM操作の基本でした。
JavaScriptのDOMとイベントリスナについて

DOMとは、Document Object Modelの略称であり、HTMLやXMLを操作するためのAPIである。

JavaScriptでは、このDOMと呼ばれるAPIを介してテキストを変更するなどの何らかの処理を要求し、HTMLを動的に変化させている。
(例えば、hoverした時にセレクタを変化させてボタンの色を変えるなど)

```.js
const h1Element = document.querySelector('h1');
console.log(h1Element);//取得したDOM要素の詳細が表示される。例：<h1>テキスト</h1>
console.dir(h1Element);//h1ElementのDOMオブジェクトの実体。オブジェクトのプロパティが一覧で表示される。
```
console.dirの実行結果
![スクリーンショット 2023-06-04 23.22.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458009/5b9a28df-aca1-c9ca-ea84-27c4865bfba1.png)

h1Elementの中の文字列を変更したい場合は、textContentを使う
```.js
h1Element.textContent = '変更後のテキスト';
//JavaScriptでは、オブジェクトの形式でHTMLにアクセスする。
```

HTMLをJavaScriptで操作するためのh1Elementなどのオブジェクトのことを、下記のように呼ぶ
・DOM
・DOMオブジェクト
・ノード
・エレメント

イベントリスナとは、クリックやホバーなど何らかのイベントが発生した時に、そのイベントを検知する機能を指す。
イベントリスナは第一引数と第二引数をもち、第一引数には検知するイベントの種類（Click, Hover mouseoverなど)を、第二引数に関数を登録する。
イベントリスナは第一引数で登録されたイベントを検知した際に、第二引数の関数が実行される。
イベントリスナに登録する関数（第二引数として記述する関数）のことは、イベントハンドラもしくはアクションと呼ぶ。
```.js
const btnEl = document.querySelector('button');
btnEl.addEventListner('click', (e) => {
    console.log(e.target);//<button>クリック</button>
    console.log('hello');
});
```
上記例では、buttonのDOM要素をbtnElとして取得し、二行目でイベントリスナの処理を記述している。
イベントリスナでは第一引数として'click'イベントが、第二引数に無名関数が指定されている。
イベントハンドラの中の引数eはe,ev,eventと表記されることが多く、これは何のイベントが発生したか（clickやhoverなど）やどのDOM要素でイベントが発生したかなど、イベント発生時の情報が自動的に格納されるイベントオブジェクトと呼ばれるものである。

例えば、イベントオブジェクトには下記のような物が格納される。
・type：発生したイベントの種類。上記記述では、click
・target：イベントが発生したDOM要素。上記では、button
【Paiza問題集】条件分岐/FizzBuzz

# Paiza問題集
Pythonで回答

## 条件分岐/FizzBuzz

### Step01 3の倍数判定
```Python
"""
3の倍数判定
https://paiza.jp/works/mondai/conditions_branch/conditions_branch__mod_step1

問題
整数Nが与えられます
Nが3の倍数の場合はYESを、そうではない場合はNOを出力してください
"""

print("YES" if int(input())%3==0 else "NO")
```

### Step02 2つの倍数判定
```Python
"""
2つの倍数判定
https://paiza.jp/works/mondai/conditions_branch/conditions_branch__mod_step2

問題
2つの倍数判定
整数Nが与えられます
Nが3の倍数かつ5の倍数の場合はYESを、そうではない場合はNOを出力してください
"""

N = int(input())
print("YES" if N%3==0 and N%5==0 else "NO")
```

### Step03 偶奇の判定
```Python
"""
偶奇の判定
https://paiza.jp/works/mondai/conditions_branch/conditions_branch__mod_step3

問題
長さNの数列Aが与えられます
この数列に含まれる偶数の要素の個数と、奇数の要素の個数を答えてください
"""

N = int(input())
A = map(int, (input().split()))
even, odd = 0, 0

for i in A:
    if i % 2 == 0:
        even += 1
    else:
        odd += 1

print(f"{even} {odd}")

```

### Step04 曜日の判定
```Python
"""
曜日の判定
https://paiza.jp/works/mondai/conditions_branch/conditions_branch__mod_step4

問題
ある月の1日は日曜日、2日は月曜日...です
X日は何曜日でしょう
"""

X = int(input())
week = ["Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri"]

print(week[X % 7])
```

### Final問題 FizzBuzz
```Python
"""
FizzBuzz
https://paiza.jp/works/mondai/conditions_branch/conditions_branch__mod_boss

問題
整数Nが与えられます
Nが3で割り切れる場合はFizz、Nが5で割り切れる場合はBuzz、 Nが3と5の両方で割り切れる場合はFizzやBuzzの代わりにFizzBuzzを出力してください
ただし、Nが3の倍数でも5の倍数でもないときはNをそのまま出力してください。
"""

N = int(input())

if N % 15 == 0:
    print("FizzBuzz")
elif N % 3 == 0:
    print("Fizz")
elif N % 5 == 0:
    print("Buzz")
else:
    print(N)
```
【Android】oss-licenses-plugin に手動でライセンスを追加する


2023年6月現在のやり方です。
[oss-licenses-plugin](https://github.com/google/play-services-plugins/tree/master/oss-licenses-plugin) に自分でライセンスを追加するには以下のようになります。

[oss-licenses-pluginにライセンスを手動で追加する](https://qiita.com/k-yamada-github/items/d122518dd812442ecec7) を参考にしています。




``` kotlin:build.gradle.kts(:app)
project.android.applicationVariants.all {
    tasks.findByName("${name}OssLicensesTask")?.doLast {
        addOssLicense(
            project,
            "Google-Service",
            "https://developer.android.com/studio/terms.html"
        )
    }
}

fun addOssLicense(project: Project, libName: String, licenseContent: String) {
    val UTF_8 = "UTF-8"
    val LINE_SEPARATOR = System.getProperty("line.separator").toByteArray(Charsets.UTF_8)

    project.android.applicationVariants.all {
        if (project.file("build/generated/third_party_licenses/$name").exists()) {
            val dependencyOutput = project.file("build/generated/third_party_licenses/$name")

            val resourceOutput = File(dependencyOutput, "res")
            val outputDir = File(resourceOutput, "raw")

            // ライセンスファイル
            val licensesFile = File(outputDir, "third_party_licenses")
            // ライセンスファイルへの書き込み前に現在の位置を保持
            val start = licensesFile.length()

            // ライセンスファイルへ書き込み
            licensesFile.appendText(licenseContent)
            licensesFile.appendBytes(LINE_SEPARATOR)

            // ライセンスメタデータファイルに書き込み
            val licensesMetadataFile = File(outputDir, "third_party_license_metadata")
            licensesMetadataFile.appendText("${start}:${licenseContent.length} $libName")
            licensesMetadataFile.appendBytes(LINE_SEPARATOR)
        }
    }
}

```
Next.js13のappディレクトリ構成でServer Componentでクエリパラメータを取得する

### はじめに
Next.js13.4からstableとなったappディレクトリでは、デフォルトのコンポーネントがServer Componentとなりました。

Client Componentでは`useSearchParams`フックが使えますが、Server Componentから利用するとエラーになってしまい使えません。
代わりに`searchParams`を利用することでServer Componentでクエリパラメータを取得することができます。

Next.jsはまだ経験が浅いので、間違っている箇所やもっと良い方法があればご指摘ください。

### 実装例

例えば以下のようにクエリパラメータで渡されたnameを取得する場合を考えます。

```
localhost:3000/sample?name=名前
```

page.tsxで`searchParams`を利用することでパラメータの値を取得できます。
クエリパラメータから受け取った値をデータフェッチ処理に渡す実装は以下のように書けます。

```react:page.tsx
const getData = async ({name}: {name: string}) => {
  // データのフェッチ処理
}

export default async function Page ({searchParams}: {searchParams: {name: string}})  {
  const data = await getData({name: searchParams.name});

  return (
    <>
    </>
  )
}
```

ちなみに[slug]などディレクトリ内に角括弧を含む場合は`searchParams`ではなく`params`を使って書くことができます。
ROS launchファイルの勉強メモ

launchファイルは何？
=
色んな機能を持つnode（例えば、ロボットの移動速度を発信するnode、カメラで取得した障害物の距離を発信するnode）をcpp或いはpyにて作っているが、１つのロボットは沢山のnodeを起動して実行する必要があるが、一つ一つ起動するのはダルいよね。それをまとめて起動してくれるのはlaunch。
launchファイルはXML形式。

ラベル(Tag)
=
主に使われているラベルは11種ある
1.launch
Topラベル、一番大きい枠のイメージ
~~~~~~~~~~~~~~~~~~~
<launch>
....
</launch>
~~~~~~~~~~~~~~~~~~~

2.node
ROSのnodeを起動するための記述
~~~~~~~~~~~~~~~~~~~
<node pkg="pkg名" type="node名" name="node実行名">
~~~~~~~~~~~~~~~~~~~
node名とnode実行名は何？何が違うの？笑
node名は本来のcppファイル名（例：亀.cpp　亀はnode名）
node実行名は実行する時に複数の同じnodeを区分する名前(お好きにつけれる名前。例：緑亀、赤亀。）
実際書くとこんな感じ：
~~~~~~~~~~~~~~~~~~~
<launch>
    <node pkg="海" type="亀" name="緑亀" />>
    <node pkg="海" type="亀" name="赤亀" />>
</launch>
~~~~~~~~~~~~~~~~~~~
nodeのプロパティはよく使われているpkg,type,nameの３つ以外、色々あるよう
output=“screen”　nodeのoutput(print?)をスクリーンに設定する
respawn="true"　nodeが停止しても自動復帰する
required="true" must nodeの設定、停止した場合他のnodeも全部停止する
args="arguments"　nodeに必要なパラメータ

3.machine
リモートPCなどの場合PCを指定する用

4.include
include:C言語と同じ感覚でlaunchも取り込めるような感じ
主なプロパティ
①file=“$(find pkg-name)/path/filename.xml”
②ns=“foo”　namespaceの定義（オプション
③clear_params=“true | false”（オプション
④pass_all_args=“true | false”（オプション

5.remap
node名を再定義する。何に使うの？例：downloadして来たnodeを自分が既に書いたnode名につなげるためのインターフェイス。

6.env
environment-variable環境変量
プロパティ
①name=“environment-variable-name”
②value=“environment-variable-value”

7.param
nodeの下にparam:パラメータ設定
~~~~~~~~~~~~~~~~~~~
<param name="タイヤ半径" value="0.3" />
~~~~~~~~~~~~~~~~~~~
ここメモして置きたいが、paramは数が少ない場合はこれで設定するのは便利だが、数が多い場合はlaunchファイルが見づらくなってしまうので、yamlファイルにてパラメータを集約した方がよい。
主なプロパティ
①name=“namespace/name”。
②value=“value” (オプション
③type=“str | int | double | bool | yaml” (オプション
④textfile=“$(find pkg-name)/path/file.txt” (オプション
⑤binfile=“$(find pkg-name)/path/file” (オプション
⑥command=“( f i n d p k g − n a m e ) / e x e ′ (find pkg-name)/exe '(findpkg−name)/exe 
′
 (find pkg-name)/arg.txt’” (オプション

8.rosparam
YAMLファイルを使う場合に使うラベル
主なプロパティ
①command=“load | dump | delete” (オプション
②file=“$(find pkg-name)/path/foo.yaml” 
③param=“param-name”
④ns=“namespace” (オプション
⑤subst_value=true | false (オプション

9.group
10.test
11.arg
launchファイルのlocal変数
~~~~~~~~~~~~~~~
<arg name="子供" default="1">
<arg name="大人" default="2">
~~~~~~~~~~~~~~~
使用時
~~~~~~~~~~~~~~~
<node pkg="海" type="亀" name="緑亀" args="$(arg 子供)" />
<node pkg="海" type="亀" name="赤亀" args="$(arg 大人)" />
~~~~~~~~~~~~~~~
これでパラメータが１の緑亀のnodeと２の赤亀のnodeが生成される。例えばパラメータが長さだとか、重量だとか、わからないけど。
主なプロパティ
①name=“arg_name”。
②default=“default value” (オプション
③value=“value” (オプション
④doc=“description for this arg” (オプション

launch起動（実行）
=
~~~~~~~~~~~~~~~~~~
roslaunch pkgName ***.launch
~~~~~~~~~~~~~~~~~~

https://qiita.com/ryuka0610/items/efc6a484d294ca4a25b8
SECCON Beginners 2023 Writeup

# 1 : crypto
## 1-1 : CoughingFox2

圧縮ファイルをもらい、解凍するとpythonファイルとテキストファイルが。
pythonファイルが暗号化プログラム、テキストがその結果です。
暗号化は下記のようにされていました。
1. encodeメソッドでflagを文字コード化
2. `c = ((flag[i] + flag[i+1]) ** 2 + i)` で i 文字目について i+1 文字目との和を2乗し、iを足す
3. リスト `cipher` に暗号化した値(=c)を加える
4. `random.shuffle(cipher)` で暗号結果をシャッフル

とりあえずシャッフルは放置して(2)の復号だけを考えようとしました。
しかし、順番が絡む以上一発で復号とはいかないし、その順番を確定させる方法が思いつきません…
flagの長さは`cipher`から44文字　※(2)ではi文字目とi+1文字目で1つの値が出るため、得られる値の総数はflagの文字数より1小さくなっている
仮に総当たりで考えるとすると44!通りなのでバカみたいな数になり、現実的ではなさそうです。
頭の「ctf4b{」までは初期位置も文字も確定してるので、とりあえずここを足掛かりにすることでどうにかなるのかとも思ったのですが、一向に進展せず。
八方塞がりになってたところ、タイトル的にこれ多分去年も類題出てるなと思って去年のwriteupを調べてみました。
するとドンピシャなのが見つかります。
暗号化された値からiを引いたもの( c - i )はi文字目とi+1文字目の文字コードの和 = 整数を2乗したものです( (flag[i]+flag[i+1])^2 )
なので i は「 c - i の平方根を取った時、値が整数になるもの」となります。
これだけだとiが複数ある可能性も否めませんが、まあ
この条件を元に、以下のような手順で解いていきます。
1. `cipher[n]`からiを引き、その平方根をとる
2. (1)の結果が整数となるiが見つかるまで総当たりで行う(0≦i≦43)
3. (1),(2)を`cipher`の全ての値について行う -> 43個の`flag[i]+flag[i+1]`の値が順番とともに求まる
4. flagの一文字目は「c」で確定していることを利用し、(3)の結果から`flag[i+1]`を求める
5. chrメソッドを使って復号し、その結果を連結して最終的にflagを求める

下記はそのプログラムです。
~~~python:solve_coughfox2.py
import math

cipher = [4396, 22819, 47998, 47995, 40007, 9235, 21625, 25006, 4397, 51534, 46680, 44129, 38055, 18513, 24368, 38451, 46240, 20758, 37257, 40830, 25293, 38845, 22503, 44535, 22210, 39632, 38046, 43687, 48413, 47525, 23718, 51567, 23115, 42461, 26272, 28933, 23726, 48845, 21924, 46225, 20488, 27579, 21636] 
sum=[0]*len(cipher) #平方根とった結果を入れる
encoded=[0]*len(cipher) #各flag[i](=encode化された文字)を入れる
ans="" #flag格納用

with open(path,mode='w') as f:
    #平方根求めた結果が正数になるiを探し、flag[i]+flag[i+1]を求める
    for n in cipher:        
        for i in range(len(cipher)):
            result=math.sqrt(n-i)
            if(result.is_integer()):
                f.write(f"{n} -> {i}:{result}\n")
                sum[i]=int(result)
                break
    
    #求めたsumを順番に並べてテキストファイルに出力
    f.write("\n")
    f.write("[sum]\n")
    [f.write(f"{i}:{sum[i]}\n") for i in range(len(sum))]

    #sum[i]=flag[i]+flag[i+1]からflag[i]を引き、flag[i+1]を求める
    f.write("\n")
    f.write("[encoded]\n")
    encoded[0]=99 #c
    for j in range(1,len(sum)):
        encoded[j]=int(sum[j-1]-encoded[j-1])
        f.write(f"{j+1}文字目:{encoded[j]}\n")

    #各文字を変換、連結してflagを求める
    for j in range(len(encoded)):
        ans=ans+chr(encoded[j])
    ans=ans+"}"

print("ans:"+ans)
print("[fin]")
~~~
これより、`ctf4b{hi_b3g1nner!g00d_1uck_4nd_h4ve_fun!!!}` が求められました。


参考サイト
https://note.nkmk.me/python-random-shuffle/
https://grapebanana.com/python-encoding-utf-8-7161/
https://note.nkmk.me/python-bin-oct-hex-int-format/
https://hack.nikkei.com/blog/ctf4b202206/#chapter4-1
https://pg-chain.com/python-sqrt
https://note.nkmk.me/python-check-int-float/
https://engineerblog.mynavi.jp/technology/seccon-beginners-ctf2022-2/
https://www.whyit.work/entry/2018/08/14/235416
https://www.seiai.ed.jp/sys/text/java/utf8table.html
https://infoma-study.com/python-system-of-equations/
Semantic Kernel最小サンプルで簡単なチャットする！（AzureでのSemantic Kernelことはじめ）

# はじめに

基本的にはMicrosoftのSemantic Kernelのチュートリアル通りです。
とは言えなんか微妙につっかかりつっかかりだったので……未来の自分のためになるべく簡単にまとめました。

https://github.com/microsoft/semantic-kernel

# 事前準備

Azureで色々進めて以下を取得しておく。
(OpenAI版の方は適宜読み替えてください！）

```text
・API KEY: なんかぐちゃぐちゃな英数字
・API BASE: https://なんちゃら.なんちゃら.azure.com/
・model_name: gpt-35-turboみたいなやつ
・deployment_id: 自分で決めた適当な名前
```

ライブラリをインストールしておいてください。
他にも怒られるライブラリがあったら適宜インストールしましょう！

```console
pip install semantic-kernel
```


# コードその１ 単発の質問に答えてくれるやつ

IDとかを格納した `.env` というテキストファイルを作る。

```text:.env
AZURE_OPENAI_DEPLOYMENT_NAME="********"
AZURE_OPENAI_ENDPOINT="https://********.azure.com/"
AZURE_OPENAI_API_KEY="************"
```

Pythonのコードを作る。

```python:sk_test.py
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAITextCompletion, AzureTextCompletion

kernel = sk.Kernel()

deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
kernel.add_text_completion_service("dv", AzureTextCompletion(deployment, endpoint, api_key))

prompt = kernel.create_semantic_function("ドラえもんのあらすじは？")

print(prompt())
```

実行する。

```text
ドラえもんのあらすじは？
ドラえもんは、未来からやってきた猫型ロボットで、のび太の家にやってきます。
のび太は、勉強が苦手で、いつもテストで赤点を取ってしまいます。
......
```

結果がでました！

# コードその２ ちょっと会話になるやつ

同じくIDとかを格納した `.env` というテキストファイルを作る。

```text:.env
AZURE_OPENAI_DEPLOYMENT_NAME="********"
AZURE_OPENAI_ENDPOINT="https://********.azure.com/"
AZURE_OPENAI_API_KEY="************"
```

Pythonのコードを作る。

```python:sk_test.py
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAITextCompletion, AzureTextCompletion

kernel = sk.Kernel()

deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
kernel.add_text_completion_service("dv", AzureTextCompletion(deployment, endpoint, api_key))

# 会話に使うプロンプトのテンプレート
sk_prompt = """
あなたはコンサルとして振る舞ってください。明るく。かわいく。
答えが見つからない場合は「わからない」と言うこともできます。

{{$history}}
User: {{$user_input}}
ChatBot: """

# 会話の準備
chat_function = kernel.create_semantic_function(sk_prompt, "ChatBot", max_tokens=100, temperature=0.7, top_p=0.5)
context = kernel.create_new_context()
context["history"] = ""

# 1つ目の受け答え
print("[質問を入力してね]")
user_input = input()

context["user_input"] = user_input
bot_answer = chat_function.invoke(context=context)
bot_answer = str(bot_answer).split("\n\n")[0]

print(bot_answer)
context["history"] += f"\nUser: {context['user_input']}\nChatBot: {bot_answer}\n"

# 2つ目の受け答え
print("[質問を入力してね]")
user_input = input()

context["user_input"] = user_input
bot_answer = chat_function.invoke(context=context)
bot_answer = str(bot_answer).split("\n\n")[0]

print(bot_answer)
context["history"] += f"\nUser: {context['user_input']}\nChatBot: {bot_answer}\n"
```

```text
[質問を入力してね]
面白い本を教えて
『人間失格』はいかがですか？太宰治の代表作で、人間の葛藤を描いた作品です。
[質問を入力してね]
他には？
『騎士団長殺し』はいかがですか？カフカの代表作で、人間の孤独を描いた作品です。
```

結果が出ました！
ちゃんと1回目のやり取りを覚えてくれているので、2回目の「他には？」が本のことだと理解してくれています！かしこい！

## おしえて偉い人……

APIで回答を得ると複数の回答（というかやり取り）がまとまって返って来ることがあります。
なので `\n\n` で区切ってデータ取得してます。
……これでいいのでしょうか？？

```python
bot_answer = str(bot_answer).split("\n\n")[0]
```
fetch()を使用してJSON-Serverに配列オブジェクトの要素を個別にPOSTする方法

```javascript:index.js

    const data = [
      {
        id: 1,
        name: 'John',
        age: 25
      },
      {
        id: 2,
        name: 'Jane',
        age: 30
      }
    ];
    
    data.forEach(item => {
      fetch('http://localhost:3000/your-endpoint', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(item)
      })
        .then(response => response.json())
        .then(result => {
          console.log(result);
        })
        .catch(error => {
          console.error(error);
        });
    });

```

### 上記のコードでは、data配列の各要素をループして、fetch()を使用して個別のPOSTリクエストを送信しています。各要素をJSON文字列に変換してリクエストのボディに設定します。

### forEach()メソッドを使用して配列の各要素に対して処理を行い、その中でfetch()を呼び出しています。各要素ごとに個別のPOSTリクエストが送信されます。

### レスポンスの処理は前回の回答と同様に行われます。then()メソッドを使用して成功時とエラー時の処理を定義します。

### 上記の例では、JSON-ServerのエンドポイントURLとしてhttp://localhost:3000/your-endpoint を使用しています。実際のJSON-Serverのエンドポイントに応じて適切なURLを指定してください。

### この方法を使用すると、配列の各要素が個別にJSON-Serverに送信され、それぞれが別々のリクエストとして処理されます。
【HTML/CSS用】VSCode拡張機能まとめ

## はじめに
HTML/CSSの基本学習を進める上で便利だったVSCodeの拡張機能をまとめました。
学習前の自分に対して「まずはこれだけ入れておこう」と伝えるスタンスで書いたものです。
日本語化や全角表示、Git関連などの拡張機能は省いています。



## [indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow)

インデントに色を付ける拡張機能です。とても見やすくなります。

![indent-rainbow](https://raw.githubusercontent.com/oderwat/vscode-indent-rainbow/master/assets/example.png)



## [Auto Rename Tag](https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag)

開始タグをリネームしたときに、対応する終了タグも自動的にリネームされる拡張機能です。

例えば、`<div>`タグの名前を`<span>`に変更した場合、通常であれば手動で対応する終了タグ</div>も</span>に変更する必要があります。
しかし、この拡張機能を使うと、開始タグを変更するだけで終了タグも自動的に同時に変更されます。

コーディングの手間が大幅に減り、タグの名前を変えたときのミスを防ぐことができます。


![auto-rename-tag](https://github.com/formulahendry/vscode-auto-rename-tag/raw/HEAD/images/usage.gif)


## [CSS Peek](https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek)

CSS Peekを使うと、HTMLファイル内のクラスやIDに対応するCSSを直接確認したり、必要であればその場で編集することができます。

HTMLファイル上でクラス名やID名を選択し、ショートカットキーを入力すると、該当するCSSスタイルが小さなポップアップウィンドウで表示されたり、CSSの定義に直接ジャンプすることができます。

HTMLとCSSの行き来がスムーズになり、効率よくマークアップできます。



![css-peek](https://github.com/pranaygp/vscode-css-peek/raw/master/readme/working.gif)


## [HTML CSS Support](https://marketplace.visualstudio.com/items?itemName=ecmel.vscode-html-css)

HTMLでクラスやIDを入力する際、CSSのファイルから定義を参照して入力の補完をしてくれます。


## [W3C Web Validator](https://marketplace.visualstudio.com/items?itemName=CelianRiboulet.webvalidator)
HTML と CSS のコードに対して、正しい文法で書かれているかチェックする拡張機能です。

構文エラーや非準拠の部分を特定し、それらを修正することができます。
我流で書き進めて変な癖がついてしまうと後々修正するのが面倒なので、学習の初期段階から導入することをおすすめします。

下図のように指摘してくれます。
![](https://github.com/celian-rib/vscode-webvalidation-extension/blob/main/images/popup.png?raw=true)


## [LIve Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)

HTMLやCSS、JavaScriptなどのファイルを編集した際に、その変更を即時にブラウザでプレビューすることが可能になります。
変更をすぐに視覚的に確認できるため、非常に便利です。
コードの修正とその結果の確認を効率的に行うことができます。

![](https://github.com/ritwickdey/vscode-live-server/raw/HEAD/images/Screenshot/vscode-live-server-explorer-menu-demo-1.gif)




## おまけ ： [Solarized](https://marketplace.visualstudio.com/items?itemName=ryanolsonx.solarized)
最後に、配色テーマです。
好きな系統のカラーなのでこちらのダークを使っています。
![solarized-dark](https://github.com/ryanolsonx/vscode-solarized-theme/raw/master/screenshots/dark-full.png)



## 画像引用元

記事内の各画像は、公式の拡張機能それぞれの紹介ページより引用しました。

- [Extensions for Visual Studio Code
](https://marketplace.visualstudio.com/)



## 終わりに
最後までお読みいただきありがとうございます。

学び始めの方に少しでも参考になれば幸いです。

記事内に不備がありましたら遠慮なくご指摘いただけると嬉しいです。
jmeterで負荷テストをやってみる


### Jmeterとは 
* ホームページ
    * https://jmeter.apache.org/
* Jmeterとは
    * Jmeterで静的や動的リソース、ウェブアプリケーションのパフォーマンスをテストする。これを使用して、サーバー、サーバーのグループ、ネットワーク、またはオブジェクトに対する重い負荷をシミュレートして、その強度をテストしたり、さまざまな負荷タイプの下で全体的なパフォーマンスを分析したりできる。


### Jmeterのインストール
* openjdkのインストール
    * 参照：https://help.rview.com/hc/ja/articles/360018669493--MacOS-OpenJDK%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%96%B9%E6%B3%95
* Jmeterのインストール
    * Apache公式サイトからJMeterのパッケージをダウンロードし、解凍してインストールします。
    * https://jmeter.apache.org/download_jmeter.cgi

### 使い方
* スレッドグループを作成する
    * Test Plan(右クリック) -> Add -> Threads(Users) -> Thread Group
    * スレッドの数を設定する
    * Ramp-upを設定する
    * ループ回数を設定する
![スクリーンショット 2023-06-04 21.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13451/a42ece4f-f39e-eeb8-c139-e4bd0896ab25.png)



* http requestを作成する
    * スレッドグループ(右くりっく) -> Add -> Sample -> Http Request
    * web サーバーの情報を設定する
    * bodyデータを設定する
![スクリーンショット 2023-06-04 21.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13451/750ef570-7e23-005e-fe34-39204afc07db.png)

* Http Header Manager
    * スレッドグループ(右くりっく) -> Add -> Config Element -> Http Header Manager
    * ヘッダー内容を追加する

* listener 
    * スレッドグループ(右くりっく) -> Add -> listener
    * View Results Tree
        * 各リクエストの結果を確認できる
        * 接続設定するときに、使うことを進める
    * Aggregate Report
        * 負荷テスト結果を取得するとき


### Ramp-upの説明, スループット、 90%line、 error(503) 
* Ramp-up
    * テストケースで送信されるリクエスト数の合計は、スレッド数×ループ回数となる。そして各スレッドは、Ramp-upに設定した時間をスレッド数で割った間隔で送信される
* スループット
    * コンピュータやネットワーク機器が単位時間あたりに処理できるデータ量のこと
* 90%Line
    * 全てのリクエストの中に、90%の通信時間を計算する
* error
    * 負荷高い場合は、エラー(503)が返す回数


### スループットの選べる方法 
* 固定なRamp-upにスレッドやループ回数を増やして、スループットが高くなるが、サーバーが503エラーが戻るときにスループットの回数の増えることも停止になる
* そういえば、ramp-upやループ数を固定して、スレッドの数をどんどん増やして、スループットを計算できる
ESLintから学ぶセキュリティ対策

# 環境
ESLint v8.41.0

# 問題発生の経緯
フラグ名が適正かどうかを判定するために hasOwnProperty を使用したところ、ESLintに怒られてしましました。

該当するコードは以下の通りです。

```javascript: 無効なフラグ名がセットされた場合に、検知する処理
function setFlag(flagName) {
  if (!flags.hasOwnProperty(flagName)) {
    console.log(`ERROR:_${flagName} is not a valid flag`);
    throw new Error(`Invalid flag name:_${flagName}`);
  }

  if (flags[flagName]) {
    console.log(`FLAG:_${flagName} is already set`);
    return;
  }

  flags[flagName] = true;
  console.log(`FLAG:_${flagName} is set`);
}
```

「no-prototype-builtins」で怒られたようです。
以下に詳しく書かれています。

https://eslint.org/docs/latest/rules/no-prototype-builtins

詳細を追ってみます。

### エラー抜粋
>一部の Object.prototype メソッドをオブジェクト上で直接呼び出すことを禁止します

>オブジェクトには、Object.prototype の組み込みをシャドウイングするプロパティが含まれる可能性があり、意図しない動作やサービス拒否のセキュリティ脆弱性を引き起こす可能性があります。

>たとえば、Web サーバーがクライアントからの JSON 入力を解析し、結果のオブジェクトに対して hasOwnProperty を直接呼び出すことは安全ではありません。
悪意のあるクライアントが {"hasOwnProperty": 1} のような JSON 値を送信し、サーバーをクラッシュさせる可能性があるためです。

要するに、直接hasOwnPropertyを呼び出す方法では、悪意のあるユーザーによって不正な値が混入される危険性があると言っています。
意図しない動作やサービス拒否のセキュリティの脆弱性を引き起こす可能性があり、最悪の場合はWebサーバーがクラッシュする可能性があります。

このような不正データが入り込む系のリスクはSQLインジェクションの概念とちょっぴり似ているような気がします。

# 正しい使い方
ESLintのドキュメンテーションのRule Detailsに使い方が記載されていました。

```javascript: 誤った記述例
/*eslint no-prototype-builtins: "error"*/

var hasBarProperty = foo.hasOwnProperty("bar");

var isPrototypeOfBar = foo.isPrototypeOf(bar);

var barIsEnumerable = foo.propertyIsEnumerable("bar");
```

```javascript: 正しい記述例
/*eslint no-prototype-builtins: "error"*/

var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");

var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);

var barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar");
```

なるほど、これが正しい使い方ですか。

# 対処法

以下のようにコードを修正することで、ESLintに怒られなくなりました。

```javascript: 正しい記述方法（フラグ名が適正かどうかを判定する処理）
function setFlag(flagName) {
  if (!Object.prototype.hasOwnProperty.call(flags, flagName)) {
    console.log(`ERROR:_${flagName} is not a valid flag`);
    throw new Error(`Invalid flag name:_${flagName}`);
  }

  if (flags[flagName]) {
    console.log(`FLAG:_${flagName} is already set`);
    return;
  }

  flags[flagName] = true;
  console.log(`FLAG:_${flagName} is set`);
}
```
これで、ESLintのルールに沿ったセキュアなコードになりました。

# まとめ
ESLintの警告でリスクを事前に知り、リスク回避することができました。
不正データの混入によるセキュリティ上のリスクを回避するためには、

* そもそも不適切な値が混入する余地のない実装をする
* 適切な入力検証を実施する
* データのサニタイズ処理を実施する

など、不正なデータの混入を防止する対策が必要です。
信頼できないデータを排除し、システムの安全性を確保しましょう。

以上です
nVIDIA Jetson Xaver NX 開発者キットのboot loaderに、シリアル端子から接続してみる。

# Jetson Xavier NX 開発者キットには、シリアル通信の端子がついています。

この端子にはboot loaderの出力がタレ流しになっているし、キー入力も可能です。

boot loaderに接続したからといって何かが出来るわけではありませんが・・・反対に出来ることがあったら知りたかも。

__接続方法__
Jetson Xavier NXのキャリアボード（マザーボードみたいなもの）には、以下のような端子がついています。
ここの、3ピン、4ピン、7ピンを使います。
<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/e91c5727-9dc2-b765-dabb-ecb4a60643c2.jpeg" />

__使うことが出来ない道具__
シリアル通信というと、RC-232Cが思い浮かぶのですが、以下のようなRC-232Cケーブルを買ってくると動作しません。
これは、5V系のものなので、データが化けてしまいます。
間違えて5V系のものを刺したからといって、壊れることはないので心配しないでください。
<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/919f5638-7e47-bff0-b029-18e83edff125.jpeg" />

5V系のものを刺して文字化けしている様子。
<img width="90%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/2e324165-e8e6-8dcb-5f2b-53bb0cb9cce6.jpeg" />

__使える道具__
TTLで 3.3V のものが販売されているので、これを買ってきます。
有名メーカー品のものは販売されていない様子です。
<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/47934b78-9ca4-9600-f6bb-f731f42e7b78.jpeg" />

__構成図__
Windows11のパソコンで作業しましたけれど、Linuxのminicomとかでも大丈夫なんじゃないでしょうか（未確認）。
![NX-1009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/8fce5460-21cf-c072-6954-12c6445b2919.png)

__シリアルケーブルの準備__
前記のとおりのものを使います。
シリアル-USB変換に、PL2303チップを使っているものであれば、Windows11では、microsoftからドライバーが提供されていました。
（つまり、刺せば動く）
以下、Windows11のデバイスマネージャーで、ケーブルが認識されている様子。
![1000q.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/1d41532f-19d2-cbf6-b43a-030e530287e0.png)

__シリアルケーブルの接続__
Jetson Xavier NXのキャリアボードの裏にプリントされているのでその通りですが。
3ピンのUART RXD には、USBケーブルのTXを刺します。
4ピンのUART TXD には、USBケーブルのRXを刺します。
7ピンにGNDを刺します。
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/5703114f-85f8-c6ab-4808-55b3bcc29707.jpeg)

![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/36138a13-a9fd-77fc-357e-c4b87a4b55e9.jpeg)

TX/TXD(送信)と、RX/RXD(受信)を逆にするのは、シリアル通信のお約束。
USBケーブルの送信を、ボードの受信につなぐという考え方です。
TX/RXは、間違えても壊れません。

__Tera Termの設定__
Tera Termの起動では、シリアルを選びます。
COMポートは、インストール状態によって変わります。
![1000K.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/cec5b2fc-a92a-b754-cecb-1990562eb0d8.jpeg)

シリアルの設定を行います。
![1000L.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/51978992-ab45-99d6-d6ec-8768524c2a4c.jpeg)

シリアルの設定を行います。
速度は、115200 bps, 8bit, non parity, stop bit=1, Flow制御=ナシです。 
![1000M.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/fcc36047-0f86-56c1-d7cd-2da8a3664ee9.jpeg)

以上で、電源投入すれば、データが表示されますし、入力もできます。
![1000P.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866173/f2354190-dfbb-c849-aa4b-b337fdbcc3f7.jpeg)

以上です。
Vimの基本操作まとめ

### 初めに
自分を含めた初学者に向けて、Vimの基本コマンドをまとめました！参考になったら嬉しいです。

### Vimとは
まずVimとは`テキストエディタ`のことで、ターミナル上で以下のコマンドを実行することで起動することができます。ファイル名を指定しなかった際は、保存時にファイル名を指定すれば保存可能です。
```ruby:
$ vim [ファイル名]
```
### 基本のモード一覧
**ノーマルモード**を起点として各モードに遷移することができます。
| モード | コマンド | 機能 |
|:-:|:-:|:-:|
|ノーマルモード|`esc`|移動、貼付、削除|
|入力モード|`i`,`a`|ファイルの編集|
|ビジュアルモード|`v`|範囲選択|
|コマンドモード|`:`|変更の保存、終了|

### 保存・終了コマンド
|コマンド|動作|
|:-:|:-:|
|`:w`|上書き保存|
|`:w ファイル名`|名前をつけて保存|
|`:q`|終了|
|`:wq`|保存して終了|
|`:q!`|強制終了|

:::note warn
 よくわからなくなったら「`ets`」でノーマルモードに戻り、「`:wq`」で保存して終了、もしくは「`:q!`」で保存せずに強制終了しましょう！
:::

### 移動コマンド
|コマンド|動作|
|:-:|:-:|
|`h`|←左に移動|
|`j`|↓下に移動|
|`k`|↑上に移動|
|`l`|→右に移動|

#### 一気に移動する場合
|コマンド|動作|
|:-:|:-:|
|`0`|先頭へ移動|
|`$`|行末へ移動|
|`:1`,`gg`|ファイルの先頭へ移動|
|`G`|ファイルの最後へ移動|
|`ctrl+o`|移動前の場所へ戻る|




### 削除コマンド
|コマンド|動作|
|:-:|:-:|
|`x`|1文字削除|
|`dd`|1行削除|
|`dw`|単語単位で削除|
|`数字+dd`|(数字)分の行削除|

### コピペコマンド
|コマンド|動作|
|:-:|:-:|
|`yy`|1行コピー|
|`p`|下にペースト|
|`P`|現在の行にペースト|
|`数字+yy`|(数字)行分のコピー|
### やり直し系
なんかミスったなと思ったらとりあえず戻りたい操作回数分「`u`」を押し、戻しすぎたら「`ctrl+r`」を使えばどうにかなる気がします！
|コマンド|動作|
|:-:|:-:|
|`u`|変更を前に戻す|
|`ctrl+r`|戻しすぎた分の取り消し|

### その他
行頭に行番号を追加すると見やすくなります。
|コマンド|動作|
|:-:|:-:|
|`:set number`|行番号を追加する|
|`:数字`|(数字)行目に移動する|



### 参照サイト
- [現役シリコンバレーエンジニアが教えるNeoVim(Vim)+Tmux+Zsh入門 - Udemy](https://www.udemy.com/course/vim-tmux-zsh/)
- [Vimの4つのモードを使いこなす - Zenn](https://zenn.dev/mo_ri_regen/articles/vim-four-modes)
- [Vimモード入門 - Qiita](https://qiita.com/gorilla0513/items/e8ccb15bfc87e7ed8d5b)