10/11 卵と牛乳が好きです

オーソドックスだけど最高.

 

ダック・タイピング

「もしも,それがアヒルのように歩き,アヒルのように泣くのなら,それはアヒルである」

クラスの型が違っても,同じメソッドを持っていれば同様に処理する,つまりそれぞれ別のクラスに所属していても,defで定義されるメソッドが同じならば,同じように処理されるという動的プログラミング言語としての機能.

以下の例では,鶴亀算を定義する.このとき,いかたこについてもつるかめのようにメソッドを定義していれば,いかたこ算を実行できる,というのがダックタイピング.

###問題
'''鶴と亀が併せて10匹,脚は28本.鶴と亀はそれぞれ何羽何匹?'''
'''烏賊と蛸が併せて11杯,脚は100本.烏賊と蛸はそれぞれ何杯?'''

#つるかめいかたこクラス
class Tsuru:
def get_name(self):
return "鶴"
def get_legs(self):
return 2

class Kame:
def get_name(self):
return "亀"
def get_legs(self):
return 4

class Ika:
def get_name(self):
return "烏賊"
def get_legs(self):
return 10

class Tako:
def get_name(self):
return "蛸"
def get_legs(self):
return 8

#鶴亀算を解く関数
##あくまでも「つる」「かめ」だけ
def calc_tsurukame(tsuru, kame, heads, legs):
tsuru_1 = tsuru.get_legs()
kame_1 = kame.get_legs()
tsuru_name = tsuru.get_name()
kame_name = kame.get_name()

kame_num = (legs - tsuru_1 * heads)//(kame_1 - tsuru_1)
tsuru_num = heads - kame_num

print("---入力---")
print("頭=", heads, "足=", legs)
print(tsuru_name, "=", tsuru_num)
print(kame_name, "=", kame_num)
return(tsuru_num, kame_num)

#もちろんつるかめは計算できる
calc_tsurukame(Tsuru(), Kame(), heads = 10, legs = 28)

#いかたこも計算できる
calc_tsurukame(Ika(), Tako(), heads = 11, legs = 100)

C:\Users\bin\Anaconda3\python.exe C:/Users/bin/PycharmProjects/practice/practice8.py
---入力---
頭= 10 足= 28
鶴 = 6
亀 = 4
---入力---
頭= 11 足= 100
烏賊 = 6
蛸 = 5

Process finished with exit code 0



ユニットテスト

プログラムのうち,小さい単位で正しく動くかどうかを検証するためのテスト.

上の鶴亀算をモジュールとして使うので,最後の部分を変える.

###問題
'''鶴と亀が併せて10匹,脚は28本.鶴と亀はそれぞれ何羽何匹?'''
'''烏賊と蛸が併せて11杯,脚は100本.烏賊と蛸はそれぞれ何杯?'''

#つるかめいかたこクラス
class Tsuru:
def get_name(self):
return "鶴"
def get_legs(self):
return 2

class Kame:
def get_name(self):
return "亀"
def get_legs(self):
return 4

class Ika:
def get_name(self):
return "烏賊"
def get_legs(self):
return 10

class Tako:
def get_name(self):
return "蛸"
def get_legs(self):
return 8

#鶴亀算を解く関数
##あくまでも「つる」「かめ」だけ
def calc_tsurukame(tsuru, kame, heads, legs):
tsuru_1 = tsuru.get_legs()
kame_1 = kame.get_legs()
tsuru_name = tsuru.get_name()
kame_name = kame.get_name()

kame_num = (legs - tsuru_1 * heads)//(kame_1 - tsuru_1)
tsuru_num = heads - kame_num

print("---入力---")
print("頭=", heads, "足=", legs)
print(tsuru_name, "=", tsuru_num)
print(kame_name, "=", kame_num)
return(tsuru_num, kame_num)

# モジュールではないときに以上の計算を実行する(モジュールのときはしない)という処理
if __name__ == '__main__':
# もちろんつるかめは計算できる
calc_tsurukame(Tsuru(), Kame(), heads=10, legs=28)
# いかたこも計算できる
calc_tsurukame(Ika(), Tako(), heads=11, legs=100)


変えた部分では,モジュールとして利用される際に,鶴亀算の演算を実行しないようにしている.

※特殊変数__name__

通常モジュールとして外部のプログラムから取り込まれるときはモジュールの名前が設定される

メインプログラムとして実行されるときにはここに__main__が設定される仕組みをつけているということ.

 

Pythonに最初からついているモジュールunittestを利用する.

import unittest
import practice8

class TestTsurukame(unittest.TestCase):

def test_tsurukame(self):
tsuru, kame = practice8.calc_tsurukame(
practice8.Tsuru(),
practice8.Kame(),
heads = 10, legs = 28)

self.assertEqual(tsuru, 6, "基本的な計算で鶴の数")
self.assertEqual(kame, 4, "基本的な計算で亀の数")

 

が,unittestの実行ができない.というかコンソールに何も出ない.本来はOKみたいなことが出るはず.使用はPyCharm.検索して以下を見つけたが

 

ksilverwall.hatenablog.com

PyCharmではプロジェクト直下にソースコードを置いたらだめで,次のような構成にする必要があるらしい.が,そこではない?よくわからない.

root/
+- main/
    +- product.py
    +- test/
        +- test_code.py

パッケージインストールもものによってはうまくできなくて,$がついているのをコマンドラインから実行するっていうのができていない.んーわからない!

 

www.ibm.com

 

Dijikstra法(つづき)

変数一覧

adj[i][j]: 頂点iから頂点jまでの距離
start: 始点のID
goal: オプション引数.終点のID
q:
プライオリティキュー.各要素は,(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル
num: グラフのノード数
dist:
始点から各頂点までの最短距離.最初は全部(グラフのノード数と同じ個数)∞にする.
prev: 最短経路における,その頂点の前の頂点のIDを格納する.上に同じ
prov_cost: いままでで一番優先度が高いもの,つまり距離が短いもの
srcに入れる

dest: ほかの頂点探索に使う.グラフのノード数と同じ長さだけ繰り返すことを指示する

まだつづく.