メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2008年2月12日火曜日

[Python][お勉強] Python入門(28) - apply関数

apply関数についてやる。

PythonではLispのようにapply関数がある。
プログラム実行時に関数の名前、引数が決まる場合にapply関数を使える。

apply関数の例


>>> def func(x,y,z): return x + y + z
...
>>> apply(func, (2,3,4))
9
>>>




キーワード引数を渡す

apply関数の第三引数を使用する。

>>> def aaa(a,b,c): return a + b + c
...
>>> apply(aaa,(),{'c':1, 'b':2, 'a':1})
4
>>>


第三引数にディクショナリの形にして渡せばキーワード引数として渡すことができる。




おしまい。
.

2008年2月11日月曜日

[Apache][CodeReading] Apache2.2.8コードリーディング11日目

今日もコードリーディング。

昨日のつづきでapr_initialize()まわりを読んだ。

つくったページは、

  • APR_ENOMEM定数/Apache2.2.8
  • APR_OS_START_CANONERR定数/Apache2.2.8
  • APR_OS_START_USERERR定数/Apache2.2.8
  • APR_OS_START_STATUS定数/Apache2.2.8
  • APR_OS_ERRSPACE_SIZE定数/Apache2.2.8
  • APR_OS_START_ERROR定数/Apache2.2.8
  • SIZEOF_ALLOCATOR_Tマクロ/Apache2.2.8
  • APR_ALIGN_DEFAULTマクロ/Apache2.2.8
  • APR_ALIGNマクロ/Apache2.2.8
  • global_allocatorスタティック変数/Apache2.2.8
  • APR_POOL_DEBUG定数/Apache2.2.8
  • apr_pools_initializedスタティック変数/Apache2.2.8

定数が定数で定義されててsのまた定数が定数で・・・という繰り返しがちょろっと。

で、今日の本丸はapr_pool_initialize()/Apache2.2.8。
結局全部読めなかった。

global_allocatorにapr_allocator_t用の領域を確保して
0クリアしたところまで。
global_allocatorはglobalってついているのにスタティック変数。
きっとシステム全体のallocatorという意味か。


領域確保できなかったらAPR_ENOMEMを返すんだけど、
errno.hのENOMEMが定義されていなかったら、APRで独自に定義する。
でその値は620007。
システムの他のエラーコードと重ならないようにしていると思うんだけど、
「へぇ」という感じ。

まだまだアロケータの中身に到達していないのでなんともいえないが、
相変わらず面白そうだ。




.

[Python][お勉強] Python入門(27) - lambda式

今日はlambda式。

Lispから来た名前だそうで。

lambda式とは
defステートメントのように関数を作成する際に使用するもの。
defステートメントとは違い「式」。よってdefステートメントでは記述できない場所に記述することが可能。
また、defステートメントでは関数の名前を記述できたが、lambda式では意図的に代入しない限り名前がない。つまり無名関数生成式ということ。

lambda式のシンタックス


lambda <arg1>,<arg2>,...<argN>: <expressions>


の形をとる。

実際に書いてみる。
まずdefステートメントから、

>>> def func(x,y,z): return x + y + z
...
>>> func(2,3,4)
9
>>>


なんてのがあったとする。
これをlambdaで書き直すと・・・、

>>> func = lambda x, y, z: x + y + z
>>> func(2,3,4)
9
>>>


な感じか。
lambdaでは名前がないので、名前に相当する変数にlambda式の結果を代入している。
defステートメントと同様にキーワード引数やデフォルト値も設定できる。


>>> func = lambda x,y=10,z=30: x + y + z
>>> func(x=1)
41
>>>




lambda式の特徴。
lambda式は「式」なので、defステートメントでは記述できない場所に記述できる。
たとえば

>>> L=[(lambda x: x**2),(lambda x: x**3),(lambda x: x**4)]
>>> for f in L:
... print f(2)
...
4
8
16
>>>


のように[]中に記述できる。なにせ「式」なので。





おしまい。
.

2008年2月10日日曜日

[Debian][Apache] 静的ファイルが送られてこない

Apache2.2にアップグレードしたばっかで気づかなかったが、
静的ファイルが一切レスポンスされない。

そういうものか??

ログレベルをdebugにして見てみると・・・


Function not implemented: core_output_filter: writing data to the network


なんてのが出力される。

とりあえず、

EnableSendfile Off


を/etc/apache2/sites-available/defaultに追記して事なきを得た。


うーむん。



.

[Python][お勉強] Python入門(26) - 引数

さて、Pythonのお時間。今日は引数を学ぶ。

引数の重要事項

  • 引数が渡されると自動的にローカルスコープの変数に代入される。
  • よって引数に渡された変数を関数内で更新しても呼び出し元では影響しない。
  • ただし、引数の内部のリファレンスを上書きした場合は呼び出し元でも影響する。
な感じ。要は変数は全てポインタっぽく動作するので、ポインタそのものはコピーされるがそのポインタが保持しているポインタを上書きすれば呼び出し元にも影響を及ぼすということか。

たとえば、

>>> L = [1,2,3,4]
>>> def func(ll):
... ll = [5,6,7,7]
...
>>> func(L)
>>> L
[1, 2, 3, 4]
>>>


としてもグローバル変数Lは更新されない。が、

>>> def func(ll):
... ll[0] = 5
...
>>> func(L)
>>> L
[5, 2, 3, 4]
>>>


と、Lの内容はコピーされているわけじゃなくて、同じリファレンスを持つので、グローバル変数の値は更新されてしまう。
この辺、要注意らしい。

仮に、上記のようにリストの中身を変更しても呼び出し元に影響されたくないとするならば、

>>> L = [1,2,3,4]
>>> def func (ll):
... ll[0] = 5
...
>>> func(L[:])
>>> L
[1, 2, 3, 4]
>>>



と、スライシングの[:]を使って全ての要素をコピーしてしまえばよい。



キーワード引数
pythonではキーワード引数なるものが使える。


>>> def func(a,b,c):
... print a, b,c
...
>>> func(c=10,b=20,a=30)
30 20 10
>>>


な感じに引数を定義順には関係なく渡すことができる。
c=10は、引数cに10をという意味。
b=20は、引数bに20をという意味。
a=30は、引数aに30という意味。
順番ではなく、引数の名前を指定して値を渡すことができる。
このことを「名前によるマッチング」という。


可変引数
*や**を使用する。


>>> def func(*a):
... print a
...
>>> func("a","b","c")
('a', 'b', 'c')
>>>


となり、*を使用した場合は引数全てがタプルとなって関数内で受け取れる。

**を使用した場合は、

>>> def func(**a):
... print a
...
>>> func(a=10,b=20,c=30)
{'a': 10, 'c': 30, 'b': 20}
>>>


となり、関数内ではディクショナリとして受け取れる。
これらは、全て自由に引数の個数を変えられる。

**を使用した場合は、引数に渡す時点で、a=10、b=20のようにキーワード引数の形で渡す必要がある。


デフォルト値
関数の定義時に、仮に引数が指定されなかったときのためにデフォルトの値を設定できる。


>>> def func(a,b=20,c=30):
... print a,b,c
...
>>> func(10)
10 20 30
>>>


呼び出し時には1つしか引数を渡していない。定義時にbとcのデフォルト値を設定してあるので、
実際に呼び出すとa=10、b=20、c=30という値で呼び出されたことになる。

仮に、

>>> def func(a=10,c,d):
... print a,b,c
...
SyntaxError: non-default argument follows default argument
>>>



と引数aにだけデフォルト値を設定すると構文エラーになる。
これは引数が2つ以上あった場合、どの引数が省略されたのかPythonは知るすべがないからである。


>>>func(10,20)

とコールした場合、10はaに設定され、20はbに設定される。
cは未定義となってしまう。




おしまい。
.

[Apache][CodeReading] Apache2.2.8コードリーディング10日目

今日もこつこつとリーディング。


今日は
apr_unix_setup_time()/Apache2.2.8周りを読破。

apr_unix_setup_timeでは、struct tmにtm_gmtoffか__tm_gmtoffを保持しないシステム用に
自力でgmtからのオフセット値を計算して保持している部分。
tm_gmtoffを保持しているシステムではコード自体がNOPになって何も処理しない。


APR_DECLARE(void) apr_unix_setup_time(void)
{
#ifdef NO_GMTOFF_IN_STRUCT_TM
/* Precompute the offset from GMT on systems where it's not
in struct tm.

Note: This offset is normalized to be independent of daylight
savings time; if the calculation happens to be done in a
time/place where a daylight savings adjustment is in effect,
the returned offset has the same value that it would have
in the same location if daylight savings were not in effect.
The reason for this is that the returned offset can be
applied to a past or future timestamp in explode_time(),
so the DST adjustment obtained from the current time won't
necessarily be applicable.

mktime() is the inverse of localtime(); so, presumably,
passing in a struct tm made by gmtime() let's us calculate
the true GMT offset. However, there's a catch: if daylight
savings is in effect, gmtime()will set the tm_isdst field
and confuse mktime() into returning a time that's offset
by one hour. In that case, we must adjust the calculated GMT
offset.

*/

struct timeval now;
time_t t1, t2;
struct tm t;

gettimeofday(&now, NULL);
t1 = now.tv_sec;
t2 = 0;

#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
gmtime_r(&t1, &t);
#else
t = *gmtime(&t1);
#endif
t.tm_isdst = 0; /* we know this GMT time isn't daylight-savings */
t2 = mktime(&t);
server_gmt_offset = (apr_int32_t) difftime(t1, t2);
#endif /* NO_GMTOFF_IN_STRUCT_TM */
}


簡単に書くと、gettimeofdayをtimezoneにNULLを伴ってコールし(マニュアルによるとtimezoneに値を指定するのは時代遅れとのこと)GMT秒を取得。
秒からstruct tmへ変換。
変換結果の夏時間をクリアしてmktimeでローカル時間に変換。
結果の差分をgmt_offsetとしてスタティック変数に保管。

な感じか。
ちなみにDebian-EtchではNOP。


次回はいよいよpoolの初期化部分に入る予定。
きっとものすごくアツイに違いない。



.

[その他] MyMiniCity ビルができてた。

わーい。

ビルが建った。

といっても小さいビルだけど。。

http://atkonn.myminicity.com/
http://atkonn.myminicity.com/ind


.