def missing_zero_initialization():
    """

    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    accumulator = None
    loop_acu = None
    for loop in for_loops:
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            if len(binops) > 0:
                lhs = assignment.target
                for binop in binops:
                    if binop.has(lhs) and binop.op == 'Add':
                        accumulator = lhs
                        loop_acu = loop
    accu_init = False
    if accumulator is not None:
        assignments = std_ast.find_all('Assign')
        for assignment in assignments:
            if loop_acu.lineno > assignment.lineno:
                lhs = assignment.target
                if lhs.id == accumulator.id and assignment.has(0):
                    accu_init = True
                    break
    if not accu_init and accumulator is not None:
        explain('The addition on the first iteration step is not correct because either the variable '
                '<code>{0!s}</code> has not been initialized to an appropriate initial value or it has not been placed'
                ' in an appropriate location<br><br><i>(miss_zero_init)<i></br>'.format(accumulator.id))
        return False
    return True
    Returns:
    """

    message = (
        'The addition on the first iteration step is not correct because either the variable <code>{0!s}</code> '
        'has not been initialized to an appropriate initial value '
        'or it has not been placed in an appropriate location')
    code = "miss_zero_init"
    tldr = "Missing Initialization for Accumulator"
    matches01 = find_matches("for ___ in ___:\n" "    __expr__")
    if matches01:
        for match01 in matches01:
            __expr__ = match01["__expr__"]
            submatches01 = __expr__.find_matches("_sum_ = _sum_ + ___", )
            if submatches01:
                for submatch01 in submatches01:
                    _sum_ = submatch01["_sum_"][0]
                    matches02 = find_matches(("{} = 0\n"
                                              "for ___ in ___:\n"
                                              "    __expr__").format(_sum_.id))
                    if not matches02:
                        return explain(message.format(_sum_.id),
                                       label=code,
                                       title=tldr)
    return False
def missing_zero_initialization():
    """

    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    accumulator = None
    loop_acu = None
    for loop in for_loops:
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            if len(binops) > 0:
                lhs = assignment.target
                for binop in binops:
                    if binop.has(lhs) and binop.op == 'Add':
                        accumulator = lhs
                        loop_acu = loop
    accu_init = False
    if accumulator is not None:
        assignments = std_ast.find_all('Assign')
        for assignment in assignments:
            if loop_acu.lineno > assignment.lineno:
                lhs = assignment.target
                if lhs.id == accumulator.id and assignment.has(0):
                    accu_init = True
                    break
    if not accu_init and accumulator is not None:
        explain('The addition on the first iteration step is not correct because either the variable '
                '<code>{0!s}</code> has not been initialized to an appropriate initial value or it has not been placed'
                ' in an appropriate location<br><br><i>(miss_zero_init)<i></br>'.format(accumulator.id))
        return False
    return True
    Returns:
    """

    matches01 = find_matches("for ___ in ___:\n"
                             "    __expr__")
    if matches01:
        for match01 in matches01:
            __expr__ = match01["__expr__"]
            submatches01 = __expr__.find_matches("_sum_ = _sum_ + ___", )
            if submatches01:
                for submatch01 in submatches01:
                    _sum_ = submatch01["_sum_"][0]
                    matches02 = find_matches(("{} = 0\n"
                                              "for ___ in ___:\n"
                                              "    __expr__").format(_sum_.id))
                    if not matches02:
                        explain('The addition on the first iteration step is not correct because either the variable '
                                '<code>{0!s}</code> has not been initialized to an appropriate initial value or it has '
                                'not been placed in an appropriate location<br><br><i>'
                                '(miss_zero_init)<i></br>'.format(_sum_.id))
                        return True
    return False
def histogram_wrong_placement():
    matches = find_matches("for ___ in ___:\n"
                           "    pass\n")
    if matches:
        matches02 = find_matches("plt.hist(___)")
        for match in matches:
            if matches02:
                for match02 in matches02:
                    if match02.match_lineno > match.match_lineno:
                        return False
    explain("The histogram should be plotted only once, after the new list has been created"
            "<br><br><i>(histo_wrong_place)<i></br>")
    return True
def histogram_wrong_placement():
    matches = find_matches("for ___ in ___:\n" "    pass\n")
    if matches:
        matches02 = find_matches("plt.hist(___)")
        for match in matches:
            if matches02:
                for match02 in matches02:
                    if match02.match_lineno > match.match_lineno:
                        return False
    explain(
        "The histogram should be plotted only once, after the new list has been created"
        "<br><br><i>(histo_wrong_place)<i></br>")
    return True
Beispiel #5
0
def histogram_wrong_placement():
    message = "The histogram should be plotted only once, after the new list has been created"
    code = "histo_wrong_place"
    tldr = "Histogram Plot Placed Incorrectly"
    matches = find_matches("for ___ in ___:\n" "    pass\n")
    if matches:
        matches02 = find_matches("plt.hist(___)")
        for match in matches:
            if matches02:
                for match02 in matches02:
                    if match02.match_lineno > match.match_lineno:
                        return False
    return explain_r(message, code, label=tldr)
Beispiel #6
0
def wrong_accumulator_initialization_placement_8_3():
    for_matches = find_matches("for ___ in ___:" "    pass")
    init_matches = find_matches("sum_length = 0")
    if init_matches and for_matches:
        for for_match in for_matches:
            for_lineno = for_match.match_lineno
            for init_match in init_matches:
                if init_match.match_lineno > for_lineno:
                    explain(
                        'The variable to hold the sum of the episode lengths (<code>sum_length</code>) must be '
                        'initialized before the iteration which uses this variable.<br><br><i>'
                        '(accu_init_place_8.3)<i></br>')
                    return True
    return False
Beispiel #7
0
def wrong_list_initialization_placement_8_3():
    for_matches = find_matches("for ___ in ___:\n" "    pass")
    init_matches = find_matches("episode_length_list = ___")
    if init_matches and for_matches:
        for for_match in for_matches:
            for_lineno = for_match.match_lineno
            for init_match in init_matches:
                if init_match.match_lineno > for_lineno:
                    explain(
                        'The list of episode lengths (<code>episode_length_list</code>) must be initialized before the'
                        ' iteration which uses this list.<br><br><i>(init_place_8.3)<i></br>'
                    )
                    return True
    return False
def wrong_list_initialization_placement_8_3():
    for_matches = find_matches("for ___ in ___:\n"
                               "    pass")
    init_matches = find_matches("episode_length_list = ___")
    if init_matches and for_matches:
        for for_match in for_matches:
            for_lineno = for_match.match_lineno
            for init_match in init_matches:
                if init_match.match_lineno > for_lineno:
                    explain(
                        'The list of episode lengths (<code>episode_length_list</code>) must be initialized before the'
                        ' iteration which uses this list.<br><br><i>(init_place_8.3)<i></br>')
                    return True
    return False
Beispiel #9
0
def wrong_list_initialization_placement_8_3():
    message = ('The list of episode lengths (<code>episode_length_list</code>)'
               ' must be initialized before the iteration which uses this list.')
    code = "init_place_8.3"
    tldr = "Wrong Initialization Placement"
    for_matches = find_matches("for ___ in ___:\n"
                               "    pass")
    init_matches = find_matches("episode_length_list = ___")
    if init_matches and for_matches:
        for for_match in for_matches:
            for_lineno = for_match.match_lineno
            for init_match in init_matches:
                if init_match.match_lineno > for_lineno:
                    return explain_r(message, code, label=tldr)
    return False
Beispiel #10
0
def wrong_accumulator_initialization_placement_8_3():
    for_matches = find_matches("for ___ in ___:"
                               "    pass")
    init_matches = find_matches("sum_length = 0")
    if init_matches and for_matches:
        for for_match in for_matches:
            for_lineno = for_match.match_lineno
            for init_match in init_matches:
                if init_match.match_lineno > for_lineno:
                    explain(
                        'The variable to hold the sum of the episode lengths (<code>sum_length</code>) must be '
                        'initialized before the iteration which uses this variable.<br><br><i>'
                        '(accu_init_place_8.3)<i></br>')
                    return True
    return False
Beispiel #11
0
def wrong_accumulator_initialization_placement_8_3():
    message = ('The variable to hold the sum of the episode lengths (<code>sum_length</code>) '
               'must be initialized before the iteration which uses this variable.')
    code = "accu_init_place_8.3"
    tldr = "Accumulator initialization misplaced"
    for_matches = find_matches("for ___ in ___:"
                               "    pass")
    init_matches = find_matches("sum_length = 0")
    if init_matches and for_matches:
        for for_match in for_matches:
            for_lineno = for_match.match_lineno
            for init_match in init_matches:
                if init_match.match_lineno > for_lineno:
                    return explain_r(message, code, label=tldr)
    return False
def warning_average_in_iteration():
    """

    Returns:

    """
    message = (
        'An average value is best computed after the properties name <code>{0!s}</code>(total) and '
        '<code>{1!s}</code> are completely known rather than recomputing the average on each iteration.'
    )
    code = "avg_in_iter"
    tldr = "Redundant Average Calculation"
    matches = find_matches("for ___ in ___:\n" "    __expr__\n")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("_average_ = _total_/_count_", )
            if submatches:
                for submatch in submatches:
                    _total_ = submatch["_total_"][0]
                    _count_ = submatch["_count_"][0]
                    _average_ = submatch["_average_"][0]
                    if _total_.id != _count_.id != _average_.id and _total_.id != _average_.id:
                        return explain(message.format(_total_.id, _count_.id),
                                       label=code,
                                       title=tldr)

    return False
Beispiel #13
0
def wrong_debug_10_6():
    """




    Returns:
    """
    matches = find_matches('quakes = earthquakes.get("depth","(None)","")\n'
                           'quakes_in_miles = []\n'
                           'for quake in _list1_:\n'
                           '    _list2_.append(quake * 0.62)\n'
                           'plt.hist(quakes_in_miles)\n'
                           'plt.xlabel("Depth in Miles")\n'
                           'plt.ylabel("Number of Earthquakes")\n'
                           'plt.title("Distribution of Depth in Miles of Earthquakes")\n'
                           'plt.show()')
    for match in matches:
        name1 = match["_list1_"][0].ast_node.id
        name2 = match["_list2_"][0].ast_node.id
        master_list = ["quake", "quakes", "quakes_in_miles"]
        if (name1 in master_list and name2 in master_list and
                name1 != "quakes_in_miles" and name2 != "quakes" and
                (name1 != "quake" or name2 != "quake")):
            return False
    explain('This is not one of the two changes needed. Undo the change and try again.<br><br><i>(debug_10.6)<i></br>')
    return True
