2013/04/29

ライブラリ:shelve

Pythonの「shelve」というライブラリについてご紹介します。

import shelve

「shelve」は、Pythonオブジェクトをファイルに保存し永続化するためのライブラリです。簡易的なデータベースとして使うことができます。インタフェースが辞書型データと非常によく似ているため、シンプルに使うことができます。

ただ、個人的にはほとんど使ったことがないため細かいところがまだよくわかっていません。以下、今回調べた基本的な使い方だけ見てみます。

オブジェクトデータの保存

FILENAME = 'my.shelve'

d = shelve.open(FILENAME)
d['dogs'] = ['Taro']
d.close()
オブジェクトの保存は通常のファイルへの保存と同じように、open()とclose()の間に処理を書く形で行います。

openして得たshelveオブジェクトに、「キー&バリュー」の形でデータを与えます。ファイルが存在しない場合は新規に作成してくれます。

オブジェクトデータの読み込み

d = shelve.open(FILENAME)
print d  # {'dogs': ['Taro']}
print d['dogs']  # ['Taro']
print 'dogs' in d  # True
d.close()
shelveで保存したデータはopen()で読むことができます。shelveオブジェクトは辞書型のデータと同じように扱うことができます。

オブジェクトデータの追加

d = shelve.open(FILENAME)
dogs = d['dogs']
dogs.append('Pochi')
dogs.append('Jiro')
d['dogs'] = dogs
d.close()

d = shelve.open(FILENAME)
print d  # {'dogs': ['Taro', 'Pochi', 'Jiro']}
d.close()
バリューの部分をリストにした場合などにそのリストに要素を追加する場合には、いったんそのリストを取り出し、値を追加した後に元に戻します。

・・・以上です。


インストール
「shelve」は標準ライブラリに含まれているので、Pythonと別途インストールする必要はありません。


参考
shelve Python Module of the Week
shelve - Python公式ドキュメント

2013/04/22

ライブラリ:cmath

Pythonの「cmath」というライブラリについてご紹介します。

import cmath

「cmath」は、実数だけでなく「虚数」も含んだ、いわゆる「複素数」を扱うためのライブラリです。

Pythonのデータ型のところでも挙げましたが、Pythonには複素数を扱える数値型が用意されています。たとえば、実数部が3、虚数部が4の数値は虚数単位 j を使って次のように表すことができます。
x = 3 + 4j

虚数同士の演算も実数と同じように行えます。
x + x  # 6 + 8j
x * x  # -7 + 24j

実数部、虚数部を取り出すには x.real と x.imag を使います。
x.real  # 3.0
x.imag  # 4.0

cmathは、この複素数型の数値に対して使える基本的な関数を用意しています。以下、使う頻度が比較的高いかなと思える関数をピックアップしてご紹介します。

cmath.polar(x)  # (5.0, 0.927...)
cmath.phase(x)  # 0.927...
複素数といえば極座標、かと思うのですが、polar()とphase()は、xy座標から極座標へと座標変換を行ってくれる関数です。polar(x)は複素数xに対して、(半径r, 位相θ)というペアを返します。一方のpolar(x)は、位相のみを返します。

cmath.rect(5.1, 0.9273)  # (3.0..., 3.99...)
rect()は、polar()やphase()とは逆に、極座標からxy座標に変換する関数です。与えられた(r, θ)のペアに対して、(x, y)のペアを返します。

cmath.exp(x)
exp(x)は、複素数の範囲で指数e**xを計算する関数です。mathライブラリのexp()の場合は実数の範囲内でのみ計算を行いましたが、cmathのexp()は虚数も含めた範囲で計算を行います。

・・・以上です。


インストール
「cmath」は標準ライブラリに含まれているので、Pythonと別途インストールする必要はありません。


参考
cmath - Python公式ドキュメント

2013/04/17

ライブラリ:math

Pythonの「math」というライブラリについてご紹介します。

import math

「math」ライブラリには、数学にまつわる変数と関数が入っています。

目的によって使う関数は異なってくるかとは思いますが、mathライブラリに含まれている変数・関数のうち一般によく使われそうなものを以下にピックアップしてご紹介します。

math.pi  # πを返します 3.1415... 
math.e  # eを返します  2.718...
piとeはその名のとおり、数学でよく使う定数、円周率「π」と自然対数の底「e」(の近似値)とを返します。math内の変数はこのふたつのみです。

math.floor(5.2)  # 5を返す
math.ceil(5.2)  # 6を返す
floor()とceil()は、浮動小数点型の数値を整数に変換する関数です。floor(x)はその名のとおり下側、x以下の最大の整数を返します。一方ceil()は、x以上の最小の整数を返します。

math.floor(-5.2)  # -6を返す
math.ceil(-5.2)  # -5を返す
マイナスの数字を扱うときには、floor(x)は絶対値が大きくなる方向に、ceil(x)は逆に絶対値が小さくなる方向に丸められる点に注意が必要です。

