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_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_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 prevent_incorrect_plt(): ast = parse_program() plts = [n for n in ast.find_all("Name") if n.id == 'plt'] if plts and def_use_error(plts[0]): explain( "You have imported the <code>matplotlib.pyplot</code> module, " "but you did not rename it to <code>plt</code> using " "<code>import matplotlib.pyplot as plt</code>.<br><br><i>(plt_rename_err)<i>", 'verifier') return True matplotlib_names = [ 'plot', 'hist', 'scatter', 'title', 'xlabel', 'ylabel', 'show' ] for name in matplotlib_names: for n in ast.find_all("Name"): if n.id == name: if def_use_error(n): explain(("You have attempted to use the MatPlotLib " "function named <code>{0}</code>. However, you " "imported MatPlotLib in a way that does not " "allow you to use the function directly. I " "recommend you use <code>plt.{0}</code> instead, " "after you use <code>import matplotlib.pyplot as " "plt</code>.<br><br><i>(plt_wrong_import)<i>" ).format(name), 'verifier') return True return False
def check_record_instance(record_instance, record_type, instance_identifier, type_identifier): if not isinstance(record_instance, dict): explain("{} was not a {} because it is not a dictionary.".format(instance_identifier, type_identifier)) return False for expected_key, expected_value_type in record_type.items(): if expected_key not in record_instance: explain("{} was supposed to have the key `{}`, but it did not.".format(instance_identifier, expected_key)) return False actual_value = record_instance[expected_key] # Handle nested record types if isinstance(expected_value_type, list): if not isinstance(actual_value, list): explain("{} was not a {} because its key `{}` did not have a list.".format( instance_identifier, type_identifier, expected_key )) return False elif actual_value: actual_value = actual_value[0] expected_value_type = expected_value_type[0] if not isinstance(actual_value, expected_value_type): explain("{} was not a {} because its key `{}` did not have a `{}` value".format( instance_identifier, type_identifier, expected_key, expected_value_type.__name__ )) return False if len(record_type) != len(record_instance): explain("{} had extra keys that it should not have.".format(instance_identifier)) return False return True
def missing_no_print(): prints = find_match('print(___)', cut=True) if not prints: explain( 'Program does not output anything.<br><br><i>(no_print)<i></br>') return True return False
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
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
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
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
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_accumulator_initialization_9_1(): match = find_match("rainfall_sum = 0") if not match: explain('The variable to hold the total value of the rainfall amounts (<code>rainfall_sum</code>) is not ' 'initialized properly.<br><br><i>(accu_init_9.1)<i></br>') 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_duplicate_var_in_add(): match = find_match("_item_ + _item_") if match: explain('You are adding the same variable twice; you need two different variables in your addition.' '<br><br><i>(dup_var)<i></br>') return True return False
def wrong_print_9_1(): """ std_ast = parse_program() for_loops = std_ast.find_all('For') # has_for = len(for_loops) > 0 for_loc = [] wrong_print_placement = True for loop in for_loops: end_node = loop.next_tree if end_node is not None: for_loc.append(end_node.lineno) calls = std_ast.find_all('Call') for call in calls: if call.func.id == 'print': for loc in for_loc: if call.func.lineno >= loc: wrong_print_placement = False break if not wrong_print_placement: break if wrong_print_placement: explain('The output of the total rainfall amount is not in the correct place. The total rainfall should be ' 'output only once after the total rainfall has been computed.<br><br><i>(print_9.1)<i></br>') Returns: """ match = find_match("for _item_ in _list_:\n" " pass\n" "print(_total_)") if not match: explain( 'The output of the total rainfall amount is not in the correct place. The total rainfall should be ' 'output only once after the total rainfall has been computed.<br><br><i>(print_9.1)<i></br>' ) return True return False
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_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
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
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
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
def wrong_list_initialization_9_1(): match = find_match('rainfall_list = weather.get("Precipitation","Location","Blacksburg, VA")') if not match: explain('The list of rainfall amounts (<code>rainfall_list</code>) is not initialized properly.' '<br><br><i>(list_init_9.1)<i></br>') return True return False
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_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 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_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_print_9_1(): """ std_ast = parse_program() for_loops = std_ast.find_all('For') # has_for = len(for_loops) > 0 for_loc = [] wrong_print_placement = True for loop in for_loops: end_node = loop.next_tree if end_node is not None: for_loc.append(end_node.lineno) calls = std_ast.find_all('Call') for call in calls: if call.func.id == 'print': for loc in for_loc: if call.func.lineno >= loc: wrong_print_placement = False break if not wrong_print_placement: break if wrong_print_placement: explain('The output of the total rainfall amount is not in the correct place. The total rainfall should be ' 'output only once after the total rainfall has been computed.<br><br><i>(print_9.1)<i></br>') Returns: """ match = find_match("for _item_ in _list_:\n" " pass\n" "print(_total_)") if not match: explain('The output of the total rainfall amount is not in the correct place. The total rainfall should be ' 'output only once after the total rainfall has been computed.<br><br><i>(print_9.1)<i></br>') return True return False
def missing_target_slot_empty(): match = find_match("for _item_ in ___:\n pass") if match: _item_ = match["_item_"].astNode if _item_.id == "___": explain("You must fill in the empty slot in the iteration.<br><br><i>(target_empty)<i></br>") return True return False
def wrong_for_inside_if(): match = find_match("if ___:\n" " for ___ in ___:\n" " pass") if match: explain( 'The iteration should not be inside the decision block.<br><br><i>(for_in_if)<i></br>' ) return True return False
def wrong_accumulator_initialization_9_1(): match = find_match("rainfall_sum = 0") if not match: explain( 'The variable to hold the total value of the rainfall amounts (<code>rainfall_sum</code>) is not ' 'initialized properly.<br><br><i>(accu_init_9.1)<i></br>') return True return False
def wrong_duplicate_var_in_add(): match = find_match("_item_ + _item_") if match: explain( 'You are adding the same variable twice; you need two different variables in your addition.' '<br><br><i>(dup_var)<i></br>') return True return False
def prevent_advanced_iteration(): ast = parse_program() if ast.find_all('While'): explain("You should not use a <code>while</code> loop to solve this problem." "<br><br><i>(while_usage)<i>") prevent_builtin_usage(['sum', 'map', 'filter', 'reduce', 'len', 'max', 'min', 'max', 'sorted', 'all', 'any', 'getattr', 'setattr', 'eval', 'exec', 'iter'])
def wrong_for_inside_if(): match = find_match("if ___:\n" " for ___ in ___:\n" " pass") if match: explain('The iteration should not be inside the decision block.<br><br><i>(for_in_if)<i></br>') return True return False
def list_not_initialized_on_run(): match = find_match("for ___ in _item_:\n pass") if match: _item_ = match["_item_"][0].astNode if def_use_error(_item_): explain("The list in your for loop has not been initialized<br><br><i>(no_list_init)<i></br>") return True return False
def wrong_iteration_body_8_3(): match = find_match("for _item_ in _list_:\n" " sum_length = ___ + ___\n") if not match: explain('The addition of each episode length to the total length is not in the correct place.<br><br><i>' '(iter_body_8.3)<i></br>') return True return False
def missing_for_slot_empty(): match = find_match("for _item_ in _list_:\n pass") if match: _item_ = match["_item_"][0].astNode _list_ = match["_list_"][0].astNode if _item_.id == "___" or _list_.id == "___": explain("You must fill in the empty slot in the iteration.<br><br><i>(for_incomplete)<i></br>") return True return False
def list_initialization_misplaced(): match = find_match("for ___ in _item_:\n pass") if match: _item_ = match["_item_"][0].astNode if data_state(_item_).was_type('list') and def_use_error(_item_): explain("Initialization of <code>{0!s}</code> is a list but either in the wrong place or redefined" "<br><br><i>(list_init_misplaced)<i></br>".format(_item_.id)) return True return False
def wrong_list_repeated_in_for(): match = find_match("for _item_ in _item_:\n pass") if match: _item_ = match["_item_"].astNode if data_state(_item_).was_type('list'): explain('The <code>{0!s}</code> variable can only appear once in the "for" block <br><br><i>' '(list_repeat)<i></br>'.format(_item_.id)) return True return False
def wrong_target_is_list(): match = find_match("for _item_ in ___:\n pass") if match: _item_ = match["_item_"].astNode if data_state(_item_).was_type('list'): explain('The variable <code>{0!s}</code> is a list and should not be placed in the iteration variable slot' ' of the "for" block<br><br><i>(target_is_list)<i></br>.'.format(_item_.id)) return True return False
def wrong_iterator_not_list(): match = find_match("for ___ in _item_:\n pass") if match: _item_ = match["_item_"].astNode if not data_state(_item_).was_type('list'): explain("The variable <code>{0!s}</code> has been set to something that is not a list but is placed in the " "iteration block that must be a list.<br><br><i>(iter_not_list)<i></br>".format(_item_.id)) return True return False
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
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
def wrong_iteration_body_8_3(): match = find_match("for _item_ in _list_:\n" " sum_length = ___ + ___\n") if not match: explain( 'The addition of each episode length to the total length is not in the correct place.<br><br><i>' '(iter_body_8.3)<i></br>') return True return False
def wrong_print_9_2(): match = find_match("for _item_ in _list_:\n" " pass\n" "print(_total_)") if not match: explain( 'The output of the total number of days with rainfall is not in the correct place. The total number of ' 'days should be output only once after the total number of days has been computed.<br><br><i>' '(print_9.2)<i></br>') return True return False
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
def wrong_print_8_3(): match = find_match("for _item_ in _list_:\n" " pass\n" "print(_total_)") if not match: explain( 'The output of the total length of time is not in the correct place. The total length of time should be' ' output only once after the total length of time has been computed.<br><br><i>(print_8.3)<i></br>' ) return True return False
def wrong_print_8_3(): match = find_match("for _item_ in _list_:\n" " pass\n" "print(_total_)") if not match: explain('The output of the total length of time is not in the correct place. The total length of time should be' ' output only once after the total length of time has been computed.<br><br><i>(print_8.3)<i></br>') return True return False
def wrong_list_initialization_placement_9_1(): match = find_match("rainfall_list = ___\n" "for _item_ in _list_:\n" " pass") if not match: explain('The list of rainfall amount (<code>rainfall_list</code>) must be initialized before the iteration that' ' uses this list.<br><br><i>(list_init_place_9.1)<i></br>') return True return False
def prevent_advanced_iteration(): ast = parse_program() if ast.find_all('While'): explain( "You should not use a <code>while</code> loop to solve this problem." "<br><br><i>(while_usage)<i>") prevent_builtin_usage([ 'sum', 'map', 'filter', 'reduce', 'len', 'max', 'min', 'max', 'sorted', 'all', 'any', 'getattr', 'setattr', 'eval', 'exec', 'iter' ])
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
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
def wrong_print_9_2(): match = find_match("for _item_ in _list_:\n" " pass\n" "print(_total_)") if not match: explain('The output of the total number of days with rainfall is not in the correct place. The total number of ' 'days should be output only once after the total number of days has been computed.<br><br><i>' '(print_9.2)<i></br>') return True return False
def wrong_list_initialization_9_1(): match = find_match( 'rainfall_list = weather.get("Precipitation","Location","Blacksburg, VA")' ) if not match: explain( 'The list of rainfall amounts (<code>rainfall_list</code>) is not initialized properly.' '<br><br><i>(list_init_9.1)<i></br>') return True return False
def wrong_list_initialization_placement_9_1(): match = find_match("rainfall_list = ___\n" "for _item_ in _list_:\n" " pass") if not match: explain( 'The list of rainfall amount (<code>rainfall_list</code>) must be initialized before the iteration that' ' uses this list.<br><br><i>(list_init_place_9.1)<i></br>') return True return False