OmniAICreator/Qiita-1.07M huggingface dataset:
PHPExcelからPhpSpreadsheetへ移行

[公式ドキュメント](https://phpspreadsheet.readthedocs.io/en/develop/topics/migration-from-PHPExcel/
)を参考に移行作業を行ったのでメモしておきます。

## 結論
列番号を随所で指定しているような使い方じゃなかったらさくっと移行できそう

## 作業メモ

PhpSpreadsheetインストール

```
$ composer require phpoffice/phpspreadsheet:^1.0.0
```

PhpExcelアンインストール

```
$ composer remove phpoffice/phpexcel
```

公式の移行スクリプト実行

```
# アプリケーションのコードディレクトリに移動しておく
$ cd src/
$ ./../vendor/phpoffice/phpspreadsheet/bin/migrate-from-phpexcel
```

createReader()/createWriter()で使っているショートネームを置換（ここはプロジェクトによって異なるかと）

```
$ grep -nrE -l '(createReader|createWriter)' . | xargs sed -i -e 's/Excel2007/Xlsx/g'
$ grep -nrE -l '(createReader|createWriter)' . | xargs sed -i -e 's/Excel5/Xls/g'
```

deprecatedなメソッドを置換（ここはプロジェクトによって異なるかと）

```
$ grep -nr -l '>getDefaultStyle()' | xargs sed -i -e 's/>getDefaultStyle()/>getParent()->getDefaultStyle()/g'
```

列番号が0始まりだったのが1始まりになったので、列番号を直接指定している所を修正。

以上です！
RDS for MySQLでの可用性向上の機能についてゆるくまとめてみた

RDS for MySQLでの可用性向上について構成検討するにあたりゆるりとまとめてみた

Auroraは素敵な機能がたくさん出ているけど今回は、RDS for MySQLの話

## マスタのMultiAZ

### 概要
- 異なるAZにスタンバイインスタンスを配備し、同期データレプリケーションする(同期レプリなので書込性能は劣化する)
- Amazonのフェイルオーバーテクノロジーにより、インフラレイヤの障害時に自動でスタンバイインスタンスにフェイルオーバーする

下記がフェイルオーバー発生の条件

- アベイラビリティーゾーンの機能停止
- プライマリ DB インスタンスのエラー
- DB インスタンスのサーバータイプ変更
- DB インスタンスのオペレーティングシステムでソフトウェアのパッチ適用中
- DB インスタンスの手動フェイルオーバーが [Reboot with failover] を使用して開始された

### うれしいポイント
- masterの可用性とデータの耐久性をメンテナンスレスで向上させる事が出来る

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html

## リードレプリカのMultiAZ
### 概要
- master-リードレプリカは非同期レプリだが、リードレプリカのAZ間は同期レプリ
- マスタのMultiAZと仕組みは同じ

### うれしいポイント
- リードレプリカが一台構成の時に、可用性を向上させることができる
- リージョンをまたいだDR対応が可能(リージョン死んだ時に、MultiAZ構成でレプリカをmaster昇格させる)
 - 本格的なDRサイト組むような環境だとたしかにうれしいかも
- アップグレードに使える(MultiAZレプリカをアップグレードした後に、master昇格させることでメンテ時間を短縮)

## リードレプリカの負荷分散
### 概要
- masterからリードレプリカを複数台作る(非同期レプリ)
 - 単一のソースインスタンスから最大5機のリードレプリカまで作れる
 - チェーンすれば台数は増やせるが、その分レプリのタイムラグは大きくなる
- Route53 のホストゾーン機能で負荷分散するのがAWS推奨らしい
 - リードレプリカを増やした時は、R53へのレコード追加が必要
 - 重み付けratioでリクエスト数調整したり、ヘルスチェックも使えるのでL４LB相当のことが出来る(こんな簡単にできてもうなんかLVSとか運用してた時代が。。。)

### うれしいポイント
- アプリケーションからのread処理をレプリカに向けることで、masterの負荷を下げれる
- 1エンドポイントに複数台レプリカ(AZも分離する)を構える事で、1台でも生きていれば処理継続出来る
 - r53のヘルスチェックを入れる必要ある 
- レプリカはスケールアウト戦略で負荷に対して対応することが可能

リードレプリカのMultiAZはアップグレード時以外はあまりおいしくないなといった印象。
MultiAZでmasterを構えて、リードレプリカを複数作って負荷分散するのが負荷対策とコスト考えた時によさそう。
Azure Data Lake AnalyticsでPython UDFを使う

Azure DataLake AnalyticsではU-SQLを用いたメインプロセスからC#,Python,RのUDFが呼べます。PythonのUDFを使う場合には以下の配慮が必要でした。

# Azure Data Lake Analytics アカウントに Python 拡張機能をインストールする
以下のページのように、Azureポータルから拡張をアクティベートする必要があります。
[チュートリアル: Python を使用して U-SQL の拡張を始める](https://docs.microsoft.com/ja-jp/azure/data-lake-analytics/data-lake-analytics-u-sql-python-extensions)

# Visual Studio にて対象となるpython UDOコードを記述

特に名称に規則はないようですが、VSのメニューからAdd UDOをすると、***.usql.pyというテンプレートが生成されるのでこれを記述します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/146939/4055350d-763a-3c8b-0b50-974b09a4eb73.png)

このファイル名を途中で変えても、VSのプロジェクト設定には反映されませんでしたので、ファイル名は最初から考えて記述するか、手動でVSプロジェクトファイルを同期する必要があります。

コードは以下のようにpandas DataFrameを入力、出力にする形で記述すればよいです。
出力されるデータフレームの型はデシリアライズされる側で有効になり、スキーマが必要になりますので、どのような型で出力されるかを予想して把握する必要があります。

```python3
def get_mentions(tweet):
    return ';'.join( ( w[1:] for w in tweet.split() if w[0]=='@' ) )

def usqlml_main(df):
    del df['time']
    del df['author']
    df['mentions'] = df.tweet.apply(get_mentions)
    del df['tweet']
    return df
```

pandasやnumpyなどはビルトインされていますが、独自ライブラリをimportするにはアーカイブしたものを転送しておく必要があります。
短いコードならコードごと貼り付けちゃえばいいですけどね。

# python UDOコードをビルド
User Defined Objectを記述し、ビルドする必要があります。実際この機能はホストのusqlコードに以下のインライン変数を定義するだけのようです。

```U-SQL
DECLARE @pyfunction string = @"..."
```

# pythonのデバッグ
U-SQLでUDOを実行した場合、pythonのエラーメッセージを見ることは可能です。
ですが、細かい問題を修正するには向かないので、pythonコードは他所で十分テストされたものを利用することをお勧めします。
fuelPHPでmigration時に.. does not contain expected class ..が出てきた時の対処法

##やりたかったこと
fuelPHPでのmigration

##エラーメッセージ
以下の内容が表示された。

```ruby:terminl
Migration "/var/www/test/fuel/app/migrations/184_add_columns_table_test.php"
does not contain expected class "Fuel\Migrations\Add_Columns_Table_Test"
```

###原因
migrationファイル名と、migrationファイル内に記述したclass名が同じじゃなかったから。

##解決策

```ruby:184_add_columns_table_test.php
<?php

namespace Fuel\Migrations;

class add_columns_table_test
{
    public function up()
    {
      \DBUtil::add_fields('trn_order', array(
            'prefecture_id' => array(
                'constraint' => 10,
                'type' => 'int',
                'default' => 0,
                'notnull' => true,
                'after' => 'transfer_flag'
            ),
            'city_id' => array(
                'constraint' => 10,
                'type' => 'int',
                'default' => 0,
                'notnull' => true,
                'after' => 'prefecture_id_1'
            )
        ));
    }

    public function down()
    {
        \DBUtil::drop_fields('trn_order', array(
            'prefecture_id_1',
            'city_id_1',
            'prefecture_id_2',
            'city_id_2',
            'prefecture_id_3',
            'city_id_3',
        ));
    }
}
```

上記でmigrationを実行したらできました。
GolangのプロセスをFIFO priorityにセットする

センサーのデータを読み取って処理するプロセスをGolangで書いたとします。
たくさんあるプロセスの中で、そのプロセスはあまり後回しにはして欲しくないので、プライオリティをFIFOレベルにセットしたいとします。

Golangのgoroutineはどのスレッドで動作するのかはコントロールすることはできません。なので、goroutineの中からスレッドのプライオリティを設定するシステムコールを呼んでもどういう結果になるか不定です。

なので、最初に自分のプロセスの優先度を設定してから、Golangの実行ファイルをexecするツールを作成しました。

```run_fifoprio.c
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>

int run_fifoprio(int fifoprio, char** cmd)
{
	struct sched_param param;

	param.sched_priority = fifoprio;
	if (sched_setscheduler(0, SCHED_FIFO, &param) < 0) {
		perror("sched_setscheduler");
		return -1;
	}
	return execvp(cmd[0], cmd);
}


int main(int argc, char** argv)
{
	if (argc < 3) {
		printf("usage: %s fifo_prio command ... \n", argv[0]);
		return 0;
	}
	return (run_fifoprio(atoi(argv[1]), &argv[2]));
}
```

