Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from Bowl import *
- from Dish import *
- from
- def statement_contains(s, l):
- """Checks to see if s (a list of words) contains an element in l"""
- ####### {v : v \in s AND v \in l} != {}
- return [v for v in s if v in l] != []
- def d(s="BUTTS"):
- #raw_input(s)
- pass
- def ordinal(s):
- """Gets a number from a standard ordinal.
- >>> ordinal("15th")
- 15
- >>> ordinal("34st")
- None
- >>> ordinal("foobar")
- None
- """
- if not s[:-2].isdigit():
- return None
- value = int(s[:-2])
- v = int(s[-3])
- th = s[-2:]
- if v is 1 and th == 'st' or v is 2 and th == 'nd' or v is 3 and th == 'rd' or th == 'th':
- return value
- return None
- ordinals_in_recipe = []
- def ordinalused(s):
- if (ordinals_in_recipe.count(s)>0):
- return False
- else:
- ordinals_in_recipe.append(s)
- return True
- poptart = []
- def ordinalusedDish(s):
- if (poptart.count(s)>0):
- return False
- else:
- poptart.append(s)
- return True
- class Kitchen:
- """A facility for interpreting the esoteric language 'Chef'."""
- class Error(Exception):
- def __init__(self, title, message):
- self.title = title
- self.message = message
- def createMB(self):
- self.mixing_bowls.append(Bowl())
- def createDH(self):
- from Dish import Dish
- self.baking_dishes.append(Dish())
- def _print_(self):
- for dish in self.baking_dishes:
- self.stdout.extend(dish.serve())
- def __init__(self, recipe="", master=None):
- """Constructor
- Initializes lists for mixing bowls and baking dishes and
- begins evaluating the recipe (taken in as a string).
- """
- self.foods = list()
- with open('food.txt', 'r') as f:
- for line in f:
- self.foods.append(line[:-1])
- if master is None:
- from collections import deque
- self.ingredients = dict() # contains a dictionary of ingredients
- self.mixing_bowls = list() # list of mixing bowls, stack-style
- self.baking_dishes = list() # list of baking dishes, stack-style
- self.stdin = deque() # Our very own stdin! So we *could* take in more than one character at a time from what the user sees
- self.stdout = deque() # Well, if we have an stdin, might as well have an stdout. May make life easier.
- self.history = list() # Contains a list (stack) of (func, arg) tuples, most-recent last. Useful for looping.
- #handles a copy constructor
- elif hasattr(master, 'ingredients') and hasattr(master, 'mixing_bowls') and hasattr(master, 'baking_dishes') and hasattr(master, 'stdin') and hasattr(master, 'stdout') and hasattr(master, 'history'):
- self.ingredients = master.ingredients
- self.mixing_bowls = master.mixing_bowls
- self.baking_dishes = master.baking_dishes
- self.stdin = master.stdin
- self.stdout = master.stdout
- def do(self, statements):
- """Does arbitrary operations from a list of valid Chef strings
- The command must be the first word, case sensitive.
- If the command does not exist, None is returned.
- The rest of the string is passed to the desired function as a list.
- Author: Sean
- """
- def is_start_verb_statement(li):
- cond1 = len(li) == 3 and li[1] == "the" and li[2] in [v + "." for v in self.ingredients]
- return cond1
- def is_end_verb_statement(li):
- cond2 = len(li) == 3 and li[1] == "until"
- cond3 = len(li) == 5 and li[1] == "the" and li[2] in self.ingredients and li[3] == "until"
- return cond2 or cond3
- def nested_verb(l):
- verb = []
- helper = []
- idea = []
- for x in range(len(l)):
- if is_start_verb_statement(l[x].split()):
- helper.append([l[x].split()[0], x])
- verb.append(l[x].split()[0])
- if statement_contains([v.lower() + "ed." for v in verb], l[x].split()):
- idea.append(x)
- idea.reverse()
- for x in range(len(helper)):
- helper[x].append(idea[x])
- """a list of starts
- (verb, start, end)"""
- return helper
- print statements
- verb_starts = nested_verb(statements)
- if not hasattr(statements, 'pop'):
- statements = [statements]
- cmd_index = 0
- my_verbs = list()
- while cmd_index < len(statements):
- cmd = statements[cmd_index]
- cmd_index += 1
- t = cmd.split()
- ##t[-1] = t[-1][0:len(t[-1])-1]
- try:
- if cmd == ["Ingredients."]:
- self._do_ingredients()
- elif len(t) < 2:
- raise Exception("Syntax Error: Commands must have at least two tokens.")
- elif hasattr(self, t[0]):
- getattr(self, t[0])(t[1:])
- elif is_start_verb_statement(t): # the word may be a verb
- # Test to see if we should continue (if the mentioned ingredient is not zero)
- # if it is, set cmd index to its end and continue
- # remove the trailing period from the ingredient name
- t[-1] = t[-1][0:len(t[-1])-1]
- if(self.ingredients[t[2]]==0):
- cmd_index = len(cmd_index-1)
- else:
- continue
- print "verby"
- elif is_end_verb_statement(t):
- print "end verby!"
- #decrement the ingredient if given and then reset the cmd index to the verb's start
- else:
- print "No such attribute."
- except KeyError:
- print "That ingredient does not exist!"
- except Exception as message:
- import sys
- sys.excepthook(*sys.exc_info())
- print ""
- print "{m}\a".format(m=message)
- return False
- def _do_ingredients(self):
- """Author: Sean"""
- s = raw_input()
- measures = {"ml":"wet", "l":"wet", "dash":"wet", "dashes":"wet", "g":"dry", "kg":"dry", "pinch":"dry", "pinches":"dry", "cup":None, "cups":None, "teaspoon":None, "teaspoons":None, "tablespoon":None, "tablespoons":None, None:None}
- types = {"heaped":"dry", "level":"dry"}
- while s != "":
- s = self._get_ingredient(s, measures, types)
- self.ingredients[s[0]] = (s[1], s[2])
- s = raw_input()
- def __repr__(self):
- """Author: Sean"""
- return " Ingredients: {ing}\n Mixing Bowls: {mb}\nBaking Dishes: {bd}\n Input Buffer: {ip}\nOutput Buffer: {op}".format(ing=str(self.ingredients), mb=str([str(m) for m in self.mixing_bowls]), bd=str([str(b) for b in self.baking_dishes]), ip=str(self.stdin), op=str(self.stdout))
- # Have this function declare a multidimensional array of strings according to differing degrees of messiness
- # so it can be called
- # ... return arr[len(mixing_bowls) // 5][len(baking_dishes) // 5]
- # or something like that.
- def __str__(self):
- """Author: Sean"""
- return "You see a mess of utensils; you have a lot of work yet to do."
- def _get_bowl(self, s):
- """Returns the mixing bowl specified by this string.
- This method searches the string provided for the mixing bowl needed:
- >>> getDish("Pour the 3rd mixing bowl into the 2nd baking dish.")
- 3
- If no ordinal for a mixing bowl is specified, it defaults to 1:
- >>> getDish("Put zucchinis into the mixing bowl.")
- 1
- If there is no mention of any mixing bowls, this function returns None:
- >>> getDish("I've got poop for brains.")
- None
- Author:
- """
- pass
- return 0
- def _get_dish(self, s):
- """Returns the baking dish specified by this string.
- This method searches the string provided for the baking dish needed:
- >>> getDish("Pour the 3rd mixing bowl into the 2nd baking dish")
- 2
- If no ordinal for a baking dish is specified, it defaults to 1:
- >>> getDish("Pour the 3rd mixing bowl into the baking dish")
- 1
- If there is no mention of any baking dishes, this function returns None:
- >>> getDish("I've got poop for brains.")
- None
- Author:
- """
- pass
- return 0
- def _get_ingredient(self, item, measures, types):
- """Takes exactly one string, a dictionary of valid measures, and a dictionary of valid measure-types and returns (name, value, type)
- Author: Sean
- """
- name = type = value = explicit_type = None
- s = item.split()
- if len(s) < 1:
- raise Exception("Ingredient Error: Blank line encountered.")
- if s[0].isdigit():
- value = int(s[0])
- if statement_contains(s[1:], measures):
- if s[1] in types:
- type = types[s[1]]
- name = s[2:]
- elif s[1] in measures:
- type = measures[s[1]]
- name = s[2:]
- else:
- raise Exception("Ingredient Error: Illegal value or ingredient encountered.")
- else:
- name = s[1:]
- elif s[0] in measures:
- type = measures[s[0]]
- name = s[1:]
- if name == []:
- raise Exception("Ingredient Error: Must specifiy an ingredient name.")
- elif s[0] in types:
- if s[1] in measures:
- type = types[type]
- name = s[2:]
- if name == []:
- raise Exception("Ingredient Error: Must specifiy an ingredient name.")
- else:
- raise Exception("Ingredient Error: Must specifiy measure for type.")
- else:
- name = s
- name = ' '.join(name)
- return (name, value, type)
- def _get_ingredients(self, l):
- """Takes a list l of ingredient-statements and populates the ingredients.
- Author: Sean
- """
- if len(l) < 1:
- raise Exception("Ingredient Error: Must have at least one ingredient.")
- measures = {"ml":"wet", "l":"wet", "dash":"wet", "dashes":"wet", "g":"dry", "kg":"dry", "pinch":"dry", "pinches":"dry", "cup":None, "cups":None, "teaspoon":None, "teaspoons":None, "tablespoon":None, "tablespoons":None, None:None}
- types = {"heaped":"dry", "level":"dry"}
- for item in l:
- ing = self._get_ingredient(item, measures, types)
- self.ingredients[ing[0]] = (ing[1], ing[2])
- def Take(self, s):
- """Take (ingredient) from refrigerator.
- This reads a numeric value from STDIN into
- the ingredient named, overwriting any
- previous value.
- Author: Sean
- """
- def is_food(s):
- return not s.isdigit() and s in self.foods
- ingredient_name = ' '.join(s[:-2])
- if not is_food(ingredient_name):
- raise Exception("Name Error: You can't eat {}".format(repr(ingredient_name)))
- elif s[-1] != "refrigerator." or s[-2] != "from":
- raise Exception("Syntax Error: Take <ingredient> from refrigerator.")
- elif len(self.stdin) is 0:
- _in = raw_input("Press enter after input: ")
- if _in.isdigit(): # if the entire input can be parsed as a single number
- self.stdin.append(int(_in)) # append that number to the buffer
- self.ingredients[ingredient_name][0] = self.stdin.popleft()
- else:
- for char in _in: # otherwise, append the integer value of each character entered to the buffer.
- self.stdin.append(ord(char))
- self.ingredients[ingredient_name][0] = self.stdin.popleft()
- else:
- self.ingredients[ingredient_name] = self.stdin.popleft()
- self.history.append((self.Take, s))
- return True
- def Put(self, s):
- """Put (ingredient) into the [nth] mixing bowl.
- This puts the ingredient into the nth mixing bowl.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0])
- bowl_num = bowl_num-1
- if not (ordinalused(bowl_num)):
- oper = self.ingredients[s[0]][0]
- self.mixing_bowls[bowl_num].put(oper)
- else:
- self.createMB()
- self.mixing_bowls[bowl_num].put(self.ingredients[s[0]][0])
- self.history.append((self.Put, s))
- return True
- def Fold(self, s):
- """Fold (ingredient) into [nth] mixing bowl.
- This removes the top value from the nth mixing bowl and places it in the ingredient.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0])
- bowl_num = bowl_num-1
- if not (ordinalused(bowl_num)):
- oper = self.ingredients[s[0]][0]
- self.ingredients[s[0]][0] = self.mixing_bowls[bowl_num].fold(oper)
- else:
- self.createMB()
- self.mixing_bowls[bowl_num].fold(self.ingredients[s[0]][0])
- self.history.append((self.Fold, s))
- return True
- def Add(self, s):
- """Two uses.
- Add (ingredient) [to [nth] mixing bowl].
- This adds the value of ingredient to the
- value of the ingredient on top of the
- nth mixing bowl and stores the result
- in the nth mixing bowl.
- Add dry ingredients [to [nth] mixing bowl].
- This adds the values of all the dry ingredients
- together and places the result into the
- nth mixing bowl.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0])-1
- d(bowl_num)
- if not (ordinalused(bowl_num)):
- oper = self.ingredients[s[0]][0]
- self.mixing_bowls[bowl_num].add(oper)
- else:
- self.createMB()
- if s[0]=="dry":
- self.mixing_bowls[bowl_num].put(sum([value[0] for ingr, value in self.ingredients.iteritems() if value[1] is 'dry']))
- else:
- self.mixing_bowls[bowl_num].add(self.ingredients[s[0]][0])
- self.history.append((self.Add, s))
- return True
- def Remove(self, s):
- """Remove ingredient [from [nth] mixing bowl].
- This subtracts the value of ingredient from
- the value of the ingredient on top of the
- nth mixing bowl and stores the result in
- the nth mixing bowl.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0]) - 1
- if not (ordinalused(bowl_num)):
- oper = self.ingredients[s[0]][0]
- self.mixing_bowls[bowl_num].remove(oper)
- else:
- self.createMB()
- self.mixing_bowls[bowl_num].remove(self.ingredients[s[0]][0])
- self.history.append((self.Remove, s))
- return True
- def Combine(self, s):
- """Combine ingredient [into [nth] mixing bowl].
- This multiplies the value of ingredient by
- the value of the ingredient on top of
- the nth mixing bowl and stores the result
- in the nth mixing bowl.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0])
- bowl_num = bowl_num-1
- if not (ordinalused(bowl_num)):
- oper = self.ingredients[s[0]][0]
- self.mixing_bowls[bowl_num].combine(oper)
- else:
- self.createMB()
- self.mixing_bowls[bowl_num].combine(self.ingredients[s[0]][0])
- self.history.append((self.Combine, s))
- return True
- def Divide(self, s):
- """Divide ingredient [into [nth] mixing bowl].
- This divides the value of ingredient into
- the value of the ingredient on top of
- the nth mixing bowl and stores the result
- in the nth mixing bowl.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0]) - 1
- if not (ordinalused(bowl_num)):
- oper = self.ingredients[s[0]][0]
- self.mixing_bowls[bowl_num].divide(oper)
- else:
- self.createMB()
- self.mixing_bowls[bowl_num].divide(self.ingredients[s[0]][0])
- self.history.append((self.Divide, s))
- return True
- def Liquefy(self, s):
- """Two uses.
- Liquefy | Liquify ingredient.
- This turns the ingredient into a liquid,
- i.e. a Unicode character for output purposes.
- (Note: The original specification used
- the word "Liquify", which is a spelling
- error. "Liquify" is deprecated.
- Use "Liquefy" in all new code.)
- Liquefy | Liquify contents of the [nth] mixing bowl.
- This turns all the ingredients in the nth mixing bowl
- into a liquid, i.e. a Unicode characters for
- output purposes.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0]) - 1
- if not (ordinalused(bowl_num)):
- self.mixing_bowls[bowl_num].liquify()
- else:
- self.createMB()
- raise Exception("Syntax Error: You're dumb")
- self.history.append((self.Liquefy, s))
- return True
- def Stir(self, s):
- """Two uses.
- Stir [the [nth] mixing bowl] for number minutes.
- This "rolls" the top number ingredients
- in the nth mixing bowl, such that the
- top ingredient goes down that number of
- ingredients and all ingredients above it
- rise one place. If there are not that many
- ingredients in the bowl, the top ingredient
- goes to tbe bottom of the bowl and all
- the others rise one place.
- Stir ingredient into the [nth] mixing bowl.
- This rolls the number of ingredients
- in the nth mixing bowl equal to
- the value of ingredient, such that
- the top ingredient goes down that number
- of ingredients and all ingredients above
- it rise one place. If there are not that
- many ingredients in the bowl, the top
- ingredient goes to tbe bottom of the bowl
- and all the others rise one place.
- """
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0]) - 1
- minutes = int (s[-2])
- if not (ordinalused(bowl_num)):
- self.mixing_bowls[bowl_num].stir(minutes)
- else:
- self.createMB()
- raise Exception("Syntax Error: You're dumb")
- self.history.append((self.Stir, s))
- return True
- def Mix(self, s):
- """Mix [the [nth] mixing bowl] well.
- This randomises the order of the
- ingredients in the nth mixing bowl.
- """
- if len(s) is 1:
- if s[-1] != "well.":
- raise Exception("Syntax Error: Mix well.")
- bowl_num = 0
- else:
- if ' '.join(s[:1]) == "the mixing":
- bowl_num = 0
- else:
- pass
- bowl_num = ordinal([val for val in s if ordinal(val) is not None][0]) - 1
- self.mixing_bowls[bown_num].mix()
- self.history.append((self.Mix, s))
- return True
- def Clean(self, s):
- """Clean [nth] mixing bowl.
- This removes all the ingredients
- from the nth mixing bowl.
- Author: Sean
- """
- if not s[0].isdigit() or ' '.join(s[1:]) != 'mixing bowl.':
- raise Exception("Syntax Error: You goofered up the cleaner!")
- self.mixing_bowls[ordinal([val for val in s if ordinal(val) is not None][0]) - 1].values = list()
- self.history.append((self.Clean, s))
- return True
- def Pour(self, s):
- """Pour contents of the [nth] mixing bowl into the [pth] baking dish.
- This copies all the ingredients from
- the nth mixing bowl to the
- pth baking dish, retaining the order
- and putting them on top of anything
- already in the baking dish.
- """
- d(len(s))
- if len(s) is not 11:
- raise Exception("Syntax Error: You dun goofed up the poor method thar")
- consts = map(' '.join, [s[:3], s[4:8], s[9:]])
- d( map(repr, consts))
- for c in consts:
- d( repr(c))
- if consts[0] != 'contents of the' or consts[1] != 'mixing bowl into the' or consts[2] != 'baking dish.':
- raise Exception("Syntax Error: You dun goofed up the poor method thar")
- nums = map(ordinal, [val for val in s if ordinal(val) is not None])
- nums = [num - 1 for num in nums]
- d(nums)
- bowl_num = nums[0]
- dish_num = nums[1]
- if not (ordinalusedDish(dish_num) or ordinalused(bowl_num)):
- pass
- else:
- self.createDH()
- self.baking_dishes[dish_num].append(self.mixing_bowls[bowl_num])
- self.mixing_bowls[bowl_num].values = list()
- self.history.append((self.Pour, s))
- #self.baking_dishes[dish_num].values.extend(self.mixing_bowls[bowl_num].values)
- return True
- def Set(self, s):
- """Set aside.
- This causes execution of the innermost
- loop in which it occurs to end
- immediately and execution
- to continue at the statement after
- the "until".
- """
- pass
- return False
- def Serve(self, s):
- """Two uses.
- Serve with auxiliary-recipe.
- This invokes a sous-chef to immediately
- prepare the named auxiliary-recipe.
- The calling chef waits until the sous-chef
- is finished before continuing.
- See the section on auxiliary recipes below.
- Serves number-of-diners.
- This statement writes to STDOUT the contents
- of the first number-of-diners baking dishes.
- It begins with the 1st baking dish,
- removing values from the top one by one and
- printing them until the dish is empty,
- then progresses to the next dish, until all
- the dishes have been printed.
- The serves statement is optional, but is
- required if the recipe is to output anything!
- """
- for dish in self.baking_dishes:
- while dish:
- self.stdout.append(dish.pop())
- s = ""
- for x in stdout:
- s+=str(x)
- print s
- return False
- def Refrigerate(self, s):
- """Refrigerate [for number hours].
- This causes execution of the recipe
- in which it appears to end immediately.
- If in an auxiliary recipe, the auxiliary
- recipe ends and the sous-chef's first
- mixing bowl is passed back to the calling
- chef as normal. If a number of hours is
- specified, the recipe will print out its
- first number baking dishes before ending.
- """
- pass
- return False
- def _verb_(self, s):
- """Takes care of VERB until VERBED.
- Not a clue on how to do this yet.
- IDEA!
- -- Create a new kitchen
- -- keep reading in commands until verbed
- -- pass commands to a new kitchen
- -- once we reach 'until verbed', execute the history again
- -- keep executing until condition is zero
- """
- nested_verb
- pass
- def interpret():
- hat = 'c= '
- kills = ["quit", "exit", "stop", "kill", "term"]
- k = Kitchen()
- cmd = raw_input(hat)
- out = True
- while cmd[:4] not in kills: # checks the first four letters
- k.do(cmd)
- print repr(k)
- cmd = raw_input(hat)
- ##def main():
- ## K = Kitchen()
- ## o = "1st"
- ## r = "2nd"
- ## d = "1st"
- ## hold = []
- ## hold.append (o)
- ## hold.append(r)
- ## hold.append(d)
- ## for x in hold:
- ## if (ordinalused(x)):
- ## K.createMB()
- ##
- ## print [str(v) for v in K.mixing_bowls]
- def main(path):
- K
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement