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
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")
Related
Python beginner here.
I am having hard time understanding how to get user input from function to use it in one of my class methods
class...
def setFirstStageSpeed(self, s):
s = # FIRST_STAGE_SPEED from main()
self.Speed = s
...
def main():
FIRST_STAGE_SPEED = 0
while True:
try:
FIRST_STAGE_SPEED = int(input("Please set first stage speed"
"for the spacecraft: "))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if FIRST_STAGE_SPEED < 0:
print("Sorry, your response must not be negative.")
continue
else:
break
...
So as shown above, I am trying to get the input value on FIRST_STAGE_SPEED to the setFirstStageSpeed() method.
Here is a solution.you should creaete a instance of SpaceCraft.that's OOP style.
class SpaceCraft:
def setFirstStageSpeed(self, s):
self.Speed = s
def main():
FIRST_STAGE_SPEED = 0
while True:
try:
FIRST_STAGE_SPEED = int(input("Please set first stage speed"
"for the spacecraft: "))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if FIRST_STAGE_SPEED < 0:
print("Sorry, your response must not be negative.")
continue
else:
break
# make a instance of SpaceCraft.if you not familiar with OOP(Object-oriented programing).you should study about it
spaceCraft = SpaceCraft()
# then call the instance method.set the first stage speed
spaceCraft.setFirstStageSpeed(FIRST_STAGE_SPEED)
so I'm in the process of learning Python, so forgive any naivety.
I'm doing some practice on Classes - and I'm making it so that when a user input their car - it looks for instantiated objects and then returns the price.
I get it to work okay for "BMW" - but when I try Ferrari - it only return the price for the BMW (20k). I'm thinking it is something not right with the price_check function part of the code.
Please could you provide some guidance here? Code below:
class Car:
car_list = []
def __init__(self, make, model, price):
self.make = make
self.model = model
self.price = price
self.car_list.append(self)
#this is the part of the code that i'm stuck with
def price_check(self):
for i in Car.car_list:
if New_Car.make == self.make:
return i.price
else:
print("Not available")
BMW = Car('BMW', '1 Series', "£20,000")
Ferrari = Car('Ferrari', 'Italia', "£90,000")
New_Car = Car(
input("What is make of your car? "), input("What is the model? "), "")
print("The cost of this car is: ", New_Car.price_check())
So essentially, I want it to return the price of the Ferrari if that's what the user typed.
Thanks in advance. And, sorry for any incorrect formatting, etc...
Okay, I agree with the comments made by #Jarvis regarding errors in your code, I would also add that in Cars init the price is a required variable and should cause an error on instantiation. In addition, in price_check, since the new_car instance has already been added to the list, price_check will also examine that entry and either find None or 0 price, so will never get to the "No Price Available" return. Here's how I would implement the Class
class Car:
car_list = []
def __init__(self, make, model, price=None): #makes providing price optional
self._make = make
self._model = model
self._price = price
Car.car_list.append(self)
#property
def make(self):
return self._make
#property
def model(self):
return self._model
#property
def price(self):
return self._price
#price.setter
def price(self, val):
self._price = val
def price_check(self):
for i in Car.car_list:
if i != self and self.make == i.make and self.model == i.model:
return i.price
return "Not available"
Two issues, first you need to append to the list not bound to your instance but the one bound to your class as a class-attribute:
def __init__(self, make, model, price):
self.make = make
self.model = model
self.price = price
# use the 'class' rather than the 'instance', you need to modify a class-attribute
Car.car_list.append(self)
Second, your issue in price check
def price_check(self):
for i in Car.car_list:
# you need to compare self's make with 'i.make' (elements in list)
if self.make == i.make:
return i.price
else:
print("Not available")
I am having trouble with a coding project in which I am trying to use classes in python to make a card game (cheat). However, when creating the player class, one of the functions that was previously defined within the class is shown as undefined. I cannot figure out the reason, and any suggestion is appreciated. Below is the definition of the classes
class card(object):
def __init__(self,rank,suit):
self.rank = rank
self.suit = suit
class player(object):
def __init__ (self):
self.number = number
self.hand = list()
#Here, hand is a list of the card class that was distributed with a suit and a rank
def check_card(self,player_rank,player_suit):
for card in self.hand:
if card.rank == player_rank and card.suit == player_suit:
return True
break
return False
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if check_card(self,rank,suit):
print(True)
else:
print(False)
Here is the actual code that will run it
player = player()
player.play_card()
The following error was received:
NameError: name 'check_card' is not defined
I have been troubleshooting and looking at different solutions, including moving the functions outside the class, but it continues to display the same error. Can anyone point out the mistake? Thanks!
You have the following two issues in your code
The way you passed self to the check_card function is wrong. You must call it in this way
self.check_card(rank,suit)
The second issue is that the number is not defined. Thus I passed it as an argument while initializing the player. Feel free to make changes for that.
This is the corrected code :
class card(object):
def __init__(self,rank,suit):
self.rank = rank
self.suit = suit
class player(object):
def __init__ (self, number):
self.number = number
self.hand = list()
#Here, hand is a list of the card class that was distributed with a suit and a rank
def check_card(self,player_rank,player_suit):
for card in self.hand:
if card.rank == player_rank and card.suit == player_suit:
return True
break
return False
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if self.check_card(rank,suit):
print(True)
else:
print(False)
player = player(3)
player.play_card()
Output :
what is the suit?spade
what is the rank?3
False
Based on this document the function call in python class is self.xxxx(args) (xxxx is denoted function name)
therefore the correct version of play_card function is shown as following.
enter code here
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if self.check_card(rank,suit):
print(True)
else:
print(False)
class Tank(object):
def _init_(self,name):
self.name = name
self.alive = True
self.ammo = 5
self.armor = 60
def _str_(self):
if self.alive:
return "%s (%i armor and %i shells left)"%(self.name,self.armor,self.ammo)
else:
return "%s is DEAD !" % self.name
def fire_at(self,enemy):
if self.ammo >= 1:
self.ammo-=1
print(self.name," fires on ",enemy.name)
enemy.hit()
else:
print(self.name," has no shells!")
def hit(Self):
self.armor-=20
print(self.name," is hit !")
if self.armor<=0:
self.explode()
def explode(self):
self.alive = False
print(self.name," explodes !!!!")
from tank import Tank
tanks = {"a":Tank("Alice"), "b":Tank("Bob"), "c":Tank("Crane") }
alive_tanks = len(tanks)
while alive_tanks > 1:
print()
for tank_name in sorted(tanks):
print(tank_name,tanks[tank_name])
first = raw_input("Who fires ?").lower()
second = raw_input("Who at ?").lower()
try:
first_tank = tanks[first]
second_tank = tanks[second]
except KeyError:
print("No such Tank ")
continue
if not first_tank.alive or not second_tank.alive:
print("One of those is dead!")
continue
print()
print("*"*30)
first_tank.fire_at(second_tank)
if not second_tank.alive:
alive_tanks -= 1
print("*"*30)
for tank in tanks.value():
if tank.alive:
print(tank.name," is the winner !")
break
On running it gives error :
tanks = {"a":Tank("Alice"), "b":Tank("Bob"), "c":Tank("Crane") }
TypeError: object() takes no parameters
What I need to resolve it?
class init methods are ddunder methods, you need to declare the init method with two underscores before and after, if not the the default init method is called.
__init__(self, name)
instead of
_init_(self, name)
Same goes for your str method, it needs to be:
__str__
I have a dictionary that contains keys that are made from a class containing 5 variables. I want to sort this dictionary by one of the class vars.
here is what i currently have
class Player:
def __init__(self,name,wins,losses,ties,winpercent):
self.__name = name
self.__wins = wins
self.__losses = losses
self.__ties = ties
self.__winpercent = winpercent
# mutators
def setname(self,name):
self.__name = name
def setwins(self,wins):
self.__wins = wins
def setlosses(self,losses):
self.__losses = losses
def setties(self,ties):
self.__ties = ties
def setwinpercent(self,winpercent):
self.__winpercent = winpercent
# accessors
def getname(self):
return self.__name
def getwins(self):
return self.__wins
def getlosses(self):
return self.__losses
def getties(self):
return self.__ties
def getwinpercent(self):
return self.__winpercent
def displayHighScores(self):
print("\n"," "*2,self.__name," "*(24-len(self.__name)),self.__wins)
def displayplayers(self):
print(self.__name)
I store Players like this:
def addplayer(players):
newName = input("\nEnter new Player name or 9 to quit: ")
wins = "0"
losses = "0"
ties = "0"
winpercent = "0"
if not newName:
print("\nNo name detected try again")
addplayer(players)
elif newName == '9':
print("\nReturning to Options menu")
else:
players[newName] = Player(newName,wins,losses,ties,winpercent)
saveData(players)
return players
Finally i am working on a sorted hi scores list. right now i can print my dictionary unsorted like this:
def printhiscores(players):
print("\n"," "*13,"HiScores")
print(" "*3,"Name"," "*20,"Wins")
if len(players) == 0:
print("\nNo current Players in memory.")
else:
for x in players.keys():
players[x].displayHighScores()
DisplayHighScores () being a part of the class object.
I have been reading on dictionary sorting using
OrderedDict(sorted(players.items(), key=itemgetter(1)))
but this returns edit:TypeError: '<' not supported between instances of 'Player' and 'Player'
Again I am looking to sort my dictionary of players by their win attribute and then print this new order to a high score screen. Any help would be greatly appreciated. I will post if i make any more progress on my own on this.
Your Player instances are not orderable however, as they don't implement comparison methods:
TypeError: '<' not supported between instances of 'Player' and 'Player'
If you wanted to sort them by the value returned, say, wins, then just access that information instead of just returning the value:
OrderedDict(sorted(players.items(), key=lambda kv: kv[1].getwins()))
Otherwise, give your Player class rich comparison methods; methods by which to determine when one instance should be sorted before or after another. You'll also need an equality test. It's easier to just implement support for < (lower then) and equality, then use the #functools.total_ordering decorator to provide the rest:
from functools import total_ordering
#total_ordering
class Player:
def __lt__(self, other):
if not isinstance(other, Player):
return NotImplemented
return self.__wins < other.__wins
def __eq__(self, other):
if not isinstance(other, Player):
return NotImplemented
return self.__wins == other.__wins
The above makes two Player instances equal when their wins are equal, and orders them by that attribute. You'll need to adjust this for your application as needed.