OmniAICreator/Qiita-1.07M huggingface dataset:
Linuxでよく使うコマンド一覧

# はじめに
一つ一つ調べるのが面倒なので、自分用に使うコマンドをまとめました。

# 目次

- [vi エディタ基本コマンド](#vi-エディタ基本コマンド)
- [Linux 基本コマンド](#linux-基本コマンド)
- [Linux コマンドラインショートカット](#linux-コマンドラインショートカット)

# vi エディタ基本コマンド

## 編集モードの切り替え
- `i` : 挿入モードに切り替え
- `v` : ビジュアルモードに切り替え
- `Esc` : コマンドモードに戻る

## テキスト操作
- `x` : カーソル位置の文字を削除
- `dd` : カーソル行を削除
- `yy` : カーソル行をコピー
- `p` : コピーしたテキストを貼り付け

## 移動
- `h` : 左に移動
- `j` : 下に移動
- `k` : 上に移動
- `l` : 右に移動
- `w` : 次の単語の先頭に移動
- `b` : 前の単語の先頭に移動

## 保存と終了
- `:w` : ファイルを保存
- `:q` : viを終了
- `:wq` : 保存して終了
- `:q!` : 保存せずに終了

## 検索
- `/text` : `text`を検索
- `n` : 次の検索結果へ移動
- `N` : 前の検索結果へ移動

# Linux 基本コマンド

## ファイル操作
- `ls` : ディレクトリの内容を表示
- `cd [directory]` : 指定したディレクトリに移動
- `cp [source] [destination]` : ファイルをコピー
- `mv [source] [destination]` : ファイルを移動または名前を変更
- `rm [file]` : ファイルを削除
- `mkdir [directory]` : 新しいディレクトリを作成
- `rmdir [directory]` : 空のディレクトリを削除

## 権限と情報
- `chmod [permissions] [file]` : ファイルの権限を変更
- `chown [user]:[group] [file]` : ファイルのオーナーを変更
- `ln -s [target] [link name]` : シンボリックリンクを作成
- `stat [file]` : ファイルの詳細情報を表示

## システム監視
- `ps` : 現在動作しているプロセスを表示
- `top` : リアルタイムのプロセス情報を表示
- `df` : ディスク空き容量を表示
- `du` : ディレクトリの使用容量を表示

## ネットワーク
- `ping [host]` : ホストとの接続状況を確認
- `ifconfig` : ネットワークインターフェースの設定を表示
- `netstat` : ネットワーク接続、ルーティングテーブル、インターフェース統計を表示

## その他
- `echo [text]` : テキストを表示
- `cat [file]` : ファイルの内容を表示
- `head [file]` : ファイルの先頭部分を表示
- `tail [file]` : ファイルの末尾部分を表示
- `grep [pattern] [file]` : ファイル内のパターンを検索して表示

# Linux コマンドラインショートカット

## カーソル移動
- `Ctrl + a` : 行の先頭に移動
- `Ctrl + e` : 行の末尾に移動
- `Alt + f` : 次の単語の先頭に移動
- `Alt + b` : 前の単語の先頭に移動
- `Ctrl + f` : 文字単位で前（右）に移動
- `Ctrl + b` : 文字単位で後ろ（左）に移動

## テキスト編集
- `Ctrl + k` : カーソルから行末までカット
- `Ctrl + u` : カーソルから行頭までカット
- `Ctrl + w` : 前の単語をカット
- `Alt + d` : カーソル位置から次の単語末尾まで削除
- `Ctrl + y` : 直前にカットしたテキストをペースト

## コマンド操作
- `Ctrl + r` : コマンド履歴から検索（インクリメンタルサーチ）
- `Ctrl + g` : コマンド履歴の検索をキャンセル
- `Ctrl + p` : 前のコマンド履歴に移動
- `Ctrl + n` : 次のコマンド履歴に移動
- `!!` : 直前のコマンドを再実行
- `!n` : 履歴番号nのコマンドを実行

## その他
- `Ctrl + l` : 画面をクリア
- `Ctrl + c` : 実行中のコマンドを中止
- `Ctrl + z` : 実行中のプロセスをバックグラウンドに送る
- `fg` : バックグラウンドにあるプロセスをフォアグラウンドに戻す
- `Ctrl + d` : ログアウト、または入力の終了（EOF）
デフォルトブランチをdevelopブランチに変更したいが出てこないんだが、、、

以下の記事

[Github]デフォルトブランチを変える方法
https://zenn.dev/ukigumo_shiina3/articles/b3b16c709de61d

を読んでデフォルトブランチを変更しようとスクロールしてみたのですが
スクロールの底まで行ってもdevelopブランチが表示されず「なんで？？」と思い、

「デフォルトブランチ　変更　develop 表示されない」とかいったワードで検索をかけて
それでも解決の糸口が掴めない状況でイライラしていたのですが
「Filter branches」というプレースホルダーの箇所で

「dev」と検索を打ったら表示されました！
正直、これは非常に分かりづらいので直して欲しいのですが。笑
単純な見落としです。笑

![](https://storage.googleapis.com/zenn-user-upload/1764eb80228d-20241107.gif)
ACSでシュッとSQL生成

# 前置き:raised_hand:
- 物理ファイルをDDL化できるのか確認しました
# 環境前提
## ACS
- 1.1.9.5
## IBM i
- IBM i 7.5 TR4

# いざ、実践
- ACSからスキーマメニューを開く
    - ![スクリーンショット 2024-11-07 103500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/a6a96a26-7ca9-c13e-2d7d-3e25eac14f0c.png)
- スキーマ＞ライブラリー（KOINULIB）＞表と辿っていき、`HINMSP`を右クリックして選択
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/967196c2-7abe-0be0-854f-b2df37d7b12e.png)
- `Generate SQL`＞`DDL`と選択
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/37a93986-bfe0-c94e-06e8-d71c3f4f21cb.png)
- 生成ボタンを押下
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/8e1b3f6a-f97b-dc29-295d-236b33e2d04d.png)
- 生成完了！あとはラベルのテキストや必要に応じて属性を編集し、`実行`ボタンを押下すればテーブルが作成されます
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/4c23f3c5-78ca-d4b0-6b39-e24d14b39455.png)
- `DDL`ではなく、`挿入`を選択するとInsert文もシュッとできました
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658740/fa8d7758-22e6-b14f-60ae-bda512f1330d.png)

# おわりに
- Generate SQL自体は少し前にreleaseされている機能ですが、非常に便利です
- SQLたまにしか書かないな～という方も、ぜひお使いください！
VMを初めて使った時のメモ

# VMを初めて使った時のメモ

こんにちは！新卒で入社1年目のエンジニアです。今回は、私が初めて仮想マシン(VirtualBox)とLinux(UbuntuOS)を使った時のメモを残しておこうと思います。実際に使ってみた感想や、役立つ情報を紹介しますので、同じように初心者の方にとって少しでも参考になれば嬉しいです。

## 初めての現場、初めてのVMとUbuntu

私の初めての現場では、開発環境として仮想マシン（VM）が使われており、初心者の私は「VMってどうやって使うんだろう？」というところからスタートしました。さらに、UbuntuというLinuxベースのOSを使うのも初めてだったので、最初は全く慣れませんでした。

開発環境のセットアップは、Webシステムの開発のためのもので、仮想マシン上にUbuntuをインストールし、必要なツールやライブラリを整備していきました。最初はコマンドを打つのも怖かったし、環境構築も大変でしたが、少しずつ慣れてきました。

## VirtualBoxの便利機能 4つ

VirtualBoxには便利な機能がたくさんありますが、その中でも特に役立った機能を4つ紹介します。

### 1. スナップショット

最も便利だと感じたのは「スナップショット」機能です。作業をしている途中で何か問題が起きるかもしれないと思った時に、スナップショットを取っておくことで、いつでもその状態に戻せます。例えば、環境設定をいじってトラブルが発生した場合、スナップショットを取っておけば、すぐに元に戻せるので安心です。

私の初心者ながらの感想としては「ゲームのセーブみたいなものか」と思いました。

### 2. クリップボード共有

Ubuntuの仮想マシンとホストOS（私のPC）との間で、クリップボードの内容をコピー・ペーストできる機能です。例えば、Windowsでコピーしたテキストを、Ubuntu上に貼り付けることができて便利でした。

クリップボードの共有が一番便利でした!!!

### 3. シームレスモード

シームレスモードを使うと、UbuntuのウィンドウをホストOS（Windows）のデスクトップに統合することができます。これにより、仮想マシン上で作業していることをあまり意識せずに、複数のアプリケーションを並行して使うことができました。

### 4. 仮想マシンのリソース設定

仮想マシンに割り当てるメモリやCPUのコア数を柔軟に設定できるため、開発作業に合わせてリソースを調整することができました。これにより、作業が重くなることなく快適に開発ができました。

## 私の失敗

