OmniAICreator/Qiita-1.07M huggingface dataset:
Mac で Gem の native extension のビルドでエラーしてハマった時のメモ


## 概要

- Gem のインストールの際、native extension のビルドでエラー
- Xcode のライセンスに同意することで gcc コマンドが使えるようになって解決
- 参照：[El Capitanでgemのnative extensionビルド失敗に対応 | EasyRamble](http://easyramble.com/failed-to-build-gem-native-extension.html)


## 問題

bundle install の途中、`ffi` という Gem の v1.9.18 をインストール中にエラー：

```bash:
ERROR:  Error installing ffi:
	ERROR: Failed to build gem native extension.
```

## 調査

もちろん次のように Gem を単体でインストールしようとしてもエラーする。

```bash:
$ gem install ffi -v '1.9.18'
```

エラーメッセージの中には development tools を入れろとある。

```bash:
The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
```

メッセージでググってこのページを発見。

- [El Capitanでgemのnative extensionビルド失敗に対応 | EasyRamble](http://easyramble.com/failed-to-build-gem-native-extension.html)

こちらを参考にさせていただきました。


## 解決

以下、参考ページに従って解決。

今回は `xcode-select` はすでにインストール済み。

```bash:
$ xcode-select --version
xcode-select version 2347.
```

しかし、参考ページと同様、gcc コマンドが使えない状態だった。

```bash:
$ gcc --version


Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.
```

メッセージで言われたとおり `sudo xcodebuild -license` を実行する。

```bash:
$ sudo xcodebuild -license
Password:


You have not agreed to the Xcode license agreements. You must agree to both license agreements below in order to use Xcode.

Hit the Enter key to view the license agreements at '/Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf'
```

Enter を押すと、ライセンスが表示されて、`Software License Agreements Press 'space' for more, or 'q' to quit` と言われる（ここでスペース押せば同意？）。
最後まで読むと `By typing 'agree' you are agreeing to the terms of the software license agreements. Type 'print' to print them or anything else to cancel, [agree, print, cancel]` と言われるので `aggree` を入力して同意。

```bash:
You can view the license agreements in Xcode's About Box, or at /Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf
```

これで `gcc` コマンドが使えるようになった。

```bash:
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.37)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
```

こうして `ffi` もインストールでき、めでたく bundle install も通りましたとさ。

```bash:
$ gem install ffi -v '1.9.18'
Building native extensions.  This could take a while...
Successfully installed ffi-1.9.18
Parsing documentation for ffi-1.9.18
Installing ri documentation for ffi-1.9.18
Done installing documentation for ffi after 20 seconds
1 gem installed
```

## 余談

正直、具体的にどこで gcc が使われているのかわかっていません...
Intl.DateTimeFormatのOptionが意味わからない

javascriptでDateをフォーマットするクラス`Intl.DateTimeFormat`というものがありますが、
optionの意味が解りません。
[Intl.DateTimeFormat - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat)

`yyyy/MM/dd`のようなスラッシュ形式にするにはどうしたらいいのでしょう？

すでにQiitaに投稿されている記事で[Intl.DateTimeFormat 日付表記option逆引き表](https://qiita.com/miyukiw/items/df979c83bc85a2ca18fe)も参考になりますが、
結果IEがバグっててどうしていいのかわからないので、片っ端から実行して結果を確認します。

検証用にghpagesに検証用のページを作ったのでお好みのブラウザで試してみてください。
https://ota-meshi.github.io/Intl.DateTimeFormat_options/index.html

localeは[言語のサポート | Google Cloud Speech API | Google Cloud Platform](https://cloud.google.com/speech/docs/languages?hl=ja)を参考にしました。

---

以下、Chrome・Firefox・IE11で確認

# `yyyy/MM/dd HH:mm:ss`形式

結論から言うと3ブラウザでは良い感じのOptionは見つけられませんでした。

`locale: 'en-ZA'`で`hour12: false`とし`year`, `month`, `day`, `hour`, `minute`, `second`を`numeric`とすればとても惜しい、ChromeとFirefoxで、`yyyy/MM/dd, HH:mm:ss`というカンマの入った形式になる様子。

`locale`=`eu-ES`も行けるかと思いましたが、
`eu-ES`はChromeがスラッシュ表記になってくれない様子。

# `yyyy/MM/dd`形式

3ブラウザでは`locale: 'en-ZA'`で`year`, `month`, `day`を`numeric`とすれば良さそうです。

# 結論
YMDのスラッシュ形式は南アフリカが良さそうです。

---

こちらも参考になるかもしれません。
[Date format by country - Wikipedia](https://en.wikipedia.org/wiki/Date_format_by_country)
javascriptで1秒毎の現在時刻の表示

# javascriptで時間の表示を行なう
javascriptのお勉強に1秒毎に現在時刻を表示させたときのメモ

# 実装コード

```html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>時間の表示</title>
</head>
<body>
	<h1 id="time"></h1>
	<script>
	time();
	function time(){
		var now = new Date();
		document.getElementById("time").innerHTML = now.toLocaleTimeString();
	}
	setInterval('time()',1000);
	</script>
</body>
</html>
```
こんな感じになる。
![date2.gif](https://qiita-image-store.s3.amazonaws.com/0/163837/cf35891b-a211-4e9f-f0fa-0c9977537103.gif)

`toLocaleTimeString()`を`toLocaleString()`にすると日付も表示される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/163837/d77f473a-a2c4-203b-2fdf-ea08b374246c.png)

# コードの説明
`Date`オブジェクトのインスタンスを作成し変数`now`に入れる

```js
var now = new Date();
```
`toLocaleTimeString()`メソッドの結果をhtmlに表示

```js
document.getElementById("time").innerHTML = now.toLocaleTimeString();
```
1000ミリ秒ごとに表示

```js
setInterval('time()',1000);
```
Mac > node.jsをインストール



いろんなサイトを見て試してみたがうまくいかず、
以下の設定ではうまくいったのでメモ

## 環境
2017/10/11
macOS Sierra (10.12.6)


## homebrew インストール


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


## nodebrew インストール

### nodebrewの最新版をインストール

```
brew install nodebrew
nodebrew -v
```

### nodeの最新版をインストール
最初に保存するフォルダを作成、その後インストール

```
mkdir -p ~/.nodebrew/src
nodebrew install-binary latest
```

#### nodeのバージョンを指定して入れたい場合には以下

```
$ nodebrew ls-remote

バージョン一覧が表示されるので、任意のバージョン番号を以下の要領で

$ nodebrew install-binary v11.15.0
```


### nodeを有効にする。（vを選択する）

```
$ nodebrew list

バージョン一覧が表示されるので、任意のバージョン番号を以下の要領で指示する。（セットする）

$ nodebrew use vX.X.X
```




## パスを通す
いろんな説明サイトでこの部分が違っており、うまくいかなかったが、
以下の設定でうまくいった。


### zshの場合

```
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc
```

変更の適用

```
exec $SHELL -l
```

確認

```
node --version
```



### bashの場合

```
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```

### bash_profileの編集
viで、~/.bash_profileを編集

```
vi ~/.bash_profile
```

oキーで行を追加し入力モードになる。
以下を追加

```
if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi
```

:wq! コマンドで保存



編集後は以下のようになっているはず

```
export PATH=$HOME/.nodebrew/current/bin:$PATH
if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi
~        
```

## nodeの確認

sourceコマンドで変更を反映させる

```
source ~/.bash_profile
```


```
node -v
```
でバージョンが表示されればOK



## yarnを入れる

```
npm install --global yarn
```




## 参考
https://qiita.com/non0311/items/664cf74d9ff4bad9cf46
短縮URLの危険性を検証してみる

## はじめに
短縮URL便利だなーと使っていたところ適当に入力した短縮URLに個人情報が書いてあったのでちょっと怖くなった…ということがあったので今回はその危険性は検証してみたいと思います！

##どう危険なのか
もうお分かりかとは思いますが、例えばスプレッドシートをリンクを知っている全員に公開とした場合見られちゃう。 
個人情報が書いてあろうものならもう悲惨ですよね。。。

## とりあえず検証
[Google URL Shortener](https://goo.gl/)（goo.glで始まるアレ）のURLが存在するかひたすらリクエストを送って検証。
今回はみんな大好きRubyでやってみます。


```ruby
# 文字列を生成するためのリスト
list = [*'a'..'z', *'A'..'Z', *'0'..'9']
# リストからランダムで文字を取得
short_uri = "https://goo.gl/"+ 6.times.map { list.sample }.join
# =>"https://goo.gl/123ABc"
```
まず、前提条件としてGoogle URL Shortenerは英数字(0-9, a-z, A-Z)が6文字らしい。
なので(0-9, a-z, A-Z）も文字列のリストを作り、その中からランダムで6文字取得しURLを生成する。


**次はURLの存在を確認してみる！**

```ruby
require 'net/http'

Net::HTTP.get_response(URI.parse("確認するURL"))
# =><Net::HTTPMovedPermanently 301 Moved Permanently readbody=true>

```
`Net::HTTP.get_response()`で指定したURLのレスポンスを取得。
Google URL ShortenerはURLが存在する場合`Net::HTTPMovedPermanently`が返ってくるらしい。


**完成コード！！**



```ruby:URLShortening_isDanger.rb
require 'net/http'

def generate_uri
  list = [*'a'..'z', *'A'..'Z', *'0'..'9']
  short_uri = "https://goo.gl/"+ 6.times.map { list.sample }.join
end

def request_uri(uri)
  response = Net::HTTP.get_response(URI.parse(uri))

  case response
  when Net::HTTPMovedPermanently
    puts uri
  end
end


50.times {
  request_uri(generate_uri)
}
```
`URLShortening_isDanger.rb`我ながらに良いネーミングセンスだと思う。

今回は50回適当なURLを叩いて見ました。

結果として、やってみると結構URLがでるでる。
簡単に見つけられちゃうから怖いですね。。。

##まとめ
短縮URLはかなり便利だけど使い方はちゃんと考えた方が良さそう。(誰に見られても大丈夫なものだけに使おう)
今回の件以外にも悪質なサイトに飛ばされるなどいろんな問題があるみたい。

##最後に
今回のソースコードはGitHubにあるのでよければissueなりコメントなりください！
https://github.com/h-akaishi/URLShortening
gitのブランチの命名規則

# TL;DR

最近になって「お、このブランチの命名規則わかりやすくてよいぞ！」という学びを得たのだが意外？と知らないひともいるっぽいので参考に書いておこうと思う。
特にこうでなければいけない…というわけではない。

今のところこの命名規則以上によいと思える命名規則に出会えてない。
こっちのほうがいいよ！とかあればコメントで教えてもらえると助かる、あるいはこの命名規則でかつて困ったことがあるも歓迎。

恐らく知ってるひとにとっては当たり前だし、今更な内容。

# 対象読者 

git使ってブランチ作ることがあるひと。

# お題:

「画像のファイルアップロード先をAWS S3に変更する」というissueがたったとする。
(ブランチ名の英語が無茶苦茶とかいう指摘はとりあえず置いておく)


## Before:

以前は`feature/modify_upload_dest_of_image_file`みたいなブランチを作ってた

## After

今は`feature/#1_modify_upload_dest_of_image_file`に変更。

このときブランチを作成する前に必ずissueを立てさせるという運用ルールを適用している。

## 良くなったこと:

- この作成されたブランチがどのissueに関連したものかが明確になった
- 1つのブランチに複数の修正を入れにくくなった
    - 修正中に見つけた不具合などを修正する際にissueを立てて別ブランチで直す…という流れになった。以前はまとめて1つのブランチで直す人が少なからずいた。
- 「これ直してほしいんだけど…」という依頼に対して「issue立てて」と返せるようになった
    - issue立てないと受けないという建前が出来た
- レビューしやすくなる
    - issueやブランチで修正する内容が細かく、1つのことに集中する形になりやすいためコミットが大きくなりすぎないためコードレビューしやすくなる。
    - ただその分、数が多くなるので改善とはいいにくい面もある。

## 悪くなったこと:

ただ悪い面も少なからずある、メリットに比べてデメリットは我慢というか無視してしまえるものだとは考えている。

- issue立てるのがダルい
    - 変数名のタイプミスを修正する…みたいなissueを立ててしまうことがある、そういうissue立てるほどでない場合にどうすべきか？というのは今のところ個人の裁量に任せっきりであまりよくないと思ってる。
    - 変数名のタイプミスが複数箇所にあるとかでなく、1箇所の場合「これのためにissue立てるのか？！」みたいな気持ちになることがある、とはいえ統一性という面ではそれでも立ててほしくて悩ましい。
- issue&ブランチ多すぎ問題
    - ちょっとした修正、修正中のブランチから更に派生したブランチ、当初のissueでは想定しきれなかったケースのためのissueとブランチを作成…みたいな感じでめっちゃ増えていく。
    - すぐさまマージしてしまえればいいがそうでないとブランチが溜まりに溜まって大変ノイジー。
    - この場合すぐにマージできないことのほうが問題だとは思う。
- issue立てないとなにもしないのかよ！もっと自発的に動け！みたいなこと言われる
    - issueないと動きません、以上。でも言ってくる側の気持ちもわかる。
- hotfixのときどうすんの？レビュー用に新規ブランチ(PR作る用途)作りたいんだけど？ってときに困る
    - その場合は`hotfix/hoge_fuga`とか`review/fuga_piyo`みたいにすれば良い気がするがあまりスマートでない…と感じてる。
    - 通常のbugfixはissue立てさせてる。

# あとがき

きちんと厳密にルールを守らせる必要はあるがissueとブランチが1セットというのが非常に良いと感じていて、割りと話の流れでありがちな「じゃあサクッと直してよ」という口頭&当事者間で完結してしまう依頼を駆逐できる。

言った言わない、どこまでやったやってない、を減らす効果が多少なりともあると感じてる、それでも0にはならない。

あとはかつて修正したissueを参考にしようとしたときにどのブランチだったかな？みたいなときわかりやすくて良い。
認証情報に記号があるときのproxy設定

proxy環境下でyumやpipなど使いたいときにはproxy設定を入れるが、proxyに認証があるとユーザ名・パスワードも入れないといけないので、下記の形式で環境変数を設定したりする。

```
(Windowsの場合の例)

set HTTP_PROXY=http://username:password@proxyhost:port
set HTTPS_PROXY=http://username:password@proxyhost:port
```

ここでusernameやpasswordに記号（\とか@とか^とか…）が入っているとき、そのまま指定することはできない。
URLエンコードする必要がある。

```
(ユーザ名がdomain\username、パスワードがp@ssのとき)

set HTTP_PROXY=http://domain%5cusername:p%40ss@proxyhost:port
set HTTPS_PROXY=http://domain%5cusername:p%40ss@proxyhost:port
```

web系の人には常識中の常識なんだろうけど、あまり記号のあるケースの記事もなく、気づくのに結構かかってしまった。
PHP7でスカラ型タイプヒントによるキャストの挙動

# PHP7のint float string boolのタイプヒントによるキャストの挙動を試してみました。

stringとboolは(string)と(bool)でのキャストと違いはなさそうでしたが、
**intとfloatは(int)と(float)でのキャストと違いがあった。**

nullはnull許容の書き方をしなければTypeErrorですが
**null許容の書き方を行えばnullはキャストされません。**

```
function A(int $arg = null){var_dump($arg);}// null許容の書き方

A('100');// int(100)
A(null);// NULL (int)nullは(int)0になるのでキャストしていない
A();// NULL
A('abc');// TypeError (int)'abc'は(int)0になるので(int)でキャストしているわけではない
A('1bc');// int(1) Notice A non well formed numeric value encountered in
```
```
function B(?int $arg){var_dump($arg);}// null許容の書き方(引数の省略は出来ない)

B('100');// int(100)
B(null);// NULL (int)nullは(int)0になるのでキャストしていない
B();// ArgumentCountError
```
```
function C(int $arg){var_dump($arg);}

C('100');// int(100)
C(null);// TypeError
```

```
function D(float $arg){var_dump($arg);}

D(100); // float(100)
D(null);// TypeError
D('abc');// TypeError (float)'abc'はfloat(0)になるので(float)でキャストしているわけではない
D('1bc');// float(1) Notice A non well formed numeric value encountered in
```

## **[strictモード](http://php.net/manual/en/functions.arguments.php#example-146)**

```
declare(strict_types=1);
```

にすると型が異なる場合はキャストせずにTypeErrorを出すようです。


# 思ったこと
個人的にはキャスト自体してほしくないですが文字列が無理やりキャストされていなくて少し安心しました。

# メモ
関数の戻り値に型の設定できます。

## 例

戻り値無し

```
function XXXX() :void
{}
```

null許可のstring

```
function XXXX() :?string
{}
```

配列

```
function XXXX() :array
{}
```
tf.summary.merge_allに含めたくないTensorがある時の対処法

# 環境
ubuntu 16.04
tensorflow 1.3.0
python 3.5

# tensorboardのtf.summary.merge_all
tensorboardを使うとき、複数のsummaryのTensorを実行用にまとめるため、よく下記のようにmerge_allを使う。

```python
# これらは一例
x = tf.constant(3)
y = tf.constant(3)
image = tf.ones([1, 10, 10, 1])
#

# summaryのTensor作成
tf.summary.scalar("x", x)
tf.summary.scalar("y", y)
tf.summary.image("image", image)
merged = tf.summary.merge_all()

print(tf.get_default_graph().get_collection(tf.GraphKeys.SUMMARIES))
# => [<tf.Tensor 'x:0' shape=() dtype=string>, <tf.Tensor 'y:0' shape=() dtype=string>, <tf.Tensor 'image:0' shape=() dtype=string>]
```

# tf.summary.merge_all に含めたくないTensorがあるとき

しかし、上記でimageだけmergedに含めたくない時はどうするか。
例えば画像情報の保存は負荷が高いので、訓練中には実行したくなかったりする。

summaryのTensor数が少ないうちは個別実行でもよいが、数十とかなってくると厳しい。

途中でmerge_allして、後から含めたくないものだけ定義する方法もあるが、あまりきれいではない気がする。

# 解決策

merge_allの実際の動作は、tf.GraphKeys.SUMMARIESに含まれているTensorをまとめて一つのTensorにするというもの。（引数でどのGraphKeysにするか指定もできる。）
そこで、下記のように、summary定義の際にcollections=[]を指定してみる。


```python
# summaryのTensor作成
tf.summary.scalar("x", x)
tf.summary.scalar("y", y)
image_summary = tf.summary.image("image", image, collections=[]) # 追加先のcollectionをなしにする
merged = tf.summary.merge_all()

print(tf.get_default_graph().get_collection(tf.GraphKeys.SUMMARIES))
# => [<tf.Tensor 'x:0' shape=() dtype=string>, <tf.Tensor 'y:0' shape=() dtype=string>]
```

このようにすると、collections=[]を指定したTensorだけ、tf.GraphKeys.SUMMARIESに追加されないため、merge_allの対象からも外すことができる。

imageを保存したいタイミングで、別途image_summaryをrunしてあげればよい。

（・・・これもきれいな方法ではない気はするし、正直GraphKeysの理解も乏しいのでもっといい方法がありそうな気はする。。）
Raspberry PiでSPI1/CE#2を使う（＋起動が遅くなる問題を回避する）

40ピンあるRaspberry Pi(Model A+/B+/2B/3B/Zero/Zero W)は，SPIが2系統備わっています．GPIO16/19/20/21が2系統目のSPI1です．

[RPi Low-level peripherals - eLinux.org](https://elinux.org/RPi_Low-level_peripherals#Model_A.2B.2C_B.2B_and_B2)
![300px-Pi-GPIO-header.png](https://qiita-image-store.s3.amazonaws.com/0/1045/1937c269-981f-b2b1-8cc1-3f8016d55244.png) 

ただし，単にSPIを有効にしただけでは，下記の通りSPI1は使えません．

```
>>> import spidev
>>> spi = spidev.SpiDev()
>>> spi.open(1,2)         # SPI1,CE#2を使おうとする
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory
```

```
$ ls /dev/spi*
/dev/spidev0.0  /dev/spidev0.1 
(spidev1.*がない...)
```

設定ファイルを書き換えると有効化できるのですが，バージョンによっては**起動がめちゃくちゃ遅くなる**ことがあるため，回避策も一緒に設定しておかないと悲しいことになります．

## 手順1. SPI1の有効化

SPI1を有効にするには， ```/boot/config.txt``` に下記を追加します．

```
dtoverlay=spi1-3cs
```

ただし，そのまま再起動*してはいけません*．

## 手順2. シリアルコンソールかBluetoothを無効化

SPI1,シリアルコンソール(UART),Bluetoothでリソースが競合するようです．無効化はどちらかで構いません．

### シリアルコンソールを無効化

```/boot/cmdline.txt``` の ```console=ttyAMA0,115200```(または```console=serial0,115200```) を削除します．

```
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait fbcon=map:10 fbcon=font:ProFont6x11 logo.nologo
```

### Bluetoothを無効化 (Raspberry Pi 3 Model B/Zero Wのみ)

```/boot/config.txt``` に下記を追加します．

```
dtoverlay=pi3-disable-bt
```

## 手順3. 再起動してSPI1を使う

これで設定は完了です．再起動すると，SPI1が使用可能になっているはずです．

```
$ ls /dev/spi*
/dev/spidev0.0  /dev/spidev0.1  /dev/spidev1.0  /dev/spidev1.1  /dev/spidev1.2
```

```
>>> import spidev
>>> spi = spidev.SpiDev()
>>> spi.open(1,2)         # エラーにならない
>>> 
```

## もしも起動が遅くなってしまった場合…

私の場合は30分経っても起動が終わらず，SSHも繋がりませんでした．

この場合，Raspberry Pi以外のデバイスで，microSDカードの内容を書き換えます．

1. 諦めて電源を切りましょう（データがぶっ壊れないことを祈りながら）．
1. カードリーダ，スマートフォン，カメラなどで，どうにかmicroSDカードを読み書きできる環境を整えます．
1. cmdline.txtやconfig.txtを編集しましょう．/boot領域はFATなので，Windowsからも見えます．

## 検証環境

- Raspberry Pi 3 Model B / Raspbian Jessie (8.0) / Linux kernel 4.4.50-v7+

## 参考資料

- [RB Pi 3 fail to load SPI1 - Raspberry Pi Forums](https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=146291)
- [Aux SPI (SPI1) + Console on Aux UART (ttyS0) = Lockup · Issue #1484 · raspberrypi/linux](https://github.com/raspberrypi/linux/issues/1484)
Kaggle - The Nature Conservancy Fisheries Monitoring上位陣リンク一覧

KaggleのThe Nature Conservancy Fisheries Monitoring[^1]の上位陣リンク一覧です

- [1位][bobutis](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538)
- [2位][Liuftvafas](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538)
- [4位][Russ W](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538)
- [7位][bestfitting](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538)
- [8位][Felix Yu](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538), ✎[Writeup](https://flyyufelix.github.io/2017/04/16/kaggle-nature-conservancy.html)
- [9位][Zsolt Vadaszi](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538)
- [10位][Krzysztof Dziedzic](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538), ✎[Qiita](https://qiita.com/namakemono/items/b64f669a96dc496ab247)
- [12位][Rand Xie](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538),✎[Qiita](https://qiita.com/namakemono/items/97ff80a976fc268a36f7)

## References

[^1]: Kaggle, [The Nature Conservancy Fisheries Monitoring](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring), 2017.
エラトステネスの篩の高速化 (2)

[1本目](https://qiita.com/peria/items/a4ff4ddb3336f7b81d50) からの続きになります。その他の高速化は

- [エラトステネスの篩の高速化 (1)](https://qiita.com/peria/items/a4ff4ddb3336f7b81d50)
- エラトステネスの篩の高速化 (2) ← **今ココ**
- [エラトステネスの篩の高速化 (3)](https://qiita.com/peria/items/e0ab38f95d16a5f7cc58)
- [エラトステネスの篩の高速化 (4)](https://qiita.com/peria/items/7c62831ad9781c7c1577)
- [エラトステネスの篩の高速化 (5)](https://qiita.com/peria/items/ffc58b31470ad3297567)
- [エラトステネスの篩の高速化 (6)](https://qiita.com/peria/items/c1d8523342e81bb23375)
- [エラトステネスの篩の高速化 (7)](https://qiita.com/peria/items/e35ddf9af359388514d8)

辺りを参照してください。

# 3,5 の倍数の省略
[前回](https://qiita.com/peria/items/a4ff4ddb3336f7b81d50) 2 の倍数を省いて倍速化したように、3 の倍数を省けば 3/2 倍、5 の倍数を省けば 5/4 倍の高速化が期待されます。が、それ以上に 5 の倍数まで除くと候補として残る数が

```math
30k+\{1,7,11,13,17,19,23,29\}
```

と全体の 8/30 になるので、コンピュータで扱うことがとても便利になります。具体的には $k$ バイト目の $i$ ビット目を $30k+m_i$ と対応させることができます。なお $\\{m_i\\}$ は上記の式の {} の中身に対応します。
あと検証してみると分かりますが、この数のまとまりに含まれる数同士は掛け合わせてもこのまとまりの中にありますし、他の数とかけ合わせるとこのまとまりから外れた結果になります。つまり数学っぽい言葉でいうと、この集合は乗算で閉じています。
では数とビットとの対応が簡単になったので、今度は篩う位置の計算をどのようにするか検討しましょう。

## 篩の初期位置

まず素数 $p=30k+m$ で篩う初期ビットは、$p^2$ の数を求める式を展開することで

```math
\begin{eqnarray}
(30k+m)^2 &=& 30^2k^2 + 2\cdot30km + m^2\\
&=& 30\times \left\{k(30k+2m)+\left\lfloor\frac{m^2}{30}\right\rfloor\right\} + (m^2 \bmod  30)
\end{eqnarray}
```

に対応するビットだということがわかります。つまり $k(30k+2m)+\lfloor m^2/30\rfloor$ バイト目の $m^2\bmod 30$ に対応するビットです。前者についてはそのまま計算することになりますが、後者については $m$ から求められる表を用意しましょう。ただ、素直に考えると 8 要素の配列で大丈夫なのですが、後の再利用を兼ねて 8x8 の表を作っておくと楽です。詳細は後述。

## 篩う位置の移動

ついで移動処理についてですが、これについては

- 今どの素数 ($p=30i_1+m_{j_1}$) で篩っているのか
- 今どの数 ($q=30i_2+m_{j_2}$) を掛けた合成数を篩ったのか

の情報が必要になります。まずはバイト位置を計算しましょう。ちょっと面倒ですが、

```math
\begin{eqnarray}
&& \left\lfloor\frac{1}{30}(30i_1+m_{j_1})(30i_2+m_{j_2+1})\right\rfloor
   - \left\lfloor\frac{1}{30}(30i_1+m_{j_1})(30i_2+m_{j_2})\right\rfloor \\
&=&i_1(m_{j_2+1}-m_{j_2}) + \left\lfloor\frac{m_{j_1}m_{j_2+1}}{30}\right\rfloor - \left\lfloor\frac{m_{j_1}m_{j_2}}{30}\right\rfloor
\end{eqnarray}
```

となります。$j_2$ が定まれば $m_{j_2}$ も $m_{j_2+1}$ も決まるので、要素 8 の配列と、8x8 の 2 次元配列を用意すれば効率的に計算できることがわかります。

ビット位置については初期位置で使いまわそうとした 8x8 のテーブルが便利です。このテーブルは要するに $m_im_j \bmod 30$ を表せばいいだけのテーブルですが、計算処理のことを考えると $m_im_j \bmod 30$ の数を直接持つよりも該当ビットを外すビットマスクにする方が効率的です。

以上を踏まえた今回のコードは [github](https://github.com/peria/primes/tree/master/eratosthenes) の Version 2 に該当します。

ちなみに用語情報だけ追加しておくと、今回のように不規則っぽい間隔(落としていく1つ1つのビットの間隔)で規則的(8個ビットを落とすと$p$バイトずつ進んでいる点)に篩っていく方法を、英語では Wheel Sieve といいます。ハンドルとかタイヤみたいな円いものというより、いくつか歯の欠けたギアみたいなものをイメージすると良いかもしれません。

# 計算時間

目安として、計算時間を記録しておきます。単位は秒。

|$x$|$\pi(x)$|Ver. 0|Ver. 1|Ver. 2| 
|--:|-------:|-----:|-----:|-----:|
|$10^7$|664579|0.047|0.017|0.007|
|$10^8$|5761455|1.039|0.352|0.189|
|$10^9$|50847534| - | 6.180|3.377|

# 補足：ビット処理

立っている最下位ビットを取得

```cpp
n & (-n)
```

立っている最下位ビットを削除

```cpp
n & (n - 1)
```

ビットカウント（実装しなくても専用命令が多くの CPU の場合あります）

```cpp
uint64 PopCnt(uint64 n) {
  n = (n & 0x5555555555555555ULL) + ((n >> 1) & 0x5555555555555555ULL);
  n = (n & 0x3333333333333333ULL) + ((n >> 2) & 0x3333333333333333ULL);
  n = (n & 0x0f0f0f0f0f0f0f0fULL) + ((n >> 4) & 0x0f0f0f0f0f0f0f0fULL);
  return (n * 0x0101010101010101ULL) >> (64 - 8);
}
```
Xcode9.0.0のCCFileUtils.cppででたエラーの対処法

Xcodeのバージョンを9.0.0にした時に出たので一応記録しておきます

```ruby:removeDirectory
{
    if (path.size() > 0 && path[path.size() - 1] != '/')
    {
        CCLOGERROR("Fail to remove directory, path must terminate with '/': %s", path.c_str());
        return false;
    }

    std::string command = "rm -r ";
    // Path may include space.
    command += "\"" + path + "\"";
    if (system(command.c_str()) >= 0)  //この行でエラーが発生！！
        return true;
    else
        return false;
}
```

エラーの内容は
Call to unavailable function 'system': not available on iOS

以下のリンク先を参考にしたらうまくいきました。
https://github.com/spaceinch/cocos2d-x/commit/96c3061928af2536f969caf6ab00572c873a54ec
prettier-markdownでmarkdown内のコードを整える

https://github.com/DSchau/prettier-markdown

markdown内のコードブロックにprettierを用いたコードフォーマットを実行するツール。これは欲しかったやつなので、[試してみました](https://github.com/pirosikick/prettier-markdown-playground)。

## インストール

[prettier-markdown](https://www.npmjs.com/package/prettier-markdown)ではなく、[@dschau/prettier-markdown](https://www.npmjs.com/package/@dschau/prettier-markdown)なので注意。`prettier-markdown`もUSAGEを見ると同じような機能だが、動かしてみると前者はscssのフォーマットがちゃんと動かなかった。また、`--single-quote`などのprettierにあるオプションももしかして指定できない感じ？であまり良くなさそう。

```console
$ yarn add -D @dschau/prettier-markdown
```

## 実行

以下のようなコードブロックが汚いmarkdownファイルを用意する

<pre>
$ cat README.md
## JS

```js
      function hoge(
        arg1,
    arg2) {
          return
        'hoge';
}
```

## SCSS

```scss
.hoge      { .fuga {
    .duga {
      text-align:
        center;
  } } }
```
</pre>

CLIは、`prettier-markdown 対象ファイル オプション`の形式で実行する。対象ファイルは`src/**/*.md`みたいな形式でもOK。オプションは`prettier`にダイレクトに渡されるっぽいので、`--single-quote`など、prettierにあるオプションはそのまま使える。`--dry`オプションだけが例外で、`--dry`オプションを使うと、どのファイルが更新されるかが表示されるが、実際にはファイルは更新されないお試しモード（dryrun）で実行できる。（prettierのWarningっぽいのが出力されるが、バグかしら？）

```console
# dryrunで実行
$ yarn run prettier-markdown README.md --single-quote --dry
yarn run v1.1.0
warning package.json: No license field
$ "/Users/xxx/xxx/xxx/node_modules/.bin/prettier-markdown" "README.md" "--single-quote" "--dry"
Warning: `parser` with value "postcss" is deprecated. Use "css", "less" or "scss" instead.
Prettified 1 file
✔︎ Updated /README.md
✨  Done in 0.43s.

# 実行
$ yarn run prettier-markdown README.md --single-quote
yarn run v1.1.0
warning package.json: No license field
$ "/Users/xxx/xxx/xxx/node_modules/.bin/prettier-markdown" "README.md" "--single-quote"
Warning: `parser` with value "postcss" is deprecated. Use "css", "less" or "scss" instead.
Prettified 1 file
✔︎ Updated /README.md
✨  Done in 0.49s.
```

実行した結果を見てみる。

<pre>
$ cat README.md

## JS

```js
function hoge(arg1, arg2) {
  return;
  ('hoge');
}
```

## SCSS

```scss
.hoge {
  .fuga {
    .duga {
      text-align: center;
    }
  }
}
```
</pre>

きれいになっている〜。prettierがサポートしている言語ならばフォーマット可能。~~あとは、[pre-commit](https://www.npmjs.com/package/pre-commit)、[lint-staged](https://www.npmjs.com/package/lint-staged)を使って、コミット時に自動フォーマットするようにすれば、漏れなくフォーマットされる。~~と、思ったが、`prettier-markdown 対象ファイル　オプション`の形式なので、`--single-quote`などオプションを指定する場合に`lint-staged`が使えないかも（何か方法があったら教えてください）。

複数人で行う執筆活動等で最後に確認したら全員のコードフォーマットが違う、みたいなことがよくあるので、prettier-markdownを使って一気に統一するとよさそうですね。
SRE本まとめ（18章 SREにおけるソフトウェアエンジニアリング）

自分の理解を深めるためにまとめてみました。[17章](https://qiita.com/bassbone/items/3b7a6e90000a9a602eef)の続きです。

## 18章 SREにおけるソフトウェアエンジニアリング

### SRE内でのソフトウェアエンジニアリングの重要性
GoogleはSREとしての経験を持つエンジニアがソフトウェアを開発していることで明らかにメリットを得ている。ソフトウェアエンジニアリングによってSREは指数関数的に拡大するサービスに対して、チームは線形でしか拡大しないようになっている。

### SREにおけるソフトウェアエンジニアリングの推進
SREはゼネラリストであることが多い。深さ優先よりも幅優先で学びたいという意欲がある。

（[19章](https://qiita.com/bassbone/items/3652503804a1f366cdaa)に続く）
【ionic】カレンダーの実装

ionic2で家計簿アプリを作ってます。
https://qiita.com/irohamaru/items/3df901cd7e12e3c85e9a

今回、カレンダーを実装したのですが、つまったポイントなどをまとめました。

##ionic2-date-picker
今回使ったのはionic2-date-pickerというコンポーネント。

ionic2-date-picker
https://www.npmjs.com/package/ionic2-date-picker

![スクリーンショット 2017-10-11 21.23.01.png](https://qiita-image-store.s3.amazonaws.com/0/186221/a477b494-86ab-fedb-5a71-bcbf2391a9e4.png)

##とりあえず組み込んでみる

自分のアプリに組み込んでみます。

カレントディレクトリを自分のアプリ（node_modulesが配置されているディレクトリ）にした後、以下のとおりインストール実行。

```
$ npm install -g ionic-date-picker --save
```

組み込み方は[先ほどのページ](https://www.npmjs.com/package/ionic2-date-picker)に書いてあるとおりです。
ボタン押下後、メソッド「showCalendar」でカレンダーを呼び出す場合の実装方法について書かれてます。


##日付選択でカレンダーを閉じるようにする

デフォルトの仕様だと、「Cancel」または「OK」ボタンを押した後でないとカレンダーは閉じないようになっています。
今回、日付選択した後にカレンダーを閉じるようにしたいので、ちょっと改造します。

以下のjsを修正します。
jsに記述された「Component」の部分で、キャンセル、OKボタンのタグが記述してある部分を消すだけです。

```js:[アプリ名]/node_modules/ionic-date-picker/date-picker.esm.js

（中略）

DatePicker = DatePicker_1 = __decorate([
    Component({

（省略）
// ↓を消す
\n    <button ion-button style=\"color:grey\" clear (click)=\"cancel()\">Cancel</button>\n    <button ion-button clear (click)=\"confirmDateSelection()\">OK</button>\n  </div>\n\n\n</div>
```

日付選択でカレンダーを閉じるために、日付選択時のメソッド「selectDate」を修正します。

キャンセル、OKボタン押下時に実行されるthis.viewCtrl.dismiss()を追加しますが、閉じた後の画面に日付のパラメータを引き渡したいので、引数に「this.selectedDateItem.momentDate.toDate()」を入れます。

```js:date-picker.esm.js
    DatePicker.prototype.selectDate = function (day) {
        if (!day.isEnabled)
            return;
        if (this.selectedDateItem && this.selectedDateItem.isSelected) {
            this.selectedDateItem.isSelected = false;
        }
        day.isSelected = true;
        this.selectedDateItem = day;
        this.currentMoment = day.momentDate.clone();

        // ↓を追加
        this.viewCtrl.dismiss(this.selectedDateItem.momentDate.toDate());
    };
```

引き渡された日付のパラメータは、

```ts:sample.ts
    this.datePicker.onDateSelected.subscribe(
      (date) => {
        this.param = date
      });
```

のように、カレンダーを閉じた後の画面で定義された変数に代入することで、画面に表示することができます。
(date) => ... のdateが、引き渡された日付のパラメータです。

※this.datePicker.onDateSelected.subscribe(...)の部分は、ionic2-date-pickerの実装サンプルに記載されているソースコードです。
ROCK64を使ってみた

# はじめに

ROCK64というワンボードコンピュータを買いました。
メモリ4GB、ギガビットイーサネット、USB3.0がついて約6500円という、コスパ最強のコンピュータです。
ですが、日本語の情報が少ないようなので、OSのインストール方法など、使い始めるまでの流れを書いておきます。

# 準備するもの

* [ROCK64 MEDIA BOARD COMPUTER](http://akizukidenshi.com/catalog/g/gM-12382/)
* [ACアダプタ](https://www.amazon.co.jp/gp/product/B074SXQ4QL)
* MicroSDカード

今回はメモリが4GBのモデルを秋葉原の[秋月電子](http://akizukidenshi.com/catalog/default.aspx)で購入しました。
ACアダプタはAmazonで購入しました。
MicroSDカードは8GBのものを使用しました。

# 注意点

注意してほしいのはACアダプタのサイズです。
**内径が1.35mm、外径が3.5mm** のものを使用してください。
また、 **5V3Aを供給できるもの** を選んでください。
今回購入したものでは正常に動作しました。

# OSのインストール

1. まず、MicroSDカードを[SDメモリカードフォーマッター](https://www.sdcard.org/jp/downloads/formatter_4/)でフォーマットします。
2. その後、GitHubから[PINE64-Installer](https://github.com/pine64dev/PINE64-Installer/releases/)をダウンロードし、インストールしてください。
3. インストールが終わったらPINE64 Installerを起動します。
4. 「Choose an OS」を選択します。
5. 「Please select your borad」で「ROCK64」を選択します。
6. その後、インストールするOSを選びます。今回は「Community Xenial Minimal　(ROCK64 SDCard)」の「build 0.5.10-118」を選択しました。
7. OSをインストールするデバイスにフォーマットしたMicroSDカードが選ばれていることを確認して、OSをインストールします。
8. インストールが終わったら、MicroSDカードを取り外します。

# 起動

ROCK64に、

* MicroSD
* HDMIケーブル
* キーボード
* LANケーブル

を接続し、最後にACアダプタを接続します。
そうすると電源が入ります。

# ログイン

初期アカウント、初期パスワードは、どちらも `rock64` です。
以上でOSインストールは完了です。

# 最後に

`$ free -h` の結果はこんな感じです。

```
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           3.8G         32M        3.7G        8.6M        100M        3.8G
Swap:            0B          0B          0B
```

OSのインストールはとても簡単でした。
スペックを考えるとRaspberryPiよりもROCK64を買ったほうがいい気がします。
もっとツールを作りたい。もっともの作りしたい。ずっとしていたい。

###Game A Week
さっき届いたQiitaのメールを見ていたら、Game A Weekというなんというか遊びで、15週で20本のゲームを作ったという記事があった。記事を見たら、さらに今年50本のゲームを作った、という人もいた。なるほどなと思う。
なるほどな、というのは、ゲームではないが、過去にたしか2011年から2013年にかけて、毎週1本新作ソフトを作って記事を書いて公開するというのを、某おばあちゃんの知恵袋的なところでやっていたことを思い出したからだ。

###3year over 150
3年続いたので、合計150本以上。アイデアはまったく尽きなかったし、いくらでもつづけられたと思う。
毎週1本だったが、ソフト作成+記事執筆にかけていた時間は、最大でも2日くらいで、たいていは6～8時間程度で終わっていた。つまり朝から作り始めて、早いと14時くらいに終わる感じだった。
そのほかの日も自分用のソフトを開発していたので、自分用のソフトは、公開用のソフトのだいたい7倍くらいの機能をもっていたことになる。そのソフトは現在も開発しつづけていて、どのくらい機能があるかどうかはわからない。今日も3つくらい機能を追加した。今日はTodo.lyの検索機能を追加した。あとこまごまと。

###多作、多産
自分でも、多作だなぁと思う。多産だと思う。ものすごく手が早いと思う。手が早いし、ツールを作ることに時間をかけるから、ツールで楽できるところもたくさんある。
ま、そんなことを思ったのだった。
もっとツールを作りたい。もっともの作りしたい。ずっとしていたい。
(この記事10分)。
実行したコマンドを簡単に記録し、メモも付加する。/How to easily record commands you ran and add notes

作業のログを取りたいとき、以前書いたような方法で全部のコマンドを記録することができます。しかし色々とコマンドを試しながら作業を進める場合、全部のコマンドを記録するのは無駄で、作業の各ステップで最終版のコマンドだけを選んで記録したいことがあります。また、それにメモ書きも加えたいところです。これを簡単に行うシェルの関数を紹介します。

When you want to record your operations, you can record every command by means like in my previous entries. But it's often meaningless to record all of your commands if you're trying to figure out how to do something. You may want to pick the final version of the commands for each step of your operation, and then want to add notes to explain what that command does. Here is an easy way to do that by some original functions of the shell.

以下を.bashrcか.zshrcに加えてください。
Add the following to your .bashrc or .zshrc

```
# Functions to record operations
function rcmd() {
    touch commands.log
    echo "# ---`date +%F_%T`---" >>commands.log
    fc -ln | tail -n 1 >> commands.log
    echo "Recorded: `tail -n 1 commands.log`"
}
function rnote() {
    touch commands.log
    echo "# $@" >> commands.log
    echo -e "Recorded: `tail -n 1 commands.log`"
}
function rrun() {
    chmod u+x commands.log
    ./commands.log
}
```

すると直前のコマンドの記録には`rcmd`、メモの付加には`rnote`が使えるようになります。さらに`rrun`で記録したコマンドを実行できます。記録先はカレントディレクトリの`commands.log`です。記録先を選択するのは手間なので決め打ちにしています。以下実行例。

Now you can hit `rcmd` to record your last command, `rnote` to add notes with it, and `rrun` to run saved commands. Commands are recorded to `commands.log` in the current directory, which is hard-coded for simplicity. 

```
> echo test
test

> rcmd
Recorded: echo test

> rnote just tested
Recorded: # just tested

> cat commands.log
# ---2017-10-11_21:00:00---
echo test
# just tested

> echo test2
test2

> rcmd
Recorded: echo test2

> rrun
test
test2
```
Square APIを使って商品を作成&削除する

Squareはデータをクラウドに持っていますので、APIを使って遠隔地にあるレジデータを操作できます。

今回は商品をAPIで作って、削除する流れを紹介します。言語はRubyを使います。

### SDKの初期化

利用するのは [square_connect](https://github.com/square/connect-ruby-sdk/) というライブラリです。これはRubygemsでインストールできます。

```
$ gem install square_connect
```

そしてSquare Developer Portalで取得できるアクセストークンを使います。

```
access_token = 'YOUR_ACCESS_TOKEN'
require 'square_connect'
SquareConnect.configure do |config|
  config.access_token = access_token
end
```

### 店舗情報を取得する

商品を登録する際には店舗情報が必要です。そのため、まずは店舗情報を検索します。

```
locations_api = SquareConnect::LocationsApi.new
begin
  locations = locations_api.list_locations.locations
rescue SquareConnect::ApiError => e
  puts "店舗情報取得時にエラーが発生しました。 #{e.message}"
  return
end

location = locations.first
```

### 商品を登録する

店舗情報を取得したら、商品を登録します。この時、v2（バージョン2）のAPIにはカタログAPIが用意されていますが、v1（バージョン1）の商品APIで登録する方が確実です。v2で登録した商品を表示しようとすると、レジアプリが落ちてしまうことがあります。

基本的にはオプショナルなのですが、バリエーションデータは必要なようです。

```
api_instance = SquareConnect::V1ItemsApi.new

item = SquareConnect::V1Item.new(name: 'APIから追加')

variation = SquareConnect::V1Variation.new
variation.name = 'Black'
variation.price_money = SquareConnect::V1Money.new(amount: 100, currency_code: 'JPY')
item.variations = [variation]

begin
  item = api_instance.create_item(location.id, item)
rescue SquareConnect::ApiError => e
  puts "商品登録時にエラーです。 #{e}"
  exit
end
```

### 商品を削除する

商品を削除する場合は店舗のIDと商品IDの2つが必要になります。

```
api_instance.delete_item(location.id, item.id)
```

### デモ

デモとして商品を登録後、20秒後に削除するというスクリプトを実行します。iPhoneのレジアプリの画面を出していますが、APIをコールして少しするとレジアプリの商品一覧にデータが反映されるのが分かります（動画は編集して待ち時間を省略しています）。

![square-item-create-delete.mp4.gif](https://qiita-image-store.s3.amazonaws.com/0/197026/0a76309d-587f-15ae-5613-205ebbdf4d6e.gif)

このように遠隔地にあるアプリを含めて情報をすばやく伝達できるのがSquare APIの良さではないでしょうか。更新ボタンを押したり、アプリを一度落としたりする必要もありません。

[Square Connect API Documentation](https://docs.connect.squareup.com/)
BitriseでAndroidのビルド時にライセンスエラーが出る問題に対する解決

# 問題
AndroidのBuild tools versionをあげたらなぜかBitriseでビルドできなくなったよ！


``` build.gradle
buildToolsVersion "26.0.2"
```

みたいな設定をしたプロジェクトをBitriseでビルドしようとすると
>Checking the license for package Android SDK Build-Tools 26.0.2 in /opt/android-sdk-linux/licenses
Warning: License for package Android SDK Build-Tools 26.0.2 not accepted.
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> You have not accepted the license agreements of the following SDK components:
  [Android SDK Build-Tools 26.0.2].
  Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
  Alternatively, to learn how to transfer the license agreements from one workstation to another, go to http://d.android.com/r/studio-ui/export-licenses.html

みたいなエラーがでてビルドできません。



[BitriseCIでAndroidSDKのライセンスエラー]("http://saburesan.hatenablog.com/entry/2017/10/11/130513")
こちらのページにライセンス情報をBitriseにアップすればOKとあったのですが、それだけれはだめでした。


# 解決方法

1. まずはローカルで`sdkmanager --licenses`を実行
2. ライセンスを承認するかを聞かれるのでひたすらyキーを押す
3. `$ANDROID_HOME/licenses/`にライセンス情報ファイルができる
4. android-sdk-licenseとandroid-sdk-preview-licenseが更新されるので、これをbitriseにアップロード
5. ビルドの前に、Bitrise環境の`$ANDROID_HOME/licenses/`以下に上記の2ファイルが配置されるようWorkflowを調節
6. ビルドできるようになる！


どうもローカルのAndroidStudioなどでsdkをアップデートしている場合などに、ライセンス情報のファイルがアップデートされない場合があるっぽい。
なので、アップロード前に、一度`sdkmanager --licenses`を実行することで、強制的にライセンス情報ファイルをアップデートするのが吉。
bs4でHTMLタグを含む文字列を扱う時の挙動

# 概要
- bs4の文字列抽出の挙動についての実験

# まとめ
- `soup.p.string`がNoneになるのはNavigableStringの仕様どおり
- soupで読み込んだ時点で閉じタグがないタイプのタグは補完が行われていると思われる
    - たとえ`<br>`であっても。。

# 共通部分
```
from urllib.request import urlopen
from bs4 import BeautifulSoup

html = """
<p>
  tanaka
  <br>
  tarou
  <br>
</p>
"""
soup = BeautifulSoup(html, 'html.parser')
```

# やりたいこと
-　型はなんでもいいから"tanaka tarou"が取り出したい

# 抽出のための試行錯誤
- 実行結果の後にコマンドの形式で記載
- 
## 最も単純なパターン
```
# None
print(soup.p.string)
```

## stringsでループ
```
'''

  tanaka


  tarou



'''
for string in soup.p.strings:
    print(string)
```

## brタグを除去
```
'''
<p>
  tanaka
  </p>
'''
# soup内のbrタグを全削除
[s.extract() for s in soup('br')]
print(soup.p)


'''

  tanaka

'''
print(soup.p.title)
```

# さらに実験
- soup上でご丁寧にbrの閉じタグが保管されていた。。。

```
'''
<br>
  tarou
  <br>
</br></br>
'''
print(soup.br.string)
```
【忘備録】Tensorflow



# インストール

## Windowsにインストール

* 公式サイトを参考にしています。
https://www.tensorflow.org/install/install_windows

* 公式のインストールマニュアルでは、`conda`コマンドでPython3.5の仮想環境を作っていますが、2017年9月時点では不要だったので省略しました。
  - Tensorflow 1.2.0からPython3.6に対応したためです。https://github.com/tensorflow/tensorflow/blob/master/RELEASE.md

## インストール方法

1. Anaconda のインストール
https://www.continuum.io/downloads

2. 「Anaconda Prompt」で、Tensorflowをインストール
 
* CPU-only versionをインストールする場合

```shell-session
(Anaconda)C:> pip install --ignore-installed --upgrade tensorflow 
```
 * GPU versionをインストールする場合

```shell-session
(Anaconda)C:> pip install --ignore-installed --upgrade tensorflow-gpu 
```


## インストールの確認

* 「Anaconda Prompt」で、Tensorflowをインストール

```shell-session
(Anaconda)C:> python
```

* Pythonインタラクティブシェルで、以下を入力

```py
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
```

* "Hello, TensorFlow!"という文字が出ればOK


## Pythonの動作環境

* IPython：入力補完や色付けしてくれるので、`python`コマンドより便利。「Anaconda Prompt」で`ipython`を実行する。
https://ja.wikipedia.org/wiki/IPython
* Jupyter Notebook：作成したプログラムや実行結果を保存できる。内部ではIPythonを実行しているみたい。「Anaconda Prompt」で`jupyter notebook`を実行する。http://jupyter.org/

## とりあえずサンプルプログラムを実行
[MNIST For ML Beginners](https://www.tensorflow.org/get_started/mnist/beginners)のサンプルコード[mnist_softmax.py ](
https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/examples/tutorials/mnist/mnist_softmax.py) を実行する。


1. minist_softmax.pyを保存する
2. 「Anaconda Prompt」で`python minist_softmax.py`を実行する。
3. 結果の"0.9183"が認識精度（91.83%)
[python] 複数行の標準入力の処理


paizaの問題で「複数行に渡る標準入力を受け取り、１行目と３行目以降の数字のペアを用いて、とある処理をせよ。ただし３行目以降の行数は２行目で指定される。」という問題がありました。標準入力の２行目以外を、int型の要素をもつリストで受け入れようとしたのですがハマってしまいました。以下そのメモ書きです。
参考URL：
http://codegeekboy.hateblo.jp/entry/paiza-input-python3

```text:複数行の標準入力　２行目はそれより下の行数を表す
7 2
8 
1 4
1 1
10 4
2 2
9 4
8 10
9 10
7 4
```

```text:output
[7, 2] 
8 
[[1, 4], [1, 1], [10, 4], [2, 2], [9, 4], [8, 1], [9, 1], [7, 4]]
```

```py3
parents = list(map(int,input().split(' ')))

N = int(input())
childs = [list(map(int, input().split())) for _ in range(N)]

"""冗長version
childs =[]
for i in range(N):
    
    line = list(map(int,input().split(' ')))
    childs.append(line)
"""

print(parents)
print(N)
print(childs)
```
Docker入門 #1 【Dockerとは】

## Dockerとは
旧dotcloud社（現docker社）が開発したLXCユーティリティ。

> LXCとはOSの仮想化技術の1つで、VMに比べて軽量であることが特徴（コンテナと呼ばれる）。
> LXCはLinuxOS上でしか動作しない。

つまりどういうことかというと

Dockerは軽量な仮想マシンを簡単に構築することができ、インフラを含めたアプリ全体をまるまる、
コンテナという箱に閉じ込めることができる。また、コンテナの配布やバージョン管理も可能

---


で、そもそもVMでの開発とどう変わるか

**DockerとVagrantの違い**

## Vagrant （+ VirtualBox）
仮想マシンを動かす仮想化ソフトのラッパーツール

VirtualBoxの構成を**Vagrantfile**というテキストに記述してVagrantに任せることで、ネットワークドライバの設定などを意識すること無く、ホスト環境に依存しない形で整備される

### 【特徴】
- Linux以外のOSの環境が構築できるため、コンテナ型と比べて自由度が高い
- OSのバージョンの違い、仮想環境ツールの違い、仮想環境ツールの設定の違いなどで構築に手間がかかる
- VagrantとVirtualBoxのバージョンの相性によってバグがある
- 仮想環境は**ホストOS型**と呼ばれ、ゲストOSがハードウェアにアクセスするにはホストOSを経由しなければならないため、オーバーヘッドが大きい

![](https://thinkit.co.jp/sites/default/files/articles/372201.png)

## Docker
OS・ミドルウェア・ファイルシステム全体を**イメージ**という単位で取り扱い、まるごとやりとり出来るツール


### 【特徴】
- 仮想環境は**コンテナ型**と呼ばれるもので、ホストOSを直接アクセスするためオーバーヘッドが少ない
- 環境構築が容易でVirtual Boxも不要
- コンテナは**移植性(ポータビリティ)**が高く、Dockerさえインストールされていれば、全く同じ環境でアプリを動かせる
- ホストOSからはコンテナは１プロセスとして認識される

![](http://www.devlog.atlas.jp/wp-content/uploads/2015/01/53bf51a08d6f70ef6387a2112cd4afa0.png)


## Docker環境構築の歴史
Dockerは多数の専用ツールで動作するため、様々なツールが登場した反面、
使われなったツールも多く、**死語**も多いので解説していきます


従来、Docker動作させるための必要なツールをまとめた、 **Docker Toolbox**が提供されていました
### Docker Toolbox
2015年8月12日 〜 2016年8月1日
Docker1.8.0と同時にリリースされた、Dockerまわりの環境を全部入れたインストーラ

```
・Docker クライアント
・Docker Machine   （Docker入りVM操作ツール）
・Docker Compose   （Docker複数コンテナ連携管理）
・Docker Kitematic （Dockerコンテナ用GUI）
・VirtualBox
```

DockerはVirtual Box環境が必須であり、
**Docker Machine**というVirtual Boxを操作するツールで環境設定を行わないとDockerを利用できませんでした

### Docker for Mac / Windowsの登場

2016年8月1日〜 **各OS純正の仮想環境**を利用する[Docker for Mac / Windows](http://www.publickey1.jp/blog/16/docker_for_macwindows_1.html)が正式版としてリリースされ、<font color="#ff0000">**Virtual Boxと環境設定が不要になり、各OSネイティブサポートの仮想環境(ハイパーバイザ)で動作**</font>するため、さらに高速になりました


| OS      | ネイティブ仮想環境（[ハイパーバイザ](http://wa3.i-3-i.info/word12196.html)） |
|---------|--------------|
| Mac     | xhyve（Yosemite v10.10.3 以降）        |
| Windows | Hyper-V （Windows10 x64 Pro,Education,Enterprise) |


環境構築も[公式サイト](https://docs.docker.com/#/docker-for-mac)からアプリをダウンロード&インストールするだけになったので非常に簡単です

<hr>


ちなみに、Docker Toolboxの登場まで
Virtual BoxとDockerを連携させるには**boot2docker**というツールが使われてきましたが
Docker Machineの登場でboot2dockerは公式に非推奨となりました

![](https://qiita-image-store.s3.amazonaws.com/0/74153/a70c3877-ccb2-bc82-d301-6055d923bd7c.png)



## なぜDocker？
普段の開発においては以下のメリットデメリットがある

##### メリット
* OS依存がなく、導入が容易
* 案件ごとに異なる環境を構築できるため、特定のPC依存を回避
* ミドルウェア導入や新インフラ環境のテストが各自のPCで可能
* 言語やツールのバージョンアップテストが容易
* チームメンバー全員が各自のPCでデバッグ可能になる

##### デメリット
* 学習コスト

## さいごに
調査の結果、学習コストはあるものの
環境構築の手軽さ、Docker界隈の盛り上がりを考えると、今がDockerの学習を始める最高のタイミングだと思いました

早速、公式サイトから[Docker for Mac / Windows](https://docs.docker.com/#/docker-for-mac)をダウンロードしてインストールしてみてはどうでしょうか

## リンク
[Docker入門 #2 【Dockerチュートリアル】](https://qiita.com/wMETAw/items/8d1b0c053a39841765bf)
[Docker入門 #3 【WordPress環境構築】](https://qiita.com/wMETAw/items/710bbbb328b78757463a)
[Docker入門 #4 【CodeIgniter環境構築】](https://qiita.com/wMETAw/items/aaf6a94a83e2ac5ac0c3)
[Docker入門 #5 【Ruby on Rails5環境構築】](https://qiita.com/wMETAw/items/8cb41425a5d0bdace2df)
[Docker コマンドチートシート](https://qiita.com/wMETAw/items/34ba5c980e2a38e548db)
macの.bash_profileってなんだ！？

環境変数設定するためのfile
PATH通して～
みたいなこと言われたらここに

```  
export PATH=$PATH:通したいPATH
```
って書いて通す。

以下も参考にする

Macの環境変数の書き方を整理してみた
https://qiita.com/isoppp/items/965ecb8e933a9557d7bf

MacでPATHを通す
https://qiita.com/nbkn/items/01a11392921119fa0153
第21回Elasticsearch勉強­会 #elasticsearchjp


とりあえずざっと書いたものなので、あとでスライド含め整理する。

## イベントページ
https://www.meetup.com/ja-JP/Tokyo-Elastic-Fantastics/events/243671140/

## 6.0 is coming
Jun Ohtani(@johtani)

* Elatic Pioneer Program
	* バグ出ししてGithub issueを。

### Elasticsearch 6.0
* アップグレード
	* 6系になってクラスタをローリングアップデートできるようになったので簡単になった
		* 5.5以下の場合は5.6に一度あげる必要はあるが。
	* Upgrade Assistant(UI & API)
* 内部のLuceneが7にアップデート、
	* 空要素が多い項目もつかいやすくなった。
	* ディスク容量も少なく。
	* 全体的に性能も上がる。
* sort条件をindexのタイミングで設定できる。
	* index速度は落ちるが、検索速度は上げれる。
* Replicationの速度が速くなった。
	* 内部のシーケンシャルナンバーを採用した。
	* 他の処理にも利用するように今実装中
* Breaking Change
	* Upgrade Assistantで確認を！
	* とは言ってもテストもすること！
* _typeが無くなった。
	* 6では_typeは1つしか使えない、5系はのは複数利用出来る。
	* 7ではほぼ一部しか使えないようになり、8では完全に消す
	* parent-childの書き方が変わる。(ドキュメント見ながらやって・・・
* RenameTemplate to index_patterns in _template
* curlとかで投げる時にContent-Typeはrequest headerにつける。
* _allが無くなる。
	* 暗黙的に使ってたので、消す。
	* Kibanaで使っていたが、基本的にフィールド指定するようになるから大丈夫。
* 2系で作られたindexは6.0では使えない。
	* 2系からは5.6とかでre-indexしてから6にする。
* plainlessの採用
	* Groovy, Python Javascript plugin Deprecate.
* Java High Level Rest Client (at.5.6.0)
	* select系のみ対応している。

### X-pack
#### Kibana
* UIの色が変わります
	* コンストラストベース
	* キーボードショートカットが増えた
* CSVダウンロードができるようになる。(Basic, free)
* Dashbord Only Mode(Gold)
	* 間違って触ってダッシュボード壊れることがなくなった。
* Full Screen Mode
* Kuery
	* JavaScriptぽい感じ。
	* Lucene Queryの代わり。
* Cluster Alearts(Gold)
	* Clusterに問題が出た時にKibanaに通知が出て、emailに飛ばせるようになる。
* thresholdを画面で設定できるようになった。(Basic)
* Logstash pipelines(Gold)


### Logstash

* Multiple Pipelines, One Logstash
	* 設定が分けれるようになった。
	* 実際の設定はEsの中に入るのでバックアップできる。

### Beats
* コンテナサポート
	* Kubernetes
	* Docker

## Elastic Stackで何を可視化すれば性能改善が捗るのか
北野 勝久さん（株式会社スタディスト）

### スライド
https://speakerdeck.com/katsuhisa91/elastic-stack-de-he-woke-shi-hua-surebaxing-neng-gai-shan-gabu-rufalseka

### 性能監視の話
* SRE サイトリライアビリティエンジニアリング
	* サイト信頼性
* モニタリング大事
* The Four Golden Signals
	* lateny
	* traffic
	* errors
	* saturations
* NewRelicを使う
	* エージェント入れる。以上。
	* いい感じのグラフがすぐ出る。
	* 欠点
		* 無料だとログの保管期間短い。
		* 高い。

### Elasticsearch
* なぜ？
	* 自分たちでみたいものを決めれる。
	* 検索分野でも使いたい。
* Elastic Stackを利用
	* Nginxアクセスログ
	* SlowQueryログ
* ボトルネックの洗い出し
	* レスポンス時間を見る。
		* カウント数小さいところはsaturation改善効果が出にくい
* HTTPステータスコードの可視化
	* 500がどのくらい出てる？
* アクセス元の可視化
	* 攻撃対象の把握などできるだろうと
* レスポンス時間*カウント数が多いところから改善


### 導入の詳細
* 導入は3日くらいで終わった。
* AWS Es Serviceを利用。
	* AWSを使ってる場合はすぐできる。
	* Esのバージョンアップの追従がつらい。
* SlowQueryログ
	* fluentdのpluginで
* geoip <> IPアドレス変換

### 今後の活用
* useragentを分類して、どっから来たか見る。
* Kibanaの運用を強化
* 検索エンジンとして使う




## AWS環境に合わせてElastic Stackをログ分析基盤として構築した話
日比野 恒さん （フューチャーアーキテクト株式会社） 

### スライド
https://www.slideshare.net/hibinohisashi/elasticsearchawselastic-stack/

### ElasticsearchをVPS内で構築するときのポイント
* EC2 Discovery Plugin
* Repository S3 Plugin
* AMI作るときはJava8,Curator5のみいれて、AMI作った後でAnsblieであとから入れる。

### LogstashをコンテナかしてAWS各種ログを取り込みときのコツ
* logstashをECSでコンテナサービス化
* ログの形式毎にフォルダ切ってS3にログ収集
* S3で難しいものは、泣く泣くCloudWatchLogs
	* cloudwatch-logs-plugin

### AWSの課題
* 東京リージョンでAZが二つしかない。。。つらい。
Windows:電源プラン切り替えのショートカットを作成するスクリプト

#概要
電源プランの切り替えを複雑なコントロールパネルからではなく、デスクトップから一発で切り替え出来るショートカットを作成します。
一つ一つ手で作ることも可能なようですが、WBEMから設定を抜き取ったほうが確実でしたのでVBスクリプトを使います。

なお、カスタム設定をショートカット化する場合は、スクリプト実行前に電源コントロールパネルから作成しておく必要があります。

#スクリプト
```basic:MakePowerCfgSC.vbs
Option Explicit
Dim oQrys,oItm
Dim oWsh,oSC,oProp,oFN,oGUID

Set oWsh = CreateObject("WScript.Shell")
Set oQrys = CreateObject("WbemScripting.SWbemLocator").ConnectServer(,"\Root\CIMV2\power").ExecQuery("Select * From Win32_PowerPlan")

For Each oItm In oQrys
	oGUID = oItm.InstanceID
	oGUID = Mid(oGUID,InStr(oGUID,"{")+1)
	oGUID = Left(oGUID,InStr(oGUID,"}")-1)

	oFN = oWsh.SpecialFolders.Item("Desktop") & ".\" & oItm.ElementName & ".lnk"
	
	Set oSC = oWsh.CreateShortcut(oFN)
	oSC.TargetPath   = "powercfg.exe"
	oSC.Arguments    = "/setactive " & oGUID
	oSC.WindowStyle  = 7 'Minimized
	oSC.IconLocation = "powercpl.dll,0"
	oSC.Description  = oItm.ElementName
	oSC.Save
Next
```

#使用方法

1. コントロールパネルから電源プランを追加、編集する
2. 電源プランショートカット作成スクリプトを保存
3. スクリプトを実行
4. 電源プランショートカットの利用

####電源プランの作成
変更したい電源プランを事前に作成しておきます。
最近のWindows10では「バランス」しか登録されていないため、この状態でショートカットを作成してもあまり意味がありません。

####ショートカットカット作成スクリプトを保存
スクリプトを拡張子vbsとして保存してください。

####スクリプトの実行
**管理者権限で実行したコマンドプロンプトから**
`cscript MakePowerCfgSC.vbs`
という感じにスクリプトを指定して実行して下さい。
Windows10等ではセキュリティが強化され、スクリプトのダブルクリックによる実行（管理者権限無しで実行）が出来ません。

powercfgコマンドに適切なスイッチを追加したショートカットが、電源プランの数だけ作成されます。
必要なものだけを拾って適切な場所に配置してお使い下さい。

####電源プランショートカットの作り方
電源プランショートカットをダブルクリック等で実行すると、即座に電源設定が切り替わります。
EdgeRouter から Wake on LAN パケットを送る

## 結論だけ先に
EdgeRouter には `/usr/sbin/etherwake` というコマンドが入っているのでそれ使ったら送れる＼(^o^)／

## [追記 2021.01] EdgeOS 2.x だと etherwake 入っていないっぽい
[ここ](https://packages.debian.org/stretch/net/etherwake) から落としてきて入れた。

``` console
$ curl -o etherwake.deb http://ftp.jp.debian.org/debian/pool/main/e/etherwake/etherwake_1.09-4+b1_$(dpkg --print-architecture).deb
$ sudo dpkg -i ./etherwake.deb
$ rm ./etherwake.deb
```

## WoL パケットの NAT 越え
外出先から自宅に VPN で繋いで、自宅ネットワーク内にあるサーバを Wake on LAN (WoL)[^wol] で起動したい。

[^wol]: 特殊なパケットを送りつけることで遠隔で停止しているマシンを起動する技術

VPN 接続した状態で普通に手元のマシンから WoL パケットを送れば起動するかと思ったら起動しない。VPN 接続した状態だと手元のマシンと自宅ネットワーク内のサーバとでネットワークアドレスが違うので、WoL パケットがルータを超えてサーバまで届くようにしないといけないらしい。

なんとかする方法はふたつあって、

- 外部から WoL パケットが飛んできたら LAN のブロードキャストアドレスに流すようにルータを設定する
- 同じネットワークに所属している機器から WoL パケットを送る

前者はあまりセキュアじゃなさそうなので、とりあえず後者ができるか考えてみる。

ルータの種類によっては GUI から WoL パケットを送る機能があるらしい。[^router]
残念ながら我が家の EdgeRouter X の GUI にはそのような機能はついてなかったので他の方法を考える。

[^router]: YAMAHA RTX シリーズとか NEC UNIVERGE IX シリーズとか

## EdgeRouter から WoL パケットを送る
自宅ではルータの他にファイルサーバも動いているので、ファイルサーバに SSH ログインして WoL パケットを投げるのが一番簡単なのだけど、ファイルサーバにファイルサーバじゃない役割を担わせるのが申し訳なくて (？) まずはルータから WoL パケットが送れるかどうかを検討する。

CentOS は `wol`, Ubuntu は `wakeonlan` というコマンドを入れれば WoL パケットを送れるらしいが、EdgeRouter の OS は Vyatta ベースなのでそのへんのコマンドは簡単には使えなさそうな雰囲気がある・・・。

ていうかネットワーク系の OS なんだからどうせデフォで入ってるでしょ、と思って探していたら `/usr/sbin/etherwake` というそれっぽいのがあった。

``` console
$ sudo etherwake -u
usage: etherwake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55

	This program generates and transmits a Wake-On-LAN (WOL)
	"Magic Packet", used for restarting machines that have been
	soft-powered-down (ACPI D3-warm state).
	It currently generates the standard AMD Magic Packet format, with
	an optional password appended.

	The single required parameter is the Ethernet MAC (station) address
	of the machine to wake or a host ID with known NSS 'ethers' entry.
	The MAC address may be found with the 'arp' program while the target
	machine is awake.

	Options:
		-b	Send wake-up packet to the broadcast address.
		-D	Increase the debug level.
		-i ifname	Use interface IFNAME instead of the default 'eth0'.
		-p <pw>		Append the four or six byte password PW to the packet.
					A password is only required for a few adapter types.
					The password may be specified in ethernet hex format
					or dotted decimal (Internet address)
		-p 00:22:44:66:88:aa
		-p 192.168.1.1
```

(ヘルプ表示が `--help` じゃなくて `-u` なのわかりづらい)

コレを使えばできそうな気がするが、単純に

``` console
$ sudo etherwake <MACアドレス>
```

とやってみても起動しない。
デフォルトでは eth0 にパケットを飛ばすようになっているので、我が家の設定だと eth0 は WAN 側なので起動したいサーバまで届かない。

``` console
$ sudo etherwake -i eth3 <MACアドレス>
```

起動したいサーバは eth3 に直接繋がっていたので、こうすると見事起動した。

最低限コレでもいいけど、NIC を直接指定するのなんか気持ち悪いのでもうちょっといいやり方にしたい。

``` console
$ sudo etherwake -b -i switch0 <MACアドレス>
```

我が家の設定だと switch0 が作られていた[^ifconfig]ので、ここにブロードキャストすれば LAN 全体に送れるかな、と思ってやってみたらできた。

[^ifconfig]: `$ sudo ifconfig` で確認できる

これで外出先からでも自宅のサーバを起動できるようになった。

めでたしめでたし。
ハマりメモ：Windows10にインストールしたMySQL5.7のmy.iniをいくら修正しても反映されない

C:\Program Files\MySQL\MySQL Server 5.7\my.ini をいくら修正しても反映されない・・・
↓
サービス一覧で確認したら、実は読み込んでいるのは C:\ProgramData\MySQL\MySQL Server 5.7\my.ini だった！
実行パスはちゃんと確認しよう