みろりHP


緑色さんの多目的ブログ
みろりえいちぴー
ごゆるりとおくつろぎあさーせ。
| カテゴリ:プログラミング |
Brett Slatkin『Effective Python』その3 クラスと継承



前回に続いて、クラスの章で楽しめたところをノートしていく。



記録管理に辞書じゃなくてヘルパークラスを使う
もちろん簡単なやつなら辞書でいい。クラスを使うタイミングとしては「辞書が入れ子になっちゃった」、「タプルが3以上の要素数をもっちゃった」など。
これは自作ゲーム『一石二鳥』のとき何を参考にするでもなく自然にできてたからよさげ。

フック
list.sort(key=lambda...)

みたいに関数を渡して振る舞いをカスタマイズする仕組みをフックというそうだ。
そもそもsortに関数を渡せることを知らんかった……。

__call__を定義するとオブジェクトが関数みたいに呼び出せる
すげー! じゃあstrクラスを改造すれば
'ただの文字列'()

なんてことができるってことかよw
と思ってすこしいじってみたんだが、どうやら文字列などの組み込み型は改造ができんようになってるようで……。このイタズラは完遂できなかった。

クラスメソッドをコンストラクタとして使う
@classmethod
def foo(cls):
    return cls()
こういう……ことだとは思うんだけどこれだけじゃ意味不明だよな。

子クラスで親クラスの__init__を呼ぶとき
super().__init__()

とする。親クラスのメソッドは子クラスでも息づくんだから、こんなの必要ないじゃんと思ったが。そっか、子クラスにinitを書いてしまったら親クラスのinitは実行されなくなっちゃうのか。

private属性の使い方
self.__foo

こういう命名の変数はprivate属性になってクラス内でしかアクセスできなくなる。子クラスからもダメ。ただし
_Klass__foo

っていう呼び出し方でコールすることが可能。
private変数は、コントロール外のサブクラスによる名前衝突を避けるために使いましょう。



クラスは理解したからこの章はまあオッケーだった。が、次章がどうもするりと入ってこねえ……。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Brett Slatkin『Effective Python』その2 関数



前回に続いて、関数のパートで楽しめたとこをノートしていく。



関数返り値にNoneを設定するのはヤメて、例外を飛ばせ。
try:
    return a/b
except ZeroDivisionError as e:
    raise ValueError('えらぁだよ') from e
てかこうやってエラーの種類を変えられるの知らなかったわ。

Pythonはクロージャをサポートしてる。
クロージャってのは、定義されたスコープの変数を参照する関数のこと。ああ、関数の中から外の変数を使えるもんね。アレのことか。

タプルの比較規則。
(0, b) (1, a)
の場合、まず[0]の0と1、そのつぎに[1]のbとaの比較になる。

nonlocal宣言でローカル変数の参照渡しみたいなことができる。
def foo():
    a = 'fooのa'

    def bar():
        nonlocal a
        a += 'なぁんつって'

    bar()
    print(a)  # fooのaなぁんつって

foo()
こういうことか。aがグローバル変数だった場合 nonlocal じゃなくて global になるところが注意。

リストを作成して返す関数は、もしかしたらジェネレータ関数にできるんじゃない?
やり方は
lis.append(x)
していたところを
yield x
にするだけ。
これはかなりいいのでは? プログラミング問題とかでよくでかいリストを返す関数を作ってたけど、あれは全部エコなジェネレータにできるってことか。

可変長位置引数で見た目をすっきりさせよう。
def foo(message, *args):

こういうやつね!
foo('メッセージ', 1, 2, 3, 4)

って呼び出せば、1以降がリストになって args に代入される。……ん? いや別に、最初からリストで渡せばよくね?
ちなみにすでにリストになってるなら
foo('メッセージ', *list)

って渡せる。いや、最初からリストでよくね???
可変長位置引数を使うとき注意しないといけないことがあって、たとえば上の foo を
foo(message, message2, *args)

に定義変更しても呼出でエラーは起こらない。これは発見困難バグを生むのでやばい。さらに、これにジェネレータを渡すと勝手にタプルにするからメモリ爆発することがある。いやメンドくせーよ! 最初からリストで渡せばいいだろ!

キーワード引数、デフォルト引数は良い。
def foo(message, option1=1, option2=2):
見るからに使い勝手いい。

デフォルト引数には罠がある。
def foo(message, when=datetime.now()):
こうするとwhenのデフォルト値は定義時の時間で固定されちゃう。fooを呼び出すたびにその時間を取得してほしいなら、デフォルト引数Noneを使う。
def foo(message, when=None):
    when = datetime.now() if when is None else when

こんな罠もあるよ♪
def foo(x, dic={}):
    dic[x] = 1
    return dic

print(foo('a'))  # {a:1}
print(foo('b'))  # {a:1, b:1}  クソワロタww
定義時にひとつのディクショナリが定義されちゃってて、以降デフォルト引数にはそのディクショナリオブジェクトが使われ続けるので、こーゆーことになる。これも上と同じで None を使う。

キーワード専用引数。
これはすげぃ。
def foo(a, b, *, option1=False, option2=False):
こうすると、option1以降の引数はキーワードでしか指定できなくなる。完全にオプション専用の引数ができるってことじゃん。
Python2ではこの構文がないのだけど、同じ動作を作ることはできる。
def foo(a, b, **kwargs):
    option1 = kwargs.pop('option1', False)
    option2 = kwargs.pop('option2', False)
    if kwargs:
        raise TypeError('Unexpected **kwargs')




今回のフェイバリットは最後のキーワード専用引数かな。すげえ便利そう。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python 迷路を解くプログラム



例によってプログラミング問題です。問題を見た瞬間おっもしろそー! と思った。
# これを……   ->  こうする!

# ########      #+########
# ## ### #      #+## ### #
#    ##  #      #++++##  #
####    ##      ####+   ##
# ## #####  ->  # ##+#####
#    #   #      #++++#+++#
# #### # #      #+####+#+#
#      # #      #++++++#+#
## ## ## #      ## ## ##+#
######## #      ########+#



みどりんの考えたのがこういうロジック。







メインロジック。いちばん上の solve_maze がトップレベル。
import os, itertools, copy, enum

