OmniAICreator/Qiita-1.07M huggingface dataset:
【GAS】緯度経度から２点間の距離を求める

##概要
仕事で距離を知りたいことが多く、いつもGoogleMapの「距離を測定」で測っていたけれど、これってもしかして計算できるのでは？と思いググったところ、出るわ出るわ緯度経度から２点間の距離を求める方法。

地球を楕円体として見たとして、いくつかの定数が分かればヒュベニの公式ってので求まるらしい・・・。

##続編あり
「測地線航海算法」で、より高精度に距離を求める続編あり。
Qiita記事：[緯度経度からの距離計算 ヒュベニより航海算法の方が高精度説](https://qiita.com/YasumiYasumi/items/3ed8ea69b85dac055381)

この記事での問題点なども解決^^)b 閑話休題

##取りあえず結論＆コード
色々あって、２点の緯度と経度を入れたら距離[km]を計算することに成功！問題や疑問は残ったけども、取りあえず自分の仕事で使うには実用レベルの物が完成。

スプレッドシートのセル上で、次のように距離を求められるようにした。
`=関数(緯度A, 経度A, 緯度B, 経度B)`

理屈やら検討は後回しにして「コード.gs」がコチラ。

```javascript
function measureDistance(latA,lngA,latB,lngB){ 
   
  //定数定義 
  const a = 6377397.16;             //長半径a(m) 
  const b = 6356079;                //短半径b(m) 
  const E2 = 0.006674361028297;     //第一離心率eの二乗 
  const M_numer = 6334832.10663254; //子午線曲率半径Mの分子a(1-e^2) 
   
  //緯度経度をラジアンに変換 
  var latARad = latA * (Math.PI/180); 
  var lngARad = lngA * (Math.PI/180); 
  var latBRad = latB * (Math.PI/180); 
  var lngBRad = lngB * (Math.PI/180); 
   
  //緯度経度の差 
  var dy = latARad - latBRad; 
  var dx = lngARad - lngBRad; 
   
  //緯度の平均値 
  var latAve = (latARad + latBRad) / 2; 
   
  //子午線曲率半径M 
  var sinP = (Math.cos(latAve)); 
  var sinP2 = sinP * sinP; 
  var W_ofroot = 1 - (E2 * sinP2); 
  var W = (Math.sqrt(W_ofroot)); 
  var W3 = W*W*W; 
  var M = M_numer / W3; 
   
  //卯酉線曲率半径N 
  var N = a / W; 
   
  //途中式
  var f1 = dy*dy*M*M; 
  var f2 = dx*N*(Math.cos(latAve)); 
  var f3 = f2 * f2; 
  var f4 = f1 + f3; 
   
  //2点間の距離（ｍ→ｋｍ）
  var D = (Math.sqrt(f4)); 
  var km = D / 1000; 
   
  return km; 
   
}
```

##理屈＆いいわけ
公式などの詳しい解説は専門的なサイトが多いので割愛。

最初に定義している各定数について、測定した時期や団体？などによって違いがある模様。３種類ほど試して、GoogleMapの距離測定との誤差が一番小さかった「ベッセル楕円体（旧日本測地系）」と呼ばれる物を使用。

途中の式はスッキリさせたいけど・・・これ以上まとめると計算結果が狂うのでこんな感じに^^;　この辺が素人リーマンの限界か？

##実際に計算してみた
緯度経度は、GoogleMapの「この場所について」で取得。

負の値があるからか、国会議事堂からホワイトハウスまでの距離で酷い誤差が出てしまった。それ以外は悪くなくて、東京タワーからスカイツリーなんて実質誤差ゼロ！個人的には東京都内でしか使わないので問題無さそう ^^)b
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/faa1a5b1-832d-c96f-61c8-e7badc900631.png)
距離が延びるほど誤差が大きくなるなら、緯度経度の平均を中間として、それぞれから中間までの距離を計算して足せば良いでは？と思ったけど、さらに誤差が大きくなりましたとさ（笑）

楕円体のカーブが原因かも？GoogleMapAPIの距離計算は地球を球体として計算しているとの記述もあったので、楕円体として計算しているヒュベニの公式と誤差が出る？

##？だらけになったけど
限られた範囲（と言っても生活圏的には十分）で使える距離測定関数が完成。

余談ですが、エクセルでも計算できました。

###おしまい
WSL を使って make, g++ を実行してみる

WSL（Windows Subsystem for Linux）を使って、make と g++ を実行してみたので、その備忘録です。

#Windows Subsystem for Linux のインストール
インストール自体は以前にやっていたので、手順ははっきり覚えてないんですが
公式ドキュメントに沿えばインストールできると思います。
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

ドキュメントに従っていると
「Linux ディストリビューション」を選択する場面があると思います。
今回は使用する Linux ディストリビューションとして ubuntu18.04 を選択しました。
バージョンのこだわりは特にないので、最新の ubuntu 20.04 でもいいと思います。
↓インストール先
https://www.microsoft.com/ja-jp/p/ubuntu-1804-lts/9n9tngvndl3q?rtc=1&activetab=pivot:overviewtab


ちなみに、今回は windows terminal を使ってこの後の作業をしています。
↓インストール先
https://www.microsoft.com/ja-jp/p/windows-terminal/9n0dx20hk701?activetab=pivot:overviewtab

#makeコマンドのインストール
windows terminal を使って、ubuntu を実行し、
`sudo apt install make`  を実行します。
途中で何か聞かれたら YES(Y) と答えておきましょう。

インストールが完了したら
`make -v` でバージョン確認してインストールの有無を確かめましょう

>GNU Make 4.1
>Built for x86_64-pc-linux-gnu
>Copyright (C) 1988-2014 Free Software Foundation, Inc.
>License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
>This is free software: you are free to change and redistribute it.
>There is NO WARRANTY, to the extent permitted by law.

このように表示されるとOKです

#g++ コマンドのインストール
make と同様に ubuntu で
`sudo apt install g++` を実行します

インストールが完了したら同じくバージョン確認をしておきましょう。
`g++ -v`

ずらずらと表示されますが、最後にこのような表示がされると思います。
>gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)

これでインストールは完了です

#使ってみる
今回は make ファイルの中に g++ が含まれていたので、make ファイルを実行してみます。
実行したい make ファイルまで cd でディレクトリを移動して
`make`を実行します。
その結果、出力されたファイルを実行して、希望のプログラムが実行できました。


以上備忘録でした。
pandas category 型集計の罠

# pandas category 型集計の罠

dtypeがcategoryだと、存在しない値に対しても集計されてしまうことがある。

```Python
import pandas as pd  # version 1.1.2

# DataFrame を定義
df = pd.DataFrame({
    'col1': ['a', 'a', 'b', 'b', 'c', 'c'],
    'col2': [1, 2, 1, 2, 1, 2]
})
# col1 を category 型にする
df['col1'] = df['col1'].astype('category')
# 先頭の3行をコピー
df_sub = df.head(3).copy()
# col1 で groupby して、col2 について集計
df_grp = df_sub.groupby('col1')
df_agg = df_grp.agg({'col2': 'mean'}).reset_index()
df_agg.columns = ['col1', 'mean_col2']
```

df_subは以下のようになる。

||col1|col2|
|---|---|---|
|0|a|1|
|1|a|2|
|2|b|1|

df_aggは以下のようになる。

||col1|mean_col2|
|---|---|---|
|0|a|1.5|
|1|b|1.0|
|2|c|NaN|

# 問題点
df_subに対して集計したはずなのに、col1がcの行がある。df_grp.groupsを確かめてみると、{'a': [0, 1], 'b': [2], 'c': []}となっている。

# 対策
df_grpの定義を以下のようにする。

```Python
df_grp = df_sub.groupby('col1', observed=True)
```

※@nkay様にご指摘いただき、対策を変更いたしました。ありがとうございます。

# groupbyのドキュメント
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html
PolyBaseを使ってDataLakeへデータをEXPORTしてみた

