2008年9月18日木曜日

乳母車より歩行車を

一人暮しのばぁちゃん

ばぁちゃんは齢 80 をこえ一人暮しをしている。去年、じぃちゃんが亡くなった。じぃちゃんが亡くなる少し前から、ばぁちゃんの足腰は弱くなっており、何かにつかまらないとフラフラしてしまう。家のいたるところに手すりをつけるための工事をした。古い家で、昔は商売をしていたので、バリアフリーについては全く考慮されていない。

外にでかけるとき、はじめは乳母車を使っていたけれど、これがいけない。自分で触ってみてはじめてわかったのだが、乳母車は足腰が弱った人のためのものではない。あくまでも健康な老人が荷物を運ぶためのものだ。そういう認識でいなければいけなかった。まず、方向転換が非常にしにくい。勿論、ものによっても違うと思うけれど、多くの乳母車は、曲がるための半径が結構でかい。最悪なのはブレーキの位置で、手をかけるところをしっかりと握ってしまうと、いざというときにブレーキに手をかけることができない。

じぃちゃんはこの乳母車を押し、その日、間違えて底がツルツルの靴を履いて買物に出かけてしまった。そして、転んで大腿骨を骨折。老人の骨折の中では、典型的なパターンだ。そして、医師からそうなった場合の 1 年後の生存率について教えられた。正直、「なぜ骨折しただけで?」と思った。その後、脳梗塞も併発し、言葉も奪われた。もしかすると、脳梗塞がキッカケで転んだのかもしれない。それまで、90 をこえても耳が遠くなり、少し足腰が弱くなった程度で、基本元気な人だったので、病院で寝たきりとなった後、「早くあちらへ行きたい」と言っていた。その言葉も段々と発することができなくなった。病院にお見舞に行くとニコリと笑うか、何かを言っていたのだけれど聞きとることができなかった。一度でいいから、自分の家に帰りたかっただろうと思う。最後は病院の一室で、ばぁちゃんに看取られて亡くなった。

 

歩行車

乳母車が非常に使いにくいため、同様のものをいろいろと探した。しかし、中々見つからない。そのとき、たまたま「福祉住環境コーディネーター」の勉強をしていたので、「歩行車」という言葉を知っていた。しかし、歩行車にもいろいろとあったけれど、「これだ!」と思うものがなかった。結局、「ウォーキー」という歩行車を購入した。日本製でないため、S サイズでも体の小さな祖母にとっては座面が高かった。そして値段も少し高かった。 ^^; それ以外は何の問題もない。その場でくるっと向きを変えることもできるし、ブレーキもしっかりとしていて、つかみやすい。 ^^  乳母車と違って、体をすっぽり中に入れるため、体を支えるときに下方向に力を入れることができる。このため、普通に歩くときのように歩行が可能になる。

今購入するなら、イーストアイの「ロレータ 」を選択すると思う。実際に福祉展で見て触ってきたのだけれど、日本人向けになっている。祖母が購入した「ウォーキー」の座面の高さは 48 cm 。それに対して、ロレータは 44 cm 。これだけ低いものは他では見たことがなかった。値段もウォーキーの半額以下だった。

 

使い勝手は使って確かめる

使い勝手というのは、実際に使ってみないとわからない。じぃちゃんが乳母車を使っていた。それが普通だと思っていた。使いやすいのかどうかということに関心が向かない。「老人ならば乳母車」という固定観念。昔の人だから不平を言わない。そういうものだと本人も思っている。

じぃちゃん家に行けば、乳母車が置いてあった。そして、それを使って唯一楽しみの買物にテクテクと歩いて行っているのも知っていた。そして、倒れた。体を支えることができずに。あのとき触って使い勝手を確認しておくべきだった。そうしたら、別の死に方ができたかもしれない。じぃちゃん、ごめん。

Python でリストの要素を指定 – car, cdr に相当するもの

リストに対して操作をするとき、その要素を簡単に指定できると楽。

2.3.6 シーケンス型 によると、(太字は引用者による)

s[i]
s の 0 から数えて i 番目の要素 (…)

i または j が負の数の場合、インデクスは文字列の末端からの相対インデクスになります

マイナスつければ末尾から指定できるの忘れてた。 パタッ(o_ _)o~† 気づかずこんな冗長な書き方を… 。

a[len(a)-1]
a[:len(a)-1]

忘れないように図を書いておこう。

080918-001

 

上記に特別な名前を付けていないところが Python 流ということかな?

ついでにコードも書いておく。

a = [1,2,3,4,5]

print u"先頭の要素: ",  a[0]
print u"2 番目以降の要素のリスト: ", a[1:]

print u"最後の要素: ", a[-1]
print u"最後の要素よりも前にある要素のリスト", a[:-1]

 

他の言語では

 LISP – Wikipedia によると、

LISPは当初IBM 704上で実装されたが、その計算機上の2つの命令がLISPの基本操作car(Contents of Address Register)、cdr(Contents of Decrement Register)になった。 ほとんどのLISPの方言において、carとcdrはそれぞれlistの最初の要素と、最初の要素以外を返す操作である。

 

Ruby には、Array - Rubyリファレンスマニュアル に要素の先頭と末尾を取得するための first, last がある。

 

Haskell では、head, tail と init, last 。(cf. Haskell で リストの n 番目の要素を取得 – PreludeList の !! )

 

リスト処理関数 によると、Scheme には、

carはリストの先頭の要素,cdrはリストの先頭の要素を除いたリストを返すと考えてもよい.これらに加えて,2番目の要素を返すcadr,3番目以降要素を含むリストを返すcddr,先頭の要素がリストであるときに,その先頭の要素を返すcaar などの関数など,4つまでのaかdを含む関数がシステムに用意されている.

 

スライスオブジェクト

3.2 標準型の階層 の内部型 (internal type) に、

スライス (slice) オブジェクト

スライスオブジェクトは 拡張スライス構文 (extended slice syntax) が使われた際にスライスを表現するために使われます。拡張スライス構文とは、二つのコロンや、コンマで区切られた複数のスライスや省略符号 (ellipse) を使ったスライスで、例えば a[i:j:step] 、 a[i:j, k:l] 、あるいは a[..., i:j] です。スライスオブジェクトは組み込み関数 slice() で生成されます。 (…)

 

「要素へアクセスするための特殊メソッド」で実装した __getitem__(self, key) が関係している。

酒飲み父ちゃんのアルコール量チェック (2) – Python で実装

「酒飲み父ちゃんのアルコール量チェック – UML でクラス図の概略を作成」の続き。

 

具体例をシンプルに計算

前回、 クラス図の概略を作成した。はじめにこのクラス図は横に置いておき、具体例をシンプルに計算してみる。例えば、

今日、父ちゃんが「日本酒 : 1 合、焼酎 : 0.5 合、ウイスキー : 30 ml 」飲んだとする。それぞれのアルコール度数を「 15 度,  25 度,  40 度」とした場合、全部で日本酒で換算すると何合飲んだか?

ん~、暗算では無理。(+_+)

これを計算するには、すべての単位を ml に換算して、

# 日本酒 1 合のアルコール量
ALCOHOL_PER_SAKE_1GOU = 180 * 15 / 100

# 飲酒
sake    = 1 * 180 * 15 / 100        # 日本酒     : 1 合
shochu  = 0.5 * 180 * 25 / 100      # 焼酎       : 0.5 合
whiskey = 30 * 1 * 40 / 100         # ウイスキー : 30 ml

# 飲酒量を日本酒で考えると
print round((sake + shochu + whiskey) / ALCOHOL_PER_SAKE_1GOU, 2)

翌日に再度、同じように計算したい場合は、「飲酒」の変数に設定した計算式の中の値を変更。別の種類の酒を飲んだら、新しく変数を追加。日本酒換算ではなくて、焼酎換算にしたい場合は、最初の ALCOHOL_PER_SAKE_1GOU  の式を変更。新しい単位が追加された場合は、単位と ml への換算の式は頭の中に記憶しておくか、または別の管理方法を考えなくてはいけない。 この方法は、あくまでも一例を計算するだけ。

 

ちょっとまとめる

翌日もう少し入力しやすいように、変更がありそうなところをまとめておく。 単位 ・ml への変換やアルコールの度数の情報を一箇所で管理、アルコール量の計算で毎回度数を 100 で割るという手間をなくしたり。とりあえず、クラスを使わないで書くなら、

