Last active
August 29, 2015 13:58
-
-
Save tylerneylon/10074737 to your computer and use it in GitHub Desktop.
A Python3 script to help exercise your memory.
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
#!/usr/local/bin/python3 | |
import datetime | |
import json | |
import os | |
import random | |
import time | |
num_words = 10 | |
num_seconds = 10 | |
scores = None | |
one_day = datetime.timedelta(days=1) | |
def clear_screen(): | |
# I have not actually tested this beyond mac os x. | |
os.system('cls' if os.name == 'nt' else 'clear') | |
def save_score(score): | |
global scores | |
score_file = 'scores.json' | |
scores = [] | |
if os.path.exists(score_file): | |
with open(score_file) as f: | |
scores = json.load(f) | |
scores.append([time.time(), score]) | |
with open(score_file, 'w') as f: | |
json.dump(scores, f, indent=2) | |
# Returns the average score and score count for the given time period, or (None, 0) | |
# if no scores are in that time. Returns values for all time if the input is None. | |
def average_and_count(day = None): | |
global scores | |
s = scores # s is the subset of scores to average. | |
if day is not None: | |
day_start = time.mktime(day.timetuple()) | |
day_end = time.mktime((day + one_day).timetuple()) | |
s = list(filter(lambda x: day_start <= x[0] < day_end, scores)) | |
if len(s) == 0: return (None, 0) | |
return (sum([x[1] for x in s]) / len(s), len(s)) | |
# Assumes the global scores list has been populated. | |
def show_averages(): | |
print(' Average Count') | |
fmt = '%-13s %4.1f %9d' | |
today = datetime.date.today() | |
print(fmt % (('Today',) + average_and_count(today))) | |
yesterday = today - one_day | |
avg, count = average_and_count(yesterday) | |
if avg is not None: print(fmt % ('Yesterday', avg, count)) | |
print(fmt % (('All time',) + average_and_count())) | |
# Load data and choose the words. | |
f = open('words') | |
all_words = f.read().split('\n')[:-1] | |
f.close() | |
correct_words = set(random.sample(all_words, num_words)) | |
# Display the words for a few seconds. | |
for w in correct_words: print(w) | |
print('\nTime left:') | |
time_left = num_seconds | |
while time_left: | |
print('\r%2d second%s ' % (time_left, 's' if time_left > 1 else ' '), end='') | |
time.sleep(1) | |
time_left -= 1 | |
clear_screen() | |
# Accept words from the user. | |
print('Type in the words you remember, one per line.') | |
print('Hit enter twice when you\'re done.') | |
user_words = set() | |
while True: | |
new_word = input().strip() | |
if len(new_word) == 0: break | |
user_words.add(new_word) | |
# Let the user know how they did. | |
num_errors = len(correct_words ^ user_words) | |
report = ['Perfect!', | |
'Only 1 mistake - not bad!', | |
'You made %d mistakes.' % num_errors] | |
print(report[min(num_errors, 2)]) | |
missed = correct_words - user_words | |
if len(missed): | |
print('\nMissed words:') | |
for w in missed: print(w) | |
incorrect = user_words - correct_words | |
if len(incorrect): | |
print('\nIncorrect words:') | |
for w in incorrect: print(w) | |
score = len(correct_words & user_words) | |
save_score(score) | |
# Pad the strings so they form nice columns with the averages. | |
print('\n%-13s %2d\n' % ('Score', score)) | |
show_averages() | |
print('\nThank you come again.') | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This script presents a random list of words and gives you 10 seconds to memorize those words. The screen is then cleared and you type in as many of them as you can remember - the order is not important.
This script keeps track of your scores over time in a file called
scores.json
. It reports your averages scores from today, yesterday (if you played), and your overall average. These metrics will let you see how you're improving over time.