OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】Rails6 + docker メール設定エラー 「Errno::EADDRNOTAVAIL (Cannot assign requested address - connect(2) for "localhost" port 1025)」

## 概要
Rails6とdocker環境でメール設定をした際に発生したエラーの備忘録です。

### 環境
- ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux]
- Rails 6.1.6
```docker-compose.yml
# 中略
  mailcatcher:
    image: schickling/mailcatcher
    ports:
      - 1080:1080     
      - 1025:1025
```

## エラー発生時のメール設定
```development.rb
 config.action_mailer.delivery_method = :smtp
 config.action_mailer.smtp_settings = { address: 'localhost', port: 1025 }
 config.action_mailer.raise_delivery_errors = true
```

### エラー内容
- Railsサーバ側 (localhost:3000) の結果
> Errno::EADDRNOTAVAIL
> Cannot assign requested address - connect(2) for "localhost" port 1025

![railstask2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1976485/199155c0-9bd9-cce4-69a0-a12dd975c992.png)

- メールサーバ側 (localhost:1080) の結果
![railstask3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1976485/3e7ab823-d47d-953d-7751-24fdc49225d6.png)

コンテナのログを確認してみると、メール送信まではできているよう。。
しかし、Internal Server Errorにより、メールはサーバまで到達できておらず。
```
web_1          | TaskMailer#creation_email: processed outbound mail in 51.4ms
web_1          | Delivered mail 62c96fb5de0b4_1530c5853b@c88a1a8f7fc3.mail (20.5ms)
web_1          | Date: Sat, 09 Jul 2022 12:08:21 +0000
web_1          | From: test@example.com
web_1          | To: user@example.com
web_1          | Message-ID: <62c96fb5de0b4_1530c5853b@c88a1a8f7fc3.mail>
〜〜〜中略〜〜〜
web_1          | Completed 500 Internal Server Error in 221ms (ActiveRecord: 8.1ms | Allocations: 56411) 
web_1          | Errno::EADDRNOTAVAIL (Cannot assign requested address - connect(2) for "localhost" port 1025):
``` 

## 原因
- smtpメールサーバのアドレス設定が間違っていた。
- Railsのwebサーバコンテナもローカルホストなので、メールサーバのサービス名(コンテナ名)を指定する必要があった。

## 解決方法
- メール設定を下記に修正。
```diff_ruby
 config.action_mailer.delivery_method = :smtp
+ config.action_mailer.smtp_settings = { address: 'mailcatcher', port: 1025 }
 config.action_mailer.raise_delivery_errors = true
```
再度メールを送信してみると、MailCatcherで受信確認できた。
![railstask4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1976485/a567d4e7-1207-71e1-b166-22490adc081a.png)

```
web_1          | TaskMailer#creation_email: processed outbound mail in 58.5ms
mailcatcher_1  | ==> SMTP: Received message from '<test@example.com>' (1240 bytes)
```

## 参考
https://railsguides.jp/configuring.html#config-action-mailer-smtp-settings

https://teratail.com/questions/274621
【VS Code】ユーザースニペットの有効範囲の指定方法まとめ

# TL;DR

* グローバルスニペットの場合は、
`C:\Users\USER\AppData\Roaming\Code\User\snippets`
に`（任意の名前）.code-snippets`を作成する。
* ワークスペースフォルダスニペットの場合は、
`${workspaceFolder}\.vscode\`
に`（任意の名前）.code-snippets`を作成する。

* 特定の言語のみで有効にしたい場合は、
`"scope": "任意の言語の名前"`
をプロパティに設定する（例：`"scope": "python"`）。
* 全ての言語で有効にしたい場合は`"scope"`プロパティを省略する。

# はじめに

ユーザースニペットには有効範囲として、

* ワークスペースのみかVSCode全体か
* 特定の言語のみか言語指定なしか

の2個の観点から合わせて4通りの指定方法があります。

「ワークスペースのこの言語だけに適用したいけどどうすればいいの？」
と言った感じになったので、この機会にまとめてみようと思います。

# グローバルスニペット

グローバルスニペットは、VSCode内の全体で有効になるスニペットです。

下記の手順：

1. F1キーでコマンドパレットを開き『Configure User Snippets』を選択する
1. 候補の中から『New Global Snippets file...』を選択する
1. ユーザースニペットのファイル名を入力する（今回は`foo`を入力しました）

を実行すると、`foo.code-snippetes`という名前のJSONファイルが生成されます。
Windows版だと、
`C:\Users\USER\AppData\Roaming\Code\User\snippets`
こちらのフォルダ配下にあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091433/d6c2d619-43ac-f9c3-04d2-50d9470a8fd3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091433/3af03040-ddf9-b274-5039-85ea0ee7b143.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091433/89c9ac32-9f2b-c81d-10fc-561967c0da51.png)

スニペット内は、以下のような感じで書きます。

```jsonc:foo.code-snippets
{
    "MainFunction": {
        "scope": "python",  // これを省略すると全ての言語で有効になる
        "prefix": "fmain",
        "body": [
            "def main() -> None:",
            "    $0",
            "",
            "",
            "if __name__ == \"__main__\":",
            "    main()",
            ""
        ],
        "description": "Template of main() function"
    }
}
```

ここで注目するのが`"scope"`です。
この`"scope"`キーで、このスニペットを有効にする範囲を設定できますが、この`"scope"`キーは省略が可能です。
なので、すべての言語で有効にしたいときは、このキーを無くすだけでOKですね。

# ワークスペースフォルダスニペット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1091433/21e2b003-e8a0-3d2a-8c2a-c5fd4d204d1d.png)

グローバルスニペットと同じ要領で、今回は『New Snippets file for (ワークフォルダ名)』を選択します。
名前を入力すると、`${workspaceFolder}\.vscode\`内にスニペットファイルが生成されます。

スニペットファイルの書き方は、グローバルスニペットと全く同じなので省略します。

# おわりに

言語指定のグローバルスニペットに関しては、`python.json`みたいなファイルを作成することでも可能ですが、今回はなるべく作り方を共通化したかったので省略しました。
（ちなみに、`python.json`で作成すると、デフォルトで`"scope": "python"`が付く感じです）

書き始めて見たら全然まとまりませんでしたが、参考になれば幸いです。

# 参考

https://code.visualstudio.com/docs/editor/userdefinedsnippets
【#24 エンジニア転職学習】DB入門　MySQLサーバ起動時のエラー

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

DBの入門をざっくり学習していきます。
本日2回目の投稿になります。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日はMySQLの環境構築からRDBの階層構造、基本的な操作コマンドを学習しました。その中でMySQLサーバの起動・切断に色々と問題が発生してかなり手間取ったので、その対処法についてお話します。

* **MySQL環境構築　←Topics!!**
* 管理コマンド
* RDBの階層
* SQLの基本文（select, update, delete, insert）

# MySQL環境構築
自分のローカル環境について
* DBMS：MySQL8.0
* CLI：PowerShell 7.2.5
* OS：Windows11
* CPU：AMD Ryzen 7 5700U
* メモリ：16GB
* SSD：500GB
MySQL公式からWindows版をDLして、本格的に触ろうかという時に下記2点問題が発生しました。とりあえず問題なく使用できるようにはしたのですが、もっと良い根本的な解決方法があるかもしれません。
1. MySQL Workbenchでサーバの切断ができない
    * 「SeverStart / Stop」を押すとWorkbenchが固まってしまう
1. powershellからサーバの起動ができない
    * `mysql -u root -p`をすると`ERROR 2003 (HY000)`メッセージが出てくる


#### 解決策
1. Powershellで`mysqladmin shutdown -u root -p`コマンドを実施
1. コントロールパネルの**WindowsService**から**MySQL80を選択、サービス開始**を押す


使用している教材はこちら↓


https://www.amazon.co.jp/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E5%AD%A6%E3%81%B9%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E3%83%9F%E3%83%83%E3%82%AF-ebook/dp/B00TTRZFDC/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1657112653&sr=8-1


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
git init する際に hint が大量に出てしまう

## 概要
`git init` する際に大量に hint が表示されてしまう。

```sh
$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
``` 

## 対処法
hint に書いてあるとおりにコマンドを叩きます

```sh
$ git config --global init.defaultBranch main
```

これでOKです。
デフォルトブランチを設定してあげました。
以上です。
ubuntu Apacheのインストール

https://qiita.com/sakkuntyo/items/03742bad0f57a4f46b07

上記の記事を参考に
初期ページを表示するまでの手順を実施

ポート解放とApacheのインストール、起動

```
# rootユーザとしてログインしておくかsudo su -

# パッケージのアップデート
$ apt update

# ufw(ファイアウォール)をインストール
$ apt install ufw

# インストール直後はufwはファイアウォールとして指定されないためufwを有効化
$ ufw enable

# 「このコマンドを実行するとssh接続が切れるかも知れませんがいいですか？」と聞かれるので y を入力してEnter

