Overview: The general strategy is to generate a new google document for each student in your class (shared with this individual only), where they can write their essay -- or paste it in from another word processor if they prefer. After the assignment deadline, you set it so that students can no longer access their documents while you're grading them and adding comments. Then, when you're ready, each student is notified that they can view their graded document.
Note: You will need to download and install Python 2.7 and the Google Data API Python Client Library to run the subsequent python scripts. (If you use Ubuntu, python should already be installed by default. You can check by running 'python -V' in a terminal window.)
Step 0: Tell students to sign up for a (free) Google Account, if they haven't already, so they can use google docs.
Step 1: create a spreadsheet of student names and Google Account emails. The easiest way is probably to create a google docs form for your students to fill out this info, and their answers will be automatically collated into a google spreadsheet for you.
Step 2: create a google doc for each student. Once you set up the script as described below, you'll be able to implement this step by simply running the 'CreateDocs.py' script.
[E.g., in Ubuntu: open a terminal windows, navigate to the directory where the scripts are saved, and type 'python CreateDocs.py' (without the quotes). In Windows: Shift-RightClick the folder containing the scripts, and select "Open a command window here", then type 'python CreateDocs.py', or perhaps something like 'C:\Python27\python.exe CreateDocs.py']
Step 3: remove student permissions while you grade. Once you set up the script as described below, you'll be able to implement this step by running 'RemovePermits.py'.
Step 4: let students see their graded docs. Once you set up the script as described below, you'll be able to implement this step by running 'ReturnDocs.py'.
Doesn't that look easy? Okay, now for the scripts (with thanks to Cédric for permission to share his code -- I've just made some minor edits)...
How to set up the python scripts:
All three scripts start the same way. So open a plain text editor (e.g. notepad or gedit), and paste in the following code:
import gdata.docs import gdata.docs.service import gdata.spreadsheet.service import re, os import gdata.docs.client import gdata.acl.data # DATA username='YOUR_GOOGLE_EMAIL' password='YOUR_GOOGLE_PASSWORD' students_data='GOOGLE_SPREADSHEET_TITLE' # format : "timestamp / firstname / lastname / email" classcode='PHI_101' assignment='ESSAY_1' # Connect to Google-Spreadsheet gd_client = gdata.spreadsheet.service.SpreadsheetsService() gd_client.email = username gd_client.password = password gd_client.source = 'OpenSource-CreateDocs-v1' gd_client.ProgrammaticLogin() # Connect to Google-DocList client = gdata.docs.client.DocsClient(source='OpenSource-CreateDocs-v1') client.ssl = True client.http_client.debug = False client = gdata.docs.client.DocsClient(source='OpenSource-CreateDocs-v1') client.ClientLogin(username, password, client.source); # q = gdata.spreadsheet.service.DocumentQuery() q['title'] = students_data q['title-exact'] = 'true' feed = gd_client.GetSpreadsheetsFeed(query=q) spreadsheet_id = feed.entry[0].id.text.rsplit('/',1)[1] feed = gd_client.GetWorksheetsFeed(spreadsheet_id) worksheet_id = feed.entry[0].id.text.rsplit('/',1)[1] rows = gd_client.GetListFeed(spreadsheet_id, worksheet_id).entry for row in rows: firstname=row.custom['firstname'].text lastname=row.custom['lastname'].text email=row.custom['email'].text title_doc=classcode+'-'+assignment+'-'+lastname+'-'+firstname print title_docEdit the 'DATA' section: enter your google email and password, the name of the spreadsheet with your students' data, and make sure that the described 'format' corresponds to the order of the columns in the spreadsheet (if not, correct the code so that they match!). You can play around with 'title_doc' if you don't want the document titles to be in the format 'PHI101-Essay1-Doe-Jane'.
Save this file. It'll serve as the base template for the three scripts.
(1) Append the following code (taking care to maintain the same indents as before), and save the resulting file as 'CreateDocs.py':
# CREATE A NEW DOCUMENT FOR EACH STUDENT new_doc = gdata.docs.data.Resource(type='document', title=title_doc) new_doc = client.CreateResource(new_doc) print 'Created:', new_doc.title.text scope = gdata.acl.data.AclScope(value=email, type='user') role = gdata.acl.data.AclRole(value='writer') acl_entry = gdata.docs.data.AclEntry(scope=scope, role=role) client.AddAclEntry(new_doc, acl_entry, send_notification=True)
(2) Load your base file, and this time append the following code and save it as 'RemovePermits.py':
feeduri='/feeds/default/private/full?title='+title_doc+'&title-exact=true&max-results=5' feed2 = client.GetResources(uri=feeduri) if not feed2.entry: print 'No document of that title.\n' doc_id=feed2.entry[0] acl_feed = client.GetAcl(doc_id) # REMOVE FIRST GRANTED PERMISSIONS FROM THE DOCUMENTS acl_entry = acl_feed.entry[1] client.DeleteAclEntry(acl_entry)
(3) Load your base file, and this time append the following code and save it as 'ReturnDocs.py':
feeduri='/feeds/default/private/full?title='+title_doc+'&title-exact=true&max-results=5' feed2 = client.GetResources(uri=feeduri) if not feed2.entry: print 'No document of that title.\n' doc_id=feed2.entry[0] acl_feed = client.GetAcl(doc_id) scope = gdata.acl.data.AclScope(value=email, type='user') role = gdata.acl.data.AclRole(value='reader') acl_entry = gdata.docs.data.AclEntry(scope=scope, role=role) new_acl = client.AddAclEntry(doc_id, acl_entry)Feel free to play around with the code, and let me know if you come up with any improvements!
N.B. Code updated as of 2013, to work with the latest gdata-python-client library (version 2.0.17).
0 comments:
Post a Comment
Visitors: check my comments policy first.
Non-Blogger users: If the comment form isn't working for you, email me your comment and I can post it on your behalf. (If your comment is too long, first try breaking it into two parts.)
Note: only a member of this blog may post a comment.