12012010 Python
昨日よくわからなかったので
d = [2007, 8, 1]
datetime.date(d[0], d[1], d[2])
と書いたのだけど
datetime.date(*d)
でいいのね。
12012010 Python
昨日よくわからなかったので
d = [2007, 8, 1]
datetime.date(d[0], d[1], d[2])
と書いたのだけど
datetime.date(*d)
でいいのね。
12012010 Python matplotlib
前週末から風邪がひどくて、会社を休んで寝ている。今日は多少ボーっとするけど昨日よりはずっと楽なので蒲団の中でノートパソコンと戯れたり。で、この前の血圧管理のグラフ化をやってみた。はてなのグラフを二つ重ねるというのは僕も考えたんだけど、CUIから
mybp -b 142,88
とか
mybp -b 142,88 -d 2007-07-31
とタイプするだけのほうがなんとなく長続きしそうだし(今までの経験から)。とここまでエントリを書いたところで、はてなグラフでそんなのやってるの思い出した。
むむーですよ。ま、pythonで書きたかった+綺麗なグラフが好きだった、、、ということで、書いたのはココ。
O/RマッパはSQLObjectで。クラスを定義したら、
class BloodPressure(SQLObject):
sbp = IntCol()
dbp = IntCol()
date = DateCol(default=datetime.date.today(), unique = True)
createTableメソッド呼ぶ
BloodPressure.createTable()
これで、実際にテーブルつくってくれるのでSQL文考えなくてよいし、テーブル作り直したいときにもdb消してもう一度createTableメソッド呼べばいいので心理的にも楽。
matplotlibは昨日書いたのを。データが少ないと目盛りがおかしいけど、1週間も続ければきちんとなるでしょう。
それにしても僕の血圧やたら高いなぁ。困った困った。
あとoptparseで固定引数の処理の仕方がよくわからなかったのだけど、パスワード生成スクリプトをきっかけにoptparseを使ってみましたを眺めたら解決した。
(options, args) = parser.parse_args()
ここのargsに固定引数が入ってんのね。
12012010 Python matplotlib
pythonのグラフ描画ライブラリであるmatplotlibで日付ごとにプロットするサンプル。
from pylab import *
from matplotlib.dates import MONDAY, WeekdayLocator
import datetime
start_date = datetime.date(2007, 5, 1)
end_date = datetime.date.today()
delta = datetime.timedelta(days=1)
mondays = WeekdayLocator(MONDAY)
dates = drange(start_date,end_date,delta)
s = rand(len(dates)) + 85
t = rand(len(dates)) + 80
fig = figure()
ax = fig.add_subplot(111)
ax.plot_date(dates, s, 'r--')
ax.plot_date(dates, t, 'bo-')
ax.xaxis.set_major_locator(mondays)
ax.autoscale_view()
ax.grid(True)
fig.autofmt_xdate()
title('My Blood Pressure')
xlabel('Date')
ylabel('Blood Pressure')
fig.savefig('datetest')
12012010 Python matplotlib
matplotlibを0.91.1にあげたら
NameError: name 'gtk' is not defined
とかでて動かなくなった。仕方ないのでsvnのrev4730を入れたら動いたけど、それでも
libpng: 1.2.22
Tkinter: Tkinter: 50704, Tk: 8.4, Tcl: 8.4
wxPython: 2.8.4.0
* WxAgg extension not required for wxPython >= 2.8
Gtk+: no
* pygtk present but import failed
Qt: Qt: 3.3.8, PyQt: 3.17.3
Qt4: no
Cairo: 1.4.0
となっている。pygtkは入ってんのになー
ビット演算を利用したアルゴリズム。Shift-ADDと違いdifference,insertion,deletionを考慮する。
可能性を論理和として積み上げていってShift-ORみたいなアプローチで評価するとこだと思う。いまいちちゃんと理解できてないが。
for j in range(1,k+1):
s[j] = (r[j] << 1) & Tc
s[j] |= (r[j-1] | s[j-1]) << 1
s[j] |= r[j-1]
s[j] |= 1
あと、perlで@a = @bとやれるところがpythonではa=bとできず、 b = copy.copy(a)なのね。
#!/usr/bin/env python
import copy
def amatch (T,P,k=-1):
text_length = len(T)
pattern_length = len(P)
po2 = map(lambda(x): 1 << x,range(31))
if k == -1: k = int(pattern_length/10) + 1
Table = [0] * 256
for i in range(pattern_length):
Table[ord(P[i])] |= po2[i]
r = [0] * (k+1)
for i in range(1,k+1):
r[i] = r[i-1] | po2[i-1]
mb = po2[pattern_length-1]
s = [0] * (k+1)
for i in range(text_length):
s[0] <<= 1
s[0] |= 1
Tc = Table[ord(T[i])]
s[0] &= Tc
for j in range(1,k+1):
s[j] = (r[j] << 1) & Tc
s[j] |= (r[j-1] | s[j-1]) << 1
s[j] |= r[j-1]
s[j] |= 1
if s[k] & mb:
return i - pattern_length + 1 if i > pattern_length else 0
r = copy.copy(s)
return -1
if __name__ == '__main__':
print "match: ", amatch("pearl","perl",1)
これもビット演算を利用したアルゴリズム。differenceを許容するけどinsertion,deletionは駄目。
#!/usr/bin/env python
from math import *
def shift_ADD (T, P, k=-1):
text_length = len(T)
pattern_length = len(P)
if k == -1: k = int(log(text_length)+1)
if k == 0: return T.find(P)
if pattern_length == 1: return T.find(P)
if pattern_length > text_length: return -1
if pattern_length == text_length and P == T: return 0
bits = int(log(k+1,2)) + 1 # ????
mask = 1 << ( bits - 1 )
ovmask = 0
for i in range(pattern_length):
ovmask |= mask
mask <<= bits
table = [ovmask >> (bits-1)] * 256
nmask = 1
for i in range(pattern_length):
table[ord(P[i])] &= ~nmask
nmask <<= bits
mask = ( 1 << ( pattern_length * bits )) -1
state = mask & ~ovmask
ov = ovmask
watch = ( k + 1 ) << ( bits * ( pattern_length - 1 ) )
for i in range(text_length):
state = ((state << bits) + table[ord(T[i])]) & mask
ov = ((ov << bits) | (state & ovmask)) & mask
state &= ~ovmask
if (state | ov) < watch:
return i - pattern_length + 1
return -1
if __name__ == '__main__':
print shift_ADD("perlpethonxx","python",2)
12012010 Python
int("101111",2)とかやると2進数の表現を10進数にできるということが分かったんだけど、逆に10進数で47を与えられたら101111といった2進数表現にするやり方がわからなかった。
Shift-ORのコード書いてるときに15って01111だよな~、5って00101だっけ?とか脳内変換はちょっと疲れた。4 | 1とか7 & 4とかいう脳内ビット計算も疲れる。
Shift-ORってのはshiftしてORとって、どんどこどんどこと0を左送りにしていって最後まで0送りできた場合にパターンマッチ成功。最後がマッチしたかどうかは補数(一番左が0で残りが1)のANDをとって0が帰ってくるかどうかで判断するという文字列検索アルゴリズム。
#!/usr/bin/env python
def shift_OR_exact (T,P):
text_length = len(T)
pattern_length = len(P)
if pattern_length > text_length: return -1
if pattern_length == text_length: return 0
if pattern_length == 1: return T.find(P)
m1b = (1 << pattern_length ) -1
table = [m1b] * 256
mask = 1
for i in range(pattern_length):
table[ord(P[i])] &= ~mask
mask <<= 1
watch = 1 << ( pattern_length - 1 )
for i in range(text_length):
i = T.find(P[0],i)
if i == -1: return -1
state = m1b
while i < text_length:
state = ( state << 1 ) | table[ord(T[i])]
if ( state & watch ) == 0:
return i - pattern_length + 1
if state == m1b: break
i += 1
return -1
if __name__ == '__main__':
print shift_OR_exact("perlpypythonruby","python")
iKnow の進捗を Python で取得するというエントリをみつけたので、さらにmatplotlibでグラフ書くようにしてみた。これを一日の終わりにcronで実行すれば記録できる。
#!/usr/bin/env python
import urllib
from BeautifulSoup import BeautifulSoup
import re
from sqlobject import *
from pylab import *
from matplotlib.dates import MONDAY, WeekdayLocator
import datetime,os
# --- Configure --- #
mydb = '/home/kzfm/iknow.db'
mygraph = '/var/www/html/images/lf/iknow'
myname = 'kzfm'
myconnect = 'sqlite://' + mydb
sqlhub.processConnection = connectionForURI(myconnect)
class RecKnow(SQLObject):
iknow_study = IntCol()
iknow_finish = IntCol()
dictation_study = IntCol()
dictation_finish = IntCol()
date = DateCol(default=datetime.date.today(), unique = True)
class Iknow:
def __init__(self,username):
b = BeautifulSoup(urllib.urlopen("http://www.iknow.co.jp/user/"+username))
iknow = b.find('div',id="study_badge_div").find('script').string
self.iknow_study = int(re.search(r"int_left.*?(\d+)", iknow).group(1))
self.iknow_finish = int(re.search(r"int_right.*?(\d+)", iknow).group(1))
dictation = b.find('div',id="dictation_badge_div").find('script').string
self.dictation_study = int(re.search(r"int_left.*?(\d+)", dictation).group(1))
self.dictation_finish = int(re.search(r"int_right.*?(\d+)", dictation).group(1))
def create_graph():
iknow_study = [i.iknow_study for i in RecKnow.select()]
iknow_finish = [i.iknow_finish for i in RecKnow.select()]
dictation_study = [i.dictation_study for i in RecKnow.select()]
dictation_finish = [i.dictation_finish for i in RecKnow.select()]
dates = [date2num(i.date) for i in RecKnow.select()]
mondays = WeekdayLocator(MONDAY)
fig = figure(figsize=(9,5))
ax = fig.add_subplot(111)
ax.plot_date(dates, iknow_study, 'co-')
ax.plot_date(dates, iknow_finish, 'mo-')
ax.plot_date(dates, dictation_study, 'yo-')
ax.plot_date(dates, dictation_finish, 'ko-')
ax.xaxis.set_major_locator(mondays)
ax.autoscale_view()
ax.grid(True)
fig.autofmt_xdate()
title('iKnow Daily chart')
xlabel('Date')
ylabel('Score')
legend(["iKnow study", "iKnow finished", "dict study", "dict finished"])
fig.savefig(mygraph)
if __name__ == '__main__':
if not os.path.isfile(mydb):
RecKnow.createTable()
iknow = Iknow(myname)
RecKnow(iknow_study=iknow.iknow_study,iknow_finish=iknow.iknow_finish,
dictation_study=iknow.dictation_study,dictation_finish=iknow.dictation_finish)
create_graph()
12012010 Python
今朝Amazonから届いたので早速読んだ。
そして一通り流し読みした感想としては、Pythonがはじめての言語で、Webアプリまで作れるようになりたいと考えているヒトには最強な選択肢かもしれんなーと。
HTTPサーバー構築からはじまって、CGIで、ほらーHTMLとコードが混在して読みにくくなっちまうだろ、だからここでTemplateシステムが出てくんだよとか、Webのシステムはデータベースが必要でSQLとか使うとさくさく感の流れが途切れるし気持ち悪いじゃろ、そこでO/Rマッパーの出番なんだぜといった、MVCフレームワークに至るまでの過程がスマートに追っかけられる内容ですな。
もし、コードが書けない人員がアサインされたら、みんなのPythonとWebアプリ編をセットで渡して、これ読んどけって言う、間違いなく。
僕は、みんなのPython Webアプリ(上級)編みたいなものをイメージして予約してしまったのでちょっと予想と違ったかなと。Appendixにあるような内容を深く掘り下げてるのかなと思ったんだけど、さすがにみんなのPythonの続編でそれはないかと。
年末にでもちゃんと手を動かしながら、がつっと読みますヨ。