# -*- coding: utf-8 -*- """ Created on Thu Feb 11 09:08:42 2016
@author: Kirby Urner A Game of Life (c) MIT License, 2016 Die: 2 or more sides Cup: 1 or more dice Exceptions subclasses Run a gauntlet of possible exceptions, with Game for scope """ from random import choice #==== What Could Go Wrong? ==== class TrafficTicket(Exception): def __init__(self, m=""): self.message = m class GoToJail(Exception): pass class SecondChance(Exception): pass #==== Element of Chance ======= class Die: """ * As many sides as you like, suggested minimum of two (like a coin) * Switch on record=True to keep a record of throws """ def __init__(self, sides=6, record=False): self.sides = range(1, sides+1) self._throws = [ ] self.record = record @property # treat as a simple attribute def throw(self): v = choice(self.sides) if self.record: self._history(v) return v def _history(self, value): self._throws.append(value) @property def history(self): if not self.record: raise AttributeError # no record kept! return self._throws class Cup: """ Put as many dice as you like in the Cup. At least one. The dice should be passed in positionally as in Cup(Die(), Die()) """ def __init__(self, *dice): self._dice = dice def __getitem__(self, n): return self._dice[n] @property def throw(self): total = 0 for die in self._dice: total += die.throw return total def some_risky_business(): """ Take a turn, see what fate has in store! """ venture_outcome = dice_cup.throw if venture_outcome == 12: # traffic misadventure raise TrafficTicket("No Left Turn!") elif venture_outcome == 2: # court finds your venture a Ponzi scheme raise GoToJail # Monopoly maneuver elif choice(range(10)) == 7: # not from dice! # starting over can be a good thing raise SecondChance else: print("So far so good...") class Game: """ Hi, I'm a context manager, like a gatekeeper, with an "in" and "out" method. Upon leaving, I handle all exceptions """ def __enter__(self): return self def __exit__(self, *exc_data): if exc_data[0]: # exception happened print("Oh well. Better luck next time!") else: print("Congratulations") # transcript is added to the game instance by the # else suite in the for loop below print("Lucky throws", self.transcript) return True # OK, we're good if __name__ == "__main__": with Game() as g: # game object available within scope """ If you're lucky, you won't roll a 2 or 12 in five rolls. Otherwise, the exception handling machinery will deal with your case. :-D """ dice_cup = Cup(Die(record=True), Die(record=True)) # two dice while True: # like an ever turning wheel of fortune... turns = 0 try: for _ in range(5): some_risky_business() # returns None ... else: print("You lucked out!") # adding the two histories gives a record of Cup throws # making an attribute of the game object g.transcript = [sum([i,j]) for i,j in zip(dice_cup[0].history, dice_cup[1].history)] # an exception will occur... except TrafficTicket as exc: print(exc.message) raise # propagate loose end! except GoToJail: print("GoToJail raised") raise # re-raise same exception except SecondChance: print("Get to start over!") continue # turns reset to 0 else: print("You tried, and succeeded!") break # escape from the Wheel of Risk print("There's still life after scope") print("The dice_cup is still with us....") for _ in range(4): print(dice_cup.throw, end=" ") print()
_______________________________________________ Edu-sig mailing list Edu-sig@python.org https://mail.python.org/mailman/listinfo/edu-sig