Commits

committed a8a1f6b Draft

Massive tabs for spaces exercies

• Participants
• Parent commits e1c2fbe

File MathsMish/MMDBConstants.py

` class MMDBConstants:`
`-	VALID_OPERATORS = ["+","x","-"]`
`-	LHS_CANDIDATES = [1,2,3,4,5,6,7,8,9,10,11,12]`
`-	LHS_STARTOFFSET = 6`
`-	LHS_THRESHOLD = 0.9`
`-	RHS_CANDIDATES = [2,3,4,5,8,6,10,8,7,11,12]`
`-	RHS_STARTOFFSET = 2`
`-	RHS_THRESHOLD = 0.4`
`-	NEVERASKED_PROB = 0.5`
`-	MOSTRECENTOK_PROB = 0.1`
`-	MOSTRECENTNOTOK_PROB = 0.4`
`+    VALID_OPERATORS = ["+","x","-"]`
`+    LHS_CANDIDATES = [1,2,3,4,5,6,7,8,9,10,11,12]`
`+    LHS_STARTOFFSET = 6`
`+    LHS_THRESHOLD = 0.9`
`+    RHS_CANDIDATES = [2,3,4,5,8,6,10,8,7,11,12]`
`+    RHS_STARTOFFSET = 2`
`+    RHS_THRESHOLD = 0.4`
`+    NEVERASKED_PROB = 0.5`
`+    MOSTRECENTOK_PROB = 0.1`
`+    MOSTRECENTNOTOK_PROB = 0.4`

File MathsMish/Question.py

` from MathsMish import MMDBConstants`
` `
` class Question(object):`
`-	pass`
`+    pass`
` '''`
` `
`-	def __init__(self, lhs, rhs, operator, id=None): `
`-		if operator == "*":`
`-			operator = "x"`
`+    def __init__(self, lhs, rhs, operator, id=None): `
`+        if operator == "*":`
`+            operator = "x"`
` `
`-		self.__validateInitArgs(lhs, rhs, operator)`
`+        self.__validateInitArgs(lhs, rhs, operator)`
` `
`-		self.__lhs = lhs`
`-		self.__rhs = rhs`
`-		self.__operator = operator `
`-		self.__suppliedAnswer = None`
`+        self.__lhs = lhs`
`+        self.__rhs = rhs`
`+        self.__operator = operator `
`+        self.__suppliedAnswer = None`
` `
`-	def __str__(self):`
`-		return "%s %s %s" % (self.__lhs, self.__operator, self.__rhs)`
`+    def __str__(self):`
`+        return "%s %s %s" % (self.__lhs, self.__operator, self.__rhs)`
` `
`-	def getHash(self):`
`-		return "%s_%s_%s" % (self.__lhs, self.__operator, self.__rhs)`
`+    def getHash(self):`
`+        return "%s_%s_%s" % (self.__lhs, self.__operator, self.__rhs)`
` `
`-	def getSuppliedAnswer(self):`
`-		return self.__suppliedAnswer`
`+    def getSuppliedAnswer(self):`
`+        return self.__suppliedAnswer`
` `
`-	def setSuppliedAnswer(self, value):`
`-		self.__suppliedAnswer = value`
`+    def setSuppliedAnswer(self, value):`
`+        self.__suppliedAnswer = value`
` `
`-	suppliedAnswer = property(getSuppliedAnswer, setSuppliedAnswer, "I'm the 'SuppliedAnswer' property.")`
`+    suppliedAnswer = property(getSuppliedAnswer, setSuppliedAnswer, "I'm the 'SuppliedAnswer' property.")`
` `
`-	def getlhs(self):`
`-		return self.__lhs`
`+    def getlhs(self):`
`+        return self.__lhs`
` `
`-	def setlhs(self, value):`
`-		self.__lhs = value`
`+    def setlhs(self, value):`
`+        self.__lhs = value`
` `
`-	lhs = property(getlhs, setlhs, "I'm the 'lhs' property.")`
`+    lhs = property(getlhs, setlhs, "I'm the 'lhs' property.")`
` `
`-	def getrhs(self):`
`-		return self.__rhs`
`+    def getrhs(self):`
`+        return self.__rhs`
` `
`-	def setrhs(self, value):`
`-		self.__rhs = value`
`+    def setrhs(self, value):`
`+        self.__rhs = value`
` `
`-	rhs = property(getrhs, setrhs, "I'm the 'rhs' property.")`
`+    rhs = property(getrhs, setrhs, "I'm the 'rhs' property.")`
` `
`-	def getoperator(self):`
`-		return self.__operator`
`+    def getoperator(self):`
`+        return self.__operator`
` `
`-	def setoperator(self, value):`
`-		self.__operator = value`
`+    def setoperator(self, value):`
`+        self.__operator = value`
` `
`-	operator = property(getoperator, setoperator, "I'm the 'operator' property.")`
`+    operator = property(getoperator, setoperator, "I'm the 'operator' property.")`
` `
`-	def getoperatorRaw(self):`
`-		return self.__operator`
`+    def getoperatorRaw(self):`
`+        return self.__operator`
` `
`-	def setoperatorRaw(self, value):`
`-		self.__operator = value`
`+    def setoperatorRaw(self, value):`
`+        self.__operator = value`
` `
`-	operatorRaw = property(getoperatorRaw, setoperatorRaw, "I'm the 'operatorRaw' property.")`
`-	def goodAnswer(self):`
`-		if self.getSuppliedAnswer() == None:`
`-			raise MMDBExceptions.QuestionNotYetAnswered`
`-		elif isinstance(self.getSuppliedAnswer(), int):`
`-			pass`
`-		else:`
`-			raise MMDBExceptions.AnswerNotAnInteger`
`+    operatorRaw = property(getoperatorRaw, setoperatorRaw, "I'm the 'operatorRaw' property.")`
`+    def goodAnswer(self):`
`+        if self.getSuppliedAnswer() == None:`
`+            raise MMDBExceptions.QuestionNotYetAnswered`
`+        elif isinstance(self.getSuppliedAnswer(), int):`
`+            pass`
`+        else:`
`+            raise MMDBExceptions.AnswerNotAnInteger`
` `
`-		a = eval(self.__str__().replace("x","*"))`
`-		if a ==  self.getSuppliedAnswer():`
`-			return True`
`-		else:`
`-			return False`
`+        a = eval(self.__str__().replace("x","*"))`
`+        if a ==  self.getSuppliedAnswer():`
`+            return True`
`+        else:`
`+            return False`
` `
`-	def __validateInitArgs(self, lhs, rhs, operator):`
`-		try:`
`-			operand = int(lhs)`
`-		except ValueError:`
`-			raise MMDBExceptions.NotInteger("LHS parameter is not an integer")`
`-		except TypeError:`
`-			raise MMDBExceptions.NotInteger("LHS parameter is not an integer")`
`+    def __validateInitArgs(self, lhs, rhs, operator):`
`+        try:`
`+            operand = int(lhs)`
`+        except ValueError:`
`+            raise MMDBExceptions.NotInteger("LHS parameter is not an integer")`
`+        except TypeError:`
`+            raise MMDBExceptions.NotInteger("LHS parameter is not an integer")`
` `
`-		try:`
`-			operand = int(rhs)`
`-		except ValueError:`
`-			raise MMDBExceptions.NotInteger("RHS parameter is not an integer")`
`-		except TypeError:`
`-			raise MMDBExceptions.NotInteger("RHS parameter is not an integer")`
`+        try:`
`+            operand = int(rhs)`
`+        except ValueError:`
`+            raise MMDBExceptions.NotInteger("RHS parameter is not an integer")`
`+        except TypeError:`
`+            raise MMDBExceptions.NotInteger("RHS parameter is not an integer")`
` `
`-		if operator not in MMDBConstants.VALID_OPERATORS:`
`-			raise MMDBExceptions.NotValidOperator`
`+        if operator not in MMDBConstants.VALID_OPERATORS:`
`+            raise MMDBExceptions.NotValidOperator`
` `
` '''`

File MathsMish/QuestionMachine.py

