OmniAICreator/Qiita-1.07M huggingface dataset:
SelenideでWebDriverManagerを使う

# はじめに
この記事は[Selenium/Appium Advent Calendar 2017](https://qiita.com/advent-calendar/2017/selenium)の3日目です。

2017/09/30にリリースされた[Selenide4.7のリリースノート](http://selenide.org/2017/09/30/selenide-4.7/)をみると、`WebDriverManager`が組み込まれたという風に書かれています。つらつらと読んでいくと、どうやら各ブラウザ毎のWebDriver実装を勝手にとってきてつかえるようにしてくれる模様。
もしそうならば、今まで手順書にバイナリダウンロードして適切なパスに配置して、テストコードのこのパス部分を修正して……という手間が省けますし、また何よりJavaのコードだけで完結させることができます。

リリースから少し時間があいてしまいましたが、この機能を試してみましょう。

# WebDriverManager とは

そもそもWebDriverManagerとはどういったものでしょうか。
[公式サイト](https://github.com/bonigarcia/webdrivermanager)をみると、「はじめに」に書いたようなことをやってくれそうな雰囲気です。日本の情報では、[WebDriverManagerを使用してgeckodriver(SeleniumのWebDriver)を自動インストールする方法](https://qiita.com/kazuki43zoo/items/71f4c09e644b45a4002c)があるので参考になります。

# SelenideでのWebDriverManagerの使い方

さて、SelenideではどうやってWebDriverManagerを使うのでしょうか。
リリースノートを見ると、以下の用に書かれています。
> There is one nuance. WebDriverManager will only work if:
> 1. You use one of supported webdrivers: chrome, edge, internet explorer, opera,  phantomjs, marionette or gecko.
> 2. Your code hasn’t set system property webdriver.chrome.driver, webdriver.edge.driver, webdriver.ie.driver, webdriver.opera.driver, phantomjs.binary.path or webdriver.gecko.driver.

Chrome、Edge、IE、Opera、PhantomJS、Marionetto/Geckoがサポートされていること、通常では行わなければならないWebDriverのバイナリパスのシステムプロパティ設定をしなくてよいとあります。
その後に以下のようにもあります。
> If you still have some question, remember that the only true information source is the SOURCE CODE!

ということなので[ソースコード](https://github.com/codeborne/selenide/blob/master/src/main/java/com/codeborne/selenide/webdriver/WebDriverBinaryManager.java)も読んでみましょう。そうすると、`isChrome`や`isEgde`などの使用するブラウザ毎に内部でWebDriverManagerを呼び出して初期化(`HogeDriverManager.getInstance().setup()`)が行われています。
では、この`isChrome`や`isEgde`は何をもって判断しているのかというと、Selenideに対して使用するブラウザを伝えてための`Configuration.browser`変数です。つまり、`Configuration.browser`でブラウザを指定するだけで後はよきに計らってくれるということです。

# サンプルソース

以下にWebDriverManagerの使用前/使用後を並べてみました。
行数としては1行しか減っていませんが、本来必要なバイナリのダウンロードとバイナリ位置に応じてパスの書き換えが不要となっていることが大きいです。

## Before 

```Java
    @Before
    public void before(){
        Configuration.browser = WebDriverRunner.GECKO;
        System.setProperty("webdriver.gecko.driver","/PATH/TO/geckodriver.exe");
    }
```

## After

```Java
    @Before
    public void before(){
        Configuration.browser = WebDriverRunner.GECKO;
    }
```

## GitHub

[以前書いたCodezineの記事](https://codezine.jp/article/detail/10335)で使用した[コード](https://github.com/shimashima35/codezine-sample)に対して、[修正したもの](https://github.com/shimashima35/codezine-sample/tree/feature/webdrivermanager)をあげておきました。
バイナリダウンロードなどの事前準備作業がいらなく、GitHubからクローンしてそのまま使えるようになっているのが便利ですね。

# おわりに

Selenideに組み込まれたWebDriverManagerについて簡単に説明しましたがいかがだったでしょうか。コード行数は大して減りませんが、個々人の環境設定の労力がなくなり複数人で開発する際のトラブルを防ぐことが出来るはずです。
便利な機能ですし導入も簡単なので皆さん積極的に使っていきましょう。
Burp Suite Tips（Intruder で Content-Length を一覧表示する方法）

# 概要

Intruder で Attack した時の一覧画面で HTTPレスポンス内の
Content-Length を見る事ができる設定方法です。
すごく単純なものですが、たまに使うので備忘録も兼ねてます。

# 対象

Burp Suite を使って診断できる方を想定しています。

# 環境

Windows 7
Burp Suite Professional 1.7.29
※ Burp Suite Community Edition でもいけると思うのですが、未確認です

# 設定方法

1. Burp Suite を起動します
1. Intruder -> Options と遷移します
1. Grep - Extract -> Extract the following items from responses にチェックします
1. Grep - Extract -> ADD で Define extract grep item 画面を開きます
   1. Extract from regex group にチェックします
   1. Case sensitive はチェックをいれたままにします
   1. 正規表現のテキストボックスに下記を入力します<br/>
     `Content\-Length\: (.*?)\r\n`
   1. OK で登録を完了させます

設定が完了したら、Intruder で Attack した時の一覧に
Content-Length が表示されるようになっていると思います。
（空文字が表示されていたら何か手順が間違えているはず…）

# おわりに

Intruder を使って診断している時、HTTPレスポンスの Length で
疑似攻撃に反応があったか判断するケースがあると思います。

基本は、標準で用意されている Length を見れば問題ないのですが、
HTTPリクエストするたびに、HTTPレスポンスヘッダset-cookieで長さの異なるセッション値が付与される等、
HTTPレスポンスの Length に揺らぎが発生する場合は、個別にレスポンスを確認していくため診断の効率が落ちていました。

毎回HTTPレスポンスの詳細をチェックするのは大変なので、「いい方法ないかな」と検討した結果、本記事のやり方を採用しています。
設定後はそこまで診断の効率が落ちなくなりました。

「もっといいやり方あるよ！」とかあれば教えていただけると嬉しいです。
AWS EC2(AMI)とBoxを連携する

# まえおき
LinuxサーバからBoxへファイル転送をする必要がでてきたため、BoxAPIを使ってファイルをアップロードする方法を調べました。

OAuth2の認証方法がわかればあとは簡単でしたが、認証部分で若干わかりずらかったので備忘録として記載です。

# 調べたこと

## 連携手段
Boxは企業向けクラウドストレージサービスなので、連携方法は色々あるようで、

・Windows/MacからデスクトップアプリケーションでSyncする
・REST API経由でデータをやり取りする
・LinuxからコマンドラインでSyncさせる

などありましたが、今回はBoxの理解をしたかったのとEC2側のストレージの枯渇が心配だったのでBoxのAPIを使うことにしました。
（ホントはrclone使ってsyncするのがよさそう）

以下手順です。

## 認証
Boxではいくつかの認証方法が用意されていて、AccessTokenを利用した方法を選択してます。
管理者権限があるなら全権限があるTokenも発行できる気がするのでそちらの方が楽かも。
（↑まだやってない）

# やったこと

### 1. 連携用のアプリケーションを発行する

BOXへログインし開発者コンソールからアプリケーションを発行する。
認証方法は「標準OAuth 2.0 (ユーザー認証)」を選択。
https://[会社名など].app.box.com/developers/console

### 2. 設定からリダイレクト先を指定する

発行したアプリの「Configuration」の「OAuth 2.0リダイレクトURI」に以下を設定

```
  http://0.0.0.0
```

### 3. ブラウザで以下を叩くと認証画面が出てくるので認証する

```
https://account.box.com/api/oauth2/authorize?response_type=code&client_id=[client_id]&state=security_token=[client_secret]
```

### 4. 認証用コードを取得する

上記で認証すると「0.0.0.0」にリダイレクトして失敗するが、URLのcodeに認証コードがついてるのでコピー。

```
http://0.0.0.0/?state=security_token%3D[client_secret]&code=[auth_code]
```

### 5. Curlなどでアクセストークンとリフレッシュトークンを発行する

上記の「auth_code」を使ってcurlやPOSTMANで実行するとAPI実行に必要なアクセストークンとリフレッシュトークンがjsonで取得できます

```curl
curl https://api.box.com/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=authorization_code&code=[auth_code]&client_id=[client_id]&client_secret=[client_secret]' \
-X POST
```

### 6. APIが通るか確認する

あとはリファレンス通りにCurlを叩くとBoxの情報を取れます。

```
curl https://api.box.com/2.0/folders/[folder_id] \
-H "Authorization: Bearer [access_token]"
```

# 所感

1. 毎度のことだが英語のドキュメント大事。

1. 認証さえ理解できればそのほかはシンプルだったが、アクセストークンが1時間で無効になることと、リフレッシュトークンが60日で無効になるので、多少プログラム側で工夫が必要そうです。
（管理者権限でAPI発行すれば良さそう）

# 参考

Box Auth
https://developer.box.com/v2.0/docs/oauth-20

Box API リファレンス：
https://developer.box.com/v2.0/reference

Access/Refresh Token の取得方法
https://www.youtube.com/watch?v=ZsQFXlMWM-E
AWS EC2(AMI) からtabcmdを実行する

# まえおき

営業の業務効率化のため、TableauServerのPDFダウンロードを自動化するためにやったこと。

# 調べたこと

色々調べてみたところ、どうやら現在はtabcmdのjarファイルをLinuxにアップロードしてshellで実行すればうまくいくようです。jarファイル最高。

# やったこと

### 1. 以下からtabcmdをダウンロードする

https://www.tableau.com/support/releases/server

### 2. ダウンロードしたファイルをサーバにアップロードする

以下に保存する。

```
$HOME/lib/tabcmd/app-tabcmd-latest-jar.jar
```

### 3. 実行用のシェルをサーバにアップロードする

必要となるディレクトリは作ります。
もしくは以下のシェルを編集します。

```shell-session:tabcmd.sh
#!/bin/sh

java -Xmx64m -Xss2048k -Djsse.enableSNIExtension=false -Dpid=$$ -Dlog.file=$HOME/lib/tabcmd/.tabcmd/tabcmd.log -Dsession.file=$HOME/lib/tabcmd/.tabcmd/tabcmd-session.xml -Din.progress.dir=$HOME/lib/tabcmd/.tabcmd -Dconsole.codepage=$LANG -Dconsole.cols=$COLUMNS -jar $HOME/lib/tabcmd/app-tabcmd-latest-jar.jar "$@"
```

### 4. シェルに引数をつけてタブローの認証を通す

tabcmdに最初にログインすればその後はコマンドは都度ログインしないでも実行できるようです。

```
sh tabcmd.sh login ***************
```

ログイン後は以下を参照しながらPDFのエクスポートをしました。

https://onlinehelp.tableau.com/current/server/ja-jp/tabcmd_cmd.htm

# 所感

難しいところは特になくわかりやすかったです。
少し前のバージョンではダウンロードしたらディレクトリ配下を全部アップロードしなければならなかったようですが仕様改善されて使いやすくなっててよかったです。

# 参考

Tabcmd on Linux
https://tableauandbehold.com/2016/06/06/tabcmd-on-linux/

How to tabcmd on Linux：
https://community.tableau.com/thread/118422
re:Invent2017に参加して来た感想

re:Invent2017に参加して来ました。
各セッションのまとめなどは、classmethodさん中心にかなり情報がありますし、新製品の発表に関してはawsの公式サイトでチェックすることができます。

[aws公式サイトのニュース](https://aws.amazon.com/jp/new/)
[classmethodさんのre:Invent情報](https://dev.classmethod.jp/series/aws-reinvent-2017/)

ということで、内容に関する情報は十分だと思ったので、自分は現地で感じたことをつらつらと書いてみることにしました

## コンテナ・サーバーレスが人気！
今回の新サービスの発表でも、EKS(Amazon Elastic Container Service for Kubernetes)やFargateが登場しましたが、セッションの数や新サービスの発表順からみても、AWSがコンテナに力を入れているのは間違いないようです。
また、参加者側からみても、大ホールでやってるセッションでさえ行列ができすぎて入れないケースも多く、ユーザーの関心も高いみたいです。移動中のバスの中でも「コンテナって何がいいの？」って話を隣に座った人としてるのをいくつか見聞きしました。

サーバーレスに関してもコンテナ同様、セッション数も多く、行列で入れないのをたくさん見かけました。人気の講演は大ホールで複数回行われるケースもありました。

自分もコンテナの良さをあまりわかってなかったのですが、なんとなくec2とサーバーレスの中間くらいな存在なんだなぁなんて気づきもありました（間違ってたらすいません）
ちなみに、バスで僕の隣に座った中東系の人は「コンテナはマイクロサービス化がしやすくていいんだよ」と言ってました

## エコーは思ったほど盛り上がってなかった
米国では発売されてからしばらくたち、市場占有率も高いエコーですがエコーに関する講演は意外に盛り上がりに欠けてました。セッションも毎日してるのはしてるんですが基本的に小さな会場で行われていて、予約なしでも入れる感じでした。
エコーに関しては言ってもまだ出たばかりなのと、アマゾンが求めているのが特定の大サービスの提携だったり、物理デバイスとの連携だったりするのでre:Inventの参加者とはターゲットが少し違ったのかもしれません

## 日本のAWS Summitとの違い
日本でも6月ごろ品川でAWS Summitが行われますが、AWS Summitとre:Inventでは以下の点が違いました

### 1. セッションの種類の割合が違った
セッションの種類として
A. AWS未利用者に対してAWSへの移行を促すセッション
B. AWS利用者に対してAWSをもっと効率的に使ってもらうためのセッション
C. AWSの新サービスについて説明するセッション
があるとすると、
AWS Summit = A: 70, B: 30, C: 0
re:Invent  = A: 30, B: 60, C: 10
くらいだった気がします。
（イベント会場の大きさやセッション数を参考にはしてますが、統計ではなく雑感です）

keynoteもAWS Summitは「xxxが東京リージョンでも利用可能になりました」という発表ですが、re:Inventは完全に新サービスの発表なので盛り上がりが全然違いました。

### 2. 料金が違った
AWS Summitは基本的に参加者無料ですが、re:Inventは参加料で約20万円かかりました。移動費・滞在費合わせると約40万円でした。その代わり、朝食と昼食はビュッフェスタイルor弁当でかなりちゃんとしたものが出て来たので、ご飯代はほとんどかかりませんでした。

### 3. 規模が違った
AWS Summitはプリンスホテルだけでやっていて同時に行われるセッション数も10-20程度ですが、re:Inventは主に3つのホテルでセッションが行われていて同時に行われるセッションは40-50になることも。
ただ、ホテル間はバスで移動しても20-30分かかるくらい離れてるのでそこはネックでした。

## 最後に
re:Inventはとてもexcitingで学びの多い会でした。
AWS Summitと違ってすでにAWSを利用している人の方が楽しいと思います。
興味ある方は来年是非いってみてください。

※ 上記は完全に個人の雑感ですので、正確な情報ではありません。事実は各人で調べていただければ幸いです。
シェルコマンドでFizzBuzz

```bash
seq 100|sed 's/.*5$/Buzz/;3~3s/[0-9]*/Fizz/'
```

sedの方を少し解説すると。
`s/.*5$/Buzz/` で、末尾に5が来るものをBuzzにする。
`3~3s/[0-9]*/Fizz` は、3行目から3行ごとに`s/[0-9]*/Fizz`する、という意味で、`.*`とせずに`[0-9]*`としているのは既にBuzzになっている行はBuzzを消さずにFizzBuzzにしたいから。
Chromeの開発者ツールの使い方

#Chromeの開発者ツールを使って、ストレスなくフロントエンドの開発を行う
いつもなんとなく使っていたのでまとめてみました
※ここに書いているのはあくまで一部の機能です。

##Chromeの開発者ツールの起動方法
1.[Ctrl] + [Shift] + [i]を同時に押す ※簡単に開けるのでおすすめ
2.右上の設定画面 → その他のツール → デベロッパーツール

##Element - HTML/CSSのソースの確認
・開いているページのHTML、CSSが確認できる
・HTMLやCSSを書き換えてページの見た目を変えることができる
・ブレークポイントの設定 ※要素が変更された時、要素の属性が削除された時、要素が削除された時

##Console - ログの確認、JSの実行
・エラーのログの確認
・JSコードを実行できる ※Jqueryが入っていなくても$$(hoge)の様に$を2つ付けることで、Jqueryと同様の事ができるらしい
・document.body.contentEditable=true を実行すると、開いているページをテキストエディタの様に編集することができるようになる

##Sources - JSのデバック
・ブレークポイントを置いてJavaScriptのデバックをすることができる
・JavaScriptのソースにdebuggerを書くことでもブレークポイントを作成することができる。 ※個人的にモーダルのデバックなどはこれがオススメです。

##NetWork - 通信の確認
・通信を確認 ※Ajaxのデバックに便利らしい、HTTPヘッダーの中身などを見ることができる
・通信にかかった時間を確認
・通信サイズの確認

##Application - クッキーの確認、ページ構成の確認
・ページの構成を確認することができる
・クッキーを確認するこができる
1行あたりの最大サイズを変更する

Impalaの行サイズはデフォルトで512KBに制限されている。殆どの場合問題にならないサイズだが、複数テーブルのJOINなどにより大量のカラムが生成された場合、この制限にひっかかり、以下のようなエラーが出る場合がある。

```
Row of size 698.78 KB could not be materialized in plan node with id 1. 
Increase the max_row_size query option (currently 512.00 KB) to process larger rows.
```

その場合、 `MAX_ROW_SIZE` クエリオプションを指定することで行サイズを拡張することができる。

# 実行例

```sql
SET MAX_ROW_SIZE=1mb;
CREATE TABLE table_pq STORED AS PARQUET SELECT * FROM table_orig WHERE col1 = 'hoge';
```

# 注意

そもそも1行あたりのデータが小さい方が好ましいので、この制限に引っかかるようであれば、オプションの変更よりまず行サイズの削減が可能かどうかを検討した方がいいだろう。

# 参考
- [Clouderaドキュメント: MAX_ROW_SIZE Query Option](https://www.cloudera.com/documentation/enterprise/latest/topics/impala_max_row_size.html)
Monacaアプリのセキュリティを担うコンテンツ セキュリティ ポリシーについて

[Monaca](https://ja.monaca.io) アプリはHTML/JavaScript/CSSでアプリのコンテンツを作ります。外部からデータを取得して利用する仕組みを使っている時に、悪意を持ったユーザによってXSSを引き起こされる可能性があります。例えばJavaScriptを実行されたり、CSSでデザインを変えられてしまうかも知れません。

そうした問題を防ぐのに使えるのがコンテンツ セキュリティ ポリシー（CSP）です。Monacaアプリではデフォルトで次のような設定になっています。

```html
<meta http-equiv="Content-Security-Policy" content="
  default-src * data: gap: content: https://ssl.gstatic.com;
  style-src * 'unsafe-inline';
  script-src * 'unsafe-inline' 'unsafe-eval'">
```

デフォルトでは以下の3つが指定されています。各項目は ; で繋ぎます。

- **default-src**  
基本設定です。指定しなかった設定（ディレクティブ）に対して使われます。
- **style-src**  
スタイルシートの設定です。
- **script-src**  
JavaScriptの設定です。

`https://ssl.gstatic.com` はAndroidで必要なドメインのようです（via https://github.com/apache/cordova-plugin-whitelist）。`gap:` は逆にiOSで必要な設定で、JavaScriptからネイティブの機能を呼び出すときに使われるスキームです。 `data:` は data://ではじまる、いわゆるdataURIを許可するという指定です。 `content:` はAndroidでファイル選択した時のスキームです。 `file:` も併用すると良いようです（via [fileスキームのURIに変換する(Android) - 闘うITエンジニアの覚え書き](https://www.magata.net/memo/?file%A5%B9%A5%AD%A1%BC%A5%E0%A4%CEURI%A4%CB%CA%D1%B4%B9%A4%B9%A4%EB%28Android%29)）。

`unsafe-inline` はHTML中の `<script />` 、 `<style />` タグの許可であったり、HTMLタグの中の `onclick` の許可になります。 `unsafe-eval` はevalの許可です。

その他に指定できる値としては以下があります。

- 'self'
- 'none'
- mediastream
- blob
- filesystem
- https:

後はドメイン指定（ワイルドカード可）で利用できるソースのドメインを指定できます。

## ソース

ソースは上記3つの他にも以下があります。他にもありますが、Corodvaアプリでは対象にならないものなのでリストに載せていません。

- **child-src**  
iframeで読み込めるドメインを指定します。
- **connect-src**  
Fetch、XMLHttpRequest、WebSocket、EventSourceなど外部接続系の制限を行います。
- **font-src**  
`@font-face` で読み込める対象を制限します。
- **img-src**  
画像の読み込める対象を制限します。
- **media-src**  
`<audio />`、`<video />` に対して利用する対象を制限します。

----

CSPの設定を間違えると、出るはずのデータが表示されなかったり、コンテンツが読み込めなかったりします。かといってあまり大らかにしすぎると万一の時にセキュリティ上のリスクが高くなります。バランスを考えつつ、指定するのが良いでしょう。
Qiita記事のコードスタイル部分を以前のやつに戻すChrome Extension作った

# 経緯
Qiitaがサイトリニューアルされて、記事内のコード部分の色がガラッと変わり、個人的に見づらかったのでなんとか変えたかった。

メインブラウザがChromeなのでExtensionで自動的に変わるみたいなのがあったらいいなと思って作った。突発的に作って、個人的に使う程度のものなのでストアには登録してません。

# 内容
やってることは至極簡単で、読み込まれたら`</head>`の直前にオーバーライドされたCSSを読み込むようにしているだけ。

```script.js
document.head.insertAdjacentHTML('beforeend',
    '<link rel="stylesheet" type="text/css" href="' + chrome.runtime.getURL("style.css") + '">'
);
```

`manifest.json`で以下の設定するのがミソっぽいです

``` manifest.json
{
  "web_accessible_resources": [
    "style.css"
  ]
}
```

# デモ
[![https://gyazo.com/923e0fd8f4151121597121378f848b9d](https://i.gyazo.com/923e0fd8f4151121597121378f848b9d.gif)](https://gyazo.com/923e0fd8f4151121597121378f848b9d)

ラグありますが、読み込み完了したら反映みたいな感じです。

# Github
https://github.com/yamanoku/Qiita_Code-Style_Before
ここからクローンなりダウンロードでディレクトリ落としてもらってデベロッパーモードで追加してください。いらんかったら削除ください。

自分がよく見る分は補完してますがこの言語のここが対応していないなどあったらIssueかプルリクでもおなしゃす。

# 参考

- https://qiita.com/sqrtxx/items/19fd2114430e9e1fb57f
- https://developer.chrome.com/extensions/manifest/web_accessible_resources
- https://developer.mozilla.org/ja/Add-ons/WebExtensions/manifest.json/web_accessible_resources
Drill で日本語使う in 2017

妻の機種変に付き合って一日が終わりましたので、小ネタでご勘弁お願いします。

さて標題の件ですが、Drillで日本語を使う際の注意点に関しては id:nagix の[こちらの記事](http://nagix.hatenablog.com/entry/2015/05/29/150215)が参考になります。
スライドが良ければ[こちら](https://www.slideshare.net/MapR_Japan/apache-drill-55237137)もどうぞ。

こちらの記事ですが最後のデフォルトで日本語を有効にするための箇所だけ現在のバージョンではObsoleteになっています。
自動的に設定する場合にはdrill-env.shに以下のように設定して下さい。

```shell-session
export DRILL_JAVA_OPTS="$DRILL_JAVA_OPTS -Dsaffron.default.charset=UTF-16LE"
```

MapRでDrill on Wardenをご利用の場合は /opt/mapr/drill/drill-<version>/conf/drill-env.sh を、Drill on Yarn をご利用の場合はご利用の site ディレクトリ以下の drill-env.sh を修正して下さい。
修正後はDrillbitまたはApplicaiton Master の再起動が必要となります。
Parquet生成時のデータが小さいときの対処法

Impalaで `CREATE TABLE AS SELECT` (以下CTAS)などを使ってParquetファイルを生成する際、SELECT文の結果によってはそれほどデータが大きくならないケースがあるが、デフォルトではクラスタのノードにまたがって分散してデータを生成するため、データが小さくなりすぎてしまう場合がある。
なるべく大きなブロックにまとめておくべきという原則から考えると、あまり望ましいことではない。
しかし、CTAS実行時に、利用するノード数を減らすことで、結果として生成されるファイル数を減らすことができる。
Impalaで利用するノード数は `NUM_NODES` オプションで指定できる。


# 実行例

```
SET NUM_NODES = 1;
CREATE TABLE table_pq STORED AS PARQUET SELECT * FROM table_orig WHERE col1 = 'hoge';
```

# どういうときに使うべきか？

たとえば、ワーカーノードが10台あるときに、デフォルトのままで生成されるファイルの平均サイズが10MB程度であれば、上記の方法を使ってデータをまとめてもいいだろう。10 * 10 = 100 MB程度のため、1ブロック128MBに収まる計算となる。通常Impalaが取り扱うデータサイズから考えるとあまり頻繁に遭遇することはないだろうが、個人用にフィルタしたデータを別テーブルとして作成する場合に、このようなケースが見られる。


# 注意
上記の例では1ノードで実行しているので、データのリモート転送量が増えるのはもちろん、実行時間も大幅に伸びてしまう。また、メモリの使用量も大きく増えるため、クエリ失敗のリスクが増大する。利用には細心の注意を払うべきだろう。参考リンクにあるClouderaのドキュメントでは、本番環境では使わないようにとの注意書きが記載されている。


# 参考
- [Clouderaドキュメント: NUM_NODES Query Option](https://www.cloudera.com/documentation/enterprise/latest/topics/impala_num_nodes.html)
pythonで一時ファイル、一時ディレクトリ(tempfile)

pythonで一時ファイルを使うにはtempfileを使う。

```py:p.py
import tempfile
import os


def main():
    with tempfile.NamedTemporaryFile() as fp:
        filename = fp.name
    if not os.path.isfile(filename):
        print(filename + ' is not exists')

    with tempfile.TemporaryDirectory() as td:
        dirname = td
    if not os.path.isdir(dirname):
        print(dirname + ' is not exists')


if __name__ == '__main__':
    main()
    exit(0)


"""
/tmp/tmpvdjzflod is not exists
/tmp/tmpwwtl1bun is not exists
"""
```

ただし、3.2以上でないとTemporaryDirectoryは使えないので注意

```
/tmp/tmp3OJjCi is not exists
Traceback (most recent call last):
  File "/home/ymko/tmp/testtest/p.py", line 21, in <module>
    main()
  File "/home/ymko/tmp/testtest/p.py", line 11, in main
    with tempfile.TemporaryDirectory() as td:
AttributeError: 'module' object has no attribute 'TemporaryDirectory'

Process finished with exit code 1
```


NamedTemporaryFileとTemporaryFileどちらを使えばいいのか悩みどころだが互換性を考えるとNamedTemporaryFileが良いようだ。
O_TMPFILEを使いたい場合はTemporaryFileを呼ぶ必要がある。

```py:tempfile.py
def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
                       newline=None, suffix=None, prefix=None,
                       dir=None, delete=True):
...
if _os.name != 'posix' or _os.sys.platform == 'cygwin':
    # On non-POSIX and Cygwin systems, assume that we cannot unlink a file
    # while it is open.
    TemporaryFile = NamedTemporaryFile

else:
    # Is the O_TMPFILE flag available and does it work?
    # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an
    # IsADirectoryError exception
    _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE')

    def TemporaryFile(mode='w+b', buffering=-1, encoding=None,
                      newline=None, suffix=None, prefix=None,
                      dir=None):
```



[11\.6\. tempfile — 一時ファイルやディレクトリの作成 — Python 3\.6\.3 ドキュメント](https://docs.python.jp/3/library/tempfile.html)
[Community Blog \- ファイルオープンと新フラグ](https://www.oreilly.co.jp/community/blog/2014/09/file-open-and-new-flags.html)
RailsのデータをSpreadsheetに出す


## やりたいこと
Railsで作ったデータをGoogle Spreadsheetに吐き出させたい

## 結論
**直で連携させるのは厳しい**
google-drive-apiとかgoogle-api-clientとかあるけど、gemで入れても
`uninitialized constant`
ってなる。
gemのバージョン指定してやらなきゃいけないとか、google-api-clientがバージョン9だとgoogle-deive-api動かないとかいろいろあってメンテナンス死にそうなのでrailsのほうでjsonではきだしてgasでspreadsheetに出す。

#### 流れ
データを作成（Rails）
↓
Json形式で出力(Rails)
↓
データを受信(Google App Script)
↓
Spreadsheetに書き込む(Google App Script)

## まずRailsの準備

1.viewの作成
`touch app/views/company.json.jbuilder`

2.conterollerの作成
`touch app/views/api/company/index.json.jbuilder`

3.ルートの設定

```ruby:config/routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :company do
      get '/', action: 'index'
    end
  end
end
```

## controllerでデータ整形

```ruby:app/controllers/api/company_controller.rb
class Api::OneController < ApplicationController
  def index
    @comcom = Company.all
    render 'index', formats: 'json', handlers: 'jbuilder'
  end
end
```

今回は簡単にallで取得してるが、けっこう柔軟にデータを入れられる


## viewで吐き出す

```ruby:app/views/api/company/index.json.jbuilder
 json.companies @comcom
```

コントローラから渡されたデータをかく


サイトにアクセスすると、こんな感じでブラウザに表示される
ローカルだとhttp://localhost:3000/api/company かな

```json:
{"companies":
   [{"id":1,
     "name":"A会社",
     "created_at":"2017-12-02T02:29:46.000Z",
     "updated_at":"2017-12-02T02:29:46.000Z"
    },
    {"id":2,
     "name":"B会社",
     "created_at":"2017-12-02T02:29:46.000Z",
     "updated_at":"2017-12-02T02:29:46.000Z"
    },
   
```

## gasで受信する

json吐き出してるurlから引っ張ってくる

```javascript:code.gs
var json_url = "http://xxx.xxx.xx/api/one"

function JSON() {
  var json = UrlFetchApp.fetch(json_url).getContentText();
  var jsonData = JSON.parse(json);
  Logger.log(jsonData["companies"]);
}
```

ログ見たら、ちゃんとデータがきてることがわかる

## 書き出す
シートを取得してくる
スプレッドシートのurlをコピる

```javascript:code.gs
var sp_url = "https://docs.google.com/spreadsheets/d/xxx/";
var spreadsheet = SpreadsheetApp.openByUrl(sp_url);
```

一行目はラベルをつけたいので二行目からデータを書き込む
getRangeで書き込む場所を指定し、setValueでデータをいれている

```
　var i=0;
  var k=1;
  for (var idx in jsonData["companies"]) {
    sheet.getRange(i+2, k).setValue(jsonData['companies'][j]['name']); 
    sheet.getRange(i+2, k+1).setValue(jsonData['companies'][j]['created_at']);  
    sheet.getRange(i*2, k+2).setValue(jsonData['companies'][j]['updated_at']);  
    i++;
  }
```

コードの全貌はこちら

```javascript:code.gs
var sp_url = "https://docs.google.com/spreadsheets/d/xxx/";
var spreadsheet = SpreadsheetApp.openByUrl(sp_url);
var json_url = "http://xxx.xxx.xx/api/one"

function JSON() {
  var sheet = spreadsheet.getSheetByName("hogehoge");
  var json = UrlFetchApp.fetch(json_url).getContentText();
  var jsonData = JSON.parse(json);
    var i=0;
    var k=1;
  for (var idx in jsonData["companies"]) {
    sheet.getRange(i+2, k).setValue(jsonData['companies'][j]['name']); 
    sheet.getRange(i+2, k+1).setValue(jsonData['companies'][j]['created_at']);  
    sheet.getRange(i*2, k+2).setValue(jsonData['companies'][j]['updated_at']);  
    i++;
  }
}
```

実行結果はこちら

![image.png](https://qiita-image-store.s3.amazonaws.com/0/216967/e739e1ef-5dbe-9a32-e13d-58b823722912.png)

ちゃんと出たやったね


### その他やったこと
mysqlから直にスプレッドシートつなげばよくない！？→ポート開けるのにチキった
でも一応できるようです
データベースに登録する時の電話番号の型は数値がいいのか？

データベースに登録する時の電話番号の型は数値がいいのか？
についてですが

電話番号はハイフンの位置なども含まれる場合があるので文字列型のほうが良い。
国際電話番号(＋81等)の管理をする場合にも同様です。

ですので、文字列でvarchar(0～255)が良いと思われる。
Appiconset generator

# はじめに

1024px x 1024pxの画像からmacOSアプリやiOSアプリで必要になるアプリアイコンを書き出すRubyスクリプトです。

以下の環境で動作確認をしています。
macOS High Sierra(10.13.1)

# appiconset

appiconsetは以下の方法でインストールできます。

```bash:1
$ gem install specific_install
$ gem specific_install -l 'git://github.com/arthur87/appiconset.git'
```

appiconsetの使い方

```bash:2
$ appiconset -h
Usage: appiconset [options] <input>
    -o, --output <output>
    -x, --xcode <version>            set xcode version; 8.3.3, 9.1
    -p, --platform <platform>        set platform; ios, mac, univarsal
    -h, --help                       Show this message
```

1024px x 1024px の画像からアプリアイコンを作成します。

```bash:3
$ appiconset icon.jpg
$ cd ./AppIcon.appiconset
$ ls
Contents.json    Icon-20@3x.png   Icon-40@1x.png   Icon-60@3x.png
Icon-1024@1x.png Icon-29@1x.png   Icon-40@2x.png   Icon-76@1x.png
Icon-20@1x.png   Icon-29@2x.png   Icon-40@3x.png   Icon-76@2x.png
Icon-20@2x.png   Icon-29@3x.png   Icon-60@2x.png   Icon-83.5@2x.png
```
Contents.jsonと複数のpngファイルが作成されます。
これらのファイルをXcodeプロジェクトのAppIcon.appiconsetにコピーします。

![スライド02.jpeg](https://qiita-image-store.s3.amazonaws.com/0/3862/a20c9553-5923-7bd3-44ec-da99eb3e1afa.jpeg)

このスクリプトでは、iOS、macOS、univarsalのアイコン作成をサポートしています。
例えば、platformにmacを指定するとmacOS向け、universalを指定するとimageset向けの3種類のアイコンを作成します。
省略した場合はiOS向けのアイコンを作成します。

```bash:4
$ appiconset icon.jpg -p mac
```

# sips

このスクリプトでは、macOSの標準コメンド「sips」を利用しています。
sipsは画像に関する情報取得や画像の変換処理ができます。
このコマンドには、縦横比を維持した変形、回転、水平反転、切り抜きなど多数のオプションがあります。

# 最後に

このスクリプトは[GitHub](https://github.com/arthur87/appiconset)で公開しています。
メソッドの切り分け方について（品質の話）


コードを腐らせがちなので、心がけるべきことを自戒も込めて書きました。
メソッドの切り分け方について参考になる規則をまとめます。

# メソッドの分解がよくなるとどうなるか
#### 1.メンテナンス性があがる
結果が局所的になるため、変更の影響を抑えることができる
柔軟に変更ができ、また変更が容易になる
障害が起きた時も保守しやすく、拡張もしやすくなる

#### 2.コードが読みやすくシンプルになる
ほかの部分も類推できるようになる
情報が隠蔽され、必要なものだけ見えるようになる
抽象化してコードが読めるようにいなる

#### 3.できるだけ作らなくても開発ができるようになる
作らないで開発は究極の効率化
実績のあるコードを使用することで、品質があがる

# どうやって切り分けたらいいのか
むやみやたらと切り分ければいいってものではない

## DRY
**Don't Repear Yourself.**
大原則のコードのコピペ厳禁　~~ついこの前コピペでコード作った。~~
コードを抽象化し、処理のまとまりに名前をつける
それを繰り返し出てくる部分と置き換える

## SLAP
**Single Level of Abstraction Principle**
抽象化レベルの統一
DRYで抽象化するときに抽象化概念のレベルで分離させる
メソッドを抽象レベルに沿って分割すると、高い抽象レベルのメソッドが目次の役割を果たしてくれるので読みやすくなる

## 対称性をもたせる
**コードの一貫性**
同じことは同じ表現にする
抽象化レベルで統一するとき、同じ種類、同質のものは同じレベルで合わせる
あるメソッド内で呼び出すメソッドの抽象度は同じレベルにする

## 変更頻度の確認
**変更理由でグルーピングする**
対称性のうちのひとつ、時間に関するレベルでの分離
変更理由が多いものは脆いコードなので、分離する
たとえば、毎年変更する必要のある部分と一般的に使える部分を分離することで一般的に使えるコードの品質を担保できる

## 関心で分離
**関心単位でモジュール化**
対称性のうちのひとつ、関心に関するレベルでの分離
たとえば「Mode-View-Controller」のフレームワークではそれぞれに役割があり、関心が分かれている
メソッドも同じように関心がまざらないように分離すると読みやすくなる

# まとめ
頑張っていっぱいコード書いていっぱい直せばいいかな！
コードは必ず変更されるということを念頭に、品質のいいコードを目指したいと思います

# 参考文献
プリンシプルオブプログラミング（著：上田 勲）秀和システム　
達人プログラマー(著：Andrew Hunt、 David Thomas)オーム社
Macにanacondaをインストールする


##概要
*Mac OS X 10.13 High Sierra
*homebrewはインストール済み
*pyenvを用いる

###pyenvインストール

homebrewを使う

```
$ brew update
$ brew install pyenv
```

パスを通す

```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

###anacondaインストール

anacondaのバージョンを調べてインストール(執筆時点だと3-5.0.0が最新)

```
$ pyenv install -l | grep anaconda
$ pyenv install anaconda3-5.0.0
```

pythonコマンドでanacondaを使うようにする

```
$ pyenv global anaconda3-5.0.0
$ pyenv versions ### anacondaの横に * がついてればOK
```
/bin/bash必須だったけど/bin/shでもいけるようにしたぞ

こんにちは、Vulsのちょんまげこと、サウナおじさんです
![alt](https://camo.qiitausercontent.com/793939a153ce1ace15a2b319cc957d3ad952a9c4/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f32323436322f35656136383466352d346261622d356339312d663361392d3730383765383061386661632e706e67)


先日、勢いで実装したAlpine対応[Vuls:#545](https://github.com/future-architect/vuls/pull/545)の中でしれっといれこみました。
![alt](https://github.com/future-architect/vuls/raw/master/img/vuls_logo.png)


これまでのバージョンでは、スキャン対象のコンテナ上で/bin/bashでコマンドを発行してました。
bashだった理由は、Vulsがスキャン対象OS上で発行するコマンドでパイプを使ったものが公開当初は結構あったんすよ。

で、パイプの前のコマンドで起きたエラーを捕捉するするために、
`set -o pipefail`
してたんすけど、これbash3.0以降にしかないオプションなんすよね。[参考](http://d.hatena.ne.jp/iww/20130409/pipefail)
なので、仕方なく/bin/bashを使ってスキャン対象サーバでコマンドを実行してました。

2016年４月に公開したVuls。
公開から改造を重ね、発行するコマンドが改善され、よくみるとパイプしてるところがほとんど無いことに気づきました。
パイプがないってことは、/bin/shにするのは今しかねぇ！
ということで、しれっとbash依存を取り除いた次第でございます。

さーてサウナでも行くべよ（日曜日20:00記）
GitHubにsshで接続できない

Configに下記記載し、GithubにSSHでは正常に接続できた。
しかし、なぜかgit cloneができない。

```
ssh -vT git@github.com
```

でデバッグすると、秘密鍵のファイルが見つからないようだ。

```.ssh/config
Host github
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_github
```

秘密鍵のファイルは~/.ssh/id_rsa_githubとしていたが、

```
 ssh -vT git@github.com
```

でデバッグした結果、どうもid_rsaで接続しようとしているようだ。

id_rsa_githubをid_rsaにrenameしたところ、git cloneが成功した。
でも原因はわからない。
Eliasでインタラクティブミュージック　Unity組み込み編(2)


前回でレベル変化部分をやってしまったので残るはActionPreset。ただしこの機能はEliasPlayer.RunActionPreset関数のみで完結するので、例のHPによる変化部分の処理についても書きます。

## ActionPresetの実行

PresetActionはEliasPlayerにたいしてRunActionPresetでPreset名を実行すればいける。


```SoundManager.cs
    public static void RunActionPreset(string actionName)
    {
        if (null == instance_ || null == instance_.elias_player_)
        {
            return;
        }
        instance_.elias_player_.RunActionPreset(actionName);
    }
```

ただし、RunActionPresetで実行できるPresetは現在アクティブなThemeのみ。別のThemeに属するPresetを実行しようとするとエラーとなる。

![スクリーンショット 2017-12-02 21.21.47.png](https://qiita-image-store.s3.amazonaws.com/0/18557/326ae6c2-9dac-14ad-ec93-cb16c71ed294.png "スクリーンショット 2017-12-02 21.21.47.png")

このエラーが出た場合はEliasStudioでPreset名とそのPresetが属するThemeを確認すると幸せになれるかも。

## 残りHPにあわせたBGM変化実装例

``` SoundManager.cs
    /// <summary>
    /// 現在再生しているThemeの最大レベルをえる
    /// </summary>
    /// <returns>最大レベル</returns>
    static public int GetGreatestLevelInActiveTheme () {
        if (null == instance_|| null == instance_.elias_player_)
        {
            return 1;
        }
        var elias = instance_.elias_player_;
        var theme = elias.GetActiveTheme ();
        var greatest_level = elias.GetGreatestLevelInTheme (theme);
        return greatest_level;
    }
```

まず現在再生中のThemeの最大レベルを確認する。
この値をキャッシュしてもいいし、Level設定頻度がそれほど多くないなら毎回問い合わせてもいい。

```BossMonster.cs
    void ControlMusic()
    {
        var max_lv = SoundManager.GetGreatestLevelInActiveTheme();
        // 適当に敵のダメージ量割合を計算する
        var ratio = (float)((MAXHP - HP) / MAXHP);
        // lv=0にしてしまうとミュートになるので1~maxの間にclampする
        var lv = (int) Mathf.Clamp(ratio*(float)max_lv , 1.0f, (float)max_lv);
        SoundManager.SetLevel(lv);
    }
```

この関数を敵ボスがダメージを受けるたびに実行する。
たったこれだけでインタラクティブミュージックが実現できる。

### まとめ

EliasStudioによるインタラクティブミュージックは簡単すぎて説明することがない。
MySQL WorkbenchとMWBファイルを用いてMySQLサーバにテーブルを作成する

# はじめに

こんにちは、
33分かかるバッチを改良しようと思いDB設定を見直しているForestLiveです。

データベースのER図を使う際に「MySQLWorkbench」や「A5ER」といった
SQL開発ツール/ER図ツールを用いて作ることが多いみたいです。

ちょこちょことER図が出来上がり、
サーバにそのまま作成したER図をアップロードできたらいいなぁ
と思いできましたのでメモ程度に残しておきます。

# 前提条件
1. MySQLサーバにアクセスできるユーザを追加しておくこと
2. MySQLWorkbenchとMySQLのサーバを連結しておくこと
3. ER図を作成しておくこと


# 実施方法
## MySQLWorkbenchアプリケーションを開く
<img width="1792" alt="01_MySQL Workbench_TOP.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/7f4cc729-8173-43c3-e93a-a77635c8ba78.png">

開くと登録済みのサーバ一覧が表示されます。
僕の場合は一つのみ設定しているのでForestLive...といった感じで表示されています。
このMySQLサーバにテーブルを追加指定行きます。

## 作成済みのMWBファイルを開く
PCに入っているMWBファイルをダブルクリックしたり、
MySQLWorkbenchからファイルを開くでMWBファイルを行ってMySQLWorkbenchにMWBファイルを展開してください。

展開されると以下のようなER図が展開されると思います。
<img width="1792" alt="02_MWBファイル.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/79f1ae4c-eda0-a0a8-a0b6-b3710c5ac859.png">


## 設定画面を開く
MACの場合はメニューから
[Database] -> [Forword Enginner]を選択してください。

![03_メニュー_forward.png](https://qiita-image-store.s3.amazonaws.com/0/56169/f76f4824-361d-f55c-8e10-c8783f609369.png)

## 設定いろいろ

### 接続先の設定
<img width="1012" alt="04_接続先の設定.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/16c6562c-20d6-56bf-9e97-c25f6dc7a512.png">

サーバに接続するために以下の内容を設定します。

|設定  |詳細  |
|---|---|
|サーバの設定  |設定済みのサーバを選択|
|僕の場合はIPアドレス|「サーバのHostname」または「IPアドレス」を記載|
|Port|MySQLサーバのポートを指定|
|Username|MySQLサーバに設定したユーザを指定|
|Password| Store Keychainをクリックしてパスワードを入力|

### オプション
あとで追記するかも

<img width="1012" alt="05_オプション.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/83e9a541-0f1e-4e51-d8f8-4bcfb609ce0a.png">



### DBに登録する内容
今回はテーブルを新規で登録するので一番上の「Export MySQL Table Objets」のみ選択します。

<img width="1012" alt="06_オプション_設定する内容（今回はテーブルのみ）.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/14be1b73-4d89-cf2f-9e67-5ac560776573.png">

### DDLが発行されます

テーブルにしたがってDDLが発行されます。
コメントまで書かれます。いいですねぇ。

あとは右下の「Continue」ボタンを押すだけです。

<img width="1012" alt="07_登録するddl.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/86fcdac9-d061-fbf0-1520-1909ddccd9f5.png">

## テーブルの確認

MySQLに入ってテーブルを確認しました。
ありました。

<img width="682" alt="08_テーブルの確認.png" src="https://qiita-image-store.s3.amazonaws.com/0/56169/18f68ae7-d4ba-ebd5-07d9-af314cdf1e05.png">
# おわりに

今回MySQLWorkbenchは触ってみて利点がだんだんとわかってきました。
GCMでDBサーバをいじれるのもいいですし、一度設定してしまえばもうコンソールから触ることはほぼ無くなります。

効率化にもぴったりかもしれませんね。
[Python]Qt Designer簡単に使い方。

こんばんは。。
pythonを使ってGUIを作る必要がありました。
いろんなGUIライブラリーありますよね？
私はその中でpyQtを選択して開発して簡単におわりました。
#Qt Designer
Qt Designerの経路は[ここ](https://qiita.com/Dreamwalker/items/de2e200c09f6807932e8)を参考してください。
#Main Window 選択。

Main Window選択してボタンとラベルを簡単に仮面に

![qtqt01.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/cf9bc489-45e3-f967-1ae4-bf05db6e29a6.jpeg)

#Ctrl + RでPreview
![qtqt02.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/fea2e2da-24d6-9baa-311b-c340a36b1cf3.jpeg)

#じゃあSaveしましょう。
![qtqt03.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/fb4ef4d9-97ee-8a68-3c1d-8ea6ac39f1d3.jpeg)

#uicフォルダーにコピーしましょう。

![qtqt04.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/d98f6ffc-7fb5-e884-d98f-6b24131ec777.jpeg)

#cmdで経路移動。

```
python -m PyQt5.uic.pyuic -x main_window.ui -o main_window.py
```

![qtqt05.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/aba28245-68dd-1ae0-408c-43abb708ea17.jpeg)

#uiからpy登場。。

```
python main_window.py 
```
![qtqt06.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/a060dbc0-3e46-8718-1c62-57299adc4eb8.jpeg)


#終わりに

今回はあんまり詳しくないのですが、
早くしやすいので、やってみてください。
実際に使ってみるととても開発速度も速かったしよかったです。
namedtuple(名前付きタプル)で簡易クラスを作る

この記事は [Pythonのコードを短く簡潔に書くテクニック Advent Calendar 2017](https://qiita.com/advent-calendar/2017/python-short-code) の2日目です。

# はじめに

データベースなどから読み込んだレコードを格納するような所謂バリューオブジェクトと呼ばれる、データを格納するだけのクラスを作りたいときがあります。

Pythonでこのクラスを作ると、`__init__`で`self.xxx = xxx`という冗長なコードを書かなくてはならないのですが、[namedtuple]（名前付きタプル)を使うと簡単に作れます。

[namedtuple]:https://docs.python.jp/3/library/collections.html#collections.namedtuple

**[2018/07/16 追記]**
Python3.7以降ではdataclassを使うほうが便利です。
[Python3.7からは「Data Classes」がクラス定義のスタンダードになるかもしれない - Qiita](https://qiita.com/tag1216/items/13b032348c893667862a)


# クラスで作った場合

```py3
class Item:
    def __init__(self, title, url, user, body):
        self.title = title
        self.url = url
        self.user = user
        self.body = body
```

# namedtupleで作った場合

```py3
from collections import namedtuple
Item = namedtuple('Item', ('title', 'url', 'user', 'body'))
```
第一引数がクラス名、第二引数がフィールド名のリストです。

# namedtupleの特徴

普通のクラスと同じようにオブジェクトを作成できます。
また、`__str__`メソッドを定義しなくても中身が確認できます。

```pycon
>>> Item('item1', 'http:example.com/item1', 'user1', 'body1')
Item(title='item1', url='http:example.com/item1', user='user1', body='body1')
>>> Item(title='item1', url='http:example.com/item1', user='user1', body='body1')
Item(title='item1', url='http:example.com/item1', user='user1', body='body1')
```

フィールドには属性名でアクセスできます。

```pycon
>>> item = Item(title='item1', url='http:example.com/item1', user='user1', body='body1')
>>> item.title
'item1'
```

タプルなのでインデックスでもアクセスできます。

```pycon
>>> item[0]
'item1'
```

タプルはイミュータブルなので値の変更はできません。

```pycon
>>> item.title = 'item2'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
```

JSONに変換もできます。

```pycon
>>> import json
>>> json.dumps(item)
'["item1", "http:example.com/item1", "user1", "body1"]'
>>> json.dumps(item._asdict())
'{"title": "item1", "url": "http:example.com/item1", "user": "user1", "body": "body1"}'
```
Gentoo Linux に TensorFlow r1.4 をインストール

# 多分以下の方法がある
- layman から overlay 持ってきてインストール
(結論、動かなかった)
- virtualenv に pip で入れる
(動いた)

# virtualenv + pip(3)
前準備
`emerge pip virtualenv`
調理
`mkdir ˜/tensorflow`

`virtualenv --system-site-packages ˜/tensorflow` もしくは
`virtualenv --system-site-packages -p python3 ˜/tensorflow #python3`

`source ˜/tensorflow/bin/activate`
`easy_install -U pip`
`pip install --upgrade tensorflow`

あとは使う前にvirtualenv に入る魔法
`source ˜/tensorflow/bin/activate`
を忘れなければ動く、はず
CPUのアーキテクチャが云々と出るかもしれませんが頑なに無視しましょう
QUIZ: サイズ不定な配列型変数？

# 誰得クイズ

問：下記Cソースコードをコンパイルした場合、配列`a`はどのように初期化されるか？ファイルは下記2行のみからなるとする。

```c:quiz.c
int a[];
int main() {}
```

≡≡≡≡≡≡≡≡≡≡c⌒っﾟДﾟ)っ

⊂(ﾟДﾟ⊂⌒｀つ≡≡≡≡≡≡≡≡≡≡


# 解答

答：変数`a`は1要素の配列としてゼロ初期化される。つまり `int a[1] = { 0 };` 相当となる。

この振る舞いはC言語特有の「*仮定義(tentative definition)*」とよばれる言語機能による。C99言語仕様 ISO/IEC 9899:1999、および対応する JIS X 3010:2003 よりそれぞれ引用。

## ISO/IEC 9899:1999

> 6.9.2 External object definitions
>
> 2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier `static`, constitutes a _tentative definition_. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.
> 
> 5 EXAMPLE 2 If at the end of the translation unit containing
>
> ```c
> int i[];
> ```
> the array `i` still has incomplete type, the implicit initializer causes it to have one element, which is set to zero on program startup.

## JIS X 3010:2003

> 6.9.2 外部オブジェクト定義
>
> ファイル有効範囲のオブジェクトの識別子を，初期化子を使わず，かつ，記憶域クラス指定子なしか又は記憶域クラス指定子 `static` で宣言する場合，そのオブジェクトの識別子の宣言を仮定義（tentative definition）という。翻訳単位が，ある識別子に対する仮定義を一つ以上含み，かつその識別子に対する外部定義を含まない場合，その翻訳単位に，翻訳単位の終わりの時点での合成型，及び 0 に等しい初期化子をもったその識別子のファイル有効範囲の宣言がある場合と同じ規則で動作する。
>
> 例2. 翻訳単位が
>
> ```c
> int i[];
> ```
>
> を含み，その翻訳単位の最後で，配列 `i` が依然として不完全型をもつ場合，配列 `i` は暗黙の初期化子によって一つの要素をもつようにされる。その要素にはプログラム開始時に 0 がセットされる。


# で？

C言語ってムツカシイ ∩( ・ω・)∩
Unity-今更ながらRigidBodyのCollision Detectionについて表にまとめてみた

#Unity-今更ながらRigidBodyのCollision Detectionについての覚え書き

UnityでRigidBodyの衝突判定を設定するときにいつも忘れるのでUnityのマニュアルの記述を表にまとめてみた。
"？？？"になっているところ、Continuous同士の衝突については記述がないみたい。

|	|RigidBodyなし	|Discrete	|Continuous	|Continuous  Dynamic|
|:-:|:-:|:-:|:-:|:-:|
| RigidBodyなし		|	|不連続	|連続	|連続		|
| Discrete		|不連続		|不連続	|不連続	|不連続		|
| Continuous		|連続		|不連続	|？？？	|連続		|
| Continuous Dynamic	|連続		|不連続	|連続	|連続		|

Unityマニュアル
https://docs.unity3d.com/ja/current/Manual/class-Rigidbody.html

>Collision Detection 	高速で動くオブジェクトが、衝突を検知せずにすり抜けることを防止します。

>- Discrete 	Discreet (不連続な)衝突判定を、シーン内の他すべてのコライダーに対して使用してください。他のコライダーは、それに対する衝突のテストを行う時に Discreet 衝突判定を使用します。通常の衝突に使用されます（これがデフォルトの値です）。

>- Continuous 	動的なコライダー（リジッドボディあり）には Discrete （不連続）な衝突、静的なメッシュコライダー（リジッドボディなし）には Continuous （連続）な衝突を適用します。Continuous Dynamic を適用したリジッドボディに対する衝突は、連続的な衝突検知をします。これは Continuous Dynamic を適用したオブジェクトの衝突相手として使用します。（物理演算のパフォーマンスに大きく影響するため、高速なオブジェクトの衝突で問題が出ない場合は Discrete のままにしてください。）

>- Continuous Dynamic 	Continuous や Continuous Dynamic 衝突を適用したオブジェクトに対して、連続的な衝突検知を行ないます。静的なメッシュコライダー（リジッドボディなし）にも連続的な衝突を適用します。その他のコライダーについては 不連続な衝突検知を行ないます。高速で動くオブジェクトに使用します。
electrumをコマンドラインから使う

# はじめに

この記事は暗号通貨アドベントカレンダー二日目の記事です

一日目にelectrumのサーバー側を書いたのでクライアント側の仕組みを書きます

# electrumの仕組み

electrumxから必要なアドレスの情報を持ってきているクライアントサーバーモデルであると前回の記事で書いたが
それを実現するのにいくつか問題がある

* 信用できるサーバーをちゃんと選べるのか（一応electrumがデフォルトでつなぐサーバーは信用できるホワイトリストを兼ねている）
* あとから信用できないサーバーにならないか（ハードフォークの更新し忘れていて違うチェーンになっていないか）

秘密鍵や送金情報はelectrumクライアントが持っているので野良サーバーが盗むことはできないが
残高情報などの嘘の情報を教えることはできる

electrumはそれをちゃんと検証する仕組みを持っていてブロックヘッダを取得し、トランザクションが本物であるか検証をしている。
それによって信用できるサーバーと信用できないサーバーを区別している

# electrumの知られざる機能（とかあおってみる）

実はelectrumはサーバーとして運用が可能である
bitcoindのコマンドラインから操作するウォレットのように扱える
秘密鍵はBIP32で管理されているので一度ニーモニックをバックアップしておけばアドレスが増えた場合でも再度バックアップする必要はない
ブロックチェーンの同期がないので保守が楽になるカモ？（無責任）

# electrumの秘密鍵

electrumの秘密鍵は暗号通貨業界でよく見かけるニーモニック（以下BIP39ニーモニックという）のように見えるが実はちょっと違う。
何が違うかというとなんとBIP39ニーモニックと仕様が違っていて互換性がないのだ。
だからelectrumでメモってもelectrumのニーモニックに対応していなければ復元できないのだ

XPRVやWIFと呼ばれる形式にすればほかでもインポートできるがそれを使うにはアドレスがどれか特定しなくてはならない
緊急時に他のウォレットでも使いたい場合には注意がいるだろう

# commandラインから使ってみよう

コマンドラインから使うにはdaemon（常駐プログラム）として起動する必要がある

## daemonとして起動する

### 起動

```
electrum daemon start
```

### 終了

```
electrum daemon stop
```

## 秘密鍵を扱う

### 秘密鍵の作成

```
electrum create
```

### 秘密鍵の復旧

```
electrum restore "xxxx xxxx xxxxx xxxxx"
```

## ウォレットを操作する

一番最初にウォレットを常駐しているelectrumに秘密鍵をロードする必要がある、そのあとウォレットを操作するコマンドが使えるようになる

### 秘密鍵のロード

```
electrum daemon load_wallet
```

### アドレス一覧

ウォレットの入金アドレスを表示

```
electrum listaddresses
```

### バランス取得

ウォレット全体の残高を取得できる

```
electrum getbalance
```

### 支払い作成

* bitcoinaddressは支払先のアドレス
* amountは送金額(0.001とかbtc指定で)
* このコマンドを使うと数字で羅列された生トランザクションが出力される
* その生トランザクションをネットワークに伝搬させないかぎり実際に送金されない
* 確定処理をするコマンドを実行する必要がある

```
electrum payto bitcoinaddress amount
```

### 支払い確定

* transaction_stringにpaytoで作った生トランザクションを入れる
* このコマンドで実際の支払い処理が完了する

```
electrum broadcast transaction_string
```


## 他にも商売用に作られたコマンドとかもある

マーチャント用のドキュメントがあり、そこではユーザーごとに支払いを受け付ける仕組みはelectrumがやってくれるようだ
（実はあまり調べてない・・・）

http://docs.electrum.org/en/latest/merchant.html

# オルトコインのelectrum達

コインによっては最新版に追従していなくて動かなかったり
秘密鍵を盗む目的で作られたelectrumもよくあるようだ
オルトコイン版のelectrumを使う場合は開発者が信用できるかどうかよく確認してから使うようにしよう
実際に開発者コミュニティに属している人が作成していたり、コイン開発者が作っているものはある程度信用してよいだろう
githubからであれば誰が作っているかすぐにわかるので参考にURLを張っておきます

| coin | url |
|-----|------|
| litecoin | https://github.com/pooler/electrum-ltc |
| monacoin | https://github.com/wakiyamap/electrum-mona |
| dash | https://github.com/dashpay/electrum-dash |
| bitcoincash | https://github.com/fyookball/electrum |
展示用にiPhone/iPadでWebページをフルスクリーン表示したままにする方法（アクセスガイド）

展示会などで、iPadでWebページを表示して、お客さんに触ってもらいたい場合なんかに使える方法です。

# 手順

[設定アプリ]→[一般]→[アクセスビリティ]→[アクセスガイド]

でアクセスガイドをONにして、該当のURLをSafariで開きHOMEボタンをトリプルクリックします。

セッションの設定を調整してから「開始」をタップします。

これでフルスクリーンのまま画面が固定され、他のアプリに移れないようになります。
tomcat 環境構築

tomcatのインストール
環境はUbuntu16.04




###JDKとJREをインストール
まずはhttp://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
からJDKをダウンロードして、
次にインストール

```
#cd ~/Downloads/
#gunzip jdk-8u152-linux-x64.tar.gz
#tar xf jdk-8u152-linux-x64.tar
#cp -r jdk-8u152-linux-x64 /usr/local/lib

#add-apt-repository ppa:webupd8team/java
#apt-get install oracle-java8-installer
```
####　環境変数設定
```
#echo 'JAVA_HOME=/usr/local/lib/jdk1.8.0_152' >> /etc/profile
#echo 'export JAVA_HOME' >> /etc/profile
#echo 'PATH=$PATH:$JAVA_HOME/bin' >> /etc/profile
```

###tomcatをインストール
まずは[tomcatの公式サイト](http://tomcat.apache.org/)からダウンロード
次にインストール

```
#cd ~/Downloads/
#gunzip apache-tomcat-8.5.24.tar.gz
#tar xf apache-tomcat-8.5.24.tar
#cp -r apache-tomcat-8.5.24  /opt
#cd /opt/apache-tomcat-8.5.24/bin/
#./startup.sh
```
PyCharm (CE) で TensorFlow を使えるようにする

備忘録。
PyCharm でvenv を作成します。ここまでは良かったんだけどbash立ち上げても入らない
*なぜだ*

外部からシェルでpip3経由してtensorflow ぶち込むと動きます

例えば
`˜/tensorflow/venv/`
にvenvを作った場合
`source ˜/tensorflow/venv/bin/activate`
`pip3 install tensorflow`
はいおしまい。簡単でした
[Python]Qt Designerの経路


#経路。
```
C:\Users\name\AppData\Local\Programs\Python\Python35\Lib\site-packages\pyqt5-tools
```

#Anacondaの場合経路。


```
C:\Anaconda3\Library\bin
```


![qtqt.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/37970e8a-8bbe-8c8e-1d83-f77f6461e599.jpeg)

![qqq.JPG](https://qiita-image-store.s3.amazonaws.com/0/137182/4a9460e1-fcf8-772e-da47-2b1ad4012caa.jpeg)
Dockerを使ってHerokuにデプロイする

　初投稿です。Rust で書いたウェブアプリケーションが [Heroku](https://www.heroku.com/home) で動くと嬉しい、という話をします。

## ローカルで動かす

　これは、`GET /hello-heroku` と叩くと `"Hello, Heroku!"` と喋るアプリケーションです。

```toml:Cargo.toml
[package]
name = "hello-heroku"
version = "0.1.0"
authors = []

[dependencies]
shio = "0.2.0"
structopt = "0.1.6"
structopt-derive = "0.1.6"
```

```rust:src/main.rs
extern crate shio;
extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use shio::prelude::*;
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(name = "hello-heroku", about = "Hello, Heroku!")]
struct Options {
  #[structopt(short = "p", long = "port", default_value = "7878")]
  port: u16,
}

fn hello_heroku(_: Context) -> Response {
  Response::with("Hello, Heroku!")
}

fn main() {
  let options = Options::from_args();

  Shio::default()
    .route((Method::Get, "/hello-heroku", hello_heroku))
    .run(format!(":{}", options.port))
    .unwrap()
}
```
[structopt](https://github.com/TeXitoi/structopt) という crate が便利なので使うと良いと思います。

```shell-session
$ cargo run -- -p 8000
```

```shell-session
$ curl localhost:8000/hello-heroku
Hello, Heroku!
```

楽しい！₍₍ (ง╹◡╹)ว ⁾⁾

## Docker で動かす

　これは、アプリケーションを乗せたイメージです。Heroku で動かす場合、公開するポート番号は環境変数 `PORT` に渡される[^1]ので、そのようにします。

```Dockerfile:Dockerfile
FROM rust:1.22.1

RUN mkdir /app
COPY ./Cargo.toml /app/Cargo.toml
COPY ./src /app/src
WORKDIR /app
RUN cargo build --release

CMD cargo run --release -- -p $PORT
```

ビルドにわりと時間かかるのが最高です。私のマシンが非力すぎるという説もある。

```shell-session
$ docker build -t hello-heroku .
$ docker run -it --rm -e "PORT=8000" -p 8000:8000 hello-heroku
```

```shell-session
$ curl localhost:8000/hello-heroku
Hello, Heroku!
```

楽しい！₍₍ (ง╹◡╹)ว ⁾⁾

## Heroku で動かす

　イメージをプッシュし、アプリケーションをデプロイします。

```shell-session
$ heroku container:push --app YOUR_APP_NAME web
```

やりました。

```shell-session
$ curl https://YOUR_APP_NAME.herokuapp.com/hello-heroku
Hello, Heroku!
```

楽しい！₍₍ (ง╹◡╹)ว ⁾⁾

## やっていく

　Docker を使うと Heroku にシュッとデプロイできて最高です。SSR (Server-Side Rust) をやっていきましょう。

## 参考

- [Container Registry & Runtime - Heroku Dev Center](https://devcenter.heroku.com/articles/container-registry-and-runtime)

- [library/rust - Docker Hub](https://hub.docker.com/_/rust/)

- [TeXitoi/structopt - GitHub](https://github.com/TeXitoi/structopt)

- [mehcode/shio-rs - GitHub](https://github.com/mehcode/shio-rs)

- https://twitter.com/ag_dubs/status/782269818485506048

[^1]: https://devcenter.heroku.com/articles/container-registry-and-runtime#dockerfile-commands-and-runtime
Androidアプリが何度落ちても再起動するようにする

[ヴァル研究所 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/val) 5日目の記事です。

# TLDR

[Autostart and StaY!](https://play.google.com/store/apps/details?id=com.atasoglou.autostartandstay&hl=ja)というアプリ（無料）を使うと、指定のアプリを監視し、落ちたとき自動的に再起動できます。

# これが何の役に立つの？

弊社では[SkyBrain](http://www.sky-brain.com/)という低価格バスロケーションシステム（バスロケ）を開発しています。つまりバスにGPS端末を載せて、バスがいつ来るか分かるようにするというシステムです。そのGPS端末としてAndroidスマホを使用しています。

そのAndroidアプリは常時起動しっぱなしで位置情報を送り続けます。ですが、どうしてもときどきアプリが落ちてしまうことがあり、困っていました。そこで逆に「落ちても再起動する」施策を導入したというわけです。

Androidに詳しい方なら自動的に再起動させるアプリを自作するのも難しくないと思いますが、開発者（私）がAndroidアプリを作るのは初めてだったので、無料のアプリを使わせて頂きました。導入以来、100%安定して動いています。作者の方に大感謝です。

# 「落ちたら再起動させればいい」という発想

乱暴なような気もしますが、考えてみればサーバでは当たり前の発想なんですね。unicorn（Rubyのアプリケーションサーバ）ではリクエスト処理に所定時間以上かかっただけでマスタープロセスはワーカープロセスをkillして新しいワーカーを立ち上げますし、supervisordやsystemdにもそういう機能があります。Googleが安いハードウェアを使って壊れたら交換するというのも同じです。

人間のユーザーが使うアプリだとそうも行きませんが、今回は無人で位置情報を送り続けるというアプリだったので、この発想が使えました。
Herokuにデフォで入ってないPHP拡張を入れる

HerokuでPHPのアプリを動かそうと思った時に、デフォで使えるPHP拡張もあれば、使えないPHP拡張もあります。
デフォで使えないPHP拡張はcomposerを使って入れる必要があります。

今回はローカルでは入っていた[GD](http://docs.php.net/manual/ja/book.image.php)がHerokuではデフォで入っていなかったので入れました。


こんな感じで`composer.json`に入れたい拡張を入れます。
この時単に`"gd":"*"`とするとうまく行かないようです。
(参考)[Heroku - how to enable gd on heroku php application?](https://stackoverflow.com/questions/27380365/heroku-how-to-enable-gd-on-heroku-php-application)

```json
{
    "require": {
        "ext-gd": "*",
    }
}
```

次に、`composer update`を実行。

```
composer update
```

あとは、コミットしてHerokuにプッシュしたらHerokuが自動でインストールしてくれるようです。


Herokuにデフォで入っているPHP拡張、入ってない拡張、サードパーティの拡張のリストはこちら。
https://devcenter.heroku.com/articles/php-support#extensions

設定方法はこちら

https://devcenter.heroku.com/articles/php-support#using-optional-extensions

以上。
【備忘録】Fedora25でのKVMのセットアップ

#やりたいこと
Fedora25でKVMを使ってVMを作成したい。
VMはGUIで管理したい。
VMをPXEブートさせたいので、ネットワークはNATを使わずにL2で接続させたい。

##ブリッジの作成
L2で物理ネットワークに接続させるためにブリッジを作成する。
Fedora25ではNetworkManagerがブリッジをサポートしてくれているので、nmcliで作成することができる。

####vsw0という名前でブリッジを作成

```
# nmcli con add type bridge ifname vsw0

# nmcli con
名前         UUID                                  タイプ          デバイス 
bridge-vsw0  1e45c3b0-a41b-4930-b468-180b2e1561fb  bridge          vsw0     
eno1         5334d359-b769-4b74-925d-13d558b310bc  802-3-ethernet  eno1     
enp3s0       5f4c3545-225a-4d1d-b2f8-55be53681d6a  802-3-ethernet  enp3s0   
virbr0       f12b5581-c28f-40a2-9ed0-aeaf01d8f5d4  bridge          virbr0   
```

####物理IFとしてeno1を接続する

```
# nmcli con add type bridge-slave ifname eno1 master bridge-vsw0

# nmcli con del eno1

# systemctl restart network

```
eno1をssh接続などで使用している場合は切れてしまうため注意！
vsw0がeno1と同じMACアドレスになれば期待通りに設定できている。

最終的に下記のようになる。

```
# nmcli con
名前               UUID                                  タイプ          デバイス 
bridge-slave-eno1  1af094e5-52da-4758-b799-1876dcc7874b  802-3-ethernet  eno1     
bridge-vsw0        1e45c3b0-a41b-4930-b468-180b2e1561fb  bridge          vsw0     
enp3s0             5f4c3545-225a-4d1d-b2f8-55be53681d6a  802-3-ethernet  enp3s0   
virbr0             f12b5581-c28f-40a2-9ed0-aeaf01d8f5d4  bridge          virbr0   
```

##KVMのインストール
VMをGUIで管理したいので、virt-managerも一緒にインストールする。

```
# dnf install kvm virt-manager libvirt
```

これで完成。とても簡単。。

あとは仮想マシンマネージャーでVMを作成する際に、ネットワークソースとして、「ブリッジ vsw0」を指定すればOK。