post_test_feedbackAPI.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import ins_test_8_5 as stm85
  2. from instructor import*
  3. #for each problem
  4. def m_itergrp_2():
  5. stm85.m_list_initialization_misplaced()#list_init_misplaced
  6. stm85.m_wrong_target_is_list()#target_is_list
  7. stm85.m_wrong_list_repeated_in_for()#list_repeat#should be moved before target_is_list
  8. stm85.m_missing_iterator_initialization()#no_iter_init,no_iter_init-blank
  9. stm85.m_list_not_initialized_on_run()#no_list_init
  10. stm85.m_wrong_iterator_not_list()#iter_not_list
  11. stm85.m_missing_target_slot_empty()#target_empty
  12. stm85.m_missing_for_slot_empty()#for_incomplete
  13. def missing_addition_slot_empty():
  14. matches = find_matches("___ = __exp1__ + __exp2__")
  15. if matches:
  16. for match in matches:
  17. __exp1__ = match.get_std_exp("__exp1__")
  18. __exp2__ = match.get_std_exp("__exp2__")
  19. cond1 = __exp1__.ast_name == "Name" and __exp1__.id == '___'
  20. cond2 = __exp2__.ast_name == "Name" and __exp2__.id == '___'
  21. if cond1 or cond2:
  22. explain('You must fill in the empty slot in the addition.<br><br><i>(add_empty)<i></br>')
  23. return True
  24. return False
  25. def wrong_compare_list():
  26. matches = find_matches("for ___ in _list_:\n if __exp__:\n pass")
  27. if matches:
  28. for match in matches:
  29. _list_ = match.get_std_name("_list_")
  30. __exp__ = match.get_std_exp("__exp__")
  31. if __exp__.has(_list_):
  32. explain('Each item in the list <code>{0!s}</code> must be compared one item at a time.<br><br><i>(comp_list)<i></br>'.format(_list_.id))
  33. return True
  34. return False
  35. def wrong_for_inside_if():#for the actual specification, we don't cover this syntax
  36. match = find_match("if ___:\n for ___ in ___:\n pass")
  37. if match:
  38. explain('The iteration should not be inside the decision block.<br><br><i>(for_in_if)<i></br>')
  39. return True
  40. return False
  41. def missing_if_in_for():#interesting case we don't cover exactly regarding syntax of specification
  42. matches = find_matches("for _item_ in ___:\n if __exp__:\n pass")
  43. if matches:
  44. for match in matches:
  45. _item_ = match.get_std_name("_item_")
  46. __exp__ = match.get_std_exp("__exp__")
  47. if not (match and __exp__.has(_item_)):
  48. explain("The arrangement of decision and iteration is not correct for the filter pattern.<br><br><i>(missing_if_in_for)<i></br>")
  49. return True
  50. else:
  51. explain("The arrangement of decision and iteration is not correct for the filter pattern.<br><br><i>(missing_if_in_for)<i></br>")
  52. return True
  53. return False
  54. def wrong_should_be_counting():
  55. match = find_match("for _item_ in ___:\n ___ = ___ + _item_")
  56. if match:
  57. 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>')
  58. return True
  59. return False
  60. def missing_counting_list():
  61. match = find_match("for ___ in ___:\n _sum_ = _sum_ + 1")
  62. if not match:
  63. explain('Count the total number of items in the list using iteration.<br><br><i>(miss_count_list)<i></br>')
  64. return True
  65. return False
  66. def missing_append_in_iteration():#TODO: implement matcher function that takes an AST node!
  67. match = find_match("for ___ in ___:\n ___.append(___)")
  68. if not match:
  69. explain("You must construct a list by appending values one at a time to the list.<br><br><i>(app_in_iter)<i></br>")
  70. return True
  71. return False
  72. def missing_append_list_initialization():
  73. matches = find_matches("for ___ in ___:\n _target_.append(___)")
  74. if matches:
  75. for match in matches:
  76. _target_ = match.get_std_name("_target_")
  77. if def_use_error(_target_):
  78. explain("The list variable <code>{0!s}</code> must be initialized.<br><br><i>(no_app_list_init)<i></br>".format(_target_.id))
  79. return True
  80. return False
  81. def wrong_append_list_initiatization():
  82. matches = find_matches("for ___ in ___:\n _target_.append(___)")
  83. if matches:
  84. for match in matches:
  85. _target_ = match.get_std_name("_target_")
  86. found = find_match("{0!s} = []".format(_target_.id))#This doesn't work because it uses the raw name, and doesn't save to the symbol table
  87. if found:
  88. _target_2 = found.get_std_name("_target_")
  89. if (not found) or _target_2.lineno >= _target_.lineno:#in theory, should use first body of both instead of lineno
  90. 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(_target_.id))
  91. return True
  92. return False
  93. def wrong_not_append_to_list():
  94. matches = find_matches("for ___ in ___:\n _target_.append(___)")
  95. if matches:
  96. for match in matches:
  97. _target_ = match.get_std_name("_target_")
  98. if _target_.data_type != "List" and _target_.id != "___":
  99. 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(_target_.id))
  100. return True
  101. return False
  102. def append_list_wrong_slot():
  103. matches = find_matches("_target_.append(_item_)")
  104. if matches:
  105. for match in matches:
  106. _item_ = match.get_std_name("_item_")
  107. _target_ = match.get_std_name("_target_")
  108. if _item_.data_type == "List":
  109. 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))
  110. return True
  111. return False
  112. def histogram_argument_not_list():
  113. matches = find_matches("plt.hist(_argument_)")
  114. if matches:
  115. for match in matches:
  116. _argument_ = match.get_std_name("_argument_")
  117. if _argument_.data_type != "List":
  118. if _argument_.id == "___":
  119. explain("Making a histogram requires a list; the list is missing.<br><br><i>(hist_arg_not_list_blank)<i></br>")
  120. return True
  121. else:
  122. explain("Making a histogram requires a list; <code>{0!s}</code> is not a list.<br><br><i>(hist_arg_not_list)<i></br>".format(_argument_.id))
  123. return True
  124. return False
  125. def histogram_wrong_list():
  126. matches = find_matches("for ___ in ___:\n _target_.append(___)\nplt.hist(_list_)")
  127. if matches:
  128. for match in matches:
  129. _target_ = match.get_std_name("_target_")
  130. _list_ = match.get_std_name("_list_")
  131. if _target_.id != _list_.id:
  132. 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>")
  133. return True
  134. return False
  135. def histogram_missing():
  136. match = find_match("plt.hist(___)")
  137. if not match:
  138. explain("The program should display a histogram.<br><br><i>(histo_missing)<i></br>")
  139. return True
  140. return False
  141. def plot_show_missing():
  142. match = find_match("plt.show()")
  143. if not match:
  144. explain("The plot must be explicitly shown to appear in the Printer area.<br><br><i>(plot_show_missing)<i></br>")
  145. return True
  146. return False
  147. def m_append_group():
  148. missing_append_in_iteration()
  149. missing_append_list_initialization()
  150. wrong_append_list_initiatization()
  151. wrong_not_append_to_list()
  152. append_list_wrong_slot()
  153. def m_histogram_group():
  154. histogram_argument_not_list()
  155. histogram_wrong_list()
  156. histogram_missing()
  157. plot_show_missing()