OmniAICreator/Qiita-1.07M huggingface dataset:
PlayFlamework2.6でslickをコンパイル時DIしたときのメモ

## 依存性の追加

``` build.sbt
libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-slick" % "3.0.0",
  "mysql" % "mysql-connector-java" % "5.1.16",
  "com.typesafe.play" %% "play-slick-evolutions" % "3.0.0"
)
```

## プロパティの定義

``` application.conf
play.application.loader = "com.exsample.MyApplicationLoader"

slick {
    dbs.default {
        profile = "slick.jdbc.MySQLProfile$"
        db {
            connectionPool = disabled
            driver = "com.mysql.jdbc.Driver"
            url = "jdbc:mysql://localhost/database_name?characterEncoding=UTF-8"
            user = "user"
            password = "password"
        }
    }
}
```

## アプリケーションローダー

``` MyApplicationLoader.scala
package com.exsample

import play.api._
import play.api.ApplicationLoader.Context
import _root_.controllers.AssetsComponents
import com.exsample.controllers._
import com.exsample.repositories._
import play.filters.HttpFiltersComponents
import slick.jdbc.JdbcBackend.Database
import router.Routes

class MyApplicationLoader extends ApplicationLoader {
  def load(context: Context) = {
    new MyApplicationComponents(context).application
  }
}

class MyApplicationComponents(context: Context)
    extends BuiltInComponentsFromContext(context) with AssetsComponents
      with HttpFiltersComponents {

  // SlickController
  lazy val db = Database.forConfig("slick.dbs.default.db")
  lazy val slickRepository = new SlickRepositoryImpl(db)
  lazy val slickController = new SlickController(controllerComponents, slickRepository)

  // router
  lazy val router = new Routes(httpErrorHandler, slickController, assets)
  // ついでのメモ
  // ↑のnew Routesについて、第一引数はhttpErrorHandler、それ以降はroutesでの定義順に渡すっぽい
}
```
Cent7、ホストオンリー接続設定の際つながらないときはまずここを見る。

VirtualBoxのネットワーク接続の設定は、先導くださる沢山の有志の方のありがたき投稿を見ることができます。
まずは各ホストの設定画面ですが、こちらもバージョンの差異で多少の導線への違いがありますが。
私が利用する、現在のバージョン(VirtualBox 5.2.8r)の場合は以下のようになっております。


<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/d8b1c096-a4fe-f743-1cee-139018096c40.png" width="50%">

#各種確認・編集画面

##ホストのNAT設定
ファイルメニューより、環境設定
<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/0ba4c07b-2d04-6a35-7126-e511edea5174.png" width="50%">

#ホストのHostOnlyネットワークの設定
ウ#ィンドウ右上の「グローバルツール」のサブメニューから「ホストネットワークマネージャー」、またはファイルメニューから直接「ホストネットワークマネージャー」
<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/14dfce59-d970-114e-31c5-394cafde7d72.png" width="50%">



##ゲストマシンのネットワーク設定
マシンツール画面左より対象のゲストを右クリックし、コンテキストメニューから「設定」
大体どの方も、アダプター1タブにNAT設定、アダプター2タブにHostOnlyへの設定を行っているようです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/888610fe-7edb-8ced-9b4c-2a9d8ea6877c.png" width="50%">



##Cent7のネットワーク設定
こちらはファイルを直接編集して設定される場合とnmtuiなどを利用した方法ですが、nmtuiが楽です。

```sh
$ sudo nmtui
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/e37794e7-e605-e461-1804-2e104fe7b635.png" width="50%">


#接続できない時

ここからenp0s8(ホストオンリーの設定）の書き換え等を行い接続可能のはずですが、そこで接続ができなかった場合に頭を悩ませる場合が多いように思います。

##enp0s3のMacアドレス
その場合はまずはenp0s3の設定を確認
nmtui側のenp0s3編集画面の「Deviceに表記されているMacアドレスと、上記＜ゲストマシンのネットワーク設定>の「アダプター1」タブより、
「高度」を展開後、MACアドレスの内容が一致してるか確認する（「：」は無視）。

<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/0d2fc893-9012-1d76-85a1-7d3acc15db98.png" width="50%">

<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/86ea5ede-e5a8-45f1-b358-b50dd7c6795a.png" width="50%">


##enp0s8のMacアドレス
同様に、nmtuiのenp0s8のMACアドレスと、上記＜ゲストマシンのネットワーク設定>の「アダプター2」タブより、
「高度」を展開後、MACアドレスの内容が一致してるか確認する（「：」は無視）。
<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/3f03d0f9-54b2-2298-9500-1a961a50896c.png" width="50%">

<img src="https://qiita-image-store.s3.amazonaws.com/0/58095/b2247803-b649-bf55-16d0-0185cb8da605.png" width="50%">

この際にMacアドレスに差異があった場合はnmtuiの方を書き換え


```sh
$ sudo systemctl restart network
```

お試しください。
Flutterで[key : value] 形式でローカルにデータを保存する

Androidでいうところの `SharedPreferences` 
iOSでいうところの `UserDefaults` 

をFlutterで使う方法を書いていきます。


## Packageの導入

https://pub.dartlang.org/packages/shared_preferences#-readme-tab-

Packageが用意されているのでこれを使います。

いつも通り、下記をpubspec.ymlに下記を追加します。

```yml

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^0.4.1

```

追加したら下記を実行

```
flutter get packages
```

## 実装

保存、取得、削除 それぞれで `async` `await` を使うので注意が必要です。

### 保存


```dart
saveData(String email) async {

    SharedPreferences pref = await SharedPreferences.getInstance();
    await pref.setString("displayName", user.email);
}
```


### 取得


```dart
getData() async {

    SharedPreferences pref = await SharedPreferences.getInstance();
    setState(() {
      userName = preferences.get("displayName");
    });
}
```

このメソッドを `initState` メソッドとかで呼ぶとデータを取得できます。

### 削除

```dart

removeData(String key) async {

    SharedPreferences pref = await SharedPreferences.getInstance();
    await pref.remove(key);
}

```

両OS一発でできるのはほんと楽だな〜
Golang で CouchDB のデータを削除 (Delete)

Golang で CouchDB のデータを削除する方法です。
次のプログラムで作成したデータを削除します。
[Golang で CouchDB を使う (Create)](https://qiita.com/ekzemplaro/items/c06b32e71eb62229dcf1)

```golang:couch_delete.go
// ----------------------------------------------------------------
//
//	couch_delete.go
//
//					May/20/2018
//
// ----------------------------------------------------------------
package main

import (
	"fmt"
	"encoding/json"
	"os"
	"strings"
	"net/http"
	"log"
	"io"
	"io/ioutil"
)

// ----------------------------------------------------------------
func main () {

	fmt.Printf ("*** 開始 ***\n")

	key_in := os.Args[1]

	fmt.Printf ("key_in = %d\n" , key_in)


	url := "http://localhost:5984/nagano/" + key_in

	json_str := url_get_proc (url)
	fmt.Printf (json_str + "\n")

	var unit_aa map[string]interface{}
	if err := json.Unmarshal([]byte(json_str), &unit_aa); err != nil {
        	panic(err)
		}

	name := unit_aa["name"].(string)
	population := unit_aa["population"].(float64)
	date_mod := unit_aa["date_mod"].(string)
	fmt.Printf ("%s\t%s\t%f\t%s\n",key_in,name,population,date_mod)


	url_target := url + "?rev=" + unit_aa["_rev"].(string)

	deleteRequest(url_target,strings.NewReader(""))

	fmt.Printf ("*** 終了 ***\n")
}

// ----------------------------------------------------------------
func url_get_proc (url string) string {
	resp, err := http.Get (url)

	json_str := ""

	if err != nil {
		log.Fatalln(err)
		fmt.Printf("%s", err)
		os.Exit(1) 
	} else {
		defer resp.Body.Close()
		 contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			os.Exit(1)
			}
		json_str := string(contents)
//		fmt.Printf("%s\n", json_str)
	return (json_str)

		}

	return (json_str)
}

// ----------------------------------------------------------------
func deleteRequest(url string, data io.Reader)  {
	client := &http.Client{}
	req, err := http.NewRequest(http.MethodDelete, url, data)
	if err != nil {
		// handle error
		log.Fatal(err)
	}
	_, err = client.Do(req)
	if err != nil {
		// handle error
		log.Fatal(err)
	}


}

// ----------------------------------------------------------------
// ----------------------------------------------------------------
```

```text:Makefile
couch_delete: couch_delete.go
	go build couch_delete.go
clean:
	rm -f couch_delete
```

実行コマンドの例

```bash
./couch_delete t2030
```

次のバージョンで確認しました。

```text
$ go version
go version go1.13.8 linux/amd64
```
capistranoでいきなりgithubに繋がらなくなった時の話

###PCを再起動したらいきなり次のような感じでcapistranoでdeployできなくなった。
```
00:00 git:check
      01 git ls-remote git@github.com:アカウント名/アプリ名.git HEAD
      01 Permission denied (publickey).
      01 fatal: Could not read from remote repository.
      01
      01 Please make sure you have the correct access rights
      01 and the repository exists.
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing on host IPアドレス: git exit status: 128
git stdout: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
git stderr: Nothing written

```
###いろいろ試した結果、次をlocalの自分のアプリのディレクトリで実行したらうまく行った。
```
ssh-add ~/.ssh/id_rsa   <ーこの鍵はGithubのssh接続で使ってるやつ
```
でもなんでいきなり繋がらなくなったんだろう。。。


最初っから繋がらないよ〜てひとはconfig/deploy.rbの以下の部分とかを確認してみてください。

```
server '自分のサーバーのIPアドレス', port: 22, roles: [:app, :web, :db], primary:true
set :repo_url, "git@github.com:アカウント名/アプリ名.git"
set :application, "アプリ名"
set :user, 'デプロイに使うユーザ名'
set :ssh_options, {
  forward_agent: true,
  user: fetch(:user),
  keys: %w(~/.ssh/デプロイユーザのSSH接続に使っている鍵)
}
```
####参考
1.[Capistranoによるデプロイで発生したgithub接続エラーを解決する](blog.wackwack.net/entry/2016/11/13/215529)

2.[Githubのsshで何故かPermission denied (publickey)となる場合の設定メモ](https://qiita.com/koara-local/items/9cc615be6b4b60f5654d)
Golang で CouchDB のデータを更新 (Update)

Golang で CouchDB のデータを更新する方法です。
次のプログラムで作成したデータを更新します。
[Golang で CouchDB を使う (Create)](https://qiita.com/ekzemplaro/items/c06b32e71eb62229dcf1)

```golang:couch_update.go
// ----------------------------------------------------------------
//
//	couch_update.go
//
//					May/20/2018
//
// ----------------------------------------------------------------
package main

import (
	"fmt"
	"encoding/json"
	"os"
	"strconv"
	"strings"
	"net/http"
	"log"
	"io"
	"io/ioutil"
	"time"
)

// ----------------------------------------------------------------
func main () {

	fmt.Printf ("*** 開始 ***\n")

	key_in := os.Args[1]
	population_in,_ := strconv.Atoi (os.Args[2])

	fmt.Printf ("key_in = %d\t" , key_in)
	fmt.Printf ("population_in = %d\n" , population_in)


	url := "http://localhost:5984/nagano/" + key_in

	json_str := url_get_proc (url)
	fmt.Printf (json_str + "\n")

	var unit_aa map[string]interface{}
	if err := json.Unmarshal([]byte(json_str), &unit_aa); err != nil {
        	panic(err)
		}

	name := unit_aa["name"].(string)
	population := unit_aa["population"].(float64)
	date_mod := unit_aa["date_mod"].(string)
	fmt.Printf ("%s\t%s\t%f\t%s\n",key_in,name,population,date_mod)

	unit_out := make(map[string]interface{})
	unit_out["_rev"] = unit_aa["_rev"].(string)
	unit_out["name"] = name
	unit_out["population"] = population_in
	today := get_current_date_proc ()
	unit_out["date_mod"] = today
	output, _ := json.Marshal(unit_out)
	json_str = string(output)

	fmt.Printf (json_str + "\n")

	putRequest(url, strings.NewReader(json_str))

	fmt.Printf ("*** 終了 ***\n")
}

// ----------------------------------------------------------------
func url_get_proc (url string) string {
	resp, err := http.Get (url)

	json_str := ""

	if err != nil {
		log.Fatalln(err)
		fmt.Printf("%s", err)
		os.Exit(1) 
	} else {
		defer resp.Body.Close()
		 contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			os.Exit(1)
			}
		json_str := string(contents)
//		fmt.Printf("%s\n", json_str)
	return (json_str)

		}

	return (json_str)
}

// ----------------------------------------------------------------
func putRequest(url string, data io.Reader)  {
	client := &http.Client{}
	req, err := http.NewRequest(http.MethodPut, url, data)
	if err != nil {
		// handle error
		log.Fatal(err)
	}
	_, err = client.Do(req)
	if err != nil {
		// handle error
		log.Fatal(err)
	}


}

// ----------------------------------------------------------------
func get_current_date_proc () string {
	now := time.Now ()
	fmt.Printf ("%s\t" ,now)
	fmt.Printf ("%d-%d-%d\n" ,now.Year (),now.Month(),now.Day())
	today := strconv.Itoa (now.Year()) + "-" +
		fmt.Sprintf ("%d",now.Month()) + "-" +
		strconv.Itoa (now.Day())

	return	today
}

// ----------------------------------------------------------------
// ----------------------------------------------------------------
```

```text:Makefile
couch_update: couch_update.go
	go build couch_update.go
clean:
	rm -f couch_update
```

実行コマンドの例

```bash
./couch_update t2032 97321473
```

次のバージョンで確認しました。

```text
$ go version
go version go1.13.8 linux/amd64
```
Golang で CouchDB のデータを読む (Read)

Golang で CouchDB のデータを読む方法です。
次のプログラムで作成したデータを読みます。
[Golang で CouchDB を使う (Create)](https://qiita.com/ekzemplaro/items/c06b32e71eb62229dcf1)

```golang:couch_read.go
// ----------------------------------------------------------------
//
//	couch_read.go
//
//					Mar/20/2018
//
// ----------------------------------------------------------------
package main

import (
	"fmt"
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"net/http"
)

// ----------------------------------------------------------------
func main () {

	fmt.Printf ("*** 開始 ***\n")

	url := "http://localhost:5984/nagano/_all_docs"

	json_str := url_get_proc (url)

	var data map[string]interface{}
	if err := json.Unmarshal([]byte(json_str), &data); err != nil {
        	panic(err)
		}

	fmt.Printf("total_rows = %f\n" , data["total_rows"])
	xx := data["rows"]
	yy := xx.([]interface{})

	for _,value := range yy {
		pp := value.(map[string]interface {})
		key := pp["id"].(string)
		url := "http://localhost:5984/nagano/" + key
		json_str_unit := url_get_proc (url)
	var unit_aa map[string]interface{}
	if err := json.Unmarshal([]byte(json_str_unit), &unit_aa); err != nil {
        	panic(err)
		}

		name := unit_aa["name"].(string)
		population := unit_aa["population"].(float64)
		date_mod := unit_aa["date_mod"].(string)
		fmt.Printf ("%s\t%s\t%f\t%s\n",key,name,population,date_mod)

		}


	fmt.Printf ("*** 終了 ***\n")
}

// ----------------------------------------------------------------
func url_get_proc (url string) string {
	resp, err := http.Get (url)

	json_str := ""

	if err != nil {
		log.Fatalln(err)
		fmt.Printf("%s", err)
		os.Exit(1) 
	} else {
		defer resp.Body.Close()
		 contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			os.Exit(1)
			}
		json_str := string(contents)
//		fmt.Printf("%s\n", json_str)
	return (json_str)

		}

	return (json_str)
}

// ----------------------------------------------------------------
// ----------------------------------------------------------------
```

```text:Makefile
couch_read: couch_read.go
	go build couch_read.go
clean:
	rm -f couch_read
