OmniAICreator/Qiita-1.07M huggingface dataset:
Bashでエイリアスを作ってくれる湯婆婆コマンドを実装してみた

[Javaで湯婆婆を実装してみる - Qiita](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2) のn番煎じネタですが、この記事が流行るより前に自分がこんなツイートをしていたのを思い出し、じゃあ実装してみるかと思った次第です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">CentOSの神隠し<br><br>湯婆婆「フン。千尋というのかい？贅沢な名だねぇ。alias 千=千尋！echo &quot;はい&quot;」<br><br>千「はい」<a href="https://twitter.com/hashtag/%E3%82%B8%E3%83%96%E3%83%AAIT%E6%A5%AD%E7%95%8C%E3%81%82%E3%82%8B%E3%81%82%E3%82%8B?src=hash&amp;ref_src=twsrc%5Etfw">#ジブリIT業界あるある</a> ...? <a href="https://t.co/768wlGihZ6">pic.twitter.com/768wlGihZ6</a></p>&mdash; namnium (@namnium_01) <a href="https://twitter.com/namnium_01/status/1308067722970849282?ref_src=twsrc%5Etfw">September 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

では早速コード。

```bash:yubaba.sh
#!/usr/bin/bash

echo "契約書だよ。そこに名前を書きな。"
read name

if [ ${#name} -le 0 ]; then
    echo "名前を書けと言ったのが聞こえなかったかい！帰りな！"
    return
fi

echo "フン。$nameというのかい。贅沢な名だねぇ"
alias "${name:0:1}"="\$name"
alias "$name"="yubaba_removed.sh"
echo "今からおまえの名前は${name:0:1}だ。いいかい、${name:0:1}だよ。分かったら返事をするんだ、${name:0:1}！！"
```

このファイルは任意の場所においてください。

```bash:yubaba_removed.sh
#!/usr/bin/bash

echo "(そのコマンドは湯婆婆に名を奪われたので使えません。)"
```