def wrong_append_problem_atl1_10_5():
    """

    Returns:

    """
    message = "You are not appending the correct values.<br><br><i>(app_alt1_10.5"
    code = "app_alt1_10.5"
    tldr = "Incorrect Value Appended"
    matches = find_matches("for _item_ in ___:\n"
                           "    if __cond__:\n"
                           "        _list_.append(__expr__)")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0].astNode
            __cond__ = match["__cond__"]
            __expr__ = match["__expr__"]
            if (__cond__.numeric_logic_check(0.1, "item > 16.1290322580645")
                    and __cond__.has(_item_)):
                # new_code = "{}*0.62".format(_item_.id)
                new_code = "_item_*0.62"
                matches02 = __expr__.find_matches(new_code)
                if not matches02:
                    return explain(message, label=code, title=tldr)
    return False
Beispiel #15
0
def missing_append_list_initialization():
    matches = find_matches("for ___ in ___:\n" "    __expr__")
    for match in matches:
        __expr__ = match["__expr__"]
        submatches = __expr__.find_matches("_new_list_.append(___)", )
        for submatch in submatches:
            _new_list_ = submatch["_new_list_"].astNode
            matches02 = find_matches("{} = []\n"
                                     "for ___ in ___:\n"
                                     "    __expr__".format(_new_list_.id))
            if not matches02:
                explain(
                    "The list variable <code>{0!s}</code> must be initialized.<br><br><i>"
                    "(no_app_list_init)<i></br>".format(_new_list_.id))
                return True
    return False
def histogram_wrong_list():
    """

    Name: histogram_wrong_list
    Pattern:

    for ___ in ___:
       <target>.append(___)
    plt.hist(<list>)

    where name(<target>) != name(<list>)

    Feedback: The list created in the iteration is not the list being used to create the histogram.

    Returns:
    """
    matches = find_matches("for ___ in ___:\n"
                           "    __expr__\n"
                           "plt.hist(_list_)")
    if matches:
        for match in matches:
            _list_ = match["_list_"].astNode
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("{}.append(___)".format(
                _list_.id))
            if submatches:
                return False
        explain(
            "The list created in the iteration is not the list being used to create the histogram.<br><br><i>"
            "(histo_wrong_list)<i></br>")
        return True
    return False
def wrong_initialization_in_iteration():
    """

    Returns:

    """
    message = (
        "You only need to initialize <code>{0!s}</code> once. "
        "Remember that statements in an iteration block happens multiple times"
    )
    code = "wrong_init_in_iter"
    tldr = "Initialization in Iteration"
    matches = find_matches("for ___ in ___:\n" "    __expr__")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("_assign_ = __expr__", )
            if submatches:
                for submatch in submatches:
                    __expr__sub = submatch["__expr__"]
                    _assign_ = submatch["_assign_"][0].astNode
                    if len(__expr__sub.find_all("Name")) == 0:
                        return explain(message.format(_assign_.id),
                                       label=code,
                                       title=tldr)
    return False
def histogram_wrong_list():
    """

    Name: histogram_wrong_list
    Pattern:

    for ___ in ___:
       <target>.append(___)
    plt.hist(<list>)

    where name(<target>) != name(<list>)

    Feedback: The list created in the iteration is not the list being used to create the histogram.

    Returns:
    """
    matches = find_matches("for ___ in ___:\n"
                           "    __expr__\n"
                           "plt.hist(_list_)")
    if matches:
        for match in matches:
            _list_ = match["_list_"].astNode
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("{}.append(___)".format(_list_.id))
            if submatches:
                return False
        explain(
            "The list created in the iteration is not the list being used to create the histogram.<br><br><i>"
            "(histo_wrong_list)<i></br>")
        return True
    return False
def missing_summing_list():
    """
    std_ast = parse_program()
    has_total = False
    for_loops = std_ast.find_all('For')
    if len(for_loops) > 0:
        for loop in for_loops:
            assignments = loop.find_all('Assign')
            if len(assignments) < 1:
                continue
            iter_prop = loop.target
            for assignment in assignments:
                binops = assignment.find_all('BinOp')
                if len(binops) < 1:
                    continue
                lhs = assignment.target
                for binop in binops:
                    if binop.has(lhs) and binop.has(iter_prop) and binop.op == 'Add':
                        has_total = True
    if not has_total:
        explain('Sum the total of all list elements using iteration.<br><br><i>(miss_sum_list)<i></br>')
    Returns:
    """
    message = 'Sum the total of all list elements using iteration.'
    code = "miss_sum_list"
    tldr = "Missing Sum in Iteration"
    matches = find_matches("for _item_ in ___:\n" "    __expr__")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("_sum_ = _sum_ + _item_")
            if submatches:
                return False
    return explain(message, label=code, title=tldr)
Beispiel #20
0
def missing_append_list_initialization():
    matches = find_matches("for ___ in ___:\n"
                           "    __expr__")
    for match in matches:
        __expr__ = match["__expr__"]
        submatches = __expr__.find_matches("_new_list_.append(___)", )
        for submatch in submatches:
            _new_list_ = submatch["_new_list_"].astNode
            matches02 = find_matches("{} = []\n"
                                     "for ___ in ___:\n"
                                     "    __expr__".format(_new_list_.id))
            if not matches02:
                explain("The list variable <code>{0!s}</code> must be initialized.<br><br><i>"
                        "(no_app_list_init)<i></br>".format(_new_list_.id))
                return True
    return False
