Flash card challenge: Difference between revisions

From OpenHatch wiki
Content added Content deleted
imported>Jesstess
(Created page with "== Project == Write a flash card quizzer from scratch. == Goals == * practice breaking down a problem and solving it in Python from scratch * practice command line option p...")
 
imported>Jeremyb
m (Reverted edits by 31.25.3.98 (talk) to last revision by Jesstess)
 
(15 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[File:Flashcards.jpg|right|300px]]

== Project ==
== Project ==


Line 12: Line 14:
== Problem statement ==
== Problem statement ==


Write a Python script that takes a file as an argument and quizzes the user based on the contents of that file until the user quits the program. Questions should be selected randomly (as opposed to going in order through the file), and the user should type in their guess. The script should say whether or not a guess is correct and provide the correct answer if an incorrect answer is given.
Write a Python script that takes a file containing flash card questions and answers as an argument and quizzes the user based on the contents of that file until the user quits the program. Questions should be selected randomly (as opposed to going in order through the file), and the user should type in their guess. The script should say whether or not a guess is correct and provide the correct answer if an incorrect answer is given.


The file will contain flash card challenges in the form:
The file will contain flash card challenges in the form:
Line 44: Line 46:
Goodbye</pre>
Goodbye</pre>


== Project steps ==
== Breaking down the problem ==


=== Step 1: Get the questions from a fixed flash card file===
=== 1. Learn about HSV values ===


Download http://web.mit.edu/jesstess/www/IntermediatePythonWorkshop/state_capitals.txt.
Run the ColorWall effects again with