```

実行コマンド

```bash
./couch_read
```

次のバージョンで確認しました。

```text
$ go version
go version go1.13.8 linux/amd64
```
kotlinx.serializationメモ

# kotlinx.serializationの雑なメモ

## Jsonの項目名を指定する
```json:json
{
  "id": 1,
  "name": "aaa",
  "created_at": "Sun May 20 2018 20:33:49 GMT+0900 (JST)"
}
```

```kotlin:User.kt
@Serializable
data class User(
  val id: Long,
  val name: String,
  @SerialName("created_at")
  val createdAt: String
){}
```

## 配列の場合

1. ``JSON.parse``の第一引数に``KSerializer<T>.list``を指定する

```json:json
[
  {
    "id": 1,
    "name": "aaa"
  },
  {
    "id": 2,
    "name": "bbb"
  }
]
```
```kotlin:User.kt
@Serializable
data class User(
  val id: Long,
  val name: String
){}
```

```kotlin:Parse.kt
fun parseList(json: String) = JSON.parse<List<User>>(User.serializer().list, json)
```

## Jsonに含まれていない属性がある場合

1. ``@Optional``アノテーションを付ける
2. Nullableにする
3. デフォルト引数にnullを指定する

```json:json
[
  {
    "id": 1,
    "name": "aaa"
    "age": 20
  },
  {
    "id": 2,
    "name": "bbb"
  }
]
```

```kotlin:User.kt
@Serializable
data class User(
  val id: Long,
  val name: String,
  @Optional
  val age: Int? = null
){}
```
Golang で CouchDB のデータを作成 (Create)

Golang で CouchDB にデータを作成する方法です。

```golang:couch_create.go
// ----------------------------------------------------------------
//
//	couch_create.go
//
//					May/20/2018
//
// ----------------------------------------------------------------
package main

import (
	"fmt"
	"encoding/json"
	"strings"
	"net/http"
	"log"
	"io"
)

// ----------------------------------------------------------------
func main () {

	fmt.Printf ("*** 開始 ***\n")

	url := "http://localhost:5984/nagano"

	deleteRequest(url,strings.NewReader(""))
	putRequest(url,strings.NewReader(""))

	dict_aa := data_prepare_proc ()

	for key,value := range dict_aa {
		output, _ := json.Marshal (value)
		json_str := string(output)
		url_target := url + "/" + key
		putRequest(url_target,strings.NewReader(json_str))
	}

	fmt.Printf ("*** 終了 ***\n")
}

// ----------------------------------------------------------------
func data_prepare_proc () map[string](map[string]interface{}) {
	dict_aa := make (map[string](map[string]interface{}))

	dict_aa["t2021"] = unit_gen_proc ("長野",71862,"1921-4-9")
	dict_aa["t2022"] = unit_gen_proc ("松本",36571,"1921-8-25")
	dict_aa["t2023"] = unit_gen_proc ("上田",18397,"1921-2-18")
	dict_aa["t2024"] = unit_gen_proc ("小諸",76518,"1921-1-30")
	dict_aa["t2025"] = unit_gen_proc ("岡谷",61459,"1921-6-24")
	dict_aa["t2026"] = unit_gen_proc ("塩尻",85623,"1921-1-10")
	dict_aa["t2027"] = unit_gen_proc ("茅野",15947,"1921-4-19")
	dict_aa["t2028"] = unit_gen_proc ("飯田",78231,"1921-7-28")
	dict_aa["t2029"] = unit_gen_proc ("中野",25948,"1921-6-8")
	dict_aa["t2030"] = unit_gen_proc ("諏訪",57832,"1921-4-11")
	dict_aa["t2031"] = unit_gen_proc ("駒ヶ根",46182,"1921-3-16")
	dict_aa["t2032"] = unit_gen_proc ("佐久",82396,"1921-5-12")
	dict_aa["t2033"] = unit_gen_proc ("伊那",21858,"1921-9-18")
	dict_aa["t2034"] = unit_gen_proc ("千曲",43172,"1921-5-21")

	return (dict_aa)
}

// ----------------------------------------------------------------
func putRequest(url string, data io.Reader)  {
	client := &http.Client{}
	req, err := http.NewRequest(http.MethodPut, url, data)
	if err != nil {
		// handle error
		log.Fatal(err)
	}
	_, err = client.Do(req)
	if err != nil {
		// handle error
		log.Fatal(err)
	}
}

// ----------------------------------------------------------------
func deleteRequest(url string, data io.Reader)  {
	client := &http.Client{}
	req, err := http.NewRequest(http.MethodDelete, url, data)
	if err != nil {
		// handle error
		log.Fatal(err)
	}
	_, err = client.Do(req)
	if err != nil {
		// handle error
		log.Fatal(err)
	}
}

// ----------------------------------------------------------------
func unit_gen_proc (name string,population int,date_mod string) map[string]interface{} {
	unit_aa := make (map[string]interface{})
	unit_aa["name"] = name
	unit_aa["population"] = population
	unit_aa["date_mod"] = date_mod

	return (unit_aa)
}

// ----------------------------------------------------------------
```

```text:Makefile
couch_create: couch_create.go
	go build couch_create.go
clean:
	rm -f couch_create
```

実行コマンド

```bash
./couch_create
```

次のバージョンで確認しました。

```text
$ go version
go version go1.13.8 linux/amd64
```
Pixelbook Dev Update で Linux が動かなくなった件の解決

# 概要
Pixelbook で LXC が動くようになり，喜んだのもつかの間，最新のアップデートで**早速動かなくなった**．具体的にはターミナルアプリ及び crosh というブラウザ内ターミナルを開いても，黒いブランク画面が表示されるだけでターミナルとして使えなくなってしまっていた．これについては皆困っているようで，Reddit 上でも[議論](https://www.reddit.com/r/Crostini/comments/8ke96b/18may_dev_update_68034310_official_build_dev_64bit/)[^1] [^2] になり，解決策が示されていた．（一応）解決できたのでここへまとめておくことにする．

# 解決策

### Secure Shell App のインストール
まず `Alt+Ctrl+t` で呼び出せる crosh を修復するために，Chrome Web Store から  extension として Secure Shell App をインストールする．とりあえずこれで crosh は動く．

### LXC Container の起動
```terminal
crosh> vmc start termina
$ run_container.sh --container_name=penguin --user=tsubasa.azumagakito --shell
```
これでとりあえずコンテナ内のターミナルに入れる．`tsubasa.azumagakito` の部分は Google Account の名前（`@`の前の部分）に該当する．この run_container.sh は，中ではいろいろやっているが，最終的に

```
exec lxc exec "${FLAGS_container_name}" -- /bin/login -f "${FLAGS_user}"
```
をやっている．もし，uid 1000 関係のエラーが出たら以下のように一旦 termina をスタートし直すとうまく行く．

```terminal
crosh> vmc stop termina
crosh> vmc destroy termina
crosh> vmc start termina
```


あとはそもそもブラウザ内ターミナルが激しく使いづらいので，下記のように hyper などを入れてみた(けど，shelf にピン止めできなくて困ってる)．

```terminal
$ curl -L https://releases.hyper.is/download/deb > hyper.deb
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100   611    0   611    0     0    263      0 --:--:--  0:00:02 --:--:--   829
100 33.3M  100 33.3M    0     0   581k      0  0:00:58  0:00:58 --:--:--  974k

