2015年8月15日土曜日

robocopy

backup
オプション
/Eサブディレクトリをコピー。空のディレクトリもコピーする
/FFTFATファイル時間(2秒の精度)を想定。FATファイルはタイムスタンプを偶数秒単位でしか記録していないためにNTFS - FAT間でファイルコピーをするとタイムスタンプに差が生じる
/R:0コピー失敗時の再試行回数を 0 にする
/MIRディレクトリツリーをミラー化する。/Eと/PURGEを組み合わせたもの
補足
/Eサブディレクトリをコピー。空のディレクトリもコピーする
/PURGEコピー先のファイルとソース内に存在しないディレクトリを削除する
robocopy c:\src c:\dst /FFT /R:0 /MIR

[Python]PyMedia

PyMedia から最新版 (pymedia-1.3.7.3.tar.gz, 2014/08/11時点) をダウンロードする。 ダウンロードしたファイルを解凍する。
$ tar zxvf pymedia-1.3.7.3.tar.gz
必要なライブラリをインストールする。 ライブラリが足りないとビルドする時に下記のように表示される。
$ python setup.py build
Using UNIX configuration...

OGG : not found
VORBIS : not found
FAAD : not found
MP3LAME : not found
VORBISENC : not found
ALSA : not found
Continue building pymedia ? [Y,n]:
依存関係解消できず。(2014/08/11) ビルド
$ python setup.py build
インストール
# python setup.py install

2015年8月14日金曜日

[Python][pyExcelerator]動作確認

次のデータが入った Excel ファイルを準備する
January February March April May June July August September October November December
tokyo 7.0 6.5 9.1 12.4 19.0 23.6 28.0 29.6 25.1 18.9 13.5 9.9
naha 16.8 18.3 19.9 21.2 23.8 26.7 28.7 28.9 28.0 25.7 21.4 18.1
sapporo -2.0 -3.2 -0.1 5.5 12.2 19.2 22.1 24.8 20.0 12.2 5.9 0.6
2 枚目の sheet, 3 枚目の sheet は空、Sheet 名は Sheet2, Sheet3
test00.py
# -*- coding:utf-8 -*-
import pyExcelerator

xlsSheets = pyExcelerator.parse_xls("test00.xls")
# (Sheet 名, シートの中身) というリストで格納される
print xlsSheets
for sheetName, values in xlsSheets:
    print "Sheet name: %s" % (sheetName)
    print "values.keys(): ", sorted(values.keys())
    row = ""
    for rowIdx, colIdx in sorted(values.keys()):
        v = values[(rowIdx, colIdx)]
        print "(%d, %d): %s" % (rowIdx, colIdx, v)

実行結果
> python test00.py
[(u'Sheet1', {(1, 3): 9.1, (3, 0): u'sapporo', (2, 8): 28.9, (3, 11): 5.9, (0, 7): u'July', (1, 6): 23.6, (0, 10): u'October', (2, 10): 25.7, (3, 7): 22.1, (0,3): u'March', (1, 11): 13.5, (2, 5): 23.8, (1, 2): 6.5, (3, 3): -0.1, (2, 9): 28.0, (2, 0): u'naha', (3, 10): 12.2, (1, 5): 19.0, (0, 11): u'November', (3, 6):19.2, (0, 4): u'April', (1, 10): 18.9, (1, 1): 7.0, (2, 7): 28.7, (3, 2): -3.2,(2, 6): 26.7, (2, 2): 18.3, (1, 4): 12.4, (0, 12): u'December', (2, 1): 16.8, (3, 9): 20.0, (0, 5): u'May', (1, 9): 25.1, (1, 0): u'tokyo', (0, 8): u'August', (3, 5): 12.2, (0, 1): u'January', (3, 12): 0.6, (1, 12): 9.9, (3, 1): -2.0, (2, 11): 21.4, (2, 4): 21.2, (3, 8): 24.8, (0, 6): u'June', (1, 8): 29.6, (1, 7): 28.0, (0, 9): u'September', (2, 3): 19.9, (3, 4): 5.5, (0, 2): u'February', (2, 12): 18.1}), (u'Sheet2', {}), (u'Sheet3', {})]
Sheet name: Sheet1
values.keys():  [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (0, 11), (0, 12), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1,5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (1, 11), (1, 12), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (2, 11), (2, 12), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (3, 11), (3, 12)]
(0, 1): January
(0, 2): February
(0, 3): March
(0, 4): April
(0, 5): May
(0, 6): June
(0, 7): July
(0, 8): August
(0, 9): September
(0, 10): October
(0, 11): November
(0, 12): December
(1, 0): tokyo
(1, 1): 7.0
(1, 2): 6.5
(1, 3): 9.1
(1, 4): 12.4
(1, 5): 19.0
(1, 6): 23.6
(1, 7): 28.0
(1, 8): 29.6
(1, 9): 25.1
(1, 10): 18.9
(1, 11): 13.5
(1, 12): 9.9
(2, 0): naha
(2, 1): 16.8
(2, 2): 18.3
(2, 3): 19.9
(2, 4): 21.2
(2, 5): 23.8
(2, 6): 26.7
(2, 7): 28.7
(2, 8): 28.9
(2, 9): 28.0
(2, 10): 25.7
(2, 11): 21.4
(2, 12): 18.1
(3, 0): sapporo
(3, 1): -2.0
(3, 2): -3.2
(3, 3): -0.1
(3, 4): 5.5
(3, 5): 12.2
(3, 6): 19.2
(3, 7): 22.1
(3, 8): 24.8
(3, 9): 20.0
(3, 10): 12.2
(3, 11): 5.9
(3, 12): 0.6
Sheet name: Sheet2
values.keys():  []
Sheet name: Sheet3
values.keys():  []

[Python][pyExcelerator]インストール

  1. pyExcelerator から pyexcelerator-0.6.4.1.zip (2011/05/04 現在) をダウンロードする
  2. setup.py を実行してインストールする
    > python setup.py install
    

[Python]mod_wsgiインストール

  1. mod_wsgi をインストール
    # yum install mod_wsgi
    
  2. /etc/httpd/conf/httpd.conf を編集
    # mod_wsgi
    LoadModule wsgi_module modules/mod_wsgi.so
    WSGIScriptAlias        /wsgi /var/www/cgi-bin/python/wsgi/test00.wsgi
    <Directory /var/www/cgi-bin/python/wsgi>
        Order allow,deny
        Allow from all
    </Directory>
    
  3. Test Script 作成
    test00.wsgi
    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    def application(environ, start_response):
        status = '200 OK'
        output = "Hello, world!"
        response_header = [('Content-type', 'text/plain'),
                           ('Content-Length', str(len(output)))]
        start_response(status, response_header)
        return output
    
  4. Test script 配置
    httpd.conf で設定した WSGIScriptAlias (/var/www/cgi-bin/python/wsgi) に上記のスクリプトを置く
  5. http://localhost/wsgi/ へアクセスする

[Python][CGI]MySQL からデータを読み込んでグラフを描く

#!/usr/bin/python
# -*- coding:utf-8 -*-
import MySQLdb
import tempfile
import os

# エラー発生時にレポートを表示
import cgitb
cgitb.enable()

html = """
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=utf-8"/>
<html>
<head>
<title>MySQL & Gnuplot</title>
</head>
<body>
data<br/>
%s
<img src="%s"/>
</body>
</html>
"""

####################################################################
# @brief グラフを描く
####################################################################
def drawGraph(dataFilename, pngfile, xmin, xmax, ymin, ymax):
 # plot データ作成
 (fd, pltFilename) = tempfile.mkstemp()

 # print "Plot tempfile name: %s" % (pltFilename)
 f = os.fdopen(fd, 'w')
 str = """
 set terminal png font "/usr/share/fonts/ipa-gothic/ipag.ttf,12"
 set output '%s'
 set title '各地の気温'
 set xlabel '場所'
 set ylabel '気温'
 set xrange [-1:3]
 set yrange [0:30]
 set boxwidth 0.5 relative
 set style fill solid 0.2
 set grid
 unset key
 plot '%s' using 2:xticlabels(1) with boxes
 """ % (pngfile, dataFilename)
 f.write(str)
 f.close()

 # gnuplot コマンド実行
 os.system("gnuplot %s" % pltFilename)

 # Temporary file 削除
 os.remove(pltFilename)

####################################################################
# @brief Main function
####################################################################
# DB に接続
db = MySQLdb.connect(user="username", passwd="password", db="dbname", charset="utf8")

# SELECT
q = "SELECT `area`, `temperature` FROM `temperature`;"
db.query(q)
result = db.store_result()

# データ表示 & データ格納
num = result.num_rows()
(fd, dataFilename) = tempfile.mkstemp()
f = os.fdopen(fd, 'w')
#print "filename: %s" % filename
data = """
<table border="1">
"""

for row in result.fetch_row(num):
 str = "<tr><td>%s</td><td>%.2f</td></tr>" % (row[0], row[1])
 data = data + str
 str = "%s\t%.2f\n" % (row[0], row[1])
 f.write(str)

data = data + "</table>"
f.close()

# グラフ作成
pngfile = "test03.png"
drawGraph(dataFilename, pngfile, -1, 3, 0, 30)

# Temporary file 削除
os.remove(dataFilename)

print html % (data, "test03.png")
これを実行しても SELinux が書き込みを禁止するので test03.png を cgi-bin 以下に生成することができない。
今は SELinux を一時停止して実験する。
# setenforce 0
この cgi ファイルのある場所に test03.png が作成されるが、cgi 実行権限のあるディレクトリ (cgi-bin) はすべて実行ファイルと解釈されるので画像が表示できない。
そこで httpd.conf の cgi ディレクトリ設定に AddHandler image/png .png を追加する。
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
AddHandler image/png .png
</Directory>
SELinux を有効のままでファイル書き込みを許可するにはスクリプトを実行するディレクトリの Type を httpd_sys_rw_content_t に変更する。
# ls -Z
drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_script_exec_t:s0 python
# chcon -t httpd_sys_script_rw_t python/
# ls -Z
drwxrwxrwx. root root unconfined_u:object_r:httpd_sys_rw_content_t:s0 python

[Python][CGI]CGI で Cookie を使う

POST されたデータを Cookie で保存するように指示する
cookiePostResult.cgi
#!/usr/bin/python
# -*- coding:utf-8 -*-
import cgi
import cgitb

# エラー発生時にレポートを表示
cgitb.enable()
f = cgi.FieldStorage()
field1 = f.getfirst('field1', '')
field2 = f.getfirst('field2', '')

# Cookie に保存
print "Set-Cookie: FIELD1=%s" % (field1)
print "Set-Cookie: FIELD2=%s" % (field2)
print "\n"

html = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Cookie POST Result</title>
</head>
<body>
<h1>Cookie POST Result</h1>
Field1: %s<br/>
Field2: %s<br/>
<a href="/cgi-bin/python/cookiePostResult2.cgi">次へ</a>
</body>
</html>
"""

print html % (field1, field2)
Set-Cookie でクライアントのブラウザに Cookie 保存するように指示する。

保存された Cookie を読み込んで表示する
cookiePostResult2.cgi
#!/usr/bin/python
# -*- coding:utf-8 -*-
import os
import cgi
import cgitb
import Cookie

# Cookie の値を読み出す
cookie = Cookie.SimpleCookie()
cookie.load(os.environ["HTTP_COOKIE"])
field1 = cookie["FIELD1"].value
field2 = cookie["FIELD2"].value

html = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Cookie POST Result 2</title>
</head>
<body>
<h1>Cookie POST Result 2</h1>
Field1: %s<br/>
Field2: %s<br/>
</body>
</html>
"""

print html % (field1, field2)

[Python][numpy]行列計算

転置行列 (transpose)
a = numpy.arange(0, 6).reshape(2, 3) # 2x3 行列
print "arange(0, 6).reshapre(2, 3):"
print a
print "transpose():"
print a.transpose() # 転置行列 (transpose)
arange(0, 6).reshapre(2, 3):
[[0 1 2]
[3 4 5]]
transpose():
[[0 3]
[1 4]
[2 5]]



逆行列 (inverse)
a = numpy.arange(0, 4).reshape(2, 2) # 2x2 行列
print "arange(0, 4).reshapre(2, 2):"
print a
print "linalg.inv(a):"
print numpy.linalg.inv(a) # 逆行列 (inverse)
arange(0, 4).reshapre(2, 2):
[[0 1]
[2 3]]
linalg.inv(a):
[[-1.5 0.5]
[ 1. 0. ]]


[Python][numpy]様々な行列

すべて 0 の行列
a = numpy.zeros((3, 4)) # 3x4 行列
print "zeros((3, 4)):"
print a
zeros((3, 4)):
[[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]


すべて 1 の行列
a = numpy.ones((3, 4)) # 3x4 行列
print "ones((3, 4)):"
print a
ones((3, 4)):
[[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]]


単位行列
i = numpy.identity(3) # 3x3 単位行列 (identity matirx)
print "identity(3):"
print i
identity(3):
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]


要素を指定して行列生成
a = numpy.array([0, 2, 3, 4, 6, 8]).reshape(2, 3)
print "array([0, 2, 3, 4, 6, 8]).reshape(2, 3):"
print a
array([0, 2, 3, 4, 6, 8]).reshape(2, 3):
[[0 2 3]
[4 6 8]]


特定の対角のみ 1 にする行列
a = numpy.eye(3)
print "eye(3):"
print a
a = numpy.eye(3, k=1)
print "eye(3, k=1):"
print a
eye(3):
[[ 1. 0. 0.]
[ 0. 1. 0.]
[ 0. 0. 1.]]
eye(3, k=1):
[[ 0. 1. 0.]
[ 0. 0. 1.]
[ 0. 0. 0.]]


[Python][numpy]numpy 事始

# -*- coding:utf-8 -*-
import numpy

a = numpy.arange(5) # start:0, stop:5
print "arange(5): ",
print a

a = numpy.arange(3, 10) # start:3, stop:10
print "arange(3, 10): ",
print a

a = numpy.arange(3, 10, 2) # start:3, stop:10, step:2
print "arange(3, 10, 2): ",
print a

a = numpy.linspace(0, 2, 6) # 0 から 2 までを 6 段階に線形分割
print "linespace(0, 2, 6): ",
print a

a = numpy.arange(10).reshape(2, 5)
print "arange(10).reshape(2, 5):"
print a
print "a.shape: ",
print a.shape
print "a.ndim: ",
print a.ndim
実行結果
> python test00.py
arange(5): [0 1 2 3 4]
arange(3, 10): [3 4 5 6 7 8 9]
arange(3, 10, 2): [3 5 7 9]
linespace(0, 2, 6): [ 0. 0.4 0.8 1.2 1.6 2. ]
arange(10).reshape(2, 5):
[[0 1 2 3 4]
[5 6 7 8 9]]
a.shape: (2, 5)
a.ndim: 2
lispace(0, 2, 6) で 0 から 2 までを 6 段階に線形分割した数列を得られる。
arange(10).reshapre(2, 5) で 0 から 10 まで (10 は含まず) の数値 (0 - 9) を 2x5 行列に並び替えている

[Python][Paramiko(sftp)]カレントディレクトリのファイルをサーバーにアップする

