OmniAICreator/Qiita-1.07M huggingface dataset:
jetson nano

# jetson nanoのmanのファイルのあるディレクトリ

* manpages
  * /usr/share/man
* manpages-ja
  * /usr/share/man/ja
    * /usr/share/man/ja/man1 ・・・実行プログラムまたはシェルコマンド
    * /usr/share/man/ja/man2 ・・・システムコール (カーネルが提供する関数)
    * /usr/share/man/ja/man3 ・・・ライブラリー呼び出し (プログラムライブラリーに含まれる関数)
    * /usr/share/man/ja/man4 ・・・Special files (usually found in /dev)
    * /usr/share/man/ja/man5 ・・・ファイルの書式と慣習 (例: /etc/passwd)
    * /usr/share/man/ja/man6 ・・・ゲーム
    * /usr/share/man/ja/man7 ・・・Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
    * /usr/share/man/ja/man8 ・・・システム管理コマンド (通常は root 用)
    * /usr/share/man/ja/man9 ・・・カーネルルーチン [非標準]

# jetson nanoのmanがない

[nVIDIA DEVELOPER Forumsの「Where are the man pages?」](https://devtalk.nvidia.com/default/topic/1052585/jetson-nano/where-are-the-man-pages-/)より

ファイル```/etc/dpkg/dpkg.cfg.d/excludes```のpath-exclude=/usr/share/manとpath-exclude=/usr/share/docの行をコメントアウトして対象のパッケージをre-インストール。

```
# Drop all man pages
 #path-exclude=/usr/share/man/*

 # Drop all documentation ...
 #path-exclude=/usr/share/doc/*
```

# jetson nanoでWebプログラミング（PHP）

```
sudo apt install apache2 libapache2-mod-php # v7.2
```
```
# sslにする場合、右のページを参考（https://qiita.com/nkojima/items/91988b1e91e311311040）
# にして、sites-available/default-ssl.confを編集
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo systemctl restart apache2
```
```
# ユーザーディレクトリを公開する場合
sudo a2enmod userdir
sudo vi /etc/apache2/mods-available/php7.2.conf #  <Directory /home/*/public_html>のphp_admin_flag engineをOnにする
sudo systemctl restart apache2
mkdir ~/public_html
```

# ユーザーディレクトリを共有フォルダにする（samba）

```
sudo apt install samba
sudo vim /etc/samba/smb.conf
sudo systemctl restart smbd
sudo smbpasswd -a $USER
```

# microk8sを使う
[Jetson Zoo - Kubernetes](https://elinux.org/Jetson_Zoo#Kubernetes)

```
sudo snap install microk8s --classic
sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube

exit #ユーザー設定の変更を有効にするため、ログインし直す。

# login
microk8s status --wait-ready
```

https://microk8s.io/docs/getting-started
Atcoderで累積和が出てきたのでこれを機にちょっと勉強する

# 累積和とは
サイズNの配列があって、ある区間iからjまでの和$(0<=i<j<=N)$を爆速で取り出すことができるアルゴリズム。

すでに先人達が多くの解説記事を上げているので、詳細な解説はここでは書かない。
（個人的にはけんちょんさんの記事がわかりやすかった）
[累積和を何も考えずに書けるようにする！](https://qiita.com/drken/items/56a6b68edef8fc605821#fn1)

# Pythonで累積和を実装する
脳筋実装すればこうなる。

```python
# 1~10のリスト
a = [1,2,3,4,5,6,7,8,9,10]

# 累積和用リスト
s = [0] * 10

s[0] = a[0]

for i in range(1, 10):
        s[i] = s[i-1] + a[i]
print(s) # [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
```

例えば、インデックスが3〜7の区間の和を取りたければ`7までの和` ー `2までの和`で求めることができる。

```python
print(s[6] - s[1]) #25
```

こういった配列sを作る方法は上に上げた脳筋forループの他にもいくつかあるが、pythonを使う上で一番早いのはおそらく`Numpy.cumsum`である。

速度については下記記事で検証されているので、気になる方はどうぞ。
[リストから和のリストを得る（累積和）](https://qiita.com/bluepost59/items/b3d982097b48488ed070)

`cumsum`の使い方は↓

```python
import numpy as np
# 1~10のリスト
a = [1,2,3,4,5,6,7,8,9,10]

# 累積和用リスト
s = np.cumsum(a)
print(s) # [ 1  3  6 10 15 21 28 36 45 55]
```

Pythonは便利なライブラリが多くていいですね。
Ubuntu18.04にPython3.8 + Pipenv環境を構築

# はじめに
Ubuntu18.04に環境構築したので、作業メモとして残します。
Python3.8のインストールにはpyenvを使用します。

### 環境
Ubuntu 18.04.3 LTS

# 手順

## 1.Git インストール
```
$ sudo apt install git
```

## 2.pyenv インストール

githubからpyenvをクローンする。

```
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

パスを環境変数に設定。
Ubuntuだと.bash_profileでなく.bashrcに記載する。
[参考]
https://github.com/pyenv/pyenv#basic-github-checkout

```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
```
シェル起動時にpyenvが起動されるように設定。

```
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bashrc
```
シェル再読込 & インストール確認。

```
$ exec "$SHELL"
$ pyenv --version
pyenv 1.2.15-2-g22c02022
```

## 3.Python3.8 インストール

Pythonのビルドに必要なパッケージをインストールする。
[参考]
https://github.com/pyenv/pyenv/wiki#suggested-build-environment

```
$ sudo apt-get update; sudo apt-get install --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
```

Python 3.8.0 をインストール（時間がかかるので気長に待ちます）

```
$ pyenv install 3.8.0
```

インストール確認

```
$ pyenv versions
* system
  3.8.0
```

## 4.ローカルで使用するPythonを指定する
pyenvでインストールしただけではPython3.8は有効にならないので、明示的にバージョンを指定する。

```
$ mkdir -p ~/sample/py38
$ cd ~/sample/py38
$ pyenv local 3.8.0
```

ローカル以下(上の例だとpy38ディレクトリ以下)でpython3.8が有効になる。(pipコマンドも同様)

```
$ python --version
Python 3.8.0
$ pip --version
pip 19.2.3
```

## 5.Pipenv インストール

```
$ pip install pipenv
$ pipenv --version
pipenv, version 2018.11.26
```

## 6.Pipenv プロジェクト作成

環境変数に`PIPENV_VENV_IN_PROJECT=true`を指定すると、プロジェクト直下にvenvディレクトリが作成される。vscodeとの連携がしやすいため、ここではtrueに設定する。

```
$ mkdir pipenvdemo
$ cd pipenvdemo
$ export PIPENV_VENV_IN_PROJECT=true
$ pipenv --python 3
```
Javaプログラミング (クラスとインスタンス、メインメソッド)

#メインメソッド
Javaは必ずクラスで構成されます。クラスのなかで処理はメソッドに書かれます。メソッドのなかで、おおもとの操作や処理はメインメソッドというメソッドに書かれます。
##メインメソッドの書き方
メインメソッドは次のように書きます。クラス名は命名ルール通りにTestクラスとしましょう。

```java
public class Test(){
  public void main(String[] args){
/*
*メインメソッドの処理の中身
*おおもとの操作はここに書かれる。
*/
 }
}
```

ここで

```java
public static void main(String[] args)
```
という書き方は覚えてください。
ちなみに、publicとstaticの間のstaticはstatic句といい、メソッドや変数に付けられます。詳しい意味はここでは触れません。

意味があってこのようなルールになったらしいのですが、そこまで追求しなくてもいいと思います。
ただ、普通のメソッドの書き方になっていることは理解してください。

##クラスを使う
では、このTestクラスのメインメソッドでCalculateクラスのmultipleIntegerNumberメソッドを使ってみましょう。
このメソッドは

```java
public class Calculate {
 public int multipleIntegerNumber(int num){
  num = 3*num;
  return num; 
 }
}
```
です。
###インスタンス化
クラスを使うにはまず、クラスのインスタンス化をします。

```java
Calculate cal1 = new Calculate();
```
このcal1はインスタンスと呼ばれます。
###メソッドの呼び出し
次にメソッドを呼び出します。

```java
cal1.multipleIntegerNumber(3);
```
こうすることで、メソッドは戻り値の9を結果として返してくれます。
セッション有効期限の伸ばし方

#セッション有効期限の伸ばし方

 自分の学習用ログ

セッションの有効期限を30日間にする場合

```php:
//1、セッションファイルの置き場を変更する
session_save_path("var/tmp");

// 2、ガーベージコレクションが削除するセッションの有効期限を設定
ini_set('session.gc_maxlifetime',60*60*24*30);

// 3、ブラウザを閉じても削除されないようにクッキー自体の有効期限を伸ばす
ini_set('session.cookie_lifetime',60*60*24*30);

// 4、セッションを使う
session_start();

// 現在のセッションIDを新しく生成したものと置き換える
session_regenerate_id();
```
Pytestで標準出力をテストする

業務でPythonを使うことになり、標準出力をテストしたかったのでメモとして

## 準備
- Python 3系
- pytest

```
pip install pytest
```

## テスト対象コード

下記プログラムをテストしたいと思います。
`say`メソッドで標準出力へ出すだけです。

```python:hogehoge.py
class HogeHoge:
  def __init__(self, name):
    self.name = name
  
  def say(self):
    print("Hello ! My name is " + self.name + ".")
```

## テストコード

`pytest`にある fixture、[capfd](https://docs.pytest.org/en/latest/capture.html)を使う

```python:test_hogehoge.py
from hogehoge import HogeHoge

def test_say(capfd):
  instance = HogeHoge("Taro")
  instance.say()

  out, err = capfd.readouterr()
  assert out == "Hello ! My name is Taro.\n"
  assert err is ''
```

```
[Sun Nov 24 17:58:49 2019] Running: c:\python\python.exe -m pytest
============================== test session starts =============================== 
platform win32 -- Python 3.7.2, pytest-5.3.0, py-1.8.0, pluggy-0.13.1
rootdir: D:\Document\repository\study_pytest
collected 1 item

test\test_hogehoge.py .                                                     [100%] 

=============================== 1 passed in 0.08s ================================ 
```

## まとめ
標準出力のテストには、`capfd`を使おう。標準エラーも取得できます。
BoxCox変換と木系アルゴリズム

機械学習の勉強仲間の友人がKaggleのハウスプライスの課題で、
**＞Box-cox変換**をした

という話をしていました！
それで精度が上がったとのこと！

https://sonaeru-blog.com/kaggle-4/
上記の記事を参考にしたそうです。

そもそもBox-cox変換ってなんや！！と思いましたので、
自分なりに調べたことをメモにします。

その友人曰く、
＞正規分布に近づけるという意味では対数化と同じようなものなのかなと

とのこと。
## Box-cox変換ってなに？？

こちらの記事が、大変参考になりました。
https://gakushukun1.hatenablog.com/entry/2019/04/29/112424

式
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518137/1d176510-b92f-a1bf-3834-7857c76bcff9.png)

変換前後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518137/d58d3fd8-cab9-b426-7759-070332f0e645.png)


**対数変換をより一般化したもの**と考えると良いように思います。
実際λ=0のときには、対数変換になります。

対数変換は、どちらかというと、上の図に近いような０でピークがあって、
裾野が正規分布よりずっと長い分布なら、理論的に完璧に正規分布に置き換えることができる。

実際上の方のグラフは下に比べて、λが０に近い値なので、
これくらいの分布なら、多分、対数変換でも線形回帰でほぼ問題ないような気がします。
(なんとなくこれまで拙い自分の経験則。と言いつつ、Box-cox変換したらもっと精度上がる？)

**しかし、そもそもこれって、線形回帰アルゴリズムを前提としてますよね！**

##決定木系のアルゴリズムはBox-coxが必要か？

Kagglerとしての順位を少しでも上げたい自分として、
個人的に一番きになるのは、LGBMのような、いわゆる「木系」は、
説明変数の特徴量エンジニアリングとして、
box_coxが不要と考えて問題ないのか？それとも使った方が良いのか？？

https://toukei-lab.com/box-cox%E5%A4%89%E6%8F%9B%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E6%AD%A3%E8%A6%8F%E5%88%86%E5%B8%83%E3%81%AB%E5%BE%93%E3%82%8F%E3%81%AA%E3%81%84%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E8%A7%A3%E6%9E%90
＞最近流行りの機械学習手法はノンパラメトリックモデルと呼ばれ、
＞背後に分布を想定していないものが多いです。

こちらの記事によると不要とのこと！！

**「numericなパラメータも、結局大小関係でしか判定され得ないから」**
が理由だと思ってます。

ただ、目的変数に関しては、必ずしもそうでないように思う。
(実際、目的変数を対数にとることも多いので)
その理由は数少ない大きな外れ値への、モデルのペナルティを下げるため
と理解しています。

じゃあ、
##目的変数をBoxCock変換する場合はあり得るのか？

https://books.google.co.jp/books?id=t1a_DwAAQBAJ&pg=PA222&lpg=PA222&dq=%E7%9B%AE%E7%9A%84%E5%A4%89%E6%95%B0+boxcox&source=bl&ots=L7yjHQ6y6G&sig=ACfU3U3U1ugf0XhDVN_4fKAVnYe9xcFBSQ&hl=ja&sa=X&ved=2ahUKEwi2p_-itoLmAhXZA4gKHUutDmcQ6AEwBXoECAoQAQ#v=onepage&q=%E7%9B%AE%E7%9A%84%E5%A4%89%E6%95%B0%20boxcox&f=false
どうやらあるようです。
ただそれはすなわち、コスト関数にRMSEを使わないことと、
多分同義なので、そちらの選択の方が直観的な気がします。
https://www.sciencedirect.com/science/article/abs/pii/S0031320396000775?via%3Dihub
そして、見事に目的変数をboxcox変換するようなコスト関数を実装しましたというabstractの論文を発見しました。

中身は見れねぇ！し、ちょっと飽きたので、この辺にしておきます。

##勉強は積み重ね

今回、知らない言葉を調べ初めて、自分なりに納得感のある答えに辿り着いた上で、
新たな疑問の仮説を立て、それについての知見を得られたのは、非常に気持ち良い体験でした。

でも、一つ一つは最近知ったばかりのことの積み重ねだなと感じました。

・指数関数についてそこそこ知ってる(これは昔のおかげ)
・β関数について知ってる(これは統計勉強会です)
・木系は変換が不要(これは昨日、渡辺さんが言ってました)
・目的変数は変換することがある(これは最近よく出くわす)
・RMSEは残差の分布を正規分布と仮定してる(これは授業でやりましたね)
・コスト関数は個別に実装できる(これは最近のKaggleです)

引き続き頑張ろうと思います。
Remotte（リモッテ）で時系列データの詳細を見る

[前回](https://qiita.com/remotte_jp/items/7ec79a400429738843d0 "Remotte（リモッテ）を利用者として使う")は利用者としてログインし、アプリの利用ページを表示してみた。
今回はその画面から「詳細画面」を表示してみる。
### 準備
[リモッテ](https://www.remotte.jp/ "ホームページ")では、利用者ログインし、画面左上のメニューボタンを押し、ステーションの承認をした後、表示したい「利用ページ」を選択することでアプリの画面を表示する。まずは「ステーションの管理」アプリの利用ページを表示するところまでの操作をしておこう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/878e12a8-5418-950b-9af5-b2b130ba2a3a.png)
### 詳細画面を表示
上記の様に、「ステーションの管理」アプリの利用ページ「現在の状態」にて、グレー色の折れ線グラフとして表示されている「CPU の温度」には過去１０分間の履歴が表示されている。このグラフをダブルクリックして履歴の詳細画面を表示してみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/d0cbc544-7ee1-abf5-3bac-a065ed4992c8.png)
履歴の詳細画面ではまず、その上部にて、画面に表示する情報の時間幅を選択できる。上記では、「１０分間」が選択されているので、折れ線グラフの左端から右端までは１０分間という訳だ。上から２段目では「日時」を選択する。スライダを左右に動かしたり、左右の矢印ボタンをクリック、ないしはグラフ表示部分を左右にフリックすることで、表示したい過去の日時を移動できる。画面の右側には、選択された日時から時間幅分の生のデータが表示されている。また、その下の保存ボタンをクリックすれば、表示中のデータを CSV 形式で保存できる。詳細画面から元の利用ページに戻るには、画面左上の左矢印を押せばよい。

同様にして、「ステーションの管理」アプリの利用ページ「ログ」で表示されている３つのテーブル表示の履歴の詳細画面も見てみよう。時間幅を「１ヶ月」にすると、より多くの情報が表示されるはずだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/8ff37754-6da8-2dd8-1bbc-7d632d9b631d.png)
### 詳細画面に遷移する表示要素
何でもかんでもダブルクリックすれば詳細画面が表示されるかと言えばそうではない。詳細画面が存在する表示要素は、履歴のグラフや表といった過去のデータを表示する要素と、次回の投稿で操作してみる予定のビデオ、音声といった表示要素だ。注意点としては、これらの詳細画面は利用者ログインした場合にのみ表示可能で、管理ツールからは表示できないこと。管理ツールでダブルクリックすると以下の画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491154/b107c461-300d-30c7-e9db-7a4e32fbe306.png)
### まとめ
履歴の詳細画面を表示することで、過去の情報を簡単にきれいに表示できた。次回はリモッテの大きな特徴の１つであるビデオと音声を扱ってみる。リモッテ・ストアから一番簡単なアプリ「ビデオと音声の配信」をダウンロード、実行し、同時にその詳細画面からスナップショットを撮ったり、ビデオ録画、再生およびファイル保存する操作をしてみよう。
AWS LambdaでECSのRunTaskを実行する


## はじめに
ECSを用いたDockerでRailsのデータベース更新する場合、どうやってデータベース更新をすればいいのか悩むことになった。

色々と調べた結果、ECSのRunTaskでデータベース更新を行う企業が多いと判明。
RunTaskをAWS Lambdaで実現するためにはどうすれば良いのかを纏める。

## ECS RunTaskとは
ECSでDockerコンテナを動作させている。
これはDockerfileで指定したコマンドが動作している。

Dockerコンテナに対して単発で実行できるのが特徴！


## 構成
- AWS Lambda(Python 3.8)
- Elastic Container Service （ECS）


## 前提
ECSですでにDockerやEC2が立ち上がっている前提とする。

### ECS情報
- クラスター名： `cluster-name`
- タスク定義： `task-definition-family`


## RunTaskでbundle exec rails routesを実行する

```python
import json
import boto3

ecs = boto3.client('ecs')

def lambda_handler(event, context):
    # ECSタスクの実行（単発）
    response = ecs.run_task(
        cluster='cluster-name',
        taskDefinition='task-definition-family',
        launchType='EC2',
        overrides={
            'containerOverrides': [
                {
                    'name': 'container_name',
                    'command': ["bundle","exec","rails", "routes"],
                    'memory': 64
                }
            ]
        }
    )

    # エラーの検知
    print(response)
    failures = response['failures']
    if len(failures) != 0:
        print(failures)
        return {
            'statusCode': 500,
            'body': json.dumps('NG!')
        }
        
    # 正常終了
    return {
        'statusCode': 200,
        'body': json.dumps('OK!')
    }
```

## 説明

参考：[ECS RunTask](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.run_task)


### run_taskのパラメータ
- cluster： ECSのクラスター名を指定する
- launchType: EC2で起動するかFargateで起動するかを指定する
- taskDefinition: 実行するタスク定義を指定（デフォルトでlatest）
- overrides: 上書きするコンテナ情報を設定する
  - containerOverrides
    - name: コンテナ名
    - command: Dockerコマンドに上書きするコマンド
    - memory: Dockerのメモリー

上記以外のパラメータ以外はboto3の公式を参照。


## まとめ
ECS RunTaskをAWS Lambdaで実行できる様にすることでCodePipelineと組み合わせたりCodeDeploy→SNSと組み合わせることもできてアーキテクチャの自由度が増すのでおすすめ！
[Go] 音声実況動画をMacで作りたくて(その一)

# はじめに
ゆっくり実況の使う音声はライセンス的に,いまいち自由に使いにくい。
https://manjubox.net/ymm4/
しかもwindows環境ならまだしも、Macでうまいことやろうとすると、virtual boxを入れたりとか
音声とは別に字幕作ったりとか正直~~めんどくさい~~手間がかかる。
ネットの海を探したら、あるのかもしれないが、そんなググる力はなかった。

だったらGoで作った方が~~楽しそう~~融通がきいてカスタマイズが自由自在だから良いと思う(小並感)

# ツール探し
### 音声
ライセンス的に自由に使えそうなのを探した結果、以下のOpenJTalkを採用。
コマンドラインから使えるので、ラップして使うことに決定
参考
[OpenJTalk](http://open-jtalk.sourceforge.net/)
http://kuuur.net/tech/movie-voice/openjtalk
### 字幕画像作成
Go製のツールでやりたいことから以下ツールを選定

```
"github.com/disintegration/imaging"
"github.com/fogleman/gg"
```

# 実行環境
13 inch mac book pro 
go version go1.13 darwin/amd64 

# 実装
~~自分だけしか使わないので~~GUIを実装を諦めてコマンドラインツールとして作成することにした。
##このツールできること
・複数人の会話劇
・音声ファイルの出力
・読み上げキャラの画像を埋め込み
・字幕画像の出力
・文字色の指定
・文字のプレフィックスによるキャラクターわけ
・一部自動改行

## いまいちな点
画像内の文字の位置計算が微妙で結構見切れる(未完成)
処理が効率化されていない(未完成)
READMEが役割を果たしていない...
コメントが中途半端

## 実行方法
1, 以下のようなテキストファイルを用意する。

```sample.txt
1.こんにちは。ゆっくり実況始めるよーーー
```
2, 設定ファイルに音声ファイルや、画像サイズ、キャラクター画像を設定する
3, go run main.goで実行する

## 出力結果
![0_こんにちは.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141154/ed3c0f5f-f10f-9bce-5b9a-db662549aa23.png)
+音声ファイル

# 得られた知見
・他オープンソースツール公開者への感謝
・modの使い方
・基本的な画像処理
・viperの使い方
・tomlの扱い方

### その他
一応参考までにgit hubにあげておきますが、ソースコードを信用してはいけません。個人ツールです。
https://github.com/hiromichi-n/text2talk

そもそも素材収録してないので、結局何がしたかったのか忘れたorz。
次は使い始めてからのバグ修正編を書きたい(願望)
Python 画像の読み込みを高速化する

画像処理や画像系ディープラーニングでは，画像を読み込む処理が頻繁に発生します．

数百枚ならまだしも，数万枚規模になると読み込むだけで数分かかってしまいますし，１回だけならまだしも，実験のために何度も読み込むならなおさら高速化したいところです．

ここでは，いくつかのライブラリを比較して，読み込み時間を減らす方法を紹介します．

# 結論

- **`pickle`か`np.save`で画像を保存しておく**（データサイズは肥大化する）
- `pickle`のプロトコルは新しいのを使う
- `np.uint8`で保存する

# 実行環境

- macOS Mojave 10.14.6
- Python 3.6

# 読み込み速度の比較

使用したライブラリと，画像１枚の読み込み（numpy.arrayとしてデータを取得）にかかった時間は以下の通りです．

| ライブラリ | 読み込み時間 |
|:-----------|------------:|
| OpenCV | 4.23 ms |
| matplotlib | 4.37 ms |
| keras.preprocessing | 3.49 ms |
| skimage | 2.56 ms |
| PIL | 2.63 ms |
| numpy | 333 µs |
| pickle(protocol=1) | 597 µs |
| pickle(protocol=2) | 599 µs |
| pickle(protocol=3) | 112 µs |
| pickle(protocol=4) | 118 µs |
| _pickle(protocol=4) | 117 µs |

読み込んだ画像は512×512のpngファイルです．

numpyとpickleについては，あらかじめ画像を`.npy`, `.pickle`として保存しておいたものを読み込みましたので，公平な比較ではありません．
**前もって画像を変換しておけば，これくらいの速度が出る**という表であり，numpyやpickleが一概に速いと結論できるものではありません．

pickleは`pickle.dump`する際に[protocolを指定](http://inarizuuuushi.hatenablog.com/entry/2017/03/25/124646)することができ，**新しいプロトコルほど，読み込みの速度が上がる**そうですので，プロトコルごとに画像データを保存しています．

[accimage](https://qiita.com//hara_pets/items/e42eb4c9f75e0ff5d6c2)のような高速なライブラリもありますが，macOSに対応していなかったので使用していません．

[hdf5](https://qiita.com/simonritchie/items/23db8b4cb5c590924d95)という選択肢もありますが，未検討です．

使用したコードは以下のとおりです．（jupyter notebook使用）

```python
import cv2
import matplotlib.pyplot as plt
import pickle
import numpy as np
from keras.preprocessing import image
from PIL import Image
from skimage import io
import _pickle

def imread1(path):
    return cv2.imread(path)

def imread2(path):
    return plt.imread(path)

def imread3(path):
    img = image.load_img(path)
    return image.img_to_array(img)

def imread4(path):
    return io.imread(path)

def imread5(path):
    img = Image.open(path)
    return np.asarray(img)

def numpy_load(path):
    return np.load(path)

def pickle_load(path):
    with open(path, mode='rb') as f:
        return pickle.load(f)
    
def _pickle_load(path):
    with open(path, mode='rb') as f:
        return _pickle.load(f)

%timeit img = imread1(img_path)
%timeit img = imread2(img_path)
%timeit img = imread3(img_path)
%timeit img = imread4(img_path)
%timeit img = imread5(img_path)
%timeit img = numpy_load(npy_path)
%timeit img = pickle_load(pickle_path_1)
%timeit img = pickle_load(pickle_path_2)
%timeit img = pickle_load(pickle_path_3)
%timeit img = pickle_load(pickle_path_4)
%timeit img = _pickle_load(pickle_path_4)
```

# データサイズの比較

512×512の.png画像を，numpyとpickleで保存した際のサイズは以下の通りです．

| ライブラリ | データ型 | サイズ |
|:-----------|------------|------------:|
| 元データ | - | 236 KB |
| numpy | np.uint8 | 820 KB |
| pickle(protocol=1) | np.uint8 | 820 KB |
| pickle(protocol=2) | np.uint8 | 820 KB |
| pickle(protocol=3) | np.uint8 | 787 KB |
| pickle(protocol=4) | np.uint8 | 787 KB |
| numpy | np.float32 | 3.1 MB |
| pickle(protocol=1) | np.float32 | 4.9 MB |
| pickle(protocol=2) | np.float32 | 4.8 MB |
| pickle(protocol=3) | np.float32 | 3.1 MB |
| pickle(protocol=4) | np.float32 | 3.1 MB |

np.uint8でも，元データの３倍以上の容量を占めてしまうことがわかりました．

ストレージに余裕があって，読み込み速度をできるだけ上げたい場合には，いったんnpyやpickleなどで読み込みやすいように変換しておくのがよいようです．
100マス量子回路計算やってみよう〜初級編〜

駒場祭で、100マス積分や100マスホモロジー計算を配布していたのを見て、ふと思いつきました。
みなさん、やってみましょう。

# やり方
左列に書いてある量子回路に、上行に書いてある量子回路をつなげてできる状態をマス目に書いてください。
ただし、初級編では

```math
\begin{eqnarray}
|0> &=& \begin{pmatrix} 1 \\ 0 \end{pmatrix}\\
|1> &=& \begin{pmatrix} 0 \\ 1 \end{pmatrix}\\
|+> &=& \frac{1}{\sqrt 2}\begin{pmatrix} 1 \\ 1 \end{pmatrix}\\
|-> &=& \frac{1}{\sqrt 2}\begin{pmatrix} 1 \\ -1 \end{pmatrix}\\
|i> &=& \frac{1}{\sqrt 2}\begin{pmatrix} 1 \\ i \end{pmatrix}\\
|-i> &=& \frac{1}{\sqrt 2}\begin{pmatrix} 1 \\ -i \end{pmatrix}\\
\end{eqnarray}
```

のいずれかを記入します。これらの定数倍($-|i>$や$i|->$など)になった場合は、定数は無視して記入します。
たったこれだけしかないので、「これ重複しとるやん」みたいなのが多数ありますが、気にせずやっていきましょう。

#初級編
![100マス量子計算超初級編.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88256/798ab098-9302-623a-9525-d391cb07d8c1.png)

# キミはできたかな?
これを暗算できないと量子プログラミングできないかというと、全然そんなことないんですが。やっぱりできた方が便利です。
毎日練習して、量子回路暗算王を目指しましょう。

# 中級編、上級編?
初級編を作ってみたら、回路が場所を取って厳しい、ということが分かりました。
また、今以上に複雑な解だと、どうやって答えを記述するか、という問題も出てきます。

うまいこと作れたら、これからも出していきます。

# 答えがほしい

以下をコピペすれば、Blueqatで答えが求まります。

```py
import numpy as np
from blueqat import Circuit

# 初級編
tate = [
    Circuit().i[0],
    Circuit().h[0],
    Circuit().x[0],
    Circuit().y[0],
    Circuit().z[0],
    Circuit().s[0],
    Circuit().h[0].x[0],
    Circuit().h[0].y[0],
    Circuit().h[0].z[0],
    Circuit().h[0].s[0],
    Circuit().x[0].s[0],
]

yoko = [
    Circuit().i[0],
    Circuit().s[0],
    Circuit().z[0],
    Circuit().y[0],
    Circuit().h[0],
    Circuit().x[0],
    Circuit().h[0].s[0],
    Circuit().h[0].z[0],
    Circuit().h[0].y[0],
    Circuit().h[0].x[0],
    Circuit().x[0].s[0],
]

states = [
    (np.array([1, 0], dtype=complex), '|0>'),
    (np.array([0, 1], dtype=complex), '|1>'),
    (np.array([1, 1], dtype=complex) / np.sqrt(2), '|+>'),
    (np.array([1, -1], dtype=complex) / np.sqrt(2), '|->'),
    (np.array([1, 1j], dtype=complex) / np.sqrt(2), '|i>'),
    (np.array([1, -1j], dtype=complex) / np.sqrt(2), '|-i>'),
]
def get_answer(c1, c2):
    state = (c1.copy() + c2).run(ignore_global=True)
    for ref, ans in states:
        if np.allclose(ref, state):
            return ans
    raise ValueError(f'Unexpected states. {state}')

for c1 in tate:
    for c2 in yoko:
        print('{:4}'.format(get_answer(c1, c2)), end=' ')
    print('')
```
gitのローカルで行ったファイル削除をリモートに反映させる

ローカルで不要なファイルを削除したが，すでにリモートへpushしてしまっていて，削除したことがうまく反映されないときの解決方法．

# やること

```
git add -u # update option
git commit -m "deleted some files"
git push
```

# コマンドの意味
`git-add`の公式ドキュメントを見ると，
> -u
--update
Update the index just where it already has an entry matching <pathspec>. **This removes as well as modifies index entries to match the working tree, but adds no new files.**
If no \<pathspec\> is given when -u option is used, all tracked files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories).__

とあり，太字にした箇所のように「インデックスのエントリをワーキングツリーに削除/同期する」とあるので，この機能を使ったことになるのだと思われ...
`git rm [filename]`でもできるそうだが，これは指定したファイルをgit管理下から外すという操作なので，複数ファイルを扱いたい場合には少し面倒．


# 参考
ほぼこのページの丸パクリです．
http://core.hatenablog.jp/entry/2013/08/09/134511
【動画解説付き】OpenCV C++版をWindows10にインストールする方法【Visual Studio 2017】

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538330/7d403141-da15-337d-ee7b-599e787675cc.png)
どうも、プログラミングの鬼シヨツ鬼です。
この記事では「WindowsでOpenCVのC++版が使いたいぜ」って人に向けてOpenCVのダウンロードからサンプルプログラム実行までの流れを説明します。
ちなみに、この記事は次の動画と同じ内容ですので、記事だけだと分かりづらい部分は、そちらもご活用ください。
**(ボタンの位置や操作方法などがわかるので、初心者の方は動画のほうが分かりやすいかも)**
[YouTube:OpenCVのインストール方法[Visual Studio][C++]](https://www.youtube.com/watch?v=I4d9o7jHow0)

#使用する環境
Windows10 64bit版
Visual Studio 2017

#OpenCVのダウンロード
OpenCVの公式ページよりOpenCVのインストーラをダウンロードします。
本記事では、現時点で最新版のバージョン4.1.2をダウンロードしました。
[ここからダウンロード](https://opencv.org/releases/)

#インストール
ダウンロードしたインストーラをダブルクリックします。
インストールディレクトリを入力するウィンドウが立ち上がるので、インストールするディレクトリを指定します。
本記事では、「C:\」にインストールをします。

#環境変数Pathの設定
環境変数Pathに「C:\opencv\build\x64\vc14\bin」を追加します。

#Visual Studioの設定

1.Visual Studio 2017を開き、「ファイル」＞「新規作成」＞「プロジェクト」＞「Visual C++」＞「空のプロジェクト」より新規プロジェクトを作成します。

2.「ソリューション プラットフォーム」より「X64」を選択します。(画面上のほう。「デバッグ」の下あたりにある)

3.「プロジェクト」＞「プロパティ」を開く。以下、プロパティ内での設定です。

4.「VC++ ディレクトリ」＞「インクルード ディレクトリ」＞「編集」より「C:\opencv\build\include」を追加します。

5.「VC++ ディレクトリ」＞「ライブラリ ディレクトリ」＞「編集」より「C:\opencv\build\x64\vc14\lib」を追加します。

6.「リンカー」＞「入力」＞「追加の依存ファイル」＞「編集」より「opencv_world412d.lib」を追加します。

#サンプルプログラム作成

1.「プロジェクト名を右クリック」＞「追加」＞「新しい項目」＞「C++ファイル」より新規ソースファイルを作成する。

2.画像表示を行う次のプログラムを書きます。

```cpp:test1.cpp
#include<opencv2\opencv.hpp>

int main(void) {
	cv::Mat img = cv::imread("C:\\opencv\\sources\\samples\\data\\baboon.jpg");

	if (img.empty()) return -1;

	cv::imshow("View", img);
	cv::waitKey();

	return 0;
}
```

3.「デバッグ」＞「デバッグなしで開始」を選択します。

4.画像が表示されれば成功！

#まとめ
OpenCVを使えば画像処理や画像認識を楽しめますので、ぜひ、チャレンジしてみてください。
読んでくれてありがとう！
参考になったら「:thumbsup_tone2:」押してね
衛星搭載通信バス

[rsp.](https://www.rymansat.com/)の仲間と衛星内通信バスのとしてCANはありかという話になった。ちょうど調べていたところだったので、いくつか紹介する。

## 衛星搭載通信バス
　[SAVOIR Advisory Group](http://savoir.estec.esa.int/SAVOIRFAIRE.htm)のリファレンス衛星アーキテクチャの提唱する衛星搭載通信バス(Onboard communication BUS) *1)

* MIL-STD-1553B
* UART
* CAN
* Spacewire

### MIL-STD-1553B
*2), *3)

　シリアル通信によるデータバスで、差動信号を使用するRS-422/RS-485を元にしている。MIL-STD-1553は、バスコントローラ(BC)，リモートターミナル(RT)，バスモニタ(BM)からなりそれぞれの間をツイスト線またはシールド線（同軸ケーブブル）でつなぐ。たぶんBCがマスタ、RTがクライアントノード。

　OSI参照モデルの物理層とデータリンク層の機能を持ち、MACアドレスに相当するアドレスでエンドtoエンドの通信を制御すると思われる。ネットワーク層以上は規定されていないが、CCSDS（宇宙データシステム諮問委員会）の規定するプロトコルに対応させているようである。

### UART

　AOCSセンサの制御に使用されると書かれている。AOCSはAttitude and Orbit Control Subsystemの略なので、衛星の姿勢や軌道制御に関わるセンサとの通信にUARTが使用されるということだろう。プロトコルまで規定されているかもしれない。
　AOCSセンサとして以下が挙げられる。*4)

* 太陽センサ
* 磁気センサ
* スタートラッカー
* ジャイロ
* GPS受信機

### CAN

*5)

　CAN (Control Area Network) は、２本のワイヤーで２値信号を送り、２本のワイヤー間の電位差でバスの論理状態が決まるインタフェースである。原型はボッシュ1983年に発表し、1986年SAE(Society of Automotive Engineers)の会議で正式に発表された。そして、1991年 CAN 2.0規格が制定された。国際標準としてデータリンク層がISO11898-1、物理層がISO11898-2が制定されている。

　ISOのCAN標準を補完するためECSS(European Cooperation for Space Standardization) によるCAN標準 ECSS-E-ST-50-15-CANbus extension protocol が制定された。*6)

* 宇宙機アプリケーションのためのCAN bus物理層仕様を規定
* 宇宙機アプリケーション内CAN bus上の上位レイヤプロトコル(CANopen)
* CANopenプロトコルに基づいたリアルタイム制御アプリケーションのための同期データ転送手法
* CANopenプロトコルに基づいた宇宙機アプリケーションの時間基準信号分配
* CAN busフレームIDの付与
* CAN bus冗長性管理

### Spacewire
*7), *8)

　SpecewireはECSSにより2003年に ECSS-E-ST-50-12C *9) として標準化された。Spacewireの処理ノード間を接続するもので、低エラーレート，低面積，低コスト，低遅延，全二重，ポイントtoポイントで結ぶシリアル接続，ワームホール方式経路設定(?)の特長を持つ。

特長

* 高性能の衛星搭載データハンドリングシステムを構築を提供
* システム統合コストの削減
* サブシステム間データハンドリングの互換性を提供
* 異なるミッションを越えてデータハンドリング機器を再利用を促進

※ESAが制定した標準なので自画自賛している面がある

## リファレンス
1) esa United space in Europe : [Architectures of Onboard Data Systems](http://www.esa.int/Enabling_Support/Space_Engineering_Technology/Onboard_Computer_and_Data_Handling/Architectures_of_Onboard_Data_Systems) Busses
2) esa United space in Europe : [Mil-STD-1553](www.esa.int/Enabling_Support/Space_Engineering_Technology/Onboard_Computer_and_Data_Handling/Mil-STD-1553)
3) JAXA 宇宙機設計標準体系 : [JERG-2-431 MIL-STD-1553B オンボードサブネットワーク設計標準](http://sma.jaxa.jp/TechDoc/Docs/JAXA-JERG-2-431.pdf)
4) [Attitude & Orbit Control System (AOCS) Introduction](https://www.slideshare.net/htyou/aocs-intro) Page 23
5) esa United space in Europe : [CAN - Controller Area Network Bus](http://www.esa.int/Enabling_Support/Space_Engineering_Technology/Onboard_Computer_and_Data_Handling/CAN_-_Controller_Area_Network_Bus)
6) [ECSS-E-ST-50-15C – CANbus extension protocol](https://ecss.nl/standard/ecss-e-st-50-15c-space-engineering-canbus-extension-protocol-1-may-2015/)
7) esa United space in Europe : [SpaceWire](http://www.esa.int/Enabling_Support/Space_Engineering_Technology/Onboard_Computer_and_Data_Handling/SpaceWire)
8) JAXA 宇宙機設計標準体系 : [JERG-2-432 Space Wire オンボードサブネットワーク設計標準](http://sma.jaxa.jp/TechDoc/Docs/JAXA-JERG-2-432.pdf)
9) [ECSS-E-ST-50-12C Space engineering SpaceWire – Links, nodes, routers and networks](http://everyspec.com/ESA/download.php?spec=ECSS-E-ST-50-12C_31JUL2008.044746.pdf)
Kubernetes上でdocker-androidを動かすためのyaml

```yaml
---
apiVersion: v1
kind: Service
metadata:
 name: android
spec:
 type: NodePort
 ports:
   - name: android-vnc
     port: 6080
     nodePort: 30680
   - name: android-console
     port: 5554
     nodePort: 30554
   - name: android-adb
     port: 5555
     nodePort: 30555
   - name: android-appium
     port: 4723
     nodePort: 30723
 selector:
   app: android
---
apiVersion: v1
kind: Pod
metadata:
 name: android
 labels:
   app: android
spec:
 containers:
 - name: android
   image: budtmo/docker-android-x86-8.0
   securityContext:
     privileged: true
   ports:
     - name: android-vnc
       containerPort: 6080
     - name: android-console
       containerPort: 5554
     - name: android-adb
       containerPort: 5555
     - name: android-appium
       containerPort: 4723
   resources:
     requests:
       memory: "2048Mi"
       cpu: "2000m"
     limits:
       memory: "4192Mi"
       cpu: "4000m"

```
【初心者】jQuery　読み込み／モーダル【備忘録１８】

##11/20～22に勉強したこと
###jQueryの読み込み
jQueryを使用する場合は、HTMLにjQueryライブラリを読み込む必要がある。
【HTML】

```html
<head>
 <script src="https:.....(ファイルのURL)..."></script>
</head>

<body>
.....
 <script src="script.js"></script>
</body>

```
上部をHTMLに書き込んでからjQueryのシートで準備⇒書いていく。

```js
$(function(){
  //この中に書いていく。

});

```

【気を付けること】
HTMLに書く際、＜/body＞の直前に書くことで表示速度が速くなる。

###モーダル
指定した箇所をクリックすると、モーダルの表示／非表示が行われる。

#####まずログインモーダル

１：まずHTMLで書いたモーダルをCSSで非表示にする。

```css
.login-modal-wrapper{
 display:none;
}
```

２：ログインボタンにclickイベントを設定し、どのように表示するか書く。

```js
$('#login-show').click(function(){
 $('#login-modal').fadeIn();
});
```

#####新規登録モーダル
１：ページに二箇所、新規登録のボタンがある場合class名を指定(idは複数×のため)

```html
... <div class="btn signup signup-show">
... <div class="btn message signup-show">
```

２：クリックした時の動作指定

```js
$('.signup-show').click(function(){
  $('#signup-modal').fadeIn();
});
```
【気を付けること】
今まで書いてきて、#signupだったり.signupと書く際に
「#」「.」が抜けることが多々あったので気を付けたい。

#####追加で知ったこと
CSSを書く際、複数のセレクタを適用する場合は「,」で区切ることができる。

###モーダルを閉じる
閉じるボタンにclickイベントを設定してからfadeOut指定

```js
$('.close-modal').click(function(){
  $('#login-modal').fadeOut();
  //ここにもうひとつ要素足す場合「,」などは不要！
});
```

クリックイベントを指定するクラス名は「ログイン」も「新規会員登録」も
共通にしておくこと！（※上記だと「close-modal」）
cmakeチートシート

# CMakeLists.txtの最小例

```cmake:CMakeLists.txt
project(test)
cmake_minimum_required(VERSION 3.10)

find_package(Eigen3 REQUIRED)
add_executable(hoge a.cpp)
include_directories(${EIGEN3_INCLUDE_DIRS})
```

```cpp:a.cpp
#include <Eigen/Core>
#include <iostream>

int main() {
  const Eigen::MatrixXd eye = Eigen::MatrixXd::Zero(2, 4);
  std::cout << eye << std::endl;
}
```

`cmake --help-command-list`すると，CMakeLists.txt内で使うコマンドの一覧が見れる．

# out-of-source buildを`cd`せずに行う
```bash
cmake -Bbuild -H.
make -C build
```

# ``find_package(XXX)``の`XXX`に書くべき文言を思い出したい場合

まずは，`cmake`がデフォルトで持っている`find_package`の対象を探してみる．

```
cmake --help-module-list
```
これは`/usr/share/cmake-3.10/Modules`を見ているっぽい．

自分でインストールしたパッケージの`find_package`は

```
pkg-config --list-all
```

で探せる．

`pkg-config`のHPは https://www.freedesktop.org/wiki/Software/pkg-config/ みたい．
探索PATHは

- /usr/share/pkgconfig/
- /usr/lib/x86_64-linux-gnu/pkgconfig

とかみたい．

# `pkg-config`を使って見つける場合
```cmake:CMakeLists.txt
project(test)
cmake_minimum_required(VERSION 3.10)

find_package(PkgConfig)
pkg_check_modules(EIGEN3 eigen3)
add_executable(hoge a.cpp)
include_directories(${EIGEN3_INCLUDE_DIRS})
```

Eigenは

- /usr/lib/cmake/eigen3/Eigen3Config.cmake
- /usr/share/pkgconfig/eigen3.pc

2つの探し方用のファイルがあるので，一番最初のように`find_package`でも探せるし，`pkg_check_modules`でも探せる．
ROS2チュートリアルのdummy robot demoを動かしてみる

# はじめに

ROS2のチュートリアル[Trying the dummy robot demo](https://index.ros.org/doc/ros2/Tutorials/dummy-robot-demo/)を動作させる手順を整理します。

ROS2の環境構築(distributionとしてdashingが、パッケージはros-dashing-desktopが導入済)がされていることを前提としています。

まだの方は、

- [Installing ROS2 via Debian Packages](https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Install-Debians/)

の"Install ROS 2 packages"までを済ませてください。Jetson Nanoだと、そのまま導入できます。Raspberry piだとRasbianではなく64bit版Ubuntuを導入する必要あります。

ROS2の環境を有効にしておいてください。

```
$ source /opt/ros/dashing/setup.bash
```

# ビルド環境の整備

デモのソースは、以下のGitリポジトリから取得できますので、

- [ros2/demos](https://github.com/ros2/demos)

これを`colcon`でビルドできるようにします。

まずは、必要なパッケージをインストールします。

```
$ sudo apt install python3-colcon-common-extensions python3-rosdep python3-argcomplete 
```

その後、rosdepの設定をしておきます。

```
$ sudo rosdep init
$ rosdep update
```

# ワークスペースの作成とビルド

次に、ワークスペースを作成して、ソースを取得し、ビルドします。今回、ワークスペース名は`ros2_ws`とします。

まずワークスペースを作成します。

```
~$ mkdir ros2_ws
~/ws$ cd ros2_ws
~/ws$ mkdir src
```

以上です。ROS1の時はcatkin_init_workspaceを実行する必要がありましたが、ROS2では必要ないようですね。

次に、ソースを取得し、dashingのブランチに切り替えます。

```
~/ws$ cd src
~/ws/src$ git clone https://github.com/ros2/demos.git
~/ws/src$ cd demos
~/ws/src/demo$ git checkout dashing
~/ws$ cd ../..
```

次は、rosdepで必要なパッケージ類を取得します。環境変数ROS_DISTROにdashingを設定しておきます。

```
~/ws$ export ROS_DISTRO=dashing
~/ws$ rosdep install --from-paths src --ignore-src -r -y
```

そして最後にビルドします。

```
~/ws$ colcon build
```

# 動かしてみる

では、デモを動かしてみます。まずは、demoが動作する環境を有効化します。

```
~/ws$ cd
~$ source ~/ros2_ws/install/setup.bash
```

次に、デモを動作させます。

```
~$ ros2 launch dummy_robot_bringup dummy_robot_bringup.launch.py
```

次に、動作を確認するために別のコンソールを開きます。（ROS2の環境を有効にすることを忘れずに）

この時点で既に、Joint情報（関節の角度情報）が送信されてますので、

```
~$ ros2 topic list
/clicked_point
/initialpose
/joint_states
/map
/move_base_simple/goal
/parameter_events
/robot_description
/rosout
/scan
/tf
/tf_static
```

と、`/joint_states`のトピックが送信されてきています。

```
~$ ros2 topic echo /joint_states
header:
  stamp:
    sec: 1574582467
    nanosec: 617346446
  frame_id: ''
name:
- single_rrbot_joint1
- single_rrbot_joint2
position:
- -0.9345480640439339
- -0.9345480640439339
velocity: []
effort: []
---
...
```

次に、ビジュアライザ(rviz)を表示して動作を確認してみます。

```
~$ rviz2
```

起動した直後は何も表示されていないと思います。以下の２つの操作が必要です。

- `Global Options`の`Fixed Frame`に`world`を指定
- `Add`ボタンを押して、`TF`を追加

![rviz2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51272/1b578d54-f366-a1c9-baef-72b22bed7e62.png)

すると、画面にリンクが表示されて元気に動きます。

![Screenshot from 2019-11-24 17-03-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51272/0848c1c7-3bee-5162-a01f-68aa548759b1.png)

以上です。
Cypressテストコード(Request関連)

## API
```integration/sample_spec.js
describe('request test', function() {
  it('', function() {
    cy.server()
    cy.route('GET','**/getUsers').as('getUsers')
    cy.wait('@getUsers')

    cy.get('#results').should('contain', 'user1')
  })
})
```

## Stub
```integration/sample_spec.js
describe('request test', function() {
  it('', function() {
    cy.server()
    cy.route('GET', '**/getUsers',
    {data: [
      {id: '1',name: 'user1'},
      {id: '2',name: 'user2'}
    ]}).as('getUsers')

    cy.wait('@getUsers')

    cy.get('#results').should('contain', 'user1')
  })
})
```

## Fixtures
```integration/sample_spec.js
describe('request test', function() {
  it('', function() {
    cy.server()
    cy.route('GET', '**/getUsers', 'fixture:getUsers').as('getUsers')

    cy.wait('@getUsers')

    cy.get('#results').should('contain', 'user1')
  })
})
```
```fixtures/getUsers.json
{
  "data": [{
      "id": "1",
      "name": "user1"
    },
    {
      "id": "2",
      "name": "user2"
    }
  ]
}
```
### 階層が深くてもいい
```integration/sample_spec.js
describe('request test', function() {
  it('', function() {
    cy.server()
    cy.route('GET', '**/getUsers', 'fixture:test/getUsers').as('getUsers')

    cy.wait('@getUsers')

    cy.get('#results').should('contain', 'user1')
  })
})
```
```fixtures/test/getUsers.json
{
  "data": [{
      "id": "1",
      "name": "user1"
    },
    {
      "id": "2",
      "name": "user2"
    }
  ]
}
```

## 複数Wait
```integration/sample_spec.js
cy.server()
cy.route('activities/*', 'fixture:activities').as('getActivities')
cy.route('messages/*', 'fixture:messages').as('getMessages')

cy.visit('http://localhost:8888/dashboard')

cy.wait(['@getActivities', '@getMessages'])

cy.get('h1').should('contain', 'Dashboard')
```
PostgreSQLでrails db:createするまでに出たエラーと解決方法

# はじめに
RailsでPostgreSQLを使おうとしたところ結構ハマったので解決方法まとめました
#環境
MacBook Air
Mojave 10.14.6
Cloud9
# エラーの原因と解決方法
## 【エラー1】  FATAL:  role "ec2-user" does not exist
PostgreSQL上に"ec2-user" というロールが存在しないという意味

※ロールとは権限をまとめたもの、ロールを設定しないとテーブルを作れなかったりする

本来はユーザーにロールを付与するものなので別物だが、上記のエラーはユーザーと
言い換えてもいいと思う

PostgreSQL上に"ec2-user"を作成してもいいが、PostgreSQLにはデフォルトで
"postgres"というロールが存在するのでそれを使うこともできる

そもそもログインユーザー名がローカルユーザー名になっているのはdatabase.ymlにusernameが抜けているからなので以下のようにusernameを追加すればOK

```ruby:database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  username: postgres

  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  
development:
  <<: *default
  database: sample_development

test:
  <<: *default
  database: sample_test

production:
  <<: *default
  database: sample_production

```

これで"ec2-user"ではなく"postgres"でアクセスされるようになるはずなのでロールが存在しないエラーは解決すると思う

## 【エラー2】  FATAL:  Peer authentication failed for user "postgres"
Peer認証を使っているため
※Peer認証とはUNIXユーザーとPostgreSQL内のユーザー名を比較して同じのがあればOK
なのでそもそもPostgreSQL内にec2-userのユーザーを作っておけば上記のエラーが出ない
今回は"postgres"を使用しており、これはUNIXユーザー名ではないのでエラーが起きたと考えられる

sudo vim /var/lib/pgsql9/data/pg_hba.conf
でpg_hba.confを開き、「peer」を「trust」か「md5」にする
「trust」 条件なしで認証
「md5」 パスワードが必要

設定を変更したあとは、sudo service postgresql restartでPostgreSQLを再起動しないと変更内容が反映されないので注意

## 【エラー3】  fe_sendauth: no password supplied
database.ymlにpasswordが設定されていないと出てくる

## 【エラー4】  FATAL:  password authentication failed for user "postgres"
database.ymlで指定しているpasswordが間違っていると出てくる

なお、PostgreSQLのデフォルトユーザーであるpostgresのパスワードはNULLになっておりどのパスワードでも解除できないので、あらかじめパスワードを設定しておく必要がある

さらにpg_hba.confの認証方法をmd5にしてしまうとパスワードを入力しないとそもそもPostgreSQLにアクセスできないのでパスワードを設定するときは一度peerかtrustにしておく
CSVファイルに向かってSQL投げたくなったときに




**DISCLAIMER: この記事は元記事（英語）が書かれてからだいたい3年くらいたっていて、いまだに書きかけです。**

# Apache Drill

[Apache Drill](https://drill.apache.org/) を使うとできる。

## 基本

```shell

root@drill:/microsoft# ~/apache-drill/bin/drill-embedded
May 03, 2016 1:05:03 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.8 2014-04-29 01:25:26...
apache drill 1.6.0
"got drill?"
```

CSVファイルにおもむろにSQLを投げることができる。また、CSVファイルの一行目をカラム名にすると、よりデータベーステーブルっぽく扱える。その際は、拡張子を `.csvh` にしておくと `drill` が自動的に一行目をカラム名として認識してくれるので楽です。

```sql

select * from dfs.`/microsoft/tmp2/B85-R2V.csvh` limit 10;
```
```sql

0: jdbc:drill:zk=local> select distinct(address), reputation_rating from dfs.`/data/iprdb/gtip-deepsight-001/archive/IP_Attack-2016-05-05-01-30-01-Raw.csvh` where reputation_rating > 5 order by reputation_rating  limit 1000;
```

`limit` とか `group by` とか `order by` とか `desc` とか普通に動きます。

```sql

select columns[6], count(*) from dfs.`/data/iprdb/gtip-microsoft-001/archive/MicroSoft-Csv-Feed-2016-05-04*-Raw.csv` where columns[2] = 'Conficker' group by columns[6] order by EXPR$1 desc limit 10;
+-----------------+---------+
|     EXPR$0      | EXPR$1  |
+-----------------+---------+
| 38.102.150.28   | 9427    |
| 104.244.14.252  | 7092    |
| 38.102.150.27   | 6997    |
| 104.244.14.253  | 5897    |
| 149.93.118.66   | 2       |
| 149.93.84.35    | 2       |
| 38.229.134.119  | 2       |
| 149.93.29.106   | 2       |
| 38.229.134.193  | 2       |
| 38.229.164.188  | 2       |
+-----------------+---------+
```

```sql

0: jdbc:drill:zk=local> select columns[2], count(*) from dfs.`/data/iprdb/gtip-microsoft-001/archive/MicroSoft-Csv-Feed-2016-05-04*-Raw.csv` group by columns[2] order by EXPR$1 desc limit 10;
+---------------+---------+
|    EXPR$0     | EXPR$1  |
+---------------+---------+
| B68-2-64      | 49184   |
| B68-2-32      | 39066   |
| B68-1-32      | 37842   |
| B68-1-64      | 35390   |
| Conficker     | 29501   |
| B85-R2V       | 16209   |
| B54-CONFIG    | 15170   |
| B106-MULTI    | 14301   |
| B157-R1       | 7561    |
| B106-Jenxcus  | 5474    |
+---------------+---------+
```

CSVファイルが複数に別れているときは、ファイル名に `*` を使うとまとめて一つのファイル（テーブル）として扱えます。なんか `UNIX` な感じでいいっすね。

```sql

select count(*) from dfs.`/root/csv/2016-04-10-*-Raw.csvh`;
```

```sql

select address, count(*) from dfs.`/data/iprdb/gtip-deepsight-001/archive/IP_Phishing-2016-05-05-01-30-01-Raw.csvh` where reputation_rating = 10 group by address order by EXPR$1 desc limit 100;
```

シェルでパラメターをいろいろ設定する

```shell

0: jdbc:drill:zk=local> !set verbose false
0: jdbc:drill:zk=local> !verbose
verbose: on

```

出力にフレーム（テーブル）がいらない場合

```
0: jdbc:drill:zk=local> !set outputFormat csv
```

## `JSON` や `S3` 扱えたりする

別途、ちゃんと書きたい。

```sql

SELECT * FROM dfs.root.`/web/logs`;

SELECT country, count(*)
  FROM mongodb.web.users
  GROUP BY country;

SELECT timestamp
  FROM s3.root.`clicks.json`
  WHERE user_id = 'jdoe';
```

## スケーラビリティ

ラップトップから1000+サーバまでスケール。全ノードが対等でマスタのないアーキテクチャ。別途ちゃんと書きたい

## ちなみに

ここでサンプルで扱っている `CSV` はセキュリティ界隈の人がみると、ニヤっとする系のデータです。
javascriptでurlに改行やスペースを入れて何かを叩く

### はまったこと
```javascript
var profile='[なまえ] hoge\n[あぴーるぽいんと] 文字列連結がとくい。("a"+"b")';
var url="https://hogehoge.com/user&profile="+profile;
```
このままだと叩けないけど、こんな感じの文字列をurlに乗せて叩きたい

### かいけつ
`encodeURIComponent`使う

```javascript
var url="https://hogehoge.com/user&profile="+encodeURIComponent(profile);
```

[ここ](https://meyerweb.com/eric/tools/dencoder/)とか使っても良さそう
Google Cloud RunのQuickstart: Build and Deployをとにかくやってみる

#Google Cloud Runの[Quickstart: Build and Deploy](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)
　Quickstartでつまづくと、やる気がしなくなる。
　こちらのQuickstartはどうでしょうか？

#Before you begin
##1.GCP プロジェクトを選択または作成します。
　ここは、既に作成済みなので飛ばした。
##2.Google Cloud Platform プロジェクトに対して課金が有効になっていることを確認します。 詳しくは、課金を有効にする方法をご覧ください。
手順は以下の通り
1.APIとサービスのページで、「APIとサービスを有効化」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530784/341a7721-9a5c-791c-d608-8c6647bd7ac1.png)

2.検索ボックスにcloud run と入力して、表示されたCloud Run APIをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530784/e47d1703-5ac2-458a-eb6d-6e20e0f6568a.png)

3.有効にするボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530784/31b4b91a-cf33-13eb-ae8f-b6bd2c03db19.png)

##3.Cloud Build and Cloud Run API を有効にします。
記載通りに
##4.Cloud SDK をインストールして初期化します。
記載通りに
##5.Update components
記載通りに

#アプリ(PYTHON)のコードはapp.pyへ、コンテナ用DockerfileはDockerfileへ、.dockerignoreは、.dockerignoreへ貼り付ける。　

　ディレクトリを作成して、以下のようにファイルをUTF-8で作成して、それぞれのファイルにコードを貼り付けていくだけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530784/36637302-c40a-e5c1-ed9b-050c0f9e1a31.png)

#上記ファイルを作成したディレクトリで、コマンドラインで２行実行します。
　PROJECT-IDは、自分のIDにする。

　gcloud builds submit --tag gcr.io/PROJECT-ID/helloworld
　gcloud run deploy --image gcr.io/PROJECT-ID/helloworld --platform managed

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530784/ea89ca32-4a84-241b-9643-487a5c4edc8f.png)

最後のhttps://以降のurlでブラウザでアクセスすると、Hello World!が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530784/d12bccd9-d461-813b-66b5-e279c5563a47.png)


(編集日時　2019/11/24　16:30　-　17:00　2まで)
(編集日時　2019/11/24　17:15　-　17:59　)
ページ番号のロジックと参考コード（java）

■目次
1、初めに
2、ページ番号ロジック
3、コード例


■初めに
検索サイトを作った時にページ番号の表示ロジックに手間取ったので載せておこうと
思いました。参考にしていただけたら幸いです。
（一例なので改善点・よりよいコードがあれば教えてください）

■べーじ番号のロジック

ページが1の時は5までの数字を出し、間に「・・・」を表示させ最後の番号を表示させる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521889/8f469861-4dbf-67ff-2cfa-0f4e25e63cd1.png)

ページ番号が5以上の時に始めのページ・前2つのページ番号・後ろ2つ・最後の番号を表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521889/08bb1c01-4a1d-6504-fcc0-7a3d0f5eed46.png)

ページが（最後のページ ー 3）の場合は初めのページ・最後までのページと前のページを表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521889/8f783e5e-d1a8-a0a7-5973-22d60a7461c5.png)

■コード例（jsp）
aタグのhrefにはリンク抜き状態のコードです。
変数名や定数名などの命名はセンスがないので良い名前があれば教えてください。

```
<%
//ページ数・現在ページの変数宣言
int currentPage;
int lastPageNum;
//変数代入
currentPage = 5;
lastPageNum = 9;
//定数宣言
final int FIRST_PAGE = 1;
final int FIRST_HALF_CHECK = 5;
final int LAST_HALF_CHECK = 4;
final int BEFORE_AND_AFTER = 2;
%>

<section>
<div class="pageLeft">
<%if(currentPage != FIRST_PAGE){ %>
<a href="">前のページへ</a>
<%} %>
</div>
<div class="pageCenter">
<%if(currentPage >= FIRST_HALF_CHECK){ %>
<a href="">1</a>
…
<%} %>
<%if(currentPage < FIRST_HALF_CHECK){ %>
	<%for(int i = 1; i <= FIRST_HALF_CHECK; i++){ %>
		<%if(i <= lastPageNum){ %>
		//aタグを入れるか入れないかの分岐（現在ページにaタグは入れない）
			<%if(i == currentPage){ %>
				<span><%=i %></span>
			<%}else{ %>
				<a href=""><%=i %></a>
			<%} %>
		<%} %>
	<%} %>
<%}else if(lastPageNum - currentPage < LAST_HALF_CHECK){ %>
	<%for(int i = lastPageNum - LAST_HALF_CHECK; i <= lastPageNum; i++){ %>
		<%if(i > 0){ %>
		//aタグを入れるか入れないかの分岐（現在ページにaタグは入れない）
			<%if(i == currentPage){ %>
				<span><%=i %></span>
			<%}else{ %>
				<a href=""><%=i %></a>
			<%} %>
		<%} %>
	<%} %>
<%}else{ %>
	<%for(int i = currentPage - BEFORE_AND_AFTER; i <= currentPage + BEFORE_AND_AFTER; i++){ %>
		//aタグを入れるか入れないかの分岐（現在ページにaタグは入れない）
		<%if(i == currentPage){ %>
			<span><%=i %></span>
		<%}else{ %>
			<a href=""><%=i %></a>
		<%} %>
	<%} %>
<%} %>
<%if(lastPageNum - currentPage >= LAST_HALF_CHECK){ %>
	…<a href=""><%=lastPageNum %></a>
<%} %>
</div>
<div class="pageRight">
<%if(currentPage != lastPageNum){ %>
	<a href="">次のページへ</a>
<%} %>
</div>
</section>
```

■まとめ
検索サイトでページナンバーロジックに1回詰まったので書いてみました。
もっといい方法や改善点等あると思いますので、その際は教えていただけると幸いです。
Railsのconfig.eager_loadの影響によるエラーについて

自身への注意喚起と同じところで躓いてしまった人がいたらすぐ解決できるように、メモします。
# 起こった問題
以下のようなcontrollerとviewがあります。（管理者一覧画面）

```ruby:sysadmin_users_controller.rb
class SysadminUsersController < ApplicationController
 def index
  @sysadmin_users = SysadminUser.order(updated_at: :desc)
 end
end
```
```ruby:index.html.slim
= "#{@sysadmin_users.count}件"
table
 thead
  tr
   th | 氏名
   th | メールアドレス
   th | 最終更新日
 tbody
   - @sysadmin_users.each do |sysadmin_user|
    td = sysadmin_user.name
    td = sysadmin_user.email
    td = l(sysadmin_user.updated_at, format: :short)
```

上記該当するURL（/sysadmin_users）にアクセスするとdevelopment環境では問題なかったのですが、staging環境では、index.html.slimの`count`がno metthod errorになりました:fearful:
# エラーの発生原因と解決方法
development環境とstaging環境によってエラーが発生するか違うため、環境によって異なる点を元にエラー原因を確かめようとしました。

## 1. データベースの違い
development環境とstaging環境で読み込んでいるデータベースが異なっているため、staging環境のデータベースをdevelopment環境にインポートし、同じテーブル状態にしました。
### 結果
エラー原因分からず、development環境はエラーが発生しませんでした。
## 2. configファイルの違い
環境ごとに異なるのが、app>config>environments配下にあるファイルです。
development.rbとstaging.rbで異なる箇所を探っていくと、怪しい箇所が・・・。

```ruby:development.rb
 config.eager_load = false
```

```ruby:staging.rb
 config.eager_load = true
```
development.rbを`config.eager_load = true`に書き換えると・・・
staging環境と同じエラーが発生しました！
### config.eager_loadって何？
@shakemurasanさんの記事が分かりやすいと思いますので、こちらを参照してみてください。
https://qiita.com/shakemurasan/items/305bd3d78d67b646bc06

config.eager_loadをtrueにすると、controllerやmodelなどのclass名がすべて事前に読み込まれます。（事前というのはおそらくrails serverが起動するタイミングです）
そのため、ページを読み込むたびにclassを読み込む必要はないので、ページ読み込みスピードは速くなります。
一方、config.eager_loadをfalseにすると、ページ読み込みスピードは遅くなりますが、rails serverの起動スピードは速くなります。

ちなみに、development環境においてconfig.eager_loadをfalseにしている理由としては、stagingとは異なり頻繁にソースコードが変更され、その度にrails serverを再起動しdevelopment環境でブラウザテストしているという背景があるためです。
### なぜconfig.eager_loadの設定でエラーが発生したのか？
事前にnamespace（class名）をすべて読み込まれるとエラーが起こって、ページにアクセスしたタイミングで特定のclassを読み込むとエラーが発生しない・・・。
ん？もしや同じnamespace（class名）が存在しているのでは？
SysadminUsersControllerで全文検索すると、ありました！同じnamespace（class名）が！

```ruby:users_controller.rb
class SysadminUsersController < ApplicationController
 def index
 end
end
```
衝撃的ことが2点。
1. users_contorllerなのに、class名がSysadminUsersController
2. このファイルは全く使用されていない・・・

ファイルを消したら、無事解決しました:ok_woman_tone1:
# 今後の対策
config.eager_loadについて理解するきっかけになったものの・・・。以下新たに肝に銘じておきます。
1. 環境ごとにエラーの有無が異なったら、app>config>environments配下にあるファイルを確認する。（まあこれはいいとして）
2. controller名とclass名を統一する
2. 使っていないファイル（controllerに限らず）は削除する（おそらくあとで使うかもしれないと残していたかもしれないが、エラーが発生する原因になり得る）
# 最後に
今回のエラーの原因は開発経験半年越えている人にとってはとても当たり前のことかもしれませんが、初めたてのメンバーからすると当たり前ではありません。チームで開発していると今初めたてのメンバーがいなくても今後現れるはずなので、しっかりドキュメントに記載し、ルール化、注意喚起したいと思います:raised_hand_tone2:
Laravelで日付をYYYY年MM月DD日 (曜日) hh: mmと表示させる

日付と時間だけだと簡単ですが、間に曜日を挟んだ場合の情報が少なくて面倒だったので、メモ
LaravelにCarbonのv2以降をインストールすれば以下のように１行でかけます。
今回は参考にdirectiveを使ってますが、viewHelperとかの方がいいかも。

```php:AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        \Blade::directive('datetime_and_week', function ($expression) {
            return "<?php echo Carbon\Carbon::parse($expression)->isoFormat('YYYY年MM月DD日 (ddd) LT '); ?>";
        });
    }
}
```

directiveなのでView clearコマンドを実行後に
viewなどで下記のように呼び出せばOK

```php:Sample.blade.php
<?php

@datetime_and_week('2019-11-24 00:00:00')
```

下記のように表示されます！
2019年11月24日 (日) 00:00

他に良い方法あれば教えてください。
jsで作ったblobをphpに送信

```javascript
blob => {
   const xhr = new XMLHttpRequest();
   const formData = new FormData();
   formData.append('audio', blob, 'input.wav');

   xhr.open('POST', '/upload.php', true);
   xhr.send(formData);
}
```

これだけ

```javascript
xhr.setRequestHeader('Content-Type', 'multipart/form-data; charset=utf-8; boundary=' + Math.random().toString().substr(2));
```

これをつけるとbinaryにならず送信できない
Rails 5 アプリのherokuへのデプロイ手順

#環境
Rails 5.0.7.2
Ruby 2.6.3

#herokuへのデプロイ手順
1. heroku にアプリを作成（すでにherokuにログインしていると仮定）
    - ```$ heroku create herokuアプリ名```
3. 本番環境用にGemfile, database.ymlを変更
    - Gemfilm: Postgre SQLとRailsを連携させる
    - database.yml: DBをPostgreSQLに設定
4. 下記を追加，実行し，本番環境へ反映
    - 本番環境上でアセットパイプラインを通るようにプリコンパイル処理を実行する
        - ```config/environments/production.rb config.assets.compile = false```
    - 本番環境上でアセットパイプラインを自動で通るように設定を変更する
        - ```$ rake assets:precompile RAILS_ENV=production```
        - 試したい場合は，以下コマンドを打ってエラーが出ないかを見てみる
            - ```$ RAILS_ENV=production bundle exec rake assets:precompile```
8. heroku にデプロイ
    - ```$ git push heroku master```
5. マイグレーション
    - ```$ heroku run rails db:migrate```

詳細：本番環境用にGemfile, database.ymlを変更

```Gemfile
group :production do
  gem 'pg', '0.21.0'
end
```

```database.yml
略
production:
  adapter: postgresql
  encoding: unicode
  pool: 5
  database: message-board_production
  username: message-board
  password: <%= ENV['MESSAGE-BOARD_DATABASE_PASSWORD'] %>
```



#まとめ
一番最初に(herokuへデプロイする前に)アセットパイプラインのための設定をしておきましょう．
私はこの順番をミスりました．