# sshのポートを開く
# これを行わないとssh切断したあと接続出来なくなってしまいます！
$ ufw allow 22

# Apacheが使用するポートを開く
$ ufw allow 80

# Apacheをインストールする
$ apt install apache2

# Apacheが稼働している事を確認する
$ curl localhost && echo success || echo failed
```

これにてApacheのインストールは完了です！！！
それでは以下の記事を参考に実際に動いているかの確認をしましょう！！！！

https://qiita.com/m-m-mame/items/a8ca30058e7a2a9a24f1

```
$ sudo systemctl status apache2
```

このコマンドを動かして写真の赤で囲った部分が「active」になっていたら
Apacheが実行中ってことです

この状態でならブラウザ上でApacheの動作を見ることができるので

まず自分のローカルIPアドレスを調べます。

```
#IPアドレスを確認する
hostname -I
```

ここで確認したIPアドレスをそのままブラウザに打ち込んでください。

するとApacheのメニュー画面的なのが出てきます。
これがApacheの初期画面で、インストールはここで終了です。

TCP/IP についてイメージしながら実施するとわかりやすいです

https://www.n-study.com/tcp-ip/conclusion-of-webaccess/

https://qiita.com/TaichiEndoh/items/b4b38c30fa23c947e1bc


Apacheの停止などは以下を参照

https://deep-blog.jp/engineer/12304/

AWS EC2 でも Apache は必須です！

https://gb-j.com/column/ubuntu-flask/
オブザーバービリティ とは

## 勉強前イメージ

聞いたことあるけどよくわからん

## 調査

### オブザーバービリティ とは

英語でObservabilityと書き、Observe(観察する) + ability(能力)を組み合わせて観察する能力=可観測性と言われています。
複雑になシステムの全体像を把握する取り組みで、それが可能な状態を表します。
いつどの部分で何が発生しているのかを観察可能にする考え方になります。
確認が可能になることで問題発生時に素早く対応することができます。
近年クラウドサービスの導入が進んで、サーバレスやコンテナでの利用が進んでいます。
これらの利用でどこで何が起こっているのかを突き止めるのは簡単なことではないです。

### モニタリングとの違いは？

どこで何が起こっているのかについては、モニタリングも似たようなことを行っています。
継続的に情報を取得しています。

モニタリングとオブザーバービリティとの違いは以下です。

- モニタリング : ビジネス寄りで、ボトルネックなどが発生した場合原因を明確にする機能
- オブザーバービリティ : 技術寄りで、発生したし事象から原因を把握するためのデータ

## 勉強後イメージ

オブザーバービリティではいろんなデータを取得する必要があるってことかな？
特にサーバレスとかなら取れるデータも限られてくるやろし・・・・

## 参考

- [オブザーバビリティとモニタリング](https://www.appdynamics.com/ja_jp/topics/observability-vs-monitoring#~3-benefits-of-observability)
ほんの一瞬だけ使えたら満足なんです。一瞬だけクレデンシャルを拝借させていただけませんでしょうか

もっとスマートな方法がありました。こちらをご参照ください。

https://qiita.com/moritalous/items/badbf01f5e18652b433d

---

そういったときのワンライナー
CloudShellのクレデンシャルを拝借します。

```shell:CloudShell
curl -s -H "X-aws-ec2-metadata-token: $AWS_CONTAINER_AUTHORIZATION_TOKEN" $AWS_CONTAINER_CREDENTIALS_FULL_URI \
    | jq -r "[\"export AWS_ACCESS_KEY_ID=\" + .AccessKeyId, \"export AWS_SECRET_ACCESS_KEY=\" + .SecretAccessKey,\"export AWS_SESSION_TOKEN=\" + .Token] | .[]"