def wrong_average_denominator():
    """

    Returns:

    """
    message = "The average is not calculated correctly."
    code = "avg_denom"
    tldr = "Incorrect Average Calculation"
    matches = find_matches(
        "for ___ in ___:\n"
        "    __expr__\n"  # where expr contains _count_ = _count_ + 1
        "__expr2__")  # where expr2 contains ___/_value_
    # where _value_.id != _count_.id
    for match in matches:
        __expr__ = match["__expr__"]
        __expr2__ = match["__expr2__"]
        # _value_ = match["_value_"][0]
        submatches = __expr__.find_matches("_count_ = _count_ + 1", )
        submatches02 = __expr2__.find_matches("___/_value_")
        if submatches and submatches02:
            for submatch in submatches:
                for submatch02 in submatches02:
                    _count_ = submatch["_count_"]
                    _value_ = submatch02["_value_"]
                    if _count_.id != _value_.id:
                        return explain(message, label=code, title=tldr)
    return False
Beispiel #22
0
def wrong_should_be_counting():
    """
    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    for loop in for_loops:
        iter_prop = loop.target
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            for binop in binops:
                if binop.has(iter_prop) and binop.op == 'Add':
                    explain('This problem asks for the number of items in the list not the total of all the values in '
                            'the list.<br><br><i>(not_count)<i></br>')
    Returns:
    """
    matches = find_matches("for _item_ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("___ = ___ + {}".format(_item_.id), )
            if submatches:
                explain(
                    'This problem asks for the number of items in the list not the total of all the values in the list.'
                    '<br><br><i>(not_count)<i></br>')
                return True
    return False
def wrong_average_numerator():
    """

    Returns:

    """
    message = "The average is not calculated correctly."
    code = "avg_numer"
    tldr = "Incorrect Average Calculation"
    matches = find_matches(
        "for _item_ in ___:\n"
        "    __expr__\n"  # where expr contains _total_ = _total_ + 1
        "__expr2__")  # where expr2 contains _value_/___
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            __expr2__ = match["__expr2__"]
            _item_ = match["_item_"][0]
            # TODO: In theory, we could merge these matches to match variables...
            submatches = __expr__.find_matches("_total_ = _total_ + _item_")
            submatches02 = __expr2__.find_matches("_value_/___")
            if submatches and submatches02:
                for submatch in submatches:
                    for submatch02 in submatches02:
                        _value_ = submatch02["_value_"][0]
                        _total_ = submatch["_total_"][0]
                        if _total_.id != _value_.id:
                            return explain(message, label=code, title=tldr)
    return False
Beispiel #24
0
def wrong_filter_problem_atl1_10_5():
    """
    find pattern where expression is equal to _item_*0.62 and
    where the condition is not equivalent to _expr_ > 10
    Returns:
    """

    matches = find_matches("for _item_ in ___:\n"
                           "    if __cond__:\n"
                           "        _list_.append(__expr__)")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0].astNode
            __cond__ = match["__cond__"]
            __expr__ = match["__expr__"]
            matches02 = __expr__.find_matches("_item_*0.62", )
            if matches02:
                for match02 in matches02:
                    _item_02 = match02["_item_"][0].astNode
                    if (_item_.id == _item_02.id and __cond__.has(_item_)
                            and not __cond__.numeric_logic_check(
                                0.1, "item > 16.1290322580645")):
                        explain(
                            'You are not correctly filtering out values from the list.<br><br><i>'
                            '(filt_alt1_10.5)<i></br>')
                        return True
    return False
Beispiel #25
0
def wrong_should_be_counting():
    """
    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    for loop in for_loops:
        iter_prop = loop.target
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            for binop in binops:
                if binop.has(iter_prop) and binop.op == 'Add':
                    explain('This problem asks for the number of items in the list not the total of all the values in '
                            'the list.<br><br><i>(not_count)<i></br>')
    Returns:
    """
    matches = find_matches("for _item_ in ___:\n" "    __expr__")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches(
                "___ = ___ + {}".format(_item_.id), )
            if submatches:
                explain(
                    'This problem asks for the number of items in the list not the total of all the values in the list.'
                    '<br><br><i>(not_count)<i></br>')
                return True
    return False
Beispiel #26
0
def wrong_debug_10_6():
    """




    Returns:
    """
    matches = find_matches(
        'quakes = earthquakes.get("depth","(None)","")\n'
        'quakes_in_miles = []\n'
        'for quake in _list1_:\n'
        '    _list2_.append(quake * 0.62)\n'
        'plt.hist(quakes_in_miles)\n'
        'plt.xlabel("Depth in Miles")\n'
        'plt.ylabel("Number of Earthquakes")\n'
        'plt.title("Distribution of Depth in Miles of Earthquakes")\n'
        'plt.show()')
    for match in matches:
        name1 = match["_list1_"][0].ast_node.id
        name2 = match["_list2_"][0].ast_node.id
        master_list = ["quake", "quakes", "quakes_in_miles"]
        if (name1 in master_list and name2 in master_list
                and name1 != "quakes_in_miles" and name2 != "quakes"
                and (name1 != "quake" or name2 != "quake")):
            return False
    explain(
        'This is not one of the two changes needed. Undo the change and try again.<br><br><i>(debug_10.6)<i></br>'
    )
    return True
Beispiel #27
0
def wrong_conversion_10_2():
    """
    '''
    # code version 2 start
    binops = __expr__.find_all('BinOp')
    for binop in binops:
        if binop.has(_target_.astNode) and binop.has(0.04) and binop.op_name == 'Mult':
            return False
    # code version 2 end
    '''
    Returns:
    """
    matches = find_matches("for _target_ in ___:\n" "    __expr__")
    if matches:
        for match in matches:
            # code version 1 start
            _target_ = match["_target_"][0]
            __expr__ = match["__expr__"]
            matches02 = __expr__.find_matches("_target_*0.04", )
            if matches02:
                for match02 in matches02:
                    _target_02 = match02["_target_"][0]
                    if _target_.id == _target_02.id:
                        return False
            # code version 1 end
        explain(
            'The conversion of <code>{0!s}</code> to inches is not correct.<br><br><i>'
            '(conv_10.2)<i></br>'.format(_target_.id))
        return True
    return False
