タグ「バグ」の一覧

Perl:コマンドライン引数でつまずく

さっきまでPerlのスクリプトと格闘していてやっと問題が解決(?)したので、対処方法をメモしておきます。でも、まさかこんなことが起き得るんですね。

さて、その問題とはコマンドライン引数に改行文字が含まれるという問題。簡単にどんなシチュエーションでこの問題が起こったかを説明します。

まず、PCが2台あります。1つをPC_A、もう1つをPC_Bとします。
PC_A(WinXP 32bit)でPerlスクリプトとそれを何度も呼び出すシェルスクリプトを作成し、PC_B(WinXP 64bit)で実行します。そのプログラムの概要はだいたい以下の通り。
実行環境はCygwinで、Perlのバージョンは5.8.8(64bit)です。

#!/usr/bin/perl

my $a = $ARGV[0].".ext";
my $b = $ARGV[1].".ext";
my $c = $ARGV[2].".ext";

print system("java -jar jarfile.jar $a $b $c");

以下がシェルスクリプト*1です。(本当はこんな規則正しいパラメータの与え方をしているわけではありません。)

./perlscript.pl 10 10 10
./perlscript.pl 10 10 20
./perlscript.pl 10 10 30
# 以下同様...

./perlscript.pl 30 30 30

で、実行させようとすると、なぜかPerlスクリプトでの最後のコマンドライン引数がおかしなことになるのです。表示させてみると、どうやらcarriage returnが入っている模様。(表示が上書きされてたりするので。)

いろいろ試した結果、シェルスクリプトの行末に半角スペースを余分に入れることで対処。
でもこれまでこんな問題にぶつかったことがなかったので、かなり戸惑いました。

続きを読む

もうバグ取りは終わりにしたい

探しても探してもわいてくるバグ。今回のバグはかなり難しい!と自負できます。 これはもう、設計段階でどれだけ例外的な場合を考えることができるかにかかっています。 完璧なアルゴリズムに則ってさっさと組んでしまいたいです。

さて、そんなわけでこのブログの読者様にもぜひ挑戦してみて欲しいです。 ちなみに本来のコードを改造して、ちょっとだけ解きやすくなっています。 クラス名が適当なのは無視ということで...。

class Entry {
    private String id;
    private double value;
    public static Comparator<Entry> ID_ASCEND_COMP;

    // getter, setter は定義済みとします。
}

class Application {

    // 問題のメソッド
    public List<Entry> merge(List<Entry> list1, List<Entry> list2 ){
        Collections.sort(list1, Entry.ID_ASCEND_COMP);
        Collections.sort(list2, Entry.ID_ASCEND_COMP);

        Iterator<Entry> it1 = list1.iterator();
        Iterator<Entry> it2 = list2.iterator();
        Entry e1 = null;
        Entry e2 = null;
        List<Entry> merged = new ArrayList<Entry>();

        while(it1.hasNext() && it2.hasNext()){
            if(e1==null)  e1 = it1.next();
            if(e2==null)  e2 = it2.next();

            int key = Entry.ID_ASCEND_COMP.compare(e1,e2);

            if(key<0){
                merged.add(e1);
                e1 = null;
            } else if(key==0) {
                e1.setValue(e1.getValue()+e2.getValue());
                merge.add(e1);
                e1 = null;
                e2 = null;
            } else {
                merged.add(e2);
                e2 = null
            }
        }
        if(e1!=null)  merged.add(e1);
        if(e2!=null)  merged.add(e2);

        while(it1.hasNext())  merged.add(it1.next());
        while(it2.hasNext())  merged.add(it2.next());

        return merged;
    }
}

で、このメソッドが何をしているかというと、引数に与えられた2つのコレクションを1つにまとめるということをしています。ただし、IDが重複しているインスタンスがあれば、片方のインスタンスに value を加算してそれを追加するというメソッドです。ちなみに、list1とlist2がnullの場合は考えなくても構いません。(NullPointerExceptionが発生して終了するだけなんで。)また、ID_ASCEND_COMPは、Entryのidをソーとキーとして昇順に並び替えるComparatorです。*2

続きを読む

これでどうだ!?

昨日、あまりに実験結果の評価が悪かったのでプログラムの見直し+実験結果の見直しをしていました。そしたらやっぱりいました、あの嫌なやつ。バグが潜んでいました。今回のは、これまでバグの確認のために使っていたデータ以外の、本番用のデータで確認したらけっこうあっさり分かってしまいました。これはちゃんとテストをしろよ!という神からの思し召しなんでしょうか。それにしても、これまでこんなにバグが潜んでいたのかを思うと凹みます。

しかも間違えていたのが、コレクション中の最小値を見つける部分という、かなり情けない場所。やっぱり例外処理をちゃんとするべきですね。

double min(Collection<Result> col) {
    double min = Double.MAX_VALUE;
    for(Result r : col) {
        min = r.getValue() < min ? r.getValue() : min;
    }
    return min;
}

はい、これが問題のソースコードです。一見正しそうに見えますが、ちょっと処理が抜け落ちています。さて、どこでしょう…。

続きを読む

バグ多すぎ

昨日もバグを取ってたんですけど、結局致命的なやつを取り逃したために
もう1回実験をしなおすことになりました(>Д<;)
今度のバグは、これまでのような凡ミスではなく、プログラムとして組むべき
アルゴリズムを間違えていたというやつです。つまり、自分の頭の中で考えていた
プログラムと、本来必要とされる仕様とがずれていたってことです。
これは、一応作ったものとしては正しいのかもしれませんが、仕様を満たして
なかったら意味はないので…。ついでに高速化もしたので、明日には結果が
出てればいいな?。

デバッグ終了

さっきやっと研究用プログラムのデバッグが終了して、実際に走らせられる状態にまで持ってこれました。これでほぼJavaのプログラムを書くのは終了ということで、あとは実験スクリプトと論文に着手していく感じになります。のろのろ走るプログラムともこれでさよならですゝ(^O^)丿

[blog] 長丁場の終了 - LostMemories


前回の記録から1週間以上も経っているわけですが、これまで何に苦戦していたかというと、現行のプログラムにも実はバグが存在していて、それが高速化プログラムのテストの動作チェックを妨げていた点です。しかも比較に大きく動作に影響する場所だったりしたので、原因を追及していくことが難しかったのです。で、今日はその現行プログラムのバグも無事にとれ、高速化プログラムがちゃんと動くことが確かめられたというわけです。

…実は、高速化プログラムには現行プログラム以上のバグがあったんですけどね(;´д⊂

とにもかくにもプログラムは完成したので、明日からは新しいプログラムでガリガリ計算させる予定です。

長丁場の終了

やっとさっきプログラムのコアの部分の作成が終了しました(´∇`)
これで残すところは実験とプログラムの高速化、そして論文執筆です。
どれもこれも手強い敵で苦戦が強いられること間違いなしなんですが、
さてどうなることやら…。

今日は、昨日解析し終わったプログラムに対して、新しい部品をくっつける
作業をしていました。これだけならひたすらガリガリプログラムを書いて、
テストしてバグがないかを確認したらいいんですが、そうはいかないのが
つらいところ。

プログラムのテストをするためには、どうしてもUNIX上で実行する必要があって*3
それをするためにVMWareにFedora8をインストール…。ダウンロードにも
時間がかかるし、インストールにも時間がかかるし、大変です。
その間ボーっと待っているのはあまりに非効率なので、実験用のスクリプトを
書き換えていました。書き換えて気づくのは、これから確かめないといけない
実験データの多さ。これにも圧倒されます。

でも、とりあえず時間がかかって面倒くさい作業は終わったので、これからは
ひたすら単調作業に精を出すことになりそうです。絶対やってる最中に嫌に
なるだろうな…。

虫取り Actionscript編

プログラムにどこからともなく侵入し、挙動をおかしくさせ、さらにはプログラマのストレスの原因にもなる「バグ」。プログラムの誕生とともに発生した「バグ」をできるだけ簡単に駆除するために、バグの一例を挙げておきます。今回はFlashで使われるActionscriptに関するバグです。(あと、2つほど続けて書きます。)

Actionscriptはその名の通りスクリプト言語です。コンパイルする必要はなく、簡単にテストすることができます。ですが、Flashで使われる関係上、バグの再現性を特定することがけっこう難しいのです。構文エラーならすぐに止まってくれますが、そうでない場合はちょっと厄介です。

まず、多くのスクリプト言語がそうであるように、変数の宣言を行わなくても自動的に解釈してくれる点。これは、わざわざ宣言を書かなくてもいい点は利点とも思われますが、逆に言えばスペルミスで別の変数名を記述しても、とりあえず動いてしまいます。これを特定するのが面倒なんです。

たとえば、こんな場合。

aaa = 12345;
trace(aaaa);   // print "Undefined"!!

これが単独で書かれていると分かりやすいですが、長いコードの中ではどうでしょう。見つけるのが大変な気がしませんか?ホントによく起きえるミスなんで、よく気をつけましょう!

あと、actionscriptを勉強したい方は、下記のブログなんかがいいと思いますゝ(^O^)丿

[blog] Flash ActionScript2.0入門ノート

有名になりつつ

最近、アクセスカウンタが微妙によく増えだしたのでそろそろばれだしたかな?あんまり中傷・誹謗は書いてないつもりだけど、やっぱり知ってる人に読まれるのは恥ずかしいかも。(なら書くなよとも思うのですが。)

さっき掲示板のしょうもないバグを見つけてしまいました。
今まで気づかなかったのも変だけど、よくもまあ残ってたなと。分岐の条件も変だったし、さらに分岐後のソースも変だった。知ってるつもりでも変な間違いはするものですな。

さあ、明日からクラブの合宿です。
毎回酒に酔いつぶれている変な人の汚名を返上すべく、今回は木管or弦パートに逃げ込んで、やり過ごそうかなと思ってます。1日目だけでもなんとか切り抜けたいところ。

このページの上部へ

About

tetsuの日記・雑記です。
iPhoneなどのスマートフォン向けサイトもあります。スマートフォンでこのページを開くか、URLの最後に i を付けていただけばOKです

広告

サイト内検索

最近のピクチャ

  • リアディレーラ

月別アーカイブ

最近のコメント

Powered by Movable Type 7.5.0