```

出力

```
export AWS_ACCESS_KEY_ID=ASI.....
export AWS_SECRET_ACCESS_KEY=cs5.....
export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2VjEN3//////////.....
```

これを使いたい環境コピーしたらOK。

# 参考サイト

これらを組み合わせただけです。いつもお世話になっております。m(_ _)m

https://dev.classmethod.jp/articles/aws-cloudshell-environment-separation-criteria/

https://tech.nri-net.com/entry/sts-temp-credential
普通のHTMLをSCSSでサクッと装飾してホットリロードもしたい

いろんな人が作ってくれたすごいものに頼り切って生きている気がします。
本日は、普通のHTML, CSS, できればSCSSもホットリロードしたい！という時に役に立つ、
すごいものの組み合わせをご紹介します！

# HTMLとCSS(とJavascript)で書いた簡単なページをホットリロードしたい

https://www.npmjs.com/package/reload

これがすごく便利です。

https://qiita.com/jesuissuyaa/items/90798223541c2d152a13

私はこの記事を見てインストールしました。
一応ざっくり説明しておくと、node, npmが使える環境で

```
npm install [-g] [--save-dev] reload
```

でインストールできます。特にこだわりが無ければ`-g`つけてグローバルインストールして良いと思います。
あとは、ホットリロードしたいindex.htmlのあるディレクトリで

```
reload -b
```

すれば完了です。
ちゃんとした使い方は

https://github.com/alallier/reload

ここにあって、たとえば`-b`オプションはブラウザを開くためのオプションであることとかも書いてます。
今回の使い方は「Using reload as a command line application」のところに載っています。

# SCSSを楽にトランスパイルしたい

HTMLとCSSだけ、みたいな簡素な構成なんだけどSCSS使いたくて、お手軽にCSSにトランスパイルしたいとき、

https://marketplace.visualstudio.com/items?itemName=glenn2223.live-sass

Live Sass Compilerを使うと便利です(Visual Studio Codeを使っている場合)。
Sassという名前ですがSCSSでも大丈夫です。
ちなみに昔から使ってるよ！という方、[昔からあった方](https://marketplace.visualstudio.com/items?itemName=ritwickdey.live-sass)はdeprecatedらしいので、確認してみてください。

こちらはVSCodeの左の方にあるExtensionsから検索して追加することができます。
検索すると、先述したdeprecatedの方が出てきたりするので注意です！

追加したら、SCSSファイルを開くと下に`Watch Sass`というボタンが出てくるので、これを押すとファイルの監視が開始されます。
あとはSCSSファイルを書き換えて保存するたび、自動的にCSSに変換してくれます！

# Live Sass CompilerでつくったCSS、reloadでホットリロードされない

本日のメインディッシュです。
実は、上記の2つを組み合わせて開発をした場合、SCSSを上書き保存してもホットリロードが走りません。
原因は、reloadの監視対象が `html,css,js` のみだからです。
この問題を解決するには、ホットリロードを開始するときのコマンドを以下のように変更します。

```
reload -b -e "html,css,scss,js"
```

ポイントは、`html,...`を "" (ダブルクォーテーション)で囲むことです。
囲まないと動かないので注意してください。
コマンドラインを使い慣れているひとなら当たり前なのかもしれませんが、自分はちょっとひっかかったのでメモでした。

`-e`以外のオプションについても、[reloadのREADME](https://github.com/alallier/reload)に詳しく載っているので、
確認するともっと便利に使えるかもしれません！

CSSアニメーションの練習したいときとか、ちょっと簡単にホットリロードでSCSS書ける環境があると良いですよね。
どなたかのお役に立てると嬉しいです。
[Lambda]s3.putObjectが初回実行時に完了しない時の対処法

AWS SDK for JavaScriptのs3.putObjectが、1回目は通らないのに2回目は通るという事態が起きました。
結論から言うと、promiseを返していなかったことが原因でした。

だめだったコード
```
s3.putobject({
    Body: {body},
}, function(err, data) {


```
ライナあれぐれっしょん！　豪ドルでやろかっと

https://jp.investing.com/currencies/aud-jpy-historical-data
ここで20年分のデータを取得

日付を指定して、１９７1〜2022年の週ごとのデータ

![スクリーンショット 2022-07-08 17.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380580/88d9552d-4660-bc86-147f-8f0bef50f62a.png)

を取得した！！

あ　次は　jupyter labの操作~?

```
from sklearn import linear_model #AI線形モデル
from sklearn.linear_model import LinearRegression #上のやつとどう違うのかわからんなんかエラーが出たので読み込みました
import numpy as np #なんだっけこれ
import pandas as pd #笹

from sklearn.model_selection import train_test_split #分けるやつ
from sklearn.metrics import mean_squared_error #性能評価の

import matplotlib.pyplot as plt #グラフのやつ
```
```
#csvの読み込み！
go_data = pd.read_csv("AUD_JPY 過去データ.csv")
go_data.head()
```
![スクリーンショット 2022-07-09 20.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380580/ba0c4e2b-b217-952d-f5b0-b55d950769be.png)

```
#行を逆に　古いものを上に
go_data = go_data.iloc[::-1]
go_data.index = range(len(go_data))
go_data.head()
```
![スクリーンショット 2022-07-09 20.35.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380580/d1befb66-ae5d-3e4a-6c61-5135ee156600.png)


```
#columnがjapaneseなのでとりあえず適当に
go_data = go_data.rename(columns={'日付け': 'day','終値': 'end','始値':'start','高値':'high','安値':'a','変化率 %':'b'})
go_data.head()
```
![スクリーンショット 2022-07-09 20.35.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380580/30b63bdb-6830-3c38-100f-196018e7e328.png)


本当は日付を使いたかったけど年月日表記だったので、、
```
# Noというcolumnを作成
serial_num = pd.RangeIndex(start=1, stop=len(go_data.index) + 1, step=1)
go_data['No'] = serial_num
go_data.tail() #末尾から確認
```
![スクリーンショット 2022-07-09 20.36.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380580/43bf51e9-ea3b-8da9-eadb-4778324bd9ca.png)


```
#終値をX NoをY
X = go_data.loc[:, ['end']]
Y = go_data.loc[:, ['No']]
```

```
２次元？変換しました
X=np.array(X)
Y=np.array(Y)
```
![スクリーンショット 2022-07-09 20.37.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380580/10b7d7a1-5609-08a9-a8ea-2695e57cd8ba.png)


```
#train,test,validに分ける~
X_train, X_test, Y_train, Y_test = train_test_split(X, Y,train_size=0.8)
X_train, X_valid, Y_train, Y_valid = train_test_split(X_train, Y_train, train_size=0.8)
```
```
# 線形回帰モデル
linear_model = LinearRegression()
# 学習はfit
linear_model.fit(X_train, Y_train)
```
```
予測
Y_pred = linear_model.predict(X_valid)
```

```
print('正解')
print(Y_valid[:5]) #正解
print()
print('予測')
print(Y_pred[:5]) #予測

#正解
#[[1959]
# [ 603]
# [1576]
# [ 215]
# [1430]]
#
#予測
#[[1629.88111471]
# [ 704.46442219]
# [1842.63881907]
# [ -89.27869522]
# [1710.26016458]]

```
うーん、うーん　うーん？？？うーん？？？？？？
ん　-89....? 貴様は一体何を予測したのか？

初めて自分でやってみたけどあわよくばこれでFXで大儲けしてやろうと思った！が！
ここまでやるので疲れた、
わからないことをたくさん調べて２日間かかったがなかなか楽しかったですね！！本当にほとんどがDataFrameの加工でした

___誰かこの記事を見かけた方、データの加工方法、記事の書き方なんでも良いです、アドバイスください。希望
間違ったりしているところは指摘が欲しいです。___


これを後　もっと未来のやつ予測して、日本のやつも予測して
グラフ化して　FXで大儲けする予定です、あ,もう大富豪になる事は
すぐそこですね！！実行


```
linear_model_mse = mean_squared_error(Y_valid, Y_pred)
print('MSE(1変数の線形回帰モデル):', linear_model_mse)
```
#MSE(1変数の線形回帰モデル): 213280.85603394746


誤差213280だってよ。
ははあ　なるほどお、　わからんわ謎

読んでくれてありがとうさぎ
お尻
GitHub Actions を使ってみた

# GitHub Actions ？
https://github.co.jp/features/actions
> GitHub Actionsを使用すると、ワールドクラスのCI / CDですべてのソフトウェアワークフローを簡単に自動化できます。 
>GitHubから直接コードをビルド、テスト、デプロイでき、コードレビュー、ブランチ管理、問題のトリアージを希望どおりに機能させます。
## 料金
- Free の場合 
    - Private リポジトリ `利用時間2,000分/月`
    - Public &nbsp;リポジトリ `無料`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733843/97ca5009-3647-b183-a763-5e940eff692d.png" width="700px">  

# 使ってみる  
<p>今回は リポジトリを作成して、master のリモートブランチにプッシュしたら、job が走って、Hellow World! がプリントされる簡単な動作を使ってみます。  

- GitHub でリポジトリを作成
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733843/2a806dd4-1a35-9977-94a6-4f81bc53cd7d.png" width="500px">  

- `git clone` する
```yaml
git clone https://github.com/<リポジトリ>
```
- `.github/workflows` 配下に `yml` ファイルを作る
```bash
cd <clone したディレクトリ>
mkdir -p .github/workflows && cd $_
touch sample.yml
```
- `sample.yml` 編集
```bash
name: actions smple

on:
  push: # git push されたら実行される
    branches:
      - master # 対象ブランチ
    workflow_dispatch:

jobs:
  hello-world: # job の名前
    runs-on: ubuntu-latest # 実行される環境
    steps:
      - name: echo sample
        run: echo "Hello World!" # 実行されるコマンド
```
- リモートブランチへpush
push 後、sample.yml ファイルの run のコマンドが自動で実行されました
![スクリーンショット 2022-07-09 19.39.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733843/0f964d2e-6245-715b-d61f-1979306f3813.png)
![スクリーンショット 2022-07-09 19.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733843/d53902ef-ebf7-3ec4-58a9-1c5a447214da.png)
# 最後に
<p>GitHub アカウントがあれば、すぐに GitHub Actions を使う事ができます。  
<p>次回は、push されたら自動テストなどを実行してみようと思います。
Docker Private Registryのリポジトリを削除


# 目的
Docker Private Registryへテスト用にimageをpushしたが、テスト用に入れたものなので削除したくなった．具体的にはgroup00リポジトリを削除する．

# 環境
- Ubuntu 20.04.4 LTS
    - K3sを実行しているVM 1台
        - アドレス：sre000t.local
- K3s v1.23.8+k3s1
    - コンテナ内でDocker Private Registryを動作させる

# 実行するコマンドと実行結果
## 1. Docker Private Registryの中身を確認する
まず，リポジトリの中身を確かめる．
`sre000t.local`はDocker Private Registryの場所に応じて変えること．
```shell
curl http://sre000t.local:5000/v2/_catalog
```
実行結果
`group00/test/test-image`が入っていることがわかる．
```shell-session
{"repositories":["group00/test/test-image"]}
```

## 2. Docker Private Registryの場所を確かめる
Docker Private RegistryのあるPodを確認する．
```shell-session
kubectl get pods
```
実行結果
```shell-session
NAME                               READY   STATUS    RESTARTS   AGE
docker-registry-7995b7874c-5c674   1/1     Running   0          8m25s
```

Docker Private RegistryのPod内部に入る．
```shell-session
kubectl exec -it docker-registry-7995b7874c-5c674 -- sh
```
実行結果
```shell-session
/ #
```
Docker Private RegistryのPod内でリポジトリの場所をlsコマンドで確認する．
```shell-session
ls /var/lib/registry/docker/registry/v2/repositories
```
実行結果
```shell-session
group00
```
## 3. リポジトリを削除する
group00が消したいリポジトリなのでgroup00を削除．
```shell
rm -r /var/lib/registry/docker/registry/v2/repositories/group00/
```

group00が消えたかどうか確認する．
```shell
ls /var/lib/registry/docker/registry/v2/repositories
```

Podから抜ける．
```shell
exit
```
## 4. リポジトリが消えたかどうかを確認する
Docker Private Registryの中身を確認する．
```shell
curl http://sre000t.local:5000/v2/_catalog
```
実行結果
```shell-session
{"repositories":[]}
```

# 参考文献

- [Docker Private Registryのtagとrepositoryを削除する方法 - Qiita
](https://qiita.com/rururu_kenken/items/9d0b98fed85fc07d0f6b)
M1 MacにAnacondaをインストールする

機械学習を行う上で、必要なライブラリ（主にTensorflow）がM1 Macに対応しないというケースが生じたので、これを機にAnacondaをインストールして仮想環境を作ろうと考えました。

ありきたりな記事にはなりますが、備忘録も兼ねて書いていきます。

# 環境

OS：macOS Monterary 12.4
シェル：zsh

# Anacondaのスクリプトをダウンロード

https://www.anaconda.com/products/distribution から「64-Bit (M1) Command Line Installer (305 MB)」をダウンロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/e768eb19-7e1d-7508-3cc0-ff7a509dbba0.png)

# スクリプトの実行

ターミナルで以下のコマンドを実行

```
$ bash ~/Downloads/Anaconda3-2022.05-MacOSX-arm64.sh
```

対話形式でインストールが進み、途中止まったらEnterキーを押して進め、「yes/no」を要求してきたら基本yesで良いです。

# 環境変数

以下のパスを``.zshrc``に登録

```
export PATH=~/anaconda3/bin:$PATH
```

bashを使っているのであれば``.bashrc``に登録

# 初期状態のアップデート

```
conda update -n base -c defaults conda
```

# 仮想環境作成

```
conda create -n 環境名 python=3.8
```

## Activate

```
conda activate 環境名
```

ここで仮想環境に入れないときは以下の記事で解決

https://japan-challenge.net/conda-activate%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92conda-init%E3%81%A7%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B/

以上

# おまけ：Tensorflowのインストール

M1 Macの場合Tensorflowのインストールに手こずったので、以下のコマンドを実行することでTensorflowのインストールが可能

```
pip install --upgrade --force --no-dependencies https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha3/tensorflow_addons_macos-0.1a3-cp38-cp38-macosx_11_0_arm64.whl https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha3/tensorflow_macos-0.1a3-cp38-cp38-macosx_11_0_arm64.whl
```

ただし、``--no-dependencies``オプションを付けているので依存関係のあるライブラリ等はインストールされていません

なので、実行しながら必要なライブラリ等を導入しましょう

# 参考文献

https://moromisenpy.com/m1-mac-anaconda/

https://qiita.com/yamagarsan/items/d9864fd01f3f4cca2938

https://qiita.com/ten-hope/items/ffa207e3b63e51c655e1
デザインパターン

## オブジェクト指向のデザインパターン

- シングルトン
値の受け渡しがなく、同じ情報が取得できる
全プログラム内で同期がとれた共有オブジェクト

- ファサード
窓口を設けるため、疎結合になり、呼び出し側に制御をかかないので
バグが減る

- ファクトリー
ファクトリークラスがオブジェクトの生成処理と、
生成するオブジェクトの種類の変更を動的に行う
SQL データベース構造の操作

#### データベースの追加

* 構文

```
create datebase データベース名;
```

#### データベースオブジェクトに使って良い文字

* 半角のアルファベット・・・ a,b,c
* 半角の数字・・・0,1,2・・・
* アンダースコア・・・_ 

* ただし、名前の最初は半角のアルファベットとする。

#### テーブル構造の変更

* 構文
```
alter table テーブル名 change 旧列名 新列名 データ型;
```

#### 列名の削除

* 構文
```
alter table テーブル名 drop 列名;
```

#### テーブルの削除

* 構文

```
drop table テーブル名;
```

#### データベースの削除

* 構文

```
drop database テーブルベース名;
```

#### 操作の注意点

※注意事項:alter table, drop table, drop database等

* 操作は基本的に取り消せない
  * 特に、実務において本番環境を操作する時は、サービスをメンテナンスモード
    にして、バックアップをとってから、alter table等を実行するのが安全

* 想定外に時間が掛かりシステムトラブルになる場合も
  * テスト環境でalter tableのテストをして問題点を洗い出してから、本番環境で
    実行するのがおすすめ。
Pythonプログラムが動くRaspberry piOS上にSSHでVsCodeを接続してみた

# Raspberry Piのシェルで、Pythonのデバッグのとかしたいよね。だからVSCodeでSSHで接続した。

Windows上で開発していたDjangoプロジェクトをSambaを使ってファイル共有して作成していたのですが、Windows上では動くが、Raspberry Pi OS上では一部のコードが、OSの仕様で動かないという小さい不具合が起きたので、直接Raspberry Pi OSのシェルで動かそうとやってみたわけです。

## 手順通りやったのに動かない。原因はSSH秘密鍵のセキュリティ権限設定
SSHでの接続は下記の記事が非常にわかりやすかったです。

https://qiita.com/nlog2n2/items/1d1358f6913249f3e186

ただ、VSCodeのSSH接続の仕様変更があったのか、上記の設定だけでは、下記のようなエラーが出て動かない

![WS000020.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/c6737e82-0b45-6dec-7726-4bf2b720a791.jpeg)
![WS000017.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/1e7b2292-76cf-f581-ed2d-be268bb35fdd.jpeg)
> Load key "C:\\Users\\****\\id_rsa": bad permissions
> pi@192.168.***.***: Permission denied (publickey).
> プロセスが、存在しないパイプに書き込もうとしました。

このエラーは、秘密鍵のクライアント側のセキュリティ権限が複数ユーザーに割り当てられていると動かないという仕様変更があったのか、秘密鍵をConfigファイルで指定した場所に置くだけでは動かない用になっていたのが原因でした。

## 実際どうやるの？
SSHの秘密鍵の権限設定は、秘密鍵のファイルの上で右クリックして出てくる、プロパティ
![WS000006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/5ff41493-75e5-c617-e163-9c9c6f3e8a95.jpeg)

セキュリティ設定（ここのオブジェクト名の欄に複数のユーザー設定があると動かない）
![WS000007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/d004b603-83c1-2235-b99e-34134c643e15.jpeg)
詳細設定
![WS000008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/121843a4-090c-7aa3-d2bb-9badc430dd82.jpeg)
継承の無効化
![WS000009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/3b9132cd-33cf-4e0f-1923-5f1fcdbfbedd.jpeg)

継承されたアクセ許可をこのオブジェクトの明示的なアクセス許可に変換します
![WS000010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/8812167d-d3e7-fce3-f4e1-4d1e54533f03.jpeg)

使っているWindowsのユーザー、プリンシパルのみ残し、適用してOKで終了です
![WS000011.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271862/9f277651-f409-3410-d016-e861a7e87d8d.jpeg)

この設定にたどり着くのに小一時間かかりました。疲れたなぁ～。
プロダクトマネジメントに関する記事リスト

• [グロースハンドブック](https://pmlibraries.com/2022/04/02/%e3%82%b0%e3%83%ad%e3%83%bc%e3%82%b9%e3%83%8f%e3%83%b3%e3%83%89%e3%83%96%e3%83%83%e3%82%af/)

• [プロダクトマネジメントのブラックボックス](https://pmlibraries.com/2022/05/15/%e3%83%97%e3%83%ad%e3%83%80%e3%82%af%e3%83%88%e3%83%9e%e3%83%8d%e3%82%b8%e3%83%a1%e3%83%b3%e3%83%88%e3%81%ae%e3%83%96%e3%83%a9%e3%83%83%e3%82%af%e3%83%9c%e3%83%83%e3%82%af%e3%82%b9/)

• [プロダクトとは何か？](https://pmlibraries.com/2022/06/01/%e3%83%97%e3%83%ad%e3%83%80%e3%82%af%e3%83%88%e3%81%a8%e3%81%af%e4%bd%95%e3%81%8b%ef%bc%9f/)

• [プロダクト・マーケット・フィット ガイドライン](https://pmlibraries.com/2022/06/09/%e3%83%97%e3%83%ad%e3%83%80%e3%82%af%e3%83%88%e3%83%bb%e3%83%9e%e3%83%bc%e3%82%b1%e3%83%83%e3%83%88%e3%83%bb%e3%83%95%e3%82%a3%e3%83%83%e3%83%88-%e3%82%ac%e3%82%a4%e3%83%89%e3%83%a9%e3%82%a4%e3%83%b3/)

• [プロダクトの機会を評価する](https://pmlibraries.com/2022/06/11/%e3%83%97%e3%83%ad%e3%83%80%e3%82%af%e3%83%88%e3%81%ae%e6%a9%9f%e4%bc%9a%e3%82%92%e8%a9%95%e4%be%a1%e3%81%99%e3%82%8b/)

• [プロダクトの出荷の時間価値](https://pmlibraries.com/2022/06/28/%e3%83%97%e3%83%ad%e3%83%80%e3%82%af%e3%83%88%e3%81%ae%e5%87%ba%e8%8d%b7%e3%81%ae%e6%99%82%e9%96%93%e4%be%a1%e5%80%a4/)

• [3つのペルソナ：マーケティング、プロダクト、アナリティクスはどのように顧客を定義しようとしているのか？](https://pmlibraries.com/2022/07/01/3%e3%81%a4%e3%81%ae%e3%83%9a%e3%83%ab%e3%82%bd%e3%83%8a%e3%83%9e%e3%83%bc%e3%82%b1%e3%83%86%e3%82%a3%e3%83%b3%e3%82%b0%e3%83%97%e3%83%ad%e3%83%80%e3%82%af%e3%83%88%e3%82%a2%e3%83%8a%e3%83%aa%e3%83%86/)
Hello Deno

最近、Denoの動向をzennやtwitterで目にする機会が増えてきた実感があって、
azukiazusaさんの [Deno の Web フレームワーク Fresh チュートリアル](https://zenn.dev/azukiazusa/articles/fresh-tutorial)　の記事や
日野澤歓也さん（@kt3k）の[Deno入門 ─ 新しいTypeScript/JavaScript実行環境でWebアプリ開発とデータベース接続の基本を体験しよう](https://eh-career.com/engineerhub/entry/2022/06/17/093000)　の記事の影響で、Denoに入門してみました。

#### Denoとは？
Node.jsの作者のライアン・ダールが、2018年に開発を開始したサーバサイドJSのランタイムで、2020年にv1.0がリリースされています。
現状、サーバサイドJSのランタイムとして、Node.jsがデファクトスタンダードとなっていますが、
Denoが生み出された理由は、ライアン・ダールが、いくつかNode.jsの設計に後悔している点があり、その後悔を克服する為に新しく立ち上げたプロジェクトになります。
現在は、Deno Land Inc.が設立され、以前よりも活発に開発されている状態になっています。 

#### Node.jsとの違いは？
Node.jsと大きく異なる点は、以下です。
- package.jsonやnode_modulesディレクトリがない
- npm, yarn等のパッケージ管理ツールがない
- API全体が、可能な限りWebブラウザと互換となる様に設計されている
- モジュールシステムが、CommonJSではなく、ES Modules仕様になっている
- TypeScriptがデフォルトでビルトインされている
- Eslint, Prettier, Jest相当のツールもデフォルトでビルトインされている
- ついでに、Tailwind CSSもデフォルトビルトインされている

#### package.json, node_modules, npm(yarn等) がない？ どういうこと？
Node.jsだと、npmやyarn等でモジュールをinstallして、package.jsonでバージョン管理をしたり、npm scriptsでタスクランナー的な利用をしたりといった事を行うのですが、
Denoだと、モジュールの扱いに関して、そういった思想ではなく、importの記述で、直接urlとバージョンを記述するといった形になっています。

↓こんな感じです。バージョンも直書きになっています。
```
import { serve } from 'https://deno.land/std@0.139.0/http/server.ts'
import { h, ssr } from 'https://crux.land/api/get/7GrKMy.ts'
```

そんなことしたら各ファイルにimport書くのめっちゃ面倒じゃん！と思ったのですが、一応公式には、
import mapsやdeps.tsというimportの記述をまとめ、インスタンスをexportする方法も紹介されており、この方式を利用するを利用すると、Node.jsをランタイムに利用している場合の開発体験とそこまで差分はなくなるのかなと思いました。

import maps
https://deno.land/manual/linking_to_external_code/import_maps

また、npm scriptsの様なタスクランナー的利用に関してですが、deno taskというデフォルトでビルトインされているタスクランナーがあり、deno.jsonというファイルを作成（結局作るんかい）して以下の様に記述し、`deno task [タスク名]` といったコマンドで運用することが可能です。

```
{
  "tasks": {
    "test": "RUST_BACKTRACE=1 deno test --allow-env --allow-read",
    "typecheck": "deno cache mod.ts"
  }
}
```

参考：　https://zenn.dev/uki00a/books/effective-deno/viewer/task-runner

個人的な所感ですが、importのURLを記述するのが面倒に感じており、
そこは、URLを意識せずとも npm install モジュール名 でモジュールインストールが可能なのが、Node.jsの良さなのでは？と思ってしまいます。
内部構造諸々を考慮した結果、import { ◯◯ } from 'https://◯◯' に落ち着いたんでしょうね。

#### TypeScript, ESLint, Prettier, Jestがデフォルトビルトインされている！
Node.jsで開発を行う場合、昨今のフロントエンド開発に必要なTypeScript, Eslint, Prettierがデフォルトではサポートされていないので、それぞれのツールをインストールし、設定ファイルを記述して初めて利用することが出来ますが、
Deno場合は、デフォルトで諸々のツールがビルトインされている為、上記の様なことが必要ありません。
Tailwind CSSもデフォルトでビルトインされている為、簡単にjsx書いてスタイルを適用したいみたいなこともすぐに実現可能です。

↓SSRして、Hello Worldを表示する記述
```
/** @jsx h */
import { serve } from 'https://deno.land/std@0.139.0/http/server.ts'
import { h, ssr } from 'https://crux.land/api/get/7GrKMy.ts'

const App = () => {
  return (
    <div class="px-8 py-4">
      <h1 class="font-semibold text-2xl">Hello Deno</h1>
      <p class="mt-2 text-gray-500">Welcome to example page!</p>
    </div>
  )
}

serve(() => ssr(() => <App />))
```

確かにここまでくると、Deno環境とこのファイルさえあれば、npm installせずとも実行可能なので良いと感じました。

今後は、Aleph.jsやFreshも調査出来たらと思います。

#### 参考記事
https://eh-career.com/engineerhub/entry/2022/06/17/093000
https://zenn.dev/uki00a/books/effective-deno/viewer/task-runner
2022年07月　ハッキング・ラボのつくりかた: 仮想環境におけるハッカー体験学習

# 環境構築(2022/07/09)
ハッキング・ラボのつくりかた: 仮想環境におけるハッカー体験学習
上記の本を参考にハッキングラボを体験することを目的とする
## VirtualBoxのインストール
https://www.oracle.com/jp/virtualization/technologies/vm/downloads/virtualbox-downloads.html

上記のサイトでvirtualboxと検索し、OSにあった環境を選択
筆者はWindowsインストーラを選択した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733953/b3ff7deb-1624-0214-2eb7-51bead5a27ea.png)
同ページを下にスクロールすると、拡張パッケージが存在するのでこちらもインストールしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733953/e119cb72-144e-e7c3-db0c-80f8a4d5c505.png)

２つのインストーラーを起動し、インストールを行う
同意を求められるが、すべて同意する
拡張パックがインストールできない場合はバージョンが異なるため、バージョンを合わせる必要がある
virtualboxが起動でき、拡張機能が以下の通りにできていれば完了

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733953/84fb0964-8dd6-60cd-4fb3-b3a1040889dc.png)

## Kali linux 導入
https://www.utorrent.com/intl/ja/downloads/win/

上記のサイトからuTorrentのインストールが本では推奨されているが面倒だったので飛ばした
（おそらくこちらでダウンロードすれば一瞬だったはずだが、、）

https://www.kali.org/get-kali/#kali-virtual-machines

kali linuxは上記のサイトでインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733953/ec57039c-8ea8-a57f-6259-f864da015813.png)
QiitaのContributionsを記録しておきたい

# 概要

Qiitaに色々書いていくにあたって、Contributionsの伸び率を日付単位で記録しておいてグラフ化することでモチベアップにつながればなぁ・・・
ということでGASを使用して日次でQiitaのマイページからContributionsを取得してスプレッドシートに書き込みしていく方法を記載します。

# 使用ツール

- GAS(Google Apps Script)
- Googleスプレッドシート

# 方法

GASにて以下ソースを記述し、時間主導型のトリガーで実行します。

:::note info
環境変数として

- `QIITA_USERNAME`: Qiitaのユーザ名
- `SPREAD_SHEET_ID`: スプレッドシートのID

を設定します。

![2022-07-09_18h51_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/40031371-736a-d7ba-f578-0f29bef988d4.png)
:::

:::note info
トリガーは自分の場合、日次で動かしたいので、こんな感じで。。。
時間単位にしたい方はお好みで(下記ソースコード内の`writeSpredSheet()`で日付の書き込みを行っている箇所を時間まで持たせる等必要ですが)
![2022-07-09_19h00_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/afc6b99a-7088-92b3-4c1c-ce9d9ea57a75.png)

:::

<details><summary>ソース</summary><div>

```js
function main() {
  // 環境変数の取得
  const properies = PropertiesService.getScriptProperties(); 
  const userName = properies.getProperty('QIITA_USERNAME');
  const spreadSheetID = properies.getProperty('SPREAD_SHEET_ID');
  
  const contributions = getQiitaContributions(userName);
  if (contributions === '') {
    return;
  }
  writeSpredSheet(spreadSheetID, contributions);
}

/**
 * QiitaマイページからContributionsを取得
 */
function getQiitaContributions(userName) {
  
  const res = UrlFetchApp.fetch('https://qiita.com/' + userName);
  
  if (res.getResponseCode() !== 200) {
    return '';
  }

  const content = res.getContentText();

  const reg = new RegExp('<a href="\/' + userName + '\/contributions".*>.*Contributions<\/span><\/a>')
  let contributes = content.match(reg)[0];
  contributes = contributes.replace(/<[^>]*>/g, '');
  contributes = contributes.replace('Contributions', '');

  return contributes;
}

// ↓新しいデータを先頭に加えるか、最終行に加えるかお好きな方を。。。

/**
 * スプレッドシートに書き込み(最終行に追加)
 */
// function writeSpredSheet(spreadSheetID, contributions) {
//  const ss = SpreadsheetApp.openById(spreadSheetID);
//  const sheet = ss.getActiveSheet();
//
//  const today = Utilities.formatDate(new Date(), "JST","yyyy/MM/dd");
//
//  sheet.appendRow([today, contributions])
//}


/**
 * スプレッドシートに書き込み(ヘッダの次の行に挿入)
 */
function writeSpredSheet(spreadSheetID, contributions) {
  const ss = SpreadsheetApp.openById(spreadSheetID);
  const sheet = ss.getActiveSheet(); 
  const today = Utilities.formatDate(new Date(), "JST","yyyy/MM/dd");

  sheet.insertRowBefore(2);
  const range = sheet.getRange('A2:B2');
  range.setValues([[today, contributions]]);

}

```
</div></details>



# おわりに

このツールが役立つように色々と記事を書いていかねば。。。


## 2022/08/22 追記

データさえ記録しておけばグラフにするとあとはグラフ化するだけで・・・
いい感じに伸びた記事があるので、伸び率が面白い感じになりました（＾ｕ＾）

![2022-08-22_14h08_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/40f673c2-a6cd-b07d-2cf9-871c963fe98f.png)

(ストックを後で読むリスト的に使用されている方も多いと思いますので、日次だと変動は無いですが、実際には増えて減った結果変動せず・・・という日もありました)
[LeetCode]コーディングテスト対策："a linear runtime complexity"と"use only constant extra space"の意味

コーディングテスト対策でLeetCodeの問題を初めて解いているのですが、問題文の英語表現に馴染みがなくそれなりに苦戦しています。

一度調べただけでは忘れてしまうので、備忘録として残しておきます。

## "You must implement a solution with a linear runtime complexity and use only constant extra space."
DeepL翻訳さん
「あなたは、線形実行時複雑さと一定の余分なスペースだけを使用するソリューションを実装する必要があります。」

なるほど、わけわからん。私は仕事で通訳をしていますが、自力で読んでも意味がわかりませんでした。これは、知識として知らなければ意味が理解できないパターンです。

（出典：LeetCodeの「Top Interview Questions」>「136. Single Number」）

#### "a linear runtime complexity"
コードを実行した際のの実行（計算）時間が、入力されたデータサイズに比例すること。

例えば、配列のループ処理等です。配列の要素が多ければ多いほど、ループを終了するのに時間がかかります。

アルゴリズムのO記法で書くと"O(n)"。

#### "use only constant extra space"
「入力データがどんなに多くても、計算は１回で済む様にしてね」

ということ。

アルゴリズムのO記法で書くと"O(1)"。

## 結論

"You must implement a solution with a linear runtime complexity and use only constant extra space."
→「データ量が増えた分だけ計算量が増えるO(n)対策を必ず行ってください。そしてそれは、データ量に関わらず計算が常に一回になるO(1)でなければなりません」



## 参考記事

https://note.com/strictlyes/n/n82d0a3874256

https://www.educative.io/courses/mastering-data-structures-and-sorting-algorithms-in-javascript/3j6xyKXNBqx
【VPN】まずは用語から理解したい！

# VPN接続の種類

主に以下4つの種類が存在する

- インターネットVPN
- エントリーVPN
- IP-VPN
- 広域イーサネット

詳しくは[こちら](https://www.qtpro.jp/blog/network/10.html)を参照

## IP-VPN
- 通信事業者の閉域網を利用してVPNを構築
    - 閉域網とは
        - 限られた利用者のみが利用可能な広域通信網
        - 物理的または論理的にインターネットに接続していないネットワーク（狭義）
    - どのように通信を行っているのか
        - 閉域網の中で仮想的な専用回線を構築している
- MPLS（Multi Protocol Label Switching）」と呼ばれる技術が利用されている

### MPLS

パケットに「ラベル」と呼ばれる2種類のヘッダ情報を付与する。

- ２つのラベルの役割
  - 転送経路を示す
  - ユーザーのネットワークを識別する



## インターネットVPN

- 主に以下２つの機能がある

  - トンネリング（Tunneling）
  - 通信パケットを暗号化する機能

### トンネリング
- 拠点間で通信するために仮想的な通信路を作ること
    - 目的：拠点と拠点の間にある外部のネットワークに影響を受けないように通信をする

### カプセリング
- パケットに新しいヘッダを付け加え、カプセル化（Encapsulation）して通信を行う
- IPsecのトンネルは、LAN内で通信するプライベートアドレスのパケットをインターネット上での通信で用いるグローバルアドレスのパケットでカプセル化することで実現する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524160/6d4142cd-2856-b546-fc97-15caf9787ad7.png)
引用元：[日経XTECH](https://xtech.nikkei.com/it/atcl/column/17/011900625/011900006/?SS=imgview&FD=1153259116)　トンネリングとカプセリングは何が違う？

### 通信パケットを暗号化する機能

- トンネリングされたパケットの盗聴や改ざんなどを防止するために、パケットを暗号化して伝送するための仕組みが必要

## 整理

このへんで用語がまざったな

|                   | 技術               | 通信方式 |
| ----------------- | ------------------ | -------- |
| IP-VPN            | ラベルスイッチング |          |
| インターネットVPN | トンネリング       | IPsec    |





## 参考

https://atmarkit.itmedia.co.jp/ait/articles/0204/27/news003_4.html

閉域網について

https://www.nttpc.co.jp/lp/vpn-collabo/column/base_02.html

トンネリングについて

https://ascii.jp/elem/000/000/458/458944/

https://xtech.nikkei.com/it/atcl/column/17/011900625/011900006/#:~:text=%E3%83%88%E3%83%B3%E3%83%8D%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%A8%E3%81%AF%E3%80%81%E6%8B%A0%E7%82%B9%E9%96%93,%E3%82%92%E6%8C%87%E3%81%99%E3%81%93%E3%81%A8%E3%81%8C%E5%A4%9A%E3%81%84%E3%80%82
expressのrouterをroute出来るの？？？

# 疑問
　expressのexpress-generatorというのはご存じでしょうか。
　そのexpress-generatorで出てくる雛形はexpressのお手本のようなプログラムをしており、そこからプログラムを書いていくと、なかなか綺麗にまとまったプログラムが出来上がります。
　そこで

```javascript
var express = require('express');
var indexRouter = require('./routes/index');
var app = express();

//これのこと
app.use('/index',indexRouter);
//これのこと
```

　という感じのメソッドが存在します。
　これのおかげでプログラムを小分けにしてURLのディレクトリ毎のプログラムを書くことが出来るのですが、中にはexample.com/usersではなく、example.com/users/tanakaみたいなディレクトリを小分けにしたいこともあるでしょう。
　細分化したURLに対応するすべてのroute関数を定義していくと、routesディレクトリ内のファイル数が大変なこといなります(一敗)。
　そこで、routeファイルの中でさらにapp.use('/index',indexRouter)のような関数を定義することは出来ないだろうかと考えて一年近く放置してた疑問を、ようやくやる気を出したので、解決したことを記事にします。

# 実験

```
余計なものは省いた今回のファイル構成です
　
├─app.js
└─ routes
   ├─ users.js
   └─ users
      ├─ tanaka.js
      └─ hanako.js
```

　app.jsはexpress-generatorで生成したままで大丈夫です。
　users.jsを以下の通りに変更。

```javascript:users.js
var express = require('express');
var router = express.Router();

var tanakaRouter = require('./users/tanaka');
var hanakoRouter = require('./users/hanako');

router.use('/tanaka', tanakaRouter);
router.use('/hanako', hanakoRouter);

module.exports = router;
```

　usersディレクトリを作成し、tanakaとhanakoを作成。

```javascript:tanaka.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with Tanaka');
});

