2010年06月09日

きれいな FizzBuzz が書けた

Pythonで、FizzBuzz。
(FizzBuzzとは、3の倍数はFizz、5の倍数はBuzz、15の倍数はFizzBuzz、それ以外は数字を出力する、サンプルプログラムのこと。)

def common_measures(x):
    return filter(lambda i:x%i==0, range(1,x+1));

def transform_by_dictionary(ary,dic):
    return map(lambda i: dic[i], filter(lambda i:i in dic,ary));

def fizzbuzz(x,dic):
    ary = transform_by_dictionary(common_measures(x),dic);
    ary += [""]*(len(dic)-1) + [repr(x)];
    return "".join(ary[0:len(dic)]);

for i in range(1,101):
    print fizzbuzz(i,{3:"Fizz",5:"Buzz"});

1から100までの各数について、次の通りの操作。
まず、common_measures関数で、約数のリストを取得。
次に、transform_by_dictionary関数に、約数リストと変換表を与えて、3をFizz、5をBuzzに変換。それ以外の要素は削除。
そして、そのリストに、空文字、数値を加えて、最初の2つの要素を取得。一つの文字列に直す。

例えば、
1→["","1"]
3→["Fizz","","3"]
15→["Fizz","Buzz","","15"]
のようなリストから、前の2要素を取って、結合すれば、表示用の文字列が取れるっていうカラクリ。

美しいコード書いたの、久しぶりのように思えます。
効率性や可読性から言うと、if-文使った普通のアルゴリズムの方が最強だけどw

(6月10日訂正)「公約数」じゃなくって、「約数」ですね。この辺が、文系の限界ってやつか。関数名はそのままにしておきます。

posted by 堤朋之 at 22:24 | Comment(0) | プログラミング

2009年08月27日

新しいタイプのコンピューターウィルス―W32/Induc

インフルエンザが猛威をふるっている今日この頃、フリーソフト界隈で問題になっているウィルスが、標題のコレ。W32は「Windows 32bit」の意味。後半は「インダク」と読むそうです。
Delphi(デルファイ)の開発環境のライブラリーのソースコードを書き換えて、コンパイルしたソフトに、悪意のあるコードを仕込むというもの。

原理を分かりやすく説明します。
プログラムを作るとき、一から全部自分で書いては、手間がかかってしょうがありません。そのため、「ライブラリー」という出来合いのプログラムを一緒に組み込みます。(ライブラリーは、主に、Delphiなどの開発環境におまけでついてきます。)では、その、ライブラリーに、何かの拍子で、悪さをするためのプログラムコードが書き加えられていたら? それを使って出来上がったソフトは、配られた先で悪さをしていまいます。
非常に単純な仕組みですね。

今回、感染するDelphiは、微妙に古めの、ver4〜7のみです。また、感染・潜伏するのみで、特に危害は与えない(発病しない)そうです。
ですから、今回の件に関しては、ソフトの再配布人とかは別として、プログラマー以外には関係なさそうです。Delphiをインストールしていなければ、発病どころか、感染すらしないのですから。
(ただ、各社が呼びかけているので、今回もウィルスチェックをお勧めします。また、安全なのは、今回のみ。あくまで、変な亜種や、同種のウィルスが現れない限りでの話です。油断禁物。)

一番怖いのが、将来、似たような手口が繰り返されること。
このタイプのウィルスは、ダウンロードサイトやCD-ROMなどで広がりやすく、1回の混入で大きく勢力を広げかねませんし、金銭的損害を受ける企業も出てくるでしょう。また、ソフトや開発環境に対する信頼まで左右されてしまいかねません。
いずれにしても、私のような、フリーソフト作者にとっては、頭痛のタネでしかありません。

しかし、そもそも、なんで、Delphiなどというマイナー言語相手に、作ろうと思ったんだろうか…。ついでにいえば、名前も、インパクを思い出すしw
ウィルス作ろうと思い立つような、愚かな脳ミソも謎ですが、それ以上に、謎が膨らみます。

posted by 堤朋之 at 19:52 | Comment(0) | プログラミング

2009年05月24日

何てゆうか…どうでもいい…プログラムたち

最近、Java屋さんをやってます。
サーブレットとか、JSPとか、eclipseとか、覚えることが多くて大変です。
その上、Subversionとか、人間関係とか、いろいろと。

