OmniAICreator/Qiita-1.07M huggingface dataset:
社内勉強会で生成AIについて発表したので70ページの資料を公開する！

## 前置き
毎週金曜日夕方に行われる社内勉強会にて、先日生成AIについて発表しました。折角なので少し加筆修正した資料を公開します。進化のスピードが早く、一時期食傷気味に陥ってましたが改めて昨今の生成AI関連の基本となるインプットを目指しました。

※資料内冒頭に記載してますが、AIの専門家ではないので認識や説明に誤りがある可能性があります。

:star:**当方も勉強中なので、「ここ違うよ」や「これの説明もあるといいんじゃない」など様々なコメント大歓迎です！**

## 資料

<script defer class="speakerdeck-embed" data-id="6c983c8899814f20855ef28dc587ad6a" data-ratio="1.77725118483412" src="//speakerdeck.com/assets/embed.js"></script>

## 資料目次
- AIの基本
    - 機械学習について
    - 深層学習について
    - 機械学習の種類
    - 教師あり学習の得意なこと
    - 教師あり学習のイメージ
    - 教師なし学習の得意なこと
    - 教師なし学習のイメージ
    - 強化学習の得意なこと
- 生成AIについて
    - 生成AIとは
    - 生成AIの位置付け
    - 生成AI利用例
    - 代表的なサービス例
    - 日本における盛り上がり
    - 生成AI市場規模
    - AGIとは
    - AGIは近い？
- GPTについて
    - GPTとは
    - Transformerとは
    - GPTシリーズの歴史
    - LLMにおける性能
    - パラメータ数比較
    - Tempreratureとは
    - トークンとは
- ChatGPTを活用
    - ChatGPTの活用
    - プロンプトエンジニアリング
    - Zero-Shot Prompting
    - One-Shot Prompting
    - Few-Shot Prompting
    - Chain-of-thought
    - ChatGPTで気をつけること
- LLMを使った開発
    - 3つのロール
    - Embedings(埋め込み)とは
    - Fine-Tuning(微調整)とは
    - プロンプトインジェクション
    - プロンプトインジェクション例
    - プロンプトインジェクション対策
    - OpneAIブランドガイドライン＆利用ポリシー
    - ReActとは
    - LangChain
    - LlamaIndex
    - guidance
    - Semantic Kernel
    - Pinecone
    - Hugging Face
    - ChatGPT Plagin
    - 自律型エージェント

## 終わりに
社内での発表は半年振りくらいで、勉強会に向けて資料を作る過程であれも必要だよなこれもあるといいよなと色々思い出しては理解が追い付いていない要素の多さに目眩がしそうになりました。改めて調査したものや、この後にじっくりと動かしては違いを把握したいなど、モチベーションが高まったのでより理解が深まったタイミングで何かしらでアウトプットしていきたいと思います。

----
弊社でQiitaEngineerFesta2023の記事投稿キャンペーンを実施してます。
参加＆投稿お待ちしております！

https://qiita.com/official-events/0cc35c4799f72609b7ec
【Bash MySQL】クエリの速度調査

## クエリの速度調査

`変更箇所`と記載されたところを各々書き換えれば、いい感じに速度調査できるはず。

```sh:sample.sh
#!/bin/sh

# MySQLの設定（変更箇所）
user="root"
pass="password"
endpoint="ここにエンドポイント"
database="sample_database"

# 実行したいクエリのパス（変更箇所）
query_path="./sample.sql"

# 同時に実行するクエリの数（変更箇所）
count=1

# 開始時刻計測
start_time=`date +%s.%N`

for i in $(seq 1 ${count}); do
  # バックグラウンドでクエリを叩く
  echo `mysql -u${user} -p${pass} -h${endpoint} ${database} < "${query_path}"` &
done

# 全ての処理が終わるまで待つ
wait

# 終了時刻計測
end_time=`date +%s.%N`

elapsed_time=$(echo "${end_time}" - "${start_time}" | bc)
echo "経過時間: ${elapsed_time}(s)"
```

以下は、スクリプト内で呼び出されるクエリ（調査対象）

```sql:sample.sql
SELECT SQL_NO_CACHE * FROM テーブル名;
```

`SQL_NO_CACHE`とは、クエリキャッシュを無効化してくれる便利なやつ（以下を参考に）

https://qiita.com/dev_makino/items/8ab5804e455d9191e353
【Trailhead】Salesforceの学習の道程

学生の頃からFortranをメインにしていた物理の数値計算野郎だった私ですが、Salesforceに携わる生活を新卒の頃に始めることになりました。
TrailheadはSalesforceを学ぶ際に出会い、~~Fortranを書きたい発作を抑えて~~Salesforceの学習に勤しんだ結果として、Trailheadの学習が一段落ついたことやSalesforceの認定資格をいくつか取れたことで、良いタイミングなのでこれまでの学習の道程をまとめておこうかと発起しました。

本記事では、私のTrailheadの実施履歴とSalesforceの資格取得履歴をまとめています。
このような輩もいるんだと思ってもらえれば良いです。

## 学習の道程
#### 2020年10月 ~ 2020年12月
https://qiita.com/HNakazawa/items/cfa87c5b26ce07486bd6
#### 2021年01月 ~ 2021年03月
https://qiita.com/HNakazawa/items/e3f991f3e8b9ea516f0e
#### 2021年04月 ~ 2021年06月
https://qiita.com/HNakazawa/items/3f90956d8bdbba37457d
#### 2021年07月 ~ 2021年09月
https://qiita.com/HNakazawa/items/100291c3b34e8dd5b42c
#### 2021年10月 ~ 2021年12月
https://qiita.com/HNakazawa/items/d6a1a21c3f439e1f4bde
#### 2022年01月 ~ 2022年03月
https://qiita.com/HNakazawa/items/8320da2ac755da1b9ed8
#### 2022年04月 ~ 2022年06月
https://qiita.com/HNakazawa/items/12a7998046297bc618cb
#### 2022年07月 ~ 2022年09月
https://qiita.com/HNakazawa/items/3fabb9929bed1833fa9c
#### 2022年10月 ~ 2022年12月
https://qiita.com/HNakazawa/items/4402eef7540c8834986b
#### 2023年01月 ~ 2023年03月
https://qiita.com/HNakazawa/items/5caa57977e2b0e754ce8
#### 2023年04月 ~ 2023年06月
https://qiita.com/HNakazawa/items/b72556033830d57fdfc1
#### 2023年07月 ~ 2023年09月
https://qiita.com/HNakazawa/items/300d781f012841d248c9
#### 2023年10月 ~ 2023年12月
https://qiita.com/HNakazawa/items/15766222b7258d7af737
#### 2024年01月 ~ 2024年03月
https://qiita.com/HNakazawa/items/637330107e55b9e535f4
#### 2024年04月 ~ 2024年06月
https://qiita.com/HNakazawa/items/a33b457da734f1159ade
#### 2024年07月 ~ 2024年09月
https://qiita.com/HNakazawa/items/1a2e595c3de1ff9cffb9
#### 2024年10月 ~ 2024年12月
https://qiita.com/HNakazawa/items/9fa7a032eb43b9161738
#### 2025年01月 ~ 2025年03月
https://qiita.com/HNakazawa/items/c333d07e50a338225e87
スプレッドシートに新しい行が挿入されたとき、1行上に設定されている関数を適用するスクリプト(GAS)

フォームの回答などをGoogle Spreadsheetで受け取ると、最終行に新しく1行追加されますが、関数を設定していても新しい行に関数が適用されたりはせず、関数が入っていないまっさらな行として挿入されています。

ちょっとしたRPAであれば、自動で関数が適用されるだけでスクリプトに頼らなくて良くなるシーンもこれまでありましたので、

- 最終行までのセルをチェック
- 1行上に関数が入った行があれば、同じ関数を該当のセルに適用

を行うスクリプトを用意し、シートの変更をトリガーに起動させることで、常に関数が設定された状況を作ります。

## 仕組み
|  | A | B | C |
|:-:|:-:|:-:|:-:|
| 一行目 | 5 | 4 | =SUM(A1:B1) |
| 二行目 | 3 | 2 | =SUM(A2:B2) |

例えば、C1C2セルにSUM関数が使われていた場合、
三行目が追加された際に、A3B3セルには数値が挿入されてもC3セルには関数は適用されません。

そこで、A-Zのアルファベット一文字と数値の組み合わせを探して、数値を置換します。

正規表現で `/[A-Z]\d+/g` に合致した文字列だけを、

```
var letter = match.substring(0, 1);  // アルファベット部分を取得
var number = parseInt(match.substring(1));  // 数字部分を取得し、整数に変換
return letter + (number + 1);  // 数字部分に1を足して結合する
```

という感じで処理する形にしてみました。

`C3` → `C4`
`D13` → `D14`
`AA24` → `AA25`（処理しているのは`A24`→`A25`部分のみ。）

絶対参照を行っている場合は、`$A$3`という記述になっているため、
置換対象の文字列から外れます。


:::note warn
懸念として、フリーフォームのテキストの結合を関数で行っている場合等で、意図しない置換が発生してしまう可能性があります。
:::

かっちり運用のRPAを組みたいなら普通にスクリプト組むべきだと思います。