##使い方

fooというGolangの実行ファイルをFIFO priority 10 で実行する

```
$ run_fifo_prio 10 foo
```

##制限事項

一般ユーザーの権限ではFIFOプライオリティにセットすることはできないので、root権限で実行する必要があります。




#追加情報
root権限以外でGolangのプロセスを動かしたい場合は、run_fifoprio にCAP_SYS_NICEのケーバビリティを与えておけばうまくいきそうです。(ただしARM Linuxでは動作未確認。)

ケーパビリティの設定
```
sudo setcap cap_sys_nice=ep run_fifoprio
```
Golangの実行ファイルを複数まとめてトータルのファイルサイズを減らす工夫(busybox方式)

#Golangの実行ファイルはサイズが大きい
Golangはスタティックリンクされた実行ファイルを生成します。そのため実行ファイルのサイズは大きくなります。
ストレージの容量が十分あれば、これはとるに足らないことなのですが組み込みLinuxではストレージにNANDフラッシュメモリを使用していて容量が少ないこともあります。
残り容量が30MBしかないところに、3MBくらいの実行ファイルがぽんぽん増えていったりするとかなりつらい状況になります。

#まずはひとつのファイルサイズを減らす

go buildのときに不要なシンボルを削るオプションをつけます。

```
go build -ldflags '-s -w'
```

#実行ファイルを複数まとめてトータルのファイルサイズを減らす工夫

組み込みLinuxを使っている人なら通じると思うのですが、いわゆる「busybox方式」です。
Golangで書かれた複数のプログラムをひとつの実行ファイルにリンクしてしまいます。これによって重複して使用されているライブラリの分のサイズが削減できます。
元々の名前でシンボリックリンクを作成しておき、実行ファイルの大元で自分がどのコマンド名で起動されたかをみて、それに応じて分岐するようにします。

このためにソースコード作成時にルールを導入します。

- mainパッケージを使用しない。それぞれ独自パッケージを定義する。
- 実行開始のメソッドはMain()とする。

単体デバッグのときと結合して動かすときではmainパッケージの内容が入れ替わります。

#具体例

GOPATHのディレクトリを起点として以下のようなソースファイルとMakefileがあります。

```
$ find . -type f
./src/bar/bar.go
./src/bar/main/main.go
./src/bar/Makefile
./src/one_binary/main.go
./src/one_binary/Makefile
./src/foo/foo.go
./src/foo/main/main.go
./src/foo/Makefile
./src/baz/main/main.go
./src/baz/baz.go
./src/baz/Makefile
```

foo, bar, baz がそれぞれのプログラムで、one_binaryが結合するときのディレクトリです。
## それぞれのプログラムのソースツリー


```src/foo/foo.go
package foo

import "fmt"

func Main() {
	fmt.Printf("Hello, I am foo.\n")
}
```

```src/foo/main/main.go 
package main

import (
	"foo"
)

func main() {
	foo.Main()
}
```

```make:src/foo/Makefile 
TARGET = foo
GO_SRCS := $(shell find . -name "*.go")

all: $(TARGET)

$(TARGET): $(GO_SRCS)
	go build -ldflags '-s -w' -o $@ main/main.go

clean:
	rm -f $(TARGET)

```

makeして実行するとこうなります。

```
$ cd src/foo/
$ make
go build -ldflags '-s -w' -o foo main/main.go
$ ls -l foo
-rwxrwxr-x 1 koba koba 1032704 Jan 16 12:47 foo
$ ./foo
Hello, I am foo.
```

bar, bazも同様のプログラムです。
実行ファイルのサイズはひとつが約1MBあります。3つだと合計で約3MBになります。

## 結合用ディレクトリ

```src/one_binary/main.go 
package main

import (
	"log"
	"os"
	"path/filepath"

	"bar"
	"baz"
	"foo"
)

func main() {
	_, cmdname := filepath.Split(os.Args[0])
	switch cmdname {
	case "foo":
		foo.Main()
	case "bar":
		bar.Main()
	case "baz":
		baz.Main()
	default:
		log.Printf("cmdname=%s is not found.\n", cmdname)
	}
}
```

mainパッケージのmain()の中で、自分が起動されたときのコマンド名をみて、それに対応するパッケージのMain()を呼び出します。

```make:src/one_binary/Makefile
TARGET = gobin

all: $(TARGET)

$(TARGET): force
	go build -ldflags '-s -w' -o $@
	ln -s $@ foo
	ln -s $@ bar
	ln -s $@ baz

clean:
	rm -f $(TARGET)
	rm -f foo bar baz

force:

```

```
$ cd src/one_binary/
$ make
go build -ldflags '-s -w' -o gobin
ln -s gobin foo
ln -s gobin bar
ln -s gobin baz
$ ls -l
total 1184
lrwxrwxrwx 1 koba koba       5 Jan 16 12:52 bar -> gobin
lrwxrwxrwx 1 koba koba       5 Jan 16 12:52 baz -> gobin
lrwxrwxrwx 1 koba koba       5 Jan 16 12:52 foo -> gobin
-rwxrwxr-x 1 koba koba 1201280 Jan 16 12:52 gobin
-rw-rw-r-- 1 koba koba     297 Jan 16 12:18 main.go
-rw-rw-r-- 1 koba koba     177 Jan 16 12:24 Makefile
$ ./foo
Hello, I am foo.
$ ./bar
Hello, I am bar.
$ ./baz
Hello, I am baz.
```

gobinはfoo, bar, bazがひとつに結合された実行ファイルです。サイズは約1.2MB。
3つを別々にビルドした場合の合計のファイルサイズは約3MBなので、それに比べて大幅にストレージ容量を節約できました。これは小さなサンプルプログラムなのでサイズが小さいですが、実際に使用するプログラムではその差はもっと顕著なものになります。
mainパッケージを使用しないなどのルールが面倒ですが、その面倒に見合うくらいの効果はあると思います。理論的にはカーネルのメモリの使用量の削減、プロセスの起動高速化にもわずかながらでもよいほうに働くはずです。
GolangでGPIOの割り込み通知を受け取る

#ユーザープロセスでGPIOの割り込みの通知を受け取る方法

