This is a script for generating a bunch of unique math tests from a “Test Template” and a spreadsheet containing test inputs and problem solutions.
In our Test Template we set the layout of our test and define our test problems. Our test problems will have variable placeholders (TestID, Question ID, VarA, etc.) that we will replace with data from our “Test Data” spreadsheet.
In our excel file, we random generate values for the A, B, and C variables (using the =RANDBETWEEN() function) and clearly identify which Question, Equation, and Test ID they correspond to. In the Excel file, we’ll calculate solutions using the input data and equation listed for each entry.
Next, we can run our script. This is dependent on the docx (Note: pip install python-docx), docx2txt, re, pandas, and tkinter libraries. Forms will pop-up prompting you for the Test Template and Test Data files.
""" Creates unique test documents with data taken from a DataFrame (which is populated from an excel file). Input: Test Template (Word Document). Test Data (Excel File) Output: 20 Unique Tests (Test Data) """ #Import modules import docx import docx2txt import pandas as pd import re from tkinter import Tk from tkinter import filedialog Tk().withdraw() #Define "Test" template template_file=filedialog.askopenfilename(title="Please select Word template") testdata_file=filedialog.askopenfilename(title="Please select Test Data spreadsheet") #Read file data template_text=docx2txt.process(template_file) testdata=pd.read_excel(testdata_file) #Produce 20 unique tests for i in range(20): new_text=template_text #Add data for 10 unique questions for j in range(10): #Define replacement dictionary #http://stackoverflow.com/questions/6116978/python-replace-multiple-strings rep={'QuestionID':str(testdata['Question'][i+j*20]), 'VarA':str(testdata['VarA'][i+j*20]), 'VarB':str(testdata['VarB'][i+j*20]), 'VarC':str(testdata['VarC'][i+j*20])} rep=dict((re.escape(k),v) for k, v in rep.items()) pattern=re.compile("|".join(rep.keys())) if j==0: new_text=pattern.sub(lambda m: rep[re.escape(m.group(0))],template_text,count=4) new_text=new_text.replace('TestID','Test #' + str(i+1)) else: new_text=pattern.sub(lambda m: rep[re.escape(m.group(0))],new_text,count=4) #Create and save new test document test_doc=docx.Document() test_doc.add_paragraph(new_text) test_doc.save(r'C:\Users\Craig\Documents\Python Scripts\Test #'+str(i+1)+'.docx')
After the files have been selected, the script reads the Test Template text and loads the Test Data into a DataFrame. We then loop through the Test Data and produce 20 unique test documents by substituting the placeholder variables with values from the Test Data spreadsheet. Each test document is clearly labeled and we can use our original Test Data as our answer key.
Thanks to Andrew Clark for his code for replacing multiple text strings.