OmniAICreator/Qiita-1.07M huggingface dataset:
サイズをKBやMB、数を万や億などに変換する

自分用メモ
「1024B => 1KB」「1000000000 => 10億」みたいに丸めてくれるやつ作ってみた。
希に欲しい時があるので残しておく。サッと作っただけなので、バグとかあるかも。
こういうのって、世にいくらでもあるだろうに、見つけられない情弱な自分が悲しい。

```js:NumberFormat.js
/**
 * 小数点指定できる四捨五入
 * @see: http://qiita.com/chiyoyo/items/eac6d7cb4d3d6a6ab3fb
 */
Math.round = function (round_original) {
  return function (number, pricision) {
    var _pow;
    switch (arguments.length) {
    case 1:
      return round_original(number);
    case 2:
      _pow = Math.pow(10, pricision);
      return round_original(number * _pow) / _pow;
    }
  }
}(Math.round);

/**
 * 数値フォーマット
 */
var NumberFormat = {
    /**
     * 任意の数に丸めた数値文字を取得する
     * 閾値にはマイナスの値は指定できません
     * ex.) 1024 => 1KB, 120000000 => 1.2億
     *
     * @param float size 元の数値
     * @param array unit 単位設定 [{threshold: 閾値, unit:'単位名'}]
     * @param int dec 小数点以下の数
     * @param boolean separate 桁区切りの有無
     * @return string
     */
    custom_format : function(size, units, dec, separate) {
        // 降順ソート
        units.sort(function (a, b) {
            if (a.threshold < b.threshold) return 1;
            if (a.threshold > b.threshold) return -1;
            return 0;
        });

        unit = {};
        for (i = 0 ; i < units.length ; i++) {
            unit = units[i];
            if (Math.abs(unit.threshold <= Math.abs(size))) {
                break;
            }
        }

        // 0除算を回避
        if (unit.threshold == 0) unit.threshold = 1;

        after_size = Math.round(size / unit.threshold, dec);

        result = '';
        if (separate) {
            result = after_size.toLocaleString();
        }

        return result + unit.unit;
    },

    // バイト丸めフォーマット
    byte_format : function(size, dec, separate) {
        units = [
            {unit: 'B',  threshold: 0},
            {unit: 'KB', threshold: 1024},
            {unit: 'MB',  threshold: 1024 ** 2},
            {unit: 'GB',  threshold: 1024 ** 3},
            {unit: 'TB',  threshold: 1024 ** 4},
            {unit: 'PB',  threshold: 1024 ** 5}
        ];
        return this.custom_format(size, units, dec, separate);
    },

    // 日本語丸めフォーマット
    japanese_format : function (size, dec, separate) {
        units = [
            {unit: '',   threshold: 0},
            {unit: '万', threshold: 10000},
            {unit: '億', threshold: 10000 ** 2},
            {unit: '兆', threshold: 10000 ** 3}
        ];
        return this.custom_format(size, units, dec, separate);
    }
};
```
Laravel5.4: Laravelのパッチバージョンを上げる