def solve_maze(maze):
    """迷路を解きます。"""

    # 最初の奴隷を用意します。
    first_walker = Walker()

    # 通路座標を奴隷の歩行可能座標として登録します。
    first_walker.walkable_points = maze.pathways

    # こいつをスタート地点に立たせます。
    first_walker.start_point = maze.start_point
    first_walker.step_to(maze.start_point)

    # 分かれ道のたびに、奴隷を増殖させて袋小路まで進ませます。
    # そのたびにwalkersリストに追加されるので、最終的に全通りのルートがwalkersに登録されることになります。
    walkers = [first_walker]
    for walker in walkers:

        # 奴隷ひとりにつき再帰関数ひとめぐり。
        walker_life(walker, walkers)

    # 勝者を決めます。
    winner = compete_walkers(walkers, maze)
    return winner


def walker_life(walker, walkers):
    """奴隷の歩みを処理する再帰関数です。"""

    # 今いるマスの東西南北に道があるか調べます(一度踏んだマスは通れない)。
    next_points = walker.look_around_next_points()

    # 進める場所がない場合、そいつは終了です。
    if not next_points:
        return

    # 道がひとつだけある場合、次のマスへ移動させます。
    if len(next_points) == 1:
        walker.step_to(next_points[0])

    # 道が2以上ある場合、奴隷を分裂させます。
    else:
        process_for_multiple_possibilities(walker, next_points, walkers)

    walker_life(walker, walkers)


def process_for_multiple_possibilities(walker, next_points, walkers):
    """道が2以上ある場合の処理です。forが長くなるのヤだから分離しました。"""

    # 進む前の奴隷をコピーしておきます。
    walker_copies = [walker.create_myself() for i in range(len(next_points) - 1)]

    # 現奴隷は次のマスへ移動します。
    walker.step_to(next_points[0])
    next_points.pop(0)

    # コピーした奴隷たちを、それぞれ別の分かれ道へ進ませます。
    # そして次の while のためwalkersリストに溜めておきます。
    for walker_copy, next_point in zip(walker_copies, next_points):
        walker_copy.step_to(next_point)
        walkers.append(walker_copy)


def compete_walkers(walkers, maze):
    """最優秀ゴール者を決めます。関数が長くなるのヤだから分離しました。"""

    # 奴隷の中から、ゴールした連中を取り出します。
    goal_walkers = list(filter(lambda walker: walker.stand_point == maze.goal_point, walkers))

    # インデックスとwalker.step_numのディクショナリ。{0:30, 1:25, 2:10}みたいになる。
    dic = {i: goal_walker.step_num for i, goal_walker in enumerate(goal_walkers)}

    # step_numでの昇順ソート。[(2,10), (1,25), (0,30)]みたいになる。
    ranking = sorted(dic.items(), key=lambda value: value[1])

    # ゴール者の中で、最短距離をいった者が最優秀ゴール者です。
    return goal_walkers[ranking[0][0]]

迷路のマスを定義する。ぶっちゃけ今回のプログラムではあんまり必要ないクラスだけど enum っていうのを使ってみたくてさあ。
class MazeSigns(enum.Enum):
    """ 迷路のマスをenumで定義してみます。
        具体値の取り出し方は MazeSigns.WALL.value こう。"""

    WALL = '#'
    PATHWAY = ' '
    FOOTPRINT = '+'
    STAND_POINT = '*'

迷路データを簡単に扱えるようにするクラス。ちょっと色気づいて、最近オライリーで覚えた private 属性を使ってみた。
class Maze:
    """ 迷路データを簡単に扱うためのクラス! 
        ほら、文字列のままだと座標指定でマスを取得するとかできないじゃん?
        そういうのができるようになります。10x10だけに対応してるよ!"""


    def __init__(self, original_maze):
        self.original_maze = original_maze

        # MazeSignsのディクショナリ。
        self.sign_dic = {sign.value:sign for sign in MazeSigns}
        # マップ文字列を二次元配列にしたものです。
        self.map_list = self.__convert_map_to_list()
        # 通路部分の座標のリストです。
        self.pathways = self.__make_pathways()
        # この迷路のスタート地点とゴール地点です。
        _ = self.__get_entrances()
        self.start_point = _[0]
        self.goal_point  = _[1]


    def __convert_map_to_list(self):
        """(private)マップ文字列を二次元配列にして、中身を全部MazeSigns型に変換します。"""

        lines = list(filter(lambda line: line != '', self.original_maze.split(os.linesep)))
        lines.reverse()

        # マネしちゃダメな堂々の二重内包表記。クソ読みづらい(笑)
        return [[self.sign_dic[cell] for cell in list(line)] for line in lines]


    def __make_pathways(self):
        """(private)歩行可能座標のリストを作ります。"""

        # 通路の部分の座標を求めます。
        pathways = []
        for x, y in itertools.product(range(10), range(10)):
            if self.map_list[y][x] == MazeSigns.PATHWAY:
                pathways.append((x, y))
        return pathways


    def __get_entrances(self):
        """(private)迷路のスタート地点とゴール地点を求めます。"""

        entrances = []
        for coordinate in self.pathways:
            if coordinate[0] in [0, 9] or coordinate[1] in [0, 9]:
                entrances.append(coordinate)
        return entrances

迷路を歩かせる奴隷を作成するクラス。
class Walker:
    """迷路を歩く奴隷を意味するクラス! 自分が歩いた座標を記録していくよ!"""

    # インスタンスひとつひとつに振るIDです。
    walker_id = 0


    def __init__(self):

        # ID。
        self.walker_id = Walker.walker_id
        # 初期座標。
        self.start_point = None
        # 現在地。
        self.stand_point = None
        # 歩行可能座標。
        self.walkable_points = []
        # 歩行履歴。
        self.walk_history = []
        # 歩行数。
        self.step_num = 0


    def __str__(self):
        """str(walker)したとき現在のコイツの状態を返します。"""

        return os.linesep.join([
            f'',
            f'初期座標:{self.start_point}',
            f'現在地:{self.stand_point}',
            f'残歩行可能座標:{self.walkable_points}',
            f'歩行履歴:{self.walk_history}',
            f'歩行数:{self.step_num}',
        ])


    def step_to(self, next_point):
        """引数の座標へ歩みます。"""

        self.stand_point = next_point
        self.walk_history.append(next_point)
        self.walkable_points.remove(next_point)
        self.step_num += 1


    def look_around_next_points(self):
        """今のマスの東西南北に歩行可能マスがあるか調べます。"""

        # 東西南北の座標です。
        next_points = [
            (self.stand_point[0], self.stand_point[1]+1),
            (self.stand_point[0], self.stand_point[1]-1),
            (self.stand_point[0]+1, self.stand_point[1]),
            (self.stand_point[0]-1, self.stand_point[1]),
        ]

        # 進める座標は、歩行履歴になくて歩行可能座標にあるもの。
        next_points = filter(lambda point: point not in self.walk_history, next_points)
        next_points = filter(lambda point: point in self.walkable_points, next_points)
        return list(next_points)


    def create_myself(self):
        """自分自身のコピーを作ります。"""

        walker = copy.deepcopy(self)
        walker.walker_id += 1
        return walker


    def draw_steps_on_map(self, maze):
        """自分が歩いた軌跡をマップに書きます。"""

        map_list = maze.map_list
        for coordinate in self.walk_history:
            map_list[coordinate[1]][coordinate[0]] = (
                MazeSigns.STAND_POINT if coordinate == self.stand_point else MazeSigns.FOOTPRINT)

        # 文字列にします。マネしちゃダメな堂々の 3重 内包表記。クッソ読みづらい。
        map_list.reverse()
        return os.linesep.join([''.join(m) for m in [[maze_sign.value for maze_sign in line] for line in map_list]])

