昨日大変だったのは

Listをもらってsizeが0ならみたいな処理書いてたんだけど,なんかぬるぽで落ちる.ライブラリのソース読むとreturn nullしてて殺気が出る.常識的に考えて空のListを返すべき.

そういうことです.通信エラーとか根本的な失敗に対してはException吐くべきであると思います.

これのせいで時間飛んで困った.

寿司をふぁぼる

userstream監視して寿司という単語をふぁぼるプログラム書いた.golang初製品

programmerMOT/sushi_twitter · GitHub

仕組み

The simplest Twitter Streaming API by Golang - DRYな備忘録

ここの人が作ってるuserstreamだけ簡単に見れるgolangライブラリがあったのでこれでuserstream監視してる.

あとは寿司のいろんな表記に対してマッチしたら適当にふぁぼる.

func IsContainSushi(text string) (b bool) {
    if m, _ := regexp.MatchString("寿司|スシ|鮨|寿し|🍣|[sS][uU][sS][hH][iI]", text); !m {
        return false
    }
    return true
}

ふぁぼるときはanacondaっていうのを使ってふぁぼるメソッドだけ利用した.

ChimeraCoder/anaconda · GitHub

様子

卒論を自動ビルドで支える技術

卒論一応出したけど,ちょっとだけ卒論を支える技術みたいな話する.わかってるとは思うけど,これがあるからって卒論ができるわけではない.

概略

  1. git pushする
  2. 自動でビルドが走る
  3. Dropboxみたいなところに投げられる

git pushする

ホスティングはお得意のbitbucketで,private持ち放題なので,githubより安い.ただgithubより重いっていう印象はある.

自動でビルドが走る

今回はwerckerを使ってビルドした.latexのビルドが必要だったから,自分でbox作った.boxとかの作り方は以下を見ればいいと思う. Werckerの仕組み,独自のboxとstepのつくりかた | SOTA

programmerMOT/wercker-latex-box · GitHub

日本語texlive環境が整うようにしている.

あとはプロジェクトのルートディレクトリにwercker.ymlをかけば使える.platexとかdvipdfmxとか入ってると思う.

box: mot/latex-box@0.0.1

Dropboxになげる

werckerからは直接Dropboxに投げられないので,適当なサーバにrsyncするようにして,rsync先でDropboxに投げるようにした. 前もってwerckerの設定で秘密鍵作って公開鍵を送り先サーバに登録しておくと良い.

