OmniAICreator/Qiita-1.07M huggingface dataset:
Windows+Vagrantでcomposer installすると"Could not delete /vagrant/vendor/"エラーが発生する場合の対処

## エラーの内容

Windows+Vagrant(VirtualBox)の環境でcomposer installを実行した際、以下のエラーが発生しました。
（開始後数秒で発生）

```
  - Installing kylekatarnls/update-helper (1.1.1): Reading /home/vagrant/.cache/composer/files/kylekatarnls/update-helper/b43c77a2aeb46815c21e75203bfa7b68c3c25b08.zip from cache
Loading from cache
 Extracting archiveExecuting command (CWD): unzip -qq  '/vagrant/vendor/kylekatarnls/update-helper/466d1f46652da6405e025fc97e3b7597' -d '/vagrant/vendor/composer/fe5048b1'
Plugin installation failed, rolling back
  - Removing kylekatarnls/update-helper (1.1.1)


  [RuntimeException]
  Could not delete /vagrant/vendor/kylekatarnls/update-helper/src/UpdateHelper:


Exception trace:
 () at phar:///usr/bin/composer/src/Composer/Util/Filesystem.php:217
 Composer\Util\Filesystem->unlink() at phar:///usr/bin/composer/src/Composer/Util/Filesystem.php:170
...(以下略)...
```

## TL;DR
"Plugin installation failed"というのが気になり以下のように実行したところ、通るようになりました。

```
composer install --no-plugins
```

※"プラグイン"とは何かを理解せずに無効にしているので、その点が少し心配です。


## その他に考えられるもの

今回の事象には当てはまらなかったものの、以下の記事も参考にしました。

