Skip to content

Instantly share code, notes, and snippets.

@rik0
Created April 17, 2011 13:51
Show Gist options
  • Save rik0/924042 to your computer and use it in GitHub Desktop.
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. ;)
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