# 酒 : アルコール度数
LIQUOR_LIST = {u'日本酒'     : 15,
               u'ウイスキー' : 40,
               u'焼酎'       : 25}

# 単位 : 各単位は ml へ変換するときに乗算する値
UNIT_LIST = {'ml'   : 1,
             'l'    : 1000,
             u'合'  : 180}

def alcoholPer1Unit(liquor, unit):
    u""" 指定された酒の1単位当たりのアルコール量を返す """
    return UNIT_LIST[unit] * LIQUOR_LIST[liquor] / 100.0

def quantityOfAlcohol(liquor, val, unit):
    u""" アルコールの量を単位 ml で返す """
    return val * UNIT_LIST[unit] * LIQUOR_LIST[liquor] / 100.0

def totalQuantityOfAlcohol(drinksOfToday):
    u""" 今日の飲酒量からトータルのアルコール量を返す """
    return sum([quantityOfAlcohol(x[0], x[1], x[2]) for x in drinksOfToday])

def isOk(quantityOfAl, limit):
    u""" 一日の許容アルコール量を超えていないかチェックする """
    return u"!!! 飲みすぎ !!!" if quantityOfAl > limit else ""

def printResult(drinksOfToday):
    today = totalQuantityOfAlcohol(drinksOfToday)
    print u"%s に換算すると %.2f %s 飲んだ" % \
            (LIQUOR, today / alcoholPer1Unit(LIQUOR, UNIT), UNIT)
    print isOk(today, quantityOfAlcohol(LIQUOR, LIMIT, UNIT))

# 飲酒制限
LIQUOR = u'日本酒'; LIMIT = 2; UNIT = u'合'

# 今日の飲酒量
drinksOfToday = [(u'日本酒', 1, u'合'),
                 (u'焼酎' , 0.5, u'合'),
                 (u'ウイスキー', 30, u'ml')]
printResult(drinksOfToday)

 

あ~、もうこれでいいような気もしてきた ^^; UI を被せるにはまだ足りないけど、計算する分にはこれでいいか。

 

クラス図に基づいて

UML で概略書いたので、それに基づいて実装してみる。図とはちょっと違うけれど ^^;

import logging
from decimal import Decimal

class Liquor:
    u""" 酒 """
    def __init__(self, name, alcoholByPercentage):
        self.name = name            # 酒の名前
        # アルコールの含有量
        self.alcoholByPercentage = Decimal(str(alcoholByPercentage))

    def __str__(self):
        return name + " " + str(self.alcoholByPercentage)
    
    def setDefaultUnit(self, unit):
        u""" この酒で使われるデフォルトの単位を設定する。

        Drink#__call__ の呼出しに先立ち、単位を設定しておく。
        """
        self.unit = unit
        return self

class Quantity:
    u""" 量 """
    def __init__(self, number, unit):
        self.number = Decimal(str(number))      # 数値
        self.unit = unit                        # 単位

    def __cmp__(self, other):
        # 単位 ml に変換してから量を比較する
        return cmp(self.convertToMl(), other.convertToMl())

    def __str__(self):
        return "%.2f" % self.number + " " + self.unit.name + \
                " (%.2fml)" % self.unit.convertToMl(self.number)

    def convertToMl(self):
        u""" 量を単位 ml に変換して返す """
        return self.unit.convertToMl(self.number)
    
    def getUnit(self):
        u""" 単位を返す """
        return self.unit

class Unit:
    u""" 単位

    基準となる単位を ml とした。すべての単位は ml へと変換するときに
    乗算する値を持たなくてはいけない。
    """
    def __init__(self, name, valOfConvMl):
        self.name = name                # 単位名
        self.convertUnits = []          # 単位変換のリスト
        # 単位 ml へ変換するために乗算する値
        self.valOfConvMl = Decimal(str(valOfConvMl))  
        
    def convertToMl(self, number):
        u""" 指定された数をml へ変換する。 """
        return number * self.valOfConvMl

