# Generating Math Tests with Python

Auto-Generate Unique Tests

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_text=docx2txt.process(template_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()