$ sudo apt-get install ./hyper.deb
$ hyper
```
![Screenshot 2018-05-20 at 20.26.20.png](https://qiita-image-store.s3.amazonaws.com/0/205151/61ed08e2-0220-4c82-449a-5f6dd866b319.png)

# 追記 201-05-23
### linux app を shelf にピン留めする方法[^3]
どうやら，launcher を起動して，terminal と検索してそれを shelf にまずピン留めする必要があったようだ．これを行っておくと，以降，apt-getでインストールしたアプリがなんとアプリケーションランチャーに表示されるようになる！！

### インストールは gdebi を使うと良さそう[^4]
hyper を入れたときにいまいち挙動が不安定だったが，なにか依存パッケージが足りていなかった説がある．以下のようにして導入すると安定した hyperterminal を手に入れることができた (ローカルにパッケージをダウンロードしてくるコマンドは前述しているので省いている)

.... **と思ったらまだやっぱ挙動おかしかった** まだまだだ．

```
$ sudo apt-get install gdebi # gdebi は普通に入れる
$ sudo gdebi ./hyper.deb     # ローカルの deb パッケージを指定してインストール
```


# Related Articles
- [ChromeOSを開発マシンにするために知っておく基本的な３つのこと \- Qiita](https://qiita.com/yasuki/items/fa14c258df0d088c6b98)
- [ChromebookでVSCodeをネイティブに動かせるようになったので試した \#Chromebook \#Pixelbook \#io18 \#io18jp \#VSCode \#gdgtokyo \- Qiita](https://qiita.com/Yatima/items/3e564cdfb6482ef9d9cf)


[^1]: [18-May Dev Update: 68.0.3431.0 (Official Build) dev (64-bit)](https://www.reddit.com/r/Crostini/comments/8ke96b/18may_dev_update_68034310_official_build_dev_64bit/)
[^2]: [crosh: terminal does not load properly](https://bugs.chromium.org/p/chromium/issues/detail?id=843682)
[^3]: [ChromeOS 68\.0\.3431\.0 Brings The Ability To Pin Linux Applications To The Shelf \| Keith I Myers](https://kmyers.me/blog/chromeos/chromeos-68-0-3431-0-brings-the-ability-to-pin-linux-applications-to-the-shelf/)
[^4]: [debファイルからインストールする際に依存関係で悩んだら \- Qiita](https://qiita.com/yanoshi/items/5faf97012bf7889feccf)
Go + reviewdog + CircleCI 環境において、一部の linter が動かない場合とその解決策

## きっかけ
[reviewdog](https://github.com/haya14busa/reviewdog) とは、 linter などの結果を Pull Request のコメントで指摘してくれるイケてるツールです。

CI で lint するのとは違って、指摘をあえて無視して merge することもできる適度なゆるさがお気に入りです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10713/f4116051-cf00-22bc-fa42-339ecce9e2b1.png)

このように Pull Request にコメントを付けるためには、reviewdog を CI で動かす必要があります。

CircleCI との連携のやり方はドキュメントに書いてる通りです。
https://github.com/haya14busa/reviewdog#circle-ci

しかし、Go のプロジェクトにおいて次のように linter を設定しましたが、最初 **golint しか動かず、他の linter の結果が来ない** 現象がおきました。

```yml:.reviewdog.yml
runner:
  golint:
    cmd: golint $(go list ./...)
  megacheck:
    cmd: megacheck $(go list ./...)
    errorformat:
      - "%f:%l:%c:%m"
  errcheck:
    cmd: errcheck -asserts -ignoretests -blank $(go list ./...)
    errorformat:
      - "%f:%l:%c:%m"
```

ローカル環境でやると megacheck, errcheck の指摘が出るのに、CirlceCI のログだと golint しか出ていませんでした。

```bash
#!/bin/bash -eo pipefail
./reviewdog -ci="circle-ci" -conf=.reviewdog.yml
cmd/get_spreadsheet_token.go:12:6: [golint] exported type Dummy should have comment or be unexported
cmd/get_spreadsheet_token.go:13:2: [golint] struct field testJson should be testJSON
```

## 原因: `dep ensure` をする前に reviewdog を動かしていた
CircleCI は毎回ソースコードを取り直すので **vendor/** 以下を再取得するのですが、その前に  `megacheck`, `errcheck` を実行するとエラーとなって reviewdog の結果に出なかったということが原因でした。**reviewdog ではなく megacheck 単体で CircleCI に実行させてみる** ことで発見しました。

```bash
#!/bin/bash -eo pipefail
megacheck $(go list ./...)
/go/src/github.com/.../cmd/get_spreadsheet_token.go:6:2: could not import golang.org/x/oauth2 (cannot find package "golang.org/x/oauth2" in any of:
	/usr/local/go/src/golang.org/x/oauth2 (from $GOROOT)
	/go/src/golang.org/x/oauth2 (from $GOPATH))
couldn't load packages due to errors: ...
Exited with code 1
```

というわけで、先に `dep ensure` すれば解決です。

### ❌まちがい 

```yml:.circleci/config.yml
- run: ./reviewdog -ci="circle-ci" -conf=.reviewdog.yml
- run: dep ensure
```

### 🔵 せいかい


```yml:.circleci/config.yml
- run: dep ensure
- run: ./reviewdog -ci="circle-ci" -conf=.reviewdog.yml
```

## 最終結果
ちゃんと `megacheck`, `errcheck`, の linter が動作して、Pull Request にも指摘が出るようになりました！ :dog: :smile: 

```bash
#!/bin/bash -eo pipefail
./reviewdog -ci="circle-ci" -conf=.reviewdog.yml
cmd/get_spreadsheet_token.go:12:6: [golint] exported type Dummy should have comment or be unexported
cmd/get_spreadsheet_token.go:13:2: [golint] struct field testJson should be testJSON
cmd/get_spreadsheet_token.go:47:35: [errcheck] 	json.NewEncoder(os.Stdout).Encode(tok)
cmd/get_spreadsheet_token.go:12:6: [megacheck] type Dummy is unused (U1000)
```
2018年5月現在のGo言語用開発環境(IDE/エディタ)を考える

2018年5月現在、Go言語用開発環境(IDE/エディタ)について比較してまとめた。

# 忙しい人向けのまとめ
* どのIDE/エディタでも**設定すればできることはそんなに変わらない**。
* なので**使い慣れもの/好きなものを使えば良い**。
* Go言語では**「保存時の挙動」でコードの書き方や意識が変わるので、どのようなことができるか知って、調整するのがおすすめ**。

# 比較対象のIDE/エディタ
## Atom (無料)

![スクリーンショット 2018-05-20 18.39.25.png](https://qiita-image-store.s3.amazonaws.com/0/14097/d47cca86-a7b1-8b01-0771-ff237f0541b5.png)

`go-plus`プラグインを入れることで、シンタックスハイライトや自動フォーマット/自動テスト、カバレッジの表示などに対応。特に設定をしなくても、デフォルトの状態でこれらの機能が動くようになるので、非常に取っつきやすい。

参考: [【はじめてのGo言語】Go言語でアプリケーションを作ってみよう 〜こんにちは、世界編〜](https://liginc.co.jp/327259)

## Visual Studio Code (無料)

<img width="2410" alt="スクリーンショット 2018-05-20 19.40.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/5399075e-24d7-6faf-ea91-a4a9c51d6b94.png">


Microsoft製の[vscode-go](https://github.com/Microsoft/vscode-go)プラグインを入れる。基本的な機能や使い方はAtomに`go-plus`を入れた場合とほとんど同じ。プラグインの更新や必要なツールのインストールの案内が充実していて親切。

参考: [Visual Studio CodeによるGo言語のデバッグ](https://dev.classmethod.jp/go/visual-studio-code-golang-debug/)

## GoLand(JetBrains) (有料 無料ライセンスもあり)

<img width="1910" alt="スクリーンショット 2018-05-20 18.26.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/14097/45fbde20-b26b-5fc3-2f45-771a37f2eb43.png">

他のJetBrains製IDEと同等の操作性・安定性があり、IDEとしての機能は非常に強力。ビルド/デバッグ時に渡す引数を設定しておけるなど、一旦その便利さに慣れると手放せなくなる「痒いところに手が届く」感がある。

ただし、高機能故GUIが複雑で設定項目も多く複雑なので、はじめは多少取っつきにくい。Android StudioなどでJetBrains系IDEに慣れている人だったら、スムーズに使えると思う。

# 機能比較
## エディタとしての機能
|項目|Atom|VSCode|GoLand|
|---|----|------|------|
|シンタックスハイライト|○|○|○|
|ビルドエラー表示|○|○|○|
|カバレッジ表示|○|○|○|
|リネーム|○|○|○|
|定義ジャンプ|○|○|○|

これらの基本的な機能は`gofmt`や`goimport`などGo言語側で用意されているため、全てのIDE/エディタでほぼ同様にサポートされている。「見せ方」はIDE/エディタによって多少異なるが、機能面での大きな違いはない。

## ファイル保存時の挙動

|項目|Atom|VSCode|GoLand|
|---|----|------|------|
|Lint|※1|○|設定すれば可能|
|フォーマット|○|○|設定すれば可能|
|Import整理|○|○|設定すれば可能|
|テスト実行|○|設定すれば可能|設定すれば可能|

※1...`linter`パッケージをインストールしている場合のみ

デフォルトの状態での、ファイル保存時の挙動はIDE/エディタによって異なっている。Atomはファイル保存時に自動でフォーマットからテストまで実行するのに対して、GoLandでは基本的に明示的にコマンドを実行したり、設定を有効にしない限り「余計なことはしない」挙動をする。Visual Studio Codeは、フォーマットやLintはデフォルトでオンになっているが、テストはデフォルトではオフになっている。

**Go言語の書き方、意識はファイル保存時の挙動によって大きく変わると思う。**

保存時に毎回テストが走り、エディタ上でカバレッジが強調される環境では、テストを書く意識が強く働くようになるし、強めのLintが走る環境では「良い(とされる)書き方で書くこと」に意識が働きやすくなる。フォーマットやImportの整理も保存時に自動で行われる環境では、インデント調整などの非生産的な作業はツールに任せて自分の手ではやらないようにする、という意識が働く。なので、ここの挙動は非常に重要なポイントであると思う。

Go言語はビルド/実行スピードの速さが売りの一つなので、他の言語に比べて保存毎にこれらの処理を自動で行うような開発スタイルを採用しやすい。とはいえ、大きなプロジェクトになってくると毎回テストを走らせていると重くてストレスになってきて、逆に生産性を下げてしまったりもするので、一概にどの設定が最適化を決めることはできない。

これらの挙動は、基本的に設定さえすればどのIDE/エディタでも大体同じような挙動に調整できるが、慣れていないと設定がわかりにくかったりする。

参考: Visual Studio Code [On Save features](https://github.com/Microsoft/vscode-go/wiki/On-Save-features)


# 考察・結論

最終的には設定さえしてしまえば、基本的にはできることはあまり変わらないのだが、設定で躓くのはあまり楽しい体験ではない。AtomやVSCodeは気軽にいつでも無料で使えるので、まずは両方試してみたらいい。肝は上述の通り「保存時の挙動」だと思うので、それによる影響を体験したら、あとは好みのエディタの方で頑張って「良い」と思う挙動に設定すれば良い。

その上で、物足りない / さらに細かいことをやってみたいと感じたらGoLandの無料トライアルを試せば良いのではないかと思う。
hls.jsのcanary版が利用できるようになった


[hls.js](https://github.com/video-dev/hls.js)のリリースタイミングは[Milestones - video-dev/hls.js](https://github.com/video-dev/hls.js/milestones)でも管理していますが、リリースはいくつかの修正を行った後にしています。

そのためPRはマージされたけど修正版のリリースがされてないという状況が発生するという問題があったため、slackで話し合った結果、コミット毎にcanaryビルドをリリースするようになりました。

いわゆるNightlyビルドのようなものです。

[![Kobito.TXA9Yr.png](https://qiita-image-store.s3.amazonaws.com/0/734/fc67b850-b6e9-b671-4876-bf88250cdbc7.png "Kobito.TXA9Yr.png")](https://video-dev.slack.com/archives/C4FC8GGEP/p1525984708000439)

次のPRでcanaryビルドのpublishが実装されています。

- [publish canary package on master commits by tjenkinson · Pull Request #1710 · video-dev/hls.js](https://github.com/video-dev/hls.js/pull/1710)

## Canary版のインストール

通常のstableバージョンは`@タグ`を付けずに`npm install`すればインストールできます。

```
$ npm install hls.js
```

Canary版は`@canary`をつけて`npm install`するとインストールできます。

```
$ npm install hls.js@canary
```

次のように`npm info`で確認すると`canary`タグのついたビルドが公開されていることが分かります。

```
$ npm info hls.js@canary

