canezzy

Untitled

Mar 29th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.52 KB | None | 0 0
  1. # autograder.py
  2. # -------------
  3. # Licensing Information: You are free to use or extend these projects for
  4. # educational purposes provided that (1) you do not distribute or publish
  5. # solutions, (2) you retain this notice, and (3) you provide clear
  6. # attribution to UC Berkeley, including a link to http://ai.berkeley.edu.
  7. #
  8. # Attribution Information: The Pacman AI projects were developed at UC Berkeley.
  9. # The core projects and autograders were primarily created by John DeNero
  10. # Student side autograding was added by Brad Miller, Nick Hay, and
  11. # Pieter Abbeel ([email protected]).
  12.  
  13.  
  14. # imports from python standard library
  15. import grading
  16. import imp
  17. import optparse
  18. import os
  19. import re
  20. import sys
  21. import projectParams
  22. import random
  23. random.seed(0)
  24. try:
  25. from pacman import GameState
  26. except:
  27. pass
  28.  
  29. # register arguments and set default values
  30. def readCommand(argv):
  31. parser = optparse.OptionParser(description = 'Run public tests on student code')
  32. parser.set_defaults(generateSolutions=False, edxOutput=False, gsOutput=False, muteOutput=False, printTestCase=False, noGraphics=False)
  33. parser.add_option('--test-directory',
  34. dest = 'testRoot',
  35. default = 'test_cases',
  36. help = 'Root test directory which contains subdirectories corresponding to each question')
  37. parser.add_option('--student-code',
  38. dest = 'studentCode',
  39. default = projectParams.STUDENT_CODE_DEFAULT,
  40. help = 'comma separated list of student code files')
  41. parser.add_option('--code-directory',
  42. dest = 'codeRoot',
  43. default = "",
  44. help = 'Root directory containing the student and testClass code')
  45. parser.add_option('--test-case-code',
  46. dest = 'testCaseCode',
  47. default = projectParams.PROJECT_TEST_CLASSES,
  48. help = 'class containing testClass classes for this project')
  49. parser.add_option('--generate-solutions',
  50. dest = 'generateSolutions',
  51. action = 'store_true',
  52. help = 'Write solutions generated to .solution file')
  53. parser.add_option('--edx-output',
  54. dest = 'edxOutput',
  55. action = 'store_true',
  56. help = 'Generate edX output files')
  57. parser.add_option('--gradescope-output',
  58. dest = 'gsOutput',
  59. action = 'store_true',
  60. help = 'Generate GradeScope output files')
  61. parser.add_option('--mute',
  62. dest = 'muteOutput',
  63. action = 'store_true',
  64. help = 'Mute output from executing tests')
  65. parser.add_option('--print-tests', '-p',
  66. dest = 'printTestCase',
  67. action = 'store_true',
  68. help = 'Print each test case before running them.')
  69. parser.add_option('--test', '-t',
  70. dest = 'runTest',
  71. default = None,
  72. help = 'Run one particular test. Relative to test root.')
  73. parser.add_option('--question', '-q',
  74. dest = 'gradeQuestion',
  75. default = None,
  76. help = 'Grade one particular question.')
  77. parser.add_option('--no-graphics',
  78. dest = 'noGraphics',
  79. action = 'store_true',
  80. help = 'No graphics display for pacman games.')
  81.  
  82. parser.add_option('-l', '--layout', dest='layout',
  83. help='the LAYOUT_FILE from which to load the map layout',
  84. metavar='LAYOUT_FILE', default='mediumClassic')
  85. parser.add_option('-a', '--pacman', dest='pacman',
  86. help='the agent TYPE in the pacmanAgents module to use',
  87. metavar='TYPE', default='KeyboardAgent')
  88.  
  89. parser.add_option('--check', dest="check")
  90.  
  91. (options, args) = parser.parse_args(argv)
  92. return options
  93.  
  94.  
  95. # confirm we should author solution files
  96. def confirmGenerate():
  97. print 'WARNING: this action will overwrite any solution files.'
  98. print 'Are you sure you want to proceed? (yes/no)'
  99. while True:
  100. ans = sys.stdin.readline().strip()
  101. if ans == 'yes':
  102. break
  103. elif ans == 'no':
  104. sys.exit(0)
  105. else:
  106. print 'please answer either "yes" or "no"'
  107.  
  108.  
  109. # TODO: Fix this so that it tracebacks work correctly
  110. # Looking at source of the traceback module, presuming it works
  111. # the same as the intepreters, it uses co_filename. This is,
  112. # however, a readonly attribute.
  113. def setModuleName(module, filename):
  114. functionType = type(confirmGenerate)
  115. classType = type(optparse.Option)
  116.  
  117. for i in dir(module):
  118. o = getattr(module, i)
  119. if hasattr(o, '__file__'): continue
  120.  
  121. if type(o) == functionType:
  122. setattr(o, '__file__', filename)
  123. elif type(o) == classType:
  124. setattr(o, '__file__', filename)
  125. # TODO: assign member __file__'s?
  126. #print i, type(o)
  127.  
  128.  
  129. #from cStringIO import StringIO
  130.  
  131. def loadModuleString(moduleSource):
  132. # Below broken, imp doesn't believe its being passed a file:
  133. # ValueError: load_module arg#2 should be a file or None
  134. #
  135. #f = StringIO(moduleCodeDict[k])
  136. #tmp = imp.load_module(k, f, k, (".py", "r", imp.PY_SOURCE))
  137. tmp = imp.new_module(k)
  138. exec moduleCodeDict[k] in tmp.__dict__
  139. setModuleName(tmp, k)
  140. return tmp
  141.  
  142. import py_compile
  143.  
  144. def loadModuleFile(moduleName, filePath):
  145. with open(filePath, 'r') as f:
  146. return imp.load_module(moduleName, f, "%s.py" % moduleName, (".py", "r", imp.PY_SOURCE))
  147.  
  148.  
  149. def readFile(path, root=""):
  150. "Read file from disk at specified path and return as string"
  151. with open(os.path.join(root, path), 'r') as handle:
  152. return handle.read()
  153.  
  154.  
  155. #######################################################################
  156. # Error Hint Map
  157. #######################################################################
  158.  
  159. # TODO: use these
  160. ERROR_HINT_MAP = {
  161. 'q1': {
  162. "<type 'exceptions.IndexError'>": """
  163. We noticed that your project threw an IndexError on q1.
  164. While many things may cause this, it may have been from
  165. assuming a certain number of successors from a state space
  166. or assuming a certain number of actions available from a given
  167. state. Try making your code more general (no hardcoded indices)
  168. and submit again!
  169. """
  170. },
  171. 'q3': {
  172. "<type 'exceptions.AttributeError'>": """
  173. We noticed that your project threw an AttributeError on q3.
  174. While many things may cause this, it may have been from assuming
  175. a certain size or structure to the state space. For example, if you have
  176. a line of code assuming that the state is (x, y) and we run your code
  177. on a state space with (x, y, z), this error could be thrown. Try
  178. making your code more general and submit again!
  179.  
  180. """
  181. }
  182. }
  183.  
  184. import pprint
  185.  
  186. def splitStrings(d):
  187. d2 = dict(d)
  188. for k in d:
  189. if k[0:2] == "__":
  190. del d2[k]
  191. continue
  192. if d2[k].find("\n") >= 0:
  193. d2[k] = d2[k].split("\n")
  194. return d2
  195.  
  196.  
  197. def printTest(testDict, solutionDict):
  198. pp = pprint.PrettyPrinter(indent=4)
  199. print "Test case:"
  200. for line in testDict["__raw_lines__"]:
  201. print " |", line
  202. print "Solution:"
  203. for line in solutionDict["__raw_lines__"]:
  204. print " |", line
  205.  
  206.  
  207. def runTest(testName, moduleDict, printTestCase=False, display=None):
  208. import testParser
  209. import testClasses
  210. for module in moduleDict:
  211. setattr(sys.modules[__name__], module, moduleDict[module])
  212.  
  213. testDict = testParser.TestParser(testName + ".test").parse()
  214. solutionDict = testParser.TestParser(testName + ".solution").parse()
  215. test_out_file = os.path.join('%s.test_output' % testName)
  216. testDict['test_out_file'] = test_out_file
  217. testClass = getattr(projectTestClasses, testDict['class'])
  218.  
  219. questionClass = getattr(testClasses, 'Question')
  220. question = questionClass({'max_points': 0}, display)
  221. testCase = testClass(question, testDict)
  222.  
  223. if printTestCase:
  224. printTest(testDict, solutionDict)
  225.  
  226. # This is a fragile hack to create a stub grades object
  227. grades = grading.Grades(projectParams.PROJECT_NAME, [(None,0)])
  228. testCase.execute(grades, moduleDict, solutionDict)
  229.  
  230.  
  231. # returns all the tests you need to run in order to run question
  232. def getDepends(testParser, testRoot, question):
  233. allDeps = [question]
  234. questionDict = testParser.TestParser(os.path.join(testRoot, question, 'CONFIG')).parse()
  235. if 'depends' in questionDict:
  236. depends = questionDict['depends'].split()
  237. for d in depends:
  238. # run dependencies first
  239. allDeps = getDepends(testParser, testRoot, d) + allDeps
  240. return allDeps
  241.  
  242. # get list of questions to grade
  243. def getTestSubdirs(testParser, testRoot, questionToGrade):
  244. problemDict = testParser.TestParser(os.path.join(testRoot, 'CONFIG')).parse()
  245. if questionToGrade != None:
  246. questions = getDepends(testParser, testRoot, questionToGrade)
  247. if len(questions) > 1:
  248. print 'Note: due to dependencies, the following tests will be run: %s' % ' '.join(questions)
  249. return questions
  250. if 'order' in problemDict:
  251. return problemDict['order'].split()
  252. return sorted(os.listdir(testRoot))
  253.  
  254.  
  255. # evaluate student code
  256. def evaluate(generateSolutions, testRoot, moduleDict, exceptionMap=ERROR_HINT_MAP,
  257. edxOutput=False, muteOutput=False, gsOutput=False,
  258. printTestCase=False, questionToGrade=None, display=None):
  259. # imports of testbench code. note that the testClasses import must follow
  260. # the import of student code due to dependencies
  261. import testParser
  262. import testClasses
  263. for module in moduleDict:
  264. setattr(sys.modules[__name__], module, moduleDict[module])
  265.  
  266. questions = []
  267. questionDicts = {}
  268. test_subdirs = getTestSubdirs(testParser, testRoot, questionToGrade)
  269. for q in test_subdirs:
  270. subdir_path = os.path.join(testRoot, q)
  271. if not os.path.isdir(subdir_path) or q[0] == '.':
  272. continue
  273.  
  274. # create a question object
  275. questionDict = testParser.TestParser(os.path.join(subdir_path, 'CONFIG')).parse()
  276. questionClass = getattr(testClasses, questionDict['class'])
  277. question = questionClass(questionDict, display)
  278. questionDicts[q] = questionDict
  279.  
  280. # load test cases into question
  281. tests = filter(lambda t: re.match('[^#~.].*\.test\Z', t), os.listdir(subdir_path))
  282. tests = map(lambda t: re.match('(.*)\.test\Z', t).group(1), tests)
  283. for t in sorted(tests):
  284. test_file = os.path.join(subdir_path, '%s.test' % t)
  285. solution_file = os.path.join(subdir_path, '%s.solution' % t)
  286. test_out_file = os.path.join(subdir_path, '%s.test_output' % t)
  287. testDict = testParser.TestParser(test_file).parse()
  288. if testDict.get("disabled", "false").lower() == "true":
  289. continue
  290. testDict['test_out_file'] = test_out_file
  291. testClass = getattr(projectTestClasses, testDict['class'])
  292. testCase = testClass(question, testDict)
  293. def makefun(testCase, solution_file):
  294. if generateSolutions:
  295. # write solution file to disk
  296. return lambda grades: testCase.writeSolution(moduleDict, solution_file)
  297. else:
  298. # read in solution dictionary and pass as an argument
  299. testDict = testParser.TestParser(test_file).parse()
  300. solutionDict = testParser.TestParser(solution_file).parse()
  301. if printTestCase:
  302. return lambda grades: printTest(testDict, solutionDict) or testCase.execute(grades, moduleDict, solutionDict)
  303. else:
  304. return lambda grades: testCase.execute(grades, moduleDict, solutionDict)
  305. question.addTestCase(testCase, makefun(testCase, solution_file))
  306.  
  307. # Note extra function is necessary for scoping reasons
  308. def makefun(question):
  309. return lambda grades: question.execute(grades)
  310. setattr(sys.modules[__name__], q, makefun(question))
  311. questions.append((q, question.getMaxPoints()))
  312.  
  313. grades = grading.Grades(projectParams.PROJECT_NAME, questions,
  314. gsOutput=gsOutput, edxOutput=edxOutput, muteOutput=muteOutput)
  315. if questionToGrade == None:
  316. for q in questionDicts:
  317. for prereq in questionDicts[q].get('depends', '').split():
  318. grades.addPrereq(q, prereq)
  319.  
  320. grades.grade(sys.modules[__name__], bonusPic = projectParams.BONUS_PIC)
  321. return grades.points
  322.  
  323.  
  324.  
  325. def getDisplay(graphicsByDefault, options=None):
  326. graphics = graphicsByDefault
  327. if options is not None and options.noGraphics:
  328. graphics = False
  329. if graphics:
  330. try:
  331. import graphicsDisplay
  332. return graphicsDisplay.PacmanGraphics(1, frameTime=.05)
  333. except ImportError:
  334. pass
  335. import textDisplay
  336. return textDisplay.NullGraphics()
  337.  
  338.  
  339.  
  340. from search import nullHeuristic
  341. from util import PriorityQueue
  342. from pacman import loadAgent, runGames
  343.  
  344. class SeachTreeNode:
  345.  
  346. def __init__(self, state, action, cost, parent):
  347. self.state = state
  348. self.action = action
  349. self.cost = cost
  350. self.parent = parent
  351.  
  352. def isConsistent(problem, heuristic=nullHeuristic):
  353. visisted = []
  354. data_structure = PriorityQueue()
  355. root = SeachTreeNode(problem.getStartState(), None, 0, None)
  356. data_structure.push(root, 0)
  357.  
  358. while not data_structure.isEmpty():
  359. node = data_structure.pop()
  360.  
  361. if problem.isGoalState(node.state):
  362. break
  363. elif node.state in visisted:
  364. continue
  365. else:
  366. visisted.append(node.state)
  367. successors = problem.getSuccessors(node.state)
  368. for s in successors:
  369. newNode = SeachTreeNode(s[0], s[1], node.cost + s[2], node)
  370. data_structure.push(newNode, newNode.cost + heuristic(newNode.state, problem))
  371.  
  372. if abs(heuristic(newNode.parent.state, problem) - heuristic(newNode.state, problem)) > s[2]:
  373. print("Heuristic is not consistent!\n")
  374. exit(1)
  375. print("Heuristic is consistent!\n")
  376. exit(1)
  377.  
  378. if __name__ == '__main__':
  379. options = readCommand(sys.argv)
  380. if options.generateSolutions:
  381. confirmGenerate()
  382. codePaths = options.studentCode.split(',')
  383.  
  384. moduleDict = {}
  385. for cp in codePaths:
  386. moduleName = re.match('.*?([^/]*)\.py', cp).group(1)
  387. moduleDict[moduleName] = loadModuleFile(moduleName, os.path.join(options.codeRoot, cp))
  388.  
  389. if options.check == "consistency" and "searchAgents" in moduleDict:
  390. agentType = loadAgent(options.pacman, True)
  391. agent = agentType(**{})
  392. agent.searchFunction = lambda prob: isConsistent(prob, agent.heuristic)
  393.  
  394. import layout as l
  395. # layout, pacman, ghosts, display, numGames, record, numTraining = 0, catchExceptions = False, timeout = 30
  396. runGames(l.getLayout(options.layout), agent, [], None, 1, None, 1)
  397. exit(1)
Advertisement
Add Comment
Please, Sign In to add comment