2013年4月18日木曜日

Androoidの開発の面倒なところとか

何箇所か言えって言われたらすぐに出てきますが、解決できる部分に関しては何とかして行きたいって考えでイロイロやってます。

以前作ったのは、コマンドラインから端末のスクリーンンショットを撮影するスクリプト。

adbscreen
https://github.com/numa08/adbscreen

monkeyrunnerを利用して、シェルスクリプトと組み合わせてスクショの撮影を行います。

最近はバイナリのインストールやデバッグ時にIntentを投げたり、Android端末からフォームに入力したりをすべてコマンドラインから済ませようとする癖がついて(マウスや端末に手を伸ばすのが面倒)きたので、開発PCに接続している端末全てに同じ操作を行うスクリプトをチョイッと書いた。

$devices(){ adb devices | awk 'NR>1 && /^\a|\d/ {print $1}'; } #デバイス一覧の取得
$devicestest(){ devices | while read dev; do $* $dev; done; } #全デバイスに対して同じ処理を行う
#例
#すべての端末にバイナリをインストールして、アプリを起動する
$reinstall(){ adb -s $1 uninstall $package; adb -s $1 install $bin && adb -s $1 shell am start -D -n ${package}/${activity}; }
$devicestest reinstall
view raw android.sh hosted with ❤ by GitHub

ちゃんとデバッグしてないけど、だいたい動く。

こういうのをまとめてAndroidのデバッグサポートスクリプトとかにしたいなー?って考えるけど、たぶんadbのコードをいじって拡張するのが正解だと思う。



2013年4月17日水曜日

Dentoo.LT3 で話してきた #dentoolt

3ヶ月に一回、電通大(UEC)に訪れる狂気、それがDentoo.LT

参加は皆勤賞の3回目、登壇は飛び入り含めて5回目。

やったこと


生放送ラジオをやってきた。

ラジオをやるために

ラジオを生放送をやるために、いくつか必要な要素はあると思うが、最も大事だと思ったのが
オーディエンスとのコミュニケーション、つまり「お便り」だと考えた俺は、あるシステムを作った。

こんなシステムだった



実工数はたぶん1日ないくらい。
10分程度の寿命だったけど、十分実用に耐えうるものだった。

実は、初めて一般に公開したWEBサービスだったんだ。

DB使わないし、入力をユーザに返すわけでもないからセキュリティに関しても気を配る必要もなかった。
気になる点はF5アタックだけだったわけだけど、同時接続数を考えても大丈夫かな?な丼勘定。

スライドにも書いたように、Play!のコントローラは利用せず、Ajaxなやりとりを行なっていたためその気になればCurlなんかでアタックできる可能性もあった。もちろん、そこの対策は行ったけど。

というわけで、SublimeText2+ねこび~んがWebアプリ開発で良い感じに強いねって印象だった。

今後の展開?

機会を見つけてまた使いたい。
リッチなUIや、もしかしたらTwitterに頼らないシステムにするのもいいかもしれない。

ちなみに公開中

GitHubでソースコードを公開中。改変、利用はご自由に。


2013年3月26日火曜日

「プログラミング出来ない奴ちょっと来い」を読んだプログラミングができない奴と、4年前の俺、ちょっと寄ってって

前置き


先日増田に投稿された記事