module.exports = router;
```

```javascript:hanako.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with Hanako');
});

module.exports = router;
```

　これで起動してみると無事respond with Tanakaと返ってきます。
　つまり、出来るという結論です。

# 最後に
　ぶっちゃけ文章べたすぎますね。。。
　直せるように努力しましょう。
【PHP初級㉘】階乗

[問題]　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksPrimary.html)
整数値を入力させ、その値の階乗を表示するプログラムを作成しなさい。ただし、0以下の値を入力した場合は1と表示する。



# コード
```php
$a = intval(fgets(STDIN));
if($a > 0){
    echo array_product(range(1, $a));
}else{
    echo '1';
}
```

↓「5」と入力

# 結果
```
120
```

↓「-2」と入力

```
1
```

☆array_product()
・・・配列の値の積を計算する関数。
Oracle  SUBSTR・SUBSTRB関数で文字列を切り取る

今回はORACLEデータベースのSQLで、SUBSTR・SUBSTRB関数を使って文字列の一部を切り取る方法を紹介します。

# 文字数で切り取る(SUBSTR)
SUBSTR関数は、文字列を指定した開始位置から指定位置文字数分を切り出します。

SUBSTR関数の基本構文は以下の通りです。

```
SUBSTR(文字列,開始位置,切り取り文字数)
```
引数の文字列に対して、指定した開始位置から指定した文字数分の文字列を切り出します。
引数の切り取り文字数は省略可能で、その場合は開始位置から最後まで切り出します。
また、開始位置からの文字数が値の長さをオーバーしてもエラーにはならずにNULLを取得します。

## SUBSTR関数を使ったSQLのサンプル
ここからは実際にSUBSTR関数を使ったSQLのサンプルを紹介します。

次のSQLでは、文字列の値を先頭から1文字を切り取っています。

```
--先頭の文字から1文字取得する場合
SELECT SUBSTR(abcde,1,1) FROM DUAL;

