By: Robert Graham Back to Guides
This is a tutorial from guest blogger Robert Graham. He wrote a very cool bit of software on the Django framework for Python that is able to mark tests built from Wufoo forms. This tutorial is a bit more technical than what we usually serve up here, so if you're a casual user, be prepared for some hardcore code action.
This software (“wufoo_quizzes”) is able to extend the functionality of Wufoo by turning survey-like forms that you build with Wufoo into tests that are marked. The user completing the test receives an email giving his/her results or a certificate if he/she “passes”, and the admin can receive an email of the complete results of the test as a CSV file.
- Server running Python
- The Wufoo API Wrapper for Python: pyfoo
- python-dateutil -
pip install python-dateutil
- django -
pip install django
Step 1) Have a Wufoo Account and Create a Test
First, you'll need a Wufoo account and a survey to use. The example I have tested this module with is about WWII history. Each test that you use with this module will need a Name and Email field. Test questions are multiple choice fields, so they have one correct answer.
Just click the Add to Wufoo button and it will be added to your Wufoo account.
Step 2) Environment Setup
Now you need to prepare a place to run the test marker from. Let's make a virtualenv for that. You may be asking why. David Fischer makes it clear:
If you develop a Python module and you don't test it with virtualenv, don't make your next release until you do. Virtualenv creates a Python environment that is segregated from your system wide Python installation. In this way, you can test your module without any external packages messing up the result, add different versions of dependency packages and generally verify the exact set of requirements for your package.
If you don't have virtualenv:
pip install virtualenv
virtualenv --no-site-packages grader source ./grader/bin/activate pip install python-dateutils pip install django
This prepares a Python environment that does not connect to your local root site-packages for dependencies and installs two of the three dependencies for this project into it. Now, download the code for wufoo_quizzes if you have not already. Unzip that in your choice location. Finally, we download our last dependency, pyfoo, which allows us to talk to the Wufoo API from Python. Unzip the .zip file you download from GitHub, then place
pyfoo.py and the scripts folder into the same directory that contains
quizgrader.py from wufoo_quizzes.
Step 3) Quiz Answers and Settings
answers.txt file in the wufoo_quizzes folder to contain the name of your test followed by new lines in a question: answer format.
WWII History Test Which country or countries benefitted from the Lend Lease Pact?: Both Which is a German field commander who fought a brilliant campaign on the Eastern front?: Manstein When did the Allies break out of Normandy?: August 1944
You can place more quizzes in this answers file like so:
WWII History Test Which country or countries benefitted from the Lend Lease Pact?: Both Which is a German field commander who fought a brilliant campaign on the Eastern front?: Manstein When did the Allies break out of Normandy?: August 1944 Other Test Name Question 1: True Question 2: False Question 3: Honey Badger Question 4: Vegas, Baby!
Make sure the question and answer text exactly matches what is on your Wufoo form. I copied and pasted mine directly from Wufoo after finishing the form.
You will also need to configure settings by creating a file named ‘locals.py' in the same directory as
quizgrader.py from wufoo_quizzes. You can copy and paste what you'll need from
quizgrader.py or the example setup below:
email_password = 'pw' api_key = 'APIKEY' wufoo_account = 'account' # this is the 'youraccount' part of youraccount.wufoo.com smtp_host = 'smtp.gmail.com' email_user = 'firstname.lastname@example.org' templates = ('/your/path/to/this/project/', '/your/path/to/the/template/dir') admin_email = 'email@example.com' admin_email_subject = 'Quiz Results' success_message_text_alt = "This is an text only alternative message for those users pass the quiz" required_score = 80.0 # 80% to pass send_user_emails = False send_admin_email = True
- Please note that the
email_passwordis the password for your
api_keyis the Wufoo API key from your Wufoo account's API page.
wufoo_accountis the subdomain piece in ‘wufoo_account.wufoo.com' which you can see when logged into Wufoo.
quizgrader.pywhere to find the template files that are included in the template directory. You can move those around if you like, but I had to give the directory of
wufoo_quizzesand the templates directory to make sure Django could find the templates.
admin_emailis the email address that will receive the results from the marking in a CSV with the subject line of
success_message_text_altallows you to specify a text-only message for user emails that pass the test. The default template for success is an HTML email which may not work in all email clients.
required_scoreis the score threshold for pass/fail on your tests.
send_admin_emaillets you specify whether you want the system to send emails at all. All results are printed to stdout if not.
Step 4) Time to Take Over the World
Run the marker, receive emails, change your life! (Make sure you activate the virtualenv as above first.)
You should see something similar to:
GreenEyedDevil:rgraham-wufoo-quizzes-tip rgraham$ python quizgrader.py WWII History Quiz Scores: firstname.lastname@example.org scored 0.00 percent on WWII History Quiz. email@example.com scored 100.00 percent on WWII History Quiz. Sending failure message to: firstname.lastname@example.org Sending certificate to: email@example.com
Users who fail the test will receive a text email from the template
failure.txt like this:
Users who pass the test will receive an HTML email from the template
certificate.html like this:
The admin will receive a text email from the template
weekly-email.txt like this:
The templates used to send emails are examples that you are welcome to use, but you may want to include your own information in them. These templates use the Django template system and can easily be modified to suit your purposes. Major changes such as which data is dynamically included in the templates will require you to modify the code, but any static changes can be made as easily as changing any text file.
Step 5) Extra Credit
Set up this script to run using cron. If you'd like to get results only from the last week, you can make some small changes to
quizgrader.py to make that happen. Uncomment the if statement where you see (2 locations):
# FIXME make the date specifiable #if datetime.datetime.strptime(entry[date_created.ID], "%Y-%m-%d %H:%M:%S") > (datetime.datetime.now() + relativedelta(weeks=-1)):
weeks=-1 to whatever date range you have in mind.
weeks=-2 for the last two weeks of results.
days=-1 for the last 24 hours of results. You will probably connect this interval to your cron interval.
This is a fairly lightweight solution that is not suitable for extremely high traffic forms, but it might be just right for you or provide you with a starting point for building something more robust.
You can also email me with requests or issues. I'll do all I can to help. Thanks for following along and happy testing!
Robert Graham is a developer, software entrepreneur and consultant who maintains a blog about the experience. Robert has been working in software since 2005. He is a Ph.D. dropout who has spent some time working for Google. One day, he'd like to work for himself.