[GPIO Sysfs Interface for Userspace](https://www.kernel.org/doc/Documentation/gpio/sysfs.txt)
このドキュメントのように、gpioが/sys/class/gpioでアクセス可能なようになっていれば、pollシステムコールでGPIOの割り込み通知を受け取ることができます。
これをGolangでやるには以下のようにします。

#GolangでGPIOの割り込みの通知を受け取るサンプル

GPIO28が1から0に変化したときに標準出力にメッセージを表示します。

```gpio_sample.go
package main

// Use CGO for struct pollfd

// #include <poll.h>
import "C"
import (
	"io/ioutil"
	"log"
	"os"
	"syscall"
	"unsafe"
)

func main() {
	setup()
	loop()
}

func loop() (err error) {
	var pfd C.struct_pollfd

	f, err := os.Open("/sys/class/gpio/gpio28/value")
	if err != nil {
		return err
	}
	defer f.Close()

	c := make([]byte, 3)
	f.Read(c)
	log.Printf("first val=%c\n", c[0])

	pfd.fd = C.int(f.Fd())
	pfd.events = C.POLLPRI
	timeout := 3000
	for {
		f.Seek(0, os.SEEK_SET)
		r1, _, errno := syscall.Syscall(
			syscall.SYS_POLL,
			uintptr(unsafe.Pointer(&pfd)),
			uintptr(1),
			uintptr(timeout))
		if errno != 0 {
			return errno
		}
		if r1 == 0 {
			log.Printf("Timeout\n")
		} else {
			f.Read(c)
			log.Printf("val=%c\n", c[0])
		}
	}
	return
}

func setup() {
	ioutil.WriteFile("/sys/class/gpio/export", []byte("28"), 0644)
	ioutil.WriteFile("/sys/class/gpio/gpio28/direction", []byte("in"), 0644)
	//ioutil.WriteFile("/sys/class/gpio/gpio28/edge", []byte("both"), 0644)
	//ioutil.WriteFile("/sys/class/gpio/gpio28/edge", []byte("rising"), 0644)
	ioutil.WriteFile("/sys/class/gpio/gpio28/edge", []byte("falling"), 0644)
}
```

システムコール pollを呼ぶために、カーネルのヘッダ内に定義されているstruct pollfdを使用します。そのためにcgoを使用しました。そのため、これをビルドするときには以下のようにCGO_ENABLED=1 とCCでクロスコンパイラを指定します。

```
 CGO_ENABLED=1 CC=arm-buildroot-linux-gnueabi-gcc  GOARCH=arm GOARM=7 go build
```
Golangでioctlのシステムコールを使う

組み込みLinuxでGolangを使っていると、ioctlのシステムコールを使用したい場面が出てきます。ioctlは汎用的で使用する場面によって異なるストラクチャを使用します。
Golangでカーネルの定義するストラクチャに値をセットする場合、以下の2つの方法があります。

1. cgoを使ってカーネルのヘッダをインクルードする。
2. Golangでメモリレイアウトが等価になるようなstructを定義して使用する。

今回は2の方法を試してみました。

# i2cのioctlで使用されていたstruct

```c
/* This is the structure as used in the I2C_RDWR ioctl call */
struct i2c_rdwr_ioctl_data {
	struct i2c_msg __user *msgs;	/* pointers to i2c_msgs */
	__u32 nmsgs;			/* number of i2c_msgs */
};
```

```c
struct i2c_msg {
	__u16 addr;	/* slave address			*/
	__u16 flags;
#define I2C_M_TEN		0x0010	/* this is a ten bit chip address */
#define I2C_M_RD		0x0001	/* read data, from slave to master */
#define I2C_M_STOP		0x8000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART		0x4000	/* if I2C_FUNC_NOSTART */
#define I2C_M_REV_DIR_ADDR	0x2000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK	0x1000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK		0x0800	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN		0x0400	/* length will be first received byte */
#define I2C_M_16BIT_REG		0x0002	/* indicate reg bit-width is 16bit */
#define I2C_M_16BIT_DATA	0x0008	/* indicate data bit-width is 16bit */
	__u16 len;		/* msg length				*/
	__u8 *buf;		/* pointer to msg data			*/
};
```

この2つのstructとメモリレイアウトが等価になるようなGoのstructを定義して使用しました。

#Golangのサンプルプログラム

```go
const (
	_I2C_RDWR                = 0x0707
	_I2C_RDRW_IOCTL_MAX_MSGS = 42
	_I2C_M_RD                = 0x0001
)

type i2c_msg struct {
	addr      uint16
	flags     uint16
	len       uint16
	__padding uint16
	buf       uintptr
}

type i2c_rdwr_ioctl_data struct {
	msgs  uintptr
	nmsgs uint32
}

func transfer(f *os.File, msgs *i2c_msg, n int) (err error) {
	data := i2c_rdwr_ioctl_data{
		msgs:  uintptr(unsafe.Pointer(msgs)),
		nmsgs: uint32(n),
	}
	err = nil
	_, _, errno := syscall.Syscall(
		syscall.SYS_IOCTL,
		uintptr(f.Fd()),
		uintptr(_I2C_RDWR),
		uintptr(unsafe.Pointer(&data)),
	)
	if (errno != 0) {
		err = errno
	}
	return
}

```

これの全ソースコードはgistに貼りました。[ここ](https://gist.github.com/tetsu-koba/33b339d26ac9c730fb09773acf39eac5)

#余談
今回使用したSoCのi2cドライバが特殊なようで、一般のi2c用のダンプコマンド等が使用で来ませんでした。よって世の中にあるいくつかのgolangのi2c用ライブラリも使えませんでした。
SoCのSDKに付属するi2cツールで使っているシステムコールをstraceで観察し、それと同様の動きをするものをgolangで書きました。
Golangから物理メモリを読み書きする

Golangではシステムコールのmmapを使用することができるので、/dev/mem かUIOで作成した/dev/uioX をmmapすれば物理メモリを読み書きすることができます。
ここではUIOを使った例を紹介します。

#UIOのデバイスを登録する

UIOについてはこの記事を参照してください。
[LinuxのUIO(User space I/O) その1](https://qiita.com/tetsu_koba/items/5cb1f3b61d0b2b6f4e2b)
この記事に従って、/dev/uio0 が作成できたとして、次にそれをGolangで書かれたプログラムからアクセスする方法を示します。

#Golangのサンプルプログラム

ソースコードはgistに置きました。[ここ](https://gist.github.com/tetsu-koba/91e7f621c89392ca4d763413433c2b9c)

```go
func mmapRegs32(addr uint32, n int) []uint32 {
	file := "/dev/uio0"

	f, err := os.Open(file)
	if err != nil {
		log.Fatal(err)
	}

	offset := int64(addr) &^ 0xfff
	data, err := syscall.Mmap(int(f.Fd()), offset, (n+0xfff)&^0xfff, syscall.PROT_READ, syscall.MAP_SHARED)
	if err != nil {
		log.Fatalf("mmap %s: %v", f.Name(), err)
	}
	f.Close()

	map_array := (*[math.MaxInt32 / 4]uint32)(unsafe.Pointer(&data[0]))
	return map_array[(addr&0xfff)/4 : ((int(addr)&0xfff)+n)/4]
}
```

Cのプログラムと同様のパラメータでSyscall.Mmap()を使用します。このメソッドは戻り値が[]byte です。
バイト単位でアクセスしたい場合はこれをこのまま使用すればよいです。
今回は4バイト単位でアクセスしたいので、[]uintの型で欲しいところです。
そのためには、一度大きなサイズのuint32の配列のポインタに変換してから、それをベースにする[]int のスライスを作成すればよいです。
.DS_Storeがgit上に残ってしまった時の対処法

gitignore_globalに.DS_Storeを入れてあげれば大丈夫でした。


＜手順＞
ルートディレクトリに戻って

```
vi ~/.gitignore_global
```
vimエディタが立ち上がるので

iキーを押してINSERTモードに。
その中に

```
.DS_Store
```

と記述してescキーを押して
:wqで保存をしてエディタから抜けます。

gitignoreの設定ができてない場合はgit statusとかしてもDS_Storeが残ったままになるので、その場合は下記のコマンドを打てば問題なく解決するかと思います。

```
git config --global core.excludesfile ~/.gitignore_global
```
phpでパスが通らなくなるという事例（php5.6とphp7の違い？php.iniの違い？）

getimagesize()の引数に持ってくるパスが
/wp-content/uploads/2017/12/example-400x300.jpgのように
最初に/が入っていると通らなくなった。

#エラーが出た環境は以下
exampleサーバ
Php 7.0.18

#対応方法
以下のように変更したら解消した。

// 画像のサイズを取得
`list($width, $height, $type, $attr) = getimagesize($srcval[1]);`
↓
//最初のスラッシュをとる
`$img_path = ltrim($srcval[1], '/');`
// 画像のサイズを取得
`list($width, $height, $type, $attr) = getimagesize($img_path);`


#exampleサーバ2では以下でもOKだった
/wp-content/uploads/2017/12/example400x300.jpg
Php5.6.32 CGIモード

#原因の予想
・phpのバージョン違いによる関数の挙動変更が原因の可能性。
　http://php.net/manual/ja/function.getimagesize.php
　http://php.net/manual/ja/migration70.php
　上記ざっと確認するもそれらしき記述を見つけられませんでした。

・php.iniによるパス解釈の違いがあるとのことでサーバの設定による違いが原因という可能性。
　https://qiita.com/Mizumon/items/6097cbf7082d05f9a550

以下調査結果
exampleサーバ
include_path	.:/opt/php-7.0.18/data/pear	.:/opt/php-7.0.18/data/pear

example2サーバ                 Local Value                 Master Value
include_path	.:/usr/local/php/5.6/lib/php	.:/usr/local/php/5.6/lib/php
bash + GNU coreutils (date) > 「27日範囲の日付区間」を「開始日が13日おき」に表示する | `--max-args`と`--replace=`の練習もかねて

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.9を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
```

### 処理概要

- 27日範囲の日付区間を表示する
    - 例: 2017/11/04から2017/12/01
- 上記を開始日が13日おきに表示する
    - 例: 2017/11/04から...
    - 例: 2017/11/17から...
    - ...

### 参考

[昨日〜9日前までの日付を空白区切りで返すサンプル](https://qiita.com/tukiyo3/items/97ec3dc0920e5c6a0470)
の @nakataSyunsuke さんと@tukiyo3 さんのコメントを参考にしました。

(`--max-args`と`--replace=`の練習もかねて)

### code v0.1

```bash:show_range_180117_exec
#!/usr/bin/env bash

set -eu  # for safety

STARTS=$(seq 0 13 50 | xargs --max-args=1 | xargs --replace=@ -- date -d "2017/11/4 @days" +"%Y/%m/%d")
ENDS=$(echo $STARTS | xargs --max-args=1 | xargs --replace=@ -- date -d "@ 27days" +"%Y/%m/%d")

echo "--START--"
echo $STARTS | xargs --max-args=1
echo "--END--"
echo $ENDS | xargs --max-args=1
```

```bash:run
$ bash show_range_180117_exec 
--START--
2017/11/04
2017/11/17
2017/11/30
2017/12/13
--END--
2017/12/01
2017/12/14
2017/12/27
2018/01/09
```

### 備考

- もっと短い書き方は未勉強
- STARTとENDを横に並べるエレガントな書き方は知らない

### code v0.2

https://ideone.com/ougqIT

```bash:show_range_180117_exec
#!/usr/bin/env bash

set -eu  # for safety

STARTS=$(seq 0 13 50 | xargs --max-args=1 | xargs --replace=@ -- date -d "2017/11/4 @days" +"%Y/%m/%d")
ENDS=$(echo $STARTS | xargs --max-args=1 | xargs --replace=@ -- date -d "@ 27days" +"%Y/%m/%d")

#echo "--START--"
#echo $STARTS | xargs --max-args=1
#echo "--END--"
#echo $ENDS | xargs --max-args=1

echo $STARTS ": START"
echo $ENDS ": END"
```

```bash:run
$ bash show_range_180117_exec 
2017/11/04 2017/11/17 2017/11/30 2017/12/13 : START
2017/12/01 2017/12/14 2017/12/27 2018/01/09 : END
```

横にSTART,ENDを並べるのをやめて、縦にしました。
CloudFormationでRecordSetを作成する時、FATAL problem: DomainLabelEmptyと出会い

CloudFormationでroute53を作っている時```FATAL problem: DomainLabelEmpty encountered```に出会いました

```yaml
ELBRecord:¬
  Type: 'AWS::Route53::RecordSet'
  Properties:
    Type: A
    AliasTarget:
      DNSName: !GetAtt␣AppELB.DNSName¬
      HostedZoneId: !GetAtt AppELB.CanonicalHostedZoneID
    Comment: 'A test Record' 
    HostedZoneName: !Ref HostedZoneName¬
    Name: !Sub 'test.001.${HostedZoneName}.'
```

#原因
parameterで定義されたHostedZoneNameが以下のようになります

```yaml
HostedZoneName:
  Type: String
  Default: 'mydomain.co.jp.'
```
これでELBRecordのNameプロパティの中身が```test.001.mydomain.co.jp..```隣、ルーツレベルの```.```が二つになってしましました。```Name: !Sub 'test.001.${HostedZoneName}'```に直せば問題解決できました。
# まとめ
```FATAL problem: DomainLabelEmpty encountered```が出たらどこかに```..```入っているということです。
解けないとヤバい！？プログラム練習問題

## はじめに

* 新人エンジニア向けにプログラムの理解度を図るための練習問題を作ったので公開
* 別に解けなくてもヤバくない、これを機に知っていけば良い
* 言語はとりあえず`PHP`で書いてます

## 問1

以下のコードの出力を答えよ

```php
function increment($a, $b, $c) {
    echo $a . "\n";
    echo $b . "\n";
    echo $c . "\n";
}

$a = 0;
increment($a, $a++, ++$a);
```

## 問1の答え

```bash
0
0
2
```

これはインクリメントの評価順の問題です
後置インクリメント（`$a++`）は式を評価した後に加算する
よって`$a`が加算される前に0で引数を渡し、その後に加算され1となる
前置インクリメント（`++$a`）は式を評価する前に加算する
よって前のインクリメントで加算され1になっているところに更に加算し2にし、それを引数に渡す
よって答えは0,0,2となる
ポイントとしては左側から順に評価されるということです
`$a`を渡す、`$a`を渡してからインクリメント、インクリメントしてから`$a`を渡す、という具合に左から読むと理解しやすいかと思います

## 問2

以下のコードの出力を答えよ

```php
function return_true(){
    echo "return_true関数が実行されました\n";
    return true;
}
function return_false(){
    echo "return_false関数が実行されました\n";
    return false;
}

if(return_true() || return_false()){
    echo "評価式はtrueでした\n";
} else {
    echo "評価式はfalseでした\n";
}
```

## 問2の答え

```bash
return_true関数が実行されました
評価式はtrueでした
```

```php
return_true() || return_false()
```

これの評価順が問題で、
AまたはBの時Aがtrue判定だと、Bはtrueでもfalseでも式全体はtrueになるためBは評価すらされません（`return_false`の関数にすら入らない）
ポイントとしては評価式の確定ポイント以降は実行されないということです
これを知っておかないと例えばこの例の場合`reeturn_false`内で他の処理を行っている場合に実行されず「なぜ？？？」となってしまいます。

## 問2類似

以下のコードの出力を答えよ

```php
function return_true(){
    echo "return_true関数が実行されました\n";
    return true;
}
function return_false(){
    echo "return_false関数が実行されました\n";
    return false;
}

if(return_false() && return_true()){
    echo "評価式はtrueでした\n";
} else {
    echo "評価式はfalseでした\n";
}
```

## 問2類似の答え

```bash
return_false関数が実行されました
評価式はfalseでした
```

さっきとは逆でAかつBの条件式です。
これも先程の例と同様でAかつBでAがfalseの場合、Bはtrueでもfalseでも式全体はfalseになるためBは評価されません。
問2が理解できていれば解けましたよね？

## 問3

以下のコードの出力を答えよ

```php
$test1 = '';
if(!!$test1){
    echo "test1: 評価式はtrueでした\n";
} else {
    echo "test1: 評価式はfalseでした\n";
}

$test2 = 'test';
if(!!$test2){
    echo "test2: 評価式はtrueでした\n";
} else {
    echo "test2: 評価式はfalseでした\n";
}
```

## 問3の答え


```bash
test1: 評価式はfalseでした
test2: 評価式はtrueでした
```

これは`!!`がどういう意味を持つのかを知っていれば簡単ですね。
`!`はNOTの意味を持ち、論理値を否定する効果があります。
例えば`!true`と書くと評価式は`false`になります。
では`!!true`はどうでしょうか？これは否定の否定になるので`true`になります。
一見意味がないように見えますが、上の問題のように文字列や変数が存在するかどうかを手っ取り早く論理値に変換する時に重宝します。
覚えておきたいテクニックのひとつなんですがググろうとすると`!!`って検索できないので案外知らない人が多い印象ですね。

## おわりに

あくまで新人エンジニア向けなので大体の人は解けると思います。
悪い意味でヤバいエンジニアにならないように日々勉強していきましょう！
QiitaでMarkdownのテーブル内にチェックボックスを作成する

Markdownのテーブル内にチェックボックスを作成するため、チェックボックス`- [ ]`を書いてみたがうまくいかない。


# はじめに
以下の表のような、オペレーション手順を表にして、作業が終わったら一つずつチェックをつけていくような表を作りかかった。

| チェック | TODO |
|:-:|:-:|
| ここにチェックボックス  | TODO  |

# 対象読者 

* [はじめに]($はじめに)書いたような表の作りたい人
* 作り方を知ってる人(教えてください。)

## 問題

表内にチェックボックスを作成すると、変換されずにMarkdown記法`- [ ]`がそのまま出力されてしまう。

| チェック | TODO |
|:-:|:-:|
| - [ ]  | TODO  |

```
| チェック | TODO |
|:-:|:-:|
| - [ ]  | TODO  |

```

## 原因

わからない！！
なぜ、表内にチェックボックスは正しく変換されないんだろう。
この辺りは、markdownの仕組みを理解していないとわからないんだろうか。。。

**ご存知のかた居ましたら教えて下さい。**

# 代替案

1. [表内にHTMLでチェックボックスを作成する。]($表内にHTMLでチェックボックスを作成する。)

## 表内にHTMLでチェックボックスを作成する。

[HTML5 チェックボックス作成について](チェックボックス)

>type="checkbox"の場合に指定可能な属性
>type="checkbox"
>チェックボックスを作成する
>使用例
>`<input type="checkbox" name="riyu" value="2">役に立つ`


* チェックボックス作成
`<input type="checkbox">テスト`

* 出力結果
<input type="checkbox">テスト

* 結果
チェックボックスが表示されず`テスト`という文字のみ出力されていまいました。

* 原因
[Qiitaで無効になったHTMLタグ][Qiitaで無効になったHTMLタグ]
> Qiita Blog(公式)：QiitaにおいてHTML要素の属性指定ができなくなりました(17/6/20)

HTMLでチェックボックスが表示されなかったのは、どうやらこの対応のようですね。

# 参考

参考にしたWebサイトや技術書などを列挙する

- [`<input type="checkbox">` …… チェックボックスを作成する][チェックボックス]
[チェックボックス]:http://www.htmq.com/html5/input_type_checkbox.shtml
- [Qiitaで使えるHTMLタグは？](https://qiita.com/APO/items/f2212bee7f0b2c69228f)
[Qiitaで無効になったHTMLタグ]:https://qiita.com/APO/items/f2212bee7f0b2c69228f#%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9input-typecheckbox

# あとがき

結果的に解決できなかったので、新しい方法を模索中
都道府県番号の配列。番号と県名逆バージョン。コピペ用。


県名が返り値で、県名を使って都道府県セレクトボックスを操作したい時

都道府県番号の配列をWebで検索かけても

`1:"北海道"`

というタイプの配列コピペしかなく、
値で検索かけて、そのプロパティ名を取得する記述を書くのもコードが長くなってめんどくさかった為

```js
var pref = {北海道:'1', 青森県:'2', 岩手県:'3', 宮城県:'4', 秋田県:'5',山形県:'6', 福島県:'7', 茨城県:'8', 栃木県:'9', 群馬県:'10',埼玉県:'11', 千葉県:'12', 東京都:'13', 神奈川県:'14', 新潟県:'15',富山県:'16', 石川県:'17', 福井県:'18', 山梨県:'19', 長野県:'20',岐阜県:'21', 静岡県:'22', 愛知県:'23', 三重県:'24', 滋賀県:'25',京都府:'26', 大阪府:'27', 兵庫県:'28', 奈良県:'29', 和歌山県:'30',鳥取県:'31', 島根県:'32', 岡山県:'33', 広島県:'34', 山口県:'35',徳島県:'36', 香川県:'37', 愛媛県:'38', 高知県:'39', 福岡県:'40',佐賀県:'41', 長崎県:'42', 熊本県:'43', 大分県:'44', 宮崎県:'45',鹿児島県:'46', 沖縄県:'47'};
```

根性で逆にしました。
今思えばプロパティと値を逆にするサイトなんか探せばあるような。

JSON形式で書いてますが、ちょっと置換すればPHPでも使用できますね。


* * *

追記
今よく考えたら手で逆にしないスマートな方法ないか？
【IEでも動く】とにかくtd内の要素を折り返す

#とにかく折り返す！

bootstrapと併用した際にテーブルのtd要素から子要素が飛び出しまくったのでとりあえずここら辺使って置けば大丈夫そうってCSSを簡単に書き殴っておく（IEでも動く）

＊Bootstrapを使用していると、white-spaceがデフォルトでnowrapに設定されていてハマった

```css:css
table#table_id {
    tabel-layout: fixed;
}

td {
    word-break: break-all !important;
}

p{
    word-wrap: break-word !important;
    white-space: normal !important;
}
```

## 参考記事：
テーブル内で長い文字列を決まった長さで改行させる方法
https://qiita.com/n_s_y_m/items/cb29d730e63772b02475

CSS 半角英数の連続文字が折り返すようにする
http://accelboon.com/tn/?p=992
Rails5 でルーティングをMarkdownで書き出す

ドキュメントとしてルーティング定義をマークダウンで書き出したかったので、実装してみました。

## 動作環境
- Rails5

## 方針
- ``rake routes``の実装をパクる
https://github.com/rails/rails/blob/5ccdd0bb6d1262a670645ddf3a9e334be4545dac/railties/lib/rails/tasks/routes.rake

- 独自の``Formatter``を作れば良さそう(ダックタイピング)
https://github.com/rails/rails/blob/63f0c04850dd0bcdc7d35266e81fa1a7778570a8/actionpack/lib/action_dispatch/routing/inspector.rb#L129-L185

## 実装
```lib/tasks/routes.rake
namespace :routes do
  desc "Exports routing to docs/routing.md"
  task export: :environment do
    all_routes = Rails.application.routes.routes
    require 'action_dispatch/routing/inspector'
    inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
    md = inspector.format(MarkdownFormatter.new, ENV['CONTROLLER'])

    File.open('docs/routing.md', 'w') do |f|
      f.puts "\# #{Rails.application.class.parent_name.camelize} all routing\n\n" << md
    end
  end

  private

  class MarkdownFormatter
    def initialize
      @buffer = []
      @current_section = "Application"
    end

    def result
      @buffer.join("\n")
    end

    def section_title(title)
      @current_section = title
    end

    def section(routes)
      routes.each do |r|
        @buffer << "#{r[:name]}|#{r[:verb]}|#{r[:path]}|#{r[:reqs]}"
      end
    end

    def header(routes)
      @buffer << "Prefix|Verb|URI Pattern|Controller#Action\n---|---|---|---"
    end

    def no_routes
      @buffer << ""
    end
  end
end
```

## 実行
```
$ rake routes:export
```
もしくは

```
$ rails routes:export
```

## 結果
```docs/routing.md
# SampleApp all routing

Prefix|Verb|URI Pattern|Controller#Action
---|---|---|---
new_user_session|GET|/users/sign_in(.:format)|devise/sessions#new
user_session|POST|/users/sign_in(.:format)|devise/sessions#create
destroy_user_session|DELETE|/users/sign_out(.:format)|devise/sessions#destroy
new_user_password|GET|/users/password/new(.:format)|devise/passwords#new
edit_user_password|GET|/users/password/edit(.:format)|devise/passwords#edit
user_password|PATCH|/users/password(.:format)|devise/passwords#update
|PUT|/users/password(.:format)|devise/passwords#update
|POST|/users/password(.:format)|devise/passwords#create
cancel_user_registration|GET|/users/cancel(.:format)|devise/registrations#cancel
new_user_registration|GET|/users/sign_up(.:format)|devise/registrations#new
edit_user_registration|GET|/users/edit(.:format)|devise/registrations#edit
user_registration|PATCH|/users(.:format)|devise/registrations#update
|PUT|/users(.:format)|devise/registrations#update
|DELETE|/users(.:format)|devise/registrations#destroy
|POST|/users(.:format)|devise/registrations#create
new_user_confirmation|GET|/users/confirmation/new(.:format)|devise/confirmations#new
user_confirmation|GET|/users/confirmation(.:format)|devise/confirmations#show
|POST|/users/confirmation(.:format)|devise/confirmations#create
```

## 参考
https://qiita.com/ayasuda/items/a2b0c818e8b5efeb44cf
Upverter > license > Free一択になっていた

回路図のデザインに使っているUpverterのpricingページを確認した。

https://upverter.com/pricing/

「Free Forever」しかない。

1年ほど前によく使っていた時は別途4000円近くの有料ライセンスがあったはずだが、ライセンス形態が変わったのだろうか?

Upverterは別会社([Altium](http://www.altium.com/))に2017年8月に買収され、その相乗効果を期待しているとUpverterからのメールか何かで読んだが、その効果が出たということだろうか。

https://www.pehub.com/canada/2017/08/3469368/ (**注意: Subscribe確認画面が表示されます**)
> Upverter of Toronto acquired by Altium

買収については、こちらを見たことを覚えていたのだろう。
https://blog.upverter.com/2017/08/28/upverter-joins-altium/

一つのサービスに月4000円を個人で払い続けるのは無理があり、無料で使わせていただいていた。いくつかのサービスに登録すると簡単に月額数万円単位の支払いになってしまう。
500円から1000円あたりの月額サービスを複数個組みあわせて使う、というのが現在の自分の個人使用形態になっている。


https://blog.upverter.com/


### ライセンスに関して質問してみた

https://forum.upverter.com/t/current-license-type-of-the-upverter/38932

回答で以下のリンクを教えていただいた。
https://blog.upverter.com/2017/08/28/upverter-joins-altium/
に
「Introducing the future of electronic product design. And it’s free.」
という記載があり無料ライセンス一本の形態に変わっていたようだ。
（太字での記載だが、意識がそちらに行ってなかった）
【AWS＋Nginx1.10】エラーログはログフォーマットを指定することができない

# 環境
- AWS
- nginx version: nginx/1.10.3 (Ubuntu)
- Rails5.1
- Unicorn
 
# やりたいこと
- Nginxのログフォーマットを変更したい
    - AWSのALBのアクセス元IPを表示したい
    - アクセス元プロトコルを表示したい
    - ついでにエラーログもフォーマットを変更したい

# 設定例
`/etc/nginx/nginx.conf`

access_logおよび、error_logに独自フォーマットの`main`を指定。

```js
        ##
        # Logging Settings
        ##

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" $request_time $upstream_response_time '
                        '"$http_x_forwarded_for" "$http_x_forwarded_proto" $host';

        access_log /var/log/nginx/access.log main;
        error_log /var/log/nginx/error.log main;
```

# 発生した問題
- Nginxが起動しない

## 原因
Nginxのエラーログに、独自フォーマットの`main`を指定指定しているため。
構文チェックを行うと以下のエラーが表示される。

```
$ nginx -t -c /etc/nginx/nginx.conf
2018/01/16 15:34:00 [emerg] 29059#29059: invalid log level "main" in /etc/nginx/nginx.conf:53
nginx: configuration file /etc/nginx/nginx.conf test failed
```
## 正しい設定
error.logにはフォーマットは指定できません。

```js
        ##
        # Logging Settings
        ##

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" $request_time $upstream_response_time '
                        '"$http_x_forwarded_for" "$http_x_forwarded_proto" $host';

        access_log /var/log/nginx/access.log main;
        error_log /var/log/nginx/error.log;
```
tmux > ペイン間の移動 > C-b 下矢印 | C-b 上矢印 | C-b 右矢印 | C-b 左矢印

```txt:動作環境
CentOS 6.8
tmux 1.6-3.el6
```

tmuxにおいてターミナルを上下２つのペインに分割して使うことが多い。

ペイン間の移動は`C-b o`であるが、tmuxをたまにしか使わないとoのキーを忘れる。

別途、キー入力ミスで以下でもペイン間の移動をできることに気付いた。

- C-b 下矢印: 別のペインに移動
- C-b 上矢印: 別のペインに移動

### 憶えること

上下２つのペインの場合、下記のような操作として覚えておくと、忘れくいだろう。

- C-b 上矢印: 上のペインに移動
- C-b 下矢印: 下のペインに移動

### 左右分割

上下２つ、左右２つの４分割にしてみた。
参考: [tmuxチートシート](https://qiita.com/nmrmsys/items/03f97f5eabec18a3a18b) 
> `%            左右にペイン分割`

- C-b 上矢印: 上のペインに移動
- C-b 下矢印: 下のペインに移動
- C-b 右矢印: 右のペインに移動
- C-b 左矢印: 左のペインに移動

一方で、c-b oの場合は「Ｚ型」にペイン間を移動する。
Sequelizeのモデル定義をclass構文で書く方法

Sequelizeのクラス定義を`define`メソッドで書いていたのですが、バージョン4からclass定義の構文で書けるというウワサを聞いて試してみようと思いました。
しかしいくら調べてもちゃんとした書き方が見つからず苦労したのでまとめておきます。

#結論
こんな感じです

```js:models/user.js
class User extends Sequelize.Model {

  // クラスメソッド
  static findByEmail(email) {
    return this.findOne({ where: { email: email }})
  }

  // インスタンスメソッド
  verifyPassword(password) {
    return bcrypt.compare(password, this.password_hash)
  }
}

User.init(
  // フィールド
  {
    id: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      autoIncrement: true,
      allowNull: false
    },
    name: {
      type: Sequelize.STRING,
      allowNull: false
    },
    password_hash: {
      type: Sequelize.STRING,
      allowNull: false
    },
    email: {
      type: Sequelize.STRING,
      allowNull: false
    }
  }, {
　　　　　　　　// オプション
    freezeTableName: true,
    underscored: true,
    timestamps: true,
    sequelize
  }
)
```

# クラスメソッド
クラスメソッドは`static`をつけたメソッドとして書くことができます。
staticメソッドの中で`this`は`User`クラスを指します。

```js:従来の書き方
// クラスメソッド
User.findByEmail = function(email) {
  return this.findOne({ where: { email: email }})
}
```

```js:classを使った書き方
class User extends Sequelize.Model {

  static findByEmail(email) {
    return this.findOne({ where: { email: email }})
  }

}
```

# インスタンスメソッド
インスタンスメソッドは、モデルのプロトタイプに関数を登録していたのが、普通のメソッド定義になりました。
`this`は`User`クラスのインスタンスを指します。

```js:従来の書き方
// インスタンスメソッド
User.prototype.verifyPassword = function(password) {
  return bcrypt.compare(password, this.password_hash)
}
```

```js:classを使った書き方
class User extends Sequelize.Model {

  // インスタンスメソッド
  verifyPassword(password) {
   return bcrypt.compare(password, this.password_hash)
  }

}
```

クラスメソッドもそうなのですが、従来の書き方でアロー演算子を使った書き方をしていたら、`this`がグローバルオブジェクトになっていて困りました。`function`を使って書かないと`this`はインスタンスを指してくれないみたいです。
「`function`キーワードはもう使うな」って偉い人が言ってましたが、何も考えずにアロー演算子でインスタンスメソッドを書いてしまうと`this`がインスタンスを指してくれないので、オブジェクト指向なものを書く時はclass構文を使っていった方がよさそうです。

# フィールド定義とオプション
```js:従来の書き方
sequelize.define('テーブル名', {フィールド定義}, {オプション})
```

```js:classを使った書き方
User.init({フィールド定義}, {オプション})
```

[Sequelizeバージョン4の新機能](http://docs.sequelizejs.com/manual/tutorial/upgrade-to-v4.html#new-features) っていうところに書いてましたが、この書き方を見つけることができなくて、長いこと苦しんでいました。
オプションには`sequelize`というキーでSequelizeのインスタンスを指定しないとエラーになります。これはよくわかんなかったですが、エラーになるので指定しましょう。

```js
{
　　 // オプション
  freezeTableName: true,
  underscored: true,
  timestamps: true,
  sequelize
}
```

# 実際に書き直した例
実際にモデルの定義をclass構文で書き直したときのコミットを貼っておきます。
https://github.com/mktoho12/myapp/commit/09f4c44a53c1d4f5453a122d6fcfa08c649b277f

# 現時点での各バージョン
- node 9.4.0
- sequelize 4.31.1
rails の request.xhr?メソッドと axios でのajax通信

これまで ajax通信には jQery 使ってたけど、[axios](https://github.com/axios/axios) にでajax通信するようになって少しハマったのでメモ

### request.xhr? とは？
リクエストが `XMLHttpRequest(いわゆるajax通信)`かどうか判定するメソッド。
リクエストがajaxかどうかで処理を分岐させる時によく使う。

### ハマったこと
今回 axios でajax通信を行なった時に `request.xhr?` が `false` を返してきた。

### 原因
`request.xhr?` の[コード](https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L263-L269)は以下のように定義されている

```rb
def xml_http_request?
  get_header("HTTP_X_REQUESTED_WITH") =~ /XMLHttpRequest/i
end
alias :xhr? :xml_http_request?
```

やってることはすごく単純で `HTTP_X_REQUESTED_WITHヘッダー`に`XMLHttpRequest` が含まれているかどうかを見てるだけ。

対して 

```js
axios.get('/hogehoge')
``` 
のようにajax通信を行なっても`HTTP_X_REQUESTED_WITHヘッダー`はつかない。
よって`request.xhr?` が必ず false を返す。

### どうすれば良いか
単純に`HTTP_X_REQUESTED_WITHヘッダー` を明示的に指定すれば良い。
こんな感じ

```js
axios.get('/hogehoge', headers: {'X-Requested-With': 'XMLHttpRequest'})
```
C++ Builder 10.2 Tokyo > Error: 未解決の外部シンボル 'System::Win::Comobj::CoInitFlags' が...参照されています > 対処

```txt:動作環境
RAD Studio 10.2 Tokyo Update 2
```

プロジェクトをビルド時に以下を含むエラーが出る。

> [ilink32 エラー] Error: 未解決の外部シンボル 'System::Win::Comobj::CoInitFlags' が C:\PROGRAM FILES (X86)\EMBARCADERO\STUDIO\19.0\LIB\WIN32\DEBUG\RTLE.LIB|syssupp から参照されています

### エラーの発生手順

1. ファイル > 新規作成 > その他 を選択
2. C++ Builderプロジェクト > コンソールアプリケーション を選択
3. 「新規コンソールアプリケーション」ダイアログにて「ターゲットフレームワーク」は「なし」を選択
    - >> 以下のひな型ができる。

```File1.cpp
#pragma hdrstop
#pragma argsused

#ifdef _WIN32
#include <tchar.h>
#else
  typedef char _TCHAR;
  #define _tmain main
#endif

#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}
```

以下のように書き換える。

```File1.cpp
#include <vcl.h>
#include <windows.h>

#pragma hdrstop
#pragma argsused

#ifdef _WIN32
#include <tchar.h>
#else
  typedef char _TCHAR;
  #define _tmain main
#endif

int _tmain(int argc, _TCHAR* argv[])
{
	String lpath = L"TEST";
	return 0;
}
```

- ファイルをビルド: 成功
- プロジェクトをビルド: 下記のエラーが出る

> [ilink32 エラー] Error: 未解決の外部シンボル '__fastcall System::Internal::Strhlpr::UnicodeFree(System::UnicodeString&)' が C:\PROGRAM FILES (X86)\EMBARCADERO\STUDIO\19.0\LIB\WIN32\DEBUG\VCLE.LIB|ustring から参照されています
[ilink32 エラー] Error: 未解決の外部シンボル '__fastcall System::Internal::Strhlpr::UnicodeSetLength(System::UnicodeString&, int)' が C:\PROGRAM FILES (X86)\EMBARCADERO\STUDIO\19.0\LIB\WIN32\DEBUG\VCLE.LIB|ustring から参照されています
[ilink32 エラー] Error: リンクを実行できません
失敗

### 対処

コンソールアプリケーションを新規作成する時にターゲットフレームワークを「ビジュアルコンポーネントライブラリ」にする。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5c6faa02-f208-af5c-42a0-550824c01152.png)

作成されたひな型に対して以下のように書き換える。

```File1.cpp
#include <vcl.h>
#include <windows.h>

#pragma hdrstop
#pragma argsused

#include <tchar.h>

#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
    String lpath = L"TEST";
	return 0;
}
```

- ファイルをビルド: 成功
- プロジェクトをビルド: 成功

### Bugなのか仕様なのか

ターゲットフレームワークの選択により、File1.cpp以外の部分で何かが違うのだろう。

ビルドエラーのメッセージを見ただけでは上記の対処にたどり着けないだろう。


### 落とし穴

「新規コンソールアプリケーション」ダイアログにて「ターゲットフレームワーク」
はIDEインストール直後は「なし」になっている。

いったん「ビジュアルコンポーネントライブラリ」に変更すると、その変更が以後記憶される。

最初の状態とは違う設定をしている場合、環境を再構築した時にエラーが発生するようになり、その原因特定に時間を取られる。
Nuxt.jsを起動した時にdev has been deprecated in build.extend(), please use isDevと出る

`dev has been deprecated in build.extend(), please use isDev` と出る

<img width="491" alt="n.png" src="https://qiita-image-store.s3.amazonaws.com/0/15187/f1834b88-0492-085b-9514-a45bc16c010a.png">

ググると、v1.0.0のリリースノートでDeprecateになっている。

https://github.com/nuxt/nuxt.js/releases/tag/v1.0.0

v1.0.0以前に[starter-template](https://github.com/nuxt-community/starter-template)からインストールしてバージョンを上げた場合、 `nuxt.config.js` を以下のように修正する必要がある。

```diff
  /*
  ** Run ESLint on save
  */
- extend (config, ctx) {
- 　　 if (ctx.dev && ctx.isClient) {
+ extend (config, { isDev, isClient }) {
+   if (isDev && isClient) {
      config.module.rules.push({
        enforce: 'pre',
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        exclude: /(node_modules)/
      })

```

参考: https://github.com/nuxt-community/starter-template/commit/a2d4038ef3ca1965cfce08d245b47936f305afd7
ES6のSpread Operatorを使った配列の作り方

# 目的
JavaScriptでn未満の整数の配列を作りたい。
できるだけシンプルに書きたい。

# Rubyの場合
`Range#to_a`でシンプルに書けます。

```ruby
n = 10
(0..n-1).to_a
#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

# JavaScriptの場合
## ES5
for文などを使ったやり方が一般的です。

```js
var n = 10,
    result = [];
for (var i = 0; i < n; i++) {
  result.push(i);
}
// result => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

## ES6 (ES2015)
ES6のSpread Operatorを使うとシンプルに書けます。

```js
const n = 10;
[...Array(n).keys()];
// => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

# 参考
[JavascriptでRubyのRange#to_aのような配列を返す方法 - rochefort's blog](http://rochefort.hatenablog.com/entry/2015/01/08/005043)
[Spread syntax - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)
[spread_(...) operator - ECMAScript 6 compatibility table](http://kangax.github.io/compat-table/es6/#test-spread_(...)_operator)

# おまけ
n未満の自然数のうち、３または5で割り切れる数字の合計を計算するプログラム
※引数nは0以上の整数とする。

## ES5
```js
function solution(n) {
  var sum = 0;
  
  for(var i = 1; i　< n; i++){
    if(i % 3 === 0 || i % 5 === 0){
      sum += i
    }
  }
  return sum;
}
```

## ES6 (ES2015)
```js
const solution = n => [...Array(n).keys()].filter(i => (i % 3 === 0 || i % 5 === 0)).reduce((a, b) => a + b, 0);
```

※`n = 0` のとき、`[...Array(n).keys()].filter(i => (i % 3 === 0 || i % 5 === 0))`が空配列になってエラーが起こるため、`reduce`には初期値0を設定しています。
apt-get で追加したリポジトリがGPGエラーになった場合の対処方法

#GPGエラーになるよ
aptにdocekrのリポジトリを追加後、apt-get updateした時にGPGエラーになりました。

```sh
パッケージリストを読み込んでいます... 完了
W: GPG エラー: https://apt.dockerproject.org/repo ubuntu-xenial InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY F76221572C52609D
W: リポジトリ https://apt.dockerproject.org/repo ubuntu-xenial InRelease は署名されていません。
N: このようなリポジトリから取得したデータは認証できないので、データの使用は潜在的に危険です。
N: リポジトリの作成とユーザ設定の詳細は、apt-secure(8) man ページを参照してください。
```
#対処方法
ここに対処方法が書いてありました。
[apt-get updateでGPGエラーが出た時の対処法](https://ystklog.com/412)
NO_PUBKEY F76221572C52609D （この値は都度違う）をubuntuのキーサーバーに問い合わせします。

```sh
#apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F76221572C52609D
pg: 鍵2C52609Dをhkpからサーバkeyserver.ubuntu.comに要求
gpg: 鍵2C52609D: 公開鍵"Docker Release Tool (releasedocker) <docker@docker.com>"をインポートしました
gpg: 処理数の合計: 1
gpg:               インポート: 1  (RSA: 1)
```
うまくいきました。
arduinoでi2c　その4

#概要
フルスクラッチでmaster書いてみた。

#写真
![CIMG2522.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/54775112-85af-e0e9-b0e5-216905ad44f1.jpeg)


#回路図
![image](https://camo.qiitausercontent.com/c01ad8b4a2c9df05101c0501b34a7eba2a8f1b21/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f31383130342f31336161663262372d316239652d653139332d633964642d3831353635373630373661612e706e67)


#サンプルコード


```
#include <inttypes.h>
#include <compat/twi.h>

#define F_CPU 				16000000UL
#define SCL_CLOCK 			50000L
#define PCF8574_ADDRESS		0x27 << 1 + 0
void i2c_init(void)
{
	TWSR = 0;
	TWBR = ((F_CPU / SCL_CLOCK) - 16) / 2;
}
unsigned char i2c_start(unsigned char address)
{
	uint8_t twst;
	TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
	while (!(TWCR & (1 << TWINT)));
	twst = TW_STATUS & 0xF8;
	if ((twst != TW_START) && (twst != TW_REP_START)) return 1;
	TWDR = address;
	TWCR = (1 << TWINT) | (1 << TWEN);
	while (!(TWCR & (1 << TWINT)));
	twst = TW_STATUS & 0xF8;
	if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) return 1;
	return 0;
}
void i2c_stop(void)
{
	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
	while (TWCR & (1 << TWSTO));
}
unsigned char i2c_write(unsigned char data)
{
	uint8_t twst;
	TWDR = data;
	TWCR = (1 << TWINT) | (1 << TWEN);
	while (!(TWCR & (1 << TWINT)));
	twst = TW_STATUS & 0xF8;
	if (twst != TW_MT_DATA_ACK) return 1;
	return 0;
}
void send(uint8_t d)
{
	uint8_t s;
	i2c_start(PCF8574_ADDRESS);
	i2c_write(d);
	s = d | 0x04;
	i2c_write(s);
	delayMicroseconds(1);
	s = d & 0xfb;
	i2c_write(s);
	delayMicroseconds(1);
	i2c_stop();
}
void set(uint8_t d)
{
	uint8_t s;
	uint8_t f1 = d & 0xf0;
	uint8_t f2 = d << 4;
	i2c_start(PCF8574_ADDRESS);
	s = f1;
	i2c_write(s);
	s = f1 | 0x04;
	i2c_write(s);
	delayMicroseconds(1);
	s = f1 & 0xfb;
	i2c_write(s);
	i2c_stop();
	i2c_start(PCF8574_ADDRESS);
	s = f2;
	i2c_write(s);
	s = f2 | 0x04;
	i2c_write(s);
	delayMicroseconds(1);
	s = f2 & 0xfb;
	i2c_write(s);
	i2c_stop();
}
void data(uint8_t d)
{
	uint8_t s;
	uint8_t f1 = d & 0xf0;
	uint8_t f2 = d << 4;
	i2c_start(PCF8574_ADDRESS);
	s = f1;
	i2c_write(s);
	s = f1 | 0x05;
	i2c_write(s);
	delayMicroseconds(1);
	s = f1 & 0xfa;
	i2c_write(s);
	i2c_stop();
	i2c_start(PCF8574_ADDRESS);
	s = f2;
	i2c_write(s);
	s = f2 | 0x05;
	i2c_write(s);
	delayMicroseconds(1);
	s = f2 & 0xfa | 0x08;
	i2c_write(s);
	i2c_stop();
}
void setup()
{
	unsigned char c;
	unsigned char address;
	int nDevices;
	Serial.begin(115200);
	i2c_init();
	send(0x03);
	delayMicroseconds(50);
	send(0x03);
	delayMicroseconds(50);
	send(0x03);
	delayMicroseconds(15);
	send(0x02);
	set(0x28);
	set(0x0c);
	set(0x01);
	set(0x06);
	data(0x68);
	data(0x65);
	data(0x6c);
	data(0x6c);
	data(0x6f);
	data(0x2c);
	data(0x20);
	data(0x77);
	data(0x6f);
	data(0x72);
	data(0x6c);
	data(0x64);
	data(0x21);
	Serial.println("ok");
}
void loop()
{
	delay(100);
}



```


以上。
GitHub API v4をPHPから呼んでみる

APIを「叩く」って言い方、よく聞くけど、痛そうだから好きじゃないのよね…。

さて、GitHubのAPI使って何かやろうと思ったら、今はv4のGraphQLなんてのがあるんですね。
https://developer.github.com/v4/

こいつをPHPから呼び出してみようというわけです。

GitHub API v4は、GraphQLのクエリを含んだJSONを、ベアラートークンを付けて、エンドポイントにPOSTすると、JSONデータが返ってくる、という仕組みになっています。QueryじゃなくMutationを投げたら更新らしいですが、今回は取得だけやってみます。

# GraphQLのクエリを書いてみる
[GraphQL API Explorer](https://developer.github.com/v4/explorer/)なんてのがあるので、ここで書いてみましょう。

とりあえず、よくあるパターンで、特定ユーザーのリポジトリの名前とURLの一覧を取得するクエリを書いてみました。

```GraphQL
{
  user(login: "mifumi323") {
    repositories(first: 10) {
      nodes {
        name
        url
      }
    }
  }
}
```

GraphQL見たことのない人でも何となくわかるんじゃないでしょうか。「mifumi323」というユーザーのリポジトリの最初の10件の名前とURLを取得するクエリです。

返ってくるJSONも見りゃわかる内容なので、省略します。

# ベアラートークンを取得する
GitHub APIの要件なのかGraphQLの要件なのか知りませんが、APIを呼び出すときにはベアラートークンが必要です。

![settings.png](https://qiita-image-store.s3.amazonaws.com/0/212471/6f9e21eb-5ea5-c381-754e-2378da363ece.png)

Settings→Developer settings→Personal access tokensと進んでいって、Generate new tokenしましょう。scopeはrepoでいいはず。発行したトークンは一度しか表示されないので、忘れずにメモしておきましょう。

# POSTする
クエリとトークンがそろったので、POSTするPHPプログラムを書いてみます。\$tokenと\$queryにはさっき作ったやつを入れましょう。

```PHP
<?php

$token = 'ここにトークンを書いてね';
$query = 'ここにクエリを書いてね';

$options = [
    'http' => [
        'method' => 'POST',
        'header' => [
            'User-Agent: My User Agent',
            'Authorization: bearer '.$token,
            'Content-type: application/json; charset=UTF-8',
        ],
        'content' => json_encode(['query' => $query]),
    ],
];
$context = stream_context_create($options);
$contents = file_get_contents('https://api.github.com/graphql', false, $context);
var_dump(json_decode($contents));
```

file_get_contentsって便利ですね。stream_context_createでPOSTするコンテンツやらヘッダやらを用意しています。

contentはクエリそのままだと受け付けないので、queryフィールドにクエリの内容を含んだJSONにしておきます。それに合わせて、Content-typeも指定しておきます。

そして、ベアラートークンをAuthorizationに入れてPOSTします。

GitHubはv3の頃もそうでしたが、ヘッダにUser-Agentを入れておかないとエラーになります。特に何かに使っているわけでもないようなので、適当に無難な文字列を入れておくといいかと思います。

# エラー処理など
GraphQLのエラーは、dataフィールドがnullになってerrorsフィールドが入ってきます。ただし、GraphQLをパースする前のエラー、例えば認証エラーなどの場合は、HTTPのエラーコードが返ってきます。

理屈を考えれば当たり前ですが、区別して扱うようにしましょう。
ADDA > runtime argument > -ntheta > to configure the [theta] steps in the file [mueller]

```txt:Environment
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

This article is related to [ADDA (light scattering simulator based on the discrete dipole approximation)](https://github.com/adda-team/adda/).

### Theta steps


I thoguht that the file [mueller] is created with the [theta] step of 1.0. 
However the step changes for the different runs of the ADDA.


With arguments below, the step is 1.0.

```bash
./adda
```

With arguments below, the step is 0.5.

```bash
./adda -shape chebyshev 0.7 12 -m 1.5 0.005 -eq_rad 6.299605 -store_int_field
```

With arguments below, the step is 0.25.

```bash
./adda -grid 104 -shape chebyshev 0.7 12 -m 1.5 0.005 -eq_rad 6.299605 -store_int_field
```

### -ntheta 

Link: [mueller > different [theta] step for different ADDA run](https://groups.google.com/forum/#!topic/adda-discuss/B6vTKmnNLPE)

In the above forum, `-ntheta` runtime arguemnt is introduced.


```bash
./adda -ntheta 180
```

```bash
./adda -ntheta 180 -shape chebyshev 0.7 12 -m 1.5 0.005 -eq_rad 6.299605 -store_int_field
```


```bash
./adda -ntheta 180 -grid 104 -shape chebyshev 0.7 12 -m 1.5 0.005 -eq_rad 6.299605 -store_int_field
```
自分が知らないWEB開発周りの単語メモ

技術的なこと調べていると必ず知らない単語が出てきて、初心者の自分は調べることの繰り返しになる。蟻地獄のように言葉の砂に埋もれていきそうなので自分が一度調べたことを随時メモ。ただの羅列なので面倒なカテゴリ分けとかは無し。

###OSS（Open-source software）
そのままオープンソースのソフトウェア。
略されるとわからないけど調べるとわかる。これって初心者あるある？

###PaaS(Platform as a Service)
ネット経由でプラットフォーム（OSとか）をサービスとして利用できる。サービスの例を出すとHerokuとか。これ系の略語は色々いくつかあっていつもごっちゃになる。

###ブロックチェーン
分散型台帳？のこと。といっても何のことかよくわからない。ブロックは台帳でブロック同士をチェーンで繋ぐようにリンクしているデータベースこのこと。Fintech系の取引とかで使われる仕組み。

###デプロイ
言葉の意味は配置に就く、分散する、展開する。アプリケーションをリリースするってことかな。デプロイは動詞なので“デプロイ”だけでリリースするって意味になるけど、“デプロイする”って言っちゃいそう。
JavaScriptでCookieをオブジェクトに変換する

　以下のように書くみたいです。
　[30 seconds of code](https://30secondsofcode.org/)より引用。

```javascript
const parseCookie = str =>
  str
    .split(';')
    .map(v => v.split('='))
    .reduce((acc, v) => {
      acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
      return acc;
    }, {});

parseCookie('foo=bar; equation=E%3Dmc%5E2'); // { foo: 'bar', equation: 'E=mc^2' }
```
macOS Sierraに簡単な方法でVueアプリを作成する

この記事ではmacOS Sierraにnpmとかvue-cliとかを使ってVueアプリを、https://github.com/vuejs/vue-cli で説明されている方法で作成してみます。

*以下に掲載しているコードやターミナルに表示されているユーザー名やディレクトリ名等(shotaimac, snakada, study, my-vue等)は適宜読み替えてください。*

#前提条件
以下のような環境で作業をしました。

macOS Sierra バージョン 10.12.6
node --version: v8.0.0 
npm --version: 5.6.0

# [vue-cli](https://github.com/vuejs/vue-cli)をインストールする
[公式のInstallation](https://github.com/vuejs/vue-cli#installation)に書いてあるとおりにやろうとすると、私の環境の場合パーミッションエラーが出てしまったので、以下のとおりsudoでおこないました。何やらdeprecated言われましたけど、一旦気にせず進めていきます。

```:ターミナル
shotaimac:study snakada$ sudo npm install -g vue-cli
npm WARN deprecated coffee-script@1.12.7: CoffeeScript on NPM has moved to "coffeescript" (no hyphen)
（ここでちょっと待つと最後に以下が表示されます）
+ vue-cli@2.9.2
added 264 packages in 18.188s
shotaimac:study snakada$ 
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213763/85afb762-1599-79b8-e76f-ef55f6ff95d7.png)

vue-cli 2.9.2 がインストールされました。


#Vueアプリを作成
[公式のUsage](https://github.com/vuejs/vue-cli#usage)を参考に、ひとまずもっとも簡単そうなwebpack-simpleテンプレートでVueアプリを作成してみます。

```:ターミナル
shotaimac:study snakada$ vue init webpack-simple my-vue

? Project name my-vue
? Project description A Vue.js project
? Author snakada
? License MIT
? Use sass? Yes

   vue-cli · Generated "my-vue".

   To get started:
   
     cd my-vue
     npm install
     npm run dev

shotaimac:study snakada$ 
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213763/ee6410f7-fe0a-c059-6e3e-82c30845928e.png)


# 開発を開始する
親切にも上記ターミナルの最後に**To get started:**で、次に何をやるべきかの指示があるのでそのとおりやってみます。

```:ターミナル
shotaimac:study snakada$ cd my-vue/
shotaimac:my-vue snakada$ npm install
（ここでちょっと待つと最後に以下が表示されます）
added 1031 packages in 104.013s
shotaimac:my-vue snakada$ 
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213763/cd0e343f-607e-7fad-ee64-17eedef5daeb.png)

npmインストールが終わったようなので、 **npm run dev** してみます。

```:ターミナル
shotaimac:my-vue snakada$ npm run dev

> my-vue@1.0.0 dev /Users/snakada/projects/study/my-vue
> cross-env NODE_ENV=development webpack-dev-server --open --hot

Project is running at http://localhost:8080/
webpack output is served from /dist/
404s will fallback to /index.html
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213763/3cefc1c6-d2f1-be7e-a2ff-780ae9a6d56c.png)

サーバーの準備が整ったようで、なおかつ勝手にブラウザで以下の画面が表示されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/213763/0276b910-4cc9-e6e2-371f-1d9523739d26.png)

いい感じです。