I am working on a little text base resultant game, but I am having troubling creating this list of Food, I want to put all my Food (either Burger, or Hotdog) in listOfFood. In my example I only included two, but they are all "base" on food.
Later then I will iterate through my listOfFood to do something. I abstracted my code to ask question (because it has too many lines, and the other information is not related to it).
class Food():
def __init__(self):
self.name = 'Food'
class HotDog(Food):
def __init__(self):
Food.__init__(self)
class Burger(Food):
def __init__(self):
Food.__init__(self)
def createFoodList(myOrders):
# A list that contain all the food (either Burger or Hotdog)
listOfFood = []
# Depend what is the type of the food, create that many food object
# and then append it to the list of food
if myOrders[0][0] == 'HotDog':
for number in myOrder[0][1]:
listOfFood.append(HotDot())
if myOrders[0][1] == 'Burger':
for number in myOrder[0][1]:
listOfFood.append(Burger())
return listOfFood
todayOrders = [['HotDog', 10], ['Burger', 5]]
print(createFoodList(todayOrders))
I wonder if I can use list comprehension or similar method to make my createFoodList function better? Because my idea is to have many different kind of Food, so if I can return this list of food, base on todayOrders list ['type of food', count] and return [food, food, food.. ]. The way I am doing right now is really complicated and long (I have a feeling this is not the right way).
Thank you very much.
Edit: Besides the list comprehension, what can I do to replace the if statements in createFoodList? It is decide on the [[food, count], [food, count]..], and I create that food and append it to my list.
2 Answers 2
foodmap = {'HotDog': HotDog, 'Burger': Burger}
print [foodmap[f]() for (f, c) in todayOrders for x in range(c)]
foodmap[f] evaluates to either HotDog or Burger (these are classes - not class names, the classes themselves). Calling someclass() creates an instance of soemclass and passes no arguments when calling someclass.__init__. Hence foodmap[f]() combines both of these - it looks up the class in foodmap and uses the class to create an instance of that class.
5 Comments
todayOrders[[]..] Like if I know the structure of the list, [[food, count], [food, count]... ].foodmap[f]() needs some clarification. When foodmap[f] return, is that an object? Since I don't think that is a string. Thank you Ignacio.foodmap is a mapping of string to class. Indexing it using a string returns the class, which you then call the constructor of.foodmap if each of your food classes has a name string (and it should anyway). [food() for food in [HotDog, Burger,..] for order_name, qty in todayOrders for _ in range(qty) if food.name == order_name]. But this is definitely too long.This looks more like a factory pattern. You can try the following solution
>>> class Food():
def __init__(self,name='Food'):
self.name = name
def __repr__(self):
return self.name
>>> class HotDog(Food):
def __init__(self):
Food.__init__(self,'HotDog')
>>> class Burger(Food):
def __init__(self):
Food.__init__(self,'Burger')
>>> def createFoodList(myOrders):
return [apply(order[0]) for order in myOrders for i in xrange(0,order[1]) if callable(order[0])]
>>> todayOrders = [[HotDog, 10], [Burger, 5]]
>>> print(createFoodList(todayOrders))
[HotDog, HotDog, HotDog, HotDog, HotDog, HotDog, HotDog, HotDog, HotDog, HotDog, Burger, Burger, Burger, Burger, Burger]
1 Comment
apply().
Foodfor every order? As far as I can see all of your hamburgers are all the same. If they really are, you can create an instance once and reuse it.