Beispiel #28
0
def missing_addition_slot_empty():
    """
    std_ast = parse_program()
    assignments = std_ast.find_all('Assign')
    for assignment in assignments:
        # left = assignment.target
        right = assignment.value
        binOp = right.find_all('BinOp')
        if len(binOp) == 1:
            binOp = binOp[0]
            if binOp.op == 'Add':
                if binOp.left.ast_name == 'Name' and binOp.right.ast_name == 'Name':
                    if binOp.left.id == '___' or binOp.right.id == '___':
                        explain('You must fill in the empty slot in the addition.<br><br><i>(add_empty)<i></br>')
                        return True
    return False
    Returns:
    """
    matches = find_matches("___ + _item_")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            if _item_.id == "___":
                explain('You must fill in the empty slot in the addition.<br><br><i>(add_empty)<i></br>')
                return True
    return False
Beispiel #29
0
def wrong_filter_problem_atl1_10_5():
    """
    find pattern where expression is equal to _item_*0.62 and
    where the condition is not equivalent to _expr_ > 10
    Returns:
    """
    message = "You are not correctly filtering out values from the list."
    code = "filt_alt1_10.5"
    tldr = "Incorrect Filter Statement"
    matches = find_matches("for _item_ in ___:\n"
                           "    if __cond__:\n"
                           "        _list_.append(__expr__)")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0].astNode
            __cond__ = match["__cond__"]
            __expr__ = match["__expr__"]
            # matches02 = __expr__.find_matches("{0!s}*0.62".format(_item_.id))
            matches02 = __expr__.find_matches("_item_*0.62")
            if matches02:
                for match02 in matches02:
                    if (__cond__.has(_item_) and
                            not __cond__.numeric_logic_check(0.1, "item > 16.1290322580645")):
                        return explain_r(message, code, label=tldr)
    return False