ソースコード
# -*- coding:utf-8 -*-
##########################################################################
# ファイルアップロードスクリプト
##########################################################################
import os
import re
import paramiko

## Upload files
def uploadFiles(top, exp):
    for file in os.listdir(top):
    if re.search(exp, file):
        print top + file
        sfconn.put(top + file, top + file)

## Main function
host = 'serveraddress'
user = 'username'
password = 'password'

currentDir = ''
dstDir = 'documents/' + currentDir
dstImgDir = 'documents/' + currentDir + 'img'

conn = paramiko.SSHClient()
conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
conn.connect(host, username=user, password=password)
sfconn = conn.open_sftp()

sfconn.chdir(dstDir)

uploadFiles('./', 'html$')
uploadFiles('./img/', 'png$')

sfconn.close()
conn.close() 

[Python][Paramiko(sftp)]基本的な使い方

情報元: Paramiko
ソースコード
# -*- coding:utf-8 -*-
import paramiko

host = 'serveraddress'
user = 'username'
password = 'password'

conn = paramiko.SSHClient()
conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
conn.connect(host, username=user, password=password)
sfconn = conn.open_sftp()

# カレントディレクトリのファイル一覧を取得
files = sfconn.listdir()
for f in files:
    print f

# ファイルを置く・取得する
sfconn.get('test.txt', 'test.txt')
sfconn.put('paramiko.txt', './paramiko.txt')

sfconn.close()
conn.close()

[Python][HTTP]Cookie 処理

urllib2.HTTPCookieProcessor() を使って Cookie 処理を行う。
# -*- coding: utf-8 -*-
## Cookie を使う
import urllib
import urllib2
import cookielib

# POST データ作成
req = {'field1':'abcde', 'field2':'12334'}
print req
params = urllib.urlencode(req)
print params

# Cookie handler
cj = cookielib.CookieJar()
cookieHandler = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookieHandler)
urllib2.install_opener(opener)

# localhost の Web サーバーに IIS を使っている場合は localhost 指定の Cookie を
# 作ることができないのでエラー終了する
url = 'http://localhost/cgi-bin/python/cookiePostResult.cgi'
request = urllib2.Request(url, params)
f = urllib2.urlopen(request)
print f.info()
data = f.read()
print data
print "================"
for index, cookie in enumerate(cj):
print index, ':', cookie
print cj
print "================"
url = 'http://localhost/cgi-bin/python/cookiePostResult2.cgi'
request = urllib2.Request(url)
f = urllib2.urlopen(request)
data = f.read()
print data
実行結果
$ python test04.py
{'field2': '12334', 'field1': 'abcde'}
field2=12334&field1=abcde
Date: Sun, 16 Jan 2011 07:12:21 GMT
Server: Apache/2.2.17 (Fedora)
Set-Cookie: FIELD1=abcde
Set-Cookie: FIELD2=12334
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Cookie POST Result</title>
</head>
<body>
<h1>Cookie POST Result</h1>
Field1: abcde<br/>
Field2: 12334<br/>
<a href="/cgi-bin/python/cookiePostResult2.cgi">次へ</a>
</body>
</html>
================
0 : <Cookie FIELD1=abcde for localhost.local/cgi-bin/python>
1 : <Cookie FIELD2=12334 for localhost.local/cgi-bin/python>
<cookielib.CookieJar[<Cookie FIELD1=abcde for localhost.local/cgi-bin/python>, <Cookie FIELD2=12334 for localhost.local/cgi-bin/python>]>
================
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Cookie POST Result 2</title>
</head>
<body>
<h1>Cookie POST Result 2</h1>
Field1: abcde<br/>
Field2: 12334<br/>
</body>
</html>
Web サーバーが IIS の場合 localhost の名前解決ができない場合に Cookie の保存ができないようだ。実験した環境では Cookie の保存ができず urlopen() でエラーとなった。
Linux Apache でテストした時は localhost 指定でも問題なく urlopen() できた。

[Python][HTTP]POST

POST するデータを urllib.urlencode() で作成し、urllib2.Request() で POST 先 URL とまとめてからアクセスする。
# -*- coding: utf-8 -*-
## POST
import urllib
import urllib2

# POST データ作成
req = {'field1':'abcde', 'field2':'12334'}
print req
params = urllib.urlencode(req)
print params
url = 'http://localhost/cgi-bin/python/postResult.cgi'
request = urllib2.Request(url, params)
f = urllib2.urlopen(request)
data = f.read()
print data
実行結果
$ python test03.py
{'field2': '12334', 'field1': 'abcde'}
field2=12334&field1=abcde
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>POST Result</title>
</head>
<body>
<h1>POST Result</h1>
Field1: abcde<br/>
Field2: 12334<br/>
</body>
</html>

[Python][HTTP]ファイルをダウンロード

read したファイルを write でファイルに書き出すことでファイルをダウンロードする。
# -*- coding: utf-8 -*-
## HTTP でファイルをダウンロードする
import urllib2

url = 'http://ftp.gnu.org/gnu/hello/hello-2.6.tar.gz'
f = urllib2.urlopen(url)
data = f.read()

# 出力先ファイルを指定して書き込む
out = open("hello-2.6.tar.gz", "wb")
out.write(data)
out.close()

[Python][HTTP]Proxy 経由

Proxy 経由でアクセスする場合は urllib2.ProxyHandler() を使って設定する。
# -*- coding: utf-8 -*-
## Proxy 経由で外部の Web server にアクセスする
import urllib2

url = 'http://www.google.com/'

# Proxy 設定
proxies = {'http': 'http://hogehoge:8080'}
proxyHandler = urllib2.ProxyHandler(proxies)
opener = urllib2.build_opener(proxyHandler)
urllib2.install_opener(opener)
f = urllib2.urlopen(url)
data = f.read()

# 受信結果を表示
print data

[Python][HTTP]HTTP 通信初歩

urllib2 モジュールを使って HTTP 通信をする。
# -*- coding: utf-8 -*-
## ローカルの Web server にアクセスする
import urllib2

url = 'http://localhost/'
f = urllib2.urlopen(url)
data = f.read()

# 受信結果を表示
print data

[Python][gnuplot]SQL データからグラフを作る

次のような SQL データからグラフを作る
2010 年 9 月平均気温
areatemperature
Tokyo25.1
Abashiri17.8
Naha28.0
# -*- coding:utf-8 -*-
from numpy import *
import Gnuplot, Gnuplot.funcutils
import os
import time
import MySQLdb

########################################################################
# @brief グラフを描く
########################################################################
def drawGraph(filename, pngfile, xmin, xmax, ymin, ymax):
 g = Gnuplot.Gnuplot(debug=1) # debug=1 を引数に付けるとコンソールに gnuplot に渡したコマンドが表示される

 # Gnuplot に指示を与える
 g('set xrange [%d:%d]' % (xmin, xmax))
 g('set yrange [%d:%d]' % (ymin, ymax))
 g('set boxwidth 0.5 relative')
 g('set style fill solid 0.2')
 g('set grid')
 g('unset key') # 凡例なし

 # データ読み込み
 str = "'%s' using 2:xticlabels(1) with boxes" % (filename)
 g.plot(str)

 # こちらでも png 出力可能, 一瞬 window が表示される
 g.hardcopy(pngfile, terminal = 'png')

 # すぐに終了してしまうとデータ出力できないので 0.1 sec sleep
 time.sleep(0.1)

########################################################################
# @brief Main function
########################################################################
# temporary ディレクトリを current directory にする
os.environ['TEMP']="."

# DB に接続
db = MySQLdb.connect(user="username", passwd="password", db="test", charset="utf8")

# SELECT
db.query("SELECT `area`, `temperature` FROM `temperature`;")
result = db.store_result()

# データ格納
filename = 'data03.dat'
pngfile = 'date03.png'
f = open(filename, 'w')
num = result.num_rows()
for row in result.fetch_row(num):
str = "%s\t%.2f\n" % (row[0], row[1])

# print str
f.write(str)
f.close()

# グラフ作成
drawGraph(filename, pngfile, -1, 3, 0, 30)

[Python][gnuplot]Temporary file を使う

データファイル, plt ファイルを temporary file にする。
tempfile.mkstemp() を使う場合はユーザー責任でファイルを削除する必要がある。
# -*- coding:utf-8 -*-
import tempfile
import os

# データ作成
(fd, dataFilename) = tempfile.mkstemp()
print "Data tempfile name: %s" % (dataFilename)
f = os.fdopen(fd, 'w')

str = """
東京\t25.10
網走\t17.80
那覇\t28.00
"""

f.write(str)
f.close()

# plot データ作成
(fd, pltFilename) = tempfile.mkstemp()
print "Plot tempfile name: %s" % (pltFilename)
pngfile = "data06.png"
f = os.fdopen(fd, 'w')

str = """
set terminal png font "/usr/share/fonts/ipa-gothic/ipag.ttf,12"
set output '%s'
set title '各地の気温'
set xlabel '場所'
set ylabel '気温'
set xrange [-1:3]
set yrange [0:30]
set boxwidth 0.5 relative
set style fill solid 0.2
set grid
unset key
plot '%s' using 2:xticlabels(1) with boxes
""" % (pngfile, dataFilename)

f.write(str)
f.close()

# gnuplot コマンド実行
os.system("gnuplot %s" % pltFilename)

# ファイル削除
os.remove(dataFilename)
os.remove(pltFilename)

[Python][gnuplot]日本語を使う

フォントを指定して日本語表示できるようにする。
data05.dat
東京 25.10
網走 17.80
那覇 28.00
set terminal png のところで IPA Gothic フォントを指定する。
# -*- coding:utf-8 -*-
import os

filename = "data05.plt"
f = open(filename, 'w')

str = """
set terminal png font "/usr/share/fonts/ipa-gothic/ipag.ttf,12"\n
set output 'data05.png'\n
set title '各地の気温'\n
set xlabel '場所'\n
set ylabel '気温'\n
set xrange [-1:3]\n
set yrange [0:30]\n
set boxwidth 0.5 relative\n
set style fill solid 0.2\n
set grid\n
unset key\n
plot 'data05.dat' using 2:xticlabels(1) with boxes\n
"""

f.write(str)
f.close()
os.system("gnuplot %s" % filename)

[Python][gnuplot]Gnuplot 用 plt ファイルを作成して実行

plt ファイルを python で書き出しおいて gnuplot コマンドを実行する。
# -*- coding:utf-8 -*-
import os

filename = "data04.plt"
f = open(filename, 'w')
str = """
set terminal png\n
set output 'data04.png'\n
plot 'data04.dat' using 1:2 with linespoints\n
"""
f.write(str)
f.close()
os.system("gnuplot %s" % filename)

[Python][gnuplot]外部データから読み込んで plot する

# -*- coding:utf-8 -*-
from numpy import *
import Gnuplot, Gnuplot.funcutils
import os
import time

# temporary ディレクトリを current directory にする
os.environ['TEMP']="."

# debug=1 を引数に付けるとコンソールに gnuplot に渡したコマンドが表示される
g = Gnuplot.Gnuplot(debug=1)
g.title('A simple example')

# Gnuplot に指示を与える
g('set boxwidth 0.9 relative')
g('set style fill solid 1.0')
g('set style data boxes')
g('set xdata time')
g('set timefmt "%Y-%m-%d"')

# データ読み込み
g.plot('"sample01.dat" using 1:2')

# こちらでも png 出力可能, 一瞬 window が表示される
g.hardcopy('sample01.png', terminal = 'png')

# すぐに終了してしまうとデータ出力できないので 1sec sleep
time.sleep(1)cmd.append('"%s"' % (font,))
sample01.dat
2010-10-01 1.1
2010-10-02 5.8
2010-10-03 3.3
2010-10-04 4.2

[Python][gnuplot]png ファイルにグラフ出力

# -*- coding:utf-8 -*-
from numpy import *
import Gnuplot, Gnuplot.funcutils
import os
import time

# temporary ディレクトリを current directory にする
os.environ['TEMP']="."

# debug=1 を引数に付けるとコンソールに gnuplot に渡したコマンドが表示される
g = Gnuplot.Gnuplot(debug=1)
g.title('A simple example')

# PNG ファイルに出力する場合は以下の 2 行を追加する
g('set term png size 400,300')
g("set output 'sample00.png'")

# Gnuplot に指示を与える
g('set data style linespoints') # give gnuplot an arbitrary command

# Plot
g.plot([[0,1.1], [1,5.8], [2,3.3], [3,4.2]])

# こちらでも png 出力可能, 一瞬 window が表示される
#g.hardcopy('sample00.png', terminal = 'png')
# Window 表示の場合は下記を有効にしてスクリプトを止める
#raw_input('Please press return to continue...\n')
# すぐに終了してしまうとデータ出力できないので 1sec sleep
time.sleep(1)

[Python][gnuplot]イ ンストール

  1. Numerical Python | Download Numerical Python software for free at SourceForge.net から Numerical Python (numpy-1.5.1rc1-win32-superpack-python2.5.exe) をダウンロードし、インストールする。
  2. Gnuplot.py - Browse Files at SourceForge.net から Gnuplot.py (gnuplot-py-1.8.zip) をダウンロードする。
  3. ダウンロードしたファイルを展開し、ディレクトリに移動してインストールを実行する。
    > python setup.py install
    
  4. pgnuplot.exe が実行できるように PATH を通す。
  5. 動作確認
    > python demo.py
    

[Python][XML]lxml - インストール

Windows
  1. Python Package Index: lxml 2.3 から Python 2.7 用パッケージ (lxml-2.3.win32-py2.7.exe) をダウンロードする
  2. ダウンロードしたファイルを実行する
動作確認
# -*- coding:utf-8 -*-
import lxml.etree
tree = lxml.etree.parse('test01.xml')
root = tree.getroot()
print root.tag
foods = root.iterfind('food')
print foods
for food in foods:
print food
children = food.getchildren()
for c in children:
print c.tag
name = food.find('name')
print "tag: ", name.tag
print "text: ", name.text
実行結果
> python test03.py
root.tag: breakfast_menu
foods: <generator object select at 0x00EAA8F0>
food: <Element food at 0xeaa940>
child.tag: name
child.tag: price
child.tag: description
child.tag: calories
tag: name
text: Belgian Waffles
food: <Element food at 0xeaa8a0>
child.tag: name
child.tag: price
child.tag: description
child.tag: calories
tag: name
text: Strawberry Belgian Waffles
food: <Element food at 0xeaaa08>
child.tag: name
child.tag: price
child.tag: description
child.tag: calories
tag: name
text: Berry-Berry Belgian Waffles
food: <Element food at 0xeaa918>
child.tag: name
child.tag: price
child.tag: description
child.tag: calories
tag: name
text: French Toast
food: <Element food at 0xeaa940>
child.tag: name
child.tag: price
child.tag: description
child.tag: calories
tag: name
text: Homestyle Breakfast

[Python][XML]xml.dom.minidom - Node のデータ表示

各 Node のデータを順番に表示する
test02.py
# -*- coding:utf-8 -*-
import xml.dom.minidom

# Node のデータを表示する
def dispNodeData(node, tag):
l = node.getElementsByTagName(tag)
for n in l:
 print n.nodeName, " - ", n.childNodes.item(0).nodeValue

