OmniAICreator/Qiita-1.07M huggingface dataset:
Nature Remoで測定した室温をThingSpeakに渡して表示。

# 背景
暑くなってきたので、部屋の温度や湿度を定期的に計測したいなと思い始めた。
ラズパイやESP32にセンサーつけて使ってもいいんだけど、子供が触りそうで怖い。
NatureRemo使ってて、せっかくそこで温度を測定してるんやから、それでいいんじゃないか。
最近使ってないGCPのVMインスタンスがあるので、そこからAPI叩いたらいいんじゃないか。

# やったこと
- NatureRemoのAPIをたたいて、温度をゲット
- ThingSpeakのAPIをたたいて、温度をアップロード

データのながれはこんな感じ↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/8fc66b13-cf96-e9ca-d9d7-6466c17f46f6.png)

# 使った環境
- GCPのVMインスタンス。無償のやつ。
- python3
- Nature Remo
- ThingSpeak

# コード
Nature RemoのAPIは昔叩いたことあったので、昔のコードを流用した。
xxx, yyy, zzz, aaaはNature RemoとThingSpeakのサイト見てそれっぽい値を入力。
thingspeakはライブラリを発見したので、それを使ってみた。

```python
import requests
import json
import thingspeak
import time

headers = {
    'accept': 'application/json',
    'Authorization': 'Bearer xxx',
}

ch = thingspeak.Channel(id=yyy, api_key='zzz', write_key='aaa', fmt='json', timeout=None)

while True:
    response = requests.get('https://api.nature.global/1/devices', headers=headers)
    data = response.json()
    temp = data[0]['newest_events']['te']['val']
    print(temp)
    humi = data[0]['newest_events']['hu']['val']
    print(humi)
    res = ch.update({1: temp, 2: humi})
    print(res)
    time.sleep(30)
```
nohupつけて実行すれば、ログアウトしてもずっと動く。
```
nohup python Remo2TS.py &
```

# 結果
30秒間隔じゃ全然温度かわらん。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/2452cc3b-e956-cc26-1e3e-713b8172adff.png)

# 最後に
そこそこ有用そうな仕組みを簡単に作れる。すばらしい。
そのうち外気温もどっかから持ってきて、比較できるようにしたい。

