OmniAICreator/Qiita-1.07M huggingface dataset:
z.com APIを用いてのデプロイ

# Z.com のセキュリティグループをAPIで変更してデプロイ

## Z.comとは

https://z.com/jp/
GMOグループが去年始めた企業向け(?)クラウドサービス
基本的な機能は抑えて有り、料金もお手頃。
管理画面からインスタンス作成から削除等、使い方も簡単だがリリースして日が浅いからか痒い部分に手がとどかない
最近はブロックチェーン用のサービスも展開しており、今後の展開が面白そう


## 経緯

仕事で使った際に、CircleCIからの自動デプロイで手間取ったので備忘録兼、誰かの手助けになればと思い簡単にメモ
インフラ初心者なのと、メモ書き程度なので間違っていたりしても許してください

## 問題点

AWSへのCircleCIからのデプロイの場合、CodeDeployや、aws cliを用いてセキュリティグループに自IPを追加してのデプロイかと思われるのだが、
Z.comにはそのような機能は無く、あるのは豊富なAPI群
https://cloud.z.com/sg/ja/cloud/docs/

## z.comクラウドのAPI利用方法

// トークン発行

```shell-session
curl -X POST \
-H "Accept: application/json" \
-d '{"auth":{"passwordCredentials":{"username":"【ID】","password":"【パスワード】"},"tenantId":"【テナントID】"}}' \
https://identity.jpt1.cloud.z.com/v2.0/tokens | jq .
```


// セキュリティグループ一覧取得

```shell-session
curl -X GET \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
https://networking.jpt1.cloud.z.com/v2.0/security-groups | jq .
```

// セキュリティグループ作成

```shell-session
 curl -X POST \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
-d '{"security_group": {"name": "【作りたいセキュリティグループ名】"}}' \
https://networking.jpt1.cloud.z.com/v2.0/security-groups | jq .
```


// セキュリティグループルール追加

```shell-session
curl -X POST \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
-d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv4", "security_group_id": "【対象セキュリティグループID】", "port_range_min": "1", "port_range_max": "65535", "protocol": "tcp", "remote_ip_prefix": "【対象CIDER】"}}' \
https://networking.jpt1.cloud.z.com/v2.0/security-group-rules | jq .
```

// IP指定なし

```shell-session
curl -X POST \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
-d '{"security_group_rule": {"direction": "ingress", "ethertype": "IPv4", "security_group_id": "【対象セキュリティグループID】", "port_range_min": "22", "port_range_max": "22", "protocol": "tcp"}}' \
https://networking.jpt1.cloud.z.com/v2.0/security-group-rules | jq .
```

// セキュリティグループルール削除

```shell-session
curl -X DELETE \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
https://networking.jpt1.cloud.z.com/v2.0/security-group-rules/【対象セキュリティグループルールID】 | jq .
```

// セキュリティグループ削除

```shell-session
curl -X DELETE \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
https://networking.jpt1.cloud.z.com/v2.0/security-groups/【対象セキュリティグループID】 | jq .
```

// ポート情報

```shell-session
curl -X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
https://networking.jpt1.cloud.z.com/v2.0/ports | jq .
```


// 割当

```shell-session
curl -X PUT \
-H "Accept: application/json" \
-H "X-Auth-Token: 【発行したトークン】" \
-d '{"port": {"security_groups": ["【割り当てたいセキュリティグループID】", "【複数入力可能】"]}}' \
https://networking.jpt1.cloud.z.com/v2.0/ports/【対象ポートID】 | jq .
```


自分の場合はpushに紐付けてデプロイ先のインスタンスのセキュリティグループの許可群にデプロイ元のIPを追加→デプロイ→セキュリティグループ削除
というのを行うスクリプトを設置して、git pushから紐付けて自動デプロイを構築した。

今後改良していくとは思うが、中途半端ではありますがメモとして残しておきます。
MT4が応答しない場合の復旧方法

# MT4が固まった

MT4がフリーズしました。

# 対処法
ユーザーフォルダを退避させて再インストール。その後、ユーザーフォルダを元の位置に戻す

※ここでのユーザーフォルダとは
C:\Users\ユーザー名\AppData\Roaming\MetaQuotes\Terminal\32桁の16進数
のこと。

大抵はこれでうまくいきますが今回はうまくいかなかったので原因調べてメモ。

# 原因
結論から言うと、以下のファイルでした。

ユーザーフォルダ下のconfigフォルダでした。この中の

- accounts.ini
- server.ini

これを削除すると正常に起動するようになりました。
デモ口座の有効期限とかが原因な気がします。

# その他の原因
よくあるフリーズの原因としてはlogフォルダの肥大化があります。

テスターで長期間のテストや運用をしているとlogファイルが数GBになったりします。

MT4のlogファイルは3つあるので、全部チェックしましょう。

- ユーザーフォルダ直下
- MQL4フォルダ下
- testerフォルダ下
Kuin マウス入力の「押しっぱなし」を無効にする処理

#マウスの押しっぱなしを無効にする
##kuina.ch公式の「入力関係」を確認
[プログラミング言語Kuin：ドキュメント](http://kuina.ch/kuin)
上記サイトの中にある「Kuinドキュメント301 wndライブラリ」の中に、マウス入力関係の機能が載っています。該当の箇所は「**wnd@Draw**」です。この中にマウスの処理に関するものが見つかりますが、ドキュメントには細かい使い方が載っていません。

##kuin.exe同梱のサンプルプログラムを確認
2017/10/8現在、プログラミング言語Kuinを導入すると付属しているサンプルプログラムの中に、マウス入力関係の使用法が示されています。
その中でマウス入力を受け付ける準備と、その処理は以下のようになっています。
kuina.ch公式のサンプルプログラムを参考にしつつお読みください。
変数や関数名はそのままです。
まずグローバルで「マウスが押されている判定」の変数を宣言。

```kuin:main.kn
var mouseDownL: bool
```

次にmain()内でマウスが押された時に発生するイベントを設定します。
この中で「`@drawMainOnMouseDownL`」とは自分で用意する関数です。
[...]は中略です。

```kuin:main.kn
func main()
    ...
    do @drawmain.onMouseDownL :: @drawMainOnMouseDownL
    ...
```

このようにしておくと、マウスの左ボタンが押された時に`@drawMainOnMouseDownL`が呼び出されるということになるようです。
以下はその`@drawMainOnMouseDownL`の中身です。

```kuin:main.kn
func drawMainOnMouseDownL(wnd: wnd@Draw, x: int, y: int)
    do @mouseDownL :: true {左ボタンが押された}
end func
```

引数は現段階で無視してください。私もよくわかりません。
最初に用意したグローバル変数 `@mouseDownL` に true を設定します。
この `@mouseDownL` を読むことで、プログラム実行中「マウスボタンが押されているか否か」を判定するという形です。サンプルプログラムとしてはこれ以上の内容は示されていません。
サンプルプログラムを実行すると「マウス左ボタンを押している間、色が変わる円が描画される」というものになります。
![20171008-1.png](https://qiita-image-store.s3.amazonaws.com/0/206420/369c5132-0610-174d-32fa-174163f06cd1.png)
A）ボタンを押していない

![20171008-2.png](https://qiita-image-store.s3.amazonaws.com/0/206420/e98df809-bee1-be6e-edb0-dccfb0ff0e4e.png)
B）ボタンを押している

##ボタンを押した瞬間だけ処理する
まずグローバル変数に「`@mouseLLock`」のようなロック用の変数を用意します。

```kuin:main.kn
var mouseDownL: bool
var mouseLLock: bool {←追加分}
```

メイン関数の中に記述するイベント取得はそのまま利用できます。
同じ内容です。

```kuin:main.kn
func main()
    ...
    do @drawmain.onMouseDownL :: @drawMainOnMouseDownL
    ...
```

次に「`@drawMainOnMouseDownL`」関数の内容をいじります。

```kuin:main.kn
func drawMainOnMouseDownL(wnd: wnd@Draw, x: int, y: int)
    {ロック判定が true の場合は無視する}
    if(@mouseLLock <> true)
        {ロック判定が false なら @mouseDownL を true にしマウス入力判定を立てる}
        do @MouseDownL :: true
    end if
    {ロックをかける。}
    do @mouseLLock :: true
end func
```
マウスを押した瞬間に「マウスが押された」「マウスをロックした」処理が起こります。この時、マウスを押しっぱなしにしていると「マウスのロック」判定によって、`@mouseDownL` への処理が無視されます。
次に「マウスを離した時」の判定を修正します。これはサンプルプログラム内で `@drawMainOnMouseUpL` として実装されていたものを、以下のように変更します。

```kuin:main.kn
func drawMainOnMouseUpL(wnd: wnd@Draw, x: int, y: int)
	do @mouseDownL :: false {左ボタン離された}
	do @mouseLLock :: false {←追加分。マウスロック解除}
end func
```

マウスが離された場合、ロック機構は不要なので無条件で `@mouseLLock` も false にします。
最後にプログラム中で「マウスを押したときに処理する部分」に、`@mouseLLock` を false とする処理を追加すれば「**マウスを押している最初の瞬間だけ処理する**」という形になり、押しっぱなし問題は解決します。
例）

```kuin:main.kn
    {マウス判定ループ}
        if(@mouseDownL = true){マウス左が押されたなら}
            do @mouseDownL :: false
            ... {以下マウスを押された時の処理}
```

これは今回の修正で「**マウスを離さない限り**、マウスを押し続けていたとしても **`@mouseDownL` が true にならない**」という状況にした為です。
closureの定義がわかんなくなったので、調べた

# 背景

goのtutorialをやっていて、closureの箇所をやっていたのだけれど、定義がわかんなくなったので、調べていた。

# 定義

[英語版のwikipediaに書いてある定義](https://simple.wikipedia.org/wiki/Closure_(computer_science))が一番しっくりきた。

> In computer science, a closure is a function that has an environment of its own. In this environment, there is at least one bound variable (a name that has a value, such as a number). The closure's environment keeps the bound variables in memory between uses of the closure.

ざっくり和訳するとこんな感じ。

コンピュータサイエンスにおいて、closureとはそれ自身の環境を持つ関数である。その環境では少なくとも一つの変数がある。そのclosureの環境はそのclosureを使用する限りにおいて、その変数を保持する。

# 勘違いしやすいやつ

よく出される例だと勘違いしやすいので、定義に則って考えると、こうなる

```go
package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
// このfibonacciは関数を返す関数なので、closureではない。言わばclosureを返す関数。
func fibonacci() func() int {
	before_two := make([]int, 2)
	before_two[0] = 0
	before_two[1] = 1
	return func() int{
		this_fibo_num := before_two[0] + before_two[1]
		before_two[0] = before_two[1]
		before_two[1] = this_fibo_num
		return this_fibo_num
	}
}

func main() {
	f := fibonacci()　// このfはclosure
	b := fibonacci() // このbもclosure
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
	for i := 0; i < 10; i++ {
		fmt.Println(b())
	}
}
```


# 雑感

今までの、イメージ的では関数を返す関数みたいなのが、closureって思っていたけど、違うってことが分かってよかった。
Kaggle - Outbrain上位陣リンク一覧

KaggleのOutbrain Click Prediction[^1]の上位陣リンク一覧です．

- [2位] [Faron](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27977#latest-161800), ✎[code](https://github.com/alno/kaggle-outbrain-click-prediction)
- [3位] [CuteChibiko](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27923#latest-159552), [rcarson](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27892)
- [4位] [Andrii Cherednychenko](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27926#latest-161316)
- [13位] [ololo](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27897), ✎[code](https://github.com/alexeygrigorev/outbrain-click-prediction-kaggle), ✎[Qiita](https://qiita.com/namakemono/items/5fba530d2f8f6c1e1418)
- [15位] [Frederik](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27897), ✎[Qiita](https://qiita.com/namakemono/items/e1070abe822bf816c149)
- [18位] [Sameh Faidi](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27897)
- [19位] [Gabriel Moreira](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27897)

## References

[^1]: Kaggle, [Outbrain Click Prediction](https://www.kaggle.com/c/outbrain-click-prediction), 2017
Twitterをやめる

Twitterは時間を搾取する悪い文明であり、粉砕しなければならないときがあります。

Twitterを粉砕するには、ターミナルを開いて以下を入力し、

```
$ sudo nano /etc/hosts
```

最終行に以下を追加します。

```
127.0.0.1 twitter.com
```

変更を保存するために、（エディタが`nano`であれば） `control` を押しながら、 `o` `Enter` `x` を続けて押します。これで、Twitterにアクセスできなくなりました。

参考：[Twitterをやめつつある](http://masawada.hatenadiary.com/entry/2017/09/30/120837)
VagrantでRocket.Chatを構築

# 経緯
社内で使えるチャットツールを検証しようと思って、Rocket.Chatの公式にあるdocker-compose.ymlを元に起動したところ、windowsで動作できませんでした。（docker toolboxとwindows8.1では駄目だっただけです...）
githubを確認すると、ubuntu16.04だとコマンド一つでできそうなのでやってみました。

# 必要なもの
- vagrant
- virtualbox

# 検証
ubuntu16.04のboxが必要なので追加します。virtualboxを使うので、providersの指定を入れます。

```shell-session
$ vagrant box add ubuntu16.04 https://atlas.hashicorp.com/bento/boxes/ubuntu-16.04/versions/2.3.8/providers/virtualbox.box
```

Vagrantfileを編集します

```Vagrantfile:Vagrantfile
Vagrant.configure("2") do |config|
  // boxの指定
  config.vm.box = "ubuntu16.04"

  // port:3000で確認できるようにします
  config.vm.network "forwarded_port", guest: 3000, host: 3000

  // 起動時に行うコマンド. 
  config.vm.provision "shell", inline: <<-SHELL
    snap install rocketchat-server
  SHELL
end

```

準備はこれだけです。後は以下のコマンドをVagrantfileのあるディレクトリで実行して、`http://localhost:3000`をブラウザで確認すればOKです。

```shell-session
$ vagrant up
```

# まとめ
これだけで動作確認することができるので非常に簡単です。ubuntu16.04が動く環境であればなんでもいいわけですね。他にも色々方法があるので、興味がある方はRocket.Chatのgithubで確認してみてください。
gitの基本的なこと

#駆け出しのプログラマーとして、gitを使ってみたかったので、調べながら使ってみたことをまとめました

まず、mkdirでディレクトリを作る
`$mkdir git_pra`


次に何でもいいから、テキストファイルを作成
`$touch pra.txt`

このディレクトリでgitを使うために
`$git init`

これで、準備完了
`$ls -a`
でチェックしてみて、
`. .. .git`
が出て来たら、成功

ここから、pra.txtの内容を変更、保存して、
`$git status`
すると赤文字で、pra.txtが表示される

変更があるけど、stagingされてないよ。って感じだと思う。
だから、
`$git add pra.txt`
でステージング
再度
`$git status`
すると、今度は緑色で表示されるから、コミットする準備ができたよーって感じだと思う。
そこで、
`$git commit -m "何かコミットメッセージ"`
これでコミットは完了
`$git log`
で確認したら、しっかりコミットされてる！！

今回はgitの基礎の基礎、コミットまでだけまとめてみました。
今後は、ブランチ切ったり、マージしたりってことをやっていきたいと思います。
リモートリポジトリはまだ、もう少し先かなぁ…
Sorcery + CarrierWave で Facebook 認証時に大きめのアイコン画像を保存する

- user_info_mapping に `remote_{カラム名}_url` をセット
- user_info_path の fields に `picture.type(large)` を入れる

```ruby:models/user.rb
class User < ApplicationRecord
  authenticates_with_sorcery!
  mount_uploader :icon, IconUploader
```

```ruby:config/initializers/sorcery.rb
  config.facebook.user_info_mapping = {email: 'email', nickname: 'name', remote_icon_url: 'picture/data/url'}
  config.facebook.user_info_path = "me?fields=email,name,picture.type(large)"
```


Sorcery の external モジュールで Facebook 認証をした段階でプロフィール画像を保存したい時用のメモ。
CarrierWave は `remote_{カラム名}_url` でURLからファイルをダウンロードしてセットすることができるので、Sorcery の external モジュールで保存する場合もこの形式でマッピングすればいい。Facebookから取得できるプロフィール画像はデフォルトではあまりにも小さすぎるため、user_info_path の picture フィールドに `picture.type(large)` を指定すると、実用的なサイズの画像を取得することができる。
Monacoin 価格通知

# Monacoin 価格通知

## 前提条件

```bash
brew install jq
```

- [jq is a lightweight and flexible command-line JSON processor.](https://stedolan.github.io/jq/)

## インストール方法

```bash
# Download script file
curl -sSo /usr/local/bin/monacoin https://gist.githubusercontent.com/hanksudo/044b9b4b3d10289484190ff5568c4db7/raw/monacoin.sh
# Give executable permission
chmod +x /usr/local/bin/monacoin
```

または、自分で `/usr/local/bin/monacoin` を作成する

```bash:monacoin.sh
#/bin/sh

# $ monacoin
# 85.6

# Get price
MONA=`curl -s https://api.zaif.jp/api/1/last_price/mona_jpy | jq .last_price`

# macOS notifier
osascript -e "display notification \"$MONA\" with title \"Monacoin\""

# print
echo $MONA

# speak
say "monacoin $MONA"
```


# 使い方

```
$ monacoin
85.6
```

## 3時間ごとに実行する - launchagents

```plist:~/Library/LaunchAgents/monacoin.price.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>monacoin.price</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/monacoin</string>
    </array>
    <key>StartInterval</key>
    <integer>60 * 60 * 3</integer>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardOutPath</key>
    <string>/tmp/monacoin.out</string>
    <key>StandardErrorPath</key>
    <string>/tmp/monacoin.err</string>
</dict>
</plist>
```

### 起動

```bash
launchctl setenv PATH /usr/local/bin:$PATH
launchctl load ~/Library/LaunchAgents/monacoin.price.plist
```
PHP7とNginxで開発環境を整える

# PHP7とNginxをインストールして開発環境を整える。
wordpress4.8系の推奨環境が、PHP7系ということでPHP7とNginxで環境を構築する方法をメモします。
ここでは、wordpressインストールまではやりません。

## NginxとPHP7のインストール
ここでハマったのは、FTPのポートを開けてなくて、1つ目のインストールができなかったことです。
なので手元のMacでダウンロードして、SCPしました。ダサすぎるｗ

### scl-utilsのインストール
手元のMacのブラウザで以下にアクセスし、ダウンロード
`ftp://ftp.scientificlinux.org/linux/scientific/6.4/x86_64/updates/fastbugs/scl-utils-20120927-8.el6.x86_64.rpm`

EC2にアップロード
`scp scl-utils-20120927-8.el6.x86_64.rpm ec2-user@xxx.xxx.xxx.xxx:/home/ec2-user`

インストール
`sudo rpm -Uvh scl-utils-20120927-8.el6.x86_64.rpm`

### remiレポジトリのインストール
`sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm`

### NginxとPHPのインストール
`sudo yum install nginx php70 php70-php-fpm`

## NginxとPHP-fpmの自動起動
```
sudo chkconfig php70-php-fpm on
sudo chkconfig nginx on
```

## Nginxの設定
SCRIPT_FILENAMEのところを$document_rootとしているところがうまく動かなかったので今回は直書き。
動くのが正義。孫正義

```
    server {
        listen       80;
        server_name  localhost;
        root         /var/www/html;
        index        index.php index.html;
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
            fastcgi_param  PATH_INFO $fastcgi_script_name;
            include        fastcgi_params;
        }
    }
```

## PHPとNginxの再起動
`
sudo service nginx restart
sudo service php70-php-fpm restart`

## PHPのファイルを作って動作確認
```
cd /var/www/
sudo mkdir html
sudo vi html/index.php
```

index.phpの内容
```
<?php phpinfo(); ?>
```

```
sudo chmod -R 755 html/
```

ブラウザでEC2のIPアドレスにアクセスするっす！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/906791ee-abeb-c12e-0496-56a313d61d1d.png)
msys2 + MinGW64 でWindows10にターミナル環境構築

## やりたかったこと
- windows10でもzsh+tmux+powerlineの環境が欲しかった(結局<a href="https://github.com/vim-airline/vim-airline">vim-airline</a>を使ってる)。
- ファイルをvimで快適に編集したかった。
- ```
$ vagrant ssh
```
のコマンドでvagrant + virtual boxの仮想環境に接続したかった。

(参照: <a href="https://qiita.com/ShoutaWATANABE/items/e2d23559ee05c59fd010">[仮想環境]コピペでOK！Vagrant + VM VirtualBox で Rails開発環境[windows10]</a>)

特に最後の問題がなかなか突破できずに、今回の方法に至りました。

## ダウンロード
https://msys2.github.io/
から MSYS2 のインストーラを取得して実行。

## アップデート・mingw他のインストール

```sh  
$ pacman -Syuu
$ pacman -S base-devel
$ pacman -S mingw-w64-x86_64-toolchain
$ pacman -S openssh vim zsh tmux git
```

## 環境変数 PATH の設定(windows10の場合)
デフォルトでは、Windows の環境変数 PATH の設定を 引き継がない。
コントロールパネル → システムとセキュリティ → システム → システムの詳細設定 →詳細設定 → 環境変数 から
Windows の環境変数に MSYS2_PATH_TYPE を追加し、値を inherit に設定する。

## デフォルトのシェルをzshに変更 (C:\msys64\msys2_shell.cmd を編集 )

```C:\msys64\msys2_shell.cmd
#79行目付近
# start "%CONTITLE%" "%WD%mintty" -i /msys2.ico /usr/bin/bash --login %1 %2 %3 %4 %5 %6 %7 %8 %9
start "%CONTITLE%" "%WD%mintty" -i /msys2.ico /usr/bin/zsh --login %1 %2 %3 %4 %5 %6 %7 %8 %9
```

## ホームディレクトリを任意の場所に変更 (‪C:\msys64\etc\fstab を編集 )

```C:\msys64\etc\fstab
# For a description of the file format, see the Users Guide
# http://cygwin.com/cygwin-ug-net/using.html#mount-table

# DO NOT REMOVE NEXT LINE. It remove cygdrive prefix from path
none / cygdrive binary,posix=0,noacl,user 0 0
C:/Users/◯◯ /home/◯◯ #追記
```

## powerline
(pythonが動作しているか確認)

```sh
$ python
Python 2.7.9 (default, Mar 1 2015, 12:57:24)                                                      
[GCC 4.9.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information.
>>>exit()
(などと表示されればOK)

$ curl -O https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py
$ pip install --user git+git://github.com/powerline/powerline
$ pacman -S socat
$ pip install psutil
$ pip install pyuv
```

## vimのプラグイン管理(neobundle)・colorscheme
配置先のディレクトリを作成

```sh
$ mkdir -p ~/.vim/bundle
```
NeoBundleをリポジトリから取得

```sh
$ git clone git://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim
```

colorscheme(molokai)

```sh
$ mkdir ~/.vim
$ cd ~/.vim
$ mkdir colors
$ git clone https://github.com/tomasr/molokai
$ mv molokai/colors/molokai.vim ~/.vim/colors/
```
-----


※tmuxを起動すると[exited]と表示されて強制終了する場合

- .tmux.conf で default-shell(command) の path を確認
- perl -pi -e 's/\r$//' ~/.tmux.conf を実行


※tmuxを起動すると勝手にbashが起動する場合 (~/.tmux.confを編集)

```~/.tmux.conf
set -g default-shell /bin/zsh
```
Windows環境でPythonのz3pyを導入する

# 本日は

数独のソルバーで必要だったz3をWindows上でPythonから使うようにします．

# できなかったこと

##  pipで導入

importはできるのにそこからモジュールのクラスにアクセスすると実行エラーになります．

```shell-session
> pip install z3
```
## conda install ... で行けるかな？
探してると一応ある．．．https://anaconda.org/asmeurer/z3
上記のサイトの呪文通り試すもPackageNotFoundErrorで怒られる．

```shell-session
> conda install -c asmeurer z3 
```

Macと同様に

```shell-session
> conda install z3-solver
```

を試してもビルドで失敗．Windows ダメなんじゃないかな．

# 解決策
## Wikiを見る
https://github.com/Z3Prover/z3/wiki/Using-Z3Py-on-Windows
のページにジャンプしてInstalling Z3Py with pre-compiled Windows binariesの案内にに従います．Download the latest pre-compile binariesのリリースのページまで行きましょう：
https://github.com/Z3Prover/bin/tree/master/releases

例えば z3-4.5.0-x64-win.zip をダウンロードします．解凍して
bin/python の中身にあるexapmle.pyの中身を見てみましょう：

```py3:example.py
# Copyright (c) Microsoft Corporation 2015, 2016

# The Z3 Python API requires libz3.dll/.so/.dylib in the 
# PATH/LD_LIBRARY_PATH/DYLD_LIBRARY_PATH
# environment variable and the PYTHON_PATH environment variable
# needs to point to the `python' directory that contains `z3/z3.py'
# (which is at bin/python in our binary releases).

# If you obtained example.py as part of our binary release zip files,
# which you unzipped into a directory called `MYZ3', then follow these
# instructions to run the example:

# Running this example on Windows:
# set PATH=%PATH%;MYZ3\bin
# set PYTHONPATH=MYZ3\bin\python
# python example.py

# Running this example on Linux:
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:MYZ3/bin
# export PYTHONPATH=MYZ3/bin/python
# python example.py

# Running this example on OSX:
# export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:MYZ3/bin
# export PYTHONPATH=MYZ3/bin/python
# python example.py


from z3 import *

x = Real('x')
y = Real('y')
s = Solver()
s.add(x + y > 5, x > 1, y > 1)
print(s.check())
print(s.model())
```

## 環境整備
### 通常
上のexample.pyのコメントに従えば，とりあえず bin に入っている
 `libz3.dll` をPathが通っているところに配置すること，bin/python/z3 を各自のPython環境のsite-package内に配置することでいけそうです．
### 超手抜き
もしくは一番手抜きな整備方法は libz3.dll とz3フォルダをimport するPythonのファイル（すなわち `import z3`を記述しているファイル）と同じ階層に配置することです．
たとえば私が `z3solver.py`, `sudoku.py` で`import z3` を宣言している場合は下の写真のようになります．
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/135978/3af1022d-38d5-31c2-962f-83999c173b44.png)

`z3solver.py`, `sudoku.py` のソースは [Kivyを用いた数独ソルバーのGUIのβ版ができました](https://qiita.com/SatoshiTerasaki/items/e1bb2fe450636e93a0bf)を参照ください．

![sudoku-windows.png](https://qiita-image-store.s3.amazonaws.com/0/135978/2592ab0f-0c0d-8fde-7293-b3840a52f04d.png)

windows 環境でもちゃんと行けましたね．よかった・・・．
Java9でのOptionalクラスの追加要素をまとめる

# はじめに
せっかくJava8の時に書いたので、Java9での追加要素についてまとめたページ
そんなに難しい機能じゃないので、もうすでにある記事で問題ない気もしますが、勉強なので気にしないことにします。

Java8の時に書いた記事は[こちら](https://qiita.com/tasogarei/items/18488e450f080a7f87f3)にあります。

# JavaDoc
http://download.java.net/java/jdk9/docs/api/java/util/Optional.html

# ifPresentの追加要素
`ifPresentOrElse`が今回追加されています。
Java8の時にあった`ifPresent`のFalseケースが一つのメソッドで完結することが出来るようになりました。

```java
Optional<String> optional = Optional.ofNullable("");
Optional<String> optional2 =Optional.ofNullable(null);
optional.ifPresentOrElse(t -> System.out.println(true), () -> System.out.println(false));
optional2.ifPresentOrElse(t -> System.out.println(true), () -> System.out.println(false));
```
```
結果：
true
false
```

# streamの追加
今回からOptinalクラスを直接streamに書き換えることが可能となりました。

``` java
Optional.ofNullable(null).stream().forEach(System.out::println);
```
```
結果：

```

nullの場合はObject型にしないと型が分からないので注意が必要です。
※キャストして明示するなりすれば大丈夫なことをコメントで指摘いただいたので追記しました

``` java
OK List<Object> optional = Optional.ofNullable(null).stream().collect(Collectors.toList());
OK List<String> optional = Optional.ofNullable((String)null).stream().collect(Collectors.toList());
NG List<String> optional = Optional.ofNullable(null).stream().collect(Collectors.toList());
```

List型をうまくStreamに変換する場合は、`flatmap`でStreamに変換してあげる必要があります。

```
List<String> list = List.of("aaa", "bbb");
List<String> list2 = null;
Optional.ofNullable(list).stream().flatMap(t -> t.stream()).forEach(System.out::println);
Optional.ofNullable(list2).stream().flatMap(t -> t.stream()).forEach(System.out::println);
```
``` java
結果：
aaa
bbb


```

`map`だとStream<String>型にまでしかしてくれないので、基本的に`flatmap`を使う必要があります。
`map`で頑張りたいあなたにと思ってStream<String>からStringを簡単に変換する方法を軽く探しましたが、よくわかりませんでした。
`flatmap`の実装見ても、こちらでわざわざ実装するべきだとは思いませんでした。
素直に使いましょう。

# orメソッドの追加
値が存在する場合は何もせず、Nullの場合にのみ実行するメソッドです。
返却値が`Optional<T>`なので、Nullの場合の代用変数を宣言するようなイメージでしょうか。
少し複雑な条件を記述したくなっても、`or`を使うことで簡潔に表現することが可能となりそうです。

``` java
System.out.println(Optional.ofNullable("aaa").or(() -> Optional.of("bbb")).get());
System.out.println(Optional.ofNullable(null).or(() -> Optional.of("bbb")).get());
```
```
結果：
aaa
bbb
```

# おわりに
JavaDoc見た感じはこの3つの機能が追加されたようです。
面倒くさかったのでリリースノートとか見なかったので、他にあったら追記します。
linuxでのkensington slimbladeのスクロール量と戻るボタンの設定

debianとかubuntuとか再インストールするたびにまいっかいこの設定のやり方忘れるので備忘録

```
$ sudo apt install imwheel
```

でimwheelをインストール
ホーム、もしくはdotfilesなんかに.imwheelrcをつくってホームにシンボリックリンク

```.imwheelrc
".*"
None, Up, Button4, 3
None, Down, Button5, 3
None, Thumb1, Alt_L|Left
```

Up,Downがスクロール量増加
Thumb1が戻るボタン

追記
".*"ですべてのアプリケーションに適応

あとはimwheelを自動起動のアプリケーションに設定

まぁ、.imwheelrcもdotfilesにぶちこんだからもう必要ないかもだけど
[Rails]さくらのオブジェクトストレージにPDF保存

# 環境
CentOS 6.5
Ruby 2.3.1
rails 5.0.0

# gemインストール

https://github.com/kmamiya/sakura_object_storage_ruby

```Gemfile
gem 'sakura_object_storage', git: 'https://github.com/kmamiya/sakura_object_storage_ruby.git'
```

# コントローラに追記
## 共通
```テーブル名_controller.rb
require 'sakura_object_storage'
```
アクション内で必ずインスタンスを発行する。
bucket_name → バケット名
api_key → キー名
api_secret_key → API秘密鍵

```テーブル名_controller.rb
instance = SakuraObjectStorage::Storage.new( bucket_name, api_key, api_secret_key )
```

## put_object
オブジェクトの保存には、

- ファイル名
- ファイル本体
- ファイルサイズ

が必要になる。
Railsでファイル保存している場合は、フォームから入力されたパラメータ(params[:file])のままではファイル本体とファイルサイズが取れなかったので、一度ローカルファイルとして保存して、openメソッドでdataとして取り出した。

```テーブル名_controller.rb
result = uploadpdf(file,file_name) #ローカルファイル保存
file = Rails.root + 'All_PDF/' + file_name
data = File.open(file, "rb") {|io| io.read}

instance.put_object(file_name,data,data.size) #オブジェクトストレージに保存

if File.exist?(Rails.root + 'All_PDF/' + file_name)
	deletepdf(file_name) #ローカルファイルを削除
end
```

## get_object
ローカルファイルをブラウザ上に表示するときはsend_fileメソッドを使ったが、今回はローカルには保存しないので、取ってきたデータをそのままsend_dataメソッドでPDFとしてinline表示させる。

```テーブル名_controller.rb
obj = instance.get_object(file_name)
send_data(
    obj,
    :type => 'application/pdf',
    :disposition => 'inline'
)
```

## delete_object
シンプル。

```テーブル名_controller.rb
instance.delete_object(file_name)
```

# 参照
- http://logicalrabbit.jp/sakura-object-storage
- http://joppot.info/2014/05/29/1503
【勉強メモ】deviseを実装させる③【挫折しない！】

#今回の目標
・ログイン、新規登録、プロフィール変更などなどのviewファイルを自分流にアレンジする！

##１、deviseのviewはコマンドを使って呼び出す
　deviseのログインとかプロフィール画面とかが英語ばかりでキモいって思った。
　そこで、自分流に書き換えてやろうと思ってviewsフォルダを開けてみたのだが、

<img width="247" alt="スクリーンショット 2017-10-08 17.44.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/dcbd8ef0-257d-293d-e5b4-6a9d72cc6af1.png">

　viewsフォルダにはそれっぽいファイルがない。
　
　どうやら、コマンドで入力をしてdeviseのviewファイルを呼び出すらしい。コマンドを使わないといけないとかどういうつもりだろうか。最初から出しておいてくれたらいいのに。
　それとも、これには何か意図があるのだろうか…？

　以下のコマンドを使ってviewを呼び出す。

```
$ rails g devise:views
```

　viewではなくてviewsになってるところに注意。viewファイルは1つじゃないからな。


##２、隠れていたviewファイルが出てきた。
コマンドを入力すると以下のようにviewsフォルダにdeviseフォルダが生まれた。
<img width="252" alt="スクリーンショット 2017-10-08 17.49.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/e70fa898-40f5-c04a-101e-170a9945da93.png">

この中にviewファイルが入っている。

それぞれのファイルは次の通り。


・ログイン: app/views/devise/sessions/new.html.erb
・ユーザー登録: app/views/devise/registrations/new.html.erb
・ユーザ情報変更: app/views/devise/registrations/edit.html.er
・パスワード変更: app/views/devise/passwords/edit.html.erb
・メール認証: app/views/devise/confirmations/new.html.erb
・パスワードリセット: app/views/devise/passwords/new.html.erb
・アカウントアンロック: app/views/devise/unlocks/new.html.erb


##３、それぞれのviewをそれぞれいじくってみる。
ちなみに、

```
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
```

とかあって「email」を「Eメール」とか表示にしたいときは

```
<%= f.label :Eメール %><br />
<%= f.email_field :email, autofocus: true %>
```

って ``<%= f.label :email %>`` の方をいじるんだよ。

##４．これで一通りのことはできたのかしらん

とりあえず、ある程度のことはここまでで解消できた。
マニュアルを読んで試してみて、分かったことをQiitaに載せていく。インプット＆アウトプットで記憶に残る勉強法をしている。

ただ、問題なのは時間がかかりすぎているということ。どんどん先に進んで後からここに載せればいいのかもしれないが、120%、やらない。絶対にやらない。後でやろうと思って、ちゃんと後でやった試しがない。

だから、随時、アップデートしてメモとして残していくことにする。

ここに勉強したことを残しておく理由は次の３つである。

・勉強したことをしっかりと記憶に残しておくため
・後で忘れてしまったとき、見られるようにするため
・これを見た心優しい方々からアドバイスをいただけるかもしれないため

果たしてどこまでこの習慣が身につくか分からないが、頑張って記録をし続けたい。

しかし手段が目的とならないようにも気をつけたい。

#過去の学習
【勉強メモ】deviseを実装させる①【挫折しない！】
https://qiita.com/takatoshi0905/items/d39832df81f3c6550b42
【勉強メモ】deviseを実装させる②【挫折しない！】
https://qiita.com/takatoshi0905/items/dbb303900f79f1208585

・deviseのインストールとuserモデルをつくった
・ログイン画面やプロフページのルート設定を行った。
・ログイン後のユーザーページのリンクを貼った
irbでソースコードフォルダ毎に履歴を分けて保存する

irb(Rails console含む)では、履歴を保存・参照することができますが、ソースコードフォルダ毎に分けて利用できた方が便利なシーンも多いので作ってみました。

と言ってもやっていることは単純で、カレントディレクトリをキーにして、履歴ファイルを設定しているだけです。

以下を `~/.irbrc` に記載します。履歴ファイルは `~/.irb/histories` フォルダに置くようにしていますが、適当に別なフォルダを指定しても問題ありません。

```ruby
require 'irb/ext/save-history'

IRB.conf[:SAVE_HISTORY] = 80000 # このあたりはお好みで。

require 'digest/md5'
require 'fileutils'
history_base = File.join(ENV['HOME'], '.irb', 'histories')
FileUtils.mkdir_p history_base unless Dir.exist? history_base
pwd_hash = Digest::MD5.hexdigest(`pwd`.chomp)
IRB.conf[:HISTORY_FILE] = File.join(history_base, pwd_hash)
```
RX VEGA で XMR(モネロ)を GPU マイニングする(2017/10/08 時点)

![Screen Shot 2017-10-08 at 18.21.55.png](https://qiita-image-store.s3.amazonaws.com/0/36275/f0a4a574-6d5a-b420-c716-0d31ffdb0c1d.png)


漢なら RX VEGA でレイトレーシングや機械学習やブロックチェーンやりたいですよね!!!

しかし現在(2017/10/08), ROCm OpenCL ドライバやコンパイラの SW スタックが未熟で複雑なレイトレーシングプログラムがきちんと動かなかったり, コンパイルエラーで開発できなくてつらいので, しばらくはマイニングで活用して GPU 代の足しにしたいと思います.

このところハッシュ計算にかかる消費電力が少なめの XMR(Monero)が人気ですので XMR を極めたいと思います.

2017/10/08 時点では, Windows 10 + Blockchain driver が最適でした.

# mining program

xmr-stack-amd 

https://github.com/fireice-uk/xmr-stak-amd

を使います.

# Linux

## ROCm

ROCm は compute workload 用のソフトウェアスタックです.
PCI-gen3 でのみ動きます(ので複数枚刺しする場合はすべてのスロットが Gen3 接続になっているかを確認ください)
x1 接続などしている場合は ROCm をあきらめ, amdgpu-pro を使うことになります.

2017/10/08 時点(ROCm 1.6.148)では, LLVM/clang ベースの OpenCL コンパイラの未熟さゆえに OpenCL のコンパイルに失敗し動きません.

1.6.148 の次リリースでは改善されるっぽいので,

https://github.com/RadeonOpenCompute/ROCm/issues/216

ROCm の次リリースをを待つか, 

https://github.com/fireice-uk/xmr-stak-amd/pull/51

にあるように unroll プラグマを調整するともしかしたらコンパイルできるかもです.

## amdgpu-pro

単体の amdgpu-pro(17.30) では動くようです(Polaris では動作確認しました)
rocm 付属の amdgpu-pro ドライバでは動きませんでした.

ただし amdgpu-pro だと powertune ができないので, 省電力で効率よく動かすことができません.
(ROCm も RX VEGA では結局まだ rocm-smi で powertune できないっぽいらしいが...?)

## OSS 版 amdgpu

動くかも? 未検証.

# Windows 10

VEGA で XMR マイニングは, ブロックチェーンドライバ(2017 Aug23 で動作確認)でないと性能が出ないことがわかりました.
Crimson ドライバでは VEGA 56 で 700 H/s, VEGA 64 で 800 H/s くらいしかでません.

xmr-stak-amd は prebuilt バイナリはトロイの木馬判定されてるようなので, 自前でビルドしておきます.

2017/10/08 時点で, VEGA 56 で 1730 H/s, VEGA 64 で 1760 H/s 程度が出ることを確認しました.
(-30% clock, mem 950, -20% powertune, 2 threads per GPU)

## 注意事項

Crossfire がオフになっていることを確認してください.

HBCC を有効にし, メモリ量をどれでもいいので何らかの値に設定しないとハッシュレートが 300 ~ 400 H/s くらい落ちます. PC を再起動すると, (Crimson Software では設定されているように見えても)実際には HBCC の設定がリセットされているので, 再度適当なメモリ量に設定を行う必要があります.

## まとめ

海外の猛者たちがいろいろ日々お互い切磋琢磨し, 最適な設定を探し出してくれています. 素晴らしいですね, ありがたいですね.

https://www.reddit.com/r/MoneroMining/comments/74hjqn/monero_and_vega_the_definitive_guide/
https://www.reddit.com/r/MoneroMining/comments/6zrszp/3xvega56_doing_4860hs_670w_vega_is_proving_to_be/

memory のクロックをあげすぎると, 計算化けするからか reject される割合が増えるので注意です

1760 H/s だと, 2017/10/08 時点では 1 ヶ月 XMR 0.8809, USD 80 となります.
(電気代除く)

https://www.cryptocompare.com/mining/calculator/xmr


## TODO

* 優秀な若人が, Monero のマイニングに興味を持ち, OpenCL カーネルチューニングにチャレンジすることで, 優秀な OpenCL 最適化若人が人類史上最速で育成されるスキームを確立したい.
* Monero の OpenCL カーネルを ROCm で動かすようにいろいろパッチや contribution をするような優秀な Linux カーネル, ROCm, clang/LLVM 若人が,
 人類史上最速で育成されるスキームを確立したい.
RDSを無料枠で起動して接続する

# RDSを無料枠で使えるので、接続してみる

## RDSを立ち上げる
###DBインスタンスの起動ボタンを押す！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/c8a52745-9785-0ddf-3903-b466d5f80c0a.png)

###MySQLのコミュティ版を選択。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/702fc968-1487-48f9-31fa-51874bf60053.png)

###無料枠で使うなら右。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/9e985e8c-1dd6-1abe-fb94-ab08ce494387.png)

###インスタンスの設定を間違えないように。
あと、マルチAZを「はい」にすると、２つのアベイラビリティゾーンにインスタンスを立ち上げるので、無料枠からはずれてしまいます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/e0cfcd08-de7a-1289-cd27-27a210e2ff84.png)

###詳細設定は、以下のような設定にしました
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/c804c1d0-1654-8d82-641d-88c7e97d424d.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/c206df85-c5ce-4b8f-bf81-d63ce66da925.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/6aa40bff-42e0-2160-22b7-1367dce1c371.png)

##EC2にmysqlクライアントをインストール
###EC2に接続
`ssh -i aws.pem ec2-user@xxx.xxx.xxx.xxx`

###MySQLクライアントをインストール
`sudo yum install mysql`

##EC2からRDSに接続
`mysql -h エンドポイント -P 3306 -u user -p`
↑のエンドポイントのところには、RDSの詳細画面で見た、エンドポイントから:3306を取った値を入れる。
下の画像は見づらいけど、インスタンスを選択してエンドポイントを確認するところ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/4b37a241-9741-9402-3c89-7c49a3cd9b49.png)
[Go] ファイルの拡張子を変更する

```path/filepath``` を使って安全に。

```go
package main

import (
    "fmt"
    "path/filepath"
)

func replaceExt(filePath, from, to string) string {
    ext := filepath.Ext(filePath)
    if len(from) > 0 && ext != from {
        return filePath
    }
    return filePath[:len(filePath)-len(ext)] + to
}

/* Example */
func main() {
    filePath := "inputDir/input.csv"

    fmt.Println(filePath)
    // => inputDir/input.csv
    
    filePath = replaceExt(filePath, ".csv", ".json")
    fmt.Println(filePath)
    // => inputDir/input.json
    
    filePath = replaceExt(filePath, ".json", "")
    fmt.Println(filePath)
    // => inputDir/input
    
    fmt.Println(replaceExt("inputDir/input", ".csv", ".json"))
    // => inputDir/input

    fmt.Println(replaceExt("inputDir/input.rcsv.csv", ".csv", ".json"))
    // => inputDir/input.rcsv.json
}
```
Go で void*（というかバリアント型） のリストようなものを実現するには？

3 日程前から（今更ながらですが）Golang を勉強している Go 初心者です。Lua ではテーブルに様々な型のデータを追加することができましたが Go ではどうなんでしょうか。Go の勉強がてら少し調べてみたのですが、なかなか、そのものズバリの答えが見つからなかったので、ここに記しておきます。

※ Go 言語勉強中ですので、「こんな風に書いたら良いよ」というオススメの書き方があったら教えて下さい。

#Goにおけるバリアント型
色々調べてみると、Go でのバリアント型は interface{} とすれば良いみたいです。非常にわかりやすく解説してあるページ「[急いで学ぶGo lang#6 インターフェイス](https://dev.classmethod.jp/go/golang-6/)」に感謝です。

というわけで、

```go:variant.go
var s interface{}
s=1.23
fmt.Printf("s=%f\n",s.(float64))
s="hello"
fmt.Printf("s=%s\n",s.(string))
```

などと書いて、実行すると、

```go:resut-variant.txt
s=1.230000
s=hello
```

となり、確かに何でも代入できそうなことが確認できます。

#Goにおけるバリアント型のリスト
Go では可変長配列のことをスライスというようです。任意の型を T という文字で表すと、T のスライス型は []T。ということは、どんな型でも格納できるスライス型は、 var list \[\]interface\{\} と書けば良いみたいです。実際に、それで上手くいっているっぽい。

```go:variant-slice.go
var list []interface{}
list=append(list,10)
fmt.Printf("list[0]=%d\n",list[0].(int))
```

#応用編：なんでも push, pop できるスタックを作ってみる
というわけで、応用編。Stack 型を定義して、いろんな型のデータを Push, Pop してみます。

まずは、スタックの定義です。Pop は２つの値を返し、2 番目の戻り値で正しく Pop できたか（=true）、スタックが空なのに Pop したのか(=false)を示すようにします。

```go:stack.go
package main

type Stack struct {
    index int
    dataBody []interface{}
}

func (self *Stack) Push(inData interface{}) {
    self.index++
    self.dataBody=append(self.dataBody,inData)
}

func (self *Stack) Pop() (interface{},bool) {
    if self.index<=0 {
        return nil,false
    }
    var ret interface{}
    ret,self.dataBody=self.dataBody[len(self.dataBody)-1],
                      self.dataBody[:len(self.dataBody)-1]
    self.index--
    return ret,true
}
```

スライスからの Pop は "[SliceTricks](https://github.com/golang/go/wiki/SliceTricks)" の Pop を参考にしました（というか、そのままですね…）。

次に、テスト用のプログラムです。

```go:test-stack.go
package main

import "fmt"

var DS Stack

func main() {
    DS.Push(10)
    DS.Push("aaa")
    t,_:=DS.Pop()
    fmt.Printf("%s\n",t.(string))
    t,_=DS.Pop()
    fmt.Printf("%d\n",t.(int))
    t,ok:=DS.Pop()
    if ok {
        fmt.Println("OK")
    } else {
        fmt.Println("Data stack is empty")
    }
}
```

実行してみると、

```go:result-test-stack.txt
aaa
10
Data stack is empty
```

となって、整数と文字列が同じスタックにプッシュ・ポップできていることが示されました。

#まとめ
go におけるバリアント型は空のインターフェイスを活用すれば実現できること、また、そのスライスも普通に書けば実現できることがわかりました。マルチスレッドというか goroutine などでひとつのスタックを共用する場合などは mutex などでロック・アンロックが必要なのかもしれませんが、C や C# などでの常識は通用しないのかもしれないので、その辺りについてもおいおい勉強していきたいと想います。
Amazon LinuxにNginxをインストール

# Amazon Linuxを無料枠で使えるのでこき使おう:laughing:

Nginxをインストールして、WEBサーバが動いているのを確認するまでのメモ
今回使用したいのはこれ！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/0b490b73-ca41-f308-d55d-dbfd8cee24ae.png)


# nginxのインストール
`sudo yum update`
`sudo yum install nginx`

# nginxのリスタート
`sudo service nginx restart`

# nginxの自動起動の設定
`sudo chkconfig nginx on`

# WEBサーバにアクセスして確認
EC2インスタンスの詳細画面を開いてIPアドレスを確認する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/3b8bda4f-38e0-67d8-399f-9795b848d17c.png)

アクセス！！LOVE！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/52386/08ee8bbc-cb9f-82c5-bc4e-85ee7ec63a7a.png)
Google Home/Google Assistantに関する情報まとめ


# GoogleHomeでできること

- [Google Home ヘルプ（Google公式）](https://support.google.com/googlehome#topic=7029677)

- [Google Home(Googleアシスタント)のコマンド一覧とできることまとめ](http://androidlover.net/google-assistant-command)

# Google Homeの中身はGoogle Assistant

- [Google アシスタント](https://assistant.google.com/intl/ja_jp/discover/)は、Googleのパーソナル・エージェント。AppleのSiriやAmazonのalexaに相当する機能。
- GoogleHomeからGoogleアシスタントを利用することができる。
- つまりGoogleHomeの中身はスマホのGoogleアシスタントと同一で、Googleアシスタントを音声で利用するためのハードウェアがGoogleHomeと理解したほうが良い。
- したがって、GoogleHomeに機能を追加する方法は、Googleアシスタントに機能を追加する方法と同一である。

# Googleアシスタントへの機能追加
## IFTTTを利用した機能追加
- GoogleアシスタントはIFTTTに対応しているので、IFTTTを利用して独自の機能を追加することができる（ 例えば、話しかけた内容をメールやLINEで送信する、ツイートするといったことが可能）
- IFTTTでは以下の４つのトリガを選択できる：
    - Say a simple phrase（特定のフレーズ）
    - Say a phrase with a number （数値を含む特定フレーズ）
    - Say a phrase with a text ingredient （キーワードを含む特定フレーズ）
    - Say a phrese with both a number and text （数値とキーワードを含む特定フレーズ）
- いずれの場合も、起動するためのキーワード、変数、アシスタントの応答文、言語を選択する。
    - What do you want to say? ：Lineで $ と送る
    - What do you want the Assistant say in response?：Lineで $ と送信しました
    - Language ：Japanese
- 実際にGoogleHomeからLineを送信するための設定例はこちら
    - [IFTTTを使ってGoogleHomeからLineを送信する - Qiita](https://qiita.com/jyoshida/items/f74afe3e421795cdd63c)

- IFTTTによる機能追加は、お手軽だが影響が自分のアカウントに限定されるため、作成した機能を公開することはできない（IFTTT内でのレシピの共有はできる）。

## Action on Googleによる機能追加
- [Actions on Google](https://developers.google.com/actions/)を利用することで、自作のアプリをGoogleアシスタント内で提供することができる。
    - https://developers.google.com/actions/
- "I want to talk to HOGE" のように話すことで、HOGEというアプリが起動される。
- Actions on Googleを利用した機能開発には３つの方法がある
    - テンプレートの利用
        - スプレッドシートを編集するだけで簡単なクイズなどを作成できる
    - スクラッチ開発
    - Dialogflow(旧API.AI）を利用したボットの開発

### API.AIによるボットの連携

参考にした記事
- [API.AI で多言語対応したGoogle Assistantアプリをサクッと作る](https://qiita.com/flatfisher/items/1de438d5213755a6bf27#_reference-349affe5bc28be6d9b66)

# GoogleHome関連の参考記事
- [GoogleHomeに関する投稿 - Qiita](https://qiita.com/tags/GoogleHome)
    - [Google home + IRKit で既存の家電を操作するアプリを作ってみた - Qiita](https://qiita.com/flatfisher/items/8e2da20b054674a23021)
    - [API.AI で多言語対応したGoogle Assistantアプリをサクッと作る - Qiita](https://qiita.com/flatfisher/items/1de438d5213755a6bf27)
    - [Google Home＋IFTTTで、お手軽に家電コントロール - Qiita](https://qiita.com/kazunori279/items/e3485f00fbe0ad85cce2)
- [Pocket: SEOとの共通点がたくさん？Actions on Google対応アプリをGoogle Assistantで発見させる3つの方法 #IO17JP](https://getpocket.com/a/read/1917263487)

# GoogleHomeを利用しての所感
- できることは、スマホのGoogleアシスタントと同じだが「スマホを探して、スマホに入力する（話しかける）」手間をショートカットできるメリットはある
- リビングのような部屋でも、普通に話しかけるだけでかなり正確に反応する
- 「天気」のように答えが単一なものはよいが、同じ曲名が複数あるような音楽の再生は使い勝手が悪いことがある
- 複数の選択肢から選ぶことができないので、優先度１位のもの以外は存在しないのと同じ。SEO的なことが超重要になる
- 検索結果があるかないかわからないようなものの検索には向かない（ストレスが多い）
- 毎回「OK、Google」「ねえGoogle」と話しかけるのでGoogle的には良いが、サードパーティのブランディングにはマイナス。AlexaやCortanaのほうが中立的
- 一般への普及を考えるとバックエンドにどのようなサービスがあるかがポイントになる。AmazonEchoと比較してもそれぞれメリット・デメリットがある
    - GmailやGoogleカレンダーを利用している人にとっては、パーソナルアシスタントとしてGoolgeHomeは優秀
    - Amazonでの買い物が多い人にはEchoの方が便利
    - 音楽や動画サービスはもともとどれを利用しているかによって、利便性が異なる（GooglePlayの人にはGoogleHome、AmazonMusicの人にはEchoが便利）
    - Outlookのデータをうまく使ってくるとしたらビジネス用途にはMSのCortanaが大化けする可能性も感じる
    - iTunes以外にメリットのないAppleは微妙か。
【勉強メモ】deviseを実装させる②【挫折しない！】

##前回やったこと
【勉強メモ】deviseを実装させる①【挫折しない！】
https://qiita.com/takatoshi0905/items/d39832df81f3c6550b42
・deviseのgemをインストールした。
・deviseのモデルをつくった
・ログイン画面になるようにルート設定した。
・gemとは「宝石」という意味だということを理解した！

##今回やること
新規登録、ログイン、ログアウト、プロフィール変更の画面を作る

##ログイン状態の有無を確認
さて、viewファイルにログイン状態を記述する必要があるわけだが

```
＜モデル名＞_signed_in?
```

で、「＜モデル名＞でログインしているの？」っていうことを意味する。

今回はモデル名をuserで作成したから、

```
user_signed_in?
```

になる。

だから、viewファイルのruby記述は

```
if user_signed_in?　#ログインしてる？って意味
  ＜ログインしている時のHTML＞
else
　＜ログインしていない時のHTML＞
end
```

っていうことになるわけか。

##２、実際にviewに記述してみる。

```app/views/layouts/application.html.erb
<% if user_signed_in? %>
     このメールアドレスで君はログインしているんだね→<%= current_user.email %>
    <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
    <%= link_to 'プロフィール変更', edit_user_registration_path %>
  <% else %>
    <%= link_to "新規登録", new_user_registration_path %> |
    <%= link_to "ログイン", new_user_session_path %>
  <% end %>
```
でやってみた。

``app/views/layouts/application.html.erb``　に記述するのは、すべての画面の中に、共通して表示させる内容だからだね。

あと、上の記述のなかでの
```
current_user
```
がキーポイントになりそうだ。読み方は「カレントユーザー」で合ってるのかしら？
```
current_user.email
```
で、current_userのemailを表記するという意味なのだろう。

っていうことは、``current_user.password``と記述したら、ログインユーザーのパスワードが表示されてしまうということか？？？

あとでこっそり試してみることにするwww

##３．実際の画面はこんなの
【新規登録画面】

<img width="346" alt="スクリーンショット 2017-10-08 16.49.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/5835c1bb-35d7-a0f6-541a-ec438ad235d9.png">

【ログイン画面】

<img width="346" alt="スクリーンショット 2017-10-08 16.50.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/4ac07f4a-b477-8c1f-b7cf-1d3891626ad6.png">

【プロフィール変更画面】

<img width="700" alt="スクリーンショット 2017-10-08 17.11.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/530d9d14-8cef-498e-233b-f74d00519da8.png">

##５．コントローラもビューもつくった覚えないんだけど．．．
　そういえば、ここまででview画面とかcontrollerの設定とか一切いじっていない。だけど、普通にログイン画面になったり新規登録画面になったりしている。プロフィール変更のビュー＆コントローラーなんかいつの間につくったんだ？

　いじったとすれば ``app/views/layouts/application.html.erb``にちょこちょこっとリンクを貼り付けただけだ。

　もう一度、``app/views/layouts/application.html.erb``をみてみると…

```app/views/layouts/application.html.erb
<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<%= link_to 'プロフィール変更', edit_user_registration_path %>
<%= link_to "新規登録", new_user_registration_path %> |
<%= link_to "ログイン", new_user_session_path %>
```

`` destroy_user_session_path, method: :delete``とか、``edit_user_registration_path``ってところにヒントがありそうだ。

　あ、分かった。

　そうか、deviseというのは、これらを上記の記述をするだけでプロフ変更画面とかログアウトメソッド的なやつとかを行ってくれるということか。

　これは便利。楽だね。gemが宝石っていうことの意味がなんとなく分かった。

##４．でも、英語ばかりでキモいんですけど…
　deviseの素晴らしさ、宝石と呼ばれる所以は理解した。すごいね、devise。

　だけどさ、英語ばっかりで正直キモい。英語圏の人がつくった宝石だからなのだろうけど、これはキモい。自分も含めて英語がサッパリの日本人が実際にこのwebページをみたら怪しさしかないよね。絶対に個人情報を抜かれると思うよ。警戒心しかない。

　これ、日本語表記に、さらに自分なりの文言でプロフィール変更ページとかつくれないものかね？ どこかのファイルで書き換えられないのかしらね？。
ビッグデータ活用が始まりつつある匿名加工情報

今年の５月30日に全面施行された改正個人情報保護法により、本人の同意なく活用できる「匿名加工情報」の制度が導入されました。全面施行から半年がたち、企業による匿名加工情報のビッグデータ活用の検討・準備がだいぶ進んできたようで、最近、メディアでも匿名加工情報に関する記事を目にするようになってきました。匿名加工情報とは何か、匿名加工情報を活用する際の注意点と難しさに関する解決記事とともに、最近発表された匿名加工処理を行うソフトウェアに関する記事などをご紹介します。

※下記サイトからの転載。ビッグデータ・AIなどに関するトピックを毎週取り上げています。
[TechCrowd: https://www.techcrowd.jp/related/](https://www.techcrowd.jp/related/)

#[改正個人情報保護法が本日いよいよ施行、ビッグデータの活用が進むか] (http://jp.techcrunch.com/2017/05/29/personal-information/)

今年の5月に改正個人情報保護法が全面施行されるタイミングで、その改正保護法の内容とビッグデータへの活用の可能性について解説しているTechCrunchの記事です。

今回の法改正により、取り扱う個人情報が5000件以下の小規模取扱事業者でも規制の適用対象となるので注意が必要な点なども指摘するとともに、何が個人情報であるかの線引きも明確になっていることをまずは解説してくれているとともに、特定の個人を識別できないように個人情報を加工し、個人情報を復元できないようにした「匿名加工情報」は、一定の条件のもとで第三者に提供できるようになることを説明してくれています。

また、この匿名加工情報のビッグデータへの活用イメージとして、交通系事業者は自社で持つ乗客の乗降データを個人が特定できないように加工したデータをデータ分析事業者などに提供できるようになると説明しています。


#[「匿名加工」の可能性と課題　専門家に聞く] (https://www.nikkei.com/article/DGXMZO16246250R10C17A5000000/)

やはり、改正個人情報保護法の全面施行のタイミングで、日本経済新聞に掲載された匿名加工情報に関する記事です。駅構内で撮影した画像の活用を進める東京急行電鉄の担当者から、情報の加工・取り扱いに関して注意している点や、利用目的・メリットなどをインタビューして聞いています。

東急電鉄は、自社アプリである「東急線アプリ」に昨年10月から「駅視-vision」というサービスで駅構内の混雑状況を加工して配信しています。本サービスは、駅の混み具合が正確にわかればその時間にあえて駅に行くのをやめる人も出てくることも期待して始めたものとのこと。雪の日などで駅構内が大混雑して苦情なども殺到するような状況を想定しているようです。少子高齢化が進む中、混在を解消するために新たに路線を作ったり車両を増やしたりするのは難しくITを屈指してソフト面で混在や混乱を避けるサービスを提供することを目指しているようです。

駅の混雑状況がわかるのは役に立ちますが、画像から特定の個人が特定されると個人情報保護法違反となるとともに、顧客心理的にも問題となるので、いろいろ実証実験も行い、人物の画像をヒト型の模様に変換するなど工夫をこらしているようです。


#[匿名加工情報を活用する会社が出現、AIの教師データに] (http://itpro.nikkeibp.co.jp/atcl/column/14/346926/100201145/)

匿名加工情報の活用に名乗りをあげる企業が登場し始めたことを紹介している、日経コンピュータの今月10月の記事です。

匿名加工情報の利用を表明している1社として紹介されているのがシーディーアイ（ケアデザイン研究所）。2017年4月に産業革新機構や介護サービス大手のセントケア・ホールディングなどが出資して設立、要介護者の自立を支援する介護サービス利用計画（ケアプラン）を作成する人工知能（AI）の実現を目指しています。

ケアデザイン研究所では、今まで職人芸の領域だったケアプラン作成の品質をAIで高めることを目指していてAIの学習データとして、特定の個人を特定できないように加工し、元の個人情報を復元できないようにした匿名加工情報とされたデータをセントケアなどから受け取り利用するとしています。匿名加工情報には性別や年齢、要介護度状態区分、既往歴、住居環境、サービス利用状況などが含まれるとのこと。

同記事では、活用を始めている企業の紹介とともに、匿名加工処理の技術面のハードルの高さも課題として指摘しています。データの内容や性質によっては、氏名やIDの削除だけでは不十分で属性や履歴なども元データに戻せないようにする必要があるからとのこと。


#[NTT、「匿名加工情報」の作成を支援するソフトウェアを開発] (http://cloud.watch.impress.co.jp/docs/news/1080207.html)

クラウドwatchに9月に掲載された、NTTが発表した匿名加工情報の作成支援ソフトウェアの開発に関する記事です。

同ソフトウェアには、匿名加工処理を行うために各種加工技法とともに、加工処理後のデータに対して、意図する匿名かが施されているか、必要とする有用性が確保されているのかという評価を行うための各種評価技法を実装しているとのこと。データ保有者は、同ソフトウェアを利用することにより、加工と評価の試行錯誤を行うのが容易になるとのことです。


#[NEC、個人情報の秘匿化や匿名化が可能なソフト–漢字やひらがなにも対応] (https://japan.zdnet.com/article/35107782/)

クレジットカード番号の秘匿化や個人情報の匿名加工が可能なソフトウェア「Voltage SecureData」の販売をNECが開始したことを伝えるZDnet Japanの9月末の記事です。
国会のホームページから議員の名前を抽出する

国会議員の名前リストが欲しくなったので、
参議院のホームページの議員一覧のページから議員の名前を抽出するスクリプトを作成しました。


```scrape_councillors_name.py

from lxml import html
import requests

page = requests.get('http://www.sangiin.go.jp/japanese/joho1/kousei/giin/194/giin.htm')

tree = html.fromstring(page.content)
rep_names = tree.xpath('//a[contains(@href, "profile")]/text()')

for name in rep_names:
    name_without_zenkaku_space =  name.replace(u"　", "")

    if name_without_zenkaku_space[0] is not '[': 
        print (name_without_zenkaku_space)
```

衆議院議員の場合は、以下。

```scrape_rep_name.py
# -*- coding: utf-8 -*-
from lxml import html
import requests

rep_names = []

for i in range(1, 11) :
    page = requests.get('http://www.shugiin.go.jp/internet/itdb_annai.nsf/html/statics/syu/'+str(i) +'giin.htm')
    tree = html.fromstring(page.content)
    # names_districtsには議員名と選挙区が入る
    names_districts = tree.xpath('//tr[@valign="top"]/td[@class="sh1td5"]/tt[@class="sh1tt1"]/text()')

    # names_districtsから議員名だけを取り出してrep_namesに入れる
    while(len(names_districts)!=0):
        rep_names.append(names_districts.pop(0).replace(u"　", "").replace("君\n", ""))
        names_districts.pop(0) 
    
print (rep_names)
```
Buildrootで作成したLinuxシステムイメージの状況を可視化する

Buildrootとは、組み込みに特化したLinuxイメージを手軽に作成できるツールであり、makeコマンドを中心にイメージ作成の操作を実施することができる。

本記事では、Buildrootのmakeに用意された幾つかのサブコマンドを使用して、作成したLinuxイメージの状況を可視化する手順および、その結果について紹介する。

## 実施環境
* Buildroot-2017.08
* イメージ作成対象はRaspi3
  * `make raspberrypi3_defconfig`のみを実行後、`make`コマンドでイメージを作成した環境での実施

Buildrootの環境構築手順については割愛する。

## パッケージ依存関係
作成するイメージに組み込まれるパッケージおよびイメージ作成に必要なホストパッケージの依存関係をグラフ描画する。

### 実行に必要なもの
* graphviz  * aptコマンド等で適宜インストールしてください
  * [公式ドキュメント](https://buildroot.org/downloads/manual/manual.html#requirement-optional)にも記載あり

### 実行方法
```
$ make graph-depends
```
グラフファイルの出力形式等はオプションでカスタマイズできるため、ドキュメントを参照

### 実行結果
`output/graphs/graph-depends.pdf`が生成されます

<img width="919" alt="dep-graph.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/13343/07b67eea-fd31-54d9-c605-c1399bcf0ee2.png">

濃い灰色となっているのが、イメージに組み込まれるパッケージであり、カスタマイズを行っていない初期状態のイメージでは、busyboxなどの最小限動作に必要なパッケージのみ組み込まれており、残りほとんどはホストパッケージとなっていることが確認できます。

## ビルド時間
`make`で各パッケージのビルド時、それぞれにかかった時間をグラフ化します。

### 実行に必要なもの
* python-matplotlib

### 実行方法
```console
$ make graph-build
```

### 実行結果
`output/graphs`配下に複数ファイルが生成されます

* build.hist-build.pdf
  * 各パッケージのビルド時間をビルド実行順にヒストグラムを表示する
* build.hist-duration.pdf
  * ビルド時間の長い順(ry
* build.hist-name.pdf
  * パッケージ名順(ry
* build.pie-packages.pdf
  * 各パッケージのビルド時間の円グラフを表示する
* build.pie-steps.pdf,
  *  パッケージビルド時の工程(extract, patch, configure,build...)ごとの割合の円グラフを表示する

build.hist-build

<img width="898" alt="timepkg.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/13343/e2a0184b-5c0a-8786-d948-3797051c540f.png">

イメージのユーザランドのパッケージはbusyboxぐらいしかなく、Linuxカーネルやgccに圧倒的ビルド時間がかかっている

build.pie-steps
 
<img width="493" alt="timestep.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/13343/db53b2ff-4658-03ef-b352-a101b52f6ccd.png">

ほとんどがBuild時間であり、次いでconfigureに時間がかかっている。

## ファイルシステム中に占めるパッケージごとのファイルサイズの割合

### 実行方法
```console
$ make graph-size
```

### 実行結果
`output/graphs`配下に複数ファイル生成される

* graph-size.pdf
  * パッケージごとの占める割合の円グラフ 
* package-size-stats.csv
  * 上記のテキスト版
* file-size-stats.csv
  * 全ファイルがどのパッケージなのか、どれぐらい使用しているかの情報

<img width="533" alt="fssize.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/13343/a63a1cdf-2f59-952c-3cf8-dc9f243a59f5.png">

Linuxが大半を占めており、これはローダブルなカーネルモジュール(.koファイル)となっております。残りはbusyboxやlibcやetc配下のものと思われます。

## まとめ
今回は実行対象が未カスタマイズの最小構成のものであったため、パッケージ数も少なくシンプルな結果ばかりとなりましたが、システムを組み上げていくにつれてパッケージ数も増え、イメージサイズやビルド時間のボトルネックの調査が必要となってくるケースに対しては有効な手段かと思います。
kaminari と draperを共存させる方法

# 起きた事象
- paginationを `gem kaminari`で実装後、`gem draper`を導入。


```
undifinend methode error
 :offset_value, :total_count
``` 

が生じる。

# 対策

[gem draper](https://github.com/drapergem/draper)を見たら、書いてありました。

```
1.config/initializer/draper.rb　を作成。

2. ファイルに下記コードを記述する。
　Draper::CollectionDecorator.delegate :current_page, :total_pages, 
 :limit_value, :total_count, :offset_value
```

# 参考

[Draper と kaminari を一緒に使う](http://tnakamura.hatenablog.com/entry/2014/09/01/123000)
[gem draper](https://github.com/drapergem/draper)
【勉強メモ】deviseを実装させる①【挫折しない！】

##deviseって何？
・gemの１つ。gemって宝石って意味。

・ユーザー登録とログインの機能を、model(データベース？)とかview(html的な見た目)をゼロからコマンド打ったり書いたりしなくてもつくれちゃうらしい。まさに、宝石。

・deviceじゃないよdeviseだよ！！
##１．gemのインストール
###gemfileに「gem 'devise'」を記述

```Gemfile.rb
gem 'devise'
```

###ターミナルに記述し、読み込みをする。

```
$ bundle install
```
###deviseの設定読み込みをする。
```
$ rails g devise:install
```

##２．devise用のモデルを作成する。
今回のモデル名はUserにする。

``` 
$ rails g devise User
```
からの、マイグレーション読み込み

```
$ rails db:migrate
```

##３．コントローラを作成する。
今回はpostsコントローラのindexアクションをつくる

```
$ rails g controller posts index
```

##４．rootの指定をする
```config/routes.rb
root "posts#index" 
#postsの中のindexアクションにアクセスせよ的な意味

devise_for :users
#deviseをインストールしたから、勝手に書いてあった
```
##５．サーバを立ち上げる
```
$ rails s
```
##６．そしたら新規登録画面とログイン画面ができていた、うぇいwww
(新規登録画面)
http://localhost:3000/users/sign_up 
<img width="349" alt="スクリーンショット 2017-10-08 15.31.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/0bfc5dab-11de-7394-0117-ff3edc189cd4.png">

(ログイン画面)
http://localhost:3000/users/sign_in
<img width="347" alt="スクリーンショット 2017-10-08 15.31.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/115b83ce-ed57-65a6-daab-970744225a59.png">

これで新規登録画面とログイン画面は追加できた！！

emailとpasswordを保存しておくデータベースは「２．devise用のモデルを作成する。」の項目でつくってあるから、改めてつくる必要は無いということなんだね。わざわざ新規画面とログイン画面を作らなくてもいいだなんて、便利♪

##８．deviseに関するページ
ログイン認証に便利！Ruby on Railsのdeviseの使い方【初心者向け】
https://techacademy.jp/magazine/7336

rails devise完全入門！結局deviseって何ができるの？
http://www.sejuku.net/blog/13378

##７．だけど疑問…
emailとpasswordのデータベースはつくれた。だけど、この後でユーザ名とかプロフとか投稿コメントとか、その他もろもろをこのemailに紐付けなくてはいけないんだよね。はたして、それはどうしたらいいんだ？？？