0

So my goal is to make an ordering system for a cafe with various types of coffee available. Right now I'm having trouble understanding why my code doesn't run, whenever I execute the code nothing happens and I'm not sure why

class Coffee(object):

    def __init__(self,name):
        self.name = name

    def coffee (self, coffee_type, price):
        self.coffee_type = coffee_type
        self.price = price

class Order(object):

    def __init__(self, name):
        self.name = name

    def newOrder (self, coffee_type, coffee_amount):
        this.coffee_type = coffee_type
        this.coffee_amount = coffee_amount




class Main(object):

    def __init__ (self, name):
        self.name = name


    from Coffee import coffee

    flat_white = coffee("1 : Flat White", 3.50)
    long_black = coffee("2 : Long Black", 3.50)
    cappuccino = coffee("3 : Cappuccino", 4.00)
    espresso = coffee("4 : Espresso", 3.25)
    latte = coffee("5 : Latte", 3.50)

    Ordering = 'Y'

    while Ordering == 'Y':
        try:
            order_coffee = int(input("What coffee would you like to order?", pprint (vars(coffee))))
            break

        except:
            ValueError
            print ("wrong input")

        order_amount = input("How many would you like to order?")

        if order_coffee == 1:
            new_Order(flat_white, order_amount)

        elif order_coffee == 2:
            new_Order(long_black, order_amount)

        elif order_coffee == 3:
            new_Order(cappuccino, order_amount)

        elif order_coffee == 4:
            new_Order(espresso, order_amount)

        elif order_coffee == 5:
            new_Order(latte, order_amount)

        else:
            print ("Please enter a valid number")
            break
arewm
  • 649
  • 3
  • 12
  • This code will not execute anything as is. How are you trying to run your ordering system? You do not need a main object, you can just have that code in a `if __name__=="__main__":` block. Or put the code in a `main()` function called within that block. – arewm Jun 29 '16 at 12:23
  • When I run your code the line `from Coffee import coffee` raises `ImportError: No module named 'Coffee'` please explain how you are trying to run your program or there is no way anyone will be able to help. – Tadhg McDonald-Jensen Jun 29 '16 at 13:20
  • 1
    As @TadhgMcDonald-Jensen pointed out, my comment here is wrong. It will run. You can see my answer below for a couple issues and solutions that I saw. – arewm Jun 29 '16 at 13:30

1 Answers1

0

It looks like there are several issues with your code. I will try to help you out with a couple.

First, no need for the __init__ method to accept a name. Just make the method accept the necessary information for the object:

class Coffee(object):
    def __init__ (self, coffee_type, price):
        self.coffee_type = coffee_type
        self.price = price

class Order(object):
    def __init__(self, coffee_type, coffee_amount):
        self.coffee_type = coffee_type
        self.coffee_amount = coffee_amount

Second, since it does not really do anything, you can replace the Main class to an execution in a conditional as is typically seen in Python programs/scripts:

if __name__ =="__main__":
    ... # put main code here

Next, the except as it is written will catch all exceptions making debugging more difficult. If you only want to catch the ValueError, do:

    except ValueError:
        print ("wrong input")

If you use the current flow (i.e. with the try except block, you should put all of the order logic within the try block as it does not make any sense outside. Also, the necessary variables needed (order_coffee) will not be defined if you have a ValueError.

Adding a break after accepting the order input will cause you to break out of the ordering loop after an order is entered. This is probably not intended behavior. No break is needed here. Ditto for after outputting "Please enter a valid number".

When creating an Order, you just need to call Order(coffee_type, coffee_amount). When you create this order, make sure to set it to a variable too. probably something like:

new_order = Order(flat_white, order_amount)

Printing "Please enter a valid number" and "wrong input" is slightly redundant. You only need one of them to print under invalid input.

Lastly, pprint will print stuff out then return None so print(..., pprint(x)) will print an extra None once it has finished pretty printing x, instead just call pprint as if it was another call to print.

-- --

Making all of these changes, you will end up with something like:

class Coffee(object):

    def __init__ (self, coffee_type, price):
        self.coffee_type = coffee_type
        self.price = price

class Order(object):

    def __init__(self, coffee_type, coffee_amount):
        self.coffee_type = coffee_type
        self.coffee_amount = coffee_amount

if __name__ =="__main__":

    coffee_available=[Coffee("1 : Flat White", 3.50), 
                      Coffee("2 : Long Black", 3.50), 
                      Coffee("3 : Cappuccino", 4.00), 
                      Coffee("4 : Espresso", 3.25), 
                      Coffee("5 : Latte", 3.50)]

    ordering = 'Y'

    while ordering == 'Y':

        print("Coffee Type\t\tPrice")
        print("-----------\t\t-----")
        for coffee in coffee_available:
            print("{}\t- - -\t$ {}".format(coffee.coffee_type,coffee.price))
        print()
        order_coffee = int(input("What is the number of the coffee you want? "))

        order_amount = input("How many would you like to order? ")

        new_order = None

        if order_coffee >= 1 and order_coffee <=5:
            new_order = Order(coffee_available[order_coffee-1], order_amount)

        else:
            print ("Please enter a valid number")
arewm
  • 649
  • 3
  • 12
  • "you will not actually be running anything if you execute this file." Did you try? The code in a class block executes like an `if True:` block (with special handling of the variables defined there) so the code in the `class Main` **will** in fact be executed. (don't get me wrong a lot of your pointers will be helpful to the OP) – Tadhg McDonald-Jensen Jun 29 '16 at 13:22
  • I did not try to run it, I had never seen that usage before and so it was the first issue I saw. Thanks for pointing out my error. – arewm Jun 29 '16 at 13:29
  • 1
    no problem ([related question here](http://stackoverflow.com/questions/26193653/why-does-a-class-body-get-executed-at-definition-time)) The OP definitely isn't using this mechanic in the intended way. One example use is [subprocess conditionally defining internal methods differently for windows then unix](https://github.com/tadhgmister/cpython/blob/master/Lib/subprocess.py#L1126) – Tadhg McDonald-Jensen Jun 29 '16 at 13:36
  • thanks for the help! I'm relatively new to python and I'm just learning things about classes and functions for it. I applied the fixes you mentioned and it does work fine except I cannot seem to print the list of coffee instances and their attributes. I will continue to work on this program as i still have to implement a receipt system and to keep count on what items and how many were ordered during a day – killerstick1 Jun 29 '16 at 14:28
  • @killerstick1 Not a problem, welcome to SO. I am sure that you can probably get it to work with `pprint`, but I would probably just create a function to print the menu since I have never used `pprint`. Another thing that you want to consider is to make sure you can exit out of the loop (i.e. check the input for some exit command and set `ordering` to something else). I have put a version of the fully edited code in the answer above. – arewm Jun 29 '16 at 14:43
  • @anon01 thank you, I will try to update my progress on this task if I incur any more problems. I was thinking of putting an exit command after I have gathered all the inputs from the user. Currently im trying to implement a receipt function which should provide a segway to other elements of my task – killerstick1 Jun 30 '16 at 11:15