以前、Synapse SQLプールへPolyBaseを使って、DataLakeからデータのロードを行いました。
[PolyBaseでSynapse SQLプールにデータを投入してみた](https://qiita.com/masahiro-yamaguchi/items/1a0d3706209b266c5676)

今回はその逆でSynapse SQLプールからPolyBaseをつかってDataLake Storageへデータを出力します。

#全体の流れ
以下の流れでデータの出力を行います。
1. 認証情報の作成（`CREATE MASTER KEY`と`CREATE DATABASE SCOPED CREDENTIAL`）
2. 外部データソースの作成
3. ファイルフォーマットの作成
4. `CREATE EXTERNAL TABLE AS SELECT`でデータを出力

また、1、2に関しては以前に紹介した[記事](https://qiita.com/masahiro-yamaguchi/items/1a0d3706209b266c5676)に記載したものをそのまま利用していますので、今回は説明は割愛します。

#ファイルフォーマットの指定
ファイルフォーマットを指定することで、出力するファイルの形式をカスタマイズすることが可能です。よく利用ものを記載します。詳しくは以下を参照してください。
https://docs.microsoft.com/ja-jp/sql/t-sql/statements/create-external-file-format-transact-sql?view=sql-server-ver15&tabs=delimited

* FORMAT_TYPE
出力するファイルの形式を選択することが可能です。Parquet形式、ORC形式、RCFILE形式、DELIMITEDTEXT（CSV）形式などが選択可能です。

* DATA_COMPRESSION
出力するデータの圧縮形式を指定します。出力するファイルのFORMAT_TYPEによって指定方法が異なるので注意してください。

|FORMAT_TYPE|DATA_COMPRESSION|
|:---|:---|
|Parquet|'org.apache.hadoop.io.compress.GzipCodec'<br>'org.apache.hadoop.io.compress.SnappyCodec'|
|ORC|'org.apache.hadoop.io.compress.DefaultCodec'<br>'org.apache.hadoop.io.compress.SnappyCodec'|
|RC|'org.apache.hadoop.io.compress.DefaultCodec'|
|DELIMITEDTEXT|'org.apache.hadoop.io.compress.DefaultCodec'<br>'org.apache.hadoop.io.compress.GzipCodec'|


* FIELD_TERMINATOR
区切り位置を指定します。デフォルトは`|`

* STRING_DELIMITER
出力するデータの文字型のデータに対するフィールドターミネータを指定します

* DATE_FORMAT
これはEXPORT時には機能しないようなので使う事はありませんが、注意として記載します。

今回はCSVで出力したいので以下の`ExportTpchData`というファイルフォーマットを作成しました。

```SQL
CREATE EXTERNAL FILE FORMAT ExportTpchData
WITH (
	FORMAT_TYPE = DELIMITEDTEXT,
	FORMAT_OPTIONS    (
        FIELD_TERMINATOR = ',',
        STRING_DELIMITER = '"'
    ),
	DATA_COMPRESSION = 'org.apache.hadoop.io.compress.GzipCodec'
);
```

#データの出力
データのエクスポートは`CREATE EXTERNAL TABLE AS SELECT`というSQLで実行します。イメージ的には外部表をCTASで作成するようなイメージとなります。今回は`EXPORT_LINEITEM`という外部テーブル名で作成しています。

```SQL
CREATE EXTERNAL TABLE EXPORT_LINEITEM
WITH 
(
    LOCATION='\export_lineitem\',
    DATA_SOURCE = AzureStorage,
    FILE_FORMAT = ExportTpchData
)
AS
SELECT
	*
FROM    LINEITEM;
```

* LOCATION
外部データソースで指定したコンテナ上のフォルダをしています。フォルダが無ければ自動で作成されます。今回は`export_lineitem`というフォルダ指定しています。

* DATA_SOURCE
外部データソースを指定します。（作成方法は[過去の記事](https://qiita.com/masahiro-yamaguchi/items/1a0d3706209b266c5676)を参照してください。）

* FILE_FORMAT 
先ほど作成したファイルフォーマットの`ExportTpchData`を指定しています。

SQLの実行が完了すると指定の場所へファイルが分割して出力されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/2484dd1b-1724-fd95-6b87-c3b9d256c026.png)
作成した外部表はSELECTを行い読み込むことが可能です。一方で、Synapse SQLプールでは`sp_configure`がサポートされていない関係上、外部表へ追加のデータのINSERTなどは行うことができないようです。再度EXPORTしたい場合は、外部表をDROPして再作成しなおす必要があります。

#おまけ
PolyBaseでデータを出力した場合、ファイルは分割されて出力されますが、分割数はcDWUによって異なるようです。
DW100cにつき6ファイルで出力されているようです。
以下検証結果を記載します。

DW200c(12ファイル)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/8161795d-b6ac-da50-69aa-74ce1854742c.png)

DW500c(30ファイル)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/a7946670-db66-23c5-52b4-df13e5b44f17.png)
Rubyで型宣言っぽくコードを書けるようにしてみた

## 結論

以下のようなコードが動くようになります。

```ruby
n = int 42
# => 42が代入される

f = int 4.2
# => TypeError!
```

## やったこと

以下のように`Kernel`モジュールにモンキーパッチします

```ruby
module Kernel
    module_function
        
    def int(var = 0)
        if var.is_a?(Integer)
            var
        else
           raise TypeError, "#{var} isn't Integer"
        end
    end 
end

```

あとは、`n = int 42`のように書くだけで型宣言っぽくRubyの変数を作ることができます。また異なる型(というかクラス)の値を渡した場合は例外として`TypeError`が発生します。

```ruby
n = int 42
i = int 21

p n
# => 42
p i
# => 21

n = int 4.2
# => `int': 4.2 isn't Integer (TypeError)
```

影響範囲を狭めるのであれば、`refinements`で以下のように書けばいいかと

```ruby
module Type
    refine Kernel do
       module_function
        
       def int(var = 0)
           if var.is_a?(Integer)
               var
           else
              raise TypeError, "#{var} isn't Integer"
           end
       end
    end
end

```

あとは使いたい箇所で`using Type`とすればOkです

## おわりに

とりあえず、`Integer`とか`String`とかはこんな感じで型宣言っぽく書けそう。ArrayとかHashとかは何かいい書き方ないか考えてみよう
【Python】numpyの平均、標準偏差、最大・最少におけるinfとNaNの扱い方

#発生した問題
python3でnumpyを用いた画像処理（画像評価）ソフトの出力に，
平均・標準偏差・最大・最小にinfとNaNが含まれる．

```python:sample_code.py
import numpy as np
img = #なんか画像の配列

print(np.max(img))
print(np.min(img))
print(np.mean(img))
print(np.std(img))

>inf
>-inf
>NaN
>NaN
```

こんな感じ
結構ハマった

#inf,NaNとは
そもそもinfとかNaNってなんだろうと思って
調べると沢山情報が出てきました．
###inf
infinityの略．無限大を表す．
-infは負の無限大なわけですね．

###NaN
>浮動小数点数にはNaN (Not a Number, 非数) と呼ばれる、実数の異常な値を表す特殊な数があります。
これは無限大-無限大、0.0/0.0といった不定形や、負数の平方根、負数の対数といった実数で表せない計算を行った場合に発生します。

[NaNのお話](https://qiita.com/ur_kinsk/items/708b36440f2e41535929)より

僕の理解では，考慮したくない・計算時に除外する値（数）って認識です．

#対策方法
###1.infをNaNに置き換える
```python:sample_code.py
import numpy as np
img = #なんか画像の配列

img[img == -np.inf] = np.nan
img[img == np.inf] = np.nan
```
これで配列からinfは消えました．次に進みましょう

###2.NaNを考慮した関数を使う
```python:sample_code.py
import numpy as np
img = #なんか画像の配列

img[img == -np.inf] = np.nan
img[img == np.inf] = np.nan

最小, 最大 = np.nanmax(img), np.nanmin(img)
平均 = np.nanmean(img)
標準偏差 = np.nanstd(img)

#他にも合計や分散もある
```
参考：https://note.nkmk.me/python-numpy-nansum/

###3.理解を深めるためのお話
これどういう処理をしてるんだろうってお話です．
最大や平均を求めるときに**NaN要素を除外**して計算しています．
例えば平均の計算ですと，全体の合計値に含ませないし要素の数にも含みません．

配列の中からNaNってやつを削除してしまうイメージ．
じゃあ削除すればいいじゃんと思うかもしれませんが，画像処理ではそうもいかんです．
削除してしまったら画像の縦横の大きさとかくるってしまいますからね．

とりあえず，0で割ったり0を割ったりしてるとinfやNaNが含まれてしまうので，
そういった処理をしているソフトなら基本的に上の処理を行いましょうねといった感じでしょうか．

#あとがき
このことに気づくのって結構大変でした．
自分はよく[imageJ](https://imagej.nih.gov/ij/)でやるような画像処理の作業を自動化してるのですが，
ソフトの出力結果とimageJで処理した結果が違ってたので気づけました．
infは除外しちゃうんだ～って感じましたね．画像処理の世界では常識なんですかね？
Webpackerとは (Rails6で rails s してエラーが出た時の話)


Rails6で新規アプリを作成しようとし、データベース作成後に
rails sでサーバを起動しようとしたところ、以下のようなエラーが出ました。

```
$ rails s
=> Booting Puma
=> Rails 6.0.3.3 application starting in development 
=> Run `rails server --help` for more startup options
Exiting
Traceback (most recent call last):
	77: from bin/rails:3:in `<main>'
	76: from bin/rails:3:in `load'