Beispiel #30
0
def missing_counting_list():
    """
    std_ast = parse_program()
    has_count = False
    for_loops = std_ast.find_all('For')
    if len(for_loops) > 0:
        for loop in for_loops:
            assignments = loop.find_all('Assign')
            if len(assignments) < 1:
                continue
            for assignment in assignments:
                binops = assignment.find_all('BinOp')
                if len(binops) < 1:
                    continue
                lhs = assignment.target
                for binop in binops:
                    if binop.has(lhs) and binop.has(1) and binop.op == 'Add':
                        has_count = True
    if not has_count:
        explain('Count the total number of items in the list using iteration.<br><br><i>(miss_count_list)<i></br>')
    Returns:
    """
    matches = find_matches("for _item_ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("_sum_ = _sum_ + 1", )
            if submatches:
                return False
    explain(
        'Count the total number of items in the list using iteration.<br><br><i>(miss_count_list)<i></br>')
    return True
Beispiel #31
0
def wrong_cannot_sum_list():
    """

    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    for loop in for_loops:
        list_prop = loop.iter
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            for binop in binops:
                if binop.has(list_prop) and binop.op == 'Add':
                    explain('Addition can only be done with a single value at a time, not with an entire list at one'
                            ' time.<br><br><i>(sum_list)<i></br>')
    Returns:
    """
    matches = find_matches("for ___ in _list_ :\n"
                           "    __expr__")
    if matches:
        for match in matches:
            _list_ = match["_list_"][0]
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("___ = ___ + {}".format(_list_.id), )
            if submatches:
                explain('Addition can only be done with a single value at a time, not with an entire list at one'
                        ' time.<br><br><i>(sum_list)<i></br>')
                return True
    return False
Beispiel #32
0
def wrong_conversion_10_2():
    """
    '''
    # code version 2 start
    binops = __expr__.find_all('BinOp')
    for binop in binops:
        if binop.has(_target_.astNode) and binop.has(0.04) and binop.op_name == 'Mult':
            return False
    # code version 2 end
    '''
    Returns:
    """
    matches = find_matches("for _target_ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            # code version 1 start
            _target_ = match["_target_"][0]
            __expr__ = match["__expr__"]
            matches02 = __expr__.find_matches("_target_*0.04", )
            if matches02:
                for match02 in matches02:
                    _target_02 = match02["_target_"][0]
                    if _target_.id == _target_02.id:
                        return False
            # code version 1 end
        explain('The conversion of <code>{0!s}</code> to inches is not correct.<br><br><i>'
                '(conv_10.2)<i></br>'.format(_target_.id))
        return True
    return False
def wrong_nested_filter_condition_10_4():
    """

    Returns:

    """
    message = ("The decisions used to filter the temperatures into "
               "the specified range of temperatures is not correct.")
    code = "nest_filt_10.4"
    tldr = "Incorrect Set of Decisions"
    matches = find_matches("for _temp_ in _list_:\n"
                           "    if __cond1__:\n"
                           "        if __cond2__:\n"
                           "            pass")
    if matches:
        for match in matches:
            _temp_ = match["_temp_"][0].astNode
            __cond1__ = match["__cond1__"]
            __cond2__ = match["__cond2__"]
            if not (__cond1__.has(_temp_) and __cond2__.has(_temp_) and
                    (__cond1__.numeric_logic_check(1, "32 <= temp")
                     and __cond2__.numeric_logic_check(1, "temp <= 50")
                     or __cond2__.numeric_logic_check(1, "32 <= temp")
                     and __cond1__.numeric_logic_check(1, "temp <= 50"))):
                return explain(message, label=code, title=tldr)
    return False
Beispiel #34
0
def missing_counting_list():
    """
    std_ast = parse_program()
    has_count = False
    for_loops = std_ast.find_all('For')
    if len(for_loops) > 0:
        for loop in for_loops:
            assignments = loop.find_all('Assign')
            if len(assignments) < 1:
                continue
            for assignment in assignments:
                binops = assignment.find_all('BinOp')
                if len(binops) < 1:
                    continue
                lhs = assignment.target
                for binop in binops:
                    if binop.has(lhs) and binop.has(1) and binop.op == 'Add':
                        has_count = True
    if not has_count:
        explain('Count the total number of items in the list using iteration.<br><br><i>(miss_count_list)<i></br>')
    Returns:
    """
    message = 'Count the total number of items in the list using iteration.'
    code = "miss_count_list"
    tldr = "Missing Count in Iteration"
    matches = find_matches("for _item_ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("_sum_ = _sum_ + 1", )
            if submatches:
                return False
    return explain_r(message, code, label=tldr)
Beispiel #35
0
def wrong_debug_10_6():
    """
    Should be on change feedback as opposed to on-run
    Returns:
    """
    message = "This is not one of the two changes needed. Undo the change and try again."
    code = "debug_10.6"
    tldr = "At least one unnecessary change"
    matches = find_matches('quakes = earthquakes.get("location.depth","(None)","")\n'
                           'quakes_in_miles = []\n'
                           'for quake in _list1_:\n'
                           '    _list2_.append(quake * 0.62)\n'
                           'plt.hist(quakes_in_miles)\n'
                           'plt.xlabel("Depth in Miles")\n'
                           'plt.ylabel("Number of Earthquakes")\n'
                           'plt.title("Distribution of Depth in Miles of Earthquakes")\n'
                           'plt.show()')
    for match in matches:
        name1 = match["_list1_"][0].ast_node.id
        name2 = match["_list2_"][0].ast_node.id
        master_list = ["quake", "quakes", "quakes_in_miles"]
        if (name1 in master_list and name2 in master_list and
                name1 != "quakes_in_miles" and name2 != "quakes" and
                (name1 != "quake" or name2 != "quake")):
            return False
    return explain_r(message, code, label=tldr)
Beispiel #36
0
def wrong_cannot_sum_list():
    """

    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    for loop in for_loops:
        list_prop = loop.iter
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            for binop in binops:
                if binop.has(list_prop) and binop.op == 'Add':
                    explain('Addition can only be done with a single value at a time, not with an entire list at one'
                            ' time.<br><br><i>(sum_list)<i></br>')
    Returns:
    """
    message = 'Addition can only be done with a single value at a time, not with an entire list at one'
    code = "sum_list"
    tldr = "Cannot Sum a List"
    matches = find_matches("for ___ in _list_ :\n"
                           "    __expr__")
    if matches:
        for match in matches:
            _list_ = match["_list_"][0]
            __expr__ = match["__expr__"]
            # submatches = __expr__.find_matches("___ = ___ + {}".format(_list_.id), )
            submatches = __expr__.find_matches("___ = ___ + _list_")
            if submatches:
                return explain_r(message, code, label=tldr)
    return False
Beispiel #37
0
def wrong_nested_filter_condition_10_4():
    matches = find_matches("for _temp_ in _list_:\n"
                           "    if __cond1__:\n"
                           "        if __cond2__:\n"
                           "            pass")
    if matches:
        for match in matches:
            _temp_ = match["_temp_"][0].astNode
            __cond1__ = match["__cond1__"]
            __cond2__ = match["__cond2__"]
            if not (
                    __cond1__.has(_temp_) and __cond2__.has(_temp_) and (
                    __cond1__.numeric_logic_check(
                        1,
                        "32 <= temp") and __cond2__.numeric_logic_check(
                1,
                "temp <= 50") or __cond2__.numeric_logic_check(
                1,
                "32 <= temp") and __cond1__.numeric_logic_check(
                1,
                "temp <= 50"))):
                explain(
                    'The decisions used to filter the temperatures into the specified range of temperatures is not '
                    'correct.<br><br><i>(nest_filt_10.4)<i></br>')
                return True
    return False
Beispiel #38
0
def histogram_wrong_list():
    """

    Name: histogram_wrong_list
    Pattern:

    for ___ in ___:
       <target>.append(___)
    plt.hist(<list>)

    where name(<target>) != name(<list>)

    Feedback: The list created in the iteration is not the list being used to create the histogram.

    Returns:
    """
    message = "The list created in the iteration is not the list being used to create the histogram."
    code = "histo_wrong_list"
    tldr = "Plotting Wrong List"
    matches = find_matches("for ___ in ___:\n"
                           "    __expr__\n"
                           "plt.hist(_list_)")
    if matches:
        for match in matches:
            _list_ = match["_list_"].astNode
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("_list_.append(___)")
            if submatches:
                return False
        return explain_r(message, code, label=tldr)
    return False
Beispiel #39
0
def missing_summing_list():
    """
    std_ast = parse_program()
    has_total = False
    for_loops = std_ast.find_all('For')
    if len(for_loops) > 0:
        for loop in for_loops:
            assignments = loop.find_all('Assign')
            if len(assignments) < 1:
                continue
            iter_prop = loop.target
            for assignment in assignments:
                binops = assignment.find_all('BinOp')
                if len(binops) < 1:
                    continue
                lhs = assignment.target
                for binop in binops:
                    if binop.has(lhs) and binop.has(iter_prop) and binop.op == 'Add':
                        has_total = True
    if not has_total:
        explain('Sum the total of all list elements using iteration.<br><br><i>(miss_sum_list)<i></br>')
    Returns:
    """
    matches = find_matches("for _item_ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            __expr__ = match["__expr__"]
            submatches = find_expr_sub_matches("_sum_ = _sum_ + {}"
                                               .format(_item_.id), __expr__)
            if submatches:
                return False
    explain('Sum the total of all list elements using iteration.<br><br><i>(miss_sum_list)<i></br>')
    return True
Beispiel #40
0
def histogram_argument_not_list():
    """

    Name: histogram_argument_not_list
    Pattern:
       plt.hist(<argument>)
    Where type(<argument>) is not "list"

    Feedback: Making a histogram requires a list; <argument> is not a list.


    Returns:
    """
    message = "Making a histogram requires a list; <code>{0!s}</code> is not a list."
    code = "hist_arg_not_list"
    tldr = "Making Histogram from Non-list"
    matches = find_matches("plt.hist(_argument_)")
    if matches:
        for match in matches:
            _argument_ = match["_argument_"].astNode
            if not _argument_.get_data_state(
            ) or not _argument_.get_data_state().was_type('list'):
                return explain_r(message.format(_argument_.id),
                                 code,
                                 label=tldr)
    return False
Beispiel #41
0
def wrong_filter_problem_atl1_10_5():
    """
    find pattern where expression is equal to _item_*0.62 and
    where the condition is not equivalent to _expr_ > 10
    Returns:
    """

    matches = find_matches("for _item_ in ___:\n"
                           "    if __cond__:\n"
                           "        _list_.append(__expr__)")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0].astNode
            __cond__ = match["__cond__"]
            __expr__ = match["__expr__"]
            matches02 = __expr__.find_matches("_item_*0.62", )
            if matches02:
                for match02 in matches02:
                    _item_02 = match02["_item_"][0].astNode
                    if (_item_.id == _item_02.id and
                            __cond__.has(_item_) and
                            not __cond__.numeric_logic_check(0.1, "item > 16.1290322580645")):
                        explain('You are not correctly filtering out values from the list.<br><br><i>'
                                '(filt_alt1_10.5)<i></br>')
                        return True
    return False
def wrong_filter_problem_atl2_10_5():
    """

    Returns:

    """
    message = "You are not correctly filtering out values from the list."
    code = "filt_alt2_10.5"
    tldr = "Incorrect Filter Statement"
    matches = find_matches("for _item_ in ___:\n"
                           "    _miles_ = __expr__\n"
                           "    if __cond__:\n"
                           "        _list_.append(_miles_)")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            __cond__ = match["__cond__"]
            _item_ = match["_item_"][0].astNode
            _miles_ = match["_miles_"][0].astNode
            matches02 = __expr__.find_matches("_item_*0.62")
            for _ in matches02:
                if not (__cond__.has(_miles_)
                        and __cond__.numeric_logic_check(1, "_item_ > 10")):
                    return explain(message, label=code, title=tldr)
    return False
Beispiel #43
0
def missing_addition_slot_empty():
    """
    std_ast = parse_program()
    assignments = std_ast.find_all('Assign')
    for assignment in assignments:
        # left = assignment.target
        right = assignment.value
        binOp = right.find_all('BinOp')
        if len(binOp) == 1:
            binOp = binOp[0]
            if binOp.op == 'Add':
                if binOp.left.ast_name == 'Name' and binOp.right.ast_name == 'Name':
                    if binOp.left.id == '___' or binOp.right.id == '___':
                        explain('You must fill in the empty slot in the addition.<br><br><i>(add_empty)<i></br>')
                        return True
    return False
    Returns:
    """
    message = "You must fill in the empty slot in the addition."
    code = "add_empty"
    tldr = "Addition Blank"
    matches = find_matches("___ + _item_")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            if _item_.id == "___":
                return explain_r(message, code, tldr)
    return False
Beispiel #44
0
def wrong_should_be_summing():
    """
    std_ast = parse_program()
    for_loops = std_ast.find_all('For')
    for loop in for_loops:
        assignments = loop.find_all('Assign')
        for assignment in assignments:
            binops = assignment.find_all('BinOp')
            for binop in binops:
                if binop.has(1) and binop.op == 'Add':
                    explain('This problem asks for the total of all the values in the list not the number of items in '
                            'the list.<br><br><i>(not_sum)<i></br>')
    """
    message = "This problem asks for the total of all the values in the list not the number of items in the list."
    code = "not_sum"
    tldr = "Counting instead of summing"
    matches = find_matches("for _item_ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            submatches = __expr__.find_matches("___ = 1 + ___", )
            if submatches:
                return explain_r(message, code, label=tldr)
    return False
Beispiel #45
0
def wrong_accumulator_initialization_9_2():
    message = ("The variable to hold the total value of the rainfall amounts "
               "(<code>rainfall_count</code>) is not initialized properly.")
    code = "accu_init_9.2"
    tldr = "Incorrect Initialization"
    if not find_matches("rainfall_count = 0"):
        return explain_r(message, code, label=tldr)
    return False
Beispiel #46
0
def missing_addition_slot_empty_8_4():
    matches = find_matches("sum_pages + _item_")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            if _item_.id == "___":
                explain('You must fill in the empty slot in the addition.<br><br><i>(add_empty_8.4)<i></br>')
                return True
    return False
Beispiel #47
0
def wrong_list_length_8_2():
    matches = find_matches("_list_ = __expr__")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            if __expr__.ast_name == "List" and len(__expr__.elts) < 3:
                explain('You must have at least three pieces<br><br><i>(list length_8.2)<i></br>')
                return True
    return False
Beispiel #48
0
def hard_code_8_5():  # TODO: This one's weird
    match = find_matches("print(__num__)")
    if match:
        for m in match:
            __num__ = m["__num__"]
            if len(__num__.find_all("Num")) > 0:
                explain("Use iteration to calculate the sum.<br><br><i>(hard_code_8.5)<i></br>")
                return True
    return False
Beispiel #49
0
def app_assign():
    message = ("Appending modifies the list, so unlike addition,"
               " an assignment statement is not needed when using append.")
    code = "app_asgn"

    matches = find_matches("_sum_ = _sum_.append(__exp__)")
    if matches:
        return explain_r(message, code)
    return False
Beispiel #50
0
def wrong_printing_list():
    matches = find_matches("for ___ in ___:\n"
                           "    __expr__")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            if __expr__.find_matches("print(___)", ):
                explain('You should be printing a single value.<br><br><i>(list_print)<i></br>')
                return True
    return False
Beispiel #51
0
def missing_target_slot_empty_8_4():
    matches = find_matches("for _item_ in pages_count_list:\n"
                           "    pass")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            if _item_.id == "___":
                explain('You must fill in the empty slot in the iteration.<br><br><i>(target_empty_8.4)<i></br>')
                return True
    return False
Beispiel #52
0
def wrong_accumulation_9_1():
    matches = find_matches("rainfall_sum = _item_ + rainfall")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            if _item_.id != "rainfall_sum":
                explain('The addition of each rainfall amount to <code>rainfall_sum</code> is not correct.'
                        '<br><br><i>(accu_9.1)<i></br>')
                return True
    return False
Beispiel #53
0
def missing_list_initialization_8_2():
    matches = find_matches("shopping_cart = __expr__")
    for match in matches:
        __expr__ = match["__expr__"]
        if __expr__.ast_name == "List":
            return False
    explain(
        'You must set the variable <code>shopping_cart</code> to a list containing the prices of items in the'
        ' shopping cart.<br><br><i>(missing_list_init_8.2)<i></br>')
    return True
Beispiel #54
0
def wrong_list_is_constant_8_2():
    matches = find_matches("shopping_cart = __expr__")
    for match in matches:
        __expr__ = match["__expr__"]
        if __expr__.ast_name == "Num":
            explain(
                'You must set <code>shoppping_cart</code> to a list of values not to a single number.<br><br><i>'
                '(list_is_const_8.2)<i></br>')
            return True
    return False
Beispiel #55
0
def append_list_wrong_slot():
    matches = find_matches("_target_.append(_item_)")
    if matches:
        for match in matches:
            _item_ = match["_item_"].astNode
            _target_ = match["_target_"].astNode
            if data_state(_item_).was_type('list'):
                explain("You should not append a list (<code>{0!s}</code>) to <code>{1!s}</code>.<br><br><i>"
                        "(app_list_slot)<i></br>".format(_item_.id, _target_.id))
                return True
    return False
Beispiel #56
0
def wrong_accumulation_9_2():
    matches = find_matches("rainfall_count = _item_ + 1")
    if matches:
        for match in matches:
            _item_ = match["_item_"][0]
            if _item_.id != "rainfall_count":
                explain(
                    'The adding of another day with rainfall to the total count of days with rainfall '
                    '(<code>rainfall_count</code>) is not correct.<br><br><i>(accu_9.2)<i></br>')
                return True
    return False
Beispiel #57
0
def wrong_decision_body_9_2():
    matches = find_matches("if __expr__:\n"
                           "    rainfall_count = rainfall_count + 1")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            if __expr__.numeric_logic_check(1, 'var > 0'):
                return False
    explain('The increase by 1 in the number of days having rainfall (<code>rainfall_count</code>) is not in the '
            'correct place.<br><br><i>(dec_body_9.2)<i></br>')
    return True
Beispiel #58
0
def wrong_comparison_9_6():
    matches = find_matches("if __comp__:\n"
                           "    pass")
    if matches:
        for match in matches:
            __comp__ = match["__comp__"]
            if not __comp__.numeric_logic_check(1, 'var > 80'):
                explain(
                    'In this problem you should be finding temperatures above 80 degrees.<br><br><i>(comp_9.6)<i></br>')
                return True
    return False
Beispiel #59
0
def wrong_filter_condition_10_3():
    matches = find_matches("if __expr__:\n"
                           "    pass")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            if __expr__.numeric_logic_check(1, "var > 0") or __expr__.numeric_logic_check(1, "var != 0"):
                return False
        explain('The condition used to filter the year when artists died is not correct.<br><br><i>(filt_10.3)<i></br>')
        return True
    return False
Beispiel #60
0
def wrong_iteration_body_9_2():
    matches = find_matches("for _item_ in _list_:\n"
                           "    if __expr__:\n"
                           "        pass")
    if matches:
        for match in matches:
            __expr__ = match["__expr__"]
            if __expr__.numeric_logic_check(1, 'var > 0'):
                return False
    explain('The test (if) to determine if a given amount of rainfall is greater than (>) zero is not in the '
            'correct place.<br><br><i>(iter_body_9.2)<i></br>')
    return True