예제 #1
0
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()
예제 #3
0
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()
예제 #4
0
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"})
예제 #5
0
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