# 参考にしたとこ
## Nature Remo
[Nature Inc](https://developer.nature.global/)

## ThingSpeak
[thingspeak/examples at master · mchwalisz/thingspeak · GitHub](https://github.com/mchwalisz/thingspeak/tree/master/examples)
[Python binding for ThingSpeak API — thingspeak 0.4.1 documentation](http://thingspeak.readthedocs.io/en/latest/index.html)

# python
[Python3で一定間隔で処理を行う - Qiita](https://qiita.com/miminashi/items/50a4f0906ab8f18b105d)
結婚式のためにリアルタイムスライドショーを作ってみる〜概要編〜

# はじまり
近々結婚式を行うことになり、余興についての情報を調べていたところ、リアルタイムスライドショーが流行っている(?)と知りました。
参列者にスマホなどで写真を送ってもらい、それを会場のスクリーンにリアルタイムで映し出すそうです。
参列者が主体的に参加できるという点では面白そうですが、なかなか良いお値段がします……。

というわけで自分で似たようなものを作ってみることにしました。

# 事例
パーティー用のリアルタイムスライドショーを作るというのは、結構されているみたいです。

1. [結婚式でLINE Message APIを使った写真共有サービスを作った話 - tomoima525's blog](http://tomoima525.hatenablog.com/entry/2017/10/16/192325)
2. [親友の結婚式二次会のためにAngularJSでリアルタイムスライドショーを開発した話](https://kt-kiyoshi.com/wp/2017/02/11/realtime-slide-show-by-angular/)

私は学生時代にPythonで数値計算したり、今はMATLABで数値計算したりするぐらいで、アプリケーション開発に関してはほとんどわかりません。
HTMLとCSSは大学の研究室のHPを数カ月管理していた程度。

バックエンドまで開発するのは難しいと判断したので、今回はフロントエンドだけ開発することにしました。
先の事例で言うと2番めの形になります。

# アプリケーションの構成
アプリケーションの構成は事例2とほとんど同じです。

今のところ次のような流れで行きたいと思います。

1. Dropboxのファイルリクエストを使い、参列者のスマホから写真を送ってもらう。
2. Dropboxのフォルダをパソコンのローカルのフォルダと同期する。これにより、リアルタイムに写真を取得する。
3. フォルダのファイル一覧を元に、JSONファイルを生成する。これはシェルスクリプトで実装する。
4. ローカルに保存した写真とJSONファイルを元に、スライドショーを表示する。スライドショーはjQueryで実装する。

jQueryを選んだのは、私がJavaScript初心者なので情報が多い技術を使ったほうがよいだろうとの判断です。
個人的に使う小規模なアプリケーションなので、速度の遅さもそんなに問題ないのではと考えました(使ってみないとわかりませんが……)。

スライドショーの実装には[slick](http://kenwheeler.github.io/slick/)を使ってみたいと思います。
なんとなく使い方がわかったら次回あたりでまとめます。

# (追記)目標

- 100人程度のパーティーで使えるようにする。
- スマホ側には特別なアプリをインストールしないようにする。
- 参列者が写真がリアルタイムに反映される様子を実感できるようにする。
- 安定した挙動(式中は流石にデバッグできない……)
AWSでMFAデバイスが壊れた＆電話認証できないときの対応

# TL;DR
- AWSで多要素認証（Multi-Factor Authentication, MFA）を利用していて、認証に使っているスマホが壊れたら、事前にAWSに登録しているアカウントの電話番号に電話がきて復旧できる
- 電話認証できないと、書類での本人確認が必要で、その中に公証人による認証が必要な書類があって手間がかかるので注意
- 今回の教訓としては引っ越したり電話番号が変わったらすぐにAWSアカウントの登録情報を更新したほうがいい。電話番号は固定じゃなく携帯にしたほうがいい。
- 加えて、MFAはバックアップ（iPhoneの場合、暗号化してバックアップするとMFAもバックアップできる）やマルチデバイス（[Authy](https://authy.com/)とか）で使ったりできるので、対応しておいた方がいい。

MFAはバックアップやマルチデバイスでは使えないと思い込んでて（だってそれができたらMFAの意味なくない？と思っていた）調べてもいなかったのが悔やまれる。あとはQRコードをバックアップしている人もいるらしいが、それはどうなんだろうか？

# 参考にした記事
[もしもAWSでMFAが壊れて秘密の質問に答えられなかったら](https://qiita.com/sashimizakana/items/a1a965178ea6b1af991a)
[AWSのMFAを解除するためにアメリカ大使館に足を運んだ話](https://qiita.com/kechol/items/9de7bbc607b5c608c77b)
[AWS の MFAキーを紛失するとやばい](https://takanamishi.hatenablog.jp/entry/2016/04/06/234122)

# 経緯
2月中旬に会社が移転し住所や電話番号が変わる（が、AWSのアカウント情報を更新していなかった←これが失敗）
5月後半にAWSのMFAにしていたスマホが突然電源が入らなくなる。最近はあまりAWSを使っていなかったのでMFAのことにはまだ気づいていない
6月になってから、MFAを再設定しようと思って調べたら電話認証があることを発見
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html

が、ここでAWSに登録していた電話番号を更新していないことに気づく。
カスタマーサポートに電話したら書類を提出することでMFAを解除できるとのこと。

# MFA解除に必要な書類
1. [Identity Verification Form and AffidavitというAWS指定の書類](https://s3.amazonaws.com/AWSCS_CustomerForms/IdentityVerificationFormAffidavit.doc)
2. パスポートか運転免許証
3. AWSアカウントで登録した住所が記載されたISPや電気代の料金明細など

# 公証人による認証
参考にした記事にもある通り、AWS指定の書類には公証役場というところで、自分が署名したことを証明してもらう必要がある。アメリカ大使館までは行かなくてもいいが、公証役場というところで証明してもらう必要がある。開いてるのは平日9時〜17時。AWSの書類が英語なので公証役場では外国文認証というものに該当するらしい。
費用的にはアメリカ大使館の方が安いかも。上の記事によるとアメリカ大使館では50ドル、公証役場だと11,500円。

公証役場によって対応が違うようで、自分が行った公証役場では、外国文認証には予約が必要だった。和訳が必要なところもあるようだが、内容が説明できればいいとのことでそれはいらなかった。けど、自分で理解するために結局和訳したので今後の参考に公開しておく。認証自体は結構すぐ終わった。あと、書類の提出先国を伝える必要があって、アメリカなのか日本なのかAWSに問い合わせたらアメリカということだった。
外国文認証にはアポスティーユとかいう外務省がその書類を認証したという方法もあるらしいが、今回はそこまではいらなかった。

# 和訳
身分証明書と宣誓供述書
この書式は、公証人が有効であることを確認する必要があります。
Amazon Web Services、Inc.が提供するWebサービスへのアクセス要求、またはこれらのサービスの継続のため、私＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿(署名者)は、以下を宣言します：

1.この宣誓供述書は、以下のアカウントに関係します（* は必須です）。
アカウントのメールアドレス：＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
AWSアカウント番号（わかっている場合）：＿＿＿＿＿＿＿＿＿＿
アカウント名 *：＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
請求先住所 *：＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
市、都道府県、郵便番号 *：＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
電話番号：＿＿＿＿＿＿＿＿＿＿＿＿＿＿

追加の質問がある場合は、このメールアドレスまたは電話番号でお客様に連絡することに同意するものとします。

2.私は上記で参照したアカウントの所有者であり、多要素認証が削除されることを要求しています。

3.私は故意に虚偽または詐欺的な陳述または表明をすることは、連邦、州または地方の刑法を侵害する可能性があり、罰金または懲役またはその両方を課す可能性があることを理解しています。

署名＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿　　　　　日付＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿

以下、公証人専用
都道府県＿＿＿＿＿＿＿＿＿＿　　　　市区町村＿＿＿＿＿＿＿＿＿＿＿＿＿＿

私はこれを証明する。＿＿＿＿＿＿＿＿＿＿＿＿＿が自ら本職の面前に現れ、上記に署名された者であることが十分に証明されており、上記の目的のために行動していることを認めた。
上記を、20＿＿年の＿＿月の＿＿番目の日に証明します。
私の委任は (日付) にて期限が終了する ：＿＿＿＿＿＿＿＿＿＿＿＿＿＿
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
（ブロック体での名前）
＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
（公証人の署名）

# そしてMFA解除
書類を3点揃えてカスタマーサポートにメールで送ったら、しばらくしてメールが来て解除されたとのこと。引っ越し＋スマホが壊れるというレアな出来事が重なったとはいえ、結局、問い合わせをはじめてから10日くらいかかった。頻繁に使ってない時期でよかった。次は絶対バックアップ作るぞ。
[subversion]指定ファイルの最新ログから任意の情報を取得したい

svnの更新通知がほしいなぁ。
でもフックスクリプトをsvnサーバーへ置く権限はないなぁ。。。
ログから必要な情報を取得して通知する機能を実現してみよう
　⇒ 今回はログから必要な情報をパースするためのスクリプトを書いてみる

# 対象
- subversionを使用している
- 指定ファイルの最新ログがほしい
- 指定ファイルのリストは別ファイルとして持っていたい
- 全部ではなく必要な情報だけほしい
- Rubyでやってみたい(Rubyしか使えない)

# 準備するもの
- Rubyが動く環境

# ファイル構成
```
./list      ：svnのファイルパスが書かれたファイル
./svnlog.rb ：ログ取得、パースを行うrubyスクリプト
```

# ファイルの内容
listへはログを出力したいファイルパスを列挙

```list:list
svn://<ファイルパス>
http://<ファイルパス>
```

```ruby:svnlog.rb
#!/usr/bin/env ruby
#listに記載されたファイルの最新ログをxml形式で取得し、必要な情報をパースするためのrubyスクリプト

require 'rexml/document'

#listの内容を1行ずつ読み込む
files = []
File.foreach(ARGV[0]) do |line|
  files.push(line.chomp)
end

#svnからlistの記載されたファイルの最新ログをxml形式で取得
logs = []
for file in files do
  command = "svn log -l 1 --xml " + file
  log = `#{command}`
  logs.push(log)
end

#日付/コミットユーザー/コメントをログからパース
dates = []
authors = []
comments = []
for log in logs do
  xml = REXML::Document.new(log)
  dates.push(xml.elements['log/logentry/date'].text)
  authors.push(xml.elements['log/logentry/author'].text)
  comments.push(xml.elements['log/logentry/msg'].text)
end

puts(dates)
puts(authors)
puts(comments)
```

# 実行方法
- list, svnlog.rb があるフォルダへ移動し、下記コマンドを実行

```bash
ruby ./svnlog.rb list
```
[Swift] firebase ってこうやったら気持ちいいのでは？

ついさっき触り始めたばかりだけど、observeがごちゃごちゃして読みにくくなるので考えてみた。

```swift
import FirebaseDatabase

protocol DataBuilder {
    
    associatedtype Output
    
    func build(snapshot: DataSnapshot) -> Output?
}

extension DatabaseQuery {
    
    func observe<B: DataBuilder>(_ type: DataEventType, builder: B, with handler: @escaping (B.Output) -> Void) -> DatabaseHandle {
    
        return observe(type) { builder.build(snapshot: $0).map(handler) }
    }
}
```

これで、例えばこう。

```swift

struct StringBuilder: DataBuilder {
    
    func build(snapshot: DataSnapshot) -> String? {
        
        return snapshot.value as? String
    }
}
```

すると、すっきりする。

```swift

override func viewDidLoad() {

    db = Database.database().reference()
        
    handler = db.child("child").observe(DataEventType.value, builder: StringBuilder(), queue: .main) { string in
            
        self.field.stringValue = string
    }
}
```

追記：
実践的にするには`DataBuilder#build(snapshot:)`を throwsに変えて  handler を `(B.Output, Error) -> Void` とするか`Result`を導入して `(Result<B.Output>) -> Void`とするのがいいと思います。
Docker上でRspecを実行するとmysqld.sockが無いって言われる

##結論
※development環境でテストを行いたい場合

rails_helper.rbでは
デフォルトでtest環境が当てられているので、
それをコメントアウトして、使いたい環境のものに変える

```ruby
#ENV['RAILS_ENV'] ||= 'test'
ENV['RAILS_ENV'] = 'development'
```



##原因
development環境でテストを流したかったけど
Rspecがtest環境を見ていたため、
database.ymlの情報と不整合が生じたため。

##出現したエラー文
hogeとhugaは各自のエラーメッセージを参照してください。

```
Failure/Error: ActiveRecord::Migration.maintain_test_schema!

Mysql2::Error:
  Can't connect to local MySQL server through socket '/hoge/huga/mysqld.sock' (2 "No such file or directory")
```


##終わり
Rspecで最初にハマるとこはこの環境が一致してない問題だと思う。

Railsがdevelopmentなので
Rspecも勝手にdevelopmentを見るものだと勘違いしてました。

勘違いって怖いですよね。

短いですが終わります。
テストコード関連も今後ストック増やしてきますー！
Peeweeで外部キーを指定しても有効にならなかった

#きっかけ
on_deleteにCASCADEを指定したのに参照先レコードを削除しても一緒に消えてくれない...

```models.py
import peewee

DB_FILE = "application.db"
db = peewee.SqliteDatabase(DB_FILE)


class User(peewee.Model):
    no = peewee.AutoField()
    name = peewee.CharField(unique=True)

    class Meta:
        database = db


class Devices(peewee.Model):
    no = peewee.AutoField()
    id = peewee.CharField(unique=True)
    owner = peewee.ForeignKeyField(User, on_delete='CASCADE', related_name='devices')

    class Meta:
        database = db
```

#結論
どうやらSQliteでは外部キーがデフォルトでオフになっているらしく手動でオンにする必要があるみたい
どういう意図なんだろう...
>参考
>SQLiteで外字キー設定する
>http://d.hatena.ne.jp/watanata2000/20110224/1298524729

確かにコンソールで確認するとオフになっていた

```
sqlite> PRAGMA foreign_keys;
foreign_keys = 0
```

#解決策
[Peewee PRAGMA statements](http://docs.peewee-orm.com/en/latest/peewee/database.html#pragma-statements)

ドキュメントを確認するとPweeweeで外部キーを有効にする方法は以下

```
db = SqliteDatabase('my_app.db', pragmas={
    'foreign_keys': 1,
})
```

```
db.pragma('foreign_keys', 1, permanent=True)
```

後者を選択

```models.py
import peewee

DB_FILE = "application.db"
db = peewee.SqliteDatabase(DB_FILE)
db.pragma('foreign_keys', 1, permanent=True)
```

再びコンソールで確認したが設定は反映されず

```
sqlite> PRAGMA foreign_keys;
foreign_keys = 0
```

ただ、アプリケーション上では正しく外部キーが機能することを確認:v:
DBファイルには設定が残らず、接続時の設定として管理されているんだろうか
初めてのRuby on rails Bootstrap導入編 [Memo for neko]

<h1>Ruby on railsの勉強の今回はbootstrap導入について簡単にメモを残しておきます。</h1>
（なぜなら、勝手に、一人で手こずってしまって時間がかかってしまったので...）
方法は、いくつかあるかと思いますが、今回は"「bootstrap-sass」"でやりました。

==環境==
・PC:Macbook Pro (Retina)
・macOS High Sierra
・rails: 5.1.6 (<font color="Salmon">*rails 6.1.2 確認済み</font>)
・bootstrap: bootstrap 4.0.0-alpha.3

==導入流れ（簡略）==
1.Gemfileへ追加
2.「bundle install」をterminalにて唱える
3.application.scssを編集 
4.application.jsを編集 
5.Bootstrapの確認用にindex.html.erbを編集
6.server再起動
7.Bootstrapが導入されているかを確認


==導入の流れ==
<h2>1. Gemfile</h2>
Gemfileに以下を追加

```ruby:Gemfile
gem 'bootstrap', '~> 4.1.1'
```

保存。

<img width="908" alt="gem.png" src="https://qiita-image-store.s3.amazonaws.com/0/69607/b8379977-fa6c-a950-1b41-9684a2f33d39.png">

terminalへ行って、「*bundle install*」を唱える
（↑↑↑これとっても重要！！！）

<h2>application.scss</h2>
app > assets > stylesheets > application.cssをエディッターで開き編集
以下を追加

```ruby:application.css
@import "bootstrap"; 
```

保存。

<img width="772" alt="scss.png" src="https://qiita-image-store.s3.amazonaws.com/0/69607/a4956917-d7b4-8050-725c-283544972ef4.png">

＋ファイル名を変更：application.css　→　application.scss

<h2>application.js</h2>
app > assets > javascripts > application.jsをエディッターで開き編集
以下を追加

*p.s. rails 6.1.2では， app > javascripts > packs > application.js

```ruby:application.js
//=require bootstrap
```

保存。

<h2>Bootstrapの確認</h2>
app>assets>views>pages>index.html.erbをエディッターで開き編集
以下を追加（これは、Bootstrapのサイトにあるテストコードを使用するのが良い）

```html:index.html.erb
<a class="btn btn-primary" href="#" role="button">Link</a>
<button class="btn btn-primary" type="submit">Button</button>
<input class="btn btn-primary" type="button" value="Input">
<input class="btn btn-primary" type="submit" value="Submit">
<input class="btn btn-primary" type="reset" value="Reset">

```

[bootstrap button sample] https://getbootstrap.com/docs/4.1/components/buttons/


＋server再起動

```ruby:サーバー起動
rails s
```


<h2>Ruby on railsにBootstrapが導入されているか確認</h2>
サイトを確認：）

[Before]
<img width="482" alt="スクリーンショット 2018-07-05 15.20.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/69607/d37e9bf0-9aa8-e8ff-1008-e1d8a673cb2a.png">

<font color="Salmon">[After]</font>　
<img width="452" alt="スクリーンショット 2018-07-05 15.13.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/69607/6096b376-fadc-76a0-8480-12da5ae4fe56.png">

これでやっとできました。
(できると思います。。。)
Koto用insightの構築

## 前準備

`sudo apt-get update`

`sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git python python-zmq zlib1g-dev wget bsdmainutils automake curl libzmq3-dev`


## ソースのダウンロード

`cd`
`mkdir koto`
`cd koto`

`
git clone https://github.com/KotoDevelopers/koto.git
git clone https://github.com/wo01/bitcore-node-koto
git clone https://github.com/wo01/insight-api-koto
git clone https://github.com/wo01/insight-ui-koto
`





## kotoのインストール

`cd koto`
`git checkout v1.1.0`
`patch -p1 < ./zcutil/bitcore.diff`


`./zcutil/fetch-params.sh`

`./zcutil/build.sh -j 2`
`cp src/kotod ../bitcore-node-koto/bin/`


`cd ../bitcore-node-koto`
`npm install`

`cd ..`
`./bitcore-node-koto/bin/bitcore-node create livenet`

`cd livenet`
`../bitcore-node-koto/bin/bitcore-node install ../insight-api-koto`
`../bitcore-node-koto/bin/bitcore-node install ../insight-ui-koto`


##起動

`../bitcore-node-koto/bin/bitcore-node start`

##環境設定

```bitcore-node.json```
{
  "network": "livenet",
  "port": 80,
  "services": [
    "bitcoind",
    "insight-api-koto",
    "insight-ui-koto",
    "web"
  ],
  "servicesConfig": {
    "bitcoind": {
      "spawn": {
        "datadir": "./data",
        "exec": "/root/koto/bitcore-node-koto/bin/kotod"
      }
    },
    "insight-ui-koto": {
      "routePrefix": ""
    }

  }
}
```

```data/koto.conf```
server=1
whitelist=127.0.0.1
txindex=1
addressindex=1
timestampindex=1
spentindex=1
zmqpubrawtx=tcp://127.0.0.1:28332
zmqpubhashblock=tcp://127.0.0.1:28332
rpcallowip=127.0.0.1
rpcuser=bitcoin
rpcpassword=local321
uacomment=bitcore
showmetrics=0
```
----

##supervisor を使ってデーモン化

`apt-get install supervisor`

```/etc/supervisor/config.d/insight.conf```
[program:insight]
user=root
autostart=true
autorestart=true
command=/root/koto/bitcore-node-koto/bin/bitcore-node start
directory=/root/koto/livenet
```

###デーモンを起動

`supervisorctl reload`

### 構築サイト

http://insight.kpool.jp/
CSSを学び〜応用について

#bootstrapの簡単な使い方!!
筆者について
.プログラミング初心者
.学び初めて三ヶ月目

HTML~PHPまで学び
bootstrapについて
1.bootstrapは時間がないときに簡単な枠組みで出来栄えがいいものができる！
2.中身を理解すれば自由度はかなり高い
3.レスポンシブが簡単にできます

参考https://www.venezia-works.com/bs4/index.php

個人的ですが、このように縦に並べ替えると非常にわかりやすいです。
<img width="1257" alt="スクリーンショット 2018-07-05 23.11.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/269021/39446bd7-4698-dc58-75d9-272b5dd6d1c1.png">

cssは動きがあり、プログラミング初心者にとってはとても面白いです！
社内SEとしてはたらきはじめました

#プログラム知識なしで社内SEとして就職しました
はじめまして。2018年7月1日より、前職を辞め、プログラムの知識が全くない状態で社内SEとして採用されました。
採用理由は、おそらくやる気だけ。あきらめないという前向きな姿勢をかっていただけたというこでした。
先輩エンジニアは、ほぼすべての言語が使いこなせるということで、ついてこれば間違いなく君は成長できるよと、励ましの言葉をいただきました。

##働き始めて3日目
毎日の仕事内容といえば、先輩が書いたプログラムを自分の言葉で説明しよう！（ちなみにエラーが絶対出るプログラム）という課題を与えられて、それに没頭することで1日が終わってしまう状態です。1行1行のもつ文の意味などがわからず、「すみません、少しお伺いしてもよろしいでしょうか。」という文句からはじまり、「この意味が理解できません。」というと、「意味を考えるよりも、まずは自分で文字出力のプログラムなどを打って、挙動を確認してみることが大事。文字出力プログラムを挟んでは、ここまでプログラムが動いたなと確認すること、プログラムを打つことが大事。」だと教えていただきました。

##課題はJAVAでPostgreSQLへ接続
3日目にして先輩から、「PostgreSQLに接続し、データを参照し更新できるexeプログラムを開発せよ。そのためには、どういった言語をつかってどういうプログラムが書けたらそれができるか私に説明してみてね。」と言われ、「・・・・。」という状態です。EclipseとSwingというものをつかって、PostgreSQLに接続し、持ってきたデータを表形式にしてswingを使って表示させる。こんなことを考えています。できるのかな・・・。
Watson Assistant にあらかじめ情報を渡す方法

#環境
IBM Cloud 上の node-red で開発しています
Assistant を利用して LINE bot との会話を構成します

#やりたいこと
Assistant で会話を始める前に Assistant に情報を渡したい
例えば今回は、LINE bot に画像を投稿して、Watson Visual Recognition で画像を認識させて、その結果を Assistant の会話で利用する必要がありました

#方法
Assistant ノードの前に function ノードを追加して以下を記述します

```js
//watson assistant の準備
msg.params = {};
msg.params.endpoint = "https://gateway.watsonplatform.net/assistant/api";
msg.params.username = "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx"; //Assistant の資格情報
msg.params.password = "xxxxxxxxxxxx"; //Assistant の資格情報
msg.params.workspace_id = "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx"; //Assistant で呼び出したい Workspace の Workspace-id

//渡したい情報を context にセットする
msg.params.context.color= "red";
msg.params.context.size= "big";

msg.payload = {};
msg.payload = "bot に投げるメッセージ";

return msg;
```

#備忘
会話はこちらからのメッセージに対して、bot が一回返答する形になります
次のメッセージをこちらから投げる時には前の msg はクリアされていて、値を保持しておけません

Assistant は継続した会話として値を保持してくれているようですので、context に入れておけば持っておけます

その後は、会話を新たに始める際に context をクリアしています
Rのpiperの皆さまに送る、何でもパイプで書いてたらハマった話

# はじめに

P値を-log10スケールにして、プロットしたい時がある。

```{r}
p <- 0.01
-log10(p)
```
```
## [1] 2
```

Rのデータ処理で人気のパッケージ{dplyr}を使う人は、パイプ演算子(%>%)を使ってスッキリと書くことが多い。

例えば、

```{r, message=F, warning=F}
require(dplyr)
p <- seq(1, 10, by = 1) %>% pnorm(., lower.tail = F)
print(p)
```
```
##  [1] 1.586553e-01 2.275013e-02 1.349898e-03 3.167124e-05 2.866516e-07
##  [6] 9.865876e-10 1.279813e-12 6.220961e-16 1.128588e-19 7.619853e-24
```

みたいに書ける。pnorm(seq(1, 10, by = 1), lower.tail = F) より可読性高い。
ドットは省略だけど、ドット付きで評価させることで比較的自由にパイプで書ける。

ここに、対数変換もしたいとする。
ほしいのはこういった値。

```{r}
-log10(p)
```
```
##  [1]  0.7995455  1.6430161  2.8696990  4.4993349  6.5426457  9.0058643
##  [7] 11.8928536 15.2061426 18.9474644 23.1180534
```

# そうだ、パイプで書こう

しかし、パイプ演算子を使って書くとドツボにはまった。

```{r}
seq(1, 10, by = 1) %>% pnorm(., lower.tail = F) %>% -log10(.)
```
```
##  [1]  0.9582008  1.6657662  2.8710489  4.4993666  6.5426460  9.0058643
##  [7] 11.8928536 15.2061426 18.9474644 23.1180534
```

正解より大きい。

# 何が起きているのか

次の評価がされてしまっているようだ。

```{r}
tmp_fun <- function(x){
    x - log10(x)
}
seq(1, 10, by = 1) %>% pnorm(., lower.tail = F) %>% tmp_fun()
```
```
##  [1]  0.9582008  1.6657662  2.8710489  4.4993666  6.5426460  9.0058643
##  [7] 11.8928536 15.2061426 18.9474644 23.1180534
```

最後の評価で、先頭にマイナスをつけなければ、正しい値がでる。

```{r}
test1 <- seq(1, 10, by = 1) %>% pnorm(., lower.tail = F) %>% log10(.)
test2 <- log10(pnorm(seq(1, 10, by = 1), lower.tail = F))
all(test1 == test2)
```
```
## [1] TRUE
```

最後の評価で、先頭にプラスをつけるとNG（普通こんなふうに書かないと思うけど）

```{r}
test1 <- seq(1, 10, by = 1) %>% pnorm(., lower.tail = F) %>% +log10(.)
test2 <- log10(pnorm(seq(1, 10, by = 1), lower.tail = F))
all(test1 == test2)
```
```
## [1] FALSE
```

# これまでに書いたコードが心配な人へ

## Linux User

find使って検索。カレントディレクトリ以下なら、

```bash
find ./ -type f -print | xargs grep '%>% -'
```

## Mac User

Finderで "%>% -" とカギ括弧付きで検索すると、それを含むRscriptなり、Rmdファイルを拾える（ポジコンスクリプトで確認済）。

## Windows User

Unknown.

# 備考

見つけたときは焦ったが、過去の解析について、私は特に実害なかった。
グーグル検索で他の人たちのスクリプトを探そうとしたが、%がどうやっても検索できず断念した。

// 以上。

# 実行環境

```{r}
sessionInfo()
```
```
## R version 3.3.1 (2016-06-21)
## Platform: x86_64-apple-darwin13.4.0 (64-bit)
## Running under: OS X 10.13.5 (unknown)
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] dplyr_0.7.4
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_0.12.16      rstudioapi_0.6    bindr_0.1.1      
##  [4] knitr_1.15.1      magrittr_1.5      xtable_1.8-2     
##  [7] R6_2.2.2          rlang_0.1.6       stringr_1.2.0    
## [10] highr_0.6         tools_3.3.1       miniUI_0.1.1     
## [13] htmltools_0.3.5   yaml_2.1.14       rprojroot_1.2    
## [16] digest_0.6.12     assertthat_0.2.0  tibble_1.3.4.9003
## [19] bookdown_0.3      bindrcpp_0.2.2    shiny_1.0.1      
## [22] questionr_0.6.0   glue_1.2.0        evaluate_0.10    
## [25] mime_0.5          rmarkdown_1.8     stringi_1.1.5    
## [28] pillar_0.0.0.9000 rmdformats_0.3.2  backports_1.0.5  
## [31] httpuv_1.3.3      pkgconfig_2.0.1
```
rustとscalaとkotilnの勉強 数当てゲーム(kotlin) 2回目 と3つやってみた感想

TRPLの数当てゲーム。
kotlinもループを使わずに書いてみる。
kotlinにはeitherとかoptionとかmaybe みたいなものがない。
エラーハンドリングもtry-catchしかない。
成功失敗と戻り値を戻したかったのでとりあえずPairで逃げておいた。

結構色々ないkotlin。
・・・と思いきやジェネレータはある。
ただしthe feature "coroutines" is experimental
yieldでシーケンスを作れるのはやっぱり楽。
rustにも早くこないかな。
kotlin.coroutines.experimental.buildSequenceで無限リストをつくるようにした。
ネームスペースにcoroutinesと入っているのを見てもわかるように、ジェネレータに特化したものではなく、コルーチン諸々があってジェネレータはその一部、みたいな感じっぽい。
ほかの機能はみてないけど。たぶん。

```kotlin
import java.util.Random
import kotlin.coroutines.experimental.buildSequence
fun main(args:Array<String>){
	val secret_number = Random().nextInt(99) + 0
	println("秘密の数字は次の通り：${secret_number}")
	println("数をあててごらん")
	println("ほら予想を入力してね")
	buildSequence{
		while(true){
			yield(readLine())
		}
	}.map{
		s->try{
			Pair(true,Integer.parseInt(s))
		}catch(e:Exception){
		Pair(false,0)
		}
	}.filter{
		p->p.first
	}.map{
		p->p.second
	}.map{
		i-> when{
			i==secret_number -> {println("正解");i}
			i<secret_number -> {println("小さ過ぎる");i}
			else -> {println("大き過ぎる");i}
		}
	}.filter{
		i->i==secret_number
	}.first()
}
```

書いてて思ったけど、mapとかfilterとかでチェーンしていく中でエラーが起きる可能性がある処理が挟まるとやっぱりeitherなりrustのresultみたいなのがないとなんかイマイチ。
scala,rust,kotlinだとやっぱscalaが一番かきやすかった気もする。
scala>>>>rust,kotlinかなあ。
rustはコンパイラとの戦いが辛かった。
kotlinは、、、一番文法を調べずに書いてるのでしょうもないことで時間がかかった。
{をどうしても(と書いちゃって・・・

あと、rustはコンパイラとの戦いが辛いんだけど、コンパイルエラーの内容が本当に親切。
rustになれると他の言語のコンパイルエラーが心もとなく感じる。

いいかげん数当てゲームはやめて先にすすまねば・・・
ubuntuとnodejsでリバースプロキシを作ってみる

# まずプロキシサーバーって何？
- 内部のネットワークとインターネットの間で動かす、通信経路のトンネルのようなもの

別に無くても外部との通信はできます。

# プロキシサーバーは何が出来るの？
- 経由する事により、プロキシサーバー側で通信内容のチェックが出来る
- プロキシサーバーの設定で、閲覧してはいけないサイトや通信を指定出来る（ブラックリスト制）
- プロキシサーバーの設定で、閲覧しても良い通信やサイトや通信を指定出来る（ホワイトリスト制）
- プロキシサーバーは通信をキャッシュする事も出来るので、高速なアクセスをする事が出来る

企業や学校のプライベートネットワークから外部ネットワークに行くために、プロキシサーバーの経由を必須にする事で
全員の通信内容を確認したい、など
このサイトは見てはいけない、見て良い　と行った制限をかける事が可能となります。
![スクリーンショット 2018-07-05 22.12.25.png](https://qiita-image-store.s3.amazonaws.com/0/266455/087f251d-cd07-2524-0fb6-8af3c5e055b7.png)


# ではリバースプロキシサーバーとは？
- 外部から来たリクエストなどを内部で経由させるためのプロキシサーバ

難しい...

# リバースプロキシサーバーは何が出来るの？
- アクセスに使用したホスト名によって使用するWebサーバーを振り分ける事が出来ます。
- 同一ホスト名でも複数のWebサーバーにリクエストを分ける事が可能(負荷分散)

LineBotのサーバーはコールバックURLのポート番号が443でなくてはならないため
２つ以上は立てられないと考えてました、が、
リバースプロキシを使う事により、複数のサーバーを立てる事が出来る様です。
![スクリーンショット 2018-07-05 22.20.42.png](https://qiita-image-store.s3.amazonaws.com/0/266455/17a7de2e-3585-1a63-a738-dc896ebe3a4d.png)
こんな事も出来ちゃうってnodejs便利すぎないですか

# 実際に立ててみる
## 筆者環境
- Ubuntu16.04(KAGOYA VPS KVMマシン)
- npm 5.6.0
- node 9.11.2
- express 4.16.0

## 手順
### 1.ポートを開ける
```
$ ufw enable
yと答える

プロキシサーバが使うポートを開ける
$ ufw allow 80
```
KAGOYAではない環境の場合、ルーターのポートマッピングや、セキュリティグループ等の設定が必要になります。

### 2.expressでwebサーバを作成する
```
expressがインストールされてない場合は以下コマンドを実行
$ npm install -g express-generator

expressでポート3000を使用するプロジェクトを作る
$ express port3000
$ cd port3000
必要なモジュール類をインストール
$ npm i
pm2でバックグラウンドで実行させる
$ pm2 start bin/www --name=3000

3000のプログラムが動いている事を確認する
$ pm2 list
┌──────┬──────┬────────┬───┬─────┬───────────┐
│ Name │ mode │ status │ ↺ │ cpu │ memory    │
├──────┼──────┼────────┼───┼─────┼───────────┤
│ 3000 │ fork │ online │ 0 │ 0%  │ 45.0 MB   │
└──────┴──────┴────────┴───┴─────┴───────────┘
```

### 3.リバースプロキシサーバーを作成・起動する
```
$ mkdir reverse-proxy
$ cd reverse-proxy

$ npm install http-proxy
プログラムを書く（なんと２行です）
$ echo "var proxy = require('http-proxy');
proxy.createProxyServer({target: 'http://localhost:3000'}).listen(80)" > index.js

起動する
$ pm2 start index.js --name=proxy

起動している事を確認する
$ pm2 list
┌───────┬──────┬────────┬───┬─────┬───────────┐
│ Name  │ mode │ status │ ↺ │ cpu │ memory    │
├───────┼──────┼────────┼───┼─────┼───────────┤
│ 3000  │ fork │ online │ 0 │ 0%  │ 45.0 MB   │
│ proxy │ fork │ online │ 0 │ 0%  │ 36.0 MB   │
└───────┴──────┴────────┴───┴─────┴───────────┘
```

### 4.ブラウザでアクセスしてみる
サーバーを立てている環境で以下コマンドを実行しIPアドレスを調べます
```$ ifconfig | grep "inet addr:"
inet addr:192.168.1.5
inet addr:127.0.0.1  Mask:255.0.0.0
```
ふーん、192.168.1.5なんですね
*127.0.0.1は ループバックアドレス といって自分自身を指すIPアドレスです

他のマシンからブラウザでアクセスしてみます。
![スクリーンショット 2018-07-05 22.49.44.png](https://qiita-image-store.s3.amazonaws.com/0/266455/efaec426-26e9-cfc3-4c4e-29a41c77e6b2.png)
表示できました！
しかもURL見た目はリバースプロキシに接続しているだけにしか見えないんですね(そりゃそうか)

そのほかにも、このリバースプロキシをSSL化する事や、ホスト名毎に使用するWebサーバを変更（ルーティング）する事、
さらにwebsocketに対応する事も可能です。
気になる方は調べて見てください。

---
こちらで大変お世話になりました。

>プロキシサーバーとは
>https://www.idcf.jp/words/proxy-server.html

>Node.jsのhttp-proxyでプロキシサーバーを作る
>https://qiita.com/setouchi/items/75de9db509f20ecaf369
[論文概要] Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields

#arXiv
https://arxiv.org/abs/1611.08050

#結果画像
<img width="903" alt="スクリーンショット 2018-07-05 22.20.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/113923/4b7ea0ba-039b-2053-96d9-09b0680d6224.png">
図1

#論文の概要
##位置付け
CVPR2017でCMUのグループによって発表された写真中に多人数いる時にも対応したスケルトンフレームの姿勢推定手法。コードは[OpenPose](https://github.com/CMU-Perceptual-Computing-Lab/openpose)としてきれいに整理して公開されている。なお、OpenPoseでは本論文の技術の他にも顔部位推定や手指推定などの他の技術も同梱している。

写真中に写っているのが一人だけの時は　Stacked Hourglass Networks for Human Pose Estimation(以降従来手法と呼ぶ)　でひとまず精度良く推定できるようになったが複数人に対しては対応できていなかった。また複数人の姿勢推定をなんの工夫もなしにやると計算量が爆発する。本論文は多人数の姿勢推定をPAFというベクトル画像を推定する処理を導入することで多人数においても推定できるようにしたもの。

##技術ポイント
入力写真から従来手法では身体部位推定のヒートマップを生成していたが、本論文ではそれに加えてPAF(Part Affinity Fields)も生成する。

PAFとは入力画像における同一人物の部位同士を結合する直線上にある画素ではその結合直線の方向を表す二次元単位ベクトルを、それ以外の画素では二次元ゼロベクトルを格納する画像のこと。(図2(c)参照)

<img width="979" alt="スクリーンショット 2018-07-05 22.21.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/113923/3e17bcd8-3e5f-151b-6cf9-82af613c2676.png">
図2

ニューラルネットのモデルの構造は部位推定ヒートマップ推定用のパスとPAF推定用のパスに分岐しているもののそれぞれのパス自体は従来手法と大差はない(図3)。ただしHourglass(砂時計)の形はしていなくてネットワーク後半では一気に画素数を展開しているように見える。さらに従来手法のようにネットワークをstackさせている点(図3のStage t)も同様。こうすることで推定結果を段階的にリファインできる。また、Stageを一つ進める際にはヒートマップとPAFを統合しているのでヒートマップとPAFはお互いの情報を使って精度を高め合う効果もありそう。

<img width="874" alt="スクリーンショット 2018-07-05 22.22.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/113923/4879c8f7-127a-4593-3a4f-a840842a1e29.png">
図3

最後に部位推定ヒートマップとPAF画像に基づいて統合処理をして最終的なスケルトンフレーム推定結果を算出する。この統合処理についてもテクニックがあり論文中では　Bipartite Matching　(図2(d))として解説されている。が、論文のメインポイントはPAF画像を導入することで従来手法で推定した部位が写真中のどの人物に属するかを効率的に推定できるようにしたことと言って良いと思う。

*基本的には個人的な視点も含んだメモです。また、事実と異なることが書かれていたらご指摘いただけたら幸いです。
Docker上のmattermostとローカルpythonでbot連携した

# 環境:grinning:
Ubuntu 16.0.4
docker 18.03.1-ce
python 3.5.2

# mattermostdriverを使う

mattermostとのやり取りを簡単にしてくれます。
https://github.com/Vaelor/python-mattermost-driver

# pythonの実装:relaxed:
flaskでwebサーバーを作ります。
flaskについては下記を参考にするなどしてください（今回はすごく簡単なことしかしません）
[ウェブアプリケーションフレームワーク Flask を使ってみる](https://qiita.com/ynakayama/items/2cc0b1d3cf1a2da612e4)

```
from mattermostdriver import Driver

from flask import Flask, request

app = Flask(__name__)

SERVER_URL = ""
CHANNEL_ID = ""
USER_EMAIL = ""
USER_PASS = ""

mat = Driver({
    'url': SERVER_URL,
    'login_id': USER_EMAIL,
    'password': USER_PASS,
    'scheme': 'http',
    'port': 8065,
    'verify': False
    })

mat.login()

@app.route('/kumobot', methods=['POST'])
def post():
    req = request.json
    dialog = req['text']
    try:
        mat.posts.create_post(options={
            'channel_id': CHANNEL_ID,
            'message': 'Hi!'
        })
    except Exception as e:
        print(e)
    return '200'

if __name__ == '__main__':
    app.debug = True
    app.run(host='0.0.0.0')
```

以下を埋めてください。

```
SERVER_URL = ""
CHANNEL_ID = ""
USER_EMAIL = ""
USER_PASS = ""
```

あとは上の実装を適当に名前をつけ(例：botserver.py)

```
$ python3 botserver.py
```

で実行!
Running on XXXという表示が出れば成功です。

# 設定:writing_hand:

## outgoingwebhooks

下記を参考にしながらwebhookを設定していきます。
[SlackクローンのMattermostを使ってみる - 外部連携編 -（WebHooks、Hubot）](https://qiita.com/terukizm/items/4524249dd7f1298fdc06)

統合機能＞外向きのウェブフックを選択すると下のような画面がでます。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/210944/6195a22b-55e3-be73-9abb-be0905d029ed.png)

トリガーワード：トリガーとなるキーワードを設定します。今回は「kumo」にします。
コールバックURL：pythonを動かしたサーバーのURLとポートを書きます。

## エラーがでる:frowning2:
```
err=Post http://XXX:5000/kumobot: address forbidden
```

https://docs.mattermost.com/administration/config-settings.html?highlight=cors
こちらにも書かれていますが、AllowedUntrustedInternalConnectionsにIPアドレスを追記するとよいみたいです。

```
$ docker cp {CONTAINER}:mm/mattermost/config/config_docker.json {LOCALFILEPATH}
$ vi {LOCALFILEPATH}
$ docker cp {LOCALFILEPATH} {CONTAINER}:mm/mattermost/config/config_docker.json
```



# テスト
トリガーワードがkumoなのでhi kumoだと繋がりませんね。
![kumobot.png](https://qiita-image-store.s3.amazonaws.com/0/210944/3b1d332b-5e0c-ccb9-9374-bec672e0ddfb.png)

うまくいきましたね！
あるディレクトリ下で、ある文字列は含むがある文字列は含まないファイルを探す方法

ディレクトリAAA下で、文字列BBBは含むが文字列CCCは含まないファイルのファイル名を出力する

```
grep -x -i -f <(grep -ril BBB AAA) <(grep -Lir CCC AAA)
```
[メモ]SeleniumでGUIテストを自動化する時に考えた設計パターン

製品のリリースサイクルが1年くらいだったのが、
随時パッチをリリースする体制に代わったので、テストを行う回数が増えてきた。

GUIぽちぽちするのは苦痛でしかないので、
今後自動化するためのベストな設計、運用について考えました。

試作段階なので変更するかもしれませんが、今のところの構成です。


#デザインパターン　

GUIは変化する可能性が高く、テストは定期的に実施します。
メンテナンスしやすい構成にしたいので、Page Object Design Patternを採用しました。
※Seleniumテストの定番構成のようです。

この辺を参考にさせてもらいました。
https://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern
http://ninoseki.hatenablog.com/entry/2013/01/09/212424
http://www.assertselenium.com/automation-design-practices/page-object-pattern/


>Page Object Design Pattern(ページオブジェクトパターン)とは
テスト対象ページ毎のクラスとテストケースクラスを分離し、変更に強いテストを作成するための仕組み。

>詳しくは上記リンク先が参考になりますが、
実際にSeleniumのメソッドで画面の要素を指定したりするのは〇〇Pageクラスを作成する。
〇〇Pageクラスは基本的には画面ごとに作成する
〇〇Testクラスで〇〇Pageのメソッドを使用してテストする。

>ページごと要素を指定するクラスを作成することで、
様々なテストケースで使いまわせるようになる。というのがポイントではないかと思います。


>- ソッドがページ遷移を伴わず、文字列等を返さない場合はvoid
- メソッドがページ遷移を伴う場合は遷移先のPageObjectを返す
- publicメソッドはそのページが提供するサービスを表す
- ページ内部を隠蔽する
- アサーションを書かない
- メソッドは他のPageObjectを返す
- ページをまるっとPageObjectで表現する必要はない
- 同じアクションが異なる結果を返す場合、異なるメソッドとして実装する


#テストの成功/失敗の判断

テスト結果の判断も、表示した画面に特定の要素があるかなどで判断できますが、
画面の表示崩れまでは分かりません。GUIは人の目で見ておかしくないか判断したいのので、
テスト結果のスクリーンショットを取って、結果は人の目で確認することにしました。


#複数ブラウザーの切り替え

Seleniumでは使用するドライバーを変えることで、同じテストコードで複数ブラウザーを使用したテストを実行できます。
 `DRIVER = new ChromeDriver();//Chromeのオブジェクト`のような記述で仕様したいブラウザーのドライバーオブジェクトを生成します。

ここは柔軟に切り替えたいので、
使用するブラウザーは設定ファイルで指定できるようにします。

その他にも、URLやスクリーンショットの保存ディレクトリなど、変更の可能性があるものは、設定ファイルに切り出して読み込むようにします。　


#要素の指定
一つ一つ設定するのは大変ですが、地道に指定しするしかないようです。
他に方法があるといいのですが。

できるなら開発時にカスタムデータでテスト用に属性を作成しておくと
GUIの変更に強くなりそうです。

#参照
ブラウザーごとの切り替え
http://www.seleniumeasy.com/selenium-tutorials/simple-page-object-model-framework-example

カスタムデータ属性の指定
https://qiita.com/okitan/items/eb8f8e253d0811777215
FlutterでスワイプしてListViewのアイテムを操作する方法

FlutterでスワイプしてListViewのアイテムを操作する方法を紹介します。

こんな動きを簡単に実装できます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/18273/d3136349-b824-48d3-94c7-57229b9a9de5.gif" width="300px">

結構はまりそうだなーと憂鬱になりながら調べてみたら[チュートリアル](https://flutter.io/cookbook/gestures/dismissible/)を見つけて超簡単でした。

`ListTile`を`Dismissible`というウィジェットでラップするだけで実現できます。

実際のコードはこんな感じになります。(行のWidgetを作る部分)

```dart
  Widget _buildRow() {
    return Dismissible(
      key: Key("some id"),
      background: Container(color: Colors.red), // start to endの背景
      secondaryBackground: Container(color:Colors.yellow), // end to startの背景
      onDismissed: (direction) {
        print(direction);
        if (direction == DismissDirection.endToStart) {
          print("end to start"); // (日本語だと)右から左のとき
        } else {
          print("start to end"); // (日本語だと?)左から右のとき
        }
      },
      child: ListTile(
        title: Text("hoge"),
        onTap: () {
          print("row clicked");
        },
      ),
    );
  }
```

backgroundにゴミ箱の画像などを表示することで操作がわかりやすくなりますね。
Chrome操作ライブラリ「Puppeteer」でスクレイピングしてみた

#はじめに
Headless ChromeをNode.js上で操作するライブラリにPuppeteerがあります（しかもGoogle製！）。
これがスクレイピングツールとしても使えそうなので、試しにWikipediaからタイトル、本文、画像を取ってみました。

#インストール手順
OS : Windows10
Puppeteerのバージョン : 1.5.0

インストールは以下のコマンドを打つだけです。

```none:Puppeteerのインストール
$ npm install puppeteer
```

※事前にNode.jsとnpmをインストールする必要があります。


# ソースコード（全体）

```javascript:crawler.js
const puppeteer = require('puppeteer');

(async () => {
  // const browser = await puppeteer.launch();
  const browser = await puppeteer.launch({ headless: false }); // ヘッドレスにしない


  const page = await browser.newPage();

  const url = 'https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%87%E3%83%AA%E3%83%BC%E3%83%9A%E3%83%B3%E3%82%AE%E3%83%B3';
  await page.goto(url, { waitUntil: 'domcontentloaded' }); // domを読み込むまで待機

  // タブを移動
  const pages = await browser.pages();
  const detailPage = pages[1];
  await detailPage.bringToFront();

  // タイトル取得
  let selector = '#firstHeading';
  const titleDom = await detailPage.$(selector);
  if (titleDom) {
    title = await detailPage.$eval(selector, e => e.textContent);
    console.log(title);
  }

  // 本文取得
  selector = '#mw-content-text > div > p';
  const contentDom = await detailPage.$$(selector);
  if (contentDom.length > 0) {
    content = await detailPage.$$eval(selector, elements => {
      let datas = [];
      for (e of elements) {
        datas.push(e.textContent);
      }
      return datas;
    });
    for (c of content) {
      console.log(content);
    }
  }

  // 画像取得
  selector = '#mw-content-text > div > table.infobox.bordered > tbody > tr:nth-child(2) > td > a > img';
  const dom = await page.$(selector);
  if (dom) {
    await dom.screenshot({ path: 'penguin.png' });
  }

  await browser.close();
})();
```

# ソースコード（詳細）

覚えておいたほうがよさそうなところだけメモ。

## 読み込むまで待機
page.goto()でページ遷移する際に、waitUntilでページのロードを待機します。

* `domcontentloaded`にすれば、htmlを読み込むまで待機
* `load`にすれば、その後画像を読み込むまで待機
* `networkidle0`にすれば、500ミリ秒コネクションがなくなるまで待機

JavaScriptを読み込むまで待とうと思ったら、`networkidle0`がよさげ？
`networkidle2`ってのもある模様。

```javascript:読み込むまで待機
await page.goto(url, { waitUntil: 'load' });
```

## タブの移動
リンクをクリックすると、新規タブに移動される場合があります。
その場合はそのタブに移動する必要があります（今回のソースではいらないけど・・・）。

```javascript:タブの移動
const pages = await browser.pages();
const detailPage = pages[1];
await detailPage.bringToFront();
```

## スクレイピング
テキストや属性を取得するときは、基本この書き方だと思います。
この例だとtextContentを指定しているので要素内のテキストを取得します。

```javascript:スクレイピング
title = await detailPage.$eval(selector, e => e.textContent);
```

## 画像の取得
DOMに対してもスクリーンショットが取れます。もちろんページにも取れます。

```javascript:画像の取得
await dom.screenshot({ path: 'penguin.png' });
```

#実行
```none:起動
$ node crawler.js
```

![penguin.png](https://qiita-image-store.s3.amazonaws.com/0/227999/7dc9c49e-ab3c-b576-75d0-0ec012740ea8.png)

なんか、画像がうまく取れませんでした・・・。
こういう時は、画像のURLにアクセスしてからpage.screenshot()をするとよさそうです。



#おわりに
割と簡単で便利でした。
PuppeteerはAPIの種類がかなり多いので、色々試してみるのも面白そうですが、公式のAPIドキュメントを呼んでもよく分からないところもまだありますね・・・。
RaspberryPiに接続したLogicool C270の露出を固定する

# **RaspberryPiでLogicool C270を使いたい**
USBカメラのLogicool HD Webcam C270は、安価でRaspberryPiとの相性が良いため利用されている方も多いのではないでしょうか。
私もRaspi+OpenCV+c270という組み合わせを検討していたのですが、その際、c270の自動露出を解除して任意の値を設定する方法にハマってしまいましたので、解決方法をメモ書きしておきます。

実行環境

* Raspbian-stretch date：2017-11-29 
* python：3.6.1
* OpenCV：3.3.0
* PyQt5：5.10.1
* USBカメラ：Logicool HD Webcam C270

本内容は、PyQt5で作成したGUIアプリにOpenCVでキャプチャした画像を表示させた状態で確認しました。


# **問題点**

Linux上でUSBカメラの設定を行う場合は、Video4Linuxを使うと良いらしいので、`v4l2-ctl`コマンドを用いて任意の露出を設定しました。
その結果、露出のパラメータである`exposure_absolute`の変更には成功したのですが、キャプチャした画像に設定内容が反映されません。

ちなみに、同様の手順をLogicool HD Webcam C615を用いて実行すると、こちらはキャプチャ画像に露出の設定が反映されます。なのでC270固有の問題なのかもしれません。


# **解決方法**

こちらを参考にすることで解決できました。
[How can I change webcam properties that OpenCV doesn't support but v4l2 API does?](https://stackoverflow.com/questions/36310724/how-can-i-change-webcam-properties-that-opencv-doesnt-support-but-v4l2-api-does)

理由は分かりませんが、`cv2.VideoCaputure()`の後、最初の一回のみ`cv2.read()`を実行した時点でカメラの設定がリセットされてしまうみたいです。
なので一度`cv2.read()`を実行し意図的に設定をリセットしておいて、その後にVideo4Linuxで露出設定を行うようにすれば任意の値を反映できます。

具体的には以下のような感じです

```python
import subprocess
import cv2

cap = cv2.VideoCapture(0)

# v4l2で設定を行う前にread()を1回実行しておく
_, _ = cap.read() # <-対策としてこの1行を追加

# v4l2の設定をsubprocessを用いて実行
cmd = 'v4l2-ctl -d /dev/video0 -c exposure_auto=1 -c exposure_absolute=20'
ret = subprocess.check_output(cmd, shell=True)

# v4l2の設定値を確認
cmd = 'v4l2-ctl --list-ctrls'
ret = subprocess.check_output(cmd, shell=True)
print(ret)

# 以降の処理でread()を実行しても、設定がリセットされることはないみたいです・・・

```

***

*2019/4/11追記*
*下記の様なコメントを頂きました。*
*当時の環境が残っていないため当方では確認できておりませんが、動作しない場合は修正してみてください。*

>Description: Raspbian GNU/Linux 9.8 (stretch)
>Release: 9.8
>こちらのバージョンではコマンドが以下のように変更となっていました。
>cmd = "v4l2-ctl -d /dev/video0 -c auto_exposure=1 -c exposure_time_absolute=300"

***




対策前（露出が反映されていない）
![screenshot_04.jpg](https://qiita-image-store.s3.amazonaws.com/0/264410/1bcd301b-993c-be83-5e23-8a4256c6d449.jpeg)

対策後（露出が反映された）
![screenshot_03.jpg](https://qiita-image-store.s3.amazonaws.com/0/264410/3657a549-eec8-c6ca-6d46-2c8ce9b6ade9.jpeg)









## **参考にさせて頂きました**
* [LinuxでUVC(USB Video Class)タイプのUSBカメラを使う](https://qiita.com/nonbiri15/items/9593d61a2be81f2b31a9)

* [OpenCV / v4l2で、Webカメラ露出固定にして、かつフリッカーを抑える方法](http://www.llul.info/entry/2016/02/19/193435)
システム間のファイル連携する際に検討すべきこと

# 概要

システム間でファイル連携をする際に、仕様を明確にしていなかったために、後々問題になることがあります。事前にどのようなことを取り決めておかないといけないかを列挙してみました。

# 詳細

## 共通検討事項

### 全ファイル共通

|検討事項|例|備考|
|:--|:--|:--|
|ファイル名|固定名、可変名|yyyyMMddHHmmsssを付けたりする。|
|拡張子|csv, tsv, json, xml, xlsx|拡張子だけではデータ形式が不明な場合もある。|
|連携対象|全データ, 前回との差分データ||
|データなし時の連携|ファイルなし, 空ファイル||
|連携後のファイル|削除する, 放置する||

## テキストファイル共通

|検討事項|例|備考|
|:--|:--|:--|
|ファイル名|固定名、可変名|末尾にyyyyMMddHHmmsssを付けたりする。|
|文字コード|UTF-8, Shift_JIS|BOMの有無。|
|改行コード|CR, LF, CRLF||

## 個別検討事項

### 可変ファイル

|検討事項|例|備考|
|:--|:--|:--|
|セパレータ|カンマ, タブ||
|文字コード|UTF-8, Shift_JIS|BOMの有無。|
|改行コード|CR, LF, CRLF||
|値に含まれる制御文字|カンマ, タブ, 改行, ダブルクォート, 改行||
|ダブルクォートでの囲み|常にあり, 常になし, 文字列のみあり, 必要に応じてあり||
|タイトル行|あり, なし||
|ヘッダー行|あり, なし|ヘッダー行と明細行で項目数が異なることもある。|
|フッター行|あり, なし|フッター行と明細行で項目数が異なることもある。|

### 固定長ファイル

|検討事項|例|備考|
|:--|:--|:--|
|タイトル列|あり, なし||
|フッター行|あり, なし|フッター行と明細行で項目数が異なることもある。|

### JSON

- 何があるのかな？

### XML

- 何があるのかな？

# 補足

- 特に CSVファイル が厄介な気がします。CSVファイルと言いながら、中身がタブ区切りであったりすることが多々あります。テキストファイルの連携は、早い段階で実ファイルを入手して確認するのが最善かと思います。
- デヂエのデータを連携した際は、値に改行が含まれていて苦労しました。

# 編集後記

思いつくままに記載したので、まだまだ検討すべきことはあると思います。
フォロー頂けるとありがたいです。
(質問)[GoogleAppScript]htmlからスクリプトを実行する

GoogleAppscrptについてわかる方が居られましたらご教授お願いいたします。
「mian.gs」からhtmlファイルを表示して。htmlファイルから「main.gs」の関数を実行する機能を実装したいです。
htmlの表示までうまく行っているのですが、htmlから「main.gs」の関数が実行できずに困っております。
ソース、実行結果は下記の通りなのですが、何かわかる方がおられましたら、ご教授お願いいたします。
●ソース
https://script.google.com/d/1KEGwlzuD0nVI2LhaXMQ1quFThYOz6sL5Y-0g-oIJX50kBI8qoA4Qg3Fh/edit?usp=sharing
●実行結果
https://script.google.com/macros/s/AKfycbxR7xFOFAddt3QEKJoBms3lTfp5MxmXCdC2HW3WVZX88lY59I9Y/exec
●main.gs
function doGet() 
{
  return HtmlService.createHtmlOutputFromFile('index');
}
function getText(){
    Logger.log('start');
    return "main.gsの返却値";
}
●index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    version1.00<br>
    <?= getText(); ?>
  </body>
</html>
●出力結果
version1.00
<?= getText(); ?>

・参考
https://tonari-it.com/gas-web-appli-function-return/
Rubyの変数（ローカル変数）の取り扱いや命名規則

# 宣言と代入

```
変数名 = 式や値
```

ローカル変数の場合、変数を宣言するだけの構文はありません（インスタンス変数は例外）。

# 変数名の慣習というか、命名規則（スネークケース）

Rubyでは変数名は、スネークケースで記載します。

```rb
get_name
```
など

## その他の慣習

変数以外にも、スネークケース以外に様々な慣習があります。

| 場合 | 慣習 | 例 |
|-----------|------------|------------|
| クラス名、モジュール名       | キャメルケース       |FooClass|
| ファイル名、ディレクトリ名     | スネークケース      |foo_class.rb|
| メソッド名、変数名       | スネークケース        | foo_method |
| MAX_SIZE         | すべて大文字のスネークケース          | MAX_SIZE  |
| 返り値が真偽値のメソッド       | ?つける       | current_user?       |

Railsのコントローラ名やモデル名にも命名規則はあります。くわしくは。

https://qiita.com/gakkie/items/3afcd505c786364aa5fa

# 参考

- https://qiita.com/TakeshiFukushima/items/647a652439b55525945f
- https://qiita.com/takahashim/items/ccfd489c9b26f15b7193
Wio Nodeの温湿度をPythonで取得する

おうちIOTやりたいので手始めに温湿度をモニターします。
サクッとWio Nodeを使って温湿度を取得してみました。

Wio NodeのセットアップからWio公式アプリでの接続までは、公式ドキュメントがあるのでそちらを参照。
http://wiki.seeed.cc/Wio_Node/

# 使っているセンサ
GROVE - デジタル温度・湿度センサ
https://www.switch-science.com/catalog/818/

# やり方
Wio公式アプリで確認できるAPIをrequestsで呼び出してJSON形式で温湿度を取得します。

# コード

```python
import requests
import json

# 温度（摂氏）の取得
# _YOUR_ACCESS_TOKEN_部分はWio公式アプリで確認できるアクセストークン
degree_url = "https://us.wio.seeed.io/v1/node/GroveTempHumD1/temperature?access_token=_YOUR_ACCESS_TOKEN_"
headers = {"content-type": "application/json"}
r = requests.get(degree_url, headers=headers)
data = r.json()
degree = data["celsius_degree"]

# 湿度の取得
# _YOUR_ACCESS_TOKEN_部分はWio公式アプリで確認できるアクセストークン
humidity_url = "https://us.wio.seeed.io/v1/node/GroveTempHumD1/humidity?access_token=_YOUR_ACCESS_TOKEN_"
headers = {"content-type": "application/json"}
r = requests.get(humidity_url, headers=headers)
data = r.json()
humidity = data["humidity"]

# ついでに不快指数を計算
discomfort_index = 0.81*degree+0.01*humidity*(0.99*degree-14.3)+46.3
```
GMOペイメントゲートウェイのリンクタイプの決済完了判定 

私も以前に使ったことがありますが、最近GMO決済に詳しい方に教えていただいたことで、リンクタイプのケースで勉強になったことがありましたのでメモ。

ドキュメント通りに実装したので、当時はそんなこと考えたこともなかったかも。

リンクタイプのRetURL（決済結果戻し先URL）ではRetURL側でのプログラム処理は確実ではないということを聞きました。
（決済後に決済結果戻し先URLに遷移する前にブラウザを閉じたりするとRetURLにPOSTされないというケースも考えられるため）

このため[結果通知プログラム](https://faq.gmo-pg.com/service/detail.aspx?id=1050&a=102&isCrawler=1)というのがある。
正常応答が確認出来なかった場合に約60分毎に5回指定したアドレスにPOSTしてくれる機能がある。
このPOSTに対する応答によって再送されるか判定される。
ただし、RetURLにPOSTされるデータとは異なるので取得できないものもあるので注意
詳しくは【結果通知プログラム（インタフェース仕様）】を参照

# つまり

RetURLと結果通知プログラムの二段構えで結果判定をする必要がありそう。（実際に試したところ結果通知プログラムの設定を行ったら両方とも実行されたので結果通知プログラムのみで判定を行う方法が良い。）
RetURLのみで実装すると決済は行われたがアプリケーション側では完了していないので途中で登録を辞めたという判定になってしまうことが希にあり、かなり厄介とのことです。

ドキュメント類は[テスト環境申込 登録](https://service.gmo-pg.com/cyllene/entry/trialStart.htm)をしてログインを行ってから確認することができます。

# 追記

実際に使用してみると

リンク決済結果受け取り（RetURL）
と
結果通知プログラム

は両方実行されてリンク決済結果受け取り画面（RetURL）より先に結果通知プログラムの方が実行されたので、リンク決済結果受け取り画面（RetURL）では処理を行わず、（完了画面の表示のみにする）結果通知プログラムで処理を行う方法で良さそう。

# デバッグ

リンクタイプでシステムエラー（エラーコードもわからない）になってしまう場合のデバッグ方法

共通のエラーテンプレートのbodyに以下を追加してみる（これでエラーコードが出力される）

```
{insert name="debug_showAllVars"}
```

[エラーコード](https://faq.gmo-pg.com/service/detail.aspx?id=480&a=102)

# その他

* ドキュメントの`弊社指定のID`とはShopIDのこと

* 結果通知プログラムはテスト環境ではpt01.mul-pay.jpから実行されました。
本番ではこれがp01.mul-pay.jpになったりするのでアクセス制限の際には注意が必要です。
カレントディレクトリをvscodeで開くfish関数を自作する

ghqなんかを使っていて、Railsアプリかなんかのリポジトリのディレクトリに移動したのはいいけど、エディタで開くのにわざわざ一個階層上がってから開いてた。。。面倒なので関数化して、カレントディレクトリをvscodeで開けるようにした。

configに下記を追加する。

```~/.config/fish/config.fish
# カレントディレクトリをvscodeで開く
alias vsc='vsc'
function vsc
  code $PWD
end
```

下記コマンドを実行するとカレントディレクトリをvscodeで開いてくれるようになる。

```
$ vsc
```

開いた後、プロジェクトを移動したいときは `control + r` で切り替えられる。

---

### bashやzshの場合
```.bash_profileか.zshrcに下記の関数を追加（動作未確認）
vsc() {
  "code" "$pwd"
}
```

関数化してみたけど，

```
$ code .
```
↑これが一番シンプル
Undoの実装の考え方

# はじめに

初めてUndoを自力で実装することになったときに何から考えればいいのか分からなかったので自分なりの考え方を整理してみます。

サンプルコードも載せようかと思ったんですがググったらいっぱいサンプルが出てきたので今さら自分がやらなくてもいいかなと思ったのでやめておきます。

# Undoのアプローチ
Undoというのは時間（ユーザーの操作）で変化するオブジェクトの状態を元に戻したり、戻したあとに先に進めたりするような機能です。gitのTreeのようなものです。と言ってもこの説明で理解できる人は今さらUndoの実装方法なんて興味ないかもしれませんが。

とにかくアプリケーションというのは時間でオブジェクトの状態が変わり、そのオブジェクトの状態を行ったり来たり遷移させるのがUndo/Redo機能ということになります。

![WS000000.JPG](https://qiita-image-store.s3.amazonaws.com/0/67050/13459fcc-a5a0-06cd-150e-3315f15d2d4d.jpeg)


で、Undoを実装する上では２つのアプローチがあると思っています。

 - 「状態」に着目する
 - 「遷移」に着目する

# 「状態」に着目するアプローチ

簡単に言うと、オブジェクトの内部状態が`A→B→C`と変化していくときに、それぞれのオブジェクトのコピーを作成しておきます。で、Undoが実行されたら１つ前の状態のオブジェクトに入れ替える、という方法になります。

![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/67050/70a44035-10d3-8aeb-18c8-9abfe6e137ef.jpeg)


いわゆるMementoパターンです。

オブジェクトの状態が変わるたびに現在の状態のバックアップを追加していくようなイメージでしょうか。

## メリット
 - 状態のスナップショットをとっていくので何世代も前の状態にいきなり戻せる。
 - Undo処理の大きさが処理自体の大きさに依存しない（めちゃくちゃ重い処理でもデータが軽ければ一瞬でUndoできる）
 - Undoの対象となる操作が仕様変更で拡大しても操作の処理自体に手を入れる必要がない（勝手にスナップショットがとられて差分が保持されるため）

## デメリット
 - 何か変化が発生するたびにオブジェクトのコピーを作るのでメモリがどんどん圧迫される
    - オブジェクトの量が多い場合は上手いこと変更のあったオブジェクトだけ選んでコピーを取る機構が必要かも（状態変化前と後で差分を取るとか）
 - コピーを作成できるような対象にしか利用できない
 - Undo対象のオブジェクトの種類が拡大するとUndoの機構自体に手を入れる必要がある

## 参考資料

デザインパターン勉強会 第18回：Mementoパターン
https://qiita.com/mitakaosamu/items/31d881ae14b28919e910

C#でUndo機能が気に入らないので力技で自作した（RichTextBox） 
http://pineplanter.moo.jp/non-it-salaryman/2017/11/29/csharp-undo-richtextbox/

# 「変化」に着目するアプローチ

簡単に言うと、オブジェクトの内部状態が`A→B`と変化するとき、`A→B`へ変化する処理と`B→A`に戻す処理を同時に記憶しておいて、Undoが実行されると逆方向の処理が行われる、という方法です（Redoするときは`A→B`へ変化する処理をもう1回実行する）。簡単に言えない。

![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/67050/8deff41a-2234-39d2-a859-a0bda2e12b85.jpeg)

いわゆるCommandパターンです。

オブジェクトの状態が実際に変わる前に「未来方向への変化」と「過去方向への変化」をペアでUndoのスタックに積んでいきます。

## メリット
 - オブジェクトそのもののコピーは作らないので省メモリ
 - Undo対象のオブジェクトの種類が拡大してもUndo機構自体は影響を受けない

## デメリット
 - Undoするたびにオブジェクトを変化させるので変化処理自体が重いとUndoも重くなる
 - 可逆的な変化に対してしかUndoできない（１回やっちゃうと戻せない処理はUndoできない）
    - 具体的な例を挙げようと思ったら思いつかなかったのでもしかしたらそんなデメリットないかも
 - Undo対象の操作が仕様変更で拡大した場合は操作処理自体に手を入れる必要がある（Undo機構の呼び出しが必要のため） 

## 参考資料
C#でUndo/Redoを実装した
https://qiita.com/nossey/items/c59910558d5501f03ad0

Undo,Redoの実装って何十回もやってる気がする
http://d.hatena.ne.jp/Youchan/20081110/1226282911

# 感想
ネットで検索するとCommandパターンでのUndo実装のやり方の方がサンプルが多いので、まずはこっちからアプローチしてみればいいかもしれない。あとC#だとUndoのためのクラスライブラリがNugetで公開されてたりしました。
intのオーバーフロー対策についてstringsパッケージから学ぶ

# Golangでのオーバーフロー
golangのintは`2147483647`が最大値でそれ以上になるとオーバーフローが起こります

動きとしては
* 定義時に`2147483647`以上の値を指定するとコンパイルが失敗する
* 四則演算を行うとオーバーフローが起こるがコンパイルは通る
https://play.golang.org/p/I4e8LFr73nZ

なので四則演算がある場合はオーバーフロー対策を行う必要があります

# strings.Repeatから学ぶ

strings.Repeatの動きはこんな感じです
https://play.golang.org/p/n5ulDrRR5cV

今回は標準パッケージのstrings. Repeatの対策を見てみます
## オーバーフロー対策

```golang:strings.Repeat
func Repeat(s string, count int) string {
	// Since we cannot return an error on overflow,
	// we should panic if the repeat will generate
	// an overflow.
	// See Issue golang.org/issue/16237
	if count < 0 {
		panic("strings: negative Repeat count")
	} else if count > 0 && len(s)*count/count != len(s) {
		panic("strings: Repeat count causes overflow")
	}

	b := make([]byte, len(s)*count)
```

> https://golang.org/src/strings/strings.go?s=13170:13209#L522

大事な行は以下です


```bash:オーバーフロー対策
} else if count > 0 && len(s)*count/count != len(s) {
```

```bash:対策を行わないとオーバーフローが起こる箇所
b := make([]byte, len(s)*count)
```

オーバーフローがおきると`len(s)*count`の結果が予期せぬ値(いい言い回しが思いつかなかった)がでるため`len(s)*count/count != len(s)`がtrueになってしまう

https://play.golang.org/p/JqOh0jOKvmh
このリンク見たらわかるはず
Faust: MS処理をするプラグインを作ってみた

MS処理をしたくって作ってみました。
まず、
## L-RからMid-Sideに変換するやつ。

```cpp:LR2MS.dsp
declare name "LR2MS";
import("stdfaust.lib");

process = (_ , _)<: + , - : /(2), /(2);
```
<img width="423" alt="スクリーンショット 2018-07-05 19.14.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/6c0599a5-50af-0f0b-dc21-dabe0c55b2b1.png">
なるべくFaustっぽい記法で書いてみました。
独特で謎が多いですが、要するに 
```process(x, y) = (x + y) / 2 , (x - y) / 2 ;``` 
と同等です。
<img width="395" alt="スクリーンショット 2018-07-07 09.59.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/e00a66e6-ce26-82a7-2369-c691e7cf5786.png">

逆にもっとつきつめるとこんな感じ?
```process = (_ , _ , 2) <: (_ + _) / _ , (_ - _) / _ ;```
<img width="388" alt="スクリーンショット 2018-07-07 16.22.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/1f63150c-9bbb-889b-d727-b8034f7a24e8.png">


そして
## Mid-SideからL-Rに戻すやつ。
Mid-Sideをそれぞれ検聴できるようにスイッチをつけました。

```cpp:MS2LR.dsp
declare name "MS2LR";
import("stdfaust.lib");

process = (_ * on_M, _ * on_S ) <: + , - ;

on_M = checkbox("/v:MS2LR/[0]Mid");
on_S = checkbox("/v:MS2LR/[1]Side");
```


<img width="591" alt="スクリーンショット 2018-07-07 09.42.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/78931f44-4ed4-36ba-98c5-48b546c62bad.png">

## faustLiveでvstプラグインにしてみました。
<img width="500" alt="スクリーンショット 2018-07-07 09.48.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/61597/b6550611-f584-1fd8-a9af-8ec3627fa234.png">


ちゃんと使えてます。

このふたつの間に、コンプ、EQなどを挟んで使うつもりです。
MySQLの全角 ( マルチバイト ) 文字とREGEXP

ハマったのでメモ。

##結論
MySQLのREGEXPはマルチバイトには対応していないので気をつけないと駄目。

## LIKEの場合

collationというものがある。

参考
https://www.slideshare.net/tmtm/mysql-2017
https://qiita.com/kazu56/items/6af85ffcf8d3954455ad

デフォルトではutf8\_general\_ci ( または utf8mb4\_general\_ci ) が設定されているらしい。
この場合、全角文字と半角文字は別の文字として判断される。

```sql
SELECT `users`.* FROM `users` WHERE (name like 'hoge')
```
 => "hoge", "Hoge"などはマッチするが、"ｈｏｇｅ", "Ｈｏｇｅ"などはマッチしない


全角半角区別なくマッチさせたかったので、collationをutf8\_unicode\_ciに無理やり変更することで対処。

参考
https://www.softel.co.jp/blogs/tech/archives/1877

```sql
SELECT `users`.* FROM `users` WHERE (name collate utf8_unicode_ci like 'hoge')
```
 => "hoge", "Hoge", "ｈｏｇｅ", "Ｈｏｇｅ", "hOｇＥ"のいずれもマッチする。

**やったぜ。**

##REGEXPの場合
検索したい文字列が1種類の場合、上記の手法で問題ない(はず)。
が、今回は複数文字列に対してマッチングさせたかった。
なのでRegEXPを利用することを考えたが、これでハマった。

```sql
SELECT `users`.* FROM `users` WHERE (name regexp 'hoge')
```

=> "hoge", "Hoge"はマッチする、"ｈｏｇｅ", "Ｈｏｇｅ"などはマッチしない

```sql
SELECT `users`.* FROM `users` WHERE (name collate utf8_unicode_ci regexp 'hoge')
```
 => "hoge", "Hoge"はマッチする、"ｈｏｇｅ", "Ｈｏｇｅ"などはマッチしない

**？**

調べたところ、MySQLはマルチバイト文字列に対するREGEXPには対応していないみたい。

https://dev.mysql.com/doc/refman/5.6/ja/regexp.html
https://stackoverflow.com/questions/39513264/mysql-regular-expression-for-multibyte-characters

公式ドキュメントはまず読んでみるべきだと反省。

`LIKE`と`OR`で頑張ろうと思うけど、そもそもレコードに保存する際に半角に変換するとかこんなクエリ考えないような設計にしたほうがいいのでは･･･？