## スクリプト
```
function insertFormulasAndCheck() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  const trigger_check = sheet.getRange("A2").getValue();

  // A2がTRUE（チェック済み状態）になっているシートのみ実行対象にする
  if (trigger_check == true) {/*そのまま実行*/}else{return /*スプリプト終了*/};
  
  // 最後の行と最後の列を取得
  const lastRow = sheet.getLastRow();
  const lastCol = sheet.getLastColumn();

  // A列の値をチェックして関数挿入済みか判定するので、A列は"関数挿入判定列"とか"Check"とか名前をつけて、開けておいてください。
  var checkCells = sheet.getRange(1, 1, lastRow).getValues();

  for (var row = 2; row <= lastRow; row++) {  // 最初の行はヘッダー行を想定しているため無視します
    if (checkCells[row-1][0] !== true) {  // A列がtrueでなければ実行
      for (var col = 1; col <= lastCol; col++) {
        // 1行上のセルから関数の取得
        var sourceCell = sheet.getRange(row - 1, col);
        var formula = sourceCell.getFormula();
    
        // 関数が空でない場合のみ、書き換えを行う
        if (formula) {
          // 関数内の"A1"（や"B2", "C3"など）を"A2"（や"B3", "C4"など）に置き換える
          var newFormula = formula.replace(/[A-Z]\d+/g, function(match) {
            var letter = match.substring(0, 1);  // アルファベット部分を取得
            var number = parseInt(match.substring(1));  // 数字部分を取得し、整数に変換
            return letter + (number + 1);  // 数字部分に1を足して結合する
          });
      
          // 新しい関数を現在の行のセルに書き込む
          var targetCell = sheet.getRange(row, col);
          targetCell.setFormula(newFormula);
        }
      }

      // 更新が完了したので、A列にチェックボックスを追加
      sheet.getRange(row, 1).insertCheckboxes().setValue(true);
    }
  }
}
```

## 注意点
A列を、処理を行ったか判別するための列として使用しています。

毎回全セルをチェックしていると莫大な実行時間がかかってしまい、実行時間制限に引っかかるためです。

A列は「Check」とか名前をつけて、そっとしておいてあげてください。
【Salesforce認定資格】Salesforce Certified Data Architectの受験結果

※本記事は2023年6月に受験した「Salesforce Certified Data Architect」の振り返りを記載しています。

## はじめに
アーキテクト資格の受験のためのバウチャーコードが手に入ったので、アプリケーションアーキテクト資格を取得するために、残っていた資格に挑戦しました。

## 試験結果
結果は __「合格」__ でした。
試験に関しては時間は余裕があり、3回見直しをしました。

| 受験料 | 試験時間 | 設問数 | 合格ライン | | 受験日 | 正答率 | 所要時間 |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| 40,000円 | 105分 | 60問 | 58% | | 2023/06/23 | 94.90% | 64分 |

内訳を見ると、データガバナンスの範囲の点数が低いので、しっかりと復習する必要がありそうです。

| 試験内容 | 内訳 | 設問数 | | 正答率 |
| :-- | :-: | :-: | :-: | :-: |
| データモデリング/データベースデザイン | 25% | 15.0問 | | 100% |
| マスタデータ管理 | 5% | 3.0問 | | 100% |
| SALESFORCEデータ管理 | 25% | 15.0問 | | 100% |
| データガバナンス | 10% | 6.0問 | | 67% |
| 大量データに関する考慮事項 | 20% | 12.0問 | | 91% |
| データ移行 | 15% | 9.0問 | | 100% |

![Salesforce_Certified_Data_Architect_01_テスト結果詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/12b38760-e01c-1cf9-462d-80d6cadccc17.png)