# Main function
dom = xml.dom.minidom.parse('test01.xml')
foods = dom.getElementsByTagName('food')
for food in foods:
 print "nodeName: ", food.nodeName
 dispNodeData(food, 'name')
 dispNodeData(food, 'price')
 dispNodeData(food, 'calories')
実行結果
> python test02.py
nodeName: food
name - Belgian Waffles
price - $5.95
calories - 650
nodeName: food
name - Strawberry Belgian Waffles
price - $7.95
calories - 900
nodeName: food
name - Berry-Berry Belgian Waffles
price - $8.95
calories - 900
nodeName: food
name - French Toast
price - $4.50
calories - 600
nodeName: food
name - Homestyle Breakfast
price - $6.95
calories - 950

[Python][XML]xml.dom.minidom

XML を解析するには minidom を使う
test01.xml
<?xml version="1.0" encoding="utf-8"?>
<breakfast_menu>
  <food id="0">
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
    <calories>650</calories>
  </food>
  <food id="1">
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>light Belgian waffles covered with strawberries and whipped cream</description>
    <calories>900</calories>
  </food>
  <food id="2">
    <name>Berry-Berry Belgian Waffles</name>
    <price>$8.95</price>
    <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
    <calories>900</calories>
  </food>
  <food id="3">
    <name>French Toast</name>
    <price>$4.50</price>
    <description>thick slices made from our homemade sourdough bread</description>
    <calories>600</calories>
  </food>
  <food id="4">
    <name>Homestyle Breakfast</name>
    <price>$6.95</price>
    <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
    <calories>950</calories>
  </food>
</breakfast_menu>
test01.py
# -*- coding:utf-8 -*-
import xml.dom.minidom
import pprint
dom = xml.dom.minidom.parse('test01.xml')
pprint.pprint(dom)

# NodeList
foods = dom.getElementsByTagName('food')
print "NodeList(food)"
pprint.pprint(foods)
print "length: %s" % (foods.length)

# Node
food = foods.item(0)
pprint.pprint(food)
print "Node(food)"
print "nodeType: ", food.nodeType
print "nodeName: ", food.nodeName
print "hasChildNodes(): ", food.hasChildNodes()
print "hasAttributes(): ", food.hasAttributes()

# NodeList
names = food.getElementsByTagName('name')
print "NodeList(name)"
pprint.pprint(names)
print "length: ", names.length
name = names.item(0)
print "Node(name)"
pprint.pprint(names)
print "nodeType: ", name.nodeType
print "nodeName: ", name.nodeName
print "nodeValue: ", name.nodeValue
print "hasChildNodes(): ", name.hasChildNodes()
print "hasAttributes(): ", name.hasAttributes()

# NodeList
nameDatas = name.childNodes
print "NodeList(data)"
pprint.pprint(nameDatas)
print "length: ", nameDatas.length

# Node
data = nameDatas.item(0)
print "Text Node(data)"
pprint.pprint(data)
print "nodeType: ", data.nodeType
print "nodeName: ", data.nodeName
print "nodeValue: ", data.nodeValue
print "data: ", data.data

# nodeType 定数
print "nodeType constants"
node = xml.dom.Node
print " ELEMENT_NODE : ", node.ELEMENT_NODE
print " ATTRIBUTE_NODE : ", node.ATTRIBUTE_NODE
print " TEXT_NODE : ", node.TEXT_NODE
print " CDATA_SECTION_NODE : ", node.CDATA_SECTION_NODE
print " ENTITY_NODE : ", node.ENTITY_NODE
print " PROCESSING_INSTRUCTION_NODE: ", node.PROCESSING_INSTRUCTION_NODE
print " COMMENT_NODE : ", node.COMMENT_NODE
print " DOCUMENT_NODE : ", node.DOCUMENT_NODE
print " DOCUMENT_TYPE_NODE : ", node.DOCUMENT_TYPE_NODE
print " NOTATION_NODE : ", node.NOTATION_NODE
実行結果
> python test01.py
<xml.dom.minidom.Document instance at 0x00B402D8>
NodeList(food)
[<DOM Element: food at 0xb45418>,
<DOM Element: food at 0xb457d8>,
<DOM Element: food at 0xb45b98>,
<DOM Element: food at 0xb45f58>,
<DOM Element: food at 0xb4b350>]
length: 5
<DOM Element: food at 0xb45418>
Node(food)
nodeType: 1
nodeName: food
hasChildNodes(): True
hasAttributes(): True
NodeList(name)
[<DOM Element: name at 0xb45530>]
length: 1
Node(name)
[<DOM Element: name at 0xb45530>]
nodeType: 1
nodeName: name
nodeValue: None
hasChildNodes(): True
hasAttributes(): False
NodeList(data)
[<DOM Text node "u'Belgian Wa'...">]
length: 1
Text Node(data)
<DOM Text node "u'Belgian Wa'...">
nodeType: 3
nodeName: #text
nodeValue: Belgian Waffles
data: Belgian Waffles
nodeType constants
ELEMENT_NODE : 1
ATTRIBUTE_NODE : 2
TEXT_NODE : 3
CDATA_SECTION_NODE : 4
ENTITY_NODE : 6
PROCESSING_INSTRUCTION_NODE: 7
COMMENT_NODE : 8
DOCUMENT_NODE : 9
DOCUMENT_TYPE_NODE : 10
NOTATION_NODE : 12

2015年4月23日木曜日

[CentOS][VirtualBox]共有フォルダー作成

  1. VirtualBox メニューの [デバイス] > [共有フォルダー設定]
  2. Windows (Host OS) に共有フォルダーを作成する (ユーザー\vbox_share)
  3. フォルダ追加アイコンを押す
  4. フォルダーのパス = 2. で作成したフォルダ
    自動マウント = On
    永続化する = On
  5. マウントする
    # mkdir /mnt/vbox_share
    # mount -t vboxsf vbox_share /mnt/vbox_share
    
  6. 動作確認
    1. Windows 側の vbox_share フォルダにファイルを置く
    2. CentOS で /mnt/vbox_share の中身を確認する
      $ ls /mnt/vbox_share
      test.txt
      
  7. 起動時に自動マウントするように /etc/rc.local にマウントコマンドを追記する(★が追記箇所)
    #!/bin/sh
    #
    # This script will be executed *after* all the other init scripts.
    # You can put your own initialization stuff in here if you don't
    # want to do the full Sys V style init stuff.
    
    touch /var/lock/subsys/local
    mount -t vboxsf vbox_share /mnt/vbox_share ★
    

[CentOS][VirtualBox]GNOME インストール

  1. インストール & 起動
    # yum groupinstall "X Window System" "GNOME Desktop Environment" "Desktop"
    $ startx
    
  2. GNOME インストール前に Guest Additions をインストールしていると X Window system 関連のインストールがスキップされているので、再インストールする
  3. GNOME terminal のフォントがずれているので修正する
    【修正前】

    【修正後】

    DejaVu Sans Mono フォントをインストールする
    # yum -y install dejavu-sans-mono-fonts
    

[CentOS][VirtualBox]Virtual Box Guest Additions インストール

  1. kernel の update、gcc, make, kernel-devel をインストールする
    # yum -y update kernel
    # yum -y install gcc make kernel-devel
    
  2. 再起動
  3. Guest Additions CD をマウントする
    # mkdir /mnt/cdrom
    # mount -r /dev/cdrom /mnt/cdrom
    
  4. Guest Additions CD のインストーラーをを実行する
    # cd /mnt/cdrom
    # ./VBoxLinuxAdditions.run
    

[CentOS][VirtualBox]ifconfig を実行すると eth0 が起動していない

  1. 起動時の設定ファイル /etc/sysconfig/network-scripts/ifcfg-eth0 を修正する
    【変更前】
    ONBOOT=no
    
    【変更後】
    ONBOOT=yes
    
  2. ネットワークを再設定
    # /etc/inet.d/network restart
    