[結果] 'a'
```

次のSQLでは、文字列の値を指定した3文字以降を全て切り取っています。

```
--文字列の指定桁(3)以降を取得する場合
SELECT SUBSTR(abcde,3) FROM DUAL;

[結果] 'cde'
```

SUBSTR関数では、文字列の後ろから指定した文字数分の文字列を抽出することが出来ます。
次のSQLでは、文字列の値を後ろから3文字目の値から最後尾の文字まで切り取っています。

```
--後ろから3番目の文字から最後尾の文字まで取得する場合
select SUBSTR(abcde,-3) FROM DUAL;

[結果] 'cde'
```

# バイト数で切り取る(SUBSTRB)
SUBSTRB関数は、文字列の指定桁数から指定バイトを切り取ります。
SUBSTRB関数の基本構文は以下の通りです。

```
SUBSTRB(文字列,  開始位置, バイト数)
```
使用方法はSUBSTR関数と同じです。

# SUBSTRB関数を使ったSQLのサンプル
SUBSTRB関数を使ったSQLのサンプルを紹介します。

```
--SUBSTRBで切り取る 
SELECT SUBSTRB('山田太郎',1,2) FROM DUAL;

[結果] '山'

SELECT SUBSTRB('12345',1,2) FROM DUAL;

[結果] '12'
```
「SUBSTRB(‘山田太郎’,1,2)」は全角「佐藤太郎」の1バイト目から2バイトを切り取ります。2バイトで切り取るので漢字では1文字が返されます。

「SUBSTRB(‘12345’,1,2)」は「12345」の1バイト目から2バイトを切り取ります。

## SUBSTRB関数で文字列を切り取りできないパターン
SUBSTRB関数で文字列を切り取りできないパターンについても紹介します。

```
--SUBSTRBで切り取りできない 
SELECT SUBSTRB('山田太郎',1,1) FROM DUAL;