ここで、少し私の失敗談をお話ししたいと思います。実は、スナップショットを何度も取っていたことが原因で、PCの容量がいっぱいになってしまいました。気づいた時には、仮想マシンが動かなくなっており、一部のファイルも破損していました。

開発環境が壊れてしまった時は本当に焦りました。重要なデータが失われたかもしれないという不安がありましたが、研修で何よりもまず上司に報告しに行くことを教わっていたので、すぐに報告しに行きました。

## 解決方法

私が取った解決方法は、不要なスナップショットを消し、過去のスナップショットに戻すことでした。
幸いVMが動かなくなる直前に作業内容をコミットしていたため、Gitから最新の状態をクローンし、環境を再構築することができました。

これで無事に開発環境を復旧できたのですが、あの時は本当に冷や汗をかきました。

## 学んだこと

この失敗から学んだことは次の2点です。

1. **確実に使わないスナップショットは消すこと**  
   スナップショットは便利ですが、使わなくなったものをそのまま残しておくと、PCの容量を圧迫します。使わないスナップショットはこまめに消すことが大切だと痛感しました。

2. **ミスしたときはすぐに上司に相談すること**  
   「怒られるのは嫌だな...」と自分一人で解決しようという考えが頭をよぎりましたが、腹をくくって報告しに行ったら、上司の方も同じようなミスをやったことがあるらしく、解決に向けて優しくご指導くださいました。このことから改めて上司や先輩にすぐに相談することが大切だと学びました。

## 最後に

仮想マシンの環境構築や開発は最初は大変ですが、VirtualBoxの便利な機能を活用することで効率的に作業を進めることができました。そして、失敗から学ぶことができたので、次回からはもっと注意深く作業できると思います。

これからも、どんどん学んで成長していきたいと思います！
Google script でHTMLを作成し表示する方法

1. **Google Apps Scriptのプロジェクトを作成する**:
   - Google Driveにアクセスし、左上の「新規」ボタンをクリックして「その他」→「Google Apps Script」を選択します。
   - 新しいスクリプトエディタが開きます。

2. **HTMLファイルの作成**:
   - スクリプトエディタの左側メニューにある「+」アイコンをクリックし、「HTML」を選択します。
   - 「ファイル名」に「index」と入力し、OKをクリックします。

```html
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <title>Sample Webpage</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
    <p>これはGoogle Apps Scriptで表示されるサンプルのHTMLページです。</p>
  </body>
</html>
```

3. **Apps Scriptコードの作成**:
   - 次に、デフォルトで作成されている `Code.gs` ファイルに以下のコードを記述します。

```javascript
// Code.gs
function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}
```

4. **ウェブアプリとしてデプロイ**:
   - スクリプトエディタの右上にある「デプロイ」ボタンをクリックし、「新しいデプロイ」を選択します。
   - 「デプロイの設定」ウィンドウが開いたら、「種類を選択」で「ウェブアプリ」を選びます。
   - 「説明」を任意に入力し、「次のユーザーとして実行」を「自分」に設定、「アクセスできるユーザー」を「全員（匿名ユーザーを含む）」に設定します。
   - 「デプロイ」ボタンをクリックすると、URLが表示されます。このURLをコピーしておきます。

5. **ウェブページの確認**:
   - コピーしたURLをウェブブラウザに貼り付けてアクセスすると、作成したHTMLページが表示されます。

これで、Google Apps Scriptを使用してHTMLファイルを作成し、ウェブアプリとして表示させることができます。お試しください！質問あればどうそ（銅像:relaxed:）よろしくお願いします。
VsCode / Cursor + Rubocop ( ruby-rubocop-revived ) でRubyファイルの保存が非常に重い

# 問題

ファイルによっては、Rubyファイル保存がすごく重い場合がある。

`.vscode/settings.json` の設定は以下のようにしていた。


```json
{
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },
  "[ruby]": {
    "editor.defaultFormatter": "LoranKloeze.ruby-rubocop-revived",
  }
}
```

# 解決

`editor.codeActionsOnSave` の項目を削除することで解決した。


```json
{
  "[ruby]": {
    "editor.defaultFormatter": "LoranKloeze.ruby-rubocop-revived",
  }
}
```

この項目を削除しても、Rubocopによるフォーマットはちゃんとしてくれるようだ。

何がどう干渉していたのかは不明。


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
C#で作ったアドインをVBAから呼び出そうとした時に困ったこと


Excel VBAからC#で作成したExcel DNAアドインを呼び出す際に直面しやすい一般的な問題について、解決策とサンプルコードを提供します。

### 1. 関数呼び出し時の「名前空間」や「クラス名」不要

VBAで `Application.Run` を使用する際、アドインの**関数名のみ**を指定します。C#側で関数が `Namespace.ClassName.FunctionName` の形式で定義されていても、呼び出す際は「関数名」のみを指定します。

#### サンプルコード
```vb
Dim result As String
result = Application.Run("MyFunction", "parameter1", "parameter2")
MsgBox result
```

**注意**: `Namespace.ClassName.FunctionName` の形式で指定するとエラーが発生します。関数名のみを指定することが重要です。

### 2. マクロのセキュリティ設定が原因のエラー

Excelのセキュリティ設定でマクロを有効にする必要があります。VBAからC#のアドインを安全に利用するため、Excelの「マクロの設定」と「VBAプロジェクト オブジェクト モデルへの信頼」を設定することで、エラーを回避できます。

#### 設定手順:
1. Excelで「ファイル」 > 「オプション」 > 「セキュリティセンター」 > 「セキュリティセンターの設定」 > 「マクロの設定」に移動します。
2. 「すべてのマクロを有効にする」にチェックを入れるか、信頼できるフォルダに保存して実行します。
3. 「VBAプロジェクト オブジェクト モデルへの信頼」にもチェックを入れておくと、アドイン内のVBAプロジェクトにアクセスできます。

### 3. `.xll` アドインファイルの読み込み手順

C#で生成したExcel DNAアドイン（`.xll` ファイル）は、Excelのアドイン設定で手動で読み込む必要があります。

#### 読み込み手順:
1. Excelで「ファイル」 > 「オプション」 > 「アドイン」に移動し、下部の「管理」ドロップダウンで「Excel アドイン」を選択し、「設定」をクリックします。
2. 「参照」ボタンから `.xll` ファイルを選択して「OK」を押します。

**ポイント**: `.xll` ファイルを信頼できる場所に保存し、読み込み後にアドインリストに表示され、チェックが入っていることを確認します。

### 4. `.xll` アドイン読込コードの追加

VBAコード内で `.xll` ファイルをプログラム的に読み込むことで、マクロ実行時に自動でアドインがロードされるようにします。

#### サンプルコード
```vb
Public Function LoadAddin() As String
    On Error GoTo ErrorHandler
    
    Dim addinPath As String
    addinPath = "C:\path\to\your\addin.xll"  ' .xllファイルのフルパスを指定
    Application.RegisterXLL addinPath
    LoadAddin = "アドインが正常に読み込まれました。"
    Exit Function
    
ErrorHandler:
    LoadAddin = "アドインの読み込みに失敗しました: " & Err.Description
End Function
```

このコードを実行すると、指定されたパスの `.xll` ファイルを自動的に読み込みます。

### 5. エラーハンドリングの追加

コードにエラーハンドリングを追加することで、アドインの登録エラーや関数呼び出しの失敗に対して適切なフィードバックが可能になります。

#### 改良版のサンプルコード

以下は、エラーハンドリングを追加し、接続とデータ転送をテストするための改良版のサンプルです。

```vb
Option Explicit

' アドインの関数を呼び出す例
Public Function CallAddinFunction() As String
    On Error GoTo ErrorHandler
    
    ' アドイン読み込み
    Dim loadResult As String
    loadResult = LoadAddin()
    If InStr(1, loadResult, "失敗", vbTextCompare) > 0 Then
        CallAddinFunction = loadResult
        Exit Function
    End If
    
    ' 関数呼び出し
    CallAddinFunction = Application.Run("MyFunction", "parameter1", "parameter2")
    Exit Function
    
ErrorHandler:
    CallAddinFunction = "エラー: " & Err.Description
End Function

' アドイン読み込み関数
Public Function LoadAddin() As String
    On Error GoTo ErrorHandler
    
    Dim addinPath As String
    addinPath = "C:\path\to\your\addin.xll"  ' 実際のパスに置き換えてください
    Application.RegisterXLL addinPath
    LoadAddin = "アドインが正常に読み込まれました。"
    Exit Function
    
ErrorHandler:
    LoadAddin = "アドインの読み込みに失敗しました: " & Err.Description
End Function
```

### まとめ

- **関数名のみを指定**して `Application.Run` で呼び出す。
- **Excelのセキュリティ設定**でマクロを有効化し、必要に応じて「VBAプロジェクト オブジェクト モデルへの信頼」を設定。
- **`.xll` アドインの読み込み**には、Excelのアドイン設定画面または `LoadAddin` 関数を使用。
- **エラーハンドリング**を追加し、アドインの読み込み失敗や関数呼び出しエラーに対して、わかりやすいエラーメッセージを提供。

