[最新記事] [過去ログ]

10/31(Tue)

/** Pythonのちょっと便利なところ。 */ Pythonやばいぐらいに便利。 Python恐いぐらいに簡単。 今まで、PerlとかJavaやってて、やっぱ超高級言語は便利やね〜♪ とか思ってたけど、比じゃないもん(^^; 今日は関数について。 1)二つの値を返す関数 C言語ではポインタを使って、一所懸命参照渡ししてましたね? Javaでは、参照型を渡して、そこに対して一所懸命更新してましたね? Pythonでは、 return x, y みたいに書けます(^^; 実際は、タプルという更新不可能なオブジェクト配列1コに入るんですが、 returnで、この書き方が出来るってのが画期的(^^) 2)可変長引数を受け取る関数 C言語では、varargsとかいうのを使ってやるらしいです。よく知りません。 printfの宣言(VC++のやつなんで、標準的じゃないかも(-_-;)なんかを見てみると、 _CRTIMP int __cdecl printf(const char *, ...); 要は、後ろの「...」が可変長ってことを表わしてるらしいです。 Javaでは、Vector辺りのコンテナに引数いれて渡してましたね? Pythonでは、 def func(*args): args[0], args[1], args[2] みたいに、ごく簡単に使えます。 おまけに、動的な型付けの言語だから、 func(1, "abc", (1, 2, 3)) みたいな形で呼べるし。 3)関数テーブル C言語では、関数へのポインタとかを駆使して、がんばってやってましたね? Javaでは...? リフレクションとか使えば出来るの? Pythonでは、関数もオブジェクトなので、 func_list = (func1, func2, func3) みたいに格納しておいて、 func = func_list[1] のように取り出せます。 4)関数の中にまた関数 Javaでいう内部クラスみたいなイメージ? 以下のように、関数の中にさらに関数を定義できます。 def outer(): def inter(): print "message from inter" inter() ここでouter()を呼び出すと、 message from inter が表示される。 恐らくだけど、outerの中でしか使わないような関数を定義するのに、 使われる形式なんじゃないかと思う。 なんか、Pythonが夢のツールに思えてきたこの頃。

10/29(Sun)