[結果] ''
```
「SUBSTRB(‘山田太郎’,1,1)」は全角「山田太郎」の1バイト目から1バイトを切り取ります。
この場合、「山」から1バイト切り取ることはできないので結果は返されませんでした。

# まとめ
以上、Oracleで文字列で切り取るSUBSTR・SUBSTRB関数でした。
ChromeBookでpyenvを導入してみた

ChromeBookでpyhonを実行するためにpyenvを導入手順
※pyenvを導入する際に行ったメモになります


## ChromeBookのスペック
|  |  |
|:-:|:-:|
| 製品名  | ideapad Duet Chromebook  |
| CPU  |  MediaTek Helio P60T |
| メモリ  | 4GB  |

※Linuxを有効化してる前提です

# 【pyenvの導入】

**・pyenvのリポジトリをクローン**
```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

**・パスを通す**
```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init --path)"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

**・profileを読み込み**
```
source ~/.bash_profile
```

※以下のコマンドで中身を見る(適用されてるかの確認)
```
sudo vim ~/.bash_profile
```

**・インストール可能なバージョン一覧**
```
pyenv install --list
```
**・バージョンを指定してpythonをインストール**
```
pyenv install 3.9.2
```
## インストールでエラーが出た場合
**※インストール時に以下の警告が発生**
```
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
WARNING: The Python tkinter extension was not compiled and GUI subsystem has been detected. Missing the Tk toolkit?
WARNING: The Python lzma extension was not compiled. Missing the lzma lib?
```

**上記、警告の対処方法**
```
sudo apt-get install libbz2-dev
sudo apt-get install tk-dev
sudo apt-get install liblzma-dev
```
**インストールしたバージョンをアンインストール**
```
pyenv uninstall 3.9.2
```

**再度インストール**
```
pyenv install 3.9.2
```

## インストールでエラーがでなかった場合
**・インストール済み一覧**
```
pyenv versions
```

**・バージョンを切り替える**
```
pyenv global 3.9.2
```
クラス外からインスタンス変数を呼び出す際に簡単に使えるメソッド

Rubyのクラスメソッドに属性としてinitializeメソッドで定義したインスタンス変数の値を外部から呼び出す際に利用できるattr_readerメソッドの使い方について記述していきます。

例として各支店の店舗名と売上の入力している値を外部から呼び出し、売上の合計をクラスメソッドで呼び出し、出力する場合

メソッドで定義して呼び出す場合
```
class Shop
  @@total_sales = 0

  def self.salesAll
    @@total_sales
  end

  def initialize(shop_name,sales)
    @shop_name = shop_name
    @sales = sales
    @@total_sales += @sales
  end

  def shopName
    @shop_name
  end

  def sales
    @sales 
  end