deploy:
  steps:
    - add-to-known_hosts:
        hostname: <送り先ホスト>
    - mktemp:
        envvar: PRIVATEKEY_PATH
    - create-file:
        name: write key
        filename: $PRIVATEKEY_PATH
        content: $HOST_KEY_PRIVATE
        overwrite: true
        hide-from-log: true
    - script:
        name: transfer application
        code: |
          pwd
          ls -la
          mv master.pdf $WERCKER_GIT_COMMIT-`date '+%Y%m%d-%H%M%S'`-master-mot.pdf
          rsync -avzr -e "ssh -i $PRIVATEKEY_PATH -o StrictHostKeyChecking=no -o UserKnownHostsFile=no" $WERCKER_ROOT/*.pdf mot@<送り先サーバ>:<送り先ディレクトリ>

送り先ディレクトリをDropboxにしておけばおk.

最後に

あとはこのDropboxの公開リンクをレビュワーに配っておけばいい. pushごとにpdfが残るのはバックアップの観点から心に余裕ができていいと思う.

hashmap的な構造でvalueからkeyを持ってくるデータ構造の紹介と利用

卒論はダメだが久々になんかアウトプットしたくなったので書く.

概要

AndroidでHashmapを使ってKeyValueなデータを管理してたのだけど, データいじってる時にValueからKeyを引きたくなる事案に遭遇した. 今回管理してたKeyValueは1対1であることが保証できたので,最初はforで回して適当に拾えばいいかとおもったけどぐぐったらBiMapなる便利なCollectionがあるらしいので使ってみた. そしたら今度はメソッドが多くなりすぎてapk吐けなくなった. しかし,MultiDexApplicationを利用したらたくさんclassあってもapk出せた. そしてうまいこと動作してめでたしめでたし.

背景

ValueからKeyを引っ張ってこれるデータ構造ほしい(Java) KeyValueが1対1であることが保証できればforとかで舐めればいいけど,たくさんデータあると大変. なんかKeyValue反転とかできたら便利

関連技術

ここでは関連する技術について述べる

Guava

Guava[1]はGoogleが開発している色々便利なデータ構造とか処理を書いたライブラリのこと. 今回はこの中に実装されているBiMapを利用した. BiMapはKeyValueなデータ構造なんだけど,inverseっていうメソッドが実装されていて,これを使えばKeyとValue反転できる.そして逆に検索可能.便利. しかしこのライブラリは巨大過ぎるゆえにクラス数,メソッド数が異常にある.

Multi Dex Support

Androidはアプリ内に定義されたメソッド数が65536を超えるとビルドできなくなる. そのための対策としてMultiDex[2]がある.まあひとつのファイルに65536詰められないなら,分ければいいやんみたいな発想.具体的には参考文献を参照のこと

実装

BiMapの利用

nini_y氏[3]はBiMapについて解説している.

BiMap<Integer, String> biMap = HashBiMap.create(); // newではない

biMap.put(0, "hogehoge");
biMap.put(1, "foofoo");

biMap.get(0); // -> "hogehoge"

biMap.inverse(); // -> BiMap<String, Integer>が得られる
biMap.inverse().get("foofoo"); // -> 1

MultiDex

このままだとメソッド数が多すぎてapk出せなくなるので,MultiDexすることで回避する. chuross氏[4]はメソッド数が多すぎることに対するMultiDexについて解説している. 以下Android Studioでの対応を記載する.

// build.gradle 

android {
    ...
    defaultConfig {
        ...
        multiDexEnabled true
    }
    ...
}

dependencies {
  ...
  compile 'com.android.support:multidex:1.0.0'
  ...
}

Applicationクラスを利用している場合

class MyApplication extends MultiDexApplication{
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

Applicationクラスを利用していない場合はAndroidManifest.xmlにMultiDexApplicationを追記してもよい

<application 
        android:name="android.support.multidex.MultiDexApplication">
</application>

評価

動いた

考察

便利

終わりに

俺は一体何をしているんだ.

参考文献

[1] google/guava https://github.com/google/guava

[2] Building Apps with Over 65K Methods | Android Developers http://developer.android.com/tools/building/multidex.html

[3] com.google.common.collect.BiMapを試す http://yy.hatenablog.jp/entry/2013/05/07/221421

[4] Androidメソッド数が65k(65536)を超えた場合にビルドができなくなる問題の対処法 http://qiita.com/chuross/items/c874e5058aa5847e1b98

追記

MultiDexするとめっちゃビルド遅くなる気をつけて.

とのことなので,そのあたりの評価はとってない.今後の課題とさせていただきます.

gradlewが謎のエラーで動かない件について

研究室の悲しみのライブラリやアプリたちを頑張ってgradle project化してたら面倒なのに引っかかった.

gradle普通にやると,gradlewとかいうgradleを持ってない下々の者でもgradleを利用できるようになる便利ツールがあるんだけど,なぜか「Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain」というエラー吐いて今動かなかった.

色々調べてると,<project root>/gradle/wrapperの中にある,gradle-wrapper.jarが存在しないからと言われた.

実際これを追加すると動いて,なんで消えちゃったんだろうみたいに思ったけど,よくよく考えるとgitignoreで*.jarがなかったことにされてるからだった.

復旧方法としては,まず,gradle-wrapper.jarを作る

$ gradle wrap

これでgradle/wrapper/gradle-wrapper.jarが完成する.

あとgitignoreしちゃってる人は無理やりaddすればコミットできる.

$ git add -f gradle-wrapper.jar

後はお好きにコミットしてください.

gitバックエンドwiki.gollum

gitをバックエンドにしたwikiのgollumを試してみた.Sinatraで動いてるらしいです.

gollum/gollum · GitHub

f:id:programmerMOT:20140103035310p:plain

こんな感じの普通のwikiになります.この画面はある程度利用した姿です.

画面編集するといい感じに指定したリポジトリにコミットしてくれます.それをそのままpushもできます.

Install

$ gem install gollum
$ gem install github-markdown # markdownを利用可能にするため

いい感じにインストール完了すると思います.2つ目のは,一部記法の利用に必要なものです.README見るとわかると思います.

setting

あとはいい感じにディレクトリ用意して

$ mkdir wiki
$ cd wiki
$ git init
$ gollum --mathjax

mathjaxはmathjax記法を利用する感じのやつです.mathjaxはいい感じの数式記述のあれです.

特に指定しなければ実行した場所にデータを置いてリポジトリを更新するらしいです. 指定するには,--gollum-path使えばいい.

advance

フッターヘッダーサイドバー

_Footerと_Headerと_Sidebarという特殊なページを作るとフッターヘッダーサイドバーをいい感じにいじれるようになる.

ただいまいち使い勝手悪くて使ってない.

認証

オプションに--configというのがあっていい感じに書けるらしいです.sinatra分かる人にはわかるらしいですが,僕もちょっとしか知らないのでわかりません.

module Precious
  class App < Sinatra::Base
    use Rack::Auth::Basic, "Restricted Area" do |username, password|
      [username, password] == ['user', 'password']
    end
  end
end

このファイルをgollum起動時に--configつけて渡すとBasic認証になります.他の認証もRackたよればいい感じに書けるらしいです.

サーバに放置

あとはいい感じに起動スクリプト書いたりしてcrontabとかでwikiリポジトリを定期的にpull,pushすればバックアップも完璧.

gollum --helpでオプション出るので参考にして頑張ってください.

おわりに

便利な機能とか見つけたら教えてください.

参考文献

githubのwikiエンジン"gollum"の導入と細かい設定 - yukke::note

vagrantでaws ec2インスタンスを立ち上げる

Vagrant 1.1 で EC2 を vagrant up - naoyaのはてなダイアリー
こちらの記事を参考にvagrantでec2を立ち上げるのを試して見ました.

ですが色々引っかかったりして大変だったので,備忘録的に残します.

まずはVagrantのインストールですがこれは他のところでもいっぱいあるのでそちらに任せるとします.ぶっちゃけvirtualBoxVagrant公式に行って最新版落としてくればいいんですけど.

Vagrantはgemでも入れようとすれば入りますが古い上にもう公式がgemはやめろって言ってるらしいので公式からパッケージを落としてくればいいと思います.


まず上記URLを参考にpluginをインストールし,awsのためのdummy boxを設定します.

$ vagrant plugin install vagrant-aws
$ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box

その後作業用ディレクトリに入ってinitします.

$ vagrant init

設定ファイルのVagrantfileをいじります.

$ emacs Vagrantfile

そしてこんな感じに編集しました.

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "dummy"

  config.vm.provider :aws do |aws, override|
    aws.access_key_id     = #EC2の権限を持ったAccessKey
    aws.secret_access_key = #EC2の権限を持ったSecretAccessKey
    aws.keypair_name = "mot-ec2"
    aws.instance_type = "t1.micro"
    aws.region = "ap-northeast-1"
    aws.ami = "ami-39b23d38"
    aws.security_groups = [ 'vagrant' ]

    override.ssh.username = "ec2-user"
    override.ssh.private_key_path = "~/.ssh/mot-ec2.pem"
  end
end

参考URLの時からVagrantがアップデートしたりしています.そのおかげで少しオプションが変わっています.

aws.amiには使用するAMIを設定します.ここではAmazonLinux(64bit)のAMIを指定しています.
参考URLの時のAMIが現在存在しなかったのでそこで引っかかったりしてました.

aws.security_groupsで指定しているvagrantセキュリティグループはsshのみを許可したセキュリティグループです.sshを許可しないと色々残念になります.それ以外のポートなどは適宜セキュリティグループを修正してください.

ここまで設定すればだいたい終わりです.

$ vagrant up      # インスタンスが立ち上がる
$ vagrant ssh     # インスタンスにssh
$ vagrant destroy # インスタンスをterminate

僕自身まだAWSとかVagrantとか全然詳しくなくて勉強しながらやってますが,楽しいですね.
こうやってサーバをすぐ調達できるのは面白いなぁ.


これからはChef-soloとかも使ってサーバ構築して潰す生活をしたいと思います.
破壊なくして創造はなし