` import logging`
` import datetime, time`
` class QuestionSelectionMethod(object):`
`-	RANDOM = 0`
`-	WEIGHTED = 1`
`+    RANDOM = 0`
`+    WEIGHTED = 1`
` class OperandType(object):`
`-	LHS = 0`
`-	RHS = 1`
`+    LHS = 0`
`+    RHS = 1`
` class QuestionMachine(object):`
`-	def __init__(self, userid, operator):`
`-		self.__module_logger = logging.getLogger("MMDB.primary")`
`-		if operator not in ['x']: `
`-			raise MathsMish.MMDBExceptions.NotValidOperator`
`-		if isinstance(userid, int): `
`-			pass`
`-		else:`
`-			raise MathsMish.MMDBExceptions.NotInteger`
`+    def __init__(self, userid, operator):`
`+        self.__module_logger = logging.getLogger("MMDB.primary")`
`+        if operator not in ['x']: `
`+            raise MathsMish.MMDBExceptions.NotValidOperator`
`+        if isinstance(userid, int): `
`+            pass`
`+        else:`
`+            raise MathsMish.MMDBExceptions.NotInteger`
` `
`-		self.__userid = userid`
`-		self.__operator = operator`
`-		self.__lhsCandidates = [] `
`-		self.__rhsCandidates = [] `
`+        self.__userid = userid`
`+        self.__operator = operator`
`+        self.__lhsCandidates = [] `
`+        self.__rhsCandidates = [] `
`                 #In the longer term __dicCandidateQuestions should`
`                 #probably be initialized within __maintainCandidateAndQuestionSpace`
`-		self.__dicCandidateQuestions = [] `
`+        self.__dicCandidateQuestions = [] `
`                 #I think it's possible that __dicCandidateQuestions is redundant`
`                 #due to it now having been replaced with the CandidateSpace `
`                 #property`
`                 self.__CandidateQuestions = []`
` `
`-		self.__rhsDefaultsInUse = MMDBConstants.RHS_STARTOFFSET`
`-		self.__lhsDefaultsInUse = MMDBConstants.LHS_STARTOFFSET`
`+        self.__rhsDefaultsInUse = MMDBConstants.RHS_STARTOFFSET`
`+        self.__lhsDefaultsInUse = MMDBConstants.LHS_STARTOFFSET`
` `
`-		self.__maintainCandidateAndQuestionSpace()`
`+        self.__maintainCandidateAndQuestionSpace()`
` `
`-		self.__questionSelectionMethod = QuestionSelectionMethod.WEIGHTED`
`-		self.__candidateOperators = ['x'] `
`+        self.__questionSelectionMethod = QuestionSelectionMethod.WEIGHTED`
`+        self.__candidateOperators = ['x'] `
` `
`-		pass`
`+        pass`
` `
`-	def __del__(self):`
`-		pass`
`+    def __del__(self):`
`+        pass`
` `
`-	#----------------------------------------------------------------------------------------------------------`
`-	def getuserid(self):`
`-		return self.__userid`
`-	def setuserid(self, value):`
`-		self.__userid = value`
`+    #----------------------------------------------------------------------------------------------------------`
`+    def getuserid(self):`
`+        return self.__userid`
`+    def setuserid(self, value):`
`+        self.__userid = value`
` `
`-	userid = property(getuserid, setuserid, "I'm the 'userid' property.")`
`+    userid = property(getuserid, setuserid, "I'm the 'userid' property.")`
` `
`-	#----------------------------------------------------------------------------------------------------------`
`-	def getCandidateQuestions(self):`
`-		return self.__CandidateQuestions`
`-	def setCandidateQuestions(self, value):`
`-		self.__CandidateQuestions = value`
`+    #----------------------------------------------------------------------------------------------------------`
`+    def getCandidateQuestions(self):`
`+        return self.__CandidateQuestions`
`+    def setCandidateQuestions(self, value):`
`+        self.__CandidateQuestions = value`
` `
`-	CandidateQuestions = property(getCandidateQuestions, setCandidateQuestions, "I'm the 'CandidateSpace' property.")`
`+    CandidateQuestions = property(getCandidateQuestions, setCandidateQuestions, "I'm the 'CandidateSpace' property.")`
` `
`-	def getNextRHSOperand(self):`
`-		return self.__getNextOperand(OperandType.RHS)`
`+    def getNextRHSOperand(self):`
`+        return self.__getNextOperand(OperandType.RHS)`
` `
`-	def getNextLHSOperand(self):`
`-		return self.__getNextOperand(OperandType.LHS)`
`+    def getNextLHSOperand(self):`
`+        return self.__getNextOperand(OperandType.LHS)`
` `
` `
`-	def getNextQuestion(self):`
`-		if self.__questionSelectionMethod == QuestionSelectionMethod.RANDOM:`
`-			myQuestion = self.__getNextQuestionRandom()`
`-		elif self.__questionSelectionMethod == QuestionSelectionMethod.WEIGHTED:`
`-			myQuestion = self.__getNextQuestionWeighted()`
`-			#return self.__getNextQuestionWeighted()`
`-		else:`
`-			raise MMDBExceptions.NotYetImplemented`
`-		`
`-		#q = Question(s.sum.lhs, s.sum.rhs, s.sum.operator, None, None, None)`
`-		return myQuestion `
`+    def getNextQuestion(self):`
`+        if self.__questionSelectionMethod == QuestionSelectionMethod.RANDOM:`
`+            myQuestion = self.__getNextQuestionRandom()`
`+        elif self.__questionSelectionMethod == QuestionSelectionMethod.WEIGHTED:`
`+            myQuestion = self.__getNextQuestionWeighted()`
`+            #return self.__getNextQuestionWeighted()`
`+        else:`
`+            raise MMDBExceptions.NotYetImplemented`
`+        `
`+        #q = Question(s.sum.lhs, s.sum.rhs, s.sum.operator, None, None, None)`
`+        return myQuestion `
` `
`-	def answerQuestion(self, proposedAnswer, myQuestion):`
`-		'''`
`-		This method is used to supply the answer to a question`
`-		and to reflect that answer into the database. Once the`
`-		attempt at an answer has been added into the database`
`-		the 'candidate space' and 'question space' is `
`-		refreshed`
`-		'''`
`-		myAttempt = Attempt(datetime.datetime.now(), myQuestion.sum.lhs, myQuestion.sum.rhs, myQuestion.sum.operator, None, self.userid, proposedAnswer)`
`-		AttemptManager.Insert(myAttempt)`
`-		self.__maintainCandidateAndQuestionSpace()`
`+    def answerQuestion(self, proposedAnswer, myQuestion):`
`+        '''`
`+        This method is used to supply the answer to a question`
`+        and to reflect that answer into the database. Once the`
`+        attempt at an answer has been added into the database`
`+        the 'candidate space' and 'question space' is `
`+        refreshed`
`+        '''`
`+        myAttempt = Attempt(datetime.datetime.now(), myQuestion.sum.lhs, myQuestion.sum.rhs, myQuestion.sum.operator, None, self.userid, proposedAnswer)`
`+        AttemptManager.Insert(myAttempt)`
`+        self.__maintainCandidateAndQuestionSpace()`
` `
`-	#----------------------------------------------------------------------------------------------------------`
`-		`
`+    #----------------------------------------------------------------------------------------------------------`
`+        `
` `
`-	def __maintainCandidateAndQuestionSpace(self):`
`+    def __maintainCandidateAndQuestionSpace(self):`
` `
`-		self.__QuestionPool = [] `
`-		self.__lstAskedMostRecentlyFailed = []`
`-		self.__lstAskedMostRecentlySucceeded = []`
`-		self.__lstNeverAsked = []`
`+        self.__QuestionPool = [] `
`+        self.__lstAskedMostRecentlyFailed = []`
`+        self.__lstAskedMostRecentlySucceeded = []`
`+        self.__lstNeverAsked = []`
` `
`-		self.CandidateSpace = self.__buildCandidateSpace()`
`+        self.CandidateSpace = self.__buildCandidateSpace()`
` `
`-		self.__buildQuestionPool()`
`+        self.__buildQuestionPool()`
` `
`-	def __getNextOperand(self, operandType):`
`-		assert operandType in (OperandType.LHS, OperandType.RHS)`
`+    def __getNextOperand(self, operandType):`
`+        assert operandType in (OperandType.LHS, OperandType.RHS)`
` `
`-		try:`
`-			if operandType == OperandType.LHS:`
`-				self.__lhsDefaultsInUse += 1`
`-				nextOperand = MMDBConstants.LHS_CANDIDATES[self.__lhsDefaultsInUse] `
`-			elif operandType == OperandType.RHS:`
`-				self.__rhsDefaultsInUse += 1`
`-				nextOperand = MMDBConstants.RHS_CANDIDATES[self.__rhsDefaultsInUse] `
`-			else:`
`-				raise MMDBExceptions.FallingOutOfIfStatement `
`-		except IndexError:`
`-			if operandType == OperandType.LHS:`
`-				self.__lhsDefaultsInUse -= 1`
`-				nextOperand = MMDBConstants.LHS_CANDIDATES[self.__lhsDefaultsInUse] `
`-			elif operandType == OperandType.RHS:`
`-				self.__rhsDefaultsInUse -= 1`
`-				nextOperand = MMDBConstants.RHS_CANDIDATES[self.__rhsDefaultsInUse] `
`-			else:`
`-				raise MMDBExceptions.FallingOutOfIfStatement `
`+        try:`
`+            if operandType == OperandType.LHS:`
`+                self.__lhsDefaultsInUse += 1`
`+                nextOperand = MMDBConstants.LHS_CANDIDATES[self.__lhsDefaultsInUse] `
`+            elif operandType == OperandType.RHS:`
`+                self.__rhsDefaultsInUse += 1`
`+                nextOperand = MMDBConstants.RHS_CANDIDATES[self.__rhsDefaultsInUse] `
`+            else:`
`+                raise MMDBExceptions.FallingOutOfIfStatement `
`+        except IndexError:`
`+            if operandType == OperandType.LHS:`
`+                self.__lhsDefaultsInUse -= 1`
`+                nextOperand = MMDBConstants.LHS_CANDIDATES[self.__lhsDefaultsInUse] `
`+            elif operandType == OperandType.RHS:`
`+                self.__rhsDefaultsInUse -= 1`
`+                nextOperand = MMDBConstants.RHS_CANDIDATES[self.__rhsDefaultsInUse] `
`+            else:`
`+                raise MMDBExceptions.FallingOutOfIfStatement `
` `
`-		return nextOperand`
`+        return nextOperand`
` `
`-	def __buildCandidateSpace(self):`
`-		'''`
`-		Iterates over the lhs and rhs candidates to produce a set`
`-		of questions which are candidates for asking. The set is limited`
`-		by the rules around when lhs and rhs values may enter the numbering`
`-		space (which in turn are based upon how many questions have been `
`-		successfully answered using a given values as lhs/rhs)`
`-		'''`
`+    def __buildCandidateSpace(self):`
`+        '''`
`+        Iterates over the lhs and rhs candidates to produce a set`
`+        of questions which are candidates for asking. The set is limited`
`+        by the rules around when lhs and rhs values may enter the numbering`
`+        space (which in turn are based upon how many questions have been `
`+        successfully answered using a given values as lhs/rhs)`
`+        '''`
` `
`-		#Create 'base level' operand lists based upon hardcoded defaults`
`-		self.__addToCandidateSpaceFromDefaults()`
`-		#... now add extra operands based upon past successful answers`
`-		self.__addToCandidateSpaceBasedUponPastSuccesses()`
`+        #Create 'base level' operand lists based upon hardcoded defaults`
`+        self.__addToCandidateSpaceFromDefaults()`
`+        #... now add extra operands based upon past successful answers`
`+        self.__addToCandidateSpaceBasedUponPastSuccesses()`
` `
`-		#Using the lhs/rhs operand candidates we have found build a set of questions`
`+        #Using the lhs/rhs operand candidates we have found build a set of questions`
` `
`-		lq=[]`
`-		for lhs in self.__lhsCandidates:`
`-			for rhs in self.__rhsCandidates:`
`-				lq.append(Question(lhs, rhs, self.__operator))`
`+        lq=[]`
`+        for lhs in self.__lhsCandidates:`
`+            for rhs in self.__rhsCandidates:`
`+                lq.append(Question(lhs, rhs, self.__operator))`
` `
`-		#... now add extra operands based upon past successful answers`
`-		self.__addToCandidateSpaceBasedUponPastSuccessesNew(lq)`
`+        #... now add extra operands based upon past successful answers`
`+        self.__addToCandidateSpaceBasedUponPastSuccessesNew(lq)`
` `
`-		#Ensure all Sums in the proposed space are in the database`
`-		#if not add them in`
`+        #Ensure all Sums in the proposed space are in the database`
`+        #if not add them in`
` `
`-		SumManager.InsertIfNecessary(lq)`
`+        SumManager.InsertIfNecessary(lq)`
` `
`-		return lq`
`+        return lq`
` `
`-	def __addToCandidateSpaceBasedUponPastSuccesses(self):`
`-		'''`
`-		Add to the two lists of candidate operands based upon past`
`-		successful answers`
`-		'''`
`-		#append those extras which meet the threshold`
`-		#self.__lhsCandidates += self.__getLHSValuesOverThreshold()`
`-		#... then append those extras which meet the threshold`
`+    def __addToCandidateSpaceBasedUponPastSuccesses(self):`
`+        '''`
`+        Add to the two lists of candidate operands based upon past`
`+        successful answers`
`+        '''`
`+        #append those extras which meet the threshold`
`+        #self.__lhsCandidates += self.__getLHSValuesOverThreshold()`
`+        #... then append those extras which meet the threshold`
` `
`-		#This is the current technique just going to try `
`-		self.__getRHSValuesOverThreshold()`
`-		self.__getLHSValuesOverThreshold()`
`+        #This is the current technique just going to try `
`+        self.__getRHSValuesOverThreshold()`
`+        self.__getLHSValuesOverThreshold()`
` `
` `
`-	def __addToCandidateSpaceBasedUponPastSuccessesNew(self, lq):`
`-		'''`
`-		Add to the two lists of candidate operands based upon past`
`-		successful answers`
`-		'''`
`-		lqNew = []`
`-		dicLHS, dicRHS = AttemptManager.GetCountOfAllSuccesses(self.userid) `
`+    def __addToCandidateSpaceBasedUponPastSuccessesNew(self, lq):`
`+        '''`
`+        Add to the two lists of candidate operands based upon past`
`+        successful answers`
`+        '''`
`+        lqNew = []`
`+        dicLHS, dicRHS = AttemptManager.GetCountOfAllSuccesses(self.userid) `
` `
`-		#Review the previously successful attempts from a point`
`-		#of view of the LHS operand. The dicLHS dictionary is a`
`-		#dictionary of dictionaries. The 'outer' key is the LHS`
`-		#value. Iterate over the 'outer' keys and determine whether`
`-		#we need to add more lhs operands based on past successes`
`+        #Review the previously successful attempts from a point`
`+        #of view of the LHS operand. The dicLHS dictionary is a`
`+        #dictionary of dictionaries. The 'outer' key is the LHS`
`+        #value. Iterate over the 'outer' keys and determine whether`
`+        #we need to add more lhs operands based on past successes`
` `
`-		for lhsOperand in dicLHS.iterkeys():`
`-			#If the lhsoperand is already represented in the `
`-			#list of questions we can ignore it`
`-			if not self.__lhsValueInQuestionList(lq, lhsOperand):`
`-				#Make a count of successful attempts for this LHS`
`-				#operand that have been successful`
`-				cntSuccesses = 0`
`-				for rhsOperand in dicLHS[lhsOperand].iterkeys():`
`-					cntSuccesses += 1`
`-				#For every success we add a new question to the`
`-				#list with lhs equal to the current lhsOperand`
`-				#and rhs being one of the not yet used rhs defaults`
`+        for lhsOperand in dicLHS.iterkeys():`
`+            #If the lhsoperand is already represented in the `
`+            #list of questions we can ignore it`
`+            if not self.__lhsValueInQuestionList(lq, lhsOperand):`
`+                #Make a count of successful attempts for this LHS`
`+                #operand that have been successful`
`+                cntSuccesses = 0`
`+                for rhsOperand in dicLHS[lhsOperand].iterkeys():`
`+                    cntSuccesses += 1`
`+                #For every success we add a new question to the`
`+                #list with lhs equal to the current lhsOperand`
`+                #and rhs being one of the not yet used rhs defaults`
` `
` `
` `
` `
` `
`-	def __lhsValueInQuestionList(self, lq, value):`
`-		'''`
`-		lq: a list of Question objects`
`-		value: an integer`
`-		'''`
`+    def __lhsValueInQuestionList(self, lq, value):`
`+        '''`
`+        lq: a list of Question objects`
`+        value: an integer`
`+        '''`
` `
`-		rv = False`
`-		for q in lq:`
`-			if q.sum.lhs == value:`
`-				rv = True`
`-				break`
`-		return rv`
`+        rv = False`
`+        for q in lq:`
`+            if q.sum.lhs == value:`
`+                rv = True`
`+                break`
`+        return rv`
` `
` `
`-	def __addToCandidateSpaceFromDefaults(self):`
`-		'''`
`-		Build two list of candidate operands based upon the base operands which`
`-		are constants and independent of previous success/failures`
`-		'''`
`-		#Establish a minimal list of lhs candidates`
`-		self.__lhsCandidates = MMDBConstants.LHS_CANDIDATES[:self.__lhsDefaultsInUse]`
`-		#Establish a minimal list of rhs candidates`
`-		self.__rhsCandidates = MMDBConstants.RHS_CANDIDATES[:self.__rhsDefaultsInUse] `
`+    def __addToCandidateSpaceFromDefaults(self):`
`+        '''`
`+        Build two list of candidate operands based upon the base operands which`
`+        are constants and independent of previous success/failures`
`+        '''`
`+        #Establish a minimal list of lhs candidates`
`+        self.__lhsCandidates = MMDBConstants.LHS_CANDIDATES[:self.__lhsDefaultsInUse]`
`+        #Establish a minimal list of rhs candidates`
`+        self.__rhsCandidates = MMDBConstants.RHS_CANDIDATES[:self.__rhsDefaultsInUse] `
` `
` `
`-	def __getRHSValuesOverThreshold(self):`
`-		'''`
`-		Returns a list of integers which are outside the base set but which due to `
`-		past successful answer by this user may be included in the question set`
`-		as lhs operands`
`-		'''`
`+    def __getRHSValuesOverThreshold(self):`
`+        '''`
`+        Returns a list of integers which are outside the base set but which due to `
`+        past successful answer by this user may be included in the question set`
`+        as lhs operands`
`+        '''`
` `
`-		#For each RHS operator we currently have determine if > 50% of the possible`
`-		#questions (based upon the current self.__lhsCandidates) have been answered`
`-		#correctly. If they have we add one extra RHS operand to the self.__rhsCandidates`
`-		#list`
`+        #For each RHS operator we currently have determine if > 50% of the possible`
`+        #questions (based upon the current self.__lhsCandidates) have been answered`
`+        #correctly. If they have we add one extra RHS operand to the self.__rhsCandidates`
`+        #list`
` `
`-		countOfLHSOperands = len(self.__lhsCandidates)`
`-		for rhs in self.__rhsCandidates:`
`-			countOfSuccessfulAttemptsUsingRHSOperands = AttemptManager.GetCountOfRHSSuccesses(self.getuserid(),rhs)`
`-			if float(len(countOfSuccessfulAttemptsUsingRHSOperands)) / countOfLHSOperands > 0.5:`
`-				try:`
`-					nextOperand = self.getNextRHSOperand()`
`-					if nextOperand not in self.__rhsCandidates:`
`-						self.__rhsCandidates.append(nextOperand)`
`-				except IndexError:`
`-					pass`
`+        countOfLHSOperands = len(self.__lhsCandidates)`
`+        for rhs in self.__rhsCandidates:`
`+            countOfSuccessfulAttemptsUsingRHSOperands = AttemptManager.GetCountOfRHSSuccesses(self.getuserid(),rhs)`
`+            if float(len(countOfSuccessfulAttemptsUsingRHSOperands)) / countOfLHSOperands > 0.5:`
`+                try:`
`+                    nextOperand = self.getNextRHSOperand()`
`+                    if nextOperand not in self.__rhsCandidates:`
`+                        self.__rhsCandidates.append(nextOperand)`
`+                except IndexError:`
`+                    pass`
` `
` `
`-	def __getLHSValuesOverThreshold(self):`
`-		'''`
`-		Returns a list of integers which are outside the base set but which due to `
`-		past successful answer by this user may be included in the question set`
`-		as rhs operands`
`-		'''`
`-		#For each LHS operator we currently have determine if > 90% of the possible`
`-		#questions (based upon the current self.__rhsCandidates) have been answered`
`-		#correctly. If they have we add one extra LHS operand to the self.__lhsCandidates`
`-		#list`
`+    def __getLHSValuesOverThreshold(self):`
`+        '''`
`+        Returns a list of integers which are outside the base set but which due to `
`+        past successful answer by this user may be included in the question set`
`+        as rhs operands`
`+        '''`
`+        #For each LHS operator we currently have determine if > 90% of the possible`
`+        #questions (based upon the current self.__rhsCandidates) have been answered`
`+        #correctly. If they have we add one extra LHS operand to the self.__lhsCandidates`
`+        #list`
` `
`-		countOfRHSOperands = len(self.__rhsCandidates)`
`-		for lhs in self.__lhsCandidates:`
`-			countOfSuccessfulAttemptsUsingLHSOperands = AttemptManager.GetCountOfLHSSuccesses(self.getuserid(),lhs)`
`-			if float(len(countOfSuccessfulAttemptsUsingLHSOperands)) / countOfRHSOperands > 0.9:`
`-				try:`
`-					nextOperand = self.getNextLHSOperand()`
`-					if nextOperand not in self.__lhsCandidates:`
`-						self.__lhsCandidates.append(nextOperand)`
`-				except IndexError:`
`-					pass`
`+        countOfRHSOperands = len(self.__rhsCandidates)`
`+        for lhs in self.__lhsCandidates:`
`+            countOfSuccessfulAttemptsUsingLHSOperands = AttemptManager.GetCountOfLHSSuccesses(self.getuserid(),lhs)`
`+            if float(len(countOfSuccessfulAttemptsUsingLHSOperands)) / countOfRHSOperands > 0.9:`
`+                try:`
`+                    nextOperand = self.getNextLHSOperand()`
`+                    if nextOperand not in self.__lhsCandidates:`
`+                        self.__lhsCandidates.append(nextOperand)`
`+                except IndexError:`
`+                    pass`
` `
`-	def __isOperandOverThreshold(self,operandCandidate, operandType, thresholdProportion):`
`-		'''`
`-		Given an operand value, whether it's a LHS or a RHS and a proportion of answers`
`-		that need to be correct to pass the threshold this method provides a YES/NO`
`-		answer`
`-		'''`
`-		if operandType == OperandType.LHS:`
`-			raise MMDBExceptions.NotYetImplemented`
`-		elif operandType == OperandType.RHS:`
`-			raise MMDBExceptions.NotYetImplemented`
`-		else:`
`-			raise MMDBExceptions.MathsMishError   `
`+    def __isOperandOverThreshold(self,operandCandidate, operandType, thresholdProportion):`
`+        '''`
`+        Given an operand value, whether it's a LHS or a RHS and a proportion of answers`
`+        that need to be correct to pass the threshold this method provides a YES/NO`
`+        answer`
`+        '''`
`+        if operandType == OperandType.LHS:`
`+            raise MMDBExceptions.NotYetImplemented`
`+        elif operandType == OperandType.RHS:`
`+            raise MMDBExceptions.NotYetImplemented`
`+        else:`
`+            raise MMDBExceptions.MathsMishError   `
` `
`-	def __getNextQuestionRandom(self):`
`-		'''`
`-		Selects a question at random from the list of candidate questions`
`-		'''`
`-		lhsidx = random.randint(0, len(self.__lhsCandidates) - 1)`
`-		rhsidx = random.randint(0, len(self.__rhsCandidates) - 1)`
`+    def __getNextQuestionRandom(self):`
`+        '''`
`+        Selects a question at random from the list of candidate questions`
`+        '''`
`+        lhsidx = random.randint(0, len(self.__lhsCandidates) - 1)`
`+        rhsidx = random.randint(0, len(self.__rhsCandidates) - 1)`
` `
`-		lhs = self.__lhsCandidates[lhsidx]`
`-		rhs = self.__rhsCandidates[rhsidx]`
`+        lhs = self.__lhsCandidates[lhsidx]`
`+        rhs = self.__rhsCandidates[rhsidx]`
` `
` `
`-		return Question(lhs, rhs, self.__operator)`
`+        return Question(lhs, rhs, self.__operator)`
` `
`-	def __getNextQuestionWeighted(self):`
`-		'''`
`-		Selects a question at using a 'weighted random' whereby`
`-		it's more likely we will get some sort of questions than others`
`-		'''`
`+    def __getNextQuestionWeighted(self):`
`+        '''`
`+        Selects a question at using a 'weighted random' whereby`
`+        it's more likely we will get some sort of questions than others`
`+        '''`
` `
` `
`-		#Establish the cumulative probablities based upon the default values`
`-		neverAskedThreshold = MMDBConstants.NEVERASKED_PROB`
`-		mostRecentlySucceededThreshold = MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB`
`-		mostRecentlyFailedThreshold = MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB`
`+        #Establish the cumulative probablities based upon the default values`
`+        neverAskedThreshold = MMDBConstants.NEVERASKED_PROB`
`+        mostRecentlySucceededThreshold = MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB`
`+        mostRecentlyFailedThreshold = MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB`
` `
`-		'''`
`-		#Establish the cumulative probablities based upon the default values`
`+        '''`
`+        #Establish the cumulative probablities based upon the default values`
` `
`-		neverAskedThresholdRange = (0,MMDBConstants.NEVERASKED_PROB)`
`-		mostRecentlySucceededThresholdRange = (neverAskedThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB)`
`-		mostRecentlyFailedThresholdRange = (mostRecentlySucceededThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB)`
`+        neverAskedThresholdRange = (0,MMDBConstants.NEVERASKED_PROB)`
`+        mostRecentlySucceededThresholdRange = (neverAskedThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB)`
`+        mostRecentlyFailedThresholdRange = (mostRecentlySucceededThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB)`
` `
`-		#Establish lengths of lists		`
`-		lenNeverAsked = len(self.__lstNeverAsked)`
`-		lenMostRecentSucceeded = len(self.__lstAskedMostRecentlySucceeded)`
`-		lenMostRecentFailed = len(self.__lstAskedMostRecentlyFailed)`
`+        #Establish lengths of lists     `
`+        lenNeverAsked = len(self.__lstNeverAsked)`
`+        lenMostRecentSucceeded = len(self.__lstAskedMostRecentlySucceeded)`
`+        lenMostRecentFailed = len(self.__lstAskedMostRecentlyFailed)`
` `
`-		#Adjust the cumulative probablities if we have no `
`-		if len(self.__lstNeverAsked) == 0:`
`-			raise MathsMishError`
`+        #Adjust the cumulative probablities if we have no `
`+        if len(self.__lstNeverAsked) == 0:`
`+            raise MathsMishError`
` `
`-		if ((lenMostRecentSucceeded > 0) & (lenMostRecentFailed > 0)):`
`-			#Entries in all three lists so leave things as they are`
`-			neverAskedThresholdRange = (0,MMDBConstants.NEVERASKED_PROB)`
`-			mostRecentlySucceededThresholdRange = (neverAskedThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB)`
`-			mostRecentlyFailedThresholdRange = (mostRecentlySucceededThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB)`
`-		else:`
`-			if ((lenMostRecentSucceeded == 0) & (lenMostRecentFailed == 0)):`
`-				neverAskedThresholdRange = (0,MMDBConstants.NEVERASKED_PROB)`
`-				mostRecentlySucceededThresholdRange = (neverAskedThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB)`
`-				mostRecentlyFailedThresholdRange = (mostRecentlySucceededThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB)`
`-				#No entry in either succeeded of failed, adjust the `
`-				#neverAskedThreshold so it goes right to top of the`
`-				#range`
`-				neverAskedThreshold = mostRecentlyFailedThreshold`
`-			if ((lenMostRecentSucceeded == 0) & (lenMostRecentFailed > 0)):`
`-				neverAskedThreshold = mostRecentlyFailedThreshold`
`-				neverAskedThreshold = mostRecentlyFailedThreshold`
`+        if ((lenMostRecentSucceeded > 0) & (lenMostRecentFailed > 0)):`
`+            #Entries in all three lists so leave things as they are`
`+            neverAskedThresholdRange = (0,MMDBConstants.NEVERASKED_PROB)`
`+            mostRecentlySucceededThresholdRange = (neverAskedThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB)`
`+            mostRecentlyFailedThresholdRange = (mostRecentlySucceededThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB)`
`+        else:`
`+            if ((lenMostRecentSucceeded == 0) & (lenMostRecentFailed == 0)):`
`+                neverAskedThresholdRange = (0,MMDBConstants.NEVERASKED_PROB)`
`+                mostRecentlySucceededThresholdRange = (neverAskedThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB)`
`+                mostRecentlyFailedThresholdRange = (mostRecentlySucceededThreshold, MMDBConstants.NEVERASKED_PROB + MMDBConstants.MOSTRECENTOK_PROB + MMDBConstants.MOSTRECENTNOTOK_PROB)`
`+                #No entry in either succeeded of failed, adjust the `
`+                #neverAskedThreshold so it goes right to top of the`
`+                #range`
`+                neverAskedThreshold = mostRecentlyFailedThreshold`
`+            if ((lenMostRecentSucceeded == 0) & (lenMostRecentFailed > 0)):`
`+                neverAskedThreshold = mostRecentlyFailedThreshold`
`+                neverAskedThreshold = mostRecentlyFailedThreshold`
` `
` `
`-			if len(self.__lstAskedMostRecentlySucceeded) == 0:`
`-				neverAskedThreshold = mostRecentlySucceededThreshold`
`-			if len(self.__lstAskedMostRecentlyFailed) == 0:`
`-				neverAskedThreshold = mostRecentlyFailedThreshold`
`+            if len(self.__lstAskedMostRecentlySucceeded) == 0:`
`+                neverAskedThreshold = mostRecentlySucceededThreshold`
`+            if len(self.__lstAskedMostRecentlyFailed) == 0:`
`+                neverAskedThreshold = mostRecentlyFailedThreshold`
` `
` `
`-		if len(self.__lstNeverAsked) == 0:`
`-			raise MMDBExceptions.MathsMishError`
`-		'''`
`-		`
`-		#To deal with having an empty recently succeeded and/or recently failed`
`-		#we loop up to 100 times whilst absorbing IndexError we encounter`
`-		for attemptCnt in range(100):`
`-			questionSelector = random.random()`
`-			try:`
`-				if questionSelector < neverAskedThreshold:`
`-					return random.choice(self.__lstNeverAsked)`
`-				elif questionSelector < mostRecentlySucceededThreshold:`
`-					return random.choice(self.__lstAskedMostRecentlySucceeded)`
`-				elif questionSelector < mostRecentlyFailedThreshold:`
`-					return random.choice(self.__lstAskedMostRecentlyFailed)`
`-				else:`
`-					raise MMDBExceptions.FallingOutOfIfStatement `
`-			except IndexError:`
`-				self.__module_logger.debug("AbsorbingIndex Error when attemptCnt was %s " % (attemptCnt)) `
`+        if len(self.__lstNeverAsked) == 0:`
`+            raise MMDBExceptions.MathsMishError`
`+        '''`
`+        `
`+        #To deal with having an empty recently succeeded and/or recently failed`
`+        #we loop up to 100 times whilst absorbing IndexError we encounter`
`+        for attemptCnt in range(100):`
`+            questionSelector = random.random()`
`+            try:`
`+                if questionSelector < neverAskedThreshold:`
`+                    return random.choice(self.__lstNeverAsked)`
`+                elif questionSelector < mostRecentlySucceededThreshold:`
`+                    return random.choice(self.__lstAskedMostRecentlySucceeded)`
`+                elif questionSelector < mostRecentlyFailedThreshold:`
`+                    return random.choice(self.__lstAskedMostRecentlyFailed)`
`+                else:`
`+                    raise MMDBExceptions.FallingOutOfIfStatement `
`+            except IndexError:`
`+                self.__module_logger.debug("AbsorbingIndex Error when attemptCnt was %s " % (attemptCnt)) `
` `
`-		raise MMDBExceptions.MathsMishError`
`+        raise MMDBExceptions.MathsMishError`
` `
`-	def __buildQuestionPool(self):`
`-		'''`
`-		Review each question and populate the output list based upon whether`
`-		it fits the ...`
`+    def __buildQuestionPool(self):`
`+        '''`
`+        Review each question and populate the output list based upon whether`
`+        it fits the ...`
` `
`-		* 'never asked'`
`-		* 'most recent OK'`
`-		* 'most recent not OK'`
`+        * 'never asked'`
`+        * 'most recent OK'`
`+        * 'most recent not OK'`
` `
`-		... category.`
`+        ... category.`
` `
`-		The output list is a list of strings each of which is the output of the`
`-		getHash property of the corresponding Question. Depending on which category`
`-		we find a question to fit the value is entered into the list multiple times as`
`-		follows ...`
`+        The output list is a list of strings each of which is the output of the`
`+        getHash property of the corresponding Question. Depending on which category`
`+        we find a question to fit the value is entered into the list multiple times as`
`+        follows ...`
` `
`-		* 'never asked' - NEVERASKED_PROB * 10`
`-		* 'most recent OK' - MOSTRECENTOK_PROB * 10`
`-		* 'most recent not OK' - MOSTRECENTNOTOK_PROB * 10`
`+        * 'never asked' - NEVERASKED_PROB * 10`
`+        * 'most recent OK' - MOSTRECENTOK_PROB * 10`
`+        * 'most recent not OK' - MOSTRECENTNOTOK_PROB * 10`
` `
`-		... in this way when a entitity is picked at random from the list the chances`
`-		of getting a member of a given category reflect the value `
`-		'''`
`-		#Get all Sum/Attempt details for a given user`
`-		lstAttempts = AttemptManager.GetAllWithAttemptDetailsForUser(self.getuserid())`
`+        ... in this way when a entitity is picked at random from the list the chances`
`+        of getting a member of a given category reflect the value `
`+        '''`
`+        #Get all Sum/Attempt details for a given user`
`+        lstAttempts = AttemptManager.GetAllWithAttemptDetailsForUser(self.getuserid())`
` `
`-		#Produce a list of Questions objects from the database rows`
`-		for myAttempt in lstAttempts:`
`-			#Q = Question(summAttRow[2], summAttRow[3], summAttRow[1])`
`-			#Q = Question(summAttRow.question.lhs, summAttRow.question.rhs, summAttRow.question.operator)`
`-			myQuestion = myAttempt.question`
`-			self.__QuestionPool.append(myQuestion)`
`-			if (myAttempt.when == None) or (myAttempt.question.hasBeenAnswered() == False):`
`-				self.__lstNeverAsked.append(myQuestion)`
`-			else:`
`-				if myAttempt.question.goodAnswer() == True:`
`-					self.__lstAskedMostRecentlySucceeded.append(myQuestion)`
`-				elif myAttempt.question.goodAnswer() == False: `
`-					self.__lstAskedMostRecentlyFailed.append(myQuestion)`
`-				else:`
`-					raise MMDBExceptions.FallingOutOfIfStatement `
`+        #Produce a list of Questions objects from the database rows`
`+        for myAttempt in lstAttempts:`
`+            #Q = Question(summAttRow[2], summAttRow[3], summAttRow[1])`
`+            #Q = Question(summAttRow.question.lhs, summAttRow.question.rhs, summAttRow.question.operator)`
`+            myQuestion = myAttempt.question`
`+            self.__QuestionPool.append(myQuestion)`
`+            if (myAttempt.when == None) or (myAttempt.question.hasBeenAnswered() == False):`
`+                self.__lstNeverAsked.append(myQuestion)`
`+            else:`
`+                if myAttempt.question.goodAnswer() == True:`
`+                    self.__lstAskedMostRecentlySucceeded.append(myQuestion)`
`+                elif myAttempt.question.goodAnswer() == False: `
`+                    self.__lstAskedMostRecentlyFailed.append(myQuestion)`
`+                else:`
`+                    raise MMDBExceptions.FallingOutOfIfStatement `
` `
`-		self.__printPoolDiagnostics()`
`+        self.__printPoolDiagnostics()`
` `
`-	def __printPoolDiagnostics(self):`
`-		print "self.__QuestionPool = %s" % ( len(self.__QuestionPool))`
`-		print "self.__lstAskedMostRecentlyFailed =%s" % len(self.__lstAskedMostRecentlyFailed)`
`-		print "self.__lstAskedMostRecentlySucceeded =%s" % len(self.__lstAskedMostRecentlySucceeded) `
`-		print "self.__lstNeverAsked = %s" % (len(self.__lstNeverAsked))`
`-		self.__module_logger.debug("self.__QuestionPool = %s" % ( len(self.__QuestionPool)))`
`-		self.__module_logger.debug("self.__lstAskedMostRecentlyFailed = %s" % len(self.__lstAskedMostRecentlyFailed))`
`-		self.__module_logger.debug("self.__lstAskedMostRecentlySucceeded = %s" % len(self.__lstAskedMostRecentlySucceeded)) `
`-		self.__module_logger.debug("self.__lstNeverAsked = %s" % (len(self.__lstNeverAsked)))`
`-		self.__module_logger.debug("self.__lhsDefaultsInUse = %s" % (self.__lhsDefaultsInUse))`
`-		self.__module_logger.debug("self.__rhsDefaultsInUse = %s" % (self.__rhsDefaultsInUse))`
`+    def __printPoolDiagnostics(self):`
`+        print "self.__QuestionPool = %s" % ( len(self.__QuestionPool))`
`+        print "self.__lstAskedMostRecentlyFailed =%s" % len(self.__lstAskedMostRecentlyFailed)`
`+        print "self.__lstAskedMostRecentlySucceeded =%s" % len(self.__lstAskedMostRecentlySucceeded) `
`+        print "self.__lstNeverAsked = %s" % (len(self.__lstNeverAsked))`
`+        self.__module_logger.debug("self.__QuestionPool = %s" % ( len(self.__QuestionPool)))`
`+        self.__module_logger.debug("self.__lstAskedMostRecentlyFailed = %s" % len(self.__lstAskedMostRecentlyFailed))`
`+        self.__module_logger.debug("self.__lstAskedMostRecentlySucceeded = %s" % len(self.__lstAskedMostRecentlySucceeded)) `
`+        self.__module_logger.debug("self.__lstNeverAsked = %s" % (len(self.__lstNeverAsked)))`
`+        self.__module_logger.debug("self.__lhsDefaultsInUse = %s" % (self.__lhsDefaultsInUse))`
`+        self.__module_logger.debug("self.__rhsDefaultsInUse = %s" % (self.__rhsDefaultsInUse))`
` `
` `
` `

