OmniAICreator/Qiita-1.07M huggingface dataset:
Embulkの設定情報（liquid版）

## 概要
Embulkで処理を作成する際、DB接続情報などの環境によって変更したい設定をどう定義すればいいか調べた内容をメモしておきます。

## Embulkのテンプレート機能を利用する
Embulkに搭載されているテンプレートエンジンLiquidの機能を使って共通化してみます。
※ Embulk 0.7.7以上

## ファイル構成

```:ファイル一覧
│ # 設定情報
├ _env.yml.liquid
│
| # bundle plugin.
├ bundle
│ ├ .bundle
│ ├ .ruby-version
│ ├ Gemfile
│ ├ Gemfile.lock
│ ├ embulk
│ └ jruby
│
│ # 処理内容
└ users.yml.liquid
```

## 設定情報
設定ファイルを作ってみる。

```liquid:_env.yml.liquid
{% assign my_host = '127.0.0.1' %}
{% assign my_database = 'fuga_db' %}
{% assign my_user = 'hoge' %}
{% assign my_password = 'test' %}
```

## 処理に組み込んでみる
実際に、上記設定を組み込んで実行してみる。

```liquid:users.yml.liquid
{% include 'env' %}
in:
  type: mysql
  host: {{ my_host }}
  user: {{ my_user }}
  password: {{my_password}}
  database: {{my_database}}
  query: |
    SELECT
      id, name, created_at
    FROM
      users
    WHERE
      deleted_at IS NULL
    LIMIT
      5
    ;
out:
  type: file
  path_prefix: "./users_"
  file_ext: csv
  formatter:
    type: csv
    delimiter: ","
    newline: CRLF
    newline_in_field: LF
    charset: UTF-8
    quote_policy: MINIMAL
    quote: '"'
    escape: "\\"
    null_string: "\\N"
    default_timezone: 'Asia/Tokyo'
```

## プレビュー
```sh:ターミナル
$ embulk preview -b bundle users.yml.liquid
```

## 実行
```sh:ターミナル
$ embulk run -b bundle users.yml.liquid
```

## まとめ
テンプレートエンジンLiquidの機能を使った場合、includeはサブディレクトリには、
対応しているが、「../」のように上の階層を指定するとエラーになることから、階層分けには不向きのようです。

例）

```:ファイル一覧
│ # 設定情報
├ _env.yml.liquid
├ try1
│  └ config.yml.liquid <- include '../env' (×)
├ try2
│  └ config.yml.liquid <- include '../env' (×)
├ try3
│  └ config.yml.liquid <- include '../env' (×)
　　　　　・
　　　　　・
　　　　　・
└ users.yml.liquid  <- include 'env' (○)
```

下記のように１つの階層で構成するには向いているようです。

例)

```:ファイル一覧
│ # 設定情報
├ _env.yml.liquid
├ try1.yml.liquid <- include 'env' (○)
├ try2.yml.liquid <- include 'env' (○)
├ try3.yml.liquid <- include 'env' (○)
　　　　　・
　　　　　・
　　　　　・
└ tryN.yml.liquid <- include 'env' (○)
```

