goo blog サービス終了のお知らせ 

路傍のプログラマ

只のプログラマが綴る愚痴と備忘録

ソースコードを見栄えよく文章に入れたい

2009-01-08 17:15:11 | プログラミング
ワープロで作った文章や、プレゼンの中で、ソースコードをきれいに示したい。
さてどうしよう?

最低限、行番号がついて欲しい。できれば予約語や文字列のハイライトも。

いろいろやってみたのでメモ。

●解決策1 SyntaxHighlighterを使う。

HTMLにソースコードを埋め込んで、きれいに表示します。

あっちこっちに解説がころがってるので詳しい説明は省略しますが、一点だけ。
HTML文書のどこかで、「dp.SyntaxHighlighter.HighlightAll('code')」を呼んでおくこと。忘れると素のテキストになってしまう。

一番簡単なのは、bodyタグのロード時にやる方法。
<body onload="dp.SyntaxHighlighter.HighlightAll('code');">

実際にやってみたのですが、
・HTMLなので、<や>などを事前に修正しておく必要があります。
・Pythonのコードで試したところ、ややこしい文字列リテラルがうまくハイライトされませんでした。

フォントがきれいで感心したのですが、どうも「Consolas」を使ってるらしい。

●解決策2 Eclipseに表示させる。

画面のスナップショットを取って画像ファイルにする、というベタなやつ。

実際にやってみると、スペルミスの部分にアンダーラインを引いてくれてるのが、やたらとうるさい。

これは、Window → Preference → General → Editors → Text Editors → Annotations → Spelling Errors → Text asのチェックを外すことで、アンダーラインを消せばOK。

デフォルトではフォントはCoureir Newなのですが、これも、Window → Preference → General → Appearence -> Colors and Fonts → Structured Text Editorsで変更できます。

プログラムの実行に必要なメモリ量を知りたい

2008-12-12 20:53:40 | プログラミング
あるプログラムを実行して、利用したメモリ量のピークを調べる。

というのをPythonでやってみます。

Windows, CPython 32bit版限定ですが・・・

どうやら、PSAPIのGetProcessMemoryInfoというのを使えば良さそうです。

Pythonからこの関数を呼び出すラッパを書くのは面倒だなあ、と思ったら、
psapi.pyというのがありました。作者のGreg Hazelさんに感謝しつつ、利用します。
http://www.koders.com/python/fid746A02473CB489389E55F55866F023DB7D42D814.aspx?s=suck

psapi.GetProcessMemoryInfoという関数は、引数としてプロセスのハンドルを渡す必要があります。ちょうど、subprocessのPopenのアンドキュメンテッド(?)な_handleというインスタンス変数がハンドルを格納していました。

結果、コードは以下のようになりました。

--------------------
# measureit.py

import sys
import subprocess

import psapi

if __name__ == '__main__':
  if len(sys.argv) == 0:
    print "measureit command-line"
    sys.exit(0)
  
  commandLine = sys.argv[1:]
  
  subp = subprocess.Popen(commandLine)
  subp.wait()
  
  memInfo = psapi.GetProcessMemoryInfo(psapi.DWORD(subp._handle))
  print memInfo["PeakWorkingSetSize"]
  
  sys.exit(subp.returncode)
--------------------

使い方は、対象となるプログラムを呼び出すコマンドラインを、measureit.pyの引数とします。

たとえば、
measureit.py cmd.exe /c
で、cmd.exe /cを実行するのに必要となったメモリ量を印字します。

C++03書けない・・・

2008-12-11 16:56:20 | プログラミング
ここ数週間、ちょこちょこっとC++0xの情報を集めては「あー、いいなー」とか「何で今まで無かったんだよ」とか思ってました。

で、今日いざC++03でソースを書こうとすると、全く書けません。

「あー、これはfor_eachとlambdaだよなあ。いやせめてauto」とか
「ポインタ渡しじゃなくてmoveがいいよなあ」とか
「このテンプレートクラスに別名つけたいよなあ」とか、

・・・もう後から後から邪念がわきます。

「VS 2010のコンパイラかgcc 4.4でコンパイルしてください」とか言ったら怒られるよなあ。絶対。

Pythonのmultiprocessingその2(か3)

2008-12-03 20:09:49 | プログラミング
Python 2.6のmultiprocessingの実験してます。

いわゆる「計算」の量に比べてデータ転送量が多いと、せっかく複数のプロセスに分割しても、プロセス間のデータ転送に時間が食われて、パフォーマンスが出ません。却って遅くなったりします。(ソースは出せないのですけれども)。

で、データ転送したくなければ、プロセス間共有メモリ(multiprocessing.Valueかmultiprocessing.Array)を使えばいい、

となりそうなものなのですが、格納できるデータ型がctypesのものに制限されていて、Pythonらしいコードは書けそうにありません。

あー、なやましい。

GILフリーのスレッドさえ入れてくれれば・・・

Python 4000に期待するしかないのかなあ。

メモ: ひとりごと

2008-11-21 16:10:16 | プログラミング
Pythonのmultiprocessingを使って、lazy evaluationみたいなことできないかなあ。

random.Random()でインスタンス生成できたんだ。スレッドごとに乱数生成器を用意すれば、バグ再現できるよなあ。

sort -> uniq in Python #2

2008-11-20 15:22:37 | プログラミング
前回(2008/08/22のエントリ)は、イテレータを引数にするuniqをPythonで書いてみる、という話でした。

今回は、リストをインプレースで修正する(破壊的な)uniqを書いてみるというお話。

書こうと思えばどうとでも書けるので、3つほど書いてみました。

def uniqit(seq):
 if len(seq) <= 1:
  return
 i = 0
 for q in seq[1:]:
  if q != seq[i]:
   i += 1
   seq[i] = q
 del seq[i + 1:]
 