File MathsMish/__init__.py

` curs = None`
` `
` def setUpPackage():`
`-	global lock`
`-	#Setup a lock file as means to communicate to the DAO's`
`-	#that we are running in test mode`
`-	lock = flock('tmp.lock', False).acquire()		`
`-	if lock == False:`
`-		raise ValueError`
`+    global lock`
`+    #Setup a lock file as means to communicate to the DAO's`
`+    #that we are running in test mode`
`+    lock = flock('tmp.lock', False).acquire()       `
`+    if lock == False:`
`+        raise ValueError`
` `
`-	mmdbConnLocal = mmdbConnection()`
`-	testDBConn = mmdbConnLocal.conn`
`+    mmdbConnLocal = mmdbConnection()`
`+    testDBConn = mmdbConnLocal.conn`
` `
`-	#Insert data into our test database`
`-	insertTestData(testDBConn)`
`+    #Insert data into our test database`
`+    insertTestData(testDBConn)`
` `
` def tearDownPackage():`
`-	global lock`
`-	#Release the lock file used to indicate that we're testing`
`-	#to the DAO's`
`-	lock.release()`
`+    global lock`
`+    #Release the lock file used to indicate that we're testing`
`+    #to the DAO's`
`+    lock.release()`
` `
` def insertTestData(testDBConn):`
`-	'''`
`-	Create tables and insert test data`
`-	'''`
`-	curs = testDBConn.cursor()`
`-	clearDownDB(testDBConn, curs)`
`-	# Create User table and populate it`
`-	curs.execute('''create table MAM_PLAYER (PLA_AUTOID integer primary key, PLA_USERNAME text unique, PLA_REALNAME text)''')`
`-	curs.execute("insert into MAM_PLAYER values\`
`-		    (NULL,'dad','Richard Shea')")`
`-	curs.execute("insert into MAM_PLAYER values\`
`-		    (NULL,'jds','John Shea')")`
`-	curs.execute("insert into MAM_PLAYER values\`
`-		    (NULL,'ems','Emma Shea')")`
`-	curs.execute("insert into MAM_PLAYER values\`
`-		    (NULL,'mum','Kerry-Lynn Sorrell')")`
`-	testDBConn.commit()`
`-	##################################################`
`-	# Create Operations Table             `
`-	curs.execute('''create table MAM_OPERATIONS `
`-	  (OPE_AUTOID integer primary key, OPE_OPERATOR text unique,`
`-		OPE_DESCRIPTION text)''')`
`-	curs.execute("insert into MAM_OPERATIONS values (NULL,'+','Adding')")`
`-	curs.execute("insert into MAM_OPERATIONS values (NULL,'-','Subtracting')")`
`-	curs.execute("insert into MAM_OPERATIONS values (NULL,'x','Multiplying')")`
`-	testDBConn.commit()`
`-	##################################################`
`-	curs.execute('''create table MAM_SUMS (SUM_AUTOID integer primary key, SUM_OPE_ID integer, SUM_LHS integer, SUM_RHS integer)''')`
`-	insertSums(testDBConn, curs)`
`-	##################################################`
`-	curs.execute('''create table MAM_ATTEMPT (ATT_AUTOID integer primary key, ATT_PLA_ID integer, ATT_SUM_ID integer, ATT_TIMESTAMP timestamp, ATT_COMPLETED boolean, ATT_CORRECT boolean, FOREIGN KEY(ATT_SUM_ID) REFERENCES MAM_SUMS(SUM_AUTOID))''')`
`-	insertAttempts(testDBConn, curs)`
`-	##################################################`
`-	curs.execute('''create table MAM_QUESTION (QUE_AUTOID integer primary key, QUE_PLA_ID integer, QUE_ORDER integer, QUE_INUSE boolean, QUE_OPERATION text, QUE_LHS integer, QUE_RHS integer)''')`
`-	##################################################`
`-	curs.execute('''DROP VIEW [VW_SUM_ATT]''')`
`-	curs.execute('''CREATE VIEW [VW_SUM_ATT] AS SELECT * FROM MAM_ATTEMPT LEFT JOIN MAM_SUMS ON MAM_ATTEMPT.ATT_SUM_ID = MAM_SUMS.SUM_AUTOID''')`
`-	reviewVWSUMATTOutput(testDBConn, curs)`
`-	`
`+    '''`
`+    Create tables and insert test data`
`+    '''`
`+    curs = testDBConn.cursor()`
`+    clearDownDB(testDBConn, curs)`
`+    # Create User table and populate it`
`+    curs.execute('''create table MAM_PLAYER (PLA_AUTOID integer primary key, PLA_USERNAME text unique, PLA_REALNAME text)''')`
`+    curs.execute("insert into MAM_PLAYER values\`
`+            (NULL,'dad','Richard Shea')")`
`+    curs.execute("insert into MAM_PLAYER values\`
`+            (NULL,'jds','John Shea')")`
`+    curs.execute("insert into MAM_PLAYER values\`
`+            (NULL,'ems','Emma Shea')")`
`+    curs.execute("insert into MAM_PLAYER values\`
`+            (NULL,'mum','Kerry-Lynn Sorrell')")`
`+    testDBConn.commit()`
`+    ##################################################`
`+    # Create Operations Table             `
`+    curs.execute('''create table MAM_OPERATIONS `
`+      (OPE_AUTOID integer primary key, OPE_OPERATOR text unique,`
`+        OPE_DESCRIPTION text)''')`
`+    curs.execute("insert into MAM_OPERATIONS values (NULL,'+','Adding')")`
`+    curs.execute("insert into MAM_OPERATIONS values (NULL,'-','Subtracting')")`
`+    curs.execute("insert into MAM_OPERATIONS values (NULL,'x','Multiplying')")`
`+    testDBConn.commit()`
`+    ##################################################`
`+    curs.execute('''create table MAM_SUMS (SUM_AUTOID integer primary key, SUM_OPE_ID integer, SUM_LHS integer, SUM_RHS integer)''')`
`+    insertSums(testDBConn, curs)`
`+    ##################################################`
`+    curs.execute('''create table MAM_ATTEMPT (ATT_AUTOID integer primary key, ATT_PLA_ID integer, ATT_SUM_ID integer, ATT_TIMESTAMP timestamp, ATT_COMPLETED boolean, ATT_CORRECT boolean, FOREIGN KEY(ATT_SUM_ID) REFERENCES MAM_SUMS(SUM_AUTOID))''')`
`+    insertAttempts(testDBConn, curs)`
`+    ##################################################`
`+    curs.execute('''create table MAM_QUESTION (QUE_AUTOID integer primary key, QUE_PLA_ID integer, QUE_ORDER integer, QUE_INUSE boolean, QUE_OPERATION text, QUE_LHS integer, QUE_RHS integer)''')`
`+    ##################################################`
`+    curs.execute('''DROP VIEW [VW_SUM_ATT]''')`
`+    curs.execute('''CREATE VIEW [VW_SUM_ATT] AS SELECT * FROM MAM_ATTEMPT LEFT JOIN MAM_SUMS ON MAM_ATTEMPT.ATT_SUM_ID = MAM_SUMS.SUM_AUTOID''')`
`+    reviewVWSUMATTOutput(testDBConn, curs)`
`+    `
` def reviewVWSUMATTOutput(conn, curs):`
`-	curs.execute('''SELECT * FROM VW_SUM_ATT''')`
`-	f = open('VWSUMATTDump.txt', 'w+')`
`-	lstSQL = curs.fetchall()`
`-	f.write(str(curs.description))`
`-	f.write('\n')`
`-	for r in lstSQL:`
`-		f.write(str(r))`
`-		f.write('\n')`
`-	f.close()`
`+    curs.execute('''SELECT * FROM VW_SUM_ATT''')`
`+    f = open('VWSUMATTDump.txt', 'w+')`
`+    lstSQL = curs.fetchall()`
`+    f.write(str(curs.description))`
`+    f.write('\n')`
`+    for r in lstSQL:`
`+        f.write(str(r))`
`+        f.write('\n')`
`+    f.close()`
` `
` def insertSums(conn, curs):`
`-	curs.execute('''DELETE FROM MAM_SUMS''')`
`-	conn.commit()		`
`-	#for rhs in range(2,12):`
`-	for lhs in MMDBConstants.LHS_CANDIDATES[:MMDBConstants.LHS_STARTOFFSET]:`
`-		for rhs in MMDBConstants.RHS_CANDIDATES[:MMDBConstants.RHS_STARTOFFSET]: `
`-			curs.execute('''insert into MAM_SUMS values (NULL, 3, %s, %s)''' % (lhs,rhs))`
`-	conn.commit()		`
`-	#`
`-	curs.execute('''SELECT * FROM MAM_SUMS''')`
`-	f = open('SUMDumpFromInsertSums.txt', 'w')`
`-	lstSQL = curs.fetchall()`
`+    curs.execute('''DELETE FROM MAM_SUMS''')`
`+    conn.commit()       `
`+    #for rhs in range(2,12):`
`+    for lhs in MMDBConstants.LHS_CANDIDATES[:MMDBConstants.LHS_STARTOFFSET]:`
`+        for rhs in MMDBConstants.RHS_CANDIDATES[:MMDBConstants.RHS_STARTOFFSET]: `
`+            curs.execute('''insert into MAM_SUMS values (NULL, 3, %s, %s)''' % (lhs,rhs))`
`+    conn.commit()       `
`+    #`
`+    curs.execute('''SELECT * FROM MAM_SUMS''')`
`+    f = open('SUMDumpFromInsertSums.txt', 'w')`
`+    lstSQL = curs.fetchall()`
` `
`-	for r in lstSQL:`
`-		f.write(str(r))`
`-		f.write('\n')`
`-	f.close()`
`+    for r in lstSQL:`
`+        f.write(str(r))`
`+        f.write('\n')`
`+    f.close()`
` `
` def insertAttempts(conn, curs):`
`-	import datetime, time`
`-	from datetime import timedelta`
`-	import random		`
`-	#===========================================================`
`-	curs.execute('''SELECT * FROM MAM_SUMS''')`
`-	f = open('SUMDumpFromInsertAttempts.txt', 'w')`
`-	lstSQL = curs.fetchall()`
`-	for r in lstSQL:`
`-		f.write(str(r))`
`-		f.write('\n')`
`-	f.close()`
`-	#===========================================================`
`+    import datetime, time`
`+    from datetime import timedelta`
`+    import random       `
`+    #===========================================================`
`+    curs.execute('''SELECT * FROM MAM_SUMS''')`
`+    f = open('SUMDumpFromInsertAttempts.txt', 'w')`
`+    lstSQL = curs.fetchall()`
`+    for r in lstSQL:`
`+        f.write(str(r))`
`+        f.write('\n')`
`+    f.close()`
`+    #===========================================================`
` `
`-	curs.execute('''DELETE FROM MAM_ATTEMPT''')`
`-	conn.commit()		`
`-	curs.execute('''SELECT * FROM MAM_SUMS''')`
`-	lstSUM = curs.fetchall()`
`+    curs.execute('''DELETE FROM MAM_ATTEMPT''')`
`+    conn.commit()       `
`+    curs.execute('''SELECT * FROM MAM_SUMS''')`
`+    lstSUM = curs.fetchall()`
` `
`-	iCount = 0`
`-	for sumrow in lstSUM:`
`-		sumid = sumrow[0]`
`-		now = datetime.datetime.now()`
`-		now = now - timedelta(minutes=12)`
`-		for minoffset in [1,1,2,1]:`
`-			secoffset = random.randrange(0, 59)`
`-			millisecondsoffset = random.randrange(0,999)`
`-			microsecondsoffset = random.randrange(0,999)`
`-			now = now + timedelta(minutes=minoffset, seconds=secoffset, milliseconds=millisecondsoffset, microseconds=microsecondsoffset)`
`-			if iCount % 3 == 0:`
`-				blnCorrect = 0`
`-			else:`
`-				blnCorrect = 1`
`-			iCount += 1`
`-			curs.execute('''insert into MAM_ATTEMPT values (NULL, 1 , ?, ?, 1, ?)''',(sumid, now, blnCorrect))`
`-	conn.commit()		`
`-	curs.execute('''SELECT * FROM MAM_ATTEMPT''')`
`-	f = open('ATTDumpFromInsertAttempts.txt', 'w')`
`-	lstSQL = curs.fetchall()`
`-	for r in lstSQL:`
`-		f.write(str(r))`
`-		f.write('\n')`
`-	f.close()`
`+    iCount = 0`
`+    for sumrow in lstSUM:`
`+        sumid = sumrow[0]`
`+        now = datetime.datetime.now()`
`+        now = now - timedelta(minutes=12)`
`+        for minoffset in [1,1,2,1]:`
`+            secoffset = random.randrange(0, 59)`
`+            millisecondsoffset = random.randrange(0,999)`
`+            microsecondsoffset = random.randrange(0,999)`
`+            now = now + timedelta(minutes=minoffset, seconds=secoffset, milliseconds=millisecondsoffset, microseconds=microsecondsoffset)`
`+            if iCount % 3 == 0:`
`+                blnCorrect = 0`
`+            else:`
`+                blnCorrect = 1`
`+            iCount += 1`
`+            curs.execute('''insert into MAM_ATTEMPT values (NULL, 1 , ?, ?, 1, ?)''',(sumid, now, blnCorrect))`
`+    conn.commit()       `
`+    curs.execute('''SELECT * FROM MAM_ATTEMPT''')`
`+    f = open('ATTDumpFromInsertAttempts.txt', 'w')`
`+    lstSQL = curs.fetchall()`
`+    for r in lstSQL:`
`+        f.write(str(r))`
`+        f.write('\n')`
`+    f.close()`
` `
` def clearDownDB(testDBConn, curs):`
`-	'''`
`-	Drop all tables from the database to all facilitate repopulation`
`-	'''`
`-	curs.execute('''select name from sqlite_master where type = "table"''')`
`-	lstSQL = curs.fetchall()`
`-	print lstSQL `
`-	for tableName in lstSQL:`
`-		print tableName`
`-		print('''drop table %s''' % tableName)`
`-		curs.execute('''drop table %s''' % tableName)`
`-	testDBConn.commit()`
`+    '''`
`+    Drop all tables from the database to all facilitate repopulation`
`+    '''`
`+    curs.execute('''select name from sqlite_master where type = "table"''')`
`+    lstSQL = curs.fetchall()`
`+    print lstSQL `
`+    for tableName in lstSQL:`
`+        print tableName`
`+        print('''drop table %s''' % tableName)`
`+        curs.execute('''drop table %s''' % tableName)`
`+    testDBConn.commit()`

File MathsMish/diagnostic.py

` import MathsMish.MMDBLogger`
` import logging`
` def mmeval(s):`
`-	s = s.replace("x", "*")`
`-	answer = eval(s)`
`-	return answer`
`+    s = s.replace("x", "*")`
`+    answer = eval(s)`
`+    return answer`
` module_logger = logging.getLogger("MMDB.primary")`
` qMachine=QuestionMachine(1,'x')`
` l = qMachine.CandidateSpace`
` for ll in l:`
`-	print ll`
`+    print ll`
` print len(qMachine.CandidateSpace)`
` print "About to start getting questions"`
` for i in range(20):`
`-	aQuestion = qMachine.getNextQuestion()`
`-	questionInString = "%s %s %s" % (aQuestion.sum.lhs, aQuestion.sum.operator, aQuestion.sum.rhs)`
`-	print questionInString`
`-	logging.debug(questionInString)`
`-	answer = mmeval(questionInString)`
`-	if i % 3 == 0:`
`-		Adjustedanswer = answer + 1`
`-	else:`
`-		Adjustedanswer = answer`
`-	module_logger.debug("Question is : %s. Calculated Answer is %s. Adjusted Answer is %s" % (questionInString, answer, Adjustedanswer))`
`-	module_logger.debug("dir(qq) = " % (dir(aQuestion)))`
`-	aQuestion.suppliedAnswer = Adjustedanswer`
`-	qMachine.answerQuestion(Adjustedanswer, aQuestion)`
`+    aQuestion = qMachine.getNextQuestion()`
`+    questionInString = "%s %s %s" % (aQuestion.sum.lhs, aQuestion.sum.operator, aQuestion.sum.rhs)`
`+    print questionInString`
`+    logging.debug(questionInString)`
`+    answer = mmeval(questionInString)`
`+    if i % 3 == 0:`
`+        Adjustedanswer = answer + 1`
`+    else:`
`+        Adjustedanswer = answer`
`+    module_logger.debug("Question is : %s. Calculated Answer is %s. Adjusted Answer is %s" % (questionInString, answer, Adjustedanswer))`
`+    module_logger.debug("dir(qq) = " % (dir(aQuestion)))`
`+    aQuestion.suppliedAnswer = Adjustedanswer`
`+    qMachine.answerQuestion(Adjustedanswer, aQuestion)`
` print "Finished in loop"`
` `
` `

` from MathsMish.mmdb.BusinessLogic.SumManager import SumManager`
` import datetime, time`
` class AttemptManager:`
`-	"""Business Logic Layer intermediary for Attempt objects"""`
`-	def __init__(self):`
`-		self.data = []`
`+    """Business Logic Layer intermediary for Attempt objects"""`
`+    def __init__(self):`
`+        self.data = []`
` `
`-	@staticmethod`
`-	def GetAllForUser(user):`
`-		return AttemptDB.GetAllForUser(user)`
`+    @staticmethod`
`+    def GetAllForUser(user):`
`+        return AttemptDB.GetAllForUser(user)`
` `
`-	@staticmethod`
`-	def GetCountOfRHSSuccesses(user, lstRHS):`
`-		'''`
`-		Returns a list of lists. The first element in each list is a value which`
`-		has previously been used as LHS operand. The second element is a count`
`-		of how many of the possible RHS candidates, previously used with the LHS`
`-		have been answered succesfully by this user`
`-		'''`
`-		if isinstance(lstRHS, list):`
`-			pass`
`-		else:`
`-			lstRHS = [lstRHS]`
`+    @staticmethod`
`+    def GetCountOfRHSSuccesses(user, lstRHS):`
`+        '''`
`+        Returns a list of lists. The first element in each list is a value which`
`+        has previously been used as LHS operand. The second element is a count`
`+        of how many of the possible RHS candidates, previously used with the LHS`
`+        have been answered succesfully by this user`
`+        '''`
`+        if isinstance(lstRHS, list):`
`+            pass`
`+        else:`
`+            lstRHS = [lstRHS]`
` `
`-		return AttemptDB.GetCountsSuccessesForUserAndRHSOperands(user, lstRHS)`
`+        return AttemptDB.GetCountsSuccessesForUserAndRHSOperands(user, lstRHS)`
` `
`-	@staticmethod`
`-	def GetCountOfLHSSuccesses(user, lstLHS):`
`-		'''`
`-		Returns a list of lists. The first element in each list is a value which`
`-		has previously been used as LHS operand. The second element is a count`
`-		of how many of the possible RHS candidates, previously used with the LHS`
`-		have been answered succesfully by this user`
`-		'''`
`-		if isinstance(lstLHS, list):`
`-			pass`
`-		else:`
`-			lstLHS = [lstLHS]`
`+    @staticmethod`
`+    def GetCountOfLHSSuccesses(user, lstLHS):`
`+        '''`
`+        Returns a list of lists. The first element in each list is a value which`
`+        has previously been used as LHS operand. The second element is a count`
`+        of how many of the possible RHS candidates, previously used with the LHS`
`+        have been answered succesfully by this user`
`+        '''`
`+        if isinstance(lstLHS, list):`
`+            pass`
`+        else:`
`+            lstLHS = [lstLHS]`
` `
`-		return AttemptDB.GetCountsSuccessesForUserAndLHSOperands(user, lstLHS)`
`+        return AttemptDB.GetCountsSuccessesForUserAndLHSOperands(user, lstLHS)`
` `
`-	@staticmethod`
`-	def Insert(myAttempt):`
`-		'''`
`-		Add to the ATT table to reflect this answer`
`+    @staticmethod`
`+    def Insert(myAttempt):`
`+        '''`
`+        Add to the ATT table to reflect this answer`
` `
`-		myAttempt: An Attempt object`
`-		user: The userid of the person who's made the attempt `
`-		'''`
`-		`
`-		lstSUM = SumManager.GetForOperands(myAttempt.question.sum.lhs, myAttempt.question.sum.rhs, myAttempt.question.sum.operator)`
`-		if len(lstSUM) != 1:`
`-			raise DatabaseIntegrityError`
`-		else:`
`-			myAttempt.question.sum.id = lstSUM[0][0]`
`-			`
`-		AttemptDB.Insert(myAttempt)`
`+        myAttempt: An Attempt object`
`+        user: The userid of the person who's made the attempt `
`+        '''`
`+        `
`+        lstSUM = SumManager.GetForOperands(myAttempt.question.sum.lhs, myAttempt.question.sum.rhs, myAttempt.question.sum.operator)`
`+        if len(lstSUM) != 1:`
`+            raise DatabaseIntegrityError`
`+        else:`
`+            myAttempt.question.sum.id = lstSUM[0][0]`
`+            `
`+        AttemptDB.Insert(myAttempt)`
` `
`-	@staticmethod`
`-	def GetCountOfAllSuccesses(user):`
`-		'''`
`-		Returns two dictionaries which contain counts of successful attempts`
`-		keyed by LHS and RHS operand. One dictionary has an initial key of `
`-		the LHS operand, the other has an initial key of the RHS operand`
`-		'''`
`+    @staticmethod`
`+    def GetCountOfAllSuccesses(user):`
`+        '''`
`+        Returns two dictionaries which contain counts of successful attempts`
`+        keyed by LHS and RHS operand. One dictionary has an initial key of `
`+        the LHS operand, the other has an initial key of the RHS operand`
`+        '''`
` `
`-		RHSCOL = 3`
`-		LHSCOL = 2`
`+        RHSCOL = 3`
`+        LHSCOL = 2`
` `
`-		#if isinstance(lstLHS, list):`
`-		#	pass`
`-		#else:`
`-		#	lstLHS = [lstLHS]`
`+        #if isinstance(lstLHS, list):`
`+        #   pass`
`+        #else:`
`+        #   lstLHS = [lstLHS]`
` `
`-		lstATT = AttemptDB.GetCountsSuccessesForUser(user)`
`+        lstATT = AttemptDB.GetCountsSuccessesForUser(user)`
` `
`-		dicLHS = {}`
`-		dicRHS = {}`
`+        dicLHS = {}`
`+        dicRHS = {}`
` `
`-		for row in lstATT:`
`-			#Load row into dicLHS `
`-			if row[LHSCOL] not in  dicLHS:`
`-				dicLHS[row[LHSCOL]] = {}`
`-			dicLHS[row[LHSCOL]][row[RHSCOL]] = None `
`-			#Load row into dicRHS `
`-			if row[RHSCOL] not in  dicRHS:`
`-				dicRHS[row[RHSCOL]] = {}`
`-			dicRHS[row[RHSCOL]][row[LHSCOL]] = None `
`+        for row in lstATT:`
`+            #Load row into dicLHS `
`+            if row[LHSCOL] not in  dicLHS:`
`+                dicLHS[row[LHSCOL]] = {}`
`+            dicLHS[row[LHSCOL]][row[RHSCOL]] = None `
`+            #Load row into dicRHS `
`+            if row[RHSCOL] not in  dicRHS:`
`+                dicRHS[row[RHSCOL]] = {}`
`+            dicRHS[row[RHSCOL]][row[LHSCOL]] = None `
` `
`-		return [dicLHS, dicRHS]`
`-	@staticmethod`
`-	def GetAllWithAttemptDetailsForUser(user):`
`-		return AttemptDB.GetAllSumsWithAttemptDetailsForUser(user)`
`+        return [dicLHS, dicRHS]`
`+    @staticmethod`
`+    def GetAllWithAttemptDetailsForUser(user):`
`+        return AttemptDB.GetAllSumsWithAttemptDetailsForUser(user)`
` `