## 参考サイト
- [Embulkの設定ファイルをincludeで共有化する方法](https://qiita.com/hiroysato/items/e7987e71a8112584b748)
- [Replace config file with command line parameter](https://github.com/embulk/embulk/issues/253)
[EC-CUBE3]商品価格の税抜き表示

デフォルトで簡単に税抜/税込表示を変更する機能はなさそう。

### プラグインを使う
例えば、[税抜き表記(税別表示)に変更プラグイン ](https://www.ec-cube.net/products/detail.php?product_id=1338) とか。

### 自前でtwigを修正する
TOPページに商品一覧を表示するため、自作で商品一覧ブロックを作って表示させており、
上記プラグインじゃ対応できないので、下記のように修正。（もしくはプラグイン使いたくない場合。）

（twig修正前）
getPrice01IncTaxMax
getPrice01IncTaxMin
getPrice02IncTaxMax
getPrice02IncTaxMin

（twig修正後）
getPrice01Max
getPrice01Min
getPrice02Max
getPrice02Min
**→IncTaxの部分を削除**
typescriptでアレがしたい

typescriptというかjsのtips集です。
簡単なスニペットを溜めていきます

## ローカルのファイルを読み込みたい

node環境限定

### 解: `fs`パッケージを使う


```shell

yarn add -D @types/node
```

```typescript

import * as fs from 'fs';

// 同期的にバッファを取得
try {
  let buffer = fs.readFileSync(path)
  console.log(buffer)
} catch(error) {
  console.log(`failed to read ${error}`)
}

// 非同期でバッファを取得
async readFile() {
  try {
    let buffer = fs.readFile(path, () => {})
    console.log(buffer)
  } catch(error) {
    console.log(`failed to read ${error}`)
  }
}

// 読み込みストリーム
let stream = fs.createReadStream(path)
stream.on("data", (chunk) => {
  console.log(chunk)
})
stream.on("close", () => {
  console.log("stream closed")
})
stream.on("error", (error) => {
  console.log("stream error")
})

```

## xsvフォーマットのテキストをパースしたい

### 解: `csv-parse`を使う

https://github.com/adaltas/node-csv-parse

```shell
yarn add csv-parse
```

```typescript

import * as fs from 'fs-extra';
import * as parse from 'csv-parse';

private parseTsv(filePath: string): Promise<any[]> {
  var result: any[] = []
  let parser = parse({delimiter: "\t", columns: true}, (err, data) => {
    result = result.concat(data)
  })
  return new Promise<any[]>((resolve: (value?: any[]) => void, reject: (reason?: any) => void) => {
    let stream = fs.createReadStream(filePath)
    stream.on("close", () => {
      resolve(result)
    })
    stream.on("error", (err) => {
      console.log(err)
      reject(err)
    })
    stream.pipe(parser)
  })
}


```
`columns` パラメータに`true`を渡してあげると、先頭の行をカラム名と解釈してくれる。
そうすると、parseメソッドに渡したクロージャには配列ではなく、先頭の行の項目をキーとしたハッシュが渡ってくるようになる。

## 書式指定フォーマット（printfのやつ）が使いたい

### 解: `sprintf-js`を使用する

https://github.com/alexei/sprintf.js

```shell
yarn add sprintf-js @types/sprintf-js
```

```typescript

let zeroPaddingNumberString = sprintf("%03d", 10)
console.log(zeroPaddingNumberString) // 010が出力される

```

## 数値を0埋めしたい

### 解: String#sliceを使う

`010`と出力したい

```typescript

const n = 10

`00${n}`.slice(-2)

```

## union型を安全に使用する

```typescript


interface IntroductionPage {
  type: "introduction";
}

interface ComicPage {
  type: "comic";
  index: number;
  imageUrl: string;
}

type Page = ComicPage | IntroductionPage;

function renderPage(page: Page) {
  // typeをチェックした後に補完が適切な型をサジェストしてくれるようになる。というのが便利

  switch (page.type) {
    case "introduction":
      return renderIntroductionPage();
    case "comic;
      return renderComicPage(page.index, page.imageUrl)
  }
}


```
イーサリアム1.8でプライベートネット作成したけど、難易度高すぎで掘れない対応

# [1.8] イーサリアムのプライベートネット作成したけど、難易度高すぎで掘れない対応
プライベートネットでイーサリアムを起動し、マイニングを実行していても、難易度が高すぎて一向に採掘ができない問題があった。(`genesis.json`の修正は試みた)

gethのコンソールで `eth.getBlock(0)` を実行してみた結果

```
eth.getBlock(0)
{
  difficulty: 17179869184,
  extraData: "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
  
  ~ 省略 ~

  totalDifficulty: 17179869184,
  ~ 省略 ~
}
```

`17179869184` !!??? difficulty高すぎワロたwww


## デフォルト難易度を変えてしまえ！
go-ethereum(https://github.com/ethereum/go-ethereum)の
`core/genesis.go` の311行目に最初に生成するブロックの難易度を設定する箇所があったので強制的に変えて解決することにした。

### 修正前
```go
// DefaultGenesisBlock returns the Ethereum main net genesis block.
func DefaultGenesisBlock() *Genesis {
	return &Genesis{
		Config:     params.MainnetChainConfig,
		Nonce:      66,
		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
		GasLimit:   5000,
		Difficulty: big.NewInt(17179869184),
		Alloc:      decodePrealloc(mainnetAllocData),
	}
}
```

ここの
`Difficulty: big.NewInt(17179869184),`
を
`Difficulty: big.NewInt(1),`

に変更する

### 修正後

```go
// DefaultGenesisBlock returns the Ethereum main net genesis block.
func DefaultGenesisBlock() *Genesis {
	return &Genesis{
		Config:     params.MainnetChainConfig,
		Nonce:      66,
		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
		GasLimit:   5000,
		Difficulty: big.NewInt(1),
		Alloc:      decodePrealloc(mainnetAllocData),
	}
}
```


その後、 `make all` をして、`build/bin/geth`を用いて起動する (Go1.10を使用)


## gethコンソール上で確認した結果

```
> miner.start()
null
> eth.blockNumber
13
> eth.blockNumber
13
> eth.blockNumber
15
> eth.blockNumber
70
```

できてる！！！


難易度も確認してみたら、マインングされていることが確認できました!

```
eth.getBlock(0)
{
  difficulty: 1,
  
  ~ 省略 ~

  totalDifficulty: 1,
  ~ 省略 ~
}
```

困った時は、ソースコードを直接かきかえような！！

おわり
[Swift]initの中でfactory methodで生成したインスタンスを返す

*コメント欄にてloveeさんから補足を頂いているのでご覧ください！

実行コード
https://iswift.org/playground?BJSCvA&v=3


```swift
struct User {
    let id: Int
}

struct UserFactory {
    static func make(id: Int) -> User {
        return User.init(id: id)
    }
}

extension User {
    init() {
        self = UserFactory.make(id: 999)
    }
}


let user1 = User(id: 100)
let user2 = UserFactory.make(id: 101)
let user3 = User()

print(user1.id)
print(user2.id)
print(user3.id)
```

`self = instance`
で、instanceを返す事ができる。出来ないと思ってたわ…。
Microsoft Translator テキスト API の使い方 (Node.js)

Microsoft Translator テキスト API の使用例です。
日本語から、ドイツ語への翻訳です。

```js:translation.js
#! /usr/bin/node
//
//	translation.js
//
//						Feb/26/2018
//
// ------------------------------------------------------------------
function translate_proc(token,text_in)
{
	var url_bb = "https://api.microsofttranslator.com/v2/http.svc/Translate?text="
	url_bb += encodeURIComponent(text_in) + "&to=de" + "&category=generalnn"

	var Client = require('node-rest-client').Client
	var client = new Client()

	const args = {
		headers: {"Authorization": "Bearer " + token}
			}

	client.get(url_bb,args,function (data, response) {
		console.log(data)
//		const str_out = data.toString('utf-8')
//		console.log(str_out)
		console.error ("*** 終了 ***")
		})
}

// ------------------------------------------------------------------
function token_translate_proc(text_in)
{
	var Client = require('node-rest-client').Client
	var client = new Client()

	const key1 = "e968e25ffc2146f00000000000000aaa"
	const url="https://api.cognitive.microsoft.com/sts/v1.0/issueToken"

	const args = {
		headers: {
			"Ocp-Apim-Subscription-Key": key1,
			"Content-Type": "application/json",
			"Accept": "application/json"
			},
		data: ""}

	client.post(url,args,function (data, response) {
		const token = data.toString('utf-8')
		translate_proc(token,text_in)
		})
}
//
// ------------------------------------------------------------------
console.error ("*** 開始 ***")

const text_in="今日はいい天気です。"
console.log(text_in)

token_translate_proc(text_in)

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

python3 の例はこちら
[Microsoft Translator テキスト API の使い方 (python3)](https://qiita.com/ekzemplaro/items/23b82bdff02eda738f7a)
RubyのRestClientでSSL証明書のチェックを無視する


```ruby
endpoint = 'https://example.com/api_endpoint'
rest_client = RestClient::Resource.new(endpoint, verify_ssl: OpenSSL::SSL::VERIFY_NONE)
response = rest_client.get()
```


refering to:
- https://github.com/rest-client/rest-client#ssl-client-certificates
- https://qiita.com/kanekoa/items/307693abc7631985bc50
Rails5.2からsecrets.yml*が廃止されcredentials.yml.encに統合されるよ

Railsを5.1系から5.2.0.rc1にアップグレードする際に、secrets周りだけ結構変わってるなーと思ったのでまとめときます。

簡単に言っておくと、平文のsecretsは全て廃止して暗号化されたcredentials.yml.encのみを扱うようになりました。また、secrets.ymlは自動生成はされなくなりましたが、ファイルがあれば以前のように`Rails.application.secrets`で参照することは出来るのでアップグレードの際にすぐに対応する必要があるわけでは無いです。

## 発端

https://github.com/rails/rails/pull/30067

DHHいわく、

* `secrets.yml` `secrets.yml.enc` `ENV['SECRET_KEY_BASE']` の３つの組み合わせだと、環境毎に何処に値を設定すれば良いのかわかりづらいし複雑だよね。
* 新しく `config/credentials.yml.enc` を追加して一元管理できるようにして、環境に関係なく `config/master.key` か `ENV['RAILS_MASTER_KEY']` で復号化できるようにしようよ。
* `credentials.yml.enc` は本番でのみ使われる想定だから、`secrets.yml`みたいに環境毎に分割されたりしないよ。
* Rails自体は復号化のkeyが無くても動くようにしておくから、開発やテストみたいな復号化の必要がない環境ではkeyは要らないようにしておくよ。
    * localとかテストみたいな環境では攻撃に耐える必要無いから、簡単な値を代わりに使っても問題ないよ。
* `secrets.yml*` は動くようにしておくから、アプリケーションが壊れたりすぐに移行する必要が有るわけでは無いよ。

という感じで、Encrypted secretsは中途半端だったから止めて新しい暗号化の機構を追加した感じですね。


## 暗号化

Rails 5.2 で新しく rails newすると、`config/master.key`と`config/credentials.yml.enc`が生成されるようになっています。(config/master.keyは.gitignoreに最初から追加されてますが、アップグレードする人は注意しておいたほうが良いです)

編集する場合には `bin/rails credentials:edit` で復号化されたファイルがエディターで開けます。エディタ指定したい場合は環境変数`EDITOR`でエディタを開く際のコマンドを指定しましょう。(`EDITOR=vim bin/rails credentials:edit`)

## 復号

読み込みの際には、`config/master.key`に復号化用の文字列を書き込むか、環境変数`ENV['RAILS_MASTER_KEY']`を使って復号化します。

開発環境やテストではsecret_key_baseは復号化出来なくても仮の値が使われると書かれているとおり、デフォルトではnilが返るだけです。本番で誤って値を設定しないままデプロイ/サービスインしてしまわないように値が設定されていない場合は例外を投げるオプションが有ります。

``` ruby
config.require_master_key = true
```

また、Deviseやその他で`Rails.application.secrets.secret_key_base`をsaltに使ってるようなケースでは修正が必要です。自分のケースではsecrets.ymlはほとんど使ってなかったのでcredentialsに統一したので、ここでアプリの修正をする必要が有りました。

## フォーマット

**追記**
Rails 6 以降からは複数環境に対応したファイルを作成できるようになります。
https://github.com/rails/rails/pull/33521


secretsと大きく変わる点として、各環境毎に設定値が分割されずにフラットな構造になりました。設定することは可能ですが、Railsが自動で読み分けてくれるわけではないという意味です。

```yml
secret_key_base: a

aws:
  access_key_id: 1
  secret_access_key: 2
```

これは結構困る人が多そうな感じが有りますね。Rails本体でも議論されてましたが、DHHが意図してフラットな構造にしてると言っていたので恐らくこれはしばらくこのままな気がします。

ただ個人的にはこの方向性は正しいかなと感じていて、環境毎に細かく分けたい場合はsecrets経由ではなく環境変数をそのまま使うようにすれば良いかなと。

どうしても環境別に暗号化してgitにpushしておきたいとかがあれば

```ruby
# config/credentails.yml.enc
development:
  aws:
    access_key_id: 12345

# lib/credentails.rb
class Credentials
  def self.env
    Rails.application.credentials[Rails.env.to_sym]
  end
end

Credentials.env.dig(:aws, :access_key_id) # => 12345
```

みたいなのを簡易的に用意してあげれば良いかなー。

## おわり

最近はKubernetesで運用することがほとんどなので、そもそもRails.envをデフォルトの3つしか使わずに、ローカル以外はRAILS_ENV=productionで全て環境変数で設定みたいな運用をすることが多いのでsecrets.ymlもcredentials.yml.encもあまり必要としていなかったので、`SECRET_KEY_BASE`から`RAILS_MASTER_KEY`に統一されたのは分かりやすくなってよかったなという印象でした。おわり。
[EC-CUBE3]お届け可能日とお届け可能日の選択肢を設定（追加）

## お届け時間の選択肢を設定する
管理画面＞設定＞基本情報設定＞配送方法設定＞（設定したい配送方法）＞お届け時間設定

## お届け可能日の選択肢を設定する
配送方法設定をいくら探しても見つからなくて困った。商品の個別設定で行うみたい。
管理画面＞商品管理＞商品マスター＞（設定したい商品）＞詳細な設定＞お届け可能日

EC-CUBEデフォルトでは下記9種類
・即日
・1~2日後（注文内容確認画面のプルダウンでは1日後以降を選択可）
・3~4日後（注文内容確認画面のプルダウンでは3日後以降を選択可）
・1週間以降
・2週間以降
・3週間以降
・1カ月以降
・2か月以降
・お取り寄せ(商品入荷後)

**・・・2日後以降を選択させたいんですけど。**

## お届け可能日の選択肢を追加する
DBの「dtb_delivery_date」テーブルに1行追加する。
1. phpMyAdminなどでデータベースにログイン。（以下、phpMyAdminの場合）
2. 画面左のテーブル一覧から「dtb_delivery_date」テーブルを選択して表示
3. 画面上部の「挿入」を選択
4. （例：2日後の選択肢を追加する場合）
　　・ date_id：（空欄でOK。勝手に追加される）
　　・ name：2日後
　　・ **value：2 　←２日後から表示させるので２**
　　・ rank：（空欄でもOK。0が追加される）←管理画面での表示順。


### 動作確認環境
・EC-CUBE：3.0.13
sassで起点要素に状態セレクタ持たせた実装したかった話

とあるhtmlのcomponentがあったとする。
それはモーダルを内包したcomponentだった。

```slim
.component-A(class='is-modalView' if isModalView)
  .wrap
    // ...
    .modal
       .contents
```

それにsassでスタイルを当てたとする

```scss
.component-A {
  .wrap {
    .modal {
      display: none;
    }
  }
}
```

`.component-A.is-modalView`の時に.modalを`display: block;`にしたいけど&が`.component-A .wrap .modal`を全部持ってるのでネスト脱出するのが案外むずい。

sass3.3から@at-rootが導入されてるのでそれと補完構文を組み合わせればそこそこうまくいけた

```scss
.component-A {
  .wrap {
    .modal {
      display: none;
      @at-root .is-modalView#{&} {
        display: block;
      }
    }
  }
}
```

どうでしょう、キモさが目立ちますかね。

## サンプル

<p data-height="450" data-theme-id="0" data-slug-hash="ddgVzZ" data-default-tab="css,result" data-user="nazomikan" data-embed-version="2" data-pen-title="16a91c738d02d1fb90e7" class="codepen">See the Pen <a href="https://codepen.io/nazomikan/pen/ddgVzZ/">16a91c738d02d1fb90e7</a> by nazomikan (<a href="https://codepen.io/nazomikan">@nazomikan</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Raspberry Pi 2 Model Bで動画表示用キオスク端末を構築する

# Raspberry Pi 2 Model Bで動画表示用キオスク端末を構築する

配信系の試験は以下のとりまとめを参照。

- [Raspberry PiでRaspberry Pi Camera V2の動画を配信する ～mjpg-streamer編～](https://qiita.com/cactanaka/items/b255bd78bb50f9ab243c)
- [Raspberry PiでUSB Web CAMの動画を配信する ～mjpg-streamer自動化編～](https://qiita.com/cactanaka/items/2a82a1b98b9dbeba31da)
- [Raspberry PiでUSB Web CAMの動画を配信する ～mjpg-streamer編～](https://qiita.com/cactanaka/items/c9c54d8842138f0f5313)
- [Raspberry Pi 2 Model BでUSB Web CAMの動画を配信する ～v4l2rtspserver編～](https://qiita.com/cactanaka/items/45521aefaf921850e82f)

配信系に関して試験を行った結果、遅延の少ない配信を行うにはmjpg-streamerを利用した方が良さそうであるという事が分かった。
その結果を踏まえ、mjpg-streamerの表示が可能な動画表示用キオスク端末の構築を試験した。

一部のWebブラウザでは未対応の可能性があるという事であったが、Raspbianの標準ブラウザであるChromiumはMotionJPEGの表示に対応しており、追加のパッケージなどは特に必要が無いようである。

## 使用機材
- Raspberry Pi 2 Model B
- 8GBのmicro SD Card

## OS
- RASPBIAN STRETCH WITH DESKTOP (2017-11-29)
    - キオスク用であるためデスクトップ版とする

## 手順

既にRaspbianをSD CardにInstallしてあるものとする。
[インストール方法については公式を参考](https://www.raspberrypi.org/documentation/installation/installing-images/README.md)

Raspberry Piを起動し、ログインしておく。(今回の作業では標準ユーザー Pi で作業している。)

### システムのローカライズ

画面左上のラズベリーアイコンからメインメニューを開き、Performancesの中にあるRaspberry Pi Configurationを選択する。それぞれに対して以下の設定を行う。

```Shell

Local:
Language:ja(Japanese)
Country:JP(Japan)
Character Set : UTF-8

TImezone:
Area:Asia
Location:Tokyo

Keyboard:
Country:Japan
Variant:Japanese

OK

ここで再起動される
```

デフォルトで設定では再起動後に自動ログインするはずなので、デスクトップ画面が表示されるまでしばらく待ちます。デスクトップ画面が表示されたら画面上方のメニューバーからコンソールを開いて以下の作業を行います。


### システム全体のアップデートを行う

```Shell
sudo apt-get update
sudo apt-get upgrade
sudo apt-get clean
```

### カーソルを非表示にするパッケージを導入する

```Shell
sudo apt-get install unclutter
```

### システム再起動時にChromiumのエラー表示を表示しないようにする

```
sudo crontab -e

# エディタを選択する (今回はnanoを選択)
Choose 1-3 [2] : 2

# 以下の設定を追記する
@reboot rm -rf ~/.config/chromium/Singleton*

# nanoエディタを終了する
C-o C-x
```

### 画面の自動オフを無効化する

```Shell
sudo nano ~/.config/lxsession/LXDE-pi/autostart

# 以下の設定を追記する
# [サーバーのアドレス]と[配信ページ名]は環境ごとに置き換えること
@xset s off
@xset -dpms
@xset s noblank
@unclutter
@chromium-browser --noerrdialogs --kiosk --incognito http://[サーバーのアドレス]/[配信ページ名]
```

---
参考
- [Raspberry Pi3でキオスク端末(自動ログイン＋ブラウザ起動)を作る。](https://qiita.com/yyano/items/c08705994363b9526d07)
- [[Raspberry Pi] スクリーンのスリープを防ぐ](https://blog.withachristianwife.com/2017/04/10/prevent-raspberrypi-from-sleeping/)
serverless.ymlテンプレートファイルを分割する

リソースが増えてくるとマッチョなserverless.ymlが誕生し、可読性が悪くなるので`resources`の部分を分割しました。

## ディレクトリ構成
```
.
├── resource_configs
│   ├── dynamodb.yml
│   ├── s3.yml
│   └── ...
│
└── serverless.yml
```

## 各設定ファイル
### serverless.yml
```serverless.yml
service: example-service

custom:
  bucketName: testbucket01

provider:
  name: aws
  runtime: python3.6
  region: ap-northeast-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: /hello
          method: get

resources:
  - ${file(./resource_configs/s3.yml)}
  - ${file(./resource_configs/dynamodb.yml)}
  ...
```

### s3.yml
```s3.yml
Resources:
  Bucket01:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: ${self:custom.bucketName}
```


## 参考
https://github.com/serverless/serverless/issues/2828
MESHとLINE Notifyの連携

MESH上で発生したイベントをLINE Notifyに通知させるまでの手順。

# MESHアプリのインストール

https://meshprj.com/jp/app/

# MESHアカウントの作成

https://hub.meshprj.com/users/sign_up?locale=ja

# IFTTTアカウントとの紐付け

<img width="375" alt="IMG_0533 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/6dc10457-502e-e5b6-bf1a-e63b7a572a91.png">

# IFTTTのタグ

<img width="375" alt="IMG_0533 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/3f4367b9-a38f-e795-9068-cb9d79ee31f5.png">

# キャンバス

<img width="375" alt="IMG_0535.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/164153/a7b8e617-1b62-b111-ce51-83068e74c603.png">

# IFTTTタグの設定

## アプリ側

<img width="375" alt="IMG_0534 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/30d8e37e-18f1-3d1b-96fe-19fb8748390e.png">

## IFTTT側

<img width="500" alt="スクリーンショット_2018-02-26_17_43_24.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/274ceb8e-487d-b602-3a18-c22dfd646ad6.png">

<img width="500" alt="スクリーンショット_2018-02-26_17_37_18.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/95e57ae7-67eb-b451-9220-7464bdaf67cd.png">

<img width="500" alt="スクリーンショット_2018-02-26_17_37_23.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/80fc09d0-79e7-5c0c-3a26-839edf0e5396.png">

<img width="500" alt="スクリーンショット_2018-02-26_17_40_58.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/9f2a4732-9fd6-e501-1c1c-d10dabb27e2d.png">

<img width="500" alt="スクリーンショット_2018-02-26_17_37_44.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/361852c6-08e8-e7f2-2547-e6ad53f32efe.png">

<img width="500" alt="スクリーンショット_2018-02-26_17_37_55.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/993c3ed9-4cc4-4389-9ae7-039e7cb9676c.png">

<img width="500" alt="スクリーンショット_2018-02-26_17_38_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/164153/77a9dfe5-1c1c-a42e-861f-b2be15e7e290.png">

# 確認

<img width="375" alt="IMG_0536.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/164153/743e1ea9-b2bc-8224-ad1f-9be2e811f58b.png">

次回はGPIOやります。
MacとRaspberryPiにMosquitto入れてみた

# はじめに
仕事でMQTTを使うことになり、手軽にMQTTが扱えるらしいMosquittoについて調べました。
既に様々な方が同様のMosquittoの導入記事をまとめていますが、Macとラズパイで微妙に導入方法が違ったりで、私自身が多少迷ったので、備忘録もかねて記事にします。
MQTTとは何かについては、ここでは触れませんので、ぐぐって見てください。

# Mosquittoのインストール

## Macの場合
Homebrewを使ってインストールできます。

```bash
brew install mosquitto
```

以下のパスにソフトがそれぞれインストールされます。

- mosquitto（ブローカー）：/usr/local/opt/mosquitto/sbin
- mosquitto_sub（購読用）：/usr/local/opt/mosquitto/bin
- mosquitto_pub（配信用）：/usr/local/opt/mosquitto/bin

これらのパスは、環境変数のPathに追加しておきます。

## RaspberryPiの場合
ラズパイというかLinuxの場合ですが、以下のコマンドでMosquittoをインストールできます。

```bash
# Mosquitto(Broker)をインストールします。
sudo apt-get install mosquitto

# Mosquittoクライアントをインストールします。
sudo apt-get install mosquitto-clients
```

# ブローカーの起動
ブローカーは、MQTT通信を仲介するサーバーです。一般的には、AWS IoT等のクラウドサービスを利用すると思いますが、あくまで動作確認のため、ここでは、MacまたはRaspberryPiで起動します。どちらで起動しても良いです。１つあれば良いので、両方同時に起動する必要はありません。
また、次の動作確認のステップで必要になるので、ブローカー端末のIPアドレスをメモに控えておいてください。

## Macの場合
以下のコマンドでMosquittoのブローカーを起動します。

```bash
mosquitto
```

## RaspberryPiの場合
以下のコマンドでMosquittoのブローカーを起動します。

```bash
sudo service mosquitto status
```

# 動作確認
上記の手順でMosquittoをインストールすると、一緒に購読用と配信用の簡易クライアントもインストールされます。簡易クライアントで動作を確認します。
説明のため、以下のようにします。

- ブローカーのIPアドレス：192.168.11.18
- トピック名：tp1/test
- 配信メッセージ：Hello

購読用端末のターミナルを開いて、以下のコマンドでトピックを購読します。
購読用端末はブローカーと同じ端末でも問題ありません。

```bash
mosquitto_sub -h 192.168.11.18 -t tp1/test
```

配信用端末のターミナルを開いて、以下のコマンドでトピックにメッセージを配信します。
配信用端末はブローカーと同じ端末でも問題ありません。

```bash
mosquitto_pub -h 192.168.11.18 -t tp1/test -m Hello
```

これで購読側のターミナルにHelloというメッセージが表示されれば成功です。

# まとめ
Mosquittoを使ってお手軽にMQTTの動作環境を作ることができました。
Gitトピックブランチの利用法


トピックブランチ
===

- 短期間だけ使う一時的なブランチ(競合を防ぐ)
- 作業後マスターにマージする

トピックブランチの作成

```
$ git checkout -b トピックブランチ名
```

---
---

一連の流れ
===

クローン or プル</br>
→ トピックブランチに移動(作成)</br>
→ 作業</br>
→ add,commit</br>
→ masterにマージ</br>
→ push</br>

その他操作
===

ブランチの確認
---

*は現在使用中のブランチを表す。

```
$ git branch
```

---

現在の状態の確認
---

```
$ git status
```

---

---

活用方法
===
トピックブランチで作業をしてリポジトリを更新

↓

マージ
---

トピックブランチで行なった変更をmasterに反映させる

- マスターブランチに移動

```
$ git checkout master
```

- masterにトピックブランチをマージ

```
$ git merge topic-branch
```

 トピックブランチの削除 ・・・　必須ではない。必要に応じて残していても良い

```
$ git branch --delete トピックブランチ名
```

もしくは、(マージしていなくても強制削除)

```
$ git branch -D トピックブランチ名
```

---

トピックブランチでミスをした時の対処
---

- 失敗内容をコミット

```
$ git add -A
$ git commit -a -m "失敗内容"
```

- マスターに移動

```
$ git checkout master
```

- ブランチを強制的に削除(-Dフラグは変更をマージしていなくてもブランチを削除できる)

```
$ git branch -D topic-branch
```
Linuxサーバ上でmarkdownのドキュメントをPDFに変換する

markdown-pdfというのを使えばmarkdownの書式のドキュメントをPDFに変換できるらしい。

# インストール

ubuntu 16.04 のサーバを使用しています。
markdown-pdf はnodeのアプリなので、nodeとnpmが使えるようにする。
また、日本語のドキュメント用に何か日本語フォントをインストールしておく。

```
sudo apt install npm nodejs-legacy fonts-ipafont-gothic
sudo npm -g install markdown-pdf
```

# mdをPDFに変換

```
markdown-pdf document.md
```
これでdocument.pdf ができる。
Jenkinsのビルド後にMattermostに投稿する

# やりたいこと
セキュリティ的なアレで社内ではSlackが利用できないのでMattermostを利用しています。
開発経験が浅いメンバが多く、平気でコンパイルエラーになるソースコードをコミットしてくるので、Jenkinsでビルドエラーになった場合、Mattermostに自動でお叱りの投稿ができるようにしたいです。

# Jenkinsにプラグインを追加する
JenkinsにMattermost Notification Pluginを追加します。
https://plugins.jenkins.io/mattermost

インターネットにつながる環境であればJenkinsのプラグインマネージャから追加できると思いますが、今回の環境はセキュリティ的なアレでつなががりません。（忌々しい・・・）
そのため、上記URLからhpiファイルをダウンロードし、Jenkinsのpluginsディレクトリに取得したhpiファイルを配置、再起動を行いプラグインを追加しました。

# MattermostにIncoming Webhookを登録する
外部システムからMattermostに投稿するための設定を行います。
チーム名の横にある点々をクリックしてメニューを表示し、「統合機能」を選択します。（英語だとIntegrationとかだと思います。）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133607/e791a2af-ff9c-b206-94c9-e333be38c1f8.png)

以下のような画面が出てくると思うので、「内向きのウェブフック」をクリックします。（英語だとIncoming Webhookとかだと思います。）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133607/84fb5a50-7abf-b51c-e474-3946261de7aa.png)

そこに、Webhookを新規作成するボタンがあるので、そこから作成します。
作成されたウェブフックのURLは後程利用します。

また、Mattermostのシステムコンソールから「統合機能によるユーザ名の上書きを許可する」を有効にしておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133607/e8cfa33f-051f-09af-6728-a8361876dd12.png)

# Jenkinsの設定を行う
システムの設定からGlobal Mattermost Notifier Settingsの項目を設定します。

| 項目       |設定内容 |
|:-----------------|:------------------|
| Endpoint             |先ほど作成した内向きのウェブフックのURL|
|Channel|投稿するチャンネル。「ユーザ名@チャンネル名」と設定すれば、ユーザ名を指定できる。ユーザ名を省略した場合は、ウェブフックを作成したユーザとして投稿される。|
|Icon to use|投稿する際のアイコンのURL。省略すればウェブフックデフォルトのアイコンになる。|
|Build Server URL|ビルドサーバ（Jenkins）のURL。|

上記を入力した後、TestConnectionボタンを押して成功すれば設定完了です。（Mattermostにテストメッセージが投稿されるので注意。）
また、上記はジョブごとに設定することもできます。

# Jenkinsのジョブを作成する
ビルド後の処理として、「Mattermost Notification」が追加できるようになっています。
通知するタイミングをチェックボックスで選択できます。今回は「Notify Failure」にしました。
高度な設定から「Include custom message」を定義すれば、投稿する内容をカスタマイズできます。
また、「Notify Repeated Failure」にチェックを入れておけば、連続で失敗した場合にも、その都度投稿が行われます。
（デフォルトでは、初回のみ投稿されます。）


----


以上でJenkinsからMattermostに投稿することができます。
Javascriptでhtmlを動的に書き換える方法！

#JavaScriptでHTMLを書き換えよう！

##DOM(ドム)という仕組みを使うぜ！
いちばんやさしいJavaScriptの教本という本によると
>DOMはHTML文書の構造を、オブジェクトをツリー状につなげた構造で表したものです。

へえ～～～
とりえず、ツリー状ってことはわかった！つぎ！

##特定のIDをもつ要素を取得して書き換える

getElementByIdメソッドというものを使うらしい。
`var test = document.GetElementById("idの値")`

idの値っていうのは、HTMLの　id=""の中の部分ね。
documentっていうのは、HTML全部っていう感じでとらえておいたらいいかな！


取得したHTML要素の内容は「innerHTML」で確認できるよ！
書き換えもできるらしい
`test.innerHTML("書き換えたいなあ～")`　これで書き換え完了！

例えば

```test.html
<div id="greet">おはよう！<div>
```

```test.js
var greet = document.getElementById('greet')
greet.innerHTML = '<h1>こんにちは～～</h1>'
```

こんな感じです！

##おわり
疲れたからおわり。
きまぐれで更新していきます。
【Atom】ビルドしたフォルダをRemote-ftpで自動アップロード

## 概要
webpackなどのビルドツールを利用している場合など、開発と公開ディレクトリが異なる場合にRemote-ftpで自動アップロードするときの手順メモ。

## ディレクトリ構成
root/
　├ dist/ (公開用ディレクトリ)
　└ dev/ (開発用ディレクトリ)

## Atomでのプロジェクトフォルダの指定
Remote-ftpの仕様上、ローカル側のアップロードフォルダ指定はできないようで、必ずプロジェクトルートからのディレクトリ構成でアップされてしまいます。
そのためAtom上でプロジェクトフォルダを指定する際にrootを指定せず、distとdevをそれぞれ指定します。
手順としては、まずdevフォルダを指定してプロジェクトを開いた後、「ファイル」>「プロジェクトフォルダを追加」でdistフォルダを追加します。
**順番は特に関係ない…と思いきや、実は関係あります。「dev」が上になるよう登録するか、既に登録した後の場合はドラッグして順番を変更します。**


こんな構成になります。↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187744/db8a390e-916b-0fbd-d841-35582bb411f3.png)

##ftpconfigファイルの作成
.ftpconfigはFTPの接続情報を記載するファイルです。
パッケージ > Remote FTP > Create FTP(/SFTP) Config File から作成できます。
（理由は後述）

```.ftpconfig
{
    "protocol": "ftp",
    "host": "(host name)",
    "port": 21,
    "user": "(user)",
    "pass": "(pass)",
    "promptForPass": false,
    "remote": "/sites/sample/",
    "secure": false,
    "secureOptions": null,
    "connTimeout": 10000,
    "pasvTimeout": 10000,
    "keepalive": 10000,
    "watch": ["../dist/"],
    "watchTimeout": 500
}
```
こんな感じです。編集すべき場所はhost,user,pass,remoteと「watch」です。

### watchとは
watchは監視対象を追加するための記述です。公式ドキュメントにも"./dist/stylesheet/…"という記述例があるように、ビルドツールなどが生成した監視外のディレクトリを対象に追加するために指定します。

今回distフォルダはAtomのプロジェクト内なので監視対象に入っているかと思いきや、どうやら**remote-ftpは.ftpconfigファイルの設置場所を基軸とする**ようなので、ここで"../dist"を指定しています。
（前述のディレクトリ順序に関する理由がここに関係しているのですが、remote-ftpは1つ目のフォルダ内に設定ファイルを作るので、いちばん上のディレクトリはdevである必要があります。）

## .ftpignoreの作成
/ftpignoreは対象ファイルの除外を指定するファイルです。
パッケージ > Remote FTP > Create ignore Fileから作成できます。

```.ftpignore
.ftpconfig
.ftpignore
id_rsa
.DS_Store
.git
dev/
```

おそらくdev/以外は最初から記述されていると思います。
dev/は開発用フォルダをアップロードしてしまわないために追記します。

## 接続テスト
設定は以上になります。
パッケージ > Remote FTP > Connect からサーバーへ接続したあとビルドツールでコンテンツを生成し、アップロードの状況を確認します。
うまくいかない場合は一度Atomを再起動後にお試しください。

## まとめ

* watchで公開フォルダを追加
* ftpignoreで開発フォルダを除外

で実現できます。 
watchの記述がよく分からず、ネットで調べても正解のかたちがよく分からず、だいぶ悩みました。。
Atomパッケージの動作がうまくいかないときの確認方法として、
「表示」>「開発」「デベロッパーツール」でchromeの開発者ツールが確認できますので、ここからエラーログを参照すれば原因がつかみやすくなります。
Embulk (MySQL -> CSVファイル)

## 概要
Embulkを使う機会があったので、使い方について忘れないようメモしておく。
MySQLの「users」テーブルからデータを取得して、csvファイルに出力するサンプルをやってみる。

## サンプルを用意する
```bash:ターミナル
$ mkdir ./try4 && cd ./try4
```

## プラグインを追加する
MySQLからデータを取得するので「embulk-input-mysql」を追加する。

```bash:ターミナル
## プラグインの独立したバンドルを作成する
$ embulk mkbundle bundle

## gemファイルにプラグインを追記する
$ vi bundle/Gemfile
gem 'embulk-input-mysql' # 追記

## プラグイン追加
$ cd bundle
$ embulk bundle
$ cd ..
```

## config.yml作成
```bash:ターミナル
$ vi config.yml
```
```yaml:config.yml
in:
  type: mysql
  host: 127.0.0.1
  user: hoge
  password: "development"
  database: hoge_db
  query: |
    SELECT
      id,
      CAST(id AS CHAR) AS mid,
      name,
      UNIX_TIMESTAMP(created_at) AS created_at
    FROM
      users
    ;
out:
  type: file
  path_prefix: "./file/users"
  sequence_format: "."
  file_ext: csv
  formatter:
    type: csv
    delimiter: ","
    newline: CRLF
    newline_in_field: LF
    charset: UTF-8
    quote_policy: MINIMAL
    quote: '"'
    escape: "\\"
    null_string: "\\N"
    default_timezone: 'Asia/Tokyo'
```

## プレビュー
```bash:ターミナル
$ embulk preview -b bundle config.yml
```

## 実行
```bash:ターミナル
$ embulk run -b bundle config.yml
```

## 参考サイト
- [Github - embulk-input-mysql](https://github.com/embulk/embulk-input-jdbc/tree/master/embulk-input-mysql)
- [embulk - file-output-plugin](http://www.embulk.org/docs/built-in.html#file-output-plugin)
- [embulk - csv-formatter-plugin](http://www.embulk.org/docs/built-in.html#csv-formatter-plugin)
AVD(Android Emulator on Windows)がとても遅い件について

ここ2週間ほど、AVD（エミュレータ）がとんでもなく遅くなる現象に悩まされていて、まったくアプリ開発がすすみません。もちろんHAXMを使っています。

どうもWindowsUpdateに時期を同じくしているなという疑いをもってはいるもののロールバックするのはあまり乗り気でなく、なんとか解決できないかとずっとやっています。

いろいろ同じ状況の人がいないのか調べているものの情報がなく、半年前で少し古い情報だけど一番近いと思われたのが以下のスレッド。

https://stackoverflow.com/questions/43558671/android-studio-emulator-extremely-slow


情報が錯綜しているのだけど、要点は

・WindowsUpdate,もしくはIntelドライバが悪さをしてるようだ
・Intelチップセットを使ってる場合に起きるのでは？(NVIDIAとのデュアルボードの場合に切り替えると解決する)
・グラフィックボードのドライバを更新することで改善の可能性がある
・AVDの設定で”Automatic"ではなくSoftware GLSE2.0にするとソフトウェアレンダリングにすると若干改善する
・..


一通り試したものの、私のPCでは大きく改善せず。何度もHAXMをアンインストール再インストールするも効果は薄く。

ちなみに会社のPCはNVIDIAを積んでるせいか超高速AVD起動でした。

なんとかならんのかしら

--- 翌日追記 ---

解決しました。以下の記事にある
『AVASTの設定「ハードウェアによる仮想化支援機能を利用する」がオンになっているのがNG』
というのがビンゴでした。まったくもってありがとうございます。
https://qiita.com/oboenikui/items/56da72def4cf477cf1e7
結果、劇的改善です。今回使えなくなる前よりも激変ですので、そもそもHAXが効いてないギリギリの状態で使っていた所、さらに負荷がかかるなんらかの要因（intelドライバの更新など）が加わって使い物にならなくなったのではないかとみています。もう少し高スペックのPCであればなんとか動いてしまって我慢して使い続けてしまうところでした。

VT-Xについては不勉強で理解しきってないのですが、そもそもこのVT-Xに対応しているCPUでなければHAXMが使えないということのはずだったのに、なぜウイルス対策ソフト側でオフにせねばならないのか腑に落ちないところです。　そして今回の敗因は「何かあったらウイルス対策ソフトを疑う」という基本を軽視したことと、実際AVASTをオフにして試すくらいのことはしたにも関わらず、この仮想化支援なんとかフラグがCPUの機能に関するものなので再起動しないと効かなかったというところだと思います。洞察が足りませんでした。ちなみにSDK総入れ替えからなにから丸一日かけて試しましたがすべて徒労でした。

--- 三日後追記 ---

激変したというのは錯覚でした。エミュレータの動作自体はさほど速くなっていません。私はモバイル派なので非力なノートPCを使っているので速さはそもそもこんなものなのです。起動が激的に速くなったというのは事実ですが、問題が起きる前も起動は速かったことを思い出しました。ノートPCを買い替えたきにエミュレータが速くなって感動したことを覚えているので。今回はWindowsUpdateを境にしてVT-X関連の挙動が変わってしまったところに加えてAvastのオプションで回避することができたというのが正しいと思います。このことを確認するにはWindowsUpdateを差し戻すしかないと思いますがめんどくさいのでやりません。日付的に怪しいのはKB4074588,この番号は同時期に私の勤め先でもキーボードマウスが操作不能になるPCが続出するという悪名高きものでした。
アルファベットを小さくしてみよう

現実逃避に作りました :innocent: 

# 方法

```py
import unicodedata

def make_smaller(string):
  new_string = ''
  
  for char in string:
    if not char.isalpha():
      new_string += char
      continue
    
    if char == 'i' or char == 'n':
      new_string += unicodedata.lookup(f'SUPERSCRIPT LATIN SMALL LETTER {char}')
      continue
    
    small_or_capital = 'CAPITAL' if char.isupper() else 'SMALL'
    
    try:
      new_string += unicodedata.lookup(f'MODIFIER LETTER {small_or_capital} {char}')
      continue
    except KeyError:
      pass
    
    try:
      new_string += unicodedata.lookup(f'MODIFIER LETTER SMALL {char}')
      continue
    except KeyError:
      pass
    
    new_string += char  # q と Q は残念ながら対応する文字がない。
  
  return new_string
```

```py
>>> make_smaller('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')
'ᴬᴮᶜᴰᴱᶠᴳᴴᴵᴶᴷᴸᴹᴺᴼᴾQᴿˢᵀᵁⱽᵂˣʸᶻᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖqʳˢᵗᵘᵛʷˣʸᶻ'

>>> make_smaller('Puella Magi Madoka Magica')
'ᴾᵘᵉˡˡᵃ ᴹᵃᵍⁱ ᴹᵃᵈᵒᵏᵃ ᴹᵃᵍⁱᶜᵃ'
```

:point_down_tone2: Android など一部の環境では表示できないので画像も上げておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/6697/9c5d13a9-5c94-de0e-0f4c-99dcd6639d71.png)

# 参考

* [Unicode Block “Spacing Modifier Letters”](https://www.compart.com/en/unicode/block/U+02B0)
* [Unicode Block “Superscripts And Subscripts”](https://www.compart.com/en/unicode/block/U+2070)
Microsoft Translator テキスト API の使い方 (python3)

Microsoft Translator テキスト API の使用例です。
日本語から、ドイツ語への翻訳です。

```py:translation.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	translation.py
#
#                   Feb/26/2018
#
# ------------------------------------------------------------------
import  sys
import  requests
from get_token import get_token_proc
# ------------------------------------------------------------------
def translate_proc(token,text_in):
	url = "https://api.microsofttranslator.com/v2/http.svc/Translate?text="
	url += text_in + "&to=de" + "&category=generalnn"
#
	headers = {"Authorization": "Bearer " + token}

	rr=requests.get(url,headers=headers)
	sys.stderr.write(str(rr.status_code) + "\n")
#
	return rr.text

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
token = get_token_proc()

text_in="今日はいい天気です。"
print(text_in)
result = translate_proc(token,text_in)
print(result)

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

次の key1 は、自分のものと置き換えて下さい。

```py:get_token.py
# -*- coding: utf-8 -*-
#
#	get_token.py
#
#                   Sep/21/2017
#
# ------------------------------------------------------------------
import  sys
import  requests
# ------------------------------------------------------------------
def get_token_proc():
	key1 = "e968e25ffc2146f00000000000000aaa"
	url="https://api.cognitive.microsoft.com/sts/v1.0/issueToken"

	headers= {"Ocp-Apim-Subscription-Key": key1}

	rr = requests.post(url,headers=headers,data="")
	sys.stderr.write(str(rr.status_code) + "\n")
#
	return rr.text
# ------------------------------------------------------------------
```
Google Safe BrowsingのAPI(V4)にRubyでLookupする

[Google Safe Browsing](https://developers.google.com/safe-browsing/)ってありまして。
APIがあるのでRubyからきゃつらのルールで不正と判断しているドメイン(または実行ファイル)をチェックしてみようとしました。

## 事前準備

- rubygems `google-api-client` をインストール
- APIKEYを環境変数にいれておく


## Lookupのサンプルコード

google-api-clientってほとんど動的生成なので、普通に使い方をソースから見ようとするとサッパリわかりません。

動的に生成されたらこうなるよというコードがリポジトリに一緒に上がっているので、そちらをドキュメント代わりにチェックします。

- https://github.com/google/google-api-ruby-client/tree/master/generated/google/apis

[safebrowsing_v4はこのへん](https://github.com/google/google-api-ruby-client/tree/master/generated/google/apis/safebrowsing_v4)ですね。

Lookupする場合、`find_threat_matches`メソッドに`Google::Apis::SafebrowsingV4::FindThreatMatchesRequest`のオブジェクトを渡すだけです。


```ruby:safebrowsing_lookup.rb
require 'google/apis/safebrowsing_v4'
sb_service = Google::Apis::SafebrowsingV4::SafebrowsingService.new
sb_service.key = ENV['APIKEY']

# タイプの詳細は https://developers.google.com/safe-browsing/v4/reference/rest/ で
tr = Google::Apis::SafebrowsingV4::ThreatInfo.new(
  threat_types: ["MALWARE", "SOCIAL_ENGINEERING"],
  platform_types:    ["ANY_PLATFORM"],
  threat_entry_types: ["URL"],
  threat_entries: [
    {"url": "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"}
  ]
)

# client_idはなるべく一意にしてねとのことですが、サンプルコードなので適当に
opts = Google::Apis::SafebrowsingV4::FindThreatMatchesRequest.new(
  client: Google::Apis::SafebrowsingV4::ClientInfo.new(
    client_id: "google-api-client",
    client_version: "0.19.8"
  ),
  threat_info: tr
)

res = sb_service.find_threat_matches(opts)

puts res.to_json
```

レスポンスのmatchesに何かしら入っていれば引っかかったということです。
ちなみに`threat_entries`の`url`は`http://〜`のようにスキーマを含めなくてもマッチします。

```shell:
$ ruby safebrowsing_lookup.rb
{
  "matches": [
    {
      "cacheDuration": "300s",
      "platformType": "ANY_PLATFORM",
      "threat": {
        "url": "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"
      },
      "threatEntryType": "URL",
      "threatType": "MALWARE"
    }
  ]
}
```


## 余談

Google Safe Browsingの影響として身近なところでは、Let's Encryptでドメインの申請をする際、このAPIでマッチしたら所有確認の時点でお断りされるんですよ。
pythonでモンテカルロUCTを実装してみた

自分の勉強も兼ねてモンテカルロ法について書いていきます。
何か間違いがあったら指摘してくださると嬉しいです。

[前回の記事](https://qiita.com/nanakrk965/items/34f3e837af052fa91860)
から色々試してランダム君に100%勝利を目指したものの、中々成果が出ないので、
素直に探索アルゴリズムを組もうかと思っています。

オセロはmin-max法が主流ですが、alpha go zero　でも使われたモンテカルロが面白そう尚且つ、プログラマーが楽できそうな方法なので、そちらを試してみたいと思います。

原始モンテカルロはある局面から、ひたすらランダムで対局を重ね、勝率の統計を取り、一番高い勝率をその局面の手として採用する方法ですが、完全にランダムだと最善手に行き着く事は中々ありません。

そこでモンテカルロUCTと言われている方法で探索したいと思います。
ただ今回はオセロの探索アルゴリズムとしてではなく、
モンテカルロ法でよく取り上げられていたスロット問題として、実装してみます。

```ucb.py 
import random
import numpy as np

def machine1():
    return random.randint(1, 10)#期待値 5.5

def machine2():
    return random.choice([0] * 8 + [10, 20]) #期待値 3

def machine3():
    return random.choice([2, 3, 5]) #期待値 3.3333...

def machine4():
    return random.choice([3, 4]) #期待値 3.5

def machine5():
    return random.choice([0] * 49 + [100]) #期待値 2

def ucb(mean, total_coin, coin, X):
    return mean + X * np.sqrt((2*np.log(total_coin)/coin))

def main(X, play_num):
    #最初は全てに1枚ずつ投資してから開始する
    machines = [machine1, machine2, machine3, machine4, machine5]
    total_values = [machine() for machine in machines]
    mean_values = total_values.copy()
    total_coin = len(mean_values)
    coins = [1] * len(mean_values)
    search_num = [1] * len(mean_values)

    for i in range(play_num):
        #どのマシーンのucb値が最大なのかを見る
        max_ucb = \
            np.argmax([ucb(mean, total_coin, coin, X) \
                       for mean, coin in zip(mean_values, coins)])

        #ucbが最大値のマシーンにコインを投資し、値を更新する。
        coins[max_ucb] += 1
        total_coin += 1
        value = machines[max_ucb]()
        total_values[max_ucb] += value
        mean_values[max_ucb] = total_values[max_ucb] / coins[max_ucb]
        search_num[max_ucb] += 1
    print(search_num)

if __name__ == "__main__":
    main(10, 10000)
```

調べればすぐに出てくると思いますが、スロット問題(多腕バンディット問題とも言われている)についても触れていきます。
スロット問題とはいくつかのスロットマシーンがあったとして、
なるべく損失する事無く、どのマシーンにコインを投資すれば、儲かる期待値が高いのかを調べるという問題です。
当然それらのマシーンはどのように設定されているかは不明です。

原始モンテカルロの場合、全てのマシーンに均等に投資しますが、これだと質の悪いスロットがあった場合、大損します。
儲けたいのであれば、やはり儲かりそうなスロットに重点的に投資したいですね。

しかし、その儲かりそうなスロットを見つけるには、ある程度の投資が必要です。何故なら1枚コインを入れて結果が悪かったとしてもたまたまの可能性があるからです。
だからと言って、儲かりそうなスロットを見つける為に、投資ばかりをしたら、損する可能性も出てきます。

つまり、探索と経験のバランスが大事になってくるわけです。
じゃあどうすればバランスよくコインを投資出来るの？
という疑問に答えてくれるのがUCBになります。

```ucb.py 
def ucb(mean, total_coin, coin, X):
    return mean + X * np.sqrt((2*np.log(total_coin)/coin))
```
(式間違ってたら教えてください)

引数のmeanはそのマシーンに投資して、コインが戻って来た平均値です。
total_coinは全てのマシーンに投資したコインの枚数です
coinはそのマシーンに投資したコインの枚数
Xは経験と探索のバランスを決める定数です。

後はこの式をマシーン別に割り当て、式の結果の値が一番大きいマシーンに投資すれば、経験と探索をバランスよく取る事が出来るようになります
この式の結果の値をucb値と言うようです。

この式の性質として、定数Xが大きいほど、探索を重視し、小さいほど、経験を重視します。
また平均値が大きいほど、当然ucb値も増えていきます
しかしcoinの枚数が増えれば、増えるほど、ucb値は小さくなっていきます。
つまりこれは良さそうなマシーンだけど、いっぱい投資したし、別のものも試してみるかという事が起きます。

では実行結果を見てみましょう。
`[9792, 44, 61, 71, 37]` 
このリストは各マシーンに投資した数になります。
期待値通りの投資数になっていますね

では次に`main(1, 10000)`とし、定数Xを減らした結果を見てみます。
`[9994, 7, 1, 2, 1]`
探索数が減っているのがわかりますね。

次に`main(50, 10000)`とし定数Xを増やした結果を見てみます。
`[7460, 551, 807, 863, 324]`
今度は探索数が増えているのがわかりますね。

この定数をどう決めるかは問題によると思いますが、alpha goは5だったようです。

さて、今回はここまでにします。
次回は、オセロの探索としてUCBを取り入れていきたいと思います。

追記1
コメントを受けてコードを修正しました。
Lonely IntegerをPHPで挑戦!! 文系学生がやってみた!!

##はじめに
インターン先でプログラミング勉強中の文系学生。

社員さんから
「これやろうか」
とのお達し。

**Lonely Integer**

???

##Lonely Integerとは
まずは、Lonely Integerの理解から始めよう。
提示されたのはHackerrankの[Lonely Integer](https://www.hackerrank.com/contests/miraidenshi/challenges/lonely-integer)。

英語なんて勿論わかるわけもなく、Google先生の力を借りよう。

Lonely Integerを訳すと、「孤独な整数」。

翻訳された内容を見てみると、整数が格納されている配列の中で1回だけ出てくる整数を表示することを指すみたい。

やるべきことはわかったから、やっていくか!!

##実践
###1.学習
まずは他の人の構文を参考にさせてもらおう。
「LonelyInteger PHP」で検索したら、GitHubGistの[このコード](https://github.com/sebastianbrosch/HackerRank/blob/master/algorithms/bit-manipulation/0001-lonely-integer.php)を発見!!

早速構文を理解していくか!!

必要な処理は次の通り。
　1.配列に含まれている要素を数え(比較に必要だから)
　2.ループ分岐の中にループ分岐(1つの配列で比較していくから)
   　　例,n[1]とn[1],n[1]とn[2],n[1]とn[3]みたいに比較していく

きっとこのほかにもあるんだろうけれど、特に必要なのはこの2つ(だと思う)。

###2.挑戦
[このコード](https://github.com/sebastianbrosch/HackerRank/blob/master/algorithms/bit-manipulation/0001-lonely-integer.php)を例に構文打っていこう。

`Run Code`を押してみたら、すんなり行けた。
じゃあ、`Subimit Code`。
よっしゃ!! クリア!!

##まとめ
今回は配列から要素の抽出する構文の学習をしました!!
具体的に何に使うのかはわからないから、調べてみよっと。
【Swift4】キーボードの上に送信フォームを実装する方法

## 実行環境
【Xcode】Version 9.2
【Swift】Version 4.0.3

## 概要
iOSキーボードの上に送信フォームを追加する方法です。

前回はキーボードの上にUIToolbarを実装しましたが、
ツールバーに送信フォーム(LINEみたいなやつ)を追加したくなったので、
今回はUIviewでツールバーを自作しています。

【前回の記事】
[【Swift4】キーボードの上にUIToolbarを実装する方法](https://qiita.com/shirape/items/2770a7793c987e2bdb70)

## 方法

### 下準備
UItextFieldをいい感じに追加しておきます。
<img width="373" alt="a.png" src="https://qiita-image-store.s3.amazonaws.com/0/238595/09dd3095-4b90-1bfb-d578-cee63c8243db.png">

### 実装

```ViewController.swift
class ViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ツールバーを作成
        let toolBar: UIView = UIView()
        toolBar.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 45)
        toolBar.backgroundColor = UIColor(red: 238/255, green: 238/255, blue: 238/255, alpha: 1.0)
        
        // テキストフィールドを作成
        let barTextField: UITextField = UITextField()
        barTextField.frame = CGRect(x: 5, y: 5, width: self.view.frame.width - 65, height: 35)
        barTextField.placeholder = "コメント..."
        barTextField.borderStyle = UITextBorderStyle.roundedRect
        
        // ボタンを作成
        let barButton: UIButton = UIButton(type: UIButtonType.system)
        barButton.frame = CGRect(x: barTextField.frame.width + 10, y: 5, width: 50, height: 35)
        barButton.setTitle("送信", for: UIControlState.normal)
        barButton.addTarget(self, action: #selector(buttonEvent(_:)), for: UIControlEvents.touchUpInside)
        
        // アイテムをツールバーに追加
        toolBar.addSubview(barTextField)
        toolBar.addSubview(barButton)
        
        // ツールバーをビューに設定
        textField.inputAccessoryView = toolBar
        textField.delegate = self
    }
    
    // ボタンタップ時に実行するメソッド
    @objc func buttonEvent(_ sender: UIButton) {
        // 処理を書く
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
}

```

## 実行結果
<img width="385" alt="スクリーンショット 2018-02-26 16.50.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/238595/336a80cb-b2b5-f79e-ec06-4483ca1e740e.png">

こっちの方法のほうがカスタマイズしやすそうですね。
他にもいい方法があれば教えてください！
Embulk (gzip -> 解凍:csv -> TreasureData)

## 概要
Embulkを使う機会があったので、使い方について忘れないようメモしておく。
「sample_01.csv.gz」ファイルからcsvを取得し、TreasureDataへ送信するサンプルをやってみる。

## サンプルを用意する

```bash:ターミナル
$ embulk example ./try3
```

## プラグインを追加する
「embulk-output-td」を追加する。

```bash:ターミナル
## プラグインの独立したバンドルを作成する
$ embulk mkbundle bundle

## gemファイルにプラグインを追記する
$ vi bundle/Gemfile
gem 'embulk-output-td' # 追記

## プラグイン追加
$ cd bundle
$ embulk bundle
$ cd ../
```

## config.yml作成 & 修正
```bash:ターミナル
$ embulk guess -b bundle seed.yml -o config.yml
$ vi config.yml
```

```yaml:config.yml
in:
  type: file
  path_prefix: /root/opt/www.qlife.jp/./try3/csv/sample_
  decoders:
  - {type: gzip}
  parser:
    charset: UTF-8
    newline: LF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    null_string: 'NULL'
    trim_if_not_quoted: false
    skip_header_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: id, type: long}
    - {name: account, type: long}
    - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
    - {name: purchase, type: timestamp, format: '%Y%m%d'}
    - {name: comment, type: string}
out:
  type: td
  apikey: <your apikey>
  endpoint: api.treasuredata.com
  database: hoge_fuga_tmp  # データベース名
  table: my_table          # テーブル名
  mode: append             # 転送モード: append(追加), replace(置き換え)
  # time_column: time      # インデックスに使用する時間カラム
  default_timestamp_format: '%Y-%m-%d %H:%M:%S'
  column_options:
    time: {format: '%Y-%m-%d %H:%M:%S', timezone: 'Asia/Tokyo'}

```

## プレビュー
```bash:ターミナル
$ embulk preview -b bundle config.yml
+---------+--------------+-------------------------+-------------------------+----------------------------+
| id:long | account:long |          time:timestamp |      purchase:timestamp |             comment:string |
+---------+--------------+-------------------------+-------------------------+----------------------------+
|       1 |       32,864 | 2015-01-27 19:23:49 UTC | 2015-01-27 00:00:00 UTC |                     embulk |
|       2 |       14,824 | 2015-01-27 19:01:23 UTC | 2015-01-27 00:00:00 UTC |               embulk jruby |
|       3 |       27,559 | 2015-01-28 02:20:02 UTC | 2015-01-28 00:00:00 UTC | Embulk "csv" parser plugin |
|       4 |       11,270 | 2015-01-29 11:54:36 UTC | 2015-01-29 00:00:00 UTC |                            |
+---------+--------------+-------------------------+-------------------------+----------------------------+
```

## 処理実行
```bash:ターミナル
$ embulk run -b bundle config.yml
```

## TreasureDataを確認
my_tableテーブルにデータが登録されている。
![screen.png](https://qiita-image-store.s3.amazonaws.com/0/142279/b4691d45-b6be-bc6c-dcde-236d8da5b2cf.png)

以上

## 参考サイト
- [Github - treasure-data/embulk-output-td](https://github.com/treasure-data/embulk-output-td)
- [TD output plugin for Embulk](http://www.rubydoc.info/gems/embulk-output-td/0.3.12)
- [Macからembulkを使ってTreasure Dataへのデータ転送を楽々行う](https://techblog.gmo-ap.jp/2016/09/30/mac%E3%81%8B%E3%82%89embulk%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6tresuredata%E3%81%B8%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E8%BB%A2%E9%80%81%E3%82%92%E6%A5%BD%E3%80%85%E8%A1%8C%E3%81%86/)
DockerでGitBucketのコンテナを作成し永続化させる

GitBucketのサーバをdockerで作成した時のメモです．docker上のコンテナで作成したリポジトリ情報が，コンテナを破棄した時に同時に消滅してしまうので，dockerのデータボリューム機能を用いて永続化をしました．

またdockerのサーバの引っ越しのたびに，コマンドを打ち直すのも面倒なので，docker-composeを利用して，簡略化しました．

ファイル構成は以下の通り．

```
.
|-gitbucket/
|     '-Dockerfile
'-docker-compose.yml
```

#GitBucketのDockerfile

``` :./gitbucket/Dockerfile
FROM tomcat:8-jre8

ADD https://github.com/gitbucket/gitbucket/releases/download/4.14.1/gitbucket.war /opt/gitbucket.war

RUN ln -s /gitbucket /root/.gitbucket

VOLUME ./gitbucket/gitbucket-data:/gitbucket

EXPOSE 8080 29418

CMD ["java", "-jar", "/opt/gitbucket.war"]

```

#docker-compose.ymlの設定
``` :./docker-compose.yml
version: '2'
services:
  gitbucket:
    image: gitbucket:0.1
    ports:
      - 8080:8080
      - 29418:29418
    volumes:
      - ./gitbucket/gitbucket-data:/gitbucket
    restart: always
```

`./docker-compose.yml`内のvolume機能で，コンテナ内の`/gitbucket`のデータをローカルの`./gitbucket/gibucket-data`で共有する．
また`restart:always`とすることで，OS再起動時に，コンテナも自動的に再起動するようにできるので必要があれば記述する．

#コンテナの起動
コンテナの起動は以下のコマンドで一発．

```sh:
$ docker-compose up
````

起動すると`gitbucket`ディレクトリ内に，リポジトリやアカウント情報を持った`gitbucket-data`フォルダが生成される．

```
.
|-gitbucket/
|     |-Dockerfile
|     '-gitbucket-data/ 
'-docker-compose.yml
```

http://localhost:8080 にアクセスして以下の画面が表示されれば成功．
![スクリーンショット 2018-02-26 16.06.55.png](https://qiita-image-store.s3.amazonaws.com/0/163680/e1533f2a-fccb-77e8-8416-4a4dd503f332.png)
初期のユーザ名とパスワードは両方とも`root`
#参考
https://qiita.com/suzukihi724/items/7859724c9a0e44bf1730
https://qiita.com/eijenson/items/25b35916afa38cdf9cea
画像の細線化を行うツール

# [hed-tool](https://github.com/knok/hed-tool)

以前[pix2pix付属のツールで画像のエッジ化を行う記事](https://qiita.com/knok/items/c3bbff0597b3158ec31c)を書きましたが、古いバージョンをベースに改造されたCaffeを用いるという点に不満がありました。
他の実装を探してみたところ、[Tensorpack](https://github.com/ppwwyyxx/tensorpack)のサンプルにHED実装と事前訓練モデルが用意されていたので、これをベースにツール化をしました。

## インストール

詳細は[ドキュメント](https://github.com/knok/hed-tool/blob/master/README.md)に記載しています。箇条書きで以下にまとめます。

* TensorFlow, [Tensorpack](https://github.com/ppwwyyxx/tensorpack)のインストール
* [GNU Octave](https://www.gnu.org/software/octave/)と[Piotr's Computer Vision Matlab Toolbox](https://pdollar.github.io/toolbox/)等のインストール
* [HED事前訓練モデル](http://models.tensorpack.com/HED/HED_pretrained_bsds.npz)のダウンロード

## 実行例

```shell-session
$ python hed-tool.py --load HED_pretrained_bsds.npz -o output.png input.png
```

### 入力画像

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31714/f5ee2ccb-fc57-59b0-55d7-b048668ef745.png)

ソース: [pixabay](https://pixabay.com/ja/%E9%9B%AA%E3%83%92%E3%83%A7%E3%82%A6-%E5%A4%A7%E3%81%8D%E3%81%AA%E7%8C%AB-%E7%8C%AB-%E9%9B%AA-%E5%86%AC-%E5%8B%95%E7%89%A9%E5%9C%92-%E5%B1%B1%E7%8C%AB-%E3%83%8F%E3%83%B3%E3%82%BF%E3%83%BC-%E9%87%8E%E7%94%9F-1985510/)

### 出力画像

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31714/caf8f629-d736-3e7f-4580-28ed35360081.png)

### 出力画像(-sオプションあり)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31714/cbf12b9a-7496-0ac7-0dd9-2531538741d5.png)