[Edu-sig] some real teaching code I use with my code school students

kirby urner kirby.urner at gmail.com
Fri Mar 18 21:18:05 EDT 2016


Here's some code I used with students last Monday, in Session 8 of 10.

They've covered all the Python keywords as of Session 7 but we still need
to keep going over all we've learned, seeing how the concepts mesh
together.

Actually at this point we haven't looked at the newest keywords async and
await, nor yield from as a construct.

An epiphany or at least a glue-it-together moment is when we show how a
decorator of a function generator may be used to give a context manager.

The two versions of the game below work the same way, but the second
applies said decorator logic.

The script suggests seeing the "context" as a Spooky Castle one enters,
there to guess one of the keywords.  That's the challenge.

Guessing right still results in an exception being raised, but one that's
handled by __exit__, whereas failure to "get it right" results in a
different exception still in need of handling even after the scope of the
with block.

Kirby

====
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 11 04:58:14 2016

@author: Kirby Urner
Copyleft MIT License

>From the docs:

sys.exc_info()

This function returns a tuple of three values that give information
about the exception that is currently being handled. The information
returned is specific both to the current thread and to the current
stack frame....  see docs for more

"""

from keyword import kwlist
from random import choice
import sys

class EscapeVictorious(Exception):
    pass

class KickFromCastle(Exception):
    pass

class Castle:

    def __init__(self, secret):
        self.__xyjk = secret
        self.guesses = 0
        self.hints = 0

    def __enter__(self):
        """get the ball rolling"""
        print("Welcome to Spooky Castle. To Escape, guess the secret
keyword")
        return self  # <-- make instance available within scope via 'as'

    def hint(self):
        if self.hints == 0:
            print("The keyword begins with", self.__xyjk[0])
        elif self.hints == 1:
            print("The keyword is", len(self.__xyjk), "letters long.")
        else:
            print("You've had your two hints, sorry")
        self.hints += 1

    def query(self):
        """gradations"""
        print("So what is the secret keyword then?  Guess so far:",
self.guesses)
        ans = input("You may answer (or type 'hint'): ")
        if ans == self.__xyjk:
            print("Excellent, we're done here")
            print("You have won the Copper Key") # <-- RealPlayer One
(novel)
            raise EscapeVictorious("Copper Key")
        elif self.guesses == 5:
            print("Uh oh, you're out of guesses, sigh")
            raise KickFromCastle("We're done!")
        elif ans == "hint":
            self.hint()
            return
        else:
            self.guesses += 1
            print("No, that's not it.")

    def __exit__(self, *exception_data):
        """raise a ruckus"""
        if exception_data[0] == EscapeVictorious:
            print("Congratulations!")
            print("Here is your", exception_data[1])
            return True
        if exception_data[0] == KickFromCastle:
            print("Better Luck Next Time")
            print("The keyword was", self.__xyjk)
            return False

if __name__ == "__main__":
    the_secret = choice(kwlist)
    try:
        with Castle(the_secret) as spooky:
            while True:
                spooky.query()
    except:
        print("Handling: ", sys.exc_info()[0].__name__)
        print(sys.exc_info()[1])  # <--- triggers __str__
        print(type(sys.exc_info()[1]))


===

# -*- coding: utf-8 -*-
"""
Created on Thu Feb 11 06:00:49 2016

@author: Kirby Urner
Copyleft MIT License

"""

from contextlib import contextmanager

from keyword import kwlist
from random import choice
import sys

class EscapeVictorious(Exception):
    pass

class KickFromCastle(Exception):
    pass

@contextmanager
def Castle(secret):
    try:
        obj = Game(secret)
        print("Welcome to Spooky Castle. To Escape, guess the secret
keyword")
        yield obj  # <-- make instance available within scope via 'as'
    except EscapeVictorious as ex:
        print("Congratulations!")
        print("Here is your", ex)
        return None # default, could leave out or pass
    except KickFromCastle:
        print("Better Luck Next Time")
        print("The keyword was", obj._Game__xyjk)
        raise

class Game:

    def __init__(self, the_secret):
        self.__xyjk = the_secret
        self.guesses = 0
        self.hints = 0

    def hint(self):
        if self.hints == 0:
            print("The keyword begins with", self.__xyjk[0])
        elif self.hints == 1:
            print("The keyword is", len(self.__xyjk), "letters long.")
        else:
            print("You've had your two hints, sorry")
        self.hints += 1

    def query(self):
        """gradations"""
        print("So what is the secret keyword then?  Guess so far:",
self.guesses)
        ans = input("You may answer (or type 'hint'): ")
        if ans == self.__xyjk:
            print("Excellent, we're done here")
            print("You have won the Copper Key") # <-- RealPlayer One
(novel)
            raise EscapeVictorious("Copper Key")
        elif self.guesses == 5:
            print("Uh oh, you're out of guesses, sigh")
            raise KickFromCastle("We're done!")
        elif ans == "hint":
            self.hint()
            return
        else:
            self.guesses += 1
            print("No, that's not it.")

if __name__ == "__main__":
    the_secret = choice(kwlist)
    try:
        with Castle(the_secret) as spooky:
            while True:
                spooky.query()

    except KickFromCastle:
        print("Handling: ", sys.exc_info()[0].__name__)
        print(sys.exc_info()[1])  # <--- triggers __str__
        print(type(sys.exc_info()[1]))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20160318/f8c45b74/attachment.html>


More information about the Edu-sig mailing list