# 親記事
[Laravel 5.4で基本的なCRUDを作る - Qiita](http://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# Laravelのパッチバージョンを上げる
(参照: [Release v5.4.24 · laravel/framework · GitHub](https://github.com/laravel/framework/releases/tag/v5.4.24))

v5.4.24が公開されました。
私の環境はv5.4.23です。

```txt:PowerShell
> composer show | Select-String laravel/framework

laravel/framework                     v5.4.23 The Laravel Framework.
```

リリースノートを読んだところ、自分の簡素なCRUDには影響なさそうです。
更新します。

```txt:PowerShell
> composer update
```

確認します。
パッチバージョンの更新は気楽に行えると感じました。

```txt:PowerShell
> composer show | Select-String laravel/framework

laravel/framework                     v5.4.24 The Laravel Framework.
```
GitHubで一時的にコメントやIssue作成を制限する新機能の使い方

GitHubで白熱した議論を落ち着かせるため、**コメント投稿、プルリクエスト作成、Issue作成できるユーザーを一時的に(24時間だけ)制限できる機能が本日(2017/5/31)にリリースされました**。

[Introducing temporary interaction limits](https://github.com/blog/2370-temporary-interaction-limits)

![issue.gif](https://qiita-image-store.s3.amazonaws.com/0/67884/2e8725b1-35f7-72bc-dd26-62b007b662f1.gif)

本エントリーでは、本機能の設定方法について解説します。

# 設定を有効にするには
[Settings]→ [Options]→[Restrict editing to collaborators only]にチェックを入れて設定できます。

![](https://qiita-image-store.s3.amazonaws.com/0/67884/27187e6b-dbf0-6836-ad81-b1f01e3d4069.png)

# 制限するユーザーを設定するには
どのユーザーに対してだけコメントやIssue作成を許可するかは、設定画面下部にある[Temporary interaction limits]で設定します。

![](https://qiita-image-store.s3.amazonaws.com/0/67884/c5008980-b8bd-78b5-75fd-f60ca3293b8b.png)

設定できる制限は次の通りです。

## 以前から存在するユーザーのみ許可する
設定名：[Limit to existing users]

最近アカウントが作成されたユーザーは、コメントやIssue作成が不可能になります。

## 以前コミットしたことがあるコントリビューターのみに許可する
設定名：[Limit to prior contributors]

一度もマスターブランチにコミットしたことのないユーザーは、コメントやIssue作成が不可能になります。

## コラボレーターのみ許可する
設定名：[Limit to repository collaborators]

コラボレーターとして許可されているユーザー以外は、コメントやIssue作成が不可能です。

# 制限されたユーザーはどうなるのか？
許可されていないユーザーは、次のアクションが24時間の間、不可能になります。

- コメント投稿
- Issueの作成
- プルリクエストの作成

次に示すのは、制限のかかっているリポジトリで、Issue作成許可のないユーザーがIssueを作成しようとしているキャプチャーです。**リポジトリに制限がかかっている旨のエラーが表示され、許可されていないユーザーはIssueを作成することができなくなります**。

![issue.gif](https://qiita-image-store.s3.amazonaws.com/0/67884/2e8725b1-35f7-72bc-dd26-62b007b662f1.gif)

同時刻、Issue作成が許可されているユーザーは、従来通りIssueを作成できます。

# 有効活用して、健全な議論を
議論が白熱して収集がつかなくなったり、リポジトリが荒らしにあっているときなど、この機能を有効活用して健全な議論を進めましょう。
ロボアプリ上でのデータ保存（1）

　ロボアプリを作っていると、どこかにデータを保存し、それを再利用したいことがあります。ロボアプリではどのように処理を行うべきなのでしょうか。
　ソフトバンクロボティクスが発行している『ロボアプリ品質チェックリスト』をみながら保存すべき場所を探ってみます。

『ロボアプリ品質チェックリスト』
https://developer.softbankrobotics.com/jp-ja/documents/checklist

**※本記述の内容は全て個人の解釈です。**

# APIドキュメントから探る
　APIドキュメントからデータの保存に使えそうなものを探してみます。ALPreferenceManagerモジュールの説明を見ると以下のように書いてあります。

>ALPreferenceManager allows managing the robot preferences.
Robot preferences are used to store, among other, all the settings for the applications running on the robot.

　ロボットアプリのデータの保存に使えそうですね。

　ですが、『ロボアプリ品質チェックリスト』のチェック項目005-004-001では

>PreferenceDBへの書き込みやPreferenceの使用がないこと

と書いてありAPIとしては存在しているものの、使ってはいけないと定義されています。

# チェックリストから探る
　ではどこに保存するべきなのでしょうか。
　チェック項目007-001-004には

>データ保存場所：アプリ内でデータ保存する場合はアプリフォルダ内(UUID配下)に保存していること※ソース上でもデータ格納先を確認すること

という記載がありました。
　アプリフォルダ内部に保存すれば良いようです。

UUID：ロボアプリのUUIDという意味だと思います。Application IDと同義と認識しています。

# アプリフォルダ内部のパスを考える
　ロボアプリがインストールされる位置は、Choregrapheから［▶︎］ボタンを押した場合と、パッケージでインストールされ実行される場合で異なります。

|インストール方法|**アプリフォルダ**のパス|
|:---|:---|
|Choregrapheから［▶︎］ボタン|`<Applications`>/.lastUploadedChoregrapheBehavior|
|パッケージでインストール|`<Applications`>/`<ApplicationID`>|

　違いを吸収するために、以下のように取得します。

```python:アプリフォルダのパスを求める
appFolder = self.behaviorAbsolutePath().replace(self.behaviorRelativePath(), "")
```

　ビヘイビアの完全パスから、ビヘイビアの相対パスを削り取った文字列がアプリがインストールされている位置です。これで、Choregrapheから［▶︎］ボタンでインストールされようがパッケージでインストールされようが、実行場面に応じて適切な場所を得られるようになりました。

　次にデータを保存するフォーマットを考えてみましょう。
　[ロボアプリ上でのデータ保存（2）](http://qiita.com/black_pepper/items/33485535175a424b58d9)に続きます。
TensorFlowでAM復調 その2

#概要
TensorFlowで、AM復調やってみた。
実際の信号でやってみた。
搬送波は、5000Hz

#AM信号
http://jsdo.it/ohisama1/C4km

#復調した音声
http://jsdo.it/ohisama1/YNJf

#環境

windows 7 sp1 64bit
anaconda3
tensorflow 1.0
Gist Clients 一覽表


Want to create a [Gist](http://gist.github.com/) from your editor, the command line, or the Services menu? 

**懶人包一覽表**

## Editor Support

* [Sublime Text 2/3](https://github.com/condemil/Gist)
* [TextMate](http://github.com/ivanvc/gists-tmbundle#readme)
* [Emacs](http://github.com/defunkt/gist.el#readme)
* [Vim](http://www.vim.org/scripts/script.php?script_id=2423)
* [Coda](http://github.com/kmorey/gist.codaplugin#readme)

## Command Line

* [gist](http://github.com/defunkt/gist#readme) (official)
* [gist.sh](http://github.com/gmarik/gist.sh#readme) (shell)
* [pygist](http://github.com/mattikus/pygist#readme) (python)
* [gistp](http://github.com/miyagawa/gistp#readme) (perl)

## OS X

* [Gist as a Service](https://github.com/fcurella/osx-gist-services)
* [Drift](http://github.com/atduskgreg/drift#readme)
* [Snippets Plugin](http://github.com/cimm/snippets-gist-scrippet#readme)

## Blog

* [Gist => Tumblr](http://github.com/eric/gistr#readme)
* [WordPress Plugin](http://github.com/paulwilliam/wordpress-github-gist-shortcode-plugin#readme)

## More

* [Gist Search on GitHub](http://github.com/search?q=gist&type=Repositories)
Python 3.6のemailライブラリ

(チラ裏品質)

3.6からemailパッケージの実装が大幅拡張され、関連してドキュメントも大幅に変わりました。秘密でもなんでもなくはっきりそう書いてあります

* https://docs.python.org/3.6/library/email.html
    * Changed in version 3.6: Docs reorganized and rewritten to promote the new EmailMessage/EmailPolicy API.
* https://docs.python.org/3.6/whatsnew/changelog.html
    * Python 3.6.0 beta 1 あたりのChange Logでprovisional抜け

以前からemailパッケージ自体は比較的良い感じです(に筆者は思います)が、ドキュメントは3.5までは古い内容がそのまま引き継がれていました。例えばRFCについて、obsoleteな方 (例えばRFC 5322じゃなくてRFC 2822) を差していたりしました (逆に言えばそれ以外はそんなに差はないはずなんですが、ドキュメント冒頭がそうなのでとかく気になる。RFC 5322だって2008年のものですよ)。3.6 のドキュメントは全体的に最新の事情を反映してます。

3.6はまだ新しい範疇に入るため主要Linuxディストロ等では標準で利用できません。概ねPython2系か、使えて3.4, 3.5という感じがします。さっと調べたところCentOS 7 (ただしepel)が3.4, Ubuntu 16.04が3.5でした。SUSEは分かりません (ｱｿﾋﾞﾀｲﾖｰ)。もちろん、pyenvやAnacondaの類に頼れば3.6系を使えます (あくまで2017年05月時点です)

旧Python3環境で開発時には3.6のドキュメントは読まずにバージョンを指定して読む方が良いです。当然一般的にそーなのですが、マイナーアップデートに関しては「バージョンxxから追加」とPythonドキュメントは親切に差分を書く傾向があるので筆者も手抜きがちです。

ただemailパッケージはほぼ「書き直した」状態ですのでより「気にする」必要があります。直にEmailMessage等のドキュメント ([たとえばこう](https://docs.python.org/3.6/library/email.message.html#email.message.EmailMessage))を見ると「ないじゃん」みたいなことになるかもしれません (同ページの冒頭に「New in 3.6」とありますが直でクラスに関するドキュメントを見ようとすると見落とす可能性が微レ存)。

Legacy APIと称される方が3.5以前のものです。3.5以前を使うなら、いっそ古いマニュアルに頼るのが当然の筋です。
[memo] nkfのコマンド

Kawatama.netさんの
「macでファイルの文字コードを変換する『nkfコマンド』の使い方とオプション一覧」
http://kawatama.net/others/mac/1754
の一部の切り貼りです。

自分用メモ

---

nkfコマンドの書式

```
$ nkf [options] [file] > [new_file]
```

【nkfコマンドの主なオプション】
-u：出力時にバッファリングを行わない
-j：JISコードに変換する
-e：EUCコードに変換する
-s：シフトJISコードに変換する
-w：UTF8コードに変換する
-r：ROT13/47の変換する
-T：テキスト・モードで出力する
file：変換元のファイルを指定する
new_file：変換先のファイル名を指定（必要な場合。不要なときは`>`以降不要）
-g：文字コード自動判別の結果を表示
–overwrite：引数のファイルに直接上書き
GitHub連携したJenkinsをサクッと構築したい

# 求めるJenkinsおじさん

* Jenkins >= 2.0

# 基盤

* AWS(使い慣れているので/ public ip あればなんでもいいです)

## AWS上の構成

EC2(publicにさらしたくない) + ELB(SSL終端させたい、ここでポート変換) の構成でいく。
ELBのSecurity Groupは自分家(自拠点)とGitHubのhookだけ許可する様に設定GitHubのIPは<https://api.github.com/meta>で調べて開けておく。

## Jenkins

サクッと作りたいのでdockerを使う。
> packageからinstallとかでもいいが、jenkinsのアップデートする時に面倒なのでdockerでold versionとnew versionの2つ立てて置いて切り替える時にポートだけ変更してアクセスするようにしたかった。(ALBのtarget groupとか使ってもいいけど面倒なので)

officialのdocker imageがある様なのでそこから作成する。

```
$ docker pull jenkins
$ docker run -p 8080:8080 -p 50000:50000 jenkins
```
8080がJenkinsのweb用のポートで、50000がslaveとの連携用のポート
> alpineベースのimageもある様でそちらを使用する場合は、`jenkins:alpine`

起動させる時にJekinsのhome directoryとか(jobなど)をhost側に出して置きたい場合は、

```
$ docker run -p 8080:8080 -p 50000:50000 -v /var/jenkins_home jenkins
```

起動する時にadminのパスワードが流れるのでそれをコピーしておく。

```
------省略------

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  <= これをコピー

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************
------省略------
```

ログイン後におすすめpluginのinstallが選択されているのでとりあえずinstall
> imageがでかくなるのが嫌な場合は個別でpluginをinstall。

Jenkinsの管理 >> Pluginの管理 >> 利用可能 から GitHub Pluginを選択してinstall

ここまできておもむろに<https://elb.endpoint/script>を開いて

```Groovy
Jenkins.instance.pluginManager.plugins.each{
  plugin ->
    println ("${plugin.getShortName()}:${plugin.getVersion()}")
}
```
を実行する。結果をコピって`plugins.txt`として保存する。

* あとで使いまーす。

## Job

とりあえず、Free Styleのprojectを作成して、

* General
  * GitHub project
    * Project url
* ソースコード管理
  * Git (通知だけしたい場合でもここを指定する必要あり)
    * リポジトリURL
    * 認証情報
* ビルド・トリガ
  * GitHub hook trigger for GITScm polling (旧: Build when a change is pushed to GitHub)

あとは好きに設定しておく。

## GitHub

Settings >> integration & services >> serviciesのadd services >> Jenkins (GitHub plugin)
を選択 
Jenkins hook url に<https://elb.endpoint/github-webhook/> (例にしたがって)
を入れてactivate。
> 上の方にtest用のボタンがあるのでそれを押すこともできるが実行されちゃうので気をつけましょう

### 連携

連携自体はこれで終わりです。

### 余談 Jenkins Update する時

/var/jenkins_homeにjobやconfigなどの情報があるので引き抜いて置きます。

```Dockerfile
FROM jenkins:alpine

VOLUME /var/jenkins_home
COPY plugins.txt /usr/share/jenkins/plugins.txt
USER root
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
USER jenkins
```
こんな感じして/var/jenkins_homeを新しいおじさんに食わせてあげるとサクッと新しいversionのjenkinsができちゃいます。(imageを移してもいいです。)
Bootstrapでテーブルを利用する方法

![テーブル.png](https://qiita-image-store.s3.amazonaws.com/0/160563/2e647c4c-1c23-b9a7-ed18-071b164c2cc1.png)


#基本的な記述方法

![table_basic.png](https://qiita-image-store.s3.amazonaws.com/0/160563/9cd94f62-9fca-f353-a273-b1eed8bf4fec.png)

* 基本的にはhtmlのtableを作成する記述と同じ
* 大枠のtableタグにクラスで"table"を指定

```html:qiita.rb
<table class="table">
    <thead>
        <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>1</th>
            <td>Hanako</td>
            <td>Qiita</td>
            <td>@Hanaq</td>
        </tr>
        <tr>
            <th>2</th>
            <td>Taro</td>
            <td>Qiita</td>
            <td>@TaroQ</td>
        </tr>
    </tbody>
</table>
```

#オプション
様々なクラスを付与することで、見た目・機能の装飾ができる

## デザイン
### ストライプ
![table_stripe.png](https://qiita-image-store.s3.amazonaws.com/0/160563/488f51a1-4cab-9312-ea50-cb96c49ca503.png)

* 偶数行の行だけ背景を灰色にする
* "table-striped"のクラスを付与

```html:qiita.rb
<table class="table table-striped">
    <!-- 基本記述と同じ -->
</table>
```

###ボーダー
![table_border.png](https://qiita-image-store.s3.amazonaws.com/0/160563/b8306b59-e088-b9a8-d5ef-2a252a1e4661.png)

* テーブルの枠組みに線をつける
* "table-bordered"のクラスを付与

```html:qiita.rb
<table class="table table-bordered">
    <!-- 基本記述と同じ -->
</table>
```

###マウスオーバー
![table_hover.png](https://qiita-image-store.s3.amazonaws.com/0/160563/d6327171-1eb3-4544-8b3a-f34d58dcb39c.png)

* テーブルにマウスオーバーした際に行全体の背景を灰色に変更する
* "table-hover"のクラスを付与

```html:qiita.rb
<table class="table table-hover">
    <!-- 基本記述と同じ -->
</table>
```

###行幅の短縮
![table_condense.png](https://qiita-image-store.s3.amazonaws.com/0/160563/5d5d3b00-935a-3df7-67df-1a8e9d50d8a1.png)

* テーブルの行の幅を狭める
* "table-condensed"のクラスを付与

```html:qiita.rb
<table class="table table-condensed">
    <!-- 基本記述と同じ -->
</table>
```

###背景色
![table_background.png](https://qiita-image-store.s3.amazonaws.com/0/160563/3f535323-3687-b9d9-6cae-bfbf0aead433.png)

* テーブルの行やセルに背景色を適用
* 背景色として適用したいクラスを付与

|色|使用クラス|
|:---|:---|
|灰色|active|
|緑|success|
|青|info|
|黄色|danger|
|赤|warning|

```html:qiita.rb
<table class="table">
    <thead>
        <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username</th>
        </tr>
    </thead>
    <tbody>
        <!-- 行全体を灰色に -->
        <tr class="active">
            <th>1</th>
            <td>Hanako</td>
            <td>Qiita</td>
            <td>@Hanaq</td>
        </tr>
        <tr>
            <!-- 各セル毎に背景色を変更 -->
            <th class="success">2</th>
            <td class="info">Taro</td>
            <td class="danger">Qiita</td>
            <td class="warning">@TaroQ</td>
        </tr>
    </tbody>
</table>
```

##レスポンシブ
![table_responsive.png](https://qiita-image-store.s3.amazonaws.com/0/160563/e301d4f9-2aa9-6685-912a-c681a165cdc6.png)

* テーブルの幅は固定で横幅が足りなくなった場合に、横スクロールさせる
* tableタグを"table-responsive"で包む

```html:qiita.rb
<div class="table-responsive">
　　<table class="table table-condensed">
    　　<!-- 基本記述と同じ -->
　　</table>
</div>
```

#参考

* [Bootstrap公式サイト](http://getbootstrap.com/css/#tables)
Dashに日本語翻訳機能を付ける

# 発端
ちょっとした調べ物の度にChromeのタブが増えていくのを憂いで先日[Dash](https://kapeli.com/dash)を導入したのですが、
英語のできない筆者にとって欠かせない[翻訳アドイン](https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb?hl=ja)的な機能がなかったので、作ってみました。

# 作り方
## Automator
- Spotlight > Automator > [こちら](http://nicomelmo.blog118.fc2.com/blog-entry-929.html)や[こちら](http://shellscript.sunone.me/filter_sed.html#行頭に文字を追加する)を参考にしつつ、以下のように設定して任意の名前で保存
- なお作成したワークフローファイルは以下にできる。わかりづらいぞ
    - /Users/ユーザ名/Library/Servicies/xxx.workflow

<img width="618" alt="automator.png" src="https://qiita-image-store.s3.amazonaws.com/0/106259/d444bd98-09ea-76bf-3d80-1378b2551035.png">

```bash:bash
cat | perl -MURI::Escape -lne 'print uri_escape($_)' | sed -e 's/^/https:\/\/translate.google.com\/?source=gtx_c#auto\/ja\//g'
```
## ショートカット
- Spotlight > ショートカット > サービスに先ほど作った機能が出てくるので、任意のショートカットを指定

<img width="780" alt="shortcut.png" src="https://qiita-image-store.s3.amazonaws.com/0/106259/8deeac35-f039-ff07-1d4e-ce13acb7e5c3.png">

## できあがり
- Dashにて翻訳したい文字を選択 > 右クリック > Servicies or ショートカットキーでポップアップが立ち上がる

<img width="611" alt="howto.png" src="https://qiita-image-store.s3.amazonaws.com/0/106259/e67bfc1c-4e47-dfac-b3c0-618f1ade6fe6.png">

<img width="399" alt="translate.png" src="https://qiita-image-store.s3.amazonaws.com/0/106259/403cc03f-d349-c699-9e95-5fdf39ed8795.png">

# 余談
- Automator初めて触ったんですが、入出力周りの作り(というか説明)が謎で若干詰まりました...
- 大した苦労もしていない割に、ポップアップの見た目がそれっぽくってウキウキです:ramen:
Cloud9上でRails 5.1+React.jsの環境構築手順

#はじめに

Cloud9上でRails5.1 + React.js環境構築の手順です。
基本コピペで行けます。

細かいことは抜きにして、とりあえず環境作りたい方対象です。

#前提条件
・Cloud9のアカウントあること
・Blankでworkspce作成済みであること

# Ruby 2.3.1 インストール
```
rvm install 2.3.1
``` 

#Rails5.1 インストール
```
gem install rails
```

#Bundlerインストール
```
gem install bundler
```

#Nodo.jsのインストール
```
nvm install v7.7.1
```

#npmでnode.jsのアップグレード
```
npm update -g npm
```

#Railsアプリケーション作成とディレクトリ移動
```
rails new webpacker-sample && cd webpacker-sample
```

#Gemfile修正
```ruby:webpacker-sample/Gemfile

gem 'webpacker', github: "rails/webpacker"
```

#bundle install
```
bundle install
```

#Yarnインストール
```
npm i -g yarn
```

#Webpackerインストール
```
rake webpacker:install
```

#コントローラ作成
```
rails g controller pages index
```

#application.html.erbに追記
```ruby:app/views/layouts/application.html.erb

<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

```

#Reactのインストール
```
rake webpacker:install:react
```

#application.jsに追記
```ruby:app/javascript/packs/application.js

require('./hello_react.jsx')
```

#ビルド
```
bin/webpack
```

#サーバー起動
```
rails s
```

#Webアクセス確認
Preview→Preview Running Applicationでブラウザ起動し、
以下ドメイン部を変更したパスでアクセス。

https://xxx.c9users.io/pages/index

Hello React!と表示されれば成功です！

#最後に
以下のファイルをいじることでReactの実装ができます。
ファイル修正後、「bin/webpack」のビルドを都度実行する必要があります。
（ビルドが面倒くさい場合は、下記参考を参照ください。）

/webpacker-sample/app/javascript/packs/hello_react.jsx
/webpacker-sample/app/views/pages/index.html.erb


#参考
以下を参考にしました。
http://qiita.com/yoshiokaCB/items/564ed0440f0428c0009a#%E8%BF%BD%E8%A8%98

おわり
unity5.6でメッセージ通知画面を作ってみる

#UnityでVRコンテンツ制作
##VRコンテンツでメッセージ通知を実現したい
![スクリーンショット 0029-05-23 17.07.14.png](https://qiita-image-store.s3.amazonaws.com/0/83409/19c9e16d-540c-a8e6-7484-3c02c60dd241.png)
(※イメージ)

VRを体験している人に、架空の設定でメッセージがきたことを通知するっていうのを実装したいと思ってます。

##準備
・VR再生ができるUnityプロジェクト
・通知アイコン用画像（↓）
![mail.png](https://qiita-image-store.s3.amazonaws.com/0/83409/5e3f3884-00e5-30f9-2c6e-94c270c89e4c.png)
画像はcubeに貼り付けています。

##実装
###配置
とりあえず、カメラを移動しても追従してほしいので、ポインターと同じ扱いの位置に配置します。
![スクリーンショット 0029-05-23 17.09.53.png](https://qiita-image-store.s3.amazonaws.com/0/83409/f0b9b364-5173-8ba9-cc7f-c987780118cf.png)
そして、軽く位置の調整をします。

###点滅させる
それっぽさを出すために点滅させます。

```c#
void Update () {
 if (cnt > 50 && cnt < 100) {
  Transform rb = GetComponent<Transform>();
  Debug.Log(rb.localScale.x);
  rb.transform.transform.localScale = new Vector3(0, 0, 0);
 } else if(cnt > 100){
  Transform rb = GetComponent<Transform>();
  Debug.Log(rb.localScale.x);
  rb.transform.transform.localScale = new Vector3(0.2484762f, -0.2484762f, 0.000002f);
  cnt = 0;
}
  cnt++;
}
```
このスクリプトを先ほどのmessage_iconにドラックします。
すると画面上で点滅すると思います。
###いまいち
しかし、これではAndroidで体験した時に、焦点が合わず「なんか上の方になんかある・・・」という形になってしまい、非常にいまいちでした。
###空間の一部に配置する
やはり、空間上にメールアイコンを配置することにしました。先ほどのmessage_iconをこのように配置します。そして、名前をmessage_boardに変更します。
![スクリーンショット 0029-05-31 1.42.12.png](https://qiita-image-store.s3.amazonaws.com/0/83409/916fcf9b-22f6-5f69-274c-d58608e50414.png)
###イベント処理
メールにフォーカスが当たったらメッセージを表示するようにします。
メッセージ![message_body.png](https://qiita-image-store.s3.amazonaws.com/0/83409/ce9bfb3b-0b9e-5781-3293-96d550eabdc5.png)
このメッセージも同じように空間に配置します。

```c#
GameObject message;
public void MoveBoxUp(){
  transform.localScale = new Vector3 (1,1,0.000001f);
  message = GameObject.Find("message_body");
  message.transform.localScale = new Vector3 (1,1,0.000001f);
}
public void MessageDelete(){
  message = GameObject.Find("message_body");
  message.transform.localScale = new Vector3 (0,1,0.000001f);
}
```
changeColorにこのようなメソッドを定義します。

そして、message_boardにこのようにイベントをつけます。
![スクリーンショット 0029-05-31 1.43.17.png](https://qiita-image-store.s3.amazonaws.com/0/83409/2de41979-da42-f3d9-017b-c1fb290dbac5.png)

最後に、message_bodyの方をこのように設定すれば完了です。
![スクリーンショット 0029-05-31 1.51.01.png](https://qiita-image-store.s3.amazonaws.com/0/83409/ec1b0a3c-fcd5-f4b6-fb93-35c9a6fc43d4.png)
用 Android Studio 3 Canary 1和 2 新增 Activity 後發生的錯誤 - Error:Execution failed for task ':app:generateDebugInstantRunAppInfo'. > Cannot find main merged manifest.

當新增 Acitivity 後，會變得沒有辦法 build ，
接著就會有像以下的錯誤訊息：

> Error:Execution failed for task ':app:generateDebugInstantRunAppInfo'.
> Cannot find main merged manifest.

可能是測試版本的問題（？）

這時候只要從最上面的 Build > Clean Project 就可以解決了

（謎之音：怎麼覺得好像想到 Xcode ，碰到怪怪的反應就先按 Clean 再說）
RxSwiftでクロージャを減らす: APIリクエストのcompletionHandlerをObservableにしてみる

RxSwiftを適用する箇所として、クロージャをObservableに切り替えるのが最近良いなと思ったので掲載。

APIクライアントからレスポンスを受けてUIを更新する操作はクロージャを使いますがこれをObservableを使って書き換えてみました。

## Before

```swift
import UIKit

class ViewController: UIViewController {
	private var label: UILabel!

	override func viewDidLoad() {
		super.viewDidLoad()

		label = UILabel(frame: view.frame)
		label.numberOfLines = 10

		fetch(completion: { [weak self] data in
			guard let strongSelf = self else { return }
			strongSelf.label.text = String(data: data, encoding: .ascii)
			strongSelf.view.addSubview(strongSelf.label)
		})
	}

	private func fetch(completion: @escaping ((Data) -> Void)) {
		let request = URLRequest(url: URL(string: "https://www.google.com")!)
		URLSession.shared.dataTask(with: request, completionHandler: { data, _, error in
			guard
				error == nil,
				let data = data
			else { return }
			completion(data)
		}).resume()
	}
}
```

## After

```swift
import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
	private var label: UILabel!
	private let disposeBag = DisposeBag()

	enum MyError: Error {
		case APIClientFailed
	}

	override func viewDidLoad() {
		super.viewDidLoad()

		label = UILabel(frame: view.frame)
		label.numberOfLines = 10

		fetch().asObservable().subscribe(onNext: { [weak self] data in
			guard let strongSelf = self else { return }
			strongSelf.label.text = String(data: data, encoding: .ascii)
			strongSelf.view.addSubview(strongSelf.label)
		}).disposed(by: disposeBag)
	}

	private func fetch() -> Observable<Data> {
		return Observable<Data>.create { observer in
			let request = URLRequest(url: URL(string: "https://www.google.com")!)
			URLSession.shared.dataTask(with: request, completionHandler: { data, _, error in
				guard
					error == nil,
					let data = data
				else { return observer.on(.error(MyError.APIClientFailed)) }
				observer.on(.next(data))
				observer.on(.completed)
			}).resume()

			return Disposables.create()
		}
	}
}
```

こういう風に作っておくと、一度に2つ以上のエンドポイントにリクエストを送ってその内容をマージしたくなったり、リクエスト前後にバリデーションが必要になったりしたときにRxSwiftの能力を発揮して複雑性を増やさずにコードを書ける気がしています。
Unit Type

在邊練習 Kotlin 的時候，看方法定義看到了一個型別

```
Unit
```

八竿子打不著的無法猜出那是什麼東西，查了一下就把它筆記下來。

官方文件是這樣寫的：

> The type with only one value: the Unit object. This type corresponds to the `void` type in Java.
> - [cf: Unit](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/)

:bulb: :bulb: :bulb: :smirk: 

所以他其實就是 void

如果有個回傳值，或是 block 的定義是寫 `-> Unit` 的話，就是可以不用回傳的意思 :white_flower:
AmazonSNSのSMS送信をLaravelでやってみた

基盤にAWSを使っているところでSMS送信をしなきゃいけなくなったのでやってみました。
AmazonSNS自体初でめちゃめちゃ時間かかったんですが、実装自体はすごく楽でした。。

# 前提

Laravel5.4

# やってみる

1. AWS SDKのサービスプロバイダーを仕込む
    やっぱりありますね。
    https://github.com/aws/aws-sdk-php-laravel

    インストールは[README](https://github.com/aws/aws-sdk-php-laravel#installation)通りにやれば大丈夫なので割愛します。

    私が一番悩んだのはアクセスキーとシークレットアクセスキーって何？！ってところでした笑
    そもそもAWSもコンソールに入ってからGUIでちょこちょこと作業することはあったんですが、細かいこと全然わかってなかったもので。。

2. 実装する

    今回はPoC的なところだけ私の担当で、本実装は他の人だったので、コンソールコマンドで実装しました。

    ```php:Console/Commands/SendSms.php
    namespace App\Console\Commands;

    use Illuminate\Console\Command;
    use AWS;

    class SendSms extends Command
    {
        /**
         * The name and signature of the console command.
         *
         * @var string
         */
        protected $signature = 'command:send:sms';

        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'Send SMS';

        /**
         * Execute the console command.
         *
         * @return mixed
         */
        public function handle()
        {
            $sms = AWS::createClient('Sns');
            // 細かい設定はpublishする前にsetSMSAttributesで設定する
            // $sms->setSMSAttributes([
            //     'DefaultSMSType' => 'Transactional',
            //     ...
            //     ..
            //     .
            // ]);
            $sms->publish([
                'Message' => 'send sms test',
                'PhoneNumber' => '+819000001234'
            ]);
        }
    }
    ```

    一番注意しなければいけなのは `SMSClient`　ではなく `SNSClient` を使うってとこですね笑
    最初aws-sdkのサンプルでS3Client使ってるのをみて勝手に `SMSClient` 使おうって思ったんですが、中身が何もなく、他の方から `そのSMS、ショートメッセージサービスじゃなくてAWS Server Migration Serviceじゃん` とご指摘を頂きようやく気付きました。。。:sweat_smile:

    [ここ](http://docs.aws.amazon.com/ja_jp/sns/latest/dg/sms_publish-to-phone.html#sms_publish_sdk)にJavaのサンプルがあって、ちゃんと `SNSClient`　使ってるのにちゃんと見なかった私が悪かったです。。。

    なかなかドキュメントの場所がわからなかったんですが、[ここ](http://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sns-2010-03-31.html)にあります。


3. 確認する
    CLIから `php artisan command:send:sms` を実行したら無事PhoneNumberにある電話番号にSMSが送信されました！

# さいごに

`まずはしっかりドキュメント読め` ってのは重々承知してたつもりなのに思い込みで突っ走ったのがいけなかったです。。
ただ、SMSClientって名前はちょっとなぁ。。。(言い訳)
Herokuにcloudcmdを入れてブラウザのみでHerokuアプリを作成する[heroku2heroku]

#はじめに
Herokuの無料枠で遊んでいます。
いつでもどこでもHerokuのアプリを開発・リリースするためにCloudcmdを使ったHerokuのデプロイ用のアプリを作成しました。
ブラウザだけでHerokuアプリの開発・リリースを行いたいという願望からスタートし、本アプリ自体もブラウザのみで作成できました。

セキュリティはcloudcmdの機能であるBasic認証のみのため、個人の責任においてご活用ください。

#使った技術
[cloudcmd](https://github.com/coderaiser/cloudcmd)
ほぼ毎日更新されているWebブラウザ用のファイラ＆ターミナルアプリ

#やり方
Herokuの「Deploy to Heroku」ボタンから本アプリ（heroku2heroku）をデプロイし、そこから任意のHerokuアプリを作成する。

##１．GitからHerokuアプリを作成する。
Herokuのアカウントを作成して以下のボタンからアプリを作成
[DeployURL]:                https://heroku.com/deploy?template=https://github.com/ranran9/heroku2heroku "Deploy"
[DeployIMG]:                https://www.herokucdn.com/deploy/button.png
[![Deploy][DeployIMG]][DeployURL]

(参照元リポジトリ)
https://github.com/ranran9/heroku2heroku
 
##２．アプリのデプロイ設定
お好きなアプリ名（App Name ）を設定し、
認証用のユーザID（CLOUDCMD_USER_ID）とパスワード（CLOUDCMD_PASS）は初期値から変更してください。

##3．アプリを開く
初回認証要求されるため、先ほど設定したユーザとパスワードでログインする。
cloudcmdが起動するので、ターミナルを起動
![image](https://qiita-image-store.s3.amazonaws.com/0/81968/b0a5bf04-b56f-2bec-10d0-5cd2cf11de3e.png)

##4.Herokuコマンドを使ってアプリを作成〜デプロイ
**Herokuの無料枠の場合、アプリが３０分程度でクリアされます。
変更内容を保存したい場合は、ローカルや他のクラウドストレージに保存する等の処理を行ってください。**
Herokuコマンドはパスを通しているので、メールアドレスとパスワードでログインすることですぐ使えます。
Herokuアプリでは/appと/var/tmpフォルダしか書き込み権限がないため、どちらかのフォルダに作業ディレクトリを作成して開発してください。
![image](https://qiita-image-store.s3.amazonaws.com/0/81968/5629695b-e213-a60b-bc08-e8a3ef76fdb8.png)

#便利な設定
##初期認証
URLを知っていれば誰でもアクセス可能なため、最低限のBasic認証を設定できます。

| キー名 | 値（初期値） |
|:------:|:------:|
| CLOUDCMD_AUTH | Basic認証を設定するか(true) |
| CLOUDCMD_USER_ID | Basic認証のユーザ名(root) |
| CLOUDCMD_PASS | Basic認証のパスワード(toor) |

##Gitの設定
毎回Gitのグローバル設定を行うのは面倒くさいので、環境変数に設定可能。

| キー名 | 値（初期値） |
|------|------|
| GIT_AUTHOR_NAME |GITの作成者名(なし)  |
| GIT_COMMITTER_NAME |GITのコミッター名(なし)  |
| EMAIL | GITのメールアドレス(なし) |

##.netrcの設定
毎回Git認証やHeroku認証を行うのは（略・・）
.netrcにそのまま設定が書き込まれます。
とりあえず３セット設定できます。
  
例：githubの場合
githubの認証トークンはGithubの[プロファイル](https://github.com/settings/developers)の「OAuth applications」から発行されたトークンです。

| KEY | VALUE |
| ------ | ------ |
| NETRC_MACHINE_1 | github.com(なし) |
| NETRC_LOGIN_1 | githubのメールアドレス() |
| NETRC_PASSWORD_1 | githubの認証トークン() |

例：git.heroku.comの場合
herokuの認証トークンはHerokuコマンドの「heroku auth:token」から発行されたトークンです。

| KEY | VALUE |
| ------ | ------ |
| NETRC_MACHINE_2 | git.heroku.com(なし) |
| NETRC_LOGIN_2 | herokuのメールアドレス() |
| NETRC_PASSWORD_2 | herokuの認証トークン() 

例：api.heroku.comの場合
herokuの認証トークンはHerokuコマンドの「heroku auth:token」から発行されたトークンです。

| KEY | VALUE |
| ------ | ------ |
| NETRC_MACHINE_3 | api.heroku.com(なし) |
| NETRC_LOGIN_3 | herokuのメールアドレス() |
| NETRC_PASSWORD_3 | herokuの認証トークン() 

#アプリの説明
cloudcmdにherokuコマンドと設定追加したくらいなので特になし。
SQL SELECT基礎(3) その場で表を作る

この記事は「SQL SELECT基礎」の第3回目です。
[SQL SELECT基礎 目次](http://qiita.com/Hiraku/items/67cf329f1ddb897b1436)
←前の記事は[SQL SELECT基礎(2) スカラ値いろいろ](http://qiita.com/Hiraku/items/2bf26e8cdf117a7f81e8)
→次の記事は[SQL SELECT基礎(4-1) 列を減らす (project 射影)](http://qiita.com/Hiraku/items/abc592d2b19b671669b1)

第一回で表の話をして、第二回で表の構成要素であるスカラについて解説しました。
やっと具体的な表の話になります。

※以下がわかってたらこの章は飛ばしてOK

```sql
-- このSELECT文の出力結果を説明して下さい。もちろん暗算で。
SELECT * FROM (SELECT * FROM (SELECT "Hello world") AS h1) AS h2
```


## その場で表を作る

SELECT文は、既にある表を加工してその場で別の表を作っていく構文です。

### SELECT文だけで表を作る

あまり使いみちはないのですが、SELECT文だけで即興の表を作ることができます。
前回、文字列の説明をするためにこんなSQL文を書きましたよね。

```sql
SELECT "Hello, world!"
```

実はこれ、1x1の表をその場で作っているのです。
カンマ「,」を挟んで複数の値を並べると、Nx1(横に長い)表になります。何個でも並べることができます。

```sql
SELECT 1,2,3,4
```

<img width="148" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/1126/b8b8fc00-baf4-d34f-4e7a-c3bc3a733fcf.png">

`UNION ALL`という構文を使うと、複数の横長の表をくっつけていくことができます。

```sql
SELECT 1,2,3,4
UNION ALL
SELECT 2,4,6,8
UNION ALL
SELECT 3,6,9,12
```

<img width="150" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/1126/6260b503-bc35-6a9c-57fc-b6c6a318b354.png">

横4 x 縦3の表が作れました。簡単ですね。

`AS`という構文を使うと、列に名前をつけることができます。UNIONで作っている場合は2行目以降は無視されるので、つけても付けなくても構いません。

```sql
SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d
UNION ALL
SELECT 2,4,6,8
UNION ALL
SELECT 3,6,9,12
```

<img width="153" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/1126/e0fda65f-6743-8855-ca78-dfa3a9022e3d.png">

この講座では、例を表現するためにこの記法を多用します。

### 既に存在するテーブルから復元する

その場で表を作れても、あまり役には立ちません。
普通はデータベースに既に存在するテーブルから復元するものです。そのときに使うのが`FROM`句です。

例えば`users`というテーブルがあったとすると、

```sql
SELECT * FROM users
```

とすればusersテーブルの中身を全部取ってくる意味になります。`users`はダブルクォーテーションでくくっていないことに注意して下さい。テーブル名は文字列ではないので、直接書くことができます。

SELECTの後ろが突然`*`となっています。テーブルには既に決まった構造があるため、`*`と書くと、自動的にテーブルの全列を取ってきて出力する意味になります。

次回の「projection」の章で詳しく説明します。

### FROMに書けるもの

FROMの後ろにはテーブル名の他に、他のSELECT文も入れ子にして書くことができます。
MySQLの場合、SELECT文の結果にもAS構文で別名を付けることができますが、FROM句に書く場合は別名をつけることが必須になっています。

```sql
SELECT * FROM (
    SELECT "Hello world"
) AS h1
```

入れ子を更に入れ子にすることも可能なので、こんな風にすることもできます。

```sql
SELECT * FROM (
    SELECT * FROM (
        SELECT "Hello world"
    ) AS h1
) AS h2
```

この例だと何も加工を施していないので、入れ子には全く意味が無いのですが、よく使いますので「この書き方が可能である」ことは覚えておきましょう。

他のプログラミング言語の素養がある方はびっくりするかもしれませんが、SELECT文には変数という概念はありません。
書きづらいと思ったらSELECT文を多段の入れ子にすることで、ちょっと読みやすくすることができます。

----

[SQL SELECT基礎 目次](http://qiita.com/Hiraku/items/67cf329f1ddb897b1436)
←前の記事は[SQL SELECT基礎(2) スカラ値いろいろ](http://qiita.com/Hiraku/items/2bf26e8cdf117a7f81e8)
→次の記事は[SQL SELECT基礎(4-1) 列を減らす (project 射影)](http://qiita.com/Hiraku/items/abc592d2b19b671669b1)
モブプログラミングを体験してきました #devkan

2017/05/29 [DevLOVE関西](https://devlove-kansai.doorkeeper.jp/events/60216) に参加してモブプログラミングを体験してきました。体験してみての感想などを簡単に書いていきます。なお、今回は東京から[@PoohSunny](https://twitter.com/PoohSunny)さんが駆けつけてくれ、モブプログラミングの説明と進行をしてくれました。

# モブプログラミングとは？
全員が同じ時間に同じ場所で同じPCでコードを書く、ペアプロのチーム全員バージョンと考えれば良いとのことです。

# どんな風にやったか？
1テーブル開発者5～7名に別れて2チームで実施しました。今回プロダクトオーナーはどちらのチームにも参加しませんでしたが、通常は開発者に加えてプロダクトオーナーも参加してモブプロを行うとのことでした。ドライバーとナビゲーターに関しては、以下の運用で進めていきました。

* ドライバーは7分で交代
* ドライバー以外は全員ナビゲーター
* ドライバーはナビゲーターの指示通りにコードを書く

その他に実装するにあたり

* 要件はプロダクトオーナーが1つずつ出す
* TDDで実装する

の２つの制約をかけて実施しました。今回は2.5時間という時間制約があったので、設計の合意にかかる時間を減らすためにこのようにされているとのことでした。
なお、モブプロをする時は、[Mobster](https://github.com/dillonkearns/mobster)というツールが便利とのことです。

# できたもの
第一部と第二部に分かれて、「ローマ数字の計算」と「自動販売機」を実装しました。どちらのお題でも、途中「とりあえずテストを通す」ための実装に取り付かれ、保守性の低いコードになってしまいました。
あと、「自動販売機」のお題で、プロダクトオーナーからの要望は最低限満たしているものの、コーラの在庫は減るけれど、ビールの在庫は減らない、のような不思議な仕様となり、PoohSunnyさんからは、「当たり前品質とかあるじゃん」と突っ込まれました。

# 実装中に言われたこと＆全体のふりかえりで出た意見
実装中や最後のふりかえり、帰宅間際の会話を通して以下のような意見が出ました。

## 「わからない」ということも意思表示をすると良い
実装中にチーム全体で黙ってしまい、ドライバーが困ってしまう場面があったのですが、
その際に、黙るのではなく「わからない」ということを伝えるのが大事とのお話がありました。
モブプロのエバンジェリストのWoodyさんのチームでは、わからない時は両手を挙げてわからないという意思表示をするとのことです。みんながわからないということがわかれば、そこは飛ばして次に行こうかという選択もできるようになるとのことでした。

## 設計をせずにやったため、保守性の低いコードになってしまった
今回はなかったのですが、普段はホワイトボードも用意して議論しながらやるようです。そして、実装前の設計は、TDDだろうが、モブプロだろうが、ちゃんとやろうねということでまとまりました。
  
## 時間を気にしながら実装したので焦ってしまった
7分だとちょっと焦るし、10分だとちょっと間延びするようです。では、何分がいい？というのは、まだ見えていないとのこと。この辺りは、チームで話し合いながら自分達に合った時間を見つけていくのが大事かなと思います。

## みんなで合意できたつもりができていない時もありそう
周りとのレベル差があり、自分だけがわかっていないような状況だと聞きづらい、というような意見もありました。これだと、みんなで合意したつもりでも実はわかっていない人がいて危ないねという話が出ました。

他にも

* たくさんの考えややり方が見れて勉強になる
* 疲れる
* 人数は5, 6人位がちょうど良さそう
* チームビルディングに使えそうだが、心理的安全がないため、危険な面もある
* チーム全体でコードが育っていったプロセスを共有できる

といった意見がありました。

# 所感
個人的に一番避けたいのは、「みんなで合意できたつもりができていない」だと感じました。
ペアプロだと、1対1のやりとりのため、わからないことがあった時は比較的聞きやすいのですが、モブプロで自分だけがわからないのかも、という時は声を挙げにくいのかなと思いました。そういったことを避けるためにも、まずはチームとして意見を言い合える環境（心理的安全な状態）を作ることが大切かなと思いました。それができると、「多くの考えが集まる」、「みんなでプロセスを共有できる」といった良さが活きてくるので、「難しいところを設計・実装する」場面や「チーム全体で知識を共有したい」場面に使えそうだなと感じました。
AWSのEC2(Ubuntu Server 16.04 LTS)にログインできない

#メモ
AWSにubuntuのサーバー立ててログインしようと思ったけどできなかったときのメモ
なんで？

##結論
**userが違う**
**Amazon Linuxだとec2-userでいいけど、ubuntuはubuntu**
ただのアホ。。

誤）
<pre>ssh -i ~/.ssh/key-xxxx.pem ec2-user@xx.xx.xx.xx
Permission denied (publickey).
</pre>

正）
<pre>ssh -i ~/.ssh/key-xxxx.pem ubuntu@xx.xx.xx.xx
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-1013-aws x86_64)
</pre>
windowsPCにWordPressをインストールする

環境
----------------
- xampp環境設定済み
- windows10

ダウンロード
----------------
以下のサイトから最新版のWordPressをダウンロードする(2017/5/31時点では4.7.5)
https://ja.wordpress.org/

設置
-----------------

- 「http://localhost/wordpress/」 で動くようにしたいので xampp/htdocs/ にダウンロードしたwordpressを設置

インストール
-----------------

- ブラウザから「 http://localhost/wordpress/ 」を開くと以下のような画面が表示される
![rapture_20170530235931.png](https://qiita-image-store.s3.amazonaws.com/0/184311/3715ae81-02fb-5342-fb9a-3d4edf9ed6d2.png)

- 「さあ、はじめましょう！」ボタンをクリック
- 画面支持に従い**データベース接続のための詳細を入力**する(自分のxamppのmysqlの設定)

![rapture_20170531000126.png](https://qiita-image-store.s3.amazonaws.com/0/184311/4e44424c-55af-eb7c-86f4-1ba9c75fd03e.png)


- DBを作成していない場合は、phpMyAdminでDBを事前に作る必要がある

- 「インストール実行」をクリック
- 　wordpressの設定を済ませて「wordpressをインストール」をクリック
- 　インストール完了


確認
-----------------
ホームページ： http://localhost/wordpress/
管理画面： http://localhost/wordpress/wp-login.php
一列でチェックボックスを表示する

# 目的
- 以下のように横一列に表示されるチェックボックスを設置する
- チェックボックスの項目はcontrollerから表示し、ベタで書かない

# 手順
## チェックボックスの項目をControllerに定義する

```java:Controller
@ModelAttribute("sortOptions")
	public List<String> sortChecboxList() {
		List<String> list = new ArrayList<String>();
		list.add("案件区分");
		list.add("金額");
		list.add("リース会社名");
		list.add("検収");
		list.add("入金");
		list.add("ステータス");
		return list;
	}
```

- ModelAttributeを指定し、リクエスト時に***sortOptions***と定義されたリストオブジェクトをリクエストスコープへ登録する

- mapなどを使った方が、区分値をcontrollerを渡せるためいいと思われる、後日追記する

## チェックボックスの入力値を受け取るフォームのフィールド
```java:Form
	private String[] checkedBox;
```
- チェックボックスからの値は、配列で戻されてくるため、配列でfieldを用意する


## テンプレート上での定義
```html:template
<div class="checkbox-inline" th:each="sort : ${sortOptions}">
	<label> <input type="checkbox" name="fchecks" th:value="${sort}" th:text="${sort}" th:field="*{checkedBox}">checkbox</input>
	</label>
</div>
```
### 値の受け渡し
- ***th:each***でリクエストスコープから先ほどコントローラで***ModelAttribute***で登録した表示項目を取得し、sort変数へリストをループしながら渡す
- th:textへsort変数を渡すと、そのループ時の内容が表示される
- チェックをクリックした時の値をコントローラへ渡すには、formクラスで定義したフィールド名を***th:field***属性に渡す __th:field="*{checkedBox}"__
- これにより、チェックされた値が、checkedBox変数へ配列で格納された状態でcontrollerへ受け渡される

### 横一列に並べる
- 項目ごとに改行される通常のチェックボックスの定義は以下であるが、

```html:template
<div class="checkbox" th:each="sort : ${sortOptions}">
```

- class属性に -inline オプションを以下のように追加する

```html:template
<div class="checkbox-inline" th:each="sort : ${sortOptions}">
```
AWS Lambda + Serverless Framework + Slackで作るカスタマイズ可能なfeedリーダー その1

## 概要

AWS Lambda + Serverless Framework + Slackを使ってカスタマイズ出来るfeedリーダーを作ろうという記事のその1です。
（最初は一つの記事で完結させようとしていたのですがやることが多すぎました...なお続編があるかどうかは不明）

こんなの作ったよ系の記事なので、ツールとかフレームワークの説明は少なめかも。

feedの例:
<img width="576" alt="slack.png" src="https://qiita-image-store.s3.amazonaws.com/0/15832/707d97f0-2719-3d63-c9cb-1c16b20acf04.png">

## そもそもfeedリーダーを作ろうと思った動機
実はfeedの機能自体はSlackにあって、各チャンネルで

```
/feed subscribe https://hoge/feed 
```

のように打つとそのチャンネルに定期的にフィードの記事が流れてきます。ただ

- 一つ一つの記事のdescriptionがとても長い
- feedによっては大きいサイズの画像が表示される

などの理由から、流れてくる記事をカスタマイズしたいなーという思いから作り始めました。

## Serverless Frameworkの説明

Serverless Frameworkは、AWS Lambdaなどの、関数単位で提供されているサービスの環境準備やデプロイ、パッケージング、バージョン管理、ローカルでのデバッグなどをやってくれるフレームワーク・ツールです。
3か4つぐらいのコマンドさえ覚えておけばなんとかなるので、非常に使いやすいです。
詳しくは以下の記事が分かりやすいかと思います。

- http://qiita.com/hiroshik1985/items/6d979ff1afb56953b62e
- http://dev.classmethod.jp/cloud/aws/easy-deploy-of-lambda-with-serverless-framework/

具体的なデプロイのコマンドなどは後述の[https://github.com/yudetamago/my_rss_to_slack_service](https://github.com/yudetamago/my_rss_to_slack_service)
を参照のこと。

## 今回の記事で出来たもの

とりあえず

- Serverless Frameworkを使ったデプロイ
- デプロイした関数をデバッグ実行するとfeed(今のところRSSのみ)を取ってきてSlackのwebhookに送信する

という最低限feedの内容をSlackに引っ張ってこれるところまで出来ました。
コードではサンプルとして[Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/)のfeedを取ってきています。

## コードの仕組み・説明
出来たもの
[https://github.com/yudetamago/my_rss_to_slack_service](https://github.com/yudetamago/my_rss_to_slack_service)

全体としてはfeedをHTTP GETで取ってきて、Slack通知用に変換して送信しているだけだったりします。
（今回は最低限のところしか作っていないので、自分で関数を呼び出してfeed内容を取得してくるだけです。。）

### Lambda Functionの機能自体に関連する部分
まず `serverless.yml` で指定した `feedToSlack` という関数を `handler.js` の `module.exports` で定義します。そして後述するfeedの処理を終えてレスポンスを返すときには、引数の `callback`にレスポンス内容を入れて `callback(null, response)` のように呼び出すとLambdaの処理は終了します。

### feedの処理
今回は[feedParser](https://github.com/danmactough/node-feedparser)というライブラリを使っていて、リクエストをそのまま `pipe` でパーサーのほうに流しています。記事を読み込むと `parser.on('readable')` のコールバック関数が呼ばれるので、そこで読み込んだ記事を `items` に入れたあと、slackの[attachments](https://api.slack.com/docs/message-attachments)に入れています。

## これからやること/やりたいこと
- descriptionにHTMLタグが入っているときの処理
    - 現状ではタグがそのままplain textで表示されるので、どうしようかな...という気持ち。
- RSSやAtomなどフィードの種類に依存しないようにする
    - `item["rss:description"]["#"]` が依存している部分だけれど、これは正直頑張るしかない。
- 同じitemが2回以上送られないよう重複管理
    - これだけはステートフルになってしまうので、何らかの方法で楽したい...
- 定期的にフィードを取ってくるようにする
    - LambdaのSchedule機能使えば出来そう。
    - ref. https://serverless.com/framework/docs/providers/aws/events/schedule/
- 複数のフィードに対応する
    - 1つのLambda Functionで並列にHTTP GETする(そもそも出来るの？)か、フィードごとにLambda Function作るかみたいなところから検討する感じ。

## まとめ

とりあえず最低限のところまでは出来たので、気力があれば続き作ります！
AWSでprivate subnetからのインターネットサービスを利用する方法について

# 何
- AWSでprivate subnetからのインターネットサービスを利用する方法について、簡単に列挙する。

## 前提
- private subnet(インターネットゲートェイへのルート定義を持たないサブネット)は、内部からインターネットに接続できない。
- そのため、そのままでは、S3やDynamoDbを使うことができない。ヤフーやグーグルも見れない。

## 改善するために方法が３つある。

### NATインスタンス
- メリット：EC2インスタンスを立てるため、柔軟な構成を取れる。
- デメリット：フェイルオーバーを自分で考慮しないといけない。

### NATゲートウェイ
- メリット：管理が楽。
- デメリット：マネージドサービスのため、柔軟な構成が取れない。

### VPCエンドポイント
- メリット：インターネット、NAT デバイス、VPN 接続、または AWS Direct Connect を経由せずに、VPC と他の AWS サービスとをプライベートに接続できる。
- デメリット：S3のみ！DynamoDbがパブリックプレビューに(2017/4/19)

## その他
- SQS,SES,SNSなどのサービスもprivate subnetからだと使えない？使える？　要調査。
- 料金的な比較もしたいが、嘘つきそうなので省略。
- 疑問）セキュリティグループで外部からのアクセスを制限だけなのと、VPCサブネットを別にしてルート定義を分けるのと、どれくらいセキュリティ効果が違うものなのか？
ペースト実行時にそのペーストされた値を取得したい


実をいうとJavaScriptは苦手なのですが、しかしそうはいっていられないのがシステムエンジニア稼業。苦手不得意未経験関係なく、どんな無茶ぶりにもこたえねばならならない悲しみ(´・ω・｀)

それはさておき、業務において「__ペーストが実行されたとき、そのペーストされた値をJavaScript上で制御したい__」ということがありました。JavaScript苦手勢なわたしはたいへん苦労したので、後学のためにもサンプルコードを記事にしておきたいと思います。

```html:paste.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>after paste event test</title>
</head>

<body>
    <form>
        <input type="text" id="test" />
    </form>
</body>

<script>
window.onload = function() {
    var element = document.getElementById("test");
    element.addEventListener("paste", function(event){
        setTimeout(function(e){
            window.alert(e.target.value);
        }, 100, event);
    });
}
</script>
</html>
```

これを実際に実行してみると、テキストボックスに対してペーストを行った瞬間にテキストボックスの内容=ペーストした内容がポップアップされることがわかります。

![paste.jpg](https://qiita-image-store.s3.amazonaws.com/0/105859/1a03d812-f6cc-f1e4-2772-8f80598b525f.jpeg)

さてここに示されたサンプルにおいてもっとも重要な部分が次のjavascriptのソースコードです。

```js
element.addEventListener("paste", function(event){
    setTimeout(function(e){
        window.alert(e.target.value);
    }, 100, event);
});
```

`paste`イベントが発火するのは意外にも「ペーストされる直前」。よって「ペーストされた後」の状態を取得したいという場合には`setTimeout`を利用して、実際的な処理の実行を「ペースト直後」にまで遅らせてやる必要があるということですね(´・ω・｀)
ebiten でフィールドの生成

[前回](http://qiita.com/zenwerk/items/eb6228ea6729890b7394)の続き。
プレイヤーが移動するフィールドをハードコードしていましたが、より効率的に生成することにします。

## フィールドの生成
簡易的に文字列からフィールドを生成します。[go-inovationの方法](https://github.com/hajimehoshi/go-inovation/blob/master/ino/fielddata.go)を参考にしています。

## ソースコード
- 全体の差分は以下
	- https://github.com/zenwerk/go-pixelman3/commit/9c550a3b11d06b02513bdca9fa8ae23486d961e0

- field/field_data.go

```go
package field

const Field_data_1 = `+                                        +
+                                        +
+                                        +
+               ++++++++++++++           +
+        +                               +
+          + ++                          +
+      +                     +  +++++    +
+       +                 +              +
+           +++++++++                    +
+      +++              +                +
+                                        +
+   ++                                   +
+           P                            +
++++++++++++++++++++++++++++++++++++++++++
`
```


- field/field.go

```go
package field

import (
	"strings"

	"github.com/hajimehoshi/ebiten"

	"github.com/zenwerk/go-pixelman3/sprite"
)

const (
	width  = 17
	height = 17

	blockMark  = "+"
	playerMark = "P"
)

type Field struct {
	Player  *sprite.Player
	Sprites []sprite.Sprite
}

func NewField(fieldData string) *Field {
	field := new(Field)

	for indexY, line := range strings.Split(fieldData, "\n") {
		for indexX, str := range line {
			switch string(str) {
			case blockMark:
				block := sprite.NewBlock()
				block.Position.X = indexX * width
				block.Position.Y = indexY * height
				field.Sprites = append(field.Sprites, block)
			case playerMark:
				player := sprite.NewPlayer()
				player.Position.X = indexX * width
				player.Position.Y = indexY * height
				field.Player = player
			}
		}
	}

	return field
}

func (f *Field) DrawImage(screen *ebiten.Image, viewport sprite.Position) {
	for _, sprite := range f.Sprites {
		sprite.DrawImage(screen, viewport)
	}
}
```

`field_data.go` で定義されている文字列がフィールドの生成元です。
`field.go` の `NewField` で文字列をループで回し、特定の文字が現れたら該当する Sprite を生成します。

## 実行結果

![field_gen.gif](https://qiita-image-store.s3.amazonaws.com/0/4428/91176462-b9cb-d2a8-234e-97e8bae06e82.gif "field_gen.gif")

## まとめ

手作業で座標を指定するよりだいぶ楽になりました。
Ubuntu に apt-get で Chrome 59 インストールして --headless してみた


## 環境

Amazon Lightsail で1ヶ月無料借りたお試しインスタンス。
OSバージョンは以下のとおり。

```
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.5 LTS
Release:        14.04
Codename:       trusty
```

## Chrome59 をインストール

[UbuntuUpdates - PPA: Google Chrome](https://www.ubuntuupdates.org/ppa/google_chrome)


上記に記載されている手順そのまま（


```
# 公開鍵を追加
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - 

# リポジトリ追加
$ sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'

# stable（2017-6-19 現在は 59 をインストール）, -beta もインストール可能
$ sudo apt-get update 
$ sudo apt-get install google-chrome-stable
```

## 取得したHTMLを標準出力に吐く

```
$ google-chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com
```

`--disable-gpu` をつけないとエラーがたくさん出てくる
`--dump-dom` によって標準出力に指定されたURLから取得した内容を出力

## スクショを撮る

試しにスクショを撮ってみます。フリー素材をよく利用させてもらっている[ぱくたそ](https://www.pakutaso.com/)さんのページを試しに撮ってみました。

```
$ google-chrome --headless --disable-gpu --screenshot https://www.pakutaso.com/
```

実行すると、カレントディレクトリに screenshot.png というファイルができます。
以下は、画像をmacのプレビュー.appで表示してみたところ。

![スクリーンショット 2017-06-19 23.20.53.png](https://qiita-image-store.s3.amazonaws.com/0/8219/0bdb30d2-cac7-258a-7325-653888b7a88e.png "スクリーンショット 2017-06-19 23.20.53.png")

localeやフォントの設定ができてなかったので日本語は残念な感じに。

## Ubuntu環境の日本語化

[Ubuntu 14.04 LTS : 日本語環境にする ： Server World](https://www.server-world.info/query?os=Ubuntu_14.04&p=japanese)

上記を参考に locale 設定

```
# 日本語関連パッケージインストール
$ sudo apt-get -y install language-pack-ja-base language-pack-ja

# システムの文字セットを日本語に変更
$ sudo update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
$ source /etc/default/locale
$ echo $LANG
```

[Ubuntu 14.04 LTSをインストールした直後に行う設定 & インストールするソフト](http://sicklylife.at-ninja.jp/memo/ubuntu1404/settings.html#font_in)

上記を参考に日本語フォントをインストール（IPAフォントにしてみた）

```
# フォントパッケージのインストール
$ sudo apt-get install fonts-ipafont-gothic fonts-ipafont-mincho

# インストール結果確認
$ fc-list
（IPAゴシック, IPA明朝などが表示される）
```

もう一度、スクショを取り直してみた。

![スクリーンショット 2017-06-20 6.17.35.png](https://qiita-image-store.s3.amazonaws.com/0/8219/928e3402-9c65-770a-8670-d497130f96fb.png "スクリーンショット 2017-06-20 6.17.35.png")

ちゃんと日本語が表示できました。


## 参考

* [ヘッドレス Chrome ことはじめ  |  Web  |  Google Developers](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)
* [UbuntuUpdates - PPA: Google Chrome](https://www.ubuntuupdates.org/ppa/google_chrome)
* [Ubuntu 14.04 LTS : 日本語環境にする ： Server World](https://www.server-world.info/query?os=Ubuntu_14.04&p=japanese)
* [Ubuntu 14.04 LTSをインストールした直後に行う設定 & インストールするソフト](http://sicklylife.at-ninja.jp/memo/ubuntu1404/settings.html#font_in)
Apple Musicからアルバムアートワーク画像を直接開くブックマークレット

# はじめに
自分は普段、Exact Audio Copyを使用して音楽を楽しんでいる。
iTunesなどのようなアルバムアートワーク画像を自動で埋め込むソフトウェアを使用していないため、
インターネットのどこかから画像を探してきて手動でファイルに埋め込んでいる。
その際の画像の取得元として優れていると感じるサイトがApple Musicである。
取り扱っているアルバムの枚数が豊富で、またアートワークの画質が平均的に良いためである。
# 課題
ブラウザでApple Musicのアルバムのページを単に開くだけでは画像を保存することはできない。
画像に対するコンテキストメニュー内に「名前を付けて画像を保存」が表示されないためである。
画像を保存するためにはHTMLソースから該当の画像のURLを探し出し、画像を直接開くか保存する必要がある。
この作業を都度行うのは非常に面倒であり、簡潔な操作で画像を保存したい。
# 解決手段
次のブックマークレットを作成した。

```js
javascript:window.open(Array.prototype.filter.call(document.getElementsByClassName('product-artwork we-artwork--fullwidth we-artwork ember-view')[0].children,e=>e.tagName=='IMG')[0].getAttributeNode('src').value.replace(/\d+x\d+w.jpg$/,'65535x0w.jpg'),'_self');
```

このコードをまるまるコピーし、Google Chromeのブックマークとして適当な名前で保存する。
![bookmarklet.png](https://qiita-image-store.s3.amazonaws.com/0/13160/e2438d5c-e6f2-1c31-eee1-421c68bd2720.png)
画像を取得したいアルバムのApple Musicのページ([例](https://itunes.apple.com/us/album/hardwired-to-self-destruct-deluxe/id1145498274))を開いた後、このブックマークを開くことで、画像が直接ブラウザで開かれる。
この画像は「名前を付けて画像を保存」が可能である。
なお、Internet ExplorerおよびFireFoxでは、Apple Musicのページ上でブックマークレットを実行することができないため、上記のコードはGoogle Chrome(またはChromiumベースのブラウザ)専用である。
(その他のブラウザでは試していない)
# 解説
上記のコードはブックマークレット用にワンライナーにしてあるが、元となるコードは次の通り。

```js
elements = document.getElementsByClassName('product-artwork we-artwork--fullwidth we-artwork ember-view');
img = Array.prototype.filter.call(elements[0].children, e => e.tagName == 'IMG')[0];
src = img.getAttributeNode('src').value; 
url = src.replace(/\d+x\d+w.jpg$/, '65535x0w.jpg');
window.open(url, '_self'); 
```

要約すると、対象となる画像のURLを取得した上でそのURLのファイル名を置換し、`window.open()`している。
ファイル名の末尾を `'65535x0w.jpg'` にしているのは、これ以上の画像サイズはサーバにないだろうとの想定の元、
最大のサイズの画像を取得するためである。
ここの値を変更し `'600x0w.jpg'` にすれば、600x600程度のサイズの画像が取得できる。
当然ながら、Apple Musicのページの仕様が変われば、上記ブックマークレットは使用できなくなる可能性が高い。
#おわりに
どれだけいるかは分からないが、アルバムアートワークを自ら探す人のために本記事を書いた。
自分のように音楽ライブラリ構築を趣味にする人に役立つとうれしい。