Simple flashcard program in Python

It’s well known among parents that the first kid gets lavished with attention and the later ones almost raise themselves. A common joke is that every move the first child makes is photographed and entered in the baby book; the last child’s baby book has just the time of birth and the photo taken at the hospital. The dropoff in scrutiny is partly due to the parents’ divided attention, partly due to the parents’ recognition that kid’s don’t need to be under a microscope, and partly due to fatigue as the parents get older.

I made flashcards for my first two kids when they were learning elementary arithmetic and dutifully went through them most nights. (In our district, the grade school teachers have outsourced the dull drilling of math facts to the parents, keeping the fun, high-level conceptual stuff to themselves.) For the third kid, I wrote this program and he drills himself, leaving me more time to “rest my eyes.”

Here’s the program. It has many more comments than I would usually put in, because I want to use it as a teaching tool for the middle child, who’s just old enough to start programming.

 1:  #!/usr/bin/env python
 3:  from random import randint
 4:  from time import localtime, mktime
 6:  # How long the user will have to answer each problem.
 7:  time_limit = 15
 9:  # Initialize the number of problems and the score.
10:  count = 0
11:  right = 0
13:  # Describe the program and let the user decide when to begin.
14:  print '''
15:  ******************* Math practice ********************
17:  There will be both addition and subtraction problems.
18:  Answer each problem by typing the answer and pressing
19:  the Return or Enter key. To get credit, you have to
20:  answer in %d seconds.
22:  Press the 'q' key when you want to quit.
23:  ''' % time_limit
25:  raw_input('Ready? Press Return or Enter to begin. ')
26:  print
28:  # 
29:  while True:
30:    count += 1
32:    # Choose three numbers so that a + b = c, with c from 10 to 20.
33:    c = randint(10,20)
34:    b = randint(0,c)
35:    a = c - b
37:    # Choose whether to give an addition (a + b = c)
38:    # or subtraction (c - b = a) problem.
39:    if randint(0, 1) == 0:
40:      # Addition.
41:      problem = '%d + %d = ' % (a, b)
42:      correct_answer = c
43:    else:
44:      # Subtraction.
45:      problem = '%d - %d = ' % (c, b)
46:      correct_answer = a
48:    # Show the problem and get the answer. Time it.
49:    start_time = mktime(localtime())
50:    user_answer = raw_input('%3d.   ' % count + problem)
51:    end_time = mktime(localtime())
53:    # Break out of the loop when the user wants to quit.
54:    if user_answer.lower() == 'q':
55:      count -= 1      # the last problem doesn't count
56:      break
58:    # Answers that took too long are counted wrong.
59:    if end_time - start_time > time_limit:
60:      print '       Too long!'
61:      continue
63:    # Check the answer and mark it right or wrong. Because user_answer
64:    # is a string, it has to be converted to an integer first. If the
65:    # answer doesn't look like an integer, it's wrong.
66:    try:
67:      if int(user_answer) == correct_answer:
68:        right += 1
69:        print '       Right!'
70:      else:
71:        print '       No, %s%d' % (problem, correct_answer)
72:    except:
73:      print '       %s?   %s%d' % (user_answer, problem, correct_answer)
75:  # Let the user know the final score.
76:  print "\n       You got %d right out of %d." % (right, count),
77:  if right == count:
78:    print "Perfect!"

Even without the comments, the program is pretty self-explanatory. The trickiest thing—and it isn’t very tricky—is the way the program handles both addition and subtraction and forces the biggest number in the problem to be in the range of 10 through 20. The youngest has already mastered addition and subtraction for numbers up to 10, so the program stays away from those problems.

The time limit of 15 seconds may seem too high, but you’d be surprised at how long it takes someone who doesn’t work at a keyboard all day to find and press the right keys. I first had the time limit at 10 seconds, but it didn’t work. My son would sometimes say the right answer, but wouldn’t type it and hit Enter until after the 10 seconds was up. Now that he’s more used to the keyboard, I’ll probably move the time limit back down.

When the youngest moves on to multiplication, I’ll work with his older brother to change the program. If I’m lucky, by the time division rolls around the older brother will be able to do the programming by himself. Fatigue, laziness, or innovative parenting?