Write the code to open and read <code>state_capitals.txt</code> (we'll deal with getting a variable filename from the user later). Create a dictionary, where each comma-separated question and answer become a key and value in the dictionary. Note that each line in the file ends in a newline, which you'll need to remove from the word.
<pre>python run.py -a</pre>


<b>Step 1 resources</b>:
The names of the effects are printed to the terminal as they are run. Pay particular attention to the first 4 effects:
<ul>
* SolidColorTest
<li>
* HueTest
File input and output: http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files.
* SaturationTest
</li>
* ValueTest
<li>
Stripping characters (like whitespace and newlines) from a string: http://docs.python.org/library/stdtypes.html#str.strip.
</li>
</ul>


In all of these effects, a tuple <code>hsv</code> containing the hue, saturation, and value describing a color are passed to <code>self.wall.set_pixel</code> to change the color of a single pixel on the wall.


=== Step 2: Randomly select questions from the question dictionary ===
What are the differences between these tests? Given these difference and how they are expressed visually, how does varying hue, saturation, or value change a color?


Write a <code>while</code> loop that loops forever and at each iteration through the loop randomly selects a key/value pair from the questions dictionary and prints the question.
<b>Check your understanding</b>: what saturation and value would you guess firetruck red have?


To randomly select a key from the dictionary, you can use the <code>random</code> module, and in particular the <code>random.choice</code> function.


When you run your script, to break out of the <tt>while</tt> loop you can press <tt>Control</tt> and then (while still holding down Control) <tt>c</tt>.
=== 2. Examine <code>Effect</code> and the interface its subclasses provide ===


<b>Step 2 resources</b>:
All of the effects inherit from the <code>Effect</code> class. Examine this class and its <code>__init__</code> and <code>run</code> methods.
<ul>
<li>
<code>while</code> loops: http://en.wikibooks.org/wiki/Python_Programming/Flow_control#While_loops
</li>
<li>
Dictionary manipulation: http://docs.python.org/tutorial/datastructures.html#dictionaries. In particular, look at getting a list of the dictionary's keys using the <code>keys</code> method.
</li>
Selecting a random value from a list using the <code>random</code> module: http://docs.python.org/library/random.html#random.choice
</li>
</ul>


What is the purpose of the <code>__init__</code> method?


=== Step 3: Get and check the user's answer ===
What is the purpose of the <code>run</code> method?


Inside your <code>while</code> loop, write the code that gets an answer from the user and compares it to the answer retrieved from the questions dictionary. If the answer is correct, say so. If the answer is incorrect, say so and print the correct answer.
Open up <code>run.py</code> and look at this chunk of code at the bottom of the file:


You can get input from a user using the <code>raw_input</code> function.
<pre>
for effect in effects_to_run:
new_effect = effect(wall)
print new_effect.__class__.__name__
new_effect.run()
</pre>


It is up to you how strict you want to be with a user's answer. Do you want capitalization to matter?
<code>effects.py</code> exports and <code>Effects</code> list at the bottom of the file. <code>run.py</code> goes through every effect in that list, creates a new instance of the effect, and invokes its <code>run</code> method.


<b>Step 3 resources</b>:
<b>Check your understanding</b>: what would happen if you added an effect to the <code>Effects</code> list that didn't implement a <code>run</code> method? (Try it!)
<ul>
<li>
Using <code>raw_input</code> to get data from the user: http://docs.python.org/library/functions.html#raw_input
</li>
</ul>




=== Step 4: Allow the user to quit the program ===


The <code>while</code> loop currently runs forever. Pick a special phrase (like "Exit") that the user can type instead of an answer that signals that they want to quit the program. When that special phrase is given, print a goodbye message and <code>break</code> out of the <code>while</code> loop to end the program.
=== 3. Examine the nested <code>for</code> loop in <code>SolidColorTest</code> ===


<b>Step 4 resources</b>:
<pre>for x in range(self.wall.width):
<ul>
for y in range(self.wall.height):
<li>
self.wall.set_pixel(x, y, hsv)</pre>
Using the <code>break</code> keyword to break out of a loop: http://docs.python.org/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops
</li>
<li>
Making decisions with <code>if</code>, <code>elif</code>, and <code>else</code>: http://docs.python.org/tutorial/controlflow.html#if-statements
</li>
</ul>


This code loops over every pixel in the ColorWall, setting the pixel to a particular <code>hsv</code> value. After that <code>for</code> loop is over, <code>self.wall.draw()</code> updates the display.


=== Step 5: Get the quiz questions file from the user===
<b>Check your understanding</b>: what would happen if you moved the <code>self.wall.draw()</code> to inside the inner <code>for</code> loop, just under <code>self.wall.set_pixel(x, y, hsv)</code> in <code>SaturationTest</code>? (Try it!)


Write the code to get the quiz questions file from a command line argument. Handle the case where a user forgets to supply a file; in this case, print an error message saying they need to supply a file, and then exit the program using the <code>exit()</code> function.
<b>Tip</b>: you can run individual tests by passing their names as command line arguments to <code>run.py</code>. For example, if you only wanted to run <code>SaturationTest</code>, you could:


<b>Step 5 resources</b>:
<pre>python run.py SaturationTest</pre>
<ul>
<li>
Command line argument parsing: http://docs.python.org/library/argparse.html#module-argparse.
</li>
<li>
Getting and checking the number of command line arguments: http://docs.python.org/library/sys.html.
</li>
</ul>




===Checking your work===
=== 4. Implement a new effect called <code>RainbowTest</code> ===


Try out your script on the following quiz files:
It should run for 5 seconds, cycling through the colors in the rainbow, pausing for a moment at each color.


* http://web.mit.edu/jesstess/www/IntermediatePythonWorkshop/metric.txt
Remember to add your effect to the <code>Effect</code> list at the bottom of <code>effects.py</code>!
* http://web.mit.edu/jesstess/www/IntermediatePythonWorkshop/french_food.txt


Does your script handle the case where the user forgets to provide a filename?
Test your new effect with


<pre>python run.py RainbowTest</pre>


===Bonus challenge===


Modify your script to quiz based on either the question or answer. e.g. for state capitals, the quizzer would present either a state, expecting its capital as the answer, or a capital, expecting its state as the answer.
=== 5. Play with the randomness in <code>Twinkle</code> ===

Walk through <code>Twinkle</code>. Find explanations of the <code>random.randint</code> and <code>random.uniform</code> functions in the online documentation at http://docs.python.org/library/random.html.

Experiment with these functions at a Python prompt:

<pre>
import random
random.randint(0, 1)
random.randint(0, 5)
random.uniform(-1, 1)
</pre>

Then experiment with the numbers that make up the hue and re-run the effect:

<pre>
python run.py Twinkle
</pre>

<b>Challenge</b>: make <code>Twinkle</code> twinkle with shades of red.


=== 6. Implement a new effect that involves randomness! ===

Remember to add your effect to the <code>Effect</code> list at the bottom of <code>effects.py</code>.

==Bonus exercises==

===Checkerboard===

Find and change the colors used in the <code>Checkerboards</code> effect, and re-run the effect:

<pre>
python run.py Checkerboards
</pre>

Then change the line

<pre>
if (x + y + i) % 2 == 0:
</pre>

to

<pre>
if (x + y + i) % 3 == 0:
</pre>

re-run the effect, and see what changed.

What other patterns can you create by tweaking the math for this effect?


=== Matrix ===

Find and change the color of the columns in the <code>Matrix</code> effect, and re-run the effect:

<pre>
python run.py Matrix
</pre>


Each column that we see on the wall corresponds to a <code>Column</code> object. Add some randomness to the color used by each column (the variable whose value you changed above) using the <code>random.random</code> function, re-run the effect, and see what happens.


===Congratulations!===


You've implemented a substantial, useful script in Python from scratch to help people study. Keep practicing!
=== Write more of your own effects! ===


[[File:Fireworks.png|150px]]
You have color, time, randomness, letters, and more at your disposal. Go nuts!
[[File:Balloons.png|150px]]

Latest revision as of 15:38, 25 November 2013

Project

Write a flash card quizzer from scratch.

Goals

  • practice breaking down a problem and solving it in Python from scratch
  • practice command line option parsing
  • practice reading from files
  • practice working with dictionaries and for loops

Problem statement

Write a Python script that takes a file containing flash card questions and answers as an argument and quizzes the user based on the contents of that file until the user quits the program. Questions should be selected randomly (as opposed to going in order through the file), and the user should type in their guess. The script should say whether or not a guess is correct and provide the correct answer if an incorrect answer is given.

The file will contain flash card challenges in the form:

question,answer
question,answer
question,answer
question,answer
...

For example, a state capitals flash card file might have the form:

Alabama,Montgomery
Alaska,Juneau
Arizona,Phoenix
...

Running the quizzer script with this file might look like this:

$ python quizzer.py state_capitals.txt
Texas? Austin
Correct! Nice job.
New Mexico? Santa Fe
Correct! Nice job.
Oregon? Portland
Incorrect. The correct answer is Salem.
Virginia? Richmond
Correct! Nice job.
Virginia? Exit
Goodbye

Breaking down the problem

Step 1: Get the questions from a fixed flash card file

Download http://web.mit.edu/jesstess/www/IntermediatePythonWorkshop/state_capitals.txt.

Write the code to open and read state_capitals.txt (we'll deal with getting a variable filename from the user later). Create a dictionary, where each comma-separated question and answer become a key and value in the dictionary. Note that each line in the file ends in a newline, which you'll need to remove from the word.

Step 1 resources:


Step 2: Randomly select questions from the question dictionary

Write a while loop that loops forever and at each iteration through the loop randomly selects a key/value pair from the questions dictionary and prints the question.

To randomly select a key from the dictionary, you can use the random module, and in particular the random.choice function.

When you run your script, to break out of the while loop you can press Control and then (while still holding down Control) c.

Step 2 resources:


Step 3: Get and check the user's answer

Inside your while loop, write the code that gets an answer from the user and compares it to the answer retrieved from the questions dictionary. If the answer is correct, say so. If the answer is incorrect, say so and print the correct answer.

You can get input from a user using the raw_input function.

It is up to you how strict you want to be with a user's answer. Do you want capitalization to matter?

Step 3 resources:


Step 4: Allow the user to quit the program

The while loop currently runs forever. Pick a special phrase (like "Exit") that the user can type instead of an answer that signals that they want to quit the program. When that special phrase is given, print a goodbye message and break out of the while loop to end the program.

Step 4 resources:


Step 5: Get the quiz questions file from the user

Write the code to get the quiz questions file from a command line argument. Handle the case where a user forgets to supply a file; in this case, print an error message saying they need to supply a file, and then exit the program using the exit() function.

Step 5 resources:


Checking your work

Try out your script on the following quiz files:

Does your script handle the case where the user forgets to provide a filename?


Bonus challenge

Modify your script to quiz based on either the question or answer. e.g. for state capitals, the quizzer would present either a state, expecting its capital as the answer, or a capital, expecting its state as the answer.


Congratulations!

You've implemented a substantial, useful script in Python from scratch to help people study. Keep practicing!