しかし、人生初のJSPが、

<% out.println("しゅっやくっは あっ!たっ!し!!"); %>
<% ="<small>"+"いぇい"+"</small>" %>

というのは、あまりにもひどすぎます。後悔先に立たず。

下のは、2日前、思いつきで書いたPythonのやつ。

(fujoshi.py)
try:
list = map(lambda line: line.rstrip(), file("coupling.txt"))
import random; random.shuffle(list)
print "空を見上げる少女の瞳に映る %s × %s" % (list[0],list[1])
except IOError, e: print "エラー:カップリングファイルが読み込めません。"
except IndexError, e: print "エラー:カップリングは2人以上です。"
(coupling.txt)
ヒイロ
デュオ
トロワ
カトル
五飛

もう、わけわかめ。

posted by 堤朋之 at 15:45 | Comment(0) | プログラミング

2007年12月07日

冷やしPythonはじめました

最近、人気急上昇中のスクリプト言語、Python(パイソン)を始めてみました。

最初は、ネット情報を頼りに、片手間でやっていたのですが、それだと限界があるので、(先週の)金曜に、『速効!Pythonプログラミング』という3000円弱の本を買ってきて、本格デビュー。
この本、分厚くて、一晩で読みきれなかった。プログラミング未経験者にはお勧めしづらいです。HTTPヘッダのユーザエージェント偽装を推奨しているページがあるんですが、なんだかなぁ…。

↓1以上100未満の素数を列挙するスクリプト、1行で書けたでしょう記念。どう見てもアホです。

print filter(lambda k:k>=2 and reduce(lambda a,b:a and (k % b != 0),range(1,k)),range(1,100))

omikuji.py

先月か先々月、始めた初日あたりに、見よう見真似で書いた、おみくじプログラムも晒しておきます。
なんか、新言語始めると、必ず、おみくじかサイコロ作っちまうのだが…。

posted by 堤朋之 at 02:20 | Comment(0) | プログラミング

2007年09月24日

最近のデスマーチ

構造体のワナ

構造体の4バイトアラインメントに引っ掛かった。

struct hoge
{
DWORD a; //4バイト変数
WORD b; //2バイト変数
DWORD c; //4バイト変数
};

コード高速化のため、コンパイラは、構造体のメンバ変数を、4バイト境界に整列するのが普通です。上の例では、bの後に2バイトの空白ができます。

PSDファイル(画像処理ソフト Photoshop のファイル)の読み書きをしようと思って、いつものように構造体を作ってファイルにあてがったのですが、PSDのファイル仕様書を作った方は2バイト境界整列のことまでしか考えていなかったらしく、クソミソな結果に終わってしまったわけです。
バイナリダンプしてみて、初めて気づきましたよ。

さて、ファイル構造を見るのには、構造体を割り当てるのが普通なのですが、そもそもこれ、コーディング手法として汚い気がするのです。
何よりもバージョンアップの際にヘッダを書き換えられたら危険ですし、それに、コードの見た目が汚くなるのは、いつもこの部分です。

文字列か何かで構造を定義すれば、データの妥当性を検証した上で、自動的に変数の値を返してくれるようなクラスの作成、前々からチャレンジしてるんですけどね…。まあ、世の中そう簡単にはいかないもので。

ポインタのインクリメント

まさか、今更やらないだろうというミス。

int a = 123;
int* p = &a;
int b = *p+1; //←ミス!!

上のコードは間違いで、int b = (*p)+1ですね。上のだと使ってないメモリ(p+sizeof(int)番地)の値を返してしまいます。
今回のケースは、変数名が長く、微妙に気づきにくい感じで、見事泥沼に嵌まってしまいました。

C言語では、コーディングを見やすくするために、単項*より+演算子の優先順位を上げています。
しかし、プログラマとしては、ポインタを使う感覚の時は*(p+1)か(*p)+1かは意識しますが、普通の変数を使う感覚の場合は、(*p)+1でしかありえないのです。
バグ回避の観点からは、あまりいい仕様ではないなと。

こんな過疎ブログでぼやいてても、しょうがないですが。

posted by 堤朋之 at 00:20 | Comment(0) | プログラミング

2007年09月18日