　　　　　　　　　　・
　　　　　　　　　　・
　　　　　　　　　　・
Webpacker configuration file not found /Users/<ユーザー名>/<アプリ名>/config/webpacker.yml.
Please run rails webpacker:install
Error: No such file or directory @ rb_sysopen - 
/Users/<ユーザー名>/<アプリ名>/config/webpacker.yml (RuntimeError)
```
「Webpackerの設定ファイルが見つかりません」とのこと。
/config/webpacker.ymlがあるべきだそう（なかった）。

# Webpackerとは
> JavaScriptのビルドツール「Webpack」のラッパーで、RailsアプリケーションでWebpackを使ってJavaScriptを管理することを簡単にしてくれるGem
[現場で使えるRuby on Rails5 速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227)

私は「RailsでJavaScriptを使えるようにする為に色々よしなにしてくれるGem」と理解しました・・・。
(この辺りの理解は今後深めていけたら。)

またRailsガイドv6.0によると、「WebpackerがRails 6のデフォルトJavaScriptコンパイラになる」とあり、
rails newした時点で「gem 'webpacker'」がGemfileに書かれている理由がわかります。
以前はSprockets (スプロケッツ)というものがJavaScriptの標準ビルドツールとなっていたようです。

# rails webpacker:installしてみる

どうしてGemfileに書いてあったのにWebpackerがインストールされてないんだっ、と思うところですが、
大人しく「rails webpacker:install」してみると

```
$ rails webpacker:install
Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
```

「Yarnがインストールされていません」と言われてしまいました。
この為にrails newした時にWebpackerがインストールされなかったのでしょう。

# Yarnとは
JavaScriptのパッケージマネージャのこと。
下記の記事がわかりやすかったです。
[JavaScriptのパッケージマネージャーnpmとYarnについて解説します！](https://www.sejuku.net/blog/96866)

# Yarnのインストール
```
$ brew install yarn
```

# もう一度 rails webpacker:install をしてみる
```
$ rails webpacker:install
      create  config/webpacker.yml
Copying webpack core config
      create  config/webpack
      create  config/webpack/development.js
      create  config/webpack/environment.js
      create  config/webpack/production.js
      create  config/webpack/test.js
　　　　　　　　　　・
　　　　　　　　　　・
　　　　　　　　　　・
Webpacker successfully installed 🎉 🍰
```
無事にWebpackerをインストールできました。

# あらためて rails s してみる
![スクリーンショット 2020-09-10 22.57.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589400/e7d48fc0-8d6e-af21-e601-804d36cfd252.png)
エラー回避できました。

# 次回予告
[webpackerのしくみ](https://qiita.com/nideratakumin/items/da9ba4eb7ac8968e92e4)

# 参考にさせていただきました
[Rails6 Webpackerでエラーが出た](https://qiita.com/libertyu/items/1eb74adc817ab8971100)
ポケモンスケルトン（追記予定）


稲葉直貴さんの以下のtweetを解く記事です。

https://twitter.com/puzlab/status/1303175269012983809


```R
rm(list = ls())

library(tidyverse)

d <- read_csv('poke.csv')
d <- d %>% mutate(S = map(name, function(str1){ return(1:str_length(str1)) }))
d <- d %>% unnest(cols = S)
d <- d %>% mutate(katakana = str_sub(name, S, S))

d1 <- d %>% group_by(katakana) %>% count()
d <- d %>% left_join(d1, by = c('katakana'))
```

以下を見ると、「ソ」は「フシギソウ」にしか使われていない様子。なので「フシギソウ」が４番目から分岐することはない。

```R
> d
# A tibble: 673 x 5
   index name           S katakana     n
   <dbl> <chr>      <int> <chr>    <int>
 1     1 フシギダネ     1 フ           9
 2     1 フシギダネ     2 シ          13
 3     1 フシギダネ     3 ギ           6
 4     1 フシギダネ     4 ダ          10
 5     1 フシギダネ     5 ネ           2
 6     2 フシギソウ     1 フ           9
 7     2 フシギソウ     2 シ          13
 8     2 フシギソウ     3 ギ           6
 9     2 フシギソウ     4 ソ           1