/** 笑った(^^; */ 昔の雑記帳を眺めていたところ、入社前研修でやっていたことを思い出しました。 それは、某建築設備会社に勤める2年目の営業マンA君が、他の同期に比べて担当している 物件が小さいために、焦燥感や不満を感じているといった設定。 このA君に対して、何かアドバイスをして下さいというのが、入社前研修の内容。 これを、今の僕の状況に当てはめてみると... 某SIベンダーH社に勤める技術者T君が、世の中の技術動向に比べて、 あまりにも古い技術しか使わない仕事しか出来ないために、不満やいらだちを感じている... なんか、すっげぇ似てません? この設定(^^; で、その時僕が書いた答えが、以下の通り。 このケースで問題なのは、物件の大きさが、 仕事の大きさと比例していると思い込んでいる点だと思います。 大きな物件の担当でも、小さな物件の担当でも、同じ仕事であるし、 得られる経験に違いは無いと思います。 また、小さな物件を担当することでしか得ることの出来ない ノウハウがあるかも知れないので、 何も劣るところは無いと考えた方が良いと思います。 笑っちゃいます(^^; なんかもう、タテマエばりばりだし(^^;; 研修だからなぁ。キレイゴト言ってれば良かったんだろうなぁ。 まあ、技術が古くても、同じ仕事だってところはあってるんですが、 得られる経験は、明らかに違うからねぇ。 さらには、古い技術で得たノウハウなんて、その時しか役に立たないし。 あああぁぁ。やっぱりブルーになるなぁ(T_T) /** ひさびさVC++ */ とあるテキスト変換に、いっつもJavaでやるのもなんだなぁ。 とか思いつつ、VC++でやることにしました。 ...すると! めちゃめちゃ速い(^^; う〜ん。やっぱりネイティブも捨てがたいなぁ。 /** MIDI検定3級に向けて? */ SMFを読み込んで、Cakewalkのイベントリスト(こんなん)みたいなものを出力する プログラムってのを作ってみました。 これを作るにあたっては、「MIDI検定3級公式ガイドブック」っていうのが、 結構役に立ちました。 MIDIの勉強にもかなりなったらしい。 まずSMFファイルを読み込んで、各トラックを取得するのですが、 0オリジンなので、0を取得したら、Track1が取れるものだと思ってたのですが、 (Track track1 = sequence.getTracks()[0];) Track0なる、謎のトラックが含まれてました。 つまり、Track0〜Track16の全17トラックがあるらしいです。 で、そのTrack0を良く見てみると、 Sysx: 0, 0/52200, F0 41 10 42 12 40 0 7F 0 41 F7 というのが含まれていました。 これは、GSリセットなので、まあ構わないんです。 ところが、こんなのも含まれていました。 Meta: 0, 0/52200, FF 54 61 6B 61 68 69 72 6F 20 53 68 69 67 65 6D 6F 74 6F なんか、ASCIIキャラクタに直せそうに見えたので、 以下のように、お得意の(?)Pythonを使って、ASCIIキャラクタに直してみました。 >>> list_2 = (0x54, 0x61, 0x6B, 0x61, 0x68, 0x69, 0x72, 0x6F, 0x20, 0x53, 0x68, 0x69, 0x67, 0x65, 0x6D, 0x6F, 0x74, 0x6F, 0x0A) >>> map(chr, list_2) ['T', 'a', 'k', 'a', 'h', 'i', 'r', 'o', ' ', 'S', 'h', 'i', 'g', 'e', 'm', 'o', 't', 'o', '\012'] と、まあこんな感じで、著作者情報が埋め込まれていると。 実は、Track0中には、漢字の名前も含まれていたりして、 ちょっとマズいかなぁとか思ってたりします(^^; まあ、Shift_JISのバイト表現だから、少し工夫しないと取り出せないけど。 (Javaなら10ステップぐらい?) そんなこんなで、SMFにはメタ情報として、 タイトルとか、著作者情報が埋め込まれているんだなぁ。 っていうのが良く分かりました。 /** NOTE_ONとNOTE_OFF */ MIDI音源に対して、NOTE_ONというメッセージを送ると、 受け取ったMIDI音源は、指定の音階(ノートナンバーというらしい)とベロシティで音を鳴らしてくれます。 反対に、NOTE_OFFというメッセージを送ると、 指定の音階の音とベロシティ(キーを離す速度)で音を消してくれます。(すぐには消えないが) ところが、音を消す方法として、NOTE_ONのベロシティ0というのもあります。 Cakewalkでも、以下のようにして、8分音符を表現しています。 (分解能 = 120) Track, Tick / Ticks, Channel, Message, Note No., Velocity 2, 7620/52320, 2, NOTE_ON, 71, 121 2, 7680/52320, 2, NOTE_ON, 71, 0 60Tick後に、NOTE_ONの0を送っていると。 なかなかこういうのって、普段何気なく使っているだけでは分からないので、 結構面白いですね(^^)

10/26(Thu)

/** 嫌気差しまくり(-_-; */ 今日は、かなぁり辞めたくなりました。 が、情報処理の結果は、1月下旬。 なんとかそれまでは我慢しないとね... 現在、Web周りのシステム開発経験、習得技術などについてまとめ中。 Webシステム開発に回してもらうための、下地作り。 知識の証明書は、資格だけじゃなくて、納得させる資料ってのも、 十分知識の証明書になり得ると思った。 いつか勝利をつかむその日まで、僕は負けない。 /** Javaで音鳴らしてみた */ 今までも、wavファイルとか、midiファイルとか、 あらかじめ作られたファイルを演奏するのは出来てたんだけど、 プログラム中で、「ド」を100の強さで。 という風に指定して鳴らすことは出来ないでいました。 一応、Java Sound APIとか、Java Media Frameworkとか、 拡張APIでは出来たんでしょうけど、ドキュメントも英語のしかなかったせいか、 いまいちやる気が起きませんでした。 インストール方法とかも、やっぱり英語だったし(>_<; で、JDK1.3にjavax.soundパッケージが含まれたのを機に、 JavaでSC-88Proを鳴らしてみようという、壮大な(?)計画が始まったのでした(^^; 以前(2000/05/22参照)にも、javax.sound.midiパッケージは試してたので、 その時の情報を頼りに、プログラミングしてみることにしました。 が、それは大失敗でした(T_T) 一所懸命、「オレがSC-88Proだ。」と言ってくるMIDIデバイスを使って、 ノートオンメッセージとか、リセットメッセージを送ってみるも、全く反応無し。 仕方が無いので、Sound BlasterのWaveTableSynthesizerとか、 普通の220番ポートに送ってみるも、やっぱり反応無し。 「だめなのか...」 と、半分諦めつつ、基本に立ち返ってドキュメントを読むことに。 昔と違って、きちんと日本語で整備されているドキュメントは読みやすく、 色んなことが分かってきました。 特に、 ・Java Sound Synthesizer, Java Sound Sequencer以外は無効なこと。(現時点では?) ・MidiSystem.getSynthesizerで、デフォルトのSynthesizerを取得できること。 ・Synthesizerは、openしないと使えないこと が分かったのが大きかったです。 そこで、デフォルトSynthesizerを取得し、そこからチャンネル1を取得し、 チャンネル1に対して、NOTE_ONメッセージを送ってみると...? ド〜♪ 予想に反して、SC-88Proから音が鳴ってくれちゃいました(^^; どうやら、Windowsのマルチメディアの設定で選択されているデバイスが使われるようです。 そこでまあなんなんですが、しょうもないプログラム書いてみました。 音程が64から始まって、1秒置きにひたすら高くなっていくというもの。 最後は、キンキンになるまで行って、Ctrl+Cしか意味をなさなくなります(^^; -- MidiTest.java -- import javax.sound.midi.*; import java.util.*; interface TimerListener extends EventListener { public void doIt(); } public class MidiTest implements TimerListener { Synthesizer syn; int note_no = 64; public static void main(String args[]) { new MidiTest(); } public MidiTest() { try { syn = MidiSystem.getSynthesizer(); syn.open(); Timer t = new Timer(); TimerThread tt = new TimerThread(); tt.addTimerListener(this); t.scheduleAtFixedRate(tt, 0, 1000); } catch(Exception ex) { ex.printStackTrace(); System.exit(1); } } public void doIt() { MidiChannel midi_ch = syn.getChannels()[0]; midi_ch.noteOn(note_no++, 100); } class TimerThread extends TimerTask { TimerListener l; public void run() { l.doIt(); } public void addTimerListener(TimerListener l) { this.l = l; } } } -- end MidiTest.java -- まあ、もう少しまともなサンプルが出来たら、Java Class Libraryに載せるとしましょう。

10/25(Wed)

/** 今日一日は結構充実? */ 降ってきた面倒な仕事は、あらかた片付けました。 その仕事ってのは、Excelシートとファイルリスト(Dirの結果みたいなもの) を組み合わせて、なんらかの結果を導くというもの。 イメージ的には、データベースの表結合に近い。 というか、これに気づかなかったら、全然終わらなかったかもねぇ。 なんせ、NT3.51な上に使えるツールが限られているから、 かんなり苦労しました(T_T) 最初は、Excelのマクロを組んで、ちまちまやってたけど、とても無理そうだと判断。 Accessに落とし込んでやれば、スムーズに処理出来そうなことに気づいて、 ショボいSQLを書いて、なんとかこなしました。 そこで学んだこと。 ExcelシートをAccessデータベースにインポートする方法。 Excelシート上での、文字列操作関連関数の使い方。 AccessでSQLを書く方法など。 (LIKEで使う%が*だったり、SELECT時の列の別名にいちいちASを使わなきゃいけなかったり(T_T)) 今日一日で、あんまり身に付けたくもないノウハウを習得しました(^^; 実は、最初に思い付いたのは、ハッシュを使って処理する方法だったのですが、 PerlもしくはJava、最悪でもC++が欲しいところなんですが、 インストールされている言語っていえば、Power Builderのみ。(DOSのバッチも?) あまりにも貧弱過ぎるよねぇ... まあ、その場の道具だけで、なんとかこなしてしまう辺り、 なんとなく面白かったりして(^^; /** 今日一日は結構充実?...と思ったけど(T_T) */ せっかく1時間半ぐらいかけて、リリース用クライアントモジュールをビルドしたのに、 前対応時(一つ前に、僕も携わってたプロジェクト)のバグが残ってた。 とか言われて、まっさかさま。 あああああぁ〜 僕の苦労は一体...(T_T) 「大丈夫。また明日やるから。」 とは言うものの、一体何が大丈夫なんだろうか。 僕のせいじゃないのに... /** もう一方の課題は...? */ Apache + JServ on Windowsでの設定について。 この環境下では、なんにも設定しないと、 ひたすらservletsというディレクトリの下にクラスファイルをひたすら突っ込んで、 http://localhost/servlets/hogeServlet という感じのURLでアクセスするしかありません。 これを階層化したいとかいう要望が、 なぜか仕事中の午前10時30分に、教育センターから電話でかかってくるんです(>_<; 例えば、http://localhost/servlets/x_project/hogeServlet という感じでアクセスしてみたいと。 そんなんできるんかい!? とか思いつつ、設定ファイルを眺めること10秒。 # Example: "ApJServMount /servlets ajpv12://localhost:8007" # if user requests "http://host/servlets/myServlets/TestServlet" # the servlet "TestServlet" in zone "myServlets" will be requested という記述を発見。 っていうか、書いてあんじゃん(^^; 今まで気づかなかった僕も僕だが、ちっとも読んであの人もあの人だろう。 その通りやってみると、あっさりうまく行きました(^^) 教えたところ、やっぱりうまくいったらしいです。 はぁ...次は一体いつ電話がかかってくるのだろう...

10/24(Tue)

/** 今日は一日マジで辛かった...(>_<; */ 昨日は帰ったら深夜2時。 結局4時間ぐらいしか寝られなかったし、なんか少し頭痛いし... とりあえず、根性で会社までたどり着く。 本当に、なんとかたどりついたって感じ。 でも、かなぁりフラフラでした。 昼休みは、1時間近く爆睡するも、全然睡眠量が足りず。 午後からの仕事は、気力を振り絞ってやるも、 ちっとも力が入らず、しょうもないミスしたりして。 おまけに、こっちの事情を知ってか知らずか、 面倒な仕事が降ってくるし。 さらには、教育センターのおじいちゃんからも仕事が降ってきて、 ややパニック状態!? マジで、明日挽回しないとヤバいです... 今日の仕事的には、なんとかオンスケジュールに乗せたけど、 定時が迫ってるのに、仕事が終わらない焦燥感ってのも、 久々に味わった気がするね。 今日は早く寝て、明日からの完全復活を目指しときます(^^)

10/22(Sun)

/** Javaを仕様レベルで見てみる */ 勉強すればするほど、「今までオレは何を勉強してきたんだ?」 的な気持ちになるのは気のせい? 何事にも言えることだと思うけど、基礎が出来てないと、 一流にはなれないんだろうねぇ。 今日は、オブジェクトのキャストについての考察。 1)コンパイルエラーになるケース StringとLongなど、継承関係について全く関係の無い場合 -- ex -- String s = "str"; Long l = (Long)s; -- 2)実行時例外(ClassCastException)になるケース 継承関係はあるが、実行時型が合わない場合 -- ex -- Object o = new Object(); Long l = (Long)o; // Down Cast -- 3)正常にキャストが行われるケース i)null参照である場合 -- ex -- Object o = null; Long l = (Long)o // Long l = nullと同等 -- ii)実行時型が合っている場合 class Base {} class Delived extends Base{} public class test { public static void main(String args[]) { Base b = new Delived(); Delived d = (Delived)b; } } iii)アップキャスト(Java仕様書語で、参照型の拡小変換というらしい) class Base {} class Delived extends Base{} public class test { public static void main(String args[]) { Delived d = new Delived(); Base b = (Base)d; } }

10/21(Sat)

/** Pythonのちょっと便利なところ。 */ Pythonの勉強を始めて間もないんですが、言語の特徴が色々あって面白いです。 いいところ1 >>> x = 1; y = 2; z = 3 >>> if x < y < z: ... print "OK!" こんなんできるし(^^; yが、xとzの間にあるかどうかというテストなんだけど、 こういうのって、なかなか他の言語にはないよねぇ。 いいところ2 >>> for i in range(10): ... print i ... これ、「for(int i=0; i<10; i++)」のPython版なんですが、 ある範囲の整数を作り出す関数なんてあったりして、 なかなか、便利さを追求してます。 /** ココがヘンだよPython */ ヘンなところ1 ブロックの終わりを表す「}」が無いのは、 なんとなく不自然。というか、すっごい違和感感じる。 インデントによる字下げのみで認識してるってのはすごいけどね。 -- while.py -- i = 10 while i: if i % 2 == 0: print i, " is even number" else: print i, " is odd number" i = i - 1 -- なんか、whileに対するの閉じカッコが無いのに違和感感じない? あと、「i--」が使えないのが不便... ヘンなところ2 for文とか、while文にも「else節」が存在する。 意味的には、breakでループが異常終了しなかった場合に、実行されるブロック。 使いようによっては、役に立つのかもねぇ? まだまだ、Python経験浅いので、良く分かりませんが。 /** Javaを仕様レベルで見てみる */ 「Sun Certified Programmer for the Java2 Platform」 懲りずに、また申し込みました(^^; さすがに今回もまた落ちるわけにはいかないので、 前回不合格の原因の分析とかして、仕様レベルを追っかける日々です。 たぶん、GridBagLayoutが一番の壁かと。 ちょっと面白いのが、floatの最大値(Infinity: 無限大)をintに代入すると、 intの最大値(Integer.MAX_VALUE)に変換されるってことです。 -- test3.java -- public class test3 { public static void main(String args[]) { double d = 1 / 0f; int i = (int)d; System.out.println("d = " + d); System.out.println("i = " + i); } } -- -- test3の実行結果 -- d = Infinity i = 2147483647 -- ちなみに、float.Nan(0f / 0f)をintに代入すると、0になるそうです。 こういうのって、仕様読まなきゃ分かんないよねぇ。 実際使うかどうかは別にして。
[最新記事] [過去ログ]