2012年1月25日水曜日

pip

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
pipの機能にsrcからインストールすると言う物がある。 が、setup.pyを実行するのではなく、中身をparseして依存関係を取り出すようだ。 Downloading/unpacking git+ssh://git@github.com/bgnori/tonic.git Cloning ssh://git@github.com/bgnori/tonic.git to /tmp/pip-jCBcP8-build Running setup.py egg_info for package from git+ssh://git@github.com/bgnori/tonic.git error in python-tonic-library setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers Complete output from command python setup.py egg_info: error in python-tonic-library setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers setup.pyのinstall_requiresの部分はこんな感じ install_requires=open('freeze.txt').readlines(), となると、makefileを書いてsetup.pyを生成するというのが一つの解になりそうだ。 freeze.txtを埋め込む操作を行うのである。 gitから取ってくるので、makeで生成されるにもかかわらず、setup.pyはcommitする必要がある。げろげろ。 エレガントな解決策はないものでしょうか。

2011年12月23日金曜日

twistedでのunittest

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

twistedでunittestをするときは、twisted.trialモジュールを利用する。 基本的にはbuilt-inのunittestと同じなのだが、deferredが存在するための仕組みが備わっている。 ここ にドキュメントがあるのだが若干分かりにくい。というか、結論を先に書いてくれ!

3つ大事なコトがある。

  1. deferredを返す関数をテストするtest methodはdeferredを返せ。
  2. timeoutをつかえ
  3. reactor.run()、reactor.stop()、reactor.crash()、reactor.iterateを呼ぶな

1)の原文は

The golden rule is: If your tests call a function which returns a Deferred, your test should return a Deferred.

である。callbackを勝手によんでくれます。もしかしたらcallLaterを使わないで値を渡す賢いやり方があるのかもしれません。

2)は、timeoutを設定することになる。これにはメソッドのアトリビュートを使用する。 これは下記のサンプルコードをみれば了解できると思われる。というか、ドキュメントは3行も書いているが、 なんでサンプルコードを載せないのか理解に苦しむ。

ここに書いたサンプルのコードを実行すると、2つのテストが成功し、最後の物がtimeoutする。

3)は守れ。理由はreactorのインスタンスの数を考えれば自明(trial自身がreactorを持っている)

#!/usr/bin/python
# -*- coding=utf8 -*-


'''
  http://twistedmatrix.com/documents/current/core/howto/testing.html

  how to run:
$ trial twisted

'''
from twisted.internet import defer, reactor

from twisted.trial.unittest import TestCase
# c.f. from unittest import TestCase



class MyTestCase(TestCase):
  def test_with_deferred_ok(self):
    d = defer.Deferred()

    def fire(ignore):
      return 'deadbeaf'

    d.addCallback(fire)
    def ok(s):
      self.assertEquals(s, 'deadbeaf')
    d.addCallback(ok)
    def fail(s):
      self.assertNotEquals(s, 'deadbeaf')
    d.addErrback(fail)

    #reactor.callLater(0, d.callback, 'deadbeaf')
    return d
    '''
      The golden rule is: If your tests call a function which returns a Deferred, your test should return a Deferred.
    '''

  test_with_deferred_ok.timeout = 1
  '''
    The way to do this in Trial is to set the .timeout attribute on your unit test method. 
    Set the attribute to the number of seconds you wish to elapse before the test raises a 
    timeout error. Trial has a default timeout which will be applied even if the timeout 
    attribute is not set. The Trial default timeout is usually sufficient and 
    should be overridden only in unusual cases.
  '''
  def test_with_deferred_fail(self):
    d = defer.Deferred()

    def fire(ignore):
      return 'moomoo'
    d.addErrback(fire)

    def ok(s):
      self.assert_(False)
    d.addCallback(ok)
    def fail(s):
      self.assertNotEquals(s, 'deadbeaf')
    d.addErrback(fail)

    return d

  test_with_deferred_fail.timeout = 1

  def test_with_deferred_timeout(self):
    d = defer.Deferred()

    def ok(s):
      self.assert_(False)
    d.addCallback(ok)
    def fail(s):
      self.assertNotEquals(s, 'deadbeaf')
    d.addErrback(fail)

    reactor.callLater(2, d.errback, 'moomoo')
    return d

  test_with_deferred_timeout.timeout = 1

2011年11月29日火曜日

パズル:おいらの回答

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
one offやりまくってしまった。orz ideaとしてはheadとtailをとって短くしていく、tailとheadを入れ替える、ということ。再起が分からない人にはかけないやつね。
#include 
#include 
#include 


void reverse (char *str) {
  char head, tail;
  int len;


  len = strlen(str);
  if (len == 0){
    return;
  }
  if (len == 1){
    return;
  }

  tail = *(str+len -1);
  *(str+len -1) = '\0';
  head = *str;
  reverse(str+1);
  *(str+len -1) = head;
  *str = tail;
  return;
}

int main (int argc, char *argv[]) {
  if (argc *lt;= 1) {
    printf("give me a string\n");
    exit(1);
  }
  char *str = argv[1];

  reverse(str);
  printf("%s\n", str);
  return 0;
}
思ったこと:

strlenを使ってよい(というか仕方ないだろう)はどーなのでしょうか。中身loopだからこれ実行したらO(n^2)だよ、多分。

まあ、パズルだから許されるだろうけど、職場で同僚がこういうコードを書いていたらヤバい。なぜなら:

from ゲリラ的雇用面接のすすめ 関数の実行速度は充分速いか? strlen を何回呼ぶ事になるのか考えてみよう。 かつて私はO(n)であるべきstrrevのアルゴリズムがO(n^2)になってしまっている アルゴリズムを目にした事がある。彼らは繰り返しの strlen をループの中で呼ん でしまっていたのだ。 まあ、問題を
void reverse (char *start, char *end) {
    return;
}

とか書き換えればいいのですが(C++のイテレータチックだな)そうすると問題が変わってしまう。

やる気に関する驚きの科学 (TED Talks)に出てくる、この絵の問題のようなものだ。

オリジナルCパズルの問題は前者、書き換えたものはfor dummiesになっているのではないかと思う。