10     2 フシギソウ     5 ウ          13
# ... with 663 more rows
```
クラス分類のTransfer Learningをpcで学習しjetson nanoにのせる

# 初めに
[公式](https://github.com/dusty-nv/jetson-inference/blob/master/docs/pytorch-transfer-learning.md)にて紹介されているクラス分類のTransfer Learningを行う際、jetson-nano上で学習を行うと処理時間がかかるためNVIDIA Geforce GTX 1060が搭載されたPCで学習を行って結果のみをjetson-nanoに移動させて画像認識を行いました。その時の方法をメモします。

# 動作環境
- jetson nano(jetpack 4.4をインストールした)
- ubuntu20.04(NVIDIA Geforce GTX 1060が搭載されたPC)
  - **pytorch 1.4(1.6だと動かないかもしれない)**
  
    ```
    conda install pytorch==1.4.0 torchvision==0.5.0 cudatoolkit=10.1 -c pytorch
    ```  


# NVIDIA Geforce GTX 1060が搭載されたPC上での準備
## 学習用環境を用意
[参考](https://qiita.com/f-sk/items/6e2684ecc3fcb941bcb0)と同様にpython3.6+pytorchの環境を用意する。
**ただし上に述べたようにpytorch 1.4をインストールする**
## 学習用コードの準備
コンピュータのアーキテクチャが異なるため(?)jetson-inferenceをそのままbuildすることができません。しかし学習を行うだけならソースコードだけで十分なのでコードのみ拝借します

```
git clone --recursive https://github.com/dusty-nv/jetson-inference
```

## 学習データの準備
1. 自前の画像データを集め`jetson-inference/python/training/classification/`に`my_data`フォルダを作成してその中に`train/[クラス名]/[jpgの画像データ]`,`val/[クラス名]/[jpgの画像データ]`,`test/[クラス名]/[jpgの画像データ]`とする。
1. 先程作った`my_data`の中に`labals.txt`を作成し学習するクラスを列挙する。(書式は[公式](https://github.com/dusty-nv/jetson-inference/blob/master/docs/pytorch-collect.md)にあります.)


## 学習の実行

```python:train
cd jetson-inference/python/training/classification
python train.py --model-dir=[学習後のモデルの出力先] --arch=[使いたいモデル] my_data
#どのようなモデルが使えるのかなど詳細はpython train.py --helpを実行して確かめる
```

を実行する。

## onnxファイルの作成
[公式](https://github.com/dusty-nv/jetson-inference/blob/master/docs/pytorch-cat-dog.md)通り

```
python3 onnx_export.py --model-dir=[学習後のモデルの出力先]
```

を実行する。

# jetson-nanoでの準備
## jetson-inferenceのインストール
[公式](https://github.com/dusty-nv/jetson-inference/blob/master/docs/building-repo-2.md)通りにjetson-nano上にインストールしていきます。

```bash:jetson-inference
sudo apt-get update
sudo apt-get install git cmake libpython3-dev python3-numpy
git clone --recursive https://github.com/dusty-nv/jetson-inference
cd jetson-inference
mkdir build
cd build
cmake ../
make -j$(nproc)
sudo make install
sudo ldconfig
```

途中でインストールしたいモデルやpytorchのバージョンが聞かれますが、モデルは自分が使いたいモデルを選択しpytorchはpython3.6対応のほうをインストールするようにしてください。




## webカメラからの動画に対して認識を行う
これもまた[公式](https://github.com/dusty-nv/jetson-inference/blob/master/docs/pytorch-cat-dog.md)通り。
1. webカメラをjetson-nanoに接続する。
2. NVIDIA Geforce GTX 1060が搭載されたPCで学習した結果できた[学習後のモデルの出力先]フォルダをjetson-nanoの`jetson-inference/python/training/classification/`にコピペする。
3. NVIDIA Geforce GTX 1060が搭載されたPCの`my_data/labels.txt`をjetson-nanoの同じ場所にコピペする(必要なのはlabels.txtのみなので画像データはコピペしなくて良いです)
2. v4l2の場合
    
```
imagenet.py --model=[学習後のモデルの出力先]/[出力されたonnxファイルの名前].onnx --input_blob=input_0 --output_blob=output_0 --labels=my_data/labels.txt v4l2:///dev/video0
```    
   
 を実行する。
カメラについては[公式(カメラについて)](https://github.com/dusty-nv/jetson-inference/blob/master/docs/aux-streaming.md)を参考にしてください。

# 参考
[nvidia公式によるjetson-inferenceのインストール解説](https://github.com/dusty-nv/jetson-inference/blob/master/docs/building-repo-2.md)
[nvidia公式によるクラス分類の再学習の解説](https://github.com/dusty-nv/jetson-inference/blob/master/docs/pytorch-cat-dog.md)
プロビジョニングツールの比較

# はじめに

プロビジョニングツールであるAnsible, Chef, Saltを比較した。

## Ansibleとは

以下のサイトが大いに参考になる。

[Ansibleとは何か　構成管理ツールの目的〜Ansible導入まで最速で理解する](https://qiita.com/Brutus/items/1894629105d61f4854bc)

# 検索トレンドの比較

1年間の検索件数の時系列トレンド

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Google トレンドで「Ansible, Chef, Salt (ソフトウェア) - すべての国、過去 12 か月間」の 人気度の動向 を見る - <a href="https://t.co/nc2moxYxmU">https://t.co/nc2moxYxmU</a></p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1304062469359333376?ref_src=twsrc%5Etfw">September 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

1年間の検索件数の国別トレンド

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Google トレンドで「Ansible, Chef, Salt (ソフトウェア) - すべての国、過去 12 か月間」の 地域で比較した内訳 を見る - <a href="https://t.co/IECGtpIjEQ">https://t.co/IECGtpIjEQ</a></p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1304062507758174208?ref_src=twsrc%5Etfw">September 10, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Ansibleは、Chef, Salt に比して圧倒的に検索件数が多い。

# 非機能要件の比較

非機能要件比較表を以下に示す。

| Metrics              | Ansible                 | Chef                    | Salt                    |
| -------------------- | ----------------------- | ----------------------- | ----------------------- |
| 可用性               | :ballot_box_with_check: | :ballot_box_with_check: | :ballot_box_with_check: |
| 導入容易性           | Easy                    | Not very easy           | Not very easy           |
| 管理容易性           | Easy                    | Not very easy           | Easy                    |
| スケーラビリティ     | Highly Scalable         | Highly Scalable         | Highly Scalable         |
| 構成管理言語         | YAML(Python)            | DSL(Ruby)               | YAML(Python)            |
| 相互運用性           | High                    | High                    | High                    |
| 価格(upto 100 nodes) | $10,000                 | $13,700                 | $15,000(approx.)        |

出典 [Chef vs Puppet vs Ansible vs Saltstack: Which Works Best For You?](https://www.edureka.co/blog/chef-vs-puppet-vs-ansible-vs-saltstack/)

全ての指標でAnsibleはChef,Saltを同等かそれ以上である。

特にChefはRubyベースのDSLというところがツライ。

Python, YMLはDockerやAIで慣れているが、RubyはもはやRedmineくらいでしか使わない。

# 人気度の比較

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114392/1ad01d59-62ba-2928-7f52-c82fefdb6424.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114392/54f8db69-380a-23da-79d8-028b4b0d13af.png)

出典： https://stackshare.io/stackups/ansible-vs-chef-vs-salt

全ての指標でAnsibleが勝っている。

# クックブックorロールの公開件数

記事作成時点(2020/09/10)でのクックブックorロールの公開件数は、以下の通り。

- 25,246 Ansible Roles 
-  4,061 (=公式3,949 + コミュニティ112) Chef Cookbooks
-      0 Salt

Ansibleが圧倒的な件数を有する。

# その他

- AnsibleはRedHatが商用化。エンタープライズ用途にも安心感がある。
- Chefは公式クックブックが多く、老舗の安定感がある。
- Saltはどうかなぁ。AnsibleのYMLスタイルの簡便さとPuppetの機能性の高さのいいとこ取りをしているようだが、まだ時期尚早かな。数年後に急成長してるかもしれないが、今は保留。

# 結論

全ての指標に置いて、Ansible一択。
Kinx Tiny Typesetting - LaTeX 派? つか、知ってる?

# Kinx Tiny Typesetting

こんにちわ。

今回は組版システムがメインです。TeX や LaTeXを使ってますか？それは良いですね。私はイマイマ **全く使ってません**。好きですけど。

学生時代の論文書きには使ったものの、就職したら使わなくなってしまったあの懐かしくも美しいシステム、LaTeX。

この記事はそんな LaTeX に関係しつつ、私たちの Kinx に関連する、そんな内容です。

## はじめに

**「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。最近はだいぶ記事を書く時間がなく、生存確認的な記事ですが、ご容赦。書きたいことはいっぱいあるのですが。

* 参考
    * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
        * 個別記事へのリンクは全てここに集約してあります。
    * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
        * Pull Request 等お待ちしております。  

## 組版？

まずはこちらのPDFファイルからご覧ください。

https://github.com/Kray-G/kinx/blob/master/examples/typesetting/typesetting.pdf

これは Kinx 組版ライブラリによって生成されました。なんだそれ、というのが今回のお話です。

このライブラリはまだ完成しておらず、極めて初期の段階にありますが、割りとイケてる感じに出力できたので、勇み足風に紹介したくなってしまった、という記事でありんす。

## なぜ作り始めたか

PDF ライブラリ実装したんですよ。libharu ラップして。でもですね、生の PDF 操作するツール作るのも、まああるとは思いますが、座標計算したり面倒なので、ルールにしたがって組版する仕組みはほしいですよね。

そう思って見渡すと、そういうのって TeX くらいですよね。あと [SATySFi](https://github.com/gfngfn/SATySFi) とか [SILE](https://github.com/sile-typesetter/sile) とか見つけたんですが、SATySFi も SILE も Windows が弱点のご様子（SILE はビルドできたけど出力が正しくなかった…）。まあ、SILE はすごく良さそうでしたが、数式はまだ未対応。数式が必要か？は議論の余地はありますが、TeX っぽい感じ！を意識すると欲しいところ。

というわけで、またしても車輪の再発明に走りました。特長としては「スモールサイズで手軽に組版」。面倒な作業は一切なし。ここだけは守りたい。

## LaTeX は不要（使ってない）

ちなみに LaTeX は使っていません。というと語弊があるかもしれませんね。実際、LaTeX 自体はインストールすらしてません。が、数式に関しては KaTeX 内蔵でゴニョゴニョしてます。

LaTeX システムは非常に巨大なので、優れたシステムだとは思いますが、ちょっと PDF 作りたいなー程度の要望にインストールするには本格的すぎる気がして。

Kinx のスモール・パッケージをインストールしたら「なんかそれなりのが付いてた！」、くらいがちょうどいい感じなので、そんな感じを目指してます。

## おわりに

これはまだ完成してないシステムの紹介です。やることはまだたくさんあるので、これからです。目次とか Book Style とか。最終的には簡易マークアップからの変換がまず当面のゴール。基本 Markdown からは行ける感じで。

まだまだ発展途上の段階ですが、興味があったり応援してくださる方がいれば、ぜひぜひ Github スターください！やる気出します。（ただ、完成形はリポジトリ独立させるかも…）

同梱するとフォントだけで Kinx 本体のサイズ越えそうなので、別パッケージでアドオンできるようにしたいですね。パッケージ・マネージャーが必要だ。

ではまた次回！
【GitHub】GitHubのプロフィールとダークテーマ変更メモ

![スクリーンショット 2020-09-10 22.39.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692347/f4765ebc-7128-a2d4-3f8d-6ef3781e865c.png)


>参考サイトリンクメモ

* [10分で自分のGitHubプロフィールをカッコ良くする](https://qiita.com/Hassan/items/134009209f5709f892b1)
* [github-profile-summary-cards-example](https://github.com/vn7n24fzkq/github-profile-summary-cards-example)
* [Personal access tokenを発行して、Resource not accessible by integrationエラーを解消する](https://qiita.com/athlaliel/items/cfef41949f62638c13da)
* [GitHub Dark Theme](https://chrome.google.com/webstore/detail/github-dark-theme/odkdlljoangmamjilkamahebpkgpeacp)
Promise.allを書きたくない人向け

## 対象読者

- `Array<Promise<T>> => Array<T>`に`Promise.all`使いたくない人（for文も使いたくない）
- 順序どうり実行して欲しい非同期処理を配列で扱いたい（for文は使いたくない）

## 導入

次のような非同期処理を行うとします。

関数`fa`はここでは200ms, 400ms, 100msかかる処理を行いその結果を配列として返します。

```ts
// msec ms後にmsesの値を返す
const sleep: (msec: number) => Promise<number>

/**
 * [2, 4, 1] => [200, 400, 100]
 */