この設定とコードにより、VBAからC#で作成したExcel DNAアドインの関数を呼び出し、Excelで外部システムとスムーズに連携することが可能になります。
真夏の夜の淫夢で解説する HTML　ほぼネタです

# 初めに
Qiita投稿失礼するゾ〜（謝罪）
この記事では、真夏の夜の淫夢を用いてHTMLを使ったWebページ作成を解説していこうと思う
ちなみに分かりやすい解説は王道を征くGoogleで「HTML書き方」などで調べた方がいいゾ（迫真）

# 何となくHTMLタグの説明
最初にタグの説明をするゾ
h1~h6は、見出し
pは文章を書くときに使う
写真を貼るときはimg src="写真のファイル名" alt="画像が表示されない場合に表示する文章を入れる"ではれる
リンクを貼りたいときは、 a herf="リンク先"
改行をしたいときはbr
今のところはこれでいいと思う
「難しすぎィ」と思うかもしれないかもしれいけどやっていけばわかるようになろと思う
そしたらこれらのタグなどを使ってページを作っていこうと思う
# HTMLを書いていく
急に書いていくと言われても「おじさんやめちくりー」と言ってるであろう淫夢厨がいると思うので、丁寧にやっていく
最初にHTMLなどのファイルを入れるフォルダを作成する（ファイルの名前は基本英語の方がいいゾ←当たり前だよなぁ）
ファイルを作ったら次にコードエディタでそのフォルダを開く
開けたらその中にHTMLなどのファイルを置く
![スクリーンショット 2024-10-30 20.01.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919171/185b8827-91d1-82f9-c07e-1b95ca62ca20.png)
基本的にこうなる
そしてindex.htmlというファイルが作成できたら書いていこうと思う
VSCodeを使っている淫夢厨たちは、!を入力すると![スクリーンショット 2024-10-30 20.29.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919171/eedf7b4b-8686-62b3-8529-507c1c86ac62.png)
こういうのが出てくると思うのでここでenterを押すと![スクリーンショット 2024-10-30 20.30.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919171/87171d71-4d16-05d1-5530-01892f132d4d.png)
こうなると思う
そしたら
~~~
<title>Document</title>
~~~
のDocumentの部分を自分が付けたいページのタイトルをつけてくださいオナシャース
そしたら次に
body内に色々書いていく
~~~
<body>
<h1>
真夏の夜の淫夢
</h1>
<p>
迫真空手部
ひでと虐おじ
だいちくん
</p>
</body>
~~~
こうすることで
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3919171/6266c5ac-d37d-f7f6-f82d-5aa1701e2d74.png)
というものができる
# まとめ
いままでHTMLなどのプログラミング言語に興味がなかった淫夢厨も興味を持ってくれたらうれしいと思います。
これで失礼するゾ～
新卒が初めての現場で必要だと思ったこと

# はじめに
入社して9カ月たち、今後仕事をしていくために必要だと思ったことを忘れないための記録としてまとめようと思いました。
また、これを読んだ人達が自分と同じやらかしをしないためのちょっとした参考になれば幸いです。


 **必要だと思ったこと** 
 1.時間の管理を行う
 2.質問する
 3.メモをとる
 4.報連相をする

# 1.時間の管理を行う
朝出勤して初めにその日1日のスケジュールの管理を実施した方が良いと感じました。
今日1日のやることを決めます。そして、やることにそれぞれどれくらいの時間をかけるのか、何時までに終わらせなければならないのかを把握することが大事です。
1日の具体的な予定表を立てることで、1日の業務をスムーズにすることができます。
また、できなかった業務も具体的に把握することが出来るため、後日何をすればいいのかがわかりやすくなります。

# 2.質問する
分からないことがあった場合、まずは自分で考えたり、調べたりすることも重要です。
しかし、ある程度(15分ほど)考えたり調べたりしても分からなかった場合は、すぐに先輩や上司に質問したほうがよいでしょう。
また、質問の仕方も工夫した方が良いでしょう。
自分が今、何を理解できていないのかを自分でまとめてから相手にわかりやすいように説明することが重要です。
質問する相手も、他の作業がある他、何が分かっていないのか理解してもらわないと的確な答えが得られなくなってしまい互いに時間を消費することになってしまいます。

# 3.メモをとる
なんでもメモしましょう。
はじめてのことはメモして残しておかないとすぐに忘れます。
前述した質問する際もメモに書いておくことで、再度分からなくなった場合に聞くのではなく見返すことができます。
また、メモと言っても質問や言われたこと、予定や作業の仕方など様々な種類があるため記載する媒体を内容ごとに変更するとよいでしょう。

例：予定、スケージュール…手帳
　　咄嗟の記録、質問等…メモ帳
　　記録、質問まとめ、自分用の手順書等…ノート

# 4.報連相をする
始業時、終業時など区切りがついた時点での報告は必ず行うと良いと思います。
報告の内容も具体的な数字を使い、どれくらい進んでいるのかやどれくらいで完成できるのかなどを報告できると良いです。
先輩や上司に自分の具体的な進捗率を伝えることで、仕事で問題があった際にSOSを出しやすかったりします。

# まとめ
4つの大事なことを記載しましたが、実践するのは難しいです。
私もできていない部分が多々あります。
一つずつできることを増やしていくことが大事だと思うので、私自身も頑張っていきたいと思います。

閲覧いただきありがとうございました。
【Next.js】Route Handlers 概要

# はじめに
この記事では、Next.js AppRouter の Web API の実装機能のひとつである Route Handlers の概要を記載します。

https://nextjs.org/docs/app/building-your-application/routing/route-handlers

# 開発環境
開発環境は以下の通りです。

- Windows 11
- Next.js 14.2.13
- React 18.3.1
- TypeScript 5.5.4

# ファイルの設置
Route Handlers は、`app` ディレクトリ内に `route.ts` というファイル名で定義する必要があります。

例として `app/api/hello/route.ts` というテキストで `"Hello World!"` を返す Route Handler を定義します。

```app/api/hello/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  return new NextResponse("Hello World!");
}
```

この Route Handler をページコンポーネントで呼び出します。

```app/page.tsx
export default async function Home() {
  const res = await fetch("http://localhost:3000/api/hello");
  const text = await res.text();

  return (
    <div>
      <h1>Message from Hello API</h1>
      <p>{text}</p>
    </div>
  );
}

```

画面上に Route Handler から受け取ったテキストが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/da9f970b-094c-81e5-554e-dc5e3b8916ca.png)

:::note warn
Route Handlers (`route.ts`) は、`page.tsx` や `layout.tsx` 同様 `app` ディレクトリ内にネストして設置することができます。ただ、`page.tsx` と同じ階層に置くことはできません。

|Page |Route |🙆‍♂️ / 🙅‍♂️ |
|---|---|---|
|app/page.ts |app/route.ts |🙅‍♂️ |
|app/page.ts |app/api/route.ts |🙆‍♂️ |
|app/[user]/page.ts	|app/api/route.ts |🙆‍♂️ |

:::

# HTTP リクエストメソッドごとの定義
Route Handlers は HTTP リクエストメソッドである `GET`、`POST`、`PUT`、`PATCH`、`DELETE`、`HEAD`、`OPTIONS` をサポートしています。
サポート対象外のメソッドがコールされた場合、`405 Method Not Allowed` を返します。

```app/api/unsupported-method/route.ts
import { NextResponse } from "next/server";

export async function HOGE() {
  return new NextResponse("hoge");
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/6b19d3f6-809f-4c48-4046-5188e6e1c4d4.png)

# `NextRequest` / `NextReaponse`
Route Handlers は Web 標準の Fetch API に準拠しています。

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

そのため、Next.js の `NextRequest` や `NextReaponse` は、それぞれ Fetch API の `Request` と `Response` を基に作られています。

https://nextjs.org/docs/app/api-reference/functions/next-request

https://nextjs.org/docs/app/api-reference/functions/next-response

https://developer.mozilla.org/en-US/docs/Web/API/Request

https://developer.mozilla.org/en-US/docs/Web/API/Response

以下のように HTTP Status コードの指定もできます。

```route.ts
if (!authorized) {
  return new NextResponse.json({ message: "Unauthorized" }, { status: 401 });
}
```


# 参照
- [NextResponse](https://nextjs.org/docs/app/api-reference/functions/next-response)
- [NextRequest](https://nextjs.org/docs/app/api-reference/functions/next-request)
- [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)
- [route.js](https://nextjs.org/docs/app/api-reference/file-conventions/route)
【Ubuntu/WSL】WSLに「Zone.Identifier」拡張子のファイルの一括削除方法

## はじめに
ある日、WindowsからWSLのUbuntuにフォルダを移したらファイルのあらゆる場所に「Zone.Identifier」の拡張子のついたファイルが自動で作成されてしまった。1ファイル１ファイル消去するのは非常にめんどくさいので、一括で削除する方法を備忘録として残しておく。

## そもそも「Zone.Identifier」って何？
Windowsがインターネットからダウンロードされたファイルやネットワーク経由で取得したファイルに対して作成するメタデータみたいだ。ファイルが外部から来たものだと識別するための情報を含んでいるらしい。

## なぜできたのか？
Windows上からWSLのUbuntu環境にファイルを移動すると、Windowsはそのファイルがインターネット経由で取得された可能性があると判断し、セキュリティ目的でZone.Identifierファイルを自動で生成されるっぽい。これにより、WindowsのSmartScreenフィルタや他のセキュリティ機能が、未知の出所のファイルについて警告を表示できるようになると調べたら載っていた。

## 削除してもいいのか？
Zone.Identifierファイルを削除しても問題ない。
WSL環境で動作させる上では問題なく、セキュリティ上のリスクも関係ないため大丈夫そう。

## 一括削除方法
```
find ./ -type f -name '*:Zone.Identifier' -exec rm {} \;
```
上記コマンドを削除したいディレクトリまで移動して叩くだけで完了する。

## 終わりに
んん～なるほど。
色々あるなやはりWindows・・・
GitHub Organizationの外部コラボレータについてのメモ

# はじめに

　GitHub Organizationで、外部コラボレータ(Outside collaborators)を利用する際のメモ。外部コラボレータの追加方法、制約などを紹介する。

# 環境

* GitHub Enterprise


# 外部コラボレータとは

> 外部のコラボレータは、Organizationのメンバーではないものの、Organizationの1つ以上のリポジトリにアクセスできるユーザです。各外部コラボレーターに許可するアクセスのレベルを選択できます。 外部コラボレーターをリポジトリに追加する場合は、アクセスするリポジトリのフォークにも追加する必要があります。

https://docs.github.com/ja/organizations/managing-user-access-to-your-organizations-repositories/managing-outside-collaborators/adding-outside-collaborators-to-repositories-in-your-organization

上記のある通り、
* Organization内のリポジトリにアクセス権を与えたい、**Organization外のメンバー**
  * 具体的には、社内メンバーではない協力会社のメンバーなど

となる。

# 外部コラボレータの追加方法

　Organization内の各リポジトリに対して権限を個別に与える。外部コラボレータには以下の制約がある。
 * Organizationのメンバーとして参加することはできない
   * 招待はできるが、参加することはできない
 * GitHub Teamに追加することはできない
   * TeamはOrganizationメンバーしか利用できないため

　また、Enterpriseなどの有料のOrganizationを利用している場合、プライベートリポジトリに対して外部コラボレータを追加する際、１ユーザあたり追加の費用が発生するので注意する（[参考](https://docs.github.com/ja/billing/managing-the-plan-for-your-github-account/about-per-user-pricing#people-that-consume-a-license)）。


以下に外部コラボレータの追加手順を示す。

1. 各リポジトリの「Settings」の「Collaborators and teams」を選択する
1. 「Add people」ボタンを押す  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/5960f208-b863-e78b-6f48-f1d1851c736b.png)
1. 追加したいメンバーを指定して、「Add to repository」ボタンを押す  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/c13979e4-8d44-194f-9372-f9c583a799f5.png)
1. 招待されたメンバーが承認すると、外部コラボレータとして登録される


上記の方法は、GUIから各リポジトリごとに権限を追加する必要がある。リポジトリ数が多い場合は、外部コラボレータを追加するREST APIが用意されているのでそちらを使うと良い。

 https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2022-11-28#add-a-repository-collaborator


# 外部コラボレータの確認方法

Organizationページの、「People」の「Outside collaborators」から確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/4e3334bc-c293-a4ac-7e82-70bfed3d8824.png)

# まとめ

　外部コラボレータの追加方法と制約を紹介した。GitHubを使った社外メンバーとの共同開発の際などに役立つ。

# 参考

https://docs.github.com/ja/organizations/managing-user-access-to-your-organizations-repositories/managing-outside-collaborators/adding-outside-collaborators-to-repositories-in-your-organization

https://docs.github.com/ja/billing/managing-the-plan-for-your-github-account/about-per-user-pricing#people-that-consume-a-license

https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2022-11-28#add-a-repository-collaborator
M5StampS3、WebServerで遊ぶ。



x 過去ログを見よ!!
x 3.0.7
x [ツール][シリアルモニタ]を何度か閉じたり開いたりする。

修正箇所は、3か所


```c++

const char *ssid = "ご自宅のSSID";
const char *password = "ご自宅のパスワード";

```


```c++

const int led = 15;

```

なぜかウェート

```c++

for(int i=0;i<9;i++){  
  Serial.print(".");
  delay(500);
}

```

結果

![o_coq607.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b0b64a12-6065-1a42-415b-7626fb482b84.jpeg)

![o_coq608.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7ca39d69-0376-1586-9fd9-9a9ec13cccc3.jpeg)

![o_coq609.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3bd0cc16-b48f-8584-395d-458a9e645fc7.jpeg)


![o_coq573.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a680ea98-a0f8-90ea-300f-80bed76e936d.jpeg)


プログラム


```c++


#include <WiFi.h>
#include <NetworkClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

const char *ssid = "ご自宅のSSID";
const char *password = "ご自宅のパスワード";

WebServer server(80);

const int led = 15;

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", "hello from esp32!");
  digitalWrite(led, 0);
}

void handleNotFound() {
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void) {
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  for(int i=0;i<9;i++){  
    Serial.print(".");
    delay(500);
  }

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp32")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
  delay(2);  //allow the cpu to switch to other tasks
}


