OmniAICreator/Qiita-1.07M huggingface dataset:
Numpy: Pythonでの高速な数値計算の基本

# 概要
Pythonは、データサイエンティストや研究者にとって人気があるプログラミング言語です。Pythonは、機械学習やデータ分析のための多くのパッケージを提供していますが、数値計算には最適ではありません。

ここで、NumPy（Numerical Python）が登場します。NumPyは、Python用の数値演算ライブラリであり、CまたはFortranで書かれているため、高速な数値計算を実行できます。この記事では、NumPyの利点、NumPyの操作方法、NumPyの配列周りの基本的な演算、およびその他の数値計算ライブラリ（例えば、SciPy）について説明します。

## NumPyの利点
NumPyには、Pythonにはない多くの高度な数学関数とアルゴリズムが含まれています。また、NumPyの配列は、Pythonの通常のリストよりも優れた特性を持ちます。

- データを格納するための効率的なデータ構造
- 多次元配列の処理を容易にするツール
- 高速で、メモリ使用量が少ない
- 手軽に配列の要素を操作可能

## NumPyの基本
NumPyは、ndarray（n-dimensional array）オブジェクトを中心に構成されています。ndarrayオブジェクトは、一次元または多次元の配列を扱うために使用できます。このセクションでは、ndarrayオブジェクトの作成方法、インデックス付け、スライシング、およびndarrayオブジェクトの基本的な演算について説明します。

### 実装例
```
import numpy as np

# 1次元のndarrayの作成
arr1 = np.array([1, 2, 3])
print(arr1)

# 出力結果: [1 2 3]

# 2次元のndarrayの作成
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2)

# 出力結果: [[1 2 3]
#             [4 5 6]]

# インデックスを使って要素にアクセス
print(arr1[0])  # 1
print(arr2[0][1])  # 2

# スライスを使った要素へのアクセス
print(arr1[1:])  # [2 3]
print(arr2[:, :2])  # [[1 2]
                       # [4 5]]

# ndarray同士の演算
arr3 = arr1 + arr2
print(arr3)

# 出力結果: [[2 4 6]
#             [5 7 9]]
```

このように、NumPyのndarrayはPython標準のリストよりも高速で、多次元配列も簡単に扱えます。したがって、NumPyを使用することで、高速かつ柔軟性のある数値計算を行うことができます。


## NumPyの演算
NumPyの主な機能は、配列の演算です。NumPyは、膨大な数の数学演算子および数学関数を提供しています。 このセクションでは、NumPyの配列演算、および他の重要な数値演算ライブラリであるSciPy（Scientific Python）について説明します。

### NumPyの配列演算
NumPyで配列の要素同士を演算する実装例です。

```python
import numpy as np

# NumPyの配列を作る
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 配列同士の足し算
c = a + b
print(c) # [5 7 9]

# 配列同士の引き算
d = a - b
print(d) # [-3 -3 -3]

# 配列同士の掛け算
e = a * b
print(e) # [ 4 10 18]

# 配列同士の割り算
f = a / b
print(f) # [0.25 0.4  0.5 ]

# 配列要素の累乗
g = a ** 2
print(g) # [1 4 9]

# 配列要素の三角関数
h = np.sin(a)
print(h) # [0.84147098 0.90929743 0.14112001]
```

上記の例では、まずNumPyのnp.arrayメソッドを使って2つの配列aとbを作成しました。その後、各配列要素同士の足し算、引き算、掛け算、割り算、累乗、三角関数など、様々な演算を行っています。これらの演算はPythonの普通のリストではできなかった高速な計算ができます。

### NumPyとSciPy

#### 最適化

SciPyは最適化問題の解法を提供しています。例えば、以下のように、最小値を求める関数を最適化する場合は、`minimize`関数を用いて解を求めることができます。

```python
from scipy.optimize import minimize

def f(x):
    return (x - 2) ** 2 + 1

result = minimize(f, x0=0)
print(result.x)  # [1.99999999]
```

#### 統計分析

SciPyは様々な統計処理も提供しています。例えば、正規分布に従う乱数を生成する場合は、以下のように`randn`関数を使うことができます。

```python
from scipy.stats import randn

a = randn(1000)  # 正規分布に従う乱数を1000個生成する
```

また、平均値や標準偏差などの統計量を計算することもできます。

```python
from scipy.stats import norm

a = randn(1000)
mean = np.mean(a)  # 平均値
stddev = np.std(a)  # 標準偏差

# 正規分布の累積分布関数(CDF)を計算する
cdf_value = norm(mean, stddev).cdf(0)

print(mean, stddev, cdf_value)
```

以上が、NumPyとSciPyの実装例です。参考にしてみてください。

## まとめ
この記事では、NumPyの作り方、ndarrayオブジェクトの作成、NumPyの配列演算について説明しました。NumPyの配列は、Pythonリストと比べて多くの点で優れた特性を持ちます。 NumPyを使うことで、高速で効率的な数値計算ができるようになります。
Ruby on Railsの習得のためタスクリスト的なの作ってみる③〜API開発・呼び出し編〜

今回はAPIを開発していきます！早速本題。


## 設定

こちらを見ながらやっていこう、、

https://railsguides.jp/api_app.html

