Showing posts with label Web. Show all posts
Showing posts with label Web. Show all posts

Thursday, May 28, 2009

Gmailのエラー

最近FirefoxでGmailをアクセスするとよく(エラーコード: ssl_error_access_denied_alert)が出てくる。
普通HTML(Ajax)バージョンはほぼ使いないぐらいになる。
仕方なく簡易HTMLで使うしたない。
これはOpera、Chromeでは起こらない問題だ。
もしかしたらProxyの設定に関係あるかもしれない。
とにかくOperaでGmailを使うしかない。
但し、OperaはGmailオフラインをサポートしていないため、ちょっと不便だ。

Wednesday, March 18, 2009

Google AppEngine Developing

offical django and google appengine list
http://code.google.com/u/@VxVXQVFQARNAXQh1/

djangoguestbook
http://code.google.com/p/google-app-engine-django-guestbook/

google-app-engine-django helper for django 0.96
http://code.google.com/p/google-app-engine-django/

django-on-google-app-engine guide:
http://thomas.broxrost.com/2008/04/08/django-on-google-app-engine/

django on windows
http://wiki.thinkhole.org/howto:django_on_windows

Friday, February 27, 2009

net2ftp - web based ftp client

http://www.net2ftp.com/

OSSレビュー

http://nextwise.jp/ossreview/
いろいろな利用者からみるOSSの情報

Monday, February 16, 2009

python perl and ruby

http://www.shido.info/py/python1.html

HOME Python 書き込む

Perl, Python, Ruby の比較
1. はじめに
この文書は旧版 を少し手直ししたものです。元の文書に載せてあるスクリプトはいまいちなので書き換えました。 それに伴い、本文のほうも替わっています。 また、実行環境の OS が Win32 から Linux に替わりました。 (今は家族も Linux を使っています。)

紫藤は長年スクリプト言語として awk と Lisp を使ってきました。 Perl というものがあり、一時はブームになっていたのも知っていたのですが、 どうもなじめなかったので、ほとんど使いませんでした。 最近、Python や Ruby といった新世代のスクリプト言語が広く使われるようになったので、 それらを試してみることにしました。

現在は Python を使っているので、Python よりの比較になっていることを念頭において読んでください。 また、この文書に批判的な意見もあるので、 そちらも参考にしてください。

お題は以前紹介した メディアにある画像ファイルをハードディスクに保存するスクリプトです。 実は我が家のパソコンはほとんどアルバムと化しており、メディアからハードディスクに移すスクリプトは FireFox 以外では私の家族に一番利用されているプログラムです。
2. 画像ファイル保存スクリプトの仕様
仕様は以下の通りです。
今月のディレクトリの下に写真用ディレクトリを作り、そこにメディアから写真を移動する。
今月のディレクトリの名前は年の下2桁と月をハイフンでつなげたものである。(例: 2007 年 6 月 → 07-06)
今月のディレクトリの下に複数の写真用ディレクトリがあり、それらのの名前は photoNN (N=0-9) である。
通し番号 NN は 01 からはじまり、1 づつ増加する。
新しく作る写真用ディレクトリの通し番号 NN は、現在ある写真用ディレクトリの通し番号の最大値に 1 を加えたもの からはじめる。
以下のように実装します。
メディアのディレクトリを走査して、ディレクトリ名をキーとし、そのディレクトリにある画像ファイルの リストを値とするハッシュ表を作る。
今月のディレクトリがなければ作る。
今月のディレクトをを調べ、写真用ディレクトリの通し番号を何番から始めればいいか決める。
メディアにある写真をディレクトリごとに HDD にコピーする。
HDD にコピーした画像ファイルと、メディアにあるもともとの画像ファイルを比較して、 等しければメディアのファイルを削除する。
例えば、
メディアに imag1, imag2 という画像ファイルの入ったフォルダーがあり、 今月のディレクトリに photo01, photo02 というディレクトリがあった場合、 photo03, photo04 というディレクトリを作り、imag1, imag2 にある画像ファイルを それぞれ photo03, photo04 に保存します。 (imag1 と imag2 の順序 (どちらが旧いかなど) は気にしません。)
3. Perl, Python, Ruby で書いてみて
2. で述べた仕様に沿って Perl, Python, Ruby で書いてみました。 現在、Python を使っているので、Python のやつが他のよりうまく書けていると思います。 初心者が一夜漬けの学習で書くとどうなるかは旧文書を見てください。
3.1. まず、Perl で
Perl で書くと次のようになります。これは旧文書のと変わっていません。
01: #! perl
02:
03: use strict;
04: use File::Copy;
05: use File::Compare;
06: use File::Find;
07: use Cwd;
08:
09: ## global parameters
10: my $DOC_DIR = 'D:/doc';
11: my $MEDIA ='G:/';
12: my $PHOTO_VIEWER = 'D:/WBIN/linar160/linar.exe';
13:
14: # getting the string of "year(NN)-month(NN)"
15: sub get_year_month{
16: my ($m, $y) = (localtime)[4,5];
17: sprintf ("%02d-%02d", $y-100, $m + 1);
18: }
19:
20: # getting the starting number of photoNN, the directory in which photos should be saved
21: # This function should be called when the program is in the month directory.
22: sub get_first_photo_dir_number{
23: my @pdirs = (glob "photo[0-9][0-9]");
24: @pdirs ? 1+ substr($pdirs[-1], -2) : 1;
25: }
26:
27: #move into the directory "$DOC_DIR/y-m"
28: sub move_into_dir_of_month{
29: my $dir_of_month = &get_year_month;
30: unless ($DOC_DIR eq cwd){
31: chdir $DOC_DIR or die "Cannot move to $DOC_DIR: $!";
32: }
33: unless (-d $dir_of_month){
34: mkdir $dir_of_month or die "cannot create $dir_of_month: $!";
35: }
36: chdir $dir_of_month or die "Cannot move to $dir_of_month: $!";
37: "$DOC_DIR/$dir_of_month" ;
38: }
39:
40: #archive photos in the media into the HD
41: # This function should be called when the program is in the month directory.
42: sub archive_photos{
43: my $photo_dir_number = shift;
44: my %dhash;
45: find({
46: wanted => sub{push @{$dhash{$File::Find::dir}}, $_ if -f},
47: }, $MEDIA);
48: for my $dir_from (sort keys %dhash){
49: my $n = @{$dhash{$dir_from}};
50: my $i = 0;
51: my $dir_to = sprintf("photo%02d", $photo_dir_number++);
52: mkdir $dir_to or die "cannot create $dir_to: $!";
53: print "\n$dir_from ==> $dir_to\n";
54: for my $fname (@{$dhash{$dir_from}}){
55: my $copy_from = "$dir_from/$fname";
56: my $copy_to = "$dir_to/$fname";
57: copy($copy_from, $copy_to) or die "cannot make a copy for $copy_from: $!";
58: if(0 == compare($copy_from, $copy_to)){
59: unlink $copy_from;
60: print ++$i, "/$n\r";
61: }else{
62: die "an error occurs during coping $copy_from";
63: }
64: }
65: }
66: %dhash;
67: }
68:
69: #main
70: my $dir_of_month = &move_into_dir_of_month;
71: my $first_photo_dir_number = &get_first_photo_dir_number;
72: if(&archive_photos($first_photo_dir_number)){
73: exec (sprintf "%s %s/photo%02d", $PHOTO_VIEWER, $dir_of_month, $first_photo_dir_number);
74: }else{
75: print "No photos in the media!\nGive Return:";
76: < STDIN>
77: }
大体 80 行くらいのコードになります。 リストは Perl のハッシュ表の値にはなれないのでリストを値としたければ、 リストのリファレンスを使う必要があります。 印象としては、awk と sed を混ぜたものをその適応範囲外まで拡張しすぎたという感じです。 崩壊寸前のダムみたいな感じで、いまいち。 ただし、ライブラリは優秀で、実行速度は速いです。