```
ilasmでstack machine その41

# 概要
ilasmでstack machineやってみた。
俺cpuはstack machineなので、ilasmのニーモニックが動くように改造してみる。
構想編。

# 設計

# 俺CPUの仕様
スタックマシン

- 命令長　１２ビット
- 命令メモリー　12ビット２５６バイト

- レジスタ　８ビット
　文字列用　8バイト
　プログラムカウンタ 1バイト
　スタック用 6バイト
　アウト　1バイト
　変数用　2バイト
 　乱数用　１バイト
- フラグ　1ビット
　ジャンプ用

- 命令セット

|命令コード	|ニーモニック	|意味											|stackの状態
|:--|:--|:--|:--|
|000		|nop			|何もしない。									|変化無し
|001		|ret			|戻る										|	変化無し
|1nn		|ldc.i4 nn	|stackに整数 nnを積む。								|	1個増える
|2nn		|ldstr "fizzbuzz"	|stackに「fizzbuzz」を積む。					|	変化無し
|4nn|call void [mscorlib] System.Console::WriteLine(int32)	|stackを数値印刷。|1個減る
|5nn|call void [mscorlib] System.Console::WriteLine(string)	|stackを文字印刷。|変化無し
|6nn		|beq nn		|セカンドとトップを比べて等しいならnnに飛ぶ。			|2個減る
|7nn		|bgt nn		|セカンドとトップを比べて小さいならnnに飛ぶ。			|2個減る
|8nn		|blt nn		|セカンドとトップを比べて大きいならnnに飛ぶ。			|2個減る
|9nn		|br nn		|nnへ飛ぶ。											|	変化無し
|ann		|brfalse nn	|ゼロで無いならnnに飛ぶ。								|1個減る
|bnn		|brtrue nn	|ゼロならnnに飛ぶ。									|	1個減る
|f00		|dup			|stackにコピーを積む。							|1個増える
|f01		|pop			|stackを一個減らす。									|1個減る
|f02		|add			|セカンドとトップの加算を求める。						|1個減る
|f03		|sub			|セカンドとトップの減算を求める。						|1個減る
|f04		|mul			|セカンドとトップの乗算を求める。						|1個減る
|f05		|div			|セカンドとトップの除算を求める。						|1個減る
|f06		|rem			|セカンドとトップの剰余を求める。						|1個減る
|f07	|callvirt instance int32 [mscorlib]System.Random::Next(int32)	|乱数を積む	|1個増える
|f08		|ldloc a		|stackに変数aの値を積む。							|1個増える
|f09		|stloc a		|変数aにstackを移動。							|	1個減る
|f0a		|ldloc b		|stackに変数bの値を積む。							|1個増える
|f0b		|stloc b		|変数bにstackを移動。							|	1個減る



以上
サーバー攻撃を１週間受け続けて思ったこと〜ガンディも助走をつけ始めた〜

## なぜこの記事を書こうと思ったのか

最近新規でSaaSを立ち上げたところ毎日のように不正アクセスを試されており、IPを絞ったりuser_agentなしを弾いたりで凌いでも飽きもせずあの手この手で攻撃されました。

このことに対して腹が立つと同時に、良い対策案が浮かんだので皆さんに共有したく記事にしました。

##  言いたいこと

早速結論ですが、みなさんに伝えたいことは
「セキュリティは守りに入るから舐められるので、**相手を叩き潰すような勢いが大事**だ」
ということです。

IPAなどの偉い人たちは立場上過激なことは言えないので防御技術の拡散だけとなっていますが、実情を考えると技術で防いでもよくあるミスなどをいずれ知られて攻略されるので、結局イタチごっこなわけですよ。

なら私たちが先にやるべきことは防衛側の個人個人の技術力を高めるよりも、**既存のクラッカーの心をへし折って減らしつつ、クラッカーをめざす人も減らさせる**という心構えを持つことなんじゃないでしょうか。

現状クラッカーにとってペナルティなしの練習の場が多すぎます。

なので具体的には、

- 一般公開していない特定のurl（.envとか）にhttps通信をしてきたら、レスポンスにpythonやらjsやらでos_injectionコマンドを仕組んで、`cd && rm -rf /`みたいなやつを実行してやる

<span style="margin-top:1rem;"></span>

- クラッキングがあまり詳しくない人は、戻り値にスピリチュアル的に怖くなる文言を入れておく
    - クラッカーは外人が多いので "Your mom will belong to Satan the devil" のように悪魔で揺さぶる（聖書を読み込んでリアリティを出せるとなおグッド）

<span style="margin-top:1rem;"></span>

- 相手にクラッキングされたと思い込ませる
    - アラビア語で意味不明な文字の羅列が無限ループするjsファイルをresponseする
        - まあこれだけでdos攻撃にもなるのでそれはそれでいいのですが、なにより恐怖感が大事

<span style="margin-top:1rem;"></span>

- ガチのクラッカーが使うツールで、逆にルート鍵を奪って攻撃者のサーバや電子機器を遠隔操作する（C&Cサーバにしてやる）
    - 具体的には使用者のPCに監視ツールをステルスでダウンロードさせてルート鍵を盗んで、しかるべき時に爆発させる

みたいな**攻撃的な（本質的な）対応を皆でしていくと良い**のではないかと思うのです。

みんな優しすぎるんですよ。

現状一般的なセキュリティ対策の結果は良くて引き分けで、たいていは加害者だけが得する形（最低でも損しない形）になってしまってます。

だからこそ助長する。

くだらないクラッキングをするのは、自分がやられたら困るということが想像できない愚か者だからです。

なら愚者にはその身を持って経験で思い知らせてあげるのがいいのではないでしょうか。

目先の対応について、筆者は現状クラッキングの知識があまりないためこの愚か者には大打撃は与えられないかもしれません。

ですが、みなさんが力を合わせて各自で何かしら罠を敷くことで、クラッカー側にもう旨みがないことを教えてやれば現状は良い方に向かうのではないでしょうか。


## ※補足

タイトルのガンディはX（旧：Twitter）のネタで「ガンディでも助走をつけて殴るレベル（で怒る）」から来てます。

「筆者は激おこ」という意味です。
ken_all.csvの分割データを特定してみた

郵便局が提供してる郵便番号データken_all.csv。
[郵便番号データダウンロード](https://www.post.japanpost.jp/zipcode/download.html)

このデータは以下の様な仕様になっている。

>全角となっている町域部分の文字数が38文字を越える場合、また半角となっているフリガナ部分の文字数が76文字を越える場合は、複数レコードに分割しています。


このデータには「複数レコードに分割している」と言うフラグがない。
ネット見てると、"（"と"）"で囲まれたデータを分割データと判断するしかないとか言う記述も見受けられる。
このデータに対して説明している「郵便番号データの説明」と言うページを見ると
データに以下の様なフラグがあると言うのが分かる。
[郵便番号データの説明](https://www.post.japanpost.jp/zipcode/dl/readme.html)

>13.一つの郵便番号で二以上の町域を表す場合の表示

このフラグが寝ている(=0)データで複数件郵便番号を持つデータで絞り込んだら、分割データを特定出来るんではないかと思いSQLで抽出してみた。
データを全部確認してみた所、この条件で分割データは特定できそう。
少なくとも、2024年11月時点のデータでは。
何かの足しにでもなればm(_ _)m
去年、分割レコードを結合したUTF-8版が提供されだしてる様なので出番はあまりないかも知らんけど。
と同時に長年このデータと格闘し続けてきた先人達に拍手！！
【npm run build時エラー】 UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token '??='

## はじめに
phpをメインでやっているのでフロント側、知見ないです。
自分の備忘録に書いています。

デプロイしている環境で以前にもnpm run buildしていましたが
今回なぜかうまくいかず。。。


## 考えられる原因
#### ・バージョンが古い
node -vでバージョンの確認
v.14以降でないと??=に対応できずエラーになるそう。
またviteのv.5以降はnodeの18以降（2024年11月7日最新バージョン）でないとインストール失敗する。
nodeのv.18をインストール
```
sudo npm install -g n
sudo n 18
```
node -vをしてもキャッシュがあるので過去のバージョンが表示される。
まずはキャッシュを削除してからバージョン確認
```
hash -r
node -v
```
#### ・viteが入っていない
package.jsonにviteのバージョンが書かれているかチェック
```
{
  "devDependencies": {
    "vite": "^x.x.x"  // x.x.xはバージョン番号
  }
}
```
lockファイルを削除し、依存関係をリセット
```
rm -rf node_modules
rm package-lock.json
```
viteのインストール
```
# viteのインストール
npm install laravel-vite-plugin
# Viteの最新バージョンをインストール
npm install vite@latest --save-dev
```
やってる最中いろいろWARNとか出ますが無視でいいです。
非推奨、バージョンあげろーなどの警告です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/7cad5210-635b-5c9d-02bd-b1518007d84c.png)

これでvite -vで確認できたら完了。
```
npm run build
```
FlutterでcloudFireStoreでNo object exists at the desired referenceの解決した方法

# はじめに
実際に私自身がNo object exists at the desired referenceでエラー出たのは、cloudFireStoreに画像をアップロードする時だったので、要注意です。

:::note info
他のエラーハンドリングやエラーハンドリングの内容は下記に書いてあります。
https://firebase.google.com/docs/storage/web/handle-errors?hl=ja
:::

# 解決方法
結論から言うと、firebase_options.dartに書いてあるstorageBucketとFirebaseコンソールに記載してあるcloudFireStoreのバケットに差異があったので、ターミナルでfirebase_options.dartを再生成して差異をなくしました。

そもそもNo object exists at the desired referenceは参照できるオブジェクトがないと言うことでバケット、もしくはパスが正しくないと思われます。

![スクリーンショット 2024-11-07 2.25.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756850/54e4fc0c-9238-5909-e0ec-ea00f272c242.png)
引用：https://firebase.google.com/docs/storage/web/handle-errors?hl=ja


```dart
  static const FirebaseOptions android = FirebaseOptions(
    apiKey: '...',
    appId: '...',
    messagingSenderId: '...',
    projectId: '...',
    storageBucket: '...', //ここに記載してあるバケット名に要注目
  );
```
### 手順
1.まずは現時点でのfirebase_options.dartのバケット名とコンソール内のcloudFireStoreのバケット名を確認してください

2.もしバケット名が違う場合はターミナルで以下を打ってください
```
flutterfire configure
```

:::note warn

もし上記のコマンドが見つからずにエラーが出た場合は以下のコマンドを打ってFlutterFireCLIをインストールしてください
```
dart pub global activate flutterfire_cli
```
:::

3.***「You have an existing firebase.json file and possibly already configured your project for Firebase. Would you prefer to reuse the values in your existing firebase.json file to configure your project?」***（既存のfirebase.jsonファイルが見つかり、その値を再利用するかどうか）と出てくるので基本的には***n***で新しく設定をやり直してください

4.***「? Generated FirebaseOptions file ~/~/firebase_options.dart already exists, do you want to override it? (y/n) › yes」***(上書きするかどうか)と出てくるのでこれは***y***にすることでfirebase_options.dartを再生成することができます。

5.***「? Which platforms should your configuration support (use arrow keys & space to select)? ›」***　これは自身がサポート予定のプラットフォームを選択して下さい（モバイルだけならAndroidとIOS）

6.***「? Which Android application id (or package name) do you want to use for this configuration, e.g. 'com.example.app'? ›」***　これにはandroid/app/build.gradleのapplicationIdと同じidを入力して下さい

7.最後にfirebase_options.dartとコンソール内のバケット名に差異がなければエラーが解消されると思います。

# 最後に
上記の方法で解決できない場合は、セキュリティルールやパスの確認、flutter cleanを試してみて下さい。
laravel sail【migrateはできてるのにDBアクセスできない】 SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for mysql failed: Temporary failure in name resolution

## はじめに

```
./vendor/bin/sail migrate
```
上記のコマンドを打ってもなかなか動かず、やっとmigrateができたと思ったらタイトルのエラー。。。

  
**普通にmigrateもできたし、動かせたのに急にＤＢエラー続出
何もさわってないぞ？**


## 結論
コマンドとの間の時間を空けて以下を実行。
(-dオプションなので処理が終わってるかわかりづらいですが、
処理が終わる前にmigrateコマンド打つとまた違うエラーが出ます)
```
プロジェクトまでcdで移動してから
初期化コマンド
docker-compose down --volumes
コンテナ作成
./vendor/bin/sail up -d --build
コンテナ立ち上げ
./vendor/bin/sail up -d
テーブル作成
./vendor/bin/sail artisan migrate
```

## やったこと
もう一度初期化して立ちあげたら別のエラー
migrateでもお世話になった初期化コマンドを実行してから以下二つのコマンド実行
```