実行はこんな感じ。
#####################################################################
# ここまでプログラム。ここから実施。
#####################################################################

questions = [
'''
##########
##########
##########
###       
###   ####
###   ####
###   ####
###   ####
      ####
##########
''',
'''
##########
###      #
### ## # #
### ## # #
#   ##    
# # #### #
# #      #
# ########
#     ####
##### ####
''',
]

for i, question in enumerate(questions):
    maze = Maze(question)
    winner = solve_maze(maze)
    print()
    print(f'-*-*-*-* question{i} *-*-*-*-')
    print(winner)
    print(winner.draw_steps_on_map(maze))

結果はこう!
-*-*-*-* question0 *-*-*-*-
<Walker オブジェクト ID:2>
初期座標:(0, 1)
現在地:(9, 6)
残歩行可能座標:[(3, 2), (3, 3), (3, 4), (3, 5), (3, 6),
              (4, 2), (4, 3), (4, 4), (4, 5), (4, 6)]
歩行履歴:[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1),
         (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (6, 6),
         (7, 6), (8, 6), (9, 6)]
歩行数:15
##########
##########
##########
###  ++++*
###  +####
###  +####
###  +####
###  +####
++++++####
##########

-*-*-*-* question1 *-*-*-*-
<Walker オブジェクト ID:2>
初期座標:(5, 0)
現在地:(9, 5)
残歩行可能座標:[(3, 6), (3, 7), (3, 8), (4, 8), (5, 8),
              (6, 5), (6, 6), (6, 7), (6, 8), (7, 5),
              (7, 8), (8, 6), (8, 7), (8, 8)]
歩行履歴:[(5, 0), (5, 1), (4, 1), (3, 1), (2, 1),
         (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
         (2, 5), (3, 5), (3, 4), (3, 3), (4, 3),
         (5, 3), (6, 3), (7, 3), (8, 3), (8, 4),
         (8, 5), (9, 5)]
歩行数:22
##########
###      #
### ## # #
### ## # #
#+++##  +*
#+#+####+#
#+#++++++#
#+########
#+++++####
#####+####



迷路を解くだけでなく、最短距離を求められてる。完璧! クラスを効果的に使えてるし、内包表記や高階関数を使いすぎなまでに使ってるし、再帰関数も使えてる。満足!


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Brett Slatkin『Effective Python』その1 Python流思考



いえーい。最近はPythonの気分なので、その流れで読むぜ。面白かったとこをノートするいつものノリで。




PEP8をまもれ!
Python本はこればっかですね! 先日までSublime Text3にPEP8のチェッカーパッケージを入れていたんだけど、「ほかのひとのコードをネットからコピペしたときペケだらけになって非常に見づらい」「関数間を2行空ける」の2点がイヤでヤメちまった。まあ基本的なところは守っているぜ。
例として記載されていたなかで目新しかったのが下記ふたつ。
len(lis) == 0
ではなく
not lis
を使いましょう。
・import文は標準モジュール、サードパーティ、自前のモジュールの順番に記載する。

PEP8で気に入ってるやつ
コーディング規約ってのは、知ると目ウロコなものがたくさんある。とくに気に入ってるのが、「一行は79文字以下におさめましょう」ってやつ。これを守るとスクリプトがスッキリして見える。積極的に守っていきたい。
どうしても行が長くなることってあるじゃん? クラス名もメソッド名も長いから書こうとしたらどうしても幅とっちゃうんだよー、とか引数が多いから仕方ないじゃん、とか入れ子が多くなればなるほどインデントが増えるんだからどうしようもないじゃんとか。でもさ、そういうときコーディング規約はこう言ってくるんだよ。「そういうときは設計がおかしい。」この発想は気に入った。そもそも名前は短いほうがいいし、引数はなるたけ少なくするのが基本だし、forとかifの入れ子は少なくするべきだ。

文字列型の bytes と str を知っておく。
文字列型には上記ふたつがあって、それぞれ変換は……
bytes_.decode('UTF8')  # str化
str_.encode('UTF8')    # bytes化
ほんでバイナリファイルの読み書きでは、open関数のオプションに rb とか wb を使うこと。まあそれはいいけどバイナリファイルなんてどんなときにいじるのか俺には想像がつかん。アレだろバイナリって、0と1だけの……。

ディクショナリ.get(キー, None)
キーがなければNoneを返す、というディクショナリのメソッド。うわこれ知らんかった、便利そうだ。

ヘルパー関数を使いましょう。
Pythonは複雑で読みづらい式を1行で書きやすい。そういうときは行を分けて読みやすくして、それをヘルパー関数にまとめましょう。最近高階関数を覚えて大はしゃぎでコードを難読化してる俺には耳が痛いお話です。

スライスを使おう!
lis[0:5]
lis[:5]
は同じ。後者を使いましょう。うへえ、0書いてたわあ。
[::2]
みっつめにはstride……なん文字ごと、が指定できる。

スライスではstart,end,strideをいっしょに使うな。
lis[2:10:2]
はダメ。わかりづらいから。やるなら2行に分けること。

mapやfilterの代わりにリスト内包表記を使おう!
そうか……mapやfilterって、内包表記に置き換えることができるのか。これは目ウロコだ。
a = [0, 1, 2, 3, 4, 5]

# だよんをつける map版
print(list(map(lambda i: f'{i}だよん', a)))

# だよんをつける 内包表記
print([f'{i}だよん' for i in a])
# ↓どちらもこうなる
['0だよん', '1だよん', '2だよん', '3だよん', '4だよん', '5だよん']
# 奇数のみ filter版
print(list(filter(lambda i: i%2 == 1, a)))

# 奇数のみ 内包表記
print([i for i in a if i%2 == 1])
# どちらもこうなる
[1, 3, 5]
……ってことか。この例ではだけど、内包表記を使えば文字数は短くなるし、わざわざlist()を使わなくて済む。逆に結果をイテレータのままにしたい場合はmap、filterの使い所だろうね。
mapとかfilter、内包表記をさらっと書ける自分に成長を感じる! いやあプログラムはじめてから2年たってるもんなあ。

内包表記ではforを重ねることもできるぞ!
rows = [
    [0, 1, 2],
    [3, 4, 5],
]

# 二重forバージョン
_ = []
for row in rows:
    for r in row:
        _.append(r)
print(_)

# 内包表記バージョン
print([r for row in rows for r in row])
# どっちもこうなる
[0, 1, 2, 3, 4, 5]
ただし3つ以上になったらヤメとくこと。読みづらくなるから、ヘルパー関数とか使いましょう。
ところで二重の内包表記の書く順番ってちょっと間違えやすくない? 最初forを二重に内包表記って聞いて、こうかと思った。
[r for r in row for row in rows]

作ろうとしてるリストがバカでかくなっちゃうときは、ジェネレータを使おう!
lis = [i for i in range(10000000000)]
こんなことしたら10000000000個要素が詰まったリストが生成されてメモリが爆発しちゃいそうじゃん? そんなときは
gene = (i for i in range(10000000000))
こうする。中身の取り出しは
next(gene)
これでいっこずつ取り出せる。lis[10]みたいに途中の要素を取り出すことができないのが難点かな? でもでっけえリストを生成しないってのはイイね。

連鎖ジェネレータはすげえ高速。
gene  = (a for a in open('foo.txt', 'r', encoding='UTF8'))
gene2 = (a.strip() for g in gene)

enumerate()の使い所は……リストを回したいが添字も欲しいとき!
for i, value in enumerate(lis, 1):
    print(i, value)
こういうこと。enumerateに第二引数を指定すれば、iがその数からスタートになる。別にlis[1]からスタートってわけじゃない。これ便利ね。

複数のイテレータを回したいならzip()を使うこと。
ああー、これは言われなくても知ってるよー。
# ただしイテレータの長さが違うと、片方が終わったところで終了しちゃう。
# それがイヤなときは itertools.zip_longest() を使うこと。
それはまったく知りませんでしたすみません。

for - else っていう構文がある。
へー! しらなかった!
# が、それは振る舞いが直感的じゃないから使うな。
えー!?

try, except, else, finally の使い分け。
try: 例外が起こるかもしれないコード
except: 例外が起こったときやること
else: tryが成功したときすること。ここをしっかり書いて、tryブロックを最小にしよう!
finally: file.close()など後始末を。「たとえelseでreturnが起こってもこのブロックは実行される。」へぇえー!!

| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python 素数



って、またpythonかよ。最近はホントpythonの波がきてる。

例によってプログラミング問題。今回は「与えられた数nまでの素数を列挙する」。最初に言ってしまうと今回のスクリプトは完全に俺の自力作ってわけじゃない。はじめに書いたものは以下のような仕組みだった。

# 1. [2〜n]のリストを作る。
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... n]