今は python や ruby があるので、いまさら新たに perl を学ぶ必要は無いと思います。
3.2. 次に Python
Python で書くと次のようになります。旧版のはいけてないので書き直しました。
001: #! /usr/bin/env python
002:
003: r"""
004: script to achive photos in the removal media into HD
005: by T.Shido
006: June 26, 2007
007: """
008:
009: import os, os.path, filecmp, shutil, re, sys, operator
010: from datetime import date
011:
012: # global parameters
013: HD = '/home/pub/photos/'
014: MEDIA = '/media/usbdisk/'
015:
016: REG_FILE = re.compile(r"\.(gif|bmp|jpe?g|tiff?|wav|mov)$", re.I)
017: REG_DIR = re.compile(r'^photo[0-9][0-9]$')
018:
019: def n_photo_dir(d):
020: """return the max NN of photoNN in directory of the month"""
021:
022: return \
023: reduce(max, \
024: [ int(x[-2:]) for x in os.listdir(d) \
025: if (os.path.isdir(os.path.join(d,x)) and REG_DIR.match(x))], \
026: 0)
027:
028: def search_media(d):
029: """search Media and returns a hash
030: whose keys are directory name and the values are lists of photo files."""
031: def search_sub(d):
032: os.chdir(d)
033: ls_d = os.listdir(d)
034: ls_f = [x for x in ls_d if os.path.isfile(x) and REG_FILE.search(x)]
035: if ls_f:
036: h[d] = ls_f
037: for d1 in [os.path.join(d,x) for x in ls_d if os.path.isdir(x)]:
038: search_sub(d1)
039:
040: h={}
041: search_sub(d)
042: return h
043:
044: def move_photos(d0, d1):
045: r"""
046: Moveing photo files from media into HD,
047: """
048: dir_of_month = os.path.join(d1, date.today().strftime("%y-%m"))
049: h = search_media(d0)
050: total_files = reduce(operator.__add__, [len(v) for v in h.itervalues()], 0)
051:
052: if total_files==0:
053: print "No photos in the media: give return"
054: sys.stdin.readline()
055: sys.exit()
056:
057: if not os.path.isdir(dir_of_month):
058: os.mkdir(dir_of_month)
059:
060: i_dir = n_photo_dir(dir_of_month)
061: count=0
062:
063: for d, ls_files in h.iteritems():
064: i_dir += 1
065: d_to = os.path.join(dir_of_month, "photo%02d" % i_dir)
066: os.mkdir(d_to)
067:
068: for f in ls_files:
069: f_from=os.path.join(d,f)
070: f_to=os.path.join(d_to, f)
071: shutil.copyfile(f_from, f_to)
072: if not filecmp.cmp(f_from, f_to):
073: print f_from + " and " + f_to + " are not same!"
074: sys.exit()
075: os.remove(f_from)
076: count+=1
077: print "%d/%d\n" % (count, total_files),
078:
079: if __name__=='__main__':
080: move_photos(MEDIA, HD)
大体 80 行になります。長さは大体 Perl で書いたものと同じです。 ソースの見栄えはとても良く、 インデントでブロックを表現するというアイデアは成功していると思います。 煉瓦のような雰囲気できっちりとしています。コーディングの自由度が少ないので、 (1年前の自分も含む)誰が書いても同じようなコードになり、読み取るのは容易です。 そのため、コメントの量も少なくて済み、変数名をコメント代わりに使う必要もありません。 変数はデフォルトで局所変数となるので、 Perl のように my で宣言する必要はありません。 また、リストの内包表現は Lisp の mapcar と remove-if-not が同時に出来るので便利です。 ライブラリは優秀で、実行速度は Perl より速い気がします。

スクリプト言語としての欠点を挙げると、
関数とメソッドが入り混じっているのですっきりしない。
多くのモジュールを import しなければならない。(80 行で 8 個もある)
があります。

