2008年9月11日木曜日

batの威力

Windowsのコンソールでスクリプト走らせると、どうしてもスクリプト内で完結してしまいがち。
(pythonだとos.walkとかでフォルダの中を走査したり)

でも、bat使って連続してファイル読み込ませると、状況見ながらリファクタリングできることに気がついた。
なんかボトルネックになってるところを発見したときに、そこを直すと、次に実行されるときには治ったやつが実行されるので便利。

for %%A in (%1) do python hoge.py < %%A
とか覚えとくと便利。

for %%A in (%2) do %1 < %%A
は、うっかり変なコマンド走らせて吃驚したのでやらない方が良さそう。

2008年9月9日火曜日

PythonでSQLiteを使う(データを書き込む)

・データを書き込む

カーソルを作成したので、データベースにテーブルを作る準備ができました。テーブルの作成には、必要なステートメントを入れて、カーソルからexecuteメソッドを呼ばなければなりません。名前(name)とメアド(email)を保存するテーブルを作ってみましょう。ついでに、それぞれの列(row)に、ユニークな番号を振るようにもしてみましょう:

>>> cursor.execute('CREATE TABLE names (id INTEGER PRIMARY KEY, name VARCHAR(50), email VARCHAR(50))')

これでテーブルが出来ました。同様にして、データの追加もexecuteメソッドで行うことが出来ます:

>>> cursor.execute('INSERT INTO names VALUES (null, "john Doe", "jdoe@jdoe.zz")')
>>> cursor.execute('INSERT INTO names VALUES (null, "Mary Sue", "msue@msue.yy")')

カーソルから、最後に登録した列(row)番号を得ることも出来ます。たぶん必要でしょう:

>>> cursor.lastrowid
2

そうそう、「ユーザの入力に応じてデータベースに入れたい」と言うでしょ。明らかに、ユーザの入力はそのままでは危ないです。悪意あるユーザは、簡単にクエリーを操ってデータベースに通せるし、深刻なダメージをデータベースに与えることが出来ます。これは許容できません。でも、ありがたいことにpysqliteにはセキュリティを確保する手段があります。ある人の名前(name)とメアド(email)を、2つの変数で持っているとしましょう:

>>> name = "Luke Skywalker"
>>> email ="use@the.force"

このとき、(自分たちで定義したんだから)これらはまあ安全です。でも、いつもそうだとは言えないでしょう。安全なクエリーに変数を入れたい時は、単にその場所にクエスチョンマークを入れればいいだけです。すると、pysqliteが残りをやってくれます(paramstyleを参照のこと):

>>> cursor.execute('INSERT INTO names VALUES (null, ?, ?)', (name, email))

今、私たちは変更を加えたので、保存しなければなりません。(もしくは、データベースに変更を通知しなければなりません)これには、コネクションのcommitメソッドを呼び出します:

>>> connection.commit()

もしも、変更したにもかかわらずcommitを呼ばず、コネクションを閉じようとすると、pysqliteはエラーを返すでしょう。こういう行動は、トラブルのもとになります。でも、やってしまった変更を保存したくないときもあるでしょう。そんなときは、rollbackメソッドを使います。(色々保存せずに電源を切るというやり方もありますけど)例えば、もう一列テーブルに加えるとしましょう:

>>> cursor.execute('INSERT INTO names VALUES (null, "Bobby John", "bobby@john.qq")')

この変更を無かったことにしたい、としましょう。我々は単にrollbackメソッドを呼べば良いのです:

>>> connection.rollback()

ほら、これで変更は消えました。
次のステップでは検索をしてみましょう。

2008年8月12日火曜日

パノラマ写真に関して

単一のレンズで全方位を映せるレンズをオリンパスが出してるが、これからはいろんなレンズで撮った画像を1枚にまとめられる技術の方が重要なのではないだろうか。
その手の技術は、技術者には普通のことなんだろうけれども、あんまりよく知らなかったので調べてみよう。

パノラマ写真をつくる
技術としてのSIFTに関して

・パノラマ写真を作るで紹介されているソフト
  1. autopano-sift
  2. hugin
  3. Enblend
説明をざっと見た感じでは、autopano-siftで特徴点の算出、huginで画像の変形、Enblendで画像の合成を行っているようだ。
何れもLinux版、Windows版ともにある。フリーでこういうものが開発されてるのはすごいなあ。見習いたい。
SIFTとか画像処理の根幹の部分は、こらからさらに重要になってくるような気がする。音声処理も。素人が処理できるレベルまでPCのスペックが上がってきてるので楽しそう。データマイニングも面白そうだし。

2008年7月15日火曜日

javascriptでクロージャ

クロージャとか、無名関数とか、引数として関数を渡すとか、javascriptって色々できるな。
難しそうだからさわってなかったけど、その場だけでごりごり書くときに便利そう。


/* New document created: 6.2.2008 18:34:27 */

function map(fn, a)
{
for (i = 0; i < a.length; i++)
{
a[i] = fn(a[i]);
}
}

function reduce(fn, a, init)
{
var s = init;
for (i = 0; i < a.length; i++)
s = fn( s, a[i] );
return s;
}

function sum(a)
{
return reduce(function(x, y){ return x+y; }, a, 0);
}

function cntYear(x) //Closure
{
var i = 0;
return function()
{
i = i + 1;
return x + i;
}
}

var a = [1, 2, 3];
map( function(x){return x*2;}, a );
map( alert, a );