hls.js@0.9.2-canary.3828 | Apache-2.0 | deps: 2 | versions: 117
JavaScript HLS client using MediaSourceExtension
https://github.com/video-dev/hls.js

...

dist-tags:
beta: 0.5.47               canary: 0.9.2-canary.3828  latest: 0.9.1

```

ブラウザからCDNで直接読み込みたい場合はcdn.jsdelivr.netを使うことで読み込めます。

```html
<!-- stable --> 
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<!-- canary -->
<script src="https://cdn.jsdelivr.net/npm/hls.js@canary"></script> 
```
google cloud platformでMyadminを使う時にハマったこと

google cloud platformで、データベースを使うことが想定されたので、設定しました。
この時に、ハマったことをまとめました。

##チュートリアルを読むとできる
チュートリアルを読むとできます。
念のため、cloud SQLのインスタンスは、作っておいてください。
また、この時に、第二世代を指定して作る場合は、rootのパスワードを設定する必要があります。
このパスワードでMyAdminにログインしますので、必ず控えて置いて下さい。

チュートリアルは、こちらです。
https://cloud.google.com/sql/docs/mysql/phpmyadmin-on-app-engine?hl=ja

チュートリアルの中で、config.inc.phpの修正箇所の入力の際は、括弧を消して下さい。
シングルコーテーションで囲む形で入力します。

phpMyAdminにログインするためのURLで、[YOUR_APP_ID]の部分を適宜書き換えることになります。
この完成したURLは、shellでgcloud app deployを実行した時に、メッセージの中で表示されます。
[YOUR_APP_ID]の確認に迷った時は、shellの出力メッセージを確認してください。

一応shellから、cloudSQLのMySQLにiログインできますので、ユーザーの確認などできます。
こちらが関連の資料です。
https://cloud.google.com/sql/docs/create-manage-user-mysql?hl=ja

##phpMyAdminにログインするとエラーが出た
phpMyAdminにログインできたと思ったら、SQLのエラーが出ました。
日本の設定に関するようでした。
そのため、ログインの画面の言語を英語にしてログインしました。
その後、表示される画面の中の言語の設定で日本語を設定しました。
再びログインする時は、日本語の画面で無事にログインできました。

##phpMyAdminは開発環境毎にインストール
phpMyAdminは、開発するプロジェクトに毎回インストールしないといけない感じのように思いました。

google cloud platformのアプリの作り方を、覚えている段階なので、再びphpMyAdminをインストールする時のために、私の備忘録の意味も込めて書きました。
AWS IoT Enterprise ButtonにLINE投稿させてみた

Amazonで購入できるようになった[AWS IoT Enterprise Button](https://www.amazon.co.jp/gp/product/B075FPHHGG)で遊んでみた。

# 使い方
とっても簡易なマニュアルに、以下のWebサイトを参照するように、と。

[AWS IoT 1-Click](https://aws.amazon.com/jp/iot-1-click/)

# 準備
アクティベートなどはクラメソさんがまとめてくれているので、それを参考にセットアップします。

[【国内販売開始】AWS IoT Enterprise Button試してみたらホンマに簡単にLambda関数を実行できた](https://dev.classmethod.jp/cloud/aws/aws-iot-enterprise-button/)

無事AWSへのデバイス登録までできました。

![スクリーンショット 2018-05-20 17.39.27.png](https://qiita-image-store.s3.amazonaws.com/0/102769/40fcb8b7-de81-e8c9-9595-5ca3c651d17c.png)

# ボタンを押したらLINEに投稿するLambdaを呼び出す

とりあえず物理ボタンを押したらLINEに投稿するような簡単な仕組みをLambdaで組んで、それをIoTボタンから呼び出すようにしてみます。

## LambdaでLINEに投稿するスクリプトの作成

LINEへの登録を終わらせて、いざ開始です。LambdaでLINEに投稿をするようなスクリプトをPythonで組みます。

```py
import json
import os
import sys

#lib配下にライブラリを配置するための前準備
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'lib'))

import requests


LINE_ENDPOINT = 'https://api.line.me/v2/bot/message/push'

LINE_HEADERS = {
    'Authorization': 'Bearer ' + os.environ['ACCESS_TOKEN'],
    'Content-type': 'application/json'
}

def run(event, context):
    payload = {
        'to': os.environ['TO_CHANNEL'],
        'messages': [{
                    'type': 'text',
                    'text': 'Hello World'
                  }]
    }

    response = requests.post(LINE_ENDPOINT, headers=LINE_HEADERS, data=json.dumps(payload))
    print(response)
```

こんな感じで、Hello Worldが呟かれるようになります。

## AWS IoT 1-Clickから呼び出されるように設定する
適当にプロジェクトを作成し、先ほどのスクリプトを呼び出せるように設定します。

![スクリーンショット 2018-05-20 19.41.13.png](https://qiita-image-store.s3.amazonaws.com/0/102769/cafae40b-c683-6668-aade-a59786a71298.png)

プレイスメントも作成して、デバイスと結びつけます。

![スクリーンショット 2018-05-20 19.42.47_deco.png](https://qiita-image-store.s3.amazonaws.com/0/102769/e19c9df9-8f7a-6386-34a6-a70f913160ce.png)


#実行
ボタンを押したら、しっかりメッセージが送られてきました。開始からここまで約1時間でできました。簡単ですね。

![IMG-1304_deco.png](https://qiita-image-store.s3.amazonaws.com/0/102769/8733dcd6-d0c4-674d-7797-d8364c6f7664.png)


# まとめ
かなり簡単にボタンクリック時のアクションの設定ができました。Lambdaが直接呼べる分、ほとんどの処理を行うことができそうです。これはいいおもちゃです。
TensorFlowで画像読み込もうとしたらハマった話

#はじめに
TensorFlowでCNN（今回は画像分類）やろうと調べると先駆者の方々はだいたい画像読み込みにOpenCVを使っているのですが、Python3だとcv2が動かない的な記事がたくさんヒットするわけです（cv3なら動いた疑惑……）。
ということでOpenCV使わずに画像読み込もうとしたらハマったので備忘録（これやってたのが随分前のことで記憶が曖昧ですがご了承ください）。

#適当な解説
まずは画像ファイルパスを正解ラベルが記されたCSVを読み込みます。

```python
# CSV読み込み
trains = np.loadtxt(csv_pass, delimiter=",", dtype=str)
```

CSVの中身はこんな感じ。

```
train/hoge1.jpg,0
train/hoge2.jpg,2
train/hoge3.jpg,1
```

以下、画像と正解ラベルを読み込む関数です。
np.loadtxtで読み込んだデータとセッションオブジェクトを渡してあげます。

```python
def get_image_and_label(sess, csv_lines):
    images = []
    labels = []
    for train in csv_lines:
        #string型なのにバイト記号bが入っているので文字列削除（なぜ？）
        delete = "¥'b¥'"
        train[0]=train[0].strip(delete) 
        
        #画像読み込み
        val = tf.cast(train[0], dtype=tf.string)
        jpeg_r = tf.read_file(val)
        image = tf.image.decode_jpeg(jpeg_r, channels=channel_num) #tf.image.decode_imageはshape型返さないのでダメらしい
        image = tf.image.resize_images(image, [IMAGE_SIZE, IMAGE_SIZE])
        image = tf.reshape(image, [-1]) #-1を指定した場合には次元が削減されflatten
        image = tf.cast(image,dtype=np.float32)
        image = image/255.0 #正規化
        image_val = sess.run(image)
        images.append(image_val)
        
        #ラベル読み込み
        tmp = np.zeros(NUM_CLASSES)
        delete = "¥'b¥'" #同じく"b"を削除
        lab=train[1].strip(delete) 
        index=int(lab) #正解ラベルのインデックス
        tmp[index] = 1
        labels.append(tmp)

    return np.asarray(images, dtype=np.float32), np.asarray(labels, dtype=np.float32)
```

なぜかCSVから読み込んだデータがstring型なのにbyte列を示す記号が付いていたりしてハマりました。自分は雑魚で理由が分からなかったので無理やり該当文字列を削除して何とか画像を読み込みました（原因ご存知の方いましたら教えてください）。
結論は普通にKerasとか使った方が良い。

#参考
ほぼコピペでエラー吐いてた箇所を修正して使わせていただきました。
https://qiita.com/kurimoto/items/0da3c900fcf790964619
WordPressのクエリにバグ。全投稿が出てしまう。

特定の投稿タイプで、where句をカスタマイズしたところ、カスタムフィールドや投稿一覧など（だったはず）に、すべての投稿が表示されてしまった。

コードです。

```php
/**
 * カスタム投稿タイプ、絞込検索でwhere句をカスタマイズ
 */
function custom_search_where($where) {
	if ($_REQUEST['post_type'] !== '*カスタム投稿タイプ名*' || is_admin()) {
//		return; // => バグの原因
		return $where;
	}

	// いろいろ処理

	return $where;
}
add_filter('posts_where', 'custom_search_where');
```

\$_REQUESTで条件分岐しているのが良くない気もしますが、$whereを返さないことで、画像なども含めて、全てが表示されてしまっていました。

その他、`posts_search`、`posts_join`についても、returnするときは引数を返す必要がありました。

#参考
https://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
Pure-FTPdをMac OSXでいじってみる

こんにちは。はにおかさいです。今回はPure-ftpdをインストールして見たいと思います。

##環境
Mac OS X 10.12.6 Sierra

#インストール
```shell
brew install pure-ftpd
```

設定ファイルは
/usr/local/etc/pure-ftpd.conf
にあります。
NoAnonymous をyesにしてあげたり、、、

#起動はこれでできます。
```shell
sudo /usr/local/sbin/pure-ftpd
```

macの標準ユーザーでpureftpdにアクセスすることはできないようなので、virtualuserでどうにかすべきなのでしょう
VSCodeでMySQLの拡張を使うときの設定

#はじめに

自分用メモなのであしからず。
タイトルにVSCodeってつけてるけどVSCode関係の設定は一切記載していません。。

##環境
Windows 10 
VSCode
MySQL 8.0.11

#VSCodeのMySQLの拡張機能

MySQLの拡張機能を使おうとすると、接続時に次のエラーが発生する場合がある。

```
Error: ER_NOT_SUPPORTED_AUTH_MODE
```

どうやら認証形式の違いでエラーをはいているらしい。MySQLのバージョンを確認。

```sql:
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.11    |
+-----------+
1 row in set (0.00 sec)

mysql>
```

ユーザーの認証形式を確認。

```sql:
mysql> use mysql
Database changed
mysql> SELECT user, plugin FROM user;
+------------------+-----------------------+
| user             | plugin                |
+------------------+-----------------------+
| mysql.infoschema | mysql_native_password |
| mysql.session    | mysql_native_password |
| mysql.sys        | mysql_native_password |
| root             | caching_sha2_password |
+------------------+-----------------------+
5 rows in set (0.00 sec)

mysql>
```

今回はrootで接続しようとしていて、認証形式は`caching_sha2_password `となっている。
そのため、以下のSQLを実行し、認証形式を変更する。

```sql:
--例
ALTER USER 'ユーザー名'@'ホスト名'
  IDENTIFIED WITH mysql_native_password
             BY 'パスワード';

--localhostのrootだとこんな感じ
ALTER USER 'root'@'localhost'
  IDENTIFIED WITH mysql_native_password
             BY 'password';

```

もう一回、SQLを実行して変更できたか確認する。

```sql:
+------------------+-----------------------+
| user             | plugin                |
+------------------+-----------------------+
| mysql.infoschema | mysql_native_password |
| mysql.session    | mysql_native_password |
| mysql.sys        | mysql_native_password |
| root             | mysql_native_password |   --<= 変わってる！
+------------------+-----------------------+
```

これで拡張機能は使用できるはず。


##参考
https://github.com/formulahendry/vscode-mysql/issues/39
https://yoku0825.blogspot.jp/2018/01/mysql-804.html
Ethereum のアドレスが適切かどうかチェックする

* Ethereum のアドレスが適切（valid）なアドレスかどうかをチェックする方法です。
* Web3 1.0.0 を使用します。

# サンプルコード

```js
const isValidAddress = Web3.utils.isAddress(address);
```

# デモ
* [https://piyolab.github.io/playground/ethereum/isValidEthereumAddress/](https://piyolab.github.io/playground/ethereum/isValidEthereumAddress/)

# Note
- Ethereum 関連の情報は https://scrapbox.io/sushiether/ に集約することにしました。
- この記事の内容に変更・更新がある場合は、以下の URL を更新します。
- https://scrapbox.io/sushiether/Ethereum_のアドレスが適切かどうかチェックする
Variable Computation の実装に関するメモ

##ポイント
* LSTMをベースに Variable Computation (VCLSTM) を実装。
* 今後、数値検証を行う。
* 今後、（広い意味で）Adaptive Computation Time について整理する。

##レファレンス
[1. Variable Computation in Recurrent Neural Networks](https://arxiv.org/abs/1611.06188)

##モデル・アーキテクチャ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/76cc91a8-c6ec-6140-3fb8-bd8481364616.png)
　　　　　 　 　        （参照論文より引用）

```math
m_t = \sigma(W_m[x_t, h_{t-1}] + b_m) \\
∀i\in1, ..., D \quad (e_t)_i = Thres_\epsilon\Bigl(\sigma\Bigl(\lambda\bigl(m_tD - i\bigr)\Bigr)\Bigr) \\
\bar{h}_{t-1} = e_t \odot h_{t-1},\quad \bar{c}_{t-1} = e_t \odot c_{t-1},\quad \bar{x}_t = e_t \odot x_t \\ 