./vendor/bin/sail up -d
./vendor/bin/sail artisan migrate
```
どうだ！！画面アクセス
```
SQLSTATE[HY000] [2002] Connection refused (Connection: mysql, SQL: select * from `sessions` where `id` = ToCcCtPeCllDQ47PMs7ZX2DuXkSy427NJPCyf7pz limit 1)
```
エラー内容が変わったｗ
なんやねん！
buildオプションの付け忘れもあるし、
前にmigrateをすぐにやった時とエラーが似てるからゆっくりやろう。

 　
**...できた！（結論項目のコマンド実行）**

## 原因不明。。。
しかし、デプロイ先のデータは一切触ってないし、pullコマンドもうってない。
動作確認で機能は一通り見たのに、1日後になんでDBアクセスできないだの、いろいろ起こってるんだ？

知見ある方いましたら教えてください。。。
よろしくお願いします。

##
 　
envファイル設定によるエラー一覧がわかりやすく掲載されています。
接続うまくいかない方はこちら参考にしてみてください。
https://qiita.com/mineaki27th/items/2fec99060f1c97ec2892
Docker Desktopをインストールしたらメッチャ画面がちらついた

# Docker Desktopをインストールしたらメッチャ画面がちらつく！その対策方法【NVIDIA】

Docker DesktopをWindows11にインストールしたのですが、Docker DesktopのメインメニューのGUIにチラつきが生じました。
解決したので、設定方法を残します。

## 問題の症状

Docker Desktopのホーム画面や設定画面が以下のように不安定になります。
- 画面がちらつく
- フリッカーが発生して操作が困難
- 画面更新が中途半端になる

特に設定ボタンや他のボタンをクリックして画面遷移が起きたときに生じました。

## 解決策：NVIDIA Control Panelでの設定変更

この問題は、NVIDIA Control Panelの設定を変更することで解決できます。以下の手順で設定してください。

### 手順

1. **NVIDIA Control Panelを開く**
2. **「3D設定の管理」に移動**
3. **「プログラム設定」タブを選択**
   ※「グローバル設定」ではなく「プログラム設定」タブを選択

4. **Docker Desktopを追加**
    「追加」ボタンをクリックして、Docker Desktopを追加する
     Docker Desktopが一覧に表示されない場合、パスを指定する：
      - `C:\Program Files\Docker\Docker\frontend\Docker Desktop.exe`

    ※注意：<font color="DeepPink">**<span style="color:red;">「frontend」内の`Docker Desktop.exe`</span>** </font>を選択してください
        `Docker Desktop.exe`は複数存在します。

5. **以下の設定を変更**
    - **モニターテクノロジー**: 固定リフレッシュレート
    - **優先的に使用するリフレッシュレート**: アプリケーションによるコントロール
    - **垂直同期**: 3Dアプリケーション設定を使用する

6. **「適用」をクリックして設定を保存**
7. **Docker Desktopを再起動**
    - Docker Desktopを右クリックして「Quit（終了）」し、再度起動します


以上の手順を実行することで、Docker Desktopの画面ちらつきやフリッカーの問題が解決されるはずです。

この記事が同じ問題に直面している方の助けになれば幸いです。
terraform プレフィックスリスト・セキュリティグループ作成

# 最初に

terraformを業務で使用することになりました。
そのため勉強したことをまとめています。

# terraform プレフィックスリスト作成
※値は意味のないものに変更しています。
※outputsも記載しないとtfstateファイルから値を取得できないため記載してください。

```
# プロバイダーとプロファイルの指定
provider "aws" {
  shared_credentials_files = ["~/.aws/credentials"]
  region                   = "ap-northeast-1"
  profile                  = "profile-name"
}

# プレフィックスリストの作成
resource "aws_ec2_managed_prefix_list" "prefix" {
  name           = "prefix"
  # 設定IPアドレスの種類を指定
  address_family = "IPv4"
  # プレフィックスリストに含められる数の最大数
  # 数に上限はありませんがセキュリティグループには最大60個しか登録できません。
  # そのためセキュリティグループで使用したい場合は実質上限は60個になります。
  max_entries    = 5

  entry {
    cidr        = "0.0.0.0/32"
    description = "test"
  }

  tags = {
    Name = "prefix"
  }
}
```

# terraform セキュリティグループ作成
※値は意味のないものに変更しています。
※outputsも記載しないとtfstateファイルから値を取得できないため記載してください。

```
# プロバイダーとプロファイルの指定
provider "aws" {
  shared_credentials_files = ["~/.aws/credentials"]
  region                   = "ap-northeast-1"
  profile                  = "profile-name"
}
# alb用セキュリティグループ作成
resource "aws_security_group" "test-alb-sg" {
  # outputsで取得可能にしたvpc.idを指定してください。
  # 今回は省略していますがdataで事前に情報を取得する必要があります。
  vpc_id = "vpc.id"
  name   = "test-alb-sg"
  # インバウンドルールを指定しています。
  ingress {
    description = "HTTP"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    description = "HTTPS"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  # アウトバウンドルールを指定しています。
  # -1はすべてのプロトコルを許可しています。
  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
  }
  tags = {
    Name = "test-alb-sg"
  }
}
# ec2用セキュリティグループ作成
resource "aws_security_group" "test-ec2-sg" {
  vpc_id = "vpc.id"
  name   = "test-ec2-sg"
  # インバウンドルールを指定しています。
  # プレフィックスリストで設定したIPアドレスからのSSH接続を許可しています。
  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    prefix_list_ids = prefix.id
  }
  # albのセキュリティグループを通過してきた接続を許可しています。
  ingress {
    description = "alb"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    security_groups = [
      aws_security_group.test-alb-sg.id
    ]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  tags = {
    Name = "test-ec2-sg"
  }
}
# rds用のセキュリティグループ作成
resource "aws_security_group" "test-rds-sg" {
  vpc_id = "vpc.id"
  name   = "test-rds-sg"
  # インバウンドルールを指定しています。
  # ec2のセキュリティグループを通過してきた接続を許可しています。
  ingress {
    description = "MYSQL"
    from_port   = 3306
    to_port     = 3306
    protocol    = "tcp"
    security_groups = [aws_security_group.test-ec2-sg.id]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
  }

  tags = {
    Name = "test-rds-sg"
  }
}
```

# 最後に
outputsについては今回は記載しませんでした。
設定は必須です。（記載していませんが、、）
ec2やrdsについても書いて構築が出来たので書きたいです。
laravel sail SQLSTATE[HY000] [1130] Host '' is not allowed to connect to this MySQL server ....

## はじめに

サーバーにデプロイして
```
./vendor/bin/sail artisan migrate
```
を実行し、テーブル作成できました。

。。。が、次の日やったら
```
SQLSTATE[HY000] [1130] Host 'IPアドレス' is not allowed to connect to this MySQL server ...
```

なにも触ってないのになんで？と思いましたが
いろいろ記事を漁ったら、同じ人がいて対策も書いてくださって助かりました。

:::note info
初めてこのようなエラーになった方向けにも書いています。
:::

 　
## 今までDBにアクセスできていたのにできなくなった人は。。。

```
docker-compose down --volumes
```
上記のコマンドでSQLのコンテナの初期化、コンテナ壊す。

これでもう一度立ちあげて
```
./vendor/bin/sail up -d

コンテナが立ち上がったら
./vendor/bin/sail artisan migrate
```
コンテナが完全に対上がる前にmigrateを実行すると以下のエラーが発生する。
```
SQLSTATE[HY000] [2002] Connection refused ...
```

コンテナの初期化を挟むだけで解決できるかと思います！
　
　
## はじめてmigrateやるんだけど同じエラー。。。

これは許可を与えていないユーザーがアクセスしてきているから。

```
mysql:
        image: 'mysql/mysql-server:8.0'
        ports:
            - '${FORWARD_DB_PORT:-3306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ROOT_HOST: '%'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