みのりカレンダーver1.1ですにょ

みのりカレンダーとセルペインター、両方更新する羽目になりました。

で、どちらを優先? ということで、みのりカレンダーから更新することにしました。
9月30日のデータが表示されないというバグがあったんで。

メモの簡易バックアップ機能がつきました。あまりアテにはなりません。無いよりマシといった程度。
あくまで、手動でDVD-Rなどにバックアップが基本。

posted by 堤朋之 at 06:32 | Comment(0) | プログラミング

2007年08月09日

カレンダーはいらない子?

昨晩、Vectorから通知メールが来たのですが、見て驚きました。
ダウンロード数、8日間で、たったの19。
自サイトの方も、1日1件あるかどうかといった感じ。

そういえば、グラフィックソフトの時は、検索すれば、試用感想とかどんどん出てきたのですが、カレンダーは、評価サイトすら見つからない。
おまけに、2ちゃんでは、カレンダースレの維持もままならない状態。(ほとんどが私の書き込みw)

カレンダーって、パソコン使う上での、必須ソフトのようなイメージがあったのですが…。
まあ、Windowsに標準で付属してこないことからして、世間様的には、不要なジャンルなのかねぇ。
でも、自主制作ソフトより過疎ってのは、どうよ?

posted by 堤朋之 at 19:02 | Comment(0) | プログラミング

2007年07月22日

仕事完了

ベクターと窓の杜にメール出して、仕事完了。

それにしても、新規公開は疲れる。テストとか、ドキュメント作成とか、ホームページ作成とか、メールの文案作成とか。
今日なんかはネットカフェで動作確認ですよ。

世間様は夏一色ですね。
セミの声は聞こえて来るし、公園で盆踊りやってるし。
ひきこもり開発者には関係ないですよ。ええ。

posted by 堤朋之 at 23:10 | Comment(0) | プログラミング

2007年07月21日

カレンダーソフト作りました

みのりカレンダー

β版です。2007年の休日・記念日は、目視で確認しましたが、それ以外は確認していません。

所詮はカレンダーソフトだろうと、ナメていたら痛い目見ました。本気で作りこむと、相当な労力になります。今まで、気に入ったソフトがなかったのですが、何となく理由が分かったような。

今日、Pentium 166MHz の旧マシンで起動してみたら、動作が激しく重いことが発覚。セルペインターは旧マシン時代から開発していたので、ロースペック環境のことも考えていたのですが、今回は全部、新マシン上での開発。
プログラマに速いマシンを与えてはいけないという話がありますが、身にしみて実感しました。
最適化すべき場所は自明ですが、結構面倒な部分なんだよな…。

条件式の組み合わせで休日を定義するのは、もしかしたら大発明かも。
m7 d13 "ナイスの日"

posted by 堤朋之 at 23:38 | Comment(0) | プログラミング

2007年06月11日

カレンダーに潜む意外な規則性とか

一年のそれぞれの月の長さは、見るからに不規則ですよね。ところが最近、カレンダーとにらめっこして、おもしろいことに気づきました。

うるう日の計算が面倒なので、2月最後の日を年末に持っていきたい。1月と2月は、前の年の13月、14月としましょう。すると…。

3月4月5月6月7月8月9月10月11月12月13月14月
313031303131303130313128/29

お気づきになりましたでしょうか? 月の長さ、デタラメに並んでいるように見えて、実は、5ヶ月単位(31,30,31,30,31)の繰り返しだったのです。

でも、最後の月が不規則に見えますよね。こう考えてみてはどうでしょう? 14月は本来30日ですが、1年が365(366)日しかないため、最後の月は30日も確保できません。そこで仕方なく28(29)日で我慢しているだけだと。
最後の所で調整しているのか…。それなら、2ヶ月の周期(31,30)も考えられるのでは? 5ヶ月が153日だから、最後の月がないだけで。
この考えをさらに推し進めれば、1ヶ月は全部31日ということになりますね。2ヶ月が61日だから、最後のところを端折って30日にしているだけで。

さて先程、うるう日を前の年の年末に持っていきましたが、すると、うるう日は、紀元前1年(=西暦0年)3月1日を起点とする、400、100、4年周期の最後の日に、行儀よく移動してくれます。
ですから、上の「最後で調整」ルールは、4年単位、100年単位、400年単位でもあてはまるわけです。
但し、4年間、400年間は、それぞれ、365日×4、100年×4より、1日だけ長いため、例外的な処理が必要になります。