\quad \\
\begin{pmatrix}
i_t \\
f_t \\
o_t \\
g_t \\
\end{pmatrix}
=
\begin{pmatrix}
\sigma(W_i[\bar{x_t},\bar{h}_{t-1}]+b_i) \\
\sigma(W_f[\bar{x_t},\bar{h}_{t-1}]+b_f) \\
\sigma(W_o[\bar{x_t},\bar{h}_{t-1}]+b_o) \\
tanh(W_g[\bar{x_t},\bar{h}_{t-1}]+b_g) \\
\end{pmatrix} \\
\tilde{c}_t = f_t * \bar{c}_{t-1} + i_t * g_t \\
\tilde{h}_t = o_t * tanh(\tilde{c}_t) \\

\quad \\
c_t = e_t \odot \tilde{c}_t + (1-e_t) \odot c_{t-1} \\
h_t = e_t \odot \tilde{h}_t + (1-e_t) \odot h_{t-1}

```
##サンプルコード
```python
  def VCLSTM(self, x, h, c, n_in, n_units, batch_size, \
                 lam, eps):
    w_m_x = self.weight_variable('w_m_x', [n_in, 1])
    w_m_h = self.weight_variable('w_m_h', [n_units, 1])
    b_m = self.bias_variable('b_m', [1])
    
    w_x = self.weight_variable('w_x', [n_in, n_units * 4])
    w_h = self.weight_variable('w_h', [n_units, n_units * 4])
    b = self.bias_variable('b', [n_units * 4])
    
    m = tf.sigmoid(tf.add(tf.add(tf.matmul(x, w_m_x), \
                tf.matmul(h, w_m_h)), b_m))
    
    a_h = m * n_units
    b_h = tf.convert_to_tensor(np.array(range(n_units)), \
                dtype = tf.float32)
    b_h = tf.tile(tf.expand_dims(b_h, axis = 0), \
                [batch_size, 1])
    e_h = tf.sigmoid(lam * (a_h - b_h)) - (1 - eps)
    e_h = tf.nn.relu(tf.sign(e_h))
    
    h_bar = h * e_h
    c_bar = c * e_h
    
    a_x = m * n_in
    b_x = tf.convert_to_tensor(np.array(range(n_in)), \
               dtype = tf.float32)
    b_x = tf.tile(tf.expand_dims(b_x, axis = 0), \
               [batch_size, 1])
    e_x = tf.sigmoid(lam * (a_x - b_x)) - (1 - eps)
    e_x = tf.nn.relu(tf.sign(e_x))
    
    x_bar = x * e_x
    
    i, f, o, g = tf.split(tf.add(tf.add(tf.matmul(x_bar, \
           w_x), tf.matmul(h_bar, w_h)), b), 4, axis = 1)
    
    i = tf.nn.sigmoid(i)
    f = tf.nn.sigmoid(f)
    o = tf.nn.sigmoid(o)
    g = tf.nn.tanh(g)
    
    c_tilde = tf.add(tf.multiply(f, c_bar), \
                 tf.multiply(i, g))
    h_tilde = tf.multiply(o, tf.nn.tanh(c_tilde))
    
    c = tf.add(tf.multiply(e_h, c_tilde), \
                 tf.multiply((1 - e_h), c))
    h = tf.add(tf.multiply(e_h, h_tilde), \
                 tf.multiply((1 - e_h), h))
    
    return h, c
```
VirtualBoxの環境を他のPCに引き継ぐ方法

VirtualBoxで作成した環境を他のPCでも使用できるようにする方法について記載していきます。

1.VirtualBoxの設定ファイルが入っているフォルダを移動したい先に移す。
（VirtualBox VMs/作成した仮想マシン名のフォルダごと移動)
2.VirtualBoxマネージャー（起動して一番最初に出る画面）でタブのファイル‣環境設定を開く。

3.「一般」メニューの「デフォルトの仮想マシンフォルダー」を移動先に設定。

4.タブのファイル‣仮想メディアマネージャーを開き、
！黄色くなっている行を右クリックし、「除去」を押す。

５．VirtualBoxマネージャーの左側の部分に自分の作成した仮想マシン（電源オフとかかいてある部分）がある場合は、それも右クリックし、「除去」→「すべてのファイルを除去」を押す。
６．タブの「仮想マシン」‣「追加」を選択し、１．で移動したフォルダ内の「～.vbox」を選択。

７．起動できるか確認する。

※一度閉じて再度VirtualBoxを起動した際に、マシンが起動できなくなった場合は、VirtualBoxのアイコンを右クリックし「プロパティ」を選択して、「互換性」タブの「互換モード」の下にある「互換モードでこのプログラムを実行する」にチェックを入れ、自分のPCのOSバージョンを選択し、OKをクリック
（ない場合は、Windows7かWindows Vistaを選択し、再度VirtualBoxを開き、起動を確認。）

８．インポート
環境を引き継ぎたい先のPCにVirtualBoxをインストールし、「新規」を押す。
名前とバージョンは引き継ぎ元PCで作成したものと同じにし、「次へ」を選択。
「ハードディスク」の画面で「すでにある仮想ハードディスクファイルを使用する」を選択し、1.で移動したフォルダ内の「～.vdi」を選択し、マシンを作成。

起動できれば、完了！

※ブリッジモードなどのネットワークの設定は再度実施する必要があります。
CentOS7 Git2系をyumからインストールする。

## 背景

CentOS7に標準搭載されているGitは未だに1系のバージョンが入っています。
サーバーの環境をする際に最新のGitをインストールします。

私の検索の仕方が悪いのか、ソースからビルドしてインストールする方法はたくさん見つかるものの、
yumからインストールする方法はどうしても見つけられなかったので自分で試すことにしました。

## yum からインストールする

```sh
# yum -y remove git
# yum -y install https://centos7.iuscommunity.org/ius-release.rpm
# yum -y install git2u yum-utils
# yum-config-manager --disable ius

# git --version
git version 2.17.0
```

## ソースからインストールする

一応、ソースからインストールする方法も書いておきます。

```sh
# yum -y remove git 
# yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker

# GITVERSION="2.17.0" &&
wget https://www.kernel.org/pub/software/scm/git/git-$GITVERSION.tar.gz &&
tar -zxf git-$GITVERSION.tar.gz &&
cd git-$GITVERSION &&
make prefix=/usr/local all &&
make prefix=/usr/local install &&
cd ../ &&
rm -rf git-$GITVERSION* &&
unset GITVERSION
```

ソースからビルドする方法はインストールするのに時間がめっちゃかかります。

## 補足

https://ius.io
IUSリポジトリに新しいRPMパッケージが作成されているそうです。
Javascript　二つのフォームの値を比較してページ遷移に制限を掛ける

# 目的
スポーツのアプリを作成中。
結果の送信画面にて引き分けが存在しないスポーツなので表側で制限を掛けたい。

#ソースコード
```erb:
    <%= form_for game, url: game_score_path do |f| %>
      <div class='form-group'>
        <%= f.label :自分の得点 %>
        <%= f.number_field :score1, class:'form-control', id:'member1-score' %>
      </div>
      <div class='form-group'>
        <%= f.label :相手の得点 %>
        <%= f.number_field :score2, class:'form-control', id:'member2-score' %>
      </div>
      <div class="mb-2">
        <span class="form-group error" aria-live="polite"></span>
      </div>
      <div class='form-group text-center'>
        <%= f.submit '申請する', data: {confirm:'入力に誤りはありませんか?'}, class:'btn btn-lightblue mx-auto', id:'scoreButton' %>
      </div>
    <% end %>