# 2. 下から順番に素数かどうかチェックする。2からその数までの数で割ってみて、割り切れなかったら素数である。
[2(素数だッ), 3(素数だッ), 4, 5, 6, 7, 8, 9, 10, 11, ... n]

# 3. 素数確定したら、リストからその数の倍数を全部削除していく。
[2(素数だッ), 3(素数だッ), , 5, , 7, , , 10, 11, ... n]

完成はしたのだけど、知り合いが言い出した。
「これ2〜nまで全部そのチェックしてんの? nの平方根まででよくない?

マジで? nが100だったら10までチェックすればいいってこと? なんで?

これの理解に時間を使っちゃったんだが、知り合いの根気強い解説もありなんとか以下のような理解ができた。
  • 2から平方根数までは上述の俺の発想で問題ない。
  • 「平方根より上はチェック必要ないよ」と言われて俺が疑問なのは、「平方根より上の素数の倍数が残ってたらどうすんの?」ってことだ。でもそれが杞憂だったんだよ。
  • なぜかといえば、平方根より上の数の倍数で、かつnまでに収まる数を作るには平方根未満の数を相方に使わないといけないからだ。そして平方根未満の数の倍数については上述のチェックで終了している。
  • どっちも平方根を超えた数だったら、nより大きい数になっちゃう。その数は対象外だから問題ない。
  • よって、俺が心配していた「平方根より上の素数の倍数」はチェック済み、または対象外ということになる。なーんだ!

n=25としたときの具体例で復習してみる。
    2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
  • 2から5までは上述の俺の発想で問題ない。
  • 6から上の数の倍数で、かつ25までに収まる数を作るには5未満の数を相方に使わないといけない。そして2,3,4の倍数については上述のチェックで終了しているから問題ない。
  • どっちも平方根を超えた数、6以上だったら、25より大きい数になっちゃう。その数は対象外だから問題ない。



というわけで完成した回答がこれ。
# get_primes.py

from math import sqrt

def get_primes(n):
    '''2からnまでの素数を求めます。'''

    # boolスイッチ。素数じゃないもののスイッチをFalseにしていきます。
    switches = [b > 1 for b in range(n+1)]

    # 素数チェックはnの平方根まででOK。
    for i in range(int(sqrt(n))+1):

        # スイッチがFalseのものは、0,1,または下の倍数スイッチオフの対象になったものです。
        if switches[i] is False:
            continue

        # 素数を残しつつ、その倍数のスイッチをFalseにしていきます。
        j = i * 2
        while j <= n:
            switches[j] = False
            j += i

    # スイッチがTrueのものが素数です。
    return [i for i in range(len(switches)) if switches[i] is True]

実行結果。素数のプログラムは速ければ速いほど良いというので時間も出してみた。
import time

# 計測開始。
start = time.time()

# 実行。
import get_primes
print(len(get_primes.get_primes(100000)))

