OmniAICreator/Qiita-1.07M huggingface dataset:
アプリとSeleniumの2つのDockerコンテナでE2Eテスト

# 概要
Protractor＋SeleniumによるE2Eテスト導入
→AngularアプリをDocker化
→あれ、E2Eテスト動かなくなってる・・！
となっていたので、Selenium Server, Angularアプリをそれぞれ異なるコンテナ上で起動してテストできるようにしました。
Docker初心者として苦労したので、その時の方法を共有します。
（Protractor、Seleniumコンテナ、docker-composeの詳細は別の記事を参考にしてください）

# 参考
* [docker-selenium 使って見た](https://qiita.com/yutaChaos/items/4a1da5d55a3bf0df889e)
    * Seleniumコンテナの基本的な使い方を大いに参考にしています

# 行ったこと
* docker-composeで以下の構成を作りました
    * ![docker構成.jpg](https://qiita-image-store.s3.amazonaws.com/0/140270/93571dbf-cab2-121f-a86c-d9135adc48c5.jpeg)
    * テストコードからE2Eテスト実行環境としてSeleniumサーバを指定
    * E2Eテスト対象としてアプリを指定

* Selenium Serverは[docker-selenium](https://github.com/SeleniumHQ/docker-selenium)のselenium/node-chrome-debugをそのまま使っています

## docker-composeにSelenium Serverを追記してup

* DB, 環境変数

```yaml:docker-compose.yml
version: "3.3"
services:
  selenium:
    container_name: selenium_test
    image: selenium/standalone-chrome-debug
    networks:
      - network1
    ports:
      - "4444:4444"
      - "15900:5900"
  app:
    build: ./app
    container_name: app_test
    networks:
      - network1
    ports:
      - "3000:3000"
    volumes:
      - ./web:/app
    environment:
      SELENIUM_HOST: selenium_test
      SELENIUM_PORT: 4444
      E2E_TARGET_HOST: app_test
      E2E_TARGET_PORT: 3000
    tty: true
    stdin_open: true
    restart: always
networks:
  network1:
    driver: bridge
```

## Seleniumコンテナが単体で動くことを確認
* http://localhost:4444/wd/hub をブラウザから開いてみる。下のような画面が表示されたらOK
    * <img width="1340" alt="Screen Shot 2018-06-14 at 12.52.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/140270/f4c0249a-2c6b-d98f-7c50-38ab65921479.png">
* vnc://localhost:15900 に接続してみる。下の画面が表示されたらOK
    * <img width="1073" alt="Screen Shot 2018-06-14 at 12.51.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/140270/5e6b2234-fbce-71a6-6376-0d9179727fe6.png">


## テストコード修正
* 設定ファイル

```js:conf.js
exports.config = {
  seleniumAddress: `http://${process.env.SELENIUM_HOST}:${process.env.SELENIUM_PORT}/wd/hub`,
  specs: ['login.js']
};
```
* テストファイル

```js:login.js
const loginUrl = `http://${process.env.E2E_TARGET_HOST}:${E2E_TARGET_PORT}/login`;

describe('ログインテスト', function() {
  beforeEach(function() {
    browser.ignoreSynchronization = true;
    browser.get(loginUrl);
  });
  it('ログイン用の画面が正しく表示できる', function() {
    expect(browser.getTitle()).toEqual('Sample Title');
  });
});
```

## テスト実行
* Selenium Server, Angularアプリを起動しておく
* テストコードのあるAngularアプリコンテナ内でテストコマンド（今回は `protractor conf.js` ）を実行
* vnc://localhost:15900 を覗くと、Chromeでテストが行われているのが見えるはず
macOSでErgodox EZのカスタマイズをする

微妙に変わっているところがあるので作りました

# 環境
* macOS High Sierra
* Ergodox EZ

# 方法
## qmkのリポジトリをクローン（forkでも良い）
`git clone git@github.com:qmk/qmk_firmware.git`

## レイアウト用ディレクトリを作る
```
cp -r qmk_firmware/keyboards/ergodox_ez/keymaps/default qmk_firmware/keyboards/ergodox_ez/keymaps/your_layout
```

## ビルドツールをインストール
```
brew tap osx-cross/avr
brew install avr-gcc
```

## qmk_firmwareリポジトリ直下にてmakeする
```
make keyboard=ergodox subproject=ez keymap=your_layout
または
make ergodox_ez:your_layout
```

## ファームウェアを焼くためのツールteensyをインストール
参考リンク先を参照

## teensyを使って焼く
teensyのcliがKarabiner-Elementsと競合するのでcliを使うときはKarabiner-Elementsを終了する

```
teensy_loader_cli -w -v -mmcu=atmega32u4 ergodox_ez_your_layout.hex
```

# 参考
https://github.com/qmk/qmk_firmware/tree/master/keyboards/ergodox_ez
https://github.com/qmk/qmk_firmware/blob/master/docs/getting_started_build_tools.md
https://www.pjrc.com/teensy/loader_cli.html
https://gist.github.com/sethherr/0930bda4b79f9371769a
https://www.k4750.net/2016/05/01/ergodox-ez%E3%82%92windows%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AC%E3%82%8B%E3%81%8F%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%81%A6%E3%81%BF%E3%82%8B/
https://qiita.com/kei_s/items/40a896d1a1c70f2961e0
https://qiita.com/ReSTARTR/items/f84f8f3c4c51c876cb2f
https://qiita.com/ReSTARTR/items/970354940f49c67fb9fd
http://nillpo.hatenablog.com/entry/2017/12/04/232524
https://github.com/platformio/platform-teensy/issues/23
[かな入力対応表（作成中）](http://www.keyboard-layout-editor.com/##@@_x:3.5%3B&=%23%0A3&_x:10.5%3B&=*%0A8%3B&@_y:-0.875&x:2.5%3B&=%2F@%0A2&_x:1%3B&=$%0A4&_x:8.5%3B&=%2F&%0A7&_x:1%3B&=(%0A9%3B&@_y:-0.875&x:5.5%3B&=%25%0A5&_a:7%3B&=&_x:4.5%3B&=&_a:4%3B&=%5E%0A6%3B&@_y:-0.875&w:1.5%3B&=%0A%0A%0A%0A%0A%0A%E3%82%9C%0A%0A%E3%80%8C&=!%0A1&_x:14.5%3B&=)%0A0&_a:6&w:1.5%3B&=%E3%81%BB%3B&@_y:-0.375&x:3.5&a:4%3B&=E&_x:10.5%3B&=I%3B&@_y:-0.875&x:2.5%3B&=W&_x:1%3B&=R&_x:8.5%3B&=U&_x:1%3B&=O%3B&@_y:-0.875&x:5.5%3B&=T&_a:7&h:1.5%3B&=&_x:4.5&h:1.5%3B&=&_a:4%3B&=Y%3B&@_y:-0.875&a:7&w:1.5%3B&=&_a:4%3B&=Q&_x:14.5%3B&=P&_a:6&w:1.5%3B&=%E3%81%B8%3B&@_y:-0.375&x:3.5&a:4%3B&=D&_x:10.5%3B&=K%3B&@_y:-0.875&x:2.5%3B&=S&_x:1%3B&=F&_x:8.5%3B&=J&_x:1%3B&=L%3B&@_y:-0.875&x:5.5%3B&=G&_x:6.5%3B&=H%3B&@_y:-0.875&a:7&w:1.5%3B&=&_a:4%3B&=A&_x:14.5%3B&=%2F:%0A%2F%3B&_a:7&w:1.5%3B&=%3B&@_y:-0.625&x:6.5&h:1.5%3B&=&_x:4.5&h:1.5%3B&=%3B&@_y:-0.75&x:3.5&a:4%3B&=C&_x:10.5%3B&=%3C%0A,%3B&@_y:-0.875&x:2.5%3B&=X&_x:1%3B&=V&_x:8.5%3B&=M&_x:1%3B&=%3E%0A.%3B&@_y:-0.875&x:5.5%3B&=B&_x:6.5%3B&=N%3B&@_y:-0.875&a:7&w:1.5%3B&=&_a:4%3B&=Z&_x:14.5%3B&=%3F%0A%2F%2F&_a:7&w:1.5%3B&=%3B&@_y:-0.375&x:3.5%3B&=&_x:10.5%3B&=%3B&@_y:-0.875&x:2.5%3B&=&_x:1%3B&=&_x:8.5%3B&=&_x:1&a:4%3B&=%0A%0A%0A%0A%0A%0A%E3%82%9B%0A%0A%E3%80%8D%3B&@_y:-0.75&x:0.5%3B&=%0A%0A%0A%0A%0A%0A%EF%BD%80%0A%0A%E3%80%9C&_a:7%3B&=&_x:14.5&a:4&fa@:0&:0&:0&:0&:0&:0&:1%3B%3B&=%0A%0A%0A%0A%0A%0A%E3%82%80%0A%0A%E3%83%BC&_a:7%3B&=%3B&@_r:30&rx:6.5&ry:4.25&y:-1&x:1%3B&=&=%3B&@_h:2%3B&=&_h:2%3B&=&=%3B&@_x:2%3B&=%3B&@_r:-30&rx:13&y:-1&x:-3%3B&=&=%3B&@_x:-3%3B&=&_h:2%3B&=&_h:2%3B&=%3B&@_x:-3%3B&=)
データベース総復習チェックリストーPHPでデータベースを扱う方法ー

データベースを用意できているという前提で進めます。

# データベースに接続する

PHPがすでに用意していくれている、PDOというものを使ってデータ接続していきます。


```php
define('DSN','mysql:host=localhost;dbname=データベース名;charset=utf8');
define('DB_USERNAME','ユーザー名');
define('DB_PASSWORD','パスワード');

$db = new \PDO(DSN, DB_USERNAME, DB_PASSWORD);
```

設定の部分とデータベースの接続を一緒にしたくないよ！！っていう方は、このようにします。


```config.php
define('DSN','mysql:host=localhost;dbname=データベース名;charset=utf8');
define('DB_USERNAME','ユーザー名');
define('DB_PASSWORD','パスワード');
```

```index.php
$db = new \PDO(DSN, DB_USERNAME, DB_PASSWORD);
```

defineはどこからでもアクセスできるので、requireとかする必要はないです！


## 接続のオプションを追加する

データベースの接続のオプションを追加する場合は、setAttributeを使います。

```php
$db -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
```

ここで例として出している「PDO::ATTR_ERRMODE」でエラーコードを設定し、「ERRMODE_EXCEPTION」でエラーコードや関連情報がプロパティとして設定されます。


これを使って、例外処理をするとこんなこともできます。

```php
try{
        $db = new \PDO(DSN, DB_USERNAME, DB_PASSWORD);
        $db ->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}catch(\PDOException $e){
        echo $e->getMessage();
        exit;
      }
```


# データベースを操作する

queryを使えば、SQLが実行できます。

```php
$db -> query("select * from todos");
```

execを使えば、アップデートや削除などができます。

```php
$db -> exec('UPDATE todos SET element = element + 1');
```
react-redux で ***** is not a function と怒られる

# react-redux で ***** is not a function と怒られる


## 解決策

connect関数にエラーで怒られていたアクションを渡していなかったのが原因だった。

```Javascript:LoginForm.js
export default connect(mapStateToProps, { emailChanged, passwordChanged, nicknameChanged, loginUser })(LoginForm);
```

どうやらreactのcomponentとreduxのアクションは全く繋がりがないのでそれをconnectするようである。そうすることでcomponent内でアクションが起きることができるようになる。
快適に開発を始めるためにやったこと

## tmuxの導入と使い方
Macに最初から入っているターミナルを使っているためまずは１つのターミナルで複数のプロセスを管理できるようにtmuxをいれました

```
# インストール
$ brew install tmux
# 起動
$ tmux

# デフォルトのshellがbashじゃない人は追加で以下を行う
$ vim ~/.tmux.conf
set-option -g default-shell /bin/zsh

$ killall tmux; tmux
```

### ウインドウの操作
iTerm2のタブ的なやつ

`<Ctrl-b>` + 下のコマンドを実行する

```
c 新規作成
w 一覧選択
& 現在のウィンドウ破棄
```

### ペインの操作
ウインドウを分割して１画面で複数のセッションを持てる

`<Ctrl-b>` + 下のコマンドを実行する

```
% 左右にペイン分割
" 上下にペイン分割
q ペイン番号を表示
カーソル 指定方向のペインへ移動 ※連続押しでプレフィックス継続
x ペインの破棄
```

# Gitで管理しているリポジトリをvimでコマンド一発で開けるようにする

```bash:ghqのインストール
$ brew tap motemen/ghq
$ brew install ghq

$ git config --global ghq.root ~/your_repo_dir
```

```bash:pecoのインストール
$ brew tap peco/peco
$ brew install peco
```

```bash:zshrcにaliasの追加
$ vim ~/.zshrc
alias v='vim $(ghq root)/$(ghq list | peco)'

$ source ~/.zshrc
```
以下のaliasを仕込むことで`v`通しただけでgihubのローカルリポジトリ一覧が出て選択するとvimでひらくことができるようになる

# [WIP]Vim
https://vim-bootstrap.com/
これからやってく


# 参考リンク
- https://qiita.com/nmrmsys/items/03f97f5eabec18a3a18b
- https://qiita.com/strsk/items/9151cef7e68f0746820d
IFTTTで風が吹いたら遅刻して、雨が降ったら休むアプレットを作ってみたぜ

#はじめに

**南の島のハメハメハ大王**の歌詞で

「風が吹いたら遅刻して」「雨が降ったら休む」がある。

そのような生活を疑似体験するためのアプレットを作ってみたぜ！

##「風が吹いたら遅刻して」のアプレット構成

はじめに、**Trigger**(If)の部分を**Weather Underground**にした。

条件を**「〇〇km/h吹いたら××する。」**にすることによって

**「風が吹いたら」**の条件付け部分ができた。

次に、**Action**(That)を**Twitter**を使ってみたぜ！

これで、風が〇〇km/h吹いたらTwitterに「風が強いので遅刻しまーす。」というツイートをするアプレットの完成だ！！

##「雨が降ったら休む」のアプレット構成

上記と同じように**Trigger**を**Weather Underground**に、**Action**を**Twitter**したぜ。

また、Weather Undergroundの条件を「明日〇〇だと」という条件付けをした。

今回のアプレットでは「雨が降ったら」なので〇の部分に「雨」にした。

そして、Twitterに「明日雨なので休みまーす。」とツイートをさせるアプレットの完成だ！！

##終わりに

今回の**IFTTT**を使用したアプレットはマルチアクションを使用していないのでかなり簡単なアプレットになってしまった。

今後はマルチアクションを使った疑似体験ができるアプレットも作っていきたい。

まだまだ、**ハメハメハ大王の生活を疑似体験**できるようなアプレットを作っていくので乞うご期待！！
Linuxのbinfmt_miscを使ってGoスクリプトを直接実行できるようにする

この記事はCloudflareによる[Using Go as a scripting language in Linux](https://blog.cloudflare.com/using-go-as-a-scripting-language-in-linux/)の内容そのまんまである。

# TLDR

Linuxカーネルには`/proc/sys/fs/binfmt_misc`という仕組みがあり、指定の拡張子／マジックコードに対して指定のインタープリタを実行させることができる。この機能を使って、Goのソースファイルを`./helloscript.go`で実行できるようにする。

例として使うGoのソースファイルは下記の通り。shebangなどは要らない。

```helloscript.go
package main

import (
	"fmt"
	"os"
)

func main() {
	s := "world"

	if len(os.Args) > 1 {
		s = os.Args[1]
	}

	fmt.Printf("Hello, %v!", s)
	fmt.Println("")

	if s == "fail" {
		os.Exit(30)
	}
}
```

# やりかた

[Using Go as a scripting language in Linux](https://blog.cloudflare.com/using-go-as-a-scripting-language-in-linux/)に書いてある通り。

```console
# binfmt_miscの機能が有効になっているか確認
$ mount | grep binfmt_misc
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=27,pgrp=1,timeout=0,minproto=5,maxproto=5,direct)

# プロセスのEXIT STATUSがちゃんとOSに渡せるようにするため、ラッパーとしてgorunを入れる
$ go get github.com/erning/gorun
$ sudo mv ~/go/bin/gorun /usr/local/bin/

# binfmt_miscの設定
$ echo ':golang:E::go::/usr/local/bin/gorun:OC' | sudo tee /proc/sys/fs/binfmt_misc/register
:golang:E::go::/usr/local/bin/gorun:OC

# スクリプトに実行属性をつける
$ chmod u+x helloscript.go

# 実行する（出来上がり！）
$ ./helloscript.go
Hello, world!
```
bash + sed > replace_3rd_line_180618_exec > 3行目を別の文字列で入替える

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

### 処理概要

- ファイルの3行目だけを特定の文字列で置換える

### 参考

- [逆引きUNIXコマンド/sedで指定した行を削除する方法](http://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8DUNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/sed%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E8%A1%8C%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95) by IT SUPPORT SAKURA

### code v0.1

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

set -eu # just in case

INFILE="in_180618.txt"
RPLTXT="PPP"

# replace 3rd line
sed '3,$d' $INFILE
echo $RPLTXT
sed '1,3d' $INFILE
```

```in_180618.txt
AAA
BBB
CCC
DDD
EEE
```

```bash
$ bash replace_3rd_line_180618_exec 
AAA
BBB
PPP
DDD
EEE
```

### 教えていただいた事項
(2018/06/18追加)

@akinomyoga さんの[コメント](https://qiita.com/7of9/items/5c97deb33e16dd7c0a68/#comment-e7343dd5097749444411)にてINFILEを一回の読込みで済む方法を教えていただきました。

情報感謝です。
Pythonでソケットを扱う（入門）


# 環境
* Ubuntu 17.10
* Python 3.6

# 参考
https://docs.python.jp/3/howto/sockets.html
https://docs.python.jp/3/library/socket.html

# サーバ側

インタープリタを起動して、下記を実行。

```
>>> import socket
>>> serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> serversocket.bind((socket.gethostname(), 8080))
>>> serversocket.listen(5)
>>> (clientsocket, address) = serversocket.accept()
```

ブロックされる。（入力を受け付けるプロンプトが進まない）

別のプロセスから接続をする。たとえば、`ss -nltp`でバインドしているアドレスを調べて、telnetで接続する。

そうすると、ブロックされていた部分が進み、入力できるようになっている。

```
>>> type(clientsocket)
<class 'socket.socket'>
>>> clientsocket.fileno()
4
>>> clientsocket.getsockname()
('127.0.1.1', 8080)
>>> clientsocket.getpeername()
('127.0.0.1', 53560)

```

一度の接続で終了しない。

```python

import socket

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), 8080))
serversocket.listen(5)

while True:
    (clientsocket, address) = serversocket.accept()


    print("handle connectin")
    clientsocket.close()
```

# クライアントが送ってきたデータを読み取る。


サーバー側。

```python

import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), 8080))
serversocket.listen(5)

while True:
    (clientsocket, address) = serversocket.accept()
    data = clientsocket.recv(4096)
    print(data.decode('utf-8'))
    clientsocket.close()
```

クライアント側。コマンドライン上から。

```
$ echo hello | nc 127.0.1.1  8080
```

# クライアントもPythonで

```
>>> import socket
>>> clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> clientsocket.connect(("127.0.1.1", 8080))
>>> clientsocket.send(b"hello")
```
nologinユーザのコマンド実行

apache+pythonの環境で、スクリプトの権限及び結果の確認に使えるので、メモします。

# apacheのユーザを確認
```shell:/etc/passwd
(前略)
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
```

＊：passwd apacheでパスワードを設定する必要があるかも。

# apache用のbashを起動
```shell
su -s /bin/bash apache
```
React NativeでiPhone XやStatusBarの上部余白にまとめて対応できる「react-native-safe-area-view」

# SafeAreaViewが動かなかった
React Navigationでカスタムヘッダーを作る際に、上からの余白をiPhone XやらiPhoneの各バージョンやらAndroidやらに対応しなければならなくてReact Nativeで提供されているSafeAreaViewを使おうとしたけど、なぜか動かなかった。

# react-native-safe-area-view
JSオンリーで版のSafeAreaViewを提供してくれるパッケージらしい。
React Navigationで早くから採用されているというので安心して使えた。

# サンプルコード
そのまま使おうとしたら上の方が黒くなるので背景白のViewでラップしました。

```react
import SafeAreaView from 'react-native-safe-area-view';

export default class Top extends Component {
  render() {
    return (
      <View style={{backgroundColor: '#fff'}}>
        <SafeAreaView forceInset={{ top: 'always' }} style={{height: 40}}>
          <Text>こんにちは</Text>
        </SafeAreaView>
      </View>
    )
  }
}
```

# 結論・まとめ
デバイスによってpadding変えたりする面倒なコードが不要になり、めちゃくちゃ便利だった。
Ruby on Rails | drop_tableでテーブル削除マイグレーションする時の良い子・悪い子・普通の子

# 良い子

rollback した時に、元と同じ構造のテーブルが生成されるようにする。
(元のデータは失われるが)

```rb
class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end
```

# 悪い子

捨てて省みぬ。

```rb
class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users
  end
end
```

# 普通な子

不可逆であることを明記する。

```rb
class DropUsers < ActiveRecord::Migration
  def up
    drop_table :users
  end

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end
```

# その他

マイグレーションをrevertする方法もあるらしい。

[drop_tableの代わりにActiveRecordMigration#revert - kikeda1104's blog](http://kikeda1104.hatenablog.com/entry/2017/06/29/215714)

# 参考

- [database - Rails DB Migration - How To Drop a Table? - Stack Overflow](https://stackoverflow.com/questions/4020131/rails-db-migration-how-to-drop-a-table)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
nuxt.jsのデバッグ方法(chrome DevTools)

#環境
windows10 
Nuxt.js
node.js v8.11.3

#デバッグ手順
package.jsonへの追記

```package.json
"scripts": {
    "debug": "node --inspect-brk=9229 node_modules/nuxt/bin/nuxt",
    ...
```

デバッガ起動

```
 > npm run debug 
...
Debugger listening on ws://127.0.0.1:9229/c1188eb8-abb6-4d7c-8888-a0491b329ae9
For help see https://nodejs.org/en/docs/inspector
```

Chromeで「chrome://inspect/」にアクセス
<img width="269" alt="chrome_debug.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/158724/95992ee2-1a62-7f23-ccda-961b707b9b94.jpeg">

[inspect] をクリックでデバッガが開く
<img width="533" alt="debugger.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/158724/53b59777-28b2-f626-1b25-81507f132422.jpeg">

ブレークポイントは[debugger]コード中に書くとBreakPointが貼れる
<img width="467" alt="breakpoint_code.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/158724/866d746d-05d6-a21d-888c-b2f45de43234.jpeg">


#参考サイト
http://d.hatena.ne.jp/Kazuhira/20180212/1518433536
ankoで表示したsnackbarのactionボタンの色を変更する


テーマ次第かもしれませんが今開発しているアプリでankoのヘルパー関数をつかってsnackbarを表示したところ、黒の背景にグレーのテキストになってしまいボタンが見にくかったです。

ボタンの色を変更するにはヘルパー関数の戻り値のオブジェクトの`setActionTextColor`を使えば簡単です。

```kotlin
val snackbar = snackbar(rootLayout, R.string.hoge, R.string.fuga, {
    // something to do 
})
snackbar.setActionTextColor(Color.WHITE)

```
React/React Nativeにおけるコンポーネント間での値・関数・中身の受け渡し

基本中の基本。

# 値を渡す

### **親コンポーネント**

```react
export default class Parent extends Component {
  render() {
    return (
      <View>
        <Child text={'こんにちは'}>
      </View>
    );
  }
}
```

### **子コンポーネント**

```react
export default class Child extends Component {
  render() {
    text = this.props.text;

    return (
      <View>
        <Text>{text}</Text>
      </View>
    );
  }
}
```

# 関数を渡す
bind(this)をしないと、updateParentState内でthisが使えないので注意。

### **親コンポーネント**

```react
export default class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      text: 'ボタンを押して',
    };
  }

  updateParentState(_text) {
    this.setState({text: _text})
  }

  render() {
    return (
      <View>
        <Text>{this.state.text}</Text>
        <Child updateText={this.updateParentState.bind(this)} />
      </View>
    );
  }
}
```

### **子コンポーネント**

```react
export default class Child extends Component {
  render() {
    return (
      <View>
        <Button onPress={() => this.props.updateText('ボタンが押されました')}>
      </View>
    );
  }
}
```

# コンポーネントがラップした中身を取得する

### **親コンポーネント**

```react
export default class CustomComponent extends Component {
  render() {
    return (
      <CustomView>
        <Text>中身のテキスト</Text>
      </CustomView>
    );
  }
}
```

### **子コンポーネント**

```react
export default class CustomView extends Component {
  render() {
    return (
      <View style={{flex: 1, backgroundColor: '#eee'}}>
        {this.props.children}
      </View>
    );
  }
}
```
Windows10のノートPC内蔵キーボードはJIS配列、Bluetooth接続のキーボードはUS配列にする設定方法

ノートPC内蔵キーボードと、Bluetooth接続しているキーボードの配列を独立して設定できず苦労しました。
売ってなかったから仕方ないけど、USキーボードのノートPC買えば良かった。

解決策を見つけたので、今後誰かの役に立つと信じて残しておきます。
（おそらく未来の自分の為にはなる。）

## 環境
OS: Windows 10
接続したキーボード：[thinkpad bluetooth ワイヤレス・トラックポイント・キーボード](https://www3.lenovo.com/jp/ja/accessories-and-monitors/keyboards-and-mice/keyboards/KEYBOARD-US-English/p/0B47189)


※ コメントで教えていただいた情報です。
本記事で記載している設定が、
<font color="Red">**Windows10 ver.1809 以降では効かなくなってしまったようです。**</font>
Windows10のバージョン情報を確認してから、本手順を実施するようにしてください。


## 手順1. ハードウェアIDの特定
1. デバイスマネージャーを開く
2. キーボードを開く
3. HIDキーボードデバイスを右クリック（もしかしたら名前が違うかも…）
4. プロパティを開く 

![プロパティ.PNG](https://qiita-image-store.s3.amazonaws.com/0/233011/bc8b4f34-d0b6-b728-f5fb-8e1723632181.png) 

Lenovoと書いてあるので、これだと特定。 
5. 詳細タブを開く
6. プロパティでハードウェアIDを選択
7. 出てきたハードウェアIDをメモる ※ コピペできます


![ハードウェアID.PNG](https://qiita-image-store.s3.amazonaws.com/0/233011/be17bec8-cd5e-e956-f4a3-7645d20f091e.png)



## 手順2. レジストリの変更
1. レジストリエディタを開く（Windows + Rキーを押したあとに、「regedit」と入力する。）
2. コンピュータ → HKEY_LOCALMACHINE → SYSTEM → CurrentControlSet → Enum → HIDとたどっていく
3. HIDの一覧から、Bluetooth接続するキーボードのハードウェアIDを見つける
4. Device Parametersを開いて、右クリック → 新規 → DWORDで設定を追加する
5. PCを再起動

- KeyboardTypeOverride：4
- KeyboardSubtypeOverride：0

![設定内容1.PNG](https://qiita-image-store.s3.amazonaws.com/0/233011/73770e15-0464-69d0-49c6-5eadeed24d97.png)
![設定内容2.PNG](https://qiita-image-store.s3.amazonaws.com/0/233011/a775ceee-7c48-5d68-6d5c-2d95cb4d42a7.png)



## 参考サイト
http://d.hatena.ne.jp/ruby-U/20101110/1289371908
AzureStorage(BLOBストレージアカウント)にPHPでファイルを転送する

# AzureStorage(BLOBストレージアカウント)にPHPでファイルを転送する

### Microsoft Azure Storage Exloprerのインストール
"**Microsoft Azure Storage Exloprer"**をインストールします。

- [Azure Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/)でOperating systemでOSを選択して"**Download Storage Explorer free**"からダウンロード
- インストール後、"**Microsoft Azure Storage Exloprer**"を立ち上げます
- "**Connect to Azure Storage**"という画面が表示されるので、デフォルト値(Add an Azure Accountにチェック、Azure environment:Azrue)のまま右下の"**Sign in**"をクリック
- Sign in画面が表示、AzurePortalにログインしている"**E-mail/password**"を入力

### コンテナの作成
BLOBではコンテナに対して、ファイルをアップロードするため事前に作成しておきます。

- Microsoft Azure Storage ExloprerでStorage Accounts > アカウント名にアクセス
- Blob Containersで右クリック > CreateBlobContainerでコンテナ名を入力

### 認証情報
AzurePortal画面で認証用の接続文字列の確認をします。

- ストレージアカウント > アカウント名 > アクセスキー > key1「接続文字列」
- コピーした際、文字列最後尾の"**;EndpointSuffix=core.windows.net**"を含めると接続時にエラーとなりますので、削除して設定して下さい。

### アップロード処理
今回はPHPで以下のように処理を書きました

composerで"**microsoft/azure-storage-blob**"をインストールしてください。


```uploadStorage.php

$connectionString = "認証情報の文字列";
$container = "アップロード先のコンテナ名"

//Storageにアクセス
BlobRestProxy::createBlobService($connectionString);

$file = "/path/to/file";
$fileInfo = pathinfo($file);
$data = file_get_contents($file);

//ファイルアップロード
$blobRestProxy->createBlockBlob($container, $fileInfo['basename'], $data);

```

これで対象のファイルがStorageAccountにアップロードされると思います。
Level 16. Preservation（The Ethernaut）

「The Ethernaut by Zeppelin Level 16. Preservation」を翻訳してみました
## **原文はこちら**
https://ethernaut.zeppelin.solutions
16. Preservationをクリック
## **16. Preservation**
難易度 8/6
このコントラクトは、2つの異なるタイムゾーンの2つの異なる時間を格納するためにライブラリを利用しているぞ。
コンストラクタは、保存する時間ごとにライブラリの2つのインスタンスをしているぞ。
このレベルのクリア条件はインスタンス（コントラクト）のオーナーを自分自身のアドレスに変更することだ。

##### **回答の助けになるヒント**
- デリゲートコールにおける低レベル関数がどのように動作するか、デリゲートする為にはどのように使用するか、Solidityのドキュメントを参照せよ。
- delegatecallがコンテキストを保持する(context-preserving)とは？の理解
- ストレージ変数の格納方法とアクセス方法の理解
- さまざまなデータタイプ間でのキャストの仕組みの理解

## **ソースコード**

```javascript:
pragma solidity ^0.4.23;

contract Preservation {

  // public library contracts 
  address public timeZone1Library;
  address public timeZone2Library;
  address public owner; 
  uint storedTime;
  // Sets the function signature for delegatecall
  bytes4 constant setTimeSignature = bytes4(keccak256("setTime(uint256)"));

  constructor(address _timeZone1LibraryAddress, address _timeZone2LibraryAddress) public {
    timeZone1Library = _timeZone1LibraryAddress; 
    timeZone2Library = _timeZone2LibraryAddress; 
    owner = msg.sender;
  }
 
  // set the time for timezone 1
  function setFirstTime(uint _timeStamp) public {
    timeZone1Library.delegatecall(setTimeSignature, _timeStamp);
  }

  // set the time for timezone 2
  function setSecondTime(uint _timeStamp) public {
    timeZone2Library.delegatecall(setTimeSignature, _timeStamp);
  }
}

// Simple library contract to set the time
contract LibraryContract {

  // stores a timestamp 
  uint storedTime;  

  function setTime(uint _time) public {
    storedTime = _time;
  }
}
```
Level 17. Locked. Delegation（The Ethernaut）

「The Ethernaut by Zeppelin Level 17. Locked」を翻訳してみました
## **原文はこちら**
https://ethernaut.zeppelin.solutions
17. Lockedをクリック
## **17. Locked**
難易度 6/6
この名前登録コントラクトはロックされており、新しい名前を登録することはできないぞ。
このレベルのクリア条件は、この名前登録コントラクトのロックを解除することだ。
##### **回答の助けになるヒント**
- ストレージの仕組みの理解
- ローカル変数のデフォルトストレージタイプについての理解
- ストレージとメモリの違いの理解

## **ソースコード**

```javascript:
pragma solidity ^0.4.23; 

// A Locked Name Registrar
contract Locked {

    bool public unlocked = false;  // registrar locked, no name updates
    
    struct NameRecord { // map hashes to addresses
        bytes32 name; // 
        address mappedAddress;
    }

    mapping(address => NameRecord) public registeredNameRecord; // records who registered names 
    mapping(bytes32 => address) public resolve; // resolves hashes to addresses
    
    function register(bytes32 _name, address _mappedAddress) public {
        // set up the new NameRecord
        NameRecord newRecord;
        newRecord.name = _name;
        newRecord.mappedAddress = _mappedAddress; 

        resolve[_name] = _mappedAddress;
        registeredNameRecord[msg.sender] = newRecord; 

        require(unlocked); // only allow registrations if contract is unlocked
    }
}
```
Level 18. Recovery（The Ethernaut）

「The Ethernaut by Zeppelin Level 18. Recovery」を翻訳してみました
## **原文はこちら**
https://ethernaut.zeppelin.solutions
18. Recoveryをクリック
## **18. Recovery**
難易度 6/6
とあるコントラクト作成者は非常に簡単なトークンファクトリコントラクトを作成した。
（このコントラクトを利用すれば）誰でも簡単に新しいトークンを作成できるぞ。
最初のトークンコントラクトをデプロイした後、コントラクト作成者は0.5個のetherを送り、より多くのトークンを取得した。
しかし、彼らは以来 このコントラクトのアドレスを失ってしまった（泣）。
このレベルのクリア条件は、失われたコントラクトアドレスから0.5ETHを回収（または除去）することだ。

## **ソースコード**

```javascript:
pragma solidity ^0.4.23; 

// A Locked Name Registrar
contract Locked {

    bool public unlocked = false;  // registrar locked, no name updates
    
    struct NameRecord { // map hashes to addresses
        bytes32 name; // 
        address mappedAddress;
    }

    mapping(address => NameRecord) public registeredNameRecord; // records who registered names 
    mapping(bytes32 => address) public resolve; // resolves hashes to addresses
    
    function register(bytes32 _name, address _mappedAddress) public {
        // set up the new NameRecord
        NameRecord newRecord;
        newRecord.name = _name;
        newRecord.mappedAddress = _mappedAddress; 

        resolve[_name] = _mappedAddress;
        registeredNameRecord[msg.sender] = newRecord; 

        require(unlocked); // only allow registrations if contract is unlocked
    }
}
```
仕事でMacを使う時のオススメの初期設定とアプリ（最低限だよ）

# これは何？
デフォルトのMacの設定では、Macを仕事で使うには不十分です。
僕なりの最低限のカスタマイズをまとめてみます。
これだけで、
・だいぶ使いやすく
・安全に
なると思います。


# 設定
## Mac設定
### Macを使いやすく
・余計な文字入力を阻止
　設定 -> キーボード -> ユーザー辞書で、
　　「英数入力中にスペルを自動変換」をオフ
　　「文頭を自動的に大文字にする」をオフ

・文字入力を早める
　設定 -> キーボード -> キーボードで、
　　「キーのリピート」を「速い」にする
　　「リピート入力認識までの時間」を「短い」にする

・トラックパッド操作（マウスポインター）を早くする
　設定 -> トラックパッド -> 軌跡の速さを速くする

・Windowsっぽく使う（トラックパッドの右下クリックで右クリック）
　設定 -> トラックパッド -> ポイントとクリックで、　
　　「副ボタンのクリック」を右下隅をクリックにする。

・Windowsっぽく使う（トラックパッドシングルタップで左クリック）
　設定 -> トラックパッド -> ポイントとクリックで、　
　　「タップでクリック」を「１本指でタップ」にする。

・でかすぎるDOCKを小さくする
　設定 -> Dock -> サイズで、　
　　「小」の方にバーを動かす。

・Dockから不要なアプリを削除
　Dockにあるアイコンを右クリック（副クリック)すると、Dockから削除できます。

・Siriをオフにする
　設定 -> Siriで、　
　　「Siriに頼むを有効にする」のチェックを外す。

### Macをセキュアに
　設定 -> セキュリティとプライバシー -> 一般で、　
　　「スリープとスクリーンセーバーの解除にパスワードを要求」を１分後にする。

　設定 -> セキュリティとプライバシー -> ファイアウォールで、　
　　「ファイアウォールをオン」をオンにする。

## オススメアプリ（最低限）
・Macの変換を賢くする
　1)Google IME（変換ソフト）を以下URLからインストール。
　インストール完了後、IMEを有効にする。
　https://www.google.co.jp/ime/

　（が、個人的には、atokが最高におすすめです。atok→Googleにしたら作業効率落ちました。）

　2)標準のMac標準の変換ソフトを切る
　設定 -> キーボード -> 入力ソースで、Google以外のやつを「-」ボタンで消す

・高機能なテキストエディタで、テキストに関するあらゆる作業を効率化
　「CotEditor」をMacApp Storeよりインストール。

・Markdownエディタ
markdownエディターなら、マイクロソフトのVS　Codeというのがおすすめです。
めっちゃ書きやすいです＆無償です。　

・Macのアプリ検索やその他の作業効率を上げる
　AlfredをMacApp Storeよりインストール。
　インストール後、Altキー + スペースキーで、アプリの検索等が行なえます。
　アプリ以外にも使えるので、使い方はググってね。

・ウインドウの大きさを自動的に調整する
Better snap toolをMacApp Storeよりインストール。
複数ウインドウを立ち上げているときに、簡単操作で、ウインドウを1/2や1/4にしてくれます。

・ウイルス対策をする。
　Macもウイルス感染しますので、ウイルス対策ソフト入れましょう。
　いろいろありますが、ソフォス(sophos)が無償でおすすめです。（個人利用ならね。）
　ユーザー登録が必要ですが、入れておいたほうがいいでしょう。sophosはPCが不安定にもならないです。

・パスワード管理ツールを入れて、簡易パスワードの使い回しをやめる
　いろんなところで入れているパスワードを安全に管理してくれます。
　各サイトでパスワードを使い分けてもきちんと管理してくれます。
　パスワード使い回さないで、各サービスで分けましょう。
　今は色んなパスワード管理ツールがありますが、有名所は1passwordというソフトです。
　若干お高いですが、最も有名です。
　MacAppStoreで売っています。
　
・スクリーンショットに文字を入れたり、モザイクを入れたりする
　skitchをMacApp Storeよりインストール。
　これがあれば、スクリーンショット加工がとても簡単です。
　特にモザイクは結構使えます。

・Windowsの方にZipファイルを送るときは、専用の圧縮ソフトを使う
　Macの標準機能でフォルダをZip化するができます。
　ただ、このZipファイルをWindowsで解凍すると、
 ・文字化けが発生する可能性がある
　　・__MACOSXという見たこないファイルが出てくる
などの問題があります。
Windowsに送る場合は、専用の圧縮（Zip化）ソフトを使いましょう。
WinArchiver LiteというソフトがMacApp Storeにあります。
ソフトを起動して、フォルダをドラッグアンドドロップすれば圧縮されます。

・クリップボードの履歴を保存
ClipyをMacApp Storeよりインストール。
また、定型文的な機能もあります。色々便利です。

以上。
一気に書き出したので、随時追加します。
git aliasのすすめ

#aliasとは？
コマンドの呼び出しを自分でカスタマイズ出来る機能です。git checkoutとか毎回打ち込むのは面倒なのでgit coで呼び出したりして楽をします。

#設定方法
設定方法は簡単です。.gitconfigファイルに[alias]を追加してあげます。
こんな感じ↓↓↓

```
$ cd
$ pwd
/Users/user_name
$ ls -a #不可視ファイルですので`-a`オプションを付けないと表示出来ません。
.CFUserTextEncoding
.DS_Store
.Trash
.android
略
.gitconfig #<=これ
$ vim .gitconfig 
```

 - vimで開いて[alias]の部分を下図のように記述してください。(他のeditorでもOK)
<img width="571" alt="スクリーンショット 2018-06-18 12.27.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/253317/f7486b2c-895c-968e-0b9d-c9d2eae57aee.png">

#aliasの色々
僕はこんな感じで設定してます。

```
[alias]
        co = checkout
        ci = commit
        st = status
        br = branch
        pl = pull
        ps = push
```
他にもオススメのaliasあったら教えて欲しいです。
bash > 文字列処理 > replace_first_N_chars_180618_exec v0.1 > 一行の先頭文字列を別の文字列で書替える

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

### 処理概要

- `20180612 120000 beginning of the process`という文字列の先頭文字列を任意の文字列で置換える

### 参考

@tukiyo3 さんに[教えていただいた](https://qiita.com/7of9/items/4629d72f78b2a873543b#comment-82cd8399d1da308d944d)cutを使います。

### code v0.1

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

set -eu #just in case

# v0.1 Jun. 18, 2018
#   - replace first 15 chars
#

function replace_datetime () {
	# [cmd] [INTXT] [TOTXT]
	# e.g. [cmd] "20180612 120000 ..." "20180618 230000"

	echo "$2"$(echo $1 | cut -b "16-")	
}

# original text
#      1234567890123456
INTXT="20180612 120000 beginning of the process"
# new date and time
TOTXT="20180618 230000"

# example
echo $INTXT
res=$(replace_datetime "$INTXT" "$TOTXT")
echo $res
```

### 実行

```bash
$ bash replace_first_N_chars_180618_exec 
20180612 120000 beginning of the process
20180618 230000 beginning of the process
```

### 注意点

文字列の中に空白を含めるためreplace_datetime 使用時は二重引用符で囲うこと。

### 備考

先頭のN文字列のNは固定にしている。

今は可変である必要がないため。
ファイルの先頭・末尾を指定行数分だけ除去する (head, tail)

```html:hello.html
<!DOCTYPE html>
<html>
<head>
<title>商品103</title>
<meta charset="utf-8">
</head>
<body>
<table border="1">
<tr><th>商品番号</th><td>103</td></tr>
<tr><th>商品名</th><td>ジャガイモ</td></tr>
<tr><th>単価</th><td>80</td></tr>
<tr><th>在庫</th><td>150</td></tr>
<tr><th>備考</th><td>
ナス科ナス属<br/>
ポテトチップス<br/>
肉じゃが
</td></tr>
</table>
</body>
</html>
```
tableタグの部分だけ切り出したい。

```
$ (head -n -2 | tail -n +8) < hello.htm
<table border="1">
<tr><th>商品番号</th><td>103</td></tr>
<tr><th>商品名</th><td>ジャガイモ</td></tr>
<tr><th>単価</th><td>80</td></tr>
<tr><th>在庫</th><td>150</td></tr>
<tr><th>備考</th><td>
ナス科ナス属<br/>
ポテトチップス<br/>
肉じゃが
</td></tr>
</table>
```
ファイルの先頭から末尾から2行目までを表示（末尾2行を除去：`head -n -2`：）し、
先頭から8行目から末尾までを表示（先頭7行を除去：`tail -n +8`）する。
GPD PocketのLinuxでwifiが使えなくなった

dmesgにこんな出力が出る。

```
direct firmware load for brcm/brcmfmac4356-pcie.clm_blob
```

https://bugs.launchpad.net/ubuntu/+source/linux-firmware/+bug/1772624

ここを見ると、どうやらlinux-firmwareの最新のバージョンにBCM4356のバグがあるらしい。
ということで最新のバージョン（linux-firmware-20180606）から前のバージョン（linux-firmware-20180518）にダウングレードして解決。
ftplibで日本語を扱う最適解

# 概要
ftplibで日本語を扱うまでに結構紆余曲折してしまったので最適解であろうコードを共有します。

# 結論
```python
from ftplib import FTP

# ※正解: インスタンス生成前に設定を変更する
FTP.encoding = "utf-8"

# あとはお好きに
ftp_instance = FTP(~,~)

# ※よくある間違い: インスタンス生成後に設定変更
#   エラー文は変わるが、結局デコードなどを行う必要がありそう
#   (ここから正常動作まで持っていったことがないので未検証)
ftp_instance.encoding = "utf-8"
```

# 余談
teratailの記事が見つかるまではftplib内のencodingを直接書き換えてました…。
正直、FTPクラスにencoding引数がある方がスマートな気がするんですが、今のとこそういったプルリクもなさそうなのでだれか改善提案をば…！

# 参考
https://teratail.com/questions/128468
下の記事はぐぐるとわりとトップに出てくるけど間違っているやつ
https://stackoverflow.com/questions/29523067/python-reading-ftp-file-list-with-utf-8
学習記録(3) -C言語

1.使用言語
　　C言語
2.製作時間
　　約30分
3.内容
　　入力された3つのお題から1つを選ぶ
4.できたこと
　　構造体の使用 -Odais
　　時間の使用 -time.h, time()
5.できなかったこと
　　動的なメモリの使用

```oekaki.c
#include <stdio.h>
#include <time.h>

typedef struct{
  char *odai0;
  char *odai1;
  char *odai2;
} Odais;

void randomOdai(Odais s);

int main(void){
  char odai0[50];
  char odai1[50];
  char odai2[50];

  Odais odais;

  printf("お題を三つ入力してください。\n");
  printf("一つ目：");  scanf("%s", odai0);
  printf("二つ目：");  scanf("%s", odai1);
  printf("三つ目：");  scanf("%s", odai2);

  odais.odai0 = &odai0[0];
  odais.odai1 = &odai1[0];
  odais.odai2 = &odai2[0];

  randomOdai(odais);

  return 0;

}

void randomOdai(Odais s){
  time_t timer;

  int sec = time(&timer);

  if (sec % 3 == 0) {
    printf("選ばれたお題は%sです。\n", s.odai0);
  } else if (sec % 3 == 1) {
    printf("選ばれたお題は%sです。\n", s.odai1);
  } else {
    printf("選ばれたお題は%sです。\n", s.odai2);
  }
}
```
初めてのSQL Server in Azure の巻

#目的
AI や App で利用するDB を作成する

#目標
基本的な操作を学習する

#KPI
DB を作成し、テーブルを作れる状態を作る
テーブルを作成し、値を入力できる状態を作る
データ投入し、クエリで値を参照できる状態を作る

#前提
最低限、下の知識が必要
https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-design-first-database

まずは、Azure で、SQL データベース　を作成する
Azure サービスログイン後、トップページで、
 SQL データベースから作成

Visual Studio をインストール。
ご存知の方も多いかと思いますが、SDK なんで重いっ！！
10GB 程度あるので、時間のある時に済ませて下さい。
　※Visual Studio はいらないかも。。。重すぎて、アンインストールして試験するのが怖いので、やらない！

SQL Server Management Studio(以降、SSMS) も同じく必要なので、インストール。
こいつも重いっ！　0.8G あります！

Azure のDB ページにアクセスして、"次に接続" を選択
"Visual Studio で開く" を実行

Visual Studio から、db ログイン情報を入力して、db 名が見えたらok

#DB を作成
SQL データベースを作った際にできてた。
これは、ok

特に記載がない場合、SSMS 上での操作を指します。

#テーブルを作成
初期設定で、なんかテーブルあるやん、、、
・システムテーブル
・ファイルテーブル
・外部テーブル

なんこれ？
まずは、初期値のテーブルを勉強、、、
##システムテーブル
下を参照
https://docs.microsoft.com/ja-jp/sql/relational-databases/system-tables/system-tables-transact-sql?view=sql-server-2017

つまり、こいつには、触れるなと。。。
参照はOK だけど、削除や変更をすんじゃねぇとおっしゃられておるように感じます。
今回は放置（変更、参照しない）方針で。

##ファイルテーブル
https://docs.microsoft.com/ja-jp/sql/relational-databases/blob/filetables-sql-server?view=sql-server-2017
こいつは、便利機能用のテーブルで、こいつも触るなと。。。
Windows API や他の SQL Server 機能との互換性を実現してくれるんだと。
こいつも放置で。
つまり、外部テーブルも放置するやつか？

##外部テーブル
Oracle でも同じ機能があるようで、下のサイトが外部テーブルについて分かりやすかった
https://www.shift-the-oracle.com/utility/

"外部ファイルに対して、あたかもテーブルが存在するかのようにアクセスすることができる" そうです。
キャッシュしておいて、読み込み速度を上げたり、認証を自分のDBで行ったりするのが役目かな。
これも、放置で良さそうな。

##App 用のテーブルを作成
GUI で作成するのは初めて！
コマンドベースではなく、どこをクリックや操作したか、メモ。

SQL Server オブジェクトエクスプローラーの"テーブル" を右クリック　＞　新しいテーブルの追加

デザインというページが開かれ、エクセルに入力するように下のような情報を投入
・名前
・データ型

今回は、ID(主キー)と服の色データを保存する用途。
RGB で服を判定して、類似の服をAI で推薦させたい。

テーブルについては、下のサイトを最低限学ぶ
https://docs.microsoft.com/ja-jp/sql/relational-databases/tables/create-tables-database-engine?view=sql-server-2017

下のテーブルを作成
名前　｜属性
・ID 　｜INT
・服の白黒　｜INT
・服の赤み　｜INT
・服の緑み　｜INT
・服の青み　｜INT

ID を主キーにしたいので、ID を右クリック　＞　主キーに設定　

Ctrl + S キーで、名前"服の評価" テーブルを保存。
オブジェクトエクスプローラーの更新　をクリック
#オブジェクトエクスプローラーの更新　をクリック
※反映されたか確認できず、1時間以上サイトをさまよってしまった笑　皆さんが、すぐ解決できることを祈りますｗ


#データ投入
先程作った"服の評価" テーブルへサンプルデータを投入する。
GUI 操作は、なんか怖い（追跡性が薄い＋GUI 更改で追えなくなることが多い）ので、ここからは、クエリでやる。
SSMS から操作
ファイル　＞　新規作成　＞　クエリを現在の接続で実行
すると、クエリを投げるスペースが開く

下のクエリを実行

```
INSERT fukudb.dbo.服の評価(ID, 服の白黒, 服の赤み, 服の緑み, 服の青み)  
    VALUES (1, 2, 3, 4, 5)  
GO
```

dbo.服の評価 を選択して、
　右クリック　＞　上位200行の編集
　上で入力した 1,2,3,4,5 の値があることを確認して完了

#所感
初めて、SQL Server Management Studio(以降、SSMS)  を使った。
GUI ベースで使いやすく、学習コストを抑えることができる。
ただ、容量が重く、作業PC にスペックを要することが難点か。
　検証機や作業PC を調達できるならば、SQL Server は、人材育成のコストを抑えやすく素晴らしいことが分かった。

SDK もあるし、SQL Server は、いいDBMS だと思う。
HerokuにvagrantからRailsアプリケーションをデプロイする

## 技術要件

- Windows10
- vagrant2.0.1
- Ubuntu16.04
- Ruby4.2.1
- Rails5.1.1

既にvagrant上にRailsアプリを作ってあることを前提に話を進めていきます。

## gemの追加

HerokuではPostgreSQLデータベースを使います。
そのためには、本番 (production) 環境にpgというgemをインストールし、RailsがPostgreSQLと通信できるようにします。

```ruby
group :production do
  gem 'pg', '0.20.0'
end
```

HerokuではSQLiteがサポートされていないため、sqlite3 gemが本番環境に導入されないようにしておきます。

```ruby
group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end
```

本番用のgem (この場合はpg gem) をローカルの環境にはインストールしないようにするために、bundle installに「--without production」を追加します。

```
$ bundle install --without production
```

これをpushします。

```
$ git commit -a -m "Update Gemfile for Heroku"
```

## Herokuのインストール

Herokuの公式サイト
https://signup.heroku.com/
から、アカウントを作成してください。

そうしたらHerokuをインストールしましょう。

```
$ curl https://cli-assets.heroku.com/install-ubuntu.sh | sh
```

続いて、自分のシステムにHerokuコマンドラインクライアントがインストールされているかどうかを確認します。

```
$ heroku --version
```

これでバージョンがきちんと表示されれば大丈夫です。
いよいよHerokuにログインして、SSH鍵を設定します。

```
$ heroku login
$ heroku keys:add
```

最後にheroku createコマンドを実行して、Herokuサーバーにサンプルアプリケーションの実行場所を作成します.

```
$ heroku create
```

## デプロイ

Railsアプリケーションをデプロイしましょう！

```
$ git push heroku master
```

アプリケーションのデータベースを動作させるためには、次のheroku runコマンドを実行して本番データベースのマイグレーションを行う必要もあります.

```
$ heroku run rails db:migrate
```

これで動くはずです！

Railsアプリケーションを更新したいときは、git commit、git pushし、herokuにもpushすればOKです！
WIP:開発環境構築を自動化したときCIでチェックしておきたいこと

開発環境構築の自動化したとき、「開発環境がいつのまにか壊れていた」「起動できなくなった」を避けるために、CIでチェックしておきたいこと。

* マイグレーション
    * 冪等性のチェック
        * 2回以上マイグレーションする
    * downのチェック
        * N個前にdownしupする
* 開発環境用データの生成プログラム
    * メンテされない傾向にあるので、CIでチェックする
        * これがメンテされないと、本番データをダンプして開発環境に入れるという危ない運用が始まってしまう
* Dockerコンテナ
    * buildしなおせるか
    * docker up できるか
* フロントエンド
    * dev-serverが立ち上がるか？
    * コンパイルできるか？
Unity用にアンドロイドプラグインを作成する際のメモ

Android Studioでの作業

android plugin 作成

"android studio"で適当にプロジェクトを作成
"android studio"で"android libraly"を作成

Unityと連携させるために、Unityのプログラムフォルダ？にある"classes.jar"を
"android library"の"libs"フォルダにコピー
"classes.jar"をaarに内包してコンパイルしてしまうと、Unityでのビルド時失敗する
"classes.jar"をaarに内包させないよう、除外する

変更(gradle)
implementation fileTree(dir: 'libs', include: ['*.jar'])
↓
compileOnly fileTree(dir: 'libs', include: ['classes.jar'])

追記(gradle)
android.libraryVariants.all{ variant->
    variant.outputs.each{output->
        output.packageLibrary.exclude('libs/classes.jar')
    }
}

スクリプト作成
Unityにメッセージを投げられるようUnityのクラスをimport

import static com.unity3d.player.UnityPlayer.UnitySendMessage;

クラスの引数にString形式の"callbackTarget"と"callbackMethod"を入れる
UnitySendMessageにより、String形式の文字列をやりとりできるようになる
UnitySendMessage(callbackTarget, callbackMethod, "onReadyForSpeech");

Unityでの作業

AndroidJavaClass TestClass = new AndroidJavaClass("パッケージ名.クラス名");
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

context.Call("runOnUiThread", new AndroidJavaRunnable(() =>
    {
        TestClass.CallStatic(
            "TestClassで定義しているfunction名",
            context,
            gameObject.name,
            "CallbackMethod"
        );
    }
));

private void CallbackMethod(string message)
{
    Debug.Log(message);
}

これにより、aarで定義した関数を実行し、返り値をUnityで定義した関数に渡すことができる
Python を setup.pyでパッケージ化してみる

Pythonで作成したプログラムをパッケージ化して配布したいときがありますよね。
例えば単純に「hello world」を表示するプログラムを作ったとします。

hello.py 

 ```hello.py 
str1 = "hello world"

def main():
    print(str1)

if __name__ == '__main__':
    main()
 ```

こんな感じにコマンドを叩けば表示されますね。

```bash
admin$ python ./hello.py
hello world
```

コマンドを打つのが面倒い場合はパッケージ化することで多少は楽になります。
パッケージ化するにはsetup.pyが必要となります。
パッケージの名前や依存関係などを含むファイルを定義してあげます。

 ```setup.py
from setuptools import setup

setup(
    name='hello',
    entry_points={
        'console_scripts': [
            'hello = hello:main',
        ],
    }
)
```

setup.pyの定義が終わったら python setup.py develop を打つことでdevelop用にインストールされます。

```bash
admin$ python setup.py develop
running develop
running egg_info
省略
Installed /Users/admin/Desktop
Processing dependencies for hello==0.0.0
Finished processing dependencies for hello==0.0.0
```

あとはhelloを打つだけで、「hello world」が表示されます。

```bash
admin$ hello
hello world
```

それでは、Enjoy your pypy and Python life!
Dockerネットワーク設定


## 現在のネットワークを確認
ネットワーク一覧を確認します。

```
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
23847b6h3971        bridge              bridge              local
34368dnf9b16        host                host                local
02em5e1bec4f        none                null                local
```

bridgeのネットワークを確認。

```
$ docker network inspect bridge
```

##Dockerネットワークを作成
ブリッジネットワーク br0を作成してみます。

```
$ docker network create --subnet=192.198.160.0/24 br0
```

##追加したネットワーク内にコンテナを作成

作成したbr0内のIPを指定してコンテナを作成＆起動します。

```
$ docker run -it --name containername -h hostname --net=br0 --ip=192.198.160.10 ubuntu bash
```

IP確認

```
$ docker inspect -f "{{.NetworkSettings.IPAddress}}" コンテナID
```
RubyMineで when ~ then を1行で書きたい

RubyMineで`when ~ then`を一行で書きたかったのですが、設定の`keep line break`をオンにしていても`Reformat Code`すると改行されてしまいます。

### 原因と対策

原因はRubyMineのバグです。なので対策は開発陣にお願いすることしかできません。

https://youtrack.jetbrains.com/issue/RUBY-13869

でアカウントを作成して投票(upvote)していきましょう。5年も前のバグなのでそろそろなおして欲しいものです。
Vagrantで立ち上げたゲストOSからDockerで起動したMySQLにアクセスする


なんだその構成っていわれそうですが、Vagrantで立ち上げたゲストOSからDockerで起動したMySQLサーバにアクセスしたい状況だったんですよ^^;

（余談。元々はVagrant上に開発テスト環境があって、データ移行プログラム開発のために別途MySQLサーバを立ち上げるのにDocker使ったって状況です）

# MySQLのポート確認

Dockerで起動してるMySQLサーバについては ```docker-compose.yml``` に記載してあるのでこれを確認。

```
version: '2'
services:
    v1db:
      image: mysql:5.6
      # volumes_from:
      #   - data-mysql
      volumes:
          - ./db/mysql_data:/var/lib/mysql
      ports:
        - "23306:3306"
      environment:
        MYSQL_ROOT_PASSWORD: ****
```

posrtsをみるとlocalhost（ホストOS)の23306ポートに接続すればDockerのMySQLサーバに接続できるのがわかる。


なのでVagrant上のゲストOSからホストOSの23306ポートにアクセスすればDockerのMySQLサーバにアクセスできるはずである

# ホストOSのIPは？

VirtualBox上の仮想マシンのネットワークはNATがデフォルトのようで、この場合のホストOSのIPは __10.0.2.2__ に固定されてるようです。

というわけでゲストOSからDockerのMySQLにつなぐには下記で大丈夫でした

```
mysql -h 10.0.2.2 -P 23306 -u root -p
```
AWS 最低限セキュアでかつお財布に優しいLAMP環境構築  2018年初夏 (VPC/EC2/RDS)

LAMP構成のサービスをAWS環境へ移行する案件のため、
コストを抑えつつ最低限セキュアな構成について備忘のためまとめます。

# 前提: 移行対象の環境について

- PHP　5系
- MySQL ５系

で常時SSLなWordPressが動く環境であればOK。
[AWS x WordPressのベスプラ](https://d0.awsstatic.com/whitepapers/wordpress-best-practices-on-aws.pdf) のようなカリカリのチューニングが求められる非機能要件はない。


# 結論:

<img width="972" alt="AWS構成-LAMP.png" src="https://qiita-image-store.s3.amazonaws.com/0/51734/67f7f74b-cb09-5afa-e6bb-bdd6517a50a4.png">

いろいろ参考にしたが、以下の公式のチュートリアルに載ってる構成に落ち着いた。
[AWS-WordPress ウェブサイトを構築する](https://aws.amazon.com/jp/getting-started/projects/build-wordpress-website/)

## 節約ポイント

- ポイント①:  
無料利用枠を使い倒す。 (ALB/EC2/RDS は1年間 1つ分は無料)
- ポイント②:  
Webインスタンスはpublic subnetに配置し、PublicIP自動割当を利用し、EIP/NATゲートウェイ/NAT インスタンスは使わない。

>[【AWS】VPC環境構築ノウハウ社内資料 2014年4月版](https://dev.classmethod.jp/cloud/aws/vpc-knowhow-2014-04/)
>NATを上手く利用するケースもまだあるかもしれません。が、基本的にもうNATは不要だと言って良いでしょう。

- ポイント③:  
Bastion(踏み台)サーバは使うときだけ起動。
- ポイント④:  
冗長化不要なサービスレベルであれば省く。

冗長化不要であれば、実質コストがかかるのは、「Bastionサーバ稼働分」、「Route53のゾーン管理分」程度なので、アカウント開設後1年間は月1000円未満で運用可能なはず！ (自己責任でお願いしますmm)

1年過ぎた2年目からEC2の費用かかってくるのでリザーブドインスタンス用いれば多少はコストを抑えられるはず。

## 参考

* [AWSで最低限セキュアな構成を組む](https://qiita.com/ausuited/items/09b626fa5264f0c650fd)
* [【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう
](https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/)
* [【AWS 再入門】VPC 環境に踏み台サーバーを構築して SSH 接続してみよう](
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-bastion-host-vpc/)
* [カンタンにAWS EC2とRDSを使ってWordPressを動かしたい！！](http://blog.serverworks.co.jp/tech/2016/11/02/first-wordpress/)
PHPからFacebookGraphAPIを使って複数枚画像が添付された投稿を行う方法

# FacabookのAPIで画像を添付した投稿方法
業務でFacebook APIを使うことになり、画像を一緒に投稿しようとしたところで盛大に詰まったので、備忘録 兼 同じところで困ってる人いたら役に立てばいいなと。

# 前提
* php-graph-sdk v5.6.2  https://github.com/facebook/php-graph-sdk
（Facebook SDK）
* PHP 5.6

# 参考にしたページ
https://developers.facebook.com/docs/graph-api/photo-uploads
（ここ見つけるまでの時間が長かった。。。）

# コード

```php
define("FACEBOOK_APPID", "<アプリID>"); 
define("FACEBOOK_SECRET", "<シークレットトークン>"); 
define("FACEBOOK_ACCESSTOKEN", "<アクセストークン>");


$fb = new \Facebook\Facebook([
    'app_id' => FACEBOOK_APPID,
    'app_secret' => FACEBOOK_SECRET,
    'default_graph_version' => 'v3.0',
]);

$fbApp = new Facebook\FacebookApp(FACEBOOK_APPID, FACEBOOK_SECRET);

$imgFilePath = "{画像のファイルパス}";

try {
    // Returns a `Facebook\FacebookResponse` object
    $response = $fb->post(
        '/me/photos',
        array (
            'source' => $fb->fileToUpload($imgFilePath),
            'published' => 'false'
        ),
        FACEBOOK_ACCESSTOKEN
    );               

    $graphNode = $response->getGraphNode();
    $photoIds[] = ['media_fbid' => $graphNode['id']];

} catch(Facebook\Exceptions\FacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}

$data = [
    'message' => "{投稿したいメッセージ}",
];           

//画像の添付処理（アップロードしたときに取得したIDを設定する
foreach ($photoIds as $key => $photoId) {
    $attachedMediaId = "attached_media[" . $key . "]";

    $data = array_merge(
        $data,
        ["$attachedMediaId" => $photoId]
    );
}

try {
    $response = $fb->post(
        '/me/feed',
        $data,
        FACEBOOK_ACCESSTOKEN
    );
} catch(Facebook\Exceptions\FacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}

```

ポイントはこの部分です。

```php:
$response = $fb->post(
        '/me/photos',
        array (
            'source' => $fb->fileToUpload($imgFilePath),
            'published' => 'false'  // これをつけ忘れると、feed投稿時にエラーに！！！
        ),
        FACEBOOK_ACCESSTOKEN
    );  
```
「'published' => 'false'」を入れないと写真単体の投稿として扱われて、記事への紐付けができなくなってしまいます。
（ここで躓いて１時間は消費してしまった）
CircleCIでRedisへの読み書きの単体テストを実行する

# はじめに

高速に動作するキャッシュとしてRedisを使うことがよくあります。しかし、書き込み、読み込みのテストをするために、毎回Redisサーバーをインストールして起動してとやるのは面倒です。CircleCIならきっと便利な機能が用意されているはず、ということで調査した話です。


# 結論

```yaml:.circleci/config.yml
jobs:
  test:
    docker:
      - image: circleci/python:3.6.1
      - image: redis:3.2.11
    steps: 
      - checkout 
      - run:
          name: run unittest
          command: |
            python -m unittest discover tests/
```

`- image: redis:3.2.11`を記述するだけです。
この状態でテストの中で、localhost:6379への読み書きを記述すると、Redisサーバーに接続できるようになっています。

# 参考

https://circleci.com/docs/2.0/executor-types/#using-multiple-docker-images
Tree Shakeable Providers and Services in Angular (日本語訳)

[インフラジスティックス・ジャパン](https://jp.infragistics.com/) の Paul です。

先日２０１８年６月１６日 土曜日に 開催されました、
[ng-japan 2018](https://ngjapan.org/) の キーノートセッションにて挙がっていた、
Tree Shakeable Providers について、
分かりやすい記事を見つけましたので共有します。

[Tree Shakeable Providers and Services in Angular (英語原文)](https://coryrylan.com/blog/tree-shakeable-providers-and-services-in-angular)

[Tree Shakeable Providers and Services in Angular (Google Translate 日本語訳)](https://translate.google.com/translate?sl=en&tl=ja&js=y&prev=_t&hl=en&ie=UTF-8&u=https%3A%2F%2Fcoryrylan.com%2Fblog%2Ftree-shakeable-providers-and-services-in-angular&edit-text=&act=url)
※機械翻訳なので少し微妙な翻訳となっていますが、英語原文を見ながらであれば理解できると思います。

Angularアプリケーションの実行パフォーマンスを上げるための重要なポイントとなりますね。

今後もAngular関連の情報共有をたくさんできるようにしたいと思います。