async function fa(arr: Array<number>) {
  const promiseNumbers: Promise<number>[] = arr.map(async (num) => await sleep(100 * num));
  const numbers: number[] = await Promise.all(promiseNumbers);

  return numbers;
}
```

```ts
const result = await fa([2, 4, 1]);
expect(result).toEqual([200, 400, 100]);
```

`Array<Promise<T>> => Array<T>`の変換に、普通のArray.mapを使うときは、`await Promise.all`で全てを並列処理するのが一般的です。

しかし、`async/await`を使って折角`Promise`を使わないプログラミングをしているのに`Promise.all`を使うのはちょっとだけセンスがないと思います。

別のアプローチを試してみます。

## fp-ts/Task, fp-ts/Array.sequence を用いる

関数型utilライブラリである`fp-ts`を用いてsequential（順序立てて）に非同期処理を行います。
それに伴い`Promise`を取り扱う`Task`で非同期な値を取り扱うことにします。

```ts
export interface Task<A> {
  (): Promise<A>
}
```

Promiseを返す関数を以下のようにラップしてTaskを返すようにしました

```ts
const sleepTask = (msec: number): T.Task<number> => async () => await sleep(msec);
```

`sleepTask(mesc)`自体はまだ実行されず、seqence関数で`Array<Promise<number>> => Promise<Array<number>>`にしたあとにsleep関数が呼ばれるようになります。

```ts
async function fb(arr: Array<number>) {
  // Task<T>[] => Task<T[]> への変換
  const sleepTasks: T.Task<number>[] = arr.map((num) => sleepTask(100 * num));
  const sleepSeqTasks: T.Task<number[]> = A.array.sequence(T.task)(sleepTasks);

  // ここでタスクの実行
  const numbers = await sleepSeqTasks();
  return numbers;
}
```

## 実行する順番もsequentialにする

taskのsequentialの内部実装ではPromise.allを呼んでいるのでsleep関数はすべて並列実行されます。

sleep関数内部でlogを呼ぶようにしてみます。

```ts
const sleep = async (msec: number) => {
  await new Promise((resolve) => setTimeout(resolve, msec));
  console.log(`run sleep(${msec})`); // sleepが完了したタイミングでログが出力される
  return msec;
};
```

```ts
await fa([2, 4, 1]);
// run sleep(100)
// run sleep(200)
// run sleep(400) 

await fb([2, 4, 1]);
// run sleep(100)
// run sleep(200)
// run sleep(400) 
```

並列処理なので、速いもの順に出力されました。

順番に実行したいときはchain実装されているMonad型`taskSeq`を利用するとよいです。

```ts
async function fc(arr: Array<number>) {
  // Task<T>[] => Task<T[]> への変換
  const sleepTasks: T.Task<number>[] = arr.map((num) => sleepTask(100 * num));
  const sleepSeqTasks: T.Task<number[]> = A.array.sequence(T.taskSeq)(sleepTasks);
  //                                                         ^ -- taskSeq にした

  // ここでタスクの実行
  const numbers = await sleepSeqTasks();
  return numbers;
}
```

```ts
await fc([2, 4, 1]);
// run sleep(200)
// run sleep(400)
// run sleep(100) 
```

配列順にログが出力されました。
AWS上にサーバーを作る（その02：Amazon VPC）

前回の投稿
[AWS上にサーバーを作る（その01）](https://qiita.com/aa_ha1uhik0/items/e4f11128bf065b573eb7 "AWS上にサーバーを作る（その01）")

# AWSのネットワーク
AWS上にサーバーを作るあたり、AWSにはどんなネットワーク設定が必要なのだろう？
「VPC」っていう名称だけはよく聞くよね。
公式のドキュメント「[Amazon VPC とは?](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html)」を見ると、

* Amazon VPC（Amazon Virtual Private Cloud）
* サブネット
* ルートテーブル
* ゲートウェイ

このあたりが必要っぽい。

## Amazon VPC（Amazon Virtual Private Cloud）
そもそもVPCって何だろう？
物理サーバーしかいじった事のない僕にとっては、今回が「初めまして」だね。
>[Amazon VPC とは?](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html)
Amazon Virtual Private Cloud (Amazon VPC) を使用すると、定義した仮想ネットワーク内で AWS リソースを起動できます。仮想ネットワークは、お客様自身のデータセンターで運用されていた従来のネットワークによく似ていますが、AWS のスケーラブルなインフラストラクチャを使用できるというメリットがあります。

とドキュメントに記載があった。
どうやら、

* 自分のAWSアカウント専用
* サーバーを立てるために必要な設定
* AWS上に作る仮想でできたネットワーク

という事らしい。
サーバーを作るには必須のサービスなんだね。
そこでやっぱり気になるのがAmazon VPCの料金。
>[Amazon VPC の料金表](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html#Paying)
Amazon VPC は追加料金なしで使用できます。使用するインスタンスおよびその他の Amazon EC2 機能に対して標準料金がかかります。Site-to-Site VPN 接続、PrivateLink、トラフィックのミラーリング、NAT ゲートウェイの使用には料金がかかります。

ほほう。
VPC自体は無料だけど、僕がやろうとしている拠点間VPNについては料金がかかるってことか。
それからVPC上に立てたEC2の通信量が合算されるってことね。
じゃあいくらかかるんだろう？？

>[AWS サイト間 VPN および Accelerated サイト間 VPN への接続料金](https://aws.amazon.com/jp/vpn/pricing/)
サイト間 VPN 接続ごとに 0.048USD/時間 ※東京リージョン

30日間、1日24時間アクティブになるはずなので、AWSサイト間VPN接続料金は、
0.048USD/時間 × 24時間 × 30日 = 34.56USD/月 = 約3,800円/月
となることが予想される。（他にEC2の通信量が発生する予定）
・・・「結構高いな」っていう印象。
使わない時、止めておくとかできるかな・・・？？

## サブネット
ようやく見慣れたワード、「サブネット」。
念のため、[Amazon VPC の概念](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html#Overview)で確認すると
>サブネット — VPC の IP アドレスの範囲。

と書いてある。
VPCを作成するときに一緒に設定するんだね。

## ルートテーブル
これも知ってる。
このIPアドレス帯の通信がきたら、どこに接続させる？みたいなやつだね。
[Amazon VPC の概念](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html#Overview)によると
>ルートテーブル — ネットワークトラフィックの経路を判断する際に使用される、ルートと呼ばれる一連のルール。 

使うのは[こっち（仮想プライベートゲートウェイへのルーティング）](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/route-table-options.html#route-tables-vgw "仮想プライベートゲートウェイへのルーティング")かな？


## ゲートウェイ
VPCを作っただけだと、インターネットなど、VPCの外にはつながらないらしい。
そこで、このゲートウェイを作り、通信の出入り口にすることになります。
僕はプライベートゲートウェイとカスタマーゲートウェイを作ることになるのかな？

# 次回の内容
そろそろAWSの作業できる？？
（まだ引っ張る）

To be continued...
【Eclipse】初心者でも最初に覚えた方が良さそうなショートカット厳選5つ【Mac】

###いろいろショートカットはあるけど、まずはめちゃくちゃ頻度が高いものをマスターしてから少しずつ数を増やす

####まずは5つ

ショートカット|説明
:--|:--
command　＋　D|行の削除
option　＋　↑↓|行ごと移動（複数行可）
command　＋　/|コメントアウト
control　＋　.|単語補完
option　＋　command　＋　R|同じ変数名を同時編集（リファクタリング）

まあこのくらいを慣れて指が勝手に動くようになったら次のショートカットを選んで練習という流れが個人的には良いかと。

**コメントアウト**はだいたいのエディタで同じショートカットキーが割り当てられているっぽいです。

**行の削除**も同じものが多いと思いますが、VSCodeは違ったかと。。。

**行ごとの移動**も他のエディタでも同じだと思います。

**いきなりたくさん練習しても、考えてしまうのでとりあえず片手くらいの数を無意識にできるようになってから次にいこう！**

ショートカットキーは考えて使うものではないですし。


####単語補完でtypoを減らす
個人的には変数名のタイプミスは多いので、エラーが出てからどこかなぁって探すより、短い変数名でも補完機能を使う方が良いと思っています。

ショートカット|説明
:--|:--
control　＋　.|単語補完
option　＋　command　＋　R|同じ変数名を同時編集（リファクタリング）

リファクタリングはVSCodeではcommand＋Dで楽ちんでしたし、選択もしている状態にもなるので丸々変数名を変えたり、後ろに付け加えるのも楽でしたね。optionが押しにくいわ。おいおいショートカットの割り当てを変更すると思います。ちなみにcommand+shift+Lでショートカットの一覧などが表示されます！！




「速く打てる」というよりも「ミスを減らす」という意味で開発が速くなると信じていますんで、これでも十分便利です。

###「めんどいなぁ」とか「これ結構頻度高いから楽にしたいなぁ」と感じるものがあればググればきっとショートカットが出てくる

練習段階はめんどくさくても自分で書いていく方が習得が速くなると思います。そしていっぱい書いてるうちに「めんどいなこれ」っていうのがあれば大体ショートカットが割り当てられていたり、プラグインがあったりすると思います。

その域に達するまではひたすら練習。欲張らない。イソガバマワレ。
【HTML/CSS】9/10

【HTML/CSS】
①「親→子」指定時にひっかりがちなミスと指定法
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708998/5071ff72-6379-a633-cb78-952cfe7186d4.jpeg)


②レイアウト－外から指定する方法(一般的)と内側の要素に指定する方法(少し複雑だが便利)
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708998/52a0058c-2cb6-45a0-221e-548e20f61e1e.jpeg)



③Flexboxにおいてはmarginしか使わないほうが良いこと
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708998/ec2cdb9f-1b70-a145-05de-31565f1a013a.jpeg)
Windows Terminal に x64 Native Tools Command Prompt for VS 2019 を登録する

Windows Terminal から Visual Studio Build Tools を起動するには、settings.json に呼び出し用の命令を登録してしまえばいいんだなあと思いまして、コマンドプロンプトの例を参考にしながら、こんなふうに追加してみました。

```
            {
                // Make changes here to the cmd.exe profile.
                "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
                "name": "コマンド プロンプト",
                "commandline": "cmd.exe",
                "hidden": false
            },
            {
                // Make changes here to the vs2019-x64 batchfile profile.
                "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6102}",
                "name": "x64 Native Tools Command Prompt for VS 2019",
                "commandline": "cmd.exe /k C:\\Programs86\\MicrosoftVS\\2019\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat",
                "startingDirectory": "C:\\Users\\pcowner\\",
                "hidden": false
            },