years = new Array(400);
map( cntYear(2008), years );
map( function(x){ if(x%400==0 || x%100!=0 && x%4==0){return 1;}else{return 0;} }, years);
alert(sum(years));

2008年7月7日月曜日

13日は何曜日が多い?

13日の金曜日を見ていて「金曜日が最も多い」というが気になって確認してみた。


import calendar

MON, TUE, WED, THU, FRI, SAT, SUN = 0, 1, 2, 3, 4, 5, 6
dict = {MON:0, TUE:0, WED:0, THU:0, FRI:0, SAT:0, SUN:0}
for y in range(2008, 2408):
for m in range(1, 13):
w = calendar.weekday(y, m, 13)
dict[w] = dict[w] + 1
print dict

実行すると、以下のような結果に。
http://codepad.org/MuBsSX7M

{0: 685, 1: 685, 2: 687, 3: 684, 4: 688, 5: 684, 6: 687}

金曜日が688回、水・日が687回、月・火が685回、木・土が684回と言う結果に。

2008年7月2日水曜日

pythonでtwitterクライアント。コマンドプロンプト版。

作ったやつを張っとこう。
ざっくり判った。twitterのAPIは簡単で判りやすい。json便利。


Windowsならではの小細工が。
でもこれcmdで立ち上げとくと便利。メモ代わりにどんどん書き込める。

# -*- coding: utf-8 -*-

'''
twitter
friends timeline post
'''
import urllib, urllib2
import json
import calendar
import time
import sys

toplevel_url = 'twitter.com'
target_url = 'twitter.com/statuses/update.json'
protocol = 'http://'
proxy = {'http':'http://hogehoge.com:80/'}
username = 'hogehoge@gmail.com'
password = 'xxxxx'

proxy_handler = urllib2.ProxyHandler(proxy)
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, toplevel_url, username, password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(proxy_handler, authhandler)
urllib2.install_opener(opener)

def twitter_post(text):
params = urllib.urlencode({'status':text.encode('utf8')})
#print params
urllib2.urlopen(protocol + target_url, params)

def twittertime2time(created_at):
unix_time = calendar.timegm(time.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'))
return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(unix_time))

while ( True ):
utext = raw_input('What are you doing?: ')
text = unicode(utext, 'mbcs')
twitter_post(text)



毎分チェックに行く方

# -*- coding: utf-8 -*-

'''
twitter
friends timeline loop_get
'''

import urllib2
import json
import calendar
import time
import shelve, sha

SLEEP_TIME = 1 * 60
HISTORY_FILE = 'tw.log'
toplevel_url = 'twitter.com'
target_url = 'twitter.com/statuses/friends_timeline/screen_name.json'
protocol = 'http://'
proxy = {'http':'http://hogehoge.com:80/'}
username = 'hogehoge@gmail.com'
password = 'xxxxxxx'

proxy_handler = urllib2.ProxyHandler(proxy)
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, toplevel_url, username, password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(proxy_handler, authhandler)
urllib2.install_opener(opener)

def twittertime2time(created_at):
unix_time = calendar.timegm(time.strptime(created_at, '%a %b %d %H:%M:%S +0000 %Y'))
return time.strftime("%b %d %H:%M:%S", time.localtime(unix_time))
#return time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(unix_time))

def memory_log(time, text):
FLG = True
log = shelve.open( HISTORY_FILE )
s = sha.new( text.encode('utf-8') )
if ( not log.has_key( s.digest() ) ):
log[ s.digest() ] = time
FLG = False
log.close()
return FLG

def print_twitt(contents):
for content in contents:
if ( not memory_log(content['created_at'], content['text']) ):
print twittertime2time(content['created_at']), content['user']['screen_name'], content['text']

while ( True ):
pagehandle = urllib2.urlopen(protocol + target_url)
json_contents = pagehandle.read()
contents = json.read(json_contents)
print_twitt(contents)
time.sleep( SLEEP_TIME )
print '.',

ベリサインは何を見てる?

公開鍵証明書について調べてるときに、気になった。
有名なベリサインは何を持って証明書を発行するのか。
発行先を確かにその発行先だと証明するために何を調査するのか。
それは、結構クリティカルな部分じゃないのかなあ。

で、結局第三者がまとめたデータベースから、その会社の代表電話番号を持ってきて、そこにかけると。
で、技術担当者に電話で確認すると。
後は、登記事項証明書を郵送することで確認する。
(法人じゃないと、士には出してるらしい。弁護士とか)その場合、証明するのは印鑑証明。

つまり
1.第三者がまとめたデータベースの電話番号と、実際の企業電話番号との一致
2.申請書と、技術担当者の在籍&申請意志との一致
3.登記事項証明書(or 印鑑証明)による申請者の身分保証
の3点で確認してるわけだ。

つまり、攻撃は2点必要。
1.第三者(帝国データバンクっぽい)のデータベース
2.登記事項証明書(or 印鑑証明)
両方が攻撃できれば、その本人でなくても証明書を発行してもらえる。


…気がついたときの証明書無効の方法も調べておかないとなあ。
参考:
名古屋工業大学大学院おもひ領域 情報工学専攻 岩田研
.p12の証明書が流出するとなりすまされるとかベリサインが書いてて何言ってんだろうと思ったけど、
証明書に秘密鍵がくっついてるファイルなんてのがあるのね。ということが一覧で判って便利。