OmniAICreator/Qiita-1.07M huggingface dataset:
Python MySQLdb で Prepared Statement がうまくいかない場合

## こんなエラーが出てうまくいかない場合
```
  File "/root/.local/lib/python3.5/site-packages/MySQLdb/cursors.py", line 184, in execute
    self.errorhandler(self, exc, value)
  File "/root/.local/lib/python3.5/site-packages/MySQLdb/connections.py", line 37, in defaulterrorhandler
    raise errorvalue
  File "/root/.local/lib/python3.5/site-packages/MySQLdb/cursors.py", line 171, in execute
    r = self._query(query)
  File "/root/.local/lib/python3.5/site-packages/MySQLdb/cursors.py", line 330, in _query
    rowcount = self._do_query(q)
  File "/root/.local/lib/python3.5/site-packages/MySQLdb/cursors.py", line 294, in _do_query
    db.query(q)
_mysql_exceptions.ProgrammingError: (1064, 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server  version for the right syntax to use near \'%s, "%s")\' at line 1')
```
Qiitaの記事とか参考にしてもなぜかうまくいかない。多分こちらの環境設定とかが問題。
実行環境は Cent OS 6.9  Python 3.5.2  MySQL 5.6.42
似たような現象の人もいるようで、、、別のやり方の個人メモです。
https://stackoverflow.com/questions/32116909/python-mysqldb-typeerror-with-formatting-problems
https://www.pythonanywhere.com/forums/topic/2857/
https://www.pythonanywhere.com/forums/topic/1825/
https://github.com/kennethreitz/records/issues/166

## mysql-connector-python を代わりに使う

```
# pip install mysql-connector-python
```

## mysql-connector-python で 同様にPrepared Statement を利用する

```python
import mysql.connector

connection = mysql.connector.MySQLConnection(host='localhost',
                             database=DB_NAME,
                             user=DB_USER,
                             password=DB_USER_PASSWORD)
cursor = connection.cursor(prepared=True)

sql = 'INSERT INTO test_table (id, content) VALUES (%s, %s)'
data = (1,"A")
cursor.execute(statement, data)
connection.commit()

dataset = [
  (2, "B"),
  (3, "C"),
  (4, "D"),
]
cursor.executemany("INSERT INTO test_table (id, content) VALUES (%s, %s)",dataset)
connection.commit()
```

カーソルを作る時に「prepared=True」を忘れないようにすればMySQLdbと同じようにできます。
2019年を高密度なものにするための自身の分析と今年のアクション(個人メモ)

# 概要
* 2018年は悪くはなかったけど、もっと良くできた
* 具体的には、無駄にした時間が多かった
* 自身の行動パターンを分析、対応策を考えたよ

# 2018年の振り返り、反省点
* 言い訳をして怠ける時間が長い
    * 食事をしながら、食べ終えても無駄にグダグダ　→　「食事の時間だから...」
    * 土日にグダグダ　→　「今日時間あるし、やろうと思えばまだいくらでもできるし...」
    * 仕事の切れ目でグダグダ　→　「ひと段落したから、あとは休憩がてら帰宅時間を挟んで帰ってからやろう...」(やらない)

* もっと効率よく時間使えたはず。

# 振り返りを分析
* 色々考えた結果結局、自身の怠惰な精神が悪い
* クソゴミ人間俺
* 怠けた時の精神パターン、大きく二つ
    * やる気スイッチ、そもそも0
        * 土日などそもそもやるべきことがない日
        * 「今日どうしようかな...」と考えてるふりしながら何もせずに1日終了
        * クソゴミ人間俺
        
    * やる気スイッチ、0 → 1 → 0から1にできない
        * やることひと段落したあと、次のやることに着手できない、する気がない
        * 「ちょっと休憩しよう。。。」から1日終了
        * クソゴミ人間俺

# 対策(精神面)
* そもそも0
    * まず、その瞬間の自身がゴミだと自覚する、自覚する癖をつける
    * より充実した高密度の人生を目指す、それをやってる自身をイメージするよう心がける
    
* 0 → 1 → 0から1にできない
    * ひと段落した時点の自身を、「ひと仕事した俺」と思ってしまってる
    * 「次にとりかかれる俺」にしないといけない
    * 具体的な「次」が常に用意されている環境にすればいいんじゃないかな

