Created
April 17, 2011 13:51
-
-
Save rik0/924042 to your computer and use it in GitHub Desktop.
Cleanly separated elementary "guess password" game. Shows extreme separation of concerns and an enhanced generator (coroutines) based solution.
The whole structure is as stateless as possible, even when objects are used. Easy stuff made hard. ;)
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
import sys | |
class TextualUI(object): | |
def __init__(self, out=sys.stdout): | |
self.out = out | |
def inform_defeat(self, _max_attempts): | |
message = 'You lost.\n' | |
self.out.write(message) | |
def inform_success(self, attempt, guess, max_attempts): | |
message = ('You won with %d/%d attempts. The secret was %s.\n' % | |
(attempt, max_attempts, guess)) | |
self.out.write(message) | |
def inform_failure(self, attempt, guess, max_attempts): | |
message = ('Your guess %s is wrong. You used %d/%d attempts.\n' % | |
(guess, attempt, max_attempts)) | |
self.out.write(message) | |
def prompt(self, attempt, max_attempts): | |
return '%d/%d> ' % (attempt, max_attempts) | |
def initial_prompt(self, max_attempts): | |
return self.prompt(1, max_attempts) | |
def input_generator(initial_prompt='> '): | |
prompt = initial_prompt | |
while 1: | |
prompt = yield raw_input(prompt) | |
if prompt is None: | |
prompt = initial_prompt | |
def guess_password(ui, input_stream, secret, max_attempts): | |
for attempt, guess in enumerate(input_stream, start=1): | |
if secret == guess: | |
ui.inform_success(attempt, secret, max_attempts) | |
return attempt | |
elif attempt == max_attempts: | |
ui.inform_defeat(max_attempts) | |
return attempt | |
else: | |
ui.inform_failure(attempt, guess, max_attempts) | |
def guess_password_prompt(ui, input_stream, secret, max_attempts): | |
guess = input_stream.next() | |
attempt = 1 | |
while 1: | |
if secret == guess: | |
ui.inform_success(attempt, secret, max_attempts) | |
return attempt | |
elif attempt == max_attempts: | |
ui.inform_defeat(max_attempts) | |
return attempt | |
else: | |
ui.inform_failure(attempt, guess, max_attempts) | |
attempt += 1 | |
guess = input_stream.send(ui.prompt(attempt, max_attempts)) | |
if __name__ == "__main__": | |
max_attempts = 3 | |
ui = TextualUI() | |
generator = input_generator(ui.initial_prompt(max_attempts)) | |
secret = 'foo' | |
guess_password_prompt(ui, generator, secret, max_attempts) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment