OmniAICreator/Qiita-1.07M huggingface dataset:
＜CakePHP＞追加したカラムにデータが保存されない

CakePHPで少しつまずいたのでメモ。
以下のようなUsersテーブルに、nameカラムを追加しました。

|     User      |    type      |
|:-------------:|:------------:|
|      id       |    ind       |
|     email     |    varchar   |
|    password   |    varchar   |
|    college    |    varchar   |
|    created    |    datetime  |
|    modified   |    datetime  |

|     User      |    type      |
|:-------------:|:------------:|
|      name     |    varchar   |

そして、Userテーブルにデータを登録した時、ちゃんとname（ユーザー名）が保存されるか動作確認。

まず、user新規登録用のビューファイルに、nameの入力フォームを追加しました。

```php:Template/Users/add.ctp
...

<?= $this->Form->create($user); ?>
<?= $this->Form->input('name'); ?>   <!-- これを追加 -->
<?= $this->Form->input('email'); ?>
<?= $this->Form->input('password'); ?>
<?= $this->Form->input('college'); ?>
<?= $this->Form->button('登録'); ?>
<?= $this->Form->end(); ?>

...
```

値を入力して、いざ実行！
user一覧用のページにname（ユーザ名）を表示させると...あれ、何も表示されないぞ？
phpMyAdminを確認しても、nameカラムだけ空白になっている。

ビューファイルで　<?= var_dump($_POST['name']); ?> を確認すると、きちんとPOSTされている。
ということはコントローラー側の処理の問題かな？と思い、

```php:UserController.ctp
...

    public function add()
    {
        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {
            $new = $this->Users->newEntity();  //確認のため追加
            $user = $this->Users->patchEntity($user, $this->request->getData());
            $data = $this->request->getData();   //確認のため追加
            if ($this->Users->save($user)) {
                $this->Flash->success(__('The user has been saved.'));
                // return $this->redirect(['action' => 'index']); 
                // ↑ add.ctpでデバッグするためコメントアウト
            } else {
                $this->Flash->error(__('The user could not be saved. Please, try again.'));
            }
        }
        $this->set(compact('user'));
        $this->set(compact('new'));    //確認のため追加
        $this->set(compact('data'));   //確認のため追加
    }

...

```

として、ビューファイルで　

```<?= var_dump($new); ?>``` と```<?= var_dump($data); ?>``` を確認すると、

```:$new
object(App\Model\Entity\User)#206 (8) { ["[new]"]=> bool(true) ["[accessible]"]=> array(5) { ["email"]=> bool(true) ["password"]=> bool(true) ["college"]=> bool(true) ["created"]=> bool(true) ["modified"]=> bool(true) } ["[dirty]"]=> array(0) { } ["[original]"]=> array(0) { } ["[virtual]"]=> array(0) { } ["[errors]"]=> array(0) { } ["[invalid]"]=> 
```

```:$data
array(4) { ["name"]=> string(5) "into" ["email"]=> string(13) "aaa@gmail.com" ["password"]=> string(4) "0000" ["college"]=> string(7) "college" } 
```


\$dataの方を見ると、入力データにはきちんとnameが存在している。
$newの方を見ると、
email, password, college, created, modifiedのキーはあるのに、nameのキーがない。

どうやら、newEntity()に原因があるようだ。公式サイトを調べてみると、

src/Model/Entityの下にある、対象のテーブル名ファイルの$_accessible プロパティーに、追加したカラムを自分で列挙する必要があるとのこと。

自分の場合はUserテーブルのカラムを追加したので、src/Model/Entity/User.phpに以下のコードを追加。

```php:src/Model/Entity/User.php
...

    protected $_accessible = [
        'name' => true,     //これを追加
        'email' => true,
        'password' => true,
        'college' => true,
        'created' => true,
        'modified' => true
    ];

...
```

これで再び動作確認をすると、nameがちゃんと保存されました！
Go言語でMySQLに接続してデータを登録してみる

## 概要
普段はPHPメインで使っています。
この度、MySQLで動作を確認するため、データを登録する機会がありました。
普段ならPHPを使うところですが、ここは学習も兼ねてGo言語を使ってみます。

※過去に[A Tour of Go](https://go-tour-jp.appspot.com/welcome/1)で学習済み

## 環境構築
まずはGo言語の環境を構築します。
対象はCentOS7系です。

### su権限を持つユーザでGo言語をインストール

```
# cd /usr/local/src/
# wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
# yum install -y wget
# wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
# tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
```

### 実行ユーザにパスを設定

```bash:.bashrc
export PATH=$PATH:/usr/local/go/bin
```

### MySQLのドライバをインストール

Go言語にはデフォルトでSQLやSQLライクなデータベースに接続するための、ドライバが用意されているため、インストールします。

```bash
$ go get github.com/go-sql-driver/mysql
```

### コード
これで準備が整いました。
実際にコードを書いていきます。
コード内の `var_dump` は[こちらの記事](https://qiita.com/suin/items/d952fb963956ac31b243)からお借りしました。

```go:execute.go
package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"time"
)

func main()  {
    // MySQLと接続
	db, err := sql.Open("mysql", "user:password@tcp(ip:3306)/db?parseTime=true")
	if err != nil {
		var_dump(err)
		return
	}
	defer db.Close()

	t := time.Now()
	const layout = "2006-01-02"

	date := t.Add(- time.Duration(24) * time.Hour * 4)
	var_dump(date.Format(layout))
	var_dump(t.Format(layout))
	add_time := date.Format(layout)

    // 3,000,000件ループさせる
	x := 3000000
	for x > 0 {
		x--
		// データ登録を実施
		_, err = db.Exec("INSERT INTO add_data(date1, date2) VALUES (?, ?) ", add_time, add_time)
		if err != nil {
			var_dump(err.Error())
			return
		}

		if x%10000 == 0 {
			var_dump(x)
		}
	}
}

func var_dump(v ...interface{}) {
	for _, vv := range(v) {
		fmt.Printf("%#v\n", vv)
	}
}
```

```bash:実行
$ go run execute.go 
[]string{"date", "stamp"}
"2018-08-06"
"2018-08-09"
(中略)
20000
10000
0
```

やはり久し振りに触ると、忘れているところが多々ありました。
それでもなんとか、Go言語を使って、MySQLのデータ登録が行なえました。
夜も遅いので、MySQLで行いたいことは、また別の機会にしたいと思います。

ここまで読んで頂きありがとうございました。

## 参考資料
* [Go言語でPHPのvar_dumpやJavaScriptのconsole.log的なもの
](https://qiita.com/suin/items/d952fb963956ac31b243)
* [GoでMySQLに接続する](https://qiita.com/taizo/items/54f5f49c6102f86194b8)
jquery-uiを新規CDNサーバーを作成時に一括してダウンロードを行うスクリプトのサンプル

```bash
#!/bin/sh

# バージョンを設定
version=$1

# 既にダウンロード済みの場合は削除してからダウンロードを行う
rmdir -rf $1
mkdir $1

# js ファイルダウンロード
cd $1
mkdir js
cd js

wget https://code.jquery.com/ui/$version/jquery-ui.js
wget https://code.jquery.com/ui/$version/jquery-ui.min.js

cd ..

# css ファイルダウンロード
mkdir css
cd css

for i in base black-tie blitzer cupertino dark-hive dot-luv eggplant excite-bike flick hot-sneaks humanity le-frog mint-choc overcast pepper-grinder redmond smoothness south-street start sunny swanky-purse trontastic ui-darkness ui-lightness vader
do
    wget https://code.jquery.com/ui/$version/themes/$i/jquery-ui.css -O jquery-ui-$i.css
done

ln -snf jquery-ui-base.css jquery-ui.css
```
Google Compute Engine（GCP）のポート（sshd）設定でハマった


夏休みということで、久しぶりにプログラミングに励んでみようと思ってGCPを触ってみたら、いきなりハマったのでメモ。

目的はGoolge Cloud Platform(GCP)におけるGoogle Compute Engine(GCE)の無料枠であるmicroインスタンスを構築してみること。

様々なところで、無料枠のGCE構築は手順はあるので、それに沿って実施したところ、sshdの設定で躓いた。
今、思うと初歩的なところなのだが、意外とハマりそうな気がした。

躓いたところは、Port設定の部分。
ひとまずVMインスタンスを作成した後、セキュリティ対応として、基本的に構築するCentOSのPort設定（デフォルトで22）を変更するというもの。それに合わせてCentOSで標準に備わっているSELinux と iptablesを無効化していく。


## SELinux と iptablesの無効化

ここでは、sshd対応（独自Port設定）のために、既存のSELinuxとiptablesを無効化していく。
※別途、コンソールよりファイアウォールのルールを追加する必要あり。

```bash
sudo systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
```

続いて、 `/etc/selinux/config` を編集

```bash
$ sudo vi /etc/selinux/config
```

下記のように変更。

```bash
SELINUX=disabled
```

続いて、Port設定を変更していくのだが、ここで問題が起こる。

## Port設定の変更

```bash
$ sudo vi /etc/ssh/sshd_config
```

sshdの設定を以下のように編集

```
#Port 22
Port XXXXXX # 好きな番号（制限はある）
```

リスタートで設定を変更する。

```bash
$ sudo systemctl restart sshd
```

を実施したところ、以下のようなエラーで進めないことになる。

```
Job for sshd.service failed because the control process exited with error code. See "systemctl status sshd.service" and "journalctl -xe" for details.
```

<font color="Red">結論を言うと、SELinuxの設定を変更をまず適応する必要があった。</font>
そのため、GCPのコンソールよりインスタンスの再起動を実施。

SELinuxが無効になっていることを確認。

```bash
$ sudo systemctl is-enabled firewalld
disabled
$ getenforce
Disabled
```

ともに `disabled` になっていること。

sshdのステータスも確認してみると、、、

```bash
$ sudo systemctl status sshd.service
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2018-XX-XX XX:XX:XX UTC; 42s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 764 (sshd)
   CGroup: /system.slice/sshd.service
           └─764 /usr/sbin/sshd -D
           
$ sudo systemctl restart sshd
```

問題のない様子なので、sshdをリロードし設定を改めて適応。


結果、自分で設定したPortで接続が可能となる。

```bash
$ gcloud compute --project "プロジェクト名" ssh --zone "us-east1-b" "XXXXX-instance" --ssh-flag="-p XXXXX"
```

Portを指定した接続は上記のように、 `--ssh-flag="-p XXXXX"
` を付け加えるだけ。

基本的なところだが、何となくVMインスタンスを構築しようとするとハマってしまった。
Scala：自分型アノテーションでDI

# 実装

### インターフェース定義
```scala 
trait Impl {
  def hello:String 
}
```

### 実装トレイト
```scala
trait M extends Impl { //インターフェースを継承する
  override def hello="i am mama"
}

trait P extends Impl { //インターフェースを継承する
  override def hello="i am papa"
}
```

### 共通処理
```scala
trait C {
  def shout(t:String):String={
    "%s Gyaaa!!!".format(t)
  }
}
```

### 利用クラス
```scala
class F extends C {
  self:Impl => //自分型アノテーションにインターフェースを設定する
    def greeting:Unit={
      println(shout(hello))
    }
}
```

# 利用方法
```scala
val mama = new F with M  //helloの実装をココで注入
mama.greeting

val papa= new F with P  //helloの実装をココで注入
papa.greeting
```

# 実行結果
```scala
i am mama Gyaaa!!!
i am papa Gyaaa!!!
```
iMessageの入力UIのようなキーボードの表示と連動するUIを作る with RxSwift, RxKeyboard

# 概要

- iMessage, LINEのようなテキスト入力UIでキーボードの表示に合わせて位置が動くViewを作る

# イメージ

![textinput.gif](https://qiita-image-store.s3.amazonaws.com/0/126441/19343a9c-995d-1481-add3-3eed8ac07dab.gif)

## サンプルリポジトリ

- [https://github.com/ryo-takahashi/LineInputUIExampleWithRxSwift](https://github.com/ryo-takahashi/LineInputUIExampleWithRxSwift)

# 環境

- Xcode 9.4
- Swift 4.1
- RxSwift 4.2
- RxCocoa 4.2
- RxKeyboard 0.8.3

# 簡単概要

- `RxKeyboard`ライブラリを使ってキーボードの高さを取得、テキスト入力UIの`BottomLayoutConstraint`に反映させる

# ライブラリの導入

```ruby:Podfile
  pod 'RxSwift'
  pod 'RxCocoa'
  pod 'RxKeyboard'
  pod 'RxOptional'
```

# UIを用意する

|ViewController(水色のところにテキスト入力UIを配置)|テキスト入力UIView|
|:-:|:-:|
|![スクリーンショット 2018-08-17 1.08.05.png](https://qiita-image-store.s3.amazonaws.com/0/126441/39393e1c-79ec-84d8-f616-fd055561a41d.png)|![スクリーンショット 2018-08-17 1.08.21.png](https://qiita-image-store.s3.amazonaws.com/0/126441/e9ccf515-8fef-1b02-585e-2564f1a4606b.png)|

# ViewController

```swift:ViewController.swift
import UIKit
import RxSwift
import RxCocoa
import RxKeyboard

class ViewController: UIViewController {

    @IBOutlet weak var messageInputView: MessageInputView!
    @IBOutlet weak var messageInputViewBottomConstraint: NSLayoutConstraint!
    
    private let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupMessageInputView()
    }

    private func setupMessageInputView() {
        RxKeyboard.instance.visibleHeight
            .drive(onNext: { [weak self] keyBoardHeight in
                self?.messageInputViewBottomConstraint.constant = -keyBoardHeight
                self?.view.layoutIfNeeded()
            })
            .disposed(by: disposeBag)
    }
}
```

# ViewController.xib

![z.gif](https://qiita-image-store.s3.amazonaws.com/0/126441/0c4c56cf-e73d-acc3-bdfe-12750f2606a1.gif)

```swift
@IBOutlet weak var messageInputViewBottomConstraint: NSLayoutConstraint!
```

- ViewControllerのconstraintとswiftコードを繋ぐ

# 簡単解説

```swift
        // RxKeyboard.instance <- シングルトンインスタンス
        RxKeyboard.instance.visibleHeight
            .drive(onNext: { [weak self] keyboardHeight in
                // keyboardの高さが変わるたびに呼ばれる
                self?.messageInputViewBottomConstraint.constant = -keyboardHeight
                // Viewの更新
                self?.view.setNeedsLayout()
                self?.view.layoutIfNeeded()
            })
            .disposed(by: disposeBag)
```

# 他にも

- `visibleHeight`はキーボードが非表示の時に0を流しますが、 スクロールビューのcontentOffsetを調整する場合は向いていないので、0を流さない`willShowVisibleHeight` を使うと良いらしいです :muscle: 

```swift
// contentOffset
RxKeyboard.instance.willShowVisibleHeight
  .drive(onNext: { keyboardVisibleHeight in
    scrollView.contentOffset.y += keyboardVisibleHeight
  })
  .disposed(by: disposeBag)
```

- 他にもkeyboardの`frame`を取得することもできるみたい（何に使うんだろう？ :thinking: 

# more detail :arrow_down: 

- [https://github.com/RxSwiftCommunity/RxKeyboard](https://github.com/RxSwiftCommunity/RxKeyboard)
Pythonでassertとtry~exceptを使った簡易エラー処理

assertで異常時に明示的に例外を発生させ、try~exceptでエラーキャッチする個人的テンプレです。

# 前提条件
- 動けばソースコードの品質が高い必要はない
- 同じプログラムを長期間、メンテナンスしながら運用する
- 一度の処理に、それなりに時間がかかるので、時間を表示したい
- エラーが起きたら、とにかく止めたい。異常復帰とか必要ない

# 処理時間を記録する
そこそこ長い処理をする際はかけて放置するわけですが、後で進捗確認する際、どの程度かかったのか知りたいもの。
なので、最近は以下のテンプレを使用しています。

```python:main.py
import time
from datetime import datetime

def main():
    print('Do task.')

def _print_time_msg(msg):
    now = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
    print(f'{now}: {msg}')
    
if __name__ == '__main__':
    _print_time_msg('start')
    t1 = time.time()

    main()

    t2 = time.time()
    elapsed_time = t2 - t1
    _print_time_msg(f'end[elapsed: {elapsed_time}]')
```

# エラーチェックを入れよう
長期間のメンテナンスを想定しているので、開発者自身であっても、細かい制限事項は忘れていくもの。
ただし、しっかりとしたドキュメントを残す程ではないケース。
私は、以下の形で制限事項を書いています。

- README等に、そのプログラムの制限事項を、記載する
- ソースコード中に、関数レベルの制限事項を、エラーチェック形式で記述する

どちらも、読みやすさも考慮し、過剰にならない程度に入れています。

## 判定式を用いたエラーチェック
通常であれば、判定式でエラーをチェックし、ユーザーに適切なレスポンスを返し、その後のプログラムの動きを制御します。
例えば以下のような形で。

```python:main.py
import os

TRAIN_DIR = './train'

def main():
    if not os.path.exists(TRAIN_DIR):
        print(f'Not exists [{TRAIN_DIR}]!')
        return
    print('Do task.')
```

## assertを用いたエラーチェック
上記コードだと、一つのエラーチェックに対し、「エラー判定式」「ユーザーレスポンス」「エラー後の制御文」が必要になります。
それによって、本筋とは関係のないソースコードが増え、可読性の低下、コーディング効率の低下を招きます。
エラー時はとにかく止めればいい条件下では、assertを活用することが効果的です。

```python:main.py
import os
TRAIN_DIR = './train'

def main():
    assert os.path.exists(TRAIN_DIR), f'Not exists [{TRAIN_DIR}]!'
    print('Do task.')
```

これで、制御文を使った時同様、フォルダが見つからない時には例外が発生し、以降の処理は実行されません。
制御文を用いる場合に比べたメリットは

- 「エラー判定式」「ユーザーレスポンス」「エラー後の制御文」が一行で書ける
- メンテナンス者は、assert内に書かれている条件が、そのプログラムの実行条件だとわかる
- プログラムの本筋を掴む際、assertは読み飛ばせる

等があります。
誤解のないよう繰り返すと、限定条件下でのメリットなので、制御文を用いる場面と切り分けは必要です。

# try~exceptで例外が発生しても後処理をする
assertに引っかかると例外が発生するため、終了時間の記録がされません。
また、想定外エラーでも例外が考えられるので、例外処理を入れましょう。
以上、「処理時間の記録」「assertによるエラーチェック」「例外処理」を入れたテンプレ。

```python:main.py
import os
import time
from datetime import datetime

TRAIN_DIR = './train'

def main():
    assert os.path.exists(TRAIN_DIR), f'Not exists [{TRAIN_DIR}]!'
    print('Do task.')

def _print_time_msg(msg):
    now = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
    print(f'{now}: {msg}')
    
if __name__ == '__main__':
    try:
        _print_time_msg('start')
        t1 = time.time()

        main()
    except:
       _print_time_msg('exception!')
       import traceback
       traceback.print_exc()
    finally:
        t2 = time.time()
        elapsed_time = t2 - t1
        _print_time_msg(f'end[elapsed: {elapsed_time}]')
```

例外をtry~exceptで捕まえてしまうと、普段ターミナルからPython実行時に表示される例外メッセージが見れなくなります。
`traceback.print_exc()`によって、例外メッセージを表示しつつ、処理を続行することができます。

# 今後
普段はUbuntuサーバのDockerコンテナにTeraTermで繋いで作業しているのですが、この方法だと、コンテナを切断してしまうと、実行履歴が見れなくなってしまいます。
実行ログをファイル出力したいですが、printによるターミナル出力も捨てられない。
そのようなクラス、以前C#では自作しましたが、PythonにはLoggerなる素晴らしいクラスがあるようなので、色々便利なログ出力を試したい。
ChromeOS/Crostini で Linux GUI アプリ解像度を調整する方法


sommelier コマンドで解像度を指定してアプリを起動できる

```
sommelier -X --scale=0.5 --dpi=160 <APP_name>
```

Docker でのGUIアプリも以下のようになんとかなる

```
$ sommelier -X --scale=0.5 --dpi=160 urxvt # たとえば urxvt を使う
<たちあがったターミナルで>
$ docker run -it --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -u 1000:1000 gns3/xeyes
```

# Future Work
- アプリごとに設定を適用したい
- 毎回指定して起動するのめんどい
Swift：NSEvent.addGlobalMonitorの小話


自分のアプリケーション以外でのイベント発火を監視するとき，`NSEvent.addGlobalMonitorForEvents()`を使うと思います．
そこで，最近気付いたのですが，`NSEvent.EventTypeMask.flagsChanged`は何もしなくても呼ばれるのに，`NSEvent.EventTypeMask.keyDown`は[環境設定]->[セキュリティーとプライバシー]->[アクセシビリティ]をいじらないと呼ばれないんですねぇ．
これはパスワードなどのハッキングを防ぐためだと思われます．はぇぇ...
Debian9でbcryptをnpm installしようと思って躓いた

#　はじめに
　備忘録的なので、すごく雑です。
　Debianにはmakeもg++も入っていないので、それをインストールしないとbcryptもnpmで入れられません。

# 実行したコマンド
```
sudo apt-get install make
sudo apt-get install build-essential g++
```

このあとに

```
npm install bcrypt
```
ってやると入るはず。
なにかご指摘があればメッセージお願いします。
Rails5.2のCredentials APIは何が嬉しいのか？ + 設定方法

# Rails5.2のCredentials APIは何が嬉しいのか + 設定方法　

## 1. 何が嬉しいの？？？
Rails5.1では、見られたくない情報の保存場所として`config/secrets.yml`と`config/secrets.yml.enc`という、２つのファイルがあった。
しかし、この２つのファイルの使い分けで多少混乱があったため、5.2ではそれらを１つのファイル`config/credentials.yml.enc`にまとめた。

**◎メリット**
- １つのファイルで見られたくない情報が管理できる！
- デプロイする際に、環境変数をいくつも設定する必要がなく、１つのmaster_keyのみ設定すればいい！

**×デメリット**
- master.keyが漏洩すれば、全ての秘密情報を見られてしまうのでくれぐれもgithubなどにあげないようにしよう😭 

## 2. Railsのcredentialsファイル編集

_bash_
`EDITOR = vim rails credentials:edit`

_fish_
`env EDITOR = vim rails credentials:edit`

-> config/credentials.yml.enc を編集できる。
中身はこんな感じ

```
# config/credentials.yml.enc

SECRET_KEY_BASE: your_secret_key_base
DB_URL: your_database_url
DB_USERNAME: your_database_username
DB_PASSWORD: your_database_password
```

credentials.yml.encを編集すれば、マスターキー(config/master.key)が生成され、.gitignoreに追加される。
この生成されたキーでcredentials.yml.encが暗号化される。

## 3. CredentialsをRails内で使う

### 3-1. マスターキーを環境変数に設定

production, staging環境では、生成したマスターキーが存在しないため、マスターキーを何らかの手段で移す必要がある。

**最も手っ取り早いのは、環境変数として設定してしまうことだ。**
`RAILS_MASTER_KEY`という名前の環境変数として設定すれば、Railsが勝手に読み込んでくれる。

もう１つの方法は、`config/master.key`をアップロードする方法だが、ここでは詳細は省く。


### 3-2. config/credentials.yml.encの中身を使ってみよう！

`Rails.application.credentials[:SECRET_KEY_BASE]`という感じで使うことができる。
credentialsファイル内で変数がネストしている場合は、`Rails.application.credentials[:production][:DATABASE_URL]`のように使える。

```
# config/secrets.yml

production:
  secret_key_base: <%= Rails.application.credentials[:SECRET_KEY_BASE] %>
```
  
```
# config/database.yml  
  
production:
  <<: *default
  database: my_database
  host: <%= Rails.application.credentials[:DB_URL] %>
  username: <%= Rails.application.credentials[:DB_USERNAME] %>
  password: <%= Rails.application.credentials[:DB_PASSWORD] %>
```
Spring Boot 1.x があと一年でEOLを迎えます。


先日、Spring Boot 2.0.4がリリースされました。
https://spring.io/blog/2018/07/30/spring-boot-2-0-4-available-now

以前のバージョンから９０以上のバグフィックスがされているようで、とても喜ばしいことですが、この日、Spring Boot 1.xが２０１９年８月１日にEOLを迎えることがアナウンスされました。
ブログの投稿が７月３０日なので、あと一年！というアナウンスだったんでしょうね。それにしてももうEOLを迎えるなんて早すぎる。。。

ということで、[こちら](https://spring.io/blog/2018/07/30/spring-boot-1-x-eol-aug-1st-2019)の記事を翻訳します。

------ここから-------------

すべての良いモノたちにも終わりが来る。。。そしてSpringBootの１．ｘ系にも。
つまり、私達は本日から１２ヶ月後の２０１９年８月１日に、メンテナンスを停止することを決定いたしました。

私達はこれからも1.5.x系のメンテナンスリリースはつづけ、最終日にブランチを終了します。

Spring Boot 1.x 系のユーザはメンテナンス終了日までに最新の2.x系のバージョンにアップグレードする計画をする必要があります。

また、Spring Boot 2.0とそれ以上のバージョンはJava8+が必要となるため、現在Java6 または7を利用している場合、JDKもアップグレードする必要があることに注意してください。

SpringBoot1.5アプリケーションを2.0にアップグレードするためにあなたが何をしなくてはならないのかについては、[こちら](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide)のマイグレーションガイドを参照してください。

幸運を！
（備忘録）VtuberやVRCで遊ぶのに必要なソフトメモ

#音声まわり
唄詠
Softalk
UTAU音源DL
ゆかりねっと
みくみくまうす

#3Dモデルまわり
Vroid
Vカツ
Hitogata
Blender（一応）
Wakaru

#動画編集まわり
ゆっくりMovie Maker
AviUtl＋拡張編集プラグイン
Javie（一応）

#VRそれ自体
バーチャルキャスト
VRChat
その他、みなさま日本語Developerの方々がリリースされる予定のソフト（ありがたいことです）
【Node.js】Uint8Array <-> 16進数文字列の相互変換

## 結論
**(1) 16進数文字列変換**
```javascript
const uint8Array = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);
const hexString = Buffer.from(uint8Array).toString("hex"); // "0001fdfeff"
const arrayFromhexString = Uint8Array.from(Buffer.from(hexString, "hex"));
```

**(2) base64変換**
```javascript
const uint8Array = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);
const b64String = Buffer.from(uint8Array).toString("base64"); // "AAH9/v8="
const arrayFronB64String = Uint8Array.from(Buffer.from(b64String, "base64"))
```

## 経緯

### プロパティにUint8Arrayを持つオブジェクトのシリアライズ・デシリアライズの問題
Uint8Arrayをプロパティに持つオブジェクトを`JSON.stringify()`でシリアライズすると、以下のようなJSON文字列に変換されます。
```javascript
const arr = Uint8Array.from(Array(10).fill(0));
const ob = { uint8array: arr }

const json_str = JSON.stringify(ob);
console.log(json_str)
// {"uint8array":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0}}
```
このJSON文字列をDBに保存して、後で`JSON.parse()`で復元した場合、プロパティの値をそのままUint8Arrayとして扱うことができません。

```javascript
const json = JSON.parse(json_str);
console.log(json.uint8array)
//{ '0': 0,
//  '1': 0,
//  '2': 0,
//  '3': 0,
//  '4': 0,
//  '5': 0,
//  '6': 0,
//  '7': 0,
//  '8': 0,
//  '9': 0 }
```

対策として、以下の方法が考えられます。
+ (1) DB格納時には16進数文字列として保存、Node.js上ではUint8Arrayとして扱う。
+ (2) DB格納時にはbase64変換した文字列として保存、Node.js上ではUint8Arrayとして扱う。

### 16進数文字列 ⇔ Uint8Array
```javascript

const arr = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);

const hex = Buffer.from(arr).toString("hex");
console.log(hex)
// 0001fdfeff

const buf_arr = Uint8Array.from(Buffer.from(hex, "hex"))
console.log(buf_arr)
// Uint8Array [ 0, 1, 253, 254, 255 ]

```

### Base64文字列 ⇔ Uint8Array
```javascript

const arr = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);

const hex = Buffer.from(arr).toString("base64");
console.log(hex)
// AAH9/v8=

const buf_arr = Uint8Array.from(Buffer.from(hex, "base64"))
console.log(buf_arr)
// Uint8Array [ 0, 1, 253, 254, 255 ]

```
Ramda の関数を巡る

# 目的
Ramda の関数はたくさんあるので整理

# 1. 関数合成
関数合成は、`pipe`, `compose` を使うのが基本。最初に渡す関数の引数が 1 の場合に使う `o` というのもある。Promise の then チェーンは `composeP`, `pipeP`。 モナドなど chain を満たすものの 直列化には、 `composeK`, `pipeK`。

さて、関数合成は関数適用の直列化とみなせるが、時にはデータを一つの関数に渡すのではなく、複数の関数に渡したい場合がある（例: 平均を求めるプログラム）。その際は、次の選択肢がある:

- `juxt`: Arrayの各要素に結果を詰める
- `applySpec`: オブジェクトの各プロパティに結果を詰める
-  `converge`: 結果を別の関数に渡す
    -  `useWith` も似た機能を持つが、関数合成の観点では不要
- `either`, `both`, `allPass`, `anyPass`: predicateを生成

面白いのが、`converge` と `call` を組み合わせた使い方だ。データをもとに、適用する関数とそれに渡すデータをまとめて作り、実行するというパターン（詳細は `call` の例をみよ) 

分岐には、`cond`（フル機能）、`ifElse`（シンプル機能）が利用できる。


# 2. 反復操作
`map`, `filter`, `reduce` あたりが基本だが、これらは汎用的なので、次に示すように、用途にあった関数を優先して使う。`sum` は和、 `product` は積、`any`, `all`, `none`, `contains` は各種判定、`find`, `findIndex`, `findLast`, `findLastIndex` は抽出、`groupBy`, `countBy` は集計、`sort`, `sortBy` は並び変え。

また、反復の打ち切りができる。`reduceWhile`、`take`、`takeWhile`、`head` などがあげられる。あと、reducer が `reduced` を使った値を返すと、`reduce` も反復を打ち切ってくれる。マイナーだが覚えておくとよいのは、`unfold`, `mapAccum`, `while`, `until`

避けて通れないのが transformer/transducer だ。`into`, `transduce` は `reduce` の一形態であるとみなせるが、反復操作を入出力を意識しない transducer として実装できるのが強み。`map`, `filter`, `take`, `takeWhile`, `groupBy`, などなど多くの反復操作が transducer となるので、これはtransducer になりそう、と思ったらマニュアルを確認するべき。

# 3. Array/Object 操作

Array関連。要素取り出し系は `head`, `last`, `nth`, 複数の要素取り出しには、`split*`, `slice`, `init`, `tail`。配列の非破壊な変更には、`insert`, `append`, `prepend`, `adjust`, `update`, `remove`。 Array が複数ある場合は、`xprod` で直積、`zip`, `zipWith`, `zipObj` で突き合わせ。ネストされたArrayに対しては、`transpose` で転置、`flatten`, `unnest` はネストの深さを下げる。

Object関連。要素取り出し系は、`prop`, `has`, `path`, `pick`, `omit` は頻出。非破壊な変更は、`assoc`, `dissoc`, `merge*`。プロパティをまとめて作る時は、`evolve`, `applySpec` を検討。`lens`, `view`, `set`, `over`がセットでレンズ機能。

ArrayとObjectの相互変換には、`toPairs`, `fromPairs`, `values`, を使う。

ArrayをSetのように扱う関数もあり、`uniq`, `difference`, `intersection`, `union`などが存在する。

# 4. 代数的データ型
基本的に Functor, Monad, Traversable, ... といった代数構造を適切に扱える。Fantasy-land spec に準拠したオブジェクトであれば、それらを適切に扱える。

具体的には、`map`, `chain`, `lift`, `ap`, `traverse`, `sequence` などが使える。monet.js や folktaleなどなどと併用できる。

# 5. 引数・呼び出し

`partial` で部分適用。引数の場所が合わない場合など、`curry` して、 `_` を代入した部分適用も使われる。

`flip`で引数順序を変更した関数を作れる。

可変引数が扱いにくい場合、`apply` で可変長引数の関数を引数1の配列をとる関数に変更できる。その逆は `unapply` 。また、可変引数の関数は、`unary`, `binary`, `nAry` で強制的に引数の数を変更できる。

関数とデータを変更したい場合がある（例：関数合成でパイプライン的にデータを処理する際）。`applyTo` を使って先に引数を決めておいて、呼び出し関数を後から指定出来る。

# 6. 便利関数
その他便利関数。`range`, `repeat`, `times` は反復に必要な Array 等を生成するのに使える。`memoizeWith` はメモ化、`once` は引数無視のメモ化とみなせる。`tap` はデバッグ。`clone` はディープコピー。`when`, `ifElse` は関数実装の中で if 文をするのを減らせる。`tryCatch`は字のごとく。
CentOS7にCowrieをAnsibleで入れてみる

# CentOS7にCowrieをAnsibleで入れてみる

## 環境
- CentOS Linux release 7.5.1804 (Core) 
- Cowrie

## ファイルの準備
※対象ホスト（target）とのansible疎通は取れている前提です

以下のファイルを準備する
- hosts
- site.yml
- host_vars/target
- roles/setup_cowrie/tasks/main.yml

```yml:hosts
[targets]
target ansible_host=192.168.1.1

[all:vars]
ansible_ssh_user=root
ansible_ssh_private_key_file=./ssh_target.key
```

```yml:site.yml
- hosts: target
  gather_facts: True
  roles:
    - setup_cowrie
```

ユーザ（cowrie）のパスワード、適宜修正

```yml:host_vars/target
cowrie_password: P@ssword
```

```yml:roles/setup_cowrie/tasks/main.yml
- name: install modules
  tags: cowrie
  yum:
    name: "@Development Tools"
    state: present

- name: install modules
  tags: cowrie
  with_items:
    - python-devel
    - python-setuptools
    - python-virtualenv
    - epel-release
  yum:
    name: "{{ item }}"
    state: present

- name: install modules
  tags: cowrie
  yum:
    name: python-pip
    state: present

- name: upgrade pip
  tags: cowrie
  pip:
    name: pip
    extra_args: --upgrade

- name: useradd cowrie
  tags: cowrie
  user:
    name: cowrie
    state: present
    password: "{{ cowrie_password | password_hash('sha512') }}"
    update_password: on_create

- name: mkdir
  tags: cowrie
  become: yes
  become_user: cowrie
  file:
    path: /home/cowrie/cowrie
    state: directory
    mode: 0755

- name: git clone by cowrie
  tags: cowrie
  become: yes
  become_user: cowrie
  git:
    repo: http://github.com/micheloosterhof/cowrie
    dest: /home/cowrie/cowrie

- name: install packages
  tags: cowrie
  become: yes
  become_user: cowrie
  shell: /bin/bash -lc "cd /home/cowrie/cowrie&&virtualenv cowrie-env&&source cowrie-env/bin/activate&&pip install --upgrade pip&&pip install --upgrade -r requirements.txt&&deactivate"
```

## playbookの実行
以下のコマンドでplaybookを実行

```
$ ansible-playbook -i hosts site.yml
```

## 起動
```
# su - cowrie
$ ./cowrie/bin/cowrie start
```

## 課題
cowrie.serviceおよびcowrie.socketがうまく動かないので
当面手動で起動・停止対応することにする
LXDのためのZFSプール作成手順

#LXD3.xのストレージバックエンドのデフォルトはdir?
realsense d435が認識されなくなってOS入れ直したのでLXD入れ直したらなぜかストレージバックエンドの設定をしそこねたっぽいというかzfs選べるとこあったかな......ipアドレスも選べなかったし
とりあえず前のイメージをexportしてgoogle drive上げて落としてimportして復帰はできた
#ZFSプール作成法
とりあえずzpoolコマンドがいるのでインストール
`sudo apt install zfsutils-linux`
好きなサイズの空のイメージを好きな場所に作る
`sudo truncate -s 30G /var/lib/lxd/zfs.img`
このイメージで構成されるプールを作成
` sudo zpool create lxd /var/lib/lxd/zfs.img`
このプールをLXDのストレージに登録(ここでつけた名前をプロファイルに書く
`sudo lxc storage create lxd zfs source=lxd`
defaultプロファイルを編集してzfsの方を使うようにする。(今回の場合lxdという名前で登録したので、pool: defaultという部分をpool: lxdとすれば良い)
`sudo lxc profile edit default`
望むならdirのdefaultは消しておく
`sudo lxc storage delete default`
とりあえずこれでできた
【Cloud9】Rails製herokuアプリに画像UP機能を実装(Cloudinary Carrierwave)する際にハマった所【備忘録】

[Cloudinary + Carrierwave + Heroku + Railsでの画像を手軽に利用する方法](https://qiita.com/GenTamura84/items/38cf899827bba050a21c)
[Rails5とCarrierWaveを使って画像アップロード機能を作る](http://twinbird-htn.hatenablog.com/entry/2018/05/25/231550)
[rails "undefined method '**_image will_change!' エラーの対処 【carrierwave】](http://tech-outlines.hateblo.jp/entry/2015/03/24/114237)
**基本的には、これらのページ様の通りに行えばできます。簡単なはずです。**でも自分は迷走し、時間を食いました。そのために備忘録として残しておきたいというのが、1つです。
そしてはじめて本格的？にチュートリアル以外の事やった(*※実装中はRailsTutorialにほぼ同じ内容が有ることを知らなかった*)んで記念に書きました。

※Cloudinaryを用いるにはherokuにクレカを登録しなければなりません。必要ですクレカ。

#ハマった箇所
- 画像を格納するカラムの名前（プロダクション環境）
- rmagickをCloud9にインストール *（※不要だった？）*

##カラムの名前
**画像が格納されるカラムの名前を image にしてはならない**

なぜなら、画像を格納されるカラムの名前を *image*　にすると
**プロダクション(heroku上)環境では、NoMethodError undefined method image will_change!**
というエラーが発生するからです。

開発中は問題なく画像UPできますしCloudinaryにも問題なく画像が上がってたので、デプロイしてから気付いたんですね…


このエラーに関しては上の3つ目のURLによって救われました。当該URLでは新たなカラムを追加する事によって対処されているようですが、私の場合はリネームで対処しました。

リネームは

```
$ rails g migration rename リネームしたいカラムの名前_column_to_テーブル名
```

というような形でマイグレーションファイルを作成し
マイグレーションファイルの内部で

```
 rename_column :テーブル名, :現在のカラム名, :変更後のカラム名（を入力）
```
とする事によってカラムのリネームを行えます。
私の場合はpostsテーブルにimageという名前のカラムを作成していましたので、その名前を変更しました。

```
class RenameImageColumnToPosts < ActiveRecord::Migration[5.2]
  def change
    rename_column :posts, :image, :picture
    rename_column :posts, :remove_image, :rem_picture
    rename_column :posts, :image_cache, :picture_cache
  end
end
```
###アップローダーも名前変更
同時に、既に作成したアップローダーも一旦デストロイします。（リネームという発想がなかった）

```
$ rails destroy uploader Image
```
アップローダーの名前をPictureとして、再度作成

```
$ rails g uploader Picture
```

そして忘れずに

```
$ rails db:migrate
```
を行いました。これで、実際にリネームされ、エラーも解消されました。
もちろん画像もUPできました！やったね！

リネームについては以上です。

##コントローラ（念の為）
最初に掲げたURLではコントローラについては言及されていません。
しかし私のような間抜けは慣れない事をやるとMVCという前提すら失念し、ストロングパラメータにpictureを加えることを忘れます。本記事は備忘録なので書いておきます。
※私の作成したアプリ内のPostモデルはUserとTopicの2つのモデルにbelongs_toしています。

```
def set_post_params
  params.require(:post).permit(:content, :topic_id, :user_id, :picture) #pictureを追加。
end
```
ビューの方もimageからpictureに名前を変えます。

```
form_for内
　<%= f.file_field :picture, id: :picture %>
```

```
<% @posts.each do |post|%>
　中略
　<%= image_tag(post.picture_url) %>
　中略
```

物忘れって怖いですね。

##rmagickをCloud9にインストール

[[Gem] RMagick をCentOSでインストール](https://qiita.com/hkengo/items/ff75f66a3f576b541bfd)
こちらを参考にさせて頂き、無事解決しました。つまりrmagickをインストールできました。

時間食った理由ですが、最初に
![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/280139/0397becb-02c0-6a57-1323-9cc4c50f425d.jpeg)
とか言われたからなんですね。apt-get使えないんですよ。CentOSとかよく知りませんが、事実として、私のCloud9環境ではapt-getと書かれているコマンドは実行できなかった模様です。
ググって出てくる優良ページ、みんなapt-getですからね…

RailsTutorial13章後半にもありますが

```
$ sudo yum install -y ImageMagick
```
でもOKです。


#おわりに
なんでカラム名をimageにするとエラーが発生するのか、わかりません。偉大なるRails様やCarriewave様、Cloudinary様が色々とよしなにやってくれるからなんですかね…
いずれにせよ、ググって出てくるサイトでは、画像格納カラムの名前をimageとしている所を幾つか見受けましたが、imageにするとダメでした。少なくとも、私の場合は。
「for + if」を「filter」で置き換えてネストを減らす

コードを書いていると、複数のデータを処理する際にfor文を使いがちになり、ネストが増える傾向にあるので、filterを利用する方法を忘れないように記しておきたいと思います。

以下のようなデータから名前の配列を生成するプログラムを考えます。
その際に、男性の場合は頭に`Mr.`を、女性の場合は`Ms.`をつけたいとします。

```javascript
const data_list = [
  { name: "aaa", sex: "man", age: 20 },
  { name: "bbb", sex: "woman", age: 30 },
  { name: "ccc", sex: "woman", age: 10 },
  { name: "ddd", sex: "woman", age: 22 },
  { name: "eee", sex: "man", age: 24 },
  ....
];
```

for + ifでかくとこのようなコードが考えられます。
mainの中がわりと込み入ってしまい、可読性は良いとは言えません。

```javascript
const data_list = [
  { name: "aaa", sex: "man", age: 20 },
  { name: "bbb", sex: "woman", age: 30 },
  { name: "ccc", sex: "woman", age: 10 },
  { name: "ddd", sex: "woman", age: 22 },
  { name: "eee", sex: "man", age: 24 },
];

const main = () => {
  const results = [];
  for (const data of data_list) {
    let result;
    if (data.sex === "man") {
      result = addMr(data);
    } else if (data.sex === "woman") {
      result = addMs(data);
    }
    results.push(result);
  }
  console.log(results)
}

const addMr = (data) => {
  return "Mr." + data.name;
}

const addMs = (data) => {
  return "Ms." + data.name;
}

main()


```

そこでfor + ifをfilterとmapで置き換えてみます。

```javascript
const main = () => {
  const men_result = data_list.filter(x => {
    return x.sex === "man";
  }).map(addMr);

  const women_result = data_list.filter(x => {
    return x.sex === "woman";
  }).map(addMs);

  const results = men_result.concat(women_result);

  console.log(results)
}

const addMr = (data) => {
  return "Mr." + data.name;
}

const addMs = (data) => {
  return "Ms." + data.name;
}

main()
```

filterで置き換えることでネストが減り、可読性も向上しました。
(順序を考慮する場合にはこの方法ではだめですが)

処理の流れも
男性のリストを作成し、名前の配列を生成 ->女性のリストを作成し、名前の配列を生成 -> 両結果を結合
というふうに処理の全体像もわかりやすくなりました。
MarkLogicとウイルス対策ソフト

概要
===
MarkLogicへのウイルス対策ソフトの導入について考察します。

背景
===
インターネットにつながるコンピュータにとってウイルス対策は不可欠です。そこでMarkLogicが入ったサーバに対するウイルス対策ソフトの導入についてまとめることとします。

ウイルススキャンの対象の除外
===
[ここ](http://esupport.trendmicro.com/solution/ja-JP/1097773.aspx)の他のDB製品に関する記述を見る限り、データが入っている所に対しては除外設定をした方が良さそうです。その理由は
・通常はデータの更新に伴ってスキャンが走るため、リソースが奪われることになる。
・スキャンによってデータファイルが隔離されるなど変質する可能性がある。
基本的にはフォレストが入っているディレクトリをスキャンの除外対象としましょう。また2個目の理由から、ジャーナルやバックアップファイルもスキャン対象外としておきましょう。

全体スキャンの実施やアップデート反映のタイミング
===
スキャン動作以外に、端末全体のウイルススキャンやウイルス対策ソフトウェアのアップデートなど、リソースを消費する場面が考えられます。これらはMarkLogicがあまり使われない閑散期に実行できるようにしましょう。

ウイルス対策ソフト製品の選定
===
公式の文書を見る限り、推奨されるウイルス対策製品は明言されていません。とりあえずは「全体スキャン・リアルタイムスキャンの除外対象を選択できる」、「全体スキャンなどの動作期間を任意に設定できる」ということが重要と考えましょう。
尤もほとんどのウイルス対策ソフトは兼ね備えていると思いますので、製品選定で重要なのはOSとの適合やMarkLogic以外のSWと競合しないものを選ぶことだと思います。

雑感
===
あくまでウイルス対策ソフトの導入に絞った記述です。万全のウイルス対策をとるためには、MarkLogicが入ったサーバの外側でのファイアウォールやIPS、WAFなどの導入が欠かせないと考えます。
また、ユーザの管理やポートの制御なども合わせて対応するようにしましょう。


------------------------------------------------------------------------
今さらちょっとだけブックマークレット入門

# はじめに
図書館のサイトが使いにくいので、なんとかならないかなぁと思い、とりあえずブックマークレットを作り始めた。

# 課題
借りた本のログが残らない
ログイン情報をブラウザに残せない
他のWEBサービスとの連携がない
使い方がわかりにくい
何回使っても慣れない
検索結果が文字だけ
予約した本が届いたらメールしてくれるがどの本が届いたかサイトにログインしないと確認できない

# ためしたこと
- 検索
- ログイン
- 本の名前取得

## 検索
図書館のサイトはこんな感じ。
ChromeでC-Shift-cして、htmlを確認してフォームの中身を確認した。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/59d7d36a-d3d4-c51b-5d70-8ebaf3baedc5.png)

こんな感じでフォームに入力してボタンをクリックするスクリプトを作ってみた。
formとnameを確認して作った。

```javascript
javascript:
(function(){
  alert('Hello World!');
  document.forms['search_form'].elements['keywords'].value = 'python';
  document.forms['search_form'].elements['btn1'].submit.click();
})();
```

ブックマークレットに登録するときはこんな感じ。

```javascript
javascript:(function(){document.forms.search_form.elements.keywords.value="python",document.forms['search_form'].elements['btn1'].click();})();
```

これができたから、何か便利になるわけではないけども…。

# ログイン
画面はこんな感じ。
Chromeのパスワード自動入力は対応していない。
毎回入力するのめんどくさい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/fd877257-538f-b889-5331-12f524a4f7ca.png)

ちょっとやりかた変えてみた。
`id`の名前使ったのと、`form`がなかったので`form[0]`と`name`を使った。

```javascript
javascript:(function(){document.location.href='https://www.lib.city.kobe.jp/opac/opacs/mypage_display',document.getElementById('user_login').value="xxx",document.getElementById('user_passwd').value="yyy",document.forms[0].elements['act_login'].click();})();
```

## 本の名前取得
こんな感じで検索結果がでてくる。
本の名前を取得してみる。
Amazonとかで検索したりするために。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/48c7c32e-87d4-46d3-4c22-e07c36da787f.png)

こんな感じで取得できた。

```javascript
javascript:(function(){var elements = document.getElementsByClassName('booklist');console.log(elements["0"].getElementsByTagName("a")[2].innerText);})();
```

# おわりに
とりあえず、いろいろできるようになった。こっからどうしよう。
ほんとは、借りた本をスプレッドシートに記載してったりAmazonのサイトから飛んで借りたりできるようにしたい。
気分がのってきたら試してみよう。
その前に図書館のサイトをもっとモダンな感じにしてほしいけども。

# 参考
[JavaScriptによるフォームの制御](http://www.shurey.com/js/form/)
[オリジナル「ブックマークレット」を作って、面倒な入力作業にサヨナラを。｜株式会社カポタスト](https://capotast.co.jp/article/detail/18/)
[JavaScriptで要素を取得する | cly7796.net](http://cly7796.net/wp/javascript/to-get-the-element-in-javascript/)
[[JavaScript]あらゆる要素を取得する | Rondo](http://yasumoha.com/blog/javascript%E3%81%82%E3%82%89%E3%82%86%E3%82%8B%E8%A6%81%E7%B4%A0%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B/)
Matplotlibで日付データをplot(グラフ)表示

単純な日付データと数値をmatplotlibでplotする方法です。

```Python
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

# 横軸：日付 periods分の日付を用意します。
x = pd.date_range('2018-08-07 00:00:00', periods=10, freq='d')

# 縦軸：数値
y = [130, 141, 142, 143, 171, 230, 231, 260, 276, 297]

ax.plot(x,y)

# 日付ラベルフォーマットを修正
dayｓ = mdates.DayLocator() 
daysFmt = mdates.DateFormatter('%m-%d')
ax.xaxis.set_major_locator(days)
ax.xaxis.set_major_formatter(daysFmt)

# グラフの表示
plt.show()
```

グラフを表示することができました。
![matplotlib.png](https://qiita-image-store.s3.amazonaws.com/0/278904/a6bca629-66ab-c08d-a244-baaf18f57bb6.png)


### 実装例
https://github.com/senseilearning/LearningProgress/blob/master/LearningProgress.ipynb

### 参考URL
下記URLを参考にしました。ありがとうございます。

PythonというかMatplotlibでスケールや単位の異なる時系列データを整形して表示する
https://qiita.com/zaburo/items/00f364422ef3fe64f156

[Python][Linux] matplotlib で時系列のグラフを書いてみた!
http://d.hatena.ne.jp/knaka20blue/20101117/1289981182
今更だけど、FeliCaからカード情報を取得してみた

#準備
・デバイス：SONY RC-S380
・カード：manaca
・[SDK for NFC Starter Kit](https://www.sony.co.jp/Products/felica/business/products/ICS-D010_cons.html)

#カード情報の読み取り
「SDK for NFC ユーザーズマニュアルPC/SC編（Lite）」に記載されているAPDUの独自定義(拡張)コマンドを使用して、カードからIDm、PMmなどを取得する。

##操作手順
<ol><li>SCardEstablishContext()関数でリソースマネージャのハンドルを取得。

```
SCARDCONTEXT hContext = 0;
LONG lResult = ::SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
```
</li>
<li>SCardListReaders()関数でデバイス名を取得。

```
LPTSTR lpszReaderName = NULL;
DWORD dwAutoAllocate = SCARD_AUTOALLOCATE;
LONG lResult = ::SCardListReaders(hContext, NULL, (LPTSTR)&lpszReaderName, &dwAutoAllocate);
```
</li>
<li>SCardConnect()関数でカードに接続。

```
SCARDHANDLE hCard = 0;
DWORD dwActiveProtocol = 0;
LONG lResult = ::SCardConnect(hContext, lpszReaderName, SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);
```
</li>
<li>SCardTransmit()関数でコマンド送信・データ受信。

```
BYTE bySndCmd[] = {0x00, 0x00, 0x00, 0x00, 0x00}; //使用するコマンド。
BYTE byRcvBuf[8] = {0x00};
DWORD dwResSize = sizeof(byRcvBuf);
LONG lResult = ::SCardTransmit(hCard, (SCARD_IO_REQUEST*)SCARD_PCI_T1, bySndCmd, sizeof(bySndCmd), NULL, byRcvBuf, &dwResSize);
```
</li>
<li>SCardDisconnect()関数でカードの切り離し。

```
::SCardDisconnect(hCard, SCARD_LEAVE_CARD);
```
</li>
<li>SCardFreeMemory()関数でデバイス名領域の解放

```
::SCardFreeMemory(hContext, lpszReaderName);
```
</li>
<li>SCardReleaseContext()関数でリソースマネージャの解放。

```
::SCardReleaseContext(hContext);
```
</li>

##コマンド例
操作手順4のSCardTransmit()関数で使用するコマンド。
・IDm取得
送信

CLA|INS|P1|P2|Lc|Data In|Le
---|---|---|---|---|---|---
FF|CA|00|00|-|-|00

受信

Data|SW1|SW2
---|---|---|
IDm(8バイト)|XX|XX|

SW1、SW2にはステータスが入る。
取得したIDmとステータスのイメージ。

```
01 02 03 04 11 12 13 14 90 00
```

#ソースコード
とりあえず詳細は[GitHub](https://github.com/Miya-24/C_CPP/tree/master/MyFelica)においてあります。
よかったら見てください。
C++は勉強中なので、コメントを頂けると幸いです。

#参考
・[SDK for NFC ユーザーズマニュアルPC/SC編（Lite）](https://www.sony.co.jp/Products/felica/business/products/ICS-D010_cons.html)
・[winscard.h header](https://docs.microsoft.com/en-us/windows/desktop/api/winscard/)
・[[PASMO] FeliCa から情報を吸い出してみる - FeliCaの仕様編 [Android][Kotlin]](https://qiita.com/YasuakiNakazawa/items/3109df682af2a7032f8d)
・[技術レポート「非接触ICカード技術"FeliCa(フェリカ)"のIDm読み取り方法](http://www.softech.co.jp/mm_140205_pc.htm)
・[PC/SC APIを用いてSuicaカードの利用履歴情報の読み取り](https://tomosoft.jp/design/?p=5543)
vue.jsで画像中にバウンディングボックスを表示させてみる

# はじめに
機械学習関連で検出や認識などをしていると、下図みたいに画像中の結果部分を強調表示したくなるときがありました。今回は、デモサイトの開発にvue.jsを利用していたので、コンポーネントとして実装してみました。

<img width="640" alt="thumbnail" src="https://qiita-image-store.s3.amazonaws.com/0/135313/deb308af-1b46-62ec-65f9-f543d5c151a9.jpeg">


# やり方
調べてみると、いろんなやり方があるようで

* SVG
* Canvas
* 外部のサーバで処理して結果を受け取る
* etc...

試してみた結果、vueのテンプレート操作と相性が良かったSVGを使うことにしました。

# コンポーネント内での処理
至って簡単。

svg要素の中に

1. imageタグで画像を描画
2. コンポーネントの引数として受け取った座標(左上を原点とした場合の割合)の個数分だけ`v-for`
で繰り返し、rectタグ(バウンディングボックス)を描画

以上


## コンポーネント内のテンプレート部分

```vuejs
<svg v-if="imgsize" :viewBox="'0 0 ' + imgsize.width + ' ' + imgsize.height">
    <image :xlink:href="src" width="100%" height="100%"/>
    <rect
      v-for="(bb, i) in bbs" :key="'bb' + i"
      :x="bb.left * imgsize.width || '0'" :y="bb.top * imgsize.height || '0'" :width="bb.width * imgsize.width || '0'" :height="bb.height * imgsize.height || '0'"
      fill="none" :stroke="bbcolor || '#EF5350'" :stroke-width="bbstroke || '2'" vector-effect="non-scaling-stroke" shape-rendering="crispEdges"/>
</svg>
```


# 結果
こんな感じ

<p data-height="500" data-theme-id="0" data-slug-hash="xJoXbo" data-default-tab="js,result" data-user="icchi" data-pen-title="vue-boundingbox" class="codepen">See the Pen <a href="https://codepen.io/icchi/pen/xJoXbo/">vue-boundingbox</a> by icchi (<a href="https://codepen.io/icchi">@icchi</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# まとめ
Reactと違い、vueだとSVG内要素の繰り返し処理など、非常に簡単に実装できました。動作も特にもっさり感はなくいい感じです。

もし需要があるなら、npmに公開しようかな...
python/opencv3.0　ホワイトバランス

動かしていません、[転載](https://stackoverflow.com/questions/46390779/automatic-white-balancing-with-grayworld-assumption)によるメモです
間違っていたらフォローお願いします（汗）

```python
import cv2 as cv
import numpy as np


def show(final):
    print('display')
    cv.imshow('Temple', final)
    cv.waitKey(0)
    cv.destroyAllWindows()

# Insert any filename with path
img = cv.imread('grayworld_assumption_0.png')

def white_balance(img):
    result = cv.cvtColor(img, cv.COLOR_BGR2LAB)
    avg_a = np.average(result[:, :, 1])
    avg_b = np.average(result[:, :, 2])
    result[:, :, 1] = result[:, :, 1] - ((avg_a - 128) * (result[:, :, 0] / 255.0) * 1.1)
    result[:, :, 2] = result[:, :, 2] - ((avg_b - 128) * (result[:, :, 0] / 255.0) * 1.1)
    result = cv.cvtColor(result, cv.COLOR_LAB2BGR)
    return result

final = np.hstack((img, white_balance(img)))
show(final)
cv.imwrite('result.jpg', final)
```
Gitlab環境構築してみる

# 環境
- Ubuntu16.04 X64
- Gitlab 10.7.2-ee

# 構築手順
```bash
#ubuntu16.04インストールしたあとから
#dashからbashにする No!
sudo dpkg-reconfigure dash
#とりあえずSSHいれる
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install -y curl openssh-server ca-certificates
sudo apt-get install -y postfix
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh | sudo bash
#設定変更
sudo vi /etc/gitlab/gitlab.rb
#external_url 'http://<User_IP adder>'
#構築
sudo gitlab-ctl reconfigure
```
#Backup

```bash
sudo gitlab-rake gitlab:backup:create
#ここにバックアップが生成される
sudo -i
cd /var/opt/gitlab/backups
ls
1534427176_2018_08_16_10.7.2-ee_gitlab_backup.tar

```
Working Agreement についてのまとめ

受講した「認定スクラムマスター研修」で印象に残った内容を切り出して、自分の経験や調べたことを加えてまとめています。

# Working Agreement について
一緒に働くための非公式の約束事、といえばよいでしょうか。
この言い方以外だと `Work Agreement` とか `Team Agreement` といった表現があります。

## 日本語訳をつけるとしたら?
辞書では「一緒に働くことの非公式の合意」などと書かれていますが、一般的な言い回しだと「チームの約束」という方がしっくり来ると思います。

## 目的
チームの自律性を促進する (= 自己組織化する) ために必要とされるものです。
チームのメンバーが自律的に活動するために必要な取り決めを用意しておき、それに従って日々の活動を規律あるものにします。
規律が云々、というと堅苦しく見えますが、要は「チームの活動を豊かにするためのもの」です。

別に事細かなものである必要はありません。チームの自律性を促進し、チームの状態をより良くするための「ボーダーライン」といった程度の取り決めでOKです。

## 内容
チーム独自で決めるので様々なものがあるでしょうが、まずは以下のようなものが含まれている必要があるでしょう。

### 物事の決め方のルール (決定のルール) とプロセス
- どうやればその事項を決定のプロセスに載せることができるか?
- 決め方はどうやるの?
    - 多数決? 全員一致? etc...

この「決定のルールとプロセス」だけは **チームメンバー全員が合意** して決めないといけない最重要事項だといえます。そして、このルール・プロセスを決めるときのポイントは、チームメンバー全員の納得性があるかどうかです。あとで「実はあのときはイヤだったんだけど」みたいな話になってしまったり、「誰かが決めればいいでしょ?」となってしまっては、自律性が損なわれてしまいます。

どのようなルール・プロセスであればチームメンバー全員の納得性がある状態にできるかどうか、についてはチームで決めなくてはいけませんが、例えば以下のようなものがあるでしょう。

- 意見や決めるための判断材料が出せるか?
- 適用が容易か?
- スピーディーであるか?
- 決める際にディスカッションにならないよう工夫されているか?
    - 変にディスカッションになるともはやカオス
    - 数名程度のチームであればそれほどカオスにならないかもしれないが意識して設計したほうが無難

### 見直しのルールとプロセス
- どうやればそのプロセスに載せることができるか?
- 決め方はどうやるの?

何かのルールを見直したいときにどうすればよいか、を決めます。現行のルールよりもよりよいルールが出てきたときに、それをうまく吸い上げて取り込めるようにします。また決めたルールが形骸化していると感じたときも、見直の絶好のチャンスになります。

### ペナルティのルールとプロセス
- いつ、どんなときにペナルティの判定がされるの?
- 誰が決めるの?
- 具体的なペナルティは何?

約束事を決めたとしても、やはりうまく守られないこともあるでしょう。しかし守られない状態を看過してなあなあになっていては規律あるチームとはいえません。
とは言え別に厳しいものである必要はありません。ペナルティを受ける人に気づきや反省を促せればよいのです。


## ないとどうなるか?
こういったプロセスやルールが明確されていないと、破綻する将来が確実に目に見えてきます。よく耳にする「あれ、こんなはずじゃなかったんだけど?」ってヤツです。
そうすると、チームの自律性が損なわれます。例えば「誰かが解決すればよい」というヒエラルキーの考え方が持ち出されてしまい、チームが自らチームを良くしていこうとする気概がなくなってしまいます。こうなるとチームは集団心理が働いて易きにつくようになってしまい、活動が停滞してしまいます。

チームは「人」の動き次第で如何ようにも変化します。人の集まりである「集団」を良い方向に向けさせるためにも、こういった約束事があることが重要だといえます。


# 参考資料
- [自己組織化プロジェクトの育て方（1）：プロジェクトを管理しないという発想 \(4/4\) \- ITmedia エンタープライズ](http://www.itmedia.co.jp/im/articles/0512/09/news134_4.html)
- [Work Agreements for a Scrum Team \| Arrk Group](http://www.arrkgroup.com/thought-leadership/work-agreements-for-a-scrum-team/)
- [Scrum Community \- Scrum Alliance](https://www.scrumalliance.org/community/articles/2015/february/team-agreements)
- [Agile Team Working Agreements](http://www.payton-consulting.com/agile-team-working-agreements-guide/)
C++ ポインタ渡し

#環境
XCode 8.3.3 ,c++11
MacOSX10.13

#やったこと
C++でポインタ渡しでハマったので、備忘の目的で登録
int型、unsigned char型でサンプルコードを実装

#サンプルコードを以下実装

```main.h
//
//  main.h
//  example1
//
//

#ifndef main_h
#define main_h

void changePointerValue(int *a);
void changePointerValue(unsigned char *b);

#endif /* main_h */
```


```main.cpp
//
//  main.cpp
//  example1
//
//

#include <iostream>
#include "main.h"


int main() {
    int a = 1;
    std::cout << "aの値は:" << a << "です。" << std::endl;
    changePointerValue(&a);
    std::cout << "aの値が:" << a << "に変更されました。" << std::endl;
    
    unsigned char b = 3;
    std::cout << "bの値は:" << static_cast<unsigned>(b) << "です。" << std::endl;
    changePointerValue(&b);
    std::cout << "bの値が:" << static_cast<unsigned>(b) << "に変更されました。" << std::endl;
}

void changePointerValue(int *a) {

    *a = (int)10;
    
}
void changePointerValue(unsigned char *b) {

    *b = (unsigned char)20;

}
```

#実行した結果

```
aの値は:1です。
aの値が:10に変更されました。
bの値は:3です。
bの値が:20に変更されました。
Program ended with exit code: 0
```
Linux/UNIX環境向け圧縮/展開コマンド早見表

圧縮と展開（解凍）、よく忘れるので一覧でコピペしやすいものが欲しかったので作りました。


## ファイル単体

今回は対象のファイル名を `sample.txt` としてのサンプル

### 圧縮

圧縮後のファイルは `sample.txt.{{圧縮形式別拡張子}}` になります。

#### 元ファイルを残さない

|圧縮種類|コマンド|
|---|---|
|gzip(gz)|`gzip sample.txt`|
|bzip2(bz2)|`bzip2 sample.txt`|

#### 元ファイルを残す

|圧縮種類|コマンド|
|---|---|
|gzip(gz)|`gzip -c sample.txt`|
|bzip2(bz2)|`bzip2 -c sample.txt`|


### 展開

#### 元ファイルを残さない

|展開種類|コマンド|
|---|---|
|gzip(gz)|`gzip -d sample.txt.gz`|
|bzip2(bz2)|`bzip2 -d sample.txt.bz2`|

#### 元ファイルを残す

|展開種類|コマンド|
|---|---|
|gzip(gz)|`gzip -dc sample.txt.gz > sample.txt`|
|bzip2(bz2)|`bzip2 -dc sample.txt.bz2 > sample.txt`|

## ディレクトリまるごと(tar)

対象のディレクトリを `dir` でのサンプルです。

圧縮後のファイル名は `dif.tar.{{拡張子}}` とします

### 圧縮

基本はtarでまとめるので以下がベースになる。
`tar -cvf 圧縮後のファイル名 対象のディレクトリ`

|圧縮種類|コマンド|
|---|---|
|gzip(gz)|`tar -zcvf dir.tar.gz dir`|
|bzip2(bz2)|`tar -jcvf dir.tar.bz2 dir`|
|xz(xz)|`tar -Jcvf dir.tar.xz dir`|

### 展開

展開は圧縮した時のディレクトリごと展開します

|展開対象|コマンド|
|---|---|
|汎用（拡張子判断)|`tar -xvf dir.tar.hoge`|
|gzip(gz)|`tar -zxvf dir.tar.gz`|
|bzip2(bz2)|`tar -jxvf dir.tar.bz2`|
|xz(xz)|`tar -Jxvf dir.tar.xz`|


## (おまけ) 他のサーバへscpで送る

* 他のサーバのIPは `192.255.255.255` とする
* 送付する先は `~/` とする
* 送るファイルは `dir.tar.gz` とする
* ユーザ名を指定する場合は `user` とする
* 秘密鍵を使う場合は `~/.ssh/secret_key.pem` を使う

|やり方|コマンド|
|---|---|
|通常|`scp dir.tar.gz 192.255.255.255:~/ `|
|ユーザを指定する|`scp dir.tar.gz user@192.255.255.255:~/`|
|ユーザと秘密鍵を指定する|`scp -i ~/.ssh/secret_key.pem dir.tar.gz user@192.255.255.255:~/`|




## 参考サイト
* [\[Linux\]ファイルの圧縮、解凍方法 \- Qiita](https://qiita.com/supersaiakujin/items/c6b54e9add21d375161f)
* [CentOS7にzipが入っていなかった件 \- Log\.log\(work\)](http://shinomiya.hatenablog.com/entry/2017/02/07/101953)
* [zipとgzipの違い〜圧縮とアーカイバ~ \- Qiita](https://qiita.com/chiiia12/items/55e8ae039ad4a7c3e2ab)
* [圧縮展開系のコマンドのまとめ \- Qiita](https://qiita.com/wnoguchi/items/cb0fa7c11b119e96f1e5)
* [scpコマンドでファイル送る、とってくる](https://qiita.com/shuuhei/items/e435762017c11f71d07d)
JavaScriptでのWeb開発に挑戦したのでメモ１

JavaScriptでWebアプリ開発にはNode.jsとのことなので、以下書籍で学習を開始してみました。その際の自分用メモになります。

**参考：JavaScriptでのWeb開発　〜Node.js + Express + MongoDB + ReactでのWebアプリを開発しよう〜その１**

Express：Node.jsでWebアプリケーションを作成する際にもっとも多く使われるフレームワークである。
＊WebサーバーとしてHTTPリクエストを取り扱う最低限の機能のみ搭載。

1.任意のディレクトリを作成

```
mkdir hoge
cd hoge
```

2.最初のプロジェクトを作成するためにpakckage.json作成

```
npm init
```

3.Expressをプロジェクトに導入

```
npm i express --save
```

####ExpressでHello World
アプリケーションのエントリポイントとなるjsを作成

```
touch app.js
```

####HTTPサーバー作成
```Javascript
var http = require('http');
var express = require('express');
var app = express()

app.use(function(req, res, next){
  return res.send('Hello World');
});

var server = http.createServer(app);
server.listen('3000');
```

####Express起動

```
node app.js
 *Control+cで抜ける
```
適当なブラウザで3000を立ち上げれば確認できる。