예제 #1
0
def binaryTree(student_answer, downwards):
    if downwards == "top":
        down = True
    elif downwards == "bottom":
        down = False
    else:
        raise Exception('Unknown parameter value supplied. Contact support.')

    root = 0
    for v in student_answer.vs:
        split = splitParentChildren(v, down)
        if split == None:
            return {'correct': False, 'feedback': 'same height of nodes'}
        (par, chil) = split
        if len(par) > 1:
            return {
                'correct': False,
                'feedback': 'too many parents',
                'vertexLabel': filter_orig_name(v)
            }
        elif len(par) == 0:
            root += 1
        if len(chil) > 2:
            return {
                'correct': False,
                'feedback': 'too many children',
                'vertexLabel': filter_orig_name(v)
            }
    if root > 1:
        return {'correct': False, 'feedback': 'too many roots'}
    return {'correct': True}
예제 #2
0
def inLeaf(student_answer, labels, downwards):
    if downwards == "top":
        down = True
    elif downwards == "bottom":
        down = False
    else:
        raise Exception('Unknown parameter value supplied. Contact support.')

    for v in student_answer.vs:
        v_orig = filter_orig_name(v)
        if v_orig in labels:
            split = splitParentChildren(v, down)
            if split == None:
                return None
            (par, chil) = split
            if len(chil) != 0:
                return {
                    'correct': False,
                    'feedback': 'not in leaf',
                    'element': v_orig
                }
            labels.remove(v_orig)
    if (len(labels) != 0):
        return {
            'correct': False,
            'feedback': "missing element",
            'exampleElement': labels[0]
        }
    else:
        return {'correct': True}
def heap_layout(student_answer):
    #find the root
    #throw error if there is more than one root, or if a node has multiple parents
    root = findRoot(student_answer, True)
    
    #check if a problem was encountered
    if (root == None):
        return {'correct': False,
                'feedback': 'layout problem'}
    layer = [root]
    nextLayer = []
    noMoreChildren = False
    while len(layer) > 0:
        for v in layer:
            value = splitParentChildren(v, True)
            if (value == None):
                return {'correct': False,
                        'feedback': 'There is a problem with the layout that makes distinguishing the heap impossible.'}
            (par, chil) = value
            if noMoreChildren and len(chil) > 0:
                return {'correct': False,
                        'feedback': 'level incorrect'}
            if (len(chil) > 2):
                return {'correct': False,
                        'feedback': 'too many children',
                        'vertexLabel': filter_orig_name(v),
                       }
            elif len(chil) == 1:
                if chil[0]['x'] > v['x']:
                    return {'correct': False,
                            'feedback': 'missing left child',
                            'vertexLabel': filter_orig_name(v)
                           }
                noMoreChildren = True
            elif len(chil) == 0:
                noMoreChildren = True
            else:
                left_child = chil[0]
                right_child = chil[1]
                if left_child["x"] > right_child["x"]:
                    left_child  = chil[1]
                    right_child = chil[0]
                nextLayer.append(left_child)
                nextLayer.append(right_child)
        layer = nextLayer
        nextLayer = []
    return {'correct': True}
def check_heap_structure(student_answer, comparator, textual):
    #for each node, check that the children are smaller or equally large as the parent
    for v in student_answer.vs:
        split = splitParentChildren(v, True)
        if (split == None):
            return {'correct': False,
                    'feedback': 'layout problem'}
        (par, chil) = split
        valueV = int(filter_orig_name(v))
        for w in chil:
            valueW = int(filter_orig_name(w))
            if comparator(valueV, valueW):
                return {'correct': False,
                        'feedback': 'child parent wrong',
                        'vertexLabel1': filter_orig_name(v),
                        'greater_smaller': textual,
                        'vertexLabel2': filter_orig_name(w)}
    return {'correct': True}
예제 #5
0
def traverse(node, labels, downwards):
    exc = None
    (left, right) = children(node, downwards)
    if (not left == None):
        (labels, exc) = traverse(left, labels, downwards)
    if (len(labels) == 0):
        return (labels, {'correct': False, "feedback": "too many nodes"})
    if (filter_orig_name(node) == str(labels[0])):
        labels.pop(0)
    else:
        return (labels, {
            'correct': False,
            "feedback": "mismatched labels",
            "vertexLabel": filter_orig_name(node),
            "expectedLabel": labels[0]
        })
    if (not right == None):
        (labels, exc) = traverse(right, labels, downwards)
    return (labels, exc)
예제 #6
0
def same_highlights(student_answer, expected):
    if not student_answer.isomorphic(expected):
        return {'correct': False, 'feedback': 'not isomorphic graphs'}
    #inefficient
    for v in student_answer.vs:
        vName = filter_orig_name(v)
        for w in expected.vs:
            wName = filter_orig_name(w)
            if vName == wName:
                if v['highlighted'] != w['highlighted']:
                    return {
                        'correct': False,
                        'feedback': 'highlighted vertices mismatched'
                    }
                break
    for e in student_answer.es:
        eSource = filter_orig_name(student_answer.vs[e.source])
        eTarget = filter_orig_name(student_answer.vs[e.target])
        for f in expected.es:
            fSource = filter_orig_name(expected.vs[f.source])
            fTarget = filter_orig_name(expected.vs[f.target])
            if (eSource == fSource
                    and eTarget == fTarget) or (eSource == fTarget
                                                and eTarget == fSource):
                if e['highlighted'] != f['highlighted']:
                    return {
                        'correct': False,
                        'feedback': 'highlighted edges mismatched'
                    }
                break

    return {'correct': True}