class Drink:
    u""" 飲酒 """
    def __init__(self, liquor, quantity=0):
        self.liquor = liquor            # 酒
        self.quantity = quantity        # 量
    
    def __str__(self):
        return u"%s, %-s" % \
                (self.liquor.name, self.quantity)
        
    def __call__(self, number):
        u""" 数値を指定し予め生成ておいた飲酒オブジェクトを元に新たに Drink
        オブジェクトを生成する。
        
        Drink オブジェクトを簡単に作るためのメソッド。この呼出しに先立ち、
        Liquor クラスだけが設定されていること。そのオブジェクトを使い、
        数値を設定するだけで、Drink オブジェクトが生成される。
        """
        assert self.liquor.unit is not None
        return Drink(self.liquor, Quantity(number, self.liquor.unit))

    def getAlcoholByMl(self):
        u""" 単位 ml でアルコールの量を返す """
        return self.getQuantityByMl() * self.getAlcoholPercentage()
        
    def getQuantityByMl(self):
        u""" 飲酒の量を単位 ml で返す """
        return self.quantity.convertToMl()

    def getAlcoholPercentage(self):
        u""" アルコールの割合を返す """
        return self.liquor.alcoholByPercentage / 100
    
    def getUnit(self):
        u""" 単位を返す """
        return self.quantity.getUnit()
    
    def getLiquorName(self):
        u""" 酒の名前を返す """
        return self.liquor.name
    
    def getAlcoholPerUnitByMl(self):
        u""" 1 単位当たりのアルコール量 を ml で返す """
        return self.getAlcoholByMl() / self.quantity.number

class DrinkList:
    u""" 飲酒のリスト """
    def __init__(self):
        self.drinks = []     # 飲酒のリスト

    def __str__(self):
        return u"--------- 飲酒リスト ---------\n" + \
            "\n".join(["%s" % drink for drink in self.drinks]) + "\n" + \
            "-"*30 + "\n" + \
            u"アルコール総量:%.2f ml" % self.getAlcoholByMl()
        
    def add(self, Drink):
        u""" 飲酒を飲酒のリストに追加する """
        self.drinks.append(Drink)
        return self
    
    def getAlcoholByMl(self):
        u""" 飲酒におけるアルコールの総量を単位 ml で返す """
        return sum([x.getAlcoholByMl() for x in self.drinks])

class AlcoholRestriction:
    u""" 飲酒制限

    ex. 「一日、日本酒で 2 合までなら飲んでいい」
    """
    def __init__(self, drink):
        self.drink = drink        # 上限となる飲酒
        
    def __str__(self):
        result = u"制限: 一日に %s で %s までなら飲んいいよ!" % \
                    (self.drink.getLiquorName(), self.drink.quantity)
        result += u"\n!!! 飲みすぎ!!!" if not self.permit() else ""
        result += u"\n%s %s に相当" % \
                    (self.drink.getLiquorName(),
                    Quantity(self.drinkList.getAlcoholByMl() / \
                                self.drink.getAlcoholPerUnitByMl(),
                            self.drink.getUnit()))
        return result
    
    def setDrinkList(self, drinkList):
        u""" 飲酒リストを設定 """
        self.drinkList = drinkList
    
    def getLimitOfAlcoholByMl(self):
        u""" 設定された飲酒の上限であるアルコール量を返す """
        return self.drink.getAlcoholByMl()
        
    def permit(self):
        u""" 指定された飲酒リストにおけるアルコールの量は許容されるか? """
        assert self.drinkList is not None
        if self.drinkList.getAlcoholByMl() <= self.getLimitOfAlcoholByMl():
                return True
        else: return False

# --- 酒-------------------------------------------------------
u""" 日本酒 """
LIQUOR_SAKE = Liquor(u"日本酒", 15)
u""" 焼酎 """
LIQUOR_SHOCHU = Liquor(u"焼酎", 25)
u""" ウイスキー """
LIQUOR_WHISKEY = Liquor(u"ウイスキー", 40)

# --- 単位 -----------------------------------------------------
# `ml' を量を比較する際の基準となる単位とする
u""" ml """
UNIT_ML = Unit(u"ml", 1)

u""" 合 """
UNIT_GOU = Unit(u"合", 180)
u""" 升 """
UNIT_SYOU = Unit(u"升", 1800)