複雑そうに見えたカレンダー、145997日、36524日、1461日、365日、153日、61日、31日、1日の周期の単純な組み合わせに還元されてしまいました。
このルールを使って、年月日と日付連番(ユリウス日)の相互変換をするコードを添付しておきます。

C言語ソースコード(ymdjd.c)

………それにしても、日頃何気なく使っているカレンダー。こんな簡単なルールで出来ていたとはちょっと驚き。ちゃんと考えて作ってあったんだな…。
じゃあ、最初から、3月始まりにしとけよ!! とマジギレしてみる。

posted by 堤朋之 at 19:40 | Comment(0) | プログラミング

2007年03月17日

セルペインター雑誌掲載

とうとう、セルペインターが雑誌に掲載されました。

「Windows100%」(晋遊舎)と、「PCJapan」(ソフトバンク)の2冊。両方とも4月号で13日発売。なお、もう1冊、別の雑誌が掲載予定中だそうで。

Windows100%は、「フリーソフト71本」コーナーに掲載ですが、それが全くのお誕生日席。一番最初の枠に載ってしまいました。掲載依頼にすぐ返事したのがよかったんでしょうか?
PCJapanも、これまたお誕生日席。1ページまるごと。まあ、一つ前のソフトは、2ページまるごとの特大お誕生日席なのですが。

Windows100%は、裏ツール系雑誌かと思いきや、微妙にアレな内容。なんで、ギ○スとか、○だめとか。漫画を描く記事とか、ギャルゲーの記事もあるし。PCエンジンの記事に至ってはもう…。一体、どういう読者層を対象にしているのか、私には全く分かりません。(※なお、年齢制限のある雑誌ではありませんが、裏系ツールの記事や、アダルト広告が載っており、このサイトとしては推薦できない旨、お断りしておきます。)

一方、PCJapanは、中上級者向けの完全硬派雑誌です。Windows再インストールや、DVD周り、Excelなどの特集をしていました。個人的には、見本誌ありがたいです。役得。役得。

posted by 堤朋之 at 01:07 | Comment(0) | プログラミング

2007年01月30日

セルペインターver1.4

Vista発売記念です。いや、Vistaで動作テストしてませんが…。
何かの祭りの時にリリースしないと、どんどん先延ばしになってしまうので。

今、大改造の真っ最中なので、とりあえず中間リリースという感じです。とはいっても、バグ修正と入力品質改善をしてあるので、1.4のご使用を強くお勧めします。

・青色トレス線にも、申し訳程度に対応しています。(今回の目玉)
・大解像度で取り込んで、主線に穴がボコボコ開いて困っている方は、オプションタブの「アンチホールフィルタ」をオンにしてみて下さい。
・ヘルプをネット上に置きました。利用者サービスというより大人の事情。(検索でこのサイトが引っかかる確率が上がる)
posted by 堤朋之 at 23:14 | Comment(0) | プログラミング

2007年01月25日

セルペインターver1.4はとっくに出来ているのですが…

青色トレス線や、大解像度取り込みへの最適化、JPEG出力などに対応したはいいのですが、大手術の後なので、テストを十分にしなければなりません。でも、面倒くさくて数日放置。初公開時と同じくらいのテスト量が必要になるので、まともにテストするとなると、大変なことになります。それに加えて、試し塗りするような画像もないしにょ。困ったにょ。

まあ、フリーソフトというものは、テスト等の手間がかかる部分を端折るから無料でいられるわけで…。なんてゆーか、ユーザーテストってやつ?…と開き直ってみる。
posted by 堤朋之 at 01:01 | Comment(0) | プログラミング

2007年01月03日

セルペインターver1.3開発中

研連用の作品を作っている最中に、ちまちましたバグを見つけてしまったので、バグ取りしなきゃまずいのです。しかも、窓の杜1月号への収録も控えてるし。

セルペインターの参照画像…というか色指定表をどんどんめくっていくと、突如出現する「メモリが足りません」エラー。これに関しては本当にお手上げです。SPIの中からSOSが発せられているのですが、どんなに格闘しても原因不明。セルペだけで起こる症状であることを考えると、SPI側ではなく、呼び出し方が悪いようです。