と思ったら、そもそもRailsのプロジェクト作成時ににAPIに不要な機能を除外できるオプションがあるらしい！まじか、適当に作っちゃったよ。
既存のプロジェクトをAPI専用に変更もできるらしいので、[こちらの手順](https://railsguides.jp/api_app.html#%E6%97%A2%E5%AD%98%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)でやってみます。

`config/application.rb`の`Application`クラス定義の冒頭に以下の設定を追加すればクラス生成やら利用モジュールやらがAPI用になるらしいです。

```
config.api_only = true
```

次に、デバッグ情報をAPIに出力するよう`config/environments/development.rb`に設定追加します。

```
config.debug_exception_response_format = :api
```

あとは、`app/controllers/application_controller.rb`にて、クラス継承元を`ActionController::API`に変えればいいみたいです。config変えたから次作るControllerからは勝手にこうなるっぽい。
```app/controllers/application_controller.rb
class ApplicationController < ActionController::API
end
```

[ミドルウェアの追加](https://railsguides.jp/api_app.html#%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E9%81%B8%E6%8A%9E)は必要次第やることにします。


## ルーティング

https://railsguides.jp/routing.html

ルーティングはこれを見つつ、[こちらの記事](https://qiita.com/tbpgr/items/f83d6c0ee33d09b523b1)も参考に、namespaceとresourcesを使っていい感じに書きます。
resourcesはよく使う複数のルーティングを一行で書けるらしい。便利。ルーティングがどうなっているかは`http://localhost:{ポート番号}/rails/info/routes`で一覧表示できます。

```/config/routes.rb
Rails.application.routes.draw do
  namespace :api, format: 'json' do
    namespace :v1 do
      resources :tasks
      resources :users
      resources :login
    end
  end
end
```

## Controllerの作成

```sh
$ rails generate controller Tasks
```
このようなコマンドでcontrollerファイルを生成することができます。
中身はとりあえず適当なjsonを返すだけ。
`render json: result;`は、`return render json: result;`の省略らしいです。

```/app/controllers/api/v1/tasks_controller.rb
module Api
  module V1    
    class TasksController < ApplicationController
      def index
        result = {taskId: 1, name: 'メール返信', limit: '2023-03-07 00:00:00', priority: 'MIDDLE'}
        render json: result;
      end
    end
  end
end
```

モジュール名を設定しないと
```
uninitialized constant Api::V1::TasksController
```
というエラーが返却されてきました。この文言自体は対象のコントローラーが見つからないという意味みたいです。モジュール名書いて解決！

で、**Rubyのモジュールってなんですか？** という話。
[リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/class/Module.html)をからは、クラスと大体同じように見えます。
↓先人の知恵に頼ります。
[クラス・モジュールの概念 Ruby](https://qiita.com/fukumone/items/2dd4d2d1ce6ed05928de)
[RubyのModuleの使い方とはいったい](https://qiita.com/shiopon01/items/fd6803f792398c5219cd)
今回ハマった例のように名前空間として使う用法と、メソッドの置き場所として使う用法があるみたいです。後者は、PHPとかでいう静的メソッドの呼び出しみたいに使えるのかな？という感じ。

## 呼び出してみる

安定と信頼のPostmanで呼び出してみます。

https://www.postman.com/


![スクリーンショット 2023-03-05 2.43.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363775/dbdf1eb5-e9eb-90da-5cc5-a0aa748079e4.png)

無事返ってきました！やったね！

## パラメータを受け取る

https://railsdoc.com/page/params

こちらによると、
```
params[:param_name]
```
でクエリパラメータもPOSTで渡されたパラメータも、更にはルーティングで指定したパラメータ（/hoge/fuga/:idみたいなやつ）も全部取れるらしいです。便利〜。

というわけで呼び出し編はここまで！残りの部分は3分クッキング的に作っておきますので。。

## 次回予告
次回はDBを使っていきたいと思います。
元がMVCフレームワークだし、Modelとか使いやすそうで期待大です！
DDDっぽいのは向いていないという噂を聞いたのでデータベース準拠でやっていくのがいいのかな？というあたりの疑問についても調査したいと思います。がんばるぞい！
C#でSlackAPIを使ってファイルを投稿するサンプルコードが古かった

# 記事の目的

KIOSKの保守やトラブルの検証のために、異常発生時にSlackにログを投げるようにしたが、
その時に微妙に詰まったので共有しておく。

## やりたいこと

KIOSK端末でエラーを出した時にログをSlackに投稿できるようにする。

## 発生したトラブル

下記2つのページを参考に適当なチャンネルにファイルを投稿する場合、
2023年3月では次のような返答が来る。

https://qiita.com/im0039kp/items/e06fe2bba5c4bbc6d46c

https://qiita.com/SugiuraF/items/2338f4228ef98e9c6486

```json
{
    "ok": false,
    "error": "invalid_auth"
}
```

要はパラメータにトークンを置く認証は無効だよ、ということです。

## 解決方法

下記ページのExampleのCURLを見てみるとこのようになっている。

https://api.slack.com/methods/files.upload

```sh
curl -F file=@dramacat.gif -F "initial_comment=Shakes the cat" -F channels=C024BE91L,D032AC32T -H "Authorization: Bearer xoxb-xxxxxxxxx-xxxx" https://slack.com/api/files.upload
```

要はヘッダにトークン情報を仕込む必要があることがわかる。このCURLと等価なコードは次の通りで、動作確認も取れた。

:::note warn
.Net 7以降ではWebClientの代わりに[HttpClient](https://learn.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclient)を使うことが推奨されています。
:::

```cs
var client = new WebClient();
client.QueryString = new NameValueCollection(){
    parameters["channels"] = "C024BE91L,D032AC32T"
};
client.Headers.Add($"Authorization: Bearer xoxb-xxxxxxxxx-xxxx")

byte[] responseBytes = client.UploadFile("https://slack.com/api/files.upload","dramacat.gif");

//結果を取得
String responseString = Encoding.UTF8.GetString(responseBytes);

Console.WriteLine(Return);
```

## まとめ

+ 公式以外のサンプルコードは古い可能性がある。今回のファイルアップロードの件ではほぼすべて古いと思ったほうが良さそうだ。
+ SlackのAPIに関しては、C#はCURLの例を参考にして実装するのが安全に見える。
【TCA】EffectTaskのtask/run/fireAndForgetメソッドの使い分け

:::note warn
[0.53.0](https://github.com/pointfreeco/swift-composable-architecture/releases/tag/0.53.0)より**task**と**fireAndForget**はSoft-Deprecatedとなりました
今後は**run**のみを使いましょう
:::

Reducerで非同期処理を実行するためのツールとして、EffectTaskには3つのstaticメソッドが用意されています。

使い分けのポイントとしては以下のようになります。

| メソッド | 用途 |
|:-:|:-:|
| `task(priority:operation:catch:)` | 1つのActionをSendする |
| `run(priority:operation:catch:)` | 0または1つ以上のActionをSendする |
| `fireAndforget(priority:_:)` | ActionをSendしない |

# `task(priority:operation:catch:)`
`task`では、以下のようにActionをreturnする必要があります。
returnする前に、複数の非同期処理を実行可能です。

```swift
return .task {
  try await operation1()
  try await operation2()
  return await .fetchResponse(TaskResult {
    try await self.fetch()
  })
}
```

# `run(priority:operation:catch:)`
`run`の使いどころは主に2つあります。
一つは、for-await-inでAsyncSequenceを処理するケースです。

```swift
return .run { send in
  for await newValue in self.listen() {
    await send(.updated(newValue))
  }
}
```

もう一つは、条件によってActionを送信しなかったり、あるいは複数送信するようなロジックを持つケースです。

```swift
return .run { send in
  guard ... else { return }  // 何もしない
  await send(
    .fetchResponse(TaskResult {
      try await self.fetch()
    })
  )
  // もっとActionをsendすることもできる
}
```

isowordsでは、`withThrowingTaskGroup`を使って複数の非同期処理を並列実行させるような使い方もしていました。

- [UpgradeInterstitialFeature/UpgradeInterstitialView.swift](https://github.com/pointfreeco/isowords/blob/bb0a73d20495ca95167a01eeaaf591a540120ce2/Sources/UpgradeInterstitialFeature/UpgradeInterstitialView.swift)
- [GameOverFeature/GameOverView.swift](https://github.com/pointfreeco/isowords/blob/bb0a73d20495ca95167a01eeaaf591a540120ce2/Sources/GameOverFeature/GameOverView.swift)

# `fireAndforget(priority:_:)`
非同期処理を実行するだけでActionを送信しない場合は、`fireAndforget`を使います。

```swift
return .fireAndForget {
  try await operation1()
  try await operation2()
}
```

# エラーのキャッチについて
`task`と`run`は`catch`という引数にエラーを受け取るクロージャを指定できます。
`operation`クロージャでエラーがスローされた場合、`catch`クロージャが実行されます。

```swift
return .task {
  try await operation()  // ここでエラーがスローされるとする
  return await .fetchResponse(TaskResult {
    try await self.fetch()
  })
} catch: {  // ここでキャッチ
  return .operationFailed  // エラーが発生したことを通知するActionをSendする
}
```

あるいは、do-catchでエラーをキャッチします。

```swift
return .task {
  do {
    try await operation()
    return await .fetchResponse(TaskResult {
      try await self.fetch()
    })
  } catch {
    return .operationFailed
  }
}
```

`task`および`run`でエラーをキャッチしなかった場合、以下のようなワーニングが出力されます。

```
An "EffectTask.task" returned from "SomeFeature.swift:58" threw an unhandled error. …

    SomeFeature.OperationError()

All non-cancellation errors must be explicitly handled via the "catch" parameter on "EffectTask.task", or via a "do" block.
```

なお、`fireAndForget`はエラーがスローされても無視され、ワーニングも出力されません。
AlmaLinux9でPowerToolsを使う方法

OpenStackでやってたらハマりました。
RHEL9からcrbって名前になっているらしいです。
```bash:shell
[root@control manage]# dnf repolist --all | grep crb
crb                         AlmaLinux 9 - CRB                           disabled
crb-debug                   AlmaLinux 9 - CRB - Debug                   disabled
crb-source                  AlmaLinux 9 - CRB - Source                  disabled
[root@control manage]# dnf config-manager --set-enabled crb
[root@control manage]# dnf repolist --all | grep crb
crb                         AlmaLinux 9 - CRB                           enabled
crb-debug                   AlmaLinux 9 - CRB - Debug                   disabled
crb-source                  AlmaLinux 9 - CRB - Source                  disabled
[root@control manage]#
```
git pushで403エラーが解決できなかったのでSSH接続を試した

### この記事について
git pushしようとしたら、下のような403エラーが出ました。
```
remote: Permission to <アカウント名>/<リポジトリ名>.git denied to <アカウント名>.
fatal: unable to access 'https://github.com/<アカウント名>/<リポジトリ名>.git/': The requested URL returned error: 403
```
* windows資格情報を削除する
* ```git config```でユーザ情報を変更する
* リモートリポジトリのURLをhttps://<githubアカウント名>@github.com/<アカウント名>/<リポジトリ名>.gitにする

など試してみましたが解決できませんでした。
2つgithubアカウント(学校用と私用)があり、これの切り替えが原因であろうと思うのですが、そこから先は分かりません。
そこで方針を変えてSSHでの接続を試みることにしました。
その際の備忘録です。
### 筆者環境
Ubuntu on windows(Ubuntuのバージョンは20.04)
### やったこと
#### 手順1　鍵生成
下のコマンドでSSH鍵を生成します。
```shell
cd ~/.ssh
ssh-keygen -t rsa -C "<githubアカウントのメールアドレス>" -f "<鍵のファイル名:任意>"
```
passphraseを何にするか聞かれます。無くてもエラーにはなりません。
SSH接続のパスワードのようなものだと思います。
ssh-keygenのオプションについて補足しておきます。
|オプション|説明|
|:-:|:-|
|-t|暗号化方式|
|-C|コメント<br>公開鍵の末尾に書き込まれます。|
|-f|鍵のファイル名<br>|

そうすると```~/.ssh```下に```<鍵のファイル名>```と```<鍵のファイル名>.pub```という2つのファイルが出来ます。前者は秘密鍵、後者は公開鍵が書き込まれています。
#### 手順2　ssh鍵をgithubに登録する
公開鍵(```<鍵のファイル名>.pub```の中身)をクリップボードにコピーします。
方法は何でもいいですが、例えば下記のコマンドなどでコピーできます。
```shell
cat <鍵のファイル名>.pub | clip.exe
```
そうしたらブラウザでgithubを開き、settings > SSH and GPG keys > New SSH Keyの順でクリックしてSSH鍵追加画面を開きます。
各項目を入力します。
Titleは任意のものを、Key typeはAuthentication Keyを選択します。
Keyにはクリップボードにコピーしている公開鍵を貼り付けます。
そうしたらAdd SSH keyボタンを押して登録を完了します。
#### 手順3　```~/.ssh/config```を設定する
```~/.ssh/config```は秘密鍵はどのファイルにあるか、ホストは何かなどの設定を書きこむファイルです。
下を追加します。
```
Host <接続名:任意>
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/<鍵のファイル名>
  TCPKeepAlive yes
  IdentitiesOnly yes
```
gitが、```~/.ssh/<鍵のファイル名>```の中身を秘密鍵として用いて、22番ポートで、github.comに接続するという意味です。
#### 手順4　gitのconfigをいじる
下のコマンドでリモートリポジトリのURLを設定します。

```shell
git remote set-url origin git@<接続名>:<アカウント名>/<リポジトリ名>.git
```
#### 手順4　接続する
下のコマンドでSSH接続します。
```shell
ssh -T <接続名>
```
結果
```
Hi <githubのアカウント名>! You've successfully authenticated, but GitHub does not provide shell access.
```
#### 完了
これでgit push出来るようになりました。

### 参考
<b>403エラー関連</b>
windows資格情報削除で解決した方
[git pushで自分のレポジトリへのアクセスが403で拒否される対処法 Remote: Permission to user1/repo denied to user2](https://qiita.com/mtc465/items/c2e8472f797e9f5bbc43)
urlを書き換えで解決した方
[git pushで403のエラーが返ってくる問題](https://qiita.com/hirotatsuuu/items/d9abff1296469f9c861c)
<b>SSH関連</b>
[【 ssh-keygen 】コマンド――SSHの公開鍵と秘密鍵を作成する](https://atmarkit.itmedia.co.jp/ait/articles/1908/02/news015.html)
[【2021年以降】コマンドラインからgithubにpush/pullすると接続エラーになる](https://trios.pro/github-403-error/)
[【GitHub】複数GitHubアカウントのSSHキーを管理する。](https://zenn.dev/rabbit/articles/543355d334776b)
Linux パフォーマンス分析 チェックリスト

# 【Linux パフォーマンス分析 チェックリスト】

メソドロジがないと、パフォーマンス調査は魚釣りのようになってしまうそうです。
チェックリストが紹介されていたので、自分用メモに残します。

## まずはこれらを確認してみよう

- [ ] `uptime`
  - 1分、5分、15分の負荷平均
- [ ] `dmesg -T | tail`
  - メモリ不足エラー等のカーネルエラー
- [ ] `vmstat -SM 1`
  - ランキューの長さ、スワップ、システム全体のCPU使用率等のシステムレベルでの統計量
- [ ] `mpstat -P ALL 1`
  - CPU間のバランス（1つのCPUだけBusyならスレッドのスケーリングに問題あり）
- [ ] `pidstat 1`
  - プロセスごとのCPUの使用状況
  - 予想外にCPUを消費しているものを明らかにし、各プロセスのユーザー/システムCPU時間を見る
- [ ] `iostat -sxz 1`
  - ディスクのIO統計（IOPS, スループット、平均待ち時間、Busy状態の割合等）
- [ ] `free -m`
  - ファイルシステムキャッシュを含むメモリの使用状況
- [ ] `sar -n DEV 1`
  - ネットワークデバイスI/O、パケットとスループット
- [ ] `sar -n TCP,ETCP 1`
  - TCP統計、接続スピード、再送
- [ ] `top`
  - 全体的なチェック

## 参考

https://www.oreilly.co.jp/books/9784814400072/
herokuでads.txtとapp-ads.txtを認証してもらう方法

# 概要
herokuで独自ドメインでサイトを公開した場合、www.example.comがというようにwwwがついてしまう。
しかし、adsenseやadmobがads.txtやapp-ads.txtをクロールして読み込むドメインは、example.com/ads.txtである。
このせいでクロールが上手くいかず、ずっとAd周りで警告が表示され続けている人は多いのではないだろうか？
その解決策をメモる。

# 解決策
CloudflareのPage Ruleを使って、www.example.com/ads.txtをexample.com/ads.txtにリダイレクトしよう。

https://developers.cloudflare.com/support/page-rules/configuring-url-forwarding-or-redirects-with-page-rules/

![スクリーンショット 2023-06-24 10.54.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253667/0f6e9e14-6ba5-a8e1-b140-471ee033fcca.png)


以上である。
Some useful OpenSSL command

OpenSSL is a swiss army knife of cryptography.

# Help

```sh
# show option of enc command
$ openssl enc help
Usage: enc [options]
Valid options are:
 -help               Display this summary
 -list               List ciphers
 -ciphers            Alias for -list
 -in infile          Input file
 -out outfile        Output file
 -pass val           Passphrase source
 -e                  Encrypt
 -d                  Decrypt
 -p                  Print the iv/key
 -P                  Print the iv/key and exit
 -v                  Verbose output
 -nopad              Disable standard block padding
 -salt               Use salt in the KDF (default)
 -nosalt             Do not use salt in the KDF
 -debug              Print debug info
 -a                  Base64 encode/decode, depending on encryption flag
 -base64             Same as option -a
 -A                  Used with -[base64|a] to specify base64 buffer as a single line
 -bufsize val        Buffer size
 -k val              Passphrase
 -kfile infile       Read passphrase from file
 -K val              Raw key, in hex
 -S val              Salt, in hex
 -iv val             IV in hex
 -md val             Use specified digest to create a key from the passphrase
 -iter +int          Specify the iteration count and force use of PBKDF2
 -pbkdf2             Use password-based key derivation function 2
 -none               Don't encrypt
 -*                  Any supported cipher
 -rand val           Load the file(s) into the random number generator
 -writerand outfile  Write random data to the specified file
 -engine val         Use engine, possibly a hardware device
```

# Generate symantec key

```shell
# generates 16 bytes (128 bits) key in binary format
$ openssl rand 16

# in hex format
$ openssl rand -hex 16
88cdbf1e106334f1bca57f730758abad

# encoded by BASE64 
$ openssl rand -base64 16
tMa1eyjIZw3g3M0dhPC87A==

# show hex format of the binary key saved in a file
$ xxd -ps symantec.key
88cdbf1e106334f1bca57f730758abad
```

# Encode/decode file by AES

Assume using aes-128-cbc algorithm (128 bits key), with 128 bits initialization vector and no salt. Padding algorithm is PKCS#5.

```sh
# encode, -K is key in hex format, -iv is initialization vector in hex format
$ openssl enc -e -aes-128-cbc -K abcdef01234567890123456789abcdef -iv 0123456789abcdef0123456789abcdef -nosalt -in file.txt -out file.txt.encode

# decode
$ openssl enc -d -aes-128-cbc -K abcdef01234567890123456789abcdef -iv 0123456789abcdef0123456789abcdef -nosalt -in file.txt.encode -out file.txt
```

# Establish HTTPS connection

```sh
$ openssl s_client -connect www.google.com:443
```
Javaのクラスパスについて


クラスパスを指定する方法は2つある。

①javaコマンド実行時にオプションで設定する。
②環境変数で設定する。


# ①javaコマンド実行時にオプションで設定する。

```
javac -classpath [パス1]; [パス2]; ...
```

複数設定する場合はセミコロンで区切る。

省略形もある。
```
javac -cp [パス1]; [パス2]; ...
```

# 環境変数を使用する方法
```
set CLASSPATH=[パス1]; [パス2]; ...
```
※等号の前後に空白を入れないように注意

# その他注意事項
## 実行時にカレントディレクトリを含める場合
デフォルトは実行時のカレントディレクトリ。上記設定をするとオーバーライドされる。
そのため、クラスパス設定時にカレントディレクトリを含めたい場合は「 . 」を含める必要がある。

## クラスパスの内容
設定内容は.zip, .jar, .classファイルへのクラスパス

* .jar / .zipの場合：クラスパスは.zipまたは.jarファイルの名前で終わる
* 無名パッケージ内の.classファイルの場合、クラスパスは.classファイルを含むディレクトリの名で終わる
* パッケージ内の.classファイルの場合、クラスパッケージはルートパッケージの入ったディレクトリ名で終わる
（ルートパッケージ：完全修飾クラス名の先頭パッケージ）

## 推奨されている方法
他のアプリケーションに影響を与えたり、逆に他のアプリケーションに値を変更されることのないように、①『javaコマンド実行時にオプションで設定する。』が推奨されているようです。





## 参考にしたサイト
[oracleドキュメント](https://docs.oracle.com/javase/jp/1.5.0/tooldocs/windows/classpath.html)
「No module named PyInstaller」の対処法

## 前置き
いつも通りPyinstallerを実行すると、

「ModuleNotFoundError: No module named 'PyInstaller'」

と、このようなエラーがいきなり発生しました。
コマンドプロンプトで「pyinstaller -v」とバージョン確認を行っても同様のエラーです。
エラーが起きる前に、新しいライブラリを沢山インストールしたので、それが原因だと推測を立て色々試行錯誤して解決していきました。
新たにインストールしたライブラリをアンインストールするも治らず、Pyinstallerを入れ直すも治らず、Google先生に聞いても解決せずで1週間程が経過していました。

## 原因
全く不明

## 解決方法
PyInstallerをアンインストールしましょう
```:cmd
>>pip uninstall pyinstaller
```
auto-py-to-exeというライブラリをgit経由でインストールします
※gitが未インストールの方はインストールをしておいてください
```:cmd
>>git clone https://github.com/brentvollebregt/auto-py-to-exe.git
>>cd auto-py-to-exe
>>python setup.py install
```
これでバージョンが表示されれば解決しています
```:cmd
>>pyinstaller -v
```

## 最後に
この解決方法はとりあえず試したいという方にオススメしています。
なぜこれで上手くいったのかを調べる精神的余力はないので、どなたか有識者がいればコメントくれると嬉しいです
本当にPyInstallerはエラーが多いので精神的に参りそうですね。。
34歳おじさんがAtCoder茶色になりました。

# 結論
ついに入茶することができました。
茶色には意地でもなってやると思っていたので達成できて満足でございます。

この記事ではCS出身でもなく、数学力のないおっさんでも、LeetCodeをやれば茶色までは持っていけるぞというものを記すものになります。
※レーティングが上がり始めたのはLeetCodeを実施したことが起因しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588716/9313bc3e-0fc4-068d-e7a2-130b40dbdd77.png)

# キャリア背景
地方国立大学理系を卒業後、半導体ICのテストをするエンジニアとしてキャリアスタートしました。(2012年ぐらい)
CとかC++とかPerlを書くことが多かったです。2016年ぐらいまで。)

いまはWEBアプリケーションエンジニアとして働いていますが、設計よりのことばかりやっています。(リソース空いた時にコーディングしてるぐらい)
本格的にコードを書く機会は無くなっていましたが、業務アプリケーションのソースコードは普通に読めます。

# 茶色というレベルに対して思うこと
- ここについては明確に言いたいのですが、灰色(自分)でもFizzBuzzレベルは楽勝で解けます。
- C問題レベルのものが楽勝で解けるレベルでないと茶色には100％到達しません。
- レーティング推移を見てもらえるとわかるように、ブランクはあったとはいえ、LeetCodeなしでは茶色には届かなかった。

- 数学力がある人だったら何の苦労もせずに茶色ぐらいは突破していくと思いますが、私はそうではありませんでした。
    - クラスにいたであろう勉強しないでも模試の数学満点取れるような人たちいますよね。アレには遠く及びません。

# LeetCodeで何をしたか

- Interviewで頻出の問題を解いた。
    - https://leetcode.com/problem-list/top-interview-questions/
- Easyで解けなかったものは内容を理解できるまで確認した。
    - だいたい解けていたんですが、binary treeの問題を初めて見た時に？？？ってなりました。
- Mediumは計算量が膨らんでもいいので自分で解く。その後にいろんな人の回答を見て「ふむふむなるほど」まで行う。
    - 理想としてはここから自分で実装できるように復習するべきですが、問題数をこなして「ふむふむなるほど」を多数得る方針にしていました。
    - その結果、AtCoderの問題を見るとこれはDP、これはDFSでやればいけそうという勘所はつくようになりました。(実装できるかは別問題)


# LeetCodeの何がよかったか

- 問題の形式や、他者の回答を確認する方法が自分の好みに合っていた。
    - AtCoderは数学的思考のプロセスが必要になることが多いと感じる。LeetCodeはどちらかというと業務寄りのプロセスかなと感じた
- コーディングインタビュー対策になる。
- Easyに着手し始めるときにWEB上でコーディングしてSubmitできるので、お試しとしての体験がよかった。

# 今後について
目標としていた入茶は達成できたので、タイミングが合うときに参加するぐらいで楽しもうかなと思います。
※土日の夜の時間を使うという点で嫁にも迷惑かけてきましたので...好き勝手させてくれてた嫁には感謝してます。

LeetCodeは続けつつ、システムドメインの学習とか個人開発に力を寄せていこうかなと思います。

入茶に苦しんでいる人がいたら、おじさんでもいけるんだぞということを希望としてがんばってください！
反変・共変ベクトル

もはやAIでは必須の行列。googleのフレームワークTENSOFLOWにも使われているテンソル。
ここで少し学習するとき出てくるときにつまずくのが共変・反変ベクトル。
以下解説。
2次元でベクトルがある。
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}

1 + 2 = 3\\   数式を改行する時にはバックスラッシュを２つ
Dockerコンテナ内でVimのYank(コピー)をホストマシーンのクリップボードにコピーした方法

# はじめに
Nvimの環境構築時にクリップボード設定で躓いたのでその共有です。
というのも、自分のNvimを使用している構成が,
1. DockerでArch Linuxのコンテナを起動
2. Tmuxを起動
3. Nvimを起動
4. Visual mode起動
5. Yank

という感じで、**Dockerコンテナ内でvimを使用**していて、
Docker内からホストマシーン(mac)のクリップボードにコピーがしたかったからです。

## 環境
- Host OS: Mac OS(13.0.1)
- Docker Image: archlinux
- Emulator: kitty
- Session Manager: Tmux (inside docker)
- Editor: Neovim(v0.8.3)

## 問題
いろんな記事を見たところ、下記の設定で解決するとのことでした。
``` init.lua
vim.opt.clipboard = 'unnamedplus'
```

しかし、ホストマシーンから直接NvimのYankを使った場合はうまくいきましたが、本来の目的である、**Dockerコンテナ内でVimを使用すると**、ホストマシーンのクリップボードへコピーできませんでした。


## 解決方法
一度Nvimが何のClipboardを使っているか下記のコマンドで調べることができました。
```lua
:checkhealth
```
結果
```
provider: health#provider#check
========================================================================
## Clipboard (optional)
  - OK: Clipboard tool found: tmux
```
Tmuxを使っていました。
ちなみにTmuxでの設定は下記のようになっています。
```.tmux.con
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "pbcopy"
```

最終的にこの[記事](https://rumpelsepp.org/blog/nvim-clipboard-through-ssh/)を参考に下記のようにclipboardの設定をしたところ、クリップボードへのコピーが可能になりました。

```init.lua
if vim.env.TMUX then
    vim.g.clipboard = {
        name = 'tmux',
        copy = {
            ["+"] = {'tmux', 'load-buffer', '-w', '-'},
            ["*"] = {'tmux', 'load-buffer', '-w', '-'},
        },
        paste = {
            ["+"] = {'tmux', 'save-buffer', '-'},
            ["*"] = {'tmux', 'save-buffer', '-'},
        },
        cache_enabled = false,
    }
end
```
上記の記事によるとSSHでリモートマシーンに接続して、
そこからVimのYankをローカルのホストマシーンのクリップボードにコピー可能らしい。


## 余談
こちらの[記事](https://github.com/glepnir/dope/blob/f3557134eb70bbc6a9ef35e120e27f798fc13b19/lua/core/options.lua#L103-L118)によると、OSによってClipboardを切り替えたい場合は下記のような設定もできるらしい。
```init.lua
-- mac osの場合
if vim.loop.os_uname().sysname == 'Darwin' then
  vim.g.clipboard = {
    name = 'macOS-clipboard',
    copy = {
      ['+'] = 'pbcopy',
      ['*'] = 'pbcopy',
    },
    paste = {
      ['+'] = 'pbpaste',
      ['*'] = 'pbpaste',
    },
    cache_enabled = 0,
  }
end
```
OSの種類は下記のコマンドで調べられる。
```
:lua print(vim.loop.os_uname().sysname)
```

## 参考記事
- [How to use the nvim clipboard through SSH?
](https://rumpelsepp.org/blog/nvim-clipboard-through-ssh/)
- [options.lua by glepnir](https://github.com/glepnir/dope/blob/f3557134eb70bbc6a9ef35e120e27f798fc13b19/lua/core/options.lua#L103-L118)
- [How to setup g:clipboard using lua?](https://www.reddit.com/r/neovim/comments/wb2obw/how_to_setup_gclipboard_using_lua/)
【Error】Gitにpushできない「error: failed to push some refs to...」

# エラー内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/d919812c-03a4-10f8-cc1f-e050b6070799.png)

# 解消方法
```
git fetch
git merge
```

これで解消できない場合、参考になるページ

https://ja.stackoverflow.com/questions/57780/git-push%E6%99%82%E3%81%ABerror-failed-to-push-some-refs-to%E3%81%A8%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E3%81%A7%E3%82%8B
【Firebase】ローカルで起動できないときの応急処置【UNSUPPORTED_DIR_IMPORT】

こんにちは。駆け出しフロントエンジニアの初投稿です。
Firebaseを使った案件で`npm run dev` すると`UNSUPPORTED_DIR_IMPORT`と出て起動できない症状が出ました。
解決した応急処置の方法を同じような犠牲者が出ないよう、~~また自分が地獄を見ないよう~~ 備忘録として残しておきます。
~~※少し前の話なので記憶がおぼろげです~~

【経緯】
2ヶ月ほど前まで機能追加、バグ修正を行なっていた案件で久々に業務を始めようとしたところ、`npm run dev`すると`UNSUPPORTED_DIR_IMPORT`が表示されて何もできなくなった。
他のプロジェクトに参加している方の環境では問題なく、完全に`おま環`状態だった。

【解決に向けて試したこと】
- 他のブランチに切り替える
- nodeのバージョンを変更する（他のエンジニアさんの環境と合わせる）
- npmのバージョンを変更する（上記と同じ）
- `npm run dev --legacy-peer-deps `してみる
- 正常なpackage.json、packagelock.jsonをもらって`npm install`する
- 正常なpackage.json、packagelock.json、node_modulesをもらって置き換える（爆

他にもいくつも試したと思いますが、解決には至りませんでした。。



でば応急処置の方法です。
まず`.babelrc`に以下を記載します
```
{
  "presets": ["next/babel"]
}

```

次にnext.config.jsに
```
module.exports = {
  swcMinify: false, //この記述を追加します。
};
```

最後にfirebase.tsに
```
import firebase from '@firebase/app';
import '@firebase/app';
import '@firebase/firestore';
import '@firebase/auth';
```
と記載するとnpm run devが通るようになります。
ただ、firebase.tsに波線が出てしまうので、あくまで応急処置です。

今後もMarkDownの練習も兼ねて備忘録として残していこうと思います。
ruby の popen で sh: -c: line 0: syntax error near unexpected token `('

# はじめに

```
diff -u <(du -ak hoge) <(du -ak hoge2)
```
のような ```<()``` で結果をpipeで渡すのを ```IO.popen```で実行しようとしたら、

```
sh: -c: line 0: syntax error near unexpected token `('
```

が出たときは、実は、```sh -c```で実行されてしまっているところが問題。
shでは、```<```を解釈できない。

# というわけで、解決法

```
IO.popen(["bash", "-c", exec_cmd], "r", :chdir=>execPath) {}
```
のように[]で、bash, -c, 実行したいコマンドとして入れてあげれば良い。

こうすれば、bashで実行される。

# 駄目な例

```
IO.popen(exec_cmd, "r", :chdir=>execPath) {}
```
のようになっていると、```sh -c```で実行されてしまう。

exec_cmdに```bash -c 実行したいコマンド```とやってもうまくはいかなく、上のように、[]で与えるべきである。

```exec_cmd = "bash -c #{Shellwords.shellescape(exec_cmd)}"```
のように、してもダメで、```[]```として、```["bash", "-c", exec_cmd]```を ```popen```に渡せばOkであった。
DeepSORTとyoloxとの組み合わせの実装を調査中

yoloxでの検出結果に対してDeepSort で追跡を実行する例のリポジトリがあった。

https://github.com/pmj110119/YOLOX_deepsort_tracker

## 追跡について思うこと
- まず、deepSortを試してみよう。
- それで、性能がよくて、実行速度も十分であればラッキー。
- もし、実行速度が不十分なときには、
    - ターゲットデバイスに固有の最適化を利用しよう。
    - 検出範囲の見直し、処理レートの見直しなどで、性能を維持しながら追跡性能を維持できるか考える。
    - 検出の最小サイズを大きくして、処理量を減らすことができるか？
- それでも実行速度が不十分すぎるときは、
    - 追跡性能が低下してもよければ、許容できる範囲の別のアルゴリズムの利用を考える。 



<iframe width="560" height="315" src="https://www.youtube.com/embed/xcXceHBkpF8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

<iframe width="560" height="315" src="https://www.youtube.com/embed/-4LuV9dyR9w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>



-----------------------------------------------------------
## Transformer　ベースのtracking　が増えてきている。
最新のアルゴリズムを試してみたい人は、そちらを探してみることだ。
深層学習(CNN, DNN)がでてきて、追跡アルゴリズムが置き換わったように、Transformerがでてきて変わってきている。


CVPR2023 でtracking　を検索してみる。

https://openaccess.thecvf.com/CVPR2023

https://openaccess.thecvf.com/content/CVPR2023/papers/Zhao_Representation_Learning_for_Visual_Object_Tracking_by_Masked_Appearance_Transfer_CVPR_2023_paper.pdf

https://github.com/difhnp/MAT

https://openaccess.thecvf.com/content/CVPR2023/papers/Wu_DropMAE_Masked_Autoencoders_With_Spatial-Attention_Dropout_for_Tracking_Tasks_CVPR_2023_paper.pdf

https://openaccess.thecvf.com/content/CVPR2023/papers/Van_Hoorick_Tracking_Through_Containers_and_Occluders_in_the_Wild_CVPR_2023_paper.pdf

# 3Dカメラでの物体検出と追跡(2024年追記)
- 3D カメラで物体検出し、そのカメラのライブラリで空間座標として追跡を実施するという方法がある。
- この方法だと、奥行きが異なる対象が一方が他方の影に隠れてしまうなどの状況での追跡が改善する。
- 同じ服装をした人が前後にいる場合だと、従来の手法では人の取り違えを生じていた。
- 3Dカメラの場合には、それが起こりにくい。
- 3Dカメラも10万円以下と安くなってきている。
- 3Dカメラで十分ならば、3Dカメラを使うのがよいとおもう。
noobなスマホアプリ開発

# はじめに
　今までHSPとPythonを少しかじったことしかありませんがこれからの人生のためにアプリ開発をしてみることにしました。具体的な計画はまだ立っていませんが少しずつやっていけたらいいと思います。（こんな調子ではいつか地獄を見そうですが）
　Qiitaへの投稿も初めてです。Markdown記法なんて初めて知りました。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

# これから
　自分がわからなくて調べたことをまとめていく予定です。忘備録的利用を考えています。アプリ開発については諦めないことが当面の目標です。
Rails Nuxtでcarrierwaveを使って画像を保存したときのはまったポイント

# はじめに
RailsのGemであるcarriewaveを使って画像保存機能を実装しました。
その際、なぜか保存はできているのに表示することができなくなりました。
解決するのに時間がかかりましたので備忘録として記載しておきます。
間違い等ございましたらご指摘いただけますと幸いです。


:::note warn
注意
今回の記事では、保存方法やcarrierwaveの使い方みたいな説明は省いております。
ご了承ください
:::

# 環境
- Rails 7.0.4
- Ruby 3.1.2
- carrierwave 2.2.3
- Nuxt 2.15.8(SSR)

# 事象
冒頭でも記載しましたが、起きた事象としてはNuxtからデータを送り保存処理がうまくいっているのに、画面に画像が表示されないというものでした。
この事象の厄介な部分は、最初はうまく表示されていたのに急に表示されなくなったことです。
追加で別のモデルにて画像を保存しようと実装していたら急に画像が表示されなくなり、別モデル側に問題があるのではないかと思いましたが、全くの別問題でした。



# 結論
それでは結論です。
uploadersファイルにて、パスを明記することで解決しました。

```java:app/uploaders/avatar_uploader.rb
  def asset_host
    return "http://localhost:3000" if Rails.env.development?
  end
```

画像を保存するとテーブルにパスが登録されます。
そのバスはよく見ると、「/uploader~~」のように、ルートパスが設定されていません。
その部分をしっかりと設定しておくと問題なく画像を表示できるようになりました。
私の場合、NuxtとRailsでポート番号を変えていたのでこの問題が起こったようです。

最初うまくいっていたのが、謎ですが、、、

私の場合は開発環境のみルートパス込みのパスを指定しております。


# 補足
下記の記事を見つけて理解が深まりました。
私の場合はうまくいかなかったのですが、今思うとconfigファイル修正後にリロードのし忘れな可能性もありますね。。。

https://teratail.com/questions/309739

ちなみに、chromeのデベロッパーツールにて、パス部分に直接パスを入力すると画像が表示されることが解決の糸口になりました。

それまではNuxt側でパスの先頭部分にルートパスを付与するような関数まで作っていたのですが、、笑


どなたかの参考になれば幸いです。

終わり

# 参考

https://github.com/carrierwaveuploader/carrierwave
Rでカラム名の文字化けを直す方法

## 症状

[『現場ですぐ使える時系列データ分析』](https://gihyo.jp/book/2014/978-4-7741-6301-7)の第五章で、データフレームからデンドログラムを作成する際に文字化けが発生した。
どうやらカラムの日本語にShift_JISが使用されてるとのこと。

## やってみたこと

文字コードのデフォルトを`.Rprofile`を使って`Shift_JIS`にしてみる

```r:.Rprofile
options(encoding="Shift_JIS")

```


文字コード確認

```r
getOption("encoding")
[1] "Shift_JIS"
```

ちゃんと変化はしている。

**しかし文字化けは相変わらず……**

Shift_JIS、Shift-jis、CP932、あるいはUTF-8など試してみたものの、特に変化なし。
この設定では意味がないことはわかった。

## 解決方法

以下の方法で文字コードを変換し、データフレームを書き換える。

```r
names(data.log.core30) <- iconv(names(data.log.core30), from = "shift-jis", to = "utf8")

# デンドログラムの表示
fit.clust=hclust(dist(t(data.log.core30)))
plot(fit.clust)

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294146/020a6920-a7ac-8ed8-b7a3-f6771e0f0678.png)



## 参考にさせていただいた記事
[MacでRStudioを使うときのドツボリメモ](https://qiita.com/mokab/items/338638a24768d9a0c5ec)
[[小ネタ]Rでデータフレームのカラム名の文字コードを変換する](https://dev.classmethod.jp/articles/convert-column-names-of-dataframe-in-r/)
Cloudflare Zero Trust Tunnel で https 有効化

# したいこと
Cloudflare Zero Trust Tunnel を使って公開した自宅サーバーに、httpsでアクセスできるようにしたい

# 方法（というか僕がつまづいた点）

- Dashboard > Zero Trust > Access > Tunnels > Public Hostname の設定ではHTTPを選択
- Dashboard > 対応するドメイン > SSL/TLS > EdgeCertificates で **Always Use HTTPS** を有効化

# 参考記事
https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/

https://note.com/hitoshiarakawa/n/n482966cdacdc

https://zenn.dev/yakumo/articles/b1f0e1115cb5b6
初投稿　～ Qiita Markdown 書き方 ～

# はじめに
自己研鑽・備忘を兼ねて、Qiita始めました。

ひとまずQiitaの書き方から調べる私。先は長い...。

ということで初投稿は、練習も兼ねて【Qiita Markdown の書き方】をまとめてみます。

右上の「投稿する✐」ボタンから早速編集スタート。


# ①見出し
文頭に <font color="red">**#**</font> を付けると見出しになる。
（#の数が多いほど小さい見出し）
># #1個の見出し
>## #2個の見出し
>### #3個の見出し
>#### #4個の見出し
>##### #5個の見出し
>###### #6個の見出し

# ②引用
文頭に <font color="red">**>** </font>を付けると引用文になる

> \> グレーのバーが出現

# ③文字の装飾
### 太字
文の前後に <font color="red"> **\*\***  </font>を付けると太字になる
> **\*\*太字にする\*\***
### イタリック
文の前後に <font color="red"> **\***  </font>を付けるとイタリックになる
> *\*イタリック文字にする\**
### カラー指定
文の前に<font color="red"> **\<font color="カラー指定">**</font>、後ろに<font color="red"> **\</font>** </font>を付けると指定したカラーになる
> <font color="blue">\<font color="blue">青色にする\</font></font>
※カラーコードでも指定可
### マークダウン無効
文頭に<font color="red"> **\\** </font>を付けるとマークダウンでの指示が無効になる
> \ \<font color="blue">カラー指定を無効にする\</font>

# ④コードの挿入
Qiitaでよく見る真っ黒なソースコード画面の挿入。
バッククォート3つ <font color="red">**```**</font> で囲うことで実装できる。

>\```
>$hello = "Hello World"
>echo $hello
>\```
```
$hello = "Hello World"
echo $hello
```

さらに、<font color="red">**```言語**</font> とすると自動でハイライトも付けてくれる。
>\```php
>$hello = "Hello World"
>echo $hello
>\```
```php
$hello = "Hello World"
echo $hello
```

なんと、<font color="red">**```言語:ファイル名**</font> でファイル名の表示も可能。
>\```php:hello.php
>$hello = "Hello World"
>echo $hello
>\```
```php:hello.php
$hello = "Hello World"
echo $hello
```

# ⑤リンクの挿入
リンクは、<font color="red">**\[リンク名](リンクURL "タイトル")**</font>で挿入できる。
※タイトルはマウスホバー時に表示されるもの。なくてもOK。
>★\[本記事はこちらを参考に作成してます](https://qiita.com/Qiita/items/c686397e4a0f4f11683d "Markdown記法 チートシート")

★[本記事はこちらを参考に作成してます](https://qiita.com/Qiita/items/c686397e4a0f4f11683d "Markdown記法 チートシート")

# ⑥その他
・目次は記事の見出しを元に、ページ右側に自動生成される
・絵文字の挿入も可能 :flushed:
　[こちらのサイトからコードをコピペ](http://www.emoji-cheat-sheet.com/ "絵文字チートシート")
　or
　編集画面右上の「絵文字を選択」ボタンから選択
・画像も右上のボタンから選択 or ドラッグアンドドロップで挿入可能
・HTMLタグが使える模様

# おわりに
初めてのQiita投稿。
とっても時間がかかりました。調べるといろいろな機能がありますね。

ひとまずは、よく使いそうだな～と思うものをまとめてみました。
投稿を重ねながらアップデートしていきます。

引き続き、学んだことのアウトプットとしてこの場を活用したいと思います！
（さて・・次回の投稿はいつになるのでしょう。）

おしまい。
ChatGPT をターミナルで動かす

OpenAI ChatGPT API を使って、ターミナルで ChatGPT を動かす。

```python
'''Chat with OpenAI GPT-3
How to use:
# 1. Install the OpenAI Python library
# pip install openai
# 2. Get your OpenAI API key from https://beta.openai.com/account/api-keys
# 3. Set your OpenAI API key as an environment variable, e.g.: export OPENAI_API_KEY=<YOUR_API_KEY>

How to run:
# python chat.py
'''
import openai


messages = [{"role": "system", "content": "あなたは優秀な助手です。"}]

while True:

    # 入力を受け取る。改行を含む文章を入力できるようにする。
    prompt = ''
    while input_text := input("Q: "):
        prompt += input_text
    messages.append({"role": "user", "content": prompt})

    # OpenAI GPT-3 に入力を渡す
    r = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature=0.9,
        max_tokens=1200,
        top_p=1,
        frequency_penalty=0.5,
        presence_penalty=0.5,
    )

    # 返答を表示する
    res_text = r.choices[0].message.content
    print(f'A: {res_text}')

    # 返答をメッセージに追加する
    messages.append({"role": "assistant", "content": res_text})

```

ポイント
* role という概念がある。 `system` はメタ的な指示。 `user` はあなたのインプット。 `assistant` は ChatGPT からのレスポンス

# 参考

* https://platform.openai.com/docs/guides/chat
自分用javaメモ

# 本ページは
椎名(@riou95) がJavaフレームワークについて調べてきたものを書き足しているページです。
フレームワークとは、プログラムを作る時の土台
フルスクラッチより土台があったほうが楽

---

<details><summary>見つけたサイト</summary>

```rb
https://www.sejuku.net/blog/3333
```

</details>

---

## Struts
現在はStruts2という新しいのがあってそっち使ってるぽい。
### 関連用語
・Webアプリ用
・MVCモデル

## Spark
マイクロフレームワーク
### 関連用語
・Webアプリ用
・REST　API
配列に文字を追加して別の配列に格納する

**Powershell**で配列に文字を追加して別の配列に格納するスクリプトを実装しました。


```powershell
######### 配列から名前を取得し、文字列を配列に格納する###
######### 新規作成 2023/3/4          ####################
#########################################################


#乱数を格納する変数
$ans = 0
#カウント変数
$cnt = 0
#大食いメッセージ
$msg = "は大食いです"
#データ配列
$data = @("松村沙友理","生田絵梨花","梅澤美波","池田瑛紗","向井葉月")
#結果配列
$result = @();
$result1 = ""

##ランダムの数字を発生するユーザー定義関数
function random(){
    $ans =  Get-Random -Minimum 1 -Maximum 20
    return $ans
}

#5回ループを繰り返し、配列の要素を5つ入れる
while ($cnt -lt 5 ){
    $ans1 = random
    #リターンコードを整数に変換して5で割る
    $ans1 = [int] $ans1 % 5
    # 5で割った余りで判定する
    $result += $data[$ans1] + $msg
    $cnt++
}            

#配列の要素を取り出す
foreach($data in $result){
    Write-Host($data)
}    
```
入門GOプログラミング　Lesson4～10

## 省略形式の変数定義
```go
var count = 10
conut := 10
```

#### for文の省略形式（C, Java, Javascriptと同じ構文）
```go

for count := 10; count > 0; count-- {
    fmt.Println(count)
}
```

## グローバル変数

```go
var era = AD;// グローバル変数
func main() {
	count := 10
	for count = 10; count > 0; count-- {
		fmt.Println(count)
	}
}
```
省略形式による変数定義は使用不可

# Lesson5
練習問題　解答例
```go
package main
import (
	"fmt"
	"math/rand"
)
func main() {
    // 各チケットの要素の配列を定義する
	spaceLineArr := [...]string{"Virgin Galactic", "SpaceX", "Space Adventures"}
	tripTypeArr := [...]string{"Round-trip", "One-way"}
    // フォーマットを定義する
	fmt.Printf("%-18v %-6v %-13v %v\n", "spaceline", "Days", "Trip type", "Price")
	fmt.Println("==============================================")
	for i := 0; i < 10; i++ {
        // 各配列からチケットの要素をランダム選択する
		spaceLineSelectNum := rand.Intn(3)
		tripTypeNum := rand.Intn(2)
		days := rand.Intn(100) + 1
		price := rand.Intn(100) + 1
		fmt.Printf("%-18v %-6v %-13v %v\n", spaceLineArr[spaceLineSelectNum],
			days, tripTypeArr[tripTypeNum], price)
	}
}
```
# Lesson6　型

### ゼロ値
値無しで変数が宣言されたとき、自動的に0が代入される
```go
var price float64
price := 0.0 // 同上
```

### 桁数を指定した表示方法
```go
var third float64 = 1.0 / 3
fmt.Println(third)
fmt.Printf("%v\n", third)// 0.33333....
fmt.Printf("%f\n", third)// 0.33333....
fmt.Printf("%.3f\n", third)// 0.333
fmt.Printf("%4.2f\n", third)// 0.33
```
`%n.Nf`
n=幅
\----
0.33
　--
　N=精度

0でパディング
```go
fmt.Printf("%05.2f\n", third)
```
■練習問題　解答例
```go

```

# Lesson7 整数
### 整数型の種類
```
int8
uint8
int16
uint16
int32
uint32
int64
uint64
```
例えばRGBを表したいとき
```go
	var red, green, blue uint8 = 0x00, 0x80, 0xd5
	fmt.Printf("color : 0x%02x%02x%02x", red, green, blue)
// color : 0x0080d5
```

■練習問題
```go
```

# Lesson8

# Lesson9
文字列リテラル
```go
peace := "peace"
var peace = "peace"// 同上
var peace = "peace"// 同上
var peace // ""と同じ
```
- 別文字への代入は可能（書き換えはPython, Java, Javascript同様で不可能（イミュータブル））
```go
message[5] := "shalom"
message[5] = d // error : cannot assign to message[5]
```

### rune型
`あいうえお`にstring型でアクセス
```go
	s := "あいうえお"

	for i := 0; i < len(s); i++ {
		b := s[i] // byte
		fmt.Printf("0x%02x\n", b)
結果
0xe3
0x81
0x82
0xe3
0x81
0x84
0xe3
0x81
0x86
0xe3
0x81
0x88
0xe3
0x81
0x8a
	}
```

rune型でデコード
```go
s := "あいうえお"
for _, c := range s {
    fmt.Printf("%v\n", string(c))
}
```
■練習問題

# Lesson10 型変換
int -> float64
```go
age := 41
marsAge := float64(age)
fmt.Println(marsAge)
```

Interger -> ASCII
```go
countDown := 10
fmt.Println("発射まであと" + strconv.Itoa(countDown) + "秒")
```
コンソールでChatGPT風に対話する

# やりたいこと
OpenAI API(gpt-3.5-turboなど)を使い、コンソール上で[ChatGPT](https://chat.openai.com/chat)風の対話ができるようにする。

# 実行にかかる費用
1,000トークンあたり0.002$
初回無料枠の18$に収まる範囲であれば無料。
[Usage](https://platform.openai.com/account/usage)ページにて確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228134/f3c01373-9e82-7ff4-6846-47dc1a8964ce.png)


# コード 
```python:chat_cli.py
import os
import openai
openai.api_key = os.environ["OPENAI_API_KEY"] 

messages = [{"role": "system", "content": ""}]
with open('C:\\xxxxxxxxx', 'r') as f:
    msg_args = f.read()
print(msg_args)
while True:
    if msg_args == "":
        text =  input("User: ").strip()
    else:
        text = msg_args
        msg_args = ""
    if text == "quit" or text == "exit":
        break
    elif:
        continue
    messages.append ({"role": "user", "content": text})
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        #model="gpt-3.5-turbo-16K",
        #model="gpt-4",
        messages=messages,
        temperature=0.2,
    )
    content = response["choices"][0]["message"]["content"]
    messages.append({"role": "assistant", "content": content})
    print("\n---\n Assistant:\n" + content + "\n---")
    
```

# コード以外の設定
- openaiライブラリのインストール
- [OpenAIのAPIキー](https://platform.openai.com/account/api-keys)を環境変数へ設定
```
pip install openai
setx OPENAI_API_KEY "YOUR_API_KEY"
```

# つまづきポイント
`openai.ChatCompletion.create`で下記エラーとなる。
openaiライブラリのバージョンを0.26.5 -> 0.27.0へ最新化したところ解消した。
```
AttributeError: module 'openai' has no attribute 'ChatCompletionion'?
```
※アップデートだけで解消しないケースもあり
[AttributeError: module ‘openai’ has no attribute ‘ChatCompletion’](https://community.openai.com/t/attributeerror-module-openai-has-no-attribute-chatcompletion/81490)


# 個人的に思うところ
単に対話するだけならブラウザのChatGPTを使えばよい。
今までAPIを使う機会が少なかったので、練習を兼ねて実装した。今後はこれを機に色々作りたい。ファインチューニングができないとか、その他今一つ理解しきれていないことも多く、色々と調べ理解を深めていきたい。
Auth0 アプリケーションメタデータによるAPIアクセス制御方法 メモ


## やりたいこと

* クライアント(アプリケーション)別に呼び出し可能なAPIを定義し、認可制御を行う。

  ![auth0_api_access.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/52232ce6-0547-295a-c812-59618dbdda9b.png)


## 設定方法

### アプリケーション

* Application -> Advanced Settings -> Application Metadataに呼び出し可能なAPIを定義する。
  * Key：`allowed_api_list`
  * Value：`事前定義したAPIのIdentifier`(複数指定したい場合は、カンマ区切りで入力する)

### Actions

* Loginフローに`check_api`というActionを定義する。

* 以下のコードを記述する。

  ```javascript
  exports.onExecutePostLogin = async (event, api) => {
    // クライアントの呼び出し可能APIリストを取得する。
    const api_list = event.client.metadata.allowed_api_list.split(',');
    // 認可リクエストに指定されたAPI(audience)がAPIリストに含まれているか確認する。
    if(!api_list.includes(event.request.query['audience'])){
      api.access.deny("This client not allowed");
    }
  };
  ```

  

## 動作確認

* 正常系確認

  1. 認可エンドポイントへアクセスする。

     ```http
     GET /authorize?state=aobraoenbaoer134r493yhvahro&redirect_uri=http://localhost:3000&client_id={client_id}&response_type=code&scope=test&audience={Appication MetadataのAllowed APIリストに定義したAPI identifier} HTTP/1.1
     Host: {YOUR_TENANT_ID}
     ```

     ※`audience`にアプリケーションメタデータの`allowed_api_list`に定義した`Identifier`を設定する。

  2. ログインする。（クエリに認可コードが付与され、リダイレクトURIにリダイレクトされる）

* 異常系確認

  1. 認可エンドポイントへアクセスする。

     ```http
     GET /authorize?state=aobraoenbaoer134r493yhvahro&redirect_uri=http://localhost:3000&client_id={client_id}&response_type=code&scope=test&audience={Appication MetadataのAllowed APIリストに定義していないAPI identifier} HTTP/1.1
     Host: {YOUR_TENANT_ID}
     ```

     ※`audience`にアプリケーションメタデータの`allowed_api_list`に<u>定義していない</u>`Identifier`を設定する。

  2. ログインする。（クエリに`error=access_denied&error_description=This%20client%20not%20allowed`が付与され、リダイレクトURIにリダイレクトされる）



## 参考情報

* [Actions Triggers: post-login - Event Object](https://auth0.com/docs/customize/actions/flows-and-triggers/login-flow/event-object)
【Mac】スプリットビューを使用して快適に開発する

# はじめに
Xcodeとシュミレーターを行ったり来たりするのでかなり時間無駄にしていると思います。
Macのスプリットビューを活用して快適な開発環境を作ります！

# こんな感じ
![画面収録_2023-03-04_20_40_57_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/12bde367-194d-8aff-3485-951cd925a77e.gif)

# やりかた
スクリーンにXcodeとシュミレータを用意します。
![スクリーンショット 2023-03-04 20.43.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b846f759-b955-6453-b3e4-977c58b8cc4f.png)

① 緑色のボタンを長押しします
② 「Tile Window to Left of Screen」を選択します
![スクリーンショット 2023-03-04 20.47.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8fb7488b-63a0-79f3-354f-2fcf488cb92a.png)

③ シュミレータを選択します
![スクリーンショット 2023-03-04 20.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a59a176f-6ea4-006a-1c36-8bd153d7aabb.png)

完成！
![スクリーンショット 2023-03-04 20.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/54a62d39-a5db-abac-7680-7152feda75da.png)

# おわり
Twitterたまたま見つけてこんな方法あるんだと思ったんですけど、
どのツイートか見つけられませんでした笑

# 参考記事
https://support.apple.com/ja-jp/HT204948
【3分でできる】Railsでbootstrapの導入方法

# はじめに

bootstrapの導入をします！
簡単に解説します！
bootstrapとは、
Twitter社が開発したCSSの「フレームワーク」です。
便利にデザインが整うやつです。

このbootstrapで理解しないといけないことがあります。
それは、
<b>「グリッドシステム」</b>です

サイトの横幅を均等に分けるガイドラインの事です。
Bootstrapは12本のグリッドで構成されます。
画面が12分割されているという事ですね。
これは理解必須なので、ぜひこちらのサイトを見てください。

参考にしてほしいサイト↓
https://websae.net/twitter-bootstrap-grid-system-21060224/


## bootstrap導入

導入方法はいくつかありますが、今回はyarnで導入します！

ターミナルで、以下コマンドを実行して下さい！
```
yarn add jquery bootstrap@4.5 popper.js
```

次に、config/webpack/environment.jsの一番下に追記。
```
const webpack = require('webpack')
environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    Popper: 'popper.js'
  })
)
```

次に、app/javascriptの配下にstylesheetsフォルダを作成。
app/javascript/stylesheetsフォルダの配下に、
application.scssファイルを作成して、記述追加します。
```
@import '~bootstrap/scss/bootstrap';
```

次に、app/javascript/packs/application.jsに記述追加。
```
import "jquery";
import "popper.js";
import "bootstrap";
import "../stylesheets/application" 
```

次にapp/views/layouts/application.html.erbを書き換えます。
```
<%= stylesheet_pack←ここです！_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
```

補足説明をします！
①stylesheet_link_tagの場合cssファイルは、app/assets 配下のファイルを参照で、
②stylesheet_pack_tagの場合は、app/javascript 配下のファイルを参照します。
今回は②で進めたいので②にしました！

これで、bootstrapの導入は完成です！
おめでとうございます！

## さいごに
いかがでしたでしょうか？
意味を理解できたら、ノールックでコマンドを入力すれば、
3分もあればできると思います^^
便利な機能を使ってrailsを学んでいきましょう！
vscode内cmdでtscコマンドを実行したらエラーになった

## 概要
Node.jsでJavaScriptを使うよりもTypeScriptを使うほうが、型定義が厳密になるため、より管理や保守がしやすいと聞いたため、本格的にNode.jsを本格利用する前に、TypeScriptでコーディングをしたいと思いコンパイルなどをしようとしていた。
しかし、いざコンパイルをしようとしてもtscコマンドが認識されずエラーとなってしまった。
解決法?? vscode内cmdをあきらめて、`cmd`を使用する。
## 環境など
+ win10
+ Node v18．14.0
+ tsc -v　Version 4.9.5
## エラー内容
```node:err
tsc : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\user\AppData\Roaming\npm\tsc.ps1 を読み込むことができ
ません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ tsc -p c:\node-workspase\8\tsconfig.json
+ ~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

 *  ターミナル プロセス "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -Command tsc -p c:\node-workspase\8\tsconfig.json" が終了コード 1 で終了しました。 
 *  ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。 

 *  実行するタスク: tsc -p c:\node-workspase\8\tsconfig.json 

tsc : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\user\AppData\Roaming\npm\tsc.ps1 を読み込むことができ
ません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ tsc -p c:\node-workspase\8\tsconfig.json
+ ~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
```
このエラーの原因についてchatGPTに質問(上記エラーべた貼り)してみたところ
>PowerShellの実行ポリシーが設定されているため、PowerShellでスクリプトを実行できない場合に発生することがあります。この場合、tscコマンドを実行する前に、PowerShellの実行ポリシーを変更する必要があります。

と、それに対する対処法が返ってきた。
しかし、内容に関して同じように実行してもエラー依然残ったままであった。

![2023-03-04_20h44_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125890/c35e4b5b-d217-a2ee-00d9-60a177733e26.png)


## エラー２
```cmd:err
tsc : 用語 'tsc' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されている
ことを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
発生場所 行:1 文字:1
+ tsc -p c:\node-workspase\8\tsconfig.json
+ ~~~
    + CategoryInfo          : ObjectNotFound: (tsc:String) [], CommandNotFoundException       
    + FullyQualifiedErrorId : CommandNotFoundException
```
GPTに聞いたところ
>このエラーは、TypeScriptコンパイラであるtscが見つからないことを示しています。可能性としては、tscをインストールしていない、PATHにtscが追加されていない、またはtscをインストールするために必要な環境変数が正しく設定されていないことが考えられます。

とのことだった。しかし、解決法に関しては先ほど既に行ったことしかなく、意味がなかった。

最終的に、vscode内にあるcmdでは認識しなかった。
しかし、標準のcmdで試しに実行してみたところ、普通にコンパイルがされた。

## まとめ
試しに、vscode_cmdで行おうとしたところ無駄に時間を食ってしまった。
cmdで実行できる以上ほとんど困りませんが、
もしこれらエラーを解決できる方がいたら教えていただきたいです。
Javaを基本からまとめてみた【データ型】

## データ型
データ型：データの種類


① 基本データ型
⇨ 整数　少数　文字　真偽値

＜データ型の一覧＞

|  データ型  |  種類  | データの幅  | データの表現範囲  |
| ---- | ---- | ---- | ---- |
| byte |整数 |8ビット|-128 ～ 127|
| short|整数 |16ビット|− 2の15乗～2の15乗 − 1(-32,768 ～ 32,767) |
| int  |整数 |32ビット|− 2の31乗～2の31乗 − 1(-2,147,483,648 ～ 2,147,483,647)|
| long |整数 |64ビット|− 2の63乗～2の63乗 − 1(-9,223,372,036,854,775,808L ～9,223,372,036,854,775,807L)  |
|float |浮動小数点数|32ビット|IEEE 754 規格の単精度浮動小数点数|
|double|浮動小数点数|64ビット	|IEEE 754 規格の単精度浮動小数点数|
| char |文字|16ビット|Unicode規格の１文字（\u0000～\uFFFF）|
|boolean|論理値|	1ビット	|trueまたはfalse|

- 数値はデフォルトで『int』と『dobule』
⇨ float型の少数にはf(F)をlong型の整数にはl(L)を付ける

- 文字のデータは'で囲む。

② 参照型(文字列：String)
⇨ 文字列　配列
String name = "菅原";

- データ自体はメモリ上の別の場所に置かれてそのアドレスの値（参照値）が変数に入る

## 参考サイト
[基本データ型と参照型：基本データ型全８種類と文字列(String)型の初心者向け解説【Java入門講座】2-3 データ型](https://www.youtube.com/watch?v=ukNoszW09BI)
Dependency Injectionをとにかく簡単にまとめてみた

Dependency Injectionとは、「あるオブジェクトが別のオブジェクトに依存している場合、その依存関係を外部から注入することによってオブジェクト間の結合度を低くし、柔軟性を持たせる」という考え方です。

具体的には、あるクラスAが別のクラスBに依存している場合などが考えられます。
__「クラスAのコンストラクタ」で「クラスBのインスタンスを生成している」__ ような場合、
クラスAとクラスBが強く結合し、クラスBを変更する場合にクラスAも変更する必要が生じてしまいます。
これを回避するために、 __「クラスAのコンストラクタにクラスBのインスタンスを渡すようにする」__ ことで、クラスAはクラスBに依存していることを表明し、外部からクラスBのインスタンスを注入することができるようになります。

下記にクラスAとクラスBが依存し合っている実装とDIを用いた実装を書いてみます。
### クラスAがクラスBに依存している例
```typescript

class ClassB {
  public log(): void {
    console.log('Hello, World!');
  }
}

class ClassA {
  private b: ClassB;

  constructor() {
    // クラスBをインスタンス化
    this.b = new ClassB();
  }

  public callB(): void {
    // クラスBのlogメソッドを使用
    this.b.log();
  }
}

// クラスAをインスタンス化
const a = new ClassA();
// クラスAのcallB()をコール
a.callB();
```
上記のような場合だと、クラスAのコンストラクタでクラスBのインスタンスを生成しているため、クラスAとクラスBが強く結合してしまっている状態です。
その為、クラスBが変更されるとクラスAを変更しなければならない可能性が非常に高くなっています。
そこで、以下のようにクラスBのインスタンスを外部から注入するように変更します。

### クラスAにクラスBのインスタンスを外部から注入した例
```typescript
class ClassB {
  public log(): void {
    console.log('Hello, World!');
  }
}

class ClassA {
  private b: ClassB;

  constructor(b: ClassB) {
    // クラスBのインスタンスが渡されているため、クラスAの中でインスタンス化しなくていい
    this.b = b;
  }

  public callB(): void {
    this.b.log();
  }
}

const b = new ClassB();
// クラスBのインスタンスをクラスAに渡す
const a = new ClassA(b);
a.callB();
```

上記の例では、クラスAのコンストラクタにクラスBのインスタンスを渡すようにしました。
これによって、クラスAは外部からクラスBのインスタンスを注入することができるようになりました。

このようにDependency Injectionを利用することで、クラス間の結合度を低くし、柔軟性を持たせることができます。また、テストコードを書く際にも、テスト用の依存性を差し替えることで、依存関係があるクラスのメソッドを単体でテストできます。

さらに、Dependency Injectionは、アプリケーション全体で共通する機能を提供するサービスを実装する場合にも役立ちます。例えば、ログ出力機能を提供するLoggerサービスを作成し、アプリケーション内の複数のクラスで利用することもできます。