それから、Python には 対話モードがあり、個々の関数をテストできます。(注1) この機能は大きめのプログラムを書くときに便利です。 main に相当する部分を、 if __name__=='__main__': のブロックに入れることによって、 Python によって直接読み込まれたとき以外は動作しないようにすることが出来ます。(注2)
個々の関数のテストは次のようにします。
プロンプトから python とだけ打ち込んで対話モードに入ります。
import hoge としてスクリプトを読み込ませます。 (例えば hoge.py を読み込む場合)
あとは hoge.foo([1,2,3]) などとして、個々の関数をテストします。(hoge.py に foo という関数が 定義されている場合)

3.3. 最後に Ruby
それでは、 Ruby ではどうなるでしょうか? (これも書き換えました)
001: #! /usr/bin/env ruby
002:
003: require "fileutils"
004:
005: # global parameters
006: HD = '/home/pub/photos/'
007: MEDIA = '/media/usbdisk/'
008:
009: REG_FILE = Regexp.compile("\\.(gif|bmp|jpe?g|tiff?|wav|mov)$",Regexp::IGNORECASE)
010: REG_DIR = Regexp.compile('^photo[0-9][0-9]$')
011:
012: H=Hash.new
013: # HD 側に何個の photoNN フォルダーがあるかを返します。
014: def n_photo_dir(d)
015: Dir.entries(d).select{|x| FileTest.directory?(File.join(d,x)) and REG_DIR =~ x
016: }.map{|x| x[5..6].to_i}.inject(0){|x,y| max(x,y)}
017: end
018:
019: # メディアに保存されている写真ファイルの一覧をフォルダーごとにまとめて返します
020: # 再帰的にファルダーのツリーを下っていき、写真ファイルの一覧をフォルダー名をキーとしてハッシュ表に登録します
021: def search_media(d)
022:
023: Dir.chdir(d)
024: ls=Dir.entries(d).reject{|x| x=='.' or x=='..' }
025:
026: ls_f=ls.select{|x| FileTest.file?(File.join(d, x)) and REG_FILE =~ x}
027:
028: H[d] = ls_f unless ls_f.empty?
029: ls.map{|x| File.join(d,x)}.select{|x| FileTest.directory?(x)}.each{|x| search_media(x)}
030: end
031:
032: # 写真ファイルをメディアから HD にコピーします
033: def move_photos(d0, d1)
034: dir_of_month=File.join(d1, Time.now.strftime("%y-%m"))
035: search_media(d0)
036: total_files = H.values.map{|x| x.size}.inject(0){|result, item| result + item }
037:
038: if total_files==0
039: then
040: p "no photos, give return"
041: STDIN.readline
042: abort
043: end
044:
045: FileTest.directory?(dir_of_month) or Dir.mkdir(dir_of_month)
046:
047: i_dir = n_photo_dir(dir_of_month)
048: count=0
049:
050: H.each{|d, ls_files|
051: i_dir += 1
052: d_to = File.join(dir_of_month, sprintf("photo%02d", i_dir))
053: Dir.mkdir(d_to)
054:
055: ls_files.each{|f|
056:
057: f_from=File.join(d,f)
058: f_to=File.join(d_to, f)
059: FileUtils.cp(f_from, f_to)
060:
061: if not FileUtils.cmp(f_from, f_to)
062: then
063: printf("Copy failed: %s => %s\n", f_from, f_tp)
064: abort
065: end
066: File.delete(f_from)
067: count+=1
068: printf("%d/%d\n", count, total_files)
069: }
070: }
071: end
072:
073: #main
074: move_photos(MEDIA, HD)
長さは 74 行となり、3つの中で一番短くなります。 ソースの見栄えも悪くなく、データがピリオドの前から、後ろに 流れていくような感じです。ちょうど、Lisp コードが括弧の中から外にデータが流れるように 見えるのと同じ雰囲気です。 また、全てがメソッドなのですっきりしています。

Win32 で試したときはすごく遅かったのですが、Linux 上ではそんなに遅く感じませんでした。 Ruby は Linux と相性がいいのかもしれません。
4. というわけで Python
Perl, Python, Ruby の比較をまとめるとつぎの表のようになります。 現在は Python を使っているのでぜんぜん公平な比較ではありません。 項目 Perl Python Ruby
書きやすさ ○ ○ ○
読みやすさ △ ◎ ○
ライブラリー ○ ○ △
実行速度 ○ ○ △
ドキュメント ◎ ○ △
ユーザー数 ◎ ○ △

コードの書きやすさは3つともそれほど違わないように思えます。ただ、読みやすさはダントツで Python が 優れています。Ruby はまずまずで、Perl は書き手の技量による部分が大きいのですが、 一般的には "読めない" コードになりがちです。

現在の人気を無視して、言語そのもののよしあしを考えると、 Python と Ruby はほぼ互角でしょう。しかし、今のところ Python の方が、 実行速度が速く、ライブラリが豊富なので、とりあえず Python を使うことにします。 また、Python には対話モードがあるのも Lisp に慣れた人間にとってはありがたいです。 Ruby は今後の健闘に期待します。
5. おわりに
以上 Perl, Python, Ruby の比較をつれづれと書きましたがご参考になりましたでしょうか? 結論は、
Python, Ruby は Perl に比べて明らかによい。(後発なので当然か)
Python と Ruby はほぼ互角。
最後に主な Web docments を挙げておきます。
Perl
perl.org
cpan.jp
Python
python.org
日本Pythonユーザ会
Ruby
オブジェクト指向スクリプト言語 Ruby
6. 追記(もう少しまじめな比較)
上の文章は小さなスクリプトを書いてみてその出来具合を比較しただけなので、 ここではもう少しまじめな比較をしたいと思います。現在は Python を使っているので Python よりの論評になっています。

Perl や Ruby は純粋なスクリプト言語で、(もちろんそれなりに大きなプログラムも書けるようにはなっているものの) プログラムを短くすることに主眼が置かれています。 一方、Python はスクリプト言語としてもつかえる大規模プログラム作成言語で、デバックの容易さに主眼が 置かれています。プログラミング言語は適応範囲が広いほど学ぶ価値があるので、 その意味で Python を学ぶことは Perl や Ruby を学ぶより有用だと思います。 (このことから google が Perl や Ruby でなく、 Python を使っている 理由が分かるような気がします。)

