-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
223 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
"""Init file for chapter_10_state package.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""Gumball machine module.""" | ||
from .state import NoQuarterState, SoldOutState, State | ||
|
||
|
||
class GumballMachine: | ||
"""Gumball machine class.""" | ||
|
||
def __init__(self, gumballs_amount: int) -> None: | ||
"""Initialize with state and gubmalls amount.""" | ||
self._state: State = ( | ||
NoQuarterState() if gumballs_amount > 0 else SoldOutState() | ||
) | ||
self._gubmalls_amount = gumballs_amount | ||
|
||
def _transition_to(self, state: State | None) -> None: | ||
"""Transition to a new state.""" | ||
if state is not None: | ||
self._state = state | ||
|
||
def insert_quarter(self) -> None: | ||
"""Insert quarter method.""" | ||
new_state: State | None = self._state.insert_quarter() | ||
self._transition_to(new_state) | ||
|
||
def eject_quarter(self) -> None: | ||
"""Eject quarter method.""" | ||
new_state: State | None = self._state.eject_quarter() | ||
self._transition_to(new_state) | ||
|
||
def turn_crunk(self) -> None: | ||
"""Turn crank method.""" | ||
new_state: State | None = self._state.turn_crank() | ||
self._transition_to(new_state) | ||
|
||
def dispense(self) -> None: | ||
"""Dispense gumball method.""" | ||
is_gumball_last = self._gubmalls_amount == 1 | ||
new_state: State | None = self._state.dispense(is_gumball_last) | ||
if new_state is not None: | ||
self._gubmalls_amount -= 1 | ||
self._transition_to(new_state) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
"""State module.""" | ||
|
||
from .gumball_machine import GumballMachine | ||
|
||
|
||
def run_pattern_example() -> None: | ||
"""Run pattern example.""" | ||
machine = GumballMachine(3) | ||
|
||
print() | ||
print('Trying to manipulate the machine without coins') | ||
machine.turn_crunk() | ||
machine.dispense() | ||
machine.eject_quarter() | ||
|
||
print() | ||
print('Trying to insert two coins') | ||
machine.insert_quarter() | ||
machine.insert_quarter() | ||
|
||
print() | ||
print('Trying to eject coin two times') | ||
machine.eject_quarter() | ||
machine.eject_quarter() | ||
|
||
print() | ||
print('Trying to turn crank two times') | ||
machine.insert_quarter() | ||
machine.turn_crunk() | ||
machine.turn_crunk() | ||
|
||
print() | ||
print('Trying to dispense gumball two times') | ||
machine.dispense() | ||
machine.dispense() | ||
|
||
print() | ||
print('Use machine the normal way') | ||
machine.insert_quarter() | ||
machine.turn_crunk() | ||
machine.dispense() | ||
machine.insert_quarter() | ||
machine.turn_crunk() | ||
machine.dispense() | ||
|
||
print() | ||
print('Trying to manipulate the sold out machine') | ||
machine.insert_quarter() | ||
machine.turn_crunk() | ||
machine.dispense() | ||
|
||
|
||
if __name__ == "__main__": | ||
run_pattern_example() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
"""Abstract state class and 4 its implementations.""" | ||
|
||
from __future__ import annotations | ||
|
||
from abc import ABC, abstractmethod | ||
|
||
|
||
class State(ABC): | ||
"""Abstract state class.""" | ||
|
||
@abstractmethod | ||
def insert_quarter(self) -> State | None: | ||
"""Abstract insert quarter method. | ||
All child classes should implement this method. | ||
""" | ||
|
||
@abstractmethod | ||
def eject_quarter(self) -> State | None: | ||
"""Abstract eject quarter method. | ||
All child classes should implement this method. | ||
""" | ||
|
||
@abstractmethod | ||
def turn_crank(self) -> State | None: | ||
"""Abstract turn crank method. | ||
All child classes should implement this method. | ||
""" | ||
|
||
@abstractmethod | ||
def dispense(self, is_gumball_last: bool) -> State | None: | ||
"""Abstract dispense gumballn method. | ||
All child classes should implement this method. | ||
""" | ||
|
||
|
||
class NoQuarterState(State): | ||
"""No quarter state class.""" | ||
|
||
def insert_quarter(self) -> State: | ||
"""Insert quarter method implementation.""" | ||
print("You inserted a quarter") | ||
return HasQuarterState() | ||
|
||
def eject_quarter(self) -> None: | ||
"""Eject quarter method implementation.""" | ||
print("You haven't inserted a quarter") | ||
|
||
def turn_crank(self) -> None: | ||
"""Turn crank method implementation.""" | ||
print("You turned, but there's no quarter") | ||
|
||
def dispense(self, is_gumball_last: bool) -> None: | ||
"""Dispense gumball method implementation.""" | ||
print("You need to pay first") | ||
|
||
|
||
class HasQuarterState(State): | ||
"""Has quarter state class.""" | ||
|
||
def insert_quarter(self) -> None: | ||
"""Insert quarter method implementation.""" | ||
print("You can't insert another quarter") | ||
|
||
def eject_quarter(self) -> State: | ||
"""Eject quarter method implementation.""" | ||
print("Quarter returned") | ||
return NoQuarterState() | ||
|
||
def turn_crank(self) -> State: | ||
"""Turn crank method implementation.""" | ||
print("You turned...") | ||
return SoldState() | ||
|
||
def dispense(self, is_gumball_last: bool) -> None: | ||
"""Dispense gumball method implementation.""" | ||
print("No gumball dispensed") | ||
|
||
|
||
class SoldState(State): | ||
"""Sold state class.""" | ||
|
||
def insert_quarter(self) -> None: | ||
"""Insert quarter method implementation.""" | ||
print("Wait for ball") | ||
|
||
def eject_quarter(self) -> None: | ||
"""Eject quarter method implementation.""" | ||
print("You already turned crank") | ||
|
||
def turn_crank(self) -> State: | ||
"""Turn crank method implementation.""" | ||
print("Even if you turn twice you got one ball") | ||
return SoldState() | ||
|
||
def dispense(self, is_gumball_last: bool) -> State: | ||
"""Dispense gumball method implementation.""" | ||
print("A gumball comes rolling out the slot...") | ||
if not is_gumball_last: | ||
return NoQuarterState() | ||
|
||
print('Machine is sold out!') | ||
return SoldOutState() | ||
|
||
|
||
class SoldOutState(State): | ||
"""Sold out state class.""" | ||
|
||
def insert_quarter(self) -> None: | ||
"""Insert quarter method implementation.""" | ||
print("You can't insert a quarter, the machine is sold out") | ||
|
||
def eject_quarter(self) -> None: | ||
"""Eject quarter method implementation.""" | ||
print("You haven't inserted a quarter") | ||
|
||
def turn_crank(self) -> None: | ||
"""Turn crank method implementation.""" | ||
print("You turned, but there is no gumballs") | ||
|
||
def dispense(self, is_gumball_last: bool) -> None: | ||
"""Dispense gumball method implementation.""" | ||
print("No gumball dispensed") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,5 +37,5 @@ omit = [ | |
parallel = true | ||
|
||
[tool.coverage.report] | ||
fail_under = 80 | ||
fail_under = 75 | ||
show_missing = true |