# --- 量 -------------------------------------------------------
# ウイスキー・バーボンなどにおける特別な量の呼び方
u""" シングル """
QUANTITY_SINGLE = Quantity(30, UNIT_ML)
u""" ダブル """
QUANTITY_DOUBLE = Quantity(60, UNIT_ML)
u""" ジガー """
QUANTITY_JIGGER = Quantity(45, UNIT_ML)

# --- 飲酒 ------------------------------------------------------
u""" 飲酒オブジェクトを簡単に作成できるようにする。

ex. Liquor.DRINK_SAKE(2)      : 「酒を 2 合飲んだ」
    Liquor.DRINK_WHISKEY(100) : 「ウイスキーを 100 ml 飲んだ」
Drink#__call__() が呼出される。
"""

u""" 日本酒の飲酒を生成するためのオブジェクト
デフォルトの単位を「合」とする。
"""
DRINK_SAKE = Drink(LIQUOR_SAKE.setDefaultUnit(UNIT_GOU))
u""" 焼酎の飲酒を生成するためのオブジェクト
デフォルトの単位を「合」とする。
"""
DRINK_SHOCHU = Drink(LIQUOR_SHOCHU.setDefaultUnit(UNIT_GOU))
u""" ウイスキーの飲酒を生成するためのオブジェクト
デフォルトの単位を「ml」とした
"""
DRINK_WHISKEY = Drink(LIQUOR_WHISKEY.setDefaultUnit(UNIT_ML))


if __name__ == "__main__":
    # 飲酒は「日本酒で2合まで」という制約
    alcoholRestriction = AlcoholRestriction(DRINK_SAKE(2))
    # 飲酒リスト
    drinkList = DrinkList().add(
        DRINK_SAKE(1)).add(
        DRINK_SHOCHU(0.5)).add(                      # 焼酎 1 合
        Drink(LIQUOR_WHISKEY, QUANTITY_SINGLE))    # ウイスキーのシングル

    # 飲酒制限に飲酒リストを設定
    alcoholRestriction.setDrinkList(drinkList)

    # 飲酒リストを表示
    print "%s" % drinkList
    # 結果を表示
    print "%s" % alcoholRestriction

 

 

ユニットテスト

やってること単純だけれど、テストしながらじゃないと実装できない ^^;

import unittest
import Liquor
import logging
from decimal import Decimal

class TestLiquor(unittest.TestCase):

    def setUp(self): 
        # 単位
        self.unitGou = Liquor.Unit(u"合", 180)
        self.unitMl = Liquor.Unit(u"ml", 1)
        
        # 酒
        self.sake = Liquor.Liquor(u"焼酎", 25)
        self.whiskey = Liquor.Liquor(u"ウイスキー", 45)
        
        #--- 飲酒 ---
        # 焼酎を 1 合飲む
        self.d1 = Liquor.Drink(self.sake, Liquor.Quantity(1, self.unitGou))
        # ウイスキーを 100 ml 飲む
        self.d2 = Liquor.Drink(self.whiskey,
                                    Liquor.Quantity(100, self.unitMl))
        # 焼酎を 2 合飲む
        self.d3 = Liquor.Drink(self.sake, Liquor.Quantity(2, self.unitGou))
        # ウイスキーを 150 ml 飲む
        self.d4 = Liquor.Drink(self.whiskey,
                                    Liquor.Quantity(150, self.unitMl))

        # 飲酒リスト
        self.dl = Liquor.DrinkList()
        self.dl.add(self.d1).add(self.d2).add(self.d3).add(self.d4)
        
        self.dl2 = Liquor.DrinkList()
        self.dl2.add(self.d1)
        
        self.dl3 = Liquor.DrinkList()
        self.dl3.add(self.d3)
        
        # 飲酒制限
        self.alcoholRestriction = Liquor.AlcoholRestriction(
                                        Liquor.Drink(self.sake,
                                            Liquor.Quantity(2, self.unitGou)))
                                                        
    def tearDown(self): 
        pass
    
            
    def testAlcoholOfDrink(self):
        u""" 飲酒におけるアルコール量のテスト """
        # 焼酎を 1 合飲んだ場合、45 ml のアルコール
        self.assertEqual(45, self.d1.getAlcoholByMl())
            
    def testAlcoholOfDrinkList(self):
        u""" 飲酒リストのアルコール量をテスト """
        dl = Liquor.DrinkList()
        
        dl.add(self.d1)
        self.assertEqual(45, dl.getAlcoholByMl())

        dl.add(self.d2)
        self.assertEqual(90, dl.getAlcoholByMl())

        dl.add(self.d3)
        self.assertEqual(180, dl.getAlcoholByMl())

        dl.add(self.d4)
        self.assertEqual(Decimal("247.5"), dl.getAlcoholByMl())
        
        # 合で
        self.assertEqual(Decimal(str(1.375 * 180)), dl.getAlcoholByMl())
    
    def testQuantityOfDrink(self):
        u""" 1 合飲んだ焼酎の飲酒の量を ml で """
        self.assertEqual(45, self.d1.getAlcoholByMl())
        u""" 1 合飲んだ焼酎の飲酒の量を 合 で """
        self.assertEqual(45, self.d1.getAlcoholByMl())
        u""" 100 ml 飲んだウイスキーの飲酒の量を ml で """
        self.assertEqual(45, self.d2.getAlcoholByMl())
    
    def testAlcoholRestrictionSetting(self):
        u""" Alcoholrestriction クラスの設定 """
        self.assertEqual(90, self.alcoholRestriction.getLimitOfAlcoholByMl())

    def testCmpQuantity(self):
        # 単位が同じ場合
        self.assertEqual(0,
            cmp(Liquor.Quantity(10, self.unitGou),
                Liquor.Quantity(10, self.unitGou)))
        self.assertEqual(-1,
            cmp(Liquor.Quantity(9, self.unitGou),
                Liquor.Quantity(10, self.unitGou)))
        self.assertEqual(1,
            cmp(Liquor.Quantity(11, self.unitGou),
                Liquor.Quantity(10, self.unitGou)))
                
        self.assertEqual(True,
            Liquor.Quantity(10, self.unitGou) ==
            Liquor.Quantity(10, self.unitGou))
        self.assertEqual(True,
            Liquor.Quantity(10, self.unitGou) <=
            Liquor.Quantity(10, self.unitGou))
        self.assertEqual(True,
            Liquor.Quantity(10, self.unitGou) >=
            Liquor.Quantity(10, self.unitGou))
        self.assertEqual(False,
            Liquor.Quantity(10, self.unitGou) <
            Liquor.Quantity(10, self.unitGou))
        self.assertEqual(False,
            Liquor.Quantity(10, self.unitGou) >
            Liquor.Quantity(10, self.unitGou))
            
        self.assertEqual(True,
            Liquor.Quantity(9, self.unitGou) <
            Liquor.Quantity(10, self.unitGou))
        self.assertEqual(True,
            Liquor.Quantity(11, self.unitGou) >
            Liquor.Quantity(10, self.unitGou))

        # 単位が異なる場合
        self.assertEqual(0,
            cmp(Liquor.Quantity(10, self.unitGou),
                Liquor.Quantity(1800, self.unitMl)))
        self.assertEqual(-1,
            cmp(Liquor.Quantity(9, self.unitGou),
                Liquor.Quantity(1800, self.unitMl)))
        self.assertEqual(1,
            cmp(Liquor.Quantity(11, self.unitGou),
                Liquor.Quantity(1800, self.unitMl)))

        self.assertEqual(True,
            Liquor.Quantity(10, self.unitGou) ==
            Liquor.Quantity(1800, self.unitMl))
        self.assertEqual(True,
            Liquor.Quantity(10, self.unitGou) <=
            Liquor.Quantity(1800, self.unitMl))
        self.assertEqual(True,
            Liquor.Quantity(10, self.unitGou) >=
            Liquor.Quantity(1800, self.unitMl))
        self.assertEqual(True,
            Liquor.Quantity(9, self.unitGou) <
            Liquor.Quantity(1800, self.unitMl))
        self.assertEqual(True,
            Liquor.Quantity(11, self.unitGou) >
            Liquor.Quantity(1800, self.unitMl))
            
        self.assertEqual(False,
            Liquor.Quantity(10, self.unitGou) <
            Liquor.Quantity(1800, self.unitMl))
        self.assertEqual(False,
            Liquor.Quantity(10, self.unitGou) >
            Liquor.Quantity(1800, self.unitMl))

    def testAlcoholRestrictionPermit(self):
        u""" 飲酒リストのテスト """
        self.alcoholRestriction.setDrinkList(self.dl)
        self.assertEqual(False,
            self.alcoholRestriction.permit())
        
        self.alcoholRestriction.setDrinkList(self.dl2)
        self.assertEqual(True,
            self.alcoholRestriction.permit())

        # 2 合 ぎりぎり
        self.alcoholRestriction.setDrinkList(self.dl3)
        self.assertEqual(True,
            self.alcoholRestriction.permit())

        self.dl3.add(self.d1)
        self.alcoholRestriction.setDrinkList(self.dl3)
        self.assertEqual(False,
            self.alcoholRestriction.permit())
            
    def testAllcoholRestrictionPermit2(self):
        u""" Liquor モジュールにおいて定義してある簡便な方法をテスト """
        # 飲酒は「日本酒で2合まで」という制約決める
        alcoholRestriction = Liquor.AlcoholRestriction(Liquor.DRINK_SAKE(2))
        # 日本酒を 1 合飲んだ
        drinkList = Liquor.DrinkList().add(Liquor.DRINK_SAKE(1))
        # 飲酒制約を設定する
        alcoholRestriction.setDrinkList(drinkList)
        # 飲酒の総量は許容範囲か?
        self.assertEqual(True, alcoholRestriction.permit())
        # 焼酎を 0.7 合飲んだ
        drinkList.add(Liquor.DRINK_SAKE(0.7))
        self.assertEqual(True, alcoholRestriction.permit())
        # ウイスキーを 30 ml 飲んだ
        drinkList.add(Liquor.DRINK_WHISKEY(30))
        self.assertEqual(False, alcoholRestriction.permit())
        # 焼酎を 0.01 合飲んだ
        drinkList.add(Liquor.DRINK_SAKE(0.01))
        self.assertEqual(False, alcoholRestriction.permit())
        
            
