-
-
Save manonthemat/7063263 to your computer and use it in GitHub Desktop.
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 urllib2 | |
import random | |
import difflib | |
import datetime | |
def fetch(url): | |
"""Fetches requested url, returns lines in list""" | |
response = urllib2.urlopen(url) | |
lines = response.readlines() | |
return lines | |
def parse(lines): | |
"""Parses lines, returning code grouped by block in dictionary""" | |
block_tags = ['def'] | |
ignore_tags = ['#'] | |
docstring_tags = ['"""', "'''"] | |
block_depth = 0 | |
result = {} | |
key = None | |
is_docstring = False | |
for line in lines: | |
# Strip trailing CR/LF/spaces | |
line = line.rstrip() | |
# Skip comments, etc | |
if search_start(line, ignore_tags): | |
continue | |
# Handle docstrings | |
if any(line.strip() == docstring_tag for docstring_tag in docstring_tags): | |
# For lines who only content is a docstring tag, open or close the docstring toggle | |
is_docstring = not is_docstring | |
continue | |
elif search_start(line, docstring_tags) and search_end(line, docstring_tags): | |
# For single line docstrings (lines that start and end with a docstring tag), skip | |
continue | |
elif search_start(line, docstring_tags) and not search_end(line, docstring_tags): | |
# For lines that start with docstring tag, but doesn't end with tag | |
is_docstring = not is_docstring | |
continue | |
# If docstring is true, line is part of a docstring block... skip. | |
if is_docstring: | |
continue | |
# Get the line's whitespace depth | |
line_depth = len(line) - len(line.lstrip()) | |
# If is new block definition, grab the line text to use as key | |
if search_start(line, block_tags): | |
block_depth = len(line) - len(line.lstrip()) | |
key = line.strip() | |
result[key] = [line[block_depth:]] | |
if line_depth > block_depth and key is not None: | |
# Remove block_depth leading whitespace, and append line to block | |
result[key].append(line[block_depth:]) | |
return result | |
def search_start(line, tags): | |
"""Returns boolean set if line starts with any tag.""" | |
# Strip the line | |
line = line.strip() | |
# Test if starts with any tag | |
starts = any(line.startswith(tag) for tag in tags) | |
return starts | |
def search_end(line, tags): | |
"""Returns boolean set if line ends with any tag.""" | |
# Strip the line | |
line = line.strip() | |
# Test if ends with any tag | |
ends = any(line.endswith(tag) for tag in tags) | |
return ends | |
def torture_someone(functions): | |
# Choose random function from list of functions | |
function = random.choice(functions.values()) | |
# Get index of random line in function | |
target_index = random.choice(range(len(function))) | |
# Make them do it until they get it right | |
accuracy = 0.00 | |
while accuracy != 1.0: | |
# Create a visual separator | |
print "=" * 60 | |
# Print lines from function, highlighting line to type | |
for line_index, line in enumerate(function): | |
if line_index == target_index: | |
result = "type this->{}".format(line) | |
else: | |
result = " |{}".format(line) | |
print result | |
# Make someone type it in, record the time to the timer. | |
start_time = datetime.datetime.now() | |
submission = raw_input("your turn >") | |
# Replace tabs with 4 whitespaces | |
submission = submission.replace("\t", " ") | |
duration = datetime.datetime.now() - start_time | |
# Judge the puny human | |
accuracy = difflib.SequenceMatcher(None, submission, function[target_index]).ratio() | |
print "-" * 60 | |
# Report their success | |
if accuracy == 1.0: | |
print "Nicely done, 100% match in {} seconds.".format(duration.seconds) | |
else: | |
print "Nope...{0:.0%} accuracy in {1} seconds. Try again.".format(accuracy, duration.seconds) | |
print "Me >{}".format(function[target_index]) | |
print "You >{}".format(submission) | |
def main(): | |
url = 'https://raw.github.com/django/django/master/django/core/servers/basehttp.py' | |
print "Pulling sample code from {}".format(url) | |
lines = fetch(url) | |
functions = parse(lines) | |
while True: | |
torture_someone(functions) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment