OmniAICreator/Qiita-1.07M huggingface dataset:
よく使うvagrantコマンド

## よく使うvagrantコマンド

### ■ 開始する場合
※defaultは、Vagrantfileで「config.vm.define」を指定した場合に付ける必要があります。

```bat:コマンド
vagrant up default
```

### ■ 一旦止めるだけの場合

```bat:コマンド
vagrant halt
```

### ■ データを破棄する場合
次回、`vagrant up` の際にはまっさらなマシンから新規インストールが行われます。

```bat:コマンド
vagrant destroy
```

### ■ provision する場合
※defaultは、Vagrantfileで「config.vm.define」を指定した場合に付ける必要があります。

```bat:コマンド
vagrant provision default
```

### ■ Boxファイルを作成する

```bat:コマンド
# box 作成用のフォルダ(任意)に移動する。
> cd xxxx(box 作成用のフォルダ)

# boxファイルの作成
> vagrant package -o xxxxx.box(box ファイル名)

# package.boxファイルが出来上がる。
```

### ■ 登録されているBoxファイルを削除する

```bat:コマンド
# box 作成用のフォルダ(任意)に移動する
> cd xxxx(box 作成用のフォルダ)

# boxファイルの削除(mackerel/centos7を適宜変更する)
> vagrant box remove mackerel/centos7

# boxファイルの確認
> vagrant box list
```

### ■ 登録されているBoxファイルを最新にする

```bat:コマンド
# box 作成用のフォルダ(任意)に移動する
> cd xxxx(box 作成用のフォルダ)

# boxファイルの更新
> vagrant box update --box (ボックス名)
```

### ■ Boxファイルを追加する
#### 1) パス(URL)を指定してBoxファイルを追加する

```bat:コマンド
# boxファイルの追加
> vagrant box add (ボックス名) (ファイルパス)
# --> e.g) vagrant box add xxxxx /var/www/xxxxx.box
# --> e.g) vagrant box add xxxxx http://exmaple.com/xxxxx.box

# boxファイルの確認
> vagrant box list
```

#### 2) jsonによる設定ファイル指定する

参考）
・ http://tsunokawa.hatenablog.com/entry/2014/10/24/153151


```json:JSONファイルの中身
{
    "name": "xxxxx",
    "provider": "virtualbox",
    "description": "Description xxxxx box",
    "versions": [
        {
            "version": "0.0.1",
            "description": "Description 0.0.1",
            "providers": [
                {
                    "name": "virtualbox",
                    "url": "http://exmaple.com/xxxxx.box.0-0-1"
                }
            ]
        },
        {
            "version": "0.0.2",
            "description": "Description 0.0.2",
            "providers": [
                {
                    "name": "virtualbox",
                    "url": "http://exmaple.com/xxxxx.box.0-0-2"
                }
            ]
        }
    ]
}
```

```bat:コマンド
# boxファイルの追加（--box-versionは省略可）
> vagrant box add (JSONファイルパス) --box-version (バージョン)
# --> e.g) vagrant box add http://exmaple.com/xxxxx.json
# --> e.g) vagrant box add http://exmaple.com/xxxxx.json --box-version 0.0.2

# boxファイルの確認
> vagrant box list
```
【メモ】Pythonと機械学習

_Pythonで学ぶ 基礎からの機械学習入門_
http://news.mynavi.jp/series/Python_ML/002/

Tensorflowでじゃんけん
https://cloudplatform-jp.googleblog.com/2017/10/my-summer-project-a-rock-paper-scissors-machine-built-on-tensorflow.html
AndroidのFirebaseはGoogle Play 開発者サービスに依存しているので注意

Firebase Remote Configを使用してアプリを開発していたのですが、特定の端末で`FirebaseRemoteConfig.getInstance().fetch()`に設定した`OnCompleteListene`が呼ばれないエラーに遭遇しました。

ログには以下のメッセージが表示されていました。

```
W/GooglePlayServicesUtil: Google Play services out of date.  Requires 11400000 but found 10932448
```

この時点で`Google Play Services`が何者か理解していませんでしたし、Firebaseとどのような関係があるのか把握できていませんでした。


## Google Play Servicesとは何か

日本語では`Google Play 開発者サービス`です。
Google Play 開発者サービスは端末にインストールされているアプリです。
個別のアプリからバージョンを更新することはできません。

ドキュメントは下記にあります。
https://developers.google.com/android/guides/overview

## FirebaseとGoogle Play 開発者サービスの関係

ドキュメントの事前準備のところに本日時点(2017/10/11)で以下の記載があります。

>
事前準備
•Android 4.0（Ice Cream Sandwich）以降、および Google Play 開発者サービス 11.0.4 以降が搭載された端末

https://firebase.google.com/docs/android/setup?hl=ja

Google Play 開発者サービスのリリースノートを確認すると 11.0.4 がリリースされたのは、2017年6月で、最近だということがわかります。
https://developers.google.com/android/guides/releases

## Google Play 開発者サービスはいつ更新されるか

ドキュメントにはこのような記載があります。

>
The Google Play services APK is delivered through the Google Play Store, so updates to the services are not dependent on carrier or OEM system image updates. In general, devices running Android 2.3 (API level 9) or later and have the Google Play services app installed receive updates within a few days. This allows you to use the newest APIs in Google Play services and reach most of the devices in the Android ecosystem. Devices older than Android 2.3 or devices without the Google Play services app are not supported.

https://developers.google.com/android/guides/overview

ただし、私が開発用に使っている端末の中に更新されてない端末がいくつかあり、本当に全ての端末で更新されているとは言えない気がしています。

## まとめ
ドキュメントに記載されているとおり、AndroidのFirebaseはGoogle Play 開発者サービスに依存しています。
Google Play 開発者サービスは基本的に自動で更新されます。
しかし、そうならない端末も存在しているので、可能であればFirebaseを使わないとアプリが使えないような作りは避けたほうが良いと思います。
【メモ】Mysqlで巨大なファイルをインポートする方法

#MYSQLで10Gを超えるようなファイルをインポートする方法のメモ
(XAMPP+MYSQL) 

##事前準備
データベースとテーブルを作っておく
テーブルは転送するテーブルの構造と同じにしておく
簡単なのは、元のデータベースから、転送するテーブルを
10行ぐらいSQLファイルでダウンロードしておいて
phpMyadminのインポートを使ってインポートして
空にしておくと、構造のみ残るので楽

##インポート作業
windows powershellを使って
1. C:\xampp\mysql\bin\mysql -u [user] -p
2. password 入力
3. use [database_name]
4. source [file_path]

で開始

Query OKと表示されたらOK
失敗すると
Query Errorと表示されるのでやり直し
大体構造が一致していないことが多い

メモまでに
addClassから遅延後にremoveClassしたい

CSSのtransitionを動作させるために、HTMLのclassを付け替えることをしばしばやることがあると思う。その付けたclassを指定時間後に消したいというケースがあった。

#やっつけ（失敗例）
```js
$('div').addClass('hoge').delay(1000).removeClass('hoge');
```
これだと狙い通りに動かない。addとremoveが一瞬で行われる。delayはアニメーションでしか有効ではない。

#queueを使ってできるらしい
```js
$('div').addClass('hoge').delay(1000).queue（function(next){
  $(this).removeClass('hoge');
  next();
}）;
```
遅延後（1秒後）にremoveClassしてくれる。
Angular tips(2)

# Angular 復習(Angular4～)

## テンプレートシンタックス

### 1. `<input [value]="expression">`

inputのvalueプロパティをexpressionでバインディングする。

### 2. `<div [attr.role]="expression">`

divのrole属性をexpressionでバインディングする。
※role属性とは、HTML5で追加された属性。

### 3. `<div [class.extra-sparkle]="expression">`

cssクラスextra-sparkleをexpressionでバインディングし、有効にするかを決定する。
ngClassに似ている。

### 4. `<div [style.width.px]="expression">`

cssスタイルをexpressionでバインディングする。

### 5. `<button (click)="readRainbow($event)">`

クリックボタンが押されたときに、メソッドが呼ばれる。
イベントの種類は、以下のリンクを参照。
https://developer.mozilla.org/en-US/docs/Web/Events

### 6. `<div title="Hello {{ponyName}}">`

titleプロパティに、{{}}で補完構文を加える。
`<div [title]="'Hello' + ponyName"`と同じ。

### 7. `<p>Hello {{ponyName}}</p>`

補完構文を加える。

### 8. `<my-cmp [(title)]="name">`

双方向に、titleプロパティと、nameをバインディングする。
`<my-cmp [title]="name" (titlechange)="name=$event">`と同じ。