end

shop1 = Shop.new("東京", 500000)
shop2 = Shop.new("大阪", 400000)
puts "#{shop1.shopName}の売上は#{shop1.sales}円で、#{shop2.shopName}の売上は#{shop2.sales}円です"
puts "全体の売上は#{Shop.salesAll}円です。"
```
インスタンス変数に入力した値はスコープによりクラス外から呼び出せないため、その値を呼び出すときにはインスタンスメソッドにて変数を呼び出すことで値を外部からでも取得できるが、個別に呼び出す際にはメソッドの記述が多くなってしまう。

そこで記述量を減らして同じことができるように
attr_readerというメソッドを使うと

```
class Shop
  @@total_sales = 0
  attr_reader :shop_name, :sales

  def self.salesAll
    @@total_sales
  end

  def initialize(shop_name,sales)
    @shop_name = shop_name
    @sales = sales
    @@total_sales += @sales
  end
end

shop1 = Shop.new("東京", 500000)
shop2 = Shop.new("大阪", 400000)
puts "#{shop1.shop_name}の売上は#{shop1.sales}円で、#{shop2.shop_name}の売上は#{shop2.sales}円です"
puts "全体の売上は#{Shop.salesAll}円です。"
```

:::info
attr_readerの後ろに:インスタンス変数名と記述すると
外部からインスタンス名.インスタンス変数の形で呼び出すことで
インスタンス変数情報を取得できる
:::
herokuとRDSを接続できないときの対処法

herokuとrds繋げるときに色々困ったので備忘録。
最終的な目標はherokuの環境変数であるDATABASE_URLを入力することです。

### RDS側のでやること

- RDSインスタンスのエンドポイントをメモっておく
- 「DBインスタンスの変更」→「接続」にて、セキュリティグループの確認。ここで設定をミスると全くRDSに接続できなくなる
- 「DBインスタンスの変更」→「接続」→「追加設定」にて、パブリックアクセスを許可するかどうかを確認


### herokuのDATABASE_URLの書き方(mysqlの場合)

- `mysql2://username:password@hostname/dbname`
- ここでのusernameとパスワードはmysql内のユーザとパスワードのこと。IAMユーザのことではないので注意
- hostnameはRDSインスタンスのエンドポイントを記入
- dbnameはmysqlに入って`show databases;`コマンドで確認可能
Octave で無相関検定

# Octave で無相関検定

二変数の母相関係数が 0 であるかどうかの検定である。

    usage:
    cor_test (x, y, alt, method)
    
    x, y はデータベクトル
    alt は文字列。
    デフォルトで両側検定 "!="
    片側検定の場合，母相関係数 < 0 の場合 "<"，母相関係数 > 0 の場合 ">" を指定する
    method は用いられる相関係数を "pearson", "spearman", "kendall" で指定する（先頭 1 文字でよい）
    戻り値を指定しない場合は p 値のみを表示する
    戻り値は `scalar structure` である（要素の取り出し方は，実行例を参照）



```matlab
pkg load statistics   % statistics が必要
format long           % 表示精度を高くする（任意）
```


```matlab
x = [49.6; 52.5; 48.3; 50.6; 56.7; 32.8; 51.6; 46.1; 54.6; 52.0; 39.3; 49.5; 45.1; 37.1; 63.9;
     48.3; 37.4; 33.4; 37.8; 51.2; 63.0; 74.3; 54.4; 60.1; 55.6];
y = [48.7; 36.8; 51.9; 65.5; 62.6; 57.3; 43.3; 57.7; 61.4; 69.8; 48.0; 37.1; 29.8; 53.6; 49.3;
     50.2; 46.1; 50.6; 51.4; 61.0; 50.8; 51.7; 52.4; 57.3; 55.4];
```

## ピアソンの積率相関係数


```matlab
cor_test(x, y)
```

    pval: 0.561832
    ans =
    
      scalar structure containing the fields:
    
        method = Pearson's product moment correlation
        params = 23
        stat = 0.588652233658702
        dist = t
        pval = 0.561831632136747
        alternative = !=
    


`scalar structure` のフィールドの値は，以下のようにして取り出す。


```matlab
a = cor_test(x, y);
```


```matlab
a.method
a.params
a.stat
a.dist
a.pval
a.alternative
```

    ans = Pearson's product moment correlation
    ans = 23
    ans = 0.588652233658702
    ans = t
    ans = 0.561831632136747
    ans = !=