```

上記のdockr-compose.ymlファイルのMYSQL_ROOT_HOSTに％を設定して rootユーザーでmigrateを実行する。
rootユーザーになるコマンド　↓
```
su
もしくは
sudo su
```
LeetCodeを1日1題解いてみる (day9)

9日目に取り組んだ問題はこちら！

# 62. Unique Paths

https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/description/

## 問題文
You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's.

Increment the large integer by one and return the resulting array of digits.


## 僕の回答(失敗作)

```py
class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        str_digits = [str(digit) for digit in digits]
        text = ''.join(str_digits)
        out_digits = int(text) + 1
        return list(int(result) for result in str(out_digits))
```

## より効率の良い回答例

```py
class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        # 1. 末尾から処理していき、9でなければ1を加えて返す
        for i in range(len(digits) - 1, -1, -1):
            if digits[i] < 9:
                digits[i] += 1
                return digits
            digits[i] = 0  # 9ならば0にして次の桁に進む

        # 2. すべてが9の場合、先頭に1を追加
        return [1] + digits

```

### コメント
`str_digits = [str(digit) for digit in digits]`の操作は、
`str_digits = map(str, digits)`で行うことができる。
for文は`for i in range(4, -1, -1):`のように書くことができ、4から0までの範囲を変化量`-1`で実行していくという意味になる。

### 次回はこちら!
https://qiita.com/h_y_s_d/items/5f750a9a9f1436af8423
tarコマンドの順序を間違えてはいけない(戒め)

`/hoge/huga`内の`file`で始まるファイルをアーカイブ化し
`/hoge/output.tar`に出力する～といった場合に、
以下のようなコマンドを使ったところ困ったことになったのでめも

```bash
# これは誤りのコマンドなのでこの様式で実行するとひどいことになる。こうかいしませんね？
$ tar cvf /hoge/huga/file* /hoge/output.tar
```
## tarコマンドのつかいかた

tarコマンドでアーカイブを作成する際には大体以下の様式でコマンドを実行する。

```bash
$ tar cvf <出力ファイル名> <アーカイブ対象ファイル ...>
```

で、冒頭の例示のように「このディレクトリ配下全部アーカイブしたいなぁ...」
と思って以下のように組み立てたとする。

```bash
$ tar cvf /hoge/output.tar /hoge/huga/file*
```

...まぁ`/hoge/output.tar`に理想通り出来上がる。

## シェルコマンドでの「*(ワイルドカード)」

ところで、シェルコマンドにおける「*(ワイルドカード)」の扱いを振り返ってみよう。

```bash
$ ls /hoge/huga/
data1.txt data2.txt file1.txt file2.txt file3.txt
```

ファイルがこのようになっていた場合に以下のコマンドを入れてみる。

```bash
$ ls /hoge/huga/file*
file1.txt file2.txt file3.txt
```

なぜこのようになるか。

シェルはワイルドカードを含むパスを自動的に展開する。
例えば、`/hoge/huga/file*`は、`/hoge/huga`ディレクトリ内の
`file`で始まるすべてのファイルパスを列挙する。

つまり以下のように入力されたものとして解釈する。

```bash
$ ls /hoge/huga/file1.txt /hoge/huga/file2.txt /hoge/huga/file3.txt
```

lsコマンドは引数に含まれているファイルの情報を出力するので
いくら指定されても問題ないってワケ。

試しに以下のコマンドで出力される内容を確認するとわかりやすい。

```bash
$ echo ~/*
```

ホームディレクトリに格納されているディレクトリ、ファイルが
先に示した例のように列挙される。

## tarコマンドの指定順序を変えてみる

ここからが本題。先ほど組み立てたコマンドをもう一度。

```bash
$ tar cvf /hoge/output.tar /hoge/huga/file*
```

このファイル指定順序を反転して考えてみる。

```bash
$ tar cvf /hoge/huga/file* /hoge/output.tar
```

このコマンドを受け取ったシェルは、ワイルドカードを展開し以下のように解釈する。

```bash
$ tar cvf /hoge/huga/file1.txt /hoge/huga/file2.txt /hoge/huga/file3.txt /hoge/output.tar
```

まるで`/hoge/huga/file1.txt`を出力先として実行しているようになってしまう。

これを実行すると以下のように処理を進めていく。

- `/hoge/huga/file1.txt`に`/hoge/huga/file2.txt`をアーカイブとして書き込む。
- `/hoge/huga/file1.txt`に`/hoge/huga/file3.txt`を追加で書き込む。
- `/hoge/huga/file1.txt`に`/hoge/output.tar`を追加で書き込もうとするが、
大体の場合当該ファイルは存在しないためエラーになる。
- 前述のエラーによってコマンドが停止する。

実行結果としては`/hoge/huga/file2.txt`、`/hoge/huga/file3.txt`が書き込まれた
かつての面影はない`/hoge/huga/file1.txt`が出来上がってしまう。
当然ながら`/hoge/huga/file1.txt`の内容はロストする上、`/hoge/output.tar`は作成されない。

## さいごに

他の`cp`コマンドや`mv`コマンドなどと同じように「ここからここに(A→B)」のような書き方もあれば、
今回の`tar` コマンドのように「ここに、これらを(A←B[])」のような書き方([※追記あり](#20241109追記))もあるので、
元データ、宛先など、それぞれのコマンドが必要としている情報を理解して利用していきたいものです。

## 2024/11/09追記

tarコマンドは`-f`オプションの引数を出力対象にするので、
以下のようにオプションの引数ですよと明示的にしておくと
間違いは減るかもしれません。
※@shibapさんありがとうございます！
```bash
$ tar cv -f /hoge/output.tar /hoge/huga/file*
```
オプションはまとめて記載できてしまうので、
慣れてきた頃にまとめて打ち込むクセがついて
メモや手順書にそのまま書いてしまう事はあるかもしれません。

それを見た「そのコマンドをなんとなく使っている人」が他のコマンドと
同じノリで使うことでこのような過ちをする可能性はあるので、
記載者は「**気をつけるオプションは分離するように**」、
打鍵者は「**分離されている意図、そのオプションの働き**」を
押さえておくと良いのかなと思います。

## 参考
https://qiita.com/tmiki/items/0027d82f62bf1ff5eb85
VisualStudioCodeにおけるTypeScript 環境構築

# はじめに 
TypeScriptを使用するには、Node.jsとそのパッケージマネージャ(npm)が必要なため、以下の手順でインストールを行います。

# 目次
1. [Node.js と NPM のインストール](#1-Node.jsとNPMのインストール)
2. [TypeScript のインストール](#2-TypeSxriptのインストール)
3. [TypeScript の初期設定 (tsconfig.jsonの作成)](#3-TypeScriptの初期設定(tsconfig.jsonの作成))
4. [TypeScript のコンパイルと実行](#4-TypeScriptのコンパイルと実行)

# 1 Node.js と NPM のインストール


1. [Node.js公式サイト](https://nodejs.org/)から最新の安定版をダウンロードしてインストールします

2. インストール後、コマンドプロンプトまたはターミナルで次のコマンドを実行し、正常にインストールされたか確認します

Node.jsのバージョンを表示するコマンド
```bash
node -v
```

NPM (Node Package Manager) のバージョンを表示するコマンド
```bash
npm -v
```

# 2 TypeScript のインストール

1. TypeScriptコンパイラをを以下のコマンドでインストールします
```bash
npm install -g typescript
```

なお、以下のコマンドでTypeScriptのコンパイラがインストールされているか確認することができます。
（TypeScriptのバージョンが表示された場合、インストールができている。）
```bash
tsc -v
```

# 3 TypeScript の初期設定 (tsconfig.jsonの作成)
1. はじめに設定ファイル（tsconfig.json）を準備します
このファイルはコンパイルオプションやディレクトリ構成を記述するものです
```bash
tsc --init
```
生成された tsconfig.json ファイル内には、TypeScriptのバージョンやコンパイルオプションが含まれます。
環境によって変化はありますが、一例を記載しておきます。

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["XXX/**/*"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}
```


# 4 HelloWorld の作成
1. 任意のディレクトリに TypeScript ファイルを作成します

```typescript:hello.ts
const message: string = "Hello, World!";
console.log(message);
```

# 5 TypeScript のコンパイルと実行

1. 以下のコマンドを用いて [4番](#4-HelloWorldの作成) で作成した hello.ts をコンパイルします
 ```bash
 tsc hello.ts
 ```
 ```bash:出力
 Hello, World!
