OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでSQLite3を使ってデータベースにリストを入れる

# ※この記事は2020年に作成しました

# やりたかったこと
麻雀の手牌（34種類）のリストをDBに入れて、CSVをかませずに直接PythonでDBから読み込む。
SQLite3ではリストを入れることはできないのが大変なポイント。

#作成したコード
```python
# coding: UTF-8
import sqlite3

#sqliteにはリスト型が存在しないため、str型にして格納する\
def tehai_to_string(tmp):
    tmp =  [int(s) for s in tmp]
    string = '' 
    for c in range(34):
        string+=str(tmp[c])
    return string

listDB =[0,0,0,2,0,0,0,3,0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0]
listDB=tehai_to_string(listDB)
#print(Stehai)
conn = sqlite3.connect('test.sqlite3')
c = conn.cursor()
c.executescript("""
DROP TABLE IF EXISTS test;
CREATE TABLE test(tehai text)
""")
c.execute("insert into test values (?)", (Stehai,))
c.execute('select * from test')
data = c.fetchall()
print(data)


conn.commit()
conn.close()
```
##実行結果
```
[('0002000300000011100111011000000000',), ('0002000300000011100111011000000000',)]
```
#文字列に変換する
sqliteにはリスト型が存在しないので、リストを文字列に変換してから、文字列としてデータベースに入れている。
DBにはタプルで入れる。

#読み込み
```python
# coding: UTF-8
import sqlite3

conn = sqlite3.connect('test.sqlite3')
c = conn.cursor()
for row in c.execute('select * from test'):
    t = list(row)
    tehai =[]
    for i in t:
        tehai += i
    tehai =  [int(s) for s in tehai]
    print(tehai)
```
##実行結果
```
[0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
```
#文字列から数値へ変換して取り出す
DBから取り出したデータはタプルなので、リストに変換してから、strの数字をintの数値に変換している。
Python3 でFelicaのIDmを読み取って記録する



## 概要

sony RC-S380を購入したので遊んでみました。

## 環境
- MAC
- Python3
- RC-S380

## 参考　

この記事のsimple sampleを使わせていただきます。

