def getAllStudentNodeKeysList():
    graph = connectToGraph()

    studentNodes = graph.data("MATCH (node:Student) RETURN node.key")

    studentNodesList = []

    count = 0
    while count < len(studentNodes):
        studentNodesList.append(studentNodes[count]['node.key'])
        count = count + 1

    return studentNodesList
def getTotalNoOfTeacherNodes():
    graph = connectToGraph()

    studentNodes = graph.data("MATCH (node:Teacher) RETURN node.key")

    return len(studentNodes)
def markStudBFSLogicGateAnswer():
    # Connect to Graph
    graph = connectToGraph()

    answerDiagramCorrect = 'false'

    teacherInputNodes = graph.data(
        "MATCH (node:Teacher) WHERE node.symbol='input' RETURN node")
    studentInputNodes = graph.data(
        "MATCH (node:Student) WHERE node.symbol='input' RETURN node")

    teacherQueue = [teacherInputNodes[0]['node']['key']]

    count = 0
    while count < len(studentInputNodes):
        if studentInputNodes[count]['node']['text'] == teacherInputNodes[0][
                'node']['text']:
            studentQueue = [studentInputNodes[count]['node']['key']]
        count = count + 1

    count = 1
    while count < len(teacherInputNodes):
        teacherQueue.insert(0, teacherInputNodes[count]['node']['key'])

        studCount = 0
        while studCount < len(studentInputNodes):
            if studentInputNodes[studCount]['node'][
                    'text'] == teacherInputNodes[count]['node']['text']:
                studentQueue.insert(
                    0, studentInputNodes[studCount]['node']['key'])
            studCount = studCount + 1

        count = count + 1

    childlessTeacherOtherParents = []
    childHavingTeacherOtherParents = []

    childlessStudentOtherParents = []
    childHavingStudentOtherParents = []

    # maintains all matched and completed nodes so far(the ones which have been removed from the queue after completion)
    matchedCompletedTeacherNodes = []
    matchedCompletedStudentNodes = []

    # each time a student gate is visited, it is added to this
    visitedStudentNodes = []

    matchedTeacherLevelNodes = []
    matchedStudentLevelNodes = []

    additionalNodes = []
    deletedNodes = []
    substitutedNodes = []
    addOrSubNodes = []
    delOrSubNodes = []

    errorneousTeacherNodes = []
    errorneousStudentNodes = []

    totNoOfAdditionalNodes = 0
    totNoOfDeletedNodes = 0
    totNoOfSubstitutedNodes = 0
    totNoOfOtherIncorrectNodes = 0

    feedback = ""

    # maintains parents to see if all its children has been traversed before and so that it can be removed from the queue
    # traversedChildMatchFoundNodes = []

    while teacherQueue and studentQueue:  # or

        teacherCurrent = teacherQueue.pop()
        studentCurrent = studentQueue.pop()

        currentTeacherNodeInfo = graph.data(
            "MATCH (node:Teacher) WHERE node.key= {key} RETURN node",
            parameters={"key": teacherCurrent})

        currentStudentNodeInfo = graph.data(
            "MATCH (node:Student) WHERE node.key= {key} RETURN node",
            parameters={"key": studentCurrent})

        if currentTeacherNodeInfo[0]['node']['symbol'] == "output":
            if currentStudentNodeInfo[0]['node']['symbol'] == "output":
                feedback = feedback + 'The output and the connections to it are correct. '

                answerDiagramCorrect = 'true'
                break

        teacherChildNodes = graph.data(
            "MATCH (parent:Teacher)-[:TO]->(child:Teacher) WHERE parent.key= {key} RETURN child",
            parameters={"key": teacherCurrent})

        studentChildNodes = graph.data(
            "MATCH (parent:Student)-[:TO]->(child:Student) WHERE parent.key= {key} RETURN child",
            parameters={"key": studentCurrent})

        for teacherChild in teacherChildNodes:
            # get all parents of current teacher child node under analysis except the current teacher parent node
            teacherChildParents = graph.data(
                "MATCH (parent:Teacher)-[:TO]->(child:Teacher) WHERE child.key= {key} AND parent.key <> {parentKey} RETURN parent",
                parameters={
                    "key": teacherChild['child']['key'],
                    "parentKey": teacherCurrent
                })

            teacherChildParentsList = list(teacherChildParents)

            childlessTeacherOtherParents = []
            childHavingTeacherOtherParents = []

            for teacherChildParent in teacherChildParentsList:
                teacherChildParentChildrenNodes = graph.data(
                    "MATCH (parent:Teacher)-[:TO]->(child:Teacher) WHERE parent.key= {parentKey} AND child.key <> {childKey} RETURN child",
                    parameters={
                        "parentKey": teacherChildParent['parent']['key'],
                        "childKey": teacherChild['child']['key']
                    })

                # check whether other teacher parents have other children besides current child
                if not teacherChildParentChildrenNodes:
                    childlessTeacherOtherParents.append(teacherChildParent)
                else:
                    childHavingTeacherOtherParents.append(teacherChildParent)

            for studentChild in studentChildNodes:
                if currentTeacherNodeInfo[0]['node']['symbol'] == currentStudentNodeInfo[0]['node']['symbol'] and \
                        teacherChild['child']['symbol'] == studentChild['child']['symbol']:

                    studentChildParents = graph.data(
                        "MATCH (parent:Student)-[:TO]->(child:Student) WHERE child.key= {key} AND parent.key <> {parentKey} RETURN parent",
                        parameters={
                            "key": studentChild['child']['key'],
                            "parentKey": studentCurrent
                        })

                    studentChildParentsList = list(studentChildParents)

                    childlessStudentOtherParents = []
                    childHavingStudentOtherParents = []

                    for studentChildParent in studentChildParentsList:
                        studentChildParentChildrenNodes = graph.data(
                            "MATCH (parent:Student)-[:TO]->(child:Student) WHERE parent.key= {parentKey} AND child.key <> {childKey} RETURN child",
                            parameters={
                                "parentKey":
                                studentChildParent['parent']['key'],
                                "childKey": studentChild['child']['key']
                            })

                        # check whether other student parents have other children besides current child
                        if not studentChildParentChildrenNodes:
                            childlessStudentOtherParents.append(
                                studentChildParent)
                        else:
                            childHavingStudentOtherParents.append(
                                studentChildParent)

                    if len(childlessTeacherOtherParents) == len(childlessStudentOtherParents) and \
                            len(childHavingTeacherOtherParents) == len(childHavingStudentOtherParents):
                        if currentStudentNodeInfo[0]['node'][
                                'symbol'] == "input" and not currentStudentNodeInfo[
                                    0]['node'][
                                        'key'] in matchedCompletedStudentNodes:
                            matchedCompletedTeacherNodes.append(teacherCurrent)
                            matchedCompletedStudentNodes.append(studentCurrent)

                        childlessStudentOtherParentsNotInQueue = []

                        # if this gate has been visited once, then already childless other parents have been removed if they were in the queue
                        # so no need to do it again and it cannot be done
                        if not studentChild['child'][
                                'key'] in visitedStudentNodes:
                            # remove childless other teacher parents and remove childless other student parents
                            for childlessTeacherNode in childlessTeacherOtherParents:

                                for childlessStudentNode in childlessStudentOtherParents:
                                    if childlessTeacherNode['parent'][
                                            'symbol'] == childlessStudentNode[
                                                'parent']['symbol']:

                                        if childlessTeacherNode['parent']['key'] in teacherQueue and\
                                                childlessStudentNode['parent']['key'] in studentQueue:
                                            teacherQueue.remove(
                                                childlessTeacherNode['parent']
                                                ['key'])
                                            studentQueue.remove(
                                                childlessStudentNode['parent']
                                                ['key'])

                                            if childlessStudentNode['parent'][
                                                    'symbol'] == "input" and not childlessStudentNode[
                                                        'parent'][
                                                            'key'] in matchedCompletedStudentNodes:
                                                matchedCompletedTeacherNodes.append(
                                                    childlessTeacherNode[
                                                        'parent']['key'])
                                                matchedCompletedStudentNodes.append(
                                                    childlessStudentNode[
                                                        'parent']['key'])

                                            visitedStudentNodes.append(
                                                studentChild['child']['key'])
                                        else:
                                            childlessStudentOtherParentsNotInQueue.append(
                                                childlessStudentNode['parent']
                                                ['key'])

                        visitedStudentNodes.append(
                            studentChild['child']['key'])

                        # insert matched gate to queue
                        if len(childlessStudentOtherParentsNotInQueue) == 0 and \
                                visitedStudentNodes.count(studentChild['child']['key']) == (len(studentChildParents) + 1):
                            teacherQueue.insert(0,
                                                teacherChild['child']['key'])
                            studentQueue.insert(0,
                                                studentChild['child']['key'])

                            if not studentChild['child'][
                                    'symbol'] == 'output':  # and not studentChild['child']['key'] in matchedCompletedStudentNodes
                                feedback = feedback + 'The gate: ' + studentChild[
                                    'child']['symbol'].upper(
                                    ) + ' and its input connections are correct. '

                            matchedCompletedTeacherNodes.append(
                                teacherChild['child']['key'])
                            matchedCompletedStudentNodes.append(
                                studentChild['child']['key'])

                        if len(teacherChildNodes) == len(
                                studentChildNodes
                        ) or len(teacherChildNodes) > len(studentChildNodes):
                            matchedTeacherLevelNodes.append(
                                teacherChild['child']['key'])
                        elif len(teacherChildNodes) < len(studentChildNodes):
                            matchedStudentLevelNodes.append(
                                studentChild['child']['key'])

                        childlessTeacherOtherParents = []
                        childlessStudentOtherParents = []
                        childHavingTeacherOtherParents = []
                        childHavingStudentOtherParents = []

                        childlessStudentOtherParentsNotInQueue = []

                        break

        if len(teacherChildNodes) == len(studentChildNodes):
            if not len(teacherChildNodes) == len(matchedTeacherLevelNodes):
                for teacherChild in teacherChildNodes:
                    if not teacherChild['child'][
                            'key'] in matchedTeacherLevelNodes and not teacherChild[
                                'child']['key'] in errorneousTeacherNodes:
                        substitutedNodes.append(teacherChild['child']['key'])
                        totNoOfSubstitutedNodes = totNoOfSubstitutedNodes + 1
                        errorneousTeacherNodes.append(
                            teacherChild['child']['key'])

                for studentChild in studentChildNodes:
                    if not studentChild['child'][
                            'key'] in matchedStudentLevelNodes:
                        errorneousStudentNodes.append(
                            studentChild['child']['key'])
        elif len(teacherChildNodes) > len(studentChildNodes):
            if len(matchedTeacherLevelNodes) < len(studentChildNodes):
                for teacherChild in teacherChildNodes:
                    if not teacherChild['child'][
                            'key'] in matchedTeacherLevelNodes and not teacherChild[
                                'child']['key'] in errorneousTeacherNodes:
                        delOrSubNodes.append(teacherChild['child']['key'])
                        totNoOfOtherIncorrectNodes = totNoOfOtherIncorrectNodes + 1
                        errorneousTeacherNodes.append(
                            teacherChild['child']['key'])
            elif len(matchedTeacherLevelNodes) == len(studentChildNodes):
                for teacherChild in teacherChildNodes:
                    if not teacherChild['child'][
                            'key'] in matchedTeacherLevelNodes and not teacherChild[
                                'child']['key'] in errorneousTeacherNodes:
                        deletedNodes.append(teacherChild['child']['key'])
                        totNoOfDeletedNodes = totNoOfDeletedNodes + 1
                        errorneousTeacherNodes.append(
                            teacherChild['child']['key'])

            for studentChild in studentChildNodes:
                if not studentChild['child']['key'] in matchedStudentLevelNodes:
                    errorneousStudentNodes.append(studentChild['child']['key'])
        elif len(teacherChildNodes) < len(studentChildNodes):
            if len(matchedStudentLevelNodes) == len(teacherChildNodes):
                for studentChild in studentChildNodes:
                    if not studentChild['child'][
                            'key'] in matchedStudentLevelNodes and not studentChild[
                                'child']['key'] in errorneousStudentNodes:
                        additionalNodes.append(studentChild['child']['key'])
                        totNoOfAdditionalNodes = totNoOfAdditionalNodes + 1
                        errorneousStudentNodes.append(
                            studentChild['child']['key'])
            elif len(matchedStudentLevelNodes) < len(teacherChildNodes):
                for studentChild in studentChildNodes:
                    if not studentChild['child'][
                            'key'] in matchedStudentLevelNodes and not studentChild[
                                'child']['key'] in errorneousStudentNodes:
                        addOrSubNodes.append(studentChild['child']['key'])
                        totNoOfOtherIncorrectNodes = totNoOfOtherIncorrectNodes + 1
                        errorneousStudentNodes.append(
                            studentChild['child']['key'])

            for teacherChild in teacherChildNodes:
                if not teacherChild['child']['key'] in matchedTeacherLevelNodes:
                    errorneousTeacherNodes.append(teacherChild['child']['key'])

        matchedTeacherLevelNodes = []
        matchedStudentLevelNodes = []

    # handles additional nodes down an additional node starting path
    if additionalNodes:
        totNoOfAdditionalNodes = detectUndetectedGates(
            "additionalNodes", graph, additionalNodes,
            matchedCompletedStudentNodes, totNoOfAdditionalNodes)

    # handles deleted nodes down a deleted node starting path
    if deletedNodes:
        totNoOfDeletedNodes = detectUndetectedGates(
            "deletedNodes", graph, deletedNodes, matchedCompletedTeacherNodes,
            totNoOfDeletedNodes)

    # handles substituted nodes down a substituted node starting path
    if substitutedNodes:
        totNoOfSubstitutedNodes = detectUndetectedGates(
            "substitutedNodes", graph, substitutedNodes,
            matchedCompletedTeacherNodes, totNoOfSubstitutedNodes)

    # handles additional/substituted nodes down a additional/substituted node starting path
    if addOrSubNodes:
        totNoOfOtherIncorrectNodes = detectUndetectedGates(
            "addOrSubNodes", graph, addOrSubNodes,
            matchedCompletedStudentNodes, totNoOfOtherIncorrectNodes)

    # handles deleted/substituted nodes down a deleted/substituted node starting path
    if delOrSubNodes:
        totNoOfOtherIncorrectNodes = detectUndetectedGates(
            "delOrSubNodes", graph, delOrSubNodes,
            matchedCompletedTeacherNodes, totNoOfOtherIncorrectNodes)


    if totNoOfAdditionalNodes == 0 and totNoOfDeletedNodes == 0 and totNoOfSubstitutedNodes == 0 and \
            totNoOfOtherIncorrectNodes == 0:
        feedback = feedback + "Excellent Job! All the inputs, gates, output, and the connections are correct! "

    feedback = feedback + "Please refer your answer diagram for feedback on where you went wrong. Green " +\
               "indicates correct gates and connections while Red indicates wrong gates and connections. " +\
               "Please note that any input(to a gate) connected to a wrong gate(a gate wbich has wrong " +\
               "connections even if the symbol is the same) is identified wrong by the system and in the highlighted gate feedback. "

    return matchedCompletedStudentNodes,  totNoOfAdditionalNodes, totNoOfDeletedNodes, \
           totNoOfSubstitutedNodes, totNoOfOtherIncorrectNodes, feedback, answerDiagramCorrect
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
Esempio n. 5
0
def markStudDFSBlockAnswer(processQuestionId, studentAnswerId):
    # Connect to Graph
    graph = connectToGraph()

    whiteSpaceTokenizer = py_stringmatching.WhitespaceTokenizer(
        return_set=True)
    jaccard = py_stringmatching.Jaccard()
    levenshtein = py_stringmatching.Levenshtein()

    teacherStartNodeKey = graph.data(
        "MATCH (node:Teacher) WHERE node.text='start' RETURN node.key")
    studentStartNodeKey = graph.data(
        "MATCH (node:Student) WHERE node.text='start' RETURN node.key")

    teachStack = [teacherStartNodeKey[0]['node.key']]
    studStack = [studentStartNodeKey[0]['node.key']]

    teachVisitedNodes = []
    studVisitedNodes = []

    # keeps track of the nodes matched in each level
    matchedTeacherNodes = []
    matchedStudentNodes = []

    notMatchedParentTeacherNodes = []

    # keeps track of all the nodes visited throughout graph traversal and a node is added to this each time it is visited
    allMatchedTeachNodes = []
    allMatchedStudNodes = []

    additionalNodes = []
    deletedNodes = []
    substitutedNodes = []
    addOrSubNodes = []
    delOrSubNodes = []

    totNoOfAdditionalNodes = 0
    totNoOfDeletedNodes = 0
    totNoOfSubstitutedNodes = 0
    totNoOfOtherIncorrectNodes = 0
    totNoOfOtherSubstitutedNodes = 0

    totNoOfMatchedNodes = 0

    feedback = ""

    while teachStack or studStack:

        if teachStack and studStack:

            teachCurrent = teachStack.pop()
            studCurrent = studStack.pop()

            teacherCurrentText = graph.data(
                "MATCH (node:Teacher) WHERE node.key= {key} RETURN node.text",
                parameters={"key": teachCurrent})

            studentCurrentText = graph.data(
                "MATCH (node:Student) WHERE node.key= {key} RETURN node.text",
                parameters={"key": studCurrent})

            teacherChildNodes = graph.data(
                "MATCH (parent:Teacher)-[:TO]->(child:Teacher) WHERE parent.key= {key} RETURN child",
                parameters={"key":
                            teachCurrent})  #teacherStartNodeKey[0]['node.key']

            studentChildNodes = graph.data(
                "MATCH (parent:Student)-[:TO]->(child:Student) WHERE parent.key= {key} RETURN child",
                parameters={"key":
                            studCurrent})  #studentStartNodeKey[0]['node.key']

            teachChildNodesList = list(teacherChildNodes)

            studChildNodesList = list(studentChildNodes)

            for teacherChild in teachChildNodesList:

                teachText = teacherChild['child']['text']
                # teachTextTokens = whiteSpaceTokenizer.tokenize(teacherChild['child']['text'])

                print(teachText)

                matchFound = 'false'

                for studentChild in studChildNodesList:
                    if not studentChild['child']['key'] in matchedStudentNodes:
                        print('current stud child')
                        print(studentChild['child']['text'])
                        childText = studentChild['child']['text']

                        synsetSim_score = getPhraseSimilarity(
                            teachText, childText)

                        if re.match(teachText, childText,
                                    re.IGNORECASE) or synsetSim_score >= 0.55:
                            print(
                                'threshold similarity added to Student stack')

                            feedback = feedback + 'The block:' + studentChild['child']['text'] + \
                                       ' connected to block:' + studentCurrentText[0]['node.text'] + ' is correct. '

                            matchFound = 'true'

                            if not teacherChild['child'][
                                    'key'] in teachVisitedNodes:
                                studStack.append(studentChild['child']['key'])

                                teachStack.append(teacherChild['child']['key'])

                                if not studentChild['child'][
                                        'key'] in allMatchedStudNodes and not studentChild[
                                            'child']['text'] == 'end':
                                    totNoOfMatchedNodes = totNoOfMatchedNodes + 1

                                allMatchedTeachNodes.append(
                                    teacherChild['child']['key'])
                                allMatchedStudNodes.append(
                                    studentChild['child']['key'])

                            if len(teachChildNodesList) > len(
                                    studChildNodesList):
                                matchedTeacherNodes.append(
                                    teacherChild['child']['key'])

                                # add to student matched node set too to check while looping through the current level children (above)
                                matchedStudentNodes.append(
                                    studentChild['child']['key'])
                            elif len(teachChildNodesList) < len(
                                    studChildNodesList):
                                matchedStudentNodes.append(
                                    studentChild['child']['key'])
                            else:
                                matchedStudentNodes.append(
                                    studentChild['child']['key'])

                            break

                if matchFound == 'false' and not teacherChild['child'][
                        'key'] in teachVisitedNodes:  # len(teachChildNodesList) == len(studChildNodesList) and
                    notMatchedParentTeacherNodes.append(
                        teacherChild['child']['key'])
                elif matchFound == 'false' and teacherChild['child'][
                        'key'] in teachVisitedNodes:
                    feedback = feedback + 'The block:' + teacherChild['child']['text'] + \
                               ' should be connected to block:' + teacherCurrentText[0]['node.text'] + '. '
                    totNoOfOtherIncorrectNodes = totNoOfOtherIncorrectNodes + 1

            if len(teachChildNodesList) == len(studChildNodesList) and len(
                    notMatchedParentTeacherNodes) == 1:

                print('^^^ONE SUBSTITUTED NODE')

                totNoOfSubstitutedNodes, totNoOfOtherIncorrectNodes, feedback = \
                    addTheOnlyUnmatchedNode('NotMatchedNode', graph, notMatchedParentTeacherNodes,
                                        teachStack, studChildNodesList, matchedStudentNodes,
                                        studStack, totNoOfSubstitutedNodes, feedback, studVisitedNodes,
                                        teachCurrent, studentCurrentText[0]['node.text'], totNoOfOtherIncorrectNodes)

            elif len(teachChildNodesList) == len(studChildNodesList) and len(
                    notMatchedParentTeacherNodes) > 1:

                totNoOfSubstitutedNodes = totNoOfSubstitutedNodes + len(
                    notMatchedParentTeacherNodes)

                againNotMatchedTeacherNodes, handledStudentNodeList, feedback = checkForCurrentNodeChildMatch(
                    'substitutedCaller', graph, matchedStudentNodes,
                    notMatchedParentTeacherNodes, studChildNodesList,
                    studVisitedNodes, studStack, teachStack, feedback,
                    studentCurrentText[0]['node.text'])

                if len(againNotMatchedTeacherNodes) == 1:
                    totNoOfOtherIncorrectNodes, feedback = addTheOnlyUnmatchedNode(
                        'NotMatchedChildrenNode', graph,
                        againNotMatchedTeacherNodes, teachStack,
                        studChildNodesList, handledStudentNodeList, studStack,
                        totNoOfSubstitutedNodes, feedback, studVisitedNodes,
                        teachCurrent, studentCurrentText[0]['node.text'],
                        totNoOfOtherIncorrectNodes)

                elif len(againNotMatchedTeacherNodes) > 1:
                    for studentChild in studChildNodesList:
                        if not studentChild['child'][
                                'key'] in handledStudentNodeList and not studentChild[
                                    'child']['key'] in studVisitedNodes:
                            feedback = feedback + 'The block:' + studentChild['child']['text'] + \
                                               ' connected to block:' + studentCurrentText[0]['node.text'] + ' is substituted, and it '

                            for againNotTeacherNode in againNotMatchedTeacherNodes:
                                teacherNodeText = graph.data(
                                    "MATCH (node:Teacher) WHERE node.key= {key} RETURN node.text",
                                    parameters={"key": againNotTeacherNode})

                                feedback = feedback + ' should be:' + teacherNodeText[
                                    0]['node.text'] + ' or'

                            feedback = feedback + ' one of the mentioned blocks. The immediate blocks that follow ' +\
                                       'this block:' + studentChild['child']['text'] + ' are also wrong. Please check them. '

                            substitutedNodes.append(
                                studentChild['child']['key'])

            # handles scenario where student graph has deleted child nodes for the current node under consideration
            if len(teachChildNodesList) > len(studChildNodesList):
                totNoOfDeletedNodes = totNoOfDeletedNodes + (
                    len(teachChildNodesList) - len(studChildNodesList))

                if len(matchedStudentNodes) == len(studChildNodesList):
                    for child in teachChildNodesList:
                        if not child['child'][
                                'key'] in matchedTeacherNodes and not child[
                                    'child']['key'] in teachVisitedNodes:
                            feedback = feedback + 'Missing Block:' + child['child']['text'] + \
                                               ' should be connected to block:' + studentCurrentText[0]['node.text'] + '. '
                            deletedNodes.append(child['child']['key'])
                elif len(matchedStudentNodes) < len(studChildNodesList):
                    feedback = feedback + 'There is/are ' + str(len(teachChildNodesList) - len(studChildNodesList)) + \
                               ' missing block(s) that should be connected to block:' + studentCurrentText[0]['node.text'] + \
                               ' and ' + str(len(studChildNodesList) - len(matchedStudentNodes)) + \
                               ' block(s) connected to block:' + studentCurrentText[0]['node.text'] + \
                               ' is/are substituted - The incorrect blocks are '

                    againNotMatchedTeacherNodes, handledStudentNodeList, feedback = checkForCurrentNodeChildMatch(
                        'deletedSubstitutedCaller', graph, matchedStudentNodes,
                        notMatchedParentTeacherNodes, studChildNodesList,
                        studVisitedNodes, studStack, teachStack, feedback,
                        studentCurrentText[0]['node.text'])

                    if len(handledStudentNodeList) == len(studChildNodesList):
                        for child in teachChildNodesList:
                            if child['child'][
                                    'key'] in againNotMatchedTeacherNodes and not child[
                                        'child']['key'] in teachVisitedNodes:
                                feedback = feedback + 'block:' + child['child']['text'] + \
                                           ' that should be connected to block:' + studentCurrentText[0]['node.text'] +\
                                           ' is missing and '
                                deletedNodes.append(child['child']['key'])

                    elif len(handledStudentNodeList) < len(studChildNodesList):
                        for child in teachChildNodesList:
                            if child['child'][
                                    'key'] in againNotMatchedTeacherNodes and not child[
                                        'child']['key'] in teachVisitedNodes:
                                feedback = feedback + ' block:' + child['child']['text'] + \
                                           ' that should be/is connected to block:' + studentCurrentText[0]['node.text'] + \
                                           ' is deleted/substituted and the immediate child blocks of this block are also wrong, please check them, and '

                                delOrSubNodes.append(child['child']['key'])

                    feedback = feedback + 'please check all these incorrect blocks. '

            # handles scenario where student graph has additional child nodes for the current node under consideration
            elif len(teachChildNodesList) < len(studChildNodesList):
                totNoOfAdditionalNodes = totNoOfAdditionalNodes + (
                    len(studChildNodesList) - len(teachChildNodesList))

                # handles scenario where all teacher nodes are matched and there are additional nodes
                if len(matchedStudentNodes) == len(teachChildNodesList):
                    for child in studChildNodesList:
                        if not child['child'][
                                'key'] in matchedStudentNodes and not child[
                                    'child']['key'] in studVisitedNodes:
                            feedback = feedback + 'Additional Block:' + child['child']['text'] +\
                                       ' is connected to block:' + studentCurrentText[0]['node.text'] + '. '
                            additionalNodes.append(child['child']['key'])
                        elif not child['child'][
                                'key'] in matchedStudentNodes and child[
                                    'child']['key'] in studVisitedNodes:
                            feedback = feedback + 'Additional connection from block:' + studentCurrentText[0]['node.text'] +\
                                       ' to block:' + child['child']['text'] + '. '
                elif len(matchedStudentNodes) < len(teachChildNodesList):
                    feedback = feedback + 'There is/are ' + str(len(studChildNodesList) - len(teachChildNodesList)) + \
                               ' additional block(s) connected to block:' + studentCurrentText[0]['node.text'] + ' and ' +\
                               str(len(teachChildNodesList) - len(matchedStudentNodes)) +\
                               ' block(s) connected to block:' + studentCurrentText[0]['node.text'] + ' is/are substituted - The incorrect blocks are '

                    againNotMatchedTeacherNodes, handledStudentNodeList, feedback = checkForCurrentNodeChildMatch(
                        'additionalSubstitutedCaller', graph,
                        matchedStudentNodes, notMatchedParentTeacherNodes,
                        studChildNodesList, studVisitedNodes, studStack,
                        teachStack, feedback,
                        studentCurrentText[0]['node.text'])

                    if len(handledStudentNodeList) == len(
                            teachChildNodesList
                    ):  # len(againNotMatchedTeacherNodes) == (len(studChildNodesList)-len(teachChildNodesList))
                        for child in studChildNodesList:
                            if not child['child'][
                                    'key'] in handledStudentNodeList and not child[
                                        'child']['key'] in studVisitedNodes:
                                feedback = feedback + 'block:' + child['child']['text'] + ' connected to block:' +\
                                           studentCurrentText[0]['node.text'] + ' is additional and '
                                additionalNodes.append(child['child']['key'])

                    elif len(handledStudentNodeList) < len(
                            teachChildNodesList
                    ):  # len(againNotMatchedTeacherNodes) > (len(studChildNodesList)-len(teachChildNodesList))
                        for child in studChildNodesList:
                            if not child['child'][
                                    'key'] in handledStudentNodeList and not child[
                                        'child']['key'] in studVisitedNodes:
                                feedback = feedback + ' block: ' + child['child']['text'] + ' connected to block:' +\
                                           studentCurrentText[0]['node.text'] +\
                                ' is additional/substituted and the immediate child blocks of this block are also wrong, please check them, and '

                                addOrSubNodes.append(child['child']['key'])

                    feedback = feedback + 'please check all these incorrect blocks. '

            matchedTeacherNodes = []
            matchedStudentNodes = []

            notMatchedParentTeacherNodes = []

            teachVisitedNodes.append(teachCurrent)
            studVisitedNodes.append(studCurrent)

        elif studStack and not teachStack:
            print('^^^^^^^^^^^^^^^STUDENT stack has moreeee.....')
            break

    # handles additional nodes down an additional node starting path
    if additionalNodes:
        feedback, totNoOfAdditionalNodes = detectUndetectedBlocks(
            "additionalNodes", graph, additionalNodes, studVisitedNodes,
            feedback, totNoOfAdditionalNodes)

    # handles deleted nodes down a deleted node starting path
    if deletedNodes:
        feedback, totNoOfDeletedNodes = detectUndetectedBlocks(
            "deletedNodes", graph, deletedNodes, teachVisitedNodes, feedback,
            totNoOfDeletedNodes)

    # handles substituted nodes down a substituted node starting path
    if substitutedNodes:
        feedback, totNoOfOtherSubstitutedNodes = detectUndetectedBlocks(
            "substitutedNodes", graph, substitutedNodes, studVisitedNodes,
            feedback, totNoOfOtherSubstitutedNodes)

    # handles additional/substituted nodes down a additional/substituted node starting path
    if addOrSubNodes:
        feedback, totNoOfOtherIncorrectNodes = detectUndetectedBlocks(
            "addOrSubNodes", graph, addOrSubNodes, studVisitedNodes, feedback,
            totNoOfOtherIncorrectNodes)

    # handles deleted/substituted nodes down a deleted/substituted node starting path
    if delOrSubNodes:
        feedback, totNoOfOtherIncorrectNodes = detectUndetectedBlocks(
            "delOrSubNodes", graph, delOrSubNodes, teachVisitedNodes, feedback,
            totNoOfOtherIncorrectNodes)




    if totNoOfAdditionalNodes == 0 and totNoOfDeletedNodes == 0 and totNoOfSubstitutedNodes == 0 and \
            totNoOfOtherSubstitutedNodes == 0 and totNoOfOtherIncorrectNodes == 0:
        print(totNoOfMatchedNodes)
        feedback = feedback + "Excellent Job! All the blocks and the flow are correct!"  # Number of correct blocks: " + ". "
        print(feedback)
    else:
        feedback = feedback + "Number of correct blocks except start and end blocks: " + str(
            totNoOfMatchedNodes) + ". "
        print(feedback)

    allocateMarksAndSaveToDatabase(totNoOfMatchedNodes, totNoOfAdditionalNodes,
                                   totNoOfDeletedNodes,
                                   totNoOfSubstitutedNodes,
                                   totNoOfOtherSubstitutedNodes,
                                   totNoOfOtherIncorrectNodes, feedback,
                                   processQuestionId, studentAnswerId)
def runDFSAndAddStatementToPyFile(studentAnswerFile):
    # Connect to Graph
    graph = connectToGraph()

    studentStartNodeKey = graph.data(
        "MATCH (node:Student) WHERE node.symbol='Start' RETURN node.key")

    stack = [studentStartNodeKey[0]['node.key']]

    visitedNodes = []

    outputVariableNames = []

    currentStructure = ""

    # maintains common nodes in paths for all if structures
    commonNodes = []

    # maintain all nodes traversed and visited including ones not completed analyzing
    traversedNodes = []

    # this dictionary has keys which are the node keys of ifs under analysis until main if path is joined and values are
    # an indication of the number of times the path joining node must be visited to continue and further reduce the
    # indentation. Yes path will have it corresponding values because yes is analyzed first while no path will have the
    # summation of yes completed ones and the corresponding no path ifs, yes has already been traversed, and that many
    # has to be traversed by the time of no path unindentations.
    ifDictionary = {}

    # maintains if node keys for if-else structures
    ifNodes = []

    doWhileNodes = []

    whileNodes = []

    mainIfCompletedNoOfPaths = 0

    indent = 0

    while stack:
        currentNode = stack.pop()

        traversedNodes.append(currentNode)

        continueWithFlow = 'false'

        if not commonNodes:
            continueWithFlow = 'true'

        while commonNodes:
            currentCommonNode = commonNodes.pop()

            if currentNode == currentCommonNode:
                indent = indent - 1

                currentIfKey = ifNodes.pop()

                if traversedNodes.count(currentNode) < ifDictionary.get(
                        currentIfKey, "none"):
                    commonNodes.append(currentCommonNode)
                    ifNodes.append(currentIfKey)
                    break
                elif traversedNodes.count(currentNode) == ifDictionary.get(
                        currentIfKey, "none"):
                    continueWithFlow = 'true'

                    if not currentNode in commonNodes:
                        traversedNodes[:] = (key for key in traversedNodes
                                             if key != currentNode)
                        traversedNodes.append(currentNode)

                    continue
            else:
                continueWithFlow = 'true'
                commonNodes.append(currentCommonNode)
                break

        if not commonNodes:
            ifDictionary = {}
            ifNodes = []
            mainIfCompletedNoOfPaths = 0

        if continueWithFlow == "true":
            currentNodeInfo = graph.data(
                "MATCH (node:Student) WHERE node.key= {key} RETURN node",
                parameters={"key": currentNode})

            currentSymbol = currentNodeInfo[0]['node']['symbol']
            currentText = currentNodeInfo[0]['node']['text']

            currentNodeParents = graph.data(
                "MATCH (parent:Student)-[]->(child:Student) WHERE child.key= {key} RETURN parent",
                parameters={"key": currentNode})

            if indent > 0:
                if doWhileNodes and not whileNodes:
                    if not doWhileNodes[-1] == currentNode:
                        indentLine(indent, studentAnswerFile)
                elif whileNodes and not doWhileNodes:
                    if not whileNodes[-1] == currentNode:
                        indentLine(indent, studentAnswerFile)
                elif doWhileNodes and whileNodes:
                    if not (doWhileNodes[-1] == currentNode
                            or whileNodes[-1] == currentNode):
                        indentLine(indent, studentAnswerFile)
                else:
                    indentLine(indent, studentAnswerFile)

            if currentSymbol == "Input":
                if '\'' in currentText:
                    words = re.split("[,]+", currentText)
                else:
                    words = re.split("[, ]+", currentText)

                for word in words:
                    if not (re.match("input", word, re.IGNORECASE)
                            or re.match("enter", word, re.IGNORECASE)
                            or re.match("read", word, re.IGNORECASE)
                            or '\'' in word or not word):
                        variable = word.strip()  #.replace(",", "")
                        studentAnswerFile.write(
                            variable + " = float(str(sys.argv[argCount]))\n")
                        if indent > 0:
                            indentLine(indent, studentAnswerFile)
                        studentAnswerFile.write("argCount = argCount + 1\n")

            elif currentSymbol == "Process":
                studentAnswerFile.write(currentText + "\n")
            elif currentSymbol == "Output":
                if '+' in currentText and '\'' in currentText:
                    words = re.split("[+,]+", currentText)
                elif ',' in currentText and '\'' in currentText and not '+' in currentText:
                    words = re.split("[,]+", currentText)
                elif '\'' in currentText and not (',' in currentText
                                                  or '+' in currentText):
                    words = re.split("[']+", currentText)
                else:
                    words = re.split("[, ]+", currentText)

                print(words)

                for wordSet in words:
                    if not (re.search("output", wordSet, re.IGNORECASE)
                            or re.search("display", wordSet, re.IGNORECASE)
                            or re.search("print", wordSet, re.IGNORECASE)
                            or '\'' in wordSet or not wordSet):
                        variable = wordSet.strip()
                        # + or , means there is a variable
                        if ',' in currentText or '+' in currentText:
                            # output has numeric variables
                            outputVariableNames.append(variable)
                            studentAnswerFile.write("print(" + "str(" +
                                                    variable + ")" + ")\n")
                        elif not (',' in currentText or '+'
                                  in currentText) and '\'' in currentText:
                            # output is just one string value
                            studentAnswerFile.write("print('" + variable +
                                                    "')\n")
                        else:
                            # output has numeric variable
                            outputVariableNames.append(variable)
                            studentAnswerFile.write("print(" + "str(" +
                                                    variable + ")" + ")\n")

            elif currentSymbol == "Decision":
                yesCurrentChildNode = graph.data(
                    "MATCH (parent:Student)-[:YES]->(child:Student) WHERE parent.key= {key} RETURN child",
                    parameters={"key": currentNode})

                yesChildParents = graph.data(
                    "MATCH (parent:Student)-[]->(child:Student) WHERE child.key= {key} RETURN parent",
                    parameters={"key": yesCurrentChildNode[0]['child']['key']})

                noCurrentChildNode = graph.data(
                    "MATCH (parent:Student)-[:NO]->(child:Student) WHERE parent.key= {key} RETURN child",
                    parameters={"key": currentNode})

                noChildParents = graph.data(
                    "MATCH (parent:Student)-[]->(child:Student) WHERE child.key= {key} RETURN parent",
                    parameters={"key": noCurrentChildNode[0]['child']['key']})

                doWhileFound = "false"

                unindentWhile = "false"

                if ((yesCurrentChildNode[0]['child']['key'] in visitedNodes or noCurrentChildNode[0]['child']['key'] in visitedNodes) \
                                        and traversedNodes.count(currentNode) == 1) or currentNode in doWhileNodes:
                    doWhileFound = "true"

                    if yesCurrentChildNode[0]['child']['key'] in visitedNodes:
                        whileOrNot = "while "
                        if traversedNodes.count(currentNode) == 1:
                            whileNextNode = yesCurrentChildNode[0]['child'][
                                'key']
                        elif traversedNodes.count(currentNode) > 1:
                            whileNextNode = noCurrentChildNode[0]['child'][
                                'key']
                    elif noCurrentChildNode[0]['child']['key'] in visitedNodes:
                        whileOrNot = "while not "
                        if traversedNodes.count(currentNode) == 1:
                            whileNextNode = noCurrentChildNode[0]['child'][
                                'key']
                        elif traversedNodes.count(currentNode) > 1:
                            whileNextNode = yesCurrentChildNode[0]['child'][
                                'key']

                    currentStructure = "DoWhile"

                    line, indent, unindentWhile, traversedNodes = handleWhileTypeConversions(
                        currentStructure, stack, whileNextNode, traversedNodes,
                        currentNode, indent, unindentWhile, whileOrNot,
                        currentText, doWhileNodes, visitedNodes)

                else:
                    if (len(whileNodes) == 0 and traversedNodes.count(currentNode) == 1) or \
                            (len(whileNodes) == 1 and traversedNodes.count(currentNode) == 2):
                        loopPath = graph.data(
                            "MATCH (currentNode:Student)-[r:YES|NO]->(nextNode:Student)-[*]->"
                            +
                            "(currentNode:Student) WHERE currentNode.key = {currentNodeKey} RETURN DISTINCT TYPE(r)",
                            parameters={"currentNodeKey": currentNode})
                    elif (len(whileNodes) == 1 and traversedNodes.count(currentNode) == 1) or \
                            (len(whileNodes) == 2 and traversedNodes.count(currentNode) == 2):
                        loopPath = graph.data(
                            "MATCH path = (currentNode:Student)-[r:YES|NO]->(nextNode:Student)-[*]->"
                            "(currentNode:Student) WHERE currentNode.key = {currentNodeKey} "
                            "WITH path, r MATCH (previousIfNode: Student) WHERE previousIfNode.key = "
                            "{previousIfNodeKey} AND NOT previousIfNode IN NODES(path) RETURN TYPE(r)",
                            parameters={
                                "currentNodeKey": currentNode,
                                "previousIfNodeKey": whileNodes[0]
                            })
                    elif (len(whileNodes) == 2 and traversedNodes.count(currentNode) == 1) or \
                            (len(whileNodes) == 3 and traversedNodes.count(currentNode) == 2):
                        loopPath = graph.data(
                            "MATCH path = (currentNode:Student)-[r:YES|NO]->(nextNode:Student)-[*]->"
                            "(currentNode:Student) WHERE currentNode.key = {currentNodeKey} "
                            "WITH path, r MATCH (previousIfNodeOne: Student), "
                            "(previousIfNodeTwo: Student) WHERE (previousIfNodeOne.key = "
                            "{previousIfNodeOneKey} AND NOT previousIfNodeOne IN NODES(path)) AND "
                            "(previousIfNodeTwo.key = {previousIfNodeTwoKey} AND NOT previousIfNodeTwo "
                            "IN NODES(path)) RETURN TYPE(r)",
                            parameters={
                                "currentNodeKey": currentNode,
                                "previousIfNodeOneKey": whileNodes[0],
                                "previousIfNodeTwoKey": whileNodes[1]
                            })

                    if not loopPath:
                        line, currentStructure, mainIfCompletedNoOfPaths = handleIfTypeConversions(
                            graph, stack, currentNode, traversedNodes,
                            noChildParents, yesChildParents,
                            noCurrentChildNode, yesCurrentChildNode,
                            currentText, commonNodes, ifNodes, ifDictionary,
                            visitedNodes, mainIfCompletedNoOfPaths)
                    else:
                        if commonNodes or whileNodes or doWhileNodes:
                            if (len(whileNodes) == 0 and traversedNodes.count(currentNode) == 1) or \
                                    (len(whileNodes) == 1 and traversedNodes.count(currentNode) == 2) or \
                                    (len(whileNodes) == 0 and traversedNodes.count(currentNode) == 2):
                                loopPathLength = graph.data(
                                    "MATCH path = (currentNode:Student)-[r:YES|NO]->(nextNode:Student)-[*]->"
                                    +
                                    "(currentNode:Student) WHERE currentNode.key = "
                                    + "{currentNodeKey} RETURN length(path)",
                                    parameters={"currentNodeKey": currentNode})
                            elif (len(whileNodes) == 1 and traversedNodes.count(currentNode) == 1) or \
                                    (len(whileNodes) == 2 and traversedNodes.count(currentNode) == 2):
                                loopPathLength = graph.data(
                                    "MATCH path = (currentNode:Student)-[r:YES|NO]->(nextNode:Student)-[*]->"
                                    +
                                    "(currentNode:Student) WHERE currentNode.key = {currentNodeKey} WITH path, r "
                                    +
                                    "MATCH (previousIfNode:Student) WHERE previousIfNode.key = {previousIfNodeKey} "
                                    +
                                    "AND NOT previousIfNode IN NODES(path) RETURN length(path)",
                                    parameters={
                                        "currentNodeKey": currentNode,
                                        "previousIfNodeKey": whileNodes[0]
                                    })
                            elif (len(whileNodes) == 2 and traversedNodes.count(currentNode) == 1) or \
                                    (len(whileNodes) == 3 and traversedNodes.count(currentNode) == 2):
                                loopPathLength = graph.data(
                                    "MATCH path = (currentNode:Student)-[r:YES|NO]->(nextNode:Student)-[*]->"
                                    +
                                    "(currentNode:Student) WHERE currentNode.key = {currentNodeKey} WITH path, r "
                                    + "MATCH (previousIfNodeOne:Student), "
                                    "(previousIfNodeTwo:Student) WHERE (previousIfNodeOne.key = "
                                    "{previousIfNodeOneKey} AND NOT previousIfNodeOne IN NODES(path)) AND "
                                    "(previousIfNodeTwo.key = {previousIfNodeTwoKey} AND NOT previousIfNodeTwo "
                                    "IN NODES(path)) RETURN length(path)",
                                    parameters={
                                        "currentNodeKey": currentNode,
                                        "previousIfNodeOneKey": whileNodes[0],
                                        "previousIfNodeTwoKey": whileNodes[1]
                                    })

                            curCommonNodePathLength = graph.data(
                                "MATCH path1 = (currentDecision:Student)-[:YES]->(a:Student)-[*]->(commonNode:Student), "
                                +
                                "path2 = (currentDecision:Student)-[:NO]->(b:Student)-[*]->"
                                +
                                "(commonNode:Student) WHERE currentDecision.key={currentNodeKey} and path1 <> path2 "
                                +
                                "and currentDecision <> commonNode RETURN length(path2)",
                                parameters={"currentNodeKey": currentNode})

                            if not curCommonNodePathLength:
                                curCommonNodePathLength = graph.data(
                                    "MATCH path1 = (currentDecision:Student)-[:YES]->(a:Student)-[*]->"
                                    +
                                    "(commonNode:Student), path2 = (currentDecision:Student)-[:NO]->"
                                    +
                                    "(commonNode:Student) WHERE currentDecision.key={currentNodeKey} and "
                                    +
                                    "path1 <> path2 and currentDecision <> commonNode RETURN length(path2)",
                                    parameters={"currentNodeKey": currentNode})

                            if not curCommonNodePathLength:
                                curCommonNodePathLength = graph.data(
                                    "MATCH path1 = (currentDecision:Student)-[:YES]->(commonNode:Student), "
                                    +
                                    "path2 = (currentDecision:Student)-[:NO]->(b:Student)-[*]->(commonNode:Student) "
                                    +
                                    "WHERE currentDecision.key={currentNodeKey} and path1 <> path2 and "
                                    +
                                    "currentDecision <> commonNode RETURN length(path1)",
                                    parameters={"currentNodeKey": currentNode})

                            if not curCommonNodePathLength:
                                whileOrNot, whileNextNode, currentStructure = handleWhileTraversal(
                                    loopPath, traversedNodes, currentNode,
                                    yesCurrentChildNode, noCurrentChildNode)

                                line, indent, unindentWhile, traversedNodes = handleWhileTypeConversions(
                                    currentStructure, stack, whileNextNode,
                                    traversedNodes, currentNode, indent,
                                    unindentWhile, whileOrNot, currentText,
                                    whileNodes, visitedNodes)
                            elif not loopPathLength:
                                line, currentStructure, mainIfCompletedNoOfPaths = handleIfTypeConversions(
                                    graph, stack, currentNode, traversedNodes,
                                    noChildParents, yesChildParents,
                                    noCurrentChildNode, yesCurrentChildNode,
                                    currentText, commonNodes, ifNodes,
                                    ifDictionary, visitedNodes,
                                    mainIfCompletedNoOfPaths)
                            else:
                                if loopPathLength[0][
                                        'length(path)'] > curCommonNodePathLength[
                                            0]['length(path2)']:
                                    line, currentStructure, mainIfCompletedNoOfPaths = handleIfTypeConversions(
                                        graph, stack, currentNode,
                                        traversedNodes, noChildParents,
                                        yesChildParents, noCurrentChildNode,
                                        yesCurrentChildNode, currentText,
                                        commonNodes, ifNodes, ifDictionary,
                                        visitedNodes, mainIfCompletedNoOfPaths)
                                else:
                                    whileOrNot, whileNextNode, currentStructure = handleWhileTraversal(
                                        loopPath, traversedNodes, currentNode,
                                        yesCurrentChildNode,
                                        noCurrentChildNode)

                                    line, indent, unindentWhile, traversedNodes = handleWhileTypeConversions(
                                        currentStructure, stack, whileNextNode,
                                        traversedNodes, currentNode, indent,
                                        unindentWhile, whileOrNot, currentText,
                                        whileNodes, visitedNodes)
                        else:
                            whileOrNot, whileNextNode, currentStructure = handleWhileTraversal(
                                loopPath, traversedNodes, currentNode,
                                yesCurrentChildNode, noCurrentChildNode)

                            line, indent, unindentWhile, traversedNodes = handleWhileTypeConversions(
                                currentStructure, stack, whileNextNode,
                                traversedNodes, currentNode, indent,
                                unindentWhile, whileOrNot, currentText,
                                whileNodes, visitedNodes)

                if unindentWhile == "false":
                    studentAnswerFile.write(line + "\n")
                    indent = indent + 1

            if not (currentSymbol == "Decision" or currentSymbol == 'End'):
                currentChildNodes = graph.data(
                    "MATCH (parent:Student)-[:TO]->(child:Student) WHERE parent.key= {key} RETURN child",
                    parameters={"key": currentNode})

                stack.append(currentChildNodes[0]['child']['key'])
                visitedNodes.append(currentNode)

    return outputVariableNames