2015年4月2日木曜日

[PowerShell]ディレクトリ一覧を取得し、ディレクトリに対して作業をする

$directories = @(Get-ChildItem | Where-Object {$_.Attributes -eq "Directory"})
Write-Debug "$directories"
foreach ($d in $directories) {
    convertFiles($d)
    compressZip($d)
}
CmdletDescription
Where-Objectオブジェクトの配列をフィルタにかけ、条件に一致するオブジェクトだけを出力する
Get-ChildItem (lsで取得した項目) で取得した項目から Attributes が Directory のものだけを抽出している
Get-ChildItem | Where-Object {$_.Attributes -eq "Directory"}

[PowerShell]7-zipを使ってzip圧縮する

###################################
# ZIP 圧縮
###################################
function compressZip([string] $directory)
{
 Set-Alias sz "C:\Program Files\Utility\7-Zip\7z.exe"

 $output = $directory + ".zip"
 sz a $output $directory
}
CmdletDescription
Set-Aliasエイリアスを作成する

[PowerShell]指定ディレクトリ内のjpgファイルにconvertコマンドを実行する

##########################################################
# 指定ディレクトリ内の jpg ファイルに対しサイズ変換をする
##########################################################
function convertFiles([string] $directory)
{
 Set-Location $directory

 Write-Debug "Search jpg files in $directory"
 $files = @(Get-ChildItem .\*.* -Include *.jpg -Name)
 Write-Debug "$files"
 foreach ($f in $files) {
  Write-Debug "convert.exe $f -strip -density 300x300 -units PixelsPerInch -geometry 50% $f"
  convert.exe $f -strip -density 300x300 -units PixelsPerInch -geometry 50% $f
 }

 Set-Location ..
}
CmdletDescription
Set-Location作業場所を指定する。cdと同等
Write-Debugデバッグメッセージをコンソールに出力する
Get-ChildItem指定された場所から項目および子項目を取得する。lsと同等
-Include: 指定された項目だけ取得する
-Name: 指定された場所にある項目の名前だけを取得します

2015年3月18日水曜日

[Python][OpenCV]OpenCVで余白削除 その2

# -*- coding:utf-8 -*-
import cv2

img = cv2.imread('cropped.jpg')
img2 = cv2.imread('cropped.jpg')

# Grayscale に変換
img_gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2 値化
ret, thresh = cv2.threshold(img_gs, 250, 255, cv2.THRESH_BINARY)

# 輪郭を取得
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# i = 1 は画像全体の外枠になるのでカウントに入れない
x1 = []
y1 = []
x2 = []
y2 = []
for i in range(1, len(contours)):
    # ret の中身は (x, y, w, h)
    ret = cv2.boundingRect(contours[i])
    x1.append(ret[0])
    y1.append(ret[1])
    x2.append(ret[0] + ret[2])
    y2.append(ret[1] + ret[3])

x1_min = min(x1)
y1_min = min(y1)
x2_max = max(x2)
y2_max = max(y2)

# 枠取りをした結果を表示
cv2.rectangle(img, (x1_min, y1_min), (x2_max, y2_max), (0, 255, 0), 2)
cv2.imwrite('cropped_edge_rectangle.jpg', img)

# ギリギリで切り出し
crop_img = img2[y1_min:y2_max, x1_min:x2_max]
cv2.imwrite('cropped_edge.jpg', crop_img)

# 少し余白を付けて付けて切り出し
offset = 100
y1_min -= offset
y2_max += offset
x1_min -= offset
x2_max += offset
crop_img = img2[y1_min:y2_max, x1_min:x2_max]
cv2.imwrite('cropped_edge_offset.jpg', crop_img)
元画像

枠取りをした結果

ギリギリで切り出した結果

少し余白を付けて切り出した結果

[Python][PIL] PILを使ってAutoCrop(余白削除)

# -*- coding:utf-8 -*-
import Image, ImageChops
import numpy as np

image = Image.open('cropped.jpg')

# getpixel(0, 0) で左上の色を取得し、背景色のみの画像を作成する
bg = Image.new(image.mode, image.size, image.getpixel((0, 0)))

# 背景色画像と元画像の差分を取得
diff = ImageChops.difference(image, bg)
#diff.show()
diff = ImageChops.add(diff, diff, 2.0, -100)
#diff.show()
# 黒背景の境界Boxを取り出す
bbox = diff.getbbox()
# 少し余白を付ける
offset=30
bbox2 = (bbox[0] - offset, bbox[1] - offset, bbox[2] + offset, bbox[3] + offset)
# 元画像を切り出す
cropped = image.crop(bbox)
cropped.save('cropped_edge.jpg')
cropped = image.crop(bbox2)
cropped.save('cropped_edge_offset.jpg')
元画像

ギリギリで切り出し

少し余白を付けて切り出し

[Python][OpenCV]OpenCVで余白削除

# -*- coding:utf-8 -*-
import cv2

img = cv2.imread('test.png')
img2 = cv2.imread('test.png')

# Grayscale に変換
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 結果を表示
#cv2.imshow('img', img)
#cv2.imshow('img2', img2)

# 2 値化
ret, thresh = cv2.threshold(img2, 250, 255, cv2.THRESH_BINARY)
#cv2.imshow('thresh', thresh)

# 輪郭を取得
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# i = 1 は画像全体の外枠になるのでカウントに入れない
x1 = []
y1 = []
x2 = []
y2 = []
for i in range(1, len(contours)):
    # ret の中身は (x, y, w, h)
    ret = cv2.boundingRect(contours[i])
    x1.append(ret[0])
    y1.append(ret[1])
    x2.append(ret[0] + ret[2])
    y2.append(ret[1] + ret[3])

x1_min = min(x1)
y1_min = min(y1)
x2_max = max(x2)
y2_max = max(y2)
cv2.rectangle(img, (x1_min, y1_min), (x2_max, y2_max), (0, 255, 0), 2)
cv2.imshow('img', img)
cv2.imwrite('test_cropRectangle.png', img)

crop_img = img2[y1_min:y2_max, x1_min:x2_max]
cv2.imshow('crop_img', crop_img)
cv2.imwrite('test_cropped.png', crop_img)

cv2.waitKey(0)
cv2.destroyAllWindows()
元画像

全画像の外枠検出結果

余白削除結果

[Python][OpenCV]画像の上下左右を削除(trim)する

# -*- coding:utf-8 -*-
import cv2

img = cv2.imread('BunkoSample_noise.jpg')
height, width = img.shape[:2]

offset = 100
# 開始座標
x = offset # 横座標(左起点)
y = offset # 縦座標(上起点)
# crop する画像サイズ
w = width - offset * 2
h = height - offset * 2
crop_img = img[y:y+h, x:x+w]
# IMWRITE_JPEG_QUALITY を指定しない時 (default) と quality = 95 は同じサイズになる
cv2.imwrite('cropped_default.jpg', crop_img)
cv2.imwrite('cropped_95.jpg', crop_img, [cv2.IMWRITE_JPEG_QUALITY, 95])
cv2.imwrite('cropped_75.jpg', crop_img, [cv2.IMWRITE_JPEG_QUALITY, 75])
cv2.imwrite('cropped_60.jpg', crop_img, [cv2.IMWRITE_JPEG_QUALITY, 60])
cv2.imwrite('cropped_50.jpg', crop_img, [cv2.IMWRITE_JPEG_QUALITY, 50])
cv2.imwrite('cropped_30.jpg', crop_img, [cv2.IMWRITE_JPEG_QUALITY, 30])
元画像(左上と右下にゴミ線が入っている)

上下左右を100dotずつ削った結果