こっちのコマンドは [パスが通った場所](https://qiita.com/fuwamaki/items/3d8af42cf7abee760a81) に置いてください。(本記事では `~/bin/yubaba_removed.sh` とします。)

そして両方に実行権限を付けます。

```bash:bash
$ chmod 755 yubaba.sh
$ chmod 755 ~/bin/yubaba_removed.sh
```

では早速実行！コマンド名を渡すと頭文字1字にしてくれます。

ただし、エイリアスコマンドの効果を継続させるために、 `source` コマンドが必要です。

```bash:bash
$ source ./yubaba.sh
契約書だよ。そこに名前を書きな。
pwd
フン。pwdというのかい。贅沢な名だねぇ
今からおまえの名前はpだ。いいかい、pだよ。分かったら返事をするんだ、p！！
$ p
/home/username/Desktop/yubaba
$ pwd
(そのコマンドは湯婆婆に名を奪われたので使えません。)
$ 
```

もとに戻したいならシェルを閉じるか `unalias` コマンドを使いましょう。

[Discord Botで湯婆婆を実装してみる](https://qiita.com/nekozuki_dev/items/485d47a459a63f59400f) じゃないですけどやっぱ実際に効果を持ったプログラムだと湯婆婆味が増しますね。

ここまで読んでいただきありがとうございました！m(_ _)m
AWSのEC2インスタンスにWebサーバーを作成する方法

# はじめに
AWSはAmazon Web Servisesの略で、Amazonが提供しているクラウドサーバーのサービスです。
AWSへの理解度を高めるために、学んだことをアウトプットします。


# 今回の流れ

* アプリケーションにNginxをインストール
* Nginxの設定

「AWSのEC2インスタンスにアプリケーションサーバーを作成する方法」（https://qiita.com/daisuke30x/items/4292f96d817805f93d62）
の続きからの説明となります。
つまり、インスタンスにアプリケーションがインストールされていることが前提です。


# EC2インスタンスにNginxをインストール

### Nginxとは
代表的なWebサーバーです。

①自身のアプリケーションにNginxのインストール

```:ターミナル
インスタンスにログイン
% ssh -i キーペア名.pem ec2-user@<パブリックIP>

Nginxのインストール
[インスタンス]$ sudo amazon-linux-extras install nginx1
=> Is this ok [y/d/N]: y

Nginxの設定
[インスタンス]$ sudo vim /etc/nginx/conf.d/rails.conf

「i」を押し、以下を入力（2箇所の<アプリケーション名>と1箇所の<Elastic IP>には自身のものを当てはめて入力）
```
```:/etc/nginx/conf.d/rails.conf
upstream app_server {
  # Unicornと連携させるための設定
  server unix:/var/www/<アプリケーション名>/tmp/sockets/unicorn.sock;
}

# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
  # このプログラムが接続を受け付けるポート番号
  listen 80;
  # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
  server_name <Elastic IP>;

  # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
  client_max_body_size 2g;

# 接続が来た際のrootディレクトリ
  root /var/www/<アプリケーション名>/public;

# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }

  error_page 500 502 503 504 /500.html;
}
```

```:ターミナル
上の入力後、escキーを押し、「:wq」を入力で保存

Nginxの権限の変更
[インスタンス]$ cd /var/lib
[インスタンス lib]$ sudo chmod -R 775 nginx  
(-R：ディレクトリ内の全ての権限を変更するためのオプション)

Nginxの起動
[インスタンス lib]]$ cd ~
[インスタンス]$ sudo systemctl start nginx
[インスタンス]$ sudo systemctl reload nginx

```

②アプリケーションの設定変更

今回はUnicornを使用していることを想定して、説明します。

* アプリケーションのconfig内のunicorn.rbファイルの編集
```config/unicorn.rb
listen 3000 を修正　=> listen "#{app_path}/tmp/sockets/unicorn.sock"
```

* インスタンスにアプリケーションの設定変更を反映

```
インスタンス内のアプリケーションディレクトリに移動
[インスタンス]$ cd /var/www/<アプリケーション名>

[インスタンス<アプリケーション名>]$ git pull origin master
```

* アプリケーションの再起動

```:ターミナル
プロセスの確認
[インスタンス<アプリケーション名>]$ ps aux | grep unicorn
=> 左から2つ目の数字がプロセスID

プロセスの停止
[インスタンス<アプリケーション名>]$ kill <unicorn_rails masterのプロセスID>

再度アプリケーションの起動
[インスタンス<アプリケーション名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
```
「RAILS_SERVE_STATIC_FILES=1」はコンパイルしたアセットファイルを見つけられるように指定する役割

**ブラウザに＜Elastic IP＞を入力し、アプリケーションが表示されれば成功です。**

※Elastic IPのような数字の羅列が嫌な場合はAWSマネジメントコンソールのVPCでDNSの設定をしてください。


# 最後に
本投稿が初学者の復習の一助となればと幸いです。
GASでスプレッドシートをオブジェクト配列にすると色々捗る

スプレッドシートからデータを引っ張ってくると、そのままだと二次元配列になります
例えば以下のようなスプレッドシート

|batting|name|uniform|
|-------|----|-------|
|  3    |坂本 |  6    |
|  4    |岡本 |  25   |

```jsx
//gs側
function getDatas(){
  const datas=SpreadsheetApp.openById("kyojindasen").getSheets()[0].getDataRange().getValues()
  console.log(datas)
}

//こんな形です
[
  ["batting","name","uniform"],
  [3,"坂本",6],
  [4,"岡本",25]
]
```

このままだとデータとして使いにくいです。

例えば、「打順が4番目の選手の名前は?」という入力に対して、"岡本"というデータを出力したいとします。

```jsx
// まさかこんな出し方はしないでしょう。
const player_name = datas[2][1]
```
しかし、二次元配列ではデータを縦に見ることはできないため、各配列の0番目を見ていって「4」を見つけるという操作ができません（無理やり転置すればできなくもないですが、無駄なのでやりません）

それに行番号や列番号で指定してしまうと、スプレッドシート の行や列が増えたり減ったりした時に対応できなくなります。

二次元配列ではなく、javascriptのオブジェクトを詰め込んだ配列にすると扱いやすくなります。

```jsx
const players= [
    {batting:3,name:"坂本",uniform:6},
    {batting:4,name:"岡本",uniform:25}
]
```

これなら「打順が4番目の選手の名前は?」という入力に対して、"岡本"というデータを出力するには以下のコードで実装できます。

```jsx
const player = players.find(player=>player.batting===4)
```

もし、「打順5番目に背番号8番の"丸"という名前の選手を加える」時には以下のように実装できます。

```jsx
const maru = {batting:5,name:"丸",uniform:8}
players.push(maru)
```

他にも色々メリットはありますが、それらを紹介する前に二次元配列をオブジェクト配列に変換する方法を紹介します。

```jsx
function getSpreadsheetData(){
      const datas = SpreadsheetApp.openById(id).getSheets()[0].getDataRange().getValues()
      const head = datas.shift()
      const items = datas.map(row => {
        return row.reduce((acc, r, idx) => {
          acc[head[idx]] = r;
          return acc;
        }, {})
      })
			return items
}
```

解説は少し難しいですが、簡単に説明します。

```jsx
const datas = SpreadsheetApp.openById(id).getSheets()[0].getDataRange().getValues()
const head = datas.shift()

//headとdatasは以下の形。
head = ["batting","name","uniform"]
datas= [
  [3,"坂本",6],
	[4,"岡本",25]
]
```

datasの一列一列に対して、配列をオブジェクトにします。

mapメソッドの中身は以下のようなことをしています。

```jsx
//この部分
row.reduce((acc, r, idx) => {
          acc[head[idx]] = r;
          return acc;
        }, {})

//reduceというメソッドでオブジェクトにしている
head= ["batting","name","uniform"]
row = [3,"坂本",6]

//idx=0
acc={}　　　　　//acc = {}
//idx=1
acc.batting=3 //acc = {batting:3}
//idx=2
acc.name="坂本"//acc = {batting:3,name:"坂本"}
//idx=3
acc.uniform=6 //acc = {batting:3,name:"坂本",uniform:6}
```

mapメソッドでは、これをrowの2番目に対しても実行を繰り返します。
最終的にdatasの数だけ要素ができます。（この場合は2つ）

reduceメソッドは初心者のうちは馴染みにくいメソッドかもしれませんが、他の言語でも使える（言い換えればそれだけ使用シーンが多いメソッド）ので、使えるようになっておくことを強く勧めます。

## 何が便利か

- もしスプレッドシートの一列目が日本語の時は、以下のように要素を取り出せます。

```jsx
const players= [
	{"打順":3,"名前":"坂本","背番号":6},
	{"打順":4,"名前":"岡本","背番号":25},
]
//背番号25の選手の名前は?
const sensyu = players.find(player=>player["背番号"]==25)
sensyu["名前"]
//=> "岡本"
```

- vuetifyを使うとv-data-tableに表示できます。
ネットワークエンジニアってどんなことするの？実機を触って体験してきた。

**[株式会社 ディック ソリューション エンジニアリング](https://www.wantedly.com/companies/company_8071387)**さんが主催するWantedly meetup、「ネットワークエンジニアってどんなことするの？実機を触って体験してみよう！」に参加してまいりましたので、何を学んだのかアウトプットしたいと思います。

#meetup概要
2020.11.7土曜13:00-17:00@浜松町

会社概要から始まり、ネットワークエンジニアの仕事、ネットワーク概論、実機を使ったネットワークの接続の実演まで、４時間オーバーの体験会はあっという間でした。こちらがどんな質問をしても、一切手を抜かず、惜しみなく説明してくださったのがとても嬉しく、またプロの熱さを感じました。

#学んだこと
###実機でネットワークを作る
やはり自分の手を使って学んだことは印象に残りやすいのでしょう。自らWindows PCとスイッチ、ルーターを接続し、隣の参加者のネットワークに接続しました。

1. PC、スイッチ、ルーターをLANで物理的に接続する
* 自らのPCのIPアドレス、マスクアドレス、ルーターアドレスを変更する。（IPアドレスって変更できるんですね！）
* teratermでルーターの設定をする
* PCとルーターを`ping xxx.xxx.x.x(IP ADDRESS)`で接続する
* 外部接続用のポートにIPアドレスを設定する
* 接続先のIPアドレスをpingし、隣の参加者のネットワークと接続する

私のグループは、最初接続できず、少しハマりました。コマンドで設定ミスしたのか、Firewallに邪魔されているのか、いろいろ探りましたが、結局、相手方がルーターのポートに設定したIPアドレスがデフォルトゲートウェイと違うがために、外部接続しようとすると誤作動が起きるということがわかり、最後には無事バグを解消し、会は美しくお開きとなりました。

###その他今日学んだ単語
* **[INTEROP](https://www.interop.jp/)**：毎年幕張メッセで開催される国内最大のネットワークの展示会。一般人も参加できるらしい。毎年このイベントのために学習意欲に溢れる若きエンジニアが有志でボランティアとして参加し、このイベントだけのために最新の技術を使ってネットワークを構築するのだとか。３週間泊まり込みで、毎年少なからずドラマがあるそうです。
* **関谷教授**：INTEROPの座長も務めるIT界のエラい人。東大教授。[この方](https://www.keisu.t.u-tokyo.ac.jp/2020/04/04/%E9%96%A2%E8%B0%B7-%E5%8B%87%E5%8F%B8/)かな？
* **村井純**：インターネットの父。慶應名誉教授。INTEROPの座長も務める。
* **CCNA試験**：CISCOシステムズが主催する資格試験。
* **ARPANET**：現在のネットワークの原型。元々は大学や研究機関を結ぶネットワークだった。
* **AS番号**：Autonomous System number。インターネットを構成する個々の独立したネットワークに割り当てられる番号。先のINTEROPイベントでは、開催期間内だけ使用するAS番号が存在しているらしい。いろんな会社がAS番号を所有している→[参考](https://www.jpix.ad.jp/jp/member.php)
* **ISP**：Internet Service Provider。いわゆるプロバイダー。いくつものISPが連携することで、世界各地に散らばるIPアドレスまで通信ができる。その大きさにより、Tier1、Tier2、Tier3に分かれ、上のTierのISPはそれを照会することで収益を得る。
* **IPアドレスの内訳**：32bitあるIPアドレスはネットワーク部とホスト部に別れ、同じネットーワーク内では、ネットワーク部を共有し、ホスト部をそのネットワーク下のデバイスに割り振る。24bitで区切り、最後の8bitがホスト部になることが多い。
* **デフォルトゲートウェイ**：接続相手がわからない時に、とりあえずデータを送信するルータのデフォルトのIPアドレス。ここでのゲートウェイとはゲート＝門のことであり、ネットーワークのゲートにいるルーターなどの中継機器を指す。
* **L2/L3**：レイヤ2、レイヤ3のこと。ネットワーク機器の通信においても層、レイヤがあるそうで。この日に使ったスイッチはL2なのでIPアドレスがありませんでした。L2では各機器に付与された物理的なIDで通信を行うそうで、これをMACアドレスと読んだりする。L3はそれよりも高次元のプロトコルである論理的なアドレス＝IPアドレスが使用される。これ、OSI参照モデルの7層の中の2,3層目のことだったんですね。 [CISCOのページ](https://www.cisco.com/c/m/ja_jp/products/switches/lan-switches.html#~stickynav=1)がわかりやすい。

「ネットワークはなぜつながるのか」を読んで勉強を進めていきたいと思います！
iterm2のホットキーウィンドウが勝手に閉じてしまうのを防ぐ

# 概要
iterm2のホットキーウィンドウを皆さんご存知でしょうか．

ホットキーを設定しておくと押した瞬間にiterm2のウィンドウを開いてくれる便利な機能です．

普段使用しているmac bookでは大変重宝しています．

しかし別のpcでiterm2をインストールして使用したところ，ホットキーウィンドウを開いているときに他のアプリケーションにフォーカスを移すとホットキーウィンドウが閉じてしまいました．（正確にはウィンドウが閉じてしまうのではなく隠れてしまう）

他のアプリケーションを触る度にいちいちホットキーを押し直すのはかなり面倒臭いです．（ホットキーの良さがなくなってしまう）

他のアプリケーションにフォーカスを映してもホットキーウィンドウが閉じないようにする設定を見つけたのでメモしておきます．


# 設定
1. iterm2の`Preference`を開く（macだと `⌘＋,` で開く）
　![スクリーンショット 2020-11-06 15.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/b9c6ed40-c5fb-cd23-929a-de2a38965d6a.png)
2. `Preference`から`Profiles`を開く（左から三番目）
　![スクリーンショット 2020-11-06 15.47.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/83a2302e-803b-ee66-8c19-7902bada5a88.png)
3. 上部のボタンの右から2番目にある`Keys`を選択し，さらに左の`Profile Name`から`Hotkey Window`を選択する．（Hotkey Windowがない場合はDefault）
　![スクリーンショット 2020-11-06 15.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/f6a86ab6-e1f2-b8c1-a006-b8797ecebba4.png)
4. 上記画像の右下にある`Configure Hotkey Window`を選択する．
![スクリーンショット 2020-11-06 15.54.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401124/575af65c-4c4f-eae9-a688-1bf8cfd43ff6.png)
上記のようなポップアップが出現するので,
`Pin hotkey window`, `Floating window`を有効化してOKを押す．
これで他のアプリケーションを押してもホットキーウィンドウが隠れなくなります．

5. iterm2を再起動する
ホットキーウィンドウは隠れなくなるが，このままだと他のアプリケーションを使用中にホットキーウィンドウを開くとなぜか他のアプリケーションの下にホットキーウィンドウが開かれてしまいます．
iterm2を一度再起動するとこの問題は無くなります．


# 参考
https://qastack.jp/superuser/1100918/how-can-i-prevent-the-iterm2-hotkey-window-from-losing-focus
Chrome DevTools Networkパネルの使い方

業務でフロントエンドのパフォーマンス改善を行うにあたり、
Chrome DevToolsの基本機能について学習した内容を備忘録としてアウトプットする。

本記事はNetworkパネルにフォーカスした内容となっている。

そもそもDevToolsとは、デベロッパーツール＝開発者向けツールとして、モダンブラウザには標準装備されているもので、ここではGoogleのChrome DevTools (バージョン: 86) について取り上げる。

DevToolsはブラウザ上で右クリックから検証で開く、またはF12で開く事が出来る。

## Networkパネル
Networkパネルでは対象ページのネットワークを通じたリソースの取得状況を可視化する事が出来るので、基本的にはリソースの読み込みに時間がかかっている部分の特定に利用する。

パネルを表示した状態で、計測したい対象ページを開く事で取得されるリソースの状況が表示される仕組みになっている。尚、macOSであれば、Command + R コマンドで素早くページリロードが出来る。
![スクリーンショット 2020-11-07 20.24.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/332f95f6-c9d7-a3ff-cb31-b46903cb5097.png)

再読み込みに関してはキャッシュが効いているかも確認が可能である。キャッシュが効いていれば、Sizeに（memory cache）や(disk cache)などと表示される。![スクリーンショット 2020-11-07 20.22.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/0e725fe3-f998-b269-3d58-e49359ad3a05.png)
初回読み込みの状況を正確に計測する為にキャッシュを無効にするにはDisable cacheにチェックを入れれば良い。
![スクリーンショット 2020-11-07 20.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/be2db0db-8aed-73aa-2398-1a6ac9f61e43.png)

#### Preserve log
Preserve log にチェックを入れるとリダイレクト前のリクエスト・レスポンスのデータが、Networkパネルの中に残るようになる。

#### Online
Fast 3G、Slow 3Gなどを選択すると3G環境を再現する事が出来る。

#### Filter、他
文字通り表示するリソースをフィルタリングする事が出来る。
単純に右側のファイル形式を選択すれば、CSSだけ、JSだけで表示する事も可能。
![スクリーンショット 2020-11-07 20.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/9e37ce44-032b-9594-62c5-8c87435b3e56.png)
Waterfallの青いラインがDOMContentLoaded、赤いラインがLoadの発生時点で示す。
DOMContentLoadedとはDOM構築が完了した時点で発火するイベント、LoadはDOM構築に加えて画像やスクリプトの読み込みが完了した時点で発火するイベントの事である。

それぞれ到達するまでの時間がパネル最下部に表示される仕様となっている。
![スクリーンショット 2020-11-07 21.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531606/7952c798-2e61-2b4f-897a-37e7414f8926.png)
Waterfall上にマウスカーソルを合わせる事でリソースの詳細を個々に確認する事が出来る。
#### Resource Scheduling
リクエストの順番決定する為のスケジューリングに要した時間
#### Queueing
レンダリングエンジン内のQueueingに処理されるのに要した時間
#### Connection Start
キューに入った後でリクエストを送信するまでに要した時間
#### stalled
マシンのネットワークを活性化させるのに要した時間
#### Request sent
HTTPリクエストを送信するのに要した時間
#### Waiting（TTFB）
リクエストを送信し終えてから最初のデータを受け取るまでに要した時間
#### Content Download
コンテンツの最初のバイトから全てを受け取り終えるまでに要した時間
SAPに落ちたんだが！！！

#はじめに
本日試験を受験してきました。スコアはわからないが落ちました。後日スコアを確認して再チャレンジですね。
間違ったところはわかりません泣
SAPだけで12万逝かれました。。。恐ろしやAWS

#今後の方針
以下の記事と
https://qiita.com/gomasa/items/6ce860a2e11a620c92ae
くらめその記事から
https://dev.classmethod.jp/articles/aws-sap-review-by-ohmura/

１　ブログに目を通す
２　クラスメソッドの記事を読む
３　教本の模擬試験を９割取れるように回す。
４  一日一回Udemy模擬試験回す。
５　合格する。
Red言語で湯婆婆

こちらの方の記事を拝読しました。[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)。笑いました。

Red布教者としてRedでやってみました。

## 実装

```red
Red [
	title: "赤婆婆（Red-Yubaba）"
	Author: "Koba-yu"
]

name: ask "契約書だよ。そこに名前を書きな。"
print ["フン。" name "というのかい。贅沢な名だねぇ。"]
new-name: first random name
print rejoin ["今からお前の名前は" new-name "だ。いいかい、" new-name "だよ。分かったら返事をするんだ、" new-name "!!"]
```

・・・なんか思った以上に短い＆読みやすくて大して解説するところがない気もしましたが、一応解説いたします。

### 1行目

askはConsole入力を待つ関数です。入力内容が戻り値で返るのでnameとして保持しました。

### 2行目

RedでのConsole出力はprint関数です。

### 3行目

random関数に文字列を渡すとシャッフルされた文字列が返ります。
first関数で先頭1文字が取得できるので、これで新しい名前が得られます。
超簡単！！

### 4行目

printする各要素の間にスペースが入ってほしくない場合はrejoinを挟めばOKです。

## 仕様違反が・・・

元ネタの方の記事では名前が未入力で返ってきたら**クラッシュするのが仕様**だったのですが、このプログラムでは残念ながらクラッシュしません。
でも他におもしろい挙動も思いつかなかったのでとりあえずそのまま・・・

## [追記]𠮷田さんも問題ないよ！

世の中には𠮷田さんから名前を奪ったときにバグってしまう湯婆婆もおわすようですが、Red湯婆婆は問題ございません！
マイナー言語なのにすごいぞRed言語！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110552/61850ab6-f45e-1220-c62f-709bd0910016.png)

ついでにやってみましたがうちの湯婆婆は家族の絆すら奪えるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110552/f940568b-ef66-1717-7422-12879d2c99d0.png)
ドラ〇もんも大好きな「どら焼き」をCSSだけで作ってみた。

# どうも7noteです。なんか偶然の副産物でできてしまったので、記事にしてみました。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/dorayaki/
暗号化技術とは

 <h1>暗号化技術とは何か</h1>

個人情報といった重要な情報をインターネット上で管理するにあたり、特定のユーザーだけがアクセスできるといったセキュリティ面において、重要なセキュリティ技術のこと。

データの中身が第３者にわからないように形を変えることを暗号化という(一般的な暗号化という言葉と意味合いは同じです)

暗号化技術には共通鍵暗号方式と公開鍵暗号方式、ハイブリッド暗号方式の３種類があります。


<h2>共通鍵暗号方式について</h2>

情報の送り手(暗号化する方)と情報を見る側(復号する側)が同じ鍵を用いる暗号化方式

○共通鍵方式のメリット

・共通の鍵を使うため、復号までの時間が早い

○共通鍵方式のデメリット

・共通の鍵を使うため、セキュリティ面が弱い

・鍵を暗号側と復号側が共有するため、ユーザーの数だけ鍵が必要になる


<h2>公開鍵暗号方式について</h2>

一般に広く展開する、公開用の鍵が存在し、暗号化用の鍵と復号に使う鍵が異なる。
送り手と受け手で違う鍵を使うことになる。


○公開鍵方式のメリット

・情報の送り手と情報の受け手で違う鍵を使うため、セキュリティ面で共通鍵方式より優れている。


○公開鍵方式のデメリット

・復号までの処理に時間がかかる


<h2>ハイブリッド暗号方式について</h2>

共通鍵方式のセキュリティの弱さ、公開鍵方式の情報伝達処理の遅さという両者のデメリットを解消した暗号化技術

○ハイブリッド暗号のメリット

・公開鍵方式に比べて処理速度が早い

・鍵の配送、管理が用意

○ハイブリッド暗号のデメリット

・共通鍵方式、公開鍵方式の両方のデメリットがカバーされているので特になし。


　　　　　　　　　　　　　　　　　　　　　以上
実運用して気づいた Aurora Serverless の注意点

Aurora Serverless を使用する機会がありましたので、調べたことをまとめてみました。

## 1. 自動スケーリングのしきい値
>設定に応じて、Aurora Serverless は、CPU 使用率、接続、および使用可能メモリの各しきい値に関するスケーリングルールを自動的に作成します。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.how-it-works.html

スケールアップ&ダウンの条件はCPU、メモリ、同時接続数のAWS側の閾値をもとにスケールアップ&ダウンされる。 現時点はこちらで閾値を設定することはできなそうでした。

## 2. 自動スケーリングアップ
>スケーリングポイントは、データベースが安全にスケーリングオペレーションを開始できる時点です。以下の条件では Aurora Serverless がスケーリングポイントを見つけられない場合があります。
>長期実行クエリまたはトランザクションが進行中である
>一時テーブルまたはテーブルロックが使用中である

スロークエリが発生している場合などはスケールアップできいないので注意が必要です。
(クエリを強制終了してスケールアップするオプションもあります。)
■自動スケーリングダウン
>スケールアップ後のスケールダウンのクールダウン期間は 15 分です。スケールダウン後の再スケールダウンのクールダウン期間は 310 秒です。

■注意点
 - 1つのクエリに時間がかかっている場合スケールアップの条件を満たしていたも自動でスケールアップされない
 - テーブルロックがかかっている場合も同様にスケールアップされない。
(クライアントとの接続を切って、強制的にスケールアップさせる設定を入れることも可能です。)

手動でスケールアップすることも可能です。
手動の際も、クライアントの接続を強制的に切って変更することも可能

## 3. ACUあたりの同時接続数 (検証済み)
1ACU: 90
2ACU: 180
4ACU: 270
8ACU: 1000

```
■1ACU(2GB)の場合
mysql> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
|                90 |
+-------------------+
1 row in set (0.00 sec)
■2ACU(4GB)の場合
mysql> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
|               180 |
+-------------------+
1 row in set (0.00 sec)
■4ACU(8GB)の場合の
mysql> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
|               270 |
+-------------------+
1 row in set (0.00 sec)
■8ACU(16GB)の場合
mysql> select @@max_connections;
+-------------------+
| @@max_connections |
+-------------------+
|              1000 |
+-------------------+
1 row in set (0.00 sec)
```
## 4. AZ障害
>Aurora Serverless とフェイルオーバー
Aurora Serverless DB クラスターの DB インスタンスが使用不能になるか DB クラスターがあるアベイラビリティーゾーン (AZ) に障害が発生した場合、Aurora は別の AZ に DB インスタンスを再作成します。この機能は、自動マルチ AZ フェイルオーバーとも呼ばれます。
このフェイルオーバーメカニズムは、Aurora プロビジョンドクラスターのフェイルオーバーよりも時間がかかります。Aurora Serverless のフェイルオーバー時間は、AWS リージョン内の他の AZ の需要やキャパシティーの可用性によって異なるため、現在定義されていません。
Aurora では、コンピューティングキャパシティーとストレージは分離されるため、クラスターのストレージボリュームは複数の AZ に分散されます。停止が DB インスタンスまたは関連する AZ に影響する場合でも、データは引き続き利用することができます。

フェールオーバーの時間は未定義ですが、AZ障害時は自動でAZ変更してくれるので良いですね。

■参考資料
仕組み
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.how-it-works.html
同時接続数について
https://dev.classmethod.jp/articles/aurora-serverless-maxconnection/
料金
https://aws.amazon.com/jp/rds/aurora/pricing/
https://dev.classmethod.jp/articles/calculate-amazon-aurora-serverless-costs/
注意点
https://dev.classmethod.jp/articles/lessons-learned-from-up-and-running-aurora-serverless/
【自分用】git コマンドまとめ

# GItってなんのために使うのか

  ファイルのバージョンを管理するため
  
# Gitの歴史

  リーナス・トーバルズ
  LinuxというOSを作った人
  
# GitHubとは


# Gitの基本的な仕組み
	
ある時点（瞬間）における対象の全体像を丸ごと写し取ったものを表す。 ストレージ（外部記憶装置）上のファイルシステムを丸ごとコピーしたものや、データベースの複製などを指すことが多い。
	
# gitの操作の流れを掴もう
	
コミット：スナップショットを記録すること
	
## ローカルは3つのエリアに分かれている(ワークツリー->ステージ->リポジトリ)

1.ワークツリー：スナップショットを記録 (git commit)コミット
2.ステージ：コミットする変更を準備 (git add) 追加
3.リポジトリ：ファイルを変更する作業場

# Gitのデータ管理の補足

## treeコマンドのインストール方法

1. ホームディレクトリ直下に .bashrc  ファイルを作成します (~/.bashrc )

2. そのファイルに以下を記載します。

        alias tree='cmd //c tree //A //F'
	
3. Git Bashを再起動します。

# 変更を記録

	$ git commit -v
	変更内容をコミット前にもう一度確認することができる
	
# 現在の状況を確認

	$ git status
	
# 変更差分を確認

## git addする前の変更分

	$ git diff
	$ git diff <ファイル名>

## git addした後の変更分

	$ git diff --staged
	
# 変更履歴を確認

	$ git log
	
## 一行で表示する

	$ git log --oneline
	
## ファイルの変更差分を表示する

	$ got log -p index.html
	
## 表示するコミット数を制限する

	$ git log -n <コミット数>
	
# ファイルの削除を記録する

## ファイルごと削除(git記録もワークツリーも削除)

	$ git rm <ファイル名>
	$ git rm -r <ディレクトリ名>
	
## gitの記録だけを消してワークツリーのファイルを残したいとき

	$ git rm --cached <ファイル名>

# ファイルの移動を記録

	$ git mv <旧ファイル> <新ファイル>
	
# pushまでの流れ

## リモートリポジトリへのショートカットを作成

「origin」がショートカット名

	$ git reote add origin <URL>

## リモートリポジトリへ送信

	$ git push <リモート名> <ブランチ名>
	$ git push origin master
	
オプション「-u」は、次回以降「git push」だけで送信できるようになる

# コマンドにエイリアスをつける

エイリアスとは、コマンドの文字列を短縮して設定することができる
次回からのコマンド入力を楽にできる

	$ git config --global alias.ci commit
	$ git config --global alias.st status
	$ git config --global alias.br branch
	$ git config --global alias.co checkout
	
# ファイルへの変更を取り消す

	$ git checkout -- <ファイル名>
	$ git checkout -- <ディレクトリ名>
	
## 全変更を取り消す

	$ git checkout -- .
	
# ステージした変更を取り消す

	$ git reset HEAD <ファイル名>
	$ git reset HEAD <ディレクトリ名>
	
## 全変更を取り消す

	$ git reset HEAD .
	
# 直前のコミットをやり直す

	$ git commit --amend
	
**ただし、リモートリポジトリにPushしたコミットはやり直したらダメ**
あくまでこのコマンドが使えるのはpush前

# リモートを表示する

	$ git remote
	
## 対応するURLを表示

	$ git remote -v

設定しているリモートリポジトリの情報を表示する
Webサイトが開く仕組みについてまとめてみる

先日自身のサーバーがウイルスで汚染されて、サイトを開くことができなくなりました。

知人エンジニアの力を借りながら復旧したのですが、その際にWebサイトがブラウザで表示されるまで流れについて教えてもらったのでまとめておきます。
何度かYoutubeや本などで勉強したのですがその際は頭に入ってこなかったですね。

今回は、復旧作業を通して実際に手を動かしながら用語を照らし合わせていったので結構理解できたつもりです。
間違っている箇所や、抜けている箇所があるかもしれませんがご容赦ください。

#名前解決（どこにアクセスするかを決める）

1 PCからURL(http:okalog.info)でDNSサーバーにリクエストが出される。
2. DNSサーバ(お名前ドットコム)から転送されて、DNSサーバー(Xserver)に命令を出す
3. DNS(Xserver)にあるIPアドレスをDNS(お名前ドットコム)を通して、PCに返す。

▶︎簡単に解説
PCからURLを送ります。例えば、私のブログでは、`https://okalog.info`がURLになります。
![46e8ef6120809abff40b6c7c84858ce8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/0fa6a89f-3a42-8d44-ccb8-cf2d12ff7663.png)


この情報をDNSサーバーに送ります。私はお名前ドットコムでドメインを購入しているので、お名前ドットコムのDNSサーバーにつながります。
![7ee1c257ef8d69b5fbb7f4f5cffebd93.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/8331dd46-b0ba-2e57-3d8b-fd19a9c94879.png)


お名前ドットコムでは、ドメインを購入しているだけでサーバーの契約はxserverでしています。
そのため、お名前ドットコムからxserverに情報(`https://okalog.info`)を転送してあげる必要があります。

普段この接続をなにも気にせず行っていたんですが、やっと理解ができました。![347d1a6312c8492ae2aa226fbde3f804.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/1499109d-639a-57c6-3ea7-f0efd80cbea4.png)

![1ec6b51d604e8cf05741489c2584bf10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/4c4182bd-4d0e-198f-7ede-f16be7e942a6.png)


そして、サーバーにはIPアドレスが設定されています。
例えば`https://okalog.info`では`183.181.90.55`がIPアドレスになります。
調べ方は簡単で、ターミナルで`ping okalog.info`と打つと、IPアドレスが表示されます。
![347d1a6312c8492ae2aa226fbde3f804.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/1078bcae-49bb-11d5-fa5e-20569e2acae9.png)


話が逸れましたが、PCからリクエストされたURLがここでIPアドレスと紐づきます。
そして、PCにIPアドレスを返すことになります。

理解をしておくこととしては、ドメイン（`https://okalog.info`）=IPアドレス(`183.181.90.55`) ということですね。
なのでIPアドレスを検索すると、当然ドメイン（`https://okalog.info`）と同じページが表示されるのです。
![cdcb813217f41c7d0b737388d0d5db03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/43481784-e53d-a9b9-8bd6-7eac34d03ca3.png)

※と思っていたのですが、うまく表示されませんでした。原因がわかったら記事更新します。
▶︎追記
リバースプロキシという技術があり、レンタルサーバーはこれを使用しているとのことでした。
難しい、、
https://qiita.com/zawawahoge/items/a931de1464ccaa228551


ちなみにGoogleのIPアドレス(172.217.24.78)で検索すると正しく表示されます。
![1d68eded2bb332636c64250a42270d58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/ec46387e-419b-e51a-c0ac-ac0ac46ed49c.png)

じゃあなんでドメインが必要なのかっていうと、数字の羅列では不便だからということですね。


#クライアント・サーバーシステム
そして、IPアドレスを無事に取得したPCは、次は、APサーバーにファイル探しにいきます。
FTPソフトを使って接続しているのはこのAPサーバーになります。APサーバーには、`index.php`や`imageフォルダ`などが格納されています。基本的に`index.html`や`index.php`に書いてある文書などは、このAPサーバーのファイルに格納されている情報だけで出力することが可能になります。

では、DBサーバーには何が格納されているかというと、

- 記事タイトル
- 記事本文
- 作成日時・更新日時
- タグ・カテゴリー
- ステータス

といった情報が格納されています。なので、`<?php the_content; ?>`や`<?php the_title; ?>`といったコードを書いて出力されている情報というのはDBサーバーから情報を取得しています。

ちなみに、DBサーバーとの接続を決定するファイルが`wp-config.php`になります。
こんな感じで書いてあるので見てみてください。
![f8fe5cca1e4a78bfed20dc236c84e770.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592040/c60b8611-a7f4-5979-8900-f0ffc904340c.png)

#まとめ
名前解決のあたりのDNSサーバーの説明がイマイチしっくりきておらずあっているのか不安ですが、なんとなく理解できたのでとりあえずOKにしています。
もう少し知識がついてきたら情報をアップデートしたいと思います。
SELECTで抽出する際にNULLだけのカラムを追加したい時（MySQL）


何らかの事情で、NULLだけのカラムを作りたい場合、

```
SELECT
Code AS code,
Name AS name,
Continent,
IndepYear,
nullif('','') AS ALLNULL
FROM
country
;
```

このように書いてあげれば


| code | name        | Continent     | IndepYear | ALLNULL |
|------|-------------|---------------|-----------|---------|
| ABW  | Aruba       | North America |       NULL    |  NULL       |
| AFG  | Afghanistan | Asia          |      1919 |     NULL    |
| AGO  | Angola      | Africa        |      1975 |     NULL    |
| AIA  | Anguilla    | North America |         NULL  |   NULL      |

NULLだけのカラムを作り出せます。

nullif('','')の応用です。

nullifについては以前書いたのでこちらを参考にしてもらえればと思います。
[MySQLでSELECTにて抽出するときに出る空文字をNULLに変換する。](https://qiita.com/tatema/items/2cd00b3ea636b942ab1c)
sort, sorted の違い（備忘録）

#sortとsortedの違い
初めまして。
これからエンジニアを目指す１９歳です。
今回は、練習問題を解いている時にふと疑問に思ったので、備忘録として
<p><b>sortとsortedの違い</b></p>
について記していこうと思います。どなたかの解決の一助になれば幸いです。
初心者なので見づらいと思いますが、ご容赦下さい。
<p>以下の順で書いていきたいと思います。</p>
ー　sortメソッドとは何か、またどう使うのか
ー　sorted関数とは何か、またどう使うのか
ー　どこが違うのか

###sortメソッドとは何か、またどう使うのか
TechAcademyマガジンによるとsortメソッドについて、以下のように書かれていました。
『sort関数とは、リストの並び替えを行うための関数です。数値や文字列のリストを昇順もしくは降順に並び替えることができます。』
また使い方については、
『sort関数は、「リスト名.sort()」という形で使うことができます。また、reverseという引数を任意で設定することもできます。reverseはデフォルトではFalseになっているので、reverseを特に設定せずに使うと昇順になります。reverse=Trueとすると降順にできます。』
実際にはsortメソッドらしいなのですが、まあ細かいことは置いておいて。
上記の内容によると、sortメソッドは『リスト』の要素の順序変更を操作するメソッドで、例えば
>\>>>str_list = list("qiita")
\>>>str_list.sort()
\>>>print(str_list)
['a', 'i', 'i', 'q', 't']

や
>\>>>str_list = list("qiita")
\>>>str_list.sort(reverse=True)
\>>>print(str_list)
['t', 'q', 'i', 'i', 'a']

と言うようにすればよいらしいです。
###sorted関数とは何か、またどう使うのか
dot blogによると
『sorted関数はPythonの組み込み関数の1つでリストやタプル、辞書、セット、文字列といった複数の要素を持つオブジェクト内の要素をソート（並び替え）し新たなリストで返す関数』
と記されており、例えば
>\>>>x = (5, 8, 4, 1, 3, 2, 7, 6)
\>>>y = sorted(x, reverse=True)
\>>>print(y)

と入力しても
>[8, 7, 6, 5, 4, 3, 2, 1]

と出力されるようです。タプル化する為には
>\>>>x = (5, 8, 4, 1, 3, 2, 7, 6)
\>>>y = tuple(sorted(x, reverse=True))
\>>>print(y)

とすればタプル化されて出力さるようです。
また辞書にsorted関数を使用をすると
>\>>>sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]

辞書の要素がリスト化されて出力されるらしいです。

###どこが違うのか
さてここまでの内容でほとんど答えは出ているので、まとめ的な形で記そうと思います。
・sortメソッドはリストにのみ適用可能で、元のリストをそのまま利用して並び替えを行う。
・一方、sorted関数はイテラブルなものに対して有効であり、並び替えをした後は新たなリストに要素を入れる。
と言うような違いがありました。
ここからは余談になりますが、
sortメソッドやsorted関数には、引数にkey=関数と指定すると、
その関数の値を比較基準にして、並び替えを実施するらしいです。
例えば、Python3.9ドキュメントによると、
>大文字小文字を区別しない文字列比較の例:

>\>>>sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

他にも
>\>>>student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
]
\>>>sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

上記のような使い方もできるようです。
（捕捉）
key=関数名とすると、最初にイテラブルオブジェクトの各要素に対してその関数の機能を実施し、その後並び替えを行なっているそうです。
例えば、上記の二つの例で言うと、
前者では最初にリスト化した文字列の各要素を全て小文字に置き換えた後、並び替えを行なっているそうです。（しかし、出力の際には元の要素に戻っている。）
なので、大小関係なく並び替えが実施されるようです。
続いて、後者ではラムダ式を用いているのですなわち、
>\>>>def ~~(student):
    return student[2]

と言うことになり、この無名関数の実引数に上記のリストの各要素（すなわち上記のタプル）が代入され、そのインデックス番号が２の値が返り値として返されたのち、それを比較対象として並び替えを行う。
ここで一つ疑問に思ったこと。
『仮に上記のインデックス番号が、同値なら次に比較されるものはなんなのか。』
どなたかご教授願えますでしょうか。


ふう。初めて書きましたが、時間と体力を使いますね。
また次回、気になったことがあったら書いていきたいと思います。
誤り等がございましたら、ご指摘のほどよろしくお願いします。

最後まで長い長い旅に付き合っていただきありがとうございました。
次回もよろしくお願いします。
MySQLでSELECTにて抽出するときに出る空文字をNULLに変換する。

MySQLで空白の文字列をNULLに変換する方法を記載します。


| Code | Name        | Continent     | IndepYear | test |
|------|-------------|---------------|-----------|------|
| ABW  | Aruba       | North America |      NULL |      |
| AFG  | Afghanistan | Asia          |      1919 |      |
| AGO  | Angola      | Africa        |      1975 |      |
| AIA  | Anguilla    | North America |      NULL |      |

というテーブルがあったとします。
このtestカラムの中の空文字をSELECTで抽出するときは全てNULLに変えたい場合です。

```
SELECT
Code,
Name,
Continent,
IndepYear,
nullif(test,'')
FROM
country
;
```

とSELECT文を書き実行すると、

| Code | Name        | Continent     | IndepYear | nullif(test,'') |
|------|-------------|---------------|-----------|------|
| ABW  | Aruba       | North America |      NULL | NULL |
| AFG  | Afghanistan | Asia          |      1919 | NULL |
| AGO  | Angola      | Africa        |      1975 | NULL |
| AIA  | Anguilla    | North America |      NULL | NULL |

このように表示されます。

`nullif(カラム名,'NULLに変えたい文字列')`
ということになります。

カラム名を整えたいなら、

```
SELECT
Code,
Name,
Continent,
IndepYear,
nullif(test,'') as test
FROM
country
;
```

としてあげれば

| Code | Name        | Continent     | IndepYear | test |
|------|-------------|---------------|-----------|------|
| ABW  | Aruba       | North America |      NULL | NULL |
| AFG  | Afghanistan | Asia          |      1919 | NULL |
| AGO  | Angola      | Africa        |      1975 | NULL |
| AIA  | Anguilla    | North America |      NULL | NULL |

になります。
Java: Guavaの@VisibleForTestingとは何か

# 概要
- [Guava](https://github.com/google/guava)には、[@VisibleForTesting](https://guava.dev/releases/30.0-jre/api/docs/com/google/common/annotations/VisibleForTesting.html)というアノテーションが用意されている
- テストコードを書くために、やむを得ずメソッドやメンバーの可視性を上げる必要があるときに付与する
- 「テストコードのために可視性を上げている」ことを示すための目印になる

# サンプルコード

```java
import com.google.common.annotations.VisibleForTesting;

public class Sample {

    @VisibleForTesting
    String load() {
        // 省略
    }

}
```

詳しい利用例は、[単体テストを書くためにstaticメソッドから脱却しよう #1 原則・ラップメソッド](https://qiita.com/flyaway/items/34069ca6ad9ada4c0fef)で解説している。

# [@VisibleForTesting](https://guava.dev/releases/30.0-jre/api/docs/com/google/common/annotations/VisibleForTesting.html)を付与するメリット

## 可視性を上げている理由を示す目印になる

「テストコードのために可視性を上げている」ことを示すための目印にすることができる。
アノテーション単独では特別な働きをすることはなく、単なる目印である(マーカーアノテーションと呼ばれる)。

## 静的解析で誤りをチェックすることができる

たとえば、静的解析ツールの一つである[SonarQube](https://www.sonarqube.org/)には、`@VisibleForTesting` を付与されたメンバやメソッドが、誤って(テストコード以外の)他のクラスのコードからアクセスされていないかをチェックするルールが存在している。このルールを利用することで、意図しない動作を早期に検知することができる可能性がある。

[Rule S5803: Class members annotated with @VisibleForTesting should not be accessed from production code](https://jira.sonarsource.com/browse/SONARJAVA-3372)

# 注意点

[JavaDoc](https://guava.dev/releases/30.0-jre/api/docs/com/google/common/annotations/VisibleForTesting.html)にある通り、本来はアクセス範囲を**privateからデフォルト(パッケージプライベート)に変更するため**に用いられる。単体テストを書くだけであればデフォルトで十分であり、publicやprotectedに変更するのは悪い設計である。

なお、[VisibleForTesting plugin for SonarQube](https://github.com/arxes-tolina/sonar-plugins#misuse-of-visiblefortesting)では、誤ったアクセス修飾子が付与されていないかをチェックできる。
※追記：バージョンが古く、正常に動作しない模様。[フォークされた版](https://github.com/whi-terao-t/sonar-plugins)では、SonarQube 8.9での動作を確認済み。

# その他の `@VisibleForTesting` アノテーション

他のライブラリ・APIにも、類似のアノテーションが存在するものがある。

|ライブラリ・API|完全修飾クラス名|
|----|----|
|[AssertJ](https://assertj.github.io/doc/)|[org.assertj.core.util.VisibleForTesting](https://joel-costigliola.github.io/assertj/core-8/api/org/assertj/core/util/VisibleForTesting.html)|
|[Android](https://developer.android.com/reference)|[androidx.annotation.VisibleForTesting](https://developer.android.com/reference/androidx/annotation/VisibleForTesting)|
|[Apache Flink](https://flink.apache.org/)|[org.apache.flink.annotation.VisibleForTesting](https://ci.apache.org/projects/flink/flink-docs-release-1.11/api/java/org/apache/flink/annotation/VisibleForTesting.html)|

# 参考URL

- [プライベートメソッドのテストは書かないもの？ - t-wadaのブログ](https://t-wada.hatenablog.jp/entry/should-we-test-private-methods)
【Android】【初心者】画像ロードライブラリ Coil 使ってみた

# 【Android】【初心者向け】画像ロードライブラリ Coil 使ってみた

## Coilとは
Androidの画像ロードライブラリです。
GlideやPicassoなどがよく使われているのかなと思いますが、CoilはKotlin firstであるのと、Kotlin Coroutineを利用したものであるというのが特徴かなと思います。

## 実装手順
### 依存関係の追加

``` build.gradle(app)
dependencies {
  implementation("io.coil-kt:coil:1.0.0")
}
```

* 詰まったこと
coilは、java8でないといけないみたいで、以下のようなエラーが出ました。

```
Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
```

* 対処法

jvm targetを8に変更してあげると、ビルドできました。
jvm targetをいじるのは初めてであまりよくわかってないです。

``` build.gradle(app)
android {
  kotlinOptions {
      jvmTarget = '1.8'
  }
}

```

### コード
``` sample.kt
// StringのURLを持っているとして
// ImageViewに対して、loadを実行するだけ
imageView.load("URL")
```

loadに渡すものは、FileやUriクラスでも可能です。

## 試しに使ってみたスクショ
* 今回やってみてるのは、Qiitaの記事を検索して、投稿者の画像を取得しています。

![スクショs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315689/6becf701-83ff-1142-e98d-01de1a9408df.png)


## 参考
[Androidの画像ロードライブラリ「Coil」のセットアップ&使い方(Kotlin)](https://qiita.com/uhooi/items/6389857820fc634dadba)
[［Android］ 画像読み込みライブラリ Coil でできることまとめ](https://qiita.com/kaleidot725/items/b2ca56bfc5a8120efcea)
個人的kubectlチートシート

公式のチートシートが以下にあるので，これで十分だと思います．

[kubectlチートシート | Kubernetes](https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/)

個人的によく使うものをチートシートを作りました．

## リソースの操作

作成/更新

```
kubectl apply -f xxx.yaml
```

削除

```
kubectl delete -f xxx.yaml
```

## ネームスペースの操作

新規作成

```
kubectl create namespace <namespace>
```

確認(一覧)

```
kubectl get ns
```

デフォルトネームスペースを変更

```
kubectl config set-context --current --namespace=dev-koyama
```

現在のネームスペースを取得

```
kubectl config view -o jsonpath='{.contexts[].context.namespace}' ; echo
```

## コンテキストの操作

現在のコンテキスト

```
kubectl config current-context
```

利用できるコンテキスト一覧

```
kubectl config get-contexts
```

使用するコンテキストを設定

```
kubectl config use-context <CONTEXT_NAME>
```

## ラベルの操作

Podごとのラベル一覧

```
kubectl get pods --show-labels
```

## サービスの操作

ServiceのTypeをNodePortへ変更

```
kubectl patch service my-svc -p '{"spec":{"type":"NodePort"}}'
```

## クラスタの操作

現在の設定を確認

```
kubectl config get-contexts
```

設定を変更

```
kubectl config use-context docker-desktop
```

## コンテナでコマンドを実行

podが複数コンテナの場合

```
kubectl exec <pod_name> --container <container_name> -- <command> 
```

podが単一コンテナの場合

```
kubectl exec <pod_name> -- <command> 
```

## コンテナのシェルに入る

podが複数コンテナの場合

```
kubectl exec -it <pod_name> --container <container_name> -- /bin/bash
```

podが単一コンテナの場合

```
kubectl exec -it <pod_name> -- /bin/bash
```

## レプリカ数の変更

```
kubectl scale --replicas=1 -f rs.yaml
```

## デバッグ用コンテナを1つデプロイ

`--rm` をつけるとexitするとコンテナが消える．

```
kubectl run -it --rm ubuntu --image=ubuntu:18.04 /bin/bash
```
[OCI][Windows]コンピュートインスタンスの自動起動/停止を、外部の常時起動Windows機から制御する


例えば、昼のビジネス時間だけコンピュートインスタンスを動かしておきたいというニーズはあると思います。
そこで、稼働場所はどこでも良いですが、常時起動しているWindows機から、タスクスケジューラーを使って自動でOCIコンピュートインスタンスの起動停止をする仕組みを作ってみたいと思います。
# 設定手順
### 1.OCI CLIの設定
PowerShell版のOCI CLIが設定済みであることが前提となります、
https://docs.cloud.oracle.com/ja-jp/iaas/Content/API/SDKDocs/cliinstall.htm
などを参考にOCI CLIをWindowsにインストールします。

### 2.インスタンス起動/停止コマンドの作成

制御対象のコンピュートインスタンスの起動コマンドと停止コマンドを作成します。
まず制御対象のコンピュートインスタンスのOCID を確認します。

![image-20201107143745788.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/acfed926-d0de-56cc-5cc6-8e17d9c0c898.png)

そのOCID を使って、以下の2つのPowerShellコマンドを作成します。

**startInstance.ps1**

```PowerShell
$instanceid = "ここに管理対象コンピュートインスタンスOCIDを貼り付ける"
oci compute instance action --instance-id $instanceid --action START

```

**stopInstance.ps1**

```PowerShell
$instanceid = "ここに管理対象コンピュートインスタンスOCIDを貼り付ける"
oci compute instance action --instance-id $instanceid --action STOP 
```

### 3.インスタンス起動停止コマンドの動作確認

起動と停止の両方のコマンドが用意できたので、交互に起動して、対象インスタンスが動いたり止まったりすることを確認します。

![image-20201107144000878.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/61adf749-1f5e-1968-01d2-8e57f92f679c.png)

### 4.タスクスケジューラーへの登録

Windowsの検索バーで“tasks” などの文字列でタスクスケジューラーを探して起動します。
アプリケーション毎にフォルダーを作るお作法なようなので、ここではOracleCloudというフォルダーを作ります。

![image-20201107144131884.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/333387e3-b20b-29b6-2aba-e6ba144c7e5f.png)

続いて、「基本タスクの作成」で操作の名前に "startInstance" (任意)と、説明"start OCI Instance"(任意)を登録します。

![image-20201107144430811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/63554892-bbec-d467-3de6-a89b4e88a2ce.png)

続いて時間で動作するトリガーの設定をします。

「タスクトリガー」は毎日
起動時間は任意、最初は動作確認するので、現在時間に近い時間で良いと思います。
タイムゾーン間で同期はチェックしません、これをチェックするとUTCの時間とみなされます。



![image-20201107145103897.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/6643cca6-ca4e-76d1-db9f-236cd6492005.png)

上記と同様にstopInstanceも登録します。

![image-20201107145506747.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3968/dc2cd221-de07-cc46-91c1-71b73908ebf4.png)

これで、自動でCompute Instanceの自動起動停止ができるようになりました。
インスタンスを放っておいても夜には止まります。

### Tips

この方法以外には、Loadbalancerの稼働インスタンス数を変化させる方法もあります。
なので、ここに記載した方法は、単純に一台のインスタンスを管理したい時に適したものだと思います。
【Rails】Rubocop実行時の「Use hash rockets syntax」を回避する方法

## 「Use hash rockets syntax」が大量に出てしまう事態

Rubocopを導入し、ターミナルで「rubocop」を実行すると下記のように
**「Use hash rockets syntax」**の指摘が大量に出てきてしまいました。

ググってもあまり記事は出てきませんでしたが、
「hash rockets syntax」は下記の記事でも書いている通り、
[Rubyのハッシュの記法まとめ](https://qiita.com/YusukeHigaki/items/18db85aa9cba3cb42569)

```ruby
user = { :first_name => "Yusuke", :last_name => "Higaki" }
```
⇒こういった、**「key => value 」**の形式のハッシュのことです。

## Rubocop実行時に出てしまった指摘

```bash
$ rubocop
Inspecting 87 files
....CCCCC.CC....CC.CC..........C.CC.CCCCCC.C...C..CC......C.....C.C.........CCCCC.CCCCC

Offenses:
app/controllers/communities_controller.rb:3:40: C: Style/HashSyntax: Use hash rockets syntax.
    before_action :validate_community, only: %i[edit update destroy]
                                       ^^^^^
app/controllers/communities_controller.rb:15:39: C: Style/HashSyntax: Use hash rockets syntax.
       @belongings = Belonging.where(community_id: @community.id)
                                      ^^^^^^^^^^^^^
app/controllers/communities_controller.rb:21:31: C: Style/HashSyntax: Use hash rockets syntax.
       @posts = @posts.where(community_id: @community.id)
                              ^^^^^^^^^^^^^
app/controllers/communities_controller.rb:24:44: C: Style/HashSyntax: Use hash rockets syntax.
       @belonging = Belonging.find_by(community_id: @community.id, user_id: current_user.id)

（以下略）
```

結論、下記を`.rubocop.yml`に追記したら、このタイプの指摘は出なくなりました。

```ruby:.rubocop.yml
HashSyntax:
  EnforcedStyle: ruby19
```

⇒これは、**「ハッシュの記法はロケット記法ではなくruby1.9のハッシュ記法を使いますよ」**ということを表します。

**「ruby1.9のハッシュ記法」**とは、
今回のrubocop実行時に指摘があった箇所に記載されているように、
ロケット記法を使わず、**「key: value」**の形でハッシュを記載する形式のことです。

そもそもruby1.9のハッシュ記法で初めから指摘を受けてないような、もっと根本的な解決策があるかもしれません。
ご存知の方は、是非ご教示いただけますと幸いです。
[Swift] カップル👫👬👭の絵文字を全バリエーション取得する

# カップル絵文字
正確には「👫(MAN AND WOMAN HOLDING HANDS)」「👬(TWO MEN HOLDING HANDS)」「👭(TWO WOMEN HOLDING HANDS)」の3つの絵文字とそのバリエーションのことです。
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638786/c65edd7f-e1e8-8dfe-b777-dc0b0c5a6e5e.png">
入力しようとするとそれぞれの肌の色を選ぶ画面が表示されます。

## 肌の色を選ばない場合
シンプルにU+1F46B、U+1F46C、U+1F46Dの絵文字が入力されます。

## 肌の色を選ぶ場合
試してみましたが、片方だけ肌の色を選ぶ、という選択肢はなさそうです。

### 両者の肌の色が同じ場合
「👭🏽」の場合、基盤となるU+1F46D「👭」に対して「U+1F3FD(&#x1F3FD;) EMOJI MODIFIER FITZPATRICK TYPE-4」を付加したものが入力されます。
他の場合も同様に基盤となる文字に対して肌の色を示すmodifierが付加されます。

### 両者の肌の色が異なる場合
この場合以下の文字列が入力されます。

```
"👩"+"{modifier}"+"\u200D"+"🤝"+"\u200D"+"👨"+"{modifier}"
"👨"+"{modifier}"+"\u200D"+"🤝"+"\u200D"+"👨"+"{modifier}"
"👩"+"{modifier}"+"\u200D"+"🤝"+"\u200D"+"👩"+"{modifier}"
```

U+200D(ZERO WIDTH JOINER)が入っているのも面白いですが、「🤝」が含まれているのがなかなか面白いですね。
この表示は両者の肌の色が等しくても上手く行きますが、なるべく短く表示するため等しい場合のみ特別に動作が変わっているようです。

# 全バリエーションを表示する
というわけで、全てのバリエーションを取得するにはこれでいけます。

```swift
let colors = ["", "\u{1F3FB}","\u{1F3FC}","\u{1F3FD}","\u{1F3FE}","\u{1F3FF}"]
let genders = [(left: "👩", right: "👨"),(left: "👨", right: "👨"),(left: "👩", right: "👩")]
let bases = ["👫","👬","👭"]
let joint = "\u{200D}"
let result = colors.flatMap{(leftColor: String) -> [String] in
    colors.flatMap{(rightColor: String) -> [String] in
        if leftColor == rightColor{
            return bases.map{$0 + rightColor}
        }else{
            if leftColor.isEmpty || rightColor.isEmpty{
                return []
            }
            return genders.map{gender in
                gender.left + leftColor + joint + "🤝" + joint + gender.right + rightColor
            }
        }
    }
}
```

「👫👬👭👫🏻👬🏻👭🏻👩🏻‍🤝‍👨🏼👨🏻‍🤝‍👨🏼👩🏻‍🤝‍👩🏼👩🏻‍🤝‍👨🏽👨🏻‍🤝‍👨🏽👩🏻‍🤝‍👩🏽👩🏻‍🤝‍👨🏾👨🏻‍🤝‍👨🏾👩🏻‍🤝‍👩🏾👩🏻‍🤝‍👨🏿👨🏻‍🤝‍👨🏿👩🏻‍🤝‍👩🏿👩🏼‍🤝‍👨🏻👨🏼‍🤝‍👨🏻👩🏼‍🤝‍👩🏻👫🏼👬🏼👭🏼👩🏼‍🤝‍👨🏽👨🏼‍🤝‍👨🏽👩🏼‍🤝‍👩🏽👩🏼‍🤝‍👨🏾👨🏼‍🤝‍👨🏾👩🏼‍🤝‍👩🏾👩🏼‍🤝‍👨🏿👨🏼‍🤝‍👨🏿👩🏼‍🤝‍👩🏿👩🏽‍🤝‍👨🏻👨🏽‍🤝‍👨🏻👩🏽‍🤝‍👩🏻👩🏽‍🤝‍👨🏼👨🏽‍🤝‍👨🏼👩🏽‍🤝‍👩🏼👫🏽👬🏽👭🏽👩🏽‍🤝‍👨🏾👨🏽‍🤝‍👨🏾👩🏽‍🤝‍👩🏾👩🏽‍🤝‍👨🏿👨🏽‍🤝‍👨🏿👩🏽‍🤝‍👩🏿👩🏾‍🤝‍👨🏻👨🏾‍🤝‍👨🏻👩🏾‍🤝‍👩🏻👩🏾‍🤝‍👨🏼👨🏾‍🤝‍👨🏼👩🏾‍🤝‍👩🏼👩🏾‍🤝‍👨🏽👨🏾‍🤝‍👨🏽👩🏾‍🤝‍👩🏽👫🏾👬🏾👭🏾👩🏾‍🤝‍👨🏿👨🏾‍🤝‍👨🏿👩🏾‍🤝‍👩🏿👩🏿‍🤝‍👨🏻👨🏿‍🤝‍👨🏻👩🏿‍🤝‍👩🏻👩🏿‍🤝‍👨🏼👨🏿‍🤝‍👨🏼👩🏿‍🤝‍👩🏼👩🏿‍🤝‍👨🏽👨🏿‍🤝‍👨🏽👩🏿‍🤝‍👩🏽👩🏿‍🤝‍👨🏾👨🏿‍🤝‍👨🏾👩🏿‍🤝‍👩🏾👫🏿👬🏿👭🏿」で全部です。
カスタムMixタスクでEcto経由でデータベースを操作する(Elixir)

# はじめに
- カスタムMixタスクでEcto経由でデータベースを操作したいです
    - [Mix.Task](https://hexdocs.pm/mix/Mix.Task.html#content)は独自に作れるんです
- 私は前提知識として、`lib/mix/tasks/hoge.ex`つくれば、`mix hoge`で実行できるタスクを実装できるのですよね〜 というところまでは知っていました
- 今回はそのタスクの中でEcto経由でデータベースを操作することをしてみたときに、エラーに遭遇しまして、解決策がわかりましたのでその記録を残しておきます
    - `Phoenix`タグをつけるかどうかは迷ったのですが、まあ[Phoenix](https://www.phoenixframework.org/)アプリを作っているときに遭遇したのでつけておきました


# カスタムMixタスク
```elixir:lib/mix/tasks/db_all_delete.ex
defmodule Mix.Tasks.DbAllDelete do
  use Mix.Task

  def run(_) do
    Mix.Task.run "app.start", []

    Demo.Repo.delete_all(Demo.Accounts.User)
  end
end
```

- `Mix.Task.run "app.start", []`の呼び出しが必要になります
- [Gigalixir](https://gigalixir.com/)にデプロイしている場合には、`gigalixir run mix db_all_delete`なんて感じで実行できます

## `Mix.Task.run "app.start", []`の呼び出しがない場合

```elixir
$ mix db_all_delete                                                                                                                     
Compiling 1 file (.ex)
** (RuntimeError) could not lookup Ecto repo Demo.Repo because it was not started or it does not exist
    lib/ecto/repo/registry.ex:19: Ecto.Repo.Registry.lookup/1
    lib/ecto/repo/queryable.ex:210: Ecto.Repo.Queryable.execute/4
    lib/mix/tasks/db_all_delete.ex:7: Mix.Tasks.DbAllDelete.run/1
    (mix 1.10.4) lib/mix/task.ex:330: Mix.Task.run_task/3
    (mix 1.10.4) lib/mix/cli.ex:82: Mix.CLI.run_task/2
    (elixir 1.10.4) lib/code.ex:926: Code.require_file/2

```
- Ecto repoが始まっていないだなんだ言われています

# 参考記事
- 詳しくはこれらの記事をご参照ください
- [How to get data from Ecto in a custom mix task](https://stackoverflow.com/questions/38225406/how-to-get-data-from-ecto-in-a-custom-mix-task)
- [カスタムMixタスク#アプリケーションの読み込み](https://elixirschool.com/ja/lessons/basics/mix-tasks/#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF)
    - ありがとうございます！

# Wrapping Up :lgtm: :qiitan: :lgtm:
- [カスタムMixタスク](https://elixirschool.com/ja/lessons/basics/mix-tasks)については、リンク先が詳しいです
    - [Mix.Task](https://hexdocs.pm/mix/Mix.Task.html#content)
- Enjoy [Elixir](https://elixir-lang.org/) !!! :rocket::rocket::rocket:
Vue CLIでPugを使いたい！

Vue CLIでHTMLを書くとき、Pugを使いたいと思い調べました。

##環境

macOS バージョン10.15.7
vue/cli バージョン4.5.8

##やったこと

`vue create ディレクトリ名`
でプロジェクトを作成した後、

`vue add pug`

を実行。

あとはvueファイルの`<template>`タグに`lang="pug"`を追加すると、`</template></template>`の中でPugを使えます。

##参考リンク
https://www.npmjs.com/package/vue-cli-plugin-pug
Python人間のRust世界転生記録 ～数列のパーサー編～

##はじめに
　こんにちは、麻菜結と申します。人が新たなプログラミング言語を学ぶときは、当然ですがそれまでに学んできた知識と照らし合わせて吸収するのが普通と思われます。「この言語のこの機能、この言語で言い換えるとこんなかんじだよなぁ」といった風ですかね。自分はこの言い換える説明の仕方には大きな価値を感じていて、あらゆる言語でそんな説明してくれないかなと思っています。というわけで、この記事では「Pythonはそこそこ慣れててるんだけど、Rustでこんな操作したいとき、どうしたら良いんだろう？」という方に向けて、ちぎったパンで目印をつけるがごとく足跡を残していく記事です。
　今回は競技プログラミングでありがちな、数列を渡された時どうやって配列にしまおうかという話をしたいと思います。

##環境
　使う環境はWindowsです。そこまでクリティカルな話はしないのであんまり気にしなくていいと思われますが。

```powershell
PS C:\> cargo --version
cargo 1.43.0 (3532cf738 2020-03-17)
PS C:\> python --version
Python 3.8.2
```

##想定される問題A
　今回想定する入力は以下のものです。数列aを格納するリストを考えます。

```
n            # 数字の数
a1 a2... an  # 数列
```
　例えば、

```
4
5 9 10 6
```

###Python的思考

　Python的思考というと主語がでかいですが、まずは数字の数`n`を捨て、数列の文字列にsplitをかけた後intに変換をしてそれらをmapで拾い集める、ような考え方が一番簡単でしょうか。

```python
input()
n = list(map(int, input().split()))
print(n)
```

###Rustで解くなら？
　標準入力マクロについては考えず、関数で格納するなら、

```rust
fn main(){
    input();
    let n: Vec<i32> = (&input()).split(" ").map(|s| s.parse().unwrap()).collect();
    println!("{:?}", n);
}
fn input() -> String{
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.trim_end().to_string()
}
```
　上のような書き方なら、難しいことなくすんなりわかると思います。
　やっていることと言えば、同様に`n`を捨て、数列の文字列を&str型として持ってきて、splitをかけた後parse（Rustは賢いので左側の型の表示をいい感じに解釈してi32にしてくれます）をして、unwrapで入力がおかしい場合を無視し、mapで値を集めて、collectで適切なコレクションにしてくれる、っていう感じですね。
　input関数については、[自分の過去の記事](https://qiita.com/asana_yui/items/a6261b70cd3de447e805)（上の例はtrimのとこ変わってる）をどうぞ。

##想定される問題B
　では以下の場合はどうしましょう。アルファベットは無視してaとbを二次元リストに格納する場合を考えます。

```
n          # データの個数
x1 a1 b1   # x:アルファベット
x2 a2 b2   # a:数字
...        # b:数字
xn an bn

```
　例えば、

```
2
a 2 3
b 8 6
```

###Python的思考
　nをループ回数として保存しておいて、データの行に入ったら一文字目をはねて、二文字目以降を読み取っていくというのが一般的な考え方でしょうか。

```python
n = int(input())
l = []
for _ in range(n):
    l.append([int(e) for e in input().split()[1:]])
print(l)
```

###Rustで解くなら？

```rust
fn main(){
    let raw = input();
    let n: i32 = raw.parse().unwrap();
    let mut v: Vec<Vec<i32>> = Vec::new();
    for _ in 0..n {
        let raw = input();
        let s: Vec<&str> = raw.split(" ").collect();
        v.push([1, 2].iter().map(|i| s[*i as usize].parse::<i32>().unwrap()).collect());
    }
    println!("{:?}", v);
}
fn input() -> String{
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf).unwrap();
    buf.trim_end().to_string()
}

```

　`let raw = input();`と書いておくと`raw`に標準入力の値を縛っておけるのでこの言語特有の貸し借りに関して管理が楽になります。
　見てもらいたいのは`[1, 2].iter().map().collect();`のあたりで、横幅が固定されているタイプの入力にはこのような書き方をするとかなり楽になります。
　`[]`で固定長の配列を使い、それをiterを通してmapに注ぎ入れることで、要素のアクセスの順番や場所の制御が簡単になります。この例だとgetとか使ってもいけそうですが、うまくいかんかったという敗北宣言を残しておきます。

##結論
**mapを使いこなせ！**
**collectとunwrapを忘れるな！**

##おわりに
　今回は、頭が切り替えられない人間が異世界でわちゃわちゃしてみたという感じでしたがいかがでしたでしょうか。これからもこんな感じの気づきをQiitaに残せたら良いな…自分が忘れたときの為に。なおシリーズものみたいなタイトルをしていますが、Rustを覚える->atCoderで使う->Qiitaにあげておくというプロセスを踏まないといけないので次があるかわかりません。`麻菜先生の次回作にご期待ください。`
　ここまでお読みくださってありがとうございました。役に立ったなら幸いです。
Mac Visual Studio Code のターミナルのShellをZshに変更できない時の対処法

# 通常は以下のコマンドで変更できます

```
# zshをデフォルトに設定
$ chsh -s /bin/zsh

# ログインシェルを表示
$ echo $SHELL
# 以下のように表示されれば成功
/bin/zsh

```

# $ echo $SHELLを記入しても/bin/bashのまま
実はこれかなりあるみたいです。
原因は分からないのですが、ターミナルの操作以外でzshに変える方法が２つあります。
順番に見ていきましょう。

### ①ターミナルを再起動する
これはかなり、初歩的ですがこれで情報が更新されて、
表示がzshになる場合があります。

### ②システム環境設定から変更する
こちらの方がめんどくさいのでやはりターミナル上での操作が便利なのですが、
以下の画像の手順でできてしまいます。
![システム環境設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625088/6cb58f41-fe27-2cfb-7f7d-93ac6eb01ca5.png)

![ユーザとグループ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625088/e04b2246-d6a8-faed-c31b-b9fb46cbd9ab.png)

![ユーザとグループ-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625088/14474589-b542-6a33-eab5-ecbc5e8027a3.png)

![スクリーンショット_2020_11_07_20_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625088/e3f38e43-6d55-ddda-b269-808435a6be01.png)

これで変更ができているはずです。
コマンド系はどうしてもうまくいかない場合があるので、別の方法を知っている強さを実感じた日でした。
CSSの@font-faceにおける src: local()の指定について

FirefoxやChromeで、Stylusを使ってフォントをお気に入りのものと置き換えたりしているが、フォントの指定で悩んだので、備忘として書いておく。

Stylusの導入などは、[【参考】FirefoxにおけるWebページの表示から、ＭＳ Ｐゴシックとかを駆逐する。その方法](https://qiita.com/rapidliner00/items/54e8dd19a9bbfb6aa745) などを参照されたい。

例えば、MS Pゴシックをメイリオに置き換えるときは以下のようにするのだが、

```css
@font-face {
    font-family: 'MS Pゴシック';
    font-weight: normal;
    src: local(Meiryo); /* 'メイリオ'では上手く行かない */
}

```

`src: local()`で指定するフォント名は。`メイリオ`ではなく`Meiryo`でないとうまくいかない。
これは、置き換え前のフォントはfont-familyで指定するが、**src:local()のカッコ内はfont-face名(Postscript名)でないといけない**のである。

フォントフェイス名(Postscript名)の調べ方は、DTL OTMaster Lightをダウンロード
し、nameテーブルの6番を確認すれば良い。

以下は、Ricty Diminished ([https://rictyfonts.github.io/diminished](https://rictyfonts.github.io/diminished)) の例である。
font-familyはRicty Diminishedで、font-faceはRictyDiminished-Regularであることが分かる。
![dtl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/cd98269a-03a7-2fa2-a8a8-9b883bfded2c.png)

【参考資料】山田敬美: [Modern 日本語フォント指定](http://cssnite.jp/lp/lp47/followup/CSSNiteLP47-s7-yamada.pdf)
【Unity】Consoleのログにファイルへのリンクを埋め込む

# TL;DR;
```csharp
Debug.Log($@"<a href=""{filePath}"" line=""{line}"">link</a>");
```

![codelin.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280975/7be2a6fb-c7e1-bf90-e9ad-babec68e2bae.gif)


# ConsoleWindow以外で

`UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal`で即時開くことができます。
Button等で蹴ってあげればいいでしょう。

また、ConsoleWindowと同じようにAタグによってリンクを張ることもできます。ただし、GUIStyleを`CN Message`にしておく必要があります。

```csharp
static Lazy<GUIStyle> STYLE = new Lazy<GUIStyle>(() => (GUIStyle)"CN Message");
EditorGUILayout.SelectableLabel($@"<a href=""{filePath}"" line=""{line}"">link</a>", STYLE.Value);
```

# Sample project

https://github.com/wallstudio/UnityTest_2019_4_4/blob/codelink/Assets/Editor/TestEditor.cs

# 参考

[Unity-Technologies / UnityCsReference (github)](https://github.com/Unity-Technologies/UnityCsReference)