math.trunc(5.2)  # 5を返す
math.trunc(-5.2)  # -5を返す
trunc()は、floor()、ceil()と同じく整数を返す関数ですが、こちらは、小数点以下の切り捨てを行います。ですので、引数が正の数でも負の数でも共通して0方向へと丸めてくれます。

math.exp(5)
math.log(5)
math.pow(5, 2)  # 25.0
math.sqrt(5)  # 2.236...
exp(x)、log(x)、pow(x, y)、sqrt(x)も名前のとおりで、それぞれ、e^x、log(x)、x^y、x^(1/2)を返してくれる関数です。

math.sin(1)
math.cos(1)
math.tan(1)
三角関数も用意されています。sin(x)はサイン、cos(x)はコサイン、tan(x)はタンジェントを返してくれます。いずれも引数の単位は度ではなく「ラジアン」です。三角関数についてはこれら以外にも、サインやコサインの逆となるいわゆるアークサインやアークコサイン、ハイパボリックサインなんかも用意されています。

三角関数周りの数字を扱うときには、内部での計算はラジアンで、表示するときは度で、と単位を変えることがよくあるかと思うのですが、そんなときには次の2つの関数が使えます。
math.degrees(1)
math.radians(30)
degrees()はラジアンから度に、radians()はその逆、度からラジアンに単位を変換してくれます。

・・・以上です。


ちなみに、数値の符号(正か負か)を返す関数は、mathライブラリの関数としてではなく、
sign(-5)  # -1
と単体で使えるようになっています。

複素数に関する関数については、別の「cmath」というライブラリにまとめられています。大学などの研究で使う計算を行うときには、「Numpy」「SciPy」という科学技術計算用のライブラリが便利です。


インストール
「math」は標準ライブラリに含まれているので、Pythonと別途インストールする必要はありません。


参考
math - Python公式ドキュメント

2013/04/11

ライブラリ:string

Pythonの「string」というライブラリについてご紹介します。

import string

「string」には、文字列に関係した変数や関数が含まれています。主に
  • 特定のグループの文字列をまとめた変数
  • 文字列をフォーマットする関数
の2つが入っています。

以下、そのそれぞれについて順番に見ていきます。

特定のグループの文字列をまとめた変数

アルファベットなどの文字グループをまとめた変数がいくつか用意されています。ある変数がアルファベットかどうかをチェックしたりするときに使えます。

string.ascii_lowercase
# 'abcdefghijklmnopqrstuvwxyz'が入っている
ascii_lowercaseには、アルファベットの小文字すべてが入っています。「ascii」がつかない「lowercase」というものもありますが、「lowercase」の方はロケーション(言語環境?)によって異なる場合があるそうです「ascii_lowercase」の方はロケーションに依存しない不変のものとなっています。

string.ascii_uppercase
# 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'が入っている
ascii_uppercaseはアルファベットの大文字を含んでいます。こちらも「ascii」のつかない「uppercase」がありますが、ちがいはlowercaseと同様です。

string.digits
# '0123456789'が入っている
string.digitsには、0から9までの数字が入っています。

string.punctuation
punctuationは、文字と文字の間の句読点、括弧などをまとめたものです。私の環境では「!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~」が入っていました。

string.whitespace
whitespaceは、空白や改行関連の文字をまとめたものです。私の環境では「\t\n\x0b\x0c\r 」が入っていました。

文字列をフォーマットする関数

文字列をフォーマットする関数のうち、Python3で使う頻度が高いのはformat()でしょうか。こちらは文字列のメソッドとして、次のようにして使うようです。
'{0}, {1}, {2}'.format('a', 'b', 'c')
# 'a, b, c'が返される

私はPython3を使っていないため、現状このformatは使ったことがほとんどありません。

その他には、文字列を大文字にしたり小文字にしたり、小技をこなす関数がたくさん用意されています。
string.capitalize(文字列)  # 各単語の先頭を大文字にする
string.lower(文字列)  # すべて小文字に
string.upper(文字列)  # すべて大文字に
string.join(リスト, セパレータ)  # リストをjoin
string.strip(文字列)  # 先頭と末尾の空白を削除
string.replace(文字列, 変更したい文字, 変更後の文字)  # 置換

ただ、これらについてはstr型変数のメソッドとして同じ名前のものが用意されているため、この用途でわざわざstringライブラリを読み込んで使う機会は多くないかと思います。

・・・以上です。


インストール
「string」は標準ライブラリに含まれているので、Pythonと別途インストールする必要はありません。


参考
string - Python公式ドキュメント

2013/04/04

ライブラリ:random

Pythonの「random」というライブラリについてご紹介します。

import random

「random」は、乱数に関係したライブラリです。標準ライブラリのひとつで、Pythonをインストールするとデフォルトで入っています。