```
Nginxでリバースプロキシを設定してfirewallを回避する

# 任意のポートで実行されているサーバーを特定のポートで外部公開
解放されているポートが固定の環境で、Nginxでリバースプロキシを設定して任意のポートで実行されているサービスを外部公開する方法。
以下の例はAWS Cloud9環境で、外部公開用のポートが8080でポート8000で起動しているサーバーを公開するためのリバースプロキシ設定である。

### 環境
Ubuntu 22.04環境で検証。

### Nginxのインストール
Nginxをインストールする。
~~~shell
apt install nginx
~~~

### Nginxの設定ファイルを編集
以下ファイルを編集する。

/etc/nginx/sites-enable/default
~~~
map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
}

server {
        listen 8080 default_server;
        listen [::]:8080 default_server;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 600;

        location / {
                proxy_pass http://localhost:8000;
                # Proxy headers
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header  Host  $host;
                proxy_set_header  Connection  close;
                proxy_pass_header X-CSRFToken;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-NginX-Proxy true;
                proxy_set_header X-Forwarded-Proto $scheme;
        }
}
~~~
時刻歴データの欠損値の補完方法いろいろ

# 概要
測定（時刻歴）データの中には，期せずして，欠損値（NaN：Not a Number）が含まれている場合がある．
Pythonで，様々なデータ補完を試みることができる．
Cursorエディタを使えば，一瞬で様々な補完方法を試すことができる．
# 欠損データ生成（サンプル）
``` interp_missing.py
# -*- coding: utf-8 -*-
# 欠損値を含むデータ生成ファイル
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# サンプルデータの作成
df = pd.DataFrame({'A': [1, 2, np.nan, 4], 'B': [5, np.nan, 7, 8]})
plt.figure("サンプルデータ")
plt.plot(df)
plt.show()
```
![スクリーンショット 2024-11-07 0.09.46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/ebb71a69-5873-bee1-47f0-8cce2dad8627.jpeg)
# 0で補完
```
df_filled = df.fillna(0)
```
# 特定の列のみ補完
```
df['A'] = df['A'].fillna(0)
plt.figure("特定列のみ補完")
plt.plot(df)
plt.show()
```

# 前方補完
```
df_filled = df.ffill()
plt.figure("前方補完")
plt.plot(df_filled)
plt.show()
```
# 後方補完
```
df_filled = df.bfill()
plt.figure("後方補完")
plt.plot(df_filled)
plt.show()
```
# 線形補完
```
df_filled = df.interpolate()
plt.figure("線形補完")
plt.plot(df_filled)
plt.show()
```
![スクリーンショット 2024-11-07 0.15.45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/f153e37b-a839-66b1-3571-3b5fa71409c6.jpeg)
# 平均値補完
```
df_filled = df.fillna(df.mean())
plt.figure("平均値補完")
plt.plot(df_filled)
plt.show()
```
![スクリーンショット 2024-11-07 0.16.56.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/46bf2301-2e84-07e1-9ced-1baa02be4196.jpeg)
# 中央値補完
```
df_filled = df.fillna(df.median())
plt.figure("中央値補完")
plt.plot(df_filled)
plt.show()
```
# 線形補完
```
df_filled = df.interpolate(method='linear')
plt.figure("線形補完")
plt.plot(df_filled)
plt.show()
```
# 最近房点補完
```
df_filled = df.interpolate(method='nearest')
plt.figure("最近房点補完")
plt.plot(df_filled)
plt.show()
```
![スクリーンショット 2024-11-07 0.23.15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/9e25f714-ef9d-201e-f911-8becd1941db9.jpeg)
# IterativeImputer
```
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

df_filled = IterativeImputer().fit_transform(df)
plt.figure("IterativeImputer")
plt.plot(df_filled)
plt.show()
```
![スクリーンショット 2024-11-07 0.25.00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/beda12cd-51d5-1366-3e3f-b7852c48958e.jpeg)
# 移動平均による補完
データ点数が少ないと，意図しない結果となることに注意．
```
df_filled = df.rolling(window=3).mean().fillna(0)
plt.figure("移動平均による補完")
plt.plot(df_filled)
plt.show()
```
# スプライン補完
```
df_filled = df.interpolate(method='spline', order=2)
plt.figure("スプライン補完")
plt.plot(df_filled)
plt.show()
```
![スクリーンショット 2024-11-07 0.28.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/8de9450b-ca14-3386-37e3-5253da8d9e7d.jpeg)
バッチファイルのサンプル

chcp 65001

rd /s /q C:\加工帳票作成支援アプリ\App
rd /s /q C:\加工帳票作成支援アプリ\Format

mkdir C:\加工帳票作成支援アプリ\App
mkdir C:\加工帳票作成支援アプリ\Format
mkdir C:\加工帳票作成支援アプリ\Project

xcopy /e /y  "C:\App\App" 	"C:\加工帳票作成支援アプリ\App"
xcopy /e /y  "C:\App\Format" 	"C:\加工帳票作成支援アプリ\Format"

pause

exit
【Java】DIとは何か (備忘録)

## はじめに
今回はJavaを学習した中で出会ったDI(dependency Injection)について記事を書いていきます。

## DI(dependency Injection)とは
DI（Dependency Injection）とは、クラス同士の結合度を低くする設計思想を指します。ここで述べる結合度とは、クラスAがクラスBに対してどれだけ依存しているかを表す概念です。

結合度が高い状態とは、クラスAがクラスBを呼び出すときに、クラスBのインスタンス（オブジェクト）を毎回生成して利用する状態を指します。この場合、クラスAはクラスBがなければ動作できません。そのため、クラスBに変更があった場合、クラスAにも大きな影響を及ぼします。

一方、DIを用いて結合度が低い状態とは、クラスAがクラスBを呼び出す際に、一度クラスCを経由することです。クラスCを介入させることで、クラスAとクラスBは独立した状態で動作できるようになります。これにより、いずれかのクラスに変更があった場合でも、影響を最小限に抑えることが可能となります。


## 例えるなら
DIの概念をわかりやすくするために、スマートホームとアシスタントAIを用いて説明します。

AIアシスタントが備わったスマートホームを想像してください。家には既にAlexというサービスと直接契約してます。しかし途中から利用するAIを変更したくなりました。ですがAlexにすべてを任せていたため、簡単に変更ができなくなっています。


上記のたとえ話の中でDIを適用した状態とは、利用者とAIサービスの間に中間業者を入れた状態です。
これから利用者は中間業者とやり取りすることになります。この状態なら、中間業者が各サービスを上手に調整してくれるので、サービスを変更しても大きな影響がありません。

## プログラム例
DIを利用したプログラムを以下に示します。

メインクラスはそれぞれのAIを備えたスマートホームです。
コード中の⓵の部分が利用するAIの宣言。コード中⓶の部分がAIを利用するサービスを宣言します。
コード⓶では利用したいAIを中間業者に渡しています。
中間クラスがAIを利用できる状態にし、コード⓷ではAIを利用できるようにしています。

``` Java:メインクラス
import AssistantAI.Alex;
import AssistantAI.Assistant;
import AssistantAI.Siro;

public class Main {

	public static void main(String[] args) {
		// Alexを利用したスマートホーム
		Assistant Alex = new Alex();         //・・・⓵
		Service Service1 = new Service(Alex);//・・・⓶
		Service1.Hello();                    //・・・⓷
		
		System.out.println();
		
		// Siroを利用したスマートホーム
		Assistant Siro = new Siro();
		Service Service2 = new Service(Siro);		
		Service2.Hello();
		
	}

}
```


以下はスマートホームで利用するAIのクラスです。
メインからAIクラスは呼び出さず中間クラスを経由します。
``` Java:AIクラス
package AssistantAI;

public interface Assistant {
    void greeting();
}

package AssistantAI;

public class Alex implements Assistant {

    @Override
    public void Greeting() {
        System.out.println("こんにちは。私は Alex です。");
        System.out.println("Riverから生まれました。");
    }
}

package AssistantAI;

public class Siro implements Assistant {

    @Override
    public void greeting() {
        System.out.println("こんにちは。私は Siro です。");
        System.out.println("Fruitから生まれました。");
    }
}

```


以下はメインクラスにAIクラスを渡すための中間クラスです。中間クラスがメインクラスの代わりにAIクラスをオブジェクト化します。メインクラスはオブジェクト化したものを扱います。
```java:中間クラス
import AssistantAI.Assistant;

public class Service {
	private Assistant AssistantAI;
	
	public Service(Assistant AssistantAI) {
		this.AssistantAI=AssistantAI;
	}
	
	public void Hello() {
		AssistantAI.Greeting();
	}
	
}
```

メインクラスを実行すると以下の結果が得られます。中間クラスがメインクラスとAIクラスの間に入ってオブジェクトのやり取りをするので利用するAIクラスを変更しても動きます。

```:Result
こんにちは。私は Alex です。
Riverから生まれました。

こんにちは。私は Siro です。
Fruitから生まれました。
```


## おわりに
以上からDIを簡単にまとめると次の通りになります。

- オブジェクトを関節的にやり取りすること
- それぞれのクラスが独立していること
- クラスの修正がしやすいこと

以上がDIに対する私の認識でした。誤り等あればご指摘ください。


## 参考文献
- Dependency Injection :: Spring Framework

https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html#page-title

- 土岐孝平 著, "プロになるためのSpring入門 ――ゼロからの開発力養成講座",
技術評論社, pp.38-47