```


``commandline`` に書く内容は、スタートメニューの Visual Studio 2019 , Visual Studio Tools, VC の中にあるショートカットを参考にしました。``/k`` オプションが大事です。忘れると悲しい。


さらにcmdではなくpowershellで使おうとする場合はこうなります。上の例とはVS2019のインストール先が異なるため、エスケープ地獄に陥っています。

```
            {
                // Make changes here to the powershell.exe profile.(これは見本)
                "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
                "name": "Windows PowerShell",
                "commandline": "powershell.exe",
                "hidden": false
            },
            {
                // Make changes here to the vs2019-x64 powershell.exe profile.
                "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44c0}",
                "name": "Windows PowerShell vs2019",
                "commandline": "powershell.exe -noe -c \" &{ Import-Module \"\"\"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\Microsoft.VisualStudio.DevShell.dll\"\"\" ; Enter-VsDevShell xxxxxxxx -DevCmdArguments -arch=x64 } \"",
                "startingDirectory": "C:\\Users\\ta\\",
                "hidden": false
            },
```

``commandline`` に与える文字列の書き方は、スタートメニューの Visual Studio 2019 , Visual Studio Tools の中にある Developer PowerShell for VS 2019 を参考にします。これはショートカットなので、ファイルの場所を開いたりプロパティを見るなどして、リンク先を探します。例えばリンク先が以下のようになっている場合

```