ここにある内容は一部Python 早めぐりと重複しています。 Python のポリシーについては A morality tale of Perl versus Python (和訳) やThe Zen of Python (和訳)を見てください。
6.1. 大規模プログラムの作成
Python は Perl や Ruby に比べて大規模プログラムが容易に作れるという利点があります。 また、小さなスクリプトを大きなプログラムに育てることがやりやすい ということも Python の特徴です。 Python で大規模プログラムが作りやすいのは次の理由に拠ります。
ソースファイルごとに名前空間が割り当てられる。
対話モードで関数を一つずつをテストすることが出来る。
if __name__=='__main__' 以下にファイルごとのテストコードを書くことが出来る。
Perl や Ruby では名前空間を分けるための宣言をわざわざ書かなければいけません。 Python では1ファイル1名前空間と割り切り、 ファイル名を名前空間名とすることによって名前の衝突を上手に回避しています。 また、 Perl でも Ruby でもはじめからモジュール専用のコードを書かなければなりませんが、 Python でははじめの小さなスクリプトに __all__ などの 約束事を書き足せばモジュールとして機能します。また、そのスクリプト単体でもつかうことが 出来ます。例えば wxPython と Tkinter で Eight Queens を作る を見てください。
6.2. ファイルの読み込み
Perl では基本的に while(<>) を使って一行ずつファイルを読み込みますが、 Python や Ruby では read() を使ってファイルを一気に読み込むことも出来ます。 (注3) これは、Python や Ruby が登場した 1990 年代はメモリーが安くなったために贅沢な使い方が出来るようになったためだと 思われます。
6.3. リストの操作
Lisp にある mapcar, remove-if-not などのリストを操作してリストを返す関数は、 Perl, Python, Ruby では以下のようなっています。
Perl は map や grep 等の関数があるが、 foreach ブロックを使うのが一般的
Python にも map や filter 等の関数があるが、内包表現を使うのがよい。
Ruby は map, select, grep などのブロック付きメソッドを使ってあらわす。
このなかで Ruby が一番 Lisp に近い仕様になっています。Python は Lisp とは一線を画しているようです。

例)要素が非負の実数の場合、その平方根を返す。 [-3,-2,-1,0,1,2,3] ⇒ [0.0, 1.0, 1.4142135623731, 1.73205080756888]
01: # Perl 5
02: my @ls0=(-3,-2,-1,0,1,2,3);
03: my @ls1=();
04: for (@ls0){
05: push @ls1, sqrt($_) if $_ >= 0;
06: }
07: print "$_\n" for (@ls1);
08:
09: # Ruby
10: p [-3,-2,-1,0,1,2,3].select{|x| x>=0}.map{|x| Math.sqrt(x)}
11:
12: # Python
13: import math
14: print [math.sqrt(x) for x in [-3,-2,-1,0,1,2,3] if x>=0]
6.4. 引数の渡し方
Perl: 引数をフラットなリストに変換して値渡し。参照渡しをするにはプロトタイプを用いる。少し複雑。
Python: 参照渡し。ただし、変更不能なオブジェクトは実質的に値渡し。 つまり、配列は、呼び出した関数内で変更を加えるともともとの配列も変更されてしまうが、数、文字列、タプルなどは変更されない。 レストパラメータ、オプショナルパラメータ、キーワードパラメータをサポート。 詳しくは Python チュートリアル 4.6 関数を定義する や Python 早めぐり 5. 関数定義 を見てください。
Ruby: Python と同じ。
6.5. 関数の生成
関数の生成は以下のようにします。Perl や Ruby では関数を返す関数が書けますが、 Python では普通はそういうことをしません(注)。その代わり、関数のクラスを定義します。 Python で書くと Perl や Ruby より長くなりますが、これはやり方は1つだけ のポリシーに従ったものです。また、より複雑な関数を生成する場合はむしろこの記法のほうがすっきりするでしょう。

例)累積機の生成。 (数nを取り、「数iを取ってnをiだけ増加させ、その増加した値を返す関数」を返すような関数)
01: # Perl 5
02: sub foo {
03: my ($n) = @_;
04: sub {$n += shift}
05: }
06:
07: # Python
08: class foo:
09: def __init__(self, n):
10: self.n = n
11: def __call__(self, i):
12: self.n += i
13: return self.n
14:
15: # Ruby
16: def foo (n)
17: lambda {|i| n += i }
18: end
使用例

01: >>> a=foo(10)
02: >>> a(3)
03: 13
04: >>> a(5)
05: 18
6.6. 高階関数
Perl: 関数のリファレンスを取ることにより関数を引数として渡せる。 (Perl コードの 46 行目)
Python: 関数名が関数へのアドレスをあらわす。
例えば、baz という関数を定義したとき、 baz(....) はその関数の呼び出し、 baz は関数のアドレスになる。関数のアドレスを引数として渡したり、 for ループの中で 用いることが可能。(Eight Queen 本体 93 行目を参照)
Ruby: 関数名を直接引数に与えると、引数が省略されたものとして解釈されるので、lambda でくるむ必要があります。 python の場合より少しタイプ量が増えます。ruby は ブロックつきメソッドを多用するので、 高階関数をあらわに使う機会は python ほど多くないと思われます。
ディレクトリを再帰的にたどって、ファイルなら関数を適用する関数 walk_dir を python と ruby で書くと以下のようになります。

[walk_dir.py]
001: #!/usr/bin/env python
002: # coding:shift_jis
003:
004: from __future__ import with_statement
005: import os, os.path, sys
006:
007:
008: def walk_dir(f, d, exp=''):
009: u'''ディレクトリを再帰的にたどって全てのファイルに関数 f を適用します'''
010:
011: for p0 in os.listdir(d):
012: p1 = os.path.join(d, p0)
013: if os.path.isfile(p1) and p1.endswith(exp):
014: f(p1)
015: elif os.path.isdir(p1):
016: walk_dir(f, p1, exp)
017:
018:
019: def head(fname):
020: u'''最初の 5 行を表示する'''
021: print '==== %s ====' % (fname,)
022: with file(fname) as f:
023: for i, line in enumerate(f):
024: if i==5: break
025: print line
026:
027:
028: # スクリプトが直接呼ばれたときに以下のブロックが実行されます。
029: if __name__=='__main__':
030: walk_dir(head, os.getcwd(), '.py')

