Welcome to HBH! If you have tried to register and didn't get a verification email, please using the following link to resend the verification email.
Test Conversion Program / Blackboard LMS QTI to Respondus Format - Python Code Bank
Test Conversion Program / Blackboard LMS QTI to Respondus Format
Today I had to write a program to convert a broken Blackboard QTI content packet to Respondus format (A software product my work uses to upload tests to our Angel LMS). Thought I provide another real world application
the data file can be downloaded here: [url]http://pastebin.com/QeP8L1Aa[/url]
Just save it as: res00001.dat
import re
#==================================================================#
# This file was created to fix a broken Blackboard Content Package #
#==================================================================#
'''
Note: qti_assessment is used as a global list,
the structure of this list is as follows:
qti_assessment = [ [
"Type: <QTYPE>", #question type: if needed by Repondus: Matching
"<TITLE>", #title of the question
{'id_hash':'<choice>'}, #dictionary to store response data: t/f questions: {'true':'True', 'false':'False'}
"<Answer>" #answer to the question, also used to check for response to place a * in front
],
[...],
[...]
]
'''
def Matching(qti_question):
"""This function reformats the matching questions to a readable data structure"""
global qti_assessment
#get the title of the question
_TITLE_ = getTitle(qti_question)
lst_title = _TITLE_.split('<br>')
#print(lst_title)
_choices_fix = {}
_roman_match = []
counter = 0
for i in range(1,len(lst_title),1):
first_dot = lst_title[i].find('. ')+2
second_dot = lst_title[i].find('. ', 5)+2
_roman_match += [lst_title[i][first_dot:second_dot-4]]
#get the choice and update the dictionary: _choices_fix
_choices_fix.update({chr(65+counter):lst_title[i][second_dot:]})
counter+=1
#create a temp dictionary to reformat data
_CHOICES_ = {}
_ANS_ = getAns(qti_question).split(', ')
for i in range(0,len(_ANS_)):
_CHOICES_.update({str(i):_roman_match[i]+' = '+_choices_fix[_ANS_[i]]})
qti_assessment += [["Type: MT\n",_TITLE_, _CHOICES_, "N/A"]] #qti_assessment = [[str(title), {id:choice}, str(id)],...]
def FillInTheBlank():
"""This function reformats the fill in the blank questions to a readable data structure"""
def TrueFalse(qti_question):
"""This function reformats the true/false questions to a readable data structure"""
global qti_assessment
#get the title of the question
_TITLE_ = getTitle(qti_question)
_ANS_ = getAns(qti_question)
qti_assessment += [["",_TITLE_, {'true':'True','false':'False'}, _ANS_]] #qti_assessment = [[str(title), {id:choice}, str(id)],...]
def MultipleChoice(qti_question):
"""This function reformats the multiple choice questions to a readable data structure"""
global qti_assessment
#get the title of the question
_TITLE_ = getTitle(qti_question)
_RESPONSES_ = qti_responses.findall(qti_question) #get a list of the choices
choices = {} #create a temp dictionary to store data restructured data
for response in _RESPONSES_: #for each reponse available
_choice_fix = ""
_ID_ = qti_label_indent.findall(response)[0] #get the hash id for checking
_CHOICE_ = qti_choice.findall(response) #get the choice text
for c in _CHOICE_:
if c != '':
_choice_fix += c
choices.update({_ID_:_choice_fix}) #make a dictionary to store id:text
_ANS_ = getAns(qti_question)
qti_assessment += [["",_TITLE_, choices, _ANS_]] #qti_assessment = [[str(title), {id:choice}, str(id)],...]
def getTitle(qti_question):
return qti_title.findall(qti_question)[0].replace('<br/>','<br>').replace('&#58;', ': ').replace(' ','').replace('&quot;','"').replace(' ','')
def getAns(qti_question):
return qti_answer.findall(qti_question)[0] #get the correct answer for comparing
def ProcessQType(qtype, qti_question):
"""This function delagates the qtype and returns a readable data structure"""
if qtype == 'Multiple Choice': result = MultipleChoice(qti_question)
if qtype == 'True/False': result = TrueFalse(qti_question)
if qtype == 'Fill in the Blank': result = Matching(qti_question)
#------------------------------------------------------------------#
#open .dat file and store qti questions lists
fname = 'res00001.dat'
path = './'
f = open(path+fname,'r')
data = f.read()
f.close()
#Strip data of all escape characters
data = data.replace('\t','').replace('\n','')
#Create a questions list to store qti question data chunks
regex = re.compile(r'<item.*?>(.*?)</item>')
qti_questions = regex.findall(data)
#loop through each question and extract relavent data:
#Title, Choices, Correct Answer
#And write it out in Respondus format for Import/Export to Angel
#----------------------------------------
#Some regular expressions to store patterns
#and setup question order for Repondus
#----------------------------------------
#get the assessment title
qti_assessment_title = re.compile(r'<assessment title="(.*?)">', re.DOTALL)
#reasign fname to new filename
fname = qti_assessment_title.findall(data)[0]
#get the title for the question
qti_title = re.compile(r'<flow class="FORMATTED_TEXT_BLOCK"><material><mat_extension><mat_formattedtext type="HTML">(.*?)</mat_formattedtext></mat_extension></material></flow>', re.DOTALL)
#get the question type: for processing
qti_qtype = re.compile(r'<bbmd_questiontype>(.*?)</bbmd_questiontype>')
#get each response to search through
qti_responses = re.compile(r'<flow_label class="Block">(.*?)</flow_label>')
#get label id and check for correct answer
qti_label_indent = re.compile(r'<response_label ident="(.*?)"')
#get response text
qti_choice = re.compile(r'<mat_formattedtext type="HTML">(.*?)</mat_formattedtext>')
#get the correct answer id to compare reponses with
qti_answer = re.compile(r'<varequal case="No" respident="response">(.*?)</varequal>')
#final output list to write out to file containing all relavent data
qti_assessment = []
for i in range(0,len(qti_questions),1):
qti_question = qti_questions[i] #each question in qti_questions
#get the qtype of the question
_QTYPE_ = qti_qtype.findall(qti_question)[0]
ProcessQType(_QTYPE_,qti_question)
#finally loop through assessment and output a Respondus formatted .txt file
f = open(path+fname+'.txt', 'w')
for i in range(0, len(qti_assessment),1):
qnum = str(i+1)+'. ';
#begin question
qti_question = qti_assessment[i][1]
qti_qtype = qti_assessment[i][0]
#if match process()
f.write(qti_qtype+qnum + qti_question+'\n')
#---------------------------------------
ans_id = qti_assessment[i][3]
#print(ans_id)
counter = 0
for key, value in qti_assessment[i][2].items():
if key == ans_id:
f.write('*')
f.write(chr(97+counter)+'. ' + value + '\n')
counter+=1
#---------------------------------------
f.write('\n\n')
#end question
f.close()
Comments
Sorry but there are no comments to display