def uniqit2(seq):
 if len(seq) <= 1:
  return
 r = [ seq[0] ]
 r.extend(q for p, q in zip(seq, seq[1:]) if q != p)
 seq[:] = r

def uniqit3(seq):
 if len(seq) <= 1:
  return
 i = 1
 while i < len(seq):
  if seq[i] == seq[i - 1]:
   seq.pop(i)
  else:
   i += 1

で、これをランダムな整数のリストをソートしたものに適用してみる、というテストをしました。

a = [ random.randint(0, 1000) for _ in xrange(5000) ]
a.sort()

t0 = time.time()
for _ in xrange(100):
  b = a[:]
  uniqitなんたら(b)
t1 = time.time()
print t1 - t0

ここでクイズ。どれが一番速かったでしょうか。

答え。

・・・は示しませんので、ご自分でお試しください。ちなみに、最速と最遅では、かかる時間は1桁違いました。

蛇足ながら、以前のエントリで書いた、イテレータを引数とするuniqを使っても、当然同じことができます。

import itertools

def iuniq(enu):
 ps, qs = itertools.tee(enu, 2)
 yield ps.next()
 for p, q in itertools.izip(ps, qs):
  if p != q:
   yield p

def uniqit4(seq):
 if len(seq) <= 1:
  return
 seq[:] = [ v for v in iuniq(seq) ]

上述の3つと比べると、最速のものよりは遅いけれど、それ以外よりは速い、という結果でした。

なかなかやるなあ(自己満足)。

Python 2.6のmultiprocessingではまる

2008-11-12 15:15:41 | プログラミング
Python 2.6のmultiprocessingモジュールのPoolを試してみました。

# 動作環境は、Windows Vista、Python 2.6、両方とも32bitです。

どうやら、apply_asyncの最初の引数として、ローカルにdefした関数を渡すとこけるようです。

くわばらくわばら。

実証コードを以下に。

---------------------------------------
import multiprocessing

def fg(x): print x * x

def test():
  pool = multiprocessing.Pool(4)
  
  def ff(x): print x * x
  
  for i in xrange(100):
    #pool.apply_async(fg, [ i ]) # これはOK
    pool.apply_async(ff, [ i ]) # こける
    
  pool.close()
  pool.join()

if __name__ == '__main__':
  test()
---------------------------------------

(追記)
公式サイトのバグリストに、似たような記述がありました。

http://bugs.python.org/issue3272

Poolのメソッドにlambdaを渡すとこける、という内容。

multiprocessing、まだ不安定なのかもしれません。

メモ: Scalaのお勉強 #5 ライブラリが・・・涙目

2008-11-11 17:03:57 | プログラミング
Scalaでそろそろまとまったコードを書こうかなあ~と思って、ファイルIOを調べてみると愕然。

Scalaの解説とかを見てると、テキストファイルからの読み込みに、

scala.io.Source

というクラスを使ってます。

名前からなんとなーくいやな感じが漂っていたのですが、(そしてそのときは無視していたのですが)

改めて、公式サイトのAPIリファレンスを見ると、案の定、ソースファイルを読み込むために作られた、などと書いてあります。

UTF8以外のエンコーディングを使いたいとか、バイナリファイルを読み書きしたいなら、java.io.なんたらを再利用してね、ということなのでしょう。

となると、ここでの選択肢は・・・

・Javaのクラスをそのまま使う。
利点 --> なんのかんの言っても「標準」なので、後から手を入れやすいだろう、といういこと。
欠点 --> せっかくScalaで書いても、Javaの回りくどいやり方を引きずってしまうこと。

・Javaのクラスをラップする。
利点 --> Scalaらしい簡潔なコードになるだろうこと。
欠点 --> 俺専用ラッパになるため、後から標準的なものが出てきたときに問題になりそうなこと。

あー、悩ましい。

Y-combinator

2008-11-07 17:31:32 | プログラミング
Scalaの勉強を進めていくうちに、Combinator Parserなるものが出てきて、

Combinatorってなんじゃ?とか思って調べているうちに、Y-Combinatorなるものに行き当たりました。

Y-Combinatorとは、関数の不動点を求めるモノだそうです。

すなわち、関数Fが与えられたとき、p = F(p)となるような値pを求める関数がY-Combinatorです。p = Y(F)。

2つの式からpを消せば、Y(F) = F(Y(F))。

この式から何となく想像付くかもしれませんが、このYを使えば、再帰的に定義されている関数から、再帰呼び出しをくくり出すことができるそうです。

何となく分かったような分からないような。

参考:
http://code.activestate.com/recipes/576366/
http://igeta.cocolog-nifty.com/blog/2008/03/fixpoint.html

というわけで、実際これがどう使えるのか全く不明のまま。面白いけど。

こういうのは学生時代にやっておくべきだった。

メモ: Scalaのお勉強 #4 usingを書いてみる

2008-11-07 13:35:40 | プログラミング
記事「'Loan' pattern」
http://scala.sygneca.com/patterns/loan
を参考にして、

自分なりのusingを書いてみる。

--------------------------------

package disposetest

object Using {
  def using[ A, R <: { def dispose :Unit } ](r: R)(f: R => A): A = {
    try {
      f(r)
    } finally {
      r.dispose
    }
  }
}

class DisposableA {
  println("I'm created.")
  
  def greet = println("I'm working.")
  
  def dispose = println("I'm disposed.")
}

object Main {
  import Using._
  
  def main(args: Array[String]) {
    val d = new DisposableA()
    using(d) { d =>
      d.greet
    }
  }
}

--------------------------------

一応、うまく動いている様子。

structured typesはducktypingみたいで便利。