で、逃げの手段として、PNGにネイティブ対応して、極力、SPIを使わずに済むようにする。これで、あのダイアログに遭遇する確率はかなり減ります。自主制作でテンパってる最中にエラーメッセージが出ると、制作意欲が恐ろしいほど減退するので、根本的な解決にはなっていないものの、案外有効かもしれません。
ついでに、メモリのコピーが不要になるので展開が速くなる、半透明色を読み込める、といった副産物も。

ついでに、JPEG対応しちまうか…。ということで、手を出したが最期。こちらでもかなり悩まされることに。原因が、セルペ以外のプロジェクト上で呼び出し関数をコンパイルすると正常動作するが、セルペのプロジェクト上でコンパイルすると、構造体のサイズチェックか何かでハネられてしまうというもの。セルペ以外でコンパイルしたファイルを、無理矢理セルペにリンクさせるという荒業で乗り切りましたが、将来メンテする際に、トラブルの種になりそうな悪寒…。念のため、JPEGは、「未対応だが実は読める」にしておくかな…。

すべての選択肢において、後ろ向きな解決方法を選んでいるような気がする…。

多分、明日かあさって位に、ver1.3出しますね。
posted by 堤朋之 at 19:54 | Comment(0) | プログラミング

2006年11月04日

グラデーションの実装

こういうメモは、普通にファイルに書いて、ディスクに保存しておけばいいのですが、そのうち、どこのディスクに保存したか忘れてしまうのがオチなわけで、それならいっそ、ネットに上げておけば安心かと。

太字で書くのはベクトルです。
普通のグラデーションツールでは、(何と言うのか知りませんが)基準線みたいなのを引きますよね?それの始点と終点をそれぞれとします。
そして、forループで左上から順に見ていく現在のピクセルをとします。
色1と色2があって、色2の濃度をt(0.0<=t<=1.0)としましょう。

結論からして、

t = (-)・(-)÷|-|
※「・」は内積、「|…|」は絶対値(長さ)。

t>1.0 のときは t = 1.0
t<0.0 のときは t = 0.0

なんて骨体。苦労して計算したのに。ただの、内積とベクトル長さとの比率かよ。

まあ、要するに、forループで全部のピクセルに対して、上のtを計算して、色1×(1.0-t)+色2×tで塗っていけば、グラデーションになるってこった。勿論、現実の計算では、遅い浮動小数演算ではなく整数演算を使うことになります。
上に書いた手順だけでも実用的な速度になりますが、隣のピクセルとのtの差分値が一定であることに着目すれば、足し算とシフト演算に置き換えることも可能な感じですね。

…とここまで書いておいて、セルペインターにはグラデ機能はつかないと。
posted by 堤朋之 at 00:28 | Comment(1) | TrackBack(0) | プログラミング

2006年10月26日

HTMLヘルプのインストール

HTMLヘルプを作るには、HTML Help Workshopというソフトが必要です。前にどこかで手に入れた配布パッケージが手元にあったのですが、WindowsXPの新マシンになってから、なぜかそのパッケージではインストールができず、面倒なことになりました。

マイクロソフトのサイトに行くと、とりあえず、「Microsoft Office 2003 リソースキット」(ork.exe)なるものをダウンロードするように言われて、何が何だかわからないまま、7MBくらいのものをダウンロードしました。
回線を切ってから、それをインストールすると、なんと、インストール先のフォルダに、HTML Help Workshopのインストーラがあるではありませんか。(それで7MBもあったのね。)
インストーラの中に、インストーラが更に入っトいるとは…。HTML Help Workshopをインストールした後は、リソースキットは、アンインストールしてしまっていいようです。(アンインストールはコントロールパネルから行って下さいね。)

英語のソフトですが、プログラムに詳しい人でなくとも、HTMLファイル群をそのままヘルプにできるので、重宝するかと思います。

余談になりますが、Windows95とか、相当昔のWindowsでは、HTMLヘルプが正常に表示されない場合があります。その場合は、HTMLヘルプワークショップの中に入っている、hhupd.exeというソフトを実行すればいいようです。
posted by 堤朋之 at 22:51 | Comment(0) | TrackBack(0) | プログラミング