OmniAICreator/Qiita-1.07M huggingface dataset:
スマホアプリ　孤独王

#はじめに
コロナにより三密を避けた開疎化が加速。それにより人々は東京から離れ地方に移住する人が増えると思います。
そこで人と離れれば離れるほどポイントが加算されるスマホゲームを作ってみようと思います。
Keras

# Keras 基本事項

- [compile](#compile)
- [fit](#fit)
- [evaluate](#evaluate)
- [predict](#predict)
- [save](#save)
- [結果を描画する](#結果を描画する)

## compile

```python
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
```

## fit

```python
history = model.fit(x, y, validation_split=0.25, epochs=50, batch_size=16, verbose=1)
```

## evaluate
訓練したモデルの評価を行う

- https://www.tensorflow.org/api_docs/python/tf/keras/Model#evaluate

## predict
訓練したモデルを使って、実際に個別のデータに対して性能を見る。

- https://www.tensorflow.org/api_docs/python/tf/keras/Model#predict

## save

## 結果を描画する
`fit`が返す`History`オブジェクトから損失率、正解率を描画することができる。

```python
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.legend(['Train', 'Test'], loc='upper left')
plt.savefig("acc.png")
```

また、`DataFrame`に変換してから描画することもできる。

```python
df_history = pd.DataFrame(history.history)
df_history.plot()
plt.savefig()
```

# RNN LSTMによる文章分類
Android Generate Signed Bundle or APKで必要なkey aliasの調べ方

#はじめに
**まず、この記事はキーストア（keystore）を紛失した人にとっては、意味のないものである！！！**
（ちなみに僕は、キーストアファイルの拡張子に`jks`は付けてません）

<img width="405" alt="スクリーンショット 2020-05-20 18.11.46.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/396bda32-4d87-75b2-1d2c-9d14ce021195.jpeg">

**そして、パスワードもわかっている人向けである！！！**

#key aliasとは？
`Build > Generate Signed Bundle / APK`を選択し、`Android App Bundle`もしくは`APK`どちらでもいいの選択し、next

key aliasとは、下の画像でいうと、`key0`となってるあれ。
<img width="650" alt="スクリーンショット 2020-05-20 18.13.00.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/6f7c4609-16ac-7ba6-7ff7-a55e36fbf3e5.jpeg">

#確かめ方
###キーストア（keystore）へのパスを確認
key aliasとは？で使った画像と全く同じである。
<img width="524" alt="スクリーンショット 2020-05-20 18.22.18.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/ea51e74e-94ba-1d29-d07a-5b97c09bb465.jpeg">

###コマンドプロントまたはターミナルを起動
`-keystore`以降に、キーストア（keystore）へのパスを入れる

```console
keytool -list -keystore /Users/gen/Desktop/basic/ionic/hCalendar/keystore
```

そしてパスワードを求められるので入れる

###発見！
key0 ありました！！
<img width="552" alt="スクリーンショット 2020-05-20 18.37.20.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/de6e8d55-8812-ce98-1162-02d1520a94a0.jpeg">
[Spark] columnの数が可変なResultSetからDataframeへの変換

Javaのsqldriverとかをたたくと、よくResultSetが返ってくるのですが、その際にdataframeに変換したいということがあったので、メモ程度に.

**ResultSetで返ってくるtableのcolumnの数があらかじめ分かっていない時です。**


```scala
    val rs = stmt.getResultSet()

    val schema = (1 to rs.getMetaData().getColumnCount()).map { i =>
      StructField(rs.getMetaData().getColumnName(i), StringType, true)
    }.toList

    val data = Iterator
      .continually { rs }
      .takeWhile(_.next())
      .map { rs =>
        val row = (1 to rs.getMetaData().getColumnCount()).map { i =>
          rs.getString(i)
        }.toList
        Row(row: _*)
      }
      .toList

    spark.createDataFrame(
      spark.sparkContext.parallelize(data),
      StructType(schema)
    )
```

こうした方がいいなどありましたら、ご教授ください.
バッチコミット作成例（配列を刻みながら処理する方法をいくつか）とFirestoreへのバッチ書き込みのサンプル

大量のデータをDBへ格納する際など、バッチオブジェクトに一定量の書き込み処理を蓄積し、定期的にコミットするという処理を行うことがあります。

上記を行うための、配列を一定間隔で刻みながら処理する方法のPythonのコードによるメモです。
もっと良い方法をご存知でしたらご指摘いただけると幸いです。

最後にGCPのFirestoreへのバッチ書き込みのサンプルコードを載せています。

更新：指摘を頂き「方法４（スライスを利用する）」を追加（@shiracamusさんありがとうございます）

## 方法１（専用のカウンタを使う）

```python
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

q = []
batch_size = 3
batch_count = 0
for d in data:
    print("{}".format(d))
    q.append(d)
    batch_count += 1
    if batch_count == batch_size:
        print("commit {}".format(q))
        q = []
        batch_count = 0

print("commit {}".format(q))

> python sample1.py
a
b
c
commit ['a', 'b', 'c']
d
e
f
commit ['d', 'e', 'f']
g
h
commit ['g', 'h']
```

## 方法２（インデックスと剰余を使う）

```python
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

q = []
batch_size = 3
for i, d in enumerate(data):
    print(d)
    q.append(d)
    if (i + 1) % batch_size == 0:
        print("commit {}".format(q))
        q = []

print("commit {}".format(q))

> python sample2.py
a
b
c
commit ['a', 'b', 'c']
d
e
f
commit ['d', 'e', 'f']
g
h
commit ['g', 'h']
```

## 方法３（最後のコミットを工夫する）

最後のcommitの記述をなくせてコードの見通しが良い方法です。

予めデータサイズを取得する必要があるのでイテラブルなデータには使えないのと、判定処理の効率が悪いのが弱点です。

```python
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
  
q = []
last = len(data)
batch_size = 3
for i, d in enumerate(data):
    print(d)
    q.append(d)
    if ((i + 1) % batch_size == 0) | ((i + 1) == last):
        print("commit {}".format(q))
        q = []

> python sample3.py
a
b
c
commit ['a', 'b', 'c']
d
e
f
commit ['d', 'e', 'f']
g
h
commit ['g', 'h']
```

## 方法３＋アルファ

Pythonのenumerateは第二引数で開始番号を指定できるので、方法３はもう少しシンプルにできます。


```python
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
  
q = []
last = len(data)
batch_size = 3
for n, d in enumerate(data, 1):
    print(d)
    q.append(d)
    if (n % batch_size == 0) | (n == last):
        print("commit {}".format(q))
        q = []

> python sample3.py
a
b
c
commit ['a', 'b', 'c']
d
e
f
commit ['d', 'e', 'f']
g
h
commit ['g', 'h']
```

## 方法４（スライスを利用する）

オシャレな方法（@shiracamusさん、ありがとうございます）
バッチオブジェクトのqに配列で渡せない場合はfor inなどでバラす。

```python
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

batch_size = 3
for i in range(0, len(data), batch_size):
    q = data[i:i+batch_size]
    print("commit", q)

> python sample3.py
commit ['a', 'b', 'c']
commit ['d', 'e', 'f']
commit ['g', 'h']
```

# 参考

方法４で、GCPのfirestoreにバッチインサートの上限の500件づつデータを追加するサンプルです。

```python
    db = firestore.Client()
    collection = db.collection("<COLLECTION NAME>")

    batch_size = 500
    batch = db.batch()
    for i in range(0, len(data), batch_size):
        for row in data[i:i + batch_size]:
            batch.set(collection.document(), row)
        print('committing...')
        batch.commit()
        batch = db.batch()
```
MacとRaspberry pi を有線Lanで直接繋ぐ

###MacとRaspberry pi を有線Lanで繋ぐ

####目的
- MacからRaspberry pi を操作したい
- Raspberry piのPC周辺環境を最小限にしたい手軽にしたい（キーボードやディスプレイをなし)
- Raspberry piからMacを経由してインターネットに接続したい
- コワーキングスペースなどで最小限の環境で開発できるようにしたい

####Raspberrypi側 環境設定
SSHとVNSをチェックONにする
<img width="496" alt="スクリーンショット 2020-05-20 14.57.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/b5bceb54-39b4-220d-ce5d-137328e0970f.png">

host名を確認しておく

```raspberrypi側
$ hostname

raspberry(各環境によって違います)
```
dhcpcd.conf はいじらなくてもOk
IPを固定する場合はここも変更する必要があります
<img width="580" alt="スクリーンショット 2020-05-20 18.08.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/c34c7855-af65-defb-15f3-3899ef988190.png">

無線をOffにする
<img width="243" alt="スクリーンショット 2020-05-20 18.07.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/c6e3a214-7b17-a926-5fe7-180714f9aaed.png">

RaspberrypiにプリインストールされたRealVNCを使用できるにしておく
https://dev.classmethod.jp/articles/raspberry-pi-4-ssh-vnc-remote/

####Mac側 環境設定

USB Lanアダプターを購入する

MacとRaspberry piを繋ぐ

無線Lanアダプターの設定Off 
(注)Raspberry側のdhcpcd.conf が固定に設定されている場合は手動でipやルーターIPを設定する場合はここも設定する必要あります
<img width="517" alt="スクリーンショット 2020-05-20 18.06.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/edb5035f-a231-92de-fad5-8080115c933f.png">

追記
注)他のサービスを利用するためにIPを入力し固定にしました。
利用したサービス　netatalk
dhcpcd.confもIPを固定にしました
<img width="533" alt="スクリーンショット 2020-05-21 16.15.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/a29c2cc3-9443-90ff-8edc-5bb9b1d32bd9.png">

インターネットを共有する設定するにする
Wifi と　Lanアダプターを設定してやる
<img width="519" alt="スクリーンショット 2020-05-20 18.02.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/a7ad7e20-12db-0508-660f-1823c2f73fb1.png">


####Mac側
VNCViewerをインストールする

host名.localをアドレスに入力する

<img width="453" alt="スクリーンショット 2020-05-20 14.51.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/590aa9b2-d8ee-62eb-f635-ec59663f564d.png">

Bonjour(iTune)がインストールされた環境だと名前を解決してくれます。Windowsの場合はiTunesなどをインストールしてBonjourサービスを有効にする必要があります
ホスト名→IPアドレス
host名.local　→　


####VNCViewにデスクトップが表示されない

ターミナルからRaspberrypiにSSHでログインする
コンフィグ画面を起動させる
```raspberrypi側
sudo raspi-config```

<img width="371" alt="スクリーンショット 2020-05-21 13.55.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/fb013220-52bc-c920-364d-bb94c10d7780.png">
raspi-config
　7 Advanced Options
　　A5 Resolution
　　　DMT Mode 85 1280x720 60Hz 16:9 

DMT Modeを選択する

raspberrypiを再起動

https://blog.goo.ne.jp/jde_aki/e/ec8b3bcfe66286a2eb3ab24196259884


以上の手順でできると思います。

参考
http://regpon.hatenablog.com/entry/2018/02/23/165107

追記
インターネットには速度上の理由から無線Lanで繋ぐことにしました
[AWS]表示名、タグの命名規則

# 概要
AWSを使っていると新しくインスタンス作ったりとかするときに、表示名つけてあげたり、タグを振ってあげたりしないといけないことがある。

・・・指針がないとめっちゃ迷うので、ネットで拾ったよさげな記事を参考に定めた。
理由がない場合はこれに従いたい。

参考
https://dev.classmethod.jp/articles/aws-name-rule/
https://qiita.com/hidekatsu-izuno/items/c1c0ce0b56a822c25e5e

# 自分の命名規則
## 表示名
```
<案件名>-<環境名>--<対象を一意に特定できる補足情報>-<AWSサービス名>
```

## タグ
以下を絶対に振る

キー|値
---|---
Name|表示名と同じにする
Stack|<案件名>
Env|<環境名>
【nuxt】【style-resources】「Semicolons aren't allowed in the indented syntax. というエラーがでて、buildできない

## やりたかった事

scssの変数や、mixin等を一括で各コンポーネントに読み込みたい。そしてそれをbuildしたい。

## 手順

下記を参考に、scssの変数や、mixin等を一括で各コンポーネントに読み込んだ。
https://github.com/nuxt-community/style-resources-module

```
npm i @nuxtjs/style-resources
```
もしくは

```
yarn add -D @nuxtjs/style-resources
```

その後、 `nuxt.config.js`にて追記

```
export default {
  buildModules: [
    '@nuxtjs/style-resources',
  ],

  styleResources: {
   // それぞれの環境に合わせて設定を記述
   sass: [],
   scss: [],
   less: [],
   stylus: []
  }
}
```
僕の場合は、scssファイルを使用していたので以下に変更

```
export default {
  buildModules: ['@nuxtjs/style-resources'],
  styleResources: {
    scss: [ // scssの変数や、mixin等のファイル名を記述
       '~assets/scss/variables.scss',
       '~assets/scss/mixin.scss',
       '~assets/scss/style.scss',
      ]
  }
}
```

## build時に、vuetify-moduleのエラーが発生

これで開発環境では特に問題起こらず一括読み込みができるようになった。
しかし、なぜがbuildができない。。。
<img width="419" alt="スクリーンショット 2020-05-20 16.53.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/22bef66f-266f-2ac7-f4c2-b791f96a9357.png">


`Semicolons aren't allowed in the indented syntax`

v-〇〇でのエラーなので、vuetify関連でエラーが発生してるぽい。

## 解決策

全く同じ現象に遭遇した人がいたので参考にしてみた。
https://github.com/nuxt-community/vuetify-module/issues/82

話を追っていくと、 一旦、node_modulesを削除、再インストールしてみると良いとのこと。

### node_modeluesの削除＆再インストール

試しに
`node_modeluesの削除`
`npm i`
を行ってみると、無事解決できた。詰まったらこれ大事ですね。

<img width="165" alt="スクリーンショット 2020-05-20 17.42.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/9ec1c1d8-63cb-053c-3cf6-2edc0e77ed25.png">
Windows 10 + OpenJDK13 + LibreOffice 6.4.3 Base + ODBC から SQL Server 2019 Express へ接続してみる

Windows 10 + OpenJDK13 + LibreOffice 6.4.3 Base + ODBC から SQL Server 2019 Express へ接続してみる(JDBCはNG -> ODBCで確認)
#目的
以前試した[Windows 10 Pro + JDK10 + LibreOffice 6.0.3.2 Base から SQL Server 2017 Express へ接続してみる](https://tabizou.hatenablog.com/entry/20180410/1523354204)の更新を試してみる
#JDBCを使用した接続(NG)
##JDBCドライバのダウンロード
[Microsoft SQL Server 用 JDBC Driver のダウンロード](https://docs.microsoft.com/ja-jp/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-ver15)
より sqljdbc_8.2.2.0_jpn.zip をDL後適当なフォルダに解凍後配置する
##SQL Server側の設定
・SQL Server 構成マネージャーの使用より
　[SQL Server ネットワークの構成]
　->[<インスタンス名> のプロトコル]
　　[TCP/IP]が有効であること
　　->[TCP/IP] をダブルクリック
　　　[TCP/IP のプロパティ] ダイアログ ボックスの [IP アドレス] タブに
　　　IP1～IPAllまで IP アドレスが表示される
　　　IPn(該当するIPアドレス)の設定値で
　　　TCPポート　　：1433
　　　アクティブ　 ：はい
　　　有効　　　　 ：はい
　　　を設定してOKを押下する
　設定後　SQLServer、SQLServerBrowserを再起動する
##LibreOffice 6.4.3 Base の設定
ツール -> オプション -> LibreOffice -> 詳細 -> クラスパス　ボタンをクリック
　-> アーカイブを追加　をクリック　して以下を追加する
　　->D:\DB\sqljdbc_8.2\jpn\mssql-jdbc-8.2.2.jre13.jar
##Baseから使用する
　左側のペインで　Base　をクリック
　->データベースウィザードが表示
　　->既存のデータベースに接続：JDBC
　　->次へ
　　　->データソースのURL：jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=demo
　　　->JDBC ドライバークラス：com.microsoft.sqlserver.jdbc.SQLServerDriver
　　　->次へ
　　　　->ユーザー名：demo
　　　　->パスワードを要求する：チェック
　　　　->次へ
　　　　　->完了
　　　　　ファイル名を指定して保存
　右側のペインから作成したデータベースが開くことを確認する
とここまで試してみたのだが、JDBCによる接続は不可という結果に
LibreOffice 6.3.6 での同様の結果に
しょうがないので、ODBCによる接続を試してみる
#ODBC接続で試してみる
　左側のペインで　Base　をクリック
　->データベースウィザードが表示
　　->既存のデータベースに接続：ODBC
　　->次へ
　　　->システム上のODBCのデータソースの名前：データソース名を選択
　　　->次へ
　　　　->ユーザー名：demo
　　　　->パスワードを要求する：チェック
　　　　->次へ
　　　　　->完了
　　　　　ファイル名を指定して保存
　右側のペインから作成したデータベースが開くことを確認する

[接続 URL のサンプル](https://docs.microsoft.com/ja-jp/sql/connect/jdbc/connection-url-sample?view=sql-server-ver15)の内容と合わない部分を修正して接続を確認

```java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ConnectURL {
    public static void main(String[] args) {

        // Create a variable for the connection string.
        String connectionUrl = "jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=AdventureWorks2017;user=demo;password=demo";

        try (Connection con = DriverManager.getConnection(connectionUrl); Statement stmt = con.createStatement();) {
            String SQL = "SELECT TOP 10 * FROM Person.ContactType";
            ResultSet rs = stmt.executeQuery(SQL);

            // Iterate through the data in the result set and display it.
            while (rs.next()) {
                System.out.println(rs.getString("Name") );
            }
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
```
#参考にしたサイトはこちら
<a href="http://d.hatena.ne.jp/tabizou/20180204/1517753054">windows10 + SQL Server2017 Expressでファイアウォールを設定する</a>
bqコマンドでデータセットを指定するとデータセット配下のテーブルを削除するようにした

# 概要
お掃除等のタイミングで、不要になったデータセット配下のテーブルをまるっと削除したい時用のスクリプトを書きました。
データセットごと削除してしまうと、やっぱりあのテーブル必要だった！？と発覚したときに復元できないので、
データセットを削除せず、テーブルを削除するようにしています。

# 使い方
スクリプトを実行するときにデータセットIDを渡すだけです。
プロジェクトIDは明示的にスクリプト内に記載します。

```
bash bq_rm_dataset_tables.sh dataset_id
```

# スクリプト
```bq_rm_dataset_tables.sh

#!/bin/bash

# project_id は明示的に固定しておく
project_id=hogehoge
dataset_id=$1

# cf. https://qiita.com/okisanjp/items/7985ddb9b1b00f1617a9
# mac は /bin/echo としないと -n がうまく動作しない
/bin/echo -n "bq rm ${project_id}:${dataset_id}.tables? [y/n]"
read answer

if [ "$answer" = "y" ]; then

  # 明示的に区切り文字を改行コードにする
  IFS=$'\n';
  # bq ls dataset | TABLE行のみ取得 | TABLE以降の文字列を削除 | 空白削除
  for LINE in `bq ls ${project_id}:${dataset_id} | grep TABLE | sed 's/TABLE.*//g' | sed 's/ //g '`
  do
    yes | bq rm ${project_id}:${dataset_id}.${LINE}
  done

fi


```
Sassの特定要素

###Sassの特定要素
CSSでは要素.クラス名で書きます。
【例】CSSの場合

```stylesheet.scss
 li {
    font-size: 10px;
    li.other {  //今回はotherをクラス名としています
      font-size: 20px;
    }
```
Sassでは＆.クラス名で書きます。
【例】Sassの場合

```stylesheet.scss
 li {
    font-size: 10px;
    &.other {
      font-size: 20px;
    }
```
上記の方がコードも短くすっきりします。
centOS7にPython３系を入れるときにちょっとはまった。

はじめて投稿します。価値があるかどうかわかりませんが、記事として残しておいたらと思い書いています。

今回、表題の通りcentOSにPython3をインストールしようとしたところ、たった数日前まで出来ていた以下のコマンドができなくなってしまいました。


yum install -y https://centos7.iuscommunity.org/ius-release.rpm

エラーというか、これ自体は厳密にはエラーではないかと思いますが、
Loaded plugins: fastestmirror, langpacks
ius-release.rpm                                                                                                                                          |  137 B  00:00:00     
Cannot open: https://centos7.iuscommunity.org/ius-release.rpm. Skipping.
Error: Nothing to do
このようなメッセージがでていきていました。

そのため、Python3系のインストールがうまくいかないということがありましたが、
https://github.com/iusrepo/announce/issues/18
こちらのサイトの通りだそうです。

どうやらリダイレクトが終了したもよう・・・。（あってる？？）

そこで、

 yum install  https://repo.ius.io/ius-release-el7.rpm

というコマンドを使ってインストールし、

その後にPython３系をインストールしたらうまくいきました。




まぁ、書いてる通りにしたので、あまり参考にならないかとは思いますが、だれか同じような悩みをもっていたらどうぞ試してみてください。
HTTPステータスコードまとめてみた


403や404という謎の暗号をこれまで、ブラウザ上でみたことがあったので
後学のために、よく見るステータスコードをまとめてみました。


#1xx ~ 5xxまでの分類

**1xx**:処理中
**2xx**:成功
**3xx**:リダイレクト
**4xx**:クライアントエラー
**5xx**:サーバーエラー


#具体的によく見るステータスコード
**200(success)**・・・httpリクエストが正常に完了したことを表す
**301(Moved Permanently)**・・・リンク先の永続的な移動
**302(Found)**・・・リンク先の一時的な移動
**303(See Other)**・・・他を参照せよ
**401(Unauthorized)**・・・認証が必要
**403(Forbbiden)**・・・アクセス禁止
**404(Not Found)**・・・指定されたリソースが見つからない
**500(Internal Server Error )**・・・内部的なエラー
**303(Service　unavailable)**・・・一時的に接続できない時、サーバーの受け入れ可能接続数を超えた時

>[プロになるためのWeb技術入門](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352)
>[amazon web services 基礎からのネットワーク&サーバー構築](https://www.amazon.co.jp/Amazon-Web-Services-%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%EF%BC%86%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89-%E6%94%B9%E8%A8%823%E7%89%88-%E5%A4%A7%E6%BE%A4-ebook/dp/B084QQ7TCF/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1BJTRN3NX1OC2&dchild=1&keywords=amazon+web+services+%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%26%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89&qid=1589964915&s=books&sprefix=Amazon%2Cstripbooks%2C335&sr=1-1)
IAMまとめ

# 概要

IAMについて調べる機会があったので、
私なりの解釈を交えて以下にまとめた。

# IAMとは

「各AWSサービスへのアクセス権限を管理するサービス」である。

以下4つの概念があるが、言葉だけだとわかりづらい。[**めちゃくちゃわかりやすい概念図**](https://milestone-of-se.nesuke.com/sv-advanced/aws/iam-policy-role-group/)を見ればすごく理解できるはず。

概念|概要
---|---
IAMポリシー|○○サービスへの読み取り権限あり、書き込み権限ありというアクセス権限設定の雛形である
IAMユーザー|そのAWSアカウント内の各サービスを利用するユーザーである。「ユーザー名、パスワード、選択してアタッチした複数のIAMポリシー」からなるデータである。各ユーザーのAWSサービスの操作権限はアタッチされたIAMポリシーの通りとなる
IAMグループ|IAMユーザーの集合体である。IAMユーザーは複数のIAMグループに所属できる。IAMグループは入れ子にすることはできない。IAMグループにもIAMポリシーを複数アタッチでき、IAMグループに所属しているIAMユーザーは、そのIAMグループにアタッチされているIAMポリシーと自身にアタッチされているIAMポリシーで設定されているAWSサービスの操作権限が与えられることになる
IAMロール|IAMユーザー、グループは人に割り当てられるものであるのに対し、ロールはそれ以外のもの・・・例えばEC2インスタンスなどに割り当てられるものである。IAMロールにも複数のIAMポリシーをアタッチする。指定のインスタンスにIAMロールを割り当てると、そのインスタンスはIAMポリシーで設定されているAWSサービスへの操作権限を有することになり、インスタンス内のプログラムで別AWSサービスを操作することができるようになる。実際にはKMSという仕組みで別AWSサービスを操作するにあたってのアクセスキーとシークレットキーが与えられ、これを使って操作することになる。AWSで用意されているSDKを利用することでこのKMSという仕組みを意識せずとも別サービスを操作することができるため、使ったほうが絶対いい。



# ロールの作成
以下、EC2から別のAWSサービスを操作させる場合を例にしたロールの作成手順。

**手順**

**1. IAMのコンソールへアクセス　＞　アクセス管理 - ロール ＞ 「ロールの作成」ボタンを押下
→「ロールの作成」ページへ遷移**
![スクリーンショット 2020-05-20 19.39.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/f7c42a85-aa23-97f7-68c8-c5d214214d2f.png)

**2. 「ロールの作成」ページの、「信頼されたエンティティの種類を選択」で「AWSサービス」を選択し、「ユースケースの選択」で「EC2」を選択して「次のステップ：アクセス権限」ボタンを押下**
→「Attach アクセス権限ポリシー」ページへ遷移
  ![スクリーンショット 2020-05-20 19.43.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/4ad2eaae-4f53-5e59-af23-91afbb3d0107.png)

**3. EC2が他のAWSサービスを操作するのに必要なアクセス権限が含まれるポリシーを選択し、「次のステップ：タグ」ボタンを押下**
→「タグの追加(オプション)」ページへ遷移

**4. 「タグの追加(オプション)」ページで任意の「キー、値」を設定して「次のステップ:確認」を押下**
参考:[[AWS]表示名、タグの命名規則](https://qiita.com/WisteriaWave/items/c41c8803ef0e14a71262)
→「確認」ページへ遷移

**5. 「確認」ページで「ロール名、説明」を入力して「ロールの作成」ボタンを押下**

以上

# ロールのアタッチ
以下、EC2へのアタッチを例にしたロールのアタッチ手順。

**1. EC2のコンソールへアクセス　
＞インスタンス-インスタンス 
＞ロールをアタッチしたいEC2インスタンスにチェックを入れ、アクション 
＞インスタンスの設定 
＞IAM ロールの割り当て/置換 と押下**
![スクリーンショット 2020-05-29 17.26.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/b48a6975-be00-9011-905c-e6f2daec0eb2.png) 
→「IAM ロールの割り当て／置換」ページが表示される。
![スクリーンショット 2020-05-29 17.29.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/e1ab3ca8-c6b4-8205-9d28-354f0ec0dcce.png)

**2. 「IAMロール」でEC2インスタンスにアタッチしたいロールを選択して「適用」を押下**

以上
DiscordのBotをGo言語で書いてHerokuに乗せて常駐化した

#記事を書いた経緯
- 自分用のメモ感覚
- DiscordのBotを自作した記事はたくさんあったが、**Goで自作した記事** と **Go×Heroku×Discordの記事**という2つの条件を満たす記事が少なかったため

#この記事の対象者
- Go言語の基礎は分かる
- Go言語でオリジナルのDiscordのBotを自作したい

※自作したBotのソースコードを全部載せるつもりはないので、どんな風に書けば良いかはググってみてください。

#準備〜導入までのプロセス
1. [Heroku](https://jp.heroku.com/)のアカウント作成
2. DiscordのBotアカウントを作成　※作り方は別の方の[記事](https://discordpy.readthedocs.io/ja/latest/discord.html)を参照
3. コードを書く　※今回利用した[外部パッケージ](https://github.com/bwmarrin/discordgo)
4. Botを常駐化させるために、プログラムをサーバー上で動かす(EC2とかGCEに乗せてもいいけど、今回はHerokuを採用)

#プロセスの一部をもうちょっと詳しく
プロセスの1と2は、たくさん記事があるのでここで説明する必要はないかなと思います。
#### 3. コードを書く について
今回利用させていただいた外部パッケージは、「[DiscordGo](https://github.com/bwmarrin/discordgo)」というパッケージです。
簡単に説明すると、DiscordGoパッケージ内に定義されている関数を呼び出すだけで、定義された関数に応じてDiscordのAPIを呼び出すことが出来る、Go言語向けに作成されたパッケージです。
DiscordGoの詳細はリンク先参照。

コードのサンプルは、[discordgo/examples/pingpong/](https://github.com/bwmarrin/discordgo/tree/master/examples/pingpong) とか [discordgo/examples/airhorn/](https://github.com/bwmarrin/discordgo/tree/master/examples/airhorn) が参考になるかなと思います。

#### 4. Botを常駐化させるために、プログラムをサーバー上で動かす について
大前提として、**無料でBotを常駐化させたい**という思いがありました。
なので、EC2でもGCEでも良かったのですが、EC2は以前Minecraftのサーバーを建てた時に使ったので今回はスルーして、GCPかHerokuかの選択肢でした。
そして今回は**Bot(アプリケーション)を動かすだけ**だったので、Herokuの[Dyno](https://jp.heroku.com/dynos)を採用しました。
※Dynoの無料枠がクレカ未登録で550h/月、クレカ登録後で1000h/月です。クレカ未登録では１ヶ月フル稼働は出来ないことに注意。

今回はGoで書いたアプリをGithubにあげて、GithubとHerokuを連携して自動デプロイ出来る環境を整えました。
やり方としては、[コチラの記事](https://j-hack.gitbooks.io/deploy-meteor-app-to-heroku/content/step4.html)を参考に進めてください。
今回僕が用意したファイルは、以下4つの最低限だけです。
- Procfile
- README.md
- main.go
- go.mod
各ファイルの中身は以下のような感じです。

```:Procfile
worker: discord_bot_atsumori
```

```README.md
// githubのリポジトリの説明欄に表示したい文章を書いてください
```

```main.go
package main

import (
	"fmt"
	"github.com/bwmarrin/discordgo"
	"os"
	"os/signal"
	"syscall"
)

const (
	TOKEN = "YOUR TOKEN"
...
...
...
```

```go.mod
module github.com/Satoshi-sts/YOUR_REPOSITORY

go 1.13

require github.com/bwmarrin/discordgo v0.20.3
```


あとはWebUIもしくはターミナルなどでコマンドを叩いてDynoを起動すれば完了です。

#最後に
作業が完了した後にこの記事を書いたので、もしかしたら抜けてる部分があるかもしれません...。
その時はごめんなさい、コメントで教えていただけるとありがたいです。

お疲れ様でした。
Windows Terminal V1.0 を使ってみた

#Windows Terminal V1.0 正式版がリリースされた
Windows Terminal 1.0正式版が、ようやくリリースされた。

Windows10 1903 以上であれば Microsoft Store からインストールもできるので、さっそく使ってみた。
###最初に起動するのをコマンドプロンプトにしたかった
設定ファイル settings.json を開き、コマンドプロンプトを起動するように変更した。
（デフォルトは PowerShell が起動する）
`  "defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",`
コマンドプロンプトに変更した
`"defaultProfile": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",`

###フォントとサイズを変更
フォントは MS ゴシックでフォントサイズが14が使いやすいので変更した。
PowerShellでも共通の設定としたかったので、共通個所に追記することにした
>       "defaults":
        {
            // Put settings here that you want to apply to all profiles.
                "fontFace": "MS Gothic",
                "fontSize": 14


###コマンドで起動
Windowsの設定で、コマンド起動するように設定されていたので、wt.exeを実行。コマンドプロンプトが起動してきた。これで、２つの画面横並びにできた。
![cmdPrompt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/470c0343-18cb-803c-b488-39794c9f2f61.png)


###上下または左右に２つにペインを分割
上にコマンドプロンプト、下にPowerShellを同時に開きたい場合は、以下のコマンドを入れると1つのタブで上下で画面が表示される
` wt.exe new-tab -p "cmd" ; split-pane -H -p "Windows PowerShell"`
![cmdandps.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/5c1fe794-a357-c024-5c33-ab4c7d1a6034.png)
####左右にするとき
引数の中で`-H`を外せば、左右で分割表示にできた
` wt.exe new-tab -p "cmd" ; split-pane -p "Windows PowerShell"`
![cmdandps-h.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/da1bc59f-2fd8-0759-3dfb-74a57ebdbfca.png)
###プロセスはコード 9009 で終了？？
はじめに適当なコマンドを打った後、Exitで抜けようとしたら、`[プロセスはコード 9009 で終了しました]`とエラーコードが表示された。
![cmdandps-h-err.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/6ffd0593-5b1f-9151-835d-7a57db8be398.png)
Hungupしているのか、exitと抜けようとしても入力を受け付けない
このエラーが出ないときは、普通に左側のほうだけウィンドウが閉じるんだけどなぁ。
###何分割までできるのか
暇なので、５分割までやってみた、5つはやりすぎた感。
`wt.exe new-tab -p "cmd" ; split-pane -p "cmd" ; split-pane -p "cmd"; split-pane -p "cmd"; split-pane -p "cmd"`
![cmdandps-h5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/164ef221-9236-350f-c4b8-3cc764bbe25e.png)

###ペインの移動をキーボードで行うには
`[Alt]キーを押しながら、矢印キー`を押すと目的のペインに移動できる。
ただ、アクティブなペインを示す青枠がかなり細いので、切り替わったペインが一瞬どっちなのか、見失うことも。。
###ペインの大きさを変更する
変更したいペインをアクティブにして、`[Alt]+[Shuft]のまま矢印キー`でペインサイズを変更できる
Splunkの列順を揃える

小ネタ
せっかく作ったのでもったいなくてということもある。

#テーブルを昔からに揃える

```sql:tabl.spl
|gentimes start=01/05/2020 end=05/10/2020
| eval _time=starttime
| timechart count span=1month
| eval host="host"
| eval _time=strftime(_time,"%B-%Y") 
| xyseries host _time count
| table host [|gentimes start=01/05/2020 end=05/10/2020
| eval _time=starttime
| timechart count span=1month
| eval _time=strftime(_time,"%B-%Y") 
| stats list(_time) as time
| eval search=mvjoin(time,",")
| fields search]
```
サブサーチが必要なのは、Splunkの列名は**自動的にアルファベット順になる**から

なので、サブサーチで`table`の引数を作ってあげている。

速度重視なので、サブサーチのなかは`tstats`とか`addinfo`のような検索時間がかからないものがいいと思います。

#まとめ

`table`の引数ってダッシュボードのトークンかサブサーチくらいじゃないと動的につくれないので、速度的に問題がなければ使ってみてください。
java（コンストラクタ）

#コンストラクの定義方法
①メソッド名がクラス名と完全に等しい
②メソッド宣言に戻り値が記述されていない（voidもダメ）


##生まれた直後の動作を定義したHeroクラス
```java
public class Hero {
  String name;
  int hp;
  public Hero() {   //コントラストの定義
    this.hp = 100;  // hpフィールドを100で初期化
  }
}
```
newされた直後に自動的に実行される処理を書いたメソッド


###コストラクタが定義されたHeroを生み出す

```java
public class Main {
  public static void main(String[] args) {
    Hero h = new Hero();      //インスタン生成と同時にHPに100が代入されている
    h.hp = 100;               //いらない

    System.out.println(h.hp); //100と表示される
  }
}
```

##コンストラクタで引数を追加情報として受け取る

```java
public class Hero {
  String name;
  int hp;
  public Hero(String name) {   //引数として文字列を１つ受け取る
    this.hp = 100;             // hpフィールドを100で初期化
    this.name = name;          //引数の値でnameフィールドを初期化
  }
}
```

###newで引数を渡す

```java
public class Main {
  public static void main(String[] args) {
    Hero h = new Hero("勇者");      //インスタン生成後、JVMによって自動的にコンストラクタが実行され、引数として"勇者"が利用される

    System.out.println(h.hp);   //100と表示される
    System.out.println(h.name); //勇者と表示される
  }
}
```

##コンストラクタのオーバーロード


```java
public class Hero {
  String name;
  int hp;
  public Hero(String name) {   //コンストラスタ①           
    this.name = name;          
  }
  public Hero() {              //コンストラクタ②
    this.name = "勇者２"        //"勇者２"を設定
  }
}
```

###コンストラスタをオーバーロードしたクラスの使用

```java
public class Main {
  public static void main(String[] args) {
    Hero h = new Hero("勇者");      //文字列引数があるのでコンストラスタ①が呼び出される
    System.out.println(h.name);    //勇者と表示される

    Hero h2 = new Hero();          //引数がないのでコンストラクタ②が呼び出される
    System.out.println(h2.name);   //勇者２と表示される
  }
}

```
ベクトル入門 : 線形代数をPythonで<1>

#線形代数
理系大学で絶対に習う線形代数をわかりやすく、かつ論理的にまとめる。ちなみにそれをPythonで実装。たまに、Juliaで実装するかも。。。
・Pythonで動かして学ぶ！あたらしい数学の教科書 -機械学習・深層学習に必要な基礎知識-
・世界基準MIT教科書 ストラング線形代数イントロダクション
を基に線形代数を理解し、pythonで実装。

#環境
・JupyterNotebook
・言語：Python3, Julia1.4

#線形結合(ベクトル入門)
線形結合は**スカラー積**と**ベクトル和**によって構成される。
2つのスカラーをa,bとして、ベクトル和をv,wとする。

スカラー積は、

```math
av,bw
```
のように掛けられたもの。

ベクトル和は、

```math
v + w
```
のように足されたもの。
これら二つの組み合わせを***線形結合***という。よって、

```math
av + bw
```
のような形のことである。ちなみにこれは項数が2つなので、***2次元面を張る***。（v=w>の場合、違うが。）

pythonで実装

```python
import numpy as np

# ベクトル 
v = np.array([1, 2, 3])
w = np.array([4, 5, 6])
# スカラー
a = 2
b = 5

#線形結合の形
linearcomb = a * v + b * w
print(linearcomb) 
```

juliaで実装

```julia
# ベクトル 
v = [1, 2, 3]
w = [4, 5, 6]
# スカラー
a = 2
b = 5

linearcomb = a * v + b * w
print(linearcomb)
```

どちらも以下のようにターミナルに出てくる

```terminal
[22 29 36]
```

#ここまで。
JavaはExcelの隣接する行に異なる背景色を設定します

Excelテーブルを作成するとき、データテーブルの2つの隣接する行を異なる背景色で塗りつぶすことにより、各行のデータをより明確に見せ、行の読み違いを避け、Excelテーブルの美観を向上させることがで。この記事では、JavaプログラムでExcelの奇数行と偶数行に代替の背景色を設定する方法を紹介します。

**使用ツール：** [Free Spire.XLS for Java](https://www.e-iceblue.com/Download/xls-for-java-free.html)（無料版）

**JARファイルのインポート方法**
**方法1：** Free Spire.XLS for Javaパッケージをダウンロードして解凍し、Spire.Xls.jarパッケージをlibフォルダーからJavaアプリケーションにインポートします。

**方法2：** mavenを使用している場合は、pom.xmlファイルに次の依存関係を追加する必要があります。

```java
<repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls.free</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>
```

**Javaコード例：**

```java
import com.spire.xls.*;

import java.awt.*;

public class ConditionalFormatting {

    public static void main(String[] args) {

        //Workbookオブジェクトを作成する
        Workbook workbook = new Workbook();

        //Excelドキュメントを読み込む
        workbook.loadFromFile("test.xlsx");

        //ワークシートを入手する
        Worksheet sheet = workbook.getWorksheets().get(0);

        //データ領域を取得する
        CellRange dataRange = sheet.getAllocatedRange();

        //条件付き書式を使用して、偶数行の背景色を薄い灰色に設定します
        ConditionalFormatWrapper format1 = dataRange.getConditionalFormats().addCondition();
        format1.setFirstFormula("=MOD(ROW(),2)=0");
        format1.setFormatType(ConditionalFormatType.Formula);
        format1.setBackColor(Color.lightGray);

        //条件付き書式を使用して、奇数行の背景色を黄色に設定します
        ConditionalFormatWrapper format2 = dataRange.getConditionalFormats().addCondition();
        format2.setFirstFormula("=MOD(ROW(),2)=1");
        format2.setFormatType(ConditionalFormatType.Formula);
        format2.setBackColor(Color.yellow);

        //ドキュメントを保存します
        workbook.saveToFile("AlternateColor.xlsx", ExcelVersion.Version2016);
    }
}
```

**出力結果：**
![xl.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/f3f71e70-45f4-f0bf-5b5a-d61766664d5b.jpeg)
PythonでARマーカーを映像から探す

#映像からARを見つけたい
ロボットとかをやってるとARマーカーをランドマークとしていろいろしたくなる。
今回はpython3とopencvで簡単にカメラからARマーカーを見つけていく。

# 環境
python3.5.4
matplotlib


opencv(contributeが入ってるやつ)
## opencv-contributeの入れ方
普通のopencvではダメ
ライセンスの関係で`aruco`が入っていないらしい
大人の世界って怖いね

`pip uninstall opencv-python`
通常版のopencvをアンインストール

`pip install opencv-contrib-python`
目的のopencvをインストール

#ARマーカーの作成

```generate.py
import cv2
import matplotlib.pyplot as plt

aruco = cv2.aruco
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
generator = aruco.drawMarker(dictionary, 0, 100)#第２引数がID　第３引数がピクセルサイズ
plt.imshow(generator)
plt.show()

```

こんなWindowが表示されるはず
![Figure_q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641105/61da32d2-8786-a082-130d-4e1ef443bfe3.png)
これをグレースケールの画像として保存

#WebカメラからARマーカーを探す
opencv様のチュートリアルでwebカメラの扱いが書いてあるのでそれを改造

```main.py
import cv2
import numpy as np
import matplotlib.pyplot as plt

cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FPS,15)
aruco = cv2.aruco
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
while(True):
    ret, frame = cap.read()

    corners, ids, rejectedImgPoints = aruco.detectMarkers(frame, dictionary)
    #ここで映像からマーカーを検出

    aruco.drawDetectedMarkers(frame, corners, ids, (0,255,0))
　　#マーカーを描画

    cv2.imshow('frame',frame)
    print(cap.get(cv2.CAP_PROP_FPS))

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
```

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">15行でこれが動くOPPYTHONすごすぎ <a href="https://t.co/Naf3ZxYiGF">pic.twitter.com/Naf3ZxYiGF</a></p>&mdash; tayutayu (@tayutayufk) <a href="https://twitter.com/tayutayufk/status/1263004309089730560?ref_src=twsrc%5Etfw">May 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな感じで相当精度よく動いてくれます

#最後に
pythonってやりたいことがすぐできていいけど
つまらん
CUDAでゴリゴリしたいんじゃ....
CLIで解凍がちょっと楽になるツールをつくった(Python3)

![uncompressor2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261602/8f087a4c-caba-4908-5cdd-e0086f907605.png)
# uncompressorってなに
Python製のCLIファイル解凍ツールです。
# 動機
僕はGUIよりCUIを好んで使います。

慣れればGUIより作業が捗るという理由からなのですが、いまいちGUIよりスマートじゃないなって思うところもあります。

そしてこれは、CUIでファイルの解凍を行ったことがある人なら誰しもが一度は感じたことがあるんじゃないかと思うのですが、

<font color="DarkOrange">圧縮/解凍系コマンドって覚えられなくない？</font>

`.zip`形式のファイルの解凍は`unzip`ですが、`.tar`だと`tar -xvf`になるのどうして？？ってはじめのうちは思いましたよね。

tarはtarでも`gzip`,`bzip2`等、圧縮方法が変わればオプションも変わるので辛い。よく使うコマンドなら多少複雑でもオプションは覚えるけど、解凍ってそんなに頻繁にするもんじゃないし、、、

こんな悩みを解決するために作ったのがこの<font color="red">__uncompressor__</font>です。

# デモ
![82409543-fd1de700-9aa8-11ea-8459-aa2f2ad50901.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261602/e7882eda-bc02-6502-6a08-7e47b00fe96e.gif)

# 使い方
使い方は至ってシンプルです。

```bash
uncmprs {解凍したいファイル} [-d|--dist 解凍先のディレクトリ]
```

# インストール
`pip install uncompressor`でインストールできます。

# さいごに
バグ等の報告いただけると助かります。
[githubはこちら](https://github.com/dhaiibfiukkiu/uncompressor)
ZabbixによるKubernetes監視の検討

# はじめに
　[VMware Tanzu](https://tanzu.vmware.com/tanzu)が発表され、世界的な潮流はOSからアプリケーションに変動しつつあります。
　日本においても、vSphere7.0が安定稼働されることが確認されれば、
　VMware Tanzuを導入・使用し、Kubernetesを利用した開発がより活性化していくことが予想されます。

　そうなった場合に、運用・保守・監視の仕組みは激変することが予想されます。
　静的なOS・NWではなく、動的なアプリケーションの監視の重要性が高くなっていく……。
　定常手順書を利用した監視運用の一部は通用しなくなり、運用が非常に高度化することが予想されます。
　※AWSのオートスケールやDockerの登場以降、避けられない流れでしたが。

　ここではそんな時代に対応すべく、監視の仕組みを**Zabbix**を通して考えていきます。

# Zabbixの役割
　Zabbixは様々な企業や現場においてOSやNWの監視を担ってきました。
　その実績は本物ですが、パブリッククラウド環境の監視では大きく出遅れており、
　CloudWatchやAzure Monitorにそのお株を取られつつあります。

　しかし、Zabbixはレガシーになった訳ではありません。
　依然としてOS監視ではカスタマイズ性が高く、取得できる情報も多いので、監視システムとしての優位を保っています。
　
　私はKubernetesを監視してやることで、動的なアプリケーションの監視でも
　Zabbixは十分な能力を発揮することができると考えます。
　VMware Tanzuは、パブリッククラウドが独走していたサーバーレスの開発領域を
　オンプレのvSphere環境でも実現させ、促進させると予想できます。
　オンプレ環境で稼働している監視システムはZabbixのシェアが高いですし、
　この時に必要とされる監視システムとして名前があがるのはZabbixだと思います。Zabbixにとってもチャンスです。

# Kubernetesとは
![components-of-kubernetes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640068/f4c7a18e-9bf9-2900-c263-1a201827ef85.png)
https://kubernetes.io/ja/docs/concepts/overview/components/

　実際に利用したことがないので不正確な部分もあるかと思いますが、
　Kubernetesは「マスターノード」と「ワーカーノード」によって構成されています。
　マスターノードは、ワーカーノードの集合である「クラスタ」を管理します。
　各ワーカーノードではDockerが稼働しており、アプリケーションが格納されています。
　そして、Podという単位になってコンテナが稼働され、クラスタ内で管理・実行されます。

　Kubernetesの「マスターノード」の監視することで、開発環境の監視が実現できそうです。

# Kubernetes監視の検討
## １．監視方式
　Kubernetesの「マスターノード」にZabbixエージェントをインストールすることを前提にしています。

　現在想定しているのは、system.runを使用して、kubectlコマンドの実行による監視です。

## ２．監視対象
①マスターノード
②ワーカーノード
③Pod
④アプリケーション

　Kubernetesでは、上記4点が監視対象とされると十分でしょう。

## ３．実行コマンド
①マスターノード
　通常のエージェント監視を設定。

②ワーカーノード
　下記のようなコマンドから取得できる情報を監視想定。
kubectl get node -o wide
kubectl describe node 【node-name】
kubectl top node

③Pod
　下記のようなコマンドから取得できる情報を監視想定。
kubectl get pod -o wide
kubectl describe pod 【pod-name】
kubectl logs 【pod-name】 -c 【init-container-2】
kubectl top pod
kubectl get events

④アプリケーション
　下記のようなコマンドから取得できる情報を監視想定。
kubectl get service -o wide
kubectl describe service 【service-name】
kubectl logs 【your-pod-name】

※可能そうであれば、LLD監視化を検討。

# おわりに
　現在はまだまだ検討段階です。実際にTanzu Kubernetesを触れる機会が来たら、検証しようと思います。

・参考
Kubernetesで監視を行う際の注意点
https://qiita.com/FY0323/items/82eeca93d00cbb4682e7

k8sの運用ってどうなの？
https://qiita.com/boono/items/0d8703cdff5a9513e679
IQ Botインストール手順（２）DBのインストールと設定　①SQL Serverのインストール

この記事は、以下の記事のサブカテゴリです。

[IQ Bot インストール手順](https://qiita.com/IQ_Bocchi/items/529dc72b6ab3d26dbfe0)　＞　[（２）DBのインストールと設定](https://qiita.com/items/7f02939799347b4db501/)

#①SQL Serverのインストール

この記事では、IQ Botを動かすために必要なSQLサーバーのインストール手順を解説します。

###1. インストーラーのダウンロード

SQL Server（Express）のインストーラーは以下のリンクからダウンロードできます。
[【外部リンク】Microsoft SQL Serverダウンロードページ](https://www.microsoft.com/ja-jp/download/details.aspx?id=42299)

<details><summary>リンク先のどれをダウンロードしていいかわからない方はこちらを参照</summary><div>
<br>
※以下は2021年1月28日時点の画面イメージです。ページの見た目は変わっている可能性があります。
<br>

####①言語選択は日本語のまま「ダウンロード」をクリック
![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/110224e1-f28d-9207-5d84-bb1906387ead.jpeg)

####②64ビット版（アドバンス**じゃないほう**）を選択して「次へ」をクリック
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/79f79598-8e8a-8b9c-8e8f-a1c11505a06a.jpeg)

すると、ダウンロードが始まります。

ダウンロード先のフォルダに、インストーラー（SQLEXPR_x64.exe）が入っていればOKです。
※インストーラーのファイル名も、Microsoft社の修正により変わる可能性があります

</div></details>





###2. インストール

1) インストーラーを右クリックして「管理者として実行」を選択
2)「このアプリがデバイスに変更を加えることを許可しますか？」というメッセージが出たら「はい」を選択
3) インストール先のPathはデフォルトのまま「OK」をクリック　→　インストールが始まるのでしばらく待ちます。
![01_インストール先のPath.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/22fa5f4c-fbf8-76a2-5156-becac4cab171.jpeg)

###3. インストール後の設定

####1) インストールが完了すると、次のような画面が起動します。「新規の……」を選択して次へ進みます。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/5c353c52-d64d-3b29-f753-e3d914473353.jpeg)

####2) ライセンスに同意して次へ。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/81a2b461-166d-fb6f-96dd-c35fc391a073.jpeg)

####3) 更新プログラムの確認は、チェックしてもしなくてもIQ Bot的には問題ありません。任意でチェックをつけ、「次へ」。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/c1a4f044-f827-2044-9679-eafcecd49df2.jpeg)

####4) 機能の選択はデフォルト（すべてチェックあり）のまま次へ。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/3e770c1e-8dc1-a13f-42e5-2f4c35352a17.jpeg)

####5) インスタンスの構成画面では、インスタンス名とインスタンスIDをともに**「AACRSQLEXPRESS」**として「次へ」。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f7f8b5de-6e2a-211d-185b-c208cdff0039.jpeg)

####6) サーバーの構成画面では、SQL Server Browserの設定を「自動」に変更して「次へ」。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/56157e9d-524b-5441-5f84-8188350b5f3d.jpeg)

####7) データベースエンジンの構成画面では、認証モードを「混合モード」にし、管理者アカウントのパスワードを任意で設定します。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/004fa531-c503-ba46-0a18-3ce0d65d71ff.jpeg)

→　すると、インストールが始まるのでしばらく待ちます。

####8) 以下のような画面がれば、インストール完了です。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/720a2fa9-87fb-33e3-4200-ce043c9e0059.jpeg)

インストールが完了せず、ロールバックされてしまう場合は以下のリンクをご参照ください。
[【リンク】SQL Server のインストールがうまくいかない場合（インストールの最後にロールバックされてしまう）](https://qiita.com/IQ_Bocchi/items/4a989eeb3c3f388a45c7)

#次のステップ

次は[②SQL Serverの設定](https://qiita.com/items/d3001507b313a7849eeb)を行います。
java（クラス型をフィールドに用いる）

#has-aの関係

####Swordクラスを定義

```java
public class Sword {
  String name;
  int damage;
}
```

####Heroクラスを定義

```java
public class Hero {
  String name;
  int hp;
  Sword sword;                //剣の情報
  public void attack() {
    System.out.println(this.name + "攻撃した！");
    System.out.println("敵に５ポイントのダメージを与えた！");
  } 
}
```

int型、String型ではなく、`Sword型`をフィールドにクラス型の変数を宣言することもできる。
**has-aの関係**
Hero has-a Sword（勇者は剣を持っている）
toioメモ


# [マットの仕様、座標系](https://toio.github.io/toio-spec/docs/info_position_id)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/d047ffb1-02af-3857-1629-35cb2a6174b1.png)

土俵とチェック型で原点が異なる。

# cube classのメソッドなど
[Globals @toio/cube Cube ](https://toio.github.io/toio.js/classes/_toio_cube.cube.html)


# cube.on
```
    cube.on('id:position-id-missed', data => { })
    cube.on('sensor:slope', data => {})
    cube.on('id:position-id', data => {})
    cube.on('id:standard-id', data =>{})

```

# buutton

```
      btn_promise = cube.getButtonStatus()
      btn_promise.then((value) => {
        let t_val = value.pressed ? 1: 0
        //ws.send("B,"+ret)  // ボタン押したらＳＥＮＤ
        console.log('getButtonStatus ', t_val)
      }, (error) => {
        console.error("error:", error.message);
      });       
```

# LED
```
  cube.turnOnLight({ durationMs: 0, red: 255, green: 0, blue: 255 })
  cube.turnOffLight()
```

# システムON
```
  cube.playPresetSound('3');
```
【AWS SAA】EIP、パブリックIPアドレス、プライベートIPの違い

#EIPとプライベートIPの違いの疑問
[この1冊で合格! AWS認定ソリューションアーキテクト](https://www.amazon.co.jp/%E3%82%A2%E3%82%AF%E3%82%BB%E3%83%B3%E3%83%81%E3%83%A5%E3%82%A2%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4046042036/ref=pd_ybh_a_1?_encoding=UTF8&psc=1&refRID=03TP29W5XR4EJP305VHR)でAWS　SAAの勉強をしていた。その教材の15Pに「EC2インスタンスに付与できるIPアドレス」が表で書かれていた。

|IPの種類  |特徴  |
|---|---|---|
|EIP |・再起動してもIPアドレスが維持される<br>・利用していない場合に課金される |
|パブリックIPアドレス  |・ランダムに割り当てられるためにIPアドレスを指定できない<br>・インスタンスを再起動すると別のIPアドレスが割り当て当てられる<br>・IPアドレスを自動で割り当てない子も可能  |
|プライベートIPアドレス |・インスタンス作成時に必ず割り当てられる<br>・インスタンス作成時にIPアドレスを指定できる<br>・再起動しても同じIPアドレスが割り当てられる  |

ここでEIPとプライベートIPアドレスは再起動しても同じIPアドレスを割り当てることができるとのことで、そうすると「EIPは利用していない場合に課金されるし、メリットがあるのか？」という疑問が生じる。

#結論
|IPの種類  |特徴  |
|---|---|---|
|EIP |再起動してもIPアドレスが維持されるパブリックIP|
|パブリックIPアドレス  |再起動するとIPアドレスが変わるパブリックIP |
|プライベートIPアドレス |再起動してもIPアドレスが変わらないプライベートIP|

つまりEIPはパブリックIPのため、プライベートIPとは用途が異なる。
EIPはパブリックIPのためIPアドレスの数値は任意の数値を指定できず、AWSが保有しているパブリックIPの中からランダムに付与される。
KARTEで特定の値をユーザー情報に送信する方法について

不動産SHOPナカジツでマーケティングを担当している浜田です。
KARTEを利用することで、非エンジニアでも簡単なjavascriptを学習することで今回の施策を実装できますのでぜひ挑戦してください。

今回はページ内にある特定の値をユーザー情報に送信する方法について解説します。
##ユーザー情報に送信したい値を決める
ユーザーが閲覧したカテゴリー情報をKARTEのユーザー情報に送信します。今回の場合、中古MS（中古マンション）の情報を送信します。

<img width="1353" alt="スクリーンショット 2020-05-20 14.42.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111504/ecb82fe5-db64-9739-5442-0154e4d7f1d6.png">
##KARTEでScriptの接客を作成

```js
//種別を判別
var syubetu = document.getElementsByClassName('icon_info')[0].getElementsByTagName('img')[0].getAttribute('alt');
var eventData = {
    物件種別: syubetu
};
eventData.json = JSON.stringify(eventData);
tracker.track('identify', eventData);
```

DOMを利用して値を取得していきます。
今回の場合、**getElementsByClassName**で取得する範囲を指定
**getElementsByTagName**で取得するタグを指定
**getAttribute('alt')**でaltタグの値を取得します。
取得した値は変数**syubetu**に代入

**eventData**の変数では、表示名とその値を指定
ここでは物件種別に取得した値を挿入

取得した情報をJSON形式で**identify**に送信して完了です。
ちなみにidentifyはユーザ情報になります。

最後に実際に値が送信されているか、来訪者のストーリー画面からユーザーデータを確認してみましょう。

<img width="794" alt="スクリーンショット 2020-05-20 15.45.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111504/a7141a4f-66a9-917d-6dc0-f0a9ed45c7c5.png">

データの受信を確認できたら完了です。
クリップボードのデータを可及的速やかにbase64エンコードするツールを作った

Windowsでは`Win + Shift + S`でスクリーンショットを撮影できますね。macでは`Command + Shift + 4`とかです。これらのショートカットキーにより、スクリーンショットを簡単にクリップボードに保存しておくことができます。

こちらをbase64として出力したい。しかしながら一旦ファイルとして保存するのも面倒くさい。

この手のツールは大体検索すれば出回ってると思ったんですがね。[ここ](https://www.base64-image.de/)とかファイルをアップロードすることには対応していてもクリップボードからのペーストには対応していません。そこで簡易的なツールを作成しました。同じことを考えたことがある方は是非使ってやってください。

https://chelproc.github.io/paste-to-base64/

雑に作ったのでソースは載せません。まあ秘匿してもいないですが。スタイリング？そんなものは知らぬ。

とはいえここはQiitaですので、はまりポイントだけ簡単に書いておきます。

# dropイベントで`e.preventDefault`してるのにページ遷移する
`dragover`イベントでも同じ操作が必要だったようです。これって常識？

```javascript
element.addEventListener('dragover', e => {
  e.preventDefault();
});
```

# 「クリックしてコピー」を実現するのに未だに`execCommand`を使わせようとする記事がたくさんヒットする

[MDN](https://developer.mozilla.org/ja/docs/Web/API/Document/execCommand)に「廃止されました」って書いてあるやん！勘弁してくだはれ。

今は[Async Clipboard API](https://developer.mozilla.org/ja/docs/Web/API/Clipboard)を使うのが普通です。騙されないようにしましょう。

ただ「Secure context」でのみ有効だそうです。まあ今時httpなサイトなんて存在しないので問題ないとは思いますが。

# あとは
バイナリデータをbase64に変換する手法は巷に記事があふれているのであえて言及しません。強いて挙げるならば`FileReader`クラスのAPIが未だにPromiseに対応していなくて使いづらいといった点でしょうか。早く改善してほしいですね。
bundle exec annotate を実行しても反応しない

##状況
annotateのGemをインストールして`bundle exec annotate`を実行しても何も表示されずエラーも帰ってこない。

実行後、modelsのファイルを開いてもスキーマの情報は追記されていない。

##解決方法
###1.annotateの設定ファイルを作成
```bash
rails g annotate:install
```

###2.設定ファイルを修正
Railsアプリケーションフォルダの
**lib/tasks/auto_annotate_models.rake**　を開く

```:auto_annotate_models.rake
      'show_indexes'              => 'true',
```
上の'true'部分を'false'に変更

```:auto_annotate_models.rake
　　　　'show_indexes'              => 'false',
```

###3.annotateを実行
```bash
bundle exec annotate
```
上記の方法でうまく行った場合はコマンド実行結果に以下が表示される

```
Annotated(数値):　"modelsのファイル名列挙"
```

その後、modelsのファイルを開くとスキーマの情報がファイル先頭に追記されている
SQL Server のインストールがうまくいかない場合（インストールの最後にロールバックされてしまう）

この記事は、以下の記事のサブカテゴリです。

[IQ Bot インストール手順](https://qiita.com/IQ_Bocchi/items/529dc72b6ab3d26dbfe0)　＞　[（２）DBのインストールと設定](https://qiita.com/items/7f02939799347b4db501/)

#SQL Server Expressがインストール時にロールバックされてしまう？！

IQ Botを動かすためには、事前に[DBのインストールと設定](https://qiita.com/items/7f02939799347b4db501/)をしておく必要があります。
筆者の環境ではSQL Serverを使っているのですが、Windowsのバージョンのロケールによっては、インストールがうまくいかずにロールバックされてしまう場合があるようです。

##確認＆対処方法

コントロールパネル ＞　時計、言語および地域　＞　地域　＞　システムロケールの変更　を起動して、**「ベータ：ワールドワイド言語サポートでUnicode UTF-8を使用」にチェックが入っていたら外します。**

![ロケールのβにチェック入ってるとうまくいかない_線つき.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/5519e3c4-9eda-301b-3afe-74f372d96f48.jpeg)

このチェックボックス自体が存在していないバージョンであれば大丈夫です。
[Python]変数(定義、出力、値変更)

#変数定義
**変数名　= 値**
""　は　''　でも可能。ただ、""　の方が半角全角の判断がしやすい。
2語以上は　_　で区切ると良い。

```python
name = "chikazu"
user_name = "chikazu"
```

#変数の出力
変数の場合は "" 又は ``　はつけない。

```python
print(name)
```

#変数値の変更
①price=100 を　200に上書き。
そのまま定義するだけ。

```python
price = 100
print(price)

price = 200
print(price)
```

②price=100 に数値を演算したものを変数に代入する。
例は + しているが他の四則演算でも可能。
今回は　100+200　で 300が出力される。

```python
price = 100
print(price)

price += 200
print(price)
```
[Ansible][EC2] ユーザーデータをAnsibleから実行するタスク



AWS EC2のユーザーデータをansibleで実行する方法です。もう1回流したいと思うことがあったので、タスクにしました。

```
- name: run USER_DATA of ec2 instance
  become: true
  shell: USER_DATA=$(set -o pipefail; curl http://169.254.169.254/latest/user-data ) && echo $USER_DATA && eval sudo $USER_DATA
  args:
    executable: /bin/bash
```
CentOS6 (PHP5.3.3)環境でmosquittoとmosquitto-phpを動かす

いまさらとは思うですが、必要になったので･･･。

CentOS6の標準のリポジトリにはmosquittoなどは入っていないので、別のリポジトリを使えるようにします。

```bash
sudo rpm --import http://wiki.psychotic.ninja/RPM-GPG-KEY-psychotic
sudo rpm -ivh http://packages.psychotic.ninja/6/base/x86_64/RPMS/psychotic-release-1.0.0-1.el6.psychotic.noarch.rpm
```

mosquittoと、mosquitto-develをインストールします。

```bash
sudo yum --enablerepo psychotic install mosquitto mosquitto-devel
```

次に、mosquitto-phpをインストールしますが、PHP5.3.3環境だとスムーズに行かないので、ソースからビルドします。（PHPのバージョンを上げようというツッコミはさておき）

```bash
wget https://github.com/mgdm/Mosquitto-PHP/archive/master.zip
mv master.zip Mosquitto-PHP.zip
unzip Mosquitto-PHP.zip 
cd Mosquitto-PHP-master/
```

PHP5.3.3環境ではソースを少しだけイジります。mosquitto.cとmosquitto_message.cの2つのファイルの先頭に、下記のコードを追記します。

```c
#ifndef PHP_FE_END
#define PHP_FE_END {NULL, NULL, NULL}
#endif PHP_FE_END
```

あとは下記のとおりビルドして、インストール。

```bash
sudo yum install php-devel
phpize
./configure --with-mosquitto=/usr/lib64/libmosquitto.so
make
sudo make install
```

これで、/usr/lib64/php/modules/にmosquitto.soがインストールされるので、/etc/php.iniの適当な場所に下記を追記します。

```ini
extension=mosquitto.so
```

最後に、Apacheを再起動しましょう。

## 参考
こちらの記事を参考にしました。
https://yoya.hatenadiary.jp/entry/20130501/php
HTMLのdata属性について

#カスタムデータ属性とは
- 要素をスタイリングすることに専念した属性

#カスタムデータ属性を使うメリット
- JavaScriptでアクセスしやすくなる。
- class属性の冗長化を防げる
- class属性はスタイル情報の指定要素として割り切った使い方ができるようになる。

#JavaScriptでデータ属性にアクセスする
JavaScriptでデータ属性にアクセスする方法は3つある


##データセットプロパティを用いる
datasetプロパティを使えば、簡単にデータ属性にアクセスできます。カスタムデータ属性ごとに1つのエントリーを持ったDOMStringMapオブジェクトを返します。

ただし、属性名を配列のキーとして扱うにはチェーンケースからキャメルケースにして使う必要がある。

```js
var owner = restaurant.dataset['ownerName'];
restaurant.dataset['ownerName'] = 'newOwner';
```



##getAtributeとsetAttributeを使う
取り出そうとした属性がない場合getAttributeメソッドはnullあるいは空文字列を返します。このメソッドを使った例は次のようになります。

```js
var restaurant = document.getElementById("restaurantId");
var ratings = restaurant.getAttribute("data-ratings");
```
既存の属性の値を変更したり、新しい属性を加えるにはsetAttributeメソッドが使えます。

```js
restaurant.setAttribute("data-owner-name", "someName");
```


##jQueryを使った方法

```javascript
var restaurant = $("#restaurantId");

var owner = restaurant.data("ownerName");
restaurant.data("ownerName", "newName");
```


#参考
[いまさら聞けない、HTML5カスタムデータ属性の基本と使いどころ – WPJ](https://www.webprofessional.jp/how-why-use-html5-custom-data-attributes/)
ラズベリーパイ同士でBluetooth通信

#1.環境
##ハードウェア
ラズベリーパイ3(親機)
ラズベリーパイ zero wh(子機)
##ソフトウェア
python3.5
#2.方法
##準備
```command:command
sudo nano /etc/systemd/system/dbus-org.bluez.service
```
"ExecStart=/usr/lib/bluetooth/bluetoothd"の後に"--compat"を追記
([こちら](https://qiita.com/oko1977/items/9f53f3b11a1b033219ea)を参考にさせていただきました。)
そして、再起動

```command:command
sudo reboot
```

シリアルポートサービスを追加

```
sudo sdptool add --channel=0 SP
```
(ここも、[こちら](https://qiita.com/oko1977/items/9f53f3b11a1b033219ea)を参考にさせていただきました。)
##ペアリング
親機、子機共通で

```command:command
bluetoothctl
```
親機のみで

```command:bluetoothctl
discoverable on
scan on
```
子機側のラズベリーパイが
"[new] {子機側のMACアドレス} raspberrypi"と認識するまでまつ。

認識したら、

```command:bluetoothctl
pair {子機側のMACアドレス}
```
これにてペアリング完了
##受信と送信
親機のラズベリーパイで

```shell_script:send.sh
#!/bin/bash

sudo echo 0 > /dev/rfcomm0
```
```command:command
sudo chmod 755 ./send.sh
```
```python:send.py
import subprocess

subprocess.run(["sudo","rfcomm","bind","0"])
subprocess.run(["./send"])
```
子機のラズベリーパイで

```python:recive.py
import subprocess
import serial
import time
import os

if not os.path.exists("/dev/rfcomm0")
    subprocess.Popen(["sudo","rfcomm","listen","/dev/rfcomm0","0"])
while not os.path.exists("/dev/rfcomm0")
    time.sleep(0.1)
time.sleep(1)
ser = serial.Serial("/dev/rfcomm0")
out = ser.read()
print(out)
```
#考察
どうやら、bluezの仕様としてbluetoothでのシリアル通信を使用するアプリケーションが動いている間しか通信を確立しないようです。
また、少なくとも私の環境では、送信側を"echo"コマンド、受信側をpythonの"serial"モジュールにしないといけないようです。
#課題
受信側のpythonプログラムを連続で実行できない。
(誰か教えてください!!!!!)

#最後に
ここまでお読みいただきありがとうございました。
間違っているところを指摘していただけるととても助かります。
よろしくお願いいたします。

また、参考にさせていただいたページは
https://qiita.com/oko1977/items/9f53f3b11a1b033219ea
です。