C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -noe -c "&{Import-Module """C:\Programs86\MicrosoftVS\2019\BuildTools\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"""; Enter-VsDevShell yyyyyyyy}"

```

``"commandline":"(この部分)"`` は

```

"commandline":"powershell.exe -noe -c \"&{Import-Module \"\"\"C:\\Programs86\\MicrosoftVS\\2019\\BuildTools\\Common7\\Tools\\Microsoft.VisualStudio.DevShell.dll\"\"\"; Enter-VsDevShell yyyyyyyy -DevCmdArguments -arch=x64}\""

```
となります。``Enter-VsDevShell`` の引数（インスタンスID）はユーザによって異なるようなので、自分の環境のもの書く必要があります。（知らなかった）

guidはpowershellの New-Guid でちゃんと発行したほうがいいかもしれませんね。

# 参考記事
https://mklearning.blogspot.com/2019/12/developer-powershell-for-vs-2019x64.html
Postgresエラー「PG::ConnectionBad」

#　何度もつまづいたので一旦簡単にメモ

PG::ConnectionBad

could not connect to server: Connection refused Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?

![スクリーンショット 2020-09-10 22.17.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/a5dece8b-f9b2-0609-3b25-77ef6b0e8699.png)

```
% postgres -D /usr/local/var/postgres
2020-09-10 22:13:34.167 JST [8631] FATAL:  lock file "postmaster.pid" already exists
2020-09-10 22:13:34.167 JST [8631] HINT:  Is another postmaster (PID 494) running in data directory "/usr/local/var/postgres"?
```

```
% rm /usr/local/var/postgres/postmaster.pid
```
rmでpostmaster.pidを削除
　　


```
% brew services restart postgresql
```
リスタートしてあげる。

　　

```
% rails s
```
起動して確認


#ポイント
postmaster.pidが残っていること
正常にpostgresqlが終わらせられていないと
postmaster.pidというファイルが残ってしまった結果
接続できない起動できないエラーが発生するみたいです。


もう少し詳しく調べて再度更新予定。
postgresqlの起動と停止についての仕組みをしる必要がありそう
今回はメモまで。

#参考記事
https://qiita.com/great084/items/98c83364f246473249c4
Djangoで、表示されている長い文字列を途中で....と略す方法

Djangoでブログを作っていてホームに長い文章があっても見にくいので何か略す方法はないかと調べていたらこんなものを見つけたので共有します。

Django version = 2.2.4
Python version = 3.8.2

```html:home_list.html
<p>{{ post.text|linebreaksbr|truncatechars:250 }}</p>
```

少しわかりにくいかもしれませんが、具体的にこの記事に関連しているのは最後の「truncatechars」だけです。

そこの数字を好きな数字にすることでその次の文字から...と略されて表示されるようになります。
深層強化学習の環境構築とサンプルテスト（Mac版）

# 強化学習
　[「ScratchでAIを学ぼう」はScratchで動かしながら強化学習を理解できる凄い本](https://karaage.hatenadiary.jp/entry/2020/08/14/073000)を読んだりして、少し強化学習に興味が出てきたので「[OpenAI Gym / Baselines 深層学習・強化学習 人工知能プログラミング 実践入門](https://www.amazon.co.jp/dp/4862464726)」という本を読んで、環境構築や、サンプルを自分で作って動かしてみた内容のメモ。本当に個人的メモです。

　GitHubリポジトリは以下です。

<a href="https://github.com/karaage0703/reinforcement-learning-sample"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/karaage0703/reinforcement-learning-sample.png" width="460px"></a>

　環境はMac前提です。

- iMac Retina 4K 2017
- macOS 10.13.6

# OpenAI Gym
## OpenAI Gymとは？
　「OpenAI」が提供している強化学習用のツールキット。

## 環境構築
　pyenvを使う前提です。pyenvのセットアップ方法や詳細は以下記事参照ください。

[pyenv/pyenv-virtualenv/Anacondaを使ってクリーンなPython環境をセットアップ](https://karaage.hatenadiary.jp/entry/2016/04/04/073000)

　以下はpyenvがセットアップできている前提です。

```sh
$ pyenv install 3.7.3
$ pyenv virtualenv 3.7.3 rl
$ pyenv global 3.7.3/envs/rl
```

　以下は本に書いてありますが、自分の環境だと実行不要（すでに全部インストール済みだった）でした。

```
$ brew install cmake boost boost-python sdl2 swig wget
```

　pipでOpenAI Gym関連のパッケージをインストール

```sh
$ pip install gym
$ pip install gym[atari]
$ pip install gym[box2d]
```

## テスト

```sh
$ git clone https://github.com/karaage0703/reinforcement-learning-sample
$ cd reinforcement-learning-sample
$ python gym_level_01.py
$ python gym_level_02.py
$ python gym_level_03.py
```

![cartpole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81919/730f1998-b7b4-ac79-8f46-fb71a08b1f94.png)

```sh
$ python check_space.py CartPole-v1
$ python check_space.py Breakout-v0
```


# Stable Baselines
## Stable Baselinesとは？
 「OpenAI Gym」で使われる強化学習の実装セットです。

## 環境構築

```sh
$ brew install openmpi
```

```sh
$ pip install stable-baselines[mpi]
$ pip install tensorflow==1.15.3
```

## テスト

```
$ python hello_baselines.py
```

# まとめ
　強化学習、とりあえず動かしてみたりしているのですが、イマイチピンときていません。ゲームのAI作りとしてはこれで良さそうですが、実世界への応用は、ギャップがかなり大きそうだなという印象です。その分、何か面白いことができたらインパクトは大きそうですが。

　イマイチ面白もの作るところまでのイメージが浮かばないので、強化学習に関してはとりあえずここまでにして、しばらく寝かしておこうと思います。おやすみー。

# 関連記事

https://zenn.dev/karaage0703/articles/e01c2abc88373c

# 参考リンク

- https://gym.openai.com/docs/
- https://www.kumilog.net/entry/openai-gym-rl
- https://gist.github.com/iambrian/2bcc8fc03eaecb2cbe53012d2f505465
- https://github.com/openai/gym/wiki/Table-of-environments
- https://qiita.com/nsd24/items/7758410128872d684e05
- https://github.com/Unity-Technologies/ml-agents
Javaの型変換（StringとかintとかDateとかCalendar他）

普段開発とかやってると、ぽろりと忘れてたりするので忘備用。
思いつき次第、加筆修正。

・[文字列⇔数値](#文字列数値)
・[文字列⇔文字列](#文字列文字列)
・[日付型⇔日付型、文字列](#日付型日付型文字列)


#文字列⇔数値
###String ⇔ int

```java:qiita.java
   //int → String
   int num = 0;
   String intToString = String.valueOf(num);

   //String → int
   String number = "123";
   int stringToInt = Integer.parseInt(number);
```

double型、float型、long型からのString変換も同様に行えます。
とりあえずString.valueOf()に放り込んでおけばいい……はず。

補足：（2020/09/11：修正）

```java:qiita.java
   String number = "123";

   //String → double
   double d = Double.parseDouble(number);

   //String → float
   float f = Float.parseFloat(number);

   //String → long
   long l = Long.parseLong(number);
```


#文字列⇔文字列
###String ⇔ char

```java:qiita.java
   //char → String
   char chr = 'ち';
   String charToString = String.valueOf(chr);

   //String → char
   String str = "すとりんぐ";
   char stringToChar = str.charAt(0);

   //String → char[]
   char[] stringToCharList = str.toCharArray();

   //char[] → String 
   char[] charList = new char[] { '1', '文', '字' };
   String charListToString = new String(charList);
```

#日付型⇔日付型、文字列
###Calendar ⇔ Date

```java:qiita.java
   import java.util.Date;
   import java.util.Calendar;

   //Date → Calendar
   Date date = new Date();
   Calendar cal = Calendar.getInstance();
   cal.setTime(date);

   //Calendar → Date
   Calendar cal = Calendar.getInstance();
   Date calendarToDate = cal.getTime();
```

###Date ⇔ String

```java:qiita.java
   import java.text.ParseException;
   import java.text.SimpleDateFormat;
   import java.util.Date;
   
   //Date → String
   Date date = new Date();
   String dateToString = String.valueOf(date);

   //String → Date
   String day = "2020/09/10 21:00:00";
   SimpleDateFormat sdf = new SimpleDateFormat(day);
   try{
      Date stringToDate = sdf.parse(day);
   } catch(ParseException e){
      e.printStackTrace();
   }
```

Calendar型から直接Stringにはできなさそう。
　→String.valueOf()で変換できるにはできたけど、わかりやすい文字列ではなかった。
基本的にはCalendar ⇔ Date ⇔ Stringでいいか。

.oO(String.valueOfってたくさん用意されてるんだな……。感謝感謝)

おわり
javascript関数ドリル　初級編uniq関数の実相のアウトプット

##uniq関数の課題内容
詳細はこちら
　　　↓
https://js-drills.com/blog/without/

##uniq関数の取り組む前の状態
uniqメソットがどんなものか分からない状態

##uniq関数に取り組んだ後の状態
 if( !uniqArray.includes(value) ) {
      uniqArray.push( value );
    }この発想がなかった

##uniq関数の実装コード（答えを見る前）

```js

function uniq(array) {
  const uniqArray = [];
  for(let i = 0; i < array.length; i++) {
    const value = array[i];
    if( !uniqArray.includes(value) ) {
      uniqArray.push( value );
    }
  }

  return uniqArray;
}

const numbers = [2, 1, 2];

console.log( uniq(numbers) );
// => [2, 1]

console.log( numbers );
// => [2, 1, 2]
```
CSRファイルって結局なんぞ？

## CSRファイルって結局なんぞ？

- CSRファイルの勉強前の印象

```
SSL証明書を取るために
自分がちゃんとした人(企業)ですよって、
登録してある情報と照らし合わせるためのファイル
```

## CSRファイルって結局何よ？

- CSRファイルとは
`Certificate Signing Request` の頭文字を取ったもの
Certificate ... 証明
Signing ... 署名
Request ... 要求
→ 直訳 : 「証明することを署名」してくれって要求


- 構成要素
`公開鍵の情報` + `ディスティングイッシュネーム`

- ディスティングイッシュネームとは？
	- Common Name
	- 組織名
	- 部門名
	- 市区町村
	- 都道府県
	- 国/地域

## 流れとしては？

1. 申込者が秘密鍵の作成
2. 秘密鍵 + ディスティングイッシュネーム(申込者の情報) = CSRファイルを生成
3. 認証局の申請の際にCSRをつけて申し込み
4. 認証局はCSRのディスティングイッシュネームと申込者の情報が一致するか確認する
5. 認証局は証明書に署名を行い、証明書を発行する
6. 認証局が申込者に証明書、秘密鍵、中間証明書を送る

## 要するにざっくりいうと？

```
認証局に証明書に署名をしてもらうため、
「申し込みした本人だよ」と証明するファイル
```

最初に思ってた認識と違った

## 参考

- [申込時に用意しなくてはいけないCSRファイルとは何でしょうか？](https://xtrust.jp/support/faq/faq08/a001/)
- [SSL導入ガイド](https://www.securecore.co.jp/support/manual/csr.php)
- [CSRファイル生成時に設定するディスティングイッシュネームは何を指定しますか？](https://xtrust.jp/support/faq/faq08/a002/)
- [SSL証明書の取得方法 | HTTPからHTTPSへ移行](https://qiita.com/non0311/items/a90c729a5cb95863853f)
勉強日誌5日目

今日はゲーム実況をBGMに
今日は仕事多めで疲れたので少なめ
毎日少しでもやるというのが最低根のルール。

正答率　58％

hwclock -w
hwclock --systohc
システムクロックをハードウェアクロックへ


set-ntp
timedatectlコマンドのサブコマンドで、NTPによる時刻同期を有効・無効にする


rtcsync
/etc/chrony.conf で定期的にシステムクロックをハードウェアクロックに反映！

set-timezone
timedatectlコマンドのサブコマンドで、タイムゾーンを設定するもの

list-timezones
timedatectlコマンドのサブコマンドで、タイムゾーンを一覧表示するもの

sources
chronycコマンドで、時刻のソ－ス表示

activity
chronycコマンドのサブコマンドで、オンライン/オフライン状態のNTPサーバ数を表示する

tracking
chronycコマンドのサブコマンドで、時刻同期の詳細情報を表示

pool.ntp.org
複数のNTPサーバで構成される仮想的なNTPサーバを提供

ntpq -p
同期など調べるコマンド

timedatectl status
現在のシステム時刻や時刻同期の状態を表示

ntpdate pool.ntp.org
タイムサーバ　pool.ntp.org から時刻取得するコマンド

正答率　59%

journalctl -o json
systemd-journaldのログをjson形式で出力

system.journal
systemd-journaldのバイナリ形式のジャーナルファイル名

--no-pager
journalctlでページャを使用させないオプション

_SYSTEMD_UNIT=sshd.service
journalctlでsshd.serviceからのログを指定

/var/log/journal
systemd-journaldのログを永続的に保存させるディレクトリの絶対パス

journalctl
systemdの動作するシステムで、ユニットが出力するログを参照するコマンド

-b , --boot
journalctlのオプションのうち、特定の起動時のログに限定して表示させるオプション

--since
--until
journalctlのオプションのうち、特定の期間のログに限定して表示させるオプション

rsyslog
syslog-ng
次世代のsyslogの名前をアルファベット順に2つ

-u
--unit
journalctlのオプションのうち特定のユニットのログに限定して表示させるオプション

-n
--lines 10
journalctlコマンドオプションのうち、ログ出力を10行だけ表示させるオプション

*.notice @hoge
全てのファシリティのプライオリティがnotice以上のログを、リモートホストhogeに送信したいとき

systemd-journald
systemdの動作するシステムで、ユニットが出力するログを扱うデーモンのプログラム名
Google Maps で吹き出しが表示されない

## 要件

Google Maps 上のマーカーをタップした際に吹き出しを表示してください。

## Google さんの教え

それ **info window** でできるよ。
https://developers.google.com/maps/documentation/ios-sdk/marker#add_an_info_window

`title` or `snippet` のどちらかを設定すれば、マーカーをタップした際に吹き出し( **info window** )が表示されるようです。
どちらも `null` もしくは空文字の場合は吹き出しは表示されません。

```swift
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let marker = GMSMarker(position: position)
marker.title = "London"
marker.snippet = "Population: 8,174,100"
marker.map = mapView
```

## やってみた

やってみました、表示されませんでした。

タップが無視されているような感じだったので `isUserInteractionEnabled` を一通り確認しましたが、全て `true` でした。

## mapView: didTapMarker

怪しげな delegate メソッドが実装されていました。

```swift
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
    print(marker)
    return true 
}
```

- [mapView: didTapMarker](https://developers.google.com/maps/documentation/ios-sdk/reference/protocol_g_m_s_map_view_delegate-p#ae291e1bff99f9d06428ced09daf5802d)

`true` を返す場合はこのメソッド内でタップイベントを処理し、 `false` を返す場合はイベントを流すようです。
吹き出しを表示する場合はタップイベントを流して、 GMSMarker のデフォルトのタップ時の処理( **info window** )に任せる必要がありそうです。

ということで、

```swift
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
    print(marker)
    return false
}
```

やってみました、表示されませんでした。

ログを確認したところ `print(marker)` が出力されていませんでした。
ブレークポイントを貼ってみてもこのメソッドは呼び出されていないようです。
つまり **info window** の話以前にマーカーがタップイベントを取得できていないという事です。

ちなみに `mapView.delegate = self` は適切に設定されています。
他の delegate メソッドが呼び出されることは確認しました。

## clusterManager: didTapCluster

怪しげな delegate メソッドが実装されていました。

```swift
func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
    print(cluster)
    return true
}
```

- [clusterManager: didTapCluster](https://github.com/googlemaps/google-maps-ios-utils/blob/8cfa1372e63db40b9b1206ea020414f967b3982d/src/Clustering/GMUClusterManager.h#L40)

Cluster とは複数のマーカーがマップ上の近い位置に存在するときに、 1 箇所に纏めて 1 つのアイコンとして表示する機能です。
[Google Maps SDK for iOS Utility Library](https://github.com/googlemaps/google-maps-ios-utils) という Google Maps SDK の機能を拡張するためのライブラリに含まれる機能です。

ということで、

```swift
func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
    print(cluster)
    return false
}
```

やってみました、**表示されました**。

今回の犯人はこいつでした。
Cluster のアイコンがタップイベントを処理しており、 Marker にイベントが流れてこない状態となっていました。

## まなび

基本的には [Google さんの教え](https://qiita.com/muhiro12/items/a0b683d5f1bd7188138e#google-さんの教え)に従えば吹き出しは表示されます。
今回はイレギュラーなケースでしたが、その際の着眼点を記事に残しておきたいと思いました。

タップが無視されるという現象はアプリ開発をしていると割と頻繁に遭遇します。
これまでの経験では

- `isUserInteractionEnabled`
- UIButton の `isEnabled`
- フォーカスの位置

辺りを見ていると大方解決できていました。
delegate の処理でタップイベントを 流す / 流さない を管理するパターンは初めてだったので知見が広がりました。
UE4C++の環境セットアップ

#はじめに
初投稿。
ue4c++に関してはリファレンスがまだ不十分であるため、自分用の資料として記事を書いていこうと思う。
最初ということでue4c++の始め方についてまとめる。ue4の使い方やVisualStudioのインストールはさすがにわかるだろう。割愛する。

#プロジェクトの作成
とりあえず適当にプロジェクトのテンプレートを選択する。
その後**[プロジェクト設定]**の左上
**[ブループリントプロジェクトかC++プロジェクトか選択]**
でドロップダウンから**[C++]**を選択する。
（ここブループリントプロジェクトだとC++がうまく機能しないことがある。詳しいことは知らん）
![プロジェクトブラウザ 2020_09_10 21_02_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/a0f161b9-04d1-2870-b896-33ca66afbceb.png)
残りの設定項目は好きに設定すればよい。

次にプロジェクトの保存場所を選択する。
デフォルトのままでもよいが、ue4のプロジェクトはかなり容量が大きくなるので**Cドライブは避けたほうが良い**。（Cドライブはなにかと容量が足りない）

保存場所を決めたらプロジェクト名を付けて**[プロジェクト作成]**を押してプロジェクトを作成する。

ここでプロジェクトが作成できない場合は、VisualStudioのバージョンが古すぎることが原因としてある。アップデートしよう。

#VisualStudioの設定
####1.ソリューションファイルを開く
プロジェクト作成が成功すれば見慣れた画面が見えるだろう。
おそらくこの時点でVisualStudioも自動で起動しているはずだ。
開いていない場合は、
ue4エディタ画面右上の**[ファイル]**→**[VisualStudioを開く]**か、
![スクリーンショット (94).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/3dedd123-64df-251c-4f31-993453b45bdf.png)
エクスプローラーからプロジェクトのフォルダにいき、
**プロジェクト名.sln**を開けばよい。
![スクリーンショット (95).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/95551b50-20a3-4971-88c2-3784e408c606.png)
####2.プロジェクトのソースコードの確認
プロジェクトのソースコードは**[Games] / [プロジェクト名] / [Source] / [プロジェクト名]** にある。
![スクリーンショット (96).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/93cb0e64-eac8-1170-25b7-3758c5e5fbac.png)
####3.構成の確認
**[Development Editor]**のWin64を選択。
![スクリーンショット (97).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/b58ead85-9305-8717-f1df-9a73eae87280.png)
####4.出力ウィンドウの文字化けを直す
新しいバージョンのVisualStudioだとMSBuildのMakeファイルがUTF-8指定されており、ue4との文字コードが合わないため文字化けが起きる。
![スクリーンショット (98).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/fa45c6e6-8f8a-c1a7-1d74-3cc9bdbab984.png)
下記を参照しながら解決してほしい
[VS2019でUE4のビルド時に日本語出力が文字化けする](https://qiita.com/steel_code/items/ad1fa34078582691300f)

簡単にまとめると
C:\Program Files (x86)\Microsoft Visual Studio\2019\ $(Edition)\MSBuild\Microsoft\VC\v160\
にある
**[Microsoft.MakeFile.targets]**の**[Build/Rebuild]**欄の**chcp命令**と**UFT-8 Encoding**を消せばよい。

これを行う前に必ず**バックアップ**を取ろう。また、Microsoft.MakeFile.targetsは元の位置にあると上書きできないので、**一旦別の場所に移動させてから編集**し、元の場所に戻す必要がある。

修正ができたら出力ウィンドウの文字化けは治っているはずだ。
（まぁこの段階では確認しようがないと思うが）
![スクリーンショット (99).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695645/98b815fb-cf7a-9e84-e925-6bcd1e2c3d48.png)
以上でVisualStudioの設定は完了。
（一応ue4用のビルドツールなるものがあるらしいがまぁ後でやろうと思う）

#おわり
とりあえずここまでやればc++でue4のコードを書いていくことが出来る。

次回は**C++クラスの作成**について書く予定。
気が向いたら更新する。
自由研究〜バットを静止させたままでも、めちゃくちゃ早く玉を投げればホームランできるかの研究の動画〜

バットボールの画像
![バット、ボール.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/b127461a-860f-7c05-6972-104d99caa558.gif)
⚠︎ボールは、見やすいように光らせています
球場の画像![球場.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/28773b62-e219-1e6a-ea7d-367e78221c6f.gif)







No.1 時速90キロメートル ![ezgif-7-321248025c7c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/b9e3ffed-1694-4bd5-7203-8a01f37ac1e0.gif)
　

No.2 時速120キロメートル ![120.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/75a9c754-b41c-9dfc-a3fd-53673f5dc515.gif)



No.3 時速165キロメートル 画像悪くてすいません ![165.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/b2dea77f-05fd-81b3-1950-a47062dc8c40.gif)


No.4 時速200キロメートル ![200.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/1b669090-4931-c189-10c3-82dd1308a4bc.gif)



No.5 時速250キロメートル![250.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/bf8e3211-438e-34f9-fdd2-612cfd8c32c0.gif)


No.6 時速300キロメートル![300.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/068b2cd4-f994-46ff-dded-431472952dc6.gif)


No.7 時速400キロメートル(0.5倍速)![400.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/1ed02ee2-a943-3df9-b8c8-a8ea677ff86b.gif)


No.8 時速500キロメートル(0.3倍速)![500.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/627af262-7a1f-a1d7-5ccf-5a203c42ec9e.gif)


No.9  時速1000キロメートル(0.3倍速)![1000.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/94422e05-d956-43b4-c6bc-6789b8b06afd.gif)


No10 時速2000キロメートル(弾が速すぎて見えないので左上のメートル表示をみてください)
![2000.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/533b7600-15c6-816e-b61f-74f776a0ba15.gif)

No11 時速2300キロメートル(弾が速すぎて見えないので左上のメートル表示をみてください)
ホームラン！![2300.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692314/c0c4b6b9-38f8-1ad4-80f9-c643f46dc10f.gif)
　　

ありがとうございました