def createNeo4jGraph(graphType, diagramType, diagramId): connection = connectToMySQL() cur = connection.cursor() if graphType == "Block" and diagramType == "Teacher": cur.execute("SELECT answerDiagram FROM process_question WHERE processqId = %s", (diagramId)) elif graphType == "Block" and diagramType == "Student": cur.execute("SELECT answerDiagram FROM process_stud_answer WHERE processStudAnsId = %s", (diagramId)) elif graphType == "LogicGate" and diagramType == "Teacher": cur.execute("SELECT answerDiagram FROM logic_gate_question WHERE logicgateqId = %s", (diagramId)) elif graphType == "LogicGate" and diagramType == "Student": cur.execute("SELECT answerDiagram FROM logic_gate_stud_answer WHERE logicgateStudAnsId = %s", (diagramId)) elif graphType == "Flowchart" and diagramType == "Teacher": cur.execute("SELECT answerDiagram FROM flowchart_question WHERE flowchartqId = %s", (diagramId)) elif graphType == "Flowchart" and diagramType == "Student": cur.execute("SELECT answerDiagram FROM flowchart_stud_answer WHERE flowchartStudAnsId = %s", (diagramId)) resultSet = cur.fetchone() cur.close() connection.close() jsonData = json.loads(resultSet[0]) createNodes(jsonData, diagramType, graphType) createRelationships(jsonData, diagramType, graphType)
def allocateMarksToLogicGateAnswerAndSaveToDatabase( matchedCompletedStudentNodes, noOfMatchedNodes, noOfAdditionalNodes, noOfDeletedNodes, noOfSubstitutedNodes, totNoOfOtherIncorrectNodes, feedback, logicGateQuestionId, studentAnswerId): connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT symbolMark, sequenceMark FROM logic_gate_question WHERE logicgateqId = %s", (logicGateQuestionId)) resultSet = cur.fetchone() print('starting mark allocation...') symbolMark = resultSet[0] sequenceMark = resultSet[1] sequenceMarkForAddDeleteSubDeductions = (80 / 100) * sequenceMark totalAddDeleteSubDiff = noOfAdditionalNodes + noOfDeletedNodes + noOfSubstitutedNodes + totNoOfOtherIncorrectNodes scoredSymbolMark = noOfMatchedNodes * symbolMark if noOfMatchedNodes == 0: scoredSequenceMark = 0 else: # maximum number of errors for additions and deletions that are allowed is 6 if totalAddDeleteSubDiff <= 6: scoredSequenceMark = sequenceMark - ( totalAddDeleteSubDiff / 6) * sequenceMarkForAddDeleteSubDeductions else: scoredSequenceMark = sequenceMark - sequenceMarkForAddDeleteSubDeductions scoredFullMark = scoredSymbolMark + scoredSequenceMark # save matched correct gates to database matchedGatesStr = "" count = 0 while count < len(matchedCompletedStudentNodes): matchedGatesStr = matchedGatesStr + str( matchedCompletedStudentNodes[count]) + "," count = count + 1 matchedGatesStr = matchedGatesStr[:-1] cur.execute( "UPDATE logic_gate_stud_answer SET symbolMark = %s, sequenceMark = %s, matchedGates = %s WHERE logicgateStudAnsId = %s", (scoredSymbolMark, scoredSequenceMark, matchedGatesStr, studentAnswerId)) cur.execute( "UPDATE student_answer SET scoredMark = %s, feedback = %s, markedStatus = %s WHERE studAnswerId = %s", (scoredFullMark, feedback, "true", studentAnswerId)) cur.close() connection.close()
def allocateMarksAndSaveToDatabase(noOfMatchedNodes, noOfAdditionalNodes, noOfDeletedNodes, noOfSubstitutedNodes, totNoOfOtherSubstitutedNodes, totNoOfOtherIncorrectNodes, feedback, processQuestionId, studentAnswerId): connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT textMark, sequenceMark FROM process_question WHERE processqId = %s", (processQuestionId)) resultSet = cur.fetchone() print('starting mark allocation...') textMark = resultSet[0] sequenceMark = resultSet[1] sequenceMarkForAddDeleteDeductions = (70 / 100) * sequenceMark totalAddDeleteDiff = noOfAdditionalNodes + noOfDeletedNodes + totNoOfOtherIncorrectNodes scoredTextMark = noOfMatchedNodes * textMark if noOfMatchedNodes == 0: scoredSequenceMark = 0 else: # maximum number of errors for additions and deletions that are allowed is 5 if totalAddDeleteDiff <= 5: scoredSequenceMark = sequenceMark - ( totalAddDeleteDiff / 5) * sequenceMarkForAddDeleteDeductions else: scoredSequenceMark = sequenceMark - sequenceMarkForAddDeleteDeductions scoredFullMark = scoredTextMark + scoredSequenceMark cur.execute( "UPDATE process_stud_answer SET textMark = %s, sequenceMark = %s WHERE processStudAnsId = %s", (scoredTextMark, scoredSequenceMark, studentAnswerId)) cur.execute( "UPDATE student_answer SET scoredMark = %s, feedback = %s, markedStatus = %s WHERE studAnswerId = %s", (scoredFullMark, feedback, "true", studentAnswerId)) cur.close() connection.close()
def markQuestionPaper(question_paper_Id): connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT questionId, type FROM question WHERE questionPaperId = %s AND " + "(type='Block' OR type='LogicGate' OR type='Flowchart')", (question_paper_Id)) resultSet = cur.fetchall() cur.close() connection.close() for row in resultSet: questionId = str(row[0]) questionType = row[1] status = markDiagram(questionId, questionType, "PaperMarker") if status == "false": return jsonify({"status": "failed"}) return jsonify({"status": "successful"})
def markDiagram(question_Id, graphType, caller): print("QuestionId: " + question_Id) directory = "StudentAnswerProgram" try: createNeo4jGraph(graphType, "Teacher", question_Id) isExactMatch = "" noOfInputs = 0 if graphType == "LogicGate": connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT isExactMatch, noOfInputs FROM logic_gate_question WHERE logicgateqId = %s", (question_Id)) resultSet = cur.fetchone() cur.close() connection.close() isExactMatch = resultSet[0] noOfInputs = resultSet[1] if isExactMatch == "false": simulateLogicGate("Teacher", noOfInputs, question_Id) elif graphType == "Flowchart": if not os.path.exists(directory): os.makedirs(directory) os.chdir(directory) connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT studAnswerId FROM student_answer WHERE questionId = %s and markedStatus = %s", (question_Id, "false")) resultSet = cur.fetchall() cur.close() connection.close() for row in resultSet: createNeo4jGraph(graphType, "Student", row[0]) if graphType == "Block": markStudDFSBlockAnswer(question_Id, row[0]) elif graphType == "LogicGate": markLogicGateAnswer(question_Id, row[0], isExactMatch, noOfInputs) elif graphType == "Flowchart": markFlowchartAnswer(question_Id, row[0]) deleteStudentGraph() deleteAllAfterMarking() if graphType == "LogicGate" and isExactMatch == "false": deleteSimulationCombinationData() elif graphType == "Flowchart": os.chdir('..') if os.path.isdir(directory): shutil.rmtree(directory) except Exception as e: deleteAllAfterMarking() if graphType == "LogicGate": # and isExactMatch == "false" deleteSimulationCombinationData() elif graphType == "Flowchart": os.chdir('..') if os.path.isdir(directory): shutil.rmtree(directory) print('Exception: ') print(e) if caller == "PaperMarker": return "false" return jsonify({"status": "failed"}) if caller == "PaperMarker": return "true" return jsonify({"status": "successful"})
def simulateLogicGate(diagramBelongsTo, noOfInputs, logicGateQuestionId): # Connect to Graph graph = connectToGraph() # noOfInputs = resultSet[0] binaryCombinationList = list(itertools.product([0, 1], repeat=noOfInputs)) queue = [] inputsProcessedOrder = '' noOfMatchedCombinations = 0 bddNodeKey = 1 inputNodes = graph.data( "MATCH (node:%s) WHERE node.symbol='input' RETURN node" % diagramBelongsTo) if diagramBelongsTo == "Teacher": count = 0 while count < len(inputNodes): queue.insert(0, inputNodes[count]['node']['key']) count = count + 1 elif diagramBelongsTo == "Student": connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT inputProcessedOrder FROM logic_gate_question WHERE logicgateqId = %s", (logicGateQuestionId)) resultSet = cur.fetchone() cur.close() connection.close() inputsProcessedOrder = resultSet[0] combinationLoopCount = 0 while combinationLoopCount < len(binaryCombinationList): inputsProcessedCount = 0 currentCombination = binaryCombinationList[combinationLoopCount] if diagramBelongsTo == "Student" or (combinationLoopCount >= 1 and diagramBelongsTo == "Teacher"): inputs = inputsProcessedOrder.split(',') for input in inputs: count = 0 while count < len(inputNodes): if inputNodes[count]['node']['text'] == input: queue.insert(0, inputNodes[count]['node']['key']) break count = count + 1 while queue: currentNode = queue.pop() currentNodeInfo = graph.data( "MATCH (node:%s) WHERE node.key= {key} RETURN node" % diagramBelongsTo, parameters={"key": currentNode}) currentChildNodes = graph.data( "MATCH (parent:%s)-[:TO]->(child:%s) WHERE parent.key= {key} RETURN child" % (diagramBelongsTo, diagramBelongsTo), parameters={"key": currentNode}) if currentNodeInfo[0]['node'][ 'symbol'] == "input" and combinationLoopCount == 0 and diagramBelongsTo == "Teacher": inputsProcessedOrder = inputsProcessedOrder + currentNodeInfo[ 0]['node']['text'] + "," if currentNodeInfo[0]['node']['symbol'] == "input": currentInput = currentCombination[inputsProcessedCount] inputsProcessedCount = inputsProcessedCount + 1 if currentNodeInfo[0]['node']['symbol'] == "output": if combinationLoopCount == 0 and diagramBelongsTo == "Teacher": inputsProcessedOrder = inputsProcessedOrder[:-1] output = currentNodeInfo[0]['node']['inputs'] graph.run("MATCH (node:%s) REMOVE node.inputs" % diagramBelongsTo) if diagramBelongsTo == "Teacher": connection = connectToMySQL() cur = connection.cursor() if noOfInputs == 1: cur.execute( "INSERT INTO simulate_logicgate(inputOne, output) VALUES('%s', '%s')", (currentCombination[0], output[0])) elif noOfInputs == 2: cur.execute( "INSERT INTO simulate_logicgate(inputOne, inputTwo, output) VALUES('%s', '%s', '%s')", (currentCombination[0], currentCombination[1], output[0])) elif noOfInputs == 3: cur.execute( "INSERT INTO simulate_logicgate(inputOne, inputTwo, inputThree, output) VALUES('%s', '%s', '%s', '%s')", (currentCombination[0], currentCombination[1], currentCombination[2], output[0])) cur.close() connection.close() elif diagramBelongsTo == "Student": connection = connectToMySQL() cur = connection.cursor() if noOfInputs == 1: cur.execute( "SELECT output FROM simulate_logicgate WHERE inputOne = '%s'", (currentCombination[0])) elif noOfInputs == 2: cur.execute( "SELECT output FROM simulate_logicgate WHERE inputOne = '%s' AND inputTwo = '%s'", (currentCombination[0], currentCombination[1])) elif noOfInputs == 3: cur.execute( "SELECT output FROM simulate_logicgate WHERE inputOne = '%s' AND inputTwo = '%s' AND inputThree = '%s'", (currentCombination[0], currentCombination[1], currentCombination[2])) resultSet = cur.fetchone() cur.close() connection.close() if resultSet[0] == output[0]: noOfMatchedCombinations = noOfMatchedCombinations + 1 for childNode in currentChildNodes: childParents = graph.data( "MATCH (parent:%s)-[:TO]->(child:%s) WHERE child.key= {key} RETURN parent" % (diagramBelongsTo, diagramBelongsTo), parameters={"key": childNode['child']['key']}) childNodeDetails = Node(diagramBelongsTo, key=childNode['child']['key']) graph.merge(childNodeDetails) if currentNodeInfo[0]['node']['symbol'] == "input": handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "and": currentInput = getInputForAndOrNandNor( currentNodeInfo, 1, 0, 0) handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "or": currentInput = getInputForAndOrNandNor( currentNodeInfo, 0, 1, 1) handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "not": inputs = currentNodeInfo[0]['node']['inputs'] if inputs[0] == 0: currentInput = 1 else: currentInput = 0 handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "nand": currentInput = getInputForAndOrNandNor( currentNodeInfo, 0, 0, 1) handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "nor": currentInput = getInputForAndOrNandNor( currentNodeInfo, 1, 1, 0) handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "xor": currentInput = getInputForXorXnor(currentNodeInfo, 0, 1) handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) elif currentNodeInfo[0]['node']['symbol'] == "xnor": currentInput = getInputForXorXnor(currentNodeInfo, 1, 0) handleGateInputsAndQueue(childNode, childNodeDetails, currentInput, childParents, queue) childNodeDetails.push() if diagramBelongsTo == "Teacher": connection = connectToMySQL() cur = connection.cursor() cur.execute( "UPDATE logic_gate_question SET inputProcessedOrder = %s WHERE logicgateqId = %s", (inputsProcessedOrder, logicGateQuestionId)) cur.close() connection.close() combinationLoopCount = combinationLoopCount + 1 return noOfMatchedCombinations
def deleteSimulationCombinationData(): connection = connectToMySQL() cur = connection.cursor() cur.execute("DELETE FROM simulate_logicgate") cur.close() connection.close()
def executeStudentAnswerProgram(outputVariableNames, flowchartQuestionId): desiredProgramExecution = "true" connection = connectToMySQL() cur = connection.cursor() cur.execute( "SELECT inputs, outputs FROM flowchart_question WHERE flowchartqId = %s", (flowchartQuestionId)) resultSet = cur.fetchone() cur.close() connection.close() outputs = resultSet[1].split(",") programOutput = {} sys.argv = ["studentAnswer.py"] if resultSet[0]: inputs = resultSet[0].split(",") for input in inputs: sys.argv.append(float(input)) if not os.path.exists("studentAnswer.py"): print('file does not exist in current path') else: print('file exists') # redirect the standard output to a string until the end of the exec method call old_stdout = sys.stdout redirected_programOutput = sys.stdout = StringIO() try: exec(open("studentAnswer.py").read()) except SystemExit: desiredProgramExecution = "false" except: desiredProgramExecution = "false" sys.stdout = old_stdout if desiredProgramExecution == "true": redirected_programOutput = redirected_programOutput.getvalue() # redirected output has new line characters to separate outputs. Therefore, split and store them for later use. redirected_programOutput = redirected_programOutput.splitlines() count = 0 for output in outputs: if len(redirected_programOutput) > count: if not all(x.isalpha() or x.isspace() for x in output): if not float(output) == float( redirected_programOutput[count]): desiredProgramExecution = "false" break else: if not output == redirected_programOutput[count]: desiredProgramExecution = "false" break count = count + 1 else: # this means that the number of outputs of the teacher and student are not the same desiredProgramExecution = "false" break return desiredProgramExecution