` from MathsMish.mmdb.mmdbConnection import SQLLITETRUE `
` from MathsMish.mmdb.mmdbConnection import SQLLITEFALSE`
` class QuestionManager(object):`
`-	"""Business Logic Layer intermediary for Question objects"""`
`-	def __init__(self):`
`-		Super.__init__()`
`-		self.data = []`
`+    """Business Logic Layer intermediary for Question objects"""`
`+    def __init__(self):`
`+        Super.__init__()`
`+        self.data = []`
` `
`-	@staticmethod`
`-	def InsertIfNecessary(lq):`
`-		'''`
`-		Populate the SUM table with any sums not currently extant.`
`+    @staticmethod`
`+    def InsertIfNecessary(lq):`
`+        '''`
`+        Populate the SUM table with any sums not currently extant.`
` `
`-		lq: List of Question objects`
`-		'''`
`-	`
`-		#Convert list of Questions to list of Dictionaries`
`-		lstIn = []`
`+        lq: List of Question objects`
`+        '''`
`+    `
`+        #Convert list of Questions to list of Dictionaries`
`+        lstIn = []`
` `
`-		for q in lq:`
`-			inUseBln = None`
`-			if q[2] == True:`
`-				inUseBln = SQLLITETRUE`
`-			elif q[2] == False:`
`-				inUseBln = SQLLITEFALSE`
`-			else:`
`-				raise MMDBExceptions.FallingOutOfIfStatement `
`-			lstIn.append({'userid':q[0], 'order': q[1], 'inuse': inUseBln, 'operator': q[3], 'lhs':q[4] ,'rhs':q[5]})`
`+        for q in lq:`
`+            inUseBln = None`
`+            if q[2] == True:`
`+                inUseBln = SQLLITETRUE`
`+            elif q[2] == False:`
`+                inUseBln = SQLLITEFALSE`
`+            else:`
`+                raise MMDBExceptions.FallingOutOfIfStatement `
`+            lstIn.append({'userid':q[0], 'order': q[1], 'inuse': inUseBln, 'operator': q[3], 'lhs':q[4] ,'rhs':q[5]})`
` `
`-		QuestionDB.InsertIfNecessary(lstIn)`
`+        QuestionDB.InsertIfNecessary(lstIn)`
` `

` from MathsMish.mmdb.DataAccess.SumDB import SumDB`
` class SumManager(object):`
`-	"""Business Logic Layer intermediary for Sum objects"""`
`-	def __init__(self):`
`-		Super.__init__()`
`-		self.data = []`
`+    """Business Logic Layer intermediary for Sum objects"""`
`+    def __init__(self):`
`+        Super.__init__()`
`+        self.data = []`
` `
`-	@staticmethod`
`-	def GetForOperands(lhs, rhs, operator):`
`-		dicIn = {'lhs':lhs, 'rhs':rhs, 'operator':operator}`
`-		return SumDB.GetForOperands(dicIn)`
`+    @staticmethod`
`+    def GetForOperands(lhs, rhs, operator):`
`+        dicIn = {'lhs':lhs, 'rhs':rhs, 'operator':operator}`
`+        return SumDB.GetForOperands(dicIn)`
` `
`-	@staticmethod`
`-	def InsertIfNecessary(lq):`
`-		'''`
`-		Populate the SUM table with any sums not currently extant.`
`+    @staticmethod`
`+    def InsertIfNecessary(lq):`
`+        '''`
`+        Populate the SUM table with any sums not currently extant.`
` `
`-		lq: List of Question objects`
`-		'''`
`-	`
`-		#Convert list of Questions to list of Dictionaries`
`-		lstIn = []`
`-		for q in lq:`
`-			lstIn.append({'lhs':q.sum.lhs,'rhs':q.sum.rhs,'operator':q.sum.operator})`
`-		SumDB.InsertIfNecessary(lstIn)`
`+        lq: List of Question objects`
`+        '''`
`+    `
`+        #Convert list of Questions to list of Dictionaries`
`+        lstIn = []`
`+        for q in lq:`
`+            lstIn.append({'lhs':q.sum.lhs,'rhs':q.sum.rhs,'operator':q.sum.operator})`
`+        SumDB.InsertIfNecessary(lstIn)`
` `

` from MathsMish.mmdb.BusinessObject.Sum import Sum `
` class Attempt(object):`
`     def __init__(self, whn = None, lhs = None, rhs = None, op = None, correct = None, uid = None, suppAns = None):`
`-	self._player = Player(uid)`
`-	self._question = Question(lhs, rhs, op, suppliedAnswer= suppAns)`
`-        self._when = whn `
`-	self._correct = None `
`+        self._player = Player(uid)`
`+        self._question = Question(lhs, rhs, op, suppliedAnswer= suppAns)`
`+            self._when = whn `
`+        self._correct = None `
` `
`     def getsum(self):`
`         return self._question`

` class Player(object):`
`     def __init__(self, id = None, username = None, fullname = None):`
`-	self._id = id `
`+        self._id = id `
`         self._username = username `
`-	self._fullname = fullname `
`+        self._fullname = fullname `
` `
`     def getid(self):`
`         return self._id`

`         if operator == "*":`
`             operator = "x"`
`         self.__validateInitArgs(lhs, rhs, operator)`
`-	`
`-	self.__sum = Sum(lhs, rhs, operator)`
`-	self.__inuse = inuse `
`-	self.__order = order `
`-	self.__userid = userid `
`-	self.__suppliedAnswer = suppliedAnswer `
`-	`
`+    `
`+    self.__sum = Sum(lhs, rhs, operator)`
`+    self.__inuse = inuse `
`+    self.__order = order `
`+    self.__userid = userid `
`+    self.__suppliedAnswer = suppliedAnswer `
`+    `
`     def __str__(self):`
`         return "%s %s %s" % (self.sum.lhs, self.sum.operator, self.sum.rhs)`
` `
`     def setsum(self, value):`
`         self.__sum = value`
` `
`-    sum = property(getsum, setsum, "I'm the 'sum' property.")	`
`+    sum = property(getsum, setsum, "I'm the 'sum' property.")   `
` `
`     def getSuppliedAnswer(self):`
`         return self.__suppliedAnswer`
`     def setSuppliedAnswer(self, value):`
`         self.__suppliedAnswer = value`
` `
`-    suppliedAnswer = property(getSuppliedAnswer, setSuppliedAnswer, "I'm the 'SuppliedAnswer' property.")	`
`+    suppliedAnswer = property(getSuppliedAnswer, setSuppliedAnswer, "I'm the 'SuppliedAnswer' property.")   `
` `
` `
`     def getinuse(self):`
`                 pass`
`         else:`
`                 raise MathsMish.MMDBExceptions.AnswerNotAnInteger`
`-	    `
`-	if self.sum.correctAnswer == self.suppliedAnswer:`
`-	    return True`
`+        `
`+        if self.sum.correctAnswer == self.suppliedAnswer:`
`+            return True`
`         else:`
`-	    return False`
`+            return False`
`     `
`     def hasBeenAnswered(self):`
`         if self.suppliedAnswer == None:`
`-	    return False`
`-	else:`
`-	    return True`
`-	`
`+        return False`
`+    else:`
`+        return True`
`+    `
`     def __validateInitArgs(self, lhs, rhs, operator):`
`         try:`
`                 operand = int(lhs)`

` class Range:`
`-	def __init__(self, lowlhs, highrhs, lowrhs, highrhs):`
`-		self.__lowlhs = lowlhs`
`-		self.__highlhs = highlhs`
`-		self.__lowrhs = lowrhs`
`-		self.__highrhs = highrhs`
`+    def __init__(self, lowlhs, highrhs, lowrhs, highrhs):`
`+        self.__lowlhs = lowlhs`
`+        self.__highlhs = highlhs`
`+        self.__lowrhs = lowrhs`
`+        self.__highrhs = highrhs`
` `
`-	def getlowlhs(self):`
`-		return self.__lowlhs`
`-	def setlowlhs(self, value):`
`-		self.__lowlhs = value`
`+    def getlowlhs(self):`
`+        return self.__lowlhs`
`+    def setlowlhs(self, value):`
`+        self.__lowlhs = value`
` `
`-	lowlhs = property(getlowlhs, setlowlhs, "I'm the 'lowlhs' property.")`
`+    lowlhs = property(getlowlhs, setlowlhs, "I'm the 'lowlhs' property.")`
` `
`-	def gethighlhs(self):`
`-		return self.__highlhs`
`-	def sethighlhs(self, value):`
`-		self.__highlhs = value`
`+    def gethighlhs(self):`
`+        return self.__highlhs`
`+    def sethighlhs(self, value):`
`+        self.__highlhs = value`
` `
`-	highlhs = property(gethighlhs, sethighlhs, "I'm the 'highlhs' property.")`
`+    highlhs = property(gethighlhs, sethighlhs, "I'm the 'highlhs' property.")`
` `
`-	def getlowrhs(self):`
`-		return self.__lowrhs`
`-	def setlowrhs(self, value):`
`-		self.__lowrhs = value`
`+    def getlowrhs(self):`
`+        return self.__lowrhs`
`+    def setlowrhs(self, value):`
`+        self.__lowrhs = value`
` `
`-	lowrhs = property(getlowrhs, setlowrhs, "I'm the 'lowrhs' property.")`
`+    lowrhs = property(getlowrhs, setlowrhs, "I'm the 'lowrhs' property.")`
` `
`-	def gethighrhs(self):`
`-		return self.__highrhs`
`-	def sethighrhs(self, value):`
`-		self.__highrhs = value`
`+    def gethighrhs(self):`
`+        return self.__highrhs`
`+    def sethighrhs(self, value):`
`+        self.__highrhs = value`
` `
`-	highrhs = property(gethighrhs, sethighrhs, "I'm the 'highrhs' property.")`
`+    highrhs = property(gethighrhs, sethighrhs, "I'm the 'highrhs' property.")`

` class Sum(object):`
`     `
`     def __init__(self, lhs = None, rhs = None, operator = None, id = None):`
`-	self._lhs = lhs `
`-	self._rhs = rhs `
`-	self._operator = operator `
`-	self.__id =  id`
`-	`
`+    self._lhs = lhs `
`+    self._rhs = rhs `
`+    self._operator = operator `
`+    self.__id =  id`
`+    `
`     def __str__(self):`
`         return "%s %s %s" % (self.lhs, self.operator, self.rhs)`
`-	`
`+    `
` `
`     def getlhs(self):`
`         return self._lhs`
` `
` `
`     def getid(self):`
`-	return self.__operator`
`+        return self.__operator`
` `
`     def setid(self, value):`
`-	self.__operator = value`
`+        self.__operator = value`
` `
`     id = property(getid, setid, "I'm the 'id' property.")`
`     `
`     def getCorrectAnswer(self):`
`-	a = eval(self.__str__().replace("x","*"))`
`-	return a `
`-	`
`+        a = eval(self.__str__().replace("x","*"))`
`+        return a `
`+    `
`     correctAnswer = property(getCorrectAnswer, setoperator, "I'm the 'correctanswer' property.")`

File MathsMish/mmdb/DataAccess/AttemptDB.py

` WHERE`
` SUM_AUTOID IN`
` (`
`-	Select A.[ATT_SUM_ID]`
`-	From [MAM_ATTEMPT] As A`
`-	Inner Join (`
`-	    Select [ATT_AUTOID]`
`-		  ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`-	    From [MAM_ATTEMPT]`
`-	    Group By [ATT_SUM_ID]) As [B]`
`-	On A.ATT_AUTOID = B.ATT_AUTOID`
`-	And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`-	WHERE`
`-	A.ATT_CORRECT = ?`
`-	AND`
`-	A.ATT_PLA_ID = ?`
`+    Select A.[ATT_SUM_ID]`
`+    From [MAM_ATTEMPT] As A`
`+    Inner Join (`
`+        Select [ATT_AUTOID]`
`+          ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`+        From [MAM_ATTEMPT]`
`+        Group By [ATT_SUM_ID]) As [B]`
`+    On A.ATT_AUTOID = B.ATT_AUTOID`
`+    And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`+    WHERE`
`+    A.ATT_CORRECT = ?`
`+    AND`
`+    A.ATT_PLA_ID = ?`
` )`
` AND`
` SUM_RHS = ?`
` WHERE`
` SUM_AUTOID IN`
` (`
`-	Select A.[ATT_SUM_ID]`
`-	From [MAM_ATTEMPT] As A`
`-	Inner Join (`
`-	    Select [ATT_AUTOID]`
`-		  ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`-	    From [MAM_ATTEMPT]`
`-	    Group By [ATT_SUM_ID]) As [B]`
`-	On A.ATT_AUTOID = B.ATT_AUTOID`
`-	And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`-	WHERE`
`-	A.ATT_CORRECT = ?`
`-	AND`
`-	A.ATT_PLA_ID = ?`
`+    Select A.[ATT_SUM_ID]`
`+    From [MAM_ATTEMPT] As A`
`+    Inner Join (`
`+        Select [ATT_AUTOID]`
`+          ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`+        From [MAM_ATTEMPT]`
`+        Group By [ATT_SUM_ID]) As [B]`
`+    On A.ATT_AUTOID = B.ATT_AUTOID`
`+    And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`+    WHERE`
`+    A.ATT_CORRECT = ?`
`+    AND`
`+    A.ATT_PLA_ID = ?`
` )`
` AND`
` SUM_LHS = ?`
` WHERE`
` SUM_AUTOID IN`
` (`
`-	Select A.[ATT_SUM_ID]`
`-	From [MAM_ATTEMPT] As A`
`-	Inner Join (`
`-	    Select [ATT_AUTOID]`
`-		  ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`-	    From [MAM_ATTEMPT]`
`-	    Group By [ATT_SUM_ID]) As [B]`
`-	On A.ATT_AUTOID = B.ATT_AUTOID`
`-	And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`-	WHERE`
`-	A.ATT_CORRECT = ?`
`-	AND`
`-	A.ATT_PLA_ID = ?`
`+    Select A.[ATT_SUM_ID]`
`+    From [MAM_ATTEMPT] As A`
`+    Inner Join (`
`+        Select [ATT_AUTOID]`
`+          ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`+        From [MAM_ATTEMPT]`
`+        Group By [ATT_SUM_ID]) As [B]`
`+    On A.ATT_AUTOID = B.ATT_AUTOID`
`+    And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`+    WHERE`
`+    A.ATT_CORRECT = ?`
`+    AND`
`+    A.ATT_PLA_ID = ?`
` )`
` ORDER BY SUM_LHS, SUM_RHS, SUM_AUTOID`
` '''`
` MAM_SUMS`
` LEFT OUTER JOIN`
` (`
`-	Select A.*`
`-	From [MAM_ATTEMPT] As A`
`-	Inner Join (`
`-	    Select [ATT_AUTOID]`
`-		  ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`-	    From [MAM_ATTEMPT]`
`-	    Group By [ATT_SUM_ID]) As [B]`
`-	On A.ATT_AUTOID = B.ATT_AUTOID`
`-	And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`-	WHERE`
`-	A.ATT_PLA_ID = ?`
`+    Select A.*`
`+    From [MAM_ATTEMPT] As A`
`+    Inner Join (`
`+        Select [ATT_AUTOID]`
`+          ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`+        From [MAM_ATTEMPT]`
`+        Group By [ATT_SUM_ID]) As [B]`
`+    On A.ATT_AUTOID = B.ATT_AUTOID`
`+    And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`+    WHERE`
`+    A.ATT_PLA_ID = ?`
` ) T1`
` ON MAM_SUMS.SUM_AUTOID = T1.ATT_SUM_ID`
` ORDER BY SUM_AUTOID`
` MAM_SUMS`
` LEFT OUTER JOIN`
` (`
`-	Select A.*`
`-	From [MAM_ATTEMPT] As A`
`-	Inner Join (`
`-	    Select [ATT_AUTOID]`
`-		  ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`-	    From [MAM_ATTEMPT]`
`-	    Group By [ATT_SUM_ID]) As [B]`
`-	On A.ATT_AUTOID = B.ATT_AUTOID`
`-	And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`-	WHERE`
`-	A.ATT_PLA_ID = ?`
`+    Select A.*`
`+    From [MAM_ATTEMPT] As A`
`+    Inner Join (`
`+        Select [ATT_AUTOID]`
`+          ,max(ATT_TIMESTAMP) as [ATT_TIMESTAMP]`
`+        From [MAM_ATTEMPT]`
`+        Group By [ATT_SUM_ID]) As [B]`
`+    On A.ATT_AUTOID = B.ATT_AUTOID`
`+    And A.ATT_TIMESTAMP = B.ATT_TIMESTAMP`
`+    WHERE`
`+    A.ATT_PLA_ID = ?`
` ) T1`
` ON MAM_SUMS.SUM_AUTOID = T1.ATT_SUM_ID`
` ORDER BY SUM_AUTOID`
` '''`
`-			`
`+            `
` `
` `
` #`
` `
` class AttemptDB():`
` `
`-	def __init__(self):`
`-		self.__module_logger = logging.getLogger("MMDB.primary")`
`-		Super.__init__()`
`-		pass`
`+    def __init__(self):`
`+        self.__module_logger = logging.getLogger("MMDB.primary")`
`+        Super.__init__()`
`+        pass`
` `
`-	@staticmethod`
`-	def GetAllSuccessesForUser(user):`
`-		return AttemptDB.__GetAllForUserByResultCriteiria(user, Result.Success)`
`+    @staticmethod`
`+    def GetAllSuccessesForUser(user):`
`+        return AttemptDB.__GetAllForUserByResultCriteiria(user, Result.Success)`
` `
`-	@staticmethod`
`-	def GetAllFailuresForUser(user):`
`-		return AttemptDB.__GetAllForUserByResultCriteiria(user, Result.Failure)`
`+    @staticmethod`
`+    def GetAllFailuresForUser(user):`
`+        return AttemptDB.__GetAllForUserByResultCriteiria(user, Result.Failure)`
` `
`-	@staticmethod`
`-	def GetAllForUser(user):`
`-		return AttemptDB.__GetAllForUserByResultCriteiria(user, Result.SuccessOrFailure)`
`+    @staticmethod`
`+    def GetAllForUser(user):`
`+        return AttemptDB.__GetAllForUserByResultCriteiria(user, Result.SuccessOrFailure)`
` `
`-	@staticmethod`
`-	def GetAll():`
`-		mmdbConn = mmdbConnection()`
`-		conn = mmdbConn.conn`
`-		c = conn.cursor()`
`-		c.execute(SELECTATT)`
`-		lstA = c.fetchmany()`
`-		return lstA`
`+    @staticmethod`
`+    def GetAll():`
`+        mmdbConn = mmdbConnection()`
`+        conn = mmdbConn.conn`
`+        c = conn.cursor()`
`+        c.execute(SELECTATT)`
`+        lstA = c.fetchmany()`
`+        return lstA`
` `
`-	@staticmethod`
`-	def GetCountsSuccessesForUserAndRHSOperands(user, lstRHSOperands):`
`-		return AttemptDB.__GetCountsSuccessesForUserAndSpecifiedOperand(user, lstRHSOperands, Operand.RightHandSide)`
`-	@staticmethod`
`-	def GetCountsSuccessesForUserAndLHSOperands(user, lstLHSOperands):`
`-		return AttemptDB.__GetCountsSuccessesForUserAndSpecifiedOperand(user, lstLHSOperands, Operand.LeftHandSide)`
`-	@staticmethod`
`-	def Insert(myAttempt):`
`+    @staticmethod`
`+    def GetCountsSuccessesForUserAndRHSOperands(user, lstRHSOperands):`
`+        return AttemptDB.__GetCountsSuccessesForUserAndSpecifiedOperand(user, lstRHSOperands, Operand.RightHandSide)`
`+    @staticmethod`
`+    def GetCountsSuccessesForUserAndLHSOperands(user, lstLHSOperands):`
`+        return AttemptDB.__GetCountsSuccessesForUserAndSpecifiedOperand(user, lstLHSOperands, Operand.LeftHandSide)`
`+    @staticmethod`