[Raspberry PiでFelicaのIDmを表示する](https://qiita.com/ihgs/items/34eefd8d01c570e92984)



## Ctrl-cで終了できるようにする

ループ内に以下の記述をしました。

```python
import signal
signal.signal(signal.SIGINT,signal.SIG_DFL)
```



## 外部のファイルからリストを読み書きする

この記事を参考にしてIDmのリストを外部ファイルに保存するようにしました。

[pythonでlistをファイルに保存し、読み込む方法(numpyも同様！](https://www.robotech-note.com/entry/2016/10/01/180840)



## 仕様

- 新しいカードをタッチしたらidm_list.txtに書き込む
- すでにタッチしたことのあるカードなら"すでに登録されています"
- 登録したカードの数がMAX_ID_NUMに達したら"リストがいっぱいです"



## 書いたコード

```python
import binascii
import nfc
import signal

class MyCardReader(object):

    def on_connect(self, tag):
        print ("読み取り中")
        self.idm = binascii.hexlify(tag.idm)
        return True

    def read_idm(self):
        clf = nfc.ContactlessFrontend('usb')
        try:
            clf.connect(rdwr = {'on-connect': self.on_connect})
        finally:
            clf.close()


class ListManagement:
    MAX_ID_NUM = 2
    def write_list(self,list):
        f = open('idm_list.txt', 'w')
        for x in list:
            f.write(str(x) + "\n")
        f.close()

    def read_list(self,list):
        f = open('idm_list.txt', 'r')
        for x in f:
            list.append(x.rstrip("\n"))
        f.close()

    def edit_list(self,list,new_idm):
        if new_idm in list:
            print ("すでに登録されています")
        elif len(list) >= self.MAX_ID_NUM:
            print ("リストがいっぱいです")
        else:
            print(str(new_idm) + "を追加します")
            list.append(new_idm)
            self.write_list(list)


if __name__ == '__main__':
    cr = MyCardReader()
    lm = ListManagement()
    idm_list = []
    lm.read_list(idm_list)

    while True:
        print ("カードをタッチしてください")
        cr.read_idm()
        print ("カードのID: ",end='')
        new_idm = cr.idm
        print (new_idm)
        lm.edit_list(idm_list,new_idm)
        # Ctrl-Cで終了するまで待機し続ける
        signal.signal(signal.SIGINT,signal.SIG_DFL)
```



## 実行結果

カードのIDは適当に変えて書いています。

```
カードをタッチしてください
読み取り中
カードのID: b'01010910231b3e0f'
b'01010910231b3e0f'を追加します
カードをタッチしてください
読み取り中
カードのID: b'012e4529359755b7'
b'012e4529359755b7'を追加します
カードをタッチしてください
読み取り中
カードのID: b'012e3d198b4d6f8a'
listがいっぱいです
カードをタッチしてください
```



## これから　
一定時間が経過して同じカードをタッチしたら削除するようにしたい
【Ruby】配列の要素を追加・削除

#【１章】はじめに
今回はRubyの配列におけるメソッドの中でも、要素を追加・削除するメソッドについてまとめました！
どれもよく使うメソッドなのでぜひ参考にしてください:woman::sunny:
では早速はじめます！

#【2章】配列に要素を追加する
###末尾に追加(<<)
```array.rb
num = [1, 2, 3, 4]
num << 5
puts num
# 出力結果 ==> [1, 2, 3, 4, 5]
```
###末尾に追加(push)
```array.rb
num = [1, 2, 3, 4]
num.push(5)
puts num
# 出力結果 ==> [1, 2, 3, 4, 5]

num.push(6, 7)
puts num
# 出力結果 ==> [1, 2, 3, 4, 5, 6, 7]
```
こちらは上記のように複数一気に追加できます！

###要素と要素の間に追加(insert)
```array.rb
num = [1, 2, 3, 4]
num.insert(2,100)
#insert(何番目の要素に入れるか指定, 入れる要素)
#要素の番号は0から始まるので、今回は2を指定しているということは実際は３番目に100を追加するという意味
puts num
# 出力結果 ==> [1, 2, 100, 3, 4]


```
###【３章】配列の要素を削除する
### 要素の番号を指定して削除(delete_at)
```array.rb
num = [1, 2, 100, 3, 4]
num.delete_at(2)
#要素の番号は0から始まるので、今回は2を指定しているということは実際は３番目を削除するという意味
puts num
# 出力結果 ==> [1, 2, 3, 4]
```

### 要素の範囲を指定して削除(slice!)
```array.rb
num = [1, 2, 3, 4, 5]
num.slice!(1, 3)
#slice!(最初に削除する要素の番号, ←で指定した番号から順番にいくつの要素を削除するか指定)
#今回は2番目の要素から３つ分削除
puts num
# 出力結果 ==> [1, 5]
```

### 要素名を指定して、該当する要素を全て削除(delete)
```array.rb
animals = ["cat", "dog", "rabbit", "dog"]
animals.delete("dog")
puts animals
# 出力結果 ==> ["cat", "rabbit"]
```

### 配列の先頭から指定した数だけ削除(shift)
```array.rb
num = [1, 2, 3, 4, 5]
num.shift(2)
#先頭から２つ分の要素を削除
puts num
# 出力結果 ==> [3, 4, 5]
```
# 【４章】さいごに

どうでしょうか？
配列の要素の追加や削除は自由自在に操れるようになっておいて損はありません！
ぜひ活用してみてください！
最後までご覧いただきありがとうございました:relaxed:
Laravel で アプリのオリジナルデフォルト環境を設定する

#はじめに
先日 [LARAVELの設定はどこを変更すべきなのか](https://qiita.com/navtujp/items/26c24b4452741ff052ac) を上げたばかりですが、調べてみるとオリジナル環境を構築するために皆さまあの手この手と工夫していて、やはり頭のいい人はひと味違うもんだと感心しきり。それらの先人の知恵を拝借の上、自分のやりたいことに近づける方法を模索した記録です。

#自分の環境とか
+ 開発環境はWSL上でnginxを常駐させてCドライブ上のLaravelアプリを読み込ませてる。
+ 実行環境は社内ローカルネットワーク上のサーバ。
+ DBは現在使用しているものを使用する。

#なにがしたいのか
+ DBの情報をデフォルト設定としてパッケージに含めたい
+ 開発を進める途中で必要なデフォルト設定を追加したい

#先人の方法とか
拙著にて「'/.env'をいじればいいんじゃね?」と書いたのはよいのですが、Laravel公式ドキュメントでは
「.envファイルは、アプリケーションのソースコントロールに含めるべきでありません。各ユーザー／サーバは異なった環境設定が必要だからです。さらに、侵入者がソースコントロールリポジトリへアクセスすることが起きれば、機密性の高い情報が漏れてしまうセキュリティリスクになります。」
などと書いてあり、まあ勉強不足ながらも、いや、勉強不足だからこそお作法には可能な限り従いたいと考えたわけです。それをふまえて
[takaday 様著 [Laravel 5.5] 読み込む.envファイルを環境ごとに切り替える](https://qiita.com/takaday/items/b992c7d8cd69343b6626)
や
[Laravel使用時に困った点と対処方法](https://developers.gnavi.co.jp/entry/laravel/matsuyan)
を拝見したところ、

+ '.env'を複数用意する('/.env','/.env.hoge','/.env.fuga' etc)

までは共通ですが、

1. 'artisan' コマンドに '--env=[環境名]' をつける( 'artisan [コマンド] --env="hoge"' とか)
2. '.htaccsess' に切替設定を書込む
3. '/bootstrap/app.php' に切替設定を書込む
4. 必要に応じて '/.env' を丸ごと書換える

という方法があるようです。

#結局
公式ドキュメント上には上記 1. の方法(とphpUnit)で切り替えること以外は、
[Laravel の .env の値は config() 経由で使う。](https://hiroto-k.hatenablog.com/entry/2018/03/28/213000)
の方法ををどうにかしてオリジナル環境設定を読み込むことができそうですが、基本は

+ '/.env' を起動時に読み込んで '/config/*.php'を経由して設定を読み込む
+ 作成した環境キャッシュから読み込む

のどちらかのようで、それ以外の方法はどこか公式ドキュメント外の方法をとる必要があるようです。
Chromeで特定のURLを開くと落ちる(Winトレンドマイクロ有環境) - 特定方法

Windows10のChromeで特定のURLを開くと、その瞬間にChromeが落ちます。
(Windows10 build1903 にアップデートしてもダメでした。)
恐らく、トレンドマイクロのせい。
問題解決には至っていませんが、その詳細を記します。

###再現方法
例えば、onamae.com とURL欄に入力してエンターキーを押すと、瞬間に落ちます。
(弊社の場合)

###試したこと（効果が無かったもの）
- PCを再起動
- 拡張機能を全部無効
- Chromeを再インストール
- 社内の別の人のPCで開く
- Chromeデバッグログを取りながら動作確認（ログが残る前に落ちる）
- デバッグウィンドウ(F12)でhtmlのダウンロードスピードを落とす
- hostsを書き換えて、HTMLデータすら取得できないようにしてしまう。

###問題なかったこと
- `onamae.com/index.html` を開く (index.htmlまで書く)
- `view-source:http://onamae.com`を開く(ソースを表示させる)
- IEを使う。（そもそも、Chromeではないですからね）
- トレンドマイクロが入っていないPCで見る

###考察
以上より、落ちる現象はHTMLの中身ではなく、URLであると推測されます。

ところで、セキュリティソフト側の「ホワイトリスト」に該当URLを書くと現象が一時的に改善します。（ずっと大丈夫ではない模様）
【php】serialize() VS var_export() VS json_encode() VS http_build_query()

# 【php】serialize() VS var_export() VS json_encode() VS http_build_query()

結論：json_encodeが早い。

php7環境で下記コードを実行

```php
<?php
$a = array_fill(0, 1000, array_fill(0, 1000, 1));
$max = 1000;

echo "serialize " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = serialize($a);
}
echo microtime() . "\n\n";

echo "var_export " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = var_export($a, true);
}
echo microtime() . "\n\n";

echo "json_encode " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = json_encode($a);
}
echo microtime() . "\n\n";

echo "http_build_query " . microtime() . "\n";
for ($i=0; $i<$max; $i++) {
    if (!($i % 100)) echo $i . "\n";
    $b = http_build_query($a);
}
echo microtime() . "\n\n";

```

実行結果

```
serialize 0.13482000 1561615171
0
100
200
300
400
500
600
700
800
900
0.38630600 1561615221

var_export 0.38633600 1561615221
0
100
200
300
400
500
600
700
800
900
0.19411200 1561615319

json_encode 0.19412900 1561615319
0
100
200
300
400
500
600
700
800
900
0.97560400 1561615333

http_build_query 0.97562600 1561615333
0
100
200
300
400
500
600
700
800
900
0.72081200 1561615394
```

* serialize 約50秒
* var_export 約98秒
* json_encode 約24秒
* http_build_query 約61秒

**結論：json_encodeが早い。**
typescriptのType predicatesを使って、配列からundefinedを取り除く式を型安全に書く

## 背景

配列の中にundefinedが紛れていて、それを取り除いた配列を作りたい場合、例えばrubyだと

```irb
# ruby
2.5.5 (main)> ["foge", nil, "huga", "foga", nil, "fuge"].compact 
=> ["foge", "huga", "foga", "fuge"]
```

こんな感じでパッとかけますが、jsだと多少面倒。

```javascript
// javascript
["foge", undefined, "huga", "foga", undefined, "fuge"].filter(e => e)
 => ["foge", "huga", "foga", "fuge"]
```

これをtypescriptで書くと悲しいことに、

```typescript
// typescript
const newArray = ["foge", undefined, "huga", "foga", undefined, "fuge"].filter(e => e);
```

この `newArray` の型が、 `(string | undefined)[]` となってしまう。これをどうにかして `string[]` にしたいよね、という話。

## 解決策: Type predicates を使う

[公式ドキュメント](https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates)

例はこんな感じ。

```typescript
function isHoge(s): s is Hoge {
  return typeof s === 'hogehoge';
}
```

この例では訳わからないことをしていますが、あくまで例として。

`type predicates` は `s is Hoge` 部分です。
なにをやっているかを一言で言うと、 **この関数がtrueを返す場合、パラメータsの型をHogeとする** ということです。

これを使って色々なものが書きやすくなりますが、今回はあくまで上記の `filter` の例にかぎって紹介します。

## 完成形

```typescript
const newArray = ['foge', undefined, 'huga', 'foga', undefined, 'fuge'].filter((e): e is string => Boolean(e));
```
つまり、 `Boolean(e)` がtrueを返す場合(この場合だと `undefined` 以外)、`e`を`string`とする、と宣言しているわけです。

これで、 `newArray` の型が、 `string[]` となります。


## PS

typescript強者の方、これよりも良い方法があればご教示ください...
Python3 (Jupyter Notebook) で Google BigQuery を操作し parquet 形式で保存

## 概要
データ分析を行う上で Python3 で Google BigQuery を操作することが多いです．
操作には下記の 2 つの手法が存在します．

- Python の BigQuery 連携ライブラリを使う
- Google Cloud Datalab を使う

今回は, Python の BigQuery 連携ライブラリを使う手法の内 pandas.io.gbq を使う手法について説明します．

## 今回の目標
BigQuery などのオンプレミス環境においてクエリを叩く回数を減らし, コストを削減することおよび, ローカル環境を圧迫しないようなデータの保持を行うことを目標にします. そのため Apache Parquet 形式で取ってきたデータを保存することにしました.

## Apache Parquet 形式とは
csvなどの行志向のデータフォーマットと違い、列志向のフォーマットで、列単位でデータを取り出す分析用途に向いています。[この記事](https://blog.amedama.jp/entry/2017/10/10/135331)で他の形式との比較をしています． 特に大規模データファイルを圧縮する際に効率が良くなるのでビッグデータの分析データの保存に用いられます．

## pandas.io.gbq ことはじめ
自分ははじめに[この記事](https://qiita.com/hik0107/items/3944ccea04371331c3b4)を参考にして, pandas.io.gbq を使おうとしていました.

```python

import pandas as pd
query = 'SELECT * FROM tablename'
data_frame = pd.read_gbq(query, 'project名')
```

すると, 下記のエラーが発生してしまいます.

```
GenericGBQException: Reason: 400 Invalid table name: `project.dataset.table`
[Try using standard SQL (https://cloud.google.com/bigquery/docs/reference/standard-sql/enabling-standard-sql)].
```

おそらく 2016 年の記事なので, 2019 年の仕様と異なってしまうことがエラーの原因であると考えられます.
さらにエラー文を読んでみると StandardSQL に設定できていないことが考えられるわけです.

## Standard SQLとLegacy SQL
BigQueryで古くに使われていたのがLegacy SQLで現在使われているのがStandard SQLである. そのため, BigQueryに対して, どちらを使うかを指定してあげる必要がある.

## 操作手法
以下の方法で Python から Google BigQuery を操作します.この方式を利用することにより, オンプレミス環境においてクエリを叩く回数を減らしコストを削減可能で, Parquetファイルとgzipを利用し圧縮効率をあげローカルに落とすデータの容量を削減することが可能です．

- ローカルに .parquet ファイル(データを保存したファイル)がないとき
    1. ローカル .sql ファイルを読み込む
    2. 読み込んだクエリで, BigQuery を叩く
    3. データフレームに格納する
    4. 列志向形式 (Apache Parquet) に圧縮して, .parquet 形式でローカルに保存する
- ローカルに .parquet ファイルがあるとき
    1. ローカルの .parquet ファイルを読み込む
    2. データフレームに格納する

## コード説明
自分は下記のようなコードを書いて, 上の条件を満たすようにしました.

```python:test.pynb
import os 
from google.cloud import bigquery
import pandas as pd
import pyarrow as pa
import pyarrow.parquet as pq

#parquetを入手，ある場合は取得しない
filePath = "../input/test.parquet"
sqlPath = "../script/test.sql"
if(not os.path.isfile(filePath)): #1
    with open(sqlPath, 'r') as fd: 
        query = fd.read() #2
    df = pd.read_gbq(query, 'project名', dialect='standard') #3
    table = pa.Table.from_pandas(df) #4
    pq.write_table(table, filePath, compression='gzip') #5
else:
    table = pq.read_table(filePath) #6
    df = table.to_pandas() #7
```

軽く説明すると, 

- #1 では os ライブラリを用いて指定したパスにデータファイルがあるかないかを確認し, なかったら if 文内の処理に移行します
- #2 では #1 で指定されたパスの .sql ファイルから, クエリを変数 query に代入します．
- #3 では #2 で取得したクエリを BigQuery 上で実行します. またここでstandard-sqlにて記述されているクエリであることを指定してあげます.
- #4 では #3 で実行したクエリの結果をデータフレーム型に代入します．
- #5 では #4 で作ったデータフレームを parquet ファイルで gzip 形式に圧縮し保存します．
- #6 では指定されたパスにデータファイルがあったとき, table にロードします
- #7 では #6 でロードした table をデータフレーム型に変更します

## 実行結果
これを実行すると Jupyter Notebook 上で, 下記のような画面が出力されます.

![Authorization.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287300/135fdd29-d287-5ef1-ed0e-78de3809535c.png)

リンクを踏み, 認証を行うことで, 認証コードが発行されます. そのコードを Jupyter Notebook 上のフォームに入力することで, Python3 の PandasGBQ で BigQuery を操作することができるようになります.


## まとめ
以上より, Python を用いてGoogle BigQuery を操作することができます．また上記のようなコードを書くことで, コストを削減し, 圧縮効率をあげ, 効率よくデータを取ってくることが可能です.
Azure Databricks: 2. Databricksの基本事項

# Databricks File System (DBFS)
Azure DatabricksのClusterには、Databricks File System (DBFS)という分散ファイルシステムがインストールされています。DBFSのファイルはAzure Blob Storageに永続化されるため、Clusterが終了してもデータが保持されるようになっています。
NotebookからDBFSにアクセスする場合には、Databricks Utilities(dbutils)、Spark API、open関数等のFileIOを使用しますが、OSとDBFSでルートディレクトリの扱いが異なるため、ファイルにアクセスする上で注意が必要になります。
## Databricks Utilities(dbutils)
dbutilsでは、DBFSのルートディレクトリを基準にパスを参照します。
dbutilsで「/mnt/my_blob_container」を指定した場合は「dbfs:/mnt/my_blob_container」を参照することになります。
dbutilsでClusterのローカルストレージを参照する場合は「**file:**/home/ubuntu」のように、OSのローカルパスに「file:」を追加したものを使用します。
## Spark API
Spark APIでファイルを読み込む場合、DBFSのルートディレクトリを基準にパスを参照します。
ただし、dbutilsとは異なり「file:/home/ubuntu」のような形でClusterのローカルストレージを参照することはできません。
そのため、Sparkでファイルの読み込みを行う場合はファイルをDBFS上に配置する必要があります。
## FileIO (上記2つ以外のファイル操作)
Pythonのopen関数等のFileIOで読み込みを行う場合、OSのルートディレクトリを基準にパスを参照します。
DBFSルートディレクトリはOS「/dbfs」にマウントされているため、DBFSの「/mnt/my_blob_container」にアクセスする場合は、「**/dbfs**/mnt/my_blob_container」のように「/dbfs」を追加したパスを使用します。

# マジックコマンド
Databricksでは、セルにマジックコマンドを指定することで、各種スクリプトの実行ができます。
マジックコマンドは1セルにつき1つだけ指定できます。
## Markdown形式でのコメント挿入: **%md**
セルにMarkdownを記載してコメントとして挿入します。

```
%md
## Blob Storageのマウント
| 項目 | 設定値 |  
| :-- | :-- |  
| ストレージアカウント | ●●●●●●●● |  
| Blobコンテナ | ●●●●●●●●●● |  
```
![img02-0201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/b9cfea03-760d-dfa8-5ba0-fd113d5bbbc3.png)

## Databricks File System(DBFS)のファイル操作: **%fs**
Databricksの分散ファイルシステムであるDBFSのリスト、コピーといったファイル操作をシェルコマンドライクに記述して実行します。
ディレクトリにあるファイルのリストを表示する場合は、下記コマンドを使用します。

```
%fs
ls /mnt/blob_container/
```
![img02-0202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/04f0fa07-785c-84ef-ad61-776e9231c363.png)

上記コマンドはPythonの下記スクリプト実行結果と同等となります。

```
display(dbutils.fs.ls("/mnt/my_blob_container/"))
```
![img02-0203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/664d60c3-430a-52c8-457d-73a89196c1ef.png)

## OS (Linux)のシェルコマンド実行: **%sh**
OSのシェルコマンドを実行する場合には「%sh」を使用します。
DBFSを%shで参照する場合は下記のとおりです。

```shell
%sh
ls /dbfs/mnt/my_blob_container/
```
![img02-0204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/d1fba49b-c7d4-c035-6f2c-cf614276814d.png)

## 各言語のスクリプト実行: **%python**, **%scala**, **%sql**, **%r**
Notebookで指定した言語以外の言語を使用する場合は、対応言語のマジックコマンドを使用します。

```scala
%scala
var x = 100
x
```
```r
%r
y <- 100
y
```
![img02-0205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/28b2e75a-5f31-73e4-f757-b76a6e34b2ec.png)
言語間で変数は共有されないため、マジックコマンドの変数に値を引き渡す場合は一旦DBFSにファイル出力をする等で渡す必要があります。
![img02-0206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/c9460ad0-3e65-8340-ac28-a61a28e2e24b.png)

## 他のNotebookの実行と読み込み: **%run** 
他のNotebookを実行する場合は「%run」で対象Notebookを指定して実行します。
%runで実行すると、同じ言語であれば他のNotebookで定義された変数をそのままの変数名で参照することができます。
メンテナンス性を高めるために、スキーマ定義を別Notebookで記述しておくといったような使い方ができます。

```
%run /Users/{ユーザー名}/{Notebook名}
```
![img02-0207.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/33083e68-5dc3-8112-13a1-9a98cffd43ef.png)

# 参考
- [Using Notebooks](https://docs.azuredatabricks.net/user-guide/notebooks/notebook-use.html)
GASでunpivotっぽいことをやる

# 以下の図のような変更をしたい
## Before

![before.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104689/1abc6901-9c3f-2ee5-919a-367549699f6a.png)

## Afte
![after.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104689/d6dd11bc-a198-e836-1318-206f585b138b.png)


```{js}
function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet(); 
    for(var i = 1; i <= 5000; i++) { //最大の行数+α　行がどんどん追加されていくため
    for(var j = 3; j>=2; j--){ //最大の列数 2は固定 1列目はそのまま入れるため
      a = sheet.getRange(i, j)
      if(!a.isBlank()){
       sheet.insertRowAfter(i);
       sheet.getRange(i+1, 1).setValue(a.getValue());
       a.clear() // 移動したら消す
       Logger.log(a.getValue());
      }
    }
  }
}
```
LaravelでLeague/Csvを使ってDBから取得したデータをcsvで吐き出す

# 前提
この記事の続編ですので環境構築などはこの記事を参照してください。
[LaravelでLeague/Csvを使ってアップロードされたcsvを読み込みDBに保存する](https://qiita.com/engineerYodaka/items/ff40588033cd5c2d146d)

# やりたいこと
Eloquentで取得したデータをcsvに吐き出し、webからダウンロードできるようにしたい。

# 実装

```ClientController.php 
public function export()
{
    $csv = \League\Csv\Writer::createFromFileObject(new \SplTempFileObject());

    // csvのヘッダーを配列で渡す
    $csv->insertOne(['id', '名前', '企業', 'メールアドレス']);

    Client::all()->each(function($client) use($csv) {
        $csv->insertOne($client->toArray());
    });

    return new Response($csv->getContent(), 200, [
        'Content-Encoding' => 'none',
        'Content-Type' => 'text/csv; charset=UTF-8',
        'Content-Disposition' => 'attachment; filename="'.'ファイル名.csv'.'"',
        'Content-Description' => 'File Transfer',
    ]);
}
```

# 実際の使い方
僕が使った時はServiceクラス作って

```ClientController.php
public function exportCSV(ClientCsvExportService $service)
{
    return $service->setHeader(['id', '名前', '企業', 'メールアドレス'])
                ->setFileName(now().'ファイル名.csv')
                ->export();
}
```
的な感じで抽象化しました。
ClientCsvExportService内でLeague/csvを使ってます。

# 感想
めっちゃ楽だった。
[csvインポートでLeague/csv使った時](https://qiita.com/engineerYodaka/items/ff40588033cd5c2d146d)はShift_JIS対応のためのShift_JISとUTF-8での処理の分岐がめんどかったんです。
楽な書き方がエンコードするとできなくなるみたいなのがあって…
けど、今回はとても楽で良かったです。

# 参考文献
https://mattstauffer.com/blog/export-an-eloquent-collection-to-a-csv-with-league-csv/
https://csv.thephpleague.com/9.0/connections/output/
聴牌かノーテンかの3層ニューラルネットワーク

# ※この記事は2020年に作成しました
#　作成したプログラム
```python
# coding: UTF-8
import csv
import numpy as np
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense

tenpai_train = np.loadtxt("C:/Users/p-user/Desktop/tenpai_xtrain.csv",delimiter=",")
x_test = np.loadtxt("C:/Users/p-user/Desktop/tehai_xtest.csv",delimiter=",")
y_test = np.loadtxt("C:/Users/p-user/Desktop/tehai_ytest.csv",delimiter=",")

'''#データの形確認
print('x_train.shape:',x_train.shape)
print('y_train.shape:',y_train.shape)
print('x_test.shape:',x_test.shape)
print('y_test.shape:',y_test.shape)
'''
x_train=np.zeros((9947,35))
y_train=np.zeros(9947)
for i in range(9947):
    if tenpai_train[i,34]==1:
        x_train[i,]=tenpai_train[i,]
        y_train[i]=1
    else:
        x_train[i,]=tenpai_train[i,]
        y_train[i]=0

x_train=np.delete(x_train,34,1)
#float型に変換し、0から1の間の値を取るようにスケール変換
x_train = x_train/4.
x_test = x_test/4.

#データをネットワークに対応するように変形
y_train = to_categorical(y_train,2)
y_test = to_categorical(y_test,2)

model = Sequential()

#中間層102、入力層34、活性化関数ReLU関数
model.add(Dense(units=102,input_shape=(34,),activation='relu'))
#出力層2、活性化関数ソフトマックス関数
model.add(Dense(units=2,activation='softmax'))

#最適化アルゴリズムAdam、損失関数クロスエントロピー
model.compile(
    optimizer='adam',
    loss='categorical_crossentropy',
    metrics=['accuracy'],
)

history_adam=model.fit(
    x_train,
    y_train,
    batch_size=32,
    epochs=20,
    verbose=1,
)
score = model.evaluate(x_test, y_test)
print('損失関数の値：',score[0])
print('精度：',score[1])
```
#ニューラルネットワークの図
<img width="651" alt="vdssd.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436155/d7951829-aed4-c6f2-c856-1aed700fa1d7.png">

#csvの中身
<img width="706" alt="kdsfjds.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436155/39e2e6d0-2c3d-00ef-5aa2-aed6998213de.png">

#結果
1日の全ての対局の手牌データ22万629を学習データ、別の日の対局の手牌データ5万個をテストデータとして使った。入力は34次元で中間層は102次元とし、出力を聴牌かそうでないかの2つで学習させた。中間層の活性化関数にはReLU、出力の活性化関数にはソフトマックス、最適化アルゴリズムにはAdam、損失関数にはクロスエントロピーを使用した。

結果は、テストデータの正解率は97％ほどになった。この原因として、過学習をしているのかもしれない。また、学習データの手牌データ22万629のうち聴牌のパターンは4947個、テストデータの手牌データ5万個のうち聴牌のパターンは1085個。全体の2％ほどしか聴牌のパターンがないから、仮に全部を聴牌じゃないと判定しても正解率は98％ほどになる。

学習データを1日の対局の聴牌数4947個＋ノーテンの手牌5000個の9947個で同じように学習すると、テストデータの正解率は35％ほどになった。
Tableauコマンドでのパブリッシュとデータソース更新のバッチ処理

大量のTableauワークブックをパブリッシュする必要があったのと手動でパブリッシュした際にいろいろと問題があったため、Tableauコマンドを使ってのパブリッシュとデータソースの更新方法をまとめました。
データソースの接続方法はDBからの抽出を前提としております。

【手動でパブリッシュを実施したときの問題点】
・時間がかかる（ワークブックが多かったり、何回もパブリッシュしないといけないとなおさら）
・サイト切り替えするのを忘れやすい
・DBがオフの状態だとパブリッシュ画面が閲覧できない現象が一定の確率で起こる（これは私の環境だけかも）

【パブリッシュコマンド形式】
tabcmd login -s [サイトURL] -t [サイト名] -u [TableauServerログインID] -p [TableauServerログインパスワード]
tabcmd publish [Tableauワークブックファイルパス] -o -r [プロジェクト名] --db-username [データソース元DBのログインID] --db-password [データソース元DBのログインパスワード] --save-db-password
tabcmd logout

【パブリッシュコマンド具体例】
tabcmd login -s http://localhost -t SiteID -u tableauadmin -p p@ssword
tabcmd publish C:\Tableau\workbook1.twbw -o -r ProjectName --db-username DBlogginID --db-password DBp@ssword --save-db-password
tabcmd publish C:\Tableau\workbook2.twbw -o -r ProjectName --db-username DBlogginID --db-password DBp@ssword --save-db-password
tabcmd logout

【データソース更新コマンド形式】
tabcmd login -s [サイトURL] -t [サイト名] -u [TableauServerログインID] -p [TableauServerログインパスワード]
tabcmd refreshextracts --project CLISTA!ベンチマーク --workbook メニュー
tabcmd logout

【データソース更新コマンド具体例】
tabcmd login -s http://localhost -t SiteID -u tableauadmin -p p@ssword
tabcmd refreshextracts --project ProjectName --workbook Workbook1
tabcmd refreshextracts --project ProjectName --workbook Workbook2
tabcmd logout
Goのモジュール管理(vgo)

久しぶりにメンテしようと思ってみたものの、モジュール管理方法を忘れてググるところから始めないといけない...。覚えているからドキュメントはいらないと思っていた事もありました。そんな過去の自分にイラっとしたついでに調べてみたらモジュール管理が便利になっていたのでメモしておきます。

# 0.はじめに（苦労）

えっと、Godepsってディレクトリーがあるな...ということはgodepってやつか。 `go get github.com/kr/godep` っと。`godep get`...あれ、goなんてPC入れ替えてからコンパイルしてないけど、どこにインストールされたかな?`go env`。あー、ここか。`/User/hoge/go/bin/dep get`っと。

```
godep: [WARNING]: godep should only be used inside a valid go package directory and
godep: [WARNING]: may not function correctly. You are probably outside of your $GOPATH.
godep: [WARNING]:	Current Directory: /Users/hoge/dev/***
godep: [WARNING]:	$GOPATH: 
godep: Unable to find SrcRoot for package .
```
プッチーン。

「めんどくさいから一つづつ`go get`すりゃいいんだろ！」

#1. Modules(vgo)を使ってみる

Go 1.11よりModules(vgo)という仕組みが標準装備になっているようです。

ということでやってみます。

```
go mod init
go: creating new go.mod: module hoge
go: copying requirements from Godeps/Godeps.json
```

なんと、秘伝のGodepsもちゃんと移行してくれたようです。

go.modとgo.sumというファイルが増えています。

使い方は?...そのまま実行するだけ？

```
go run hoge.go             
go: finding github.com/julienschmidt/httprouter v0.0.0-20160219154026-77366a47451a
go: downloading github.com/julienschmidt/httprouter v0.0.0-20160219154026-77366a47451a
go: extracting github.com/julienschmidt/httprouter v0.0.0-20160219154026-77366a47451a
```

これはなかなか便利です。`go get`でインストールするだけで、バージョン管理もきちんとされるようです。開発環境をdockerなどに展開していても、普通にbuildできるので非常に便利です。

#2.モジュールのアップデートをする

使っているhttprouterは2016年のファイルっぽいですね...。動いた後の放置されっぷりがよくわかります。アップデートは`go get -u`のようです。

```
go get -u
go: finding github.com/julienschmidt/httprouter v1.2.0
go: downloading github.com/julienschmidt/httprouter v1.2.0
go: extracting github.com/julienschmidt/httprouter v1.2.0
```

これで最新のものにアップデートすることができました。go.modファイルもきちんと書き変わっています。

# その他

しばらくGo使っていなかったので、久しぶりの進化にびっくりしました。

# 参考

詳細については他の

https://qiita.com/propella/items/e49bccc88f3cc2407745
https://www.wantedly.com/companies/wantedly/post_articles/132270
Azure Databricks: 1. リソースの作成

# はじめに
Azure Databricksのリソース作成から、DatabricksワークスペースでのCluster、Notebookの作成までを行います。

# Databricksワークスペースの作成
Azureポータルの「リソースの作成」をクリックし、検索に「Databricks」を入力します。
候補に「Azure Databricks」が出てくるので、クリックして作成を開始します。
![img01-0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/4f3989ed-a446-95e3-25d6-e5f17a24c6f4.png)
必要事項を入力して作成を実行します。
![img01-0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/1201e991-0c45-6256-19ff-45183ebcb2ba.png)
作成が完了するまでしばらく待機します。  
ポータル右上の「通知」で作成が完了したら、「リソースに移動」で作成したリソースのページを開きます。
![img01-0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/ba3cc717-24fb-95b1-5734-5d0e2e42c8d0.png)
リソースのページの「Launch Workspace」をクリックして、Databricksワークスペースにログインします。
![img01-0004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/f3f80d25-847b-3385-07e0-8d9e738d1f12.png)
![img01-0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/1497801b-b85a-a45f-5445-90f524877da0.png)

# Clusterの作成
Databricksワークスペースのサイドバーにある「Clusters」をクリックします。
![img01-0006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/35ffb4ec-5a87-abca-297d-60a7b1adfd35.png)
「+Create Cluster」をクリックしてClusterの作成を開始します。
![img01-0007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/1b2bd640-15b6-d257-feaf-5bf8521ff907.png)
必要事項を入力、設定していきます。
今回は、以下の設定値で作成します。

| 項目 | 内容 | 設定値 |  
| :-- | :-- | :-- |  
| Cluster Name | Clusterの名称 | 任意の名称 |  
| Databricks Runtime Version | Databricksランタイムバージョン ( [Release Note](https://docs.azuredatabricks.net/release-notes/cluster-images/index.html#releases) )| Runtime 5.3 |  
| Python Version | Pythonバージョン | 3 |  
| Enable autoscaling | オートスケール設定 | 有効 |  
| Terminate after ～ minutes of inactivity | 実行状態にないClusterを削除するまでの時間 | 30 |  
| Worker Type | Workerのインスタンスタイプ | Standerd_F4s |  
| Min Workers | オートスケールの最小Worker数 | 1 |  
| Max Workers | オートスケールの最大Worker数 | 4 |  
| Driver Type | Driverのインスタンスタイプ | Same as worker |  
![img01-0008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/9225a6ca-e07a-fd90-5531-d45ae3c78a93.png)
Clusterの「State」が「Running」になるまでしばらく待機します。
![img01-0009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/c709bf23-c33e-2558-ed6b-c46814aae7ba.png)

# Notebookの作成
サイドバーの「Workspace」をクリックし、「Users」=>「{アカウント名}」とディレクトリを移動して、ユーザーディレクトリを表示します。  
右上のドロップダウンリストから「Create」=>「Notebook」を選択します。
![img01-0010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/ad8f5222-322e-7e48-f49a-66e144cac69d.png)
「Name」に任意のNotebook名を入力し、「Language」に「Python」、「Cluster」に先ほど作成したClusterを設定して「Create」をクリックします。
![img01-0011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/d117b300-65ef-3bf1-199e-6d86da6aa30e.png)
以上でNotebookの作成は完了です。
![img01-0012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322093/20477f8e-ba17-d93f-cce4-18e38318c078.png)
yarn workspaceでtsconfig.jsonを共通化したモノレポを作りたい

本稿では、tsconfig.jsonの設定を各パッケージで共有したモノレポをyarn workspaceで実現するまでの手順をステップバイで説明する。


### モノレポの初期化


```
mkdir my-monorepo
cd my-monorepo
```

yarn initでpackage.jsonを生成する。

```bash
yarn init --yes --private
```

生成された内容は次のようになる。モノレポルートのpackageは`private`が`true`になっている必要がある。

```package.json
{
  "name": "my-monorepo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "private": true ←ここがtrueになっているのが大事
}
```

パッケージを置き場を作る。名前は自由だが慣例にならい、ここでは`packages`という名前のディレクトリを作る。

```bash
mkdir packages
```

yarnにパッケージ置き場を認識してもらうために、package.jsonに`workspaces`を追記する。

```package.json
{
  "name": "my-monorepo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "private": true,
  "workspaces": ["packages/*"] ←　これを加える
}
```

### 各パッケージの初期化

`./packages`ディレクトリにパッケージを作る。

```bash
mkdir packages/{foo,bar}
```

現状のディレクトリ構成は次のようになっている。

```tree
モノレポルート
├── package.json
└── packages
    ├── bar
    └── foo
```

各パッケージにてpackage.jsonを作成する。

```bash
cd packages/bar
yarn init --yes
cd ../foo
yarn init --yes
```

package.json作成後のディレクトリ構成:

```tree
モノレポルート
├── package.json
└── packages
    ├── bar
    │   └── package.json
    └── foo
        └── package.json
```


作成された`package.json`の中身

```packages/foo/package.json
{
  "name": "bar",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}
```

各パッケージに`typescript`モジュールをインストールする。

```bash
cd ${モノレポルートのディレクトリ}
yarn workspace foo add --dev typescript
yarn workspace bar add --dev typescript
```

ちなみに、`tsc`がインストールされたかは次のように確認できる。

```
yarn workspace foo tsc --version
```

ディレクトリ構成はだいたい次のようになる(関係のあるファイルだけ記載)。


```tree
モノレポルート
├── node_modules
│  ├── .bin/tsc ※1へのシンボリックリンク
│  └── typescript/bin/tsc ※1
├── package.json
├── packages
│  ├── bar
│  │  ├── node_modules/.bin/tsc ※1へのシンボリックリンク
│  │  └── package.json
│  └── foo
│     ├── node_modules/.bin/tsc ※1へのシンボリックリンク
│     └── package.json
└── yarn.lock
```

### tsconfig.jsonの共通化


モノレポルートにtsconfig.jsonを作る。

```bash
tsc --init
```

このファイルが共通設定を書く場所になる。

つづいて、各パッケージにもtsconfig.jsonを作る。


```bash
yarn workspace foo tsc --init
yarn workspace bar tsc --init
```

これまでの手順で3つのtsconfig.jsonが作成される。

```
モノレポルート
├── packages
│   ├── bar
│   │   └── tsconfig.json
│   └── foo
│       └── tsconfig.json
├── tsconfig.json
```


foo/tsconfig.jsonからモノレポルートのtsconfig.jsonを参照するようにする。


```packages/foo/tsconfig.json
{
  "extends": "../../tsconfig.json"
}
```

bar/tsconfig.jsonも同様に。


```packages/bar/tsconfig.json
{
  "extends": "../../tsconfig.json"
}
```

各パッケージにTypeScriptファイルを追加し、コンパイルしてみる。

```bash
echo 'export const foo = (x: any) => x' > packages/foo/index.ts
echo 'export const bar = (x: any) => x' > packages/bar/index.ts

yarn workspace foo tsc
yarn workspace bar tsc
```

コンパイルされ、JavaScriptファイルができる。

```packages/foo/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.foo = function (x) { return x; };
```

以上で、tsconfig.jsonの共通化は完了。

この手順で出来上がった成果物はGitHubにて公開している: https://github.com/suin/typescript-playground/tree/share-tsconfig-between-packages
AngularJSでcontrollerが2回呼ばれてしまう

メモ書き程度。

## 概要
考えられるのは以下の2パターンです。
 1.router側とview側の両方で記述している
 2.UI Routerのバグ [^1]

今回は後者についてです。
パラメータを受け取ってURLを`'/url/:hogehoge'`のように指定していると発生する場合があります。
パラメータを指定せずに画面遷移すると`$stateParams.hogehoge`にundefinedが入ります。
`$locationChangeSuccess`によって`$stateParams.hogehoge`に空文字が入った状態で再度呼ばれてしまいます。

最新バージョンでは修正されていますが、古いバージョンでは発生する場合があります。
その場合はバージョンを上げるか、回避策[^2]を使ってください。

[^1]: https://github.com/angular-ui/ui-router/issues/1476
[^2]: https://github.com/angular-ui/ui-router/issues/1476#issuecomment-71620437
【Python】10行未満のコードで作る「インターバル通知」

# はじめに
こんにちは。
今回は、Tkinterのmessageboxモジュールを使って、一定時間ごとに通知をしてくれるものを作っていきます。
**この記事では一時間ごとに通知がくるようにしています。**
これで時間間隔を意識しながら、作業を進めることができますね！:smile:

こんな感じに通知がきます！
<img width="154" alt="インターバル通知.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/6fdc09d3-d2bb-1468-dc11-87846b057eb5.png">


# 完成したプログラム

こちらが完成したプログラムになります。

```IntervalAlert.py
import tkinter as tk
import tkinter.messagebox as mb
import time

win = tk.Tk()
win.withdraw() #ウィンドウ非表示
while True:
	time.sleep(3600) #秒単位
	mb.showinfo("通知","1時間経ったよ！！")
```

実際に通知がくるかどうかを試してみるために、time.sleepに渡す引数を10にしてみてください。
10秒後に通知が来ましたか？

ここまで読んでいただき、ありがとうございました。
廃れゆくかも知れない Web Speech API でアシスタントアプリを再稼働したお話

# 音声アシスタント「HiBot」
https://webmidori.xsrv.jp/app-hibot/

![hibot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44077/ea787589-2778-d76e-6306-85094bb5d5cb.png)

![hibot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44077/360c5a1c-36f7-0daf-8326-048c3742a059.png)



## なんの話か
自作アプリの紹介です。

映画「アイアンマン」のラボに登場する AI・ジャーヴィスを見て、
音声アシスタントに仕事や趣味を手伝ってほしいなー、と思って作りました。
**もう4年ほど前になります(2015年か2014年…)**。

## 稼働条件
- **Google Chrome** ※ HTML5 で音声認識が使えるのは Chrome のみ…（iOS 版はなぜか無理？）
- Chrome なら、PC/モバイルとも対応

## 使用例
- 画面を開くと、アシスタントが挨拶します
- 最初にマイクへのアクセスと、（スマホの場合）ポップアップを開くのを許可してください

1. 画面のアシスタントをクリックまたはタップ（短時間、マイクがONになります）
2. 「レシピ検索」と呼びかける→ 「続けてキーワードをどうぞ」と HiBot が答える
3. 例えば「牛丼」と返事をする→  クックパッドの牛丼のレシピ画面を表示
4. 
※答えられる内容は、画面上にあるリストになります

## 使用している技術
* HTML5 (webkitSpeechRecognition, SpeechSynthesisUtterance) ※詳しくは MDN の [Web Speech API](https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API) をご参照下さい
* CSS
* jQuery ※ PHP との非同期通信用（近日中に axios に置き換えたい…）
* PHP ※主にスクレイピングや外部の Web API をたたくため

※ご覧の通り、クラウドサービスは使っていません。**HTML5 だけで音声認識/合成を行えるのは素晴らしいです**。

## 開発を辞めていた理由
これを作っている最中に Alexa と Google アシスタントが登場したのと、
HTML5 の Speech 系の API が Google Chrome でしか動かない、という事情から
開発をやめていました。

## 再稼働してみて分かったこと
- 「音声認識」の HTML API はまだ生きている
- 「音声合成」の HTML API は2018年で廃止が決定？（注意的なエラーが出たのでそのうち調査します）
-  Google のクラウドサービス: [Cloud Speech-to-Text](https://cloud.google.com/speech-to-text/?hl=ja)が
台頭しているため、今後、HTML5 での発展は厳しそう
- いざとなれば Cloud Speech-to-Text に乗り換えればOK（月間60分無料）なので、ツールとして便利に仕上げたい
- マーケットや天気のウェブ API が、ここ数年で廃止→ その呼びかけは現状除去 (2019.06.26) いずれは再実装します
- ウェブとつながったサービスは、常にメンテナンスが必要と実感（サービスが停止している時にどうするか、例外処理は必須）
- 音声合成、音声認識はやっぱり楽しい
- 言葉と言葉のやりとりより、画面があった方がやはり便利

## 今、考えていること
- 音声認識は Google Chrome のみ対応とはいえ、実質無料で使えるし、代替で Cloud Speech-to-Text があるので、開発を続けようという気になった
- 緯度・経度の情報と連携すれば、現在地情報を元に、天気をはじめ周辺情報を取り出せるので今後はそこを充実させたい
- ループ処理を実装して、常に音声を待ち受けるようにする
- 独自に情報収集するページを作って開いたり、Bootstrap のテンプレートから好みのデザインを作り上げたり、ウェブのジャーヴィスにしていきたい
- 色んな「Bot」を開発する力をつけて、色んなものを自動化していきたい
- **OSS で音声合成、音声認識のソフトウェアがあれば教えてください！**
EC2にgit、docker、docker-compose、pip、pythonコマンドをインストールする方法


EC2を立ち上げた際にやることを忘れがち&チームに共有としてメモしておきます。

準備まではQiitaの「[(下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce)」という記事がわかりやすかった。

## コマンドのインストール
### git

```bash
$ sudo yum install git
```

gitの連携方法は以下

```bash
# gotconfigを作成、編集
$ vi .gitconfig

[user]
  name = your_name
  email = hoge@hoge.com

# githubに公開鍵を登録するために公開鍵作成
$ chmod 700 ~/.ssh
$ cd ~/.ssh
$ ssh-keygen -t rsa
```

あとは、Github/Gitlabに公開鍵を登録してcloneするだけ。

### docker

```bash
# yum の更新
$ sudo yum update -y

# yum から docker をインストール
$ sudo yum install -y docker

# docker サービスの起動
$ sudo service docker start

# ec2-user を docker グループに追加する
$ sudo usermod -a -G docker ec2-user

# ログインしなおして以下を実行しインストールされていることを確認
$ docker info
```

docekrコマンドをsudo無しで実行する場合は以下を実行

```bash
# dockerグループがなければ作る
$ sudo groupadd docker

# 現行ユーザをdockerグループに所属させる
$ sudo gpasswd -a $USER docker

# dockerデーモンを再起動する (CentOS7の場合)
$ sudo systemctl restart docker

# exitして再ログインすると反映される。
$ exit
```

### docker-compose 

```bash
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version 
```

他のリンクにしたい場合以下から探す  
https://github.com/docker/compose/releases/

### byobu

```bash
$ sudo yum update -y
$ wget https://launchpad.net/byobu/trunk/5.119/+download/byobu_5.119.orig.tar.gz
$ tar xzf byobu*.tar.gz
$ cd byobu-* && ./configure
$ sudo make && sudo make install
```

### pip

```bash
$ curl -O https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py --user # or python3
```

### python

```bash
# 依存関係インストール
$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel -y

# 本体インストール
$ pyenv install 3.6.5

# このOSで使用するPythonのバージョンを宣言
$ pyenv global 3.6.5

$ pyenv rehash
$ python --version
```
Jetson Nanoのセットアップ

ここではNVIDIAから発売されている[Jetson Nano](https://www.nvidia.com/ja-jp/autonomous-machines/embedded-systems/jetson-nano/)の活用を紹介していきます。
Jetson Nanoを利用することで、個人開発者でもコンパクトなプラットフォームに本格的なソフトウェアを実装して、最先端のAIを活用できます。

# 使用するもの
- Jetson Nano
- Micro SD card (16GB以上)
- 5V AC アダプター（MincroUSB）
- HDMI モニター
- USBキーボード、マウス
- LANケーブル


# 1. SDイメージのダウンロードと書き込み
Jetson Nanoの環境構築を行います。[SDcard image](https://developer.nvidia.com/embedded/dlc/jetson-nano-dev-kit-sd-card-image)をダウンロードします。
※イメージファイルの容量は5GBあるので、安定したネット環境でダウンロードすることをおすすめします。 


ダウンロードした「jetson-nano-sd-r32.1.1-2019-05-31.zip」を解凍して、イメージライターでSDカードに書き込みます。今回は「[Win32DiskImager](https://sourceforge.net/projects/win32diskimager/)」を使用しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/41138279-663a-bd6e-9a72-6e8be21c9e9c.png" width=50%>

# 2. OSの初期設定
イメージファイルを書き込めたらSDカードをJetson Nanoに挿入します。モニター、キーボード、マウス、有線LANを接続します。ACアダプターを接続すると電源が入ります。

初期設定の項目を以下に挙げます。　　

- 使用許諾の承認
- 言語の選択　(今回は英語を選択)
- キーボードの選択　(Japaneseを選択)
- タイムゾーンの選択　(Tokyoを選択)
- アカウントの設定

# 3. デスクトップ
初期設定が完了すると以下のようなデスクトップ画面が表示されます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440646/e4cae5bc-5cc2-7489-fba3-b5e5e0efdc5c.png)



`Ctrl+Alt+T`でターミナルを開いて、以下のコマンドでアップデートを行います。　　

~~~
$ sudo apt-get update  
$ sudo apt-get upgrade  
~~~
初期設定は以上になります。

[次回](https://qiita.com/Hiroki-Fujimoto/items/b4dd25ba98b3687b1127)はカメラを使ったデモを動かしていきます。
RDS(MySQL)のストレージ領域の肥大化

# 概要
RDS(MySQL)を運用していて、ストレージ領域が肥大化することがあったのでその対応を共有します。

# 環境
エンジン：MySQL
エンジンバージョン：5.7.19

# 結論
まずは、結論から。
MySQLを再起動するとストレージ領域が解放されます。

# 事象
MySQL(リードレプリカ)のストレージが150GBあり、
DBサイズが60GBだったにも関わらず、ストレージの残容量が1GB近くになっていました。

# 原因
MySQLのテンポラリーテーブルが肥大化していました。

MySQLには、クエリ実行時にメモリ上に収まりきらなかったデータ(tmp_table_size以上)をInnoDBテーブルとしてテンポラリテーブル(**ibtmp1**) に書き出します。tmp_table_size以下であればMEMORYテーブルとしてメモリ上に作成されるようです。

このテンポラリーテーブルは、MySQL 5.7.6以からストレージエンジンがInnoDBになったようなんですが、厄介なのは、このテーブルは**MySQLを再起動しないと確保したストレージ領域を解放しない**のです。

ちなみにMySQL 5.7.5以前は、テンポラリーテーブルのストレージエンジンはMyISAMだったようで、テンポラリーテーブルがディスクを使い切り、クエリがabortされるとストレージ容量は元に戻る仕様？だったようです。
参考：https://yoku0825.blogspot.com/2015/04/mysql-576.html

テンポラリテーブルについては[こちら](https://blog.ybbo.net/2013/07/09/mysql%E3%81%AEtemporary-table-%E4%B8%80%E6%99%82%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB-%E3%81%A8tmp-file%E3%83%86%E3%83%B3%E3%83%9D%E3%83%A9%E3%83%AA%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A3/)の解説が分かりやすかったです。

# 対応
[こちら](https://codeday.me/jp/qa/20190402/531133.html)を拝見すると、テンポラリーテーブルのサイズを制限することは可能なんですが、RDS(MySQL)だとパラメータ変更はできませんでした。

つまり、現状だとDBの再起動するしかなさそうです。
[こちら](https://aws.amazon.com/jp/premiumsupport/knowledge-center/view-storage-rds-mysql-mariadb/)にもさらっと記載があります。

> MySQL 5.7 以降では、一時テーブル (ibtmp1) が過剰なストレージ領域を使用すると、領域を解放するために、DB インスタンスを再起動します。

別の手段として(お金がかかってしまいますが)、RDS(MySQL)のストレージの自動拡張機能がサポートされたみたいなのでそちらを設定しても良いですね。
https://dev.classmethod.jp/cloud/aws/rds-storage-auto-scaling/

# まとめ
ibtmp1のサイズはどこかで見れないんですかね？
RDS(MySQL)のストレージ容量はちゃんと監視しましょう。
Maya の sculpt deformer を実装してみたいときのメモ

## 背景

* Maya の sculpt deformer をゲームエンジンなどで利用したい.

https://knowledge.autodesk.com/support/maya/learn-explore/caas/CloudHelp/cloudhelp/2019/ENU/Maya-CharacterAnimation/files/GUID-8A7188B9-34C1-48B8-B690-5CB0EA36932D-htm.html

## Sculpt deformer

Maya にはいくつかパラメータがありますが, ここでは stretch を考えます.
stretch モードでは, たとえば布っぽい平面に球をめり込ませ, 布を引っ張るなどの効果を実現できます.

## アルゴリズム(sphere)

* sculpt 物体の位置と半径(sphere)とする
* sculpt origin(locator). sculpt の影響を計算する原点(pivot)


`dir = sculptObject.position - sculptOrigin.position` で押し出す方向を決める.


sculptObject.position + sculptObject.radius の範囲内に derorm したいメッシュがあったら, その頂点を dir の方向に押し出す. 押し出せる頂点位置は sculptObject.position + sculptObject.radius を限界とする.

## 任意形状を sculpt 

正確にやるなら GJK あたりで多面体との交差判定が必要そう.
Bullet あたりでできるかも.

## TODO

* sculpt deformer の可動範囲が狭いのであれば bake deformer あたりで skinning にコンバートも考えてみる
* 実装する(スクリプト言語でさらっと試せる open source 3D ツール欲しい. ofx?)
webpack + stylelint ホットリロード時にstylelintを実行する。

### 概要
webpackでホットリロード時にstyelintを実行することで、早期にエラーを検知することが可能です。  
### 前提条件
webpackの設定やstylelintはすでに設定済みの想定です。  

### github
動作確認済みのリポジトリ  
[https://github.com/TakuyaTaniguchi/staticDevelop](https://github.com/TakuyaTaniguchi/staticDevelop)

### 手順

npm-scripts

```package.json
{
  "scripts": {
    "dev": "webpack-dev-server --mode development --watch"
  }
}
```

[stylelint-webpack-plugin](https://github.com/webpack-contrib/stylelint-webpack-plugin)のインストール

```
yarn add stylelint-webpack-plugin --dev
```
 
[webpack.config.js](https://github.com/TakuyaTaniguchi/staticDevelop/blob/master/webpack.config.js)に設定を追加

```webpack.config.js
const StyleLintPlugin = require('stylelint-webpack-plugin');
const STYLELINT = ['./src/**.scss'];//検知対象ファイルの設定　カンマ区切りで検知対象を追加できる。
-~~~~~~~~~~~~~~
//pluginsに設定を追加
plugins: [
  new StyleLintPlugin({
      files: STYLELINT,
      syntax: 'scss'
   }),
],
```

たったこれだけでホットリロード中の検知が可能になります。  
※まだまだ初心者のため、 設定間違いや、処理に悪いところがあればコメントに頂ければと思います:bow_tone1:

参考資料:
https://gist.github.com/manavsehgal/69c2e0f0083df14010a638187654378e
awscli を pip でインストールするときは Python 3 を使ってください

Python 2 は 2020-01-01 に EOL を迎えます。
しかし、いまだに PyPI からのダウンロードの50%強は Python 2 からのものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969/c1660d82-3512-c15f-1596-6b2ce3e19cb7.png)
from [PyPI Stats](https://pypistats.org/packages/__all__)

この膨大なPython 2からのダウンロード数は、 Python のライブラリをメンテナンスしている人たちに Python 2 のサポートを続けさせるプレッシャーになっています。 Python 2 の EOL までにこのダウンロード数をなるべく下げたいところです。

だれがこんなに Python 2 で `pip install` をしているのでしょうか。OS別ダウンロード数統計にヒントがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969/b73f71e6-71b2-9d90-5892-a38cad890d90.png)

過半数の Python ユーザーが macOS か Windows を使っているのに対して、ダウンロードの90%くらいが Linux からのものです。 CI, CD, サーバーのプロビジョニングで実行される `pip install` が多いのでしょう。

ではどのパッケージが多くダウンロードされているのでしょうか。 [PyPI Stats のランキング](https://pypistats.org/top) を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969/1e554690-e6b5-0451-4fc9-e73ffcd934a3.png)

トップ20のうち、pip とその依存ライブラリである setuptools を除いた 18 パッケージは、 requests, awscli かその依存パッケージです!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1969/feebbf68-665a-247a-f022-fddbda7bacfd.png)

そして awscli パッケージの 80% 以上が Python 2 から `pip install` されています!!

もし多くの人に読まれているドキュメントや Dockerfile のサンプルなどで awscli を Python 2 から pip install しているのを見かけたら、この記事か [英語版](https://dev.to/methane/use-pip3-to-install-awscli-44pk) のURLを紹介して Python 3 に移行するように提案してみてください。
[初心者向け]VuexのStoreを細かくモジュール分けしよう

はじめまして、PMをやっているtatsukenと申します。はじめまして
研修の一環でvue.js、expressを書くことがあったので、そのことを中心にまとめていきたいと思います。
#はじめに
Vuexを始めたばかりの自分はVuexに関連する処理をすべて`store.js`などの一つのファイルに記述してしまっており、ファイルが非常にファットになってしまっおり、可読性も非常に下がってしまっていました。
そこでVuexファイルを細かくモジュール分していきたいとおもいます。

##必要な環境
* Vue
* Vuex

##実装
まず`store/`以下に任意のjsファイルを作成してください。今回は`user.js`というファイルを作成しています。

```user.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
    //stateデータ
    user: null
}
const mutations = {
    //同じ処理を行うならnewMsgはobjectに
    setUserInfo(state, userInfo) {
        //任意の同期処理
        state.user = userInfo
    }
}
const actions = {
    getUser() {
        //任意の非同期処理
    }
}
export default {
    namespaced: true,
    state,
    actions,
    mutations,
}
```
このように`state`,`mutations`,`actions`それぞれを定数に入れてそれを`export`しています。
##それぞれのモジュールを集約しよう
`store`ディレクトリと同じ階層に任意のjsファイルを作成してください。今回は`store/index.js`を作成します。

```index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
    modules: {
        user: user
    },
})
```
ここではまず`store/`以下の作成したVuexファイルを`import user from './store/user'`でインポートします。
そしてモジュールを集約して`export`しています。
##main.jsで呼び出し

```main.js
import Vue from 'vue'
import store from './store/index'
new Vue({
  render: h => h(App),
  store
}).$mount('#app')
```
`mian.js`内で`store/index`をインポートし、`Vueインスタンス`内にインポートしたものを読み込んでください。
##Vuexを呼び出す際の注意点

```sample.vue
<script>
export default {
  created() {
    this.$store.dispatch("user/getUser");
    this.$store.commit("user/setUserInfo", "hoge");
    this.$store.state.user.user;
  }
};
</script>
```
このように呼び出し先の指定が`index.js`での定義から、`"user/getUser"`、`"user/setUserInfo"`、`state.user.user`のようになっていることに注意です。

#最後に
このようにVuexのファイルを細かくモジュール分けすることができました。
ファイルを細かくモジュール分けすると可読性が上がり、開発効率が上がると思います。
機会があればぜひ試してみてください。
なにか間違いなどあれば指摘していただけると幸いです。
mcrypt非推奨による暗号化復号化導入

#php7.2でmcryptが非推奨
PEAR::Crypt_Blowfishを使っていると警告が溢れてくるようになったので対策。

#必要なライブラリを探す
Composerで入れられるパッケージがあるっぽいので試す

[webiny/crypt](https://packagist.org/packages/webiny/crypt)

```bash
#足りないライブラリを追加
sudo apt install php-xml php-mbstring
#Composerに追加
composer require webiny/crypt
#↓Composerにpathが通ってないなら↓
#php composer.phar require webiny/crypt

```

#サンプルコード

```php
require __DIR__ . '/vendor/autoload.php';

class MyClass
{
        use Webiny\Component\Crypt\CryptTrait;
        function myMethod(){
                $key = 'aqwsedrfgthyjuikolp';
                $text = 'money-money-money';
                $encrypted = $this->crypt()->encrypt($text, $key);
                try{
                        $decrypted = $this->crypt()->decrypt($encrypted, $key);
                        $decryptedBad = $this->crypt()->decrypt($decrypted, 'bad-bad-bad');
                } catch (\Exception $e) {
                        var_dump($e->getMessage());
                }
                var_dump($encrypted);
//                string(64) "HhgH~省略~vaYz/"
                var_dump($decrypted);
//                string(17) "money-money-money"
                var_dump($decryptedBad);
//                bool(false)
        }
}

$m = new MyClass();
$m->myMethod();
```

とりあえず動いた
古いblowfishをデコードできるかは別途要検証…
anacondaでcondaするときにHTTPErrorが出るのそれproxyの問題じゃない？？

# それproxyが悪さしてるんじゃない？
```
$ conda install -c anaconda pydot -y
CondaHTTPError: HTTP 000 CONNECTION FAILED for url <~~~~~~>

An HTTP error occurred when trying to retrieve this URL.
HTTP errors are often intermittent, and a simple retry will get you on your way.

If your current network has https://www.anaconda.con blocked, please file
a support request with your network engineering team.

ConnectTimeout(MaxRetryError(.......
```
別にインターネットはhttp://anaconda.com をブロックしているわけでもない.
proxyは設定しているはずなのにcondaのインストールが通らない……．

もしかして：proxy

設定してると思いきや設定してないことがある
謎のHTTPErrorに悩まされている場合は，一度.condarcファイルを確認してほしい．

# proxy設定が別にあるってマジ？

anacondaでは環境設定とは別に，condaとしてproxyを設定する必要があるみたい．
~~なんだそのクソ仕様~~

# .condarcを探す or 作る
anacondaの設定ファイル.condarcにproxyの設定を書き込む．
anacondaのルート直下に作るのが正しい．
windowsであれば通常ユーザールートの直下にAnaconda3のディレクトリ```C:\Users\[ユーザー名]\Anaconda3```があるのでそこに.condarcを作るか，すでにあれば追記する．
Unix系OSは```/opt/conda/```の下に作るか追記する．

無ければ適当なエディタ[^1]で作成してください．

[^1]: メモ帳はエディタではない

# .condarcを記述する
```:.condarc
proxy_servers:
    http: http://[ユーザ名]@[ホスト名]:[ポート番号]
    https: http://[ユーザ名]@[ホスト名]:[ポート番号]

# 例 http: http:keisuke@hoge.jp:8080
```
dockerでanacondaを使っている場合は，毎回記述するのがめんどくさいのでDockerfileに直接

```:Dockerfile
RUN echo 'proxy_servers:\n        http: http://[ユーザ名]@[ホスト名]:[ポート番号]\n    https: http://[ユーザ名]@[ホスト名]:[ポート番号] >> /opt/conda/.condarc

```
とか書くといい．

# 終わりに
死ぬほどはまって時間を溶かした．
windowsのプロキシ設定をしているとhttpだけ書いてくれていたりする．~~なんだその微妙な仕様は~~

そもそもanacondaを使うやつが悪いって？それはそう……(研究室の都合です)
出力メソッドの使い分け

#はじめに
初投稿です。備忘録としてまとめています。

print puts p ppメソッドの特性と出力結果を大まかに書いてみた。
参考：たのしいRuby
###print
```
array = ["秋山","山本","馬場" ]

print "ロバート"
print 3
print array
```
###結果
```
ロバート3["秋山", "山本", "馬場"]
```
printメソッドは改行、スペース無し。配列は展開されずに出力。

###puts
```
array = ["秋山","山本","馬場" ]

puts "ロバート"
puts 3
puts array
```
###結果
```
ロバート
3
秋山
山本
馬場
```
printメソッドと違い、一行ごとに改行が入り見やすくなる。

###p
```
array = ["秋山","山本","馬場" ]

p "ロバート"
p 3
p array
```
###結果
```
"ロバート"
3
["秋山", "山本", "馬場"]
```
文字列は""（ダブルクオーテーション）込みで出力される。文字列、数値、配列の型を分けて出力してくれる。

###pとppの比較
```
require "pp"
array = [
    {title:"羅生門", auther:"芥川龍之介"},
    {title:"銀河鉄道の夜", auther:"宮沢賢治"},
    {title:"こころ", auther:"夏目漱石"}
]
p array
pp array
```
###結果
```
[{:title=>"羅生門", :auther=>"芥川龍之介"}, {:title=>"銀河鉄道の夜", :auther=>"宮沢賢治"}, {:title=>"こころ", :auther=>"夏目漱石"}]

[{:title=>"羅生門", :auther=>"芥川龍之介"},
 {:title=>"銀河鉄道の夜", :auther=>"宮沢賢治"},
 {:title=>"こころ", :auther=>"夏目漱石"}]

```

ppメソッドはハッシュをキー毎に改行して見やすくしてくれる。
デバック時に便利
groupby後の文字列連結

毎回どうしても忘れてしまうのでメモ。

Dataframe中に入っている特定の列の値（カテゴリ、文字列とか）を、別の列の値でgroupbyした際にカンマ区切りでgroupby後の列に入れる方法。

dfが

|列A|列B|
|---|---|
|A1|b1|
|A1|b2|
|A2|b3|
|A3|b4|
|A2|b5|
|A1|b6|
|A1|b7|
|A3|b8|

である場合に、

    df.groupby(‘列A’)

した際に

|groupby後列Ａ|列C|
|---|---|
|A1|b1,b2,b6,b7|
|A2|b3,b5|
|A3|b4,b8|

とする方法↓

    df.groupby('列A')[‘列B'].apply(lambda x: "%s" % ','.join(x))



列Bが数字（int,floatなど）であれば lambda式の部分を　

lambda x: "%s" % ','.join(str(x))

にすればＯＫ

追記：下記の方法もあるとコメントもらいました。こっちが見やすくていいですね。

    df.groupby('列A')['列B'].agg(','.join)