0から1の間の浮動少数点数を返すrandom()をベースに、整数を返す関数、与えられた任意のリストの中からひとつを抽出する関数など乱数関連の関数が豊富に用意されています。

以下ではその中からいくつかピックアップしてご紹介します。

random.random()
random()は、0.0から1.0の間の浮動小数点数を返します。厳密には区間[0.0, 1.0)、つまり、0ちょうどを含む「0以上」から1ちょうどを含まない「1未満」までの数を返します。

random.randrange(start, stop)
randrange()は、startからstopまでの整数の中からランダムにひとつを返します。forループでよく使うrange(start, stop)と同じように、startそのものは含みますが、stopそのものは含みません。つまり、「start、start+1、start+2、...、stop-1」の合計「stop-start」個の整数が抽出対象の集合となります。

random.randint(a, b)
こちらもrandrange()と同じく、整数をランダムに選んで返す関数です。randrange()とのちがいは、上限の値を含むかかどうか、のちがいです。randint(a, b)の場合は、a、bの値をともに含みます。数学的に書けば、「integer n s.t a <= n <= b」となります。

random.choice([リスト])
choice()は、与えたリストの要素からひとつ、ランダムにピックアップして返します。リストだけでなく、文字列、タプルなど、シーケンス型の変数であれば引数に取ることができます。

random.choice([1, 2, 3, 4])  # たとえば3
random.choice(mydict.items())  # items()などと組み合わせれば辞書の要素もランダムで選べます

random.sample([リスト], [整数])
choice()がひとつだけ値を取り出すのに対し、sample()は複数の要素を重複なく取り出してくれる関数です。もしもとのリストで要素が重複していた場合は、重複分だけその要素を取り出す確率が高くなります。

この関数を使えば、たとえば、高校数学で習った組み合わせの問題の「袋に7コの玉が入っています。赤い玉が4つ、白い玉が3つ、その中から3つ取り出したときの・・・」なんてシミュレーションも

random.sample(['r', 'r', 'r', 'r', 'w', 'w', 'w'], 3)  # ['w', 'r', 'w']など

という風に簡単に実現できます。

私は実際に使ったことはありませんが、一様分布だけでなく、正規分布、三角分布、ガウス分布など異なる分布をもつランダム値を扱う関数なんかも用意されています。


インストール
「random」は標準ライブラリに含まれているので、Pythonと別途インストールする必要はありません。


参考
random - Python公式ドキュメント

2013/04/01

Pythonの例外処理

Pythonにおける例外処理について説明してみたいと思います。

Pythonでは、例外処理の「try catch」のロジックは「try~except」で実現することができます。

以下、最も基本的な使い方から順にいくつか発展形を見ていきます。

try - except

try:
    f = open('sample.txt', 'r')
except:
    print 'cannot open sample.txt'
tryのブロックの中にある処理を行なって、例外(エラー)が発生したらexceptの方の処理へと移ります。

例外が発生しなかった場合は、exceptのブロックはパスしてtry後の手続きへと進んでいきます。


try - except ExceptionName

try:
    f = open('sample.txt', 'r')
except IOError:
    print 'cannot open sample.txt'
エラーの種類を限定して例外処理を行いたい場合は、exceptの後に例外のクラス名を渡します。上の場合ですと、入出力に関わるIOErrorのみをキャッチします。


try - except ExceptionName, var

try:
    f = open('sample.txt', 'r')
except Exception, e:
    print e, 'error occurred'
exceptで捉えたエラーがどんなエラーだったのか確認したい場合は、「exept 例外名, 変数名」とすると、渡した変数にエラーの名前が入ります。上の場合ですと、eの部分にエラー名が入ります。


try - except - else

try:
    f = open('sample.txt', 'r')
except:
    print 'cannot open sample.txt'
else:
    lines = f.readlines()
elseブロックをつけると、例外が発生しなかった場合にだけ行いたい処理を指定することができます。


try - except - finally

try:
    f = open('sample.txt', 'r')
except:
    print 'cannot open sample.txt'
finally:
    f.close()
finallyブロックをつけると、例外が発生してもしなくても、いずれの場合でも共通で行う処理を指定することができます。

finallyは基本的にtry~exceptの処理の最後に実行されるようです。ただ、tryのブロックの中で例外が発生したのにそれががどのexceptでもキャッチされなかった場合には、少し複雑な流れになるようです。finallyを正しく使うには公式のドキュメントなどを参照したうえで使うのがよいかと思います。

また、例外を正しく扱うには、どういった種類の例外があるのか、事前に調べておくのがよいかと思います。そちらのチェックも公式ドキュメントがおすすめです。

以上です。


例外処理に関しては、次のようにPEP20 Zen of Pythonでも言及されています。
Errors should never pass silently.
Unless explicitly silenced.
このあたり、Pythonの言語設計のベースの考え方とも直結しているみたいです。


参考
エラーと例外 - Python公式ドキュメント
例外の種類 - Python公式ドキュメント