Quizbank/Python/numerical/numerical.py

import os, re, shutil, sys,time,datetime
from os import listdir #probably not needed

## REMINDER: ############################################
## Remove 00questions if a new question has been added  #
#########################################################

## Program takes the basename of the current working directory (cwd) and
## uses that to define the QuizName.  It then calls getQuestions(..) to 
## collect all the questions in this folder as a list of filenames
## of the form 'questionname'.txt.  
##
## The wikitext numerical file contains a lot of boilerplate text which
## is kept in /boilerplate as a collection of textfiles that are inserted
## into a long string called quiz.  As these textfiles are inserted into
## quiz, text and linebreaks (\n) are added.  Also added are the all
## renditions (typically 20) of the questions and answers.  This is done
## with the help of buildUP(..) and checkFormat(..) functions.

##functions:

##def getQuestions: Either reads the inventory or creats it (this should
##be upgraded to verify that the inventory is up to date). The input variable
##is True if it is desired to printout the quesitons, or false if that is
##not needed.  The function outputs the number of questions and a list
##corresponding to the names of the questions.

##def buildUp: Used to add text in the boilerplate folder to the quiz.
##The input variables are the name of the boilerplate folder, the name of
##the 'textfile'.txt file (in boilerplate) to be added, and above the very
##long variable called quiz (which is later printed out and placed in the
##bank).  The output is the quiz with the material added.

##def checkFormat: A short auxillory file that reads the line of a textfile
## that define each question.
##These textfiles were created by the python code with the same name,
##and contain magic prefixes to facilitate the conversion of the "question'.txt
##file into the wikiquiz textfile to be placed in the bank (and posted on
##Wikiversity).  The input is a line of text and the magic prefix required
##at this point in the buildup of the string called quiz.  The output is
##either "Null" or the string with the magic prefix removed.  

##def getQA: As buildup creates the quiz, it requires questions and answers
##to all the renditions in a way that does not follow the order given in
##the textfile associated with the quesitons.  This is because the wikitext
##



def getQuestions(printThis):
    allFiles = os.listdir()
    #update 00inventory.txt    
    with open('00inventory.txt','w') as inventory:
        for item in allFiles:
            if item[0:2]!='00' and item[-4:]=='.txt':
                inventory.write(item+'\n')    
    if '00questions.txt' not in allFiles:
        with open('00questions.txt','w') as newfile:
            newfile.write(str(datetime.datetime.now()))
        print('Create and fill 00questions.txt')
        sys.exit()
    else:
        with open('00questions.txt','r') as questionFile:
            #questionList = [line.split(',') for line in questionFile.readlines()]
            questionList = questionFile.readlines()
    #remove the end characters using rstrip:lstrip if leading; lstrip if both   
    numberQuestions=len(questionList)
    print('len(questionList',len(questionList))
    for n in range(numberQuestions):
        questionList[n]=questionList[n].rstrip('\n')
        if printThis:
            print(allFiles,'\n')   
    return [numberQuestions, questionList]

def buildUp(folder,filename,quiz):   
    with open(folder+filename,'r') as file:
        string=file.read()
        string=string.replace('\\n', '\n')
    return quiz+string

## These two methods take a quizname and return two lists
## called questions and answers that contain the Q and A

def checkFormat(string,expect): #looks for magic word "expect"
    ignore=len(expect)          #RETURNS STRING W/O MAGIC WORD
    if string[:ignore]==expect:
        return string[ignore:]
    else:
        return 'Null'           #RETURNS NULL IF WRONG WORD

def getQA(quizName,nQues):
## this picks a question in quiz and creates all the renditions
## as two lists questions and answers.  The length of each list
## is the number of renditions.  The first (zeroth) rendition
## contains the bracket that are needed for quiz extension.
    print(quizName,'ingetQA')
    with open('00questions.txt','r') as file:
        questionList=file.readlines()
    for n in range(len(questionList)):
        questionList[n]=questionList[n].rstrip('\n')
    NQues=len(questionList)
