OmniAICreator/Qiita-1.07M huggingface dataset:
健忘録: Scala 2.11でDef Macroを使う時の手順と動くサンプルコード

ただの健忘録。

build.sbt に以下を追加。

```
scalacOptions in Global += "-language:experimental.macros"

libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value
```

以下みたいな感じで書く。準クオートで書くprintlnマクロはこんな感じ。

```scala
import language.experimental.macros
import scala.reflect.macros.whitebox.Context

object PrintMacro {
  def p(msg: String): Unit = macro impl

  def impl(c: Context)(msg: c.Expr[String]) = {
    import c.universe._
    q"""
        println(${msg})
      """
  }
}
```

とか、変数名デバッグマクロとか作るときは、構文木作れるreify/spliceが便利。

```scala
import language.experimental.macros
import scala.reflect.macros.whitebox.Context

object DebugMacro {
  def debug(param: Any): Unit = macro debug_impl

  def debug_impl(c: Context)(param: c.Expr[Any]): c.Expr[Unit] = {
    import c.universe._
    val paramRep = show(param.tree)
    val paramRepTree = Literal(Constant(paramRep))
    val paramRepExpr = c.Expr[String](paramRepTree)
    reify { println(paramRepExpr.splice + " = " + param.splice) }
  }
}
```

文字列でプロパティアクセスするマクロとかはこんな感じ。

```scala
import language.experimental.macros
import scala.reflect.macros.whitebox.Context

object AccesserMacro {
  def accesser(obj: Any, property: String): Any = macro impl

  def impl(c: Context)(obj: c.Expr[Any], property: c.Expr[String]) = {
    import c.universe._
    val Expr(Literal(Constant(propString: String))) =  property
    Select(obj.tree, TermName(propString))
  }
}
```

Def Macroのドキュメントにも書いてあるけどケースクラスの構造化代入使うと便利。

詳しいマクロやり方は、
http://docs.scala-lang.org/ja/overviews/macros/overview
を見つつScalaDocコメント読むのが良さそう。

StackOverFlowにマクロ職人が沢山いるので検索すると勉強になる。
http://stackoverflow.com/search?tab=votes&q=Scala%20macro

2.11でwhiteboxマクロとblackboxマクロというのが2.11で分かれていたので注意。
http://docs.scala-lang.org/ja/overviews/macros/blackbox-whitebox
【Xcode】StoryboardでViewを角丸にする


#やり方

Viewならなんでも大丈夫ですが、今回はButtonでやってみます。

まず、Storyboardでボタンを選択した状態で
右側のバーのUser Defined Runtime Attributesを表示させてください。