出力されたファイルサイズ
$ ls -l
-rw-rw-r-- 1 xxxx xxxx 283451  3月 18 13:58 BunkoSample_noise.jpg
-rw-rw-r-- 1 xxxx xxxx 238097  3月 18 22:59 cropped_30.jpg
-rw-rw-r-- 1 xxxx xxxx 277427  3月 18 22:59 cropped_50.jpg
-rw-rw-r-- 1 xxxx xxxx 296614  3月 18 22:59 cropped_60.jpg
-rw-rw-r-- 1 xxxx xxxx 341120  3月 18 22:59 cropped_75.jpg
-rw-rw-r-- 1 xxxx xxxx 575140  3月 18 22:59 cropped_95.jpg
-rw-rw-r-- 1 xxxx xxxx 575140  3月 18 22:59 cropped_default.jpg

[Python][OpenCV]Python用OpenCVのインストール

Ubuntu ソフトウェアセンターで以下のものをインストールする
  • python-opencv

[Python][OpenCV]画像サイズを取得

# -*- coding:utf-8 -*-
import cv2

img = cv2.imread('test.jpg')
print "img.shape=", img.shape
height, width = img.shape[:2]
print "height=", height
print "width=", width
実行結果
$ python getImageSize.py 
img.shape= (1802, 1150, 3)
height= 1802
width= 1150

2015年3月17日火曜日

[Elisp] OSを判別する

*scratch* で下記をテスト
(print system-configuration)

"i686-pc-linux-gnu"
"i686-pc-linux-gnu"
(string-match "linux" system-configuration)
8

(string-match "mingw" system-configuration)
nil

2015年3月1日日曜日

robocopy

ファイルの移動
オプション
/MOVEファイルおよびディレクトリを移動、移動後はソースから削除する
/R:0コピー失敗時の再試行回数を 0 にする
/Eサブディレクトリをコピー。空のディレクトリもコピーする
robocopy C:\src C:\dst /MOVE /R:0 /E

[Linux] PDF ファイルのプロパティ表示

PDF ファイルのプロパティを表示する
$ exiftool HighlightFileFormat.pdf 
ExifTool Version Number         : 9.46
File Name                       : HighlightFileFormat.pdf
Directory                       : .
File Size                       : 252 kB
File Modification Date/Time     : 2015:03:01 06:07:51+09:00
File Access Date/Time           : 2015:03:01 06:08:06+09:00
File Inode Change Date/Time     : 2015:03:01 06:07:54+09:00
File Permissions                : rw-r-----
File Type                       : PDF
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : Yes
Modify Date                     : 2003:06:18 14:57:03-08:00
Create Date                     : 2003:04:15 16:05:06Z
Page Count                      : 8
Creation Date                   : 2003:04:15 16:05:06Z
Mod Date                        : 2003:06:18 14:57:03-08:00
Producer                        : Acrobat Distiller 5.0.5 for Macintosh
Author                          : Adobe Developer Support
Metadata Date                   : 2003:06:18 14:57:03-08:00
Creator                         : Adobe Developer Support
Title                           : Highlight File Format
Page Mode                       : UseOutlines
PDF にプロパティ値を書き込む
$ exiftool -Title="test title" -Author="someone" test.pdf

[ImageMagick]JPGからPDF変換