### 9. `<video #movieplayer ...><button (click)="movieplayer.play()"></video>`

movieplayerというローカル変数を作成し、イベントバインディング、データバインディング内でvideo要素の実体にアクセスできるようにする。

### 10. `<p *myUnless="myExpression">...</p>`

アスタリスクをつけることで、要素を組込テンプレートに置き換えます。
`<ng-template [myUnless]="myExpression"><p>...</p></ng-template>`と同じです。
ng-templateは、実体を持たない要素です。また、通常は表示されません。

#### 11. `<p>Card No.: {{cardNumber | myCardNumberFormatter}}</p>`

補完文字列を指定したpipeでフォーマットします。

#### 12. `<p>Employer: {{employer?.companyName}}</p>`

クエスチョンマークをつけると、employerオブジェクトが未定義(companyNameがない)の場合は、無視される。
エラーにならないと。
PostfixのSMTP Authを利用したメールリレー設定

# PostfixのSMTP Authを利用したメールリレー設定

ローカルネットワークに構築したPostfixサーバーからSMTP Authを要求するISP等のSMTPサーバーを利用してメールリレーする際の設定方法のメモ。

1. ```/etc/postfix/smtp-auth``` を編集
> [SMTPサーバー名] [ユーザー名]:[パスワード]

2. ```/etc/postfix/main.cf``` を編集して設定項目を追加
※注意: ```relayhost```の設定についてカッコは付けたまま記述します
> relayhost = [SMTPサーバー名]:587
> smtp\_sasl\_auth\_enable = yes
> smtp\_sasl\_password\_maps = hash:/etc/postfix/smtp-auth
> smtp\_sasl\_security\_options = noanonymous

3. ```postmap hash:/etc/postfix/smtp-auth``` を実行してハッシュマップDBを更新する
4. ```service postfix reload``` でPostfixの設定をリロードする
chromeでHTTPでのアクセス時に警告マークを表示する

## 参考

