OmniAICreator/Qiita-1.07M huggingface dataset:
知らないなんてもったいない！次世代ターミナル「Warp」

# はじめに

ターミナルは、プログラマーやシステム管理者などの技術者にとって、**日常的な作業の中で欠かせないツール**です。
しかし、デフォルトのターミナルには機能的な制限があり、作業効率が低下してしまうこともあります。
本記事では、そんな問題を解消してくれる**Warp**の基本的な使い方や便利な機能について紹介します。

# Warpとは
Rust言語ベースの非常に高速でUIがオシャなターミナルであり、個人であれば無料で利用することができます。
また、Warpには様々な便利機能がデフォルトで備わっており、**コマンドの入力補完機能**や**AIコマンド検索機能**などを活用することで高速で快適な開発を実現することができます。

:::note warn
Warpは現在Macのみサポートされており、Web(WASM),LinuxやWindwosは順にサポートされる予定のようです。
:::

# インストール方法

インストール方法は、Warpホームページのダウンロード(https://www.warp.dev/) からか、Homebrewを使用してのダウンロードする方法の2つがあります。
インストール後の初回起動時にGitHubかGoogleアカウントでのサインインと簡単な質問を答えることで登録完了です。

https://www.warp.dev/

## Homebrewからダウンロードする場合

以下のコマンドを実行して、Homebrewを使用してWarpをインストールできます。
```console
brew install --cask warp
```
Homebrewをまだインストールしていない方は[こちら](https://brew.sh/index_ja)

# Warpの便利機能
ここからが本題の機能説明です。

## AIコマンド検索

`#` の後に実行したい内容を入力するとAIが提案してくれる。
**日本語でも検索可能！**
![warp-ai-search-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/58f24166-1df1-911e-72bb-b93937632e99.gif)

## GUIテキスト操作
タイポした時に　` ← `　や `Option + ←`を使って間違えた文字まで戻る億劫な時間と作業から解放してくれます。
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/ebac83b9-f4d4-e28c-35c4-91446114033e.gif)

## コマンド入力補完
tabを押すことで入力候補の一覧を表示でき、入力中にもコマンド履歴に基づいて入力候補を提案してくれます。
![warp-suggest.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/bcb26705-ab7c-6dc5-5bd3-62b1dbe0caff.gif)

## ブックマーク機能
コマンド履歴をブックマークに登録することで重要なコマンドに高速アクセスできます。
ブックマークのみを辿るには`Option + 上下キー(↑↓)`
![スクリーンショット 2023-04-16 19.31.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/04676444-7cfa-1ed6-9047-134265235548.png)

## 見やすいコマンド履歴
`↑`を押下するだけで過去に打ち込んだコマンドを一覧で見返すことができます。かなり過去のものまで見れるので地味に便利です。
![スクリーンショット 2023-04-16 16.46.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/02fb0d14-85fb-1137-e52d-a02913736bee.png)

## コマンドパレット
`Command + P`でWarpで実行できるキーボードショートカットを見ることができます。
![command.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/8318f1bf-b325-42e9-16a1-252c3a6a78ef.gif)

## ちょっとした補足

### VScodeからWarpを開く方法
VScodeの設定から`terminal`で検索し、Terminal > Externalの部分をデフォルトの`Terminal.app`から`Warp.app`に変更することで、VScode画面から`Command + Shift + C`でWarpを起動することができます。
![スクリーンショット 2023-04-16 20.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/1a25853e-2f61-99de-33c2-4b23c9c6fa5f.png)

### 背景のテーマ変更
右上のWarpアイコン->歯車アイコン->Appearance->Current themeの順に行くと、いくつかテーマを選択することができます。
お好みのテーマを見つけてモチベーションアップ！
![スクリーンショット 2023-04-16 16.37.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3314085/106baeb1-1d09-b2ad-6a8e-36af021bb79a.png)

## 最後に
ご拝読いただきありがとうございました。
Warpを使えば、ターミナル作業がさらにスムーズになり、作業効率も向上することでしょう。ぜひ、Warpをダウンロードして、より快適なターミナル環境を手に入れてください！
それって本当に検出だけの問題ですか

## 趣旨
- 一般物体認識のアルゴリズムは、改良が続いていて性能の向上が著しい。
- だからといって、一般物体認識を利用した利用例が、必ずしも飛躍的に伸びているとは言い難い。
- それは実は、問題の本質が一般物体認識にあるのではないのにかかわらず、一般物体認識の問題としてしか理解していないことによるのではなかろうか？

## 一般物体認識の後に続くありがちな処理
### 例：前方車両検出
1. 追跡処理
2. 検出対象の方位と角度幅の算出
3. 検出対象物への距離の算出
4. 検出対象物との相対速度の算出
5. 衝突可能性と衝突予測時刻の算出
6. 緊急ブレーキ処理の判断

（前方の車両検出を見つけたいという処理は、これらの後処理を含んだものになっている。）

参考記事　qiita [AI映像解析で車両の速度を自動算出すると異常値ばっかりで苦労した](https://qiita.com/ComputerVision/items/fcd39dcb272edf37518c)


# 交差点での車両検出
- その車両があるというだけの情報では、行動を起こすための情報としては不足していますよね。
- それが自車の進行方向に対して影響する車両なのかどうかが知りたいですよね。
- その自動車は近づいてくいる側の見え方なのか、前方に進行している車両なのかの区別は必須ですよね。
- 四角い枠で囲ってあるのでは不十分であって、どっちの見え方なのかという見え方の分類も必要ですよね。
- 乗用車と大型車両との区別もほしいですよね。
- 右折するタイミングを見計らっている車両についても注意を払いたいですよね。
- 自車が右折車両だったら、トラックの影に直進しようとするバイクが隠れているかもしれないという予測に基づいて、余裕のある判断で右折をしたいですよね。
- そういった全てを満たすように、交差点での車両検出はなされているはずですよね。


### 例：信号検出
１．交通信号を検出する
２．交通信号が何色の表示であるか判定する。
３．自車の走行に影響する信号を選択する。
４．信号に付随する表示の検出

![矢印のある表示](http://dktg.info/midochari/wp-content/uploads/2014/12/img_0-12.jpg)
5. さまざまな車両の照明と信号との区別。
6. さまざまなイルミネーションとの区別
6. 標識検出も関連している。
6. 信号の時系列的な理解。青信号・黄信号・赤信号への推移を理解すること。
6. 信号機は、３次元のルートの中でその位置を開削されなくてはならない。
（だから、画像上の位置では不十分だ。）
信号機は、それがどのルートのどういう車種に向けてなされているものかを解釈されねばならない。


参考記事　Zenn [【自動運転】信号機認識に挑む / 走行画像15,000枚のアノテーションとYOLOXモデルによる深層学習実践](https://zenn.dev/turing_motors/articles/70c5072c04d04c)


### 例：立ち入り禁止区域への立ち入り者の検知
１．人物検出
２．立ち入り禁止区域の理解
３．検出した人物の位置と立ち入り禁止区域との判定の連動
４．人物の追跡
５．人物の顔の検出
６．照合可能な顔画像の保存
７．警備システムへのアラーム処理
８．記録の保持。

## いずれの場合も検出したこと自体は一連の処理の最初のきっかけにすぎないということだ。
- だから、最初の検出をクリアしたところで、残りの課題が解決しなければならないまま残っている。
- ビジネスとして成功するための他の要因をどのように解決するのかを同時に考えなくちゃならない。

## 解決しやすい課題に置き換えることが大事
[～回転レーン上での寿司カバーの異常を検知し迷惑行為を防止](https://www.kurasushi.co.jp/author/004447.html)
食べ終わった皿をレーンに戻すなどの行為があった場合 に検出するということに徹していることで、課題の多くを解決している。

## 付記：　検出してくれという依頼が実は検出だけではないことについて類似の指摘
[ディープラーニングで映像から動かない歩行者を検出するのに苦労した](https://qiita.com/ComputerVision/items/c57d861cfa149b65a39d)

> ・映像解析はCSV吐き出して終わりではない。どこまで何を可視化するかが重要。
VuetifyでVue非推奨機能eventBusを使ってみる

# 非推奨ですが便利な機能eventBus
この機能はVue2の環境でのみ動作します。またVue2においても非推奨となっている機能です。
Vue3では削除されました。VueXを使って同じ動作が出来ますがこれだけの目的でいれるのはどうかと思う。
非推奨とはいえ便利ですので、使う側はサポートの対象外であることを理解していればいいだけの話。

# コンポーネント間のイベント通信eventBus
親を通さないでコンポーネント間のイベントがやり取りできる機能です。
親がなくてPHPでコンポーネントを並べているような環境では必要になるのではないかと思う。

# サンプル
<p class="codepen" data-height="280" data-default-tab="result" data-slug-hash="abRNRER" data-user="nakai1980" style="height: 280px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nakai1980/pen/abRNRER">
  Untitled</a> by nakai1980 (<a href="https://codepen.io/nakai1980">@nakai1980</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### サンプル解説
sendTestクリックで受信側にテキスト「test」が送られるそれだけです。
親には何も組み込んでおりません。
```vuejs
<script>
import Vue from "vue";
const bus = new Vue();

// on ComponentA
bus.$emit('test-event', data);

// on ComponentB
bus.$on('test-event', handler);
</script>
```
サンプルをさらに平たくしたのが上記になります。
emitしたものをonで受け取るだけです。
使い方は下記の様なjsファイルを作成してインポートしてやるのが良いと思います。
```bus.js
import Vue from "vue";
export default new Vue();
```
Cargo Alternate Registryを使ってオレオレツールを誰かに使ってもらいやすくする

CargoないしRustのパッケージレジストリといえばcrates.ioで、ここにpublishしておけば`cargo install ...`でインストール可能になるわけですが、Rustで書いたオレオレツールやClosedな環境でのみ使うツールを公開するわけにはいかないので、なにかいい方法はないかな〜と探してみて一番楽そうだった方法のメモ。

:::note warn
あくまで「Closedな環境」が前提。Publicにしたらやばい。
:::

## 準備

「Cargo Alternate Registryを使って」とまるで自作したかのようないい振りだけど感謝しながら既成ツールを使う。

Cargoは使える状態だとして、[CargoリポジトリのWiki](https://github.com/rust-lang/cargo/wiki/Third-party-registries)に記載されていたcargo-http-registryを使う。

https://github.com/d-e-s-o/cargo-http-registry

```plaintext
cargo install cargo-http-registry
```

## やる

レジストリとして使うディレクトリへのパスを渡すだけ。

お試しで`/tmp`あたり作っておけば良さそう。パスが存在しなければ勝手に作ってくれる。

```plaintext
cargo-http-registry /tmp/registry
```

これでレジストリの準備はおわり。

### レジストリを使うための設定

このレジストリを`cargo`コマンドが認識できるように`~/.cargo/config.toml`に次を追記しておく。

ポートは環境によって変わりそう。`cargo-http-registry`を実行して生成された`config.json`に記載されたポートに合わせる。

```toml
# ~/.cargo/config.toml
[registries]
my-registry = { index = "http://127.0.0.1:62159/git" }
```

fileプロトコルでも使えるみたいなので、ファイルサーバーにレジストリを設置しておくみたいな場合はそっちでも良さそう。

### クレート公開側の設定

`cargo publish`で公開したいので、そのためのアレコレ。

### 自前レジストリにログインする

ログインする。

```
> cargo login --registry=my-registry                 
please paste the token found on http://127.0.0.1:62159/me below
<何でもいいので適当に入れておく>
       Login already logged in
```

トークンはこの際何でもいいので適当に入れる。`Login already logged in`になればOK。

### 適当なクレートを公開してみる

ハローワールドを公開してハローワールドしてみる。

```plaintext
cargo new my_crate_bin && cd my_crate_bin
cargo publish --registry=my-registry --allow-dirty
```

正しく公開できると`cargo-http-registry`で指定したディレクトリ直下に`my_crate_bin-0.1.0.crate`が爆誕しているはず。

公開方法としてはコレで良いですが、公開するであろうパッケージの`Cargo.toml`に次を追記しておくと、crates.ioに万が一にでも上がってしなうことはなくなる（そもそもログインしていなければ上がることはないが）。

```toml
publish = ["my-registry"]
```

cargo-http-registryのREADMEで初めて知った。

## オレオレクレートを使ってみる

自分以外の誰かが使うことを想定して。

もちろん利用者も`~/.cargo/config.toml`に自前レジストリを使うための設定が必要になる。

また、（環境変数でもコントロール可能なので必須ではないが）HTTPプロトコルでアクセスするなら[`net.git-fetch-with-cli`](https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli)を`true`にしておく。

```toml
# ~/.cargo/config.toml
[registries]
my-registry = { index = "http://127.0.0.1:62159/git" }

[net]
git-fetch-with-cli = true
```

これで利用者側の準備おわり。インストールしてみる。

```plaintext
cargo install my_crate_bin --registry=my-registry

# net.git-fetch-with-cliの設定を書かないままHTTPでやり取りするならこっち
CARGO_NET_GIT_FETCH_WITH_CLI=true cargo install my_crate_bin --registry=my-registry
```

インストールできたはず。

```
> my_crate_bin
Hello, world!
```

OK。もういらんので消す。

```
> cargo uninstall my_crate_bin                     
    Removing /Users/sk/.cargo/bin/my_crate_bin
```

## おわりに

Cargo Wikiに記載されている代替ツールはいくつか検討してみたが、（自作するモチベーションはなくて）コレが一番自分のユースケースにあってそうだった。

（Crate？Package？わからん）
StreamlitでChatGPTのStreamを表示する

## 環境
- Python 3.10
- Streamlit 1.21.0
- openai 0.27.4

## Colab (Jupyter)
Colabなどを用いてChatGPTの`stream=True`にした時にストリームで表示するにはいくつか方法が考えられますが、`print(end='')`などで連結しながら出力するのが手軽だと思います。

```python
import openai

completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "昔々あるところに"}],
    stream=True,
)
for chunk in completion:
    next = chunk['choices'][0]['delta'].get('content', '')
    print(next, end='')
```

![2023-04-16_chatgpt_colab.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/ab3993cb-195d-f427-93cf-521825a7da4b.gif)

お好みに応じて、以下のコードで途中に改行を入れたりします。

```python
if "。" in next:
    print("")
```

## Streamlit
[Streamlit](https://streamlit.io/)でChatGPTのStreamを出力するには、`streamlit.empty()`で要素のコンテナを作っておいて、連結したテキストを都度表示します。

```python
import openai
import streamlit

input_text = streamlit.text_input('入力')
if len(input_text) > 0:
    completion = openai.ChatCompletion.create(
        model='gpt-3.5-turbo',
        messages=[{"role": "user", "content": input_text}],
        stream=True,
    )
    result_area = streamlit.empty()
    text = ''
    for chunk in completion:
        next = chunk['choices'][0]['delta'].get('content', '')
        text += next
        result_area.write(text)
```

![2023-04-16_chatgpt_streamlit.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/f2f1e6d4-a398-6dbb-7f23-10238c75577b.gif)


## 参考
- [st\.empty \- Streamlit Docs](https://docs.streamlit.io/library/api-reference/layout/st.empty)
- [How to ‘stream’ output in ChatGPT style while using openAI Completion method \| by Avra \| Feb, 2023 \| Medium](https://medium.com/@avra42/how-to-stream-output-in-chatgpt-style-while-using-openai-completion-method-b90331c15e85)
[AWS Q&A 365][SecretManager]AWSのよくある問題の毎日5選 #31

# 1. AWS Secrets Managerで秘密情報をローテーションするプロセスは何ですか？
回答：AWS Secrets Managerで秘密情報をローテーションするには、ローテーション関数を作成し、関数のネットワークアクセスを設定し、ローテーションのためにシークレットを構成し、ローテーション関数の実行ロールを作成する必要があります。シークレットのタイプによっては、スーパーユーザーシークレットを作成する必要がある場合もあります。ローテーション関数が設定されたら、ローテーション戦略に従ってシークレットが自動的にローテーションされます。

# 2. AWS Secrets Managerで秘密情報をすぐにローテーションできますか？
回答：はい、AWS Secrets Managerでは、AWS CLIを使用してすぐに秘密情報をローテーションできます。「aws secretsmanager rotate-secret --secret-id MyTestDatabaseSecret」コマンドを使用して、指定された秘密情報のすぐにローテーションを開始できます。

# 3. AWS Secrets Managerで秘密情報をローテーションする際の問題をトラブルシューティングするにはどうすればよいですか？
回答：AWS Secrets Managerで秘密情報をローテーションする際の一般的な問題には、ネットワークアクセスに関する問題、欠落または不正確なアクセス許可、ローテーション関数コードに関する問題があります。これらの問題をトラブルシューティングするには、CloudTrailログを確認し、ローテーション関数コードを確認し、アクセス許可とネットワークアクセス設定を確認することをお勧めします。

# 4. AWS Secrets Managerで自動的にローテーションできる秘密情報の種類は何ですか？
回答：AWS Secrets Managerは、データベースの資格情報、Amazon DocumentDBの資格情報、Amazon Redshiftの資格情報など、さまざまな秘密情報の自動ローテーションをサポートしています。特定のローテーション戦略と設定は、秘密情報のタイプによって異なる場合があります。

# 5. AWS Secrets Managerで削除予定の秘密情報を監視するためにCloudWatchを使用できますか？
回答：はい、CloudWatchを使用して、AWS Secrets Managerで削除予定の秘密情報を監視することができます。これには、CloudTrailログファイルの配信をCloudWatchログに設定し、削除イベントを監視するCloudWatchアラームを作成し、アラームが正常に動作することを確認する必要があります。
[AWS Q&A 365][SecretManager]Daily Five Common Questions #31

# 1. What is the process of rotating secrets in AWS Secrets Manager? 
Answer: Rotating secrets in AWS Secrets Manager involves creating a rotation function, setting up network access for the function, configuring the secret for rotation, and creating an execution role for the rotation function. Depending on the type of secret, a superuser secret may also need to be created. Once the rotation function is set up, the secret will automatically rotate according to the rotation strategy defined. 

# 2. Can secrets be rotated immediately in AWS Secrets Manager? 
Answer: Yes, secrets can be rotated immediately in AWS Secrets Manager using the AWS CLI. The command "aws secretsmanager rotate-secret --secret-id MyTestDatabaseSecret" can be used to initiate an immediate rotation of the specified secret. 

# 3. How can I troubleshoot issues with rotating secrets in AWS Secrets Manager? 
Answer: Common issues with rotating secrets in AWS Secrets Manager include problems with network access, missing or incorrect permissions, and issues with the rotation function code. To troubleshoot these issues, it is recommended to check the CloudTrail logs, review the rotation function code, and verify the permissions and network access settings. 

# 4. What types of secrets can be rotated automatically in AWS Secrets Manager? 
Answer: AWS Secrets Manager supports automatic rotation for a variety of secrets, including database credentials, Amazon DocumentDB credentials, and Amazon Redshift credentials. The specific rotation strategy and settings may vary depending on the type of secret. 

# 5. Can CloudWatch be used to monitor secrets scheduled for deletion in AWS Secrets Manager? 
Answer: Yes, CloudWatch can be used to monitor secrets scheduled for deletion in AWS Secrets Manager. This involves configuring CloudTrail log file delivery to CloudWatch logs, creating a CloudWatch alarm to monitor deletion events, and testing the alarm to ensure it is working correctly.
配信してるときに翻訳字幕を出すプログラムを作りたい

```mermaid
graph LR
マイク --> |音声認識| Python -->|日本語を投げる| 翻訳API
OBS --> |監視| テキストファイル
Python --> |翻訳結果書き込み| テキストファイル
翻訳API --> |翻訳結果を返す|Python

subgraph 配信PC
OBS
テキストファイル
マイク
Python
end
```
こんな感じかな
現状の懸念点としては、
翻訳APIがDeepLで考えてたけど無料枠すぐ使えなくなりそうで心配。

https://qiita.com/tanabee/items/c79c5c28ba0537112922

こちらをやってみようかなって思ってる。
WSL2のデータを外部ディスクから抜く

# 目的
WSL2 が稼働していたWindows機が物理的に壊れてしまったが、HW構成を変えたらWindowsが起動しなくなってしまった。
せっかくなのでクリーンインストールしたいが、必要なデータは抜くだけ抜きたい。といった状態。
とりあえずUbuntu18.04のLive DVDで当該SSDをマウントして、データだけコピーしてしまえ、ということで。

# 作業内容

目的のディスクが刺さった状態のUbuntu18.04がある
UbuntuならGUIで覗きに行けば勝手にROでマウントしてくれる
```bash
/dev/nvme0n1p2  931G  563G  368G  61% /media/ubuntu/A82CE8972CE861B4
```
にC:\がマウントされている状態。
とりあえずNTFSで置かれているものはここから抜く

WSL2分についてはWindows各ユーザのAppData以下にvdhxファイルを生成してそのへんに置くらしい。

Ubuntu
```bash
ubuntu@ubuntu:/media/ubuntu/A82CE8972CE861B4/Users/(ユーザ名)/AppData/Local/Packages/CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc/LocalState$ ls -lh
合計 12G
-rwxrwxrwx 2 ubuntu ubuntu  12G  4月  3 01:19 ext4.vhdx
```
このvhdx自体はWSL2でしか読めないファイルらしく、Windows環境にコピーする必要がある。

コピーしたら、PowerShellで以下実行

```powershell
PS C:\Users\User> wsl --mount --vhd ".\ext4.vhdx"
ディスクは '/mnt/wsl/CUsersUserext4vhdx' として正常にマウントされました。
注: /etc/wsl.conf で automount.root 設定を変更した場合、場所は異なります。
ディスクのマウントを解除してデタッチするには、'wsl.exe --unmount \\?\C:\Users\User\ext4.vhdx' を実行してください。
PS C:\Users\User> wsl --mount --vhd ".\ext4.vhdx"
```

ちなみに
```
> wsl --mount --vhd ".\ext4.vhdx"
コマンド ライン オプションが無効です: --mount
```
と言われた場合、wslのバージョンが古いらしい。`wsl --update`すれば解決した。

```
PS C:\Users\User> wsl --update
インストール中: Linux 用 Windows サブシステム
Linux 用 Windows サブシステム  はインストールされました。
```
AWSのセキュリティグループ・ネットワークACLまとめ

# セキュリティグループ
AWSの仮想ファイアウォールサービス
* インバウンドルール：拒否ルールの設定はできず、許可ルールを設定する。
より広い範囲のIPアドレスが許可される。
* アウトバウンドルール：デフォルトではすべてのトラフィックを許可
* 設定単位はENI単位
* IPアドレスだけではなく、CIDRやセキュリティグループ単位でも許可ルールを設定できる。
* アウトバウンドルールを許可すれば、インバウンドは気にしなくてもいい。（ステートフル・インスペクション型）
# ネットワークACL
サブネット単位で設定するファイルウォール
* デフォルトではすべてのトラフィックを許可
* ステートレス・インスペクション型：アウトバウンドの通信を許可した場合、インバウンドにも明示的な許可が必要
* 低い番号のルールが先に評価され、マッチした時点でそのルールのアクションが適用される。
* 許可ルールを適用した後に、拒否ルールを適用する。
AWS　VPC関連の復習

# VPCとは
AWS内部の仮想ネットワーク環境
# サブネットとは
小さなネットワークに分割し、セキュリティレベルを高める。
サブネットはAZをまたぐことはできない。
<dl>
<dt>パブリックサブネット</dt>
・インターネット接続可<br>
・ルートテーブルにインターネットゲートウェイへのルーティングあり
（デフォルトゲートウェイ（0.0.0.0/0）にインターネットゲートウェイが設定されている。）<br>
・外部公開しても良いリソースを設定
<dt>プライベートサブネット</dt>
・インターネット接続不可<br>
・ルートテーブルにインターネットゲートウェイへのルーティングなし<br>
・セキュリティの高いリソース（DBなど）を配置
</dl>

# ルートテーブルとは
* サブネットに関連づけて使用
* サブネットから外に出る通信をどこに向けて発信するか決めるルール・定義
* 最も明確なルールが優先されて適用（例えば、全ての0.0.0.0/0より、向き先が明確なものが優先される。）

# インターネットゲートウェイ
VPC内部リソースがインターネットにアクセスするためにアタッチする。
* 自動スケールし、可用性が高い。
* サブネットのルートテーブルを設定し使用する。（パブリックサブネットのルートテーブルにインターネットゲートウェイへのルーティングあり）

# NATゲートウェイ
* プライベートサブネットからインターネット接続を可能とする目的で使用する。
* アウトバウンドはできるが、インバウンドはできない。
* サブネットのルートテーブルを設定し使用する。（プライベートサブネットのルートテーブルにインターネットゲートウェイへのルーティングあり）

# ENI(Elastic network interface)
仮想ネットワークインターフェーズ
EC2インスタンスのIPアドレスはENIに付与される。（EC2にはデフォルトで1つ付与されている（デタッチ不可））
インスタンスに複数のENIをアタッチできる。

# EIP/パブリックIP
パブリックIPアドレス-インターネットと通信可能なIPアドレス(グローバルIP)
EC2インスタンスではデフォルトで可変
→セキュリティや通信設定などで難あり。。。
↓
EIPを使用する！

## EIP(Elastic IP Address)
* インスタンスにアタッチ/デタッチ可能で静的なパブリックIPアドレス
* インステンスが再起動、停止、終了しても同一アドレス
* インターネット接続用のIPアドレスは、public IP addressかElastic IP addressのどちらか一方しかもてない。
* 基本無料だが、どこにもアタッチされていないEIPは料金がかかってしまう。
JAVA X2 type02　Season1 Chapter2：いい加減Java環境作ってみます！

今回からいよいよプログラム書きます・・のまえに、まずは環境設定から。
一例として私（貧乏ビギナー）の揃えた環境をかき出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/650cbdc2-c5f3-b367-171b-d265d3200d36.png)


# 環境こんな感じに揃えました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/181a905c-202d-b223-16ed-67dab71bd0b9.png)


まずは私の用意した環境は以下の通りです。
マイマシーンスペックは以下の通り。

### PC
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/e5cc5603-fd69-081f-20fd-19caa2da3b31.png)

先日秋葉原で中古で入手してきたタワー型のPCです。

### OS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/ccb9f332-e94a-3715-0092-a776138306cf.png)


職場がWindows環境のため選択しました。

## javaのインストール

コマンドプロンプトでwingetしてみました。（wingetの[参考サイトこちら](https://astherier.com/blog/2021/08/winget-usage-1/)）
先にwinget search javaで出た結果は以下の通り。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/f793bbd3-b76b-f32e-8eee-0f83bf90521c.png)

うえぇ・・・めたくそある・・
とりあえずこの辺、ウインドウス使ってるし。Microsoft Build of OpenJDK with Hotspot 17をインストールして使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/3a4530a4-6449-7d9b-4878-12a7f3bb1771.png)

ここで疑問。JDKって？？

### JDK　:　JAVA STANDARD EDITION DEVEROPMENT KIT

JAVAの開発環境です。これにはフレームワークは含まれていませんとのこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/054a3dba-be9d-5e8e-43e1-eb6af7a320cf.png)
こんなこと書いてありました。要はどうやらプログラムを作るときに必要なあれこれが詰まっている。

対する<B>JRE</b>(JAVA Runtime Environment)は、実行だけのキット。利用者側に必要なあれこれが揃っています。

## 環境変数(^2)の設定

windowsの設定から、以下の個所を確認。JAVA_HOMEにインストールしたJAVAが設定されているか確認します。
JAVAでは、JAVA_HOMEを設定する他、pathに「%JAVA_HOME%\bin」を追加しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/371769e6-2e44-ff14-e325-decf6452f81c.png)

>＾2　<B>環境変数設定てなんでやるの？</B>
環境変数は、コーディングの際の補完機能です。これ設定しないと、JAVAのコンパイル等、JDKの機能使うときにフルパスたたかなきゃならなくなります・・そんなんめんどくさいから、「JAVAいうたらここ見るようにして！」と設定しておくのです。もちろん他の言語などでも同じです。

### IDE(^1)

バージョン: 1.77.3 (user setup)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/94888674-b37f-c1a9-57e8-120bbffc393d.png)

>^1 IDEとは：
「Integrated Development Environment」の略で、開発で利用されるエディタやコンパイラ等のソフトウェアを、その他様々な支援ツールを1つの開発環境で扱えるようまとめた開発環境のこと

そこそこのPCで、普段使いのOSで、無料で使える「VSCode」を選択しました。

## 拡張機能に追加

ここからはVSCodeの設定です。

拡張機能（左のブロックのようなマーク）から、EXTENTION PACK FOR JAVA をインストールします。
なんのためって、これを追加することで、コーディングが楽になります。
どう楽になるのかは後ほど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/62731518-7a7d-a688-ab32-b28a4e53088e.png)


## ディレクトリを準備

現時点でのツリーはこんな感じです。
workspaceフォルダを作成、その下に言語名のついたフォルダを。。。

これは一例です。
取り急ぎ
- src : ソースプログラムしまうところ
- bin : バイナリファイルしまうところ
くらいしか考えていません。
他のファイル名などは、なるべくわかるように名前付け心がけています。
（まだ迷子なのでご容赦ください）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/c5c810bb-aad3-b294-4d20-8d84810f2486.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/f34d8429-f44f-fe67-7e0a-4d6fe8a22ddc.png)


だいぶ長くなりました。だいたいの環境は書き出したので、いったんここまで。
環境は人によって異なるので、あくまで一例としてご参考までに。


＞＞次回、Chapter3[「JAVAさん！はじめまして！！」](https://qiita.com/comchiki66/items/32bf1121e03806200a98)をお送りします。
多少Mermaid記法を扱えるようになったのでやりたいことをメモしておく

# やりたいこと
```mermaid
flowchart LR
    
    FUJITSU --> |情報を保存|db[(Database)] 
    RasPi3 --> |情報を保存|db
    RasPi0 --> |情報を保存|db
    DELL --> |情報を保存|db

    MAIN --> |見に行く|db
    db -->|UIを提供| MAIN[MAINPC\norスマホ]

    subgraph LAN内
        FUJITSU
        RasPi3
        RasPi0
        DELL
    end
    subgraph LAN外サーバー
        db
    end
```

自宅で動いてるサーバー達の状態を出先でも気軽に確認したいと思って。
巷では便利な機能が色々あるみたいだけど、
今のところ知りたいのは生き死にくらいなので、
Pythonあたりで定期実行させて、
Googleスプレッドシートに保存させて、
気になった時に見に行くようにしようと思ってる。
SAC が公布する SAC Analytics Designer 開発者手引き を翻訳してみた (DeveloperHandbookSACAnalyticsDesigner)　①SAC Analytics Designer 


# SAC Analytics Designer って何？(SAC開発者向け)
　 (参照元： https://liuat.com/archived/DeveloperHandbookSACAnalyticsDesigner.pdf )
## Analistic Applicaton とは？
Analistic Applicatonを使用すると、様々なフォームでデータを描写し、シンプルなダッシュボードから、高度なカスタマイズアプリケーションが利用可能
### Analistic Applicaton で使用されるスクリプト言語は？
Analistic Applicaton では **JavaScript** がサポートされる
　例：
　　SAC でサポートされているAPIのメソッド：フィルタリングでは setFilter(’ディメンション’,’メンバー’)があり、ブラウザのランタイムによって実行される。スクリプトエディタは「型」（オブジェクト指向）情報を使用し「型」のチェックに加え、モデル情報を使用し、ディメンションやメンバーに関するヘルプ機能を提供する。

　SAC でサポートされているAPI:　　　
　　  https://help.sap.com/doc/958d4c11261f42e992e8d01a4c0dde25/release/en-US/index.html

## ストーリー機能 と Analytic Applicationsの違い
### ①ストーリー と Analytic Applicationsでは期待されている用途が異なる
**⑴ストーリー**
-  **業務ユーザーに対し、何ができて何ができないかを説明**するために利用される事が想定されている
　　
**⑵Analytic Applications**
- コーディングでデフォルト機能を自由に変更可能
- アンドロイドアプリケーションのような**ライフサイクルがあり、開始ステップやイベントなどコーディング制御**が可能
### ②Analistic Applicatonで実現できてストーリー実現できない機能
　・スクリプティング：**コーディングによる豊富なカスタマイズが可能**
　・AnalisticAapplicaton 独自機能の**ドロップダウンボックス と ボタン**はストーリーで使えない
## Analistic Designer
### Analytics DesignerはSAC機能の一つ Analistic Applicaton作成に使用
Analytics Designerの、ここで言う「デザイン」とは、

　**①データモデル定義
 　②スクリーンレイアウト作成
 　③ウィジェット作成
　④スクリプトによるカスタマイズ**

を意味する

　・Analytics Designer ショートカット
　https://help.sap.com/docs/SAP_ANALYTICS_CLOUD/00f68c2e08b941f081002fd3691d86a7/68dfa2fd057c4d13ad2772825e83b491.html?locale=en-US

## Analytic Applications 作成フロー
Analytic Applicationsは**データドリブンでモデルかOdata接続が必要**。全てのウィジェットはイベントに対応し、イベントハンドラーにコードを実装し、Analytic Applicationsにロジックを追加可能
　手順：
- ①用途決め：Analytic Applicationsでテーブル、チャートどちらのタイプを使用してデータ可視化するか決める
- ②テーブル、チャートを選択すると、モデル選択のステップに移る
　　（＊モデルは業務データの接続元で、ディメンション：項目とメジャー：数値で構成される）
- ③ウィジェット（テーブル、チャート）のデータ出力に加え、フィルターなどの設定を追加
## Analytic Applications 分類
Analytic Applicationsは高度なカスタマイズが可能な為、種類が膨大に存在するが、大きく３パターンに分類される
　**パターン**：
- ①テーブル帳票出力
テーブルで構成され、スクリーン一覧にデータを出力する。多数のインターフェース（ボタン、チェックボックス、ドロップダウンボックス etc）を実装し、一つのテーブルに、異なる多様で複雑な方法でデータを出力する。
- ②ダッシュボード 計器盤（運転席）
- ③汎用Applications
## Analytic Applicationsにおけるスクリプトの挙動
全ての**ウィジェットはイベントに対応**し、**ウィジェット自身もApplicationsイベントに対応**(OnInitialization など)。提供されるスクリプト**APIを使用し、顧客の特定の要望に合わせて調整することが可能**
　**例：**
- ⑴ Applications イベント：
　Applications全体のイベントの一つのOnInitialization イベントは、アプリケーション実行時に一番最初に起動するイベントである。アプリケーション起動時に、読み込みたいコードを実装する（データセットや初期化処理など）。
- ⑵ ウィジェット イベント：
ウィジェット：ドロップダウン イベントの一つのOnSelectでは、ドロップダウンで値が選択されたときに発生。フィルターなどを実装可能。
Androidの音声認識使ってAIと英会話したかった


https://platform.openai.com/docs/guides/chat

OpenAIの[Chat Completion](https://platform.openai.com/docs/guides/chat/chat-completions-beta) と スマホの音声入力 で英会話できるんでね？って思い立ったのでサクッとやってみた。ボットでも良さそうですが、Androidの音声認識のお勉強も兼ねてNativeアプリにて。

モデル：gpt-3.5-turbo

### プロンプト

> System : You are a helpful and friendly assistant that helps people practice their English conversation skills.Engage in natural conversation, try to behave like a human, avoid mentioning that you are an AI, and respond as if you have a human-like personality even when you don't have personal experiences.

> Hi! I'm Me, Please start with a friendly brief self-introduction and a simple question!

いくつか試しましたが、現状最初に与えるプロンプトはこんな感じになりました。
~~何回か試行錯誤しつつほぼほぼChatGPTに考えてもらった~~

とりあえず守って欲しかったのが以下です。
- フレンドリーさ
- 英会話のアシスタントであること
- AIであることを明示しないこと

### コード

https://github.com/kkhouse/EnglishConversation/tree/develop/use_nativeApi


参考
Apiのモデルクラスや通信コードは以下からのコピペです。個人利用レベルで良ければこれ真似すれば大概は良さそうです。（大事なのは、プロンプトをどうするかなので）

https://github.com/aallam/openai-kotlin

### ざっくり解説

- 起動後のUI
<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/8924e424-4446-fea1-1af1-9f42a8336d30.png">

シンプルに以下に流れです。

最初のプロンプトをリクエスト 
-> レスポンスのAI返答をUIに表示 
-> 音声認識経由で取得した文字列をユーザの返答としてリクエスト
-> 繰り返し。

あとは
- マイク長押しで音声認識
- メッセージ右のアイコンでテキストを [TextToSpeech](https://developer.android.com/reference/android/speech/tts/TextToSpeech) )で音読

をしてくれたりします。
（もしかすると、端末の言語設定英語でないとうまくいかない端末があるかもしれません）

- やりとり

短めの文であればいい感じです。（up -> App　って言いたかった。。）

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/7476e330-0e03-a5b8-4711-17665ee3b66d.png">

私の発音もダメなのですが、長めの文はAndroid標準の音声認識の限界を感じます。
カンマがつかないだったり、音の途切れで文を分けてくれないだったり、頭が大文字にならないだったり、
<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/90f26afd-0b17-65e7-4ea0-7caec9a924ff.png">

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/434c26d1-43fb-2604-6c8a-a10c35bed4e8.png">

~~あと、AI回答長くなるとフレンドリーさがなくなってる気がする~~


You と質問してしまうとおかしくなる。「AIであることを明示しない」的なルールを破っているようにも感じる。この辺が難しい。。

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/f85e2b83-e3c1-ea0d-c655-f1e5f845c295.png">



### 終わり
思った通りにできない。。と所感です。

プロンプトエンジニアリング難しいですね。ChatGPTでプロンプト考えてもらったりするのですが、筆者の頭では使いこなせてない感が強い。
この流れについて行ってる猛者の方々、ただただ尊敬です。

以下は引き続き。

- 音声認識はこの際、以下みたいなリッチなものを使ってしまう

https://cloud.google.com/speech-to-text/docs/reference/rest

- しばらく遊ぶので良いプロンプトをひたすらTwitterで漁る



~~ちなみに私の英会話力はないに等しいので、回答はChatGPTに教わりました~~
Ubuntu22.04+Perl+Selenium+Chromeでスクレイピング

# 必要なモジュール
* Google Chrome
* ChromeDriver
* Selenium::Remote::Driver

## Google Chromeのダウンロードとインストール

https://www.google.com/intl/ja_jp/chrome/

コマンドでインストールする方法もあるが、今回はUbuntuにデフォルトでインストールされているFirefoxを使って、
Ubuntu用の最新バージョンのdebファイルをダウンロードしてインストールしました。

## ChromeDriverのダウンロードとインストール
Chromeと同じバージョンのものをダウンロードして、zip解凍したものを、
/usr/bin/chromedriverとして格納しました。

https://chromedriver.chromium.org/downloads

## Perlモジュールをインストール
```bash
$ sudo apt install libexpat1-dev
$ cpanm install Selenium::Remote::Driver
```
libexpat1-devはSelenium::Remote::Driverをインストールする際に必要。

## コードを書く

```perl
use Selenium::Chrome;

my $driver = Selenium::Chrome->new;
$driver->get('https://www.google.com/');
sleep(1);
print $driver->get_title() . "\n";
$driver->shutdown_binary();
```

Selenium::ChromeはSeleniumサーバーが不要なやつで、
Selenium::Remote::Driverをインストールすることで使える、みたいな認識。

# バージョン違いに注意
Chromeのバージョンに合わせて、ChromeDriverもバージョンアップが必要になるが、
手動でダウンロード＆更新するのも面倒なので、下記が便利そう。

https://yatt.hatenablog.jp/entry/20170402/1491105255
統計検定 準1級 合格体験記

統計検定 準1級に一度は落ちるも（3点足らず...）、傾向と対策を練って、1回目の試験から10日後の再受験で80点を取得し合格しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">統計検定準一級、二度目の受験で合格しました！<br><br>10日前に受けたときは合格点に3点足らず、悔しい思いをしたので、今回合格できて良かったです😅<br><br>2回受験した感覚ですが、ワークブックを中心に勉強した方が良さそうだなと感じました。 <a href="https://t.co/IN6sQGCXEH">pic.twitter.com/IN6sQGCXEH</a></p>&mdash; 藤原 (@tngyun58541845) <a href="https://twitter.com/tngyun58541845/status/1645059435835056129?ref_src=twsrc%5Etfw">April 9, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


この記事では、2度の受験を経験した筆者が、感じたこと・気付いたことを皆さんにシェアしようと思います。

皆さんの受験の参考になれば幸いです。

# この記事で解説すること
- この記事の執筆時（2023年4月）では、CBTに対応した過去問題集がないため、どのような問題が出題されるのか不安な方が多いと思います。そこで、この記事ではPBTとCBT方式における出題傾向の違いを解説します。
- また、出題傾向に対応したオススメの勉強法を紹介します。

# 対象とする読者
- 統計検定準1級の勉強を始めたものの、どのように勉強すれば良いかわからない人
- CBT形式での出題形式が分からず、不安な人

# 筆者のバックグラウンド
- 統計検定 2級 保有
- 理工系の大学院卒
- 大学で、深層学習・機械学習・統計学等を勉強

# 1度目の受験で不合格に
自分なりにきちんと準備して臨んだ、初めての統計検定準1級でしたが、結果は57点で不合格。体感としては合格点をギリギリ超えられたかなと思っていたので、「不合格」の文字が見えたときは、かなり落ち込みました。悔しすぎて帰りの電車の中で、すぐに10日後の再受験を申し込みました（笑）。

2回目の受験で確実に合格点を取るために、今回の敗因の分析を始めました。

まず、1度目の受験までに行った勉強は以下の通りです。
- 統計学実践ワークブック　2周
- 統計検定 準1級　公式問題集　3周

私はこれらの参考書を、ワークブックで知識や計算方法をインプット、公式問題集でアウトプットをするという感じで使っていました。というのも、過去問をベースにした問題が本番でも出ると思っていたからです。

しかし、実際に試験を受けた感想としては、**ワークブックの内容に重点を置いている印象**を受けました。具体的には、
- ワークブックの例、例題に類似した問題が出題される
- 例や例題になっていなくても、公式っぽいもの（各種検定手法等）は、自分できちんと計算できるかが問われる
- 用語の定義や意味をきちんと理解しているか問われる

という印象を受けました。もちろん、ワークブックとは出題形式が異なる問題も出題されますが、**ひとまず合格点が取れれば良いという人はワークブックを重点的にやった方が良い**と思いました。

そこで、2度目の目の受験までの間、次の勉強をしました。
- ワークブックの例・例題を全て解き直す。（メイン）
- 各種用語・統計手法の意味や計算方法を再確認。（おまけ程度）

そして2度目の受験に向かいます。

# 2度目の受験で合格
2度目の受験ですが、1問目・2問目が難しくて、このとき正直落ちたかと思いました😅。しかし、問題が進むにつれて、見慣れた問題も多くなり、自信を持って回答することができました。結果は80点で合格！合格の喜びと試験から解放される安堵感で一杯でした。

2度目の受験でも、ワークブックをベースとした問題が結構出たので、やはり**私の勉強の方向性は間違っていなかった**と思いました。

# オススメの勉強法
最後に、私の受験体験に基づくオススメの勉強フローを紹介します。
1. **ワークブックを利用して、知識をインプットする**。ちなみに、ワークブックだけでは内容を理解しきれないと思うので、ここでは具体的な資料は示しませんが、適宜、他の参考書やサイトを参照してください。色々な方が紹介してくれています。
1. **公式問題集でアウトプットする**。本番の試験問題と公式問題集は、問題の雰囲気は異なりますが、アウトプットを通して理解を深める目的で、公式問題集を解くことは必須だと思います。
1. **試験直前期は、自分がこれまで得てきた知識を、試験に合格するために特化した知識に変換・調整しましょう**。その際、主に基準となるのはワークブックの例・例題にあるような問題を何も見ずに、解けるかどうかです。

最後まで、読んでいただきありがとうございます。皆様が試験に合格できることを祈っています！
実行ファイルEXEでwxpythonのGUI上でhtmlが表示されない場合

# 実行環境
python 3.10.9


foliumで生成したOSMの地図をwxpythonのGUIで表示するというプログラムを作成しましたが、pyinstallerを使用してexe化した際に地図がGUI上に表示されないという問題にハマったので備忘録的に記載します。
__wx.html2.WebViewがexe化したときに正常に動作していないようでした__


# 直接使用するライブラリ
まず、pyinstallerでexe化する際にライブラリで必要なものをpipでインストールします。
```
pip install folium wxpython pyinstaller
```

# 依存関係のあるライブラリ
foliumを含むPythonスクリプトをexe化するために必要なライブラリは、pyinstallerが必要とするライブラリの他に、pywin32やsetuptoolsなど、Windows環境で必要なライブラリが必要になります。

したがって、foliumを含むPythonスクリプトをexe化するために必要なライブラリは、以下のものになります。
```
pip install pywin32 setuptools
```
これらのライブラリを含めて、Pythonスクリプトをexe化することで、foliumを含むPythonスクリプトを実行可能ファイルとして作成することができます。

# pipでインストールしたバージョン
folium                    0.14.0
wxPython                  4.2.0

# exe化実行
### 1 Pythonスクリプトを作成する。
foliumを使用したPythonスクリプトを作成します。
wx.html2.WebViewでSetPageを使ってhtmlページを表示する

### 2 pyinstallerを使用して、Pythonスクリプトを実行可能ファイルに変換する。
pyinstallerを使用してfoliumを含むPythonスクリプトを実行可能ファイルに変換する場合、foliumが依存するライブラリに加えて、pyinstallerが必要とするライブラリを含める必要があります。
```
pyinstaller your_script.py --hidden-import jinja2 --hidden-import markupsafe --hidden-import branca --hidden-import requests --hidden-import urllib3 --hidden-import chardet --hidden-import certifi --hidden-import flask --hidden-import werkzeug
```
上記のコマンドでは、foliumを含むPythonスクリプトをyour_script.pyに置き換えてください。また、foliumが依存するライブラリの他に、pyinstallerが必要とするライブラリも--hidden-importオプションを使用して指定しています。

### 3 pyinstallerのdatasパラメータを使用して、バイナリやJavaScriptファイルを実行可能ファイルに含める
変換が完了したら、２のコマンドで生成されたyour_script.specファイルを編集して、foliumが依存するJavaScriptファイル（例えばLeafletやjQuery）やwxpythonで必要なバイナリを含める必要があります。
__ここで、wxPython(4.2.0)ではWebView2Loader.dllをAdd Binaryとして指定する必要があります。__
参考 ：https://github.com/wxWidgets/Phoenix/issues/2234


```your_script.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
    ['your_script.py'],
    pathex=[],
    binaries=[('.venv\\Lib\\site-packages\\wx\\WebView2Loader.dll', '.')],
    datas=[('.\\\\.venv\\\\Lib\\\\site-packages\\\\branca\\\\*.json', 'branca')],
    hiddenimports=['jinja2', 'markupsafe', 'branca', 'requests', 'urllib3', 'chardet', 'certifi', 'flask', 'werkzeug'],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='your_app',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
coll = COLLECT(
    exe,
    a.binaries,
    a.zipfiles,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='your_script',
)
```
### 4 pyinstallerを再度実行してexe化
```
pyinstaller your_script.spec
```

上記のような手順で作成したexeファイルで、foliumで作成したhtml地図をwxpythonのGUI上に表示することができました。
（参考URL先では過去のwxpythonのバージョンではバイナリ追加手順は必要なかったようなので、過去のバージョンにするのも手かと、、、）
Headless CMSのStrapi環境構築

# はじめに
流行りのHeadless CMSを試してみたかったので、Headless CMSのStrapiの環境構築をしてみたので、備忘録として環境構築方法について残しておきます。

Headless CMSについては省略します。
調べている際に、自分は以下のサイトを参考にさせてもらいました。
Strapiについても以下のサイトに記載せれています。

https://wk-partners.co.jp/homepage/blog/hpseisaku/htmlcss/headless-cms/

# 環境構築
管理画面にアクセスするまでの環境構築はかなり簡単にできました！

#### 事前準備
npmとNode.jsが必要になります
インストールされていなければ、インストールして下さい。

#### Strapiをインストール
```
$ npm install strapi
```

#### strapiアプリを新規作成
```
$ npx create-strapi-app my-project --quickstart
```
または
```
$ yarn create strapi-app my-project --quickstart
```

上記コマンドを入力すると、インストールが始まります。
インストールが終わると、Strapiのアカウント作成画面が自動で開くので、名前、パスワード、メールアドレスを入力し、登録を完了して下さい。

以上で、環境構築完了です！

# まとめ
すごい簡単に環境構築できました！
管理画面など触ってみた内容はまた別記事で書こうかと思います。
SQLの基本


## はじめに
データ分析に必要なSQLの基本をまとめました

データ操作言語(DML)

|文字|用途|
|:--|:--|
|SELECT|列名の検索|
|FROM|テーブルの選択|
|WHERE|条件式の入力|
|DISTINCT|SELECTの後ろにつけて検索するデータの重複を削除する|
|IS NULL|条件式でNULLであるものを抽出|
|BETWEEN|条件式で下限と上限を指定|
|IN|複数の条件式で一つでも当てはまれば抽出|
|LIKE|ワイルドカード（％、_）を用いて曖昧な検索|
|ORDER BY,ASC,DESC|レコードを昇順や降順に並び替える|
|JOIN|テーブルのキーを指定して同じ項目を結合|
|LEFT,RIGHT,FULL OUTER JOIN|指定した方向の列は全て表示し、一致しないものはNULL|
|CROSS JOIN|テーブルの積を表示|
|JOIN AS|自己結合する際にFROM句でASで別名をつけて区別|
|EXISTS|存在するか（サブクエリなどで）|
|ANY,SOME|サブクエリなどでいずれかの値を評価|
|UNION,UNION ALL|SELECTで取得したレコードを統合、ALLをつけると重複分も記述|
|EXCEPT,MINUS|上の取得レコードにあって下の取得レコードにないものを取得|
|INTERSECT|共通するレコードを取得|
|INSERT INTO VALUES|レコードを追加|
|INSERT SELECT|他のテーブルから取得したレコードを追加|
|UPDATE|条件式のところにSETで項目を更新|
|DELETE FROM|条件式似合うものをテーブルから削除|
|SUM ,AVG ,COUNT ,MAX ,MIN|集計関数として指定した列の様々な計算を行う|
|GROUP BY|指定した列内で同じ種類のものをまとめて表示|
|HAVING|集計関数を条件式に入れたいときに使う|
|+,CONCAT,縦棒２個|文字列を連結するときに各DBMSで異なる|
|UPPER,UCASE,LOWER,LCASE|文字列を大文字や小文字に変換|
|SUBSTRING,Mid|文字列の一部を取得。DBMSで異なる|
|TRIM ,LTRIM ,RTRIM|文字列の左右の空白を削除|
|TRIM,BOTH,LEADING,TRAILING|文字列の左右の特定の文字を削除|
|REPLACE,TRANSLATE|文字列内の指定した文字を別のものに置き換える|
|CHAR_LENGTH,LEN,LENGTH|文字列の文字数を取得|
|OCTET_LENGTH,LENB,LENGTHB,LENGTH|文字列のバイト数を取得|
|数学関数|色々な計算|
|日付関数|日時を取得|
|型変換関数|数値や文字列、日付の型を入れ替える|


データ定義言語 (DDL)

|文字|用途|
|:--|:--|
|CREATE DATABASE|データベースを作成|
|DROP DATABASE|データベースを削除|
|ALTER TABLE|テーブルの定義を変更する|
|RENAME TABLE|テーブル名を変更する|
|CREATE VIEW|ビューを作成する|
|CREATE INDEX|インデックスを作成する|
|CREATE USER|ユーザーを作成する|
|GRANT|ユーザーにアクセス権を追加する|
|REVOKU|ユーザーからアクセス権を削除する|
|CREATE TRIGGER|トリガーを作成する|


データ制御言語(DCL)

|文字|用途|
|:--|:--|
|BEGIN TRANSACTION|トランザクションを開始する|
|COMMIT|トランザクションを確定する|
|ROLLBACK|トランザクションを取り消す|
|SAVEPOINT|セーブポイントを作成する|


参考サイト

https://www.sql-reference.com/
laravel 8.x debugbarのインストール

# laravel8でdebugbarのインストール

エラーが出て解決までに時間がかかったため、同じようなエラーに遭遇している人のお役に立てればと思い残しときます。


### インストール
```
composer require barryvdh/laravel-debugbar
```
インストールのコマンドを叩いたところ、以下のエラーが出てきた。

### エラー
```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - barryvdh/laravel-debugbar[v3.8.0, ..., 3.8.x-dev] require illuminate/routing ^9|^10 -> found illuminate/routing[v9.0.0-beta.1, ..., 9.x-dev, v10.0.0, ..., 10.x-dev] but these were not loaded, likely because it conflicts with another require.
    - Root composer.json requires barryvdh/laravel-debugbar ^3.8 -> satisfiable by barryvdh/laravel-debugbar[v3.8.0, v3.8.1, 3.8.x-dev].

You can also try re-running composer require with an explicit version constraint, e.g. "composer require barryvdh/laravel-debugbar:*" to figure out if any version is installable, or "composer require barryvdh/laravel-debugbar:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.
```
### 原因と解決
laravel８以降は、Debugbarのサービスプロバイダが自動的に登録されなくなり、サービスプロバイダを手動で登録でエラーが解決する。

config/app.phpのそれぞれの行に以下を追加。

```php:providers
Barryvdh\Debugbar\ServiceProvider::class,
```

```php:aliases
'Debugbar' => Barryvdh\Debugbar\Facade::class,
```

再度インストールのコマンドを実行で無事インストールされた。
【GAS】Slackにダイレクトメッセージを送る

slackのユーザーのchannelIDは下記の手順で一括取得
https://qiita.com/80syokumotsu/items/46205cd71da5cd2d6ce1

tokenは下記の手順で登録
https://qiita.com/80syokumotsu/items/bf1043606289a28f1d02
```
const slack_app_token5 = PropertiesService.getScriptProperties().getProperty("slack_token");
//botからDMを送る
//function postDM() {
function postDM2(id,text) {

  //【処理1】DMを開き、チャンネルIDを取得する
  var channel_id = id
  const message = text;
  //var channnel=id

  //var getchannelid=getChannelID_(id)
  //Logger.log(getchannelid)
 // channel_id=	getchannelid
  
  Logger.log(channel_id)
  //【処理2】指定の[チャンネルID]にDMを送信する
  const message_options = {
    "method" : "post",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : {
      "token": slack_app_token5,
      "channel": channel_id,
      "text": message
    }
  }
  //必要scope = chat:write

  const message_url = 'https://slack.com/api/chat.postMessage';
  UrlFetchApp.fetch(message_url, message_options);
}
/**
* メンバーIDを受け取りチャンネルIDを返す
*
* @param {string} メンバーID
* @return {string} チャンネルID
*/
function getChannelID_(id) {
  const options = {
    "method" : "post",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : {
      "token": slack_app_token5,
      "users": id
    }
  }
  //必要scope = im:write
  const url = 'https://slack.com/api/conversations.open';
  const response = UrlFetchApp.fetch(url, options);
  const obj = JSON.parse(response);
  console.log(obj);
  return obj.channel.id;
}

function getMassage(){
 //var sheets = SpreadsheetApp.openById('スプレッドシートのID');
  var sheets = SpreadsheetApp.getActiveSpreadsheet();
  //「"フォームの回答 1"」のシート情報を取得し「fmSheet」に代入
  var fmSheet =sheets.getSheetByName("フォームの回答 1");
  //シート「フォームの回答 1」のC列の最終行取得
  var fmSheetlastRowC = fmSheet.getRange(1, 3).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
  //シート「フォームの回答 1」の最終行のM（13列目）列の値がchannelIDなのでidに入れる
  var id= fmSheet.getRange(fmSheetlastRowC,13,1,1).getValue();
  //シート「フォームの回答 1」の最終行のG（7列）列の値が送信したいメッセージ内容なので取得してtextに入れる
  var text = fmSheet.getRange(fmSheetlastRowC,7,1,1).getValue();
  Logger.log(id);

  Logger.log(text);
  postDM2(id,text)

}
```

参考にしたサイト：https://moripro.net/gas-slackapi-bot-send-dm：
【GAS】SlackのchannelIDを一括で取得する

# 目的
Slackのユーザーに直接DMを送りたいため、channelIDを取得するGASを作成
# 前提条件
- Slackの管理者であること
- Bot User OAuth Token があること
- Bot Token Scopes　で下記の権限を追加していること

・channels:read
View basic information about public channels in a workspace

・chat:write
Send messages as @ｘｘｘ

・chat:write.customize
Send messages as @ｘｘｘ with a customized username and avatar

・commands
Add shortcuts and/or slash commands that people can use


・groups:write
Manage private channels that ｘｘｘｘ has been added to and create new ones

・im:read
View basic information about direct messages that ｘｘｘｘ has been added to

・im:write
Start direct messages with people

・links:write
Show previews of URLs in messages

・mpim:read
View basic information about group direct messages that ｘｘｘｘ has been added to

・mpim:write
Start group direct messages with people

・usergroups:read
View user groups in a workspace

users.profile:read
View profile details about people in a workspace

users:read
View people in a workspace

# 手順
1．新規にスプレッドシートを作成する。
2．slackという名前のシートを作成する。
3．「拡張機能」「AppScript」の順に開く
4．Bot User OAuth Tokenをプロパティに登録するスクリプトを作成する
https://qiita.com/80syokumotsu/items/46205cd71da5cd2d6ce1
5．Slackの情報を取得するスクリプトを作成
スクリプト名：slackget.gs


```
const slack_app_token4 = PropertiesService.getScriptProperties().getProperty("slack_token");

function getSlackUser() {

  const options = {
    "method" : "get",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : { 
      "token": slack_app_token4
    }
  };


  const url = "https://slack.com/api/users.list";
  const response = UrlFetchApp.fetch(url, options);
  
  const members = JSON.parse(response).members;

  let arr = [];


  for (const member of members) {
    
    //削除済、botユーザー、Slackbotを除く
    if (!member.deleted && !member.is_bot && member.id !== "USLACKBOT") {

      let member_id = member.id;  
      let dispname = member.profile.display_name; //表示名
      let real_name = member.real_name; //氏名(※表示名ではない)
      let channelid = getChannelID_(member_id);
      console.log(dispname);
      
      arr.push([member_id,dispname,real_name,channelid]);
    }
    
  }


  //スプレッドシートに書き込み
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('slack');
  sheet.getRange(1,1,1,1).setValue("SlackID");
  sheet.getRange(1,2,1,1).setValue("表示名");
  sheet.getRange(1,3,1,1).setValue("ユーザー名");
  sheet.getRange(1,4,1,1).setValue("channelid");
  sheet.getRange(2, 1, sheet.getMaxRows()-1, 2).clearContent();
  sheet.getRange(2, 1, arr.length, arr[0].length).setValues(arr);
}


function getChannelID_(member_id) {
 
  const options = {
    "method" : "post",
    "contentType": "application/x-www-form-urlencoded",
    "payload" : {
      "token": slack_app_token4,
      "users": member_id
    }
  }
  
  //必要scope = im:write
  const url = 'https://slack.com/api/conversations.open';
  const response = UrlFetchApp.fetch(url, options);
  
  const obj = JSON.parse(response);
  console.log(obj);
  
  return obj.channel.id;
 
}
```

6．slackシートにslackのユーザーの情報が追記される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640876/d9fb16d1-37d6-cad0-1436-3aa4b724bf9f.png)
バッテリー表記のCの解釈



![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 電流を一瞬だけドカンとながせる瞬発力がほしい

## やること
サーボモーターを一度にたくさん動かす時などに瞬間的な電流が必要になります。
バッテリーの放電能力は高いほど助かりますが、表記スペックをどう解釈すればいいかを簡単にまとめます。
（ご専門の方からも解釈はだいたい合っていると確認いただいてます。）


## 参考
https://engineer-education.com/lithium-ion-battery01/

https://batteryconcier.com/capacity-rate/

## バッテリーに記載の「〜C」は充電放電スピード

バッテリーに「C」という単位の表記がありますが、これはクーロンではなく「Cレート」とのこと。CはキャパシティのC。
このCレートは、バッテリーの充電及び放電のスピードを示します。
電池の理論容量を1時間で完全充電（または放電）させる電流の大きさが1Cであると定義されます。

定格容量が1,000mAhの電池を定電流で放電した場合、1Cは1,000mA。
2Cは1/2時間で完全に放電する場合は2,000mAとなり。5Cならば1/5時間で5,000mAとなります。

スペック表記にあるCの値が大きいほど、放電能力が高いバッテリーということになります。

## バッテリー表記のスペックの読み方

バッテリーに以下のような表記があったとします。

・20-30C DISCHARGE
・1,000mAh

20-30Cというのは、通常時放電能力は20C - 大体1秒未満の瞬間的な放電能力は30Cという意味です。
バッテリーの容量を表すのが1,000mAhなので、

放電能力[A] = Cレート[C] × バッテリー容量[Ah]
通常：20C×1Ah＝20A
瞬間：30C×1Ah＝30A

となり、最大で20A、1秒未満なら30Aを出力できるということらしいです。
仮に20Cで流しつづけた場合は、理論上は1/20時間なので3分しか持たないということになります。たぶん。

## 具体例で見る

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/b89c3db8-25f8-0737-fa78-4f9822eccb3c.png" width= 400>


この銀色のバッテリーは、
・80C-160C
・1,050mAh
なので、
通常：80Cx1.05Ah=84A
瞬間：160Cx1.05Ah=168A
仮に20Cで運用すれば21Aを供給しつづけて約3分、80Cで運用すれば45秒持つということになります。たぶん。
充電時のアンペアのセレクトも、4Aとかで実行して問題ないはずです。（やったことないけど）

---
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/b61a4311-f325-e5a5-a35a-447a88365f3e.png" width= 400>

この赤いバッテリーは、
・30C
・1,300mAh
なので、
通常：30Cx1.3Ah=39A
瞬間：不明
仮に20Cで運用すれば26Aを供給しつづけて約3分持つということになります。たぶん。
こちらも充電時のアンペアのセレクトを4Aに設定しても問題ないはずです。（やったことないけど）

---

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/6a6512ad-63d4-cd29-e92e-2f1d7d569a3e.png" width= 400>

この黒いバッテリーは、写真では20C-40Cですが、メーカーのサイトによると最新版のスペックは
・C-Rate(連続/バースト)：15C/20C
・850mAh
だそうなので、
通常：15Cx0.85Ah=12.75A
瞬間：30Cx0.85Ah=25.5A
仮に15Cで運用すれば12.75Aを供給しつづけて約4分持つということになります。たぶん。


## まちがってるかも！

間違っていたら教えてください。

## なぜ調べているか

電源を使った際にもリポ級の瞬発力を出せるよう、電源や機体にキャパシタを追加したいと考えています。
Zabbixサーバの言語設定に新しい言語を追加する


## きっかけ
zabbixサーバの画面にアクセスすると、言語が英語表記であった。
設定>言語　を選択すると、「日本語(ja_JP)」がグレーアウトで選択できない...
また、言語の横に、以下のエラーメッセージが表示されていた。

```
You are not able to choose some of the languages, because locales for them are not installed on the web server.
```
どうやら、OS上に、日本語がインストールされていない..?

そのため以下の内容を実施した。

## 0.システム要件
サーバ：　Ubuntu Server 22.04 LTS
Zabbix : バージョン6.0

## 1. 言語設定確認

現在採用されている言語設定を確認します
```
# localectl
```
コマンド結果
```
   System Locale: LANG=ja_JP.UTF-8
       VC Keymap: n/a
      X11 Layout: jp
       X11 Model: pc105
```
あれ、日本語になっている...

zabbix公式に今回やりたいことの記載があったので、指示に従う
- [Zabbix公式　フロントエンドへの言語追加](https://www.zabbix.com/documentation/6.0/jp/manual/appendix/install/locales)


```
# vi /etc/locale.gen
```
以下ののコメントアウト外す
```
#ja_JP.UTF-8 UTF-8
↓
ja_JP.UTF-8 UTF-8
```
再読み込みする
```
# locacl-gen
```
コマンド結果
```
Generating locales (this might take a while)...
  en_US.UTF-8... done
  ja_JP.UTF-8... done
Generation complete.
```

サーバ再起動する
再起動しないと、反映されなかったので...
```
# reboot
```

## 2.Zabbix画面確認
今回は、日本語のみのインストールのため、相変わらずエラーは表示されますが、日本語（ja_JP）を選択できるようになりました。
![スクリーンショット 2023-04-16 171245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713122/ad797902-cba3-f6a4-ded5-66874cdcf3ab.png)

## 3.おわり
Ubuntu上にZabbixの構築は何回か行っていましたが、サーバ構築時の言語設定がうまくいかなかったのでしょうか。この事象は小さいですが、初めてでした。localectl コマンドを認知していなかったので、また一つ学ぶことができました。
JAVA X2 type02　Season1 Chapter1 ：「オブジェクト指向が苦手です」

今回も何も役に立たない記事です。
私のやったことがなにも生まなかったを淡々と書いただけです。
大して役に立たないとお察しでしたら記事は読まないで大丈夫です。（心が弱いのでディスり不要です）

内容としては「なぜプログラミングビギナーが概念だけで理解しようとするとハマる。」というところです。

# オブジェクト指向アレルギー

まずは恒例のググルカス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/3b0bec58-5809-d0ab-6c3e-6a475ab4b0d7.png)

検索結果ですでに頭痛が痛い！！！

オブジェクト、とはなんぞや？と聞いても「モノ」と言われる。
そもそもオブジェクト指向ってなにを解決するために出てきたものなの？？

この辺全然わからない～（号泣）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/15daa961-be84-a7d3-78ea-11e9d78d527c.png)

未知との遭遇。

だいたい、ネットに乗ってる情報しかり。
独特の用語でさらーっと書いてあって<B>こっちが理解するか否かなんてどーでもいい</B>ような書きぶりで嫌。私だけ？
そりゃそうですよね。できあがった概念に名前をつけて、これを実現します！て宣言であって完全に実現できるかは別問題だし。

仕方がないから。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/311465c9-2157-6318-25f5-f79ab2e0d95d.png)
↑これ読みました。<B>なんとなく</B>わかって<B>なにも</B>わかりませんでした。
読了したときはなんとなくわかった気になって、まとめようと思いました。
でも、自分の言葉でまとめようとすると全然言葉が出てこない。
呑み込めてないんですよね。

型だのなんたらイズムだのどうだの、実際モノ作りながら読んでなければ理解できません。
そこで自分なりに出た答え。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/003118c8-e007-f09f-6d6a-4f6e3d3fee41.png)

### 考えるより書く、慣れる。

それしかないに至る。
手を動かして、疑問に至ったらまた考えて
そしてまた手を動かすでいいかなーと。

私のようにハマるアホはいないと思いますが、
同じ悩み抱えてるビギナーさんいらしたら、言うてあげてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/857df231-4561-e741-a5ea-22d9eba2bcd9.png)


#### 「今説明聞いてもなにも頭に入らないよ。とにかく書いてみよう。」

オブジェクト指向とは
「プログラムの考え方、書き方の一つ。概念から入ってすぐ理解できるものじゃない。」
って。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308477/0897cd8e-75cf-245c-688e-97529d5fd528.png)


## 最後に

なんでこんな中身のない記事を書いたかというと。
すでに理解している立場の方から学び始めの方にむけて「まず書いてみろ」が伝わらない場合があると感じたからです。
それと、わからなくて散々もがいた結果、言われたこと（すなわち四の五の言わずに書け！）を理解した部分があったからです。
指導上で発生する「ばかめ。こうなるから考えないでやってみろなんだよ」のソースとしてお使いください。

＞＞次回、[Chapter2「いい加減Java環境作ってみます！」](https://qiita.com/comchiki66/items/e2da00df8d2cee6965a9)をお送りします。
公式のGitHubからnodebrewをインストールすることに失敗したのは、perlのパスが通っていないことが原因だった

# 背景
Node.jsの環境構築をするにあたって、nodebrewを公式GitHubからインストールすることを試みたが、できなかった。
nodebrewをインストールするにはperlの環境が必要で、perlのインストールおよび内部コマンドとして使える状態にすることが必要だった。

# 解決
macOSには予めperlは入っているので、パスを通してから、再度GitHubからインストールしたら、成功した。

■　nodebrewのパスをシェルに設定するコマンド
```
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

### ※「パスを通す」とは
ターミナルに対して、インストールしたもの（今回はnodebrew）のファイルの位置を教えて、”今後nodebrewコマンドが実行されたら、この位置のこのファイルを実行してね”と指示するもの。