##    Verify that nQues does not exceed the questions in the quiz.
    if nQues>=NQues:
        print('nQues>=NQues in',quizName,':',nQues,'>=,',NQues)
        os._exit(0)    
    with open(questionList[nQues],'r') as file:
        rawQuestion=file.readlines()
    name=checkFormat(rawQuestion[0],'_name_')
    name=name.strip('\n')
    header=checkFormat(rawQuestion[1],'_head_')
    header=header.strip('\n')
    questions=[] #contains NRen questions (identical w/ random)
    answers=[] #Nren lists of five (Nren=#renditions)
    nRen=0 # nRen counts the renditions
    for nRaw in range(len(rawQuestion)):
        s=rawQuestion[nRaw]
        #print('<<<<<<< nRaw ',nRaw,s)
        if s[:3]=='_Q_':
            nRen=nRen+1 #increment renditions
            question='<!--'+header +'_'+str(nRen)+'-->'
            if nRen==1:
                question='{<!--'+header +'_'+str(nRen)+'-->'    
            question=question+checkFormat(s,'_Q_')
            if nRen==1:
                question=question.strip('\n')
                question=question+'}\n' #had to move newline
            questions.append(question)
##            print('*s*',question) #diagnostic
            answerStart=True
        elif s[:1]=='+' or s[:1]=='-':
            if answerStart: #start new answerList
                answerList=[]
##                print('start answers') #diagnostic
                answerStart=False
                j=1
            answerList.append(s)
##            print('*a*',s) #diagnostic
            j=j+1
            if j==5:
                answers.append(answerList)
    return [questions,answers]
#
#Start Program
#
#This gets the name of the quiz, the number of questions on the quiz
# and a list of quiz questions... I think???
quizName=os.path.basename(os.getcwd())
[Nquiz,quizList]=getQuestions(False)# Argument False of no printout needed

##print('\nname, N, list\n', qName,Nq,qList,'\n\n') #diagnostic

folder='./boilerplate/'
quiz=''
quiz=buildUp(folder,'1.2.txt',quiz)
quiz=quiz+quizName
quiz=buildUp(folder,'1.4.txt',quiz)
quiz=buildUp(folder,'1attribution.txt',quiz)
quiz=buildUp(folder,'2.txt',quiz)
quiz=buildUp(folder,'2whom2see.txt',quiz)
quiz=buildUp(folder,'3.txt',quiz)
###
#dignostic to get at the proble,
quiz=quiz+'<quiz display=simple>\n'

for nQues in range(Nquiz):    #add 1st [0] ques
##    print('Adding first question of ',qList[nQues])
    [ques,answ]=getQA(quizName,nQues)
    quiz=quiz+ques[0]
    answList=answ[0]
    for i in range(5):
        quiz=quiz+answList[i]
    quiz=quiz+'\n'
quiz=quiz.rstrip('\n')# remove unneeded linefeed at end
quiz=quiz+'\n</quiz>'  #ends quiz extensino quiz
quiz=buildUp(folder,'4.txt',quiz)
quiz=quiz+'\n'

for nQues in range(Nquiz):
    [ques,answ]=getQA(quizName,nQues)
    quiz=quiz+'\n====*_Question_* '+ str(nQues+1)+'====\n'
    for nrend in range(1,len(ques)):#Nrend=len(ques)
        quiz=quiz+'\n=====*_Rendition_* ' + str(nQues+1)
        quiz=quiz+'-'+str(nrend+1)+'=====\n'
        quiz=quiz+ques[nrend]
        answList=answ[nrend]
        for i in range(5):
            quiz=quiz+answList[i]

    #quiz=quiz.rstrip('\n')# remove unneeded linefeed at end
quiz=quiz+'</div></div>\n'
quiz=buildUp(folder,'5instructions.txt',quiz)
print(quiz)

outputAt='./output/'+quizName+'.txt'
with open(outputAt,'w') as fout:
    fout.write(quiz)
print('---------------------------------------------------------')
print('This [[v:Quizbank]] wikitext file can be found at')
print('QuizSoftware/numerical'+outputAt)
print('''1. Place the textfile into QuizSoftware/bank ''')
print('''2. Either: ''')
print('''    a. Upgrade course folder's cvs file QuizSoftware/courses''')
print('''    b. Run QuizSoftware/program.py and follow the instructions''')
print('''3. Don't forget to upgrade the Studyguide's permalink''')
print('---------------------------------------------------------')