wxHTMLのメモ
#!/usr/bin/local/python # -*- coding: utf-8 -*- import sys import os import wx import wx.html from wx import xrc class MyApp(wx.App): def OnInit(self): self.frame = wx.Frame(None, -1, "test") sizer = wx.BoxSizer( wx.VERTICAL ) self.main_wnd = wx.html.HtmlWindow( self.frame, wx.ID_ANY) sizer.Add(self.main_wnd, 1, wx.ALL|wx.EXPAND, 5) self.frame.SetSizer( sizer) self.frame.Layout() self.main_wnd.SetPage("<h1>ERRO</h1>") self.frame.Show() return True def OnExit(self): pass if __name__ == "__main__": app = MyApp() app.MainLoop()
RGB->L*a*b*変換
とりあえずメモ
RGB2XYZ_D65 = ( 0.412453, 0.357580, 0.180423, 0.212671, 0.715160, 0.072169, 0.019334, 0.119193, 0.950227 ) D65 = ( 0.950456, 1., 1.088754 ); _coff = ( RGB2XYZ_D65[0]*(1.0/D65[0]),RGB2XYZ_D65[1]*(1.0/D65[0]),RGB2XYZ_D65[2]*(1.0/D65[0]), RGB2XYZ_D65[3]*(1.0/D65[1]),RGB2XYZ_D65[4]*(1.0/D65[1]),RGB2XYZ_D65[5]*(1.0/D65[1]), RGB2XYZ_D65[6]*(1.0/D65[2]),RGB2XYZ_D65[7]*(1.0/D65[2]),RGB2XYZ_D65[8]*(1.0/D65[2]), ) def _conv_func(v): if v > 0.008856: return v ** (1.0 / 3.0) else: return (903.3 * v + 16 ) / 116.0 def rgb2lab(rgb): rgb = [x/255.0 for x in rgb] xyz = ( rgb[0]*_coff[0] + rgb[1]*_coff[1] + rgb[2]*_coff[2], rgb[0]*_coff[3] + rgb[1]*_coff[4] + rgb[2]*_coff[5], rgb[0]*_coff[6] + rgb[1]*_coff[7] + rgb[2]*_coff[8], ) fX, fY, fZ = map(_conv_func, xyz) L = 116.*fY - 16.; a = 500.*(fX - fY); b = 200.*(fY - fZ); return (L, a, b)
JavaScriptでデフォルト引数を使う
最近、JavaScriptを使うことになったので勉強中。
デフォルト引数が使いたいなと思いググったところ、下のコードが沢山ヒットする。
def test(a) { a = a || デフォルト値 ... }
え、これってデフォルト引数が0やFalseの場合ダメだよね・・・?
正しくはこうだと思うんだが・・・
def test(a) { if(a === undefined) a = デフォルト値; ... }
「a == undefined」ではなく「a === undefined」なので注意。
JavaScriptに詳しい方で、修正がありましたらご指摘ください。
[追記]
コメントから指摘がありました。
上記の方法だとundefinedが上書きされている可能性があるので、厳密に求めたい場合は以下の方法が良さそうです。
def test(a) { if(typeof a === 'undefined') a = デフォルト値; ... }
上記の方法からタイプ量もそんなに増えない為、かなり良い方法だと思います。
edvakfさん、ありがとうございました。
Windowsを再起動/終了/スリープ/休止状態にする
再起動/終了
import os #Windowsの再起動 os.system('shutdown -r -f') #Windowsの終了 os.system('shutdown -s -f')
スリープ/休止状態
import ctypes #Windowsのスリープ ctypes.windll.PowrProf.SetSuspendState(0, 1, 0) #Windowsの休止 ctypes.windll.PowrProf.SetSuspendState(1, 1, 0)
文字列のcsvを解析する方法
csvモジュールはcsvファイルしか解析できないと思われがちだが、メモリ上のcsvを解析する事も可能。
一番簡単な方法は、以下の通り。
import csv for row in csv.reader(['one,two,three']): print row # ['one', 'two', 'three']
複数行の文字列も解析可能。
import csv csv_str = """ one,two,three four,five,six """ for row in csv.reader(csv_str.strip().splitlines()): print row #['one', 'two', 'three'] #['four', 'five', 'six']
但し上の方法だと、フィールドが複数行の場合は改行が削除されてしまう。
改行を保持したまま解析したい場合はStringIOを使う。
import csv csv_str = """ one,two,three four,five,"six seven" """ for row in csv.reader(csv_str.strip().splitlines()): print row # Bad #['one', 'two', 'three'] #['four', 'five', 'sixseven'] #改行を保持したい場合は、StringIOを使う import StringIO for row in csv.reader(StringIO.StringIO(csv_str.strip())): print row # Good #['one', 'two', 'three'] #['four', 'five', 'six\nseven']
小技
Excelからセルをコピペするとタブ区切りになる。
タブ区切りに対応する場合はcsv.reader()の第2引数にcsv.excel_tabを指定すると簡単。
import csv import StringIO csv_str = """ one\ttwo\tthree four\tfive\tsix """ for row in csv.reader(StringIO.StringIO(csv_str.strip()), csv.excel_tab): print row
おまけ
csv.Sniffer.sniff()を使うと、csvの区切り文字などをpythonが推測してくれる。
外部のCSVの形式が不定の場合に使えるかも。
import csv import StringIO csv_str = """ one\ttwo\tthree four\tfive\tsix """ io = StringIO.StringIO(csv_str.strip()) try: #サンプルを元に区切り文字を推測する dialect = csv.Sniffer().sniff(io.readline()) except: dialect = csv.excel io.seek(0) for row in csv.reader(io, dialect): print row #タブ区切りだと推測成功 #['one', 'two', 'three'] #['four', 'five', 'sixseven']
区切り文字がある程度決まっている場合は、sniff()の第2引数に区切り文字の候補を与えてあげると精度が上がる。
# 区切り文字がタブかカンマの2択の場合は以下の通り dialect = csv.Sniffer().sniff(io.readline(), "\t,")
SCons入門(3)
SCons入門(1) - Pashango’s Blog
SCons入門(2) - Pashango’s Blog
ファイル/ディレクトリ操作「Copy,Move,Delete,Touch,Mkdir,Chmod」
SConsではファイル/ディレクトリ操作用に以下の関数が用意されている。
Copy(dst, src) | ファイル/ディレクトリのコピー |
---|---|
Move(dst, src) | ファイル/ディレクトリの移動 |
Delete(tgt) | ファイル/ディレクトリの削除 |
Touch(tgt) | タイムスタンプの更新 |
Mkdir(tgt) | ディレクトリの作成 |
Chmod(tgt, prm) | パーミッションの変更 |
これらの関数は単独では使用できない、Commandなどのアクション部分に組み込んで初めて動作する。
SConstructのサンプルは以下のとおり。
Command("file.out", "file.in", [ Mkdir("tmpdir"), Copy("tmpdir/main.c", "main.c"), "mycommand $SOURCE $TARGET", Move("$TARGET", "tmpdir/$TARGET"), Delete("tmpdir"), Touch("$TARGET"), Chmod("$TARGET", 0755), ])
実行結果は以下のとおり、テンポラリデイレクトリの生成/削除を行い、最後にパーミッションを変更している。
>scons scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... Mkdir("tmpdir") Copy("tmpdir/foo.in", "foo.in") mycommad foo.in foo.out Move("foo.out", "tmpdir/foo.out") Delete("tmpdir") Touch("foo.out") Chmod("foo.out", 0755) scons: done building targets.
SCons入門(2)
ファイル更新チェックの方法を変更する「Decider」
SConsでは、ファイルの更新チェックに標準でMD5を使用する。
そのため、タイムスタンプが異なっていても、ファイル内容が同じであれば不要なビルドを避けてくれる。
MD5で更新チェックは非常に便利なのだが、映像ファイルなどのファイルサイズが大きいものには不向きである。
そこでSConsでは、ファイルの更新チェック方法を「Decider」で設定することができる。
以下、Deciderの設定例。
#MD5で更新チェック(標準) Decider('MD5') #タイムスタンプが新しければ更新 Decider('timestamp-newer') Decider('make') #timestamp-newerの別名 #タイムスタンプが異なっていれば更新 Decider('timestamp-match') #MD5が変更、または、タイムスタンプが新しければ更新 Decider('MD5-timestamp')
もちろん、カスタムの更新チェック関数を設定することも可能。
Program('hello.c') def decide_if_changed(dependency, target, prev_ni): if self.get_timestamp() != prev_ni.timestamp: dep = str(dependency) tgt = str(target) if specific_part_of_file_has_changed(dep, tgt): return True return False Decider(decide_if_changed)
ここで気をつけなければいけないのは、最後に記述された「Decider」が有効になるということ。
以下のようにa.txtは「make」で更新チェック、b.txtは「MD5」で更新チェックしようとしても、後に書かれたDeciderが有効になってしまい2つのファイルともMD5で更新チェックされてしまう。
env = Environment(ENV = os.environ) env.Decider('make') env.Command("a.out", "a.txt", "python my_convert.py $SOURCE $TARGET") env.Decider('MD5') env.Command("b.out", "b.txt", "python my_convert.py $SOURCE $TARGET") #a.txtもb.txtもMD5で更新チェックされてしまう!
複数のDeciderを有効にしたい場合は、Environmentを分ける必要がある。
env_make = Environment(ENV = os.environ) env_md5 = env_make.Clone() env_make.Decider('make') env_md5.Decider('MD5') env_make.Command("a.out", "a.txt", "python my_convert.py $SOURCE $TARGET") env_md5.Command("b.out", "b.txt", "python my_convert.py $SOURCE $TARGET")
出力ファイルをインストールする「Install,InstallAs」
出力ファイルを、指定ディレクトリにコピーするには「Install」または「InstallAs」を使う。
すでにコピー先にファイルがある場合、タイムスタンプなどを考慮して必要があれば上書きする。
#出力ファイルを/usr/binにインストール(コピー)する output = Program('cmd.c') Install('/usr/bin', output) #複数ファイルのインストールも可能 Install('/usr/bin', ['cmd_a', 'cmd_b']) #ファイル名を変えながらインストールする場合はInstallAsを使う InstallAs('/usr/bin/new_cmd', 'cmd')
標準のビルドターゲットを設定する「Default」
SConsでビルドターゲットを省略した場合、標準のビルドターゲットがビルドされる。
「Default」で標準のビルドターゲットを設定する事が出来る。
以下、Sconstructの記述例、「hello.c」と「goodbye.c」の2つのタスクがあるが、「hello.c」を標準のビルドターゲットにする。
hello = Program('hello.c') Program('goodbye.c') Default(hello)
コマンドラインから「scons」と打つと、標準のビルドターゲット「hello.c」だけがビルドされる。
「goodbye.c」は明示的にビルドターゲットを指定しない限り、ビルドされなくなる。
> scons -Q cc -c -o hello.o hello.c cc -o hello hello.o > scons -Q scons: `hello' is up to date. > scons -Q goodbye cc -c -o goodbye.o goodbye.c cc -o goodbye goodbye.o
クリーンされるファイルの制御「Clean,NoClean」
コマンドラインで「scons -c」と打つと、ビルドファイルがクリーンアップされる。
この時、SConsが削除すべきファイルを自動的に調べてくれるのだが、「Clean」で削除するファイル/ディレクトリを追加できる。
Cleanの第1引数は、削除対象ファイルと関連があるビルドターゲット。
第2引数は、追加する削除対象ファイルとなる。
以下の例では、ビルド時に出るlogファイルをクリーン時に削除する例。
a = Program('a.c') b = Program('b.c') Clean(a, 'a.log') Clean(b, 'b.log')
コマンドラインから「scons -c」を打つと、logファイルも削除される。
> scons -c scons: Reading SConscript files ... scons: done reading SConscript files. scons: Cleaning targets ... Removed a Removed a.log Removed b Removed b.log scons: done cleaning targets. #ターゲット指定も可能(この場合はbとb.logは削除されない) > scons -c a scons: Reading SConscript files ... scons: done reading SConscript files. scons: Cleaning targets ... Removed a Removed a.log scons: done cleaning targets.
Clearの第1引数に'all'を指定すれば、ビルドターゲット省略時にクリーンされるようになる。
また「Glob」を使えば、ワイルドカードでファイルを指定できる。
#scons -c の時、workディレクトリも削除する Clean('all', 'work') #logファイルをすべて削除してければGlobを使う Clean('all', Glob('*.log'))
逆にクリーンアップ時に削除して欲しくないファイルなどは「NoClean」で指定する。
例えば「Install」したファイルも標準では削除対象になってしまうので、「NoClean」を使う。
a = Program('a.c') a_inst = Install('/usr/bin', a) NoClean(a_inst)