if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG,
        format='%(asctime)s %(levelname)s ' + \
               '"%(pathname)s", line %(lineno)d, %(message)s')
    logging.getLogger().setLevel(logging.DEBUG)
    unittest.main()

2008年9月17日水曜日

Python のグローバル変数

4.1 名前づけと束縛 (naming and binding) によると、

ある名前がブロック内で束縛されている場合、名前はそのブロックにおけるローカル変数 (local variable) です。ある名前がモジュールレベルで束縛されている場合、名前はグローバル変数 (global variable) です。

6.13 global 文 によると、

global 文は、列挙した識別子をグローバル変数として解釈するよう指定することを意味します。 global を使わずにグローバル変数に代入を行うことは不可能です (…)

global 文で列挙する名前は、同じコードブロック中で、プログラムテキスト上 global 文より前に使ってはなりません。

試してみる。

hoge = 10

def test():
    # ローカル変数
    hoge = 1000

test()
print hoge   #=> 10


def test2():
    # グローバル変数
    global hoge
    hoge = 1000
    
test2()
print hoge   #=> 1000

PHP と同様か。

Ruby では、変数の前に $ を付けるとグローバル変数になる。(cf. 変数と定数 - Rubyリファレンスマニュアル)

Firebug が動かなくなったら

しばしばあるのだけれど、 Firebug を開くと灰色の画面が出るだけで何も表示されないことが。何か他のアドオンとバッティングしてるためなのか、それとも仕様なのかどうもよくわからない。 (+_+)  Firebug の動作を切り替えても何の反応もない。

080917-001

 

その度に Firefox を再起動していたが、次のようにすると Firebug が動作してくれた。

画面下の Firebug のアイコンをクリックし、「Firebug を新しいウィンドウで開く」を選択。

080917-002

 

新しいウィンドウが開いたら、メニューより、「表示 > 更新」を選択。

080917-003

 

上記の「更新」にショートカットキーとして、 Ctrl + R がついている。新しくウィンドウを開かなくても、ショートカットキーを押すだけで元のように動作するようになる。