そして、Key Pathに```layer.cornerRadius``` と入力し、TypeはNumberを選択してください。
Valueの値で丸みを調整します。
　
こんな感じです。
![image](https://qiita-image-store.s3.amazonaws.com/0/133776/1418d2fe-625b-8e50-cd58-f912e977e6be.png)


Storyboardでは角は丸くなっていませんが、実際にアプリを動かすと反映されています。

#参考

[Giving UIView rounded corners](http://stackoverflow.com/questions/1509547/giving-uiview-rounded-corners)
FirebaseをStaging環境とかDebug環境とかRelease環境で切り替えをする


## はじめに

Firebaseをアプリに実装していてDeployGateなどでテストをしているとRelease環境のAnalyticsが反応してしまって実際の生の完全なデータが取得できないので `GoogleService-Info.plist` を2つ取得してそれぞれの環境にわけてあげようという話です。

## プロジェクト準備

1. Xcodeでプロジェクトを新しく作る
2. Firebaseでプロジェクトを作る
3. 普通にFirebaseとiOSアプリの設定をする
4. スキームの設定 [Xcode7 でスキームの設定をする](http://qiita.com/odorry/items/fc332e1084ebf74e8f65)この記事を見るとわかります！

上記のところまでは省略します。

![スクリーンショット 2016-09-12 午後1.28.33.png](https://qiita-image-store.s3.amazonaws.com/0/97280/e613970f-d607-e820-e785-a8e629d3b504.png "スクリーンショット 2016-09-12 午後1.28.33.png")

こんな状態まではセットアップしておく

## FirebaseにStaging用のプロジェクトを作る(必要ならDebug用も)

Release環境と同じようにプロジェクトを作成し、 `GoogleService-Info.plist` をダウンロードする。

ダウンロードした `GoogleService-Info.plist` を `GoogleService-Info-Staging.plist` とリネームして、プロジェクトに追加する。

![スクリーンショット 2016-09-12 午後1.43.44.png](https://qiita-image-store.s3.amazonaws.com/0/97280/701c4c01-ad2b-ee28-fec6-9e826aa03852.png "スクリーンショット 2016-09-12 午後1.43.44.png")

追加する際にStaging環境にtargetが選択されていることを確認する。

```swift:AppDelegate.swift
import UIKit
import Firebase

#if STAGING
    let firebasePlistName = "GoogleService-Info-Staging"
#else
    let firebasePlistName = "GoogleService-Info"
#endif

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let firbaseOptions = FIROptions(contentsOfFile: NSBundle.mainBundle().pathForResource(firebasePlistName, ofType: "plist"))
        FIRApp.configureWithOptions(firbaseOptions)
        return true
    }
    ・・・
}
```

これでRelease環境とDebug環境のFirebaseを切り替えることができました！
[UWP]ソフトキーボードを非表示にする方法

## 問題

UWPアプリで、ソフトキーボードをXaml上から非表示にしたい

例）・検索用のテキストボックス上でEnterキーを押した時
　　・検索実行ボタンを押した時

## 対応

UWPでは、Windows.UI.ViewManagement.InputPane を通じてソフトキーボードの表示状態をコントロールできます。

以下のような「ソフトキーボードを消すアクション」を作って、TextBoxやButtonへの入力に反応して実行できるようにします。

```csharp:HideInputPaneAction.cs

public class HideInputPaneAction : DependencyObject, IAction
{
	public object Execute(object sender, object parameter)
	{
		return Windows.UI.ViewManagement.InputPane.GetForCurrentView().TryHide();
	}
}


```

Xaml側では「Enterキー押下イベントを補足するビヘイビア」や「検索ボタンの押下」をトリガーにして HideInputPaneAction を実行させます。


```xml:検索UI.xaml
<StackPanel Orientation="Horizontal">

    <TextBox Text="{Binding SearchText.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             InputScope="Search"
            >
        <i:Interaction.Behaviors>
            <mybehavior:KeyboardTrigger Key="Enter">
                <mybehavior:KeyboardTrigger.Actions>
                    <core:InvokeCommandAction Command="{Binding DoSearchCommand}" />

                    <mybehavior:HideInputPaneAction />

                </mybehavior:KeyboardTrigger.Actions>
            </mybehavior:KeyboardTrigger>
        </i:Interaction.Behaviors>

    </TextBox>

    <Button Content="検索" 
            Margin="8 0"
            Width="80"
            >
        <i:Interaction.Behaviors>
            <core:EventTriggerBehavior EventName="Tapped">
                <core:InvokeCommandAction Command="{Binding DoSearchCommand}" />

                <mybehavior:HideInputPaneAction />

            </core:EventTriggerBehavior>
        </i:Interaction.Behaviors>
    </Button>
</StackPanel>

```
Oracle Database 11g TIPS


あくまで自分用のメモですが、
間違った箇所などをご指摘いただけると、ありがたいです。

# 接続関連

現在のOracleに接続しているプロセス情報

```sql
SELECT * FROM v$session;
```

また上記結果のSIDとSERIAL#を使って接続プロセスをKILL(切断)することができる。

```sql
-- 例) sidが123、serial#が444のとき
ALTER SYSTEM KILL SESSION '123, 444';
```


最大接続数などを表示
```sql
SELECT * FROM v$license;
```

# ROWNUMの挙動

ROWNUMはSELECTされるタイミングで番号が振られるので、
副問い合わせとORDER BYをうまく使わないと予想通りの結果を得られない。
よく調べずにMySQLのLIMITみたいな使い方をすると痛い目を見る。
```sql
  -- テーブル作成
  CREATE TABLE "TBL_SHOHIN"
  (
    "ID"   VARCHAR2(20 BYTE),
    "NAME" VARCHAR2(20 BYTE)
  );
;
```

```sql
  -- ROWNUMの挙動をテスト
  SELECT ROWNUM AS ROWNUM2, HOGE.* FROM (
    SELECT * FROM (
      SELECT 
         ROWNUM AS ROWNUM1
        ,ID
        ,NAME 
      FROM 
        TBL_SHOHIN 
      ORDER BY ID ASC
    ) ORDER BY ID DESC
  ) HOGE
  ;
```

■実行結果

|ROWNUM2|ROWNUM1|ID|NAME|
|-|-|-|--------|
|1|5|5|クッキー|
|2|4|4|スフレ  |
|3|3|3|羊羹    |
|4|2|2|どら焼き|
|5|1|1|プリン  |

# 記号
(+)記号は、先行する列が結合内の外部結合列であることを指定します。
```sql
SELECT * FROM Table1, Table2
WHERE Table1.Key = Table2.Key (+)
```
上記と下記SQLは等価
```sql
SELECT * FROM Table1
LEFT JOIN Table2 ON(Table1.Key = Table2.Key)
```

OTNの「演算子」詳細が記載されている
[こちら](http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05750-03/operators.htm)


# オブジェクト情報取得関連

```SQL
SELECT *
FROM   USER_OBJECTS
WHERE  OBJECT_TYPE = 'PROCEDURE'
ORDER BY OBJECT_NAME;
```

指定できるOBJECT_TYPEは下記の通り
* TABLE
* INDEX
* VIEW
* FUNCTION
* PROCEDURE
* TRIGGER
* PACKAGE
* PACKAGE BODY
* SEQUENCE
* SYNONYM
* DATABASE LINK

また下記のSQLでプロシージャのソースを取得できる


```sql
SELECT * FROM USER_SOURCE WHERE NAME = 'プロシージャ名' ORDER BY LINE;
```

```sql
-- カラムの情報を取得
SELECT COLUMN_NAME FROM (
    SELECT 
      C.* 
    FROM 
       USER_TAB_COLUMNS C
      ,USER_TABLES T 
    WHERE
      C.TABLE_NAME = T.TABLE_NAME 
    ORDER BY C.TABLE_NAME, C.COLUMN_ID
)
WHERE TABLE_NAME = 'HOGE';
```

コードを自動生成するときなど、プロシージャの引数を知りたいことがある。
ソースを読めば判明するが、プログラムで処理する場合パースせずにやりたい。
そんなときに下記方法を利用する。

プロシージャはUSER_PROCEDURESに定義されている。
コンパイルエラーが出ているプロシージャはこのテーブルに記載されない。

```sql
-- ユーザー定義のプロシージャ一覧を表示
SELECT 
  OBJECT_NAME 
FROM 
  USER_PROCEDURES
;
```
プロシージャの引数は、USER_ARGUMENTSテーブルに記載されている。
コンパイルエラーが出ているプロシージャはこのテーブルに記載されない。

```sql
-- ユーザー定義プロシージャの引数一覧を取得する
SELECT 
  OBJECT_NAME,
  ARGUMENT_NAME,
  POSITION,
  DATA_TYPE,
  IN_OUT,
  DATA_LENGTH,
  PLS_TYPE
FROM 
  USER_ARGUMENTS
;
```

# 型変換の際にヌル文字混入

本来やるべきではないのだろうが、やまれぬ事情でVARCHAR2->NCHARに変換するときに、
ヌル文字列(\0)が混入する件。

```sql
    -- 1文字あたりのバイト数が拡張変換になるため？
    RTN_CODES := TO_NCHAR(TMP);
    
    -- ヌル文字を除去するとキレイなデータになる
    RTN_CODES := REPLACE(RTN_CODES, CHR(0), null);
```


```sql
-- 文字コードを確認する
SELECT NLS_CHARSET_NAME(NLS_CHARSET_ID('CHAR_CS')) AS CHAR_CS,
       NLS_CHARSET_NAME(NLS_CHARSET_ID('NCHAR_CS')) AS NCHAR_CS FROM DUAL;
```


実行結果

|CHAR_CS|NCHAR_CS|
|:----------:|:----------:|
|JA16SJISTILDE|AL16UTF16|
homebrewで導入したコマンドをNetbeansから使えるようにする


homebrew でインストールしたコマンドは  `/usr/local/bin/` にインストールされるが、アプリケーションは`~/.bashrc`の指定は無視され独自のPATHが設定されるので使えない。

アプリ毎にPATHを指定する方がMacOSのバージョン毎に変わっており、よくわからなかったので、Netbeans起動スクリプトを直接開きPATHを追加で動いた。


起動スクリプト(Netbeans 8.1の場合)
/Applications/NetBeans/NetBeans 8.1.app/Contents/Resources/NetBeans/bin/netbeans

```netbeans
...
# However, if you add GPL Version 2 code and therefore, elected the GPL
# Version 2 license, then the option applies only if the new code is
# made subject to such option by the copyright holder.

#
# /usr/local/bin/ をPATHに追加
#
export PATH=/usr/local/bin/:$PATH

```
UTF-16エンコードのXMLファイルをgolangでパースする

# 注意
この方法が正しいのかどうかは不明です。

# やり方

```xml
<?xml version="1.0" encoding="utf-16"?>
<root>
	<elem id="1">
		Hello World
	</elem>
	<elem id="2">
		こんにちは世界
	</elem>
</root>
```

こんな感じのUTF-16(BOM付きBig Endian)のXMLファイルがあったとして

```go
package main

import (
	"encoding/xml"
	"io"
	"os"
	"io/ioutil"
	"bytes"
	"unicode/utf16"
	"unicode/utf8"
	"strings"
	"fmt"
)

type Elem struct {
	Id   string  `xml:"id,attr"`
	Text string  `xml:",chardata"`
}

type Root struct {
	Elems []Elem `xml:"elem"`
}

// UTF-16(BOM付き,BE)想定
func decode_utf16(b []byte) string {
	u16s := make([]uint16, 1)

	ret := &bytes.Buffer{}

	b8buf := make([]byte, 4)

	lb := len(b)

	for i := 2; i < lb; i += 2 {
		u16s[0] = uint16(b[i+1]) + (uint16(b[i]) << 8)
		r := utf16.Decode(u16s)
		n := utf8.EncodeRune(b8buf, r[0])
		ret.Write(b8buf[:n])
	}

	return ret.String()
}

func fake_charset_reader(enc string, r io.Reader) (io.Reader, error) {
	return r, nil
}

func main() {
	fp, err := os.Open("utf-16.xml")

	if err != nil {
		panic(err)
	}

	xml_doc, _ := ioutil.ReadAll(fp)

	var root Root

	nr := strings.NewReader(decode_utf16(xml_doc))
	decoder := xml.NewDecoder(nr)
	decoder.CharsetReader = fake_charset_reader
	err = decoder.Decode(&root)
	if err != nil {
		panic(err)
	}

	fmt.Println(root)
}
```

こんな感じのコードでパースできる。

ポイントは2箇所

- `decode_utf16(xml_doc)`でUTF-16をUTF-8に変換してるとこ
- `decoder.CharsetReader` に `fake_charset_reader` を代入してるとこ

`decode_utf16()` で UTF-8 に変換しないと、XMLの一行目をちゃんと読み取ってくれないので、UTF-8のファイルじゃないよ。と怒られる。だからと言って、変換したデータだけ渡しても、CharsetReaderがセットされてないよと怒られる。んで、CharsetReader を charsetパッケージのCharsetReaderにしても、ちゃんと動かない(これがなぜかは不明だけど、おそらく渡ってきたio.ReaderがUTF-8に変換されているから、UTF-16じゃねぇよ！って怒られているんじゃないか)、なので、CharsetReaderにフェイクのCharsetReaderをかまして、エンコード無視でUTF-8のReaderを使うという作戦。一応、うまくいく。ただ、UTF-16にしかない文字コードとかあったらコケそう。

# 参考
* [How to convert xml encoding UTF-16 to UTF-8 in golang]
http://stackoverflow.com/questions/34890522/how-to-convert-xml-encoding-utf-16-to-utf-8-in-golang

* [Unmarshal an ISO-8859-1 XML input in Go]
http://stackoverflow.com/questions/6002619/unmarshal-an-iso-8859-1-xml-input-in-go

* [XMLのパース/生成]
http://cuto.unirita.co.jp/gostudy/post/standard-library-xml/

* [UTF-16は、実は５種類ある！]
http://d.hatena.ne.jp/chaichanPaPa/20081124/1227514306
Visual Studio CodeでPythonコーディングをする設定

[Visual Studio Codeを使ってみる](http://qiita.com/fukuit/items/9572ec53e21ce2b3e445) の続きです。

> あとは、lintを設定して、文法チェック等をさせるようにすれば、環境設定としては、だいたい終了なはずだけれど、pep8を呼び出せる用に設定する方法については、宿題ということにして、調べておくことにする。

# Visual Studio CodeにPythonの拡張機能をインストールする
[以前に書いたとおり](http://qiita.com/fukuit/items/9572ec53e21ce2b3e445#python)、その名も[Python](https://marketplace.visualstudio.com/items?itemName=donjayamanne.python)という拡張機能をインストールして、有効化してあります。

## lintの設定をする
lintというのは、もともとの意味は糸くずとかそんな意味らしいんだけれど、要するに縫いあがった洋服の糸くずをとるような作業をする、、、とか、そんな由来なんでしょうか。端的に言うと、文法など小姑のようにチェックすることです。

Pythonの文法・表記チェックというと、コーディング規約PEP8準拠かどうかを調べるその名もpep8というコマンドや、pylintというコマンドなどがあります。

今回は、pylintを呼び出すための設定をVisual Studio Codeに対して行います。

## pylintのインストールを行う
私はAnacondaで環境構築をしているので、以下のようにして、pylintをインストールします。

まず、anacondaでpylintのパッケージングされているかどうかを検索します。

```Bash
% anaconda search -t conda pylint
```

すると、anaconda/pylintがどうやら標準的な配布物っぽいです。

```Bash
% anaconda show anaconda/pylint
Using Anaconda API: https://api.anaconda.org
Name:    pylint
Summary:
Access:  public
Package Types:  conda
Versions:
   + 1.2.0
   + 1.2.1
   + 1.1.0
   + 1.4.1
   + 1.4.0
   + 1.4.2
   + 1.3.1
   + 1.5.4

To install this package with conda run:
     conda install --channel https://conda.anaconda.org/anaconda pylint
```

ということで、インストール方法が分かりました。

```Bash
% conda install --channel https://conda.anaconda.org/anaconda pylint

```

### ちなみにpep8の場合
anaconda環境では、pep8はインストール済でした。


## 「ユーザー設定」に記載する
Visual Studio Codeのユーザー設定を行います。

ファイルの保存ごとにlintが働いてチェックされるようにするために必要なのは、以下の一文があれば、ほぼ十分です。

```
	"python.linting.enabled": true
```

というか、多分、デフォルトでこうなっていて、pylintが走るようになっています。

ちなみに、いやいやpep8派だという場合は、以下のようにするだけです。

```
	"python.linting.enabled": true,
	"python.linting.pylintEnabled": false,
	"python.linting.pep8Enabled": true
```

あとは、必要に応じて、以下の設定をしておけば良いと思います。

コードを変更するたびにチェックする場合、ファイルの保存時にチェックする場合は、以下の項目をtrueにします。

```
    "python.linting.lintOnTextChange": true,
    "python.linting.lintOnSave": true,
```

以上により、Visual Studio CodeにてPythonコードを記載する際に、lintによる文法・表記方法などのチェックが可能になりました。

## 2017-12-15 追記

[takerushi](https://qiita.com/takerushi)様から、ご指摘がありました。

詳しくはコメントをご覧いただくとして、

```json
    "python.linting.lintOnTextChange": true,
```

は廃止されたようです。
Android Studioで、身に覚えのない箇所でエラー　XML編

ビルド時に、Messageウインドウにエラーが表示された場合は、
エディタタブに表示されるファイル名(values.xmlなど)だけでなく、
パスをよく見よう！

intermediatesとかmergedとか表示されていませんか？

> ～intermediates\res\merged\～\values.xml

など、ビルド時に自動生成された、複数のxmlファイルをまとめた後のファイルになっている事が多いです。
あわてて、別のファイルを編集しないようにしましょう。
三角関数で円周運動


デモ：http://codepen.io/mo4_9/pen/amvxKE


角度をラジアンに変換し、
`degree * Math.PI / 180`

それを三角関数に渡して、半径をかける

```javascript:座標を計算する
calcBallPos(radius, space, speed) {
  speed = speed || 1.0;
  const rad = ( this.degree * speed + this.diameter + space ) * Math.PI / 180;
  const x = radius * Math.sin(rad);// X座標 = 半径 x Sinθ
  const y = radius * Math.cos(rad);// Y座標 = 半径 x Cosθ

  return {'x':x, 'y':y};
}
```

```javascript:角度を更新する
render() {

  this.degree++;

  const pos1 = this.calcBallPos(100, 10, 2);

  this.sphere.position.set(pos1['x'], pos1['y'], 0);
  
}
```

> 参考
[sin関数](http://www.ajaxtower.jp/js/math_class/index9.html)
postgres_fdwの使い方

結局使わなかったけど、postgres_fdwの定義方法を調べたのでメモ。

## postgres_fdwとは？
２つのpostgresqlのデータベースがある場合に、一方のデータベースから他方のデータベースのテーブルを参照する技術です。
一度FOREIGN TABLEを定義すれば、ローカルにあるデータベースと同じようにSELECT, INSERT, UPDATE, DELETEができます。

設定が必要なのは参照する側のデータベースのみで被参照のデータベースの方は何一つ手を入れる必要はありません。

heroku-postgresでも試しましたが、何の問題もなく動きました。


## How to use
細かいところは[ドキュメント](https://www.postgresql.jp/document/9.5/html/postgres-fdw.html)を読んでもらうとして、実際に流したSQLは以下のような感じです。

FOREIGN TABLEはいくつでも定義することができます。

``` sql
CREATE EXTENSION postgres_fdw;
CREATE SERVER app1 FOREIGN DATA WRAPPER postgres_fdw 
OPTIONS (host 'xxxx.compute-1.amazonaws.com', dbname 'xxxx', port '5432');

CREATE USER MAPPING FOR public SERVER app1
OPTIONS (user 'xxxx', password 'xxxx');

CREATE FOREIGN TABLE app1_users (
  id                     BIGINT,
  name                   VARCHAR(40)  NOT NULL,
  email                  VARCHAR(255) NOT NULL,
  password               VARCHAR(255) NULL,
  image_url              VARCHAR(255) NULL,
  created_at             TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at             TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP
) SERVER app1
OPTIONS (table_name 'users');

SELECT count(*) FROM app1_users;
```

heroku-postgresにつなぐ場合はSSLの設定が必要かと思いましたがデフォルトがPreferred(必要であればSSLを使う)なので、特に設定しなくても問題なく動きました。

便利です。
πの推定(PythonとRの比較)

Pythonの勉強を続けています。本日の小ネタは、πの推定に関連するものです。私の知ってる限り、コードを短く書いてみました。RとPythonを比べて見ましょう。

ルール：短く早いもの勝ち
では、勝負の行方は？

##Python

```
>>> 
PI.est: 3.1415926237881826
elapsed_time:41.08441209793091
```

```π.py
import time
start = time.time()

n = 2**25
num = 1
Pi = 0
while num > 0:
    Pi += 4*(-1)**(num-1)*(2*num-1)**(-1)
    num += 1
    if num > n:
        print("PI.est:",Pi)
        break
    
elapsed_time = time.time()-start
print("elapsed_time:{0}".format(elapsed_time))
```

##R

```
            ユーザ            システム                経過  
5.13999999999999346 0.53999999999999915 5.69000000000232831 
> PI.est
[1] 3.1415926237874712
```

```π.r
system.time({
  n = 2**25
  x <- 1:n
  PI.est <- 4*sum( (-1)**(x-1)*(2*x-1)**(-1) )
})
PI.est
```

##結果
ベクトルや行列の計算なら、やっぱりRの勝ちですね！
phpredis で、hMSetは pipelineでhSetを大量に投げつけるのよりどのくらい早いかベンチマークとってみた。

ハッシュ型の[hMSet](https://github.com/phpredis/phpredis/tree/2.2.8#hmset)が、hSetをたくさん呼ぶのと比べてどのくらい早いのか気になったので、ベンチマークとってみました。

各種バージョンは以下の通り。

software | version
:-- | --:
PHP | 5.6.24
phpredis| 2.2.8
redis-server | 2.8.19

```php
// hMSet // 3.4 sec
bench(function($redis, $target){
  return $redis->hMSet("a", $target);
});

// foreach($arr){set} // 30 sec
bench(function($redis, $target){
  $res = true;
  foreach($target as $key => $value) {
    $res = ($res &&  $redis->hSet("a", $key, $value));
  }
  return $res;
});

// Redis::MULTI  // 33 sec
bench(function($redis, $target){
  $multi = $redis->multi();
  foreach($target as $key => $value) {
    $multi->hSet("a", $key, $value);
  }
  return $multi->exec();
});

// Redis::PIPELINE  // 7 sec
bench(function($redis, $target){
  $multi = $redis->multi(Redis::PIPELINE);
  foreach($target as $key => $value) {
    $multi->hSet("a", $key, $value);
  }
  return $multi->exec();
});

function bench($func) {
  $redis = new Redis();
  $redis->connect('/tmp/redis.sock');
  $redis->select(254);
  $target = range(1, 1000);

  $st = microtime(true);
  for($i = 0; $i < 100; $i++) {
    $redis->del("a");
    $res = $func($redis, $target);
  }
  echo microtime(true) - $st . PHP_EOL;
}
```

pipelineの倍くらい早いです。普通にhSetをforeachしただけだと、10倍位差がでてますねー。

# 使ったマシンのスペック

`redis-benchmark` の結果だけ貼っておくので、これで察してください。

```redis-benchmarkの結果
[sitri@ndxbn:~]redis-benchmark -q
PING_INLINE: 64683.05 requests per second
PING_BULK: 58997.05 requests per second
SET: 56338.03 requests per second
GET: 61766.52 requests per second
INCR: 59136.61 requests per second
LPUSH: 59701.50 requests per second
LPOP: 60459.49 requests per second
SADD: 60168.47 requests per second
SPOP: 62774.64 requests per second
LPUSH (needed to benchmark LRANGE): 60569.35 requests per second
LRANGE_100 (first 100 elements): 30202.36 requests per second
LRANGE_300 (first 300 elements): 12763.24 requests per second
LRANGE_500 (first 450 elements): 8623.66 requests per second
LRANGE_600 (first 600 elements): 6710.96 requests per second
MSET (10 keys): 45662.10 requests per second
```

## ほかやりたいこと
Set型の`sAdd()`とかZSetの`zAdd()`とかだと可変引数ですし、そっちもやりたい。
CircleCIで生成したHTMLをS3で公開する


# 概要

S3で静的コンテンツをホスティングしている場合に、そのコンテンツの更新をCircleCIを使って自動化する方法についてまとめます。

Maven等で出力したレポートのHTMLをS3で公開、更新するようなケースを想定しています。

# 前提

 - S3バケットは作成済である
 - 静的ウェブサイトホスティングが有効になっている

# 手順

## IAMユーザの作成

- CircleCI用のIAMユーザを作成して、Access Key IdとSecret Access Keyを控える
- 専用のユーザを作成することをCircleCIも推奨している

## IAMポリシーの作成

- S3の特定バケットにsyncできるポリシーを作成する
- 作成したポリシーにユーザを紐付ける
- [Policy Generator](http://awspolicygen.s3.amazonaws.com/policygen.html)など活用する

### サンプル

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "StmtXXXXX",
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetObject",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::your.s3.backet",
                "arn:aws:s3:::your.s3.backet/*"
            ]
        }
    ]
}
```

ポイントとしては下記。

 - Resourceはバケット自体とバケット配下の階層両方の指定が必要
 - PutObjectAclをAllowする必要がる

## バケットポリシーの作成

このままだと全公開されてしまうので、必要に応じてIP制限をかける。

 - S3コンソールからバケットポリシーの作成を行う
 https://console.aws.amazon.com/s3/home
 - 対象のバケットを選択→[プロパティ]→[アクセス制限]→[バケットポリシーの編集]

### サンプル

```json
{
	"Version": "2012-10-17",
	"Id": "PolicyXXXXX",
	"Statement": [
		{
			"Sid": "StmtXXXXX",
			"Effect": "Deny",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::your.s3.backet/*",
			"Condition": {
				"NotIpAddress": {
					"aws:SourceIp": [
						"XXX.XXX.XXX.XX",
						"XXX.XXX.XXX.XX"
					]
				}
			}
		}
	]
}
```

- 許可IP以外をDenyする
- 許可IPにGetObjectを許可する
- 許可と拒否IPそれぞれでアクセスしてみて、期待挙動になるか確認する
   - 許可IP以外だと403が返るはず

## CircleCIの設定

### AWS Permissionsの設定

- 対象のプロジェクトを選択
- [Project Settings]→[AWS Permissions]
- 作成したIAMユーザの認証情報を入力する

### circle.ymlの設定

- aws cli で対象のファイルをsyncする

#### サンプル

```yml
machine:
  java:
    version: oraclejdk8
dependencies:
  override:
    - mvn dependency:resolve
test:
  override:
    - mvn integration-test
deployment:
  deploy:
    branch: aws_deploy
    commands:
      - mv your_uploadcontents $CIRCLE_ARTIFACTS
      - aws s3 sync $CIRCLE_ARTIFACTS/your_upload_contents s3://your.s3.backet/ --delete --acl public-read
```

ポイントは下記の通り。
- aws_deployブランチの変更の際デプロイする

- 作成したコンテンツを$CIRCLE_ARTIFACTSに移動
   - これはCircleCIのArtifactsを使いたいだけで、S3にアップロードするのと直接関係はない
 - $CIRCLE_ARTIFACTS 配下をS3バケット直下と同期
    - `--delete` で削除も同期
    -  `--acl public-read` でコンテンツを公開する
       - これをしないと、webサイトとしてアクセスできるようにならない

# 参考

 - [s3cmd sync に必要なIAMポリシー](http://qiita.com/takashi0314/items/d971ee7d5e91ac6dc7e2)
 - [S3のアクセスコントロールまとめ](http://qiita.com/ryo0301/items/791c0a666feeea0a704c)
 - [AWS S3 で listObjects が "AccessDenied" を返す場合](http://qiita.com/macoshita/items/e3316ffc45a8eac1c9c8)
 - [CircleCIからS3にアップロードするための設定
](http://qiita.com/tjinjin/items/c03e39cd46b222d0b3a3)
 - [S3でIP制限](http://qiita.com/you_matz/items/b3885891e576f5604323)
 - [s3cmd sync に必要なIAMポリシー](http://qiita.com/takashi0314/items/d971ee7d5e91ac6dc7e2)
ec2ssh updateで生成されたホスト名に連番を割り振る

# ec2ssh updateで生成されたホスト名に連番を割り振る


## 説明
下記のプログラムを実行すると、ec2ssh updateを実行して、~/.ssh/config の中に同じ名前のインスタンスがあったら連番を振ってくれます。
python 2.7.10で動作確認。

下のような感じで書き換えてくれます。

```text
Host ec2instance
    ...

Host ec2instance
    ...

Host ec2instance
    ...
```

 ↓

```text
Host ec2instance
    ...

Host ec2instance2
    ...

Host ec2instance3
    ...
```

## ソース
```py
#! /usr/bin/env python
#-*- coding: utf-8 -*-

import io           # input/output
import subprocess   # コマンド実行
import re           # 正規表現
import os
from datetime import datetime

import sys

# Trueでec2sshや保存操作を行わない
DEBUG = False

# confirm
def query_yes_no(question, default="yes"):
    valid = {"yes": True, "y": True, "ye": True,
             "no": False, "n": False}
    if default is None:
        prompt = " [y/n] "
    elif default == "yes":
        prompt = " [Y/n] "
    elif default == "no":
        prompt = " [y/N] "
    else:
        raise ValueError("invalid default answer: '%s'" % default)

    while True:
        sys.stdout.write(question + prompt)
        choice = raw_input().lower()
        if default is not None and choice == '':
            return valid[default]
        elif choice in valid:
            return valid[choice]
        else:
            sys.stdout.write("Please respond with 'yes' or 'no' "
                             "(or 'y' or 'n').\n")

# データ内容を読込む
def read_content(filePath):
    f = io.open(filePath, mode='r', encoding='utf-8')
    content = f.read()
    f.close()
    return content

# データ内容を上書き
def save_content(filePath, data):
    f = io.open(filePath, mode='w', encoding='utf-8')
    content = f.write(data)
    f.close()

# ホスト名を書き換える
def renameHostName(v):
    hostName = v.group()

    if hostName in hostsDict:
        # ホスト名が重複している場合
        hostsDict[hostName]['num'] += 1
        hostName += str(hostsDict[hostName]['num'])
    else:
        hostsDict[hostName] = {}
        hostsDict[hostName]['num'] = 1

    return hostName

if query_yes_no('Do you need a backup of your pre-modified config file?') :
    makeBackup = True
else:
    makeBackup = False

hostsDict = dict()

# config fileのパス
configFilePath = os.environ['HOME'] + '/.ssh/config'

# コマンド実行
subprocess.call('ec2ssh update', shell=True)

baseContent = read_content(configFilePath)

# バックアップ保存
if DEBUG == False and makeBackup == True:
    save_content(configFilePath + '.bak.' + datetime.now().strftime('%Y%m%d_%H%M%S'), baseContent)

pattern = r"Host .*"
renamedContent = re.sub(pattern, renameHostName, baseContent)

if DEBUG == False:
    save_content(configFilePath, renamedContent)

print renamedContent
print 'Success! Please check the above result of modifying your config file.'
```
errBot を導入して Slack と連携させてみる

## errBot のインストール

``` bash
$ mkvirtualenv -p `which python3` errenv
(errenv) $ pip install errbot
(errenv) $ mkdir mybot
(errenv) $ cd mybot/
(errenv) ~/mybot$ errbot --init
Your Errbot directory has been correctly initialized !
Just do "errbot" and it should start in text/development mode.
```

## errBot を起動してみる

``` bash
(errenv) ~/mybot$ errbot
```

bot のコンソールが起動するのでコマンドを入力してみる

``` text
 >>> !tryme
It works !
```

コンソールを終了するには python のコンソールと同じように ` Ctrl + D ` か ` Ctrl + C `


## slackclient のインストール

``` python
(errenv) $ pip install slackclient
```




## errbot 設定ファイルの編集

``` bash
(errenv) $ vi ~/mybot/config.py
```

設定ファイルのテンプレート
https://raw.githubusercontent.com/errbotio/errbot/master/errbot/config-template.py

とりあえず ` BACKEND ` 、 `BOT_ADMINS` と `BOT_IDENTITY` だけ変更しておく

``` python
import logging

BACKEND = 'Slack'

-- snip --

BOT_ADMINS = ('@xxxx', )
BOT_IDENTITY = {
    'token': 'xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
}

```

slack の token は
https://my.slack.com/services/new/bot
から取得


### errbot をデーモンとして起動

``` bash
(errenv) $ errbot --daemon
```

適当なチャンネルに bot を招待してテストしてみる

<img width="682" alt="スクリーンショット 2016-09-12 15.30.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/5763/c5d0553c-4b42-1ca1-b8a8-60533fde8f20.png">




http://errbot.io/en/latest/user_guide/configuration/slack.html
Bluemixでデータ分析「dashDB」：DB2 V11のクライアントでLinuxからdashDBに接続してみた。

"IBM Data Server drivers and clients"、要はDB2とかに使うクライアントで、V11という新しいバージョンから、dashDBへの接続が正式にサポートされているようです（以下引用）

> v11 以降、IBM Data Server Driver は dashDB および SQLDB をサポートしています。

https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.swg.im.dbclient.install.doc/doc/t0007315.html

## はじめに
今回は最小限のものだけ入れたいなと思ったので、CLPだけ使えるように、IBM Data Server Runtime ClientをCentOS7(64bit)インストールしました。
http://www-01.ibm.com/support/docview.wss?uid=swg21385217

（キャプチャが大きくて、長めの記事に見えますが、全然すぐ終わります（笑））

## インストール前の準備

ダウンロードしたパッケージの解凍

```console
$ tar xvfz ibm_data_server_runtime_client_linuxx64_v11.1.tar.gz
```

インストールのためのコマンドを実行します（GUI環境（X環境）が必要です）

```console
$ cd rtcl/
$ ./db2setup
```

## インストールウィザード

### なんか格好良い画面で「新規インストール」をクリック
![スクリーンショット 2016-09-08 23.40.42.png](https://qiita-image-store.s3.amazonaws.com/0/119378/a49d95f5-88b2-1987-3efd-b173ecc1ed0c.png)

### 「次へ」をクリック
![スクリーンショット 2016-09-08 23.41.22.png](https://qiita-image-store.s3.amazonaws.com/0/119378/7613bb10-5edd-2e87-9bcb-915f1ea915e9.png)

### 特にコダワリないので、「標準」を選びました。「次へ」をクリック
![スクリーンショット 2016-09-08 23.42.45.png](https://qiita-image-store.s3.amazonaws.com/0/119378/717fd94b-0453-dfec-e0e8-c996e0d0ca88.png)

### パスワードを設定します。「次へ」をクリック
![スクリーンショット 2016-09-08 23.43.59.png](https://qiita-image-store.s3.amazonaws.com/0/119378/4078183e-7493-c83c-8172-e85e64e876e8.png)

### 「完了」をクリックしてしばらく待ちます・・・
![スクリーンショット 2016-09-08 23.44.30.png](https://qiita-image-store.s3.amazonaws.com/0/119378/81a8d579-b52f-5c55-45b5-31f6720f265c.png)

![スクリーンショット 2016-09-08 23.50.17.png](https://qiita-image-store.s3.amazonaws.com/0/119378/68d8e8f6-1270-7a43-9305-c36d0382d549.png)

**これでインストール完了。とっても簡単でした**


## ためしに、selectでもしてみよう！
ご参考：http://qiita.com/azzeten/items/554552a1150da6607d35#%E6%8E%A5%E7%B6%9A%E7%A2%BA%E8%AA%8D

```console
$ db2 catalog tcpip node dashENT remote dashdb-xxxxxxx.bluemix.net server 50000
DB20000I  CATALOG TCPIP NODE コマンドが正常に完了しました。
DB21056W  ディレクトリーの変更は、
ディレクトリー・キャッシュがリフレッシュされるまで反映
されません。
```

```console
$ db2 catalog db bludb as DDEP at node dashENT
DB20000I  CATALOG DATABASE コマンドが正常に完了しました。
DB21056W  ディレクトリーの変更は、
ディレクトリー・キャッシュがリフレッシュされるまで反映
されません。
```

### 接続！
```console
$ db2 connect to DDEP user hogename using hogepassword

   データベース接続情報

 データベース・サーバー = DB2/LINUXX8664 11.1.0
 SQL 許可 ID            = HOGENAME...
 ローカル・データベース別名 = DDEP
```

###SQLを打ってみる

```console
$ db2 "select count(*) from meisai"

1
---------------------------------
                           10000.

  1 レコードが選択されました。
```

よし!
うまくまとめるアイディアソンとは

# はじめに
最近、アイディアソンに参加する機会が増えました。
しかし、話が盛り上がり過ぎてしまい最後のまとめがうまくいかなかったというような経験がありました。
円滑に楽しくアイディアソンを進めるためにはどの点を意識すれば良いかをメモ程度に書き記していきたいと思います。

#アイディアソンとは
そもそもアイディアソンとは
>特定のテーマについてグループ単位でアイデアを出し合い、それをまとめていく形式のイベント。アイデア(Idea)とマラソン(Marathon) を合わせた造語で、2000年代に米国で使われ始めたと言われている。特定のテーマに興味と知識を持ったITエンジニアやデザイナーらが集まってグループごとにソフトウェアを開発・改良し、その完成度を競うイベント「ハッカソン」(Hackathon:ハッキングの Hackと Marathon を合わせた造語)の事前ミーティングとして開催される場合が多い
（詳しくは[こちら](https://kotobank.jp/word/%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2%E3%82%BD%E3%83%B3-191246)を参照）

#6W4Hを意識し内容を具体化する
#### 6W4Hとは？
- Why（どうしてこれが必要なのか）
- What（どういうアイディアか）
- Who（誰が実行・解決するのか）
- Whom（ターゲットは誰か）
- When（いつ）
- Where（どこで）
- How（どういう手段でこれをやるか）
- How long（運用期間はどれくらいか）
- How many（成功するための目標はどこか）
- How much（お金の予算はいくらか）

これら１０項目を意識しながら話し合いを進めていくことによりまとめるのが簡単になると思います。

####Why（どうしてこれが必要なのか）
まずアイディアソンを行う上で**なぜ必要なのか**を１番に考えなければなりません。
アイディアを形にした際、何かしらの問題解決につながるのか。また、これは本当に必要なのかを考えましょう。
何に困っているかを意識すると考えやすいかもしれません。

####What（どういうアイディアか）
アイディアの内容を具体的にするためにどういうアイディアなのかを考えなければなりません。
１つのアイディアに対して掘り下げることにより具体的なものが見えてきます。

####Who（誰が実行・解決するのか）
何を使って課題を解決するのかを考えなければなりません。　例：アプリ？ウェブサイト？
技術（テクノロジー）を用いて課題解決をすることは可能かもしれません。しかし、それは誰が行うのかを考えることで、よりアイディアが現実味を帯びてきます。
誰が何をできて何をできないかを意識すると考えやすいかもしれません。

####Whom（ターゲットは誰か）
Whyの部分で考えられるかもしれませんが、対象となる人・物を考えなければなりません。
対象者を絞ることにより本当に必要としている機能が見えてくるかもしれません。

####When（いつ）
どのタイミングでアイディアが活用されるのかを考えます。

####Where（どこで）
場所や場面などを想定することでよりアイディアが具体化していきます。

####How（どういう手段でこれをやるか）
ここではアイディアを形にしていく上での具体的な工程を考えます。
アプリを用いて課題を解決していくにしても、どのような機能を用いてどのように解決するのか考えていく必要があります。

####How long（運用期間はどれくらいか）
運用期間を明確化することにより無駄なコストを削減することができるかもしれません。

####How many（成功するための目標はどこか）
成功値を設定することで成功・失敗が明確化されます。
目標を設定することにより分析など次につなげることができます。

####How much（お金の予算はいくらか）
課題を解決するためにはいくらのお金が必要かを明確にする必要があります。
また、時間なども見積もると良いかもしれません。

#まとめ
アイディアソンでまとめる時間があまりないときやまとめるのが苦手と思っている人はこれらを意識してみてはいかがでしょうか？
rollup.jsでpostcssをコンパイルするサンプル

**forkリポジトリーを利用してcssの出力処理をしていた部分が現在では
不要なアテにならないノウハウです！**

本記事は、[Tutorial: How to Bundle JavaScript With Rollup](https://code.lengstorf.com/learn-rollup-js/) を参考に、
postcss周りの設定だけを概括した内容となります。

> https://github.com/pokkur/style_on_rollup

## フォルダ構成
```zsh
Project/
├── src/
│   ├── js/
│   │   └── main.js
│   └── css/
│       └── style.css
├── dist/
│       └── index.html
├── rollup.config.js
└── package.json
```

## 各種設定
```js:package.json
{
  "name": "postcss_on_rollup",
  "version": "1.0.0",
  "description": "",
  "main": "dist/js/main.min.js",
  "scripts": {
    "watch": "rollup -c --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+ssh://git@github.com/pokkur/style_on_rollup.git"
  },
  "author": "Pokkur",
  "license": "MIT",
  "engines": {
    "npm": ">=3.9.0",
    "node": ">=5.11.1"
  },
  "devDependencies": {
    "babel-preset-es2015-rollup": "^1.2.0",
    "lost": "^7.1.0",
    "npm-run-all": "^3.0.0",
    "postcss-cssnext": "^2.7.0",
    "postcss-size": "^1.0.0",
    "precss": "^1.4.0",
    "rollup": "^0.35.9",
    "rollup-plugin-babel": "^2.6.1",
    "rollup-plugin-postcss": "^0.2.0",
    "rollup-plugin-riot": "^0.4.2",
    "rollup-plugin-stylus-css-modules": "^1.2.1",
    "rollup-watch": "^2.5.0",
    "rucksack-css": "^0.8.6"
  },
  "dependencies": {
    "debug": "^2.2.0"
  }
}

```

```js:rollup.config.js
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import precss from 'precss';
import cssnext from 'postcss-cssnext';
import rucksack from 'rucksack-css';
import size from 'postcss-size';
import lost from 'lost';

export default {
  entry: 'src/js/main.js',
  dest: 'dist/js/main.min.js',
  format: 'iife',
  plugins: [
    postcss({
      extensions: ['.css', '.sss'],
      extract: './dist/css/main.css', //css書き出し
      sourceMap: true,
      plugins: [
        precss(),
        cssnext({
          calc: false,
          rem: false,
        }),
        size(),
        rucksack(),
        lost(),
      ],
    }),
    commonjs(),
    babel({
      babelrc: false,
      presets: ['es2015-rollup'],
      include: '**/*.js',
      sourceMap: true
    }),
  ],
};
```

**※[本家でextract対応したようです](https://github.com/egoist/rollup-plugin-postcss/commit/dc14ea4aa2895a9c62ccb9b920c1090c5de7df05)。**
~~rollup-plugin-postcssは、下記プルリクエスト版をビルドしたindex.jsを使用することで、
コンパイルしたcssをjsに書き込まず、ファイル書き出しできます。~~

> https://github.com/zperrault/rollup-plugin-postcss




## main.js
下記のようにcssをインポートしてあげましょう。

```js:/src/js/main.js
import '../css/style.css';
```

## style.css

```postcss:/src/css/style.css
:root {
  --gothic: sans-serif;
}

$base: rebeccapurple;

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  font-family: var(--gothic);
  font-size: 62.5%;

  > .main-content {
    position: relative;
  }
}

.popup {
  background: $base;
  size: 300px 50px;
}

```
Mac でモニタ２台から１台にしたときに、ウィンドウが消える場合

MacOSX では、最後に閉じられたウィンドウの位置を記憶しています。このため、モニター２台使用時に２台目モニターに配置していたウィンドウが、モニター１台にしたときに表示されないという問題が発生します。

ウィンドウメニューから、ウィンドウの最小化などを利用すると現れることがあります。

最終手段としては、モニターの解像度をより大きくスペースを使うように変更します。これでほぼ確実に現れます。

これでも現れない場合は、、
JUnitについて

##ワーディング
- SUT(System Under Test)：テスト対象となるクラスやオブジェクトを指す
- 実測値(actual value)：テスト対象となるオブジェクトやクラスにメソッド呼び出しなどの操作を行い、メソッドが返す値やオブジェクトの変改する状態
- 期待値(expected value)：仕様から一意に決まるもの。仕様変更がなければ不変な値
- テストフィクスチャ(test fixtures)：テストの実行時に必要とされるすべてのデータや状態のこと
- アサーション(assertion)：比較検証のしくみのこと。「テスト結果である実測値が期待値と一致する」という宣言
- アノテーション：Java5で導入された言語仕様の一つで、クラス、メソッド、変数などに補助的な情報を宣言するための仕様。JUnitでも複数のアノテーションを提供している

##テストメソッドの制約
- publicメソッドとする
- org.junit.Testアノテーションを付与する
- 戻り値をvoidとし、引数を持たない

##4フェーズテスト
<<<<<<< HEAD
1. 事前準備(set up)：テスト対象オブジェクトと(SUT)の初期化、必要な入力値、期待される結果などの準備を行う
=======
1. 事前準備(set up)：テスト対象オブジェクト(SUT)の初期化、必要な入力値、期待される結果などの準備を行う
>>>>>>> EDIT_REQUEST
2. 実行(exercise)：SUTに対し、テストする操作を1つだけ行う
3. 検証(verify)：テストの結果として得られた実測値が期待値と同等であるかを比較検証する
4. 後処理(tear down)：次のテストの実行に影響がないように後始末する。「Garbage Collection」によりほとんどの場合は省略

##テストコードのベストプラクティス
- 一定のパターンで同じようなコードが多くなる傾向があるが、プロダクションコードのように整理(重複排除)すべきではない
 - 可動性が低下するため
 - どこまで重複を排除するかはセンスが問われるところ
- 1つのテストケースでは1つのSUTを対象にしなければならない
 - 複数のSUTが存在すると何のテストをしているのかが不明瞭になるため
- クラスごとに対応するテストクラスを作る
 - テスト対象と同じパッケージに
 - クラス名を「テスト対象のクラス名+Test」に
- テスト対象のクラスのインスタンスを生成する際に、変数名を「sut」とすると良い
 - テスト対象オブジェクトがどれであるかが理解しやすくなる
- コンストラクタを検証する際は変数名を「instance」とすると良い
- 実測値の変数名は「actual」、期待値の変数名は「expected」とすると良い
 - 一般的なコーティング標準では、変数名として意味のある名前を付けるのがいいが、テストコードでは仕様上の意味ではなく、期待値であるか実測値であるかの把握が重要
- 4フェーズの区切りをコメントとして記述しておくと読みやすくなる
- <span>@</span>Beforeアノテーションがついたメソッド名は「setUp」とすると良い
- <span>@</span>Afterアノテーションがついたメソッド名は「tearDown」とすると良い

##テストメソッドのベストプラクティス
- メソッド名はJavaの仕様に従う範囲で日本語(母国語)を入れる
 - 関わる全員が日本語をわかる前提
 - メソッド名だけでテスト内容がわかる
 - レポートを出す際にも理解しやすくなる
- 「throws Exceptionの禁止」は適用しない
 - テストメソッドはJUnitによって実行され、例外処理はフレームワーク上で行われます。(予期しない例外が起きても、JUnitがよしなに処理してくれる)

##アサーション
- assertThatメソッドをstaticインポートして利用する
- テストコードを自然言語に近い構文とするため
 - asserThat(actual, is(expected));　→　assert that actual is expected

##JUnitが提供するアノテーション
1. <span>@</span>Test：テストメソッドを宣言する
 - 使用可能お属性
     - expected：例外の創出を検証するテストで、送出が期待される例外クラスを指定する
     - timeout：ユニットテストのタイムアウト値(ミリ秒)を設定する。パフォーマンステストのために利用する機能ではない
2. <span>@</span>Ignore：テストの実行から除外する
 - 基本的には常にすべてを実行し、成功するようにすべきだが、都合により一時的にテストの実行を制御した場合に使用
3. <span>@</span>Before：テストの実行前の処理を行う
 - void、public、引数を持たない必要がある
 - 主に初期化処理のため使うが、クラス内の各テストメソッドの共通処理に限る必要がある
 - テストクラス間で共通処理が必要な場合は「ルール」機能を使うべき
4. <span>@</span>After：テスト実行後に処理を行う
 - void、public、引数を持たない必要がある
 - テストの成功/失敗にかかわらず必ず実行される
5. <span>@</span>BeforeClass：テストの実行前に一度だけ処理を行う
 - void、public、static、引数を持たない必要がある
 - テストメソッドは基本的に独立しているべきだので、使うシーンが多くはない
 - 一部のライブラリの制約によりテストクラス単位で行わなければならない状況や、データの初期化のコストが大きくテストメソッド毎に実行できないような状況で使用すべき
6. <span>@</span>AfterClass：テストの実行前に一度だけ処理を行う
 - 詳細は<span>@</span>BeForeClassと同様
Atom カスタマイズ

# はじめに

- Windows と Mac で設定を共有したいけれど、固有の設定を判別できるようにしたい。

# ステータスバーなどのフォントサイズを変更する

```css
@font-size: 1rem;

html,
body,
.tree-view,
.tooltip,
.tab-bar .tab,
.find-and-replace .find-meta-container,
atom-text-editor[mini],
.btn,
.status-bar,
linter-message {
  font-size: @font-size;
}
```

# プラットフォーム毎に設定を分ける

https://discuss.atom.io/t/platform-specific-settings/15472/3

```coffeescript:init.coffee
if platform = document.body.className.match(/platform-(darwin|win32|linux)/)?[1]
  path = require 'path'
  CSON = require path.join atom.getLoadSettings().resourcePath, '/node_modules/season'
  config = CSON.readFileSync atom.config.getUserConfigPath()
  if config[platform]?
    for own scopeSelector, scopeConfig of config[platform]
      for own namespace, namespaceConfig of scopeConfig
        for own key, value of namespaceConfig
          atom.config.set "#{namespace}.#{key}", value, scopeSelector
```

```json:config.cson
'*':
  'editor':
    'softWrap': true # enable softWrap
'source.python':
  'editor':
    'softWrap': false # except in python files
'darwin':
  '*':
    'editor':
    'softWrap': false # disable softWrap on mac
  'source.python':
    'editor':
    'softWrap': true # except in python files
```

# Packages
## Theme
- slack-ui
- zenburn-syntax

## Utilities
- atom-alignment
- atom-beautify
- autocomplete-paths
- compare-files
- jumpy
- keybinding-cheatsheet
- maximize-panes
- sort-lines
- Sublime-Style-Column-Selection
- toggle-quotes

## View
- block-cursor
- file-icons
- highlight-line

## HTML, Markdown
- browser-plus
- color-picker
- emmet
- markdown-preview-plus
- markdown-writer
- pigments

## Git
- git-plus
- merge-conflicts

## language, programming
- linter
- linter-eslint
- project-manager
- surround-with
最新の安定版どどんとふをConoHaのVPSで導入(投稿時点1.48.00)

#**参考にしたページ**
**[Apache 2.4 + ruby 2.0.0 + どどんとふで最小限構築メモ](http://qiita.com/Akagi/items/64d266df4d2320abb77b)**
**[どどんとふ1.46.00を最小構成のCentOS7から構築できた時の手順](http://qiita.com/kotet/items/ec6701540ea336083405)**
* * *
##はじめに
備忘録です。誰かに見せることを考えて居ません。
ただ質問があればお気軽にどうぞ。答えられるとは限りませんので悪しからず……
自分の場合の導入手順は上の2つとは少し違いましたので書いた次第です。追記は多分あります

#環境
**ConoHa VPS** 月**900**円

|名称|設定値|
|:-----------------:|:------------------:|
|タイプ           |VPS|
|リージョン       |東京|
|メモリ           |1G|
|イメージタイプ    |OS|
|OS種類           |CentOS7.2(64bit)|
|自動バックアップ  |無効|
|ディスク容量      |SSD 50GB|
|接続許可ポートIPv4|全て許可|
|接続許可ポートIPv6|全て許可|
|SSH Key          |新しいキーを登録|
足りない所は自分で決める所です。

#最低限の手順
アップデートする、必要なものをインストールする(updateとupgradeはほぼ同じ)
rootでログイン

```
$ sudo yum update
$ sudo yum install wget libyaml-devel gcc httpd unzip policycoreutils-python
```

Rubyを導入する

```
$ wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.6.tar.gz
$ tar -zxvf ruby-2.1.6.tar.gz
$ cd ruby-2.1.6
$ ./configure
$ sudo make install
$ rm -RI ruby* #Ruby導入に使った不要なディレクトリを削除
$ yum install ruby-devel
(msgpackのビルドに必要なため入れる)
$ gem install msgpack
```

これが済んだら、公開鍵認証でのみログイン出来るユーザーを作ります。

```
$ adduser 新ユーザー名
$ passwd 新ユーザー名
$ gpasswd -a newuser wheel
$ id 新ユーザー名
$ uid=500(新ユーザー名) gid=500(新ユーザー名) groups=500(新ユーザー名),10(wheel)
```

このように表示されたらユーザー作成成功。
公開鍵認証を設定する時に、ユーザーの共有鍵ファイル、及びそれを格納するディレクトリは**必ず**そのディレクトリをホームディレクトリにしているユーザーで作ってやらないと詰まります。1日詰まりました。

どどんとふをセットアップする
[どどんとふのリンク](http://www.dodontof.com/Download/DodontoF_release/)に飛んで一番新しそうな安定版を探す。

```
//どどんとふの取得&展開
$ cd ~
$ wget http://www.dodontof.com/Download/DodontoF_release/バージョン
$ mv DLしたどどんとふのファイル名 D.zip #長ったらしいのでD.zipにしてやりやすくする
$ mv D.zip /var/www/html
$ cd /var/www/html
$ unzip D.zip
$ mv DodontoF_WebSet/* /var/www/
$ mv public_html/* .
$ rm DodontoF_WebSet/ public_html/ -rf
$ mv saveData ..
//所有権とかセキュリティコンテクストとか権限の変更
$ chown -R apache ../*
$ chgrp -R apache ../*
$ cd html/DodontoF 
$ chmod -R 705 saveDataTempSpace fileUploadSpace replayDataUploadSpace ../../saveData ../imageUploadSpace
$ chmod 700 DodontoF*.rb
$ chmod 600 log.txt*
```

/etc/httpd/conf/httpd.conf を編集する。

```httpd.conf
# vim /etc/httpd/conf/httpd.conf
- #AddHandler cgi-script .cgi
+ AddHandler cgi-script .cgi .rb

+ <Directory "/var/www/html/DodontoF/">
+ DirectoryIndex DodontoF.swf
+ Options ExecCGI
+ </Directory>
```

config_local.rbを作る。ここは人それぞれだけど…

```config_local.rb
# vim src_ruby/config_local.rb
$isMessagePackInstalled = true
#せっかくVPSなんだから、これで高速化オプションを適用しよう
```

DodontoFServer.rbを編集する。

```vim DodontoFServer.rb
- #!/user/local/bin/ruby -Ku
+ #!/user/bin/ruby -Ku
```

編集の必要が無かったけど必要な変更オプション

```
# vim /etc/selinux/config
- SELINUX=enforcing
+ SELINUX=disabled
```

httpdをstartする。enableも入れると再起動したタイミングでhttpdが起動する。

```
$ systemctl enable httpd
$ systemctl start httpd
```
wp cliが普段動いていたのに何かしらのerrorで急に動かなくなった場合

いままで動いていたWP-CLIが動かない！そんなときはたいていバージョンの問題です。
以下のようなエラーが出る感じですね。

```
PHP Fatal error:  Uncaught Error: Call to undefined function apply_filters() in /wp-includes/load.php:317
Stack trace:
#0 /usr/local/Cellar/wp-cli/0.23.1/php/utils-wp.php(22): wp_debug_mode()
#1 /usr/local/Cellar/wp-cli/0.23.1/php/wp-settings-cli.php(59): WP_CLI\Utils\wp_debug_mode()
#2 /usr/local/Cellar/wp-cli/0.23.1/php/WP_CLI/Runner.php(807): require('/usr/local/Cell...')
#3 /usr/local/Cellar/wp-cli/0.23.1/php/WP_CLI/Runner.php(755): WP_CLI\Runner->load_wordpress()
#4 /usr/local/Cellar/wp-cli/0.23.1/php/wp-cli.php(21): WP_CLI\Runner->start()
#5 /usr/local/Cellar/wp-cli/0.23.1/php/boot-fs.php(17): include('/usr/local/Cell...')
```

その際はとりあえずWP-CLIを最新バージョンにしてみましょう

```
wp cli update
```

でアップデートできるはずです。もしそれでもエラーが出る場合。例えば以下の様な感じです

```
Error: You can only self-update Phar files.
```

権限がなにかしらおかしい可能性が高いです。その場合は、再度インストールをし直したほうがさくっと進められる可能性が高いです。

- [WP-CLIのインストール方法](http://wp-cli.org/ja/)

よい、WP−CLI生活を
Riot.js入門 なるべく簡単に とはいえ 少し実用的に

# やりたいこと

なるべく簡単に、とはいえそこそこ実用的なくらいに、``Riot.js`` を使いたい。
``Riot.js``はランタイムでのコンパイルなども可能です。開発者てきにはメリットありますが、多少ユーザメリットが感じられないので……プリコンパイルしてサーバにあげたいです。あと、開発環境的にあんまり複雑なことすると手軽感がなくなるので、最低限ですませたい。
ということでメモがてら作ってみました。

## 環境構築
### npmインストール
してください。

### 各種 npm install

```
$ npm install -g riot
$ npm install --save-dev gulp
$ npm install --save-dev gulp-riot
$ npm install --save-dev gulp-connect
```

gulpで使いたいのでいろいろインストールしておく。

### テンプレート的なファイルの準備

```gulpfile.js
var gulp = require('gulp');
var riot = require('gulp-riot');
var connect = require('gulp-connect');

gulp.task('build', function(){
    gulp.src('./src/*.html')
    .pipe(riot())
    .pipe(gulp.dest('./dist'));
});

gulp.task('watch', function(){
    gulp.watch('./src/*.html', ['build']);
});

gulp.task('connect', function(){
    connect.server({
        root: '.'
    });
});

gulp.task('default', ['connect', 'watch']);
```

```index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>my web site</title>
</head>
<body>
    <app></app>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.1/riot.min.js"></script>
    <script src="./dist/index.js"></script>

    <script>
        riot.mount('app');
    </script>
</body>
</html>
```

```src/index.html
<app>
    <h1>My Web Site</h1>
    <p>hogehoge</p>
</app>
```

上記のファイルをまるっと作る。

## ビルド

``gulp``の実行。

```
$ gulp
```

これでソースをいじるとかってにコンパイルされてブラウザで確認ができます。

## 本来なら次にやること

個人的に、あまり``Riot.js``に執着して流儀にのっかって心中はしたくないので、なるべく、疎な感じにしておきたいです。なので、基本は普通に HTML を書いて使いまわしのコンポーネント部分だけを ``Riot.js`` にする方向で作りたいので、下記の感じで進めていきたいと思います。

* ``xxxx.html`` を作る。
* 何か他のページと共通化したい部分だけを``Riot``の流儀で書いて ``src/*.html`` に配置する
* ``./xxxx.html`` と ``./dist/*`` をサーバにアップする
apt-cyg をインストールする(2016年版)


Windows上で cygwin を使っているが、setupメニューでパッケージインストールするのは、面倒だしバッチ処理ができずに不便だ。そこで apt-cyg を導入した。
> Windows10ならば cygwin をやめて Bash on Ubuntu on Windows を使えば apt-get が使えるのはわかっているが、それはまた別の話。

Qiita上には、すでにいくつか記事があって参考にしたが、公式リポジトリの情報が古かったり、githubからcloneで取ってくる事例が見当たらず、改行コードで嵌ったので、覚え書きとして記事にした。

## 導入方針

* cygwinターミナルの上で github から clone し、バージョンアップへの追随を git pull で可能にする.

## 手順
```bash
# cygwinターミナルを開き、リポジトリをクローンする.
# 公式は transcode-open だが、野良も含めて多数の fork あり.
# 下記の「参考記事」に紹介されているので、お好みのリポジトリを選べば良い.
git clone https://github.com/transcode-open/apt-cyg.git
cd apt-cyg/

# gitの改行コード設定を、Windows環境にあわせてCRLFにしている場合は,
# 改行コードLFでapt-cygを再取得する.
git config core.autocrlf input
rm -f apt-cyg
git reset --hard

# apt-cygをPATH上に置く.
install apt-cyg /usr/local/bin

# 国内のcygwinリポジトリを登録する.
apt-cyg -m ftp://ftp.iij.ad.jp/pub/cygwin/ update

# 以後は、バージョンアップのタイミングで下記を実行する.
cd apt-cyg/
git pull
install apt-cyg /usr/local/bin
```

### 参考記事
http://seesaawiki.jp/w/kou1okada/d/apt-cyg
http://qiita.com/tkzwyk/items/24ac4d55a3a1d8951708
http://qiita.com/FSMS/items/68b5956301d987d1be2b
Kube-dnsを1ネームスペースで試す

#概要
kube-dnsをデフォルトのネームスペースで動かします。
cluster-dnsサンプルを動かし複数のコンテナ間で通信できることを確かめます。
[「KubernetesをUbuntuで動かす」](http://qiita.com/mmitti/private/6c1bedbcffdda6a63473)で構築した環境が前提となります。

#動作環境
上記の記事と同じ環境となります。

||masterサーバー|nodeサーバー|
|:----|:----|:----|
|ホスト名|master|node1|
|IPアドレス|192.168.137.20|192.168.137.21|
|動作しているサービス|kube-apiserver<BR>kube-controller-manager<BR>kube-scheduler<BR>**kube-dns**|kubelet<BR>kube-proxy|

dnsサーバー(kube-dns)はmaster上53番ポート（デフォルト値）で動作しています。
また、今回はドメイン名をmmitti.infoとして記載しています。
必要に応じて変更してください。（デフォルトはcluster.localです。）


#master側の構築
kube-dnsのインストールです。
途中まで[こちらの記事](http://qiita.com/mmitti/private/6c1bedbcffdda6a63473#kubernetes%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A8%E8%A8%AD%E5%AE%9A)と同じ手順となります。

```
wget https://github.com/kubernetes/kubernetes/releases/download/v1.3.6/kubernetes.tar.gz
tar xzvf kubernetes.tar.gz
cd kubernetes/server
#お使いの環境に合わせて
tar xzvf kubernetes-server-linux-amd64.tar.gz
```

続けてkube-dnsのバイナリをコピーします。

```
sudo cp kubernetes/server/bin/kube-dns /opt/bin/
sudo ln -s /opt/bin/kube-dns /usr/local/bin/
```

/etc/init/kube-dns.confを以下の内容で作成します。
KUBE_DNS_OPTSは環境に応じて変更してください。

```
description "Kube-dns service"
author "@mmitti"

respawn

start on started kube-apiserver
stop on stopping kube-apiserver

pre-start script
        KUBE_DNS=/opt/bin/$UPSTART_JOB
        if [ -f /etc/default/$UPSTART_JOB ]; then
                . /etc/default/$UPSTART_JOB
        fi
        if [ -f $KUBE_DNS ]; then
                exit 0
        fi
    exit 22
end script

script
        KUBE_DNS=/opt/bin/$UPSTART_JOB
        KUBE_DNS_OPTS="--kube-master-url=http://master:8080 --domain=mmitti.info"
        if [ -f /etc/default/$UPSTART_JOB ]; then
                . /etc/default/$UPSTART_JOB
        fi
        exec "$KUBE_DNS" $KUBE_DNS_OPTS
end script
```

#node側
kubeletのパラメータの変更を行います。
/etc/init/kubelet.confのKUBELET_OPTSに以下を追記します。

```
--cluster-dns=192.168.137.20 --cluster-domain=mmitti.info
```

なお、cluster-dnsとcluster-domainを設定しないと以下のエラーが出るようです。

```
kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy.
```


#cluster-dnsサンプル
解凍したkubernetes以下のexamples/cluster-dnsに移動して作業してください。

dns-frontend-pod.yaml(差分のみ示します)

```
14c14
<         - http://dns-backend.development.cluster.local:8000
---
>         - http://dns-backend.default.svc.mmitti.info:8000
```

以下のコマンドを順に実行してpodを作成します。

```
kubectl create -f dns-backend-rc.yaml
kubectl create -f dns-backend-service.yaml
kubectl create -f dns-frontend-pod.yaml
```

最後に動作を確認します。

```
kubectl logs dns-frontend
```
以下のように表示されればOKです。

```
10.254.104.56
Send request to: http://dns-backend.default.svc.mmitti.info:8000
<Response [200]>
Hello World!
```

なお、登録されるサービスのドメインは`サービス名.ネームスペース.svc.ドメイン`となります。

#参考
https://github.com/kubernetes/kubernetes/tree/master/build/kube-dns
コメント記法

コメントは読むのに時間がかかるし、画面も占有する。
コメントを書く際は、読むに値する内容を記述しよう。

コードを書く際は、下記点を意識しよう。
* コードを読んでわかることはかかない
* コメントを記載する前に、リファクタリングをしてコードで伝えられるようにならないか考える

また、下記の様なルールを採用して、コメントを記述していこう。

| 記法 | 意味 |
|-----|-----|
| TODO: | 後でやる|
| FIXME: | 不具合のあるコード|
| HACK:| その場しのぎの解決|
| XXX:| 大きな問題がある|
Re:dash のグラフを画面キャプチャして投稿してくれる slack bot を書いたよ！

https://github.com/hakobera/redashbot

こんな感じで動きます。

![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/25774/f714ff83-5957-17bc-75c4-dee54a2c8efd.png)

メッセージのフォーマットは、`@botname <visualization URL>`という形式。
例: `@redashbot https://your-redash-server.example.com/queries/1#2`

[【Slack×Re:dash】リアルタイムKPI通知をコード0行で実現する](http://data.gunosy.io/entry/slack-redash-kpi-notify)

上の画像でもやってますが、上記記事に書いてある、Slack の reminder 機能との組み合わせでも動作します。

公式インテグレーションと機能は重複するのですが、以下のモチベーションで書きました。

- 公式とはいえ、外部になんでもできる API Key を預けるのは微妙
- Private な環境に立っている re:dash とも連携できる
- Heroku でさくっと動かせる (Hobby プラン以上が必要なのでお金がかかります）
- 複数の re:dash にも対応できる<del>（予定）</del> 対応しました！ https://github.com/hakobera/redashbot/pull/1 Thanks @yuya_takeyama 

早速使ってますが、便利です。