* [Google Chrome 開発版、「安全ではない」警告マークを非HTTPSページに表示 | 海外SEO情報ブログ](https://www.suzukikenichi.com/blog/chrome-canary-marks-non-secure-origins-as-non-secure/)
* [Google、10月提供のChrome 62以降で、入力欄のあるすべてのHTTP接続ページで警告を表示 -INTERNET Watch](http://internet.watch.impress.co.jp/docs/news/1057563.html)
* [HTTPでフォーム送信するサイトにGoogleが警告を一斉送信、Chrome62から実装するセキュリティ警告に備えてHTTPS移行を促す | 海外SEO情報ブログ](https://www.suzukikenichi.com/blog/chrome-warns-against-non-https-sites-that-have-text-input-fields/)
* chrome 61 にて確認。(2017/10/12時点で最新)

## 設定

![a.png](https://qiita-image-store.s3.amazonaws.com/0/25728/6be098e6-2204-e0c5-0e04-ea43f05ef2ce.png)

アドレスバーに `chrome://flags` と入力しEnter

`Mark non-secure origins as non-secure`の項目で設定を変えれば良い。
一番下が一番厳しい。
`Incognito mode`はシークレットモードのこと。


## Warn on HTTP after editing forms

* 通常は以下マークのみ。input type=text だけの場合は以下。

![mark.png](https://qiita-image-store.s3.amazonaws.com/0/25728/28cbd75d-279f-2eec-ae38-ab8da8031acd.png)


* input type=passwordが含まれる場合、「保護されていません」と表示。

![hogo.png](https://qiita-image-store.s3.amazonaws.com/0/25728/4ea2a456-d7ae-83e4-d151-f9e9b7a4f7fe.png)


## Always mark HTTP as actively dangerous

アドレスバーの隣に「保護されていません」の表記が付く。

![スクリーンショット_2017-10-12_09-20-46.png](https://qiita-image-store.s3.amazonaws.com/0/25728/56d0de8d-7a21-db46-2f0f-b05b2a8da847.png)
`docker-compose run` で起動したコンテナでポートマッピングが効かない


次のようなコンテナの3000ポートをホストの3000ポートにマッピングする設定で`docker-compose run`コマンドを使ってコンテナを起動しました。
しかし`localhost:3000`にアクセスしましたが、コンテナの3000ポートのページが表示されない問題で少しハマりました。

```yml|docker-compose.yml
version: '2'
services:
  develop:
    build: .
    tty: true
    privileged: true
    ports:
      - "3000:3000"
```

解決方法は `docker-compose run  --service-ports`と`--service-ports`オプションをつけることです。

`docker-compose run`は基本的に単発のコマンドを実行するためのコマンドであり、`docker-compose up`で起動されたコンテナとのポートマッピングの競合を防ぐために、このような仕様になっているみたいです。

参考
https://github.com/docker/compose/issues/1259#issuecomment-90878095
自作アプリ Ｎｏ.5 (1個)

**以前作っていたホームページを一度作り直すので、
そのホームページに書いていたコードをこっちに残しときます。**

# No.5 Hello Worldを表示するファイルを作成するプログラム
```

# coding:utf-8
# No.5
# hello worldを表示するファイルを作成するプログラム
 
def main():
    print('以下の文を書いてください')
    saisyo = input('#coding: utf-8 と書いてね')
    hello = input('print("Hello World") と書いてね')
    name = input("最後にこのファイルの名前を決めてね")

    # "/n"を使うことで改行
    kekka = saisyo+"\n"+hello

    print(kekka)

    # .pyは拡張子を決定し、wというのは書き込みモード
    file = open(name+'.py','w')

    # ファイルにkekkaに代入されている文字列を書き込む処理
    file.write(kekka)
    file.close()
    print('Hello Worldと表示されるプログラムがこのファイルを実行した場所に作成されたよ！')

main()

# なんで関数を作ったのかは覚えていません・・・ｗ

```

# ※番外編

このファイルと同じフォルダに鳴らしたい音源が存在することが前提となってます。
番外編と書いたのは音を鳴らしたい時どうすればいいか調べていた時に参考になるコードを見つけ、それを参考にしたからです。音を鳴らす部分のコードはほぼコピペの為自作じゃないからですｗ

```
# coding: utf-8

# x秒後に音をならして教えてくれるプログラム

import time
import wave
import pyaudio
 
print("設定したら音を鳴らして教えてくれるよ！")
time.sleep(2)
ongen = input("まずは鳴らしたい音源ファイルを入力してね！例：doremi.wav")
sec = input("何秒後にお知らせしますか?")
print("OK!時間が来た教えるねー！")
time.sleep(int(sec))
print("時間だよー！")
    
if __name__ == '__main__':
   
    wf = wave.open(ongen, "r")
    # ストリームを開く
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True)
    # チャンク単位でストリームに出力し音声を再生
    chunk = 1024
    data = wf.readframes(chunk)
    while data != '':
        stream.write(data)
        data = wf.readframes(chunk)
    stream.close()
    p.terminate()
　time.sleep(1)
```
【Python@Pandas】エラー"Try using .loc[row_indexer,col_indexer] = value instead"の回避策について

*df.dropnan()* メーソドで、ある欄にNaNの値を含む行を削除すると、
全体のレコード数は減少しますが、indexの順番は単に削除された行をスキップだけです。
そのデータセットを使用して解析を行うと、以下のエラーメッセージが表示されます。
※結果への影響はないと思います。

>A value is trying to be set on a copy of a slice from a DataFrame.
>Try using .loc[row_indexer,col_indexer] = value instead

回避策として、*df.reset_index()* メーソドを使用して、データセットのindexを直すことで
事象を解消することができます。

###参考資料
[Returning a view versus a copy] (http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy)
Ruby の puts は to_s より先に to_ary が実行される (配列と文字列を除く)

https://docs.ruby-lang.org/ja/latest/method/Kernel/m/puts.html より抜粋

> 配列や文字列以外のオブジェクトが引数として与えられた場合には、 当該オブジェクトを最初に to_ary により配列へ、 次に to_s メソッドにより文字列へ変換を試みます。



```rb
class Integer
  def to_ary
    ['to_ary']
  end

  def to_s
    '10'
  end
end

puts 1
```

出力

```
to_ary
```

## 参考サイト

https://docs.ruby-lang.org/ja/latest/method/Kernel/m/puts.html
【JavaScript】xxx.split is not a function というエラーが発生していた←記載内容が間違っていました

記載内容に間違いがありました。

`xxx.split is not a function`

というエラーが発生していると記載していましたが、
修正前の状態に戻し再確認を行ったところ、**エラーは発生しませんでした**。
ロジックだけでは無く、データもエラーが発生していた時と同じにしましたが、
再現出来なくなっていました。

また、チェックボックスから取得した値の型がどうなってるを`typeof 型を確認したい変数`で確認したところ、
`string`
になっていました。

```javascript:sample3
$("input[type='checkbox']").click(function() {
  //チェックしたチェックボックスの値を取得
  var v = $(this).val();
  //チェックボックスの値の型を確認するために追記した箇所です。
  console.log("v=" + v + " type=" + typeof v);
  // userLsitが空っぽだったらvを入れて、userListに何らかの値が入ってたらカンマ区切りで結合
  // 実際のコードは、ココでチェックされた値だけをuserListに入れるって処理も記述されています。
  if (userList.length > 0) {
    userList = userList + "," + v;
  } else {
    userList = v;
  }
};

```

間違った記事を指摘して頂き有難うございました。
指摘がなければチェックボックスの値がNumberになる事があると、間違った認識を持ち続けることになっていました。

# 今後の対応
修正前の状態に戻し、定期的にエラーが発生していないか確認を行い、
再度エラーが発生する事があれば、調査と修正を行い、この記事の更新を行います。

# 今回の間違いで学んだこと
1. もっと調べる
2. ログの出力などを行い、確認を十分に行う
3. チェックボックスの値はNumberにはならない
4. シンタックスハイライト・書き方は意識して分かりやすいように書く



**ココから下は間違いを含む記事です**

# 概要
4年くらい前に作られたhtmlを見てたら
`xxx.split is not a function`
というエラーが発生していたので調査と修正を行いました。
その備忘録です。

# 原因
エラーが発生していた箇所は下記のような記述になっていた。

```js
var userNo = userList.split(",");
```

userListには、チェックしたチェックボックスの値がカンマ区切りで保存される。

```javascript:sample1
$("input[type='checkbox']").click(function() {
  //チェックしたチェックボックスの値を取得
  var v = $(this).val();
  // userLsitが空っぽだったらvを入れて、userListに何らかの値が入ってたらカンマ区切りで結合
  if (userList.length > 0) {
    userList = userList + "," + v;
  } else {
    userList = v;
  }
};
```

チェックボックスは複数存在していて、値は1,2,3・・・みたいな数値が割り当てられていた。

例えば、値が「1」のチェックボックスを初めて押下すると、`userList`には「1」が保存され、
次に値が「2」のチェックボックスを押下すると、`userList`には「1,2」が保存される仕組み。
エラーが発生していた箇所　『　`var userNo = userList.split(",");`　』　は、チェックボックスが押下されると
呼ばれる仕組みになっていた。
実際のコードとは少し違いますが、下記みたいな感じ。

```javascript:sample2
$("input[type='checkbox']").click(function() {
  //チェックしたチェックボックスの値を取得
  var v = $(this).val();
  // userLsitが空っぽだったらvを入れて、userListに何らかの値が入ってたらカンマ区切りで結合
  if (userList.length > 0) {
    userList = userList + "," + v;
  } else {
    userList = v;
  }
  //！！！エラーが発生していた記述！！！
  var userNo = userList.split(",");
};
```

初めて押下した時は、`userList`の値が「1」みたいにカンマ区切りでは無い値が入ってるため
`userList`に入ってる値がNumber型と判定されて、
`userList.split is not a function`
のようなエラーが発生していました。
この状態で、さらにチェックボックスを押下すると、`userList`の値は「1,2」みたいになるため、
エラーは出ずに正常な処理が行われていた。

# いつから？
このhtmlが作られた時は発生して無かったはず。
もしかしたらテスト漏れだったのかもしれませんが・・・

# チェックが厳密になった？
構文のチェックが厳密になったのかな？と思って調べてみたけど分かりませんでした。
やっぱりテストが不十分だったのかな。


# 修正方法
エラーが発生していた箇所を下記のように変更しました。

```js
var userNo = (String(userList)).split(",");
```

『 `userList = String(v);` 』にした方が良かった・・・。
bow 導入メモ

# 日本のリポジトリに変更

```bash
sudo sed -i -e 's%http://.*.ubuntu.com%http://ftp.jaist.ac.jp/pub/Linux%g' /etc/apt/sources.list
```

# 最新版の git をインストール

```bash
# Ubuntu 
sudo add-apt-repository ppa:git-core/ppa
sudo apt update; sudo apt install git
```

## github と SSH 接続設定

1. 以下を実行

```bash
ssh-keygen -t rsa -C "your_email@example.com"
```
2. [~/.ssh/id_rsa.pub]の内容を [https://github.com/settings/keys](https://github.com/settings/keys) に貼付

3. `ssh -T git@github.com`

- [https://git-scm.com/download/linux](https://git-scm.com/download/linux)

# 最新版の Fish shell のインストール

```bash
sudo apt-add-repository ppa:fish-shell/release-2
sudo apt-get update
sudo apt-get install fish
```

- [https://launchpad.net/~fish-shell/+archive/ubuntu/release-2](https://launchpad.net/~fish-shell/+archive/ubuntu/release-2)

## fish のパッケージマネージャ fisherman をインストール

```bash
curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
```

## cmder から fish を起動する方法

```
# Setup -> Startup -> Tasks -> Commands
## Task parameter
-icon "%USERPROFILE%\AppData\Local\lxss\bash.ico"

## Start console
C:\Windows\System32\bash.exe ~ -c fish -cur_console:p
```

# +lua の vim8.0 をビルド

- [既存のvimをluaオプション付きのvim8.0に入れ替える。](https://qiita.com/Fendo181/items/8a5545cd7550bd9a3c91)

# 最新版の nginx をインストール

1. nginx 公式の PGP キーを追加

```bash
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
```

2. [`/etc/apt/sources.list`] に以下を追加

```bash
# `codename` is 'lsb_release --all -> Codename'
deb http://nginx.org/packages/debian/ codename nginx
deb-src http://nginx.org/packages/debian/ codename nginx
```

3. `sudo apt install nginx'

# 最新版の mysql をインストール

1. [https://dev.mysql.com/downloads/repo/apt/](https://dev.mysql.com/downloads/repo/apt/) から 佐新板の .deb をダウンロード

```bash
# リポジトリ追加
wget http://dev.mysql.com/get/mysql-apt-config_x.x.x-x_all.deb
sudo dpkg -i mysql-apt-config_x.x.x-x_all.deb

# インストール
sudo apt update
sudo apt install mysql-server

# バージョン確認
mysql --version (2017/10/11)
> mysql  Ver 14.14 Distrib 5.7.19, for Linux (x86_64)
> using  EditLine wrapper

# 起動
sudo service mysql start
mysql -u root -p
```

# 最新版の PHP をインストール

```bash
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.1
```

# anyenv のインストール

## pyenv のインストール

### conda のインストール
Paper > Marching Triangles: Delaunay Implicit Surface Triangulation (1997) by Hilton et al. | Radial Basis Function Generated Finite Differences (RBF‐FD): Basic Concepts and Some Applications by Fornberg and Flyer

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.4045
Marching Triangles: Delaunay Implicit Surface Triangulation (1997)
by A. Hilton , J. Illingworth

任意の形状をDelaunay Trianglesで生成する方法の論文。

Reeger et al.(2016)の論文ではHalton Sequenceなどで球面上の点を生成し、その点をもとにDelaunay trianglesを生成していたが、上記の論文ではいきなりDelaunay trianglesを生成しているようだ。

非球形粒子をDelaunay Triangles分割して、それぞれの点の物理量をもとに積分をすればいいのかもしれないが、積分時の係数の計算がよくわかっていない。

Reeger et al.(2016)では、球面三角形を平面三角形に変換した上で、総和を求めることで積分をしているが、座標変換時の係数の計算方法を理解できていない。
p178の$\tilde{A}W=\tilde{I}$を解いているようではある。

Reeger et al. (2016)で使っているRBFは論文のp180に記載されている$\phi(r) = r^7$の場合の$\alpha$と$\beta$からなる式。

### link

1) Reeger et al. (2016) Numerical Quadrature over the Surface of a Sphere by Jonah A. Reeger and Bengt Fornberg

2) [Power Pointファイル: Radial Basis Function Generated Finite Differences (RBF‐FD):Basic Concepts and Some Applications](https://icerm.brown.edu/materials/Slides/tw-17-5/Radial_Basis_Function-generated_Finite_Differences_(RBF-FD)-_Basic_concepts_and_some_applications_]_Bengt_Fornberg,_University_of_Colorado.pdf)

3) [Radial basis interpolation by @skitaoka さん](https://qiita.com/skitaoka/items/571b9ea840f0e6dea033)

4) [SVMでナントカデータを分析してみた by @hashikami さん](https://qiita.com/hashikami/items/6541e62c4e4b696a1199)
> 本課題ではRBFカーネル$exp(−\frac{1}{2\sigma^2}|x_i − x_j|^2)=exp(−\gamma|x_i − x_j|^2)$を用いた。
atコマンドで、指定時間後に自動終了させる

## 参考

* [IBM Knowledge Center - at コマンド](https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/com.ibm.aix.cmds1/at.htm)

```
apt install -y at
```

## 一分後にtopを終了する例

topを別に起動しておく。

```sh:
top
```

```sh:一分後にtopを終了する例
echo "killall top" | at now + 1 minutes
```

60秒後かと思っていたら、次の0秒に実行されるので注意。

minutes以外に使える文字は以下

```
minutes
hours
days
weeks
months
years
```

サービスを起動する指定時間帯を絞ったり、
一定時間起動したら電源を落とすとかできそう。

```sh:明日topを終了する例
echo "killall top" | at tomorrow
```

## atコマンドで実行予定の内容を確認

```sh:
# ジョブ一覧を表示
atq

# ジョブの詳細を表示
at -c 1
```
Google Analytics360のデータをBigQueryで分析するための基礎知識

Google Analyticsの有料版である「Analytics360」を導入すると、Google AnalyticsのRAWデータをBigQueryにエクスポートして分析することができる。非常に素晴らしいソリューションなのだが、あまり情報がないため、基本的な情報とリファレンスへのリンクを整理しておく。

（作成中）

# 前提知識
# Google Analytics360

- [機能全般 \| Google アナリティクス 360 – Google](https://www.google.com/intl/ja/analytics/360-suite/analytics/capabilities/)
- 導入相談→[Google アナリティクス 360の導入・運用支援ならNRIネットコム](https://www.nri-net.com/special/googleanalytics360suite/)
 
# BigQuery

- [BigQuery のドキュメント  \|  Google Cloud Platform](https://cloud.google.com/bigquery/docs/?hl=ja)


# GA360のBigQueryへのエクスポート

- Google Analytics360はRAWデータをBigQueryにエクスポートすることができる。
- GA360のデータをBigQueryにエクスポートするためには、予めGA360側で設定が必要になる。
- GA360のデータをBigQuery上にエクスポートするとエクスポートしたビューID(数字7-9桁)のデータセットが作成される。
- ga_sessions　テーブルにデータが格納される。
    - BigQuery上はエクスポートの日付ごとに　ga_sessions_YYYYMMDD　というテーブルが作成される。

![bq.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/a3c043a7-b919-7c16-ce7c-d14f74fc545b.png)



# BigQuery上のデータ構造
## データ構造のリファレンス
- 重要：GA360のエクスポートデータの構造はGoogleにより規定されており、以下のページで確認できる
    - [BigQuery Export のスキーマ \- アナリティクス ヘルプ](https://support.google.com/analytics/answer/3437719?hl=ja)

## BigQuery上のデータの単位（＝行の考え方）
- 重要：GA360のエクスポートデータの行はセッションに対応している。		
- 重要：ただし、１セッションの中に　ヒット（hits）単位で繰り返し　項目を持っている。	
- ヒットには、　ページ　と　イベント　のような種類がある		
    - ページ：セッション内でのページビューごとに自動生成（設定不要）
 - イベント：GA上でイベントをハンドリングするための設定をした場合のみ取得できる

## BigQuery上の重要な項目・概念（＝列の考え方）

[BigQuery Export のスキーマ](https://support.google.com/analytics/answer/3437719?hl=ja)のうち、特に重要な項目のみ抜粋しておく。

- fullVisitorId
    - Cookie単位にユーザを識別するID

- visitNumber
    - 当該ユーザのセッション数
- visitId
    - セッションのID
- hits.number
    - セッション内でのヒットの連番
- hits.type
    - ヒットの種類
- ページに関連する項目群
    - 参照したページのURLやタイトルは以下の項目に格納されている
        - hits.page
        - hits.page.pagePath
        - hits.page.pagePathLevel1
        - hits.page.pagePathLevel2
        - hits.page.pagePathLevel3
        - hits.page.pagePathLevel4
        - hits.page.hostname
        - hits.page.pageTitle 

- イベントに関する項目
    - イベントに関する情報は以下の項目に設定されている
        - hits.eventInfo
        - hits.eventInfo.eventCategory
        - hits.eventInfo.eventAction
        - hits.eventInfo.eventLabel
        - hits.eventInfo.eventValue
- ディメンション
    - GA上でデータを分析するための軸。
- カスタムディメンション
    - GA上で設定することで、自分で定義できるディメンション。
        - たとえば、ログインIDなどをカスタムディメンションに格納する、といった利用ができる。
        - customDimensions.index
        - customDimensions.value
Xcode のパスに半角スペースが入っているとき Pods/FirebaseCrash/batch-upload がエラー

batch-upload を実行すると、内部で `xcrun --find swift-demangle` が実行されて、
swift-demangle のパスを取得します。

このとき、利用中の Xcode.app へのパスに半角スペースが入っている環境では、
`No such file or directory` エラーになって、処理が完了しません。

swift-demangle へのパスは環境変数 SWIFT_DEMANGLE でも指定できるものの、
Xcode へのパスには半角スペースを入れない方が安全そうです。

```bash
export SWIFT_DEMANGLE="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-demangle"
```

なお swift-demangle が使えない環境では、`/bin/cat` で代替されるようです。

batch-upload が `Done.` と表示すれば、アップロード完了です。

```bash
    if [[ -x "${SWIFT_DEMANGLE:=$(xcrun --find swift-demangle 2>/dev/null)}" ]];
    then
        SWIFT_DEMANGLE_COMMAND="${SWIFT_DEMANGLE} -simplified"
    else
        SWIFT_DEMANGLE_COMMAND=/bin/cat
    fi
    fcr_mktemp SYMBOL_FILE
    "${DUMP_SYMS:="$(script_dir)/dump_syms"}" -a "${ARCH}" ${DWARF_COMPANION:+-g "${DWARF_COMPANION}"} "${EXECUTABLE}" | ${SWIFT_DEMANGLE_COMMAND} >|"${SYMBOL_FILE}" || return $?
```
Laravel(v.5.5) - Database: Migrations

## 見たやつ
[mySQLの型](https://www.dbonline.jp/mysql/type/)
[Laravelのmigrationでハマったときに見たやつ](https://qiita.com/Yorinton/items/3dbf6ad30358bd80fcb0)
[ER図をSequelが吐き出したdotファイルからgraphvisで作成する](https://qiita.com/suin/items/25cc0e9d6670a62f4d8e)

## Laravel以前にDB知識で知らなかったこと
* varcharはcharと違って、足りない文字数を空白埋めしない
* リレーションは同じ型じゃないと貼れない（intとmediumintとかはムリ）

## やったとこ
https://laravel.com/docs/5.5/migrations#creating-columns



## マイグレーションファイルの作成

テーブル作成するときも、テーブル更新するときもphp artisan make:migrationコマンドで作成。
Laravel側がマイグレーションファイルの更新を管理してるので、前のマイグレーションに巻き戻したりとかも出来るらしい。
make:migrationコマンドのオプションでcreateとtableってのがあって、これはテーブル名を指定するもの。
恐らくこれで紐付けて、マイグレーションファイルの更新を管理してる。
更新管理履歴？が書き込まれてるファイルは

* vendor/composer/autoload_classmap.php
* vendor/composer/autoload_static.php

### テーブル作成の場合

```
php artisan make:migration [file_name] --create [table_name]
```

これやるとdatabase/migration内にタイムスタンプ付きのファイルが生成される。

テーブル作成のコードの書き方は[ココ](https://laravel.com/docs/5.5/migrations#migration-structure)見ればおｋ。
up関数内をいじる。

### テーブル更新の場合
```
php artisan make:migration [file_name] --table [table_name]
```

これも同じ。まだやってないけどたぶんそう。

### マイグレーション
```
php artisan migration
```
これで作ったマイグレーションファイルを全部実行（たぶん）。
エラー出たりミスったときは

```
php artisan migrate:reset
```
でテーブルを削除できる。
でもエラーが起きたマイグレーションファイルのテーブルは中途半端になってるのかこれじゃ削除できないので手動で消した。

### リレーションでハマったところ
int型とmediumint型で外部キー設定しようとしたら出来なかった。
型は揃えよう。
[Laravelのmigrationでハマったときに見たやつ](https://qiita.com/Yorinton/items/3dbf6ad30358bd80fcb0)
に書いてあった

```
$table->engine = 'InnoDB';
```
とか

```
$table->string('id')->unique();
```
は俺の時は関係なかった。

とりあえずマイグレーションまで終わった。
[ネクスト](https://qiita.com/tom-ock/items/6e221f95da0c5c55b8eb)。
Docker上でgolangの開発環境を整える

#Docker上で簡単なgoの開発環境を整える

##環境

MacOS High Sierra 10.13.1 Beta
docker version 17.09.0-ce
go version 1.8.3

##ファイル構造

```
-app
 |-docker-compose.yml
 |-Dockerfile
 |-main.go
 |-templates
      |
      |-chat.html
```

##docker-composeをセットアップ

```docker-compose.yml
version: '3'
services:
  app:
    build: .
    ports:
      - "8080:8080"
```

##Dockerfile

```Dockerfile:Dockerfile
FROM golang:latest

WORKDIR /go
ADD . /go

CMD ["go", "run", "main.go"]

```

docker上のGOPATHはデフォルトで/goとなる。

##main.goを追加

サンプルアプリケーションを書きます

```main.go
package main

import(
  "log"
  "net/http"
  "path/filepath"
  "sync"
  "text/template"
)

type templateHandler struct {
  once sync.Once
  filename string
  templ *template.Template
}

func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  t.once.Do(func() {
    t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename)))
  })
  t.templ.Execute(w, nil)
}

func main() {
  http.Handle("/", &templateHandler{filename: "chat.html"})

  if err := http.ListenAndServe(":8080", nil); err != nil {
    log.Fatal("ListenAndServe", err)
  }
}
```

これで準備は完了です
実際に動かしてみてください

```
$ docker-compose up
```

```
$ docker-compose up
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled
on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Starting goapp_app_1 ...
Starting goapp_app_1 ... done
Attaching to goapp_app_1
```

こうなったら成功です

localhost:8080

に接続してchat.htmlの内容が表示されたらOK
【Golang】structのField名で気をつけるところ

Goの勉強を開始したのでメモ。
structのField名の違いで起こる挙動の違いについてまとめておきます。

(随時更新)

# 小文字で始まるField名は外部パッケージからのアクセスできない

ディレクトリ構成

```
.
|-- main.go
`-- mypkg
    `-- hoge.go
```

## 小文字の場合

~~~hoge.go
package mypkg

type Hoge struct {
    name string
    age int
}
~~~

~~~main.go
package main

import (
    "fmt"
    "./mypkg"
)

func main() {
    var x mypkg.Hoge
    x.name = "namae"
    x.age = 20
    fmt.Printf("x.name=%s, x.age=%d\n", x.name, x.age)
}
~~~

**実行結果**
各フィールドに対して`undefined (cannot refer to unexported field or method name)`というエラーが出る

## 大文字の場合

~~~hoge.go
package mypkg

type Hoge struct {
    Name string
    Age int
}
~~~
~~~main.go
package main

import (
    "fmt"
    "./mypkg"
)

func main() {
    var x mypkg.Hoge
    x.Name = "namae"
    x.Age = 20
    fmt.Printf("x.Name=%s, x.Age=%d\n", x.Name, x.Age)
}
~~~
**実行結果**
正しく`x.Name=namae, x.Age=20`という結果が得られる

# 小文字で始まるField名はencode/decodeされない

## 小文字の場合

~~~main.go
package main

import (
    "fmt"
    "encoding/json"
)

type Hoge struct {
    name string `json:"name"`
    age int `json:"age"`
}

func main() {
    b := []byte(`{"name":"namae", "age":20}`)
    x := Hoge{}
    json.Unmarshal(b, &x)
    fmt.Printf("x.name=%s, x.age=%d\n", x.name, x.age)
}
~~~
**実行結果**
エラーは吐かないが`x.name=, x.age=0`が出力され、decodeされていない。

## 大文字の場合

~~~main.go
package main

import (
    "fmt"
    "encoding/json"
)

type Hoge struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

func main() {
    b := []byte(`{"name":"namae", "age":20}`)
    x := Hoge{}
    json.Unmarshal(b, &x)
    fmt.Printf("x.Name=%s, x.Age=%d\n", x.Name, x.Age)
}
~~~
**実行結果**
正しく`x.Name=namae, x.Age=20`という結果が得られる

# まとめ

| | 外部パッケージからのアクセス | エンコード |
|:--:|:--:|:--:|
| 大文字始まり | 可能 | される  |
| 小文字始まり | 不可 | されない | 


# 参考

https://qiita.com/zurazurataicho/items/4a95e0daf0d960cfc2f7

http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/index.html#unexp_struct_field_enc
golangでQRコードを生成するパッケージを作ってみた

どうもはじめまして、qiitaには初めて投稿するプログラミング初心者です。
今年の夏ごろからgolangの本を読んでいて、golangを学ぶ過程でgolangで何か作りたいなと考えてQRコードを生成するパッケージを自作してみました。
[githubはこちら](https://github.com/taiga533/GO-QRMaker)
※あくまでもgolangの学習目的で制作したものであり、完全な動作は保証しませんのでご注意下さい。
※QRコードのバージョン情報はバージョン7までしか記録していないので、素の状態だとバージョン7までのQRコードが生成できます。
# 使い方
```go
package main
import (qrcode "github.com/taiga533/GO-QRMaker")

func main () {
  //pngとしてQRコードを出力します。
  //qrcode.SimplyEncode("QRコードにするデータ", "ファイルパス+ファイル名", 誤り訂正レベル[1~4], 画像サイズ[3倍なら3])
  err := qrcode.SimplyEncode("テスト文字列", ."/output/qrcode", 4, 2)
}
```
という感じです。
# 作るうえで苦労したところ
* 誤り訂正符号の実装  
JISの規格書(X 0510)を読めば分かる話なのですが、QRコードはBCH符号やRS符号といった誤り訂正符号を利用しQRコードの読み取り精度を上げています。  
この誤り訂正符号が数学に弱い私にとっては曲者で[ITレストラン様](http://itrestaurant.hatenablog.com/entry/2012/12/21/004734)や[yamicha.com's Blog様](http://void.yamicha.com/blog/?mode=view&number=703)を拝見しながら気合で実装しました。
* sliceを扱う  
golangにおける可変長配列であるsliceの扱いでコピー先の値を変更したらコピー元の値も変更されているとかをたまに忘れしまったりして苦労しました。

# 作ってみてよかったと思うこと
* golangに対する理解が深まった  
[スターティングgo言語](http://amzn.asia/bGmDulV)という本を読んだ後に作ったのですが、本を読むだけより良かったのかなと思います。
* QRコードにとても詳しくなった気がする  
すごいどうでもいいことですが最近街中でQRコードを見かけると（このQRコードのバージョンいくつだ？）とか思うようになった。

# 後悔とこれから
今回はできる限り自分で考えることを優先して作成したので、2進数を文字列で処理しているのがダメなポイントだと思っています。後からgithubなんかでgolangのQRコード生成パッケージを見ていたらしっかり数値として扱っていたので参考にすべきでした。
なので今後なにか作ったりするときは他人のコードも参考にしていこうと思います。
それに関連してマスク処理における（1:1:3:1:1の暗:明:暗:明:暗）のパターンの減点を実装しておりませんのでご注意下さい。
世界のナベアツをPythonの関数にしてみた

世界のナベアツ＝「3の倍数と3が付く数字の時だけアホになります」という芸を持つ芸人。
ということで、世界のナベアツをPythonの関数にしましたｗ

…以下のnabeatsu.pyの中で定義してるnabeatsu()がそれ。
1から引数に与えた数字まで評価し、数字が3の倍数と3が付く数字の時には"Aho"という文字列とその時の数字を、それ以外の時は数字を出力する。
残骸がいろいろ残ってるけどご愛敬ｗ

```Python:nabeatsu.py

import os
import sys

def nabeatsu(numb):
    keta = 1
    cnt = 1
    while True:
        if(10 ** (keta - 1)) == numb:
            break
        else:
            if(10 ** (keta - 1)) > numb:
                keta = keta - 1
                break
            else:
                keta = keta + 1

    print("%d" % keta)


    while True:
        if(cnt % 3) == 0:
            print("Aho %d" % cnt)
        else:
            if("3" in str(cnt)):
                print("Aho %d" % cnt)
            else:
                print("%d" % cnt)
        if cnt == numb:
            break
        else:
            cnt = cnt + 1

def main():
    nabeatsu(100)

if __name__ == '__main__':
    main()

```
ちょっとずつ読むドメイン駆動設計 第ニ部 モデル駆動設計の構成要素 第六章 ドメインオブジェクトのライフサイクル4(ファクトリ)

# ファクトリ　その１

> オブジェクトは蒸留して、その意味に関係しないものや相互作用において果たす役割をサポートしないものが一切残らないようにしなければならない。
> 複雑なオブジェクトに、それ自体を生成する責務を負わせると、問題が生じる。(第二部第六章より）

そのままですね。ドメインにおいて、意味を持たないオブジェクトや集約の生成・組み立てはファクトリに任せる。

ドメイン駆動設計で、オブジェクトを設計すると、エンティティやバリューオブジェクトでクラスがいっぱいになります。
これらの生成を集約のルートやオブジェクトのコンストラクタでやってしまうと、本来の集約やオブジェクトの仕事に余計な責務を負うことになります。それを分離するということですね。

## どこにファクトリを置くか

> 重要なのは、ファクトリの設計を掘り下げることではなく、ドメイン設計における重要なコンポーネントとして、ファクトリの居場所を示すことである。(第二部第六章より）

どこにファクトリを置くかが、つまり、**集約やオブジェクトを誰が生成するのかということが、重要なビジネスの関心事になる**ということですね

### 1. 集約のルート

例えば、既存の集約に要素を追加する場合などに適用できる。
DDD本の例では、"購入注文"(集約)が複数の"購入品目"を持っていて、さらに"購入品目"を追加する場合は、"購入注文"が追加分の"購入品目"を生成するということです。

### 2. 他のオブジェクトの生成に密接に関わるオブジェクト

DDD本の例では、"証券取引口座"が"取引注文"を生成しています。
注意点としては、"証券取引口座"が生成した"取引注文"を持つわけではなく、生成するのに適したオブジェクトだから生成する責務だけを持っているということですね。

### 3. 専用のファクトリオブジェクトかサービスを作成

自然な置き場所がない場合は**ためらわず**専用のファクトリオブジェクトを作りましょう。通常は集約全体を生成します。

### 4. コンストラクタでいい場合

構築が複雑ではなく、かつ、オブジェクトを使用する側が実装に関心がある場合。
コンストラクタ内では、他のクラスのコンストラクタを呼び出すのは避けることとあります。そこまで複雑ならばコンストラクタがそぐわないということですね。

４のケースはあまりない気がしますね。なので、基本は1〜３になるかと思います。

明日につづく。
CarrierWave でアップロード済みのファイルを別のサーバーにアップロード

アップロードされているファイルを別のサーバーに移行するために試したこと

```ruby
# avator.file : CarrierWave::Uploader
# another_directory: Fog::Storage::AWS::Directory etc
avator = Avator.first
[avator.file, *avator.file.versions.values].compact.each do |uploader|
  file = uploader.instance_variable_get(:@file)
  another_directory.files.create(
    {
      body: file.read,
      content_type: file.content_type,
      key: uploader.path,
      public: uploader.fog_public
    }.merge(uploader.fog_attributes)
  )
end
```

## file

CarrierWave::Uploader のインスタンス変数 `@file` に `CarrierWave::Storage::Fog::File` インスタンスがセットされているのでこれを活用する

## path

CarrierWave::Uploader#path をそのまま key に使う
[C言語]OpenSSLのBIGNUMで、指数がマイナスのときの計算

opensslのライブラリをC言語で使っていたら、ハマったのでメモ。

`bn.h` に `BN_mod_exp` という関数があるが、こいつで `n^(-2)` みたいな事をしようと思ったら、うまくいかなかった。

```
// 変数名とかやり方とかなかなかアレなんで、おおめにみてください。。
BN_set_word(shisu, 2); // shisu に 2　が入る
BN_set_negative(shisu, 1);  // shisu が -2 になる
BN_mod_exp(out, n, shisu, mod, ctx); // 計算
// out が変な値に...
```

`BN_mod_exp` はどうも負の指数の計算をうまいことしてくれないので、以下のように変更した。

```
BN_set_word(shisu, 2); // shisu に 2　が入る
BN_mod_exp(out, n, shisu, mod, ctx); // n^2 の計算
BN_mod_inverse(out, out, mod, ctx); // n^2 の逆元、つまり 1/n^2 を計算
// out が適切な値に！
```

`n^(-2)` を `1/n^2` として計算したらうまくいきました。

自分もわからないことだらけ(特に数学的に)なので、危うい情報ですがうまくいったのでメモしました。
mod の世界が故のナニカなのか。。
ただのBIGNUMの仕様なのか。。

用語ひっかけ:
負の指数
マイナスの指数
負の値
マイナスの値
べき乗
Unity から iOS の Speech で音声認識する

iOS10 で公開された Speech API ですが、もう iOS11 も出たという今頃になって、 Unity から使ってみたくなりました。
しかし plugin はどうやら誰も公開していなかったようなので、作ってみました。

## TL;DR

GitHub で公開していますので、 clone して使ってください。
https://github.com/noir-neo/UniSpeech

<img width="375" alt="Image uploaded from iOS.png" src="https://qiita-image-store.s3.amazonaws.com/0/21888/abc5cd75-ee9e-6619-8163-10f1271048c3.png">


## 使い方

### ISpeechRecognizer を実装する

```
public class SpeechRecognizer : MonoBehaviour, ISpeechRecognizer
{
    // 音声認識したときに呼ばれる
    public void OnRecognized(string transcription) { }

    // アクセスが承認されたときに呼ばれる
    public void OnAuthorized() { }

    public void OnError(string description) { }
    public void OnUnauthorized() { }
    public void OnAvailable() { }
    public void OnUnavailable() { }
}
```

### コールバックを受け取る GameObject の名前を登録する

`UniSpeech.SpeechRecognizer.CallbackGameObjectName = gameObject.name;`
サンプルプロジェクトでは Start() に書いています。

### ユーザーに音声認識へのアクセスの承認を求める

`UniSpeech.SpeechRecognizer.RequestRecognizerAuthorization();`
同じくサンプルプロジェクトでは Start() に書いています。

### 音声認識を開始する

`UniSpeech.SpeechRecognizer.StartRecord();`
サンプルプロジェクトでは OnAuthorized() に書いています。

## 実装の説明

### Swift での SpeechRecognizer の実装

https://github.com/noir-neo/UniSpeech/blob/master/Assets/UniSpeech/Plugins/iOS/SpeechRecognizer.swift

ほぼ [Apple のサンプルコード](https://developer.apple.com/library/content/samplecode/SpeakToMe/Listings/SpeakToMe_ViewController_swift.html#//apple_ref/doc/uid/TP40017110-SpeakToMe_ViewController_swift-DontLinkElementID_6)のままなので特筆すべきことはないです。


### Unity -> Swift のブリッジ

上記のサンプルが Swift だったり、情報量が逆転してきていて Swift で書きたかったので、こちらの plugin を使いました。
https://github.com/miyabi/unity-swift

これを入れればほとんどいい感じになるのですが、 objective-c での interface の定義だけは必要なので、3重定義になってしまうのはなんとか自動生成にしたいと思いました。

## さいごに

さすがに認識精度はかなり高いです。
Unity からモバイルで使える音声認識というと、まだ何かとハードルが高いのが現状ですが、マルチプラットフォームを捨ててサクッとネイティブの機能を使うという選択肢も用意してみました。

Android も同じように音声認識の API が公開されているので、インタフェースを揃えたプラグインにしたら便利そうだなとは思いましたが、特にやる予定はありません。

また native -> Unity に string 以外を返そうとすると面倒なので今回は端折りましたが、 bestTranscription 以外も返すようにするとか、使い勝手の改善の余地はあって、それは気が向いたらやっていきます。
Google Homeでうんこなう

Google Homeを手に入れたので、[Amazon Dash Buttonでうんこなう](https://qiita.com/daikiojm/items/0d2840761299bcc66eff) に引き続き、「Google Homeでうんこなう」 を実現してみようと思います。

# Google Homeのセットアップ

Wi-Fiに接続されたスマートフォンでGoogle Homeアプリを起動して、画面に表示される手順に従ってセットアップを行います。


# IFTTTのセットアップ

## Twitter連携

IFTTTの[Twitter](https://ifttt.com/twitter)のページの「Connect」から、つぶやくアカントと連携しておきます。

<img width="766" alt="スクリーンショット 2017-10-12 0.20.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/20b203e1-52c0-5abe-b2fb-7d83eb7fb8c9.png">


## Google Assistantの連携

IFTTTの[Google Assistant](https://ifttt.com/google_assistant)のページの「Connect」から、使用するGoogle Homeに紐付けてあるGoogleアカウントを選択して連携設定をしておきます。

## Appletの作成

[New Applet](https://ifttt.com/create)から、「+This」側にGoogle Assistantを選択します。
次の選択肢が出てくるので、「Say a simple phrase」を選択します。

<img width="979" alt="スクリーンショット_2017-10-12_0_23_49.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/2b901a21-4403-389d-ed4d-c7cb3fceec7b.png">

次のように、Google Assistantが反応する語句、それに対する応答語句を設定します。

<img width="436" alt="スクリーンショット_2017-10-12_0_29_11.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/bfaeab0d-7a11-36d8-928a-61c98bf16f49.png">

画像を見て分かる通り、「うんこなう」ではなく「うんこ now」や「うんこnow」と設定すると、正しく認識するようです。



次に、「+That」側に、Twitterを選択します。
次の選択肢が出てくるので、「Post a tweet」を選択します。

<img width="698" alt="スクリーンショット_2017-10-12_0_34_08.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/9b9dcc87-652a-4255-348a-c870e54bd81a.png">

次の画面では、実際にTwitterにつぶやく語句を設定します。
Twitterの制約で連続して同じ内容をツイートできないので、`{{CreatedAt}}`でツイート時の時刻情報を付加します。

<img width="537" alt="スクリーンショット 2017-10-12 0.35.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/3f22aad3-4cb1-eb37-204d-90c204ade543.png">



# うんこしてみる

用を足した際に 「うんこなう」 とGoogle Homeに話しかけます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「おっけーGoogle うんこなう」 <a href="https://t.co/lAC38Vc0eZ">pic.twitter.com/lAC38Vc0eZ</a></p>&mdash; Daiki (@daikiojm) <a href="https://twitter.com/daikiojm/status/918147735575916545?ref_src=twsrc%5Etfw">2017年10月11日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>



# 課題

## ツイートにCreatedAtが付加されない問題

IFTTTのツイート文言に設定した、`{{CreatedAt}}`が実際のツイートには付加されていないようです。このままでは、連続してツイートが出来ないので、改善が必要です...

## 設置場所問題
スマートスピーカーの特性上、Google Home本体が操作者の声が届く範囲に設置されていなければなりません。そのため、トイレでうんこなうをしたい場合、トイレにGoogle Homeを設置するか、トイレのドアを開けた状態で用を足さなければいけなそうです。
普段からドアをかけたままする派の人にとっては問題なさそうですが、ドアをしっかりと締める葉の人にとっては設置場所問題は大きな課題だと思います。

# 所感

今まで、Arduino + RaspberryPi、Amazon Dash Buttonとうんこなうを実現するデバイスを変え、色々試してみましたが、今回試したGoogle Homeが今までで一番うんこなうに適したデバイスだと感じました。(課題はあるが...)
Amazon Echoも年内に国内で発売するということで、今年もスマートスピーカーでうんこなうを盛り上げて行きたいと思います💩

# 参考

https://qiita.com/kazunori279/items/fdadbfde58ed133bb9d5
CarrierWave 複数のファイルサーバーに同時アップロード

CarrierWave で config 設定したサーバー以外にもアップロードしようとしてやってみたこと

# 概要

- 別のファイルサーバーの directory を定義
- `store` のコールバックを使って同じファイルを別のサーバーにもアップロード

## directory

別のサーバーの設定で別の directory を定義する

参考 https://github.com/carrierwaveuploader/carrierwave/blob/v1.2.1/lib/carrierwave/storage/fog.rb

```ruby
class AvatorUploader < CarrierWave::Uploader::Base
  def another_directory
    @another_directory ||= begin
      another_connection.directories.new(
        key: 'BUCKET',
        public: fog_public
      )
    end
  end

  def another_connection
    @another_connection ||= ::Fog::Storage.new(another_options)
  end

  # provider, access_key 等の config
  def another_options
    {
      # ...
    }
  end
end
```


## after_store でアップロード


### 引数

after_store のコールバックには引数に `new_file` が渡されるがファイルアップロード時には `nil` となっている
https://github.com/carrierwaveuploader/carrierwave/blob/v1.2.1/lib/carrierwave/uploader/store.rb#L56

### ファイル

アップロードしたファイルは `@file` に `CarrierWave::Storage::Fog::File` インスタンスとして存在するが
アップロード直後の after_store では `@file.read # => ''` となる
(原因調査中) 

そこで必要な値を渡して Fog から新しくファイルを取得する


```ruby
class AvatorUploader < CarrierWave::Uploader::Base
  after :store, :upload_to_another

  def upload_to_another(_new_file)
    new_file = CarrierWave::Storage::Fog::File.new(self, storage, store_path)
    another_directory.files.create(
      {
        body: new_file.read,
        content_type: new_file.content_type,
        key: store_path,
        public: fog_public
      }.merge(fog_attributes)
    )
  end
end
```

## その他

各 versions の after_store で実行されるので全ての versions で対応できている
FPGAでHDMI出力（Full-HD）：その③動作確認

[FPGAでHDMI出力（Full-HD）：その②エンコード/パラシリ変換](https://qiita.com/cyebu1103/items/3de26a84cc57e6c48a66)のつづき


#UCFファイル

[ATLYSボード](http://store.digilentinc.com/atlys-spartan-6-fpga-trainer-board-limited-time-see-nexys-video/)の構成に合わせてピンの設定を以下のようにします。

```ucf:pin.ucf
NET "o_HDMI_CLK_p" LOC = "B6" |IOSTANDARD = TMDS_33 ; # Clock
NET "o_HDMI_CLK_n" LOC = "A6" |IOSTANDARD = TMDS_33 ;
NET "o_HDMI_RED_p" LOC = "B8" |IOSTANDARD = TMDS_33 ; # Red
NET "o_HDMI_RED_n" LOC = "A8" |IOSTANDARD = TMDS_33 ;
NET "o_HDMI_GRN_p" LOC = "C7" |IOSTANDARD = TMDS_33 ; # Green
NET "o_HDMI_GRN_n" LOC = "A7" |IOSTANDARD = TMDS_33 ;
NET "o_HDMI_BLU_p" LOC = "D8" |IOSTANDARD = TMDS_33 ; # Blue
NET "o_HDMI_BLU_n" LOC = "C8" |IOSTANDARD = TMDS_33 ;
```


# 動作確認

実機で動作確認し、Full-HDサイズで画像が映ることが確認できました。

ここまでピクセルクロック＝148.5MHzとして説明してきましたが、148.5MHzだとデータ化けがあるのか画像のちらつきがありました。
最終的には140MHzにしています。


![DSC_2729.jpg](https://qiita-image-store.s3.amazonaws.com/0/204268/dbc6d6d8-2ac5-5615-03f5-4b9684fd1c97.jpeg)
写真では分かりづらいですが、黒い十字はななめに移動しています。
![DSC_2730.jpg](https://qiita-image-store.s3.amazonaws.com/0/204268/f1457657-86ac-d550-bd8c-7068ad6a8acd.jpeg)

## 1080pの30fps対応
ピクセルクロック周波数を30fps対応の74.25MHzにすると、30fpsで画像表示できます。

ただし、パソコン用のモニタだと30fpsに対応していない機種が多いので注意ください。
（テレビは映る場合が多いです。）


#まとめ
SPARTAN6 FPGAでHDMI出力することができました。
今後はカメラ画像を取り込んでHDMIから出力してみようかと思っています。

今回作成したモジュールですが、SERDESE部分はSpartan6用のハードマクロを使用しておりますので、
他のデバイスを使用しているかたは、デバイスに合わせて直す必要があります。
OctoPiでUSB Webcam

# 概要
OctoPiにUSB Webカメラを付けても映らないので/boot/octopi.txtを修正して映るようになった。

# 環境
* OctoPrint version : 1.3.4
* OctoPi version    : 0.14.0
* Raspberry Pi 2
* USB Webカメラ    : AliExpressで買った箱にも入っていないノーブランド

# 手順

1. [OctpPi](https://octopi.octoprint.org/)に従ってMicro SDカードにインストール
2. USB WebカメラのDevice IDを調べる。
  Class=VideoのDevを見る。

    ```コマンド
$ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/5p, 480M
        |__ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=smsc95xx, 480M
        |__ Port 3: Dev 4, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
        |__ Port 5: Dev 5, If 0, Class=Video, Driver=uvcvideo, 480M
        |__ Port 5: Dev 5, If 1, Class=Video, Driver=uvcvideo, 480M
        |__ Port 5: Dev 5, If 2, Class=Audio, Driver=snd-usb-audio, 480M
        |__ Port 5: Dev 5, If 3, Class=Audio, Driver=snd-usb-audio, 480M
```

3. USB WebカメラのProduct IDを調べる。
  2.で調べたDevice IDと同じ行のIDがProduct ID。 例では"1908:2310"

    ```コマンド
$ lsusb
Bus 001 Device 005: ID 1908:2310 GEMBIRD 
Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```

3. `/boot/octopi.txt`に下記2行を追加。
  2行目の""で囲われた中に3.で調べたProduct IDを入れる。

    ```/boot/octopi.txt
camera="auto"
additional_brokenfps_usb_devices=("1908:2310")
```

6. Raspberry Piを再起動

### 動いた！
ソフトウェアテストとは

# テストの役割とは
## テストは情報を見つけ出すこと。
ただ行うだけでなく、目的を意識する必要がある。

- 重要なバグを見つけ出すため？
- 品質の評価のため？
- テストプロセスの評価のため？

機械的に作業を行うのではなく、常に疑問を持ち続けることで新しい発見が生まれる。

## ステークホルダー
PM, プログラマ, ドキュメントライター, 経営陣・株主, ユーザー
特に、「テスト担当者 = ユーザーの代弁者」であり、サービスの対象者の基準で製品価値を評価するべき。

## 真理は、重要なバグを素早く見つけること。
そのためには、その機能やプログラムの内容を理解し、ユーザーの心理をよく把握する必要がある。

## プログラマとの協力
テスト結果を素早くフィードバックして、効率よくPDCAを回すことが理想。

## テストとは、ものを壊すネガティブな役割を担う
テストの目的は、「プログラムが正しく動作することを検証する作業」ではない。
プログラムの失敗、すなわちバグに注目すると、効率よくバグを叩き出せる。
限られた時間は有限であり、その時間をどう使いバグを見つけるか考える必要がある。

## 「テスト完了しました」とは
- プログラム中の全てのバグを見つけた
- プログラムのありとあらゆる箇所をチェックした
- テスト仕様書の項目を全て確認した
- 現状において確認できる範囲でのテストケースを完了した

「完了した」「終了した」「実施した」を分け、誤解を防ぐこと。

## テストのみで品質は保証できない
品質を作り込むのは開発者であり、テスト担当者はそれをサポートする。
テスト結果や障害レポートは、品質保証を推進する上で重要な役割であるが、品質保証はチームの総力を結集して初めて可能になる。
【Firebase】日付順にソートする方法

angularFireでionicとFirebaseを連携させた家計簿アプリを作っています。
https://qiita.com/irohamaru/items/3df901cd7e12e3c85e9a

その中で、Firebaseから受け取ったテーブルの一覧を日付順（日付もテーブルの一項目）にソートする方法をメモしておきます。

##うまくソートされないパターン

javascriptでは日付を扱う場合、いろいろと注意が必要だそうです。
https://qiita.com/labocho/items/5fbaa0491b67221419b4

date型（例：Mon Sep 01 2017 00:00:00 GMT+0900）を「YYYY/MM/DD」のフォーマットに変換したかったので、toLocaleDateStringというメソッドを使うことに。

ただし、toLocaleDateStringは「月」「日」が１桁の場合にゼロパディングしてくれないらしいです。
https://so-zou.jp/web-app/tech/programming/javascript/grammar/object/date.htm

そのためか、普通にソートしようとしてもうまくいきませんでした。

↓angularfireでのorderby実装についてQ&A
https://github.com/angular/angularfire2/blob/master/docs/rtdb/querying-lists.md


```ts:sample.ts
// テーブル：sampleのカラム:dateの昇順でソート
  db.list('/sample' , {
    query {
      orderByChild: 'date'
    }
  });
```

↓ソートがうまくいっていない例
![スクリーンショット 2017-10-12 0.49.21.png](https://qiita-image-store.s3.amazonaws.com/0/186221/7ff763c9-c3a7-33be-3ac6-8ef57104ada6.png)



##日付のフォーマットを整える

YYYY/MM/DDの形式であれば正しくソートされると仮定し、日付をゼロパディングするための関数を作って補完することにしました。

```ts:sample.ts
  // Firebaseにデータ登録
  this.sample.push({
    date: this.convertDate(date.toLocaleDateString()),
    name: this.name,
    money: this.money
  });

  // 日付ゼロパディング用関数
  convertDate(date) {
    var tmpDate = date;
    var tmpYear = tmpDate.getFullYear();
    var tmpMonth = tmpDate.getMonth() + 1;
    var tmpDay = tmpDate.getDate();
    var strYear = tmpYear.toString();
    var strMonth = tmpMonth.toString();
    var strDay = tmpDay.toString();

    if (tmpMonth < 10) {
      strMonth = '0' + tmpMonth.toString();
    }
    if (tmpDay < 10) {
      strDay = '0' + tmpDay.toString();
    }
    return strYear + '/' + strMonth + '/' + strDay;
  }
```

##結果

うまくソートされました。

![スクリーンショット 2017-10-12 1.05.31.png](https://qiita-image-store.s3.amazonaws.com/0/186221/a9d8950e-38db-2e66-b2eb-6c4d31775a15.png)
icalBuddyとgeektoolを用いて、icalのまだ残ってる予定だけをデスクトップに表示できるようにした


## はじまり

次の予定が思い出せなくなる度にicalを開いて確認するのも億劫なので、`icalBuddy`と`Geektool`を用いて、デスクトップにicalを表示してくれるようにしてました。
この辺りの設定の仕方はいろんな方が書かれているので、略します…

### [icalBuddy](http://hasseg.org/icalBuddy/)とは

icalのデータをコマンドラインで取得できるようにしてくれます。最終更新はかなり前ですが、問題なく使えます。locationやnotesも出力してくれて便利なので、使い始めました。

### [Geektool](https://www.tynsoe.org/v2/geektool/)とは

デスクトップを柔軟にカスタマイズできるアプリケーションです。以下の形式のデータをデスクトップに表示できるようにしてくれます。

* Logs
* Script
* Image
* Web

## 気になってたこと

`icalBuddy`のおかげでカレンダーごとに色がついて表示してくれたり、一日ごとに区切って表示してくれたり、と至れり尽くせりだなとは思うものの

 **今日の終わった予定は表示されない方が嬉しいなぁ**

と感じたので、`icalBuddy`の出力を変換するシェルスクリプト`RemSch.sh`を書いてみました。

## [RemSch](https://github.com/yoshi65/RemSch)(remaining schedule)について

名前は短絡的ですが、**remember**もかかってるようでうまく収まってるなと思ってます。

終わった予定を表示しないようにするついでに、デスクトップに表示されてても嬉しくないデータを非表示にしてしまうようにしました。

環境はzshです。学生として研究室に所属してからなので、触り始めてまだ半年の稚拙なシェルスクリプトにはなってますが、なかなか良いなぁと勝手に思ってます。

### 仕様について

#### 一般的なお話

日毎の表示で並んでいるからこそメリットがあると思うので、デフォルトの元データは

```zsh:default.sh
icalBuddy -sd eventsToday+1
```

となっていて、常に`-sd`オプションは適用されます。オプションとして、`icalBuddy`のオプションのいくつかをそのまま選べるようにしました(正直普段自分が使っているやつだけです)。`-f`,`-nc`に関してはそのままで、`-num NUM`だけは`eventsToday+NUM`となるようにしてあります。

```
optional arguments:
  -f		Format output
  -nc		No calendar names
  -num NUM	Print events occurring between today and NUM days into the future
```

予定が終わっているかは24時間制の`hhmm`で現在時刻と、予定のical上での終了時刻を比較して、判断しています。
終日の予定は表示されたままになるようになっています(まだlocationやnotesが入っていない場合しか動作しないので、思い立った時に改善します)。

#### 個人的なお話

私の普段使いではgoogle calendarも読み込んでいることもあってか、`note`におけるhangoutsと`attendees`が表示されてしまうのが幅をとって鬱陶しかったので、そちらも表示されないようになってます。
以下のような感じで表示されていたので、雑な作りにはなりますが、`-::`を含む行の間と`attendees`を含む行を削除しています。

```zsh:display_sample
• test (fuga@foo.com)
    location: hoge
    notes: -::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-
           説明のこのセクションは編集しないでください。

           この予定には Google ビデオハングアウトが含まれています。
           参加: https://plus.google.com/hangouts/_/calendar...
           -::~:~::~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~:~::~:~::-
    attendees: hoge, hage, bar
    18:00 - 20:00
```

## 感想

衝動的に踏み出した初投稿なので、読んでくれる方がいたら歓喜です。問題のある仕様や記載があれば、教えていただけると助かります。

## 参照元
[icalBuddy](http://hasseg.org/icalBuddy/)
[Geektool](https://www.tynsoe.org/v2/geektool/)