```matlab
printf("%s = %.5g,  df = %d,  p value = %.5g\n", a.dist, a.stat, a.params, a.pval)
```

    t = 0.58865,  df = 23,  p value = 0.56183


## スピアマンの順位相関係数

`method` に `"spearman"` を指定するときには，`alt` がデフォルト `"!="` であっても，明示的に指定しなければならない。


```matlab
cor_test(x, y, "!=", "spearman")
```

    pval: 0.31324
    ans =
    
      scalar structure containing the fields:
    
        method = Spearman's rank correlation rho
        params = [](0x0)
        stat = 1.008447829550165
        dist = stdnormal
        pval = 0.313239521224296
        alternative = !=
    


## ケンドールの順位相関係数

`method` に `"kendall"` を指定するときには，`alt` がデフォルト `"!="` であっても，明示的に指定しなければならない。


```matlab
cor_test(x, y, "!=", "kendall")
```

    pval: 0.425611
    ans =
    
      scalar structure containing the fields:
    
        method = Kendall's rank correlation tau
        params = [](0x0)
        stat = 0.796724671951258
        dist = stdnormal
        pval = 0.425610951872934
        alternative = !=
EVVSサーチ開発メモ

# 機能

### 検索機能
- 以下の項目がよく検索されるはず
  - 機体名
    - 部分一致や検索候補があったほうがいいかもしれない
  - コスト 
    - チェックマークで複数選択できて検索できる方がいい 

# DB
### ER図
https://github.com/kbc18a11/exvs-search-drawio

### メモ 
- 機体の名前はよく検索するから、インデックスをかけたほうがいいかも
- 形態移行がある機体のために、`機体情報-<機体詳細`の関係が良いかも
  - 機体情報　形態が変わっても、変わらない情報
  - 機体詳細  形態が変わったら、変わる情報

# スケジュール
- 最初はリリースを優先する。
  - 完璧を求めるとモチベーションが持たないため
  - 最初は以下の検索ができればいい
    - コスト
    - 機体名

# 技術選定
### フロントエンド
- TypeScript
- Next.js
- Bootstrap
- CSSModule 

### バックエンド
- Go
- Echo
- Gorm
- MariaDB

### インフラ
- デプロイ先
　　- バックエンド Conoha
　　- フロントエンド Vercel
- Render Disk 機体サムネイルの保管場所
- Docker
StandardError: An error has occurred, this and all later migrations canceled:の解消法


## マイグレーションをする際に発生
```
class CreateInterviews < ActiveRecord::Migration[6.1]
  def change
    create_table :interviews do |t|
      t.integer :user_id
      t.string :title
      t.text :body
      t.timestamps
    end
  end
end
```
記述自体に問題はありませんでしたが、エラー文を確認すると、undefined local variable or method `　t' for #<....>と出ており、特にtに関するものを確認します。問題ありませんでしたが、t.の前に『全角のスペース』が入っていました。これを直すと無事マイグレーションできました。

## 初心者ほど凡ミスがないかを疑う
特に初学者ほどコマンドは慎重に書くと思いますが、こう言う見当たらないミスほど時間を費やすので、コマンド＋f でそもそもの形式を確認してみるのも解決までの近道になりそうです。
【CSSのみ】checkboxをクリックで指定したclassの要素を非表示する方法

## 概要

javascriptではなくcssのみを使いチェックを外すと非表示になる機能を実装しました。
チェックボックスが外れると指定した`class`が`display:none;`になる仕組みです。

## 実装例

Sample2のチェックボックスを外すと
![form3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713225/315cf538-8163-096a-77e1-80a02701ade9.jpeg)

Sample2が非表示になる。
![sample2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713225/903a53d8-9553-f98f-2bf0-8ed53fdb378c.jpeg)

## 完成コード

```ruby:html

<div style="position:relative">
<input type="checkbox" class="check_button" checked>
<div class="sample">Sample1</div>
</div>
	
<div style="position:relative">
<input type="checkbox" class="check_button" checked>
<div class="sample">Sample2</div>
</div>
	
<div style="position:relative">
<input type="checkbox" class="check_button" checked>
<div class="sample">Sample3</div>
</div>
	
```

```ruby:css
.sample{
	border: solid 1px #CCCCCC;
	padding: 10px;
	margin-bottom: 10px;
}

.check_button{
	position: absolute;
	top: 30%;
	right: 20px;
	}

.check_button:not(:checked){
    display: none;
}
	
.check_button:not(:checked)~.sample{
    display: none;
}
	
```

## 解説

チェックボックスをあらかじめ`checked`にしておき、チェックボタンが外れたら非表示にする。

```ruby:html
<div style="position:relative">
<input type="checkbox" class="check_button" checked>
<div class="sample">Sample2</div>
</div>
```

`input`タグは閉じタグがないため間接セレクタ `~` を用いて非表示にしたい`class`を指定する。
`チェックボックスのclass:not(:checked)`　`~`　`非表示にしたいclass`

```ruby:css
.check_button:not(:checked)~.sample{
    display: none;
}	
```

## メモ

チェックだと機能的に分かりにくいので、cssを使いチェックボックスを「削除」ボタンに変更したい。
実装できたら追記します。
「Starship」+「iTerm2」でターミナルをかっこよくしてみた

mac標準のターミナルが使いづらすぎるので色々調べてカスタムしてみました。
参考になれば真似してみてください。

## 標準ターミナルかそれ以外か
(なんかローランドみたいになりましたw)
mac標準ターミナルの初期状態がこれ
![スクリーンショット 2022-07-09 13.38.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/ea0c3ba2-a248-b53d-7081-bbab6da982d2.png)
なにか使いづらそう。っていうかモチベが上がらなさそう。
（標準ターミナルをカスタムしても使いやすくなるみたいです。）

自分の好きなものを使えばいいと思いますが、今回は「iTerm2」をインストールして行きたいと思います。
（会社の先輩方がみんな使ってたので笑）
## iTerm2をインストール
↓ **公式サイトからもダウンロード可能みたいです。** 
[iTerm2](https://iterm2.com/)

とりあえずHomebrewでインストール
```
brew install iterm2
```

標準だと使いづらそうですが、ここから進化させますよおおーー！！

## iTerm2を設定していく
まずはiTerm2を設定していきます。

**iterm2** → **Preferences** から設定を行っていきます。
## HotKeyWindow
iTerm2にはHotKeyWindowという便利機能が備わっています。
設定したKeyを入力すればどこからでもiTerm2を立ちあげることができるってやつ。

任意のProfilesを作成してHotKeyWindowを設定していきます。
![スクリーンショット_2022-07-09_14_11_27-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/1d8e9085-5045-07fa-ac6b-0afa8dd4d12e.png)

windowタブでHotKeyWindowで起動させた時のサイズを設定できます。
とりあずフルスクリーンにしておきました。

![スクリーンショット_2022-07-09_14_23_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/c0765488-9aca-29a8-6368-bec64d59aede.png)

## フォントの設定
Mac標準のフォントもたくさんありますが、なんとなくそれっぽいのをダウンロードしてみたいと思います。
[フォントダウンロードはこちら](https://www.nerdfonts.com/font-downloads)

今回は **Fira Code Nerd Font** をダウンロードしてみました。
installが完了したらzipファイルを開いてフォントをインストール。
![スクリーンショット 2022-07-09 15.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/1342b2cd-bbd2-3835-ba35-2cf9b41d7012.png)

これでご自身のMacのFontBookにダウンロードしたフォントが追加されます。

### とりあえずこんな感じ

なんかそれっぽい。

![スクリーンショット 2022-07-09 15.42.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/5200a613-a3f6-2432-cd20-616f777e68e4.png)

## Starshipのインストール
Homebrew経由で[Starship](https://starship.rs/ja-jp/guide/#%F0%9F%9A%80-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)をinstall。
```
brew install starship
```
### Starshipの初期化
使用しているshellの設定ファイルにて初期化設定を行います。
自分はzshなので.zshrcにて以下を記述。

```~/.zshrc
eval "$(starship init zsh)"
```

設定するとこんな感じ！！

![スクリーンショット 2022-07-09 15.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/40abdeae-c401-4778-30e6-a41b39fa65fd.png)

### HotKeyWindowが閉じてしまう
HotKeyWindowを起動している時に他のアプリを触ると自動的に閉じてしまう場合は以下の設定で回避可能です。

**Preferences** → **Profiles** → **Keys** → **ConfigureHotKeyWindow** → **Pin hotkey window** を有効にする。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644766/d8cc0abb-e574-8fc5-b776-907cde9a1734.png)

## 終わりに
iTerm2でStarshipを導入してみました。
今回はStarshipを導入してみただけですが、拡張性が高く色々な設定ができるみたいなので調べてみてください！

以下フォルダを作成して、Starshipの設定を記述できます。
```
mkdir -p ~/.config && touch ~/.config/starship.toml
```

詳しくは[公式サイト](https://starship.rs/ja-jp/config/)を参照してください！