Letting Python do the Work
There are entire books written about how to automate tasks with Python. There are two features about Python that make it tractable. The first is it's ease and second is it's manipulative power. Recently, someone asked me if I could automate an online testing environment. Many exotic solutions came to mind but Python yielded a quick and simple solution. This solution allowed for minimal testing and fully automated grading. Let's take a look.
The first part of the task is to distribute the test in an asynchronous way. This can be accomplished with s3 in AWS. Every uploaded object gets a url that is by default private. For a planned online test time you can make that url public for people to start their test. This can be done with a cron job on an Ec2 instances with an S3FullAccess role. Naturally, we can use Python to make the test url publicly available. This script will do it.
import sys import boto3 from boto3.session import Session boto3.resource('s3').ObjectAcl('classbucket','SecondTest.pdf').put(ACL='public-read')
There are a few ways that you could automate the running of this script through AWS. The serverless way is via Lambda and scheduling through CloudWatch Events. The more traditional way is via a cron job on a server as mentioned above.
Similarly, if you wanted to suspend access to the file after the test you could also do that via a script. Here is a Python example
import sys import boto3 from boto3.session import Session boto3.resource('s3').ObjectAcl('classbucket','SecondTest.pdf').put(ACL='authenticated-read')
Authenticated read will enforce use of either access keys or roles to access the document. This will keep the document private to people outside your AWS account.
Submission and Grading
Students can email in their work as an attached file. This let's you establish a time line from the time stamp on the email and you can homogenize their submissions by distributing an answer template beforehand. The real magic here is grading the exams. We can easily grade a hundred exams in a few seconds using Python. Here is a script to do just that.
import glob import sys from operator import itemgetter dir = "emails/*" exam = glob.glob(dir) for email in exam: with open(email, 'r') as file1: with open("key.txt", 'r') as file2: same= set(file1).intersection(file2) same.discard("\n") order = sorted(same, key=itemgetter(1)) correct = 0 with open(email, 'a') as file_out: file_out.write("*********************") file_out.write("\n") file_out.write("Your correct answers are") file_out.write("\n") for line in order: correct+=1 file_out.write(line) file_out.write("\n") file_out.write("the score is " + str(correct)+ "/15")
Reading through this script you can see how it works. You can point it at a directory of submitted exams and then when each exam is opened it is compared to the answer key. The answer key sits as a sibling to the emails/ directory. The correct answers are parsed out by using set intersection. Finally, the score is written to the bottom of the exam being graded. Here is a sample run against an answer key where every answer is 'A'.
Random Name 1. A 2. C 3. A 4. A 5. C 6. B 7. C 8. A 9. B 10. E 11. C 12. E 13. C 14. C 15. A ********************* Your correct answers are 1. A 3. A 4. A 8. A 15. A the score is 5/15
Other Possible Solutions
It would be an interesting exercise to take this online test giving platform to the next level via AWS. You could use ElasticBeanStalk to serve your test via a Java application. This would even allow for federated authentication via Cognito and grading on the server side for an instance score to the user. To take it a step further an RDS database could be used to track user data such as score, time spent, and anything else we want to parse out of the session. Python is a dependency for the AWS cli and it would seem Amazon recognizes it's power and flexibility. The next time you find yourself doing mundane, repetitive work on a computer consider what Python can do for you.