```

```js:
var form  = document.getElementsByTagName('form')[0];
var error = document.querySelector('.error');
var score1Form = document.getElementById("member1-score");
var score2Form = document.getElementById("member2-score");
var button = document.getElementById("scoreButton");
score1Form.addEventListener("input", function (event) {
  var score1 = document.getElementById("member1-score").value;
  var score2 = document.getElementById("member2-score").value;
  if (!score1 == score2) {
    error.innerHTML = ""; 
    error.className = "error";
  }
}, false);
score2Form.addEventListener("input", function (event) {
  var score1 = document.getElementById("member1-score").value;
  var score2 = document.getElementById("member2-score").value;
  if (!score1 == score2) {
    error.innerHTML = "";
    error.className = "error";
  }
}, false);
button.onclick = function(){
  $('form').submit(function () {
    var score1 = document.getElementById("member1-score").value;
    var score2 = document.getElementById("member2-score").value;
    if (score1 == "" || score2 == "") {
      error.innerHTML = "スコアを入力してください";
      error.className = "error active";
      return false;
    } else if(score1 == score2){
      error.innerHTML = "勝敗がつくスコアを入力してください";
      error.className = "error active";
      return false;
    } else{
      this.submit();
    }
  });
};
```

```scss:
.error {
  width  : 100%;
  padding: 0;
 
  font-size: 80%;
  color: white;
  background-color: #900;
  border-radius: 0 0 5px 5px;
 
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.error.active {
  padding: 0.3em;
}
```

#解説

送信ボタンを押した時にスコアが同点もしくは一方でも空の場合にエラー文が一文でます。
その時に一文字でもどちらか一方でも入力があればエラー文を即座に消す処理です。
エラー二つに分けて書いてますが同じ場所に出力する仕様ですので配列の変数にしてeachで回した方が短いし見易い。

#参考
https://developer.mozilla.org/ja/docs/Learn/HTML/Forms/Data_form_validation
エラー、構造に関してはこちらを拝借。
Thermo MSで取得した .rawファイルを何とかcsvまでもっていった

#Thermo MSで取得した .rawファイルを何とかcsvまでもっていった
###全データをstringbuilderを利用して展開した




```

        async private Task<StringBuilder> RawDecode(string[] fileName)
        {
           MSFileReader_XRawfile rawfile = new MSFileReader_XRawfile();

            rawfile.Open(fileName[0]);
            rawfile.SetCurrentController(0, 1);

            int totalscannum = 0;

            rawfile.GetNumSpectra(ref totalscannum);

            double ProfilePeakWidth = 0.0;
            object MassList = null;
            object PeakFlags = null;
            int ArraySize = 0;

            textBox.Text = ""; //テキストボックスの初期化

            StringBuilder rawcsv = new StringBuilder();

            await Task.Run(() => {
                int a = 1;
            
                do
                {
                    rawfile.GetMassListFromScanNum(ref a, null, 1, 0, 0, 0, ref ProfilePeakWidth, ref MassList, ref PeakFlags, ref ArraySize);
                    double[,] mslist = (double[,])MassList;

                    for (long i = 0; i < mslist.GetLength(1); i++)
                    {
                            rawcsv.Append(a.ToString());
                            rawcsv.Append(",");
                            rawcsv.Append(mslist[0, i].ToString());
                            rawcsv.Append(",");
                            rawcsv.Append(mslist[1, i].ToString("#;#;0"));
                            rawcsv.Append("\r\n");
                            i++;//なんだこれ？
                        }
                       a++;

                    } while (a < totalscannum + 1) ;
                    rawfile.Close();
                
                delegate_WriteLine TextWrite = new delegate_WriteLine(WriteLine);
                this.textBox.Invoke(TextWrite, rawcsv);
            });
            
            progressBar1.Value = 0;
            return rawcsv;
        }

        delegate void delegate_WriteLine(StringBuilder datas);
        private void WriteLine(StringBuilder datas)
        {
            this.textBox.Text = datas.ToString();
        }
```
###
【Google VR】インタラクションサンプルコード


Daydreamのコントローラで動作確認

コントローラの名称はこちらを参照
[Daydream View のコントローラとヘッドセットを使用する](https://support.google.com/daydream/answer/7184597?hl=ja)

GvrControllerInput
https://developers.google.com/vr/unity/reference/class/GvrControllerInput


```csharp
// Daydreamボタンを押した瞬間True
if(GvrControllerInput.HomeButtonDown){
    Debug.Log("HomeButtonDown");
}

// ポジションリセンターした瞬間True（Daydreamボタンの長押し）
if(GvrControllerInput.Recentered){
    Debug.Log("Recentered");
}

// アプリボタンを押した瞬間True
if(GvrControllerInput.AppButtonDown){
    Debug.Log("AppButtonDown");
}
// アプリボタンを押した指を離した瞬間True
if(GvrControllerInput.AppButtonUp){
    Debug.Log("AppButtonUp");
}

// タッチパッドにタッチした瞬間True
if(GvrControllerInput.TouchDown){
    Debug.Log("TouchDown");
}
// タッチパッドから指が離れた瞬間True
if(GvrControllerInput.TouchUp){
    Debug.Log("TouchUp");
}
// タッチパッドにタッチしている間ずっとTrue
Debug.Log("IsTouching : " + GvrControllerInput.IsTouching);

// タッチパッドのタッチしている位置 0~1
Debug.Log("TouchPos : " + GvrControllerInput.TouchPos);
// タッチパッドのタッチしている位置 -1~1
Debug.Log("TouchPosCentered : " + GvrControllerInput.TouchPosCentered);

// コントローラの傾き
Debug.Log("Orientation : " + GvrControllerInput.Orientation);
// コントローラの正面方向のベクトル
Vector3 rayDir = GvrControllerInput.Orientation * Vector3.forward;
Debug.Log("rayDir : " + rayDir);

// 角速度 | 回転の動きを取得
// 操作しないとVector3.zeroに戻る
// ex.一定速度以上でコントローラを振ったらボールを投げる
Debug.Log("Gyro : " + GvrControllerInput.Gyro);

// 加速度 | 重力、振動、衝撃を計測
// ex.コントローラが傾いているとか、ぶら下がっているとかを判定する
Debug.Log("Accel : " + GvrControllerInput.Accel);
```

> 参考
[付録B Daydreamコントローラーを使ってみる](https://github.com/oreilly-japan/unity-virtual-reality-projects-ja/wiki/%E4%BB%98%E9%8C%B2B)
ハイフンで範囲を示した数の展開

#'3,5,7-10' → [3,5,7,8,9,10]

```python
def expand_numbers(s,nmin=1,nmax=100):
    a=[]
    for v in re.split('[\s,]+',s):
        if '-' in v: 
            v0,v1=v.split('-')[:2]
            if v0 == '': v0=nmin
            if v1 == '': v1=nmax
            a.extend(range(int(v0),int(v1)+1))
        else:
            a.append(int(v))
    return list(set(a))
```

```python
expand_numbers('3,5,7-10')
[3, 5, 7, 8, 9, 10]

expand_numbers('-5,8')
[1, 2, 3, 4, 5, 8]

expand_numbers('3-5,4-7')
[3, 4, 5, 6, 7]
```

##コメント

##参考文献
curl https://sh.rustup.rs -sSf | sh を non-interactive に実行する

（自分用のポータブルな開発環境を作る場合など）DockerなどでRustを扱いたい場合に、Dockerfileを使ってnon-interactiveにセットアップする場合は下記のように```| sh -s -- ```を使うことができます。

```
curl https://sh.rustup.rs -sSf | sh -s -- -y
```

``--`` の後に通常通りrustのインストールオプションを記述するだけです。


ちなみに、Rustの下記のgithub.io上の日本語ドキュメントでも```| sh -s -- ```を使ったオプション指定方法が紹介されています。
[https://rust-lang-ja.github.io - Nightly Rust](https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/nightly-rust.html)

```
$ curl -s https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly
```