「プログラミングできない奴ちょっと来い(http://anond.hatelabo.jp/20130322031333)」

Gunosyで流れてきたり、トラックバックも沢山ついてるので気になっていたら、やっぱり

「プログラミングは一朝一夕に達成できるものじゃない - カレーなる辛口Javaな転職日記(http://d.hatena.ne.jp/JavaBlack/20130324/p1)」

なんて記事も書かれてました。

俺のポジションとしては概ね後者のエントリーに同意です。紹介されている本も良書なので読んでおくべき本だと思います。

だけど、この方法でプログラミングができるようになる人ってのはたぶん、本を一回読んで理解できて、授業なんかを受けて及第点を取って、コードを書いて一発で自分の物にする「頭のいい」人なんじゃないかと思いました。

あ、ちょっと言い過ぎました。

今回のブログのタイトルにもした「4年前の俺」は、プログラミングができない人間でした。どれくらいできないのかと言うと、次のような感じ。

  • 大学のプログラミングの実習の単位を落とす
  • 「1年勉強したらどうにかなるやろ!」と思って独学で勉強した
  • 結局、同じ授業を3回受けて単位を取得した
  • 可だった
大学の授業なので当然ながら周りの人達は1度の履修で合格、たまに再履がいても2回でどうにかなるレベルの授業。
それを3回も受けないとどうにもならなかったので、自信を持って「プログラミングができない!」を名乗っていいと思います。

ちなみに、今はプログラミングができるのか?と聞かれると今は次のような感じ。
  • 業務や趣味で利用している言語やFWのリファレンスを見れば、要望の実現可能性、必要な工数の見積、実装、試験が行える
  • 数カ月後に自分が見て理解のできるコードが記述できる
  • 数万行レベルのシステムに絡んだことはない
したがって、下の上くらいは名乗っていいと思います。中級はまだ早い気がしますが。

ですが「プログラミングができない」とは思っていません。
よって「プログラミングができない人が、初級レベルになる方法」レベルでの提案をさせてもらいたいです。

ただ、時期的に新卒や学生向けです。

対象読者


理由(授業、仕事など)があってアプリやシステム、ライブラリの実装を行いたいと思っていても、本を読んでも理解ができず、授業を聞いても頭に入ってこず、コードを書いても呪文にしか思えない人。このような人で「自分はプログラミングができない」思っている大学生や新卒。
あと、もしも時空が歪んでこの記事が4年前から閲覧できるなら、当時の俺。

プログラミングができるようになる2つの方法


結論から言うと方法は2つで、両方の実践が早道でした。
  • まず、良い師を見つけて自分が良い弟子になること
  • 良い友を見つけて、自分も良い友であり続けること
こうやって書くと、プログラミング以外でも通用できそうなただの体育会系一般論な気がして来ました・・・。

良い師を見つけて、良い弟子になること

良い師とは、「プログラミングができて、それを人に教えることができる」人です。

情報系の大学生ならこれは簡単ですね、あなたの履修している授業の先生です。

新卒も同じですね、あなたの教育担当の上司です。彼らに積極的を活用しましょう。

あなたはプログラミングができないのです。もっと言うと「何がわからないのか分からない」のです。だから聞きに言ってください。訪ねてください。師はあなたに教えるために居ます。あなたに教えて、その成果で飯を食ってます。

自分一人で考える時間が勿体無いです。俺はこれで2年間を無駄にしました。

良い友を見つけて、自分も良い友であり続けること

あなたの同期や同僚はあなたと同じレベル・・・と言う訳にはいかないと思います。

俺の大学の同期はみんなできる人で、ちゃんと4年で大学を卒業し、中には大学院にも行って就職をしました。俺が何年もかけて取った単位を簡単に取り、良い成績を納めてました。

でも、すごく良い人達でした。

詰んでる俺を助けてくれようと色々教えてくれたことを覚えてます。ただ、俺の態度は悪かったです。

まあ、嫉妬と言うかそういうのがありました。同じ学年で同じ授業を受けてるのに、なんで彼らは良い点取ってるのに、俺はできないんだ?そういう思いがあったので、彼らのアドバイスを素直に受け入れられなかったと思います。

お陰で2年間を余計に過ごしました。

まとめ

良書も読みましょう、コードだって書くべきです。
そして、それらと並行しつつ自分ができないのを認めて、誰かに頼りましょう。
以上が、自分が余分に大学生を2年間過ごして学んだ事柄でした。

元となった2つの記事とは、あんまり関係のない話に落ち着いた気がする・・・。

2013年3月6日水曜日

Hosebirdを使ってユーザーストリームを取得する

TwitterAPIも1.1になったりと色々盛り上がっている中、新しいライブラリのHosebirdをTwitterが公開しました。

米Twitter、Streaming API向けJavaクライアント「Hosebird Client」をオープンソースに

TwitterがAPIのクライアントライブラリをOSSにするのは初めてとのこと。

面白いのが、Twitter4jを利用していること。どの程度のことができるのかはわかりませんが、
今までTwitter4jを利用して作成したアプリケーションの拡張なんかがお手軽にできるかもしれませんね。

というわけで、TwitterなのでScalaでコードを書いてみました。sbt 0.12.2, scala2.9.3で動きます。

name := "hosebird"
version := "0.1.0"
scalaVersion := "2.9.3"
libraryDependencies += "com.twitter" % "hbc-core" % "1.3.0"
libraryDependencies += "commons-lang" % "commons-lang" % "2.6"
view raw build.sbt hosted with ❤ by GitHub
package jp.numa08.hosebird
import com.twitter.hbc.ClientBuilder
import com.twitter.hbc.core._
import com.twitter.hbc.core.processor.StringDelimitedProcessor;
import com.twitter.hbc.httpclient.auth.OAuth1
import com.twitter.hbc.core.endpoint.UserstreamEndpoint;
import scala.collection.JavaConversions._
import java.util.concurrent.LinkedBlockingQueue
import org.apache.commons.lang.StringEscapeUtils
object MyApp extends App {
val oauth = new OAuth1("consumerKey", "consumerSecret", "token", "tokenSecret")
val texts = new LinkedBlockingQueue[String](100000)
val client = new ClientBuilder()
.hosts(Constants.USERSTREAM_HOST)
.authentication(oauth)
.processor(new StringDelimitedProcessor(texts))
.endpoint(new UserstreamEndpoint())
.build()
client.connect
Stream.continually(texts.take).foreach(json => { val out = StringEscapeUtils.unescapeJava(json)
println(out)})
}
view raw MyApp.scala hosted with ❤ by GitHub



ClientBuilder#hostとClientBuilder#endpoint を変えてあげれば他のストリームもお手軽に取得できます。


あ、FirehoseだからHosebirdなのか。今気がついた・・・・。

GitHub





2013年2月10日日曜日

Scala + Sbtでデーモンを作る方法



サーバーで動作を行うデーモンを、Scalaで書きます。

なお、環境はRHEL系のLinuxで動作を確認しました。それ以外のOSの方は
適宜読み替えてください。

また、ビルドなどはsbtを利用するので、「始めるsbt」などを読んでおくと
いいと思います。

1.Scalaのコードを書く


1.1 参照の追加


sbtを使ってアプリを構成します。今回、ApacheCommonDaemonを利用するので、
build.sbtに次のように参照を追加します。

libraryDependencies += "commons-daemon" % "commons-daemon" % "1.0.10"
view raw build.sbt hosted with ❤ by GitHub


1.2 Scalaのコードを書く


Daemonインターフェースを継承したクラスを書きます。
今回は次のようにしました。
package jp.numa08.main
import org.apache.commons.daemon._
class MyDaemon extends Daemon {
var daemonService:MyDaemonService = _
@throws(classOf[DaemonInitException])
@throws(classOf[Exception])
def init(context:DaemonContext){
daemonService = new MyDaemonService()
}
@throws(classOf[Exception])
def start(){
daemonService.start()
}
@throws(classOf[Exception])
def stop(){
daemonService.stop()
}
def destroy(){
}
}
view raw mydaemon.scala hosted with ❤ by GitHub

一応、例外を明示的に投げるように書いておいています。

1.3 実行可能ファイルを作る


sbt-assembkyを使って実行可能なjarファイルを用意しました。
sbt-assemblyについては、こちらの記事を参照してもらえると嬉しいです。

2. jsvcのセットアップ


2.1 ソースコードをダウンロードする

http://commons.apache.org/daemon/download_daemon.cgi

上記のURLから''native-src''をダウンロードします。

ビルド対象のコードは
jsvc/commons-daemon-1.0.12-native-src/unix
view raw jsvc_source.sh hosted with ❤ by GitHub
にあります。

2.2 ビルドに必要なライブラリ、ツール群をインストールする。


ApacheCommonDaemonのページによると次のツールが必要とのことです。
  • GNU AutoConf (at least version 2.53)
  • An ANSI-C compliant compiler (GCC is good)
  • GNU Make
  • A Java Platform 2 compliant SDK

yumなどを利用してインストールしましょう。

2.3 ビルド、インストールする


./configure
make
make install
view raw build.sh hosted with ❤ by GitHub

jsvc -help ができることを確認。

3. 起動する


起動スクリプトと終了のスクリプトを記述しました。
デーモンらしく,/etc/rc..d/init.d/以下に保存をすると
いいと思います。
MY_JARFILE=/usr/local/bin/my_daemon.jar
MY_PID_FILE=/usr/local/etc/my_daemon.pid
MAIN_CLASS=jp.numa08.main.MyDaemon
prog=my_daemon
RETVAL=0
start() {
echo -n $"Starting ${prog}:"
jsvc -home ${JAVA_HOME} -cp ${CLASSPATH}:${MY_JARFILE} -pidfile ${MY_PID_FILE} ${MAIN_CLASS}
RETVAL=$?
if [[ $RETVAL == 0 ]]; then
echo -e "\t\t [\033[1;32m OK \033[0m]"
else
echo -e "\t\t [\033[1;31m FAILED \033[0m]"
fi
return $RETVAL
}
stop() {
echo -n $"Stopping ${prog}"
jsvc -stop -pidfile ${CHOCOLA_PID} ${MAIN_CLASS}
RETVAL=$?
if [[ $RETVAL == 0 ]]; then
echo -e "\t\t [\033[1;32m OK \033[0m]"
else
echo -e "\t\t [\033[1;31m FAILED \033[0m]"
fi
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
start
stop
;;
*)
echo $"Usage: ${prog} {start|top}"
RETVAL=2
esac
exit $RETVAL
view raw my_daemon.sh hosted with ❤ by GitHub

4. 参考にしたWEBページなど

以下のページを参考にしました。
Play framework 2.0でデーモン化する方法
始めるSBT
SBTで実行可能なjarファイルを作る
Apche Commons Daemon

2013年1月1日火曜日

Scalaでダックタイピング?implicitを使ってみたよ

あけましておめでとうございます。

年明け最初の記事は、Scalaの勉強ということでimplicitを使ってみた話。

Javaの実装でtoHoge()な書式が好きなので、interfaceを使って実現をするのですが、
既存のクラスに関してはそれができません。

その具体例と、対応方法は次のコード。
Outputableを実装したクラスを受け取って出力を行うクラスです。

public interface Outputalbe {
public String output();
}
view raw Outputable.java hosted with ❤ by GitHub


自前のクラスに関しては、implementsすれば好き勝手に実装ができますね。

public class Profile implements Outputalbe {
private final String name;
private final int age;
public Profile(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String output() {
return String.format("Hey, I am %s , and I'm %d old.", this.name,
this.age);
}
}
view raw Profile.java hosted with ❤ by GitHub


そして出力用のコード。

public class Display {
public static void main(String[] args) {
Display display = new Display();
Outputalbe data = new Profile("numa08", 24);
display.out(data); //Hey I am numa08 and , I'm 24 old.
}
private void out(Outputalbe data) {
System.out.println(data.output());
}
}
view raw Display1.java hosted with ❤ by GitHub


しかし、既存のクラスに関してはそうはいかないので、ラッパークラスを
用意することになります。

import java.text.SimpleDateFormat;
import java.util.Calendar;
public class OutputableCalendar implements Outputalbe {
private final Calendar calendar;
public OutputableCalendar(Calendar calendar) {
super();
this.calendar = calendar;
}
@Override
public String output() {
SimpleDateFormat format = new SimpleDateFormat("'Today is 'yyyy/MM/dd");
return format.format(this.calendar.getTime());
}
}


import java.util.Calendar;
import java.util.GregorianCalendar;
public class Display {
public static void main(String[] args) {
Display display = new Display();
Calendar today = GregorianCalendar.getInstance();
Outputalbe data = new OutputableCalendar(today);
display.out(data); //Today is 2013/01/01
}
private void out(Outputalbe data) {
System.out.println(data.output());
}
}
view raw Display2.java hosted with ❤ by GitHub


呼び出し元も、新しいクラスを呼び出したりで面倒くさい。

Javaという言語は面倒臭いですん。

さて、Rubyではもっと柔軟な感じにいけて、クラスの定義を
コードの途中で再開させることができるのです。

まずは、自前のクラスに対しての実装。
require "./Profile.rb"
def display(data)
puts data.output
end
profile = Profile.new("numa08", 24)
display(profile) #Hey I am numa08 and , I'm 24 old.
view raw Display1.rb hosted with ❤ by GitHub


class Profile
def initialize(name, age)
@name = name
@age = age
end
def output
"Hell, I am #{@name} , and I'm #{@age} old."
end
end
view raw Profile.rb hosted with ❤ by GitHub


そして、既存のクラスの拡張。
class Time
def output
strftime("Today is %Y/%m/%d")
end
end
view raw Time.rb hosted with ❤ by GitHub


def display(data)
puts data.output
end
today = Time.now
display(today) #Today is 2013/01/01
view raw Display2.rb hosted with ❤ by GitHub


Rubyって便利。

そして、最後にScala。暗黙的変換のimplicitキーワードを使ったメソッドを
用意することで、コンパイラが自動的に適した型に変換するメソッドを呼び出して
くれるのです。

trait Outputable {
def output:String
}


class Profile(name:String, age:Int) extends Outputable{
override def output = {
"Hey I am " + name + " and , I'm " + age + " old."
}
}
view raw Profile.scala hosted with ❤ by GitHub


def output(data:Outputable) = {
println(data.output)
}
val me = new Profile("numa08", 24)
output(me) //Hey I am numa08 and , I'm 24 old.
view raw Display1.scala hosted with ❤ by GitHub


implicitを使って変換を行う例。

import java.text.SimpleDateFormat;
import java.util.Calendar;
class OutputableCalendar(calendar:Calendar) extends Outputable{
override def output = {
val format = new SimpleDateFormat("'Today is 'yyyy/MM/dd")
format.format(calendar.getTime)
}
}
implicit def toOutput(calendar:Calendar) = new OutputableCalendar(calendar)


import java.text.SimpleDateFormat;
import java.util.Calendar;
def output(data:Outputable) = {
println(data.output)
}
val today = Calendar.getInstance
output(today) //Today is 2013/01/01
view raw Display2.scala hosted with ❤ by GitHub


実に気持ちがいい。呼び出し元は、クラスの変換とか意識しなくていいんですよ。

ただ、Javaでも型変換にtoHoge()な実装をしない
コードをたくさん見てきたので、ちょっとアレ。

今年も、綺麗なコードを求めてがんばりますね。

さて、今回参考にした書籍は次。


あと、最近はPlay frameworkを使ってScalaを
勉強してます。