-
Notifications
You must be signed in to change notification settings - Fork 6.9k
/
state.py
89 lines (66 loc) · 2.18 KB
/
state.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""
Implementation of the state pattern
http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
*TL;DR
Implements state as a derived class of the state pattern interface.
Implements state transitions by invoking methods from the pattern's superclass.
"""
from __future__ import annotations
class State:
"""Base state. This is to share functionality"""
def scan(self) -> None:
"""Scan the dial to the next station"""
self.pos += 1
if self.pos == len(self.stations):
self.pos = 0
print(f"Scanning... Station is {self.stations[self.pos]} {self.name}")
class AmState(State):
def __init__(self, radio: Radio) -> None:
self.radio = radio
self.stations = ["1250", "1380", "1510"]
self.pos = 0
self.name = "AM"
def toggle_amfm(self) -> None:
print("Switching to FM")
self.radio.state = self.radio.fmstate
class FmState(State):
def __init__(self, radio: Radio) -> None:
self.radio = radio
self.stations = ["81.3", "89.1", "103.9"]
self.pos = 0
self.name = "FM"
def toggle_amfm(self) -> None:
print("Switching to AM")
self.radio.state = self.radio.amstate
class Radio:
"""A radio. It has a scan button, and an AM/FM toggle switch."""
def __init__(self) -> None:
"""We have an AM state and an FM state"""
self.amstate = AmState(self)
self.fmstate = FmState(self)
self.state = self.amstate
def toggle_amfm(self) -> None:
self.state.toggle_amfm()
def scan(self) -> None:
self.state.scan()
def main():
"""
>>> radio = Radio()
>>> actions = [radio.scan] * 2 + [radio.toggle_amfm] + [radio.scan] * 2
>>> actions *= 2
>>> for action in actions:
... action()
Scanning... Station is 1380 AM
Scanning... Station is 1510 AM
Switching to FM
Scanning... Station is 89.1 FM
Scanning... Station is 103.9 FM
Scanning... Station is 81.3 FM
Scanning... Station is 89.1 FM
Switching to AM
Scanning... Station is 1250 AM
Scanning... Station is 1380 AM
"""
if __name__ == "__main__":
import doctest
doctest.testmod()