* [Error in composer update] (https://github.com/kylekatarnls/update-helper/issues/3)
    * エラーメッセージの出たパッケージのIssueにあったもので、事象は同じですが、ここではcomposer.pharをカレントディレクトリに直接インストールして"php composer.phar install" したところ解決したとのことです。私の環境ではこの方法では解消しませんでした。
* [composer で Could not delete エラーで先に進めなくなった場合の対処法](https://qiita.com/waterada/items/b47daf501e5fe1a70743)
    * 今回は開始直後に発生したため、タイムアウトが原因でこの事象が発生するようです。
Sinatraでエラーメッセージが表示されない問題

今Sinatraを使って掲示板を作っているんですけど、エラーメッセージ実装で戸惑ったのであげておきます。

#前提
投稿フォームの入力欄はタイトルと本文。
どちらも空白は駄目です。

バリデーションで引っかかった際は投稿フォームに戻りエラーメッセージが表示されます。

![エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281802/10a51b22-52c7-c854-ef1e-14042709d879.png)

こちらが実際に出来たページです。

#苦戦したところ
最初は「バリデーションに引っかかったらエラーメッセージを配列に入れてViewに渡せばいいだけだから簡単じゃん」と思っていました。

しかし、何故かViewで表示されない。
そこでデバッガで見てみるとどこかのタイミングで配列がnilになっていました。

それは表示されねえや！（笑)と思いながら原因を探りました。

#解決策
初めの僕のコードは以下のようになっていました。

```rb
post '/posts/create' do
  @post = Post.new(title: params[:title], body: params[:body])
  if @post.save
    redirect '/posts/page/1'
  else
    @errors = @post.errors.full_messages.uniq!
    redirect '/posts/new'
  end
end
```

redirectが問題でした。
redirectされるとアクションが呼び直されてしまうので@errorsがnilになってしまうのです。

ですので、redirectせずそのままViewファイルを渡してあげます。

```rb
post '/posts/create' do
  @post = Post.new(title: params[:title], body: params[:body])
  if @post.save
    redirect '/posts/page/1'
  else
    @errors = @post.errors.full_messages.uniq!
    erb :new_post
  end
end
```

これで無事エラーメッセージが表示されるようになりました。

#まとめ
今回はsinatraでエラーメッセージを表示させる方法についてまとめました。
sinatraは参考になるサイトも少ないので僕自身とても苦戦しています。
同じような環境の人の解決のきっかけになれれば幸いです。
if文は本当に遅いのか？if文の代わりにbit演算で絶対値を求めるアルゴリズムを書いてGoでベンチマーク取ってみた

# この記事はなに？
「Turing Complete FM」面白いですよね。
[この回](https://turingcomplete.fm/13#t=56:11)を聞いていて、絶対値を求めるアルゴリズムの速度について気になったのでベンチマークテストをしてみました。

## 先に結果から
- 絶対値を取るアルゴリズムについて、少なくともGo1.11.2以降であればif文を使っても速度面でのデメリットはないよ
- 速度面でのデメリットがないので、可読性を考慮して普通にif文を使って書く方がおすすめだよ
- ただし、Atcoderで使用されているGo1.6については速度差が出るので、Atcoderで少しでも実行速度を上げたいならif文を使わずに実装した方がいいよ
- [ベンチマークの実行結果はこちら](#ベンチマーク)


## 絶対値を求めるアルゴリズム
### bit演算を使用してif文を使わないアルゴリズム(Turing Complete FMで紹介されていたもの)

```go
const intSize = 32 << (^uint(0) >> 63)

func abs(x int) int {
	m := x >> (intSize - 1)
	return (x ^ m) - m
}
```

簡単に解説しておくと、1行目ではintSizeが32bitか64bitかを判定しています。（参考：[TCFMのるいさんによるQiita記事](https://qiita.com/ruiu/items/28c77ed483cec365fe84)）
`m := x >> (intSize - 1)`では、xの最上位ビットを最下位ビットまで右シフトしているので、xが負のときは`1`が連続するために`m := -1`となり、xが非負のときは`m := 0`となります。
続く`(x ^ m) - m`の部分で、xが負のときは2の補数と同様の計算式となり、`(x ^ -1) + 1`となるので、xのbitを全部反転して1を足していることになります。xが非負のときは`(x ^ 0) - 0 = x`となってxがそのままreturnされます。
詳しくは[こちら](https://turingcomplete.fm/13#t=56:11)を聞いてください。

### if文とかけ算を使用するアルゴリズム
```go
func ifAbs(x int) int {
	if x < 0 {
		return -1 * x
	} else {
		return x
	}
}
```

### if文のみ使用してかけ算を使わないアルゴリズム
```go
func ifAbsAnd(x int) int {
	if x < 0 {
		return -1 ^ x + 1
	} else {
		return x
	}
}
```
なぜわざわざかけ算をしないバージョンを用意しているのかというと、TCFM内でかけ算も遅くなりがちであるという話が出たためです。
こちらについても一緒にベンチマークを行ってみます。

## ベンチマーク
### ソースコード
<details><summary>ベンチマークソースコード（長いのでたたんでいます）</summary><div>

```go
package test

import (
	"testing"
)

const intSize = 32 << (^uint(0) >> 63)
const loop = 1000000

func abs(x int) int {
	m := x >> (intSize - 1)
	return (x ^ m) - m
}

func ifAbs(x int) int {
	if x < 0 {
		return -1 * x
	} else {
		return x
	}
}

func ifAbsAnd(x int) int {
	if x < 0 {
		return -1 ^ x + 1
	} else {
		return x
	}
}

func BenchmarkAbs(b *testing.B) {
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for j := 0; j < loop; j++ {
			_ = abs(i)
		}
	}
}

func BenchmarkIfAbs(b *testing.B) {
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for j := 0; j < loop; j++ {
			_ = ifAbs(i)
		}
	}
}

func BenchmarkIfAbsAnd(b *testing.B) {
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		for j := 0; j < loop; j++ {
			_ = ifAbsAnd(i)
		}
	}
}
```
</div></details>

### ベンチマーク実行結果
それぞれ「MacOS Mojave10.14.5」で[Docker Official Images](https://hub.docker.com/_/golang)を使用して実行しました。
結果は冒頭に記載した通り、Go1.11.2では実行速度差がほとんど出ず、Go1.6ではif文を使用しないアルゴリズムが倍程度早く実行されました。

#### Go1.11.2
```
root@21b57f8e170a:/go/benchmark/test# go test -bench .
goos: linux
goarch: amd64
BenchmarkAbs-4              5000            305530 ns/op
BenchmarkIfAbs-4            5000            301753 ns/op
BenchmarkIfAbsAnd-4         5000            306744 ns/op
```

#### Go1.6
```
root@5e04c8c946b5:/go/benchmark/test# go test -bench .          
testing: warning: no tests to run
PASS
BenchmarkAbs-4              2000            605807 ns/op
BenchmarkIfAbs-4            1000           1188589 ns/op
BenchmarkIfAbsAnd-4         1000           1171685 ns/op
```

## 所感
- 同じソースコードで同じマシンで実行した結果にも関わらず、Go1.6とGo1.11.2では2倍から4倍ほど早くなっていたことが驚きだった
- レガシーなソースコードの速度改善をする場合、アルゴリズムとは別にGo自体のバージョンアップを行うことで速度が改善することもあるかも
- Atcoder、Goのバージョン上げてくれ頼む・・・！！
gpsの研究　その52

#概要

gpsを理解したかった。
AgriBusNAVIで、遊んでみた。
wemosで、bt04を使ってみる。
AgriBusNAVIからは、BLUETOOTHなGPSに見える。

#写真

![DSCN0358.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/095df581-0454-260a-dc41-75e9b0ec91d2.jpeg)

#接続

```
bt04    wemos
RXD  -   D14
TXD  -   D15
G    -   g
VCC  -   3.3v
```

以上。
Ubuntu18.04にElements環境を構築する

#はじめに
Hello Qiiters!
しがない大学生の卒研用備忘録.

#環境構築
Ubuntu 18.04(初期化済み)

###STEP1: Bitcoin Coreのインストール
以下Ubuntuのターミナルで実行

```terminal
sudo apt-add-repository ppa:bitcoin/bitcoin
sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install bitcoind
```

正常にインストールされているかチェック

```terminal
which bitcoind
>/usr/bin/bitcoind
```
上記ならOK.
尚, 他環境ではどうなるかわからない.

###STEP2:Elementsのインストール
**STEP2-1:Gitのインストール**

```terminal
sudo apt install git
```

**STEP2-2:Gitからリポジトリをクローン**
*注意: ご自身のホームディレクトリに移動してからクローンしてください[初期:/home/username]*

```terminal
git clone https://github.com/ElementsProject/elements.git
```

**STEP2-3:必要なパッケージをインストール**

```terminal
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
sudo apt-get install libboost-all-dev
sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler imagemagick librsvg2-bin
sudo apt-get install libqrencode-dev autoconf openssl libssl-dev libevent-dev
sudo apt-get install libminiupnpc-dev
sudo apt-get install libdb4.8-dev libdb4.8++-dev
sudo apt install jq
```

インストールが終わったら, ホームディレクトリにある(であろう) `elements`に移動

```terminal
cd elements
```

**STEP2-4:Elementsのインストール**
上記コマンドでディレクトリの移動ができたら, 以下のコマンドを叩く.

```terminal
./autogen.sh
./configure
make
```

最後に`make install`っと...
ん？エラーが出たぞ.

```terminal:エラー文
$ make install
Making install in src
make[1]: ディレクトリ '/home/yu/elements/src' に入ります
make[2]: ディレクトリ '/home/yu/elements/src' に入ります
make[3]: ディレクトリ '/home/yu/elements' に入ります
make[3]: ディレクトリ '/home/yu/elements' から出ます
make[3]: ディレクトリ '/home/yu/elements/src' に入ります
make[4]: ディレクトリ '/home/yu/elements' に入ります
make[4]: ディレクトリ '/home/yu/elements' から出ます
 /bin/mkdir -p '/usr/local/lib'
 /bin/bash ../libtool --preserve-dup-deps  --mode=install /usr/bin/install -c   libelementsconsensus.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libelementsconsensus.so.0.0.0 /usr/local/lib/libelementsconsensus.so.0.0.0
/usr/bin/install: cannot create regular file '/usr/local/lib/libelementsconsensus.so.0.0.0': Permission denied
Makefile:4979: recipe for target 'install-libLTLIBRARIES' failed
make[3]: *** [install-libLTLIBRARIES] Error 1
make[3]: ディレクトリ '/home/yu/elements/src' から出ます
Makefile:13324: recipe for target 'install-am' failed
make[2]: *** [install-am] Error 2
make[2]: ディレクトリ '/home/yu/elements/src' から出ます
Makefile:12996: recipe for target 'install-recursive' failed
make[1]: *** [install-recursive] Error 1
make[1]: ディレクトリ '/home/yu/elements/src' から出ます
Makefile:783: recipe for target 'install-recursive' failed
make: *** [install-recursive] Error 1
```
よくよく読んでみると`Permission denied`とのこと. 要するに権限がない, と.
というわけで以下を実行

```
$ sudo make install
~~
$ which elementsd
>/usr/local/bin/elementsd
```

大丈夫そうですね.

これでElementsのインストールが完了しました.
お疲れ様でした.

次回はElementsの動作設定です.

#引用
>[Elements by BlockStream](https://elementsproject.org/elements-code-tutorial/installing-bitcoin)
Siri +Raspberry PI+でIoT コーヒーメーカーの電源を入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/edb18c6f-6aea-ce07-0b9c-fc7f470c551f.png)
## Siri+Raspberry PI+でIoT コーヒーメーカーの電源を入れる
## 配線
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/ca3a6d5a-51e0-7aaa-283a-b986f33db3ef.png)
### 茶色と黒にコーヒーメーカに接続、青と赤をAC 100Vコンセントに接続する。
### 最初の一歩
raspberry pi からon off させてみよう。
[broadlink sc1](https://japanese.alibaba.com/product-detail/New-arrival-BroadLink-SC1-one-button-60635211147.html?spm=a2700.7724838.2017115.13.5356170brZGm0g)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/241eff0e-534c-32a2-b4fb-80e206abbded.png)

### ネット環境を調べよう。

``` netstat.py
import broadlink
ssid,passwd='ssid','password'
broadlink.setup(ssid,passwd, 3)
dev = broadlink.discover(timeout=20)
net=[]
for d in dev:
    d.auth()
    n=dict(type=d.get_type(),ip=d.host[0],port =d.host[1],
             mac = "-".join([format(x,"02x") for x in [x for x in reversed(d.mac)]]),
             timeout = d.timeout)
    net.append(n)
print(net)
```

```
[{'type': 'SP2', 'ip': '192.168.1.151', 'port': 80, 'mac': '78-0f-77-17-5d-70', 'timeout': 10}]
```
##Broadlink sc1は、sp2として認識される。

```on_off.py
import broadlink,netaddr,time,binascii,json,sys
net1={'type': 'SP2', 'ip': '192.168.1.151', 'port': 80, 'mac': '78-0f-77-17-5d-70', 'timeout': 10}
sp2 = broadlink.sp2((net1["ip"], net1["port"]),netaddr.EUI(net1["mac"]),net1["timeout"])
sp2.auth()
sp2.set_power(False if sp2.check_power() else True)
```
実行するとon off を繰り返す。

## 本番プログラム

``` simplesw.py
'''
simple switch 
'''
import broadlink,netaddr,time,binascii,json,sys
import logging,signal
net1={'type': 'SP2', 'ip': '192.168.1.151', 'port': 80, 'mac': '78-0f-77-17-5d-70', 'timeout': 10}
from pyhap.accessory import Accessory, Bridge
from pyhap.accessory_driver import AccessoryDriver
from pyhap.const import (CATEGORY_SWITCH)
logging.basicConfig(level=logging.INFO, format="[%(module)s] %(message)s")
class SW(Accessory):
     category = CATEGORY_SWITCH
     def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        serv_tv = self.add_preload_service('Switch')
        self.char_on = serv_tv.configure_char('On', setter_callback=self.sw)
     def sw(self,value):
        logging.info("スウィッチ: %s", value)
        sp2 = broadlink.sp2((net1["ip"], net1["port"]),netaddr.EUI(net1["mac"]),net1["timeout"])
        sp2.auth()
        sp2.set_power(value)
def get_bridge(driver):
    bridge = Bridge(driver, 'Bridge')
    bridge.add_accessory(SW(driver, 'コーヒーメーカ'))
    return bridge
driver = AccessoryDriver(port=51826, persist_file='simple.state')
driver.add_accessory(accessory=get_bridge(driver))
signal.signal(signal.SIGTERM, driver.signal_handler)
driver.start()
```
実行
```
pi@raspberrypi:~/hk_project/HAP-python$ python simple.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/382f11d6-b5b0-c048-df06-7c61af6fd0b0.png)

IPhome HomeでQRコードを読み込み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/b9594193-9c35-cb21-62ee-59972da6a4b5.png)

[ソースコードは、ここ](https://github.com/yutakahirata/HAP-python)
Upgrade Rundeck 2.x to 3.x

## Background

しばらく運用して活躍してくれた Rundeck がいつの間にかメジャーバージョンアップしていたため、2.x から 3.x にアップデートしました。ドキュメントが発見できればすぐわかるのですが、ちょっとした設定を追加する必要があるため備忘録として記録を残します。

## Upgrade by YUM

そもそもRundeckはいくつかのやり方でインストールできますが、ここでは YUM を使ってインストールした想定で、それをアップデートします。

```
sudo yum upgrade rundeck rundeck-config
```

[インタラクティブシェルで config を migrate できる](https://docs.rundeck.com/docs/upgrading/upgrade-to-rundeck-3.x.html)とも書いてある気がするけど、なんも起きなかったので次へ。。。

## Edit rundeck-config.properties

ローカルデータベースではなく Remote MySQL Database をデータソースにしているので、properties ファイルに `dataSource.driverClassName` と `rundeck.log4j.config.file` を追加。ここはデータソースによって違うので[ここ](https://docs.rundeck.com/docs/administration/configuration/database/index.html)を参照。

```/etc/rundeck/rundeck-config.properties
## 省略 ##

dataSource.dbCreate = update
dataSource.url = jdbc:mysql://your.db.host/table?autoReconnect=true&useSSL=false
dataSource.username=db_user
dataSource.password=db_pwd
dataSource.driverClassName=com.mysql.jdbc.Driver ## << ADDED >>

# log4j
rundeck.log4j.config.file = /etc/rundeck/log4j.properties ## << ADDED >>

## 省略 ##
```

## Download JDBC driver

JDBCドライバを自分でいれないといけないので、libディレクトリをつくってダウンロード。[ここ](https://docs.rundeck.com/docs/administration/configuration/database/index.html)の指示に従う。

```shell
sudo mkdir /var/lib/rundeck/lib
cd /var/lib/rundeck/lib
sudo wget http://repo.boundlessgeo.com/main/ojdbc14/ojdbc14/10.2.0.3.0/ojdbc14-10.2.0.3.0.jar

cd ..
sudo chown rundeck:rundeck lib
sudo chown rundeck:rundeck lib/ojdbc14-10.2.0.3.0.jar
```

## Restart Rundeck

Rundeckを再起動しておしまいです。

```shell
sudo /etc/init.d/rundeckd restart
```
hontoで購入した書籍のリストを抽出する

購入した電子書籍を管理するために、スプレッドシートに書き出したいと思いました。
私は、電子書籍の購入は主にKindleとhontoを利用しています。（セール時期に応じて安い方で購入）

Kindleは、ググるとJavaScriptを利用した一覧の抽出方法が載っていたのですが、
honto版はなかったので、自分で書きました。


##Amazonの場合
以下全文をコピペして、ブラウザから実行します。
(URL欄に貼り付け、またはF12を押してブラウザから実行)

```js
javascript: t = [];

for (i = 0; 1; i++) {
  o = document.getElementById('title' + i);
  if (!o) break;
  t.push("A\t" + o.innerHTML + "\t" +
    document.getElementById('author' + i).innerHTML +
    "\t" + document.getElementById('date' + i).innerHTML);
};
for (i = 0; i < t.length; i++) document.write(t[i] + "<br/>");
```

参考
[購入した電書のリストを管理する(Kindle/Kobo編)](https://wakufactory.jp/densho/tools/booklist.html
)

##hontoの場合
事前に、My本棚の表示を以下の様に切り替えておいてください
・50冊表示に変更
・本棚形式から一覧形式の表示に切り替え

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272758/9b9593d8-027c-69a0-c302-64334c603d67.png" width="70%">

その後、以下のJavaScriptを実行します。
(URL欄に貼り付け、またはF12を押してブラウザから実行)

```js
javascript: t = [];
for (i = 0; i < 50; i++) {
  o = document.getElementById('dy_030_prdNm[' + i + ']');
  a = document.getElementById('dy_030_athrNm[' + i + ']');
  if (!o) break;
  if (a) {
    t.push("hont\t" + o.innerHTML + "\t" + a.innerHTML);
  } else {
    t.push("hont\t" + o.innerHTML);
  };
};
for (i = 0; i < t.length; i++) document.write(t[i] + "<br/>");
```

実行イメージ
こうすると
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272758/111a585b-5495-24a2-a374-281939659087.png" width="70%">
こうなります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272758/8f787d29-dfa1-1bdf-d0c6-de374b7fc656.png" width="70%">

※注意
1ページごとしか実行できないので、全部取得するためには、ページを何回か切り替えてください。。
（ページも自動で進む方法が分かる方がいれば、教えていただきたいです)
コマンドのショートカットの登録

# コマンドのショートカットの登録

alias と呼ばれる記法を使って、コマンドのショートカットを登録することができる。

bash の場合は、基本的に ~/.bash_profile に記述することが多い。zsh の場合は、 ~/.zshrc に記述するのがスタンダード。

```
$ vim ~/.zshrc
```

記載する。

```
alias g="git"
alias s="git status"
```

読み込む。

```
$ source ~/.zshrc
```

設定完了！！！！！
zsh + prezto 環境構築

# zsh + prezto 環境構築


## zshの導入

＊　zshとは、ターミナルの補完機能が非常に使いやすくなる、いい感じの「シェル」の 1 つ。


* zshインストール

```
$ brew install zsh zsh-completions

```

* ログインシェルを変更する。

```
$ sudo vim /etc/shells
```

vimの画面に入るので、一番下に下記を追加する

```
/usr/local/bin/zsh
```

cat コマンドでターミナル上に指定したファイルの中身を出力する。

```
$ cat /etc/shells
```

追加されていればおっけ！！


*　シェルを変更するコマンド

```
$ chsh -s /usr/local/bin/zsh
```


## preztoの導入

preztoとは、ターミナルをいい感じにするやつ。

* まずはzshのターミナルを起動してgitをcloneする。

```
$ git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
```

必要なファイルを作る。

```
$ setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```

＊ ~/.zpreztorcに追加編集。

```
# Set the Prezto modules to load (browse modules).
# The order matters.
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'syntax-highlighting' \ 追加
  'autosuggestions' \　追加
  'prompt' \
```


あとは、


＊ めちゃめちゃたくさんファイルが作られるが大事なのが、 .zshrc というファイル。パスを通すため、ファイルに追加記載する。

```
$ vim ~/.zshrc
```
 からの

```
# Homebrew
export PATH=/usr/local/bin:$PATH

# Homebrew rbenv
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

ファイルを読み込む。

```
$ source ~/.zshrc
```

確認

```
$ rbenv --version
```

で、rbenv のバージョンが表示されれば無事に設定完了!!!
Rubyの環境構築

# Rubyの環境構築

## Homebrewをインストールする

＊ AppStore から Xcode がある前提。なければインストール。その後、コマンド入力。

```
$ xcode-select --install
```

＊ [Homebrew](https://brew.sh/index_ja.html)のページからインストールのコマンドを持ってくる。

例

```
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```


＊ インストールされたか確認する

```
$ brew --version
```


## rbenvを導入する

＊ Rubyのバージョン管理などをやりやすくするためのパッケージ

```
$ brew install rbenv
$ rbenv init
```

1. ターミナルのウィンドウを一度閉じて新しいウィンドウを開き直す
2. 記載れているコマンドを叩く [rbenv](https://github.com/rbenv/rbenv)

```
  $ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash
```

これで終わり！

＊ アップデートの方法

```
$ brew upgrade rbenv ruby-build
```


## rbenv に Rubyをインストールする

インストール可能なバージョンを見るためのコマンド

```
$ rbenv install -l
```

インストールする

```
$ rbenv install 2.6.2
```


rbenvでインストールしたら、必ずうつコマンド

```
$ rbenv rehash
```

確認

```
$ rbenv versions
```

と

```
$ ruby -v
```

＊ しかし、Rubyのバージョンが変わってなかったら、パスを通す

```
$ rbenv global 2.6.2
$ ruby -v
```


# Rubyインストール完了！！！！！！！


#おまけ

## よく使うGemを入れておく　homeにね。

### bundler 必須

bundler という Gem を使うと  導入するライブラリのバージョンを固定し、ライブラリを一括でインストール できるのです。

```
$ gem install bundler
```

使い方はGemfileを作成し、以下のコマンドを実行する。

```
$ bundle install --path vendor/bundle
```

すると、

今いるディレクトリ直下にある Gemfile の中身を読み取り、vendor/bundle の配下に、Gem がインストールされる。

正常に bundle install が終わると、 Gemfile.lock というファイルが作成されます。

Gemfile.lock は、インストールした Gem のバージョンを固定するためのもので、以降 bundle install をするときは、この Gemfile.lock で指定されたバージョンのものがインストールされるようになる。



### rails やら　binding.pry　やら

```
$ gem install bundler rails pry-byebug pry-docs
```
Dockerのvolumeとbind mountの違い


どちらも永続化データの書き込み目的で存在しますが、現在はVolumeの使用が推奨されています。



##Docker volume
Hostマシーンのファイルシステムにデータを書き込む。
ただし、書き込まれるファイルシステムはDockerによって管理されており、DockerCLIからアクセス可能で、またホストマシーンからは隠蔽されていて見えない

正確に言うとディレクトリの場所が分かれば見えるけど、マウント先は名前で指定するため、ホスト側のディレクトリは意識しなくて良い仕組みで動く。


##Docker bind mount
ファイルシステムの特定のディレクトリをDocker containerと接続しアクセスできるようにマウントする。

Hostのファイルシステム側から簡単にディレクトリが見えていじれてしまうし、Host側のディレクトリ構造を意識しなければならず、Container内部からHost側のファイルシステムに簡単にアクセスできてしまうなどの問題がある。非推奨。
Dockerコンテナ例

パッと見返せるメモ用です

# 実行

```
docker container run -p 3000:3000 --rm --name ${container_name} ${image_name}:${tag} -e="var_name=value"
```

# ビルド

```
docker build . --tag imagename:tag
```


# 一覧系

```
$ docker ps -aq
$ docker images -q
$ docker container ls -al
```

# 削除系

```
$ docker system prune
$ docker rm $(docker ps -aq)
$ docker rmi $(docker images -q)
$ docker volume prune
```

####全ての稼働コンテナ一覧表示
```
docker stop ${container_id|container_name}
docker rm ${container_id|contaienr_name} 
// 停止中のコンテナを削除
docker rm ${contaienr_id|}
```
JMeterを使った負荷テストを実施してみる

実務で使ったので、メモの意味も含めて。

使用したバージョン：5.1.1

# 実際に使ってみる

nodejsで以下のようなAPIを作成してみました。

```javascript
// ライブラリ読み込み
var express    = require('express');
var app        = express();

var port = process.env.PORT || 8080; // port番号を指定


// GET http://localhost:3000/api/v1/
app.get('/api/test/',function(req,res){
    res.json({
        message:"Hello,world"
    });
});

app.listen(port);
```

このAPIについて試したい目的は、「同時リクエストの負荷が高まるとどうなるのか」とします。

## jmxファイルを作成
以下のようなテストを作成します。HTTPのgetを上記で作成したサーバに投げるのみです。
※「各スレッドグループを別々に実行」にチェックを入れないと、4つのテストが同時に走ってしまうので注意
<img width="872" alt="jmeter_gui.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55118/66ef7484-d643-9a74-9988-2b0eb86f0b41.png">
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55118/73996860-538b-31f3-d7b3-9829115d53ae.png)

今回はスレッドを４つ用意しました。赤枠で囲った部分が異なるだけです。

<img width="692" alt="thread_setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55118/92ce823e-d5c3-1e1c-0eb8-0f43bfc33c2d.png">

スレッド数: 60
Ramp-Up期間(秒): 60
「60秒の時間をかけて処理開始し、スレッド毎にシナリオを一回だけ実行する」
= 「秒間1リクエストのテスト」
となります。
※画像で設定した4つ目のテスト(秒間1000リクエスト)は java.net.BindException発生するので無効にしてありますorz
※windowsによる制限なんだろうか・・・

## 実行
### ※GUIは本番の負荷試験では使うべきではない
[参考](http://jmeter.apache.org/usermanual/get-started.html#load_test_running)
`Don't run load test using GUI mode !`
GUIはテストを作成する上では非常に便利なんですが、自分の体験としては
高い負荷のテストを実行しようとすると途中で止まってしまう。(JMeterのGUI自体がボトルネックになっているようだ)
のでかなり不便です

CUIならば、オプション指定で結果をまとめてくれます。

と非常に便利です。

### CUIで実行
`jmeterフォルダ/bin`以下で
(Linux)`./jmeter.sh -n -t <上記で作成したファイル名>　-l <結果ファイル> -e -o report` で実行
テスト結果がreportフォルダ内に出力されます。

## 結果
`report/index.html`を参照するといろいろな角度からテスト結果を見ることができます。
意味ありそうなやつを。Time Vs Threadsを見ると、
同時アクセスのスレッドが増えたら平均レスポンスタイムは増えていることがわかります。
上記実装はシングルスレッドなのでこんなもんなのかな、という感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55118/7986fba4-868a-5989-f1d9-9c62738aaf00.png)
WindowsにてVirtualBox6.0のVMを自動起動する

# 概要

こちらにも記載させていただきました、よければ遊びに来てみてくださいませ
https://red-full-moon.com/virtualbox-60-auto-start/

Windowsホストマシンを再起動したりしたときにVMが自動起動するスクリプトを使っていたが、VirtualBox（VB）を6.0に最新化したら引数エラーになってしまった。

# 今まで
C:\Users\【ユーザ名】\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
にautoUpVm.batを作成してその中に下記を記載

```bat
start "" /b "C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" -startvm "仮想マシン名"
```

# VBアプデ後のエラー
-startvmという引数は存在しないよ！
とダイアログが出るように…

# 回避策
batファイルの中身を下記に変更

```bat
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" startvm "仮想マシン名"
```

# まとめ
引数の宣言の仕方が変わったのか、前から怪しかったのが今回切られてしまったのかは不明だが、これからはこれで自動起動していく。
Serverless の Typetalk 通知プラグインを作った話

## 概要
Serverless の Typetalk 通知プラグイン [serverless-plugin-typetalk](https://www.npmjs.com/package/serverless-plugin-typetalk) を作ったので紹介する記事です。

## 前提知識
Typetalk って何？という方は [こちら](https://www.typetalk.com/)

## Serverless とは？

https://github.com/serverless/serverless
> The Serverless Framework – Build applications comprised of microservices that run in response to events, auto-scale for you, and only charge you when they run. This lowers the total cost of maintaining your apps, enabling you to build more logic, faster.

マイクロサービスのアプリを構築するためのフレームワークです。AWS だけでなく色々なプラットフォームをサポートしており、コミュニティによるプラグインも多数提供されていてとても便利です。

## 使い方
1) Typetalk でボットを作成します。

<img width="1081" alt="Screen Shot 2019-06-19 at 1.52.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27079/850f5d35-e7eb-942f-316c-e62dccd59dba.png">

*メッセージの投稿を行うので、topic.post にチェックを入れます*

| 項目 | 値 |
|-----|----|
| ID | serverless-typetalk-plugin |
| Full Name | serverless-typetalk-plugin |

2) ボットの投稿に必要な値を環境変数に設定します。

```
$ export TYPETALK_TOKEN={手順1で作成したボットのトークン}
$ export TYPETALK_TOPIC_ID={ボットを作成したトピックのID}
```

3) serverless.yml を作成します。

サンプルコード

```javascript
// handler.hello
'use strict';

module.exports.hello = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }, null, 2),
  };
};
```

```yaml
# serverless.yml
service: serverless-plugin-typetalk-example

plugins:
  - serverless-plugin-typetalk

custom:
  typetalk:
    token: ${env:TYPETALK_TOKEN}
    topicId: ${env:TYPETALK_TOPIC_ID}

provider:
  name: aws
  runtime: nodejs10.x

functions:
  hello:
handler: handler.hello
```

4) serverless コマンドをインストールします。

```
$ npm i -g serverless
```

5) プラグインをインストールします。

```
$ npm i serverless-plugin-typetalk
```

6) 実行します。

```
$ sls deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Typetalk notification has been sent.
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service serverless-plugin-typetalk-example.zip file to S3 (67.2 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
Service Information
service: serverless-plugin-typetalk-example
stage: dev
region: us-east-1
stack: serverless-plugin-typetalk-example-dev
resources: 5
api keys:
  None
endpoints:
  None
functions:
  hello: serverless-plugin-typetalk-example-dev-hello
layers:
  None
Serverless: Typetalk notification has been sent.
```

7) メッセージが投稿されます。

<img width="778" alt="Screen Shot 2019-06-19 at 2.01.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27079/057b4b11-ca68-0d2f-0fc5-d813f59d5106.png">

手順は以上となります。いかがだったでしょうか？フィードバック歓迎です :pray:
FirebaseUIでGoogle認証した情報をGoogleDriveで使いまわす方法。

やぁ。
掲題の課題を解決するのに4日かかったよ・・・

＜フロー＞
1.FirebaseUIでGoogle認証
↓
2.別の画面へ遷移。
↓
3.GoogleDriveを扱う画面遷移。（1.で認証した情報を使用）

という感じ、何度も(3.でもう一回)Google認証するの嫌でしょ・・・？僕もです。

(3.)だけ、(1.)は適当にぐぐるとわかるやろ！
ってことでソースコードです。

```java:TestActivity.java
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.testactivity);
            // nanya kanya execute
            requestSignIn();
        }
        private void requestSignIn() {
            Log.d(TAG, "Requesting sign-in");
            if(FirebaseAuth.getInstance().getCurrentUser() != null){
                for(UserInfo ui :FirebaseAuth.getInstance().getCurrentUser().getProviderData()){
                    if(ui.getProviderId().equals(GoogleAuthProvider.PROVIDER_ID)){
                        // Use the authenticated account to sign in to the Drive service.
                        GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(this, Collections.singleton(DriveScopes.DRIVE_FILE));
                        GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this); // !! importance here !!
                        if(account != null){
                            credential.setSelectedAccount(account.getAccount());                 // !! importance here !!
                            // Get the app's Drive folder
                            Drive googleDriveService =
                                    new Drive.Builder(AndroidHttp.newCompatibleTransport(),new GsonFactory(),credential)
                                            .setApplicationName(getResources().getString(R.string.app_name))
                                            .build();
                            // The DriveServiceHelper encapsulates all REST API and SAF functionality.
                            // Its instantiation is required before handling any onClick actions.
                            mDriveServiceHelper = new DriveServiceHelper(googleDriveService);
                            return;
                        }
                    }
                }
                Toast.makeText(this,"notfound",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this,"not login",Toast.LENGTH_SHORT).show();
            }
        }

```

ってね。
なんか文句あったらコメントにどしどしお願い。
お名前.comで取得したドメイン + お名前メール + 外部レンタルサーバ

これまでお名前.comで取得したドメインに対して外部レンタルサーバを紐づけて運用していたのですが、
このドメインでメールアドレスも取得したいなと思い、追加でお名前メールを申し込みました。
その時、サーバの設定で若干苦戦したので解決方法を記しておきます。

# やりたいこと
お名前.comで取得したドメインで、以下のような設定をしたい。

+ Aレコードは外部レンタルサーバ
+ MXレコードはお名前メールサーバ


# 手順

#### お名前.com Navi からネームサーバを変更。

お名前.com Navi の管理画面にログインしてドメイン設定タブを開き
ネームサーバを設定したいドメインのラジオボタンにチェックを入れます。
今回、私が紐づけたいのはお名前メールなので、
「レンタルサーバ（SDプラン・お名前メール）」の右横にある「設定する」ボタンをクリックします。
![スクリーンショット 2019-06-19 0.49.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/d72a156f-a66c-8093-f597-142632e3e01f.png)


確認画面が表示されるので、内容を確認して「設定する」ボタンをクリックします。
![スクリーンショット 2019-06-19 0.52.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/97b05556-8236-13f1-4969-5c9740814601.png)

これで無事にこのドメインでメールの送受信ができるようになりました。
しかし、このままだとWEBが閲覧できない状態なので、Aレコードを外部レンタルサーバに向けなければなりません。

**問題はここから・・・**:dash:

Aレコードを設定しようと思い、
お名前.com Navi のDNS関連機能の設定 > DNSレコード入力 からAレコードの設定をしてみたものの
待てど暮らせど変更が反映されません。
以下のコマンドを何度叩いても、アドレスはお名前のサーバを向いたまま:disappointed_relieved:

```
nslookup mydomain.com 8.8.8.8
```

# 結論
Aレコードを設定する場所が お名前.com Naviの管理画面ではなかった！

## 手順
#### お名前メールの管理画面に遷移。
お名前.com Navi のTOP > ご利用状況 > お名前メール をクリックします。
![スクリーンショット-2019-06-19-0.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/1bee80c5-f1ef-7a31-8272-96e1c9c51947.png)

ログインボタンからお名前メールのコントロールパネルに遷移します。
![スクリーンショット-2019-06-19-0.59.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/37650810-c501-3ad1-7f92-2204336af4fb.png)

#### 独自ドメイン設定からAレコードを設定。
サービス設定 > 独自ドメイン設定 をクリックします。
![スクリーンショット-2019-06-19-1.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/fb9f8da0-e58d-8e18-69a9-d33bf63a5534.png)

DNS設定ボタン をクリックします。
![スクリーンショット-2019-06-19-1.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/573350b1-5edf-dffd-4d4e-ea93a5f8007e.png)

Aレコードに外部レンタルサーバのIPアドレスを指定します。
![スクリーンショット 2019-06-19 1.03.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239398/85eec7af-2b46-2036-7653-f12ef3cc646b.png)

**これで完了です**:exclamation:


念の為nslookupで確認。（私は即時で反映されましたが数時間かかる場合もあります）

```
nslookup -q=MX mydomain.com
```
→ gmoserver.jpが返される

```
nslookup -q=A mydomain.com
```
→ 外部レンタルサーバのIPアドレスが返される

実際にメールの送受信も問題なくでき、WEBも意図した通りに表示されました。


# 参考サイト

- [公式ガイド](https://guide.onamae-server.com/om/details.php?g=5&_ga=2.11593012.1889954231.1560697030-1153508685.1560409572&_gac=1.213718374.1560410076.Cj0KCQjw6IfoBRCiARIsAF6q06uFn0D0W0FyucShzsqAeYK3k0CItOIZD-NtQiXbSLDy684Xya6URuUaAi4UEALw_wcB
)

- https://ideen.jp/technology/onamae_dns
QiitaとGitHubのマークダウンの相違点と流用

# はじめに
- Qiitaで書いた記事のファイルを入れているリポジトリの`README.md`にも記事内容を入れておくことを思い立って、試しにそのまま貼り付けてみたところ、さほど直しを要しませんでした。
- 今後のために、マークダウンで書かれたドキュメントを流用する場合に注意する必要のあることをまとめておこうと思います。

# できること
- QiitaからGitHubへ持って行く場合、インライン画像を含めて、ほぼそのまま移せます。
- 画像の本体は、Qiitaの記事を消さなければ、そのままQiita側で保持されるものと思われます。

# 相違点
- 改行
    - Qiita: 画像の直後に改行文字があると改行されます。
    - GitHub: 画像の直後でも、改行には行末に二重空白文字が必要です。

# あとがき

### 今後
- 気付いたことを追加していきたいと考えています。
- 私の知らないことをご存じなら、ぜひ教えてください。

### 連携機能を使わない理由
- 現在の連携は、記事のソースファイルをGistで管理させるだけですよね?
    - Gistだとリポジトリ分かれちゃうし…
- 記事とリポジトリを直結して、リポジトリの`README.md`が記事になって、Qiitaのソーシャル機能が使えるような連携だと良いのですが…
    - Qiita側でも記事を編集してコミットしたいですね。
    - 記事の画像はAWS使わずにGistに逃がせますね。
扇形のツールチップメニューの作成

今回は、ちと興味をもった、以下の記事を自分なりに実装してみた過程とその顛末となります。

元ネタ：
[tooltipmenu](https://coliss.com/articles/build-websites/operation/css/css-demo-circular-tooltip.html)


id属性を付ければ、もっと単純にはなるんですが、CSSセレクタで出来ることの理解も主眼にしてるのもあるので
その観点で見て貰えればと思います。

## Goal
結果出来たのが以下のメニュー。
HowToがメインなので見た目のゴージャス感がオリジナルより劣ってるのはご容赦ください。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="html,result" data-user="anyworks" data-slug-hash="zVKKPR" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Vanilla HTML+CSS menu">
  <span>See the Pen <a href="https://codepen.io/anyworks/pen/zVKKPR/">
  Vanilla HTML+CSS menu</a> by anyworks (<a href="https://codepen.io/anyworks">@anyworks</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

### Step by step

個人的に、jsfiddle派なので、以下は外部リンクで参照して貰う形になります。すみません。

#### まずは、骨組みを作るために、staticなメニューを作成します。

[static menu](https://jsfiddle.net/anyworks/svb9dtew/1)
ここでのポイントは、、、特に無いですかね。fontawsomeを使ってアイコン表示してるとこくらいですか。

#### ちょこっとDynamicにします。

[dynamic menu](https://jsfiddle.net/anyworks/svb9dtew/2)
ここでのポイントは、

- `span:not(:first-child)` で、メニューアイコン以外を隠してるところ。このセレクタ地味に便利です。
- あとはバグが潜んでるところですかね。しかも、かなり致命的な。

#### クリック可能にします。要は、バグを直したversionです。

[clickable dynamic menu](https://jsfiddle.net/anyworks/svb9dtew/3)
    
ここでのポイントは、

1.  以下のセレクタはフォーカスがあたってるのが前提となってるところ（=フォーカスが外れると、非表示となる為クリック出来ない）
`span:first-child:focus ~ span:not(:first-child)`
ちなみに、このセレクタ自体の意味は、フォーカスが当たっている（クリックされた）要素を兄弟としてもつ、最初以外の要素すべて。です。

1. `span:not(:first-child):hover`
フォーカス後に表示された要素がhoverされている場合、focus時と同様の定義を与えて、表示を持続させる訳です。こうすることで、フォーカス要素がクリック可能となる訳です。


#### 最後に、アニメーションを追加します

[dynamic menu with effect](https://jsfiddle.net/anyworks/svb9dtew/5)

ここでのポイントは、

1. `transition` を各メニューに付けます。具体的にいえば、`span:not(:first-child)`に付与してます。変化させたい対象の初期状態です。
- `span:first-child:focus ~ span:nth-child(N)` で個々の位置を指定。表示位置を差別化するために必須。変化させたい対象の最終状態です。
- `span:nth-child(N):hover` でhover要素の最終表示状態を維持します(前回同様、クリック不可となるバグを回避するため）
- `span:not(:first-child):active` でhover後のclick時にも要素の最終表示状態を維持します。hoverに定義しても可ですが、その場合はクリック後も表示が残ってしまうのでactiveの方がEffectとしては自然となります。
    
総じて、隠されている要素をhover->clickする時は表示を維持して、クリック可能するのが肝な気がします。


#### 最終版

[final version](https://jsfiddle.net/anyworks/svb9dtew/)

見た目の微調整が面倒だったのでscssになってしまってますが、CSSはかなりシンプルにできたと思います。
釣りにおけるマズメ判定処理

##経緯
海関係のプロダクトを作る際に普段は、フレームワークを使っているが、便利さにあやかり過ぎてアルゴリズム考える力や基礎力が確実に衰えている感じがしたので、自己研鑽と振り返りも兼ねて、簡単なものを作り始めたのがきっかけ。

##題材
魚が釣れる時間帯を通知する簡単なプログラム

・現在時刻を確認して、釣れる時間帯かを判定

・ステータスは以下
　6:00～8:00→朝マズメ（植物プランクトンが光合成のために水面に浮上するため）
　8:00～17:00→日中（基本活性はまばら、釣れる場合もあり）
　17:00～19:00→夕マズメ（大型魚が小魚を求めて活性化する）
　18:00～6:00→夜間（魚達が動き出す。大型魚も狙える）


#サンプル
```java:mazumeAlert.java
import java.util.*;
import java.text.SimpleDateFormat;

class mazumeAlert {

	public static void main(String[] args){
		
		String display_result = "";		
		Calendar cTime = Calendar.getInstance();
		
		SimpleDateFormat sdf = new SimpleDateFormat("H");	
		int current_hour = Integer.parseInt(sdf.format(cTime.getTime()));
		
		if(current_hour >= 6 && current_hour < 8){
			display_result = OceanStatus.MORNING.getStatus();
		}
		
		if(current_hour >= 8 && current_hour < 17){
			display_result = OceanStatus.NOON.getStatus();
		}
		
		if(current_hour >= 17 && current_hour < 19){
			display_result = OceanStatus.SUNSET.getStatus();
		}
		
		if((current_hour >= 19 && current_hour <= 23) 
		|| (current_hour >= 0 && current_hour < 6)){
			display_result = OceanStatus.NIGHT.getStatus();
		}
		
		System.out.println(display_result);
	}

	enum OceanStatus {
		MORNING("朝マズメ:釣れる時間帯"),
		NOON("日中：まずまずの時間帯"),
		SUNSET("夕マズメ：釣れる時間帯"),
		NIGHT("オールナイト釣れる");

		private final String status;

		private OceanStatus(String status) {
		this.status = status;
		}

		public String getStatus() {
			return this.status;
		}
	}
}
```

##あとがき
振り返りがてらの練習なので、大したものではないですが、
コツコツ使えるロジックを日々継続して蓄積できたらと思っています。
【初心者】Reactアプリケーションを作ってデプロイする方法【歓迎】

# TL;DR
React初心者がマークダウンビューアを作ってGitHub Pages ( github.io )で公開するまでの話。
色々忘れそうなので備忘録。

# つくったもの
シンプルなマークダウンビューアを作りました。
https://y0kuda.github.io/react-markdown-viewer
(リポジトリ: https://github.com/Y0KUDA/react-markdown-viewer)
![](https://raw.githubusercontent.com/Y0KUDA/react-markdown-viewer/master/howdy.gif)

## 1. 雛形作成
`create-react-app`で雛形の作成が可能。
私はTypeScriptを使って開発したいので`--typescript`引数を付けています。

```sh
create-react-app my-app --typescript
```

とりあえず、`yarn start`を実行すれば雛形のアプリケーションが起動します。

## 2. node packageのインストール
必要に応じてnode packageをインストールします。
今回はマークダウン表示するために`remarkable`をインストールします。
私はTypeScriptで開発しますが、型情報が含まれていないので`@types/remarkable`も併せてインストールします。

```sh
yarn add remarkable
yarn add @types/remarkable
```

## 3. コーディング
`App.tsx`を以下のように変更します。

```tsx:App.tsx
import React, { useState } from "react";
import "./App.css";
import Remarkable from "remarkable";

const App: React.FC = () => {
  const [input, updateInput] = useState("# howdy.\nInput your markdown.");

  return (
    <div className="App">
      <h3>Input Markdown</h3>
      <textarea
        id="markdown-content"
        onChange={(e: any) => {
          updateInput(e.target.value);
        }}
        defaultValue={input}
      />

      <h3>Output</h3>
      <div
        className="md"
        dangerouslySetInnerHTML={{__html:new Remarkable().render(input)}}
      />
    </div>
  );
};

export default App;
```

## 4. URLの設定
GitHub Pagesで公開するために環境変数`PUBLIC_URL`を設定します。
環境を汚染しないように`cross-env`を使います。
ビルド時に設定されてればいいので、`package.json`の`build`に追記します。

```json
"build": "react-scripts build",
```
↓

```json
"build": "cross-env PUBLIC_URL=/react-markdown-viewer react-scripts build",
```

## 5. ビルド
`yarn build`でビルドできます。
ビルド生成物は`./build`に出力されます。
これらをサーバにアップロードすることで公開できます。

## 6. GitHub Pagesで公開
GitHub Pagesでは任意のディレクトリをルートに設定することができないので、別のブランチに`./build`がルートディレクトリになるように設定しましょう。

```sh
git subtree push --prefix build/ . gh-pages
git push origin gh-pages:gh-pages
```

これで、`master`ブランチの`./build`の中身が`gh-pages`ブランチのルートにクローンされます。
githubリポジトリのSettingsからGitHub Pagesで公開する設定が可能です。今回の場合、`gh-pages`ブランチを公開するように設定します。
これでアクセスできるようになります。
https://y0kuda.github.io/react-markdown-viewer

今回は、URLを短くしたいので、`./build`がルートになるように設定しましたが、この作業をしない場合でも`./build`にアクセスするURLを指定すれば動かすことが可能です。その場合、URLは`https://y0kuda.github.io/react-markdown-viewer/build`になります。

# さいごに
最後まで読んでくれてありがとうございます。
既に腐るほどありそうな記事を書いてごめんなさい・・・
でも、誰かのためになれば幸いです。
指摘やアドバイス、コメント等あれば遠慮なくお願いします。


# 参考
https://ja.reactjs.org/docs/hooks-state.html
https://qiita.com/mikakane/items/87c8f676815da4e5ac04#%E3%81%B2%E3%81%A8%E3%81%A4%E4%B8%8B%E3%81%AE%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92github-pages%E3%81%AB%E5%85%AC%E9%96%8B%E3%81%99%E3%82%8B
【UiPath】メールの絞り込みあれこれ

メールの取得処理で、**メールの件数多いから絞り込みたい…**
ってことはよくあると思います。

今回は**getOutlookMailMessages**アクティビティを使ったメール絞り込み方法について、
つまづいた点と解決策、参考サイトについてシェアします。

##絞り込み方法
getOutlookMailMessagesアクティビティのプロパティの「フィルター」にいろいろと条件を書いていくのですが、書き方は2種類あります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/81436774-c0e7-1e20-1959-f3c94d617634.png)

###メールフィルター
通常の方法です。以下サイトが参考になります。
[Outlookで受信したメールを操作してエクセルに転記する](https://uipath.site/use/receivemail.html)
[メール取得処理のフィルタ設定について](https://forum.uipath.com/t/topic/91596)

例えば、指定の受信日以降のメールに絞り込みたい場合、
**[ReceivedTime] >= 'mm/dd/yyyy'**
と書きます。

###DASL構文
SQLのような書き方でフィルタをかける方法です。
以下サイトが参考になります。
[Outlook で検索条件を絞り込んでより良い検索結果を得る](https://support.office.com/ja-jp/article/outlook-%E3%81%A7%E6%A4%9C%E7%B4%A2%E6%9D%A1%E4%BB%B6%E3%82%92%E7%B5%9E%E3%82%8A%E8%BE%BC%E3%82%93%E3%81%A7%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E6%A4%9C%E7%B4%A2%E7%B5%90%E6%9E%9C%E3%82%92%E5%BE%97%E3%82%8B-d824d1e9-a255-4c8a-8553-276fb895a8da)
[アウトルックで添付ファイルを保存したい](https://forum.uipath.com/t/topic/99453)

例えば、添付ファイル付きのメールに絞り込みたい場合、
**"@SQL=" & Chr(34) & "urn:schemas:httpmail:hasattachment" & Chr(34) & " = True"**
と書きます。

##詰まった点
指定の受信日以降、かつ、添付ファイル付きのメールに絞り込みたかったので、
以下のように書いたのですがメールが1件も取得できませんでした。
日付の書き方もmm/dd/yyyy形式で合ってるはずなんですが…　謎です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/57f3b4c4-86ed-e826-93a8-554b6bb3202c.png)

##結局InvokeCode使っちゃいます
手っ取り早くパフォーマンスに影響なく、かつメールを絞り込みたい場合は**InvokeCode**使ってます。
ただ、メールの抽出データがないとどうしようもないので、

- getOutlookMailMessagesアクティビティで**受信日From/Toで絞り込んだメールリストを取得**
- **InvokeCode**でさらに絞り込み

の2段階構成とします。
getOutlookMailMessagesの取得データが大量にならない程度にデータ量を調整し、
細かい絞り込みはInvokeCodeで行うというわけです。

以下、指定の受信日以降、かつ、添付ファイル付きのメールに絞り込む例です。

まずは受信日で絞り込み。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/aa780b86-3b0b-dadd-3acd-97e1cf4bc101.png)

InvokeCodeのコード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/3e207c83-73a3-055b-7924-b98693ddcc6c.png)

```vb
returnList = New List(Of MailMessage)()
Dim mail As MailMessage
For Each mail In mailList
	If mail.Attachments.Count > 0 Then
		returnList.Add(mail)
	End If
Next
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/a89d0c0b-a20a-6bad-6648-9a4868ce2d40.png)


##まとめ
メールフィルタ、DASL構文どちらでも絞り込みは可能ですが、場合によっては併用しないと期待通りの結果にならないこともあります。
コーディングが苦でなければInvokeCode使うのが手っ取り早いです。
form_forで取得できるparamsについて

## 概要
以前form_forで取得できるparamsでつまづいた経験があったので、投稿します。

form_forでparamsのデータを取得したとき、{"article(#テーブル名)"=>"hoge(#paramsデータ)"}で取得されて「何故？」ってなったときの対処法です。

このとき、binding.pryでparamsを取得してみると以下のようになっているはずです。

```ruby:paramsの取得結果
[1] pry(#<ArticleController>)> params
=> <ActionController::Parameters {"utf8"=>"✓",
 "authenticity_token"=>"gIvkzIoFCV5rwNBg6uxAl00JImeHW0yMi2esjwvXsjWohISeEXGdYyJv7K41rJVaDz8oJGKNblDcQ/0BxIvFZw==",
"article"=>{"article"=>"aaaa"}, #　ここに着目。"article"キーのvalueがハッシュになっています。
"commit"=>"投稿",
"controller"=>"article",
"action"=>"create"}
permitted: false>
```

form_forでparamsを取得すると、form_tagとは違ってparams[キー]の中にハッシュデータが入ります。
strongParameterでデータが生成されているためにこの形になっているのですが、詳しくは下記をご参考ください。

RailsのStrong Parametersを調べる
https://qiita.com/mochio/items/45b9172a50a6ebb0bee0

## 解決方法

```ruby:article_controller.rb
def create
  Article.create(article_params)
end

  def article_params
    params.require(:article).permit(:article).merge(user_id: current_user.id)
  end
# require(:モデル名)をつけることで、入力したデータを取得できる。
```

何か間違いがありましたらご意見いただけると幸いです。
システム開発ツールまとめ

##IDE
**Visual Studio Code**
*https://code.visualstudio.com/*
**Eclipse**
・英語版
*https://www.eclipse.org/downloads/*
・日本語版
*https://mergedoc.osdn.jp/*
**IntelliJ IDEA**
*https://www.jetbrains.com/*
**Sublime Text3**
*https://www.sublimetext.com/*
**Sakura Editor**
*https://sakura-editor.github.io/*
**Notepad++**
*https://notepad-plus-plus.org/*

##比較
**Winmerge**
*https://winmergejp.bitbucket.io/*
**DIFF**
*https://www.diffchecker.com/*

#画面キャプチャ取得
**FastStone Capture**
*https://www.faststone.org/FSCaptureDetail.htm*
**Share X**
*https://getsharex.com/*
##Linuxアクセルクライアント
**WinScp**
*https://winscp.net/eng/index.php*
**Tera Term**
*https://ttssh2.osdn.jp/*
**Poderosa**
*https://ja.poderosa-terminal.com/*
**Cyber Duck**
**Git Bash**
**Windows10 なら WLS なども使えます**
プログラミング学習をしている時に壁にぶち当たり、悩んでいる時に救われた一言

#プログラミング学習をしている時に壁にぶち当たり、悩んでいる時に救われた一言



あるライフコーチの方からの一言でした。
### 「仕事としてお金を貰えなくても、喜んでやることが自分のやりたいことだよ」

***
#### 自分のSPEC(2019年6月現在)
- 組み込みエンジニアでC言語で1年開発経験  
- 社会人三年目

***


現在、TECH::EXPERTという未経験からエンジニアを育てるというコンセプトの
プログラミング教室に通っています。



自分はプログラミング経験者です。
ですが、web系言語は経験がなかったので、
web系の勉強ができるスクールに通おうと考えていました。

教室使い放題という所に魅力を感じて、
TECH::EXPERTさんで勉強しようと入学しました。

勉強をしている時は、
新しい言語や、考え方が全く違くて
「おお、そうやって書くんだ！」
「保守性が高いなーC言語と違ってガチガチだなー」
と比較的楽しんでいました。


カリキュラムの後半のところで、
個人アプリを開発する段階になり、
**「よし、めっちゃいい企業に入るために、企業の求めることをめっちゃ分析して、
最高のポートフォリオ作ってやるぜ！」**
と気合いを入れていました。

しかし、自己分析をすると
そもそも**どんな会社**に入りたいんだ。。。
何のために**プログラミング学習**を始めたんだっけ。。。
**自分より優秀な人が沢山いて勝てる気全くしないのに、なんで学んでいるのだろう**。。。
と色々考える自分がいて一向に進みませんでした。

さらに、他のメンバーや同じ期で入った人はどんどん作っている姿をみて
**「自分は経験者なのに、まだ何も決まってなくて、
しかも、目的も学習意欲も低いし、ダサいな。。。」**と感じて
さらに相談できなくなっていきました。

そんな時、
あるライフコーチ(チームに一人配属されている)の方が、
**「悩んでいるみたいですね。大丈夫ですが？」**
と心配で話しかけてくださって、
自分の考え方を、親身になって聞いてくださったりしました。そんな時に、
#### 「仕事としてお金を貰えなくても、喜んでやることが自分のやりたいことだよ」
と言っていただき
確かに、当たり前のことなんですが、
悩みに悩んだ自分にはかなり響きました。

そして、
#### ここで学んだことは確かに仕事には直結しないかもしれない。けれど、次の仕事で必ず活かせることがあるから頑張ろう。
とライフコーチの方に言ってもらえて、
#### 今、確かにエンジニアになるために勉強しているけど、必ずしもエンジニアになる必要はないのか

と自分の考え方が広がったような気がしました。

今、学んでいることは将来使わないかも知れない
だけど、ここで学んで悩んだことは将来に役にたつかも知れないし、
ここで自分のできないから逃げたら一生逃げ続ける人生になるかも知れない。
と思う。

全力であと一ヶ月勉強しようと思う。



最後に勉強になったなっと思うこと
1. 自分の素の姿(かっこ悪い)を話すことは、絶対にした方がいいと感じたこと
2. 悩みに悩んだからこそ、救われたなって感じたこと
3. 自分も、人に何か思いとか考え方とか伝えたいなって感じたこと



<br>
<br>
<br>
文章書くの下手だな俺、、、、
文章の構造の本とか今度読もう。

拙い文章ですみません。
自分の考えと今後アウトプットしていこうと考えているので
まず、第一歩として、
書きました。

今後は文章構成も、
考えながらアウトプットしていきたいと思います！

エンジニアになるかわからないですが、
駆け出しエンジニアの僕を応援してください！
よろしくです！！！！
pywinautoでfirefoxをクリック

# 目標
firefox の自動操作
今回は pywinauto を用いて右クリックをするところまで実行してみる

# 参考サイト
メモ帳を用いた基本操作: https://githubja.com/pywinauto/pywinauto
pywinautoリファレンス: https://pywinauto.readthedocs.io/en/latest/HowTo.html
pywinautoリファレンス(hwndwrapper): https://pywinauto.readthedocs.io/en/latest/code/pywinauto.controls.hwndwrapper.html

# 事前準備
handle を指定してfirefox を取得するため、swapyを利用
https://pywinauto.github.io/pages/swapy-is-a-pywinauto-inspector-and-code-generator.html

# コード
```right_click_firefox.py
from pywinauto.application import Application

firefox = Application().connect(handle=2951732)   # firefoxを起動後、swapyを見てhandleを指定
dlg = firefox.window(handle=2951732)            # 現在開いているタブをhandleを指定して取得
dlg.click(button='right', coords(200,200))      # 現在開いているタブの座標(200,200)を右クリック
```

これでfirefox画面上に右クリックをしたときの表示が出れば成功

**(2019/06/19 追記)**
dlgはpywinauto.base_wrapper.BaseWrapper に基づいているため、以下のコードでも可。
ただし、マウスがその地点に飛んでしまうので他の操作は出来なくなる。
リファレンス : https://pywinauto.readthedocs.io/en/latest/code/pywinauto.base_wrapper.html

```right_click_firefox.py
from pywinauto.application import Application

firefox = Application().connect(handle=2951732)
dlg = firefox.window(handle=2951732)           
dlg.click_input(button='right', coords(200,200))      # click() から click_input() に変更
```


# 最後に
Application().connect() の方法はいくつかある。handleを調べなくてもできる方法もあるはず。

また、firefoxは現在開いているタブだけでなく、いくつかのウィンドウで構成されている

```
>>> firefox.windows()
```

で一覧を確認できる
pythonで正規表現

pythonで正規表現使うときの為の自分用メモです

## 種類と用途

**re.match(正規表現パターン, 対象文字列):**
普通の正規表現サーチ。指定範囲の1部を()で囲んで呼べるのが便利。

**re.search(正規表現パターン, 対象文字列):**
位置関係なしに指定パターンが出てくるか探してくれる。1つ見つけたら終わりにするのでありなし確認に使う。NGワード探しとかに使うと短く書けて便利。

**re.findall(正規表現パターン, 対象文字列):**
位置関係なしに指定パターンに該当する文字列を探して見つけた分を全部listにして返してくれる。何回出てくるか分からないときに使うと便利。

**re.sub(正規表現パターン, 置き換える文字列, 対象文字列):**
置き換えに使う。

## 返り値の違い

```python:python
import re
result = re.match('([a-z]+)([0-9]*)', 入力文字列)
result = re.search('([a-z]+)([0-9]*)', 入力文字列)
result = re.findall('([a-z]+)([0-9]*)', 入力文字列)
```
上記のパターンで正規表現サーチをかけた返り値をresultに入れた場合に結果をどうやって取り出すか一覧にしてみました。re.match()、re.search()はオブジェクトが返ってきてresult[0]、result.group()、result.group[0]で該当文字列全体、()で囲んでグループを指定してあればresult[k]またはresult.group[k]でk番目のグループの文字列が受け取れるようです。

re.findall()はresultがlistなのでこっちは分かりやすいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/b5eb1761-d042-94e3-ac26-ed00f9366fbe.png)

## パターンの書き方

| 文字       | 説明        | マッチする例      |
|:----------:|:----------:|:----------------:|
| .          | 任意の文字  |                  |
| [0-9]      | 任意の数字  |   1, 2, 3, 9, 0  |
| [^0-9]     | 数字以外    |  a, う, ｵ, -, z  |
| [a-z]      | 任意のアルファベット | a, e, h, t, z |
| \s         | 任意の空白文字   | \t, \n, \r, \f, \v  |
| \w         | 任意の英数字 | a, u, R, 0, - |

## 繰り返しの書き方
| 文字       | 説明  |
|:-----------------:|:------------------:|
| *      | 0回以上の繰り返し (できるだけ長く)      |
| *?      | 0回以上の繰り返し (できるだけ短く)      |
| +     | 1回以上の繰り返し (できるだけ長く) |
| +?    | 1回以上の繰り返し (できるだけ短く) |
| {m}   | m回繰り返し |
| {m, n} | m～n回繰り返し |


## 多数回実行するときは先にcompileする

```python:python
textList = ['hoge', 'hoge12', '123hoge', 'hoge123hoge', 'fuga_12345', '123_fuga_456', 'fuga123']
for text in textList:
    result = re.match('.*?[0-9]+', text)
```
複数回処理するなら下のように1度compileしてから実行した方が早い。

```python:python
repattern = re.compile('.*?[0-9]+')
textList = ['hoge', 'hoge12', '123hoge', 'hoge123hoge', 'fuga_12345', '123_fuga_456', 'fuga123']
for text in textList:
    result = repattern.match(text)
```
C++/CLIでWindows APIを呼び出す時に、GetLastError()とMarshal::GetLastWin32Error()のどちらを使用すべきか。

もう古代の技術の話題ですが。

## TL;DR

- C++/CLIから直接Windows APIを呼び出す場合は、`Marshal::GetLastWin32Error()`のほうが便利
- C++/CLIの外のライブラリからWindows API呼び出す、または`SetLastError()`する場合は、`GetLastError()`を使用しなければならない。

## Windows APIをC++/CLIから直接呼び出した場合
C++/CLIから直接呼び出と、P/Invoke(DLLImport)のコードが生成される。
ILを確認すると、C#の下記に相当するコードになる。

```csharp
[DllImport("", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
[MethodImpl(MethodImplOptions.Unmanaged)]
[SuppressUnmanagedCodeSecurity]
internal unsafe static extern void* CreateFileW(char* P_0, uint P_1, uint P_2, _SECURITY_ATTRIBUTES* P_3, uint P_4, uint P_5, void* P_6);
```

リンカーの[/CLRSUPPORTLASTERROR](https://docs.microsoft.com/ja-jp/cpp/build/reference/clrsupportlasterror-preserve-last-error-code-for-pinvoke-calls?view=vs-2019)オプションでは、規定で`SetLastError = true`が設定されるようになっている。

そのため、`Marshal::GetLastWin32Error()`でエラーコードを参照でき、`gcnew System::ComponentModel::Win32Exception()`でも最後のエラーコードが使用される。

C++/CLIから`GetLastError()`を呼び出しても、おそらく動作はするはずだが望ましくない(はず)。

## C++/CLIの外のライブラリからWindows API呼び出した場合
DLLやスタティックリンクライブラリからWindows APIを呼び出す、またはその中で`SetLastError()`を呼び出しても、当然P/Invoke(DLLImport)のコードが生成されない。
そのため、CLRからはいつ`SetLastError()`されたかわからないので、明示的に`GetLastError()`を呼び出す必要がある。

そもそも、ライブラリの外で`GetLastError()`をする設計は望ましくない。

## 個人的な方針
Windows APIをC++/CLIから直接呼び出して最後のエラーコードを取得するケースがほとんどで、"C++/CLI"を使っているのだから、理由がなければ`Marshal::GetLastWin32Error()`で最後のエラーコードを取得する。