2012年12月8日土曜日

シェル芸人への道


第2回シェル芸人養成勉強会に参加してきた。
hbsstudyハンズオンにも参加していたので、なんとなく雰囲気が掴めていて前回よりついていけたような気がする。 前回と同じく以下、自分の知らなかったことの(断片的な)まとめ。

パイプステータス

パイプを何個もつなげると、最後の終了ステータスしか分からないと思っていたが、
実はPIPESTATUSに最後のステータス以外も配列として格納されている。
% echo hoge | cat
hoge
% echo hoge | cat | cat | cat | cat
hoge
% echo ${PIPESTATUS[@]}
0 0 0 0 0
% echo hoge | cat | cat error | cat | cat
cat: error: No such file or directory
% echo ${PIPESTATUS[@]}
0 0 1 0 0

フィールドを指定したソート

-kn,m (nは開始フィールド、mは終了フィールド)オプションでソートに使用する基準を指定できる。
-kオプションを使うことは知っていたけど、このあたりの理解が曖昧になっていた。
% cat hoge
a 12
a 13
b 13
a 432
b 111
b 43
# フィールド1番目、2番目の順でそれらをキーとしてソート
% sort hoge | sort -k1,1 -k2,2nr
a 432
a 13
a 12
b 111
b 43
b 13

ランダムソート

要素をランダム(ハッシュに応じて)ソートする。
これはソートと言っていいのか?という疑問はある。
% seq 1 10 | sort -R
5
9
1
2
6
3
10
8
4
7

grep検索パターンをファイルから指定

-fオプションを使うことにより、検索するパターンをファイルから取得できる。これは便利。
% cat fuga
hoge
fuga
piyo
% cat fuga2
fuga
piyo
piyopiyo
# fuga2の内容をパターンとしてfugaからgrep
% grep -f fuga2 fuga
fuga
piyo

プロセス置換

これを一般的になんて表現したらいいのか分からないけど、以下のようにするとファイルに出力を意識することなく、ファイル出力されたものとして他のコマンドに結果を渡せる。
# 裏側ではファイル出力してるのやろうけど、使用者からは意識しなくて言いと言う意味
(ご指摘を受けたので修正)

以下のようにすると、プロセスの入出力をファイルのように取り扱うことができる(ファイルは出力していない)。
% cat hoge
a 12
a 13
b 13
a 432
b 111
b 43
% wc <(cat hoge)
      6      12      32 /dev/fd/63

どれも明日使える内容ばかりですね!!

しかしこれくらいで感心しているようでは、シェル芸人の道のりはまだまだ遠い。。

2012年11月20日火曜日

[Android] AVDの作成時に"Error: null"と表示されて作成失敗する。


 Androidのエミュレータを作成するときに作成ボタンを押しても反応せずに、 "Error:null"とだけログに表示される。


 困ったときのStackOverFlowがやはり役に立って、このあたりの回答と参考にすると、 結局のところ環境変数ANDROID_SKD_HOMEに.androidの上のディレクトリ(\Users\toyuserなど)を指定してやればこのエラーは出なくなった。


 問題はなんで今まで作成できたものが出来なくなったのかは分からないけど、とりあえず解決したらかクローズ。

2012年11月9日金曜日

[Android]スライドで大きさを変えられる可変ビュー作ってみた


Androidっていわゆるスライドバーみたいな感じでビューの大きさを変えることって
標準のウィジェットでは用意されていない。

やからスライド(ドラッグ)で大きさを可変にできるビューを作ってみた。

なまえは適当にSlideBarDrugViewControllerとしてみた。
ソースはコチラ(Github)。以下は使い方の簡単なメモ。

レイアウト

スライドバー用のビューと、その上下にビューを用意する。
今回は例なのでビューの種類は何でもいい。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello"
        android:id="@+id/view0"
        android:gravity="center" />

    <TextView
        android:id="@+id/view1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SlideBar"
        android:background="#6090ef"
        android:gravity="center" />
    
    <Button
        android:id="@+id/view2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="BottomView" />


</LinearLayout>


MainActivity

Mainのアクティビティにレイアウトを読み込ませる。
以下の2点を使用する。
  • (1)で書かれている4つの引数を与える
  • (2)のようにonTouchイベントをcontrollerに渡す

public class SlideBarWidgetActivity extends Activity {
    
 Context context;
 SlideBarDrugViewController controller;
 View upperView;
 View slidebarView;
 View bottomView;
 
 
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        upperView = (View)this.findViewById(R.id.view0);
        slidebarView = (View)this.findViewById(R.id.view1);
        bottomView = (View)this.findViewById(R.id.view2);
        context = this;
        
    }
    
 public void onWindowFocusChanged(boolean hasFocus) {
  WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  Display display = wm.getDefaultDisplay();
  final int screenHeight = display.getHeight();
  
        Rect r = new Rect();
        this.upperView.getGlobalVisibleRect(r);
  if(controller == null){
      /**
  * (1)以下の4つの引数を与える
  * drugView 可変ビュー(スライドバーの上部ビュー)
  * slideBarView スライドバーとなるビュー
  * minpx 可変ビューの上部(top)の絶対座標
  * maxHeight スライドバーが下に動く最大サイズ。画面全体の大きさを入れると最下端まで移動させられる
  */
   controller = new SlideBarDrugViewController(upperView, slidebarView, r.top, screenHeight);
  } 
 }
  
 @Override
 public boolean onTouchEvent(MotionEvent event){
           // (2) onTouchイベントをcontrollerに委譲
   return controller.onTouchEvent(event);   
 }
    
}

実行結果

画像では分かりにくいけど、ScrollBarをスライドさせるとそれにあわせて上下のビューの大きさが変化する。

2012年10月28日日曜日

#hbstudyハンズオン


10問お題が出されてそれをbashワンライナーで解けという内容でした。
普段からのコマンド習熟度が問われるわけですね。
・・・と思ったらawk習熟度が思いっきり問われました。

以下は自分が知らなかったことの(断片的な)まとめ。

標準入力をcatで受け取るには


ハイフンを引数に取ればいける。知らなかった。
もちろん複数の引数をとればcatの出力は連結される。

$ echo "hoge" | cat -


bashでデータをランダムにシャッフルするには

慣れている人がやればawkでもうこれは慣用句らしい。

以下は1~10の数字をランダムにシャッフルする例


$ seq 1 10 | awk '{print rand()" "$1}' | sort | awk '{print $2}'
10
4
8
6
1
2
9
5
7
3
awkでの切った貼ったはお手のものですね。

欠けているデータを探すには

お題では1~10までのどれか一つの数字が欠けていてさらにシャッフルされたデータがあるとき、その欠けている数字のみを表示するというもの。
diffはそれ以外のものも表示されてしまうので禁止。


$ cat num
10
8
6
1
2
9
5
7
3
$ seq 1 10 | cat - num | sort -n | uniq -u
4

ここの問題のミソは比較したいデータをまとめてソートしてuniqで一行しかないものをとってくると言うこと。-uオプションとかこういう風に使えるのね。

FizzBuzz問題

できるだけエレガント?に

$ seq 1 100 | awk '$1%15==0{printf "FizzBuzz "} $1%5==0{printf "Buzz "} $1%3==0{printf "Fizz "} {print $1" "}' | awk '{print $1}' | tr "\n" " "

1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buz

まあこれはいろんな方法がありそう。自分は最初bashのtestコマンドで頑張っていたがawkの方が短くなるね。


所感?

印象深かったことは、玄人(バイニン)の人たちは息をするかの如くawkを書きなぐっていたこと。
自分はawkほとんど慣れていなかったので、後半はついていけなかった。。

あの時間から3時間シェルと遊ぶのはなかなかエネルギーが必要やったけど、いい勉強になった。

2012年10月14日日曜日

MongoDBメモ

MongoDBのインポートコマンドのメモ
mongoimport -v -d Document名 -c Collection名 --file JSONファイル
上記のコマンドで、JSONファイルで書かれたデータをMongoDBにインポートできる。

2012年10月2日火曜日

Scala体験記_2

Scalaのifは文(statement)じゃ無くて式(expression)なんだぜ。だから以下のように書けたりする。

    val a = if (1 < 2 ) {10} else {20}
    println(a)
まぁこれだけやと三項演算子と何が違うの?っていわれそうやけども。

if式でハマってしまったのは、if式の評価順が予想よりも低いこと。
以下の例の出力結果はどうなるやろうか。


    val a = if (1 < 2 ) {
       10
    } else {
       20
    } 
       + 5
    println(a)

意味もなくネストして書いてみたけど、こいつの出力結果は10となる。 これはifよりも{20} + 5が先に評価されたせい。 これに気づかずに1時間ぐらい悩んでたら良くある誤解として取り上げられていたのでメモ。

2012年10月1日月曜日

Scala体験記


Scalaを使って何か書いてみようと思ったけど、基本的なループの書き方すらよく分かってなかったので復習がてら内容をメモ

以下Int型リストの総和を求めるというものすごく簡単な例

関数型っぽく書いたとき


def calcsum(list:List[Int]) : Int = {
    if (list.isEmpty)
      0
    else
      list.head + calcsum(list.tail)
  }

Java(手続き型)っぽく書いたとき


  def calcsum2(list:List[Int]) : Int = {
    var sum = 0
    for( value <- list) sum += value
    sum
  }

こういう風に関数型と手続き型の両方で書けるのがScalaのいいところ。 その気になれば全部Javaっぽく書くのも可能。

2012年9月20日木曜日

1つのプロジェクトにJavaとScalaを混在させてビルドする方法

もうすでに詳細なやり方が他の記事で書かれていたので、メモ代わりにリンクを張っておく

 Scala Eclipseプラグインの導入からビルドまでの手順

 JavaプロジェクトでScalaコードを含めてビルドする手順

 思ったより簡単にJavaプロジェクトにScalaコードを書いて実行することができた。
 Scalaで定義したメソッドの定義をJava側のコードで補完とかもできるので一部だけScalaを混ぜても 違和感無く使用できそうな感じがした。



 Androidコードもこの調子でさくっとビルドできればいいんやけど。。

2012年9月19日水曜日

Eclipse4.2(JUNO)でScalaプラグインインストール時のエラー

Eclipse4.2からScalaトップページのプラグインを入れたら以下のようなエラーが出た。
Cannot complete the install because one or more required items could not be found. Software currently installed: Scala IDE for Eclipse 2.0.2.v-2_09-201207120929-81d0972 (org.scala-ide.sdt.feature.feature.group 2.0.2.v-2_09-201207120929-81d0972) Missing requirement: Scala Plugin 2.0.2.v-2_09-201207120929-81d0972 (org.scala-ide.sdt.core 2.0.2.v-2_09-201207120929-81d0972) requires 'bundle org.eclipse.jdt.core [3.6.0,3.7.10)' but it could not be found Cannot satisfy dependency: From: Scala IDE for Eclipse 2.0.2.v-2_09-201207120929-81d0972 (org.scala-ide.sdt.feature.feature.group 2.0.2.v-2_09-201207120929-81d0972) To: org.scala-ide.sdt.core [2.0.2.v-2_09-201207120929-81d0972]
JUNO用のプラグインは別に用意されているようで、 ここからJUNO用のプラグインをダウンロードできる。

2012年9月18日火曜日

Ubuntu/Linux Mintでsun jdkを入れる手順

Ubuntu/MintではデフォルトではopenJDKが入っている。 sun JDKは手動でインストールしないといけない。 手順をメモ廊下と思ったけど、このページが非常に参考になるため、割愛

2012年9月17日月曜日

2012年9月14日金曜日