## 学習方法
LDVについての学習をする必要があったので、[公式ドキュメント](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_large_data_volumes_bp.meta/salesforce_large_data_volumes_bp/ldv_deployments_introduction.htm)を読み込むことを中心に学習し、SoR・MDM・SSOTについての学習は直前に[Salesforce Developers Japanの動画](https://www.youtube.com/watch?v=MfS8gxmsDCI)を見て押さえました。
また、Trailheadのアーキテクトジャーニーで紹介されているページを読み込みました。

https://trailhead.salesforce.com/ja/users/welcome4/trailmixes/architect-data-architecture-and-management-ja

全体を通しての資格に向けた学習時間は7時間程度でしたが、試験中はもっと学習しておくべきだったと後悔していました。

## 学習の意識付け
私は[Salesforce Developers Japanの動画](https://www.youtube.com/watch?v=MfS8gxmsDCI)を知るタイミングが遅くて直前になってしまいましたが、始めに見ておくことをお勧めします。
私はドキュメントを端から読み進めるような学習をしましたが、動画を見ておくことで要点が押さえられ、学習の効率が上がるかと思います。
外部データとの連携の経験がなければ、Herokuを使えば外部オブジェクト等の連携の確認ができるのでお勧めです。
私はTrailheadでHerokuの環境を作っていたので、流用して学習していました。

https://trailhead.salesforce.com/ja/content/learn/modules/salesforce_heroku_integration?trailmix_creator_id=strailhead&trailmix_slug=prepare-for-your-heroku-architecture-credential
Powerlevel10kで仮想環境にいるかどうか分かりやすくする

# 仮想環境内にいるということを明示する
Pythonで開発を行う際，仮想環境を用いることが多々あると思います．時々，仮想環境内にいるのかいないのかわからなくなることがあったので，[Powerlevel10k](https://github.com/romkatv/powerlevel10k)上に仮想環境にいるのかいないのかを表示する方法を書き残したいと思います．

# 表示例
## 設定前
![Screenshot 2023-06-28 at 0.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563637/2e273d92-3d48-2d98-0fb2-416ca171ed4f.png)

## 設定後
![Screenshot 2023-06-28 at 0.17.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563637/fe1a88c0-4cd3-6ef6-1c86-0c820eadfd27.png)

## 違い
右側に表示されているPythonのバージョンの左側に仮想環境名が表示されるようになります．

# 設定方法
ホームディレクトリ(`~/`)にある`.p10k.zsh`を以下のように編集します．

これを...
```.p10k.zsh
# If set to "false", won't show virtualenv if pyenv is already shown.
# If set to "if-different", won't show virtualenv if it's the same as pyenv.
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=false
```
こう．
```.p10k.zsh
# If set to "false", won't show virtualenv if pyenv is already shown.
# If set to "if-different", won't show virtualenv if it's the same as pyenv.
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_WITH_PYENV=if-different
```

# 問題点
ディレクトリ名 + ランダムな9文字が表示されるため，幅が足りなくなると非表示になってしまいます．
owasp zapについて

# 脆弱性診断のツール
***
## 無料
## そこそこ優秀
## 簡単

***

# 使い方
***
## 1. owaspzapをインストール
***
## 2. ローカルプロキシの設定（owaspzap側とブラウザ側の両方）
***
## 3. 診断する項目と強度（低、中、高）を設定
***
## 4. ローカルプロキシを設定したブラウザで診断したいURLにアクセス
***
## 5. 診断対象のURLをコンテキストに含める
***
## 6. 診断を開始する
***


# ポイント
・静的診断と動的診断があり、それぞれに診断項目が用意されている

・診断ロジックの関係により、誤判定がある

***

# やってはいけないこと
・本番環境で実行しない。

・公開されているwebサイトに対して勝手に実施しない。
RubyとPythonの基本的な書き方の差まとめ

#### 言語が変わると書き方もちょっと変わる。RubyとPythonのよく使う基本的な書き方について、違いをまとめて見ました。

### 文字列の出力
Python
```python
print("Hellow World")
```
Ruby
```ruby
puts "Hello World"
```
### ターミナルでの入力を受け取る
Python
```python
x = input("入力してください")
```
Ruby
```ruby
puts "入力してください"
x = gets
```
### 変数の型変換（文字列から整数）
Python
```python
string_x = "1"
integer_x = int(string_x)
```
Ruby
```ruby
string_x = "1"
integer_x = string_x.to_i
```

### 変数展開
Python
```python
name = "Suzuki"
age = 18
# 書き方1
print(f'私の名前は{name}です。年齢は{age}歳です')
# 書き方2
print('私の名前は{}です。年齢は{}歳です'.format(name, age))

```
Ruby
```ruby
name = "Suzuki"
age = 18
puts "私の名前は#{name}です。年齢は#{age}歳です"
```
### 条件分岐
Python
```python
x = int(input())
if x % 15 == 0:
    print(f'{x}は15の倍数です')
elif x % 3 == 0:
    print(f'{x}は3の倍数です')
elif x % 5 == 0:
    print(f'{x}は5の倍数です')
else:
    print(f'{x}は3の倍数でも5の倍数でもないです')
```
Ruby
```ruby
x = gets.to_i
if x % 15 == 0 #thenは省略
    puts "#{x}は15の倍数です"
elsif x % 3 == 0
    puts "#{x}は3の倍数です"
elsif x % 5 == 0
    puts "#{x}は5の倍数です"
else
    puts "#{x}は3の倍数でも5の倍数でもないです"
end
```

### 繰り返し処理
Python
```python
for i in range(100):
    print(i)
```
```python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in numbers:
    print(number)
```
Ruby
```ruby
100.times do |i|
    puts i
end
```
```ruby
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers.each do |number|
    puts number
end
```

### 論理演算子（かつ、または、否定）
Python
```python
# a > 0 かつ b > 0
a > 0 and b > 0

# a > 0 または b > 0
a > 0 or b > 0

# a > 0 ではない
not a > 0
```

Ruby
```ruby
# a > 0 かつ b > 0
a > 0 && b > 0

# a > 0 または b > 0
a > 0 || b > 0

# a > 0 ではない
!(a > 0)
```
【Salesforce認定資格】Salesforce Certified Associateの受験結果

※本記事は2023年2月に受験した「Salesforce Certified Associate」の振り返りを記載しています。

## はじめに
新しくリリースされたアソシエイト資格を話のタネに受験しました。

## 試験結果
結果は __「合格」__ でした。
試験に関しては時間は余裕がありましたが、悩む内容がなかったので見直しはしませんでした。

| 受験料 | 試験時間 | 設問数 | 合格ライン | | 受験日 | 正答率 | 所要時間 |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| 10,000円 | 70分 | 40問 | 62% | | 2023/02/11 | 100.00% | 14分 |

満点でした。

| 試験内容 | 内訳 | 設問数 | | 正答率 |
| :-- | :-: | :-: | :-: | :-: |
| Salesforceエコシステム | 32% | 12.8問 | | 100% |
| ナビゲーション | 28% | 11.2問 | | 100% |
| データモデル | 25% | 10.0問 | | 100% |
| レポートとダッシュボード | 15% | 6.0問 | | 100% |

![Salesforce_Certified_Associate_01_テスト結果詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/4ef35fcb-444d-4725-d898-078321a4a552.png)

## 学習方法
アドミニストレーター資格よりも簡単ということで、試験ガイドを読むだけで受験に臨みました。

## 学習の意識付け
Salesforceエコシステムについては、存在を知らなければならないものもあるので、Salesforce界隈のコミュニティやサイトについては知っておく必要がありましたが、大体のサイトがTrailheadから見れるため、Trailheadのサイト徘徊をしておけば何とかなります。
他の範囲については、Salesforceに触れていれば解けるため、Salesforceの実機で色々と触ると良いかと思います。
Amazon.comアカウントとAWSアカウントが紐づいている時代があったって話

過去、AWSアカウントを発行すると、裏でAmazon.comアカウント（Amazon.comでお買い物するアカウント）も作成されて、このアカウント情報が紐づいてしまうといった時代がありました。

このアカウントが紐づいてしまう状態。

2017年8月10日以降に作成されたアカウントでは解消されたようです。
（この日付について何かしらの公式ドキュメント上で記載はないようですが、フォーラムやre:PostでAWSサポートの人が情報を投稿していた）

それ以前に作成されたAWSアカウントでは、

- AWSのルートに登録したメールアドレスでAmazon.comにログインできたり。
- AWS側で登録したカード情報が、Amazon.comに登録されていたり。
- AWSアカウント側で設定変更を行ったら、Amazon.comアカウント側にも反映されたり。（メールアドレスとかパスワードとか）
- Amazon.comアカウント側で設定変更を行ったら、AWS側にその設定が反映したり。

情報が共有されて厄介な事になるケースがありました。

ここらへんの問題について、以前はAWSフォーラムに投稿されており。（現在は削除）

[https://forums.aws.amazon.com/thread.jspa?threadID=85882](https://forums.aws.amazon.com/thread.jspa?threadID=85882)

こちらの投稿をたまに覗いては、これにハマると大変そう……といった感想をもっていました。

AWSとAmazon.comのアカウントの紐づけを解除するには、最終的にはアカウントを新規に発行して、移行するといった解決策しかないみたいな感じだったかと思います。

AWSフォーラムはAWS re:Postに統合するにあたって、上記記事は削除されてしまっており。
この問題がその後どうなったかが気になっていましたが。

AWS re:Postでこの件に言及している投稿があったので忘備録。

以下、AWS re:Postの投稿。

[How can a root-AWS account be decoupled from an Amazon.com retail account?](https://repost.aws/questions/QU7G1Nr9gsTuGzt0yUe7Z3qw/how-can-a-root-aws-account-be-decoupled-from-an-amazon-com-retail-account)

## 関連する投稿

下記のRedditの記事だったり。

[Decoupling legacy AWS accounts from Amazon.com retail accounts](https://www.reddit.com/r/aws/comments/lllqof/decoupling_legacy_aws_accounts_from_amazoncom/)

下記のような小話があったり。

https://twitter.com/QuinnyPig/status/1275137983109308419

[Whiteboard Confessional: Help, I’ve Lost My MFA Device!](https://www.lastweekinaws.com/podcast/aws-morning-brief/whiteboard-confessional-help-i-ve-lost-my-mfa-device/)

ここらへんを見ると、どんな事が起きていたかはわかるかと思います。

## で、re:Postの投稿をみるとこの件、解決に向けてうごいてはいるらしい

2023年現在。

AWS re:Postの記事にAWSサポートの方の解答を読むと、現在も対応中との事がわかります。

また改めてここらへんの情報を検索した所。　下記のようなツイートもありました。

https://twitter.com/henrykploetz/status/1589917382449201152

このツイートにあるメールが来ている状態ならば、Amazon.comアカウントとAWSアカウントの紐づけが解除されていて、パスワード変更を行っても変更が共有されず。
それぞれのアカウントに情報を設定できるようです。

ちなみにこのツイートを見てから所有している古いAWSアカウントのルートアカウントに登録しているメールを確認してみましたが、同じメールが届いてました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d72b6ccc-1f7d-6e2c-24c3-0d80c8396037.png)

## 総評

業務利用しているアカウントが、これにハマっていたら……と想像するとなかなか辛い気持ちになりますが。

2017年8月10日以前に作成されたアカウントに関わるなんて際には少し気にしておきたい情報ではあります。
Eclipse　リファクタリング機能

## Eclipse リファクタリング機能


- **メソッドのリネーム（Rename）**
メソッドの名前を変更する
→すべての呼び出し箇所も自動的に更新される

- **フィールドのリネーム（Rename）**
フィールドの名前を変更
→すべての参照箇所も更新される

- **ローカル変数の抽出（Extract Local Variable）**
コード内の一部をローカル変数として抽出することができる
→重複を減らしたり、可読性を向上できる

- **メソッドの抽出（Extract Method）**
メソッド内の一部のコードを新しいメソッドとして抽出できる
→コードの再利用性を高めたり、メソッドの責務を明確化できる

- **パラメータの導入（Introduce Parameter）**
メソッドに新しいパラメータを追加できる
→メソッド間のデータの受け渡しを柔軟に行える

- **インライン化（Inline）**
メソッドや変数の使用箇所をインライン化できる
→不要なメソッド呼び出しや変数参照を削除できる

- **メソッドの移動（Move）**
メソッドを別のクラスに移動できる
→関連するメソッドをまとめたり、クラスの構造を整理できる

### リファクタリング機能参照方法
コードの右クリックメニュー
ショートカットキー（Alt + Shift + T）
【Python】`001_sample.json`と同じ中身のファイルを100個、連番で瞬時に作成する方法

# 概要
- `001_sample.json`というファイルがあったとします。中身を全く同じ状態のまま、`100_sample.json`までファイルをコピー＆連番で命名させる方法を紹介します。

# サンプルコード解説

- サンプルコードでは、`shutil`モジュールを使用してファイルのコピーを行います。

```sample.py
import shutil

# ファイルのコピー元とコピー先のパスを指定
source_file = "001_sample.json"
destination_directory = "./"

# 100回ループしてファイルをコピー
for i in range(2, 100):
    # コピー先のファイル名を生成
    destination_file = f"{str(i).zfill(3)}_sample.json"
    # ファイルをコピー
    shutil.copyfile(source_file, destination_directory + destination_file)
```

- `source_file`変数に元となるファイルのパスを指定
- `destination_directory`変数にコピー先のディレクトリのパスを指定（この例ではカレントディレクトリ）
- 1から100までの範囲でループを回し、`f"{str(i).zfill(3)}_request.sh"`を使用してコピー先のファイル名を生成
    - `zfill(3)`は、生成されるファイル名が常に3桁のゼロパディングされることを保証
- 最後に、`shutil.copyfile`を使用してファイルをコピー。

## 備忘録
- `os`モジュールを使用する方法もあると思います。
- `shutil.copyfile()`関数は、ソースファイルと宛先ファイルのパスを指定するだけで、簡単にファイルをコピーできるのが良いですよね。パスの組み立てやファイルのオープン・クローズなどの手間が不要です。
27歳総務職　WEBエンジニア目指すため勉強内容を記録していく②

【勉強内容】
Progate　HTML & CSS 学習レッスン 中級編
１～７まで

所感
・細分化されているとわからないとこが多い
　（link rel＝ ？　href?　仕組みが分かっていない）
・手を動かすだけになっている気がする
・追加で書籍購入検討
DockerでMySQLにログインする


①MySQLが載っているコンテナのIDを調べる（↓して一番左にでてくる）
※名前はdocker-compose.ymlで調べられる
~~~
docker ps -a
~~~

②上記コンテナを起動する
~~~
docker start CONTAINER ID
~~~

③入室いたす
~~~
docker exec -i -t CONTAINER ID bash
~~~

④MySQLにログイン
※パスロードとユーザ名は.envに記載あるとおり（DB_USERNAME/PASSWORD）
~~~
 mysql -u USERNAME -p PASSWORD
~~~

完了！
【HTML/CSS】セーフエリアに対応する方法

## はじめに

PWAで`"display": "standalone"`とした場合に、画面下端に配置したボタンとホームバーが重なってしまうことがあります。

![IMG_6AF350887619-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/c9d1d6c2-7ec4-9121-573d-976715758034.jpeg)

これを改善する方法について記載します。

## ビューポートのメタ値を追加する

HTMLのメタタグに`viewport-fit=cover`を追加します。

```html
<meta name="viewport" content="viewport-fit=cover" />
```

## CSSで余白を追加する

余白が必要な要素に以下を設定します。

```css
.sample {
  padding-bottom: env(safe-area-inset-bottom);
}
```

すると以下のようにボタンの下に適切な余白ができます。

![IMG_1077BAF91629-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/6d87b2f4-4a15-3607-817c-f9ce4972a120.jpeg)

画面を横向きにした際にアイコンなどがノッチに重なるのを避けるには以下のようにします。

```css
.sample {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}
```

## 参考

https://developer.mozilla.org/ja/docs/Web/CSS/env
「覚えてないです」といってもいいが、「だと思います」と言ってはいけない。

# 曖昧な言葉はやめよう
## あったこと
（会議中）
私：「あれ、バックで動くこの処理を変更したら画面に影響でますかね。後輩くん、画面の処理作ってくれたと思うけど影響あるかな？」

後輩くん：「おそらく影響はないと思います」

私：（本当かな・・・）

## 言いたいこと
「おそらく」や、「思います」という言葉は、聞く人を不安にさせてしまいます。
私も新人のころ注意されまくったのですが、今回これらの言葉を受け取る側になって身に沁みました。
とはいえ、自分が昨日書いた処理ですら忘れてしまうことは多々あります。
その時は、遠慮せず **「覚えていない」** と言って大丈夫です。
なぜなら、上記のような場合、一番確認したいのはあくまで処理がどうなっているかであるからです。分からないことへの責任は気にしてません。
なので、覚えていなければ覚えていない、分からなければ分からないと、はっきりいいましょう！
私も、後輩が安心して分からないと言えるような環境を作っていきたいです。
URL置換のブックマークレットをclass構文で書いてみた

URLを一部置換するブックマークレットを作ってみました。
javascript:の後に設置すると動きます。
prodとtestを任意の値に変更で色々使い回し可能かと思います。

```javascript
class ChangeUrl{
  constructor(){
    this.area = location.href;
    this.test = 'test';
    this.prod = 'prod';
    this.onChange();
  }
  onChange(){
    if(this.area.indexOf('test')>0){
      location.href = this.area.replace(/test/g, 'prod');
    }else if(this.area.indexOf(this.prod)>0){
      location.href = this.area.replace(/prod/g, this.test);
    }
  }
}
new ChangeUrl();
```

■わからないとき検索すると幸せになれる単語たち
class構文/正規表現/indexOf()

■目に見えて便利を実感できるので、コード書く練習にブックマークレットは良いですね。
レガシーな開発環境と向き合うエンジニアのキャリアプラン

## はじめに
「エンジニアキャリアについてあなたの考えをシェアしよう！」のキャンペーンに触発されてキャリアについて考えてみました。

この文章で私が「レガシーな開発環境」と表現している部分について一つ補足を加えておきたいと思います。
レガシーなシステムや技術スタックが悪いというわけではありません。それらは長い時間を経て築き上げられ、多くのビジネスを支えてきた証です。
私が「レガシー」と感じる部分は、自身のスキルセットが現代の新しい技術トレンドから取り残されているという自己認識によるものです。

私の現状と目指す方向について、以下で詳しく説明していきます。

## 自己紹介
新卒２年目のエンジニアで、PHPをメインに開発しているバックエンドエンジニアです。

## 「キャリアプラン」について思い浮かんだこと
キャリアプランについて考えてみて、思い浮かんだことを書いてみます。
- キャリアの悩み
- 将来エンジニアとしてどうなりたいか
- 叶えたいキャリアに対して、どういう行動をしているか
- キャリアに対しての自分が感じる劣等感
- キャリアとは別にエンジニアとして成し遂げたいこと

ここで挙げたことを見出しとして、それぞれについて書いていきます。

## 現在のキャリアへの悩み
### 現在の仕事とレガシーな開発環境
現在は２社目の会社で受託開発をしています。
1社目から共通してPHPとJQuery、HTML,CSSを使った開発の経験が多く、レガシーな開発環境に携わっていると感じています。
「モダン」といわれているような環境からはかけ離れており、現在の仕事では技術的な成長に繋がる環境に身を置けていません。

### 技術的な実力不足
現状の自分の技術スタックがレガシーなものに偏っていることもあり、弱いと感じています。
業務で利用したことがあるものを列挙すると以下のような感じです。
- PHP
  - Laravel
  - CakePHP
  - Smarty
- JavaScript
  - JQuery
- AWS
  - EC2
  - CloudFront
唯一、Laravelが使えているのはいいところですが、大規模なプロジェクトでの経験ではないので微妙、悩ましいと感じます。

## 将来エンジニアとしてどうなりたいのか
個人的に技術に触るのが好きで個人開発や勉強をやっている部分があるので、技術的な専門知識を持ちつつも、チームメンバーの技術的な課題を解決し、プロジェクトを成功に導くテックリード（リードエンジニア）になりたいと考えています。
ここで自分が言っているテックリードのイメージは以下の記事のものです。
[テックリードという役割](http://bit.ly/44hj3dH)

## 叶えたいキャリアに対して、どういう行動をしているか
テックリードの立場になるために最低限、技術的な面での成長と、チームに対する影響を与えられるようになることが必要だと考えます。
技術のインプット・アウトプットの量を増やすことを意識しています。
アウトプットは技術記事の投稿と個人開発がメインになります。
最近は、自分の技術的な理解とコミュニケーション能力を同時に向上させるために、ライトニングトーク（LT）にも挑戦してみました。

上記のアウトプットを時々チームで共有するなどやってるアピールを見せることで先輩方のモチベーションをあげれているようです。
チーム内で、技術的な信頼を積み上げていけるように継続敵に努力しようと思います。

ほかには、プライベートで行っている先輩とのチーム開発をあえてNext.jsでやっていて、社内で公開しようと考えています。
サービスを使ってもらったり、新しい技術のメリットを実際に伝えるためのきっかけになればいいなと思います。


## キャリアプラン
上記を踏まえて考えているキャリアプランを共有します。

### 技術力の強化
単に新しい技術を学ぶだけではなく、それが会社でどのように価値を生むのかを理解することにも焦点を当てて考えたいと思います。
個人開発や学習を継続し、その成果をアウトプットとして、具体的には技術記事やWebサービスの形で具現化していきます。

また、新しい技術を学ぶ際には、その技術が将来的にどのように自分のキャリアに貢献するのかを考慮します。
上記の価値とキャリアへの影響を軸に学ぶ技術を都度決めていきます。

さらに、積極的にチーム内で学んだことを共有し、新しいことを学んでいることをアピールします。
これにより、自分だけでなくチーム全体の技術力の向上やメンバーのモチベーションにつながることを目指します。

### チームへの影響力の強化
私が目指すテックリードの役割は技術力だけでなく、チームへの影響力も必要とします。
そのためまずは自分の技術的な成果をチームで共有し、他のメンバーのモチベーションを高めることを続けます。
また、自分が学んだ新しい技術をチームに導入する提案を行い、チーム全体の技術力の向上に貢献することも目指します。

私のスキル向上がチーム全体の成果にどう影響するかについて考える時、私は以下の三つのポイントを重視して考えようと思います。

1. **新しい技術の導入**: 私が新しい技術を学び、それをチームに共有することで、生産性の向上を図る。
2. **メンターシップ**: 私が学んだ知識や経験をチームメイトと共有することで、チーム全体のスキルレベルが向上します。
3. **新しい視点の導入**: 現在の問題を新しい視点から解決するためのアイデアを提供することができます。

これらのアプローチを通じて、私自身の成長がチーム全体の成果向上に直結すると考えています。

### テックリードを目指す
参考にしている記事では、
> 自身の技術力、そしてリーダーシップをもってエンジニアチームのアウトプットを最大化させていくのがテックリードの役割である。

と記載されていて、これがエンジニアとして私が目指す姿に近いです。

私が目指すテックリードの役割は、単に技術力を持つだけではなく、チームへの影響力も必要とています。
そのため、自分の技術的な成果をチームで共有するだけでなく、他のメンバーの意見を尊重する姿勢も大切にします。
チーム内で浮いてしまわないように気を付けようと思います。

また、新しい技術を学んだ際には、その技術がチームやプロジェクトにどのようなメリットをもたらすのかを明確に説明し、チームに導入する提案を行います。
これにより、チーム全体の技術力の向上に貢献することを目指します。

## さいごに
いろいろ書きましたが、今いるチームのメンバーが寛容な方ばかりで見守ってもらえる環境があるからこそ成り立つプランだと考えています。
チームに影響を与えたり自分がステップアップすることも大事ですが、会社に所属する身としては事業に貢献して売上を出すのが一番なので、今度は迷惑をかけないようにやっていこうと思います。

レガシーな環境を自分の働きかけで変えていくのは難しいと思いますが、チーム全体の成果を向上させるために、私自身のスキルを向上させることを最優先にしていきます。
【Python】mysqlclientのインポートができないとき

# 環境
macOS 10.13
Python 3.11

# 問題

`pip install mysqlclient`を実行して以下のようなエラーが発生するとき、

```
# エラー末尾
failed to solve: process "/bin/sh -c pip install --upgrade pip     && pip install setuptools wheel     && pip install -r requirements.txt" did not complete successfully: exit code: 1
make: *** [build] Error 17
```

過去のバージョンを指定してインストールすることで解決できる場合があります。

## PyPIからリリース履歴を確認

https://pypi.org/project/mysqlclient/#history

執筆現在、2023年6月のため一つ前のバージョンが`2.1.1`ということがわかります。

![スクリーンショット 2023-06-27 23.03.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568351/d46ca546-110f-d4d9-c63b-0cdb561fe541.png)

## インストール再チャレンジ

```
pip install mysqlclient==2.1.1
```

これで無事インストールはできました。
しかし、根本の解決にはなっていないので引き続き調査を進めて参ります。

Ubuntuの場合は以下@Ken227さんの記事も参考になるかと思いますので、
是非ご参考ください！
https://qiita.com/Ken227/items/02482710e297ef691c8e
【Salesforce認定資格】Salesforce Certified Sharing and Visibility Architectの受験結果

※本記事は2022年10月に受験した「Salesforce Certified Sharing and Visibility」の振り返りを記載しています。

## はじめに
個人的に設計方面の興味が湧いてきたことと、社内的にアーキテクトが不足していることから、アーキテクト方面の資格に挑戦することになりました。

## 試験結果
結果は __「合格」__ でした。
試験に関しては時間は余裕があり、3回の見直しができました。

| 受験料 | 試験時間 | 設問数 | 合格ライン | | 受験日 | 正答率 | 所要時間 |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| 40,000円 | 120分 | 60問 | 67% | | 2022/10/07 | 88.37% | 73分 |

内訳を見ると、全体的に取れていたので知識定着が進んでいる確認ができました。

| 試験内容 | 内訳 | 設問数 | | 正答率 |
| :-- | :-: | :-: | :-: | :-: |
| 宣言的共有 | 76% | 45.6問 | | 87% |
| パフォーマンス | 7% | 4.2問 | | 75% |
| プログラミング的共有 | 17% | 10.2問 | | 100% |

![Salesforce_Certified_Sharing_and_Visibility_01_テスト結果詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3285411/fc278342-80f8-9fd0-7a96-4ca16710d25a.png)

## 学習方法
基本的には宣言的共有を押さえる必要があったため、ロール階層や共有ルール等のアドミニストレーター資格の範囲の復習を始め、Experience Cloudライセンスと共有セットについての学習を行いました。
Experience Cloudに関しては実務経験がなかったため、Trailheadの学習と実機での構築で確認し、[ドキュメントにあるExperience Cloudライセンス](https://help.salesforce.com/s/articleView?id=sf.users_license_types_communities.htm&type=5)の表を隙間時間に見続けました。
他には、Apex共有に関しての知識が追加で必要でしたが、こちらについては実務で検討したことがあったため、[ドキュメント](https://help.salesforce.com/s/articleView?id=sf.security_apex_sharing_reasons.htm&type=5)を読むくらいの学習でした。

## 学習の意識付け
宣言的共有の範囲については、アドミニストレーター資格で学習した範囲を具体的な要件に沿って組み合わせることができれば、正解まで辿り着ける問題が半分程度あるため、アドミニストレーター資格の共有関連の知識は押さえておく必要があるかと思います。
暗黙的な共有（特に取引先関連の暗黙的な共有）についての問題も多々あったので、覚えておくと安心です。
Clean Architecture を読むときに必要なクラス図の読み方


## 依存
依存先のオブジェクトの変更が、依存元オブジェクトに影響を与える可能性のある関係


```mermaid
classDiagram
    class Teacher {
        + publicTeach()
    }
    
    class MathTextbook {
        + getContent()
    }
    
    class ScienceTextbook {
        + getContent()
        - privatePrintContent()
    }
    
    Teacher --> MathTextbook: uses
    Teacher --> ScienceTextbook: uses
```

```TypeScript

class MathTextbook {
  public getContent() {
    return '数学の教科書'
  }
}
　

class ScienceTextbook {
  public getContent() {
    return '理科の教科書'
  }
  private privatePrintContent() {}
}


class Teacher {
 public publicTeach() {
   const mathTextbook = new MathTextbook()
   const scienceTextbook = new ScienceTextbook()
   console.log(mathTextbook.getContent())
   console.log(scienceTextbook.getContent())
 }
}
```


## 実装
interface を実装するクラスの関係

```mermaid
classDiagram
    class MathTextbook {
        getContent()
    }
    
    class ScienceTextbook {
        getContent()
    }
    
    Textbook <|.. MathTextbook: implements
    Textbook <|.. ScienceTextbook: implements
```

```TypeScript

interface Textbook {
  getContent()
}

class MathTextbook implements {
  getContent() {
    console.log('数学の教科書')
  }
}
```
rails validate do ... endについて

# はじめに
バリデーションを記載するときは```validates```を使用してきて```validate do ... end```の書き方を知らなかったので記載


## validates と validate の違いについて

validatesメソッド・・・事前に定義されたバリデーションオプションを使用して検証ルールを指定する
validateメソッド・・・カスタムなバリデーションロジックを自由に記述する

#### validatesについて詳しく
・複数のバリデーションルールを一度に指定するために使用される
・モデルクラス内で使用され、属性の検証ルールを定義
・バリデーションルールはハッシュ形式で指定され、属性名とバリデーションオプション（プレゼンス、長さ、一意性など）を組み合わせて指定する
##### 実際の使い方
```user.rb
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
end
```
上記の例では、name属性が存在すること、email属性が存在し、かつ一意であることを検証している。validatesメソッドは、複数の属性とそのバリデーションルールをまとめて指定するための便利な方法。

#### validateについて詳しく
・カスタムなバリデーションロジックを定義するために使用される
・個別のメソッドとしてモデルクラス内に定義され、特定のバリデーション処理を行う
・validateメソッド内でカスタムなバリデーションコードを記述することができる
##### 実際の使い方
単一の属性のカスタムバリデーション
```user.rb
class User < ApplicationRecord
  validate :custom_validation

  def custom_validation
    if age < 18
      errors.add(:age, "must be at least 18")
    end
  end
end
```
Userモデルのcustom_validationメソッドを定義。このメソッド内で、age属性が18未満の場合にエラーメッセージを追加している。

複数の属性を使用したカスタムバリデーション
```user.rb
class User < ApplicationRecord
  validate :custom_validation

  def custom_validation
    if age < 18
      errors.add(:age, "must be at least 18")
    end
  end
end
```
Userモデルのcustom_validationメソッド内で、start_dateとend_date属性の関係性を検証。もしstart_dateが存在し、end_dateが存在し、かつstart_dateがend_dateよりも後の場合、エラーメッセージを追加する。

複数の属性を使用したカスタムバリデーション（モデル間の関連を検証）
```order.rb
class Order < ApplicationRecord
  belongs_to :user
  validate :validate_user_credit_limit

  def validate_user_credit_limit
    if user.present? && total_amount > user.credit_limit
      errors.add(:base, "Exceeded user's credit limit")
    end
  end
end
```
Orderモデルのvalidate_user_credit_limitメソッド内で、ユーザーのクレジット限度額を超える注文を検証。userが存在し、かつtotal_amountがユーザーのクレジット限度額を超える場合、エラーメッセージを追加する。


### validate使用時のエラーメッセージ追加方法
validate使用時はerrors.addメソッドを使用して自分でエラーメッセージを追加することで、バリデーションエラーが発生したことを示す。

#### errorsメソッド
errorsメソッド・・・モデルのエラーオブジェクト（ActiveModel::Errorsクラスのオブジェクト）を返す

#### addメソッド
エラーオブジェクトのaddメソッド・・・モデルのオブジェクトにバリデーションエラーを登録する
```errors.add(:base, "Exceeded user's credit limit")```
第一引数：属性名のシンボル
第二引数：エラーメッセージ

※第２引数には直接メッセージ指定だけでなく、:empty :invalidなどの既存のものや、開発者自身が決めた任意のシンボルも指定できる

```errors.add(:expired_at, :expired_at_too_old)```

```
ja:
  activerecord:
    models:
~省略~
    errors:
      messages:
        expired_at_too_old: は掲載開始日より新しい日時にしてください。
```

## 参照
[【Rails | バリデーション validates と validate の違い](https://qiita.com/YUUKI-Git611/items/85c028f7ac098e9576fd)
ubuntu(virtual box)にanacondaを構築してみた

参考サイト
https://paper.hatenadiary.jp/entry/2016/12/14/171620


# Anacondaをインストールする
## Anacondaをダウンロードする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/cb66ce83-4dbf-bc30-a814-e8305150c724.png">

## shを実行する
```shell
$ sh Anaconda3-2023.03-1-Linux-x86_64.sh
```

## ライセンスに同意する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/a99ec40f-0913-af01-d568-52d82dd1837b.png">

## ディレクトリを指定する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/827dc2e9-b712-0abd-1fed-11f034216438.png">

既定値は /home/(user名)/anaconda3

## conda initを実行する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/71eefe05-e3a0-b727-ff33-5c46e82287ef.png">

## インストール完了
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/d18f0b09-b4fa-0613-9ab0-e8343c261fc8.png">





# 仮想環境を作る
## 仮想環境を作る
```shell
$ conda create -n pythonenv python=3.10
```
-n の後に、仮想環境名を指定する

## 仮想環境一覧を確認する
```shell
$ conda env list
```
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/451df75b-4e49-fe6c-b230-2dd1e51c35bf.png">

## 仮想環境を有効にする
```shell
$ conda activate pythonenv
$ conda env list
```
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/ddf4d5dc-b999-35cd-93f5-7c00c07b4fe9.png">

pythonenvが有効になったので、pythonenvの横に*がついた

# vscodeをインストールする
下記記事を参照
https://qiita.com/towamz/items/5472226e0ea542db5548


# vscodeに仮想環境のコンパイラを指定する
## コンパイラをクリックする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/3887efcb-b222-4f97-07be-308edf6b3983.png">

右下のpythonの横

## コンパイラを選択する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/79432d02-7ee4-b3eb-ddfa-24a0f44af07d.png">

## コンパイラが変更された
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/bfe339c2-3e70-2d63-c4c1-872c898ad6c8.png">

## 動作確認する
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/6a949ac4-4584-27b3-b905-691b7b0f6d44.png">

Hello Worldが表示された
Hugoのフロントマターで定義した変数の設定をGitフックで強制する

Hugoのフロントマターの値の入力を強制させるためにGitフックを使ったのでそのメモです
## Hugoのフロントマターとは
公式Docs:https://gohugo.io/content-management/front-matter/ 
フロントマターはmdファイルの先頭に書くもので、これを使うことで、mdファイルのメタデータを設定することができます。  
フロントマターの記述方法は、TOML, YAML, JSON, ORG形式の４つあり、そのうちどれかを選ぶことができます。（自分はYAML形式）  
フロントマターの変数には、定義済みのもの（date, draft, imagesなど）と自分で自由に定義できるものがあります。  
Hugoには、Archetypesというmdファイルを作る際のテンプレートのようなものがあり、このArchetypesにフロントマターも設定しておくことで、いちいち最初からフロントマターやその変数をちまちま書く必要がなくなります。 

私は自分の日報とちょっとしたメモや記事置き場としてHugoを使った個人ブログをやっており、 Archetype内フロントマターは以下のように設定しています。  
[個人ブログ](https://piyopanman.dev)
- 日報のフロントマター
``` yml
---
title: {{ .Name | time.Format .Site.Params.DateFormat }} # DataFormatで指定した形式の日時がタイトルになる
date: {{ .Date }} # hugo new でmdファイルを作成したときの日時が入る
categories: "日報"
draft: false

score: # 自分で定義した変数。1日の評価を0から10で指定する
---
```
## フロントマターで定義した変数に値を設定することをGitフックを使って強制する
フロントマターにはさまざまな変数を設定することができます。  
[個人ブログ](https://piyopanman.dev)の日報では、その日1日の評価を0から10の間で評価するためにscoreを独自の変数として定義しています。  
scoreごとに日報一覧表示させたときに表示する色を変え、視覚的にその日どれくらい頑張ったかをわかりやすくする、ということをしています。
具体的には、0~4だと青、5~7だと緑、8~9だとピンク、10だと赤、という感じです。
![スクリーンショット 2023-06-27 22.26.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671055/1ffdc833-24a8-cee0-de73-3a6fe21fa5fd.png)

そのため、scoreには0から10の範囲の数字を設定する必要があります。  
しかし、Hugoでは変数の値の設定を強制することは機能として提供していないため（私調べ）、たびたびscoreを設定しないまま日報を公開してしまうことがありました。
そこで、Gitフックを使って、コミットする前にscoreに値が設定されているかどうかをチェックし、されていなかったらコミットを中止するような仕組みを作ることにしました。  

書いたフックスクリプトは次のとおりです。  
```sh:pre-commit
#!/bin/bash

score_regex='^score: (10|[0-9])'

# daily-reports以下のmdファイルにscoreを0-10で指定していることをチェックする
is_can_commit=true
for file in $(git diff --name-only --cached | grep 'content/daily-reports/.*\.md$'); do
    line=$(awk 'NR==7' "$file")
    if [[ !("$line" =~ $score_regex) ]]; then
	      is_can_commit=false
        echo "$file にscoreが0-10で指定されていないよ"
    fi
done

if ! $is_can_commit; then
  echo "日報のmdファイルにscoreを指定してからコミットしてください"
  exit 1
fi
```

- ステージングに追加された変更されたファイルのうち（`git diff --name-only --cached`）
- `content/daily-reports/`ディレクトリ以下のmdファイルの（`grep 'content/daily-reports/.*\.md$'`）
- ７行目が（`line=$(awk 'NR==7' "$file")`）
- `score`で始まり、0〜10のいずれかでおわる（`"$line" =~ $score_regex`）  

ことをチェックし、もしそうなっていないファイルがあれば、scoreが0から10で指定されていない旨を出力し、コミットを中止します。
実際に、scoreに値を設定せずにステージングしコミットしようとした時の出力はこちらです。
![スクリーンショット 2023-06-27 22.14.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671055/80e1d6a0-f702-d255-ccc5-008bd520c1fa.png)


シェルスクリプトはほとんど書いたことがないので良くない書き方をしてる部分が多いかもしれません。  
お気づきの点がありましたらコメントなどでご指摘いただけると幸いです🙏

## GitフックをGit管理する
デフォルトだと、Gitフックのフックスクリプトは`.git/hooks`以下に定義されており、Git管理することができません。
しかし、（個人ブログから必要ないかもしれないけど）GitフックもGit管理したかったので以下のことをしました。
- `.githooks`ディレクトリを作る
- `.githooks`ディレクトリのなかに`pre-commit`を作成し、上で紹介したフックスクリプトを記述する
- `git config --local core.hooksPath .githooks`でフックスクリプトの場所を`.githooks`以下であると設定する 

これでGit管理できるようになりました。
参考にさせていただいた記事はこちらです：https://www.farend.co.jp/blog/2020/04/git-hook/

## 終わり
やったこととしては以上です。何かお気づきの点がありましたらぜひ教えてください。
最後までお読みいただきありがとうございました。
NHKアイデアソンに参加してきたぞ！！！

# NHKアイデアソン in 北海道に参加してきました。

参加してきましたわよ。アイデアソンとやらに。

# はじめに

NHKが主催するアイデアソンで、今回は北海道で開催されたので、参加してきました。
旅費出るし。

# どんな感じだったのか

とりあえず、アイデアソンというのは、アイデアを出して、それをプレゼンして、それを評価してもらうというものです。

今回は、ローカルフレンズという方々の発表を聞いて、その後に、アイデアソンを行いました。

## ローカルフレンズ

今回のゲストスピーカーとして、ローカルフレンズの方々が来てくれました。

- **加藤 朝彦**（一般社団法人HATCH代表／喜茂別町ローカルフレンズ）
地域おこし協力隊として人口1900人の喜茂別町に移住。町の中心地にカフェがないことから空き家を改装し、地域と人をつなぐコーヒースタンド＆シェアスペースにする。2021年5月にローカルフレンズ喜茂別編をプロデュース。その後、都市部と地方の機会格差解消などに取り組む一般社団法人を設立。地域活動のかたわら、札幌のスタートアップでも勤務。IoTとAIで灯油タンク内の残量を可視化し、最適な配送を行うサービスなどを提供している。

- **保志 弘一**（漁師／広尾町ローカルフレンズ）
十勝・広尾町の漁師一家の三代目。次世代に続く地域と漁業の在り方の探求をライフワークとし、この数年は昆布に付加価値をつける事業に取り組んでいる。2023年、廃棄されていた昆布の端材を粉砕し、調味料にした「星屑昆布」の開発に連なる複合的な取り組みが、全国青年・女性漁業者交流大会で最高位の農林水産大臣賞を受賞した。町の酪農家、漁師、地域おこし協力隊などで構成される団体・ピロロツーリズム推進協議会に所属し、産業間連携に注力している。2022年7月にローカルフレンズ広尾編をプロデュース。

- **谷山 嘉奈美**（サウナとジビエ・かなりあつい／下川町のローカルフレンズ）
名古屋で保健師をしていたが、「ミステリーツアー」という行き場所の分からない旅に参加し、林業が盛んな下川町（道北）に出会い移住。町は環境や持続可能性の領域で先進的な取り組みが多く、移住者の交流も盛ん。町の木材を使った軽トラサウナを開発し出張サウナの提供を開始。またジビエ料理の研究も行っており、イベントで提供している。ＳＮＳでは“かなりあつい”というアカウントで情報発信中。2023年2月にローカルフレンズ下川編をプロデュース。

- **古川 泰人**（株式会社MIERUNE/酪農学園大学特任講師）
地図情報技術者。民間企業を経て北海道大学CoSTEPで科学技術コミュニケーションなどを学んだのち、北海道大学農学研究科などの研究員として勤務。その後2016年に位置情報のコンサルティングやシステム開発を行うMIERUNEを創業。また、Code for Sapporoのコアメンバーとして、「さっぽろ保育園マップ」や「ひぐまっぷ」などのコーディネートに関わり、Code for Japanでもフェローとしてシビックテックやオープンデータに関する活動を行っている。2020年にはJUST道ITグループの一員として「北海道新型コロナウイルスまとめサイト」の開発・運用に携わった。このほかにも2019年から総務省地域情報化アドバイザーに任命され、オープンデータ、シビックテック、オープンサイエンスなどに関する講演や研修などを行ってきた。

# アイデアソンとは

今回のアイデアソンは、Code for Japanの協賛で行われました。

>アイデアソンは アイデアとマラソンを組み合わせた用語である。 新しいアイデアを生み出すために行われるイベントである。 主にIT分野で使われている。 1990年頃アメリカで使われ始めたと言われている。 ハッカソンと違い、物を作るではなく、アイデアを生むことに重きを置いたイベントである。 ハッカソンの練習としてアイデアソンを用いることもある。 アイデアソンとは、アイデアとマラソンを掛け合わせた造語で、アイデアとマラソンを合わせてアイデアソンと名付けられた。
    
[アイデアソン - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2%E3%82%BD%E3%83%B3)

ということで、アイデアソンとは、アイデアを出すことに重きを置いたイベントです。

今回は、Code for Japanの協賛で行われました。
アイデアソンのテーマは、**「地域の課題を解決するアイデア」** でした。

# 総評

## 良かった点

今回のアイデアソンは年齢も職種も一切関係なく、誰でも参加できるということで、様々な方が参加していました。
私のチームにも、別の高専のの方と一般の方2名が参加していました。
大人の方が丁寧に進行してくれたおかげもあってか課題解決まですぐにたどりつくことができました。
短い時間の中で以下に妥協点を見つけつつ課題解決まで持っていくかかなり大変でしたが、それもまた良い経験となりました。

## 悪かった点

これと言ってないのですが、強いて言うならメンターさんの紹介が最後にあったことですかね。
技術メンターさんの協力が必要な点もあったのですが、メンターさんの情報がなかったためお声掛けできませんでした。
また、メンターさんの紹介が最初にあったほうがいろいろ変わってきたかもしれません。

# まとめ

今回のアイデアソンは、とても良い経験となりました。
また、アイデアソンに参加したいと思います。
どうやら秋ごろに今回の続きとして、ハッカソンが開催されるようなので、そちらにも参加したいと考えています。
SadServersの解説: #1~#3

※今回登場するコマンドでわからないものがあれば, 是非ChatGPTに聞いて見てください!!

# 1. "Saint John": what is writing to this log file?
## 問題
`/var/log/bad/log`にログを出力し続けているプロセスがあり, このプロセスを停止させよという問題. 
    
## 解説
```bash
tail -f /var/log/bad.log
```

とすると, 確かに出力され続けるのが確認できる. 
    
```bash
lsof /var/log/bad.log
```
をして, `/var/log/bad.log`を開いているプロセスを見つけて, PIDを取得する. 

```bash
kill [PID]
```

でプロセスを終了させたらOK.

# 2. "Saskatoon": counting IPs.
## 問題
`/home/admin/access.log`内にhttpリクエストのログが取得されていて, 最も多くのリクエストを送信したIPアドレスを探せという問題. 

## 解説
```bash
cat /home/admin/access.log
```
をすると, `XXX.YYY.ZZZ.WWW - - 〜`という行がログとして保存されていることがわかる. 
    
```bash
cut -d ' ' -f 1 /home/admin/access.log
```
    
`cut`で区切り文字に空白, として-fに対して1をすることで, 各行のIPアドレスの部分だけが抽出できる.
```bash
cut -d ' ' -f 1 /home/admin/access.log | sort | uniq -c | sort
```

重複しているものを数えるときは`uniq -c`コマンドを使うが, ソートされていない出力に対して実行すると正しく値が検出できないため, 先にソートして`uniq`を適用. 
    
最後に`uniq`の出力結果をソートして, ケツのIPアドレスを見にいくと正解がわかる.

# 3. "Santiago": Find the secret combination
## 問題
`/home/admin`内の`*.txt`のファイルから, Aliceという単語が出現した行を探し出し, 
1) 全ファイルのAliceが出現した行数の合計
2) 一回だけAliceが現れたファイルがあり, そのファイルのAliceの直後にある数字

1, 2の二つの数字を出力せよという問題.

## 回答
```bash
find /home/admin -maxdepth 1 -type f | grep .txt | xargs cat | grep Alice | wc -l
```
    
`find`で`/home/admin`内のファイルをまず見つける. `-maxdepth 1` とすることで, `/home/admin`よりも深いディレクトリは探索しないようにする.     
これに`xargs`で`cat`を行うと, 一気に全部のファイルの中身を表示させられる. 
`cat`の出力結果を`grep`して, `wc`でAliceが出てくる行数を表示させたら1の答えがわかる. 
    
```bash
cat [ファイル名] | grep Alice | wc -l
```
    
さっきと同じようなAliceが出てくる行数を調べる(今回はファイル一つずつ). 
    
`cat`でファイルの中身を表示して, `grep`でAliceが含まれる行を抽出して, `wc`で行数を表示する. `*.txt`を一つずつ調べると, Aliceが出てくるのが1行しかないファイルを見つけられる. 

```bash
cat [1回しかないファイル] | grep Alice -A 1
```

見つかったファイルに対して, `grep -A [数字]`を使って, 条件に一致した行の後ろの, 特定の行数分も取得できて, この結果から2の答えがわかる.
angular mrb with table

mrbのtable内部の処理について備忘録
ラジオボタンイベントだけでは、行選択した際にラジオボタンがTRUEにならないため色々調べた結果、以下コードで実現可能。
※追記　SCSSでhighlightに好きな色を設定。
# HTML
```html:tableRadio.html
<mat-radio-button
 color="primary"
 (click)="$event.stopPropagation()"
 (change)="selectItem(row)"
 [checked]="selection.isSelected(row)"
 [aria-label]="radioLabel(row)"
></mat-radio-button>
----------------------------------------------------------------------------------------
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr
    mat-row
    *matRowDef="let row; columns: displayedColumns;"
    (click)="selectItem(row)"
    [ngClass]="{'highlight' : selectedItem == row}"
    class="selectable"
  ></tr>
```
# typescript
```typescript:tableRadio.ts
import { SelectionModel } from '@angular/cdk/collections';
import { Component } from '@angular/core';
import { MatTableDataSource, MatRow } from '@angular/material';
----------------------------------------------------------------------------------------
export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}
----------------------------------------------------------------------------------------
  dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
  selection = new SelectionModel<PeriodicElement>(false, []);
  selectedItem = <PeriodicElement>{};

  radioLabel(row?: PeriodicElement): string {
    return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${
      row.position + 1
    }`;
  }

  selectItem(row: PeriodicElement) {
    this.selection.toggle(row);
    this.selectedItem = row;
  }
```


#Demo
![tableRadio.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491775/167a8400-8fc2-0658-0e1f-da4b6c495540.gif)

angular table radioとかで検索したら元ネタが見つかるかも。
【SwiftUI】点線の区切り線を作成する

# はじめに
SwiftUIの標準機能では点線の区切り線が実装できなかったので、カスタムで作成してみました。

# 実装
```swift
struct Line: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: rect.width, y: 0))
        return path
    }
}
```

# 使い方
```swift
struct ContentView: View {
    var body: some View {
        Line()
            .stroke(style: .init(dash: [4, 3]))
            .foregroundColor(.black)
            .frame(height: 0.5)
    }
}
```

![simulator_screenshot_B33557A6-ECE5-4F9C-AFA5-F361FC6971A4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/afb9ea6c-34a1-ab9d-5284-5945637104a5.png)

# おわり
いい感じにできました
CISOハンドブック ――業務執行のための情報セキュリティ実践ガイド

https://www.amazon.co.jp/s?k=ciso%E3%83%8F%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF&i=stripbooks&adgrpid=133661322655&hvadid=658831412140&hvdev=c&hvlocphy=1009255&hvnetw=g&hvqmt=e&hvrand=4415723458303123111&hvtargid=kwd-1118979214763&hydadcr=4072_13329056&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_3rkq6bzdgb_e

本書を手に取った背景
CISSP受験のための勉強。CISSPにはマネジメントに関する内容も出てくるため、本書を読んでみようかと思った。

本書のテーマ
CISOになったとき、経営陣の言葉を理解したり、業務執行の手がかりとなる内容をなっている。

個人的なポイント
１，PDCAもいいが、OODAを使う。
OODAは想定外の事態や、緊急席の高い事態への対応を想定している。Observr,Orient,Decide,Act。セキュリティは想定外の事態も起こりえるので親和性が高い。
経営陣に緊急性を伝えたいときにも使える。

２，財務諸表もみれるようにする
CISOはセキュリティを見れていればいいわけではない。ビジネス観点からセキュリティについていつでも語れる必要があり、当然財務諸表も見れる必要がある。
例えば、ROIを考慮したセキュリティ投資などである。

３，監査の分類
職員による監査、第三者による監査の二種類がある。

４，外部認証、情報セキュリティ対策実施状況の把握
ISO、SOC、STAR、個人情報保護などさまざまな規格や認証がある。

５，新しい領域のセキュリティ
IOT、自動車、AI、」ChatGPTなど新しい技術へのセキュリティをチェックする必要がある。

６，地政学リスク
ビジネス展開している企業が懸念するリスクの３位にサイバー攻撃、サイバーテロがランクインしていた。

７，CISOの役割
事業貢献、コーポレート・ガバナンス、リスク管理、セキュリティ対策が主な業務。

８，他のCxOとコミュニケーションをとり、会議などを適宜実施する
CIO、CFOなどいろんな部署のトップと話す必要がある。例えば、なにかセキュリティインシデントが発生したとき、財務部や法務部とも話す必要がある。

１番心に残った部分
ピンポイントではないが、ビジネス観点からセキュリティをどう考えればいいかが非常にわかりやすかった。

今後やれること
・数字の意識
・OODA実践

まとめ
基本的には、CISOの総論に近い内容。CISOがどんな役割で、どんな知識が必要で、どこから情報を得られるかというのが中心で、各項目の各論にはそこまで深く触れてない。
しかし、セキュリティに携われるものとしては、把握したいし、せっかくなら目指したい。
ドックランチャーのPlankにログアウトボタンをつける簡単な方法

# 説明
- Xubuntu で、ドックランチャーの Plank に、ログアウトボタンをつける簡単な方法の紹介です。他の Linux では試していません。
- Plank がすでにインストールされている前提での記事です。
- すでに、デスクトップでの右クリックで、アプリケーションメニューを表示できるようにしていれば、3. の操作だけでログアウトボタンをつけることができます。
# 手順
1. デスクトップ上で右クリックし、「デスクトップの設定(S)...」をクリックします。
![Plank_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1849635/3fbd451d-a37a-388f-44ad-0087ef3f3c07.png)
2. タブの「メニュー(M)」をクリックし、「デスクトップでの右クリックでアプリケーションメニューを表示する(D)」にチェックをつけて、「× 閉じる(C)」をクリックします。
![Plank_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1849635/ff1e9952-200f-ff66-5f86-2e0d0882e256.png)
3. デスクトップ上で右クリック、「アプリケーション(A)」をクリック、「ログアウト」をPlankにドラッグアンドドロップすれば、ログアウトボタンのできあがりです。
![Plank_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1849635/986ed4bd-885d-89d5-1119-36e51db10be4.png)
【Vue.js3】computed(getter)とmethods(setter)の違い

# 例
結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/41d1315a-df50-c955-5c17-8b57e3bd5056.png)

```html:index
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/main.css">
</head>
<body>
    <div id="app">
        <p>{{ message.split('').reverse().join('') }}</p>
        <p>{{ reversedMessage }}</p>
        <p>{{ reversedMessageMethod() }}</p>
    </div>

    <script src="https://unpkg.com/vue@3.1.5"></script>
    <script src="js/main.js"></script>
</body>
</html>
```

```js:main.js
const app = Vue.createApp({
    data: () => ({
        message: 'Hello Vue.js!'
    }),
    computed: {
        reversedMessage: function() {
            return this.message.split('').reverse().join('')
        }
    },
    methods: {
        reversedMessageMethod: function() {
            return this.message.split('').reverse().join('')
        }
    }
}).mount('#app')
```

data、computed。methodsで同じ結果が得られるプログラムを用意しました。

# computed

・算出プロパティ
・htmlファイルで呼び出すときに、()が不要

```
<p>{{ reversedMessage }}</p>
```
・getterとsetterが定義できる
・キャッシュ有り(依存関係に基づきキャッシュされるため)
→処理を高速化

## getter

プロパティの値を取得するための関数です。プロパティにアクセスするときにゲッターが呼び出され、その返り値が参照されます。ゲッターは、データの加工や計算を行うために使用されることがあります。

```js:
// ゲッターの定義
getters: {
  formattedMessage: function() {
    return this.message.toUpperCase();
  }
},
```

# methods

・メソッド
・htmlファイルで呼び出すときに、()が必要

```
<p>{{ reversedMessageMethod() }}</p>
```

・getterしか定義できない
・キャッシュ無し(呼び出されるたびに処理を行い、結果を返すため)

## setter

プロパティの値を設定するための関数です。プロパティに値を代入するときにセッターが呼び出され、その引数として渡された値を使用してプロパティの値を更新します。セッターは、プロパティの値の変更時に追加のロジックを実行するために使用されることがあります。

```js:
setters: {
  setMessage: function(value) {
    this.message = value.trim();
  }
}
```
任意のHTTP ステータスコードを返すWebサーバーを雑に構築する

# はじめに
テスト目的で任意のHTTPステータスコードを返すWebサーバーが必要になり、実際に作ってみたので備忘録としてアプトプットします。

# 方法

VM起動時にブートストラップのスクリプトとして以下を動作させます。

```bash:init.sh
#! /bin/bash
apt update 
apt install -y python3 python3-pip 
pip3 install flask

cat << EOF > ./app.py
from flask import Flask
import random

app = Flask(__name__)

@app.route('/')
def run():
　　　　# この部分に任意のステータスコードを入れる
  status_code = [100, 200, 300, 400, 500]
  return '', random.choice(status_code)

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=80)
EOF

sudo nohup python3 app.py &
```

Azure VMでブートストラップさせる方法については以下の記事に書いているので、ご参照ください。

https://qiita.com/tkhs1121/items/31621e43991c7a0a29cf


# おわりに
用途は限られていますが、お役に立てれば幸いです。
基本情報対策：科目B「挿入ソート」

科目Bの問題を解いている時にトレースミスが多く、その原因としてそもそもを知らない、理解していない状態だったため、トレースミスをした問題をコードに起こして紐解いていくことにしました。平日は毎日投稿を目指します。


# 挿入ソートとは
基本挿入法アルゴリズムの一つ


以下の場合に導入を検討する
①データセットが小さい場合:
 挿入ソートは、データセットの要素数が比較的小さい場合に効果的です。データセットが少ない場合、挿入ソートの実行時間は他の高度なソートアルゴリズムよりも短くなる傾向があります。


②部分的にソートされたデータが存在する場合: 
すでにソートされている範囲に新たな要素を挿入するため、部分的にソートされたデータに対しては高い効率を発揮します。

③データセットがほぼソートされている場合: 
ほぼソートされたデータでは、挿入ソートは比較回数を最小限に抑えながらソートを行うことができます。

ただし、データセットが非常に大きい場合やランダムな順序で並んでいる場合には、挿入ソートは効率的ではありません。そのような場合には、マージソートやクイックソートなどの高速なソートアルゴリズムが一般的に選択されます。



投稿①　「挿入ソート」

```java:Main.java

import java.util.Arrays;

public class Main {
    public static int[] intoSortMachine(int[] array){
        int tmp;
        int j;
        for(int i =1; i<array.length; i++){
            tmp = array[i]; //<= 比較対象を格納する
            j = i;  // <= iは直接操作できないため　jで代用してデクリメントを行う

            while( j > 0 && array[j-1] > tmp ){
//                ↑　Jが0より大きいすなわち配列要素からはみ出ない事
//                　　　　　　　　↑前の配列要素より小さい時に条件が成立する。

//              ソート処理
                array[j] = array[j-1];  //tmpより大きい要素を後ろに移動する
                j--;                    //Jの値を-1してさらに前の要素と比較を行う
            }

            array[j] = tmp;       //場所が確定した時、配列要素を格納する
            System.out.println(Arrays.toString(array));

        }
        return array;
    }
}
```

```java:MainTest.java
import org.junit.Test;


import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

public class MainTest {
    @Test
    public void testIntoSortMachine() {
        // テスト用のデータ
        int[] array = {5,1,4,3,2};
        // 期待される結果
        int[] expected = {1,2,3,4,5};
        // テスト対象のメソッドを実行
        int[] sortedArray = Main.intoSortMachine(array);
        // 期待される結果と実際の結果を比較
        assertArrayEquals(expected, sortedArray);

//  [1, 5, 4, 3, 2]
//  [1, 4, 5, 3, 2]
//  [1, 3, 4, 5, 2]
//  [1, 2, 3, 4, 5]
//  １つの値を前に持っていく作業をしているだけ。
    }
}
```

蓋を開けてみたらシンプルでした。


ポイント①
変数jは 変数iを格納するのですが、ここで格納する理由は変数iを直接操作することができない為、代わりに変数jに担当してもらっていたことが理解できました。

```java
for(int i =1; i<array.length; i++){
            tmp = array[i]; //<= 比較対象を格納する
            j = i;  // <= iは直接操作できないため　jで代用してデクリメントを行う
```

ポイント②
疑似言語で見た時、内容が理解できずトレースができなかった箇所。ここも紐解いてみたら意外とシンプルでした。
```java
   while( j > 0 && array[j-1] > tmp ){
//         ↑　Jが0より大きいすなわち配列要素からはみ出ない事
//                ↑前の配列要素より小さい時に条件が成立する。
```

ポイント③
ソートの処理をここで実施している。
```java
array[j] = array[j-1]; 
//tmpより大きい要素を後ろに移動する
    j--;                   
//Jの値を-1してさらに前の要素と比較を行う
```
あとは繰り返し条件を抜けたら終了した配列番号に格納する
```java
array[j] = tmp;       
//場所が確定した時、配列要素を格納する
```
これを繰り返したのち、ソートが完了する
```java
// テスト用のデータ
int[] array = {5,1,4,3,2};　
//実行結果
//  [1, 5, 4, 3, 2]
//  [1, 4, 5, 3, 2]
//  [1, 3, 4, 5, 2]
//  [1, 2, 3, 4, 5]
//  １つの値を前に持っていく作業をしているだけ。
```


だれかの参考になればうれしいです^^