from instructor_utility import *
def append_group_on_change():
wrong_not_append_to_list()
def append_group():
missing_append_in_iteration()
missing_append_list_initialization()
wrong_append_list_initiatization()
wrong_not_append_to_list()
append_list_wrong_slot()
def find_append_in(node):
appendList = []
calls = node.find_all("Call")
for node in calls:
if node.func.attr == "append":
appendList.append(node)
return appendList
def missing_append_in_iteration():
ast = parse_program()
for_loops = ast.find_all("For")
for loop in for_loops:
if len(find_append_in(loop)):
return False
explain("You must construct a list by appending values one at a time to the list.
(app_in_iter)")
return True
def wrong_not_append_to_list():
ast = parse_program()
for_loops = ast.find_all("For")
for loop in for_loops:
append_nodes = find_append_in(loop)
for node in append_nodes:
listNode = node.func.value
if listNode.data_type != "List" and listNode.id != "___":
explain("Values can only be appended to a list. The variable {0!s} is either not initialized, not initialized correctly, or is confused with another variable.
(app_not_list)".format(listNode.id))
def missing_append_list_initialization():
ast = parse_program()
for_loops = ast.find_all("For")
loop_appends = []
for loop in for_loops:
loop_appends.extend(find_append_in(loop));
assignments = ast.find_all("Assign")
for append_call in loop_appends:
append_loc = append_call.lineno
append_var = append_call.func.value
found_init = False
for assignment in assignments:
if assignment.has(append_var) and assignment.lineno < append_loc:
found_init = True
break
if found_init == False and append_var.id != "___":
explain("The list variable {0!s} must be initialized.
(no_app_list_init)".format(append_var.id))
return True
return False
def wrong_append_list_initiatization():
ast = parse_program()
for_loops = ast.find_all("For")
loop_appends = []
for loop in for_loops:
loop_appends.extend(find_append_in(loop));
assignments = ast.find_all("Assign")
for append_call in loop_appends:
append_loc = append_call.lineno
append_var = append_call.func.value
init_fail = False
for assignment in assignments:
if assignment.has(append_var) and assignment.lineno < append_loc:
if assignment.value.ast_name == "List":
if len(assignment.value.elts) != 0:
init_fail = True
else:#or if its not even a list
init_fail = True
if init_fail and append_var.id != "___":
explain("The list variable {0!s} is either not initialized correctly or mistaken for another variable. The list you append to should be initialized to an empty list.
(app_list_init)".format(append_var.id))
return
def append_list_wrong_slot():
ast = parse_program()
append_calls = find_append_in(ast)
for append_call in append_calls:
arg = append_call.args[0]
caller = append_call.func.value
if arg.ast_name == "Name":
if arg.data_type == "List" and caller.id != "___":
explain("You should not append a list ({0!s}) to {1!s}.
(app_list_slot)".format(arg.id, caller.id))