instructor_append.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from instructor_utility import *
  2. def append_group_on_change():
  3. wrong_not_append_to_list()
  4. def append_group():
  5. missing_append_in_iteration()
  6. missing_append_list_initialization()
  7. wrong_append_list_initiatization()
  8. wrong_not_append_to_list()
  9. append_list_wrong_slot()
  10. def find_append_in(node):
  11. appendList = []
  12. calls = node.find_all("Call")
  13. for node in calls:
  14. if node.func.attr == "append":
  15. appendList.append(node)
  16. return appendList
  17. def missing_append_in_iteration():
  18. ast = parse_program()
  19. for_loops = ast.find_all("For")
  20. for loop in for_loops:
  21. if len(find_append_in(loop)):
  22. return False
  23. explain("You must construct a list by appending values one at a time to the list.<br><br><i>(app_in_iter)<i></br>")
  24. return True
  25. def wrong_not_append_to_list():
  26. ast = parse_program()
  27. for_loops = ast.find_all("For")
  28. for loop in for_loops:
  29. append_nodes = find_append_in(loop)
  30. for node in append_nodes:
  31. listNode = node.func.value
  32. if listNode.data_type != "List" and listNode.id != "___":
  33. explain("Values can only be appended to a list. The variable <code>{0!s}</code> is either not initialized, not initialized correctly, or is confused with another variable.<br><br><i>(app_not_list)<i></br>".format(listNode.id))
  34. def missing_append_list_initialization():
  35. ast = parse_program()
  36. for_loops = ast.find_all("For")
  37. loop_appends = []
  38. for loop in for_loops:
  39. loop_appends.extend(find_append_in(loop));
  40. assignments = ast.find_all("Assign")
  41. for append_call in loop_appends:
  42. append_loc = append_call.lineno
  43. append_var = append_call.func.value
  44. found_init = False
  45. for assignment in assignments:
  46. if assignment.has(append_var) and assignment.lineno < append_loc:
  47. found_init = True
  48. break
  49. if found_init == False and append_var.id != "___":
  50. explain("The list variable <code>{0!s}</code> must be initialized.<br><br><i>(no_app_list_init)<i></br>".format(append_var.id))
  51. return True
  52. return False
  53. def wrong_append_list_initiatization():
  54. ast = parse_program()
  55. for_loops = ast.find_all("For")
  56. loop_appends = []
  57. for loop in for_loops:
  58. loop_appends.extend(find_append_in(loop));
  59. assignments = ast.find_all("Assign")
  60. for append_call in loop_appends:
  61. append_loc = append_call.lineno
  62. append_var = append_call.func.value
  63. init_fail = False
  64. for assignment in assignments:
  65. if assignment.has(append_var) and assignment.lineno < append_loc:
  66. if assignment.value.ast_name == "List":
  67. if len(assignment.value.elts) != 0:
  68. init_fail = True
  69. else:#or if its not even a list
  70. init_fail = True
  71. if init_fail and append_var.id != "___":
  72. explain("The list variable <code>{0!s}</code> is either not initialized correctly or mistaken for another variable. The list you append to should be initialized to an empty list.<br><br><i>(app_list_init)<i></br>".format(append_var.id))
  73. return
  74. def append_list_wrong_slot():
  75. ast = parse_program()
  76. append_calls = find_append_in(ast)
  77. for append_call in append_calls:
  78. arg = append_call.args[0]
  79. caller = append_call.func.value
  80. if arg.ast_name == "Name":
  81. if arg.data_type == "List" and caller.id != "___":
  82. 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(arg.id, caller.id))