# 計測結果。
my_time = time.time() - start
print(f'my_time : {my_time}')

#
# 9592 (2〜100000間の素数の数)
# my_time : 0.031523704528808594 (かかった秒数)
#


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python Decimalでひとネタ



パイソニスタ・ショート・ショート。『float と Decimal』。

print(0.1 * 3.0)
# 結果 0.30000000000000004  なんじゃそらー

print(Decimal('0.1') * Decimal('3.0'))
# 結果 0.3

つかえねーな float は。へへへ Decimal の旦那ぁ! 頼りになるのは旦那だけでさ!

print(1.0 / 3.0 * 3.0)
# 結果 1.0

print(Decimal('1.0') / Decimal('3.0') * Decimal('3.0'))
# 結果 0.9999999999999999999999999999  なんじゃそらー

テメーもかよ Decimal のクソが!! 何のためにアンタを import したと思ってんのよ!! ペッ!!


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
シンタックスハイライトを導入する



プログラミングのブログとかでさー、スクリプトに色がついてるやつ(シンタックスハイライトっていうらしい)がよくあるじゃん。あれに憧れてみろりhpも少し装飾してみた。ただこのブログサービスの仕様による条件がひとつ。このjugemブログ、新たにCSSファイルとかJSファイルをアップロードできないんだよ。それを踏まえて今回の変更をノートしておく。



シンタックスハイライト。 code-prettifyなるライブラリを使う。Javascriptではあるのだが、ネットにスクリプトが上がっているのでそれをインポートするだけでOK。jugemブログでもそれは可能。こういうの助かるなー。
<!-- コードの装飾 -->
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>

背景色とかフォントの装飾。 CSSを自作した。新たにCSSファイルを追加することはできないのだけど、CSSを追記することは可能なので。
pre.mycode {
    padding: 0.5em, 1em;
    overflow: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
}

pre.mycode code {
    font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    font-size: 15px; /* ろりhpのデフォルトが15.2なので気持ち小さめに。 */
}

pre.mycode code:first-line {
    line-height: 0px;
}

pre.beige {
    background: #f3e9dd;
}

pre.lightgreen {
    background: #ebf9cb;
}

使い方。
<pre class="mycode lightgreen"><code class="prettyprint">
# ここにスクリプトを書く。
</code></pre>



さらにガッツリ装飾したり、行番号をつけたり背景色ごと変更するのも主流みたいだったけれど、この程度のあっさり具合がろりhpに合うと思ったんでこのくらいで。


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python プログラミング問題をやってみた2 後半戦



先回の続き。



4. ボックスサイズ
単位がセンチメートルの3つの引数をとり、体積を計算しリットルとして返す関数をかけ。
def problem4(cm1, cm2, cm3):

    # 値チェックします。
    cm = [cm1, cm2, cm3]
    for c in cm:
        if not (isinstance(c, int) or isinstance(c, float)):
            print(f'引数はintかfloatにしてよー: {c}')

    # Decimal化します。
    import decimal
    cm = map(lambda c: decimal.Decimal(str(c)), cm)

    # 立方センチメートル出します。reduceってのはなんか配列を片っ端から処理してくれるやつ。
    import functools
    cubic_cm = functools.reduce(lambda x, y: x * y, cm)

    # リットルに変換します。1000立方cm = 1.0リットル。
    return cubic_cm / 1000

実行結果。
print(problem4(2.0, 2.0, 2.0), end='\n')
print(problem4(10.0, 10.0, 10.0), end='\n')
print(problem4(123.4, 123.4, 123.4), end='\n')
print(problem4(2, 2, 2), end='\n')
----------
0.008
1.000
1879.080904
0.008

先回知った Decimal を早速使っちゃったぜ。モジュールを使用しちゃうのはちとずっこい感じがしたんだけれど、問題2があまりに面倒だったからさ……。で、1個インポートしたら2個も3個も一緒でしょと functools も使っちゃったぜ。map関数も使っているし lambda にも慣れてきたぜ。



5. 最悪のFizzBuzz
最悪の - しかし動作する - FizzBuzzプログラムをかけ。

こういうの大喜利みたいで楽しいね。ふたとおり作ってみた。

def problem5(start, end):

    # ■ 最悪POINT 1: 変数名が日本語。ぞわっとするー!
    結果リスト = []

    # ■ 最悪POINT 2: 一回しか使わない変数をわざわざ作成してる。意味ねー!
    end2 = end + 1
    for i in range(start, end2):

        # ■ 最悪POINT 3: 真偽用の変数を作るにしてもboolじゃなく文字列を使用してる。Falseにしとけー!
        iは3の倍数です = 'いいえ'
        iは5の倍数です = 'いいえ'

        # ■ 最悪POINT 4: 3の倍数の求め方が「ずっと3を足していって該当したら」。頭わるそー!
        three = 3
        while True:
            # ■ 最悪POINT 5: コードを見れば分かることをわざわざ説明するコメントを書いてる。意味ねー!
            # threeがiと同じときiは3の倍数ですを'はい'にする。threeがiより大きくなっちゃったらwhileを終了。
            if three == i:
                iは3の倍数です = 'はい'
            elif three > i:
                break
            # ■ 最悪POINT 6: three += 3 という書き方を知らない。知っとけー!
            three = three + 3

        # ■ 最悪POINT 7: 上と同じような処理なのに関数化してない。しとけー!
        five = 5
        while True:
            if five == i:
                iは5の倍数です = 'はい'
            elif five > i:
                break
            # ■ 最悪POINT 8: って、+=知ってんのかよ! だったら上のも += 3 にしろよ!
            five += 5

        # ■ 最悪POINT 9: 無駄に ! を使ってる。この場合 == 'はい' にするべき。
        if iは3の倍数です != 'いいえ':
            if iは5の倍数です != 'いいえ':
                結果リスト.append('FizzBuzz')
                continue

        # ■ 最悪POINT 10: このあたりは if elif でまとめればいいのにばらばらにifしてる。
        if iは3の倍数です != 'いいえ':
            結果リスト.append('Fizz')
            continue

        if iは5の倍数です != 'いいえ':
            結果リスト.append('Buzz')
            continue

        # ■ 最悪POINT 11: ここまで処理が進むってことは絶対両方 'いいえ' なのにわざわざifに入れてる。意味ねー!
        if iは5の倍数です == 'いいえ':
            if iは3の倍数です == 'いいえ':
                結果リスト.append(str(i))

    # ■ 最悪POINT 12: for部が長すぎる!

    結果の文字列 = ''
    # ■ 最悪POINT 13: すごくダメな例外処理の使い方してる。で、出た〜〜w except pass 奴〜〜ww
    try:
        i = 0
        while True:
            結果の文字列 = 結果の文字列 + 結果リスト[i] + ','
            i += 1
    except:
        pass

    return 結果の文字列
