-2

Define a function called restaurant_price that takes one argument, a Restaurant, and returns the value of the price field of that Restaurant. So define a list containing a few Restaurants

I keep getting the error of Restaurant not defined.

This is my code:

def restaurant_price (Restaurant:Restaurant)-> float:
    return Restaurant.price

from collections import namedtuple 
Restaurant = namedtuple('Restaurant', 'name cuisine phone dish price')
RC = [
    Restaurant("Thai Dishes", "Thai", "334-4433", "Mee Krob", 12.50),
    Restaurant("Nobu", "Japanese", "335-4433", "Natto Temaki", 5.50),
    Restaurant("Nonna", "Italian", "355-4433", "Stracotto", 25.50),
    Restaurant("Jitlada", "Thai", "324-4433", "Paht Woon Sen", 15.50),
    Restaurant("Nola", "New Orleans", "336-4433", "Jambalaya", 5.50),
    Restaurant("Noma", "Modern Danish", "337-4433", "Birch Sap", 35.50),
    Restaurant("Addis Ababa", "Ethiopian", "337-4453", "Yesiga Tibs", 10.50) ]
assert restaurant_price(RC[1]) == 5.50

Then I need help on this second question: Write a sequence of statements that prints out the list of Restaurants RC in order from least expensive to most expensive (best dish).

print(RC.sort(key=restaurant_price))
user1937198
  • 4,987
  • 4
  • 20
  • 31
anonymous fox
  • 39
  • 1
  • 5
  • Welcome to SO! Only one question at a time please. Please add the complete error message and where in your code it is indicating. – AlG Jan 21 '15 at 20:38
  • @howaboutNO nothing in his code appears to be incorrect syntax to me. – Adam Smith Jan 21 '15 at 20:39
  • It's correct syntax, refer the guy to the faq about how to post questions and errors (but give him a chance), and yes his order of declarations is incorrect. – user3467349 Jan 21 '15 at 20:40
  • @howaboutNO that's a [function annotation](https://www.python.org/dev/peps/pep-3107/) – Adam Smith Jan 21 '15 at 20:40
  • As an aside: can you use `namedtuple`s that way? I thought `fields` had to be an iterable, so it would have to be `['name','cuisine','phone','dish','price']` – Adam Smith Jan 21 '15 at 20:43
  • @AdamSmith re:aside It seems so, I presume its because it's not possible to create a key with a space in it i.e. ["dish price"] would not be a valid namedtuple field, even though it's a valid dict field. – user3467349 Jan 21 '15 at 20:52

2 Answers2

1

Your first line uses a function annotation that requires the definition of Restaurant to be known. You don't define your namedtuple Restaurant until several lines later.

Either invert those lines, or just use a string for your function annotation, e.g.:

def restaurant_price (Restaurant:'Restaurant')-> float:
    return Restaurant.price
# note that for style purposes, you shouldn't capitalize that since you're
#    treating it as an object not a class. Use instead:
# # def restaurant_price(restaurant:'Restaurant') -> float:
# #     return restaurant.price
# note also that this is just operator.attrgetter('price')

Here's some more detail, since even experienced Python users seem to be getting tripped up on the function annotation.

A function annotation describes the parameter being referenced, but must be a valid expression. Restaurant is not a valid Python expression until you defined in as a namedtuple a bit later in your code, but 'Restaurant' is a string constant, which is of course just fine.

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • What I still don't understand is what the point of annotations without assertions is, or compiler optimization for that matter... – user3467349 Jan 21 '15 at 20:59
  • It's a bit like building hardware for something without any software support for that hardware. You can "bolt on" introspection later on, especially automatically in your IDE or etc. [the PEP](https://www.python.org/dev/peps/pep-3107/) has more info under the header [Use Cases](https://www.python.org/dev/peps/pep-3107/#use-cases) – Adam Smith Jan 21 '15 at 21:01
  • It seems to me if one can write a func `def restaurant_price (Restaurant: Restaurant) -> float` - and then pass a completely different object and have it return a string, then it's kind of self defeating clarity. Why not at least enforce annotations for whoever uses them? – user3467349 Jan 21 '15 at 21:05
  • @user3467349 I expect that things like `pylint` *will* throw warnings at you if you try to pass a string to a function annotated to expect an int. As for why the core Python compiler doesn't throw an error in these cases, you'd have to ask the BDFL :P – Adam Smith Jan 21 '15 at 21:09
  • Ok. You guy were spot on with changing the order of my statements and getting rid of the capitalization. Can anyone suggest how to write the code for: Write a sequence of statements that prints out the list of Restaurants RC in order from least expensive to most expensive (best dish), it should use the sort(), and key=restaurant_price as an argument to sort(). – anonymous fox Jan 21 '15 at 22:24
  • @anonymousfox what have you tried? This sounds like a separate question, however. – Adam Smith Jan 21 '15 at 22:27
  • Yes, your right. I'll post a new question for that. Thanks. – anonymous fox Jan 21 '15 at 22:37
0
def restaurant_price (resant:Restaurant)-> float:
    return restaurant.price


assert restant_price(RC[1]) == 5.50
anonymous fox
  • 39
  • 1
  • 5