$ convert test/*.jpg test.pdf
test フォルダにある全ての jpg ファイルを 1 つの PDF ファイルにまとめる

[ImageMagick]PDFからJPEG変換

$ convert test.pdf test/%03d.jpg
test フォルダ下に 000.jpg, 001.jpg, 002.jpg と分割されていく

2015年2月22日日曜日

[Ubuntu]Windows用HDDをマウントする

  1. blkid(ブロックデバイスの属性を見つけて表示する)を使いパーティションのUUIDを調べる
    $ sudo blkid 
    [sudo] password: 
    /dev/sda2: LABEL="New Volume" UUID="B678FFE478FFA173" TYPE="ntfs" 
    /dev/sdb1: UUID="C40473FE0473F232" TYPE="ntfs" 
    /dev/sdb5: UUID="aeaaad63-cc5b-4dd0-94de-4eaf43b79d61" TYPE="ext4" 
    /dev/sdb6: UUID="a7f972c6-7a5e-480f-94e8-e210ba705da0" TYPE="swap" 
    
  2. マウントポイントを作成する
    $ sudo mkdir /mnt/dataHdd
    
  3. /etc/fstabに設定を記載する(☆の行を追加)
    UUID=a7f972c6-7a5e-480f-94e8-e210ba705da0 none            swap    sw              0       0
    UUID=B678FFE478FFA173 /mnt/dataHdd ntfs rw 0 0  ☆
    
  4. mountコマンドでマウントする
    $ sudo mount /mnt/dataHdd/
    

2015年1月15日木曜日

[Perl]cloc ソースコードカウント

ダウンロード
cloc
実行例
$ perl cloc-1.60.pl ./hello/
      32 text files.
      30 unique files.
      18 files ignored.

http://cloc.sourceforge.net v 1.60  T=1.00 s (15.0 files/s, 9409.0 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Bourne Shell                     5            774            915           5784
make                             4            110             41            849
m4                               2             96             14            781
C                                2              4              1             16
C/C++ Header                     2              7              9              8
-------------------------------------------------------------------------------
SUM:                            15            991            980           7438
-------------------------------------------------------------------------------
Makefile等を除く
$ perl cloc-1.60.pl --exclude-lang=make,m4,"Bourne Shell" ./hello/
      32 text files.
      30 unique files.
      29 files ignored.

http://cloc.sourceforge.net v 1.60  T=0.50 s (8.0 files/s, 90.0 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                                2              4              1             16
C/C++ Header                     2              7              9              8
-------------------------------------------------------------------------------
SUM:                             4             11             10             24

[Python][XML] lxml

  1. インストール
    • Windows
      1. Pyhon Package Index: lxml 2.3 から Python 2.7 用パッケージ (lxml-2.3.win32-py2.7.exe) をダウンロードする
      2. ダウンロードしたファイルを実行する
  2. 動作確認
    # -*- coding:utf-8 -*-
    import lxml.etree
    
    tree = lxml.etree.parse('test01.xml')
    root = tree.getroot()
    print root.tag
    foods = root.iterfind('food')
    print foods
    
    for food in foods:
        print food
        children = food.getchildren()
        for c in children:
            print c.tag
    
        name = food.find('name')
        print "tag: ", name.tag
        print "text: ", name.text
        
    実行結果
    > python test03.py
    root.tag: breakfast_menu
    foods: 
    food: 
    child.tag: name
    child.tag: price
    child.tag: description
    child.tag: calories
    tag: name
    text: Belgian Waffles
    food: 
    child.tag: name
    child.tag: price
    child.tag: description
    child.tag: calories
    tag: name
    text: Strawberry Belgian Waffles
    food: 
    child.tag: name
    child.tag: price
    child.tag: description
    child.tag: calories
    tag: name
    text: Berry-Berry Belgian Waffles
    food: 
    child.tag: name
    child.tag: price
    child.tag: description
    child.tag: calories
    tag: name
    text: French Toast
    food: 
    child.tag: name
    child.tag: price
    child.tag: description
    child.tag: calories
    tag: name
    text: Homestyle Breakfast
        

[Python][XML] minidom - Node のデータ表示

各 Node のデータを順番に表示する
test02.py
# -*- coding:utf-8 -*-
import xml.dom.minidom

# Node のデータを表示する
def dispNodeData(node, tag):
l = node.getElementsByTagName(tag)
for n in l:
    print n.nodeName, " - ", n.childNodes.item(0).nodeValue

# Main function
dom = xml.dom.minidom.parse('test01.xml')
foods = dom.getElementsByTagName('food')
for food in foods:
    print "nodeName: ", food.nodeName
    dispNodeData(food, 'name')
    dispNodeData(food, 'price')
    dispNodeData(food, 'calories')

実行結果
> python test02.py
nodeName: food
name - Belgian Waffles
price - $5.95
calories - 650
nodeName: food
name - Strawberry Belgian Waffles
price - $7.95
calories - 900
nodeName: food
name - Berry-Berry Belgian Waffles
price - $8.95
calories - 900
nodeName: food
name - French Toast
price - $4.50
calories - 600
nodeName: food
name - Homestyle Breakfast
price - $6.95
calories - 950

[Python][XML] xml.dom.minidom

XML を解析するには minidom を使う

test01.xml
  <?xml version="1.0" encoding="utf-8"?>
  <breakfast_menu>
    <food id="0">
      <name>Belgian Waffles</name>
      <price>$5.95</price>
      <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
      <calories>650</calories>
    </food>
    <food id="1">
      <name>Strawberry Belgian Waffles</name>
      <price>$7.95</price>
      <description>light Belgian waffles covered with strawberries and whipped cream</description>
      <calories>900</calories>
    </food>
    <food id="2">
      <name>Berry-Berry Belgian Waffles</name>
      <price>$8.95</price>
      <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
      <calories>900</calories>
    </food>
    <food id="3">
      <name>French Toast</name>
      <price>$4.50</price>
      <description>thick slices made from our homemade sourdough bread</description>
      <calories>600</calories>
    </food>
    <food id="4">
      <name>Homestyle Breakfast</name>
      <price>$6.95</price>
      <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
      <calories>950</calories>
    </food>
  </breakfast_menu>

test01.py
# -*- coding:utf-8 -*-
import xml.dom.minidom
import pprint

dom = xml.dom.minidom.parse('test01.xml')
pprint.pprint(dom)

# NodeList
foods = dom.getElementsByTagName('food')
print "NodeList(food)"
pprint.pprint(foods)
print "length: %s" % (foods.length)

# Node
food = foods.item(0)
pprint.pprint(food)
print "Node(food)"
print "nodeType: ", food.nodeType
print "nodeName: ", food.nodeName
print "hasChildNodes(): ", food.hasChildNodes()
print "hasAttributes(): ", food.hasAttributes()

# NodeList
names = food.getElementsByTagName('name')
print "NodeList(name)"
pprint.pprint(names)
print "length: ", names.length
name = names.item(0)
print "Node(name)"
pprint.pprint(names)
print "nodeType: ", name.nodeType
print "nodeName: ", name.nodeName
print "nodeValue: ", name.nodeValue
print "hasChildNodes(): ", name.hasChildNodes()
print "hasAttributes(): ", name.hasAttributes()

# NodeList
nameDatas = name.childNodes
print "NodeList(data)"
pprint.pprint(nameDatas)
print "length: ", nameDatas.length

# Node
data = nameDatas.item(0)
print "Text Node(data)"
pprint.pprint(data)
print "nodeType: ", data.nodeType
print "nodeName: ", data.nodeName
print "nodeValue: ", data.nodeValue
print "data: ", data.data

# nodeType 定数
print "nodeType constants"
node = xml.dom.Node
print " ELEMENT_NODE : ", node.ELEMENT_NODE
print " ATTRIBUTE_NODE : ", node.ATTRIBUTE_NODE
print " TEXT_NODE : ", node.TEXT_NODE
print " CDATA_SECTION_NODE : ", node.CDATA_SECTION_NODE
print " ENTITY_NODE : ", node.ENTITY_NODE
print " PROCESSING_INSTRUCTION_NODE: ", node.PROCESSING_INSTRUCTION_NODE
print " COMMENT_NODE : ", node.COMMENT_NODE
print " DOCUMENT_NODE : ", node.DOCUMENT_NODE
print " DOCUMENT_TYPE_NODE : ", node.DOCUMENT_TYPE_NODE
print " NOTATION_NODE : ", node.NOTATION_NODE

実行結果
> python test01.py
<xml.dom.minidom.Document instance at 0x00B402D8>
NodeList(food)
[<DOM Element: food at 0xb45418>,
<DOM Element: food at 0xb457d8>,
<DOM Element: food at 0xb45b98>,
<DOM Element: food at 0xb45f58>,
<DOM Element: food at 0xb4b350>]
length: 5
<DOM Element: food at 0xb45418>
Node(food)
nodeType: 1
nodeName: food
hasChildNodes(): True
hasAttributes(): True
NodeList(name)
[<DOM Element: name at 0xb45530>]
length: 1
Node(name)
[<DOM Element: name at 0xb45530>]
nodeType: 1
nodeName: name
nodeValue: None
hasChildNodes(): True
hasAttributes(): False
NodeList(data)
[<DOM Text node "u'Belgian Wa'...">]
length: 1
Text Node(data)
<DOM Text node "u'Belgian Wa'...">
nodeType: 3
nodeName: #text
nodeValue: Belgian Waffles
data: Belgian Waffles
nodeType constants
ELEMENT_NODE : 1
ATTRIBUTE_NODE : 2
TEXT_NODE : 3
CDATA_SECTION_NODE : 4
ENTITY_NODE : 6
PROCESSING_INSTRUCTION_NODE: 7
COMMENT_NODE : 8
DOCUMENT_NODE : 9
DOCUMENT_TYPE_NODE : 10
NOTATION_NODE : 12

[awk]指定した行の値を加算する

test04-3.awk
BEGIN {
 # 変数の初期化
 FS=","
 dog_sum1 = 0
 dog_sum2 = 0
 cat_sum1 = 0
 cat_sum2 = 0
}

{
 if ($2 == "dog") {
  dog_sum1 += $3
  dog_sum2 += $4
 }
 else if ($2 == "cat") {
  cat_sum1 += $3
  cat_sum2 += $4
 }
}

END {
 # 結果を表示する
 print "category,sum1,sum2"
 print "dog,"dog_sum1","dog_sum2
 print "cat,"cat_sum1","cat_sum2
}
test.csv
This is test.

1,dog,10,20
2,cat,500,200
3,dog,40,20
4,cat,10,500
実行結果
> awk -f test04-3.awk test.csv
category,sum1,sum2
dog,50,40
cat,510,700

[awk]行の先頭に文字列を追加

正規表現で先頭が数字の行を取り出し、その行の先頭に文字列を追加する test04-2.awk
BEGIN {
}

# 先頭が数字の行に文字列を追加する
{
 if (match($1, /^[0-9]/)) {
  # 先頭が数字の行を取り出す
  print "hoge,"$0
 }
}

END {

}
test.csv
This is test.

1,dog,10,20
2,cat,500,200
3,dog,40,20
4,cat,10,500
実行
> awk -f test04-2.awk test.csv > out.csv
出力結果
hoge,1,dog,10,20
hoge,2,cat,500,200
hoge,3,dog,40,20
hoge,4,cat,10,500

[awk]正規表現

match() を使うことで正規表現を使用できる。 test04.awk
BEGIN {
}

# 先頭が数字の行だけを表示する
{
 # if ($1 ~ /^[0-9]/) {
 # これを使うと buffer: と表示される
 if (match($1, /^[0-9]/)) {
  print $0
 }
}

END {

}
test.csv
This is test.

1,dog,10,20
2,cat,500,200
3,dog,40,20
4,cat,10,500
実行結果
> awk -f test04.awk test.csv
1,dog,10,20
2,cat,500,200
3,dog,40,20
4,cat,10,500
match() ではなく ($1 ~ /^[0-9]) を使った場合、buffer と表示される。
> awk -f test04.awk test.csv
buffer: T
buffer: 1
1,dog,10,20
buffer: 2
2,cat,500,200
buffer: 3
3,dog,40,20
buffer: 4
4,cat,10,500