昔の俺が書いてたようなpython」がテーマだ。初心者あるあるを詰め込んだようなFizzbuzz。
もう片方は逆に、いまの俺じゃないと書けないpython
def problem5(start, end):
    # ■ 最悪POINT: ワンラインで読みづらい(横長になりすぎないよう改行はしてる)。
    return list(
        map(
            lambda i:
                str(i)
                if (i % 3 and i % 5)
                else ('' if i % 3 else 'Fizz') + ('' if i % 5 else 'Buzz'),
            range(start, end + 1))
    )
最近覚えた高階関数や三項演算子をバリバリ使って一行Fizzbuzzを作ってみた。上のより高度ではあるけど、クッソ読みづらいから逆に最悪と言っていいんじゃね?

実行結果。
print(problem5(1, 10), end='\n')
print(problem5(100, 110), end='\n')
print(problem5(1500, 1510), end='\n')
----------
1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,
Buzz,101,Fizz,103,104,FizzBuzz,106,107,Fizz,109,Buzz,
FizzBuzz,1501,1502,Fizz,1504,Buzz,Fizz,1507,1508,Fizz,Buzz,


| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python プログラミング問題をやってみた2 前半戦



こんなのを見つけたので、また腕試しにトライしてみたぜ。ちと長くなっちゃったので前半後半にわける。3問目はコードを書く問題じゃなかったから抜かしてる。



1. アナグラム
2つの引数を取り、引数がアナグラム(どちらも全く同じ文字を含んでいる)ならばtrueを、そうでないならばfalseを返す関数をかけ。
def problem1(arg1, arg2):

    # まず引数チェックをします。
    if not (isinstance(arg1, str) and isinstance(arg2, str)):
        print(f'引数は文字列だけ認めるよ: {arg1}, {arg2}')
        return False

    # 長さが違う時点でダメです。
    if len(arg1) != len(arg2):
        print(f'長さが違う時点でダメ: {arg1}, {arg2}')
        return False

    # arg1の文字が全部arg2に同数含まれてるか? という判断基準でいく。
    for a in arg1:
        if arg1.count(a) != arg2.count(a):
            print(
                f'arg1の文字"{a}"がarg1には{arg1.count(a)}個あるけど'
                f'arg2には{arg2.count(a)}個あるよ: {arg1}, {arg2}'
            )
            return False

    print(f'OKだよーん: {arg1}, {arg2}')
    return True

実行結果。
print(problem1('abcde', 'edcba'), end='\n')
print(problem1('abcde', 'abcdei'), end='\n')
print(problem1('abcde', 1), end='\n')
print(problem1('abcde', 'edcbf'), end='\n')
print(problem1('日本語はどうでしょうね', 'ううしでどねはょ日本語'), end='\n')
print(problem1('ABA', 'ABB'), end='\n')
----------
OKだよーん: abcde, edcba
True
長さが違う時点でダメ: abcde, abcdei
False
引数は文字列だけ認めるよ: abcde, 1
False
arg1の文字"a"がarg1には1個あるけどarg2には0個あるよ: abcde, edcbf
False
OKだよーん: 日本語はどうでしょうね, ううしでどねはょ日本語
True
arg1の文字"A"がarg1には2個あるけどarg2には1個あるよ: ABA, ABB
False

最近使いこなせるようになってきた isinstance とか楽しんで使ってみた。けどまあ、こういう問題を解くときはそういうのナシで短くまとめるようにしたほうが見栄えがよかったかと思わんでもない。



2. 税金計算
金額(ドル)と、税率(%)を引数にとり、答えの金額をセントとして配列で返せ。

これが曲者だった。ところでこれは、金額に税額を足せってことで合っているよな? ほんでその金額をドルとセントに分けて [ドル, セント] にしろってことだよな? 俺はそういう理解でやってみたぞ。

def problem2(dollar, tax_rate):

    if not (isinstance(dollar, float) and isinstance(tax_rate, float)):
        print(f'引数はfloatだけ認めるよ: {dollar}, {tax_rate}')
        return False

    dollar, tax_rate = str(dollar), str(tax_rate)

    # 小数点は右からいくつめにあるの? **.**** なら 4 を取得します。
    # [::-1]は文字列の反転。pt_lctnはpoint_locationのことです。
    dollar_pt_lctn = dollar[::-1].find('.')

    # 税率は%単位だから、最後に/100ぶんの2を足すよ。 *.* なら 3 を取得します。
    tax_rate_pt_lctn = tax_rate[::-1].find('.') + 2

    # ドル、税率から小数点を削除ります。晴れてintになりました。さらばfloat。
    dollar_int = int(str(dollar).replace('.', ''))
    tax_rate_int = int(str(tax_rate).replace('.', ''))

    # 税金額を出します。floatでやると誤差が生じてワヤになるからintで。
    tax_amount = dollar_int * tax_rate_int

    # 元のドルを税金額に桁あわせします。float同士だと足し算ですら狂うのでintでやります。
    # 小数点を削除ったドルに、税率の小数点の位置ぶん0加えたものがそれ。
    original_dollar = int(str(dollar_int) + '0' * tax_rate_pt_lctn)

    # 元のドルに税金額を足します。
    result = str(original_dollar + tax_amount)

    # 削除ってた小数点を戻します。
    # 位置は、最初に削除ったふたつの小数点の位置を足したところ。
    # 100.1ドル と 9.75% だったら 右から5番目になる。(%ぶんの+2を忘れずに。)
    pt_lctn = dollar_pt_lctn + tax_rate_pt_lctn
    result_ = (str(result)[0:-pt_lctn] + '.' + str(result)[-pt_lctn:])

    print(f'額は ${result_} になりました。結果の配列は下に表示されます。')

    # なんやかんやで $***.***** を [***, **.***] にして返します。
    dollar_part = str(result)[0:-pt_lctn]
    dollar_part = int(dollar_part if dollar_part else '0')
    cent_part = str(result)[-pt_lctn:] + '0'
    cent_part = float(cent_part[0:2] + '.' + cent_part[2:])

    return [dollar_part, cent_part]