[walk_dir.rb]
001: #! ruby
002:
003:
004: # walk directories recursively
005: # and apply proc if the element is a file
006: def walk_dir(proc, d=nil, exp='')
007: Dir.foreach(d){|s|
008: if s != '.' and s != '..' then
009: p=File.join(d,s)
010: case File.ftype(p)
011: when "file"
012: if(exp.length==0 or File.extname(p) == exp) then
013: proc.call(p)
014: end
015: when "directory"
016: walk_dir(proc, p, exp)
017: end
018: end
019: }
020: end
021:
022: # show first 5 lines of a file
023: def head(fname)
024: print "\n\n==== " + fname + " ===\n"
025: i=0
026: open(fname) do |f|
027: f.each{|line|
028: if i==10 then break end
029: print line
030: i+=1
031: }
032: end
033: end
034:
035: #-----
036:
037: walk_dir(lambda{|fname| head(fname)}, Dir.pwd, '.rb')
6.7. その他
Python と Ruby はイテレーターを使って遅延評価が出来ます。
Python の オンラインドキュメント は大変良い。Ruby のはイマイチ。
Python と Ruby は実はほとんど同じで、むきになるほどの差はないと思います。 (ただ、Python は Haskell などの最近の関数型言語の影響が強く見られ、 一方、Ruby は Smalltalk や Eiffel などのオブジェクト指向言語と Lisp の影響が見られます。)
Python はオブジェクト指向を強要しないので Ruby より初学者には学びやすいかもしれません。
注1:
Python は言語の機能として対話環境をサポートしています。 perl では Term::Readline::Gnu にある perlsh を使えば Python と同じことができるそうです。 ruby では irb で同じことができます。

注2:
perl や ruby でもできるそうですが、この機能は、モジュールと通常のスクリプトの書式が同じであるという python の特徴があって初めて威力を発揮すると思います。 perl や ruby でこの機能を有効に使った例をご存知の方はお教えください。

注3:
perl でファイルを一気に読み込めないといっているわけではありません。 perl で一気読みするには次のようにするそうです。
my $data = do{ local $/; };

HOME Python 書き込む

Sunday, February 15, 2009

Python, Ruby ... Syntax Compare

http://0xcc.net/blog/archives/000137.html

http://hopper.unco.edu/course/CS102/S08/syntaxcompar.html

http://codesyntax.netfirms.com/lang-python.htm

Google App Engine Mail sender

http://builder.japan.zdnet.com/sp/google-app-engine/story/0,3800086196,20371280-4,00.htm

Monday, February 2, 2009

Chrome open source version

http://d.hatena.ne.jp/NyaRuRu/20080909/p1

http://code.google.com/intl/ja/chromium/

Saturday, January 17, 2009

draw2d

js based 2d visio like opensouce library
http://draw2d.org/draw2d/

svg news

a good source for svg news

http://updates.zdnet.com/tags/svg.html

Windows WMF and EMF format

http://www.undocprint.org/formats/winspool/emf

web on the fly drawing

flash-svg-editor-live-demo:
http://blog.tiagocardoso.eu/mainada/comics-sketch/2008/11/12/flash-svg-editor-live-demo/

inputdraw tag
http://mainada.net/inputdraw

comics sketch
http://mainada.net/comicssketch

HTML5 Canvas Element

http://www.html5.jp/canvas/what.html
Library http://sourceforge.net/project/showfiles.php?group_id=163391
ExplorerCanvas 0002 (excanvas)




Canvasの生い立ち

Canvasは、もともとはAppleが発祥で、当初、Mac OSでおなじみのDashboardで使われた技術仕様です。その後、Apple、Mozilla Foundation、Opera Softwareといったブラウザベンダが立ち上げたWHATWGという団体にて策定作業が行われていた「Web Applications」と呼ばれる規格に採用されました。この「Web Applications」は、現在、W3Cが次世代HTML標準を見据え「HTML5」という名称で策定作業に着手しています。

HTML5は策定中ということもあり、HTML5を実装したブラウザはありませんが、Canvasに関しては、Safari1.3以降、Opera9以降、Firefox1.5以降ですでに実装されています。

Internet Explorerの状況

MicrosoftがWHATWGに参画していないせいもあってか、もっともブラウザシェアが高いInternet ExplorerはCanvasに対応していません。これでは、実践においてCanvasの利用がためらわれてしまいます。しかし、GoogleがExplorerCanvasというJavaScriptライブラリを公開したことにより、状況が変わってきました。

Monday, January 12, 2009

File Sharing Site

http://www.ziddu.com/

Friday, November 28, 2008

adobe air

http://sites.google.com/site/shin1ogawa/adobe-air

Python 講習会 資料

http://www.unixuser.org/~euske/doc/python/tutorial0917.html

Python 講習会 資料

Version 1.0 (2004年 9月)

対象: ある程度プログラミングの経験がある Java あるいは Perl のユーザ。


概要

  • インタプリタ言語。覚えることは最小限。もとは教育用。
  • Java と Perl の中間? プロトタイプに最適。
  • オープンソース by Guido van Rossum、コミュニティで開発。
  • 高い互換性 - UNIX、Windows、MacOS で動作。
    (Linux 上で開発した cdb を使った検索プログラムや、 スレッド使用の http サーバなどが Windows、MacOSX でも無修正で動いた。)
  • 読みやすいコード、オブジェクト指向、安定動作、豊富なライブラリ。
  • 対話型重視の環境 (オンラインヘルプ、簡易IDE付)
  • 最新バージョンは Python ???. (2004年9月時点では 2.3.4 だったが、現在はもっと上)。
  • ホームページ: http://www.python.org/
  • Python用 IDE 一覧: http://c2.com/cgi/wiki?PythonIde (オープン:7、商用:3、Eclipseプラグイン:1)
  • Python Quick Reference: http://rgruet.free.fr/PQR2.3.html

ソースコード

  • インデントによってブロックを決定する。
  • # はコメント (行末まで)
    #!/usr/bin/env python

    a = 1
    b = 2
    c = a + b

    if c == 3:
    print "correct"
    else:
    print "wrong"

式と演算

  • Python の型:
    • 真理値型 … False、 True [2.3以降、それ以前は 0 と 1 で代用]
    • 整数 … 3
    • 実数 … 3.14159
    • 複素数 … 1+2j
    • 文字列 … "abc"
    • Unicode 文字列 … u"日本語"
    • リスト (配列) … [1, 2, "z", [3,4]]
    • 辞書 (ハッシュ) … {"a":1, "b":2}
    • None型 (null) … None
    • オブジェクト, 関数
    • Perl と違う: 数値型と文字列型は区別される。 3+"5" → エラー
  • 数値演算
    • C, Java とほぼ同じ: +, -, *, /, %, (), **
    • 三項演算子 ? : はない。
  • 代入文
    • 変数を宣言する必要はない。
    • x = 2
    • y += 1 (y++, y--はない)
    • (a,b) = (b,a) 多重代入

文字列型と Unicode 文字列型

  • 文字列型はただのバイト列 (日本語を認識しない)
  • 文字列定数:
    • 'abc'
    • "abc"
    • """abc
      def"""
      (改行を含められる)
    • \ でエスケープ: '\n', '\020', '\x1a', "I'm \"quoted\"."
  • 演算:
    • "abc" + "def" * 3 → "abcdefdefdef"
    • 切り出し: a = "0 p 1 y 2 t 3 h 4 o 5 n 6"
      • a[0] → "p"
      • a[-1] → "n"
      • a[2:4] → "th"
      • a[1:] → "ython"
      • a[:-3] → "pyt"
      • a[2:-1] → "tho"
    • 変更は不可能 (ハッシュのキーに使えるように)
    • "abc" in s (包含の判定)
    • s.strip() → 先頭と末尾の空白・改行を削除した文字列が新たに返される。 (chomp)
    • s.replace("a", "b") → "a" を "b" に置換した文字列が新たに返される。
    • 正規表現は別の枠組みが必要 (→ 後述)
    • %演算子 (sprintf):
      "x=%d, y=%d" % (x,y) → "x=4, y=5"
  • 数値←→文字列の変換:
    • int("123") → 123 / str(123) → "123"
    • chr(65) → "A" / ord("A") → 65 (文字型と文字列型を区別しない)
  • Unicode型
    • 定数は u"abc"、 u"あいうえお" のように書く。
    • 内部表現は Unicode を使い、コーデック (codec) によって 入出力時に Unicode型と文字列型とを相互変換する。
      (日本語codec は http://www.python.jp/Zope/download で配布、 Python2.4 から日中韓国語の codec が標準装備)
    • 文字列型との相互変換: s.encode("shift_jis") → Shift JIS で表現したバイト列。
    • str() でも文字列に変換できる: EUC-JP がデフォルトなら、
      str(u"あ") → '\xa4\xa2' / unicode('\xa4\xa2') → u'あ'
    • ソースコードのエンコーディングは最初のコメントで判定される:
      #!/usr/bin/env python
      # encoding: shift_jis
      print u'この文字列定数はシフトJISとして解釈されます'

制御構造

  • if, for, while だけ。(break, continue)
  • 字下げが必要。
    if a == b:
    print "equal"
    else:
    print "not"

    n = 1
    while n < 100:
    print n
    n *= 2

    for i in [1,2,3,4,5,6,7,8,9,10]: Perl の foreach に相当する
    if i == 5:
    break
    print i
  • 比較演算子: ==, !=, <=, < , >=, >, in
  • Java と違うもの: &&, ||, ! → and, or, not
  • Java にないもの: in

入出力

  • ファイルオブジェクトを操作する:
    • fp = file("/etc/hosts", "r")
    • fp.read(n) → ファイル全部を文字列で返す。
    • fp.readline() → ファイル1行を返す。(終端は '')
    • fp.close()
    • fp2 = file("/tmp/x", "w")
    • fp2.write("write")
  • デバッグ用出力: print (改行する)
    • print x
    • print "x=", x, "y=", y
    • print >>fp, "write" (改行が入るので注意)
    • print "name=%s, age=%d" % (name, age)

例外処理

  • Perl と違う: ちょっとしたことでも頻繁に例外が出るのでキャッチしなければならない。
  • try: ~ except: でキャッチ。
    try:
    fp = file("/etc/nosuchafile")
    except IOError:
    print "cannot open"
  • raise で送出。
  • IndexError, KeyError, ValueError, IOError などがある。
  • 自作のクラスを例外として使用可。

リストと辞書

  • リスト (配列):
    • a = [1,2, "abc", 4]
    • b = [2, [3], [[4], []]]
    • a[0], a[-1], a[2:4], a[1:], a[:-3], a[2:-1] (文字列と同様)
    • a[:] (コピーされたリスト)
    • [1,2] + [3,4] * 2 → [1,2,3,4,3,4]
    • a.append(5) (末尾に要素 5 を追加)
    • a.extend([6,7]) (末尾に要素 6 と 7 を追加 - a.append([6,7]) とは異なる)
    • a.insert(0, 7) (先頭に要素 7 を追加)
    • del a[3] (3番目の要素を削除)
    • a.reverse() (反転、a は上書きされる)
    • a.sort() (ソート、a は上書きされる、自前の比較関数を書くやり方は → 後述)
    • x in y → x が y の要素に含まれているかどうか (線型探索)
    • range(10) → [0,1,2,3,4,5,6,7,8,9] (for で使用)
    • "a b c".split(" ") → ["a", "b", "c"]
    • ", ".join(["a", "b", "c"]) → "a, b, c"
  • 辞書 (ハッシュ)
    • d = {}
    • d = { "a":2, "b":4 }
    • d["a"] = 1
    • del d["a"]
    • "a" in d → "a" が d のキーに含まれているかどうか
    • d["x"] 該当するキーがない場合は KeyError 例外になる。
      try:
      x = d["x"]
      except KeyError:
      print "x is not found"
    • d.get("x", 0)
    • d.keys(), d.values()
    • 文字列以外の型でもキーにできる。(ただし変更不可能であること)

関数定義と呼び出し

  • 関数定義
    def func(x, y, z=0):
    return x*x+y*y+z*z
  • 呼び出し: func(3,4) → 25, func(3,4,5) → 50
  • 関数もオブジェクトである:
    def func(): ...
    print func(3,4,5)
    a = func
    print a(3,4,5)

    def loaddata(): ...
    def savedata(): ...
    def exitit(): ...
    menu = {"load":loaddata, "save":savedata, "exit":exitit}
    f = menu[choice]
    f()

    def mycompare(a,b):
    return cmp(len(a), len(b))
    a = ["abc", "de", "x", "yyyy"]
    a.sort(mycompare)

オブジェクト指向

  • Person オブジェクトの定義:
    class Person:

    # コンストラクタ: Person(name,age)
    def __init__(self, name, age):
    self.name = name
    self.age = age
    return

    def __repr__(self):
    return '' % (self.name, self.age)

    def display(self, out):
    out.write("Name: %s\n" % (self.name))
    out.write("Age: %d\n" % (self.age))
    return

    obj = Person("Shinyama", 29)
    print obj
    obj.age = 30
    obj.display(fp)
  • Java と違う: self が必要! (Java の this に相当する)
  • obj.method(a,b,c) → method の第一引数 self に obj が渡される。
  • コンストラクタ: __init__(self)
  • 文字表現: __repr__(self) デバッグに便利

リスト操作いろいろ

  • 内包表現
    • a = [ n*n for n in range(5) ] → a = [1, 4, 9, 16, 25]
    • ", ".join([ "%s='%s'" % (k, d[k]) for k in d.keys() ])
  • イテレータ (リストのように扱えるがメモリ消費しない)
    • 整数: xrange(1000000)
    • 辞書: dic.iterkeys(), dic.itervalues()
    • ファイル: fp.xreadlines()

ライブラリ (モジュール) を使う

  • モジュールもオブジェクト: 関数や変数を格納した、単なる「でっかいクラス (構造体)」でしかない。
    アクセスする文法はクラスと一緒。
  • import と from:
    import math
    print math.log(2)
    print math.pi

    from math import log
    print log(2)

    (from math import log はじつはこれと同じ)
    import math
    log = math.log

    (正規表現を使う)
    import re
    pat = re.compile("([a-zA-Z]+)=([0-9]+)")
    m = pat.search("a=123")
    print m.group(1), "=", m.group(2)

    (dbファイルを使う)
    import dbm
    mydb = dbm.open("mydb", "n")
    mydb["abc"] = "xyz"
    mydb["123"] = "456"
    mydb.close()
  • dbm、(g)zip、csv、base64、popen
  • http (クライアント/サーバ), ftp, smtp, pop3, imap, ssl 関連
  • htmlパーサ、xmldom、xmlrpc、email 処理

ライブラリ (モジュール) を作る

  • ファイル名 mylog.py は mylog というモジュール名をもつ:
    #!/usr/bin/env python

    import math

    def log2(x):
    return math.log(x) / math.log(2)

    if __name__ == "__main__":
    print "log2(10)=", log2(10)
  • 使い方 :
    import mylog
    print mylog.log2(10)
    from mylog import log2
    print log2(10)
  • モジュール中のすべての文は実行され、def で関数定義される。
  • mylog.py が直接実行された場合、if __name__ == "__main__": の中が実行される。
  • ディレクトリもまた構造体と同じ扱い。mylibs/mylog.py 中にある log2 という関数 (または変数) は mylibs.mylog.log2 という名前でアクセスできる。
  • モジュール探索時に環境変数 PYTHONPATH をさがす。

すてきな機能

  • 補完機能 (tab)
  • オンラインヘルプ
    >>> import urllib
    >>> help(urllib)
    ...
    >>> help(urllib.urlopen)
    ...
  • pickle - オブジェクトを文字列表現に変換、ファイルに保存できる。
  • Tkinter - プラットフォーム独立の GUI
    import Tkinter

    def action1():
    print "boo!"
    b = Tkinter.Button()
    b["text"] = "Hit Me"
    b["command"] = action1
    b.pack()
    Tkinter.mainloop()
  • Jython - Java で動く Python 実装。Java のライブラリが使える。じつは CPython より速い
    from java.applet import Applet

    class HelloWorld(Applet):
    def paint(self, g):
    g.drawString("Hello from Jython!", 20, 30)
  • IronPython - .NET 上の実装。これも CPython より速い

結論

  • web クローラ: 100~500行
  • 形態素解析器: 150行
  • sample.py
  • Total Cost of Development: Python + Java <>

Monday, November 24, 2008

Flash Chart

http://www.amcharts.com/

Monday, September 29, 2008

Blogger Source Code Wedget

http://code.google.com/p/syntaxhighlighter/wiki/Configuration
http://fazibear.googlepages.com/blogger.html
http://www.kuribo.info/2008/06/blogger-syntax-highlighter.html

Source code syntax highlight box example:


class first {
}


You can display multiple programming language syntax with this widget.
1. open the following page http://fazibear.googlepages.com/blogger.html, and click "add widget" button to add the widget to your blogger.
2. edit your post make all the source code around with

<pre name="code" class="your language i.e. java">
your source code, but remember to replace all < > to & lt ; & gt ;
<pre>


the following languages are supported.

c
c++
c#
css
delphi
html
java
js
pascal
php
python
ruby
sql
vb
xml


the following options are also available.

nogutter Will display no gutter.
nocontrols Will display no controls at the top.
collapse Will collapse the block by default.
firstline[value] Will begin line count at value. Default value is 1.
showcolumns Will show row columns in the first line.

The options are passed together with the alias and are separated by a colon : character.


<pre name="code" class="html:nocontrols:firstline[10]">
... some code here ...
</pre>

Wednesday, July 2, 2008

Google社の基盤技術「MapReduce」についてエンジニアに聞く

http://techon.nikkeibp.co.jp/article/NEWS/20080627/154025/

Google社の基盤技術「MapReduce」についてエンジニアに聞く
ソフトウエア OS インタフェース ゲーム データベース サーバ ファイル・システム オープンソース 通信 ネットワーク 企業・市場動向 教育 コンテンツ デジタル家電 ブラウザ 大学 実装
2008/06/27 17:11


Senior Software EngineerのChristophe Bisciglia氏

 米Google Inc.で大規模並列プログラミングの教育コース「Academic Cluster Computing Initiative(ACCI)」の立案者であるSenior Software EngineerのChristophe Bisciglia氏に,インタビューする機会を得た。Bisciglia氏は現在,中国・上海でサービスの開発に携わっている。

――Googleのサービスを支える技術として,ACCIで教えているのは何か。
Christophe Bisciglia氏 並列処理のプログラミング/モデルである「MapReduce」と分散ファイル・システムである「GFS(Google File System)」だ。これらを実装した「Hadoop」というオープンソースのソフトウエアを教材に使っている。

――並列プログラミングとなると,習得が難しいのでは。
Christophe Bisciglia氏 対象は大学3~4年生で,それほど難しいものじゃない。MapReduce自体は単一のマシンでも動作する。モデルとして,それがスケールすることを保証できるというものだ。

――しかし,MapReduceがベースとする関数型プログラミング・モデルは,決して単純じゃなくて習得もしにくい。
Christophe Bisciglia氏 確かにMapReduceは,関数型プログラミングからヒントを得ている。しかしMLやSchemeみたいな関数型言語ではない。GUIなどにオブジェクト指向プログラミングが向くように,ものすごい量のデータを処理するのに向いた方式だ。大量のデータから適切なものを取り出したり,合成したりする場面に関数型プログラミングを適用した。
 MapReduceを使うことで,複雑な処理は開発者から見えなくなる。例えばインデクスの作成過程では,それぞれの言葉をキー,値をURLとした「キーと値」のペアを作る。それぞれのペアは独立していて,ほかのペアと依存関係がない。だから同時並列に処理ができる。これがMapフェーズで起きることだ。ReduceフェーズではこうしたMapフェーズで作ったデータをまとめる作業を実施する。

――そうするとReduceフェーズは,並列化しにくいのでは。
Christophe Bisciglia氏 その通りだ。Reduceフェーズでも並列化の恩恵を受けるのは,例えば検索のリクエストが複数あれば,それぞれのReduceフェーズが独立した存在になることだ。典型的な処理の場合,Mapフェーズの方が作業量が多い。だからReduceフェーズの並列性が低くても,バランスがとれている。

――インデクス作成以外ではどのようなアプリケーションがあるのか。
Christophe Bisciglia氏 ログ作成やWebアプリケーションなども向いている。GoogleDocsなどを考えれば,個々のユーザーの操作は独立しているからね。基本は大量のデータを保存するプロセスや,データを取り出す処理が向いている。そういう意味では,センサ・ネットワークなどの処理にも向くだろう。交通量データや風速データなど,大量のデータから意味を取り出す作業は依存関係が存在しないからだ。逆に言えば,リレーショナル・データベースの処理などはスケールさせにくい。

――スケールがしにくいということは,クラウド・コンピューティングに向かないということにならないか。
Christophe Bisciglia氏 クラウド・コンピューティングはMapReduceによる大量のデータ格納/合成プロセスと,AjaxによるWebベースのインタフェースでデータを入力するという組み合わせで成り立っている。ほとんどのアプリケーションはクラウド・コンピューティングに移行できるだろう。
 クラウド・コンピューティングには,複数ユーザーが共同作業をするためのプラットフォームになるという,ローカルだけの処理にはない魅力がある。例えば「Google Docs」は,一つの文書を複数ユーザーで編集できる。新しいデバイスやOSに対応するのも容易だ。Webブラウザーさえあればよいのだから。
 ただグラフィックス処理を大量に必要とするタイプのゲームなどを,クラウド・コンピューティングで実現するのは難しいだろう。ゲームと言っても,最近流行しているMMORPG(Massively Multiplayer Online Role-Playing Game)のようなものはクラウド・コンピューティングに向く。ゲームの大半はクラウド・コンピューティングで実現可能だ。既に,5年前には考えられなかったような多くのアプリケーションがクラウド・コンピューティングで動いている。

――Google File Systemはどうやって並列性を確保しているのか。
Christophe Bisciglia氏 ファイル・システムのメタデータを管理する「マスター」と,実データを管理する「チャンク・サーバー」に分かれている。ファイルをブロック単位で分けて,マスターがどのチャンク・サーバーにそのブロックを割り当てているかを管理する。ブロックのサイズは64Mバイトで,大体3~4個のサーバーに複製を置く。マスターも複製を作る。一見するとマスターにリクエストが集中しそうなモデルだが,マスター・サーバーの処理時間は短く,たいした負荷にはならない。

――最近Google社が提供を始めたアプリケーション・ソフトウエアの基盤サービスである「Google App Engine」は,GFSとMapReduceを組み合わせて実現しているのか。
Christophe Bisciglia氏 基本的にはGoogle App EngineはデータAPIだ。大きなテーブルを大量のユーザーがアクセスできるスケーラビリティを確保する。ローレベルのファイル・システムにはGFSを使っている。

Monday, June 2, 2008

Open Ajax Alliance:Successful Deployment of Ajax and OpenAjax

http://www.openajax.org/whitepapers/Successful%20Deployment%20of%20Ajax%20and%20OpenAjax.php
Open Ajax Alliance - the Ajax standardization organization