# 対策(具体的なアクション)
* そもそも0
    * レコメンド環境を構築
        * [過去の自分からのアドバイスを伝えてくれる自分専用リマインダーが欲しくなったのでやってみた](https://qiita.com/Somelu01/items/ce7bc7e27534cff0e318)を参考
        * 振り返りを行った今の気持ちを定期的に通知、やる気を奮い立たせる
        * 脱、ゴミクズ人間俺
    * 自身の時間の使い方を振り返る環境を用意
        * [taskchute cloud](https://taskchute.cloud/users/top)を活用
        * 以前から使っていたけど、ちゃんと振り返る時間を設ける
        * 振り返る時間を今後はきちんと設けるっている気持ちも、レコメンドする
        * 脱、ゴミクズ人間俺

* 0 → 1 → 0から1にできない
    * 「次のアクション」が常に用意されている環境を構築
        * [trello](https://trello.com/)でタスクを管理
        * trello自体はこれまでも活用していたが、次に取りかかれるアクションが用意できているかという観点でタスクを分解するよう心がける
        * 次のアクションを常に用意するっていう気持ちも、レコメンドする
        * 脱、ゴミクズ人間俺

# 今年のアクションまとめ
* trelloにより、「次のアクション」を常に用意するようにタスクを管理
* taskchute cloudにより、高密度に時間が使えているかを意識、振り返り
* twitter bot + slackのIFTTT連携により、各種アクションのレコメンド、精神面のサポートを行う
【Unity】キャラクターにカメラの追従をする方法（Mac Bookのキーボードを使う）

<font color="Magenta">キャラクターにカメラの追従をする方法（Mac Bookのキーボードを使う）
</font>
環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1081752576297644032

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">キャラクターに✨カメラの追従✨をする。を勉強したよぉ。<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#unity3d</a> <a href="https://t.co/Oq7DKuvmFX">pic.twitter.com/Oq7DKuvmFX</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1081752576297644032?ref_src=twsrc%5Etfw">2019年1月6日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



1.Mac Bookのキーボードで操作するのは、下記のページを参照して実装。
【Unity】なめらかにCharacter Controller移動（Mac Bookのキーボードを使う）
https://qiita.com/nonkapibara/items/e20a492d2beb2d8dacac


2.Main Cameraに、カメラの追従スクリプトをセットする
<img width="1286" alt="スクリーンショット 2019-01-06 11.26.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/18630bd2-a6ba-dd83-54e5-ecd4d7d5dd8d.png">


```c#:followingCharacterScript
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class followingCharacterScript : MonoBehaviour {
    // 追従距離の差分
    Vector3 offset;
    // カメラを追従するターゲット
    public GameObject playerTarget;
    // カメラ追従スピード
    public float followSpeed;

    void Start()
    {
        // 追従距離の計算
        offset = playerTarget.transform.position - transform.position;
    }

    private void LateUpdate()
    {
        // スムージング
        transform.position = Vector3.Lerp(
            transform.position,
            playerTarget.transform.position - offset,
            Time.deltaTime * followSpeed
        );
    }
}
```
Pimoroni Inky wHAT / Inky pHAT 関係いろいろ

# 概要
以前、[RasPi Zero/ZeroW対応3色電子ペーパーモジュールinky pHATが販売再開](https://qiita.com/nakatafu/items/b5a9c672115d9bf56456)で英国Pimoroni社のe-Paperユニット inky pHAT / wHATについて書いたが、その後約１年が経過し製品が増えてきたので覚書を兼ねて記録しておく。

* 製品リンク
* 日本からの入手方法
* インストール時の注意点
* 搭載パネル、データシート
* 他のRaspi用e-paperユニット

![IMG_20181231_164402.jpg](https://qiita-image-store.s3.amazonaws.com/0/112961/c270ed32-3d42-23fa-4a2b-c89e58e2b57c.jpeg)

# 製品リンク
この１年間の間に以下の展開があった。

* inky pHATシリーズ(212x104 pixels 2.13型)の配色バリエーションが３種に増加(従来の白黒赤の３色に加え、２色：白黒、３色：白黒黄)
* inky wHATシリーズ(400x300 pixels 4.2型)追加。色のバリエーションは２種（３色：白黒赤、２色：白黒）

Pimoroni社の製品リンクは以下。

* inky pHAT (https://shop.pimoroni.com/products/inky-what)
* inky wHAT (https://shop.pimoroni.com/products/inky-phat)
 
# 日本からの入手方法
* 私は[Pimoron社の通販サイト](https://shop.pimoroni.com/)から直接購入しています。送料をケチると時間がかかってしまう。
* pHATは国内でも通販しているところがる。(価格は全て税込）
* Amazonは5800円とか高いところが多いので避けた方が良いと思われる。
* [せんごくネット通販](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-5AWU) 3500円 : 白黒、白黒黄の取り扱いもあり。
* [ロボショップ株式会社](https://www.robotshop.com/jp/ja/inky-phat-raspberry-pi.html) 3708円
* [マルツオンライン](https://www.marutsu.co.jp/pc/i/26919200/) 3416円

# ドライバインストール
* バリエーションの増加と共に、ドライバが大幅に書き直された。また、pHATの初期型のサポートが打ち切られた。(旧版のライブラリは現在も使用可能) ((https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-inky-phat) 参照)
* Raspbian Stretchにインストールしましたが、以下を実施しないとうまくインストールできまない。

　- 一部のパッケージを事前に手動でインストール

```
sudo apt-get install libxml2-dev libxslt1-dev python-dev
```

　- wikiquotesのインストール時にcc1が動き続けて終了しない → スワップを増加して対応 (wikiquotes側で対応されて不要になっている様な気もする)
　- 幾つかのフォントのインストールに失敗するが、

各チュートリアルは
inky pHAT (https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-inky-phat)
inky wHAT (https://learn.pimoroni.com/tutorial/sandyj/getting-started-with-inky-what)

特にinky wHATは簡単に画像ファイルを２色ディザ変換後表示できる[dither-image-what.py](https://github.com/pimoroni/inky/blob/master/examples/what/dither-image-what.py)がとても簡単で使いやすい。（トップに貼った写真もこれを使ったサクッと出したもの。）

# 搭載パネル、データシート
現物のFFCへの印字やドライバ、写真などから各e-Paperモジュールのものと思われるデータシートが特定できた(Red/Black/Whiteのみ)ので以下に各リンクを示す。
なお、[旧版ライブラリ](https://github.com/pimoroni/inky-phat/blob/master/library/inkyphat/inky212x104.py)の_v2_initには”Sent by dev board but undocumented in datasheet”等というコメントが入っていて、興味深い。

* inky pHAT V1 (R/B/W) WAVESHARE社 (https://www.waveshare.com/w/upload/5/5b/2.13inch_e-Paper_(D)_Datasheet.pdf) 
* inky pHAT V2 (R/B/W) MIDAS DISPLAY (http://www.farnell.com/datasheets/2693679.pdf)
* inky wHAT (R/B/W) MIDAS DISPLAY (http://www.farnell.com/datasheets/2693681.pdf)

# 他のRasPi用e-Paperユニット
* 212x104 ピクセル 2.13型のRaspi用のe-paperモジュールはWAVESHARE社のものも出回っている。サイズのバリエーションもある。
* 使っているモジュールはinky pHATのV1と同じだが、Raspiとのインタフェースのピンの割り当てが異なる。そのため、ドライバは少し書き換えれば相互に流用可能になると思われる。（未確認）
Unityのプロジェクトを多重起動する方法

<font color="Magenta">
Unityのプロジェクトを多重起動する方法
</font>

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1

ターミナルでコマンド起動する
```open -n /Applications/Unity/Unity.app --args -projectPath /Users/non/nonVRSample
```

<img width="916" alt="スクリーンショット 2019-01-06 12.10.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/0888b748-fc29-c5e4-6b57-aa07ff5cd21d.png">



#
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【Unity】やっとVR用のゲームができました！！<br>シーンの遷移も、スマホにVR用の出力もできました！！<br>やった！！<br>v(≧∇≦)v イェェ～イ♪<a href="https://twitter.com/hashtag/unity?src=hash&amp;ref_src=twsrc%5Etfw">#unity</a> <a href="https://twitter.com/hashtag/unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#unity3d</a> <a href="https://twitter.com/hashtag/VR?src=hash&amp;ref_src=twsrc%5Etfw">#VR</a> <a href="https://t.co/AEsbXdrnhX">pic.twitter.com/AEsbXdrnhX</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1076511052043448320?ref_src=twsrc%5Etfw">2018年12月22日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Google BigQueryでLEFTJOINしたい

# Google Big QueryでLEFTJOINしたい
備忘録として書きます．

欲しい形
<img width="227" alt="スクリーンショット 2019-01-06 11.36.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/206657/bb8246a9-220f-0541-c673-959fb732a76d.png">
setaiNoは世帯番号，SNS_cntはSNSにアクセスした回数，HP_cntはHPにアクセスした回数を表す．

まず，手元にあるデータの形を見る．
<img width="168" alt="スクリーンショット 2019-01-06 11.43.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/206657/d199988f-fa36-a028-15f7-11f686ad4359.png">
<img width="159" alt="スクリーンショット 2019-01-06 11.45.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/206657/0ce75e59-7554-a2b5-258a-6cddbbee0122.png">

この二つのデータをleftjoinして「欲しい形」にしたい．
世帯番号18だけがSNSもHPも見ている．
以下で実行できる．
```
SELECT
  A.setaiNo AS setaiNo,
  A.SNS_cnt AS SNS_cnt,
  A.HP_cnt AS HP_cnt
FROM
  [JR2.SNS_cnt] AS A
LEFT OUTER JOIN
  [JR2.HP_cnt] AS B
ON
  A.setaiNo = B.setaiNo
```
データをASで定義しないとうまく結合できないです．
最後にデータの列名を綺麗にするためにデータを定義しています．
Ubuntu1804デスクトップにsteamをインストールする。

暇つぶしになるかと思い、Steamをubuntuにインストールしようと思いました。

参考にしたサイト
[Install Steam on Ubuntu 16.04 / 17.10 / 18.04 Desktop](https://websiteforstudents.com/install-steam-on-ubuntu-16-04-17-10-18-04-desktop/)


## 実行したコマンド
リポジトリ追加
`sudo add-apt-repository multiverse`
リポジトリ情報の更新
`sudo apt update`
steamのインストール
`sudo apt install steam`

アプリケーション一覧に表示されます。

![Screenshot from 2019-01-06 11-25-59.png](https://qiita-image-store.s3.amazonaws.com/0/213689/e6c0a40d-7fef-1f07-b934-b4d10300ad72.png)

アカウントがすでにある人はログインするときに
メールでコード認証が発生する様子。
Linux対応ソフトならインストールもできるみたいです。

![Screenshot from 2019-01-06 11-54-55.png](https://qiita-image-store.s3.amazonaws.com/0/213689/580aabdc-a31a-6a84-8405-09f5d6e6cdbf.png)

VirtualBOXでHDDだからかめっちゃ遅いですが、
とりあえず遊べました。
Macへの PostgreSQL, PostGISインストール


macOS High SierraにPostgreSQLとPostGISをHomebrewでインストールした際のメモ。
昔とは色々変わっているところも多いようなので手探りで。

# 環境
- macOS High Sierra 10.13.6
- Homebrew 1.8.6


# インストール

PostgreSQLのインストール

```
> brew install postgres
```

PostGISのインストール

```
> brew install postgis
```

PostGISインストール時に以下のようなエラーが発生。

```
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Permission denied @ dir_s_mkdir - /usr/local/Frameworks
Error: Permission denied @ dir_s_mkdir - /usr/local/Frameworks
```

以下のように対応したのち、postgisを再インストール。<br>
参考：[Homebrewで入れたPythonでのlinkエラー問題](https://qiita.com/Jung0/items/d4012814e6fb1b694208)

```
> sudo mkdir /usr/local/Frameworks
> sudo chown [username]:admin /usr/local/Frameworks
```

インストールされたバージョンは以下

- PostgreSQL 11.1
- PostGIS 2.5.1

# DBの作成と起動

おそらくPostgreSQLインストールの時点で /usr/local/var/postgresql/ 以下にDBが存在している？様子だが、これを削除してから以下のように作り直した。

```
> initdb /usr/local/var/postgres -E utf8
```

サービスの起動はbrew servicesを使用（postgresqlインストール時のメッセージを参考に）。

```
> brew services start postgresql
```

一応、postgresユーザをスーパーユーザとして作成しておく。

```
> createuser -s postgres
```

PostGISのDB作成。

```
> createdb -U postgres geomdb
> psql -U postgres geomdb

psql (11.1)
Type "help" for help.

geomdb=# CREATE EXTENSION postgis;
CREATE EXTENSION
geomdb=# SELECT PostGIS_Version();
            postgis_version
---------------------------------------
 2.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)

geomdb=#
```


# 参照

- [PostgreSQL and PostGIS installation in Mac OS.](https://medium.com/@Umesh_Kafle/postgresql-and-postgis-installation-in-mac-os-87fa98a6814d)
- [Installing and configuring PostgreSQL on macOS (OSX)](https://www.elliotblackburn.com/installing-postgresql-on-macos-osx/)

- [Homebrewで入れたPythonでのlinkエラー問題](https://qiita.com/Jung0/items/d4012814e6fb1b694208)
- [OS X に PostgreSQL を Homebrew でインストールして brew services で起動する](https://qiita.com/takuya0301/items/c0720753de98572703b8)
AWS Global Acceleratorを試してみた

AWS Global Acceleratorを試してみました。

# どんなもの？
リージョンにまたがって配置されたEIP, NLB, ALBに対して、Static IPに対し接続したトラフィックを分散するサービスです。

# 前準備

あらかじめ動作確認用に、us-east-1とus-west-1にALB+EC2(nginx)の環境を作成しておきます。

# 1. Acceleratorを作成する

<img width="611" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/63f34679-72da-4382-1685-ac3df611f852.png">

# 2. Listenerを追加する

<img width="1173" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/d467485f-6442-eff0-b07b-62ecb787cc5e.png">


# 3. Endpoint Groupを追加する

<img width="1175" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/c3de79d0-38b4-3a02-1daa-115540bf5a64.png">

# 4. Endpointを追加する

あらかじめ作成しておいたALBを指定します。

<img width="1174" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/00de3b9f-afee-2878-056e-716f2ba9f191.png">

作成されるとStatic IPが2個払い出されます。

<img width="1429" alt="4-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/4c94f366-0640-2f88-c058-bb1501bcb79b.png">


# 5. 接続してみる

東京に近いus-west-1の方に接続されます。
<img width="861" alt="5-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/d1f242ce-55d9-d362-cd8f-4bb0d716d5a6.png">

us-west-1の方のnginxを止めると、statusがunhealthyになり
<img width="1419" alt="5-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/e5974e75-5d5d-0819-e039-f7df5dd9e776.png">

502の後
<img width="310" alt="5-2-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/c255e9a5-3667-a02a-413b-717e33a92008.png">

しばらくすると今度はus-east-1の方に接続されます。
<img width="735" alt="5-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/3949772c-e0ae-ff28-e680-54de49ae946c.png">

us-west-1の方のnginxを起動してしばらくすると、また東京に近いus-west-1の方に接続されます。
その状態で、今度はus-west-1のTraffic dialを1%に変更します。
<img width="1417" alt="5-4.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/e5c0ddde-7100-59a8-9626-d26453332575.png">

するとus-east-1の方に接続されます。
<img width="736" alt="5-5.png" src="https://qiita-image-store.s3.amazonaws.com/0/192584/14d49ef7-adbc-e393-ff23-295fd6d231fc.png">

# 雑感
Route53でトラフィックを分散するのと違いDNSのキャッシュを考慮しなくて良いのでいいですね。
AWS EC2 のインスタンスのコピーを作成

AWS EC2 のインスタンスのコピーを作成してサーバーを動かす方法です。
OS を環境ごとまるごとコピーして、IP アドレスを変えて動作させることです。

1) 既存の OS から 自分の AMi を作成
2) 自分の AMI からインスタンスを作成
の２つのステップになります。

私は、Ubuntu 18.04　で次の手順で行いました。

1) 既存の OS から 自分の AMi を作成

>instance-id は変更して下さい。

```bash
ws ec2 create-image --instance-id i-0ebb41a6f489999b9 --name "Second server" --no-reboot
```

そうすると、次のように出力されます。

```json
{
    "ImageId": "ami-0045ec213e5999b99"
}
```

2) 自分の AMI からインスタンスを作成
この作業はコンソールで行いました。
![ami_jan0601.png](https://qiita-image-store.s3.amazonaws.com/0/179446/10bd7936-5a9d-59c0-65fa-2cc3871cbc27.png)
CentOS7にRabbitMQを入れる

# 環境

```
server
os:centos7
  |
client
os:centos7
```

# 手順

serverで実行する。

```bash
username='admin'
password='secret'

yum install -y epel-release
yum install -y rabbitmq-server
systemctl start rabbitmq-server.service
systemctl enable rabbitmq-server.service
rabbitmqctl add_user $username $password
rabbitmqctl set_user_tags $username administrator
rabbitmqctl set_permissions $username '.*' '.*' '.*'
rabbitmq-plugins enable rabbitmq_management
systemctl restart rabbitmq-server.service
firewall-cmd --permanent --new-service=rabbitmq
firewall-cmd --permanent --service=rabbitmq --add-port=5672/tcp
firewall-cmd --permanent --new-service=rabbitmq-management
firewall-cmd --permanent --service=rabbitmq-management --add-port=15672/tcp
firewall-cmd --permanent --add-service=rabbitmq
firewall-cmd --permanent --add-service=rabbitmq-management
firewall-cmd --reload
```

clientで実行する。

```console
username='admin'
password='secret'
queue='demo.queue'
server='server'

curl -o ./rabbitmqadmin http://$server:15672/cli/rabbitmqadmin
chmod -v +x ./rabbitmqadmin
cat <<__TEXT__ | tee ~/.rabbitmqadmin.conf >/dev/null
[default]
hostname = $server
username = $username
password = $password
__TEXT__

# キューを作る
./rabbitmqadmin declare queue name="$queue"

# キューにメッセージを加える
echo "msg" | ./rabbitmqadmin publish routing_key="$queue"

# メッセージ数を得る
./rabbitmqadmin list queues -f pretty_json \
| jq "
    map({\"name\":.name, \"messages\":.messages}) \
    | map(select(.name=\"demo.queue\"))
  "

# 消さずにメッセージを得る
./rabbitmqadmin get queue="$queue" -f pretty_json

# メッセージを消す
./rabbitmqadmin purge queue name="$queue"

# キューを消す
./rabbitmqadmin delete queue name="$queue"
```
Mojaveにしたらpeco-historyできなくなったときの対処法

コマンド履歴をpecoろうと思ったらエラーになってしまったので、対処法のメモ。

書いてる人は、こちらを参考に bash+peco-historyを使ってます。
https://qiita.com/yungsang/items/09890a06d204bf398eea

### 発生状況
Ctrl-R > pecoの一覧から選択したら

```bash
$ 47:65: execution error: System EventsにApple Eventsを送信する権限がありません。 (-1743)
```

### 対処法
- 権限がないのが原因なので
システム環境 > セキュリティとプライバシー > オートメーション の System Events.app にチェック
<img width="661" alt="スクリーンショット 2019-01-06 10.33.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/6568/d2c3c435-3ac1-2a5c-94de-128a748fab22.png">
- 再度、Ctrl-R > pecoの一覧から選択すると、確認アラートが開くので
<img width="467" alt="スクリーンショット 2019-01-06 10.35.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/6568/d79df776-c770-c562-de5d-6b89b9fa4836.png">
- システム環境画面を開き、ターミナルを許可すればOK

無事にpeco-historyできるようになりました！
bashで8 queensを並列処理

並列処理で8 queensを解きます。bashで竹内関数( https://qiita.com/nihongi/items/21a4a215920150ef7eb8 )では、サブシェルをdisった気がしますが、ここではサブシェルが活躍します。

## 並列化しない場合

```bash:8queens1.sh
#!/bin/sh

board="0000000000000000000000000000000000000000000000000000000000000000"

put() {
  # ${1}の${2}列目にクイーンを置く
  # 0列目は無条件に置ける
  if [ ${2} -eq 0 ]; then
    for i in {0..7}
    do
      tmp=${1:0:$(( ${2} + 8 * ${i} ))}"1"${1:$(( ${2} + 8 * ${i} + 1 ))}
      put ${tmp} 1
    done
  else
  # 1列目以降
    # もしi行目にクイーンを置いたら(${2}-1)列目までに衝突があるかを調べる
    # 衝突がなければクイーンを置いて次の列に行く
    for i in {0..7}
    do
      for j in `seq 0 $(( ${2} - 1 ))`  # j列目
      do
        # 横方向
        if [ "${1:$(( ${j} + 8 * ${i} )):1}" = "1" ]; then
          continue 2
        fi
        # 斜め上方向
        if [ $(( ${i} + ${j} - ${2} )) -ge 0 ]; then
          if [ "${1:$(( ${j} + 8 * ( ${i} + ${j} - ${2} ) )):1}" = "1" ]; then
            continue 2
          fi
        fi
        # 斜め下方向
        if [ $(( ${i} + ${2} - ${j} )) -le 7 ]; then
          if [ "${1:$(( ${j} + 8 * ( ${i} + ${2} - ${j} ) )):1}" = "1" ]; then
            continue 2
          fi
        fi
      done
      # 衝突なし
      tmp=${1:0:$(( ${2} + 8 * ${i} ))}"1"${1:$(( ${2} + 8 * ${i} + 1 ))}
      if [ ${2} = 7 ]; then
        echo ${tmp}
      else
        put ${tmp} $(( ${2} + 1 ))
      fi
    done
  fi
}

put ${board} 0
```
実行結果

```console
$ time sh 8queens1.sh
1000000000000010000010000000000101000000000100000000010000100000
1000000000000010000100000000010000000001010000000000100000100000
(途中省略)
0010000000001000010000000000000100000100000100000000001010000000
0010000000000100000100000100000000000001000010000000001010000000

real    0m19.155s
user    0m11.444s
sys     0m7.939s
```
長いので途中省略してますが、92個の解が表示されます。時間は19秒程度です。

## 並列処理化

putの再帰呼び出しの部分をサブシェルでバックグラウンドでの実行に変えます。差分だけ載せます。

```console:diff
$ diff 8queens1.sh 8queens2.sh
12c12
<       put ${tmp} 1
---
>       (put ${tmp} 1)&
44c44
<         put ${tmp} $(( ${2} + 1 ))
---
>         (put ${tmp} $(( ${2} + 1 )))&
```
実行結果

```console
$ time sh 8queens2.sh

real    0m0.003s
user    0m0.001s
sys     0m0.002s
$ 0001000001000000000000100010000000000100000000010000100010000000
0000100001000000000100000000001000100000000000010000010010000000
0010000000001000010000000000000100000100000100000000001010000000
0010000000000010010000000000000100000100000100001000000000001000
0000010000010000010000000000000100001000000000101000000000100000
0010000000000100000000010100000000010000100000000000001000001000
(以下省略)
```
timeコマンドが先に終わって、その後にわらわらと答えが返ってきます。実体がバックグラウンドで動いているのでこうなります。最後の答えが返るまで約5秒くらいです。CPUのコア数が4なので、時間が4分の1に減ったのだと思います。よくわかりませんが。

## 結論

並列処理にしたら本当に速くなりました。めでたしめでたし。
DonckeyCarのセットアップ(RaspberryPi)

基本的には、"http://docs.donkeycar.com/"に従って作業したが、
そのままでは上手くできなかった部分をメモ

ver2.5.8のインストールからver2.5.1のダウングレードと走行開始まで

1.pip install donkeycar[pi]

2.python -c "import donkeycar as dk; print(dk.__version__)"
 ->ver2.5.8であることが確認できる。
　 2.5.8だと学習などの処理が動作しない(？)ので2.5.1にダウングレードする。 
  (※2019年1月時点)

3.pip install donkeycar==2.5.1
 ->ver2.5.8でも学習できる環境ができたのでダウングレード不要(※2019年2月)

4.python -c "import donkeycar as dk; print(dk.__version__)"
 ->ver2.5.1であることを確認

5.donkey createcar mycar01

6.nano mycar01/manage.py

7.python mycar01/manage.py drive --js
  -> mycar01/tub の中に画像・走行データが保存されている。
     -> データ削除は、
　　　　 rm mycar01/tub/＊.jpg
　　　　 rm mycar01/tub/record_＊.json

8.python mycar01/manage.py drive
  -> mycar01/tub の中に画像・走行データが保存されている。
     -> データ削除は、
　　　　 rm mycar01/tub/＊.jpg
　　　　 rm mycar01/tub/record_＊.json
macOS Mojaveにpyenv-virtualenv環境構築

## 初めに
macOS Mojaveにpyenv-virtualenv (python 3.6.7)の構築で一手間あったためのメモ

## 関連packages

```
$ brew update
$ brew install zlib
```

## pyenv, pyenv-virtualenv

```
$ brew install pyenv
$ brew install pyenv-virtualenv
```

## pyenv用 Profile
```
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

## python

```
$ pyenv install 3.6.7
$ pyenv rehash

# 確認
$ pyenv versions
* system (set by /Users/xxxx/.pyenv/version)
  3.6.7
```

インストールに失敗する場合は下記を実施

```
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```
> MojaveにはmacOS SDK headerが入っていない事が原因

## pyenv-virtualenv環境構築
```
$ pyenv virtualenv 3.6.7 pvenv3.6.7

# 確認
$ pyenv versions
* system (set by /Users/xxxx/.pyenv/version)
  3.6.7
  3.6.7/envs/pvenv3.6.7
  pvenv3.6.7
```

## local設定(pvenv3.6.7 )
```
$ pyenv local pvenv3.6.7

# 確認
$ python -V
Python 3.6.7

$ cat .python-version	
pvenv3.6.7
```

## 参考

https://qiita.com/niwak2/items/5490607be32202ce1314
https://qiita.com/1000ch/items/93841f76ea52551b6a97
https://qiita.com/zreactor/items/c3fd04417e0d61af0afe
aws-cli の簡単な使い方

aws-cli の設定を変更した際にちゃんと動くかざっと確認する方法です。

aws-cli のインストール

>Arch Linux

```bash
sudo pacman -S aws-cli-v2
```

>Ubuntu 21.10

```bash
wget https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip
unzip awscli-exe-linux-x86_64.zip
sudo aws/install
```

設定は、次のファイルで変更します。
>.aws/config
>.aws/credentials

```text:.aws/config
[default]
output = json
region = ap-northeast-1
```

```text:.aws/credentials
[default]
aws_access_key_id = AKIAICUGUJTHE2AAAAAB
aws_secret_access_key = JdJTvIFukHeGO4kNWYez111111111111
```

バージョンの確認

```text
$ aws --version
aws-cli/2.7.35 Python/3.9.11 Linux/5.15.0-48-generic exe/x86_64.ubuntu.22 prompt/off
```

ログインユーザーの確認

```text
$ aws sts get-caller-identity
{
    "UserId": "AIDAIHEWDBIJGJOGUABCD",
    "Account": "153035299999",
    "Arn": "arn:aws:iam::153035299999:user/somebody"
}
```

>有効でないと次のようになります。

```text
$ aws sts get-caller-identity

An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid.
```

AWS のユーザーの確認

```bash
aws iam list-users
```

特定のユーザーの確認

```bash
aws iam get-user --user-name scott
```

AWS のグループの確認

```bash
aws iam list-groups
```

AWS のグループの確認 （コンパクト）

```bash
aws iam list-groups --query 'Groups[].GroupName'
```

EC2 のインスタンスの確認

```bash
aws ec2 describe-instances | jq '.Reservations[].Instances[].InstanceId'
```

EC2 のインスタンスの確認　(IP アドレス)

```bash
aws ec2 describe-instances | jq '.Reservations[].Instances[].PublicIpAddress'
```
爆速アウトプットのためにはテキストじゃなく超圧縮の写真やイラストを活用すべきかも、目は口ほどにものを言う‥いや‥なんだっけ

For High speed out putting Image described all things ! stronger than thousand text 
爆速アウトプットのためにはテキストじゃなく超圧縮の写真やイラストを活用すべきかも、目は口ほどにものを言う‥いや‥なんだっけ

# Our purpose is "telling" not "Describing" 

![image](https://user-images.githubusercontent.com/13635059/50730808-845f0900-1199-11e9-978a-0393efd0881d.png)



# Take good photo is better at Writing cost and Read cost

![image](https://user-images.githubusercontent.com/13635059/50730813-993b9c80-1199-11e9-9a37-03dc27b8d061.png)

# Image is better to understand Language border free

![image](https://user-images.githubusercontent.com/13635059/50730811-8de87100-1199-11e9-8304-1299277ec2c9.png)




---

https://twitter.com/yumainaura

https://github.com/YumaInaura/YumaInaura/issues

https://github.com/YumaInaura/YumaInaura/issues/259








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
書籍出版数からわかるAI関連キーワードのトレンド

# はじめに
　ハンス・ロスリングさんの著書「[FACTFULNESS(ファクトフルネス)　10の思い込みを乗り越え、データを基に世界を正しく見る習慣][1]」に触発されて、データ（書籍出版数）からAI関連キーワードのトレンドを見てみました。
[1]:https://www.amazon.co.jp/gp/product/4822289605

# トレンド1
　「人工知能」、「機械学習」、「IoT」といったビッグキーワードは2017年をピークに2018年は微減しています。それに対して「深層学習（ディープラーニング含む）」、「Python」といったもう少し技術よりのキーワードは2018年も継続して増加しています。

![AI_booktrend.png](https://qiita-image-store.s3.amazonaws.com/0/128327/5eac74d2-d2b3-17d6-aad4-923b2808eeb2.png)

　モバイルのトレンドでも、ビッグキーワードに少し遅れて、技術よりのキーワードのピークが来る傾向にありました。世の中で騒がれ始めたタイミングで開発が本格化するため、技術よりの書籍のピークが少しずれているように思います。

![mobile_booktrend.png](https://qiita-image-store.s3.amazonaws.com/0/128327/3fe66ac5-3074-a166-879b-6ae4113789c5.png)

# トレンド2
　深層学習のフレームワークを比較してみました。2017年には「Chainer」と「TensorFlow」が互角でしたが、2018年はくっきりと明暗が分かれてしまいました。Chainerは国産フレームワークで、ネットで十分情報があるため、書籍のニーズが少なかった可能性が考えられます。PyTorchが2018年に伸びているのが予想外でした。あまり使われている印象が無いので。

![DL_framework_booktrend.png](https://qiita-image-store.s3.amazonaws.com/0/128327/ea8e61d1-fd60-692b-a978-61e6ef9b55f8.png)

# 書籍情報の取得方法
　「[国会図書館サーチ ＡＰＩ で書籍情報をまとめて取得](http://ailaby.com/ndl_search/)」を参考にさせていただきました。
一点だけ、注意点としては、出版年月日の「from」パラメータは年だけを指定する必要があります。[国会図書館の外部提供インタフェース（API）](http://iss.ndl.go.jp/information/api/)からダウンロードできる仕様書にこんな記載があります。

> なお、 「年月(YYYY-MM)」「年月日(YYYY-MM-DD」の指定時は、指定の粒度未満の出版 年を持つ書誌はヒットしない。(例えば、1999-01~2000-12(YYYY-MM 形式)と指定 した場合、出版年に 1999-12(YYYY-MM 形式)や 2000-01-01(YYYY-MM-DD 形式) を持つ書誌はヒットするが、1999 や 2000(YYYY 形式)の書誌などはヒットしない。) 


#おわりに
　書籍出版数からトレンドを調べてみました。書籍以外にも、論文数や特許出願数などからもトレンドを把握できるかトライしてみたいと思います。
DonkeyCarのセットアップ(Ubuntu18.04)

基本的には、"http://docs.donkeycar.com/"に従って作業したが、
そのままでは上手くできなかった部分をメモ

1.インストール
sudo apt-get install virtualenv build-essential python3-dev gfortran libhdf5-dev

2.セットアップ
virtualenv env -p python3     ・・・起動毎に実行
source env/bin/activate　　　　・・・起動毎に実行
pip install tensorflow==1.8.0

mkdir Workspace_Donckey

git clone https://github.com/autorope/donkeycar
~~pip install -e ./donkeycar~~
pip install donkeycar==2.5.1

cd ~/Workspace_donkey
donkey createcar mycar

3.学習
rsync -r pi@IP_Address:~/mycar01/tub ~/Workspace_donkey/mycar
python mycar/manage.py train --tub mycar/tub --model mycar/models/mypilot

rsync -r mycar/models/mypilot pi@IP_Address:~/mycar01/models/
※raspberrypiから↓
python mycar01/manage.py drive --model=mycar01/models/mypilot


4.画像→動画
mkdir mycar01_bak_190105
rsync -r pi@IP_Address:~/mycar01 ~/Workspace_donkey/mycar01_bak_190105
donkey makemovie --tub mycar01_bak_190105/mycar01/tub --out ./movie.mp4 --config mycar/config.py
AWS IoT ボタンと IFTTT を繋いで活用してみる

# 概要
衝動買い的に、Wi-Fi でつながる「[AWS IoT エンタープライズボタン](https://www.amazon.co.jp/dp/B075FPHHGG)」と LTE でつながる「[SORACOM LTE-M Button powered by AWS](https://soracom.jp/products/gadgets/aws_button/)」を購入したので、とりあえず [IFTTT](https://ifttt.com/) と繋いでみました。

# コード
手順はソラコムの中の人が書かれている以下の記事が大変わかりやすいです。
[1-click/functions/ifttt at master · j3tm0t0/1-click - GitHub](https://github.com/j3tm0t0/1-click/tree/master/functions/ifttt)

AWS lambda でコードを動かす必要がありますが、一度作ってしまえばいじる必要なし。[AWS IoT 1-Click](https://aws.amazon.com/jp/iot-1-click/) の管理画面でボタン毎の設定をして、それに合わせて IFTTT で Applet を作ればいろんな使い方ができるようになっています。

ちなみに私は、上記記事で公開されている AWS lambda 用の node.js スクリプトの仕様を少し変更して、python で書き直して使ってます。コードは以下に置いておきます。
[Python script for AWS lambda to forward AWS IoT 1-Click event to IFTTT - GitHubGist](https://gist.github.com/nikotan/05634b1f6114f14c93e64e9f3238228a)

# 活用例
ボタンが IFTTT に繋がるようになったので、実際の使い方を2つほど組んでみました。

### 1. スマートコンセントの ON/OFF ボタン
家で使ってるスマートコンセント（[tp-link HS105](https://www.tp-link.com/jp/products/details/cat-5258_HS105.html)）を AWS IoT エンタープライズボタンでリモートコントロールします。

◆ AWS IoT 1-Click でのプレイスメント作成
![プレイスメント(aws1)](https://qiita-image-store.s3.amazonaws.com/0/336603/dd858025-5838-0dc7-b081-05e1b59408b0.png)

◆ IFTTT での Applet 作成
ボタンの押し方（LONG/SINGLE/DOUBLE）に応じて、スマートコンセントの ON/OFF を切り替え。
![IFTTT Applet(aws1)](https://qiita-image-store.s3.amazonaws.com/0/336603/4dd19211-3abf-6eae-1247-57a680f164db.png)
今までスマートコンセントはスマートスピーカー経由で使っていましたが、手元のボタン押すだけで済むのは意外と便利です。ボタンってすごい。

### 2. 子供に持たせる連絡ボタン
子供に持たせて、ボタンが押されたら LINE でメッセージを飛ばします。

◆ AWS IoT 1-Click でのプレイスメント作成
![プレイスメント(soracom1)](https://qiita-image-store.s3.amazonaws.com/0/336603/8d84cd66-95cd-980c-1984-2ec25ffe2da4.png)

◆ IFTTT での Applet 作成
プレイスメントで設定した属性値を使って LINE メッセージを作成・送信。
![IFTTT Applet(soracom1)](https://qiita-image-store.s3.amazonaws.com/0/336603/30704666-9aff-1fbb-ae67-66ef4adfd96c.png)
![IFTTT Applet(soracom1)](https://qiita-image-store.s3.amazonaws.com/0/336603/e3218ed5-a03f-5729-5ac5-d4d700abf466.png)

ボタンが押されると、以下のような LINE メッセージが飛んできます。
![LINE](https://qiita-image-store.s3.amazonaws.com/0/336603/e138c2ae-bab5-3be6-6b50-b5b864cd4b52.jpeg)
ちょっとした連絡手段として使えるシーンがある、かも。
OpenCV インストール手順

---

前提：LINUX環境

---
## 1. PIPのインストールを行う
~~~
curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python3
~~~

## 2. Python向けOpenCVのインストールを行う
~~~
pip3 install opencv-python
~~~

## 3. 動作確認

~~~
import numpy as np
import cv2
 
img = cv2.imread('filename', cv2.IMREAD_GRAYSCALE)

cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
~~~

画像が出てくればOK
Macにnodejsを入れたときにFailed to create the fileでインストールできない

macでnodejsを入れるときにエラー（Failed to create the file）になったさいの対処法です。

## 環境
maxos 10.14
Homebrew 1.8.6

## エラー内容

```
# brewでnodebrewをインストール
$ brew install nodebrew
# 最新版のnodejsをインストール
$ nodebrew install-binary latest

Fetching: https://nodejs.org/dist/v11.6.0/node-v11.6.0-darwin-x64.tar.gz
Warning: Failed to create the file 
Warning: /Users/kzfm/.nodebrew/src/v11.6.0/node-v11.6.0-darwin-x64.tar.gz: No 
Warning: such file or directory
                                                                           0.0%
curl: (23) Failed writing body (0 != 1058)
download failed: https://nodejs.org/dist/v11.6.0/node-v11.6.0-darwin-x64.tar.gz
 ```

https://nodejs.org/dist/v11.6.0/node-v11.6.0-darwin-x64.tar.gz
はアクセスできる。

## 原因と対処法

インストール先のディレクトリがないため

 `mkdir -p ~/.nodebrew/src`
でディレクトリを作っておく。

```
$ nodebrew install-binary latest
Fetching: https://nodejs.org/dist/v11.6.0/node-v11.6.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully
```

できた！

homebrew使っているとこの手のエラーは遭遇したことはないので忘備録としてとっておく。
.@googleime_jp Mac OS + Google IME 日本語入力で、日本語からの絵文字変換は本当に辛い。理由は複数あるがサジェストが理由なことがわかった。

.@googleime_jp Mac OS + Google IME 日本語入力で、日本語からの絵文字変換は本当に辛い。理由は複数あるがサジェストが理由なことがわかった。

.@googleime_jp Mac OS + Google IME input and convert to emoji is so bitter that reason is mainly SUGGEST feature

very thanks to GOOGLE IME we never live without you on inputting WORLD! but emoji inputting is so troublesome so i wrote this topic.

# そもそも何で変換できるかわからなすぎる

its SOOOOOOOOOOOOOO hard find convert rules


- いいね、と打っても 👍 手 が出てこない / ロボット と打っても 🤖 ロボットが出てこない
- 変換できる文字がごく限られているので、打ちたい絵文字を使うのに本当、、、、、、、、に膨大なコストがかかる
- Mac的な問題なのか Google IME 的な問題なのかは完全には自信がない、断言する自信は

# サジェストのランキングを自分で作らなければいけない

- 「て」と入力したときに 👍 が出てくる状態を自分で作っている
- このサジェストはすぐにIMEに忘れられる、また て とたくさん入力して候補のランキング上位にする必要がある

![image](https://user-images.githubusercontent.com/13635059/50730326-08ab8f00-118e-11e9-8924-25ac13ebe844.png)

# サジェストの法則を覚えても問題が起こる

if we remember customized suggest rule but many troubles happen

- 日本語で手と打ちたい時に絵文字の👍手が出てきてしまう
- 手といちど入力するとまたサジェストのランキングが崩れる
- サジェスト機能を使うことじたいが本当にbitterすぎる、にがすぎる

絵文字の世界、、権利向上を、、願うぜ、、


# emoji pallet 最強説

また別の話で。

![image](https://user-images.githubusercontent.com/13635059/50730305-8d49dd80-118d-11e9-956f-ca8b4f315e56.png)


---

https://twitter.com/yumainaura

https://github.com/YumaInaura/YumaInaura/issues

https://github.com/YumaInaura/YumaInaura/issues/255








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ESP32でBLEスキャンとHTTPS送信を同時に実行できない問題の回避策

# 問題
「[Wi-Fi＆BluetoothモジュールESP32とBLEタグで誰かの在宅状況を見守ってみる](https://qiita.com/nikotan/items/918f7a3d80a65e247064)」で作ったArduinoコードを久しぶりに引っ張り出してきて、パラメータだけ変更してビルドしてESP32に書き込んだら、うまく動かなくなりました(^^;)。色々試してみると、どうやら、BLEスキャンとWIFI経由でのHTTPS送信が同時に実行できない問題だったようです。
*(っていうか、逆になんで今まで動いていたのか謎なんですが、結局調べてもよくわからなかったので謎のまま。。。)*

少し前の記事ですが、以下でも同じ現象が報告されています。
[ESP32でBLEで受信したデータをWi-Fi経由でhttp送信はできるが、httpS送信ができない - つれづれ日記](https://diary.sshida.com/20180505-4-ESP32でBLEで受信したデータをWi-Fi経由でhttp)

# 回避策
試行錯誤の結果、最終的には「BLEスキャンとHTTPS送信を同時に実行しない」という当然の対策に行き着きました。流れは以下の通り。

1. まずはBLEスキャンだけ実行して、スキャン結果をEEPROMに書き込みリセット<br>※このとき、Wi-Fiは使いません。
2. リセットからの復帰後、EEPROMからスキャン結果を読み取ってWi-FiでHTTPS送信<br>※このとき、Bluetoothは使いません。

安直ですが、これで安定動作してくれます。
起動毎に処理を切り分けるやり方は色々ありそうですが、今回の用途では、起動時にリセット理由をチェックして処理を切り分けています(BLEスキャンの後はSOFTWARE RESET、HTTPS送信の後はDEEP SLEEPさせているので、リセット理由だけで処理が決まります)。EEPROMに何かしらのフラグを保管しておくのがスマートかもしれません。

# コード
コードは以下に置いておきます。
[nikotan/BLETagMonitor_esp32.ino - GitHubGist](https://gist.github.com/nikotan/5c52005722baab7c3d87402b5e906be8)

`setup()`の中で、起動時のリセット理由をチェックして処理を振り分けてます。
こんな感じ。

```c:setup()だけ
void setup()
{
  delay(500);

  // reset理由をチェック
  RESET_REASON r = rtc_get_reset_reason(0);
  if (r != 12)
  {
    // software reset 以外の場合
    doScanBLETag();
  }
  else
  {
    // software reset の場合
    doSendResult();
  }
}
```
Firefox65.0b8でDNS over HTTPSやDNSSEC、Encrypted SNIを有効にする方法

**2021年2月現在、業界全体で、ESNIからECHへ移行中です。下記の確認ページでESNIだけはOKになりません。**
**https://blog.cloudflare.com/encrypted-client-hello/**
**https://blog.mozilla.org/security/2021/01/07/encrypted-client-hello-the-future-of-esni-in-firefox/**

手順① まず下記サイトに行って現状のセキュリティ状態を把握しておく。→いくつか？マークになっているとおもわれる。これらを４つすべてＯＫにするのが今回の目的です。
https://www.cloudflare.com/ssl/encrypted-sni/

手順② about:configで下記を設定する

```
network.trr.bootstrapAddress=1.1.1.1
network.trr.mode=2
network.security.esni.enabled=true
```
(network.trr.mode=3にするとDoHのみ使用する）
(network.trr.mode=2の場合、DoHに失敗したときに従来のDNSを自動的に使用する）

手順③ 一旦Firefoxを再起動する（念のため）

手順④ 再度下記サイトに行って４つともＯＫになっていることを確認する。
https://www.cloudflare.com/ssl/encrypted-sni/

お疲れさまでした。
![Screenshot_2019-01-10 Cloudflare ESNI Checker Cloudflare .png](https://qiita-image-store.s3.amazonaws.com/0/149781/12ac0497-1f87-dae6-87fb-c113f82d9e45.png)
ESP32で取得したデータをgrafanaで表示する。

これまで、ESP8266やESP32で取得した時系列数値データは、[ThingSpeak](https://thingspeak.com/)にアップデートして、グラフとして表示してきた。
一方で、サーバのCPU負荷やメモリ残量は、[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/)を用いて[influxdb](https://github.com/influxdata/influxdb)に収集したデータを、[Grafana](https://grafana.com/)で可視化するとともに、[slack](https://slack.com/)にアラートを通知するようにしている。

ThingSpeakは昔からあるとても便利なASPサービスなのだが、グラフ表示の自由度が低いという弱点がある。今回もある目的で利用しはじめたが、グラフ表示の自由度が低く、他のASPサービスに乗り換えようか悩んでいた。
ふとある日、ESP32からinfluxdbに直接書き込みにいければ、grafanaで可視化できるので便利かもしれないとひらめいた。調べてみたところ、influxdataのページに、[How to send sensor data to InfluxDB from an Arduino Uno](https://www.influxdata.com/blog/how-to-send-sensor-data-to-influxdb-from-an-arduino-uno/)というページを見つけた。
UDPの認証なしでデータをひたすら送り続けることで、データを蓄積できるとのこと。蓄積できれば、grafanaで可視化やアラート通知も簡単にはず。
設定してやってみた。UDPで投げつけるだけなので、マイコンの処理も軽く、お手軽。簡単にグラフが書けた。

問題は、受信側(サーバ側)のIPアドレスとポート番号、DBのスキーマが分かれば、誰でもデータを送れること。DoS攻撃を食らう可能性はゼロではない。しかし、個人で使う分には現実的に問題になることはないと思われるため、取り合えずやってみることにした。

この問題を解決するには、Basic認証か、クライアント証明書を使うか。手軽にBasic認証を使いたいが、通信路でパスワードが漏れる可能性がある点をどう考えるか。
もう少し考えてみたい。
Raspberry Pi (Raspbian)の無線LAN環境をキーボード、マウス、HDMIディスプレイなしで変更

# 1.   はじめに
Raspberry Pi の無線LAN環境を変更する際、無線LANルータに合わせてSSIDや暗号化キーを変更する必要があります。
ここで、
　　・USBキーボード
　　・USBマウス
　　・USBハブ
　　・HDMIケーブル
　　・ディスプレイ(HDMI)
を接続して設定するのも面倒なので、RaspbinanをインストールしたmicroSDを直接WindowsCで変更する方法をまとめました。
（ここでは、Windows10を使用）

# ２.   手順
<strong>（１）microSDをWindows10PCにセット</strong>
<strong>（２）microSDフォルダーをエクスプローラで開く</strong>
#![01.png](https://qiita-image-store.s3.amazonaws.com/0/59815/64707bd9-bda9-0264-cf5b-4795791620cd.png)
<strong>（３）「wpa_supplicant.conf」ファイルの作成</strong>
　　　（３－１）ルートフォルダーにテキストドキュメントを新規作成
![02.png](https://qiita-image-store.s3.amazonaws.com/0/59815/76efdd03-92c0-444d-8b6b-267e36a43eda.png)
　　　（３－２）テキストドキュメント内容を編集し、上書き保存

```Command:内容
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="SSID"
    psk="暗号化キー"
}
```

SSID、暗号化キーはお使いの無線LAN環境に合わせて変更してください。
<strong>（４）ファイル名の変更</strong>
　　<font color="blue">「新しいテキストドキュメント.txt」</font>を<font color="blue">「wpa_supplicant.conf」</font>に名前の変更
　　　<font color="green">”拡張子を変更しますとファイルが使えなくなる可能性があります。変更しますか？”　には「はい」で答える。</font>

<strong>（５）microSDをWindows10PCから取り外し、Raspberryセットし起動</strong>
　　　Raspbian起動まで少し時間がかかります。
　　　（２～３分ぐらいかな）
<strong>（６）起動確認</strong>
　　　「raspberrypi.local」にpingで疎通確認。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/59815/588ba7a2-bf5a-159f-9cfe-2646830a2d4e.png)


以上で無線LAN環境の変更設定完了です。


# ３.  注意点
今回の設定では無線LANルータの<font color="red">暗号化キーが平文のままで暗号化されていません。</font>
セキュリティを強化したい方は、<font color="blue">wpa_passphraseコマンド</font>で暗号化キーを生成して、適用してください。

参考情報：
http://www.atmarkit.co.jp/ait/articles/1601/23/news008.html
SDLアプリコンテスト 六日目

#概要

SDLアプリコンテスト、見つけたので挑戦してみる。
sdl_coreを起動してみた。

#写真

![Screenshot from 2019-01-06 08_01_09.png](https://qiita-image-store.s3.amazonaws.com/0/18104/2c6c2da7-4ece-987f-e1e2-427bfadf1026.png)

#手順

- git clone https://github.com/smartdevicelink/generic_hmi.git
- chromium-browser index.html

#ポートの調査

|TCP port|	description|
|:--|:--|
|3001|	Exposes core's file system in /usr/sdl/bin/storage|
|8087|	Websocket used by the HMI to communicate with SDL Core|
|12345|	SDL Core's port used to communicate with mobile application over TCP|

以上。
Node-redのJSONata事例 ~特定のフィールド名を持つものだけを取り出す~

#概要
タイトルの通りです。

#説明
payloadで渡された複数あるObjectの中で、msg_で始まるものだけを拾いたい場合は以下で動きます。

```
( 
$.payload.$sift(function($v, $k) { $match($k,/msg_/)});

)
```

というか、JSONataのドキュメントに載ってるsiftの事例まんまです。
謎なのは、/msg_/だと動くけど、/msg/だと動かない点。msgが予約語なんだろうか。。
あまり深く調べずに先に進んでしまったので、だれかご存知だったら教えてください。
Node-redのJSONata事例 ~ある配列の値を使って、別配列中のObjectを処理する~(ボツネタだけど動くよ)

#概要
Node-redのJSONata式のボツネタだけど事例なので載せます。

#背景
・HTMLフォームから最大3つの画像（URLかファイルで、1、2、3とナンバリングされる）を受け取りたい。
・ユーザーはラジオボタンでURLかファイルを選択する。
・ユーザーは一度ファイルをブラウザ上で指定した後に「やっぱURLで」と気が変わったらURLを指定してSubmitできる。

→この場合に、ラジオボタンの選択内容と実際にPOSTで受け取るファイルの個数がずれる場合が出てくる可能性があるので、要らないデータは保存したく無い！というのがやりたい事。

#さて
（色々すっ飛ばして、）以下の様な`msg.req.files`と`msg.msgs`が存在する。

```JSON
{
    "req":{
        "files":[
        {
            "fieldname": "msg_1_img_file",
            "originalname": "hogehoge.png",
            "encoding": "7bit",
            "mimetype": "image/png",
            "size": 60708
        }
    ]},
    "msgs": [
        {
            "index": 0,
            "type": "image",
            "imgtype": "url",
            "img": {
                "url": "http://hogehoge.com/"
            },
            "text": ""
        },
        {
            "index": 1,
            "type": "image",
            "imgtype": "file",
            "img": {
                "url": ""
            },
            "text": ""
        },
        {
            "index": 2,
            "type": "text",
            "imgtype": "url",
            "img": {
                "url": ""
            },
            "text": ""
        }
    ]
}
```

`msg.req.files`はPOSTでブラウザから渡された画像が入ってくる。（ここではbufferは省略）
`msg.msgs`には、背景でいうところのラジオボタンの値(imgtype)が入っている。

#JSONata
これらを使って、msg.msgsでファイル形式としてユーザーがUpしてきたファイルのみをmsg.payloadにコピーしたい。


```javascript


(
   $filenames := $map(
       $.msgs[
           type="image" and imgtype="file"
       ] ,
       function($v,$i,$a){
           "msg_" & $v.index & "_img_file"
       }
   );
   
   $map(
       $filenames,
       function($v,$i,$a){
           $.req.files[ fieldname = $v ]
       }
   );
)
```

#解説
最初のfilenamesは、msg.req.files配列の中のfieldnameに存在するはずの名前を配列として作成する。
そして、そのfilenamesの配列でmapをかけて、それがmsg.req.filesにある場合はそれが配列として戻る様にする。

#ボツの理由
~~1、HTML側でラジオボタンを操作した時に、片方の中身を消してしまう方が良くね？~~
2、仮にこの方式でやった場合に、データ保存した後にそのID/URLをどうやって正しい場所に入れるかを考えるのがまためんどくさい
3、というかmsg.req.filesを使ってsplitした方が一回に一つのファイルしか評価しなくて良いからシンプルなんじゃね？

#以上です
という事で、サラッと書いたので万人向けの優しい記事では無いですが、node-redのJSONataの事例として上げておきました。
csv-moduleではbinary保存ができません(´･ω･`)


## CSVモジュール 
PythonにはCSVをR/Wするモジュールがあって、２次元配列のある変数でも `.writerows` メソッドに渡せば簡単にファイル作成ができます。

```py
import csv
import random

def outputCSV(path, items):
    with open(path,'w') as fout:
        writer = csv.writer(fout, lineterminator='\n')
        writer.writerows(items)

if __name__ == '__main__':
    path = "./sample.csv"

    word = ["#nhk_video","#その1秒をけずりだせ","#ジェジュン","#視聴率"
            ,"#東洋大","#mv","#剛健","#whistle","#キャイ～ン・天野ひろゆき","#箱根ロス","#ひるおび"]

    items = []

    for w in word:
        row = [w, random.randint(0,100), random.randint(0,100)]
        items.append(row)

    outputCSV(path, items)
```

## 問題点
`python main.py`
と直接terminalで叩く場合はOKなのですが、cronで起動する場合は

```
UnicodeEncodeError: 'ascii' codec can't encode character '\u2026' in position 16: ordinal not in range(128)
```
とエラーが出てしまいます。:scream_cat:

調べてみると、bynary形式でないとエラーになってしまうみたいなのですが、`with open(path,'wb') as fout:` とopen形式を変えてもcsv-module自体が対応していない、ようです。

なので、文字列を `"#nhk_video".encode() `にして書き込むしか方法がない、です。

``` python
def outputCSV(path, items):
    with open(path,'wb') as fout:
        for row in items:
            line = ""
            for i,cell in enumerate(row):
                if 0 < i:
                    line += "," 
                line += str(cell)
            line += "\n"
            fout.write(line.encode())
```

## おわりに
- 標準モジュールでもbinary形式でファイルを保存出来る!
- 他のパッケージを使うとbinary形式でファイルを保存出来る!

みたいなコメント求む！


##見たリンク
- [PythonでCSVの読み書き](https://qiita.com/okadate/items/c36f4eb9506b358fb608)
- [【Python】【Python 3.6】【Encode エラー】（UnicodeEncodeError: 'ascii' codec can't encode characters）と（TypeError: write() argument must be str, not bytes）](https://go-journey.club/archives/7113)
- [CSV ファイルの読み書き(公式)](https://docs.python.jp/3/library/csv.html#module-csv)
[Python] ModuleNotFoundError解決方法

Pythonで別ディレクトリのモジュールをインポートしようとすると、***ImportError***や***ModuleNotFoundError***が吐き出されることがあります。
このエラーはインポートしようとしたモジュールが、検索対象のパス(sys.path)の中に含まれていないことが原因です。
これを解決する方法を3つ書きます。

# デモ環境
ディレクトリ構造は以下のように想定し、app/app.pyからlib/module.pyを読み込もうと思います。

```
$ pwd
/home/test/

$ tree
.
├── app
│   └── app.py
└── lib
    └── module.py
```

# sys.path.append()
app/app.pyでsys.path.append()でsys.pathに任意のディレクトリを追加して、そのディレクトリをモジュール探索対象にします。

```python:app.py
import sys
sys.path.append('../lib')
from module import hello

hello()
```

しかし、この方法はPythonのコーディング規約であるPEP8に違反しています。

```
$ pycodestyle app/app.py 
app/app.py:3:1: E402 module level import not at top of file
```

出力されたメッセージによると、***モジュールをインポートするためのコードはファイルの上部になければならない***、ということらしいです。
別のディレクトリにあるモジュールをインポートする前に`sys.path.append('../lib')`を実行しているのが原因です。
PEP8に準拠したい場合はこの方法は推奨しません。⬅というか、PEP8に準拠すべきです。

# PYTHONPATH
PYTHONPATHという環境変数に自作モジュールのフルパスを代入します。

```
export PYTHONPATH="$PYTHONPATH:/home/test/lib"
```

これでsys.pathに追加されます。
しかし、一時的にsys.pathに追加されているだけなので、シェルの別タブや新規シェルではsys.pathには含まれません。
永続的に有効にしたい場合は次のようにします。

```
echo 'export PYTHONPATH="$PYTHONPATH:/home/test/lib"' >> ~/.bashrc
```

# 拡張子pthファイル
拡張子が***pth***であるファイルをsys.pathに含まれているディレクトリ下に置きます。ファイルの名前は任意です。
ファイルの中には自作モジュールのフルパスを一行に一つ書きます。

デモ環境では、sys.pathに`~/.local/lib/python3.6/site-packages`が含まれていると仮定します。

```
echo "/home/test/lib" > ~/.local/lib/python3.6/site-packages/mymodules.pth
```

これだけで、ファイルに書いたパスがsys.pathに追加されます。
ちなみに、拡張子pthでは`#`でコメントアウトできます。


3つの解決方法を書きましたが、管理のしやすさから拡張子pthのファイルを使用する方法が、個人的にはいいと思っています。

# 参考
- [29.13. site — サイト固有の設定フック — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/site.html)
- [29.1. sys — システムパラメータと関数 — Python 3.6.5 ドキュメント](https://docs.python.jp/3/library/sys.html#sys.path)
情報を齟齬なく伝えるために

システム開発において重要なことのひとつは，共同開発者やクライアントに対して情報を正確に伝えること．そして情報を正確に伝えるために特に重要なことは，

1. 伝え方・手段
1. 事前知識

の共通認識が，伝える側・受け取る側であらかじめとられていることである．

## 伝え方・手段の共通認識
人は，概念として理解している情報を文章化して話したり図を描いて見せたりすることで他人に伝える．このとき無意識的に，概念を文章や図といった人に伝えるための形に変換する作業を行っている．受け取る側は逆に，伝えられた文章や図から概念に変換することで情報を理解する．

「概念 ⇆ 人に伝えるための形」の変換のために必要なものが，共通の言語や文章・図のフォーマットであり，「概念」と「伝える／伝えられたもの」との対応表である．

|![send.png](https://qiita-image-store.s3.amazonaws.com/0/68605/81d10333-a5c5-46df-294f-44322c6bdbc0.png)|![receive.png](https://qiita-image-store.s3.amazonaws.com/0/68605/798cc1aa-44e6-b408-4c70-ebd635ac9eba.png)|
|:---:|:---:|
|伝える|受け取る|


共通の言語や文章・図のフォーマットを持つことのできていない２者間では情報を正確に伝えることはできない．英語しか理解できない相手に対しては，日本語でどれだけ丁寧に説明しても伝えたい情報を伝えることはできないのと同じことである．

共通の言語やフォーマットを０から作るのは容易ではない．容易にそれらの共通認識を取るためには，広く一般的に定義されているものを用いるのが良い．システムの設計について伝える際には，既存の仕様書と同様のフォーマットで新しい仕様書を書く，UML などの統一モデリング言語を利用する，編み出した独自の単語はなるべく使わずに辞書に記載されている言葉と意味を堅持するなどの方法が挙げられる．

一般的に定義されていないものを取り扱う場合には，伝える側と受け取る側双方が協力して新しい言葉やフォーマットを明確に定義する必要がある．

## 事前知識の共通認識
齟齬のない情報伝達とは，自分の理解と相手の理解を一致させることであると言える．自分の理解と相手の理解を一致させるためには，これから伝えようとしていることに関して相手がどれだけの事前知識を持っているかを理解しておくことが必要である．そうすることによって，情報伝達の齟齬をなくすことができると同時に最低限の労力で相手に情報を伝えることができる．

**相手の事前知識が理解できている場合：**

|![a.png](https://qiita-image-store.s3.amazonaws.com/0/68605/bf5fba19-bfc4-a7c4-a683-1c41030f6ae2.png)|![b.png](https://qiita-image-store.s3.amazonaws.com/0/68605/a73846ba-6064-8b18-f30f-c8ca8f5c9dbe.png)|
|:---:|:---:|
|相手の事前知識を理解|自分と相手の理解が一致|

**相手の事前知識が理解できていない場合：**

|![c.png](https://qiita-image-store.s3.amazonaws.com/0/68605/7357a20a-8e73-c2c7-4ca1-6d7e010fc17c.png)|![d.png](https://qiita-image-store.s3.amazonaws.com/0/68605/de65b8ac-1a5d-0d35-34cf-a029bf56a5ca.png)|
|:---:|:---:|
|相手の事前知識を理解していない|自分と相手の理解に齟齬|

事前知識も含めて網羅的に伝えることで，相手の事前知識に依存せずに情報を正確に伝えることができるかもしれないが，情報伝達だけにかけられる時間や労力は限られているのでそれは難しい．

## まとめ
情報を齟齬なく伝えるために重要なこと：

- 一般的な定義に基づいた言語やフォーマットを用いる
- 一般的に定義されていない手段を用いる場合や一般の定義とは異なる使い方をする場合，その手段を明確に定義し，共通の認識を持った上で用いる
- 相手の事前知識を理解した上で情報の伝達を行う
SambaのファイルサーバをWindowsで利用する時につまずいたこと

#何が起こったか
ラズパイにSambaをインストールして、ファイルサーバーを作った。
Windowsのマシンと無線LANを構築し、ファイルを共有しようとした。
しかし、Windowsのマシンからファイルサーバーにアクセスする方法を間違え、
この間違いがわかるのに一日かかった。

#間違い
アクセス方法がWindowsのエクスプローラーの左にある（下図のような）ネットワークからだと思っていたが、
![explorer.png](https://qiita-image-store.s3.amazonaws.com/0/167549/91809f37-cddd-437a-0491-0c657459b283.png)
エクスプローラーのURIを入力するところに

(YenMark)(YenMark)w.x.y.z
※(YenMark)を半角の￥
　w.x.y.zはファイルサーバーのIPアドレス

を入力することでアクセスする方法が正しかった。

#間違えた原因
上図のネットワークを選択すると、ファイルサーバーのMACアドレスを持つデバイスが一覧に含まれていて、
プロパティを開くと利用不可と表示されたため、別に原因があると思った。
しかし、ファイルサーバーではtestparmコマンドでエラーはなかったので、smb.confの設定が間違っているとか、
ネットワークの設定おかしいというところに検討をつけたために気づけなかった。

#最後に一言
WindowsのエクスプローラーのUIが悪かったと思います。
HerokuからAWSへ移行する（DBエクスポート・インポート）

###　やりたいこと
Herokuで運用していたアプリケーションをAWSへ移行する。
今回はDB関連の作業を対象に備忘として残す。

###　環境
MySQL5.7
Heroku JawsDB
RDB
MacOS

### JawsDBからエクスポート

```mysqldump:基本形
mysqldump --set-gtid-purged=OFF -uユーザ -h ホスト -p データベース > dump.sql
```

一応説明。
`--set-gtid-purged=OFF`はgtid関連のWarning抑止。
`--single-transaction`は、バックアップなどではよく使われるけど、今回は移行なので未使用。（業務的にデータ更新を止めれたので。）

基本形で一発でいければ楽なのだけど、データが多いと以下が返却される。
`mysqldump: Error 1317: Query execution was interrupted when dumping table xxx at row: xxx`

その場合は重量級テーブルとそれ以外のエクスポートを分ける必要がある。

```mysqldump:重量級以外
mysqldump -t --set-gtid-purged=OFF -uユーザ -h ホスト -p データベース --ignore-table=データベース.除外したいテーブル > dump_other_tables.sql
```

`--ignore-table`で重量級テーブルを除外する。重量級が複数ある場合は`--ignore-table`ごと複数書く。

重量級については、一発でエクスポートできない場合は`where`オプションでさらに分割する。

```mysqldump:重量級（whereで分割）
mysqldump -t --set-gtid-purged=OFF -uユーザ -h ホスト -p データベース 対象テーブル --where "id < 100000" > dump_XXX.sql
```

ちなみに`-t`はcreate table含めない。なので、移行先でいちいちDDLを叩きたくない場合は`-d`で定義だけエクスポートも必要。

### EC2にDumpファイルコピー
RDSはインターネットからは繋げない（設定にした方が良い）のでEC2を踏み台に接続する。
そのため事前にEC2にDumpファイルをコピーしておく。[参考](https://qiita.com/Yorinton/items/df24281fcf07729fa0f9)

```sh
/Users/XXX/.ssh
scp -i aws-eb コピーしたいファイル ec2-user@IPアドレス:/home/ec2-user　dump_XXX.sql 
```

### EC2にsshでログインしてインポート

```
cd プロジェクトディレクトリ
eb ssh

[ec2-user@xxx ~]$ mysql -uユーザ -h エンドポイント -p データベース < dump_XXX.sql 
```