def coloring(student_answer, noColors):
    colors = set()
    for v in student_answer.vs:
        colors.add(v['color'])
        for w in student_answer.neighbors(v):
            wVert = student_answer.vs[w]
            if wVert['color'] == v['color']:
                return {
                    'correct':
                    False,
                    'feedback':
                    'Vertices \'{0}\' en \'{1}\' are adjacent and have the same color.'
                    .format(filter_orig_name(v), filter_orig_name(wVert))
                }
    if len(colors) > noColors:
        return {
            'correct': False,
            'feedback': 'color count wrong',
            'colorCount': len(colors),
            'expectedColorCount': noColors
        }
    return {'correct': True}
예제 #8
0
def binarySearchTree(student_answer, downwards):
    bTree = binaryTree(student_answer, downwards)
    if not bTree['correct']:
        return bTree

    labels = []
    for v in student_answer.vs:
        try:
            label = filter_orig_name(v)
            labels.append(int(label))
        except:
            return {
                'correct': False,
                'feedback': 'label not numerical',
                'vertexLabel': filter_orig_name(v)
            }

    labels.sort()
    iOrder = inOrderTraversal(student_answer, labels, downwards)
    if not iOrder['correct']:
        return {'correct': False, 'feedback': 'not sorted order'}
    else:
        return {'correct': True}
def vertex_degree_at_most(student_answer, max_degree):
    for v in student_answer.vs:
        if v.degree() > max_degree:
            v_name = filter_orig_name(v)
            if not v_name:
                v_name = '-no label-'
            return {
                'correct': False,
                'feedback': 'max degree too high',
                'vertexLabel': v_name,
                'vertexDegree': v.degree(),
                'maxDegree': max_degree
            }
    return {'correct': True}
예제 #10
0
def nodeDepth(student_answer, label, depth, downwards):
    if downwards == "top":
        down = True
    elif downwards == "bottom":
        down = False
    else:
        raise Exception('Unknown parameter value supplied. Contact support.')

    for v in student_answer.vs:
        if filter_orig_name(v) == label:
            vertex = v
            dep = 0
            while not v == None:
                split = splitParentChildren(v, down)
                if split == None:
                    return {'correct': False, 'feedback': 'layout problem'}
                (par, chil) = split
                if len(par) > 1:
                    return {'correct': False, 'feedback': 'layout problem'}
                elif len(par) == 1:
                    dep += 1
                    v = par[0]
                elif dep == depth:
                    return {'correct': True}
                else:
                    return {
                        'correct': False,
                        'feedback': 'depth wrong',
                        'vertexLabel': label,
                        'depthReal': dep,
                        'depthExpected': depth
                    }
    return {
        'correct': False,
        'feedback': 'missing vertex',
        'vertexLabel': label
    }
예제 #11
0
def equivalent(student_answer, graph_answer, colors_choice, edge_choice):
    check_colors = colors_choice == "yes"
    check_edge_labels = edge_choice == "yes"
    if len(student_answer.vs) != len(graph_answer.vs):
        return {
            'correct': False,
            'feedback': 'vertex count wrong',
            'vertexCount': len(student_answer.vs),
            'expectedVertexCount': len(graph_answer.vs)
        }
    if len(student_answer.es) != len(graph_answer.es):
        return {
            'correct': False,
            'feedback': 'edge count wrong',
            'edgeCount': len(student_answer.es),
            'expectedEdgeCount': len(graph_answer.es)
        }
    vs_stud = sorted(student_answer.vs, key=lambda vertex: vertex['name'])
    vs_graph = sorted(graph_answer.vs, key=lambda vertex: vertex['name'])

    for i in range(0, len(vs_graph)):
        #check if the matching vertex exists
        if (vs_stud[i]['name'] != vs_graph[i]['name']):
            return {
                'correct': False,
                'feedback': 'missing vertex',
                'vertexLabel': filter_orig_name(vs_graph[i])
            }
        if (vs_stud[i].degree() != vs_graph[i].degree()):
            return {
                'correct': False,
                'feedback': 'degree wrong',
                'vertexLabel': filter_orig_name(vs_graph[i]),
                'vertexDegree': vs_stud[i].degree(),
                'expectedDegree': vs_graph[i].degree()
            }

        if (check_colors and vs_stud[i]['color'] != vs_graph[i]['color']):
            return {
                'correct': False,
                'feedback': 'color wrong',
                'vertexLabel': filter_orig_name(vs_graph[i]),
                'vertexColor': vs_stud[i]['color'],
                'expectedColor': vs_graph[i]['color']
            }

        graph_neigh = sorted(vs_graph[i].neighbors(),
                             key=lambda vertex: vertex['name'])
        stud_neigh = sorted(vs_stud[i].neighbors(),
                            key=lambda vertex: vertex['name'])
        for j in range(0, len(graph_neigh)):
            if (graph_neigh[j]['name'] != stud_neigh[j]['name']):
                return {
                    'correct': False,
                    'feedback': 'neighborhood wrong',
                    'vertexLabel': filter_orig_name(vs_graph[i])
                }
        if (check_edge_labels):
            graph_edges = sorted(vs_graph[i].all_edges(),
                                 key=lambda edge: edge['label'])
            stud_edges = sorted(vs_stud[i].all_edges(),
                                key=lambda edge: edge['label'])

            for j in range(0, len(graph_edges)):
                if (graph_edges[j]['label'] != stud_edges[j]['label']):
                    return {
                        'correct':
                        False,
                        'feedback':
                        'edge label wrong',
                        'edgeLabel':
                        str(stud_edges[j]['label']),
                        'fromLabel':
                        filter_orig_name(
                            student_answer.vs[stud_edges[j].source]),
                        'toLabel':
                        filter_orig_name(
                            student_answer.vs[stud_edges[j].target])
                    }
    return {'correct': True}