実行結果。
print(problem2(100.0, 8.00), end='\n')
print(problem2(0.10, 10.56), end='\n')
print(problem2(100.10, 9.75), end='\n')
print(problem2(100, 9.75), end='\n')
print(problem2(123.456789, 8.1234), end='\n')
print(problem2(4.64, 9.75), end='\n')
print(problem2(0.10, 10.56), end='\n')
print(problem2(1.0, 100.0), end='\n')
----------
額は $108.0000 になりました。結果の配列は下に表示されます。
[108, 0.0]
額は $.11056 になりました。結果の配列は下に表示されます。
[0, 11.056]
額は $109.85975 になりました。結果の配列は下に表示されます。
[109, 85.975]
引数はfloatだけ認めるよ: 100, 9.75
False
額は $133.485677797626 になりました。結果の配列は下に表示されます。
[133, 48.5677797626]
額は $5.092400 になりました。結果の配列は下に表示されます。
[5, 9.24]
額は $.11056 になりました。結果の配列は下に表示されます。
[0, 11.056]
額は $2.0000 になりました。結果の配列は下に表示されます。
[2, 0.0]

見づら。何この見づらい関数。それもこれもすべて float の計算が微妙に狂うせいなのだよ。
print(0.1 * 3)  # 0.30000000000000004 になる。なんでだよ。
print(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1)  # 0.7999999999999999 になる。なんでだよ!!
なんかねえ、二進数が小数がうまく表せないせいで起こるらしいよこれは。そういうわけで float 同士の計算は避けようと思って上述のクソ長い関数は爆誕した。

のだが、のちにググったら「そういうときは Decimal を使え」とあってですね……。Decimalというのはintでもfloatでもない数値型で、正確な小数を表せるとかで。
import decimal

def problem2(dollar, tax_rate):

    # Decimal型(正確な小数)に変換します。
    dollar = decimal.Decimal(str(dollar))
    tax_rate = decimal.Decimal(str(tax_rate))

    # 元の額 + 税額
    result = dollar + dollar * (tax_rate / 100)

    # ドル部とセント部に分けます。
    return [int(result), float((result - int(result)) * 100)]
これで上述関数と同じ結果が出る。ほなら float を廃止して Decimal にしたほうがいいんじゃないの、pythonの旦那?



後半に続く。

| 緑色 | プログラミング | comments(0) |
| カテゴリ:プログラミング |
Python ユニットテストノート



先日の読書に影響されて、ユニットテストっていうものを調べてみたぜ。えーとまとめると以下のような感じか?
  • スクリプトはたくさんの関数が集まってできてるじゃん?
  • 大雑把にいえば、関数が全部バグなしだったら全体もバグなしってことになるじゃん?
  • ユニットテストは関数単位でテストすること。いろんなパターンの引数で関数を呼び出しまくって、返り値が正しいかチェックしまくる。
  • これをスクリプト書いてる最中に定期的に実行してれば、どっかのタイミングで関数が壊れたらスグわかる!

なるほどって感じだ。これまで、作った関数のチェックといえば、実際に使うところでちょろっと呼び出して結果を print するくらいだったもんね。全体のリファクタリングをやるときも有効そう。以下目次。
とりあえず pip しとく
テスト対象
ユニットテストファイル
カバレッジ



とりあえず pip しとく
  • $ pip install nose
  • $ pip install coverage
  • $ pip install mock
  • $ pip install parameterized



テスト対象。foo.py って名前にしといた。この中のメソッドをユニットテストしていくぜ。
class Foo:

    # test_1 と test_2 で扱うよー。
    @staticmethod
    def static_method(x, y):
        return x + y

    # test_3 と test_4 で扱うよー。
    @staticmethod
    def exception_method(x):
        if x is True:
            raise TypeError()
        elif x is False:
            raise ValueError()
        elif x == 1:
            return x
        else:
            return None

    # test_5 で扱うよー。
    @staticmethod
    def use_other_class_method():
        return Bar.static_method()


class Bar:

    # test_5 で扱うよー。
    @staticmethod
    def static_method():
        return 1

    # test_7 で扱うよー。
    X = 1

    # test_7 で扱うよー。
    @classmethod
    def class_method(cls):
        return cls.X



ユニットテストファイル。foo_test.pyって名前にしといた。テストファイルの名前は test_ か _test をつけないとダメ。とりあえず使う予定の import を並べとく。
from nose.tools import ok_, eq_, with_setup
from mock import Mock
from parameterized import parameterized

import foo  # これはテストするモジュール。

実例1: 基本的なテスト。Foo.static_methodをテストする。
def test_1():

    # Input.
    x = 1
    y = 2

    # Expected.
    expected = 3

    # Verify.
    actual = foo.Foo.static_method(x, y)
    eq_(expected, actual)

実例2: たくさんの入力値、期待値パターンを一気に書く。ぶっちゃけ実例1は忘れて全部コレでよさげ。
@parameterized([
    (1, 2, 3),
    (3, 4, 7),
    (6, 3, 9),
])
def test_2(x, y, expected):

    # Verify.
    actual = foo.Foo.static_method(x, y)
    eq_(expected, actual)

実例3: 例外をテスト。Foo.exception_methodをテストする。raises っていうアノテーションを使う方法もあったけれど、それと parameterized を組み合わせる方法がよくわかんなかったからコレで。
@parameterized([
    (True, TypeError),
    (False, ValueError),
])
def test_3(x, expectedException):

    try:
        foo.Foo.exception_method(x)
    except Exception as e:
        ok_(isinstance(e, expectedException))
        return
    ok_(True is False, 'Exception must be thrown.')

実例4: parametarized に例外を含む。実例2,3の合成。例外を出すかもしれないし普通に返り値が来るかもしれないメソッドをテストする。このかたちが今回の完成形って感じがする。あとは必要に応じて後述のモックを使えばよいか。
@parameterized([
    (True, True, TypeError),
    (False, True, ValueError),
    (1, False, 1),
    ('a', False, None),
])
def test_4(x, expectException, expected):

    # 通常の返り値期待。
    if not expectException:
        actual = foo.Foo.exception_method(x)
        eq_(expected, actual)
        return

    # 例外期待。
    try:
        foo.Foo.exception_method(x)
    except Exception as e:
        ok_(isinstance(e, expected))
        return
    ok_(True is False, 'Exception must be thrown.')

