OmniAICreator/Qiita-1.07M huggingface dataset:
VimでCoffeeScriptのSyntaxHighlightを当てる方法

こんかいは[これ](https://github.com/kchmck/vim-coffee-script)を使います


# install

```rb
mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
```

# add lines to .vimrc

```vim
# coffeescript
call pathogen#infect()
syntax enable
filetype plugin indent on
```

# Clone the vim-coffee-script repo into ~/.vim/bundle/

```rb
cd ~/.vim/bundle && \
git clone git://github.com/tpope/vim-sensible.git
```

# references

https://github.com/tpope/vim-pathogen#installation
https://github.com/kchmck/vim-coffee-script
poltergeistでjQuery UIのAutocompleteをテストする


poltergeistでAutocompleteのテストをしようとしたらハマったのでメモ。

以下のようなメソッドを用意しておく。

```ruby
def fill_autocomplete(field, options = {})
  fill_in field, with: options[:with]

  page.execute_script %Q{ $('##{field}').trigger('focus') }
  page.execute_script %Q{ $('##{field}').trigger('keydown') }
  selector = %Q{ul.ui-autocomplete li.ui-menu-item a:contains("#{options[:select]}")}

  expect(page).to have_selector('ul.ui-autocomplete li.ui-menu-item a')
  page.execute_script %Q{ $('#{selector}').trigger('mouseenter').click() }
end  
```

あとはそれを使うだけ。例えばこんな感じ。

```ruby
require 'rails_helper'

feature "Users" do
  scenario "sign up", js: true do
    visit sign_up_path
    fill_in :username, with: 'test'
    fill_in :email, with: 'test@example.com'
    fill_in :password, with: 'test'
    fill_autocomplete('country', with: 'Japan')
    click_button :submit
  end
end
```

参考：[How to Do jQuery UI Autocomplete With Capybara 2](http://ruby-journal.com/how-to-do-jqueryui-autocomplete-with-capybara-2/)
rubyでファイル名を抜き出す

正規表現やFileクラスを用いて自分の好きな形にする。

例えば、以下のような画像URLがあった場合
`http://hogehoge.co.jp/mono/actjpgs/medium/japan.jpg`

**・japn.jpgを取り出す**
***

```hoge.rb
file_url = "http://hogehoge.co.jp/mono/actjpgs/medium/japan.jpg"
p File.basename(file_url) # => "japan.jpg"

#Fileクラスを使用しない場合

split_file = file_url.split("/")

p split_file # => ["http:", "", "hogehoge.co.jp", "mono", "actjpgs", "medium", "japan.jpg"]

p split_file[6] # => "japan.jpg"
p split_file[-1] # => "japan.jpg"
```


**・meduim/japn.jpgを取り出す**
***

```hoge.rb
file_url = "http://hogehoge.co.jp/mono/actjpgs/medium/japan.jpg"

# pattern1

  if matchfile = file_url.match(/medium\/.+/)
	puts matchfile # => medium/japan.jpg
  end

# pattern2

  if file_url =~ /(medium\/.+)/
	puts $1        # => medium/japan.jpg
  end

# pattern3

split_file = file_url.split("/")
p split_file[-2..-1].join("/")  # => medium/japan.jpg
```
=~は（）をつけないと$1に値がセットされませんので注意を。
jacksonを使ってjsonをデシリアライズする

# 最初に

play(java)でデータのプロセス間の通信をする際にデフォルトで入っているjacksonを使ってjsonでやりとりするようにしたところ、導入のところで少し引っかかった。

# 引っかかった点

## オブジェクト内にクラスを定義するときはstaticなクラスにしないと落ちる

テストのためにクラス内に変換先のオブジェクトをpublic classで書いたりするとエラーになる。

``` App.java
    public class App extends Controller{
        public static Result index() throws Exception{
            ObjectNode node = Json.newObject();
            Test test = Json.fromJson(node, Test.class);
            return ok(node);
        }
        public class Test {
            private String test;
            public String getTest() {return test;}
            public void setTest(String test) {this.test = test;}
        }
    }
```

結果

    play.api.Application$$anon$1: Execution exception[[RuntimeException: org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class controllers.App$Test]: can not instantiate from JSON object (need to add/enable type information?) at [Source: N/A; line: -1, column: -1]]]

外に出せばOK。この辺はインナークラスの扱いを理解していれば言うまでもなさそう。

## 空入力のコンストラクタがないと怒られる

また、デシリアライズ先のオブジェクトに引数が空のコンストラクタを用意しないと怒られる。↓みたいなのは怒られる。エラーは↑と同じ。
何もコンストラクタを記述しなければ気にする必要はないから忘れてると地味にハマるかもしれない。

``` Test.java
    public class Test {
        private String test;
        public Test(String test){}
        public String getTest() {
            return test;
        }
        public void setTest(String test) {
            this.test = test;
        }
    }
```

## インスタンス化したObjectMapper以外の物を使うと超遅い

↓みたいなやり方もあるが超遅い。一桁くらい処理時間に違いがある。

``` java
    new ObjectMapper().readValue(json, Test.class);
    Json.fromJson(json, Test.class);
```

処理速度を比較すると↓みたいな感じ。なんかの機能で大量のjson化されたオブジェクトをデシリアライズするとかやろうとすると顕著な差が出る。

ObjectMapper#readValue >> インスタンス化+ObjectMapper#readValue >= Json.fromJson

ObjectMapperは使い回しが十分に効くので、色んなところで使うようならそれらの親クラスを作ってそこでfinal staticで初期化したものを使ってしまうといいかも知れない。試したことはない。

## 余計な情報がjsonの中に含まれてると例外が飛んでくる

例えば↓みたいなのを動かすと"UnrecognizedPropertyException"を投げてくる。
非チェック例外なのでインタフェースの定義が変わって追加が入った場合サービスがまともに機能しなくなるリスクがある。

``` App.java
    public class App extends Controller{
        public static Result index() throws Exception{
            ObjectNode node = Json.newObject();
            node.put("no", "");
            Test test = Json.fromJson(node, Test.class);
            return ok(node);
        }
        static class Test {
            private String test;
            public String getTest() {return test;}
            public void setTest(String test) {this.test = test;}
        }
    }
```

対応法は↓のアノテーションを付けるだけ。デフォルトだとfalseとして扱われ、例外を投げる。
＠JsonIgnoreProperties(ignoreUnknown=true)

変更後↓

``` App.java
    public class App extends Controller{
        public static Result index() throws Exception{
            ObjectNode node = Json.newObject();
            node.put("no", "");
            Test test = Json.fromJson(node, Test.class);
            return ok(node);
        }
        @JsonIgnoreProperties(ignoreUnknown=true)
        static class Test {
            private String test;
            public String getTest() {return test;}
            public void setTest(String test) {this.test = test;}
        }
    }
```
文化とAPI

これは[Web API Advent Calender](http://www.adventar.org/calendars/571)  11日目の記事です。

我々のひと世代上の年代、メインフレームやクライアントサーバ向けのアプリケーション開発を行ってきた世代では、システムエンジニアと言うとシステムデザイナーのようなロールだったとよく耳にします。また日本でのプログラマーは、欧米などで言うところのコーダーに意味合いとしては近く、システムエンジニアが仕様化したドキュメントを、コンピューター言語に翻訳する役割という訳です。

それが最近はそもそもシステムをスタンドアローンでゼロから作り上げる事は少なく、共通機能はクラウドから安価に持ってきて使うという技術革新がサーバ、ネットワーク、セキュリティ機器だけでなく、アプリケーション実装に必要なミドルウェア、各種ファンクションサービスで出現している。

そうなってくると、プログラマーはシステムエンジニアが従来から担当していた領域にも足を出せるようになったと捉えられます。勿論、そういったクラウドサービス事業者へのイネーブルメントを売りにしているベンダー企業もありますので、世の中から全くそういう仕事が要らなくなったという訳ではありません。

従来のプログラマーがシステムエンジニアの領域に入ってくると、システムエンジニアはどうしたらいいのか。より上流の、例えばコンサルティングやアーキテクトなどの複合領域でシステムをインテグレートするような領域に移行していくのでは考えています。じゃあ、コンサルタントは？
クラウドによって、サービス開発に柔軟性が出た事で、ブルーオーシャンは計りきれない広がりを見せているので、これからのコンサルタントはビジネスを創りだすようなロールが求められるでは、と。

ここで、ちょっと余談ですが、以前「システム開発」という領域で日米の事業の違いをインタビューなどを通してリサーチした事があります。興味深いのは、エンジニアキャリアパスが大きくここに影響していた事でした。欧米では、

**・高いエンジニア給与**
**・２〜３年での転職サイクル**

という文化的背景があり、限られた時間内での効率的で、集中出来る開発環境の整備に余念がないという現実があります。一方で、各個人も頻繁に転職をする為には常に客観的に技術力を把握して、技術力向上に余念がない。これが、利便性の高いクラウドサービス台頭を促進していると考えられ、クラウドサービス、転職サイクル面でのオープン化が進むエコシステムを形成しています。

オンプレミスからクラウド、クラウドのAPI利用、ソフトウェア処理の浸透、就業文化の違い、効率化の考え方。APIは、システムをサービスとして利用させる大きなイノベーションであり、Webの足をシステムに食わせると思いきや、色々なファクターが絡んでいる。

ここが面白いなあ〜と思い、APIエコノミーでビジネスをやろうと決めて、はや１年以上が過ぎました。まだまだここから色々な事が繋がって行くWeb APIに期待！
Shift_JISのCSVを作成するCSVSjisというgemを作った

ExcelってなぜかShift_JISでcsvを読み込むので、UTF-8で生成すると文字化けするんですよね。
業務でわりとShift_JISのcsvを作るケースがあるのでgem化しました

csv_sjis | RubyGems.org
https://rubygems.org/gems/csv_sjis

halenohi/csv_sjis | github.com
https://github.com/halenohi/csv_sjis

## 使い方

```
data = [
  ['名前', '年齢'],
  ['こうぞう', 29]
]

file_path = Pathname.new(File.dirname(__FILE__) + '/sample.csv')

CSVSjis.open(file_path, 'w') do |csv|
  data.each do |row|
    csv << row
  end
  csv.close
end

file_path.read # => "名前","年齢"\n"こうぞう",29\n
```

デフォルトでencodingがShift_JISに設定されてます

UTF-8で保存したければオプションを指定します

```
CSVSjis.open(file_path, 'w', encoding: 'UTF-8') do |csv|
  csv << row
  csv.close
end
```

## 変換できない文字の対応

UTF-8からShift_JISに変換できない文字がある場合普通だと ```Encoding::UndefinedConversionError```という例外が発生してしまうんですが、```?```にreplaceされるようにしています。

この部分はこちらを参考にさせていただきました

Ruby - CSV.open で Encoding::UndefinedConversionError になる場合 - Qiita
http://qiita.com/kano-e/items/19df487e163c606bd652

が、しかしあまり```?```になってほしくはないので事前に互換性のある文字に置換するようにしています。

置換する文字は以下のように対応しています
```
－ => -
～ => ~
```

この部分はこちらを参考にさせていただきました

Ruby - UTF-8からShift_JISに変換する時の注意 - Qiita
http://qiita.com/akkun_choi/items/a1fbde5d6d065df3fc97

Unicodeの似た文字を整理してみた - y-kawazの日記
http://d.hatena.ne.jp/y-kawaz/20101112/1289554290

まだまだ置換の対応が不十分だと思うので新しい文字を見つけ次第追加して育てていきたいと思います。
cpandocべんりってはなし

# 前置き
perl入学式でなぜcpandocの話をするのかというと、 Perl入学式とPerlの advent calenderを間違えたからです、、、。
この記事ではkarupaneruraさんがperldocの解説のおまけとして紹介していたcpandocの使い方と、自分が作ったccpandocの紹介をしたいと思います。

# cpandocの使い方
cpandocはPod::Cpandocをインストールすると使えるようになるコマンドで、ローカルマシンに存在しないモジュールでもperldoc相当の情報が得られます。
オプションもperldocとほぼ同じです。

    cpandoc -m Acme #コード表示
    cpandoc Acme #ドキュメント表示

cpandocにしかない機能として、変更履歴の取得があります。

    cpandoc -c Acme #Changesを取得

# 自分の利用例

* twitter botがcpanモジュールの更新を通知してきたらcpandoc -c で素早く変更内容を見る
* パスが通ってなくてドキュメントが見れないけど、余計なこと考えたくないとき

# ccpandocの話

で、Changesって自分の場合短時間に何回も見ることが多いです。

その場その場はもう見ないだろと思って消すんですが、短期記憶が弱すぎて4,5回見ることが多いので、キャッシュすることにしました。
**Pod::Cpandoc::Cache**をインストールすると、ccpandocコマンドが使えるようになります。

    $ time ccpandoc -c Acme
    real 0m0.743s
    user 0m0.221s
    sys  0m0.093s

    $ time cpandoc -c Acme
    real 0m2.325s
    uer 0m0.200s
    sys  0m0.092s


ccpandoc使わなくてもemacsからcpandocを使えるようにしてバッファに残しておけばいいんですけど、誰か。

# 参考

モジュールを書いたときのブログ記事
http://blog.tokubass.net/2014/06/cpandoc.html

CPAN Module の変更点をサクッと調べる方法
http://blog.livedoor.jp/xaicron/archives/54445186.html
プロキシ環境下でAndroid Studioを起動するとエラーが起きる

[Android Studio](http://developer.android.com/sdk/index.html)をインストールして起動したところ、以下のようなメッセージでエラーダイアログが出てそこから進めなくなってしまいました。

```
The following SDK components were not installed: extra-android-m2repository, tools, addon-google_apis-google-21, android-21, sys-img-x86-addon-google_apis-google-21, source-21, extra-google-m2repository
```

原因はプロキシ設定ができていないことで、設定ファイルを書き換えると、起動時に設定のためのウインドウが表示されるようになります。
（このときいくつかエラーダイアログが出る場合がありますが、めげずに何回か試すと起動できました）

* * *
**手順**
* （ユーザーフォルダ）/.AndroidStudio/config/options/other.xml を開く
* `USE_HTTP_PROXY`と`USE_PROXY_PAC`の設定をそれぞれ`true`にする

```other.xml
    :
    <option name="USE_HTTP_PROXY" value="true" />
    <option name="USE_PROXY_PAC" value="true" />
    :
```
* Android Studioを起動する

* * *

（起動の途中でGUIから設定できるようになっていると便利ですね・・）


※ 参考にしたサイト
・[Android Studio doesn't start, fails saying components not installed - Stack Overflow](http://stackoverflow.com/questions/27376465/android-studio-doesnt-start-fails-saying-components-not-installed)
MAMP memcache install

久しぶりにMAMPを最新にアップデート
http://www.mamp.info

ls /Applications/MAMP/bin/php
_php5.6.2/ php5.1.6/  php5.2.17/ php5.3.29/ php5.4.34/ php5.5.18/

のように新しい物をリネームしとけば自動的に最新2つがMAMP settingからの選択肢になるのでPHPバージョンの切り替えに便利。

各バージョンへのmemcacheインストールのメモ
cd /Applications/MAMP/bin/php/php5.4.34
mkdir include
cd include
wget http://pa1.php.net/get/php-5.4.34.tar.gz/from/this/mirror
tar xvzf php-5.4.34.tar.gz
mv php-5.4.34 php
cd php/ext
/Applications/MAMP/bin/php/php5.4.34/bin/pecl download memcache
tar xvzf memcache-2.2.7.tgz
cd memcache-2.2.7
/Applications/MAMP/bin/php/php5.4.34/bin/phpize
cd ../..
./configure
cd ../../bin
./pecl i memcache
Rails で Rakeタスクを作る

## 基本タスク

#### 1. Rakeファイルを作成
ここでは`hello`というタスクを作成してみる。

```bash
$ rails g task hello
```

`lib/tasks`に`hello.rake`が作成される。中身は

```hello.rake
namespace :hello do
end
```

#### 2. description（説明） と task（タスク）を記述

```hello.rake
namespace :hello do
  desc "朝のあいさつ"
  task :morning do
    p "おはよー"
  end

  desc "昼のあいさつ"
  # モデルにアクセスする場合はenvironmentが必要
  task :noon => :environment do
    user = User.first
    p "こんにちは、#{user.name}さん"
  end
end
```

rakeタスクに追加されているか確認

```bash
$ rake -T

rake hello:morning
rake hello:noon
```

#### 3. 実行してみる

```bash
$ rake hello:morning
"おはよー"
```

## ログを出力する

```hello.rake
namespace :hello do
  desc "朝の挨拶"
  task :morning do
    logger = Logger.new('log/development.log')
    logger.info('task morning が起動されました。')
    p "おはよー"
  end
end
```

## namespaceを入れ子にする

```hello.rake
namespace :hello do
  # タスクの説明

  namespace :morning do
    desc "丁寧なあいさつ"
    task :politely do
      p "おはようございます"
    end

    desc "フレンドリーなあいさつ"
    task :friendly do
      p "おはよー"
    end
  end
end
```

```bash
$ rake hello:morning:friendly
"おはよー"

$ rake hello:morning:politely
"おはようございます"
```

## 引数を渡す

#### 環境変数で渡す

```hello.rake
namespace :hello do
  desc "朝のあいさつ"
  task :morning do
    p ENV['GREETING']
    p ENV['TO_NAME']
  end
end
```

```bash
$ rake hello:morning GREETING="おっはよー" TO_NAME="太郎"
"おっはよー"
"太郎"
```

* グローバルに定義されている環境変数と名前が被っていないか確認した方が良い。

#### タスクに直接渡す

```hello.rake
namespace :hello do
  desc "朝のあいさつ"
  task :morning, 'GREETING', 'TO_NAME' do |task, args|
    p args['GREETING']
    p args['TO_NAME']
  end
end
```

```bash
$ rake hello:morning["おっはよー", "太郎"]
"おっはよー"
"太郎"
```
SimpleCovでカバレッジが取れないんですけど！の対処法

タイトルの通り、rails以外のアプリ作って久しぶりにSimpleCovでカバレッジ計測しようとしたらずっと0.0 / 0.0 LOC (100.0%) covered.とか言われて困ったので備忘録

----

答えは http://studio.tgl.jp/blog/?p=1803 にありました。

> カバレッジ対象のソースはSimpleCov#start以降にrequireする必要があります。
> SimpleCov#start前にrequireするとカバレッジが取れませんので注意です。

#### 詳細
元のspec/spec_helper.rb

```
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'hogehoge' #評価したいコード
require 'simplecov'
SimpleCov.start
```

修正後のspec/spec_helper.rb

```
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'simplecov'
SimpleCov.start
require 'hogehoge' #評価したいコード
```

* たったこれだけだけどハマりました…
[PHP]値配列にワンライナーでラベルを付けるやつ

`$hoge`が対象の配列
`$master`が配列のラベルマスタ

array_flipで`$hoge`のkey valueを逆転させ、
array_intersect_keyで第一引数の`$master`の中で、keyが一致したものだけを返却してるだけ。
array_mapとかでやりたくなるけど、こっちのほうが割とシンプル
配列操作系豊富で色々考えるのたのすぃー

```php:hoge.php
$master = array(0 => '東京', 1 => '神奈川', 2 => '埼玉');
$hoge = array(0 => 1, 1 => 2);
var_dump(array_intersect_key($master, array_flip($hoge)));
```

```
array(2) { [1]=> string(9) "神奈川" [2]=> string(6) "埼玉" }
```
【Ｎumpy】savetxt()をappendモードで呼び出す

# What's this
ndarrayをファイルに保存する関数savetxt()をappendモードで行う方法。

#コード
```py:savetxt.py
import numpy

a = [[3, 4, 5], [6, 7, 8], [9, 10, 11]]
nda = numpy.array(a)

a2 = [[-3, -4, -5], [-6, -7, -8], [-9, -10, -11]]
nda2 = numpy.array(a2)

with open('output.txt', 'a') as f_handle:
	numpy.savetxt(f_handle, nda)
	numpy.savetxt(f_handle, nda2)
```

#参考
http://stackoverflow.com/questions/17731419/appending-a-matrix-to-an-existing-file-using-numpy
http://stackoverflow.com/questions/19793692/strings-and-arraysmatrix-row-wise-numpy-savetxt
SDKManagerが起動しない

ある日突然SDKManagerが起動しなくなってしまいました。
AndroidSDKの`tools/android.bat`を起動すると↓のようになってしまう･･

```
tools>android.bat
-v / -version: Only prints the Java version found.
'-v' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
無効なパスの指定です
ERROR: SWT folder '' does not exist.
Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.
```

`tools/lib/find_java.bat`でJavaのexeファイルの場所を探しているところでうまくいっていないよう。

```
for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s') do set java_exe=%%a
```

この時点での`java_exe`を確認すると、`-v / -version: Only prints the Java version found.`のようになっていて、これが最初のエラーになっているらしいです。

ヘルプを出力したときの最後の行が代入されている？

```
tools>lib\find_java32.exe -h
Outputs the path of the first Java.exe found on the local system.
Returns code 0 when found, 1 when not found.
Options:
-h / -help       : This help.
-t / -test       : Internal test.
-e / -error      : Print an error message to the console if Java.exe isn't found.
-j / -jdk        : Only returns java.exe found in a JDK.
-s / -short      : Print path in short DOS form.
-p / -path `dir` : A custom path to search first. Pass in JDK base dir if -j is set.
-w / -javaw      : Search a matching javaw.exe; defaults to java.exe if not found.
-m / -minv #     : Pass in a minimum version to use (default: 1.6).
-v / -version: Only prints the Java version found.
```

結局、[こちら](http://d.hatena.ne.jp/hiro-nagasaku/20130521/1369096256)を参考に`find_java.bat`でJavaのexeファイルのパスを直接定義したら、動くようになりました。
（なぜ`-v / -version: ...`になってしまうかは結局よくわかりませんでした・・）

```find_java.bat（抜粋）
rem Check we have a valid Java.exe in the path. The return code will
rem be 0 if the command worked or 1 if the exec failed (program not found).
for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s') do set java_exe=%%a
if not defined java_exe goto :CheckFailed

:SearchJavaW
rem Check if we can find a javaw.exe at the same location than java.exe.
rem If that doesn't work, just fall back on the java.exe we just found.
for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s -w') do set javaw_exe=%%a
if not exist "%javaw_exe%" set javaw_exe=%java_exe%
```
↓↓

```find_java.bat（抜粋）
rem Check we have a valid Java.exe in the path. The return code will
rem be 0 if the command worked or 1 if the exec failed (program not found).
rem for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s') do set java_exe=%%a
set java_exe="C:\PROGRA~1\Java\JDK18~1.0_2\bin\java.exe"
if not defined java_exe goto :CheckFailed

:SearchJavaW
rem Check if we can find a javaw.exe at the same location than java.exe.
rem If that doesn't work, just fall back on the java.exe we just found.
rem for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s -w') do set javaw_exe=%%a
set javaw_exe="C:\PROGRA~1\Java\JDK18~1.0_2\bin\javaw.exe"
if not exist "%javaw_exe%" set javaw_exe=%java_exe%
```

※ 参考にしたサイト
・[android.batが正常に動作しない件について - BLOG_2012～(PC,Audio,etc・・・・)](http://d.hatena.ne.jp/hiro-nagasaku/20130521/1369096256)
[Fabric]引数にbooleanを使おうとしてはまったので対策をメモ

背景
====

たとえば、

```py
from fabric.api import run

def test(flag=False):
    if flag is True:
        run("echo hoge")
    else:
        run("echo fuga")
```
とか書いて、

```sh
$ fab -H host test:flag=True
```

とか実行しようとすると、
`fuga` が出力されたりする。

Fabric で渡す引数は str。

```py
>>> "True" is True
False
```

なんらかの形で変換をかけてやる必要がある。

対応策
=======

その1 キャストする
-------------------

単純にキャストする。

```py
from fabric.api import run

def test(flag=True):
    if bool(flag) is True:
        run("echo hoge")
    else:
        run("echo fuga")
```

```sh
$ fab -H host test:flag=False
fuga
```

だけど、

```sh
$ fab -H host test:flag=false
```

とかで死にます。`"True"`/`"False"`はbooleanにキャスト出来るけど、`"true"`/`"false"`はキャスト出来ない

その2 strtobool
----------------
標準ライブラリにこんなやつが。

```py
from distutils.util import strtobool
from fabric.api import run

def __strtobool(arg):
    return bool(strtobool(arg))

def test(flag="True"):
    flag = __strtobool(flag)
    if flag is True:
        run("echo hoge")
    else:
        run("echo fuga")
```

こんな感じで書く。これを使うと、`"True"`とかの代わりに"y", "t", on"とかそれっぽい諸々の文字列が使えるようになる。

ただし、`def test(flag=True):`とか、デフォルト引数にboolean型のまま書くとエラー吐いて落ちる。

そのときのための折衷案とかを用意する。ついでに、strtobool() に変換出来ない文字列突っ込んだときのために例外も取ってみる。

```py
def __strtobool(arg):
    try:
        if type(arg) == type(True):
            return arg
        else:
            return bool(strtobool(arg))
    except ValueError:
        ...
```

なんかだんだん面倒くさくなってきますね。
HashMapの総回し

PHPでの仕事が一段落したのでjavaのお勉強も並行して行なっていきます。
参考書は[スッキリ分かるjava入門](http://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BJava%E5%85%A5%E9%96%80-%E4%B8%AD%E5%B1%B1-%E6%B8%85%E5%96%AC/dp/4844330861)。
実践編も買ってガンガン色んな問題等を解いていくのが学習効率いいのかな？
PHPのような便利関数が無い（？）ので、あれこれ苦労しながら勉強中。

とあるEラーニングサイトの問題にて、連想配列を使いたい問題が出てきたので
HashMapとやらを触ってみましたが、その中身を総当たりしようとすると、
色々やり方があるようなのでメモ。

例として、以下のHashMapを総当たりしてkeyとvalueを表示します。

```java:example
HashMap<String, Integer> map = new HashMap<String, Integer>();
```

## for

```
Set<String> keys = map.keySet();
for (int i = 0; i < keys.size(); i++) {
    String key = keys.toArray(new String[0])[i];
    System.out.println(key + " => " + map.get(key));
}
```

意味は分かるけれどあまりスマートでは無いような気がします。


## 拡張for（foreach）

```
for (String key : map.keySet()) {
    System.out.println(key + " => " + map.get(key));
}
```

かなりスマートになった気がしますし書きやすいですが、パッと見で意味分かるんかな…？
慣れてる人は読みやすいのかもしれません。


## Iterator

```
for(Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext(); ) {
    String key = iterator.next();
    System.out.println(key + " => " + map.get(key));
}
```

``hasNext()``は次の要素が存在するときtrueになることを利用したループ。
そもそもIteratorの意味がよく理解できていないんだけれど、
「配列などの各要素に対する繰り返し処理の抽象化」とwikiには書かれている、
それってつまりforeach（拡張for）で済む話なんじゃなかろうか。
うーん？


```
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

というデータがあったときに1～10までの数字を全てメモリに持つか、
1から10までの1つずつをメモリに順番に入れていって、それぞれ処理をするか、の違いなのかな？

# 追記

##  entrySet

```
for (Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " => " + entry.getValue());
}
```

[Mapを回すときはkeySetよりも、entrySetの方が早い](http://qiita.com/kei2100/items/0ce97733c92fdcb9c5a9)の記事を拝見して。

それぞれに利点があるんだろうな。まだ分からないけれど。

# 追記の追記

そして某Eラーニングサイトの問題は順番も指定されていたので、HashMapじゃダメのよう。
HashMapって順番不定なんだね。


# 追記の追記の追記

``LinkedHashMap``に変えるだけでいいんだ！なんて便利！
tree  コマンド (awk版実装)

以前 *sed*(1) を利用した tree コマンドの実装が投稿されていたので、*awk*(1) 版を投稿。
ワンライナーで済む分だけ *sed*(1) 版の方が遙かに美しいですが折角なので。

遙か昔 (1997年頃) に必要に迫られてでっち上げたスクリプトなので、表示が崩れるなど不具合のある可能性もありますがそのまま公開しちゃいます。

```
#!/bin/sh
LANG=C
du -a $* |
sort -k 2|
awk '{
    num = split($2, path, "/")
    max = (max < num) ? num : max
    for(i=1; i<=num; i++)
        if(old[i] == path[i])
            printf("  |")
        else
            break
        printf("- %s \n", path[i])
        old[i] = path[i]

        while(++i <= max)
            old[i] = ""
  }'
```
Xfce4.4にてタイピング中のタッチパッドDisable設定（UbuntuStudio,Xubuntu）

タイピング中のタッチパッドのDisableにはsyndaemonが利用できる。

```shell-session
$ syndaemon -d
```

デフォルトではタイピング終了から２秒間Disableされる。-iコマンドで秒数指定可能  
0.5秒の例

```shell-session
$ syndaemon -d -i .5
```
alt,shiftキーなど修飾キーを対象外とするには-K  
カーソル移動は活かしたまま、タップとスクロールを無効にするには-t　　
VAIO Proではなんだが-t選択してもタッピングが発生するため最終的に以下のオプションになった

```shell-session
$ syndaemon -d -i .5 -K
```

スタートアップにこれを登録すれば万事解決
スタートアップについては別項参照
【解答例】Haskell IOモナド 超入門

[Haskell IOモナド 超入門](http://qiita.com/7shi/items/d3d3492ddd90d47160f2)の解答例です。

# シャッフル

【問1】次のコードから`do`を取り除いて、bindや`return`は使わずに`unIO`や`IO`で書き換えてください。

```hs
{-# LANGUAGE UnboxedTuples #-}

import GHC.Base
import System.Random

shuffle [] = IO $ \s -> (# s, [] #)
shuffle xs = IO $ \s ->
    let (# s1, n   #) = unIO (getStdRandom $ randomR (0, length xs - 1) :: IO Int) s
        (# s2, xs' #) = unIO (shuffle $ take n xs ++ drop (n + 1) xs) s1
    in  (# s2, (xs !! n) : xs' #)

main = IO $ \s ->
    let (# s1, xs #) = unIO (shuffle [1..9]) s
        (# s2, r  #) = unIO (print xs) s1
    in  (# s2, r  #)
```
```text:実行結果（毎回異なる）
[3,5,4,9,2,7,8,6,1]
```

# 再実装

【問2】IOモナドを扱う`bind`と`return'`を実装してください。`>>=`, `<<=`, `<-`, `return`は使わないでください。

```hs
{-# LANGUAGE UnboxedTuples #-}

import GHC.Base

a `bind` b = IO $ \s ->
    let (# s1, r1 #) = unIO a s
        (# s2, r2 #) = unIO (b r1) s1
    in  (# s2, r2 #)

return' x = IO $ \s -> (# s, x #)

main = return' "hello" `bind` putStr `bind` print
```
```text:実行結果
hello()
```
「Divide and Conquer」と「Begin with the End in Mind」


後出しですが、[L5 Advent Calendar](http://www.adventar.org/calendars/438)の6日目の記事です。

初日に書いて、どこかの空きでと思っていたら、予想以上に参加してくれる人が増えて、書きたかったことが書けなくなったので、6日目にねじ込みました。

さて、書きたかったことは、僕なりの仕事のやり方のコツです。
コツといってもとても抽象的な話になりますが、大事にしている（より正確に言えば、結果として大事にした選択をしている）ことは、「Divide and Conquer」と「Begin with the End in Mind」ということです。

# Divide and Conquer
日本語では、「分割統治」と翻訳されることが多いと思います。

コンピュータ科学などでは教科書に載っているような一般的な話だと思いますが、wikipediaでは次のように説明されています。

> 
分割統治法（ぶんかつとうちほう、英語: divide and conquer algorithm、D&C）は、そのままでは解決できない問題を小さな問題に分割することで、最終的に問題を解決しようとする考え方。また、その方法やアルゴリズム。
クイックソートやマージソートに代表されるようなソートでよく使われている。また、構造化プログラミングでも、この考え方に基づいている。
（Wikipediaより)

アルゴリズムの手法の１つとして説明されていますが、解きたい問題がそのままでは解決方法が複雑になりすぎる場合に、その問題をより小さな問題に分割し、それぞれを解決し組み合わせることで、本来の問題の解決策を導くという、ごく一般的に利用できるテクニックです。

ある種、万能な方法とも言えるのですが、利用するための条件が１つあります。

それは、 **問題の分割を適切にできる** ことが必須になります。

## 問題の分割が難しい場合

当たり前ですが、そもそも分割できないと小問題が何かすら分かりませんし、強引に問題を小問題に分割したとしても、その場合は小問題が解決したとしても、本来の問題が解決しません。

分割ができない場合は大きく次の３つがあると思います。

### 論理的思考が苦手
論理的に正しく分割しないと、小問題の解決が本来の問題の解決につながりません。

### 小問題が多すぎる
多すぎる小問題は、その全体像を見失わせます。
この場合は、適度な大きさの問題を間に作成し、幾層かに階層的に問題を分割することで解決できると思います。

### そもそも問題が複雑すぎる
スキルではなく、問題が複雑なために、どう分割すると良いかが不明なので、この場合は、一筋縄ではいきません。

最初の2つについては、単なるスキルの問題です。センスがいい人であれば、すぐにできるようになると思いますし、苦手な人でも上司なり、先輩なりできる人に相談すれば解決するかと思います。
問題は、3つ目です。

## 問題が複雑過ぎる場合の対処方

これは僕自身の経験則的なところですが、主に2つの方針をとります。

## 情報を集める
問題が複雑に見えるということは、言い換えれば、現在の視点で解決することは難しいと言えます。
その場合は、問題について関連する情報を集めて、違う視点からのアプローチを検討します。

## 限定的に解決を目指す
これは情報の集め方の1つであるとも思いますが、問題をある解決しやすい条件下だけに限定し、その問題に取り組ます。これにより、その条件下での解にたどり着くことができれば、元の問題についても何かの知見を得て、視点を変えるきっかけになるかもしれません。
また、場合によっては、業務という観点で言えば、その条件下で解決すれば十分というケースもあります。それなのに、オーバースペックな問題に取り組む必要があるかは検討すべきでしょう。


# Begin with the End in Mind

この言葉は、THE 7 HABITS OF HIGHLY EFFECTIVE PEOPLE(７つの習慣)で言われている、2番目の習慣です。日本語だと、「終わりを思い描くことから始める」、「目的を持って始める」という訳され方をします。

僕はこの習慣はとても大事なことだと思っています。
仕事をするとどうしても、What（何を？）、How（どうやって？）というプロセスに思考が行きがちです。
ですが、その裏には、必ず、Why（何のために？）という目的とか、意思があります。
プロセスは実施する時、場所、人によって最適解は異なり、変えていくべきですが、目的や意思はぶれると面倒です。

とある人が自分は社長だから朝令暮改は当たり前だということを言っていました。
この話を聞いて、納得する部分ととても嫌な部分と両方を感じました。多分、その答えはここなんだと思います。

プロセスは朝令暮改でも構わないと思います。むしろ、効率のためであれば、そうあるべきでしょう。
でも、目的や意思が朝令暮改の組織は組織として成立しないと思います。
（念のために言いますが「変えるべきではない」と言っている訳ではないです。）

ちょっと開発の話になりますが、ストーリーワークショップ、ATDD、TDDというのは、粒度の差はありますが、基本的にはBegin with the End in Mindを後押しする仕組み何だと思います。

特に熟慮した訳ではないですが、数個のクラスの設計をして説明をした際に、新人の人から、なぜその発想に到れるのか教えてもらえますか？という趣旨の質問をされました。

ぱっと思いついた答えは、それが自然だから、とか、それが美しいから、だったのでした。
では、なぜ、自然なのか、なぜ、美しいのかまで考えてみると、結局のところ、

これらのクラスが提供すべき機能があり、それを使う側から見て使いやすく（この定義も必要ですが、ここでは割愛）、それを充足する最小限のものというのが、少なくとも、どうも自然とか、美しいという言葉の定義に近い気がしています。

言い換えるならば、作成するクラスのEnd（どんな機能を誰にどんな風に提供するか？）を意識するところが大前提なのだと思います。

今回は小さなクラス群だったので、これを無意識にやっていたのですが、これを意識的にやる設計作業がTDDと言えるかと思います。


# 最後に

僕なりの重要視していることを2つのキーワードでまとめてみましたが、いかがでしたでしょうか？

7日目は、同じくバックデートして土方さんが埋めてくれるはずです。
よろしくお願いします。
Swiftの自前ログクラス

Swiftを少し触り始めたので、その時のメモを残します。

## はじめに
自分仕様にログの出し方を整えておきたいと思い、ログクラスを作ることにしました。
Swiftもそうですが、Objective-Cもあまり触ったことがないので、もしかしたら、もっと簡単なやり方があるのかもしれませんが。

## ログ出力でやりたいこと
* 時間を出力したい
* 実行行を出力したい
* 実行クラス、メソッドを出力したい
* ログレベルを出力したい

とりあえずこんなところでしょうか。

## Logger.swift
``` Logger.swift
import Foundation

class Logger{
    class func debug(
            message: String,
            function: String = __FUNCTION__,
            file: String = __FILE__,
            line: Int = __LINE__) { Logger.write("[DEBUG]", message: message, function: function, file: file, line: line) };
    class func info(
            message: String,
            function: String = __FUNCTION__,
            file: String = __FILE__,
            line: Int = __LINE__) { Logger.write("[INFO]", message: message, function: function, file: file, line: line) };
    class func warning(
            message: String,
            function: String = __FUNCTION__,
            file: String = __FILE__,
            line: Int = __LINE__) { Logger.write("[WARNING]", message: message, function: function, file: file, line: line) };
    class func error(
            message: String,
            function: String = __FUNCTION__,
            file: String = __FILE__,
            line: Int = __LINE__) { Logger.write("[ERROR]", message: message, function: function, file: file, line: line) };
    class func write(
            loglevel: String,
            message: String,
            function: String,
            file: String,
            line: Int) {
            
            let now = NSDate() // 現在日時の取得
            let dateFormatter = NSDateFormatter()
            dateFormatter.locale = NSLocale(localeIdentifier: "ja_JP")
            dateFormatter.timeStyle = .MediumStyle
            dateFormatter.dateStyle = .MediumStyle
            //println(dateFormatter.stringFromDate(now)) // => 2014/12/11 15:19:04
            
            var nowdate = dateFormatter.stringFromDate(now)
            
            var filename = file
            if let match = filename.rangeOfString("[^/]*$", options: .RegularExpressionSearch) {
                filename = filename.substringWithRange(match)
            }
            println("\(loglevel) => \"\(message)\" \(nowdate) L\(line) \(function) @\(filename)")
    }
}
```


まあ、なんというかもしかしたらもっと良いやり方があるんかもしれないのですが。

## 使い方
> DEBUG,INFO,WARNING,ERROR

```
Logger.debug("hogehoge")
Logger.info("hogehoge")
Logger.warning("hogehoge")
Logger.error("hogehoge")
```

## 出力結果

>[DEBUG] => "hogehoge" 2014/12/11 15:56:16 L21 application(_:didFinishLaunchingWithOptions:) @AppDelegate.swift

>[INFO] => "hogehoge" 2014/12/11 15:56:16 L22 application(_:didFinishLaunchingWithOptions:) @AppDelegate.swift

>[WARNING] => "hogehoge" 2014/12/11 15:56:16 L23 application(_:didFinishLaunchingWithOptions:) @AppDelegate.swift

>[ERROR] => "hogehoge" 2014/12/11 15:56:16 L24 application(_:didFinishLaunchingWithOptions:) @AppDelegate.swift
goamz と goroutine を使って S3 へ非同期アップロードする + Signed URL の取得


S3ファイルをアップロードして Signed URL (時間制限でアクセス可能なURL）を取得してみます。

S3にアップロードされたオブジェクトは（IAMアカウント等の設定を行わない限り）基本的に全公開か非公開となり、オブジェクト単位での公開/非公開の設定はできません。

しかし、Signed URL を取得することによって、時間制限付きで任意のオブジェクトを公開することができます。
今回は Go の [goamz](https://github.com/goamz/goamz) ライブラリを使ってファイルのアップロードから Signed URL の取得までを行ってみます。

## 仕様
- 同じ階層にある `images` ディレクトリの中の画像ファイルをS3へアップロードする
- ファイル名は SHA256 のハッシュ値に変換する
- Signed URL を構造体に詰めて返す

## コード

```go
package main

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/goamz/goamz/aws"
	"github.com/goamz/goamz/s3"
)

type SignedURLResponse struct {
	URL string
}

var image_exts = []string{
	"bmp",
	"gif",
	"jpeg",
	"png",
	"tiff",
}

func IsImageFile(file []byte) (bool, string) {
	mime := http.DetectContentType(file)
	s := strings.Split(mime, "/")

	if len(s) < 2 {
		return false, ""
	}

	for _, ext := range image_exts {
		if ext == s[1] {
			return true, mime
		}
	}
	return false, ""
}

func GenFileHash(file []byte) string {
	h := sha256.New()
	h.Write(file)
	bs := h.Sum(nil)

	return hex.EncodeToString(bs)
}

func S3Upload(bucket *s3.Bucket, dir string) {
	wg := new(sync.WaitGroup)
	fs, _ := ioutil.ReadDir(dir)

	for _, f := range fs {
		wg.Add(1)
		go func(inner_f os.FileInfo) {
			buf := make([]byte, inner_f.Size())
			img, _ := os.Open(dir + "/" + inner_f.Name())
			defer img.Close()
			img.Read(buf)

			is_image, mime := IsImageFile(buf)
			if is_image {
				filename := GenFileHash(buf) + filepath.Ext(inner_f.Name())
				fmt.Println("Uploading .. " + filename)

				err := bucket.Put(filename, buf, mime, s3.BucketOwnerFull, s3.Options{})
				if err != nil {
					log.Fatal(err)
				}
			}
			wg.Done()
		}(f)
	}
	wg.Wait()
}

func GetSignedURL(bucket *s3.Bucket) []SignedURLResponse {
	ch := make(chan SignedURLResponse)
	list, err := bucket.List("", "", "", 100)
	if err != nil {
		log.Fatal(err)
	}

	count := 0
	for _, c := range list.Contents {
		count++
		go func(inner_c s3.Key) {
			signed_url := bucket.SignedURL(inner_c.Key, time.Now().Add(time.Second*60))
			ch <- SignedURLResponse{URL: signed_url}
		}(c)
	}

	signed_urls := make([]SignedURLResponse, 0, count)
	for i := 0; i < count; i++ {
		signed_urls = append(signed_urls, <-ch)
	}

	return signed_urls
}

func main() {
	auth, err := aws.EnvAuth()
	if err != nil {
		panic(err)
	}

	s3client := s3.New(auth, aws.APNortheast)
	bucket := s3client.Bucket("test-bucket")

	S3Upload(bucket, "images")
	fmt.Println("Done")

	// SignedURL の取得
	signed_urls := GetSignedURL(bucket)
	fmt.Println(signed_urls)
}
```

## 参考文献
以下の記事を参考にしました。ありがとうございました。

- [Qiita : golang で S3 に大量ファイルを並列でアップロードする](http://qiita.com/yamasaki-masahide/items/32031ade842fb6125bf0)
- [Qiita : S3 の事前署名付き（期限付き）URL を生成する](http://qiita.com/inokappa/items/dc3ef8b564c7d1f63be2)
- [Qiita : 【個人メモ】GoのビルトインライブラリでファイルのMIME Typeを推測したい場合](http://qiita.com/futoase/items/7f54b971285d8b91cd3c)
[小ネタ]Kaminariで行番号を表示する

コントローラー内で

```rb:some_controller.rb
@anyresults = AnyModel.page(params[:page])`
```

のように結果セット@anyresultsを取得した場合viewで

```rb:some.html.slim
ul
  - @anyresults.each.with_index(1) do |anyresult, i|
    li = i + @anyresult.offset_value 
end
```

とすればよい。
AndroidStudio入門 - インストール編


昨日、Android Studio の正式版がリリースされたというニュースが人気だったので、これを気にNativeApplication 作ってみようかなと思い、昼休みを利用して Mac OS X へのインストール手順を纏めてみました。

## Android Studio のダウンロード

まずは、[公式ページ](http://developer.android.com/sdk/index.html)にアクセスして、ページ中程の [Download Android Studio for Mac] をクリックします。


![Android Studio   Android Developers.png](https://qiita-image-store.s3.amazonaws.com/0/42939/1e4e7c85-1081-0ee4-649d-e5a9338615ed.png "Android Studio   Android Developers.png")


## Android Studio のインストール

Android Studio をインストールしていきます。
基本はピコピコ [Next] ボタンを押していれば OK です。

次の画面で JDK の Path を指定してあげるか、Mac OS X 用の JDK を Download しましょう。
[Mac OS X x64] のリンクからをクリックすると、いつもの ORACLE のページが表示されます。

![スクリーンショット 2014-12-10 17.16.52.png](https://qiita-image-store.s3.amazonaws.com/0/42939/28c48265-8171-a911-fc53-7657dc3f782b.png "スクリーンショット 2014-12-10 17.16.52.png")

いつもの ORACLE のページ。

![スクリーンショット 2014-12-10 17.38.29.png](https://qiita-image-store.s3.amazonaws.com/0/42939/8c0a4457-6433-3baf-56e2-cd03ffadabd0.png "スクリーンショット 2014-12-10 17.38.29.png")

ちょっと下にスクロールすると、各 OS 毎のダウンロードリンクが並んでいます。
[Accept License Agreement] にチェックを入れて、 Mac OS X x64 のリンクをクリックすると、JDK7がダウンロードされます。

![スクリーンショット 2014-12-10 17.38.16.png](https://qiita-image-store.s3.amazonaws.com/0/42939/f997f291-f53e-9469-c603-c7f5e4f9985b.png "スクリーンショット 2014-12-10 17.38.16.png")



ダウンロードしたdmgファイルをダブルクリックして、30億のデバイスで走る Java をインストールしましょう。インストール完了後に再び Android Studio のインストール画面に戻り、[Detect] ボタンをクリックすると、勝手にパスが入力されるので、[Next] ボタンを **ッターン！**

![スクリーンショット 2014-12-10 17.22.12.png](https://qiita-image-store.s3.amazonaws.com/0/42939/9d652fe2-0816-2733-77e3-49237f07e2b7.png "スクリーンショット 2014-12-10 17.22.12.png")

Android Virtual Device は、通常のアプリの場合不要そうですが、よく解っていないのでとりあえずこれもインストールします。[Next] ボタンを **ッターン！**

![スクリーンショット 2014-12-10 17.28.56.png](https://qiita-image-store.s3.amazonaws.com/0/42939/0389c055-fa9e-d458-68f9-4a0f0b7c47e9.png "スクリーンショット 2014-12-10 17.28.56.png")

[Accept]にチェックを入れて[Finish]ボタンを **ッターン！**

![スクリーンショット 2014-12-10 17.29.07.png](https://qiita-image-store.s3.amazonaws.com/0/42939/9bbfd2c0-7c32-3d5e-fd3a-798c9ae4f038.png "スクリーンショット 2014-12-10 17.29.07.png")

インストールが開始されるので、アニメを見るか、ご飯を食べる等して気長に待ちましょう。

![スクリーンショット 2014-12-10 17.29.15.png](https://qiita-image-store.s3.amazonaws.com/0/42939/a601669c-af01-e7aa-8440-d1ef51049568.png "スクリーンショット 2014-12-10 17.29.15.png")

無事にインストールが完了すると下記のように表示されます。[Finish] ボタンを **ッターン！**

![スクリーンショット 2014-12-10 17.38.46.png](https://qiita-image-store.s3.amazonaws.com/0/42939/ed36ab76-cd3f-f2fe-a238-bd2e1616f6c5.png "スクリーンショット 2014-12-10 17.38.46.png")

インストールが終了して、Android Studio が起動します。

![スクリーンショット 2014-12-10 17.39.11.png](https://qiita-image-store.s3.amazonaws.com/0/42939/3daebda7-b45e-b309-75df-483af42d4b69.png "スクリーンショット 2014-12-10 17.39.11.png")

## 次回
実際に AndroidStudio を触っていきながら、便利だったことを纏めていきます。
MySQLのSET型を使ってみようとしてやめた

MySQLのSET型を使ってみようとしてやめた時のメモ。

ドキュメント→ <http://dev.mysql.com/doc/refman/5.6/en/set.html>

作ったテーブルはこんなの。

```sql
CREATE TABLE `Color` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `flags` set('red','blue','green') DEFAULT NULL,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `flags_INDEX` (`flags`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
```

下記のデータを突っ込んで、試します

```sql
INSERT Color (flags, name) VALUES
	('red', '赤'),
	('blue', '青'),
	('green', '緑'),
	('red,blue', '紫'),
	('red,green', '黄'),
	('blue,green', '水'),
	('red,blue,green', '白');
```

flags に blue を含んだものを取得したい場合

```sql
SELECT * FROM Color WHERE FIND_IN_SET('blue', flags);
```

```
# id, flags, name
2, blue, 青
4, red,blue, 紫
6, blue,green, 水
7, red,blue,green, 白
```

## なんでやめたの

上のクエリ、インデックスが効くわけじゃないんです。like 句を使っても書ける　とドキュメントにあるんだけど、そっち使って書いても駄目。

一応、blue or red,blue or blue,green or red,blue,green みたいな書き方をすると効くんだけど、いやいやいや……。

フラグが増えたらALTER TABLEなのかとかも気になったし、とても古い記事だけど [使うべきじゃない](http://ftp.nchu.edu.tw/MySQL/tech-resources/articles/mysql-set-datatype.html) という記事も読んでしまい、結局使うのをやめました。まぁ利用用途次第ですかね。
React.jsの地味だけど重要なkeyについて

今回はReact.jsのVirtual DOM実装の中でもユーザーが意識するべき点の`key`について書きたいと思います。

React.jsではPropに`key`という値を指定することが出来て、Componentのリストを表示するような時につけていないとdevelopment環境だと`console.warn`で

>>
Each child in an array should have a unique "key" prop. Check the render method of KeyTrap. See http://fb.me/react-warning-keys for more information.

と表示されます。

このkeyはVirtualDOMのdiffから実際のDOMに反映させるときに最小限の変更にするために使われます。

例えば

```js
var KeySample = React.createClass({
  getInitialState() {
    return {
      list: [1,2,3,4,5]
    };
  },
  add() {
    this.setState({ list: [0].concat(this.state.list) });
  },
  render() {
    var list = this.state.list.map(function(i) { return <li key={i}>{i}</li> });
    return (
      <div>
        <ul>{list}</ul>
        <button onClick={this.add}>add</button>
      </div>
    );
  }
});
```

http://jsfiddle.net/koba04/tttLsmuL/

のようなComponentがあった時に、`add`するときに配列の要素にUniqueなIDが指定されていると先頭に要素が追加されたことがわかるので、そこだけ実際のDOMに反映することが出来ます。そうでないと1を0に2を1に...とそれぞれの要素の値を変更することになってしまい無駄になります。

そうすると↑のkeyの指定は問題があることがわかります。
`add`すると0が先頭に追加されているようになっているのですが、値をkeyにしているので一度0が追加された以降は何も追加されなくなります。
その裏側では、keyによってすでにある0と追加しようとしている0が比較されて差分がないので追加されないようになっています。

ちなみにwarnで下記のような警告がちゃんと出ます

>>
Warning: flattenChildren(...): Encountered two children with the same key, `.$0`. Child keys must be unique; when two children share a key, only the first child will be used.

上のサンプルはkeyを外すと0が何個でも追加されるようになります。


ちなみにこの辺りと似た工夫はAngular.jsのtrack byやvue.jsのtrackbyなど別のフレームワークでも見ることが出来ます。


## key must by unique

上記の`console.warn`にもある通り、keyにはそのリストの中で必ずユニークになる値を指定する必要があります。なのでkeyにする値の候補としてはユーザー一覧におけるユーザーIDなどになります。

配列のIndexをkeyに指定すると意味ないことがわかると思います。


## ReactCSSTransitionGroup

React.jsにはCSSアニメーションのためのaddonがあるのですが、これは要素が1つの場合でもアニメーションさせる要素に必ずkeyをつける必要があったりします。
これはReactCSSTransitionGroupでは要素の追加・削除をtrackingしたいのでそのためにkeyを必要としているのだと思います。(実装は見てないですが...)

ReactCSSTransitionGroupについてはまだ後日改めて書く予定です。


## おまけ

http://blog.arkency.com/2014/10/react-dot-js-and-dynamic-children-why-the-keys-are-important/

参考として最後に`key`にはまったというエントリーを紹介しておきたいと思います。

簡単に説明すると、

```html
<CountriesComponent>
  <TabList />  {/* 国一覧 */}
  <TabList />  {/* ↑の都市一覧 */}
</CountriesComponent>
```

上記のようなComponentの構成になっていてTabListそれぞれがStateとしてactiveなtabのindexを持っています。

そして国一覧を変更した時に、都市一覧のactiveなindexを0にリセットしたいのにそのまま残ってしまってハマったという内容です。

activeはgetInitialStateで0にリセットされるようになっていて、国が変わった時に都市一覧のTabListは国に対応した都市のリストで再作成されてリセットされると思ったようなのですが、実際はTabList自体は再利用されて中のリストだけが更新されます。

つまりgetInitialStateが呼ばれずリセットされないというのがこの問題の原因です。

なのでTabListにkeyを指定して国が変わった時は都市のComponentが再生成されるようにすればOKということが解決方法の1つとして書かれています。

つまり`key`を明示することで新しくComponentを作るようにしています。

```html
<CountriesComponent>
  <TabList key='countriesList'/>  {/* 国一覧 */}
  <TabList key={this.state.currentCountry} />  {/* ↑の都市一覧 */}
</CountriesComponent>
```

まぁ、この場合はブログでも言及されていますが、TabList内でactiveのStateを持つのではなくてContriesComponentが管理してPropでactiveな情報もTabListに渡してあげるのが正しいんじゃないかなと思っています。


--------------

というわけでReact.jsのkeyが持つ役割について説明しました。

明日はReact.jsのVirutal DOMについて書きたいと思います。
Virtual DOM Advent Calendarを見ればいいのですが、この流れで少し触れておきたいので簡単に...。
BrowserSyncの使い方

## BrowserSyncって何？

テキストエディターでHTML,CSS,JavaScriptのコードを編集して、結果を確認するのにWebブラウザーにフォーカスを移してF5で更新して……
というWeb開発のワークフローを簡素化するプログラムです。
BrowserSyncは**ファイルの変更を監視して、変更を即座にブラウザーに反映させる**ことができます。
しかもCSSファイルの編集は**ページの再読み込みをすることなく反映されます。**
複数ブラウザーを立ち上げていてもOK！モバイルブラウザーも自動で同期します！

テキストエディター上での作業に集中することができるので、作業効率が劇的に向上します。これを使わない理由はありません！！

## インストール方法

### Node.jsをインストール

BrowserSyncはNode.jsで動くので、まずNode.jsをインストールします。
[Node.js](http://nodejs.org/)のサイトからインストーラーをダウンロードして簡単にインストールできます。

### BrowserSyncをインストール

Node.jsはnpmというパッケージマネージャーでNode.jsのソフトやライブラリーを簡単にインストールできるようになっています。BrowserSyncもnpmでインストールできます。
ターミナル(Windowsではコマンドプロンプト、以下ターミナルで統一)を開いて以下のコマンドを実行してください。

```bash
npm install -g browser-sync
```

※エラーが出る場合は管理者権限で実行してください。(`sudo npm install -g browser-sync`)

## BrowserSyncを使う

基本的な利用ケースはHTMLファイルの変更を監視して、変更を検知したら自動的にブラウザーをリロードすることです。
HTMLファイルのあるディレクトリでターミナルを開いて、次のコマンドを入力してください。

```bash
browser-sync start --server --files *.html
```

上記のコマンドは、カレントディレクトリに http://localhost:3000/ でアクセス可能なWebサーバーを立ち上げ、Webブラウザーを起動します。そしてカレントディレクトリ内の全てのhtmlファイルの変更を監視し、変更が起きた時に自動的にWebブラウザーをリロードします。

もしCSSやJSファイルも監視対象にしたい場合は

```bash
browser-sync start --server --files "*.html, *.css, *.js"
```

のようにカンマ区切りで指定します。

めんどくさいときは

```bash
browser-sync start --server --files *
```

でも良いです。この場合カレントディレクトリ内の全てのファイルを監視対象にします。

※`*`は任意の文字列を表します。`*.css`は拡張子が.cssの全てのファイルという意味です。

## 動的ページを開発する場合

ここまでは静的ファイルのHTMLを編集する場合の方法ですが、BrowserSyncはPHPやNode.jsなどによる動的ページにも対応することができます。
開発中のWebアプリケーションが http://localhost:8080 で動作しているとき、監視対象とするHTML等があるディレクトリで下記コマンドを入力してください。

```bash
browser-sync start --proxy localhost:8080 --files *
```

BrowserSyncは http://localhost:8080 へのプロキシサーバーとして動作し、 http://localhost:3000 でアクセスを受け付けます。そして自動的にHTML内にリロード用のスクリプトを埋め込みます。
メモ: golangで月末日を取得する方法


これで正しいのか、あんまり自信ない。

コード
--------
```go:getlastdayofmonth.go
package main

import (
	"fmt"
	"time"
)

func main() {
	loc, _ := time.LoadLocation("Asia/Tokyo")
	t := time.Date(2014, time.March, 1, 0, 0, 0, 0, loc).AddDate(0, 0, -1)
	fmt.Println(t)
	fmt.Println(t.Day())
}
```

上記では、2014 年 3 月の月初から 1 日分を引き算している。

`timeDate()` 内の **loc** 部分の指定は別に time.UTC でも問題ない…と思う。

```console:出力
2014-02-28 00:00:00 +0900 JST
28
```

Go Playground は [ここ](https://play.golang.org/p/o5n6iM8VZO)


参考
--------
* [time - The Go Programming Language](http://golang.org/pkg/time/)
* [src/pkg/time/example_test.go - The Go Programming Language](https://golang.org/src/pkg/time/example_test.go)
* [src/pkg/time/zoneinfo_abbrs_windows.go - The Go Programming Language](http://golang.org/src/pkg/time/zoneinfo_abbrs_windows.go)
	* ここにタイムゾーンらしき記載があるのだが、「JST」の使い方が分からなかった…
ChicagoBossで複数のDBを使用する


[ChicagoBoss] (http://www.chicagoboss.org) で DB1 の foosテーブル、DB2 の barsテーブルを使いたいときは、Shardingの機能を使えばいいらしい。

# 設定

1. boss.config に db_shards の設定を書く。

 ``` 
{db_host, "localhost"},
{db_port, 27017},
{db_adapter, mongodb},
{db_shards, [
    [
        {db_host, "localhost"},
        {db_adapter, mongodb},
        {db_port, 27017},
        {db_database, "db1"},
        {db_shard_id, shard_first},
        {db_shard_models, [foo]}
    ],
    [
        {db_host, "localhost"},
        {db_adapter, mongodb},
        {db_port, 27017},
        {db_database, "db2"},
        {db_shard_id, shard_second},
        {db_shard_models, [bar]}
    ]
]},
```
 - db_host, db_port, db_adapter などを db_shards より上に書いていた場合も、db_shards に書いた設定が優先されるとのこと。

2. モデル src/model/foo.erl, src/model/bar.erl を作る。

3. boss_dbからアクセスする。

```
boss_db:find(foo, [], []),
boss_db:find(bar, [], []),
```

* 指定したテーブルのモデル(src/model/*.erl)がない場合、module_not_loaded というエラーになる。
* 指定したテーブルのモデルは存在するが実DBの設定がない場合、[]が返る。(エラーにならない)

# 設定(db_shard_modelsに書かない場合)

* db_shard_modelsに書かない場合、上に指定したdb_databaseにあるテーブルは読み込まれるらしい。

 ``` 
{db_host, "localhost"},
{db_port, 27017},
{db_adapter, mongodb},
{db_database, "db1"},
{db_shards, [
    [
        {db_host, "localhost"},
        {db_adapter, mongodb},
        {db_port, 27017},
        {db_database, "db1"},
        {db_shard_id, shard_first},
        {db_shard_models, []}
    ],
    [
        {db_host, "localhost"},
        {db_adapter, mongodb},
        {db_port, 27017},
        {db_database, "db2"},
        {db_shard_id, shard_second},
        {db_shard_models, [bar]}
    ]
]},
```

* この場合、fooテーブルを指定すると、db1から読まれる。

```
boss_db:find(foo, [], []),
```

# 注意

* ChicagoBossの命名規則で、実際のテーブル名のsを取ったものがmodel名となる。
 * テーブル(collection)名: foos
 * model名: foo

[Specifying table and column names] (http://www.chicagoboss.org/api-record.html#mappings) の通りに
-table("foo") と指定しても、fooテーブルが読み込まれないのは何故だろう。
GsonとProguard


AndroidでJsonを扱うライブラリとして有名なGsonですが、
Proguardを有効にしたビルドだと問題が発生します


# 問題

普通だと

```java
new Gson().fromJson(jsonString, Hoge.class);
```

で`jsonString`を`Hoge`クラスに変換出来るはずです
しかしProguardを有効にしてあると、`Hoge`クラスのフィールド名が難読化されて例えばアルファベット1文字に変更されているため、
`jsonString`におけるjsonのキー名と`Hoge`クラスのフィールド名が一致しなくなり`fromJson`によるjsonのパースに失敗し、
結果として全て`null`が入った`Hoge`クラスのインスタンスが得られることとなります

# 解決策

解決策は2つあります

## Proguardでリネームしない

例えば

```gradle
-keepnames class com.example.android.Model.** { *; }
```

のように、実装した`Model`パッケージ内の全てのクラスについてクラスとクラスメンバをリネームしないように
設定しておけば解決します
リネームさえ防げばいいので、`-keep`ではなく`-keepnames`で十分です

## `@SerializedName`を使う

Gsonの機能として、クラスのフィールド名とJsonのキー名を一致させなくても
`@SerializedName`を使ってフィールド名とキー名を対応させることが出来ます

```java
class Hoge {
	@SerializedName("field_name")
	private String fieldName;
}
```

とすればフィールド名は`fieldName`でJsonの`field_name`としてパース出来るようになります

__proguard難しい...__
メモ:pythonで月末日を取得する方法 (月初日も追記)


日付関連プログラムあるあるの「月末」の取得。
結局、 StackOverflow 参考にしたそのままなのですが…メモ。

[date - Get Last Day of the Month in Python - Stack Overflow](http://stackoverflow.com/questions/42950/get-last-day-of-the-month-in-python)


注意
--------
python あるある なのですが、`calendar.py` などという名前でプログラムファイルを作らないこと。標準モジュールの代わりにそれが呼ばれてしまうので。
もし

```consle
AttributeError: 'module' object has no attribute 'Calendar'
```

とか、

```console
AttributeError: 'module' object has no attribute 'monthrange'
```

とかエラーが出たら、作業ディレクトリに生成されているはずの `calendar.pyc` を削除すること。


calendar モジュールを使う方法
--------

例えば 2014年12月の場合。

```python
import calendar

print calendar.monthrange(2014,12)
```

[8.2. calendar — 一般的なカレンダーに関する関数群 — Python 2.7ja1 documentation](http://docs.python.jp/2.7/library/calendar.html#calendar.monthrange) によると、
> calendar.monthrange(year, month)(原文)
> year と month で指定された月の一日の曜日と日数を返します。

というわけで、

```console:出力
(0, 31)
```

と返ってくる。これは、月初の曜日が月曜日 (曜日番号 0 番) で、指定月の日数が 31 日ということ。

なので、

```python
import calendar

_, lastday = calendar.monthrange(2014,12)
print(lastday)
```

```console:出力
31
```

で得られるのが指定月の月末の日、ということになる。


datetime.timedelta(days=1) を使う方法
--------
翌月の月初から 1 日を引き算する。
datetime モジュールでは timedelta サブクラスを使うことで加減算や大小比較が算術演算子を使って出来るようになっている。

[8.1. datetime — 基本的な日付型および時間型 — Python 2.7ja1 documentation](http://docs.python.jp/2/library/datetime.html#timedelta)

```python
import datetime

date = datetime.date(2015, 1, 1) - datetime.timedelta(days=1)
print date.day
```

```console:出力
31
```

上記どちらかの方法がよさ気では、という感じ。

月初日は次のように求められると思います。

```py
import datetime

dt = datetime.datetime.utcnow()
# datetime.datetime(2017, 11, 26, 20, 51, 59, 745695)
dt.date() - datetime.timedelta(days=dt.day - 1)
# datetime.date(2017, 11, 1)
```

以上。

ちな Ruby
----
```ruby
require 'Date'
puts Date.new(2001,2,-1).day
```

うお、 1 行かー…。

```console:出力
28
```

Ruby らしいといえばらしい気もする。

おわり。

----

## 追記
前月の末日

```python
from datetime import datetime, timedelta

yesterday = datetime(2018, 3, 29).date()
last_day_of_previous_month = yesterday - timedelta(days=yesterday.day)
```
スマートフォンで Amazon.co.jp サイトを「PCサイト」として表示させるパラメタ


## どうするの？

amazonサイトのGETパラメタとして ```force-full-site=1``` を渡します．


## 具体的には？


通常通りAmazonの商品を表示するには次のようなURLで可能ですね．

```
http://www.amazon.co.jp/dp/{ASINコード}
```

![](http://i.gyazo.com/18c1d7b0a7721c54d97bae3edf052c0f.png)

このままアクセスすると，ブラウザのUserAgentによって判断され，PCページorモバイルページが表示されます．

今回の目的である強制的にPCサイトを表示する方法は

```
http://www.amazon.co.jp/dp/{ASINコード}?force-full-site=1
```

という形で渡すことで実現できます．

## 実際に確認してみましょう！

http://www.amazon.co.jp/dp/1852247819
http://www.amazon.co.jp/dp/1852247819?force-full-site=1

![](http://i.gyazo.com/89673c68b09073b6b9e69342a5400c49.png)

## 参考文献

http://www.amazon.co.jp/gp/aw/help.html?id=200145110
LPICレベル1対策 - システムの起動とランレベル

#### システムが起動するまでの流れ

1. BIOS
    2. ハードウェアのチェックと初期化
    3. ディスクのブートセクタを読み込んで、ブートローダーに制御を渡す
2. ブートローダー
    3. ハードウェアからカーネルを読み込む
3. カーネル
    4. メモリの初期化、システムクロックの設定
    5. initプログラムを実行
4. init
    5. システムの初期化スクリプトを実行
    6. ランレベルにしたがって、システムサービスや、デーモンの起動
    7. OSの起動が終わったって状態になったら、ログインプロンプトを表示する

#### 起動時のイベントの確認

起動時のログの確認方法は3つある。

* dmesgコマンド
* /var/log/messagesを確認する
* /var/log/boot.logを確認する

#### /sbin/initについて

initは何をしているのか。

**/etc/inittabファイルの設定にしたがってデーモンを起動する**

1. /sbin/initのやってること
    * /etc/inittabを読み込む
    * /etc/rc.sysinitスクリプトを実行
    * /etc/rcスクリプトを実行

2. /etc/rcスクリプトがやってること
    * /etc/rcランレベル.dディレクトリ以下のスクリプトを実行する。

#### SysVinitとは

Unix系OSで広く使われてきたOS起動の仕組み。
ただ、サービスを順番に起動し、の並列起動が出来ないという欠点がある。

最近では、Upstartやsystemdを採用するケースがある。

#### ランレベルとは

**ランレベルについては後で追記します**
テキストを選択させないCSS

テキストを選択されないように指定しているサイトがあります。モバイルのサイトでよく見かける気がします(^^ゞ

# テキストを選択させない
user-selectを使います。

```css:テキストを選択させないCSS
p {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}
```

これでpタグのテキストは選択されなくなります。
モバイルでは問題なく動くんですかね−。IEは10以上で対応みたいです(☝ ՞ਊ ՞)