実例5: メソッドをすげ替える(モックする)
def test_5():

    # 対象メソッド内の Bar.static_method をモックします。
    # フツーに実行したら 1 が返ってくるけど、そこを 5 にすげ替える。
    foo.Bar.static_method = Mock(return_value=5)

    # Expected.
    expected = 5

    # Verify.
    actual = foo.Foo.use_other_class_method()
    eq_(expected, actual)

実例6: モジュールの前後に関数を実行させる
def setup():
    '''setupって名前で作れば自動で実行。'''
    print('実例6: setup')
def teardown():
    '''teardownって名前で作れば自動で実行。'''
    print('実例6: teardown')

実例7: 関数の前後に関数を実行させる
def setup2():
    foo.Bar.X = 5
def teardown2():
    foo.Bar.X = 1

@with_setup(setup2, teardown2)
def test_7():
    eq_(5, foo.Bar.class_method())

実行は下記コマンドを打てばよい。test_、_testのついたファイル、関数を全部自動実行してくれる。あるいはテストファイル内に実行スクリプトを書いてもよいぞ。
$ nosetests -v -s --with-coverage

# テストファイル内に書く場合。
nose.main()
テストをちゃんとクリアしたかどうかズラッと出てくれる。vがテスト名の表示、sが標準出力の表示、with-coverageがカバレッジの出力。



カバレッジ。このカバレッジってやつが楽しくてな。テストがスクリプトをすみずみまで舐め回したかどうか見せてくれるんだよ。下記コマンド実行で閲覧用htmlを出力してくれる。
$ coverage html


こんなんが出る。楽しすぎるじゃん。今回は Bar.static_method は実行してないから(モック例に使ったため)舐め回し不足として赤くなってる。わかりやすいな。
注意事項として、テスト実行に
nose.main()
を使うとカバレッジが中途半端に赤くなる。具体的にはスクリプトの定義文部分。本当なら定義とかを全部終わらす前に網羅率の計測をしなくちゃならないんだが、スクリプト内に実行文を書いちゃうと定義処理が終わってから計測を開始することになっちゃってダメなんだろう。スクリプト内からのテスト実行も可能って話だったが、実際はターミナルから実行したほうが無難かもしんない。



オッケー終了! わりと実用的にまとまった気がする。


| 緑色 | プログラミング | comments(0) |
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< May 2018 >>
+ みろりHP内検索
+ 閲覧記事
+ 過去記事アーカイブ
+ カテゴリ
+ 年月選択
  • 2018年 05月 (3)
  • 2018年 04月 (7)
  • 2018年 03月 (6)
  • 2018年 02月 (6)
  • 2018年 01月 (8)
  • 2017年 12月 (9)
  • 2017年 11月 (9)
  • 2017年 10月 (4)
  • 2017年 09月 (6)
  • 2017年 08月 (6)
  • 2017年 07月 (8)
  • 2017年 06月 (4)
  • 2017年 05月 (7)
  • 2017年 04月 (8)
  • 2017年 03月 (7)
  • 2017年 02月 (10)
  • 2017年 01月 (6)
  • 2016年 12月 (8)
  • 2016年 11月 (8)
  • 2016年 10月 (5)
  • 2016年 09月 (5)
  • 2016年 08月 (7)
  • 2016年 07月 (9)
  • 2016年 06月 (6)
  • 2016年 05月 (8)
  • 2016年 04月 (10)
  • 2016年 03月 (10)
  • 2016年 02月 (8)
  • 2016年 01月 (9)
  • 2015年 12月 (9)
  • 2015年 11月 (6)
  • 2015年 10月 (5)
  • 2015年 09月 (4)
  • 2015年 08月 (8)
  • 2015年 07月 (5)
  • 2015年 06月 (3)
  • 2015年 05月 (7)
  • 2015年 04月 (8)
  • 2015年 03月 (12)
  • 2015年 02月 (8)
  • 2015年 01月 (4)
  • 2014年 12月 (5)
  • 2014年 11月 (5)
  • 2014年 10月 (7)
  • 2014年 09月 (4)
  • 2014年 08月 (7)
  • 2014年 07月 (6)
  • 2014年 06月 (4)
  • 2014年 05月 (12)
  • 2014年 04月 (9)
  • 2014年 03月 (6)
  • 2014年 02月 (6)
  • 2014年 01月 (8)
  • 2013年 12月 (7)
  • 2013年 11月 (10)
  • 2013年 10月 (10)
  • 2013年 09月 (9)
  • 2013年 08月 (11)
  • 2013年 07月 (10)
  • 2013年 06月 (9)
  • 2013年 05月 (15)
  • 2013年 04月 (11)
  • 2013年 03月 (5)
  • 2013年 02月 (7)
  • 2013年 01月 (6)
  • 2012年 12月 (9)
  • 2012年 11月 (10)
  • 2012年 10月 (10)
  • 2012年 09月 (4)
  • 2012年 08月 (2)
  • 2012年 07月 (7)
  • 2012年 06月 (13)
  • 2012年 05月 (13)
  • 2012年 04月 (15)
  • 2012年 03月 (4)
  • 2012年 02月 (12)
  • 2012年 01月 (9)
  • 2011年 12月 (5)
  • 2011年 11月 (13)
  • 2011年 10月 (2)
  • 2011年 09月 (2)
  • 2011年 08月 (1)
  • 2011年 06月 (1)
  • 2011年 05月 (4)
  • 2011年 04月 (10)
  • 2011年 03月 (8)
  • 2011年 02月 (11)
  • 2011年 01月 (14)
  • 2010年 12月 (14)
  • 2010年 11月 (17)
  • 2010年 10月 (17)
  • 2010年 09月 (19)
  • 2010年 08月 (22)
  • 2010年 07月 (18)
  • 2010年 06月 (16)
  • 2010年 05月 (19)
  • 2010年 04月 (15)
  • 2010年 03月 (22)
  • 2010年 02月 (18)
  • 2010年 01月 (18)
  • 2009年 06月 (2)
  • 2009年 04月 (1)
  • 2007年 12月 (10)
  • 2007年 11月 (7)
  • 2007年 10月 (9)
  • 2007年 09月 (4)
  • 2007年 07月 (5)
  • 2007年 06月 (11)
  • 2007年 05月 (6)
  • 2007年 04月 (4)
  • 2006年 01月 (21)
  • + ブックマーク
    + 最近のコメント
    + アクセスカウンター
    全体(since 2010.02.03.)
    今日… 昨日…