I am having problems with my elif statements - python

I'm programming a game to try and improve my skills in python. In this part of the code I am trying to program a shop with a money system testing one variable against 5 different possible answers
while True:
choice=str(input("What would you like to buy? (Type in 'nothing' when you don't want anymore items) "))
if choice!="health potion" and "strength potion" and "strength booster" and "armour piece" and "nothing":
print()
next_line=input("I do not understand what you wrote. Try again please ")
print()
elif choice=="nothing":
next_line=input("The merchant says 'Thanks for business' ")
print()
break
elif choice=="health potion":
gold=gold-10
if gold<0:
gold=gold+10
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You bought a health potion ")
health_potions=health_potions+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
elif choice=="strength potion":
gold=gold-15
if gold<0:
gold=gold+15
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You bought a strength potion ")
strength_potions=strength_potions+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
elif choice=="strength booster":
gold=gold-45
if gold<0:
gold=gold+45
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You boosted your strength ")
strength_booster=strength_booster+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
elif choice=="armour piece":
gold=gold-30
if gold<0:
gold=gold+30
next_line=input("Sorry but you don't have enough gold ")
print()
else:
next_line=input("You bought an armour piece ")
armour=armour+1
next_line=input("You now have "+str(gold)+" gold coins ")
print()
When you input health potion the code goes on like normal but with the other inputs it goes to this part of the code
if choice!="health potion" and "strength potion" and "strength booster" and "armour piece" and "nothing":
print()
next_line=input("I do not understand what you wrote. Try again please ")
print()

For fun, here is a significantly more advanced version.
Don't worry if it doesn't all make sense right away; try tracing through it and figuring out how it works. Once you fully understand it you will have a much better grasp of Python!
class Character:
def __init__(self, name, health=50, strength=20, gold=200, inventory=None):
"""
Create a new character
inventory is a list of items (may have repeats)
"""
self.name = name
self.health = health
self.strength = strength
self.gold = gold
self.inventory = [] if inventory is None else list(inventory)
def buy(self, item):
"""
Buy an item
"""
if self.gold >= item.cost:
print(item.buy_response.format(name=item.name, cost=item.cost)) # print acceptance
self.gold -= item.cost # pay gold
item.buy_action(self) # apply purchased item to character
return True
else:
print("Sorry but you don't have enough gold.")
return False
class Item:
def __init__(self, name, cost, buy_response="You bought a {name} for {cost} GP", buy_action=None):
# store values
self.name = name
self.cost = cost
# what to print on a successful purchase
self.buy_response = buy_response
# apply a purchased item to the character
self.buy_action = self.make_buy_action() if buy_action is None else buy_action
def make_buy_action(self):
def buy_action(char):
"""
Purchase default action: add item to character inventory
"""
char.inventory.append(self)
return buy_action
#staticmethod
def buy_strength_booster(char):
"""
Purchase strength booster action: increase character strength
"""
char.strength += 1
def __str__(self):
return self.name
class Shop:
def __init__(self, name, *inventory):
"""
Create a shop
inventory is a list of (num, item); if num is None the store has an unlimited supply
"""
self.name = name
self.inventory = {item.name:(num, item) for num,item in inventory}
def visit(self, char):
"""
Serve a customer
"""
print("\nHowdy, {}, and welcome to {}!".format(char.name, self.name))
while True:
print("\nWhat would you like to buy today? (type 'list' to see what's available or 'done' to leave)")
opt = input("{} GP> ".format(char.gold)).strip().lower()
if opt == 'done':
print("Have a great day, and c'mon back when you've got more gold!")
break
elif opt == 'list':
item_names = sorted(name for name, (num, item) in self.inventory.items() if num is None or num > 0)
if item_names:
print(", ".join(item_names))
else:
print("Huh - looks like we're all sold out. Try again next week!")
break
elif opt in self.inventory:
num, item = self.inventory[opt]
if num is None or num > 0:
yn = input("That's {} GP. You want it? [Y/n]".format(item.cost)).strip().lower()
if yn in {'', 'y', 'yes'}:
if char.buy(item) and num is not None:
self.inventory[opt] = (num - 1, item)
else:
print("(scowling, the proprietor stuffs the {} back under the counter)".format(item.name))
else:
print("'Fraid we're all out of those.")
else:
print("Sorry, hain't had one o' those around in a coon's age!")
def main():
# stock the store
shop = Shop("Dwarven Dave's Delving Deal Depot",
(6, Item("health potion", 10)),
(6, Item("strength potion", 15)),
(3, Item("strength booster", 45, "You boosted your strength!", Item.buy_strength_booster)),
(None, Item("armor piece", 30)) # unlimited stock
)
# create a buyer
jeff = Character("Jeff")
# visit the store
shop.visit(jeff)
if __name__ == "__main__":
main()

Your issue is with this statement:
if choice!="health potion" and "strength potion" and "strength booster" and "armour piece" and "nothing":
Comparing strings like this doesn't work. You need to make sure it isn't in an array of the strings
if choice not in ("health potion","strength potion","strength booster","armour piece","nothing"):
Otherwise it will always be true, so the first statement will always execute.

Related

[textRPG]How to keep random creating of class and class atrributes every time i run a program[Python]

I am trying some text based rpg game as a beginner in python. But i am struggling to get done one thing.
If i use while loop to run program 5 times. So i want repeat killing monster but without saving his attributes.
If you run this code, character kills a monster in couple of moves and appends his experience to himself and monster hp decreases to <= 0 and dies.
Looping whole program does not work, randomly created monster is still the same, i just want to create new monster with new random attributes every time i loop program. It is possible? I am new to this and can't figure it out at this moment. Some tips ?
Here is some code but without while loop: final output is to loop this menu and fight simulator to gain exp and items from random monsters.
import random
import time
# List of items to drop
normal_items = ['Copper ore', 'Apple', 'Animal skin', 'Stone', 'Feather', 'Rotten egg', 'Bag of sand', "Simple dagger", "Blue flower"]
rare_items = ['Energized wand', 'Staff of purity', 'Enhanced gloves', 'Adamant chest plate']
legendary_items = ['Crown of Immortality', 'Robe of fire-dragon']
drop_chance_dice = random.randint(1, 100)
# Simple drop chance function
def dice():
if drop_chance_dice <= 70:
random_choice = (random.choice(normal_items))
print(f"You got: {random_choice} ")
if 70 <= drop_chance_dice <= 98:
random_choice = (random.choice(rare_items))
print(f"You got: {random_choice} ")
if 99 <= drop_chance_dice <= 100:
random_choice = (random.choice(legendary_items))
print(f"Congratulations! You got an legendary item: {random_choice}")
# Instances and mobs
rat_nest= ['Rat', 'Giant Rat', 'Leader of Rats']
northern_forest = ['Snake', 'Wolf', 'Witch']
# My Character Class
class YourCharacter:
def __init__(self, intro, name, attack, exp, level, hp):
self.intro = intro
self.name = name
self.attack = attack
self.exp = exp
self.level = level
self.hp = hp
# Creating my character(preset)
my_character = YourCharacter("Your character \n", 'FroGres', 16, 0, 1, 100)
# Introduction
def introduction_of_player(my_character):
print(f"{my_character.intro}")
print(f"{my_character.name}")
print(f"Attack: {my_character.attack}")
print(f"Experience: {my_character.exp}")
print(f"Level: {my_character.level}")
print(f"HP: {my_character.hp}")
# Monsters class build
class Monster:
def __init__(self, intro, name, attack, exp, level, hp):
self.intro = intro
self.name = name
self.attack = attack
self.exp = exp
self.level = level
self.hp = hp
# Monsters attributes + list of mobs (for testing - to be upgraded)
# rat nest
rat = Monster("You fight vs: \n", "Rat", random.randint(4, 6), random.randint(8, 14), random.randint(1, 3),
random.randint(50, 100))
giant_rat = Monster("You fight vs: \n", "Giant Rat", random.randint(6, 8), random.randint(10, 18), random.randint(2, 4),
random.randint(80, 130))
rat_boss = Monster("You fight vs: \n", "Leader of Rats", random.randint(4, 6), random.randint(8, 14),
random.randint(1, 3),
random.randint(50, 100))
# northern forest
#Witch = Monster("You fight vs: \n", "Witch", random.randint(8, 12), random.randint(12, 20), random.randint(3, 6), random
# .randint(120, 200))
list_of_mobs = [rat, giant_rat, rat_boss]
event_mob = random.choice(list_of_mobs) # Random pick monster , USED in function
# Introduction of Monster
def introduction_of_monster_ratnest(list_of_mobs):
print(f"{list_of_mobs.intro}")
print(f"{list_of_mobs.name}")
print(f"Attack: {list_of_mobs.attack}")
print(f"Experience: {list_of_mobs.exp}")
print(f"Level: {list_of_mobs.level}")
print(f"HP: {list_of_mobs.hp}")
def escape_or_fight():
take_input = input("[a]ttack or [r]un?")
if take_input == 'a':
return attack()
if take_input == 'r':
print("You run as fast as possible.. ")
print("You returning to your hideout..")
else:
print("Something wrong")
# Menu of actions
def menu_dungs():
asking = input("Where do you want to go?: 1.Rat Nest or 2.Northern Forest :")
if asking == "1":
print("You entering rat nest.. good luck!\n")
time.sleep(1)
print("Some ugly creature stays on your way!")
print(f"{event_mob.name} is looking at you!")
if event_mob == rat:
introduction_of_monster_ratnest(rat)
escape_or_fight()
elif event_mob == giant_rat:
introduction_of_monster_ratnest(giant_rat)
escape_or_fight()
elif event_mob == rat_boss:
introduction_of_monster_ratnest(rat_boss)
escape_or_fight()
else:
print("Something went horribly wrong.. Don't even ask..")
elif asking == "2":
print("You entering northern forest.. good luck!\n")
print("Dungeon unavailable at this moment, try another one")
pass
# Not in use
else:
print("Try again and choose correct location\n")
menu_dungs()
def attack():
gain_exp = event_mob.exp + my_character.exp
rounds = 0
while event_mob.hp > 0:
event_mob.hp = event_mob.hp - my_character.attack
rounds += 1
print(f"You hit with: {my_character.attack} damage. Enemy HP is {event_mob.hp}")
print(f"Enemy HP after your attack is {event_mob.hp}", "\n")
if event_mob.hp <= 0:
print(f"{event_mob.name} has died..")
print(f"It tok you: {rounds} moves to kill that creature! \n")
print("Congratulations! Here is your loot")
dice()
print(f"You got: {event_mob.exp} experience from that fight.")
print(f"Your experience is now: {gain_exp}")
menu_dungs()
I tried: to create new unique monster with new randomly created attributes every time i run program. I used while loop but monster is not "respawning"
I expect: Some sort of simulator, after i kill monster, program creates new one and my character gains experience and items every fight.
I wonder: If there is some method to makes this class unique every loop.
Here is HOW-TO to achieve all goals in your question:
each time generate monsters with different parameters
respawn monsters
First you create 3 sepreate functions that would return a new monster - the class of returned value is always the same (Monster) but they return new instances on each call:
def get_rat():
return Monster("You fight vs: \n", "Rat", ...)
def get_giant_rat():
return Monster(...)
def get_rat_boss():
reutrn Monster(...)
You will also need to modify how you select monsters. I would suggest to create list of functions - so instead of selecting a monster you select a function, that generates monster:
# This should replace the list_of_mob
list_of_mob_generators = [get_rat, get_giant_rat, get_rat_boss]
And the last - you should select monster on each loop interation in main menu (so the monster could respawn). The shortest way is to change your global variable:
event_mob = None # we change event_mob initially to None - we will select in later
def menu_dungs():
global event_mob # this is new
asking = input("Where do you want to go?: 1.Rat Nest or 2.Northern Forest :")
if asking == "1":
event_mob_generator = random.choice(list_of_mob_generators) # get one of the functions
event_mob = event_mob_generator() # call the function to get monster
print("You entering rat nest.. good luck!\n")
time.sleep(1)
print("Some ugly creature stays on your way!")
print(f"{event_mob.name} is looking at you!")
# and this condition has changed, since we do not have one instance of each monster anymore
if event_mob.name == 'Rat':
introduction_of_monster_ratnest(event_mob)
escape_or_fight()
elif event_mob.name == 'Giant Rat':
introduction_of_monster_ratnest(event_mob)
escape_or_fight()
elif event_mob.name == 'Rat Boss':
introduction_of_monster_ratnest(event_mob)
escape_or_fight()
else:
print("Something went horribly wrong.. Don't even ask..")
... # and so on
and of course do not forget a while loop for main menu =)
while True:
menu_dungs()
Thanks for help, program works as i wanted but still shows me 8 yellow errors in attack() function. Cannot find reference 'hp' in 'None' etc.
maybe because this event_mob = None ?
Could you run this code and see what is going on ? very likely i did put something in wrong place..
import random
import time
# List of items to drop
normal_items = ['Copper ore', 'Apple', 'Animal skin', 'Stone', 'Feather', 'Rotten egg', 'Bag of sand', "Simple dagger", "Blue flower"]
rare_items = ['Energized wand', 'Staff of purity', 'Enhanced gloves', 'Adamant chest plate']
legendary_items = ['Crown of Immortality', 'Robe of fire-dragon']
drop_chance_dice = random.randint(1, 100)
# Simple drop chance function
def dice():
if drop_chance_dice <= 70:
random_choice = (random.choice(normal_items))
print(f"You got: {random_choice} ")
if 70 <= drop_chance_dice <= 98:
random_choice = (random.choice(rare_items))
print(f"You got: {random_choice} ")
if 99 <= drop_chance_dice <= 100:
random_choice = (random.choice(legendary_items))
print(f"Congratulations! You got an legendary item: {random_choice}")
# Instances and mobs
rat_nest= ['Rat', 'Giant Rat', 'Leader of Rats']
#not in use
northern_forest = ['Snake', 'Wolf', 'Witch']
# My Character Class
class YourCharacter:
def __init__(self, intro, name, attack, exp, level, hp):
self.intro = intro
self.name = name
self.attack = attack
self.exp = exp
self.level = level
self.hp = hp
# Creating my character(preset)
my_character = YourCharacter("Your character \n", 'FroGres', 16, 0, 1, 100)
# Introduction
def introduction_of_player(my_character):
print(f"{my_character.intro}")
print(f"{my_character.name}")
print(f"Attack: {my_character.attack}")
print(f"Experience: {my_character.exp}")
print(f"Level: {my_character.level}")
print(f"HP: {my_character.hp}")
# Monsters class build
class Monster:
def __init__(self, intro, name, attack, exp, level, hp):
self.intro = intro
self.name = name
self.attack = attack
self.exp = exp
self.level = level
self.hp = hp
# Monsters getting functions
# rat nest
def get_rat():
return Monster("You fight vs: \n", "Rat", random.randint(4, 6), random.randint(8, 14), random.randint(1, 3),
random.randint(50, 100))
def get_giant_rat():
return Monster("You fight vs: \n", "Giant Rat", random.randint(6, 8), random.randint(10, 18), random.randint(2, 4),
random.randint(80, 130))
def get_rat_boss():
return Monster("You fight vs: \n", "Rat Boss", random.randint(4, 6), random.randint(8, 14),random.randint(1, 3),
random.randint(50, 100))
# northern forest
# def get_witch():
# return Monster("You fight vs: \n", "Witch", random.randint(8, 12), random.randint(12, 20), random.randint(3, 6), random
# .randint(120, 200))
list_of_mobs_generators = [get_rat, get_giant_rat, get_rat_boss]
def escape_or_fight():
take_input = input("[a]ttack or [r]un?")
if take_input == 'a':
return attack()
if take_input == 'r':
print("You run as fast as possible.. ")
print("You returning to your hideout..")
else:
print("Something wrong")
# Menu of actions
event_mob = None
def menu_dungs():
global event_mob
asking = input("Where do you want to go?: 1.Rat Nest or 2.Northern Forest :")
if asking == "1":
event_mob_generator = random.choice(list_of_mobs_generators)
event_mob = event_mob_generator()
def introduction_of_monster_ratnest(event_mob):
print(f"{event_mob.intro}")
print(f"{event_mob.name}")
print(f"Attack: {event_mob.attack}")
print(f"Experience: {event_mob.exp}")
print(f"Level: {event_mob.level}")
print(f"HP: {event_mob.hp}")
print("You entering rat nest.. good luck!\n")
time.sleep(1)
print("Some ugly creature stays on your way!")
print(f"{event_mob.name} is looking at you!")
if event_mob.name == 'Rat':
introduction_of_monster_ratnest(event_mob)
escape_or_fight()
elif event_mob.name == 'Giant Rat':
introduction_of_monster_ratnest(event_mob)
escape_or_fight()
elif event_mob.name == 'Rat Boss':
introduction_of_monster_ratnest(event_mob)
escape_or_fight()
else:
print("Something went horribly wrong.. Don't even ask..")
elif asking == "2":
print("You entering northern forest.. good luck!\n")
print("Dungeon unavailable at this moment, try another one")
pass
# Not in use
else:
print("Try again and choose correct location\n")
def attack():
gain_exp = event_mob.exp + my_character.exp
rounds = 0
while event_mob.hp > 0:
event_mob.hp = event_mob.hp - my_character.attack
rounds += 1
print(f"You hit with: {my_character.attack} damage. Enemy HP is {event_mob.hp}")
print(f"Enemy HP after your attack is {event_mob.hp}", "\n")
if event_mob.hp <= 0:
print(f"{event_mob.name} has died..")
print(f"It tok you: {rounds} moves to kill that creature! \n")
print("Congratulations! Here is your loot")
dice()
print(f"You got: {event_mob.exp} experience from that fight.")
print(f"Your experience is now: {gain_exp}")
while True:
menu_dungs()

Tying values to keys in a dictionary and then printing

This is a smaller portion of the main code I have been writing. Depending on user selection they can add player informationa and then print the information from the dictionary player roster. I want to store the information and then print in this format but I havent been able to figure out how to do this.
Name ****
Phone Number ****
Jersey Number ****
Im new to dictionaries but I have spent hours reading and searching over the past couple of days about dictionaries and have tried several different ways to do this but failed. I have gotten the closest the way I have it setup now but it still doesnt work right. I feel like I am storing the information incorrectly into the dictionary for starters, any help would be greatly appreciated.
player_roster = {}
def display_roster(self): #Print Roster
if len(player_roster) != 0:
for x in player_roster.keys():
print('Name:', x, 'Phone Number:', player_roster[x])
else: #Print No One on Roster
len(player_roster) == []
print('No names have been entered:')
def add_player(self,): #Enter Members Name
name = input('Enter New Players Name:')
phone_number = input('Enter Players Phone Number:')
jersey_number = int(input('Enter Players Jersey Number'))
player_roster[name] = phone_number, 'Jersey Number', jersey_number
#If I input Toby as Name 444-444 as Phone Number and 3 as Jersey number it outputs like this
Name: Toby Phone Number: ('444-4444', 'Jersey Number', 3)
# I would like it to output like
Name: Toby
Phone Number: 444-4444
Jersey Number: 3
There are some things i would change in your code but to keep this close to what you asked for take a look at this:
def display_roster():
if len(player_roster) != 0:
for x in player_roster.keys():
print('Name:', x)
print('Phone Number:', player_roster[x][0])
print('Jersey Number:', player_roster[x][1])
else:
print('Roster is empty.')
return
player_roster = {}
def add_player():
name = input('Enter New Players Name:\t')
phone_number = input('Enter Players Phone Number:\t')
jersey_number = int(input('Enter Players Jersey Number:\t'))
player_roster[name] = [phone_number, jersey_number]
return
add_player()
display_roster()
# PRINTS:
#Name: Toby
#Phone Number: 444-4444
#Jersey Number: 3
Printing in multiple lines gives you the result you want. As stated in the comments this can also be done with a single print() statement but i do not think compact code makes much difference to you yet.
Further, this len(self.player_roster) == [] line does not make sense. This is as good as simply writing True in a line. The "emptiness" of the team is checked by the else:.
Finally, i would slightly change the way players are stored in the "Roster" dictionary and have it like this: {"Toby": ['444-4444', 3], ...}
I would propose that you replace the print statement to this:
print(" Name: %s \n Phone Number: %s \n Jersey Number: %d") % player_roster[x]
You're pretty much there. The below modification would allow you to print as you need (and is slightly more readable):
class PlayerDictionary():
def __init__(self):
pass
player_roster = {}
def display_roster(self): #Print Roster
if len(self.player_roster) != 0:
for key, value in self.player_roster.iteritems():
print(str(key) + ": " + str(value))
else: #Print No One on Roster
len(self.player_roster) == []
print('No names have been entered:')
def add_player(self,):
self.player_roster['Name'] = input('Enter New Players Name:')
self.player_roster['Phone Number'] = input('Enter Players Phone Number:')
self.player_roster['Jersey Number'] = int(input('Enter Players Jersey Number'))
if __name__ == "__main__":
player = PlayerDictionary()
player.add_player()
player.display_roster()
A slightly more maintainable solution would be to create a class for Player. Set the properties on the object and overload the str function e.g.
class Player(object):
def __init__(self):
self.__name = ""
self.__phone_number = ""
self.__jersey_number = ""
#property
def name(self):
return self.__name
#property
def phone_number(self):
return self.__phone_number
#property
def jersey_number(self):
return self.__jersey_number
#name.setter
def name(self, val):
self.__name = val
#phone_number.setter
def phone_number(self, val):
self.__phone_number = val
#jersey_number.setter
def jersey_number(self, val):
self.__jersey_number = val
def __str__(self):
return ("Name: %s\nPhone Number: %s\nJersey Number: %s" % (str(self.__name), str(self.__phone_number), str(self.__jersey_number)))
if __name__ == "__main__":
player = Player()
player.name = input('Enter New Players Name:')
player.phone_number = input('Enter Players Phone Number:')
player.jersey_number = int(input('Enter Players Jersey Number'))
print(player)

Getting functions to interact with each other

The project: Write a program in python in which the virtual dealer Jake plays against the virtual players: Mike and Will. Mike and Will are free to bet on different outcomes with different payout ratios. This will allow the comparison of various strategies. You should keep track of each player's bank roll (including the dealer)
The game is played with a 7 faced die with numbers [0 - 6] numbers[1, 2, 3] are blue and numbers [4, 5, 6] are green.
Correct Parity Pays: 2/1
Correct Colour Pays: 2/1
Exact Number Pays: 5/1
Here is the first draft with the modifications #Harvey Summer suggested. Comments on how I can improve the code's structure and performance are appreciated.
from random import choice
from random import randint
class die_face():
# This class is used to define the properties linked to each outcome on the dice.
def __init__(self, num, colour, parity):
self.num = num
self.colour = colour
self.parity = parity
# Determine the properties linked to each outcome on the dice.
zero = die_face(0, 'none', 'none')
one = die_face(1, 'blue', 'odd')
two = die_face(2, 'blue', 'even')
three = die_face(3, 'blue', 'odd')
four = die_face(4, 'green', 'even')
five = die_face(5, 'green', 'odd')
six = die_face(6, 'green', 'even')
options = [zero, one, two, three, four, five, six,]
class bet():
# Define the bets
def __init__(self, bet_type, odds):
self.bet_type = bet_type
self.odds = odds
num_bet = bet('num', 5)
colour_bet = bet('colour', 2)
parity_bet = bet('parity', 2)
class broker():
# Define the properties of the broker.
def __init__(self, name, balance):
self.name = name
self.balance = balance
def __str__(self):
result = "Name: {} \n" \
"Balance: {}" .format(self.name, self.balance)
return result
def modify_balance(self, amount):
self.balance += amount
main_broker = broker('Main',1e3)
def random_strategy():
# Bet a random amount on a random game with a random guess.
guess = 'empty'
game_mode= choice([num_bet, colour_bet, parity_bet])
if game_mode == num_bet:
guess = randint(0,6)
elif game_mode == colour_bet:
guess = choice(['blue','green'])
elif game_mode == parity_bet:
guess = choice(['even','odd'])
value = randint(1,10)
return game_mode , value, guess
class player():
# This class defines each player
def __init__(self, name, strategy, bank_roll):
self.name = name
self.strategy = strategy
self.bank_roll = bank_roll
def modify_balance(self, amount):
self.bank_roll += amount
def __str__(self):
result = "Name: {} \n" \
"Bank Roll: {}" .format(self.name, self.bank_roll)
return result
def play(self):
return self.strategy()
# Add the players
Will = player("Will",random_strategy,100)
def dealer(type, bet_value, guess):
#Roll the dice
correct = choice(options)
#Return amount based on Win or Lose
if type == num_bet.bet_type:
if correct.num == guess:
return num_bet.odds * bet_value - bet_value
else:
return -bet_value
if type == colour_bet.bet_type:
if correct.colour == guess:
return colour_bet.odds * bet_value - bet_value
else:
return -bet_value
if type == parity_bet.bet_type:
if correct.parity == guess:
return parity_bet.odds * bet_value - bet_value
else:
return -bet_value
def main_play(player):
# Collect the bets from the players
bets = player.play()
# Roll and return bets
amount = dealer(bets[0].bet_type, bets[1], bets[2])
# Distribute the money
main_broker.modify_balance(amount*-1)
player.modify_balance(amount)
print(player)
print(main_broker)
I would create a bettingtable as a broker where money is put at risk and the outcome to the dealer and players are exchanged based on the play outcome, and allow players and dealer to place bet and collect winnings. Encapsulate betting logic to the players and abstracted it from a game rules class. Each player should have a risk tolerance or game play style (lame, aggressive, cheater, etc.)
If you build this right, it shouldn't matter what the game is: dice, cards, etc. should basically play the same.

Why do I get an attribute error with my class?

EDIT BELOW!
Here is my retail_item class:
#RetailItem Class
class RetailItem:
def __init__(self, desc, inventory, price):
self.__desc=desc
self.__inventory=inventory
self.__price=price
#mutators
def set_desc (self, desc):
self.__desc=desc
def set_inventory (self, inventory):
self.__inventory=inventory
def set_price (self, price):
self.__price = price
#accessors
def get_desc(self):
return self.__desc
def get_inventory(self):
return self.__inventory
def get_price(self):
return self.__price
def __str__(self):
return 'Item Description:' + self.__desc, \
'\tNumber of Units:' + self.__inventory, \
'\tPrice: $' + self.__price
And my cash_register class:
#CashRegister Class
class CashRegister:
def __init__(self, purchase, total, show, clear):
self.__purchase=purchase
self.__total=total
self.__show=show
self.__clear=clear
#mutators
def purchase_item(self, purchase):
self.__purchase=purchase
def get_total(self, total):
self.__total=total
def show_item(self, show):
self.__show=show
def clear(self, clear):
self.__clear=clear
#accessors
def acc_purchase(self):
return self.__purchase
def acc_total(self):
return self.__total
def acc_show(self):
return self.__show
def acc_clear(self):
return self.__clear
And finally my program:
import retail_item
import cash_register
SHOW = 1
PURCHASE = 2
CART = 3
TOTAL = 4
EMPTY = 5
QUIT = 6
def main():
mylist = make_list()
#mycr = cash_register.CashRegister(mylist)
choice = 0
# Process menu selections until user quits program.
while choice != QUIT:
# Get the user's menu choice.
choice = get_menu_choice()
# Proces the choice.
if choice == SHOW:
show_items(mylist)
elif choice == PURCHASE:
purchase_item(mylist)
elif choice == TOTAL:
get_total(mylist)
elif choice == EMPTY:
clear(mylist)
def make_list():
item_list = {}
desc = 'Jacket'
inventory = 12
price = 59.95
entry = retail_item.RetailItem(desc, inventory, price)
item_list[desc]=entry
desc = 'Jeans'
inventory = 40
price = 34.95
entry = retail_item.RetailItem(desc, inventory, price)
item_list[desc]=entry
desc = 'Shirt'
inventory = 20
price = 24.95
entry = retail_item.RetailItem(desc, inventory, price)
item_list[desc]=entry
return item_list
# The get_menu_choice function displays the menu and gets
# a validated choice from the user.
def get_menu_choice():
print()
print('CASH REGISTER MENU')
print('-------------------------')
print('1. Show Retial Items')
print('2. Purchase Item(s)')
print('3. Show Current Shopping Cart')
print('4. Show Total of Items Purchased')
print('5. Empty Your Shopping Cart')
print('6. Quit the program')
print()
# Get the user's choice.
choice = int(input('Enter your choice: '))
# Validate the choice.
while choice < SHOW or choice > QUIT:
choice = int(input('Enter a valid choice: '))
# Return the user's choice.
return choice
def show_items(mylist):
print('\t\tDescription\t\tUnits in Inventory\t\tPrice')
print('--------------------------------------------------------------------------------')
x=1
for item in mylist:
print('Item #', x, '\t\t', item.get_desc(), '\t\t\t\t', item.get_inventory(), '\t\t\t$', format(item.get_price(), ',.2f'),sep='')
print()
x+=1
def purchase_item(mylist):
desc = input('Enter the item you wish to purchase: ')
if desc in mylist:
amount=int(input('How many would you like to buy: '))
if mylist[units]>0:
mylist[units]-=amount
elif (units-amount<0):
mylist[units]=0
else:
mylist[units] = 0
entry=cash_register.CashRegister(desc, units,)
mylist[desc]=entry
print()
def get_total(mylist):
print()
def clear(mylist):
print(mylist)
mylist.clear()
print(mylist)
main()
So my question is, how to I update only one object of a class?
And how do I call on the cash_register class?
Here are the instructions for the assignment, if that helps:
This exercise assumes that you have created the RetailItem class for Programming
Exercise 5. Create a CashRegister class that can be used with the RetailItem class. The
CashRegister class should be able to internally keep a list of RetailItem objects. The
class should have the following methods:
• A method named purchase_item that accepts a RetailItem object as an argument.
Each time the purchase_item method is called, the RetailItem object that is passed as
an argument should be added to the list.
• A method named get_total that returns the total price of all the RetailItem objects
stored in the CashRegister object’s internal list.
• A method named show_items that displays data about the RetailItem objects stored
in the CashRegister object’s internal list.
• A method named clear that should clear the CashRegister object’s internal list.
Demonstrate the CashRegister class in a program that allows the user to select several
items for purchase. When the user is ready to check out, the program should display a list
of all the items he or she has selected for purchase, as well as the total price.
EDIT: Here's my somewhat final code. I know it's not pretty, and I apologize for the lack of comments. I would still like some feedback even though I'll be submitting it shortly (for my own betterment and for job opportunities!) Here it is:
import retail_item
import cash_register
SHOW = 1
PURCHASE = 2
TOTAL = 3
EMPTY = 4
QUIT = 5
def main():
#set all variables to zero
lister = []
inv=[]
cost=[]
desc=''
inventory=0
price=0
total=0
purchase=0
#setting variable for each class
cash=cash_register.CashRegister(purchase, total, lister, inv, cost)
retail=retail_item.RetailItem(desc, inventory, price)
#classes
desc = 'Jacket'
inventory = 12
price = 59.95
#setting classes
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
#Adding to cart
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
desc = 'Jeans'
inventory = 40
price = 34.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
desc = 'Shirt'
inventory = 20
price = 24.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
choice = 0
# Process menu selections until user quits program.
while choice != QUIT:
# Get the user's menu choice.
choice = get_menu_choice()
# Proces the choice.
if choice == SHOW:
show_items(cash, retail, lister, inv, cost)
elif choice == PURCHASE:
purchase_item(cash, retail, lister, inv, cost)
elif choice == TOTAL:
get_total(cash, retail, lister)
elif choice == EMPTY:
price=0
cash.set_total(price)
clear(cash, lister)
# The get_menu_choice function displays the menu and gets
# a validated choice from the user.
def get_menu_choice():
print()
print('CASH REGISTER MENU')
print('-------------------------')
print('1. Show Retail Items')
print('2. Purchase Item(s)')
print('3. Show Total of Items Purchased')
print('4. Empty Your Shopping Cart')
print('5. Quit the program')
print()
# Get the user's choice.
choice = int(input('Enter your choice: '))
# Validate the choice.
while choice < SHOW or choice > QUIT:
choice = int(input('Please enter a valid choice: '))
# Return the user's choice.
return choice
def show_items(cash, retail, lister, inv, cost):
print('\t\tDescription\t\tUnits in Inventory\t\tPrice')
print('--------------------------------------------------------------------------------')
cash.show_item(lister, inv, cost)
def purchase_item(cash, retail, lister, inv, cost):
JACKET=1
JEANS=2
SHIRT=3
QUIT=4
choice=0
print()
print('WHICH WOULD YOU LIKE TO BUY')
print('-------------------------')
print('1. Jacket')
print('2. Jeans')
print('3. Shirt')
print('4. Quit')
print()
print('Choose as many as you like. Press 4 then ENTER to quit.')
while choice != QUIT:
# Get the user's menu choice.
choice = int(input('Which would you like to buy: '))
if choice < JACKET or choice > QUIT:
choice = int(input('Please enter a valid choice: '))
while choice != QUIT:
# Proces the choice.
if choice == JACKET:
desc = 'Jacket'
inventory = 12
price = 59.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
cash.set_total(price)
break
elif choice == JEANS:
desc = 'Jeans'
inventory = 40
price = 34.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
cash.set_total(price)
break
elif choice == SHIRT:
desc = 'Shirt'
inventory = 20
price = 24.95
retail.set_desc(desc)
retail.set_inventory(inventory)
retail.set_price(price)
cash.purchase_item(retail.get_desc(), lister)
cash.purchase_item(retail.get_inventory(), inv)
cash.purchase_item(retail.get_price(), cost)
cash.set_total(price)
break
print()
def get_total(cash, retail, lister):
print()
cash.show_items(cash.get_list(lister))
print('Your total is: $', format(cash.cost_total(),',.2f'))
def clear(cash, lister):
print('Shopping cart emptied.')
lister=lister.clear()
price=0
cash.set_total(price)
return lister
main()
RetailItem Class:
class RetailItem:
def __init__(self, desc, inventory, price):
self.__desc=desc
self.__inventory=inventory
self.__price=price
#mutators
def set_desc (self, desc):
self.__desc=desc
def set_inventory (self, inventory):
self.__inventory=inventory
def set_price (self, price):
self.__price = price
#accessors
def get_desc(self):
return self.__desc
def get_inventory(self):
return self.__inventory
def get_price(self):
return self.__price
def __str__(self):
return 'Item Description:' + self.__desc, \
'\tNumber of Units:' + self.__inventory, \
'\tPrice: $' + self.__price
And again, lastly my CashRegister Class:
#CashRegister Class
class CashRegister:
def __init__(self, purchase, total, lister, inv, cost):
self.__purchase=purchase
self.__total=total
self.__lister=[]
self.__inv=[]
self.__cost=[]
#mutators
def purchase_item(self, purchase, lister):
self.__purchase=purchase
lister.append(purchase)
return lister
def set_total(self, price):
self.__total+=price
def show_item(self, lister, inventory, price):
i=0
while i<len(lister):
s=('Item # %i\t%s\t\t\t\t%i\t\t\t%4.2f') % ((i+1),lister[i],inventory[i],price[i])
s = s.strip(' \t\n\r')
print(s)
i+=1
def show_items(self, lister):
i=0
print('You have purchased the following items')
while i<len(lister):
print(lister[i])
i+=1
def clear(self, lister):
i=0
while i<len(lister):
del lister[i]
i+=1
return lister
def get_list(self, lister):
return lister
#accessors
def acc_purchase(self):
return self.__purchase
def cost_total(self):
return self.__total
def acc_show(self):
return self.__show
def acc_clear(self):
return self.__clear
Thanks again guys! I used this site often, and though I didn't use much of what y'all gave me this time, you're still awesome!
This code has a couple of major problems. Without a stack trace I can't say exactly why you're getting an AttributeError, but I can tell that CashRegister objects can't be instantiated as written. Its __init__ refers to nonexistent variables - item and items.
Your CashRegister class is taking arguments to __init__ that aren't necessary - and in some cases should be methods. I don't see any reason your CashRegister class should take any __init__ arguments - it should initialize the list of RetailItem objects and probably a running total and do nothing else. purchase_item should update those internal attributes, get_total and show_items should read them (or get_total should calculate the total based on the list if you don't keep a running total) and clear should reset them both.
Stylistically, mutators and accessors and hidden internal data are not a Pythonic idiom. In general Python classes get and set member data directly, and get refactored to use properties if the behavior ever needs to change. I see that this is for a class/exercise, so you might be using them because they're required, but if not you're better off without them.
edit
This is what my main() would look like, making the minimal edits to show the logic:
def main():
items = make_list()
mycr = cash_register.CashRegister()
# at this point, mycr.show_items() should return [] and mycr.get_total() should return 0
choice = 0
while choice != QUIT:
choice = get_menu_choice()
if choice == SHOW:
mycr.show_items()
elif choice == PURCHASE:
item, quantity = get_purchase(items)
if item and quantity:
item.set_inventory(max(0, item.get_inventory() - quantity))
mycr.purchase_item(item, quantity)
elif choice == TOTAL:
print(mycr.get_total())
elif choice == EMPTY:
mycr.clear()
def get_purchase(items):
desc = input('Enter the item you wish to purchase: ')
if desc in items:
amount=int(input('How many would you like to buy: '))
return items[desc], amount
else:
return None, 0
This doesn't cover every possibility - for instance, as with your original code it allows entering higher quantities than are currently available with no side effect besides setting the quantity to 0. But the exercise description doesn't mention inventory tracking, so maybe that's not a requirement.

How do I create lists in Python while using object oriented programming? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I'm trying to create an initial attribute that also creates a list.
class Player(object):
"""A virtual player"""
def __init__(self, name, items, max_items = 5):
# still need to create item list
self._items = []
self.name = name
self.max_items = max_items
print "\nA new player named",self.name,"has been created.\n"
def inventory(self):
if len(self.items) > 1:
print "\nThe inventory is:"
print self.items
else:
print "Your inventory is empty"
def take(self, new_item):
if self.items <= self.max_items:
self.items.append(new_item)
else:
print "\nSorry, your inventory is completely full."
def drop(self, drop_item):
if drop_item not in self.items:
print "That item does not exist in your inventory."
else:
self.items.remove(drop_item)
def main():
player_name = raw_input("What name do you want to give the player?: ")
player = Player(player_name)
choice = None
while choice != 0:
print \
"""
Player Menu
0 - Quit
1 - Print inventory
2 - Add an item
3 - Drop an item
"""
try:
choice = int(raw_input("Choice: "))
except (ValueError):
print "Invalid number."
if choice == 0:
print "\nGoodbye\n"
elif choice == 1:
player.inventory()
elif choice == 2:
new_item = raw_input("What item do you wish to add to your inventory?: ")
new_item = new_item.lower()
player.take(new_item)
elif choice == 3:
drop_item = raw_input("What item do you want to drop?: ")
drop_item = drop_item.lower()
player.drop(drop_item)
# main
main()
raw_input("\nPress enter to exit.")
self._items = [] is absolutely correct.
But you have some logical errors in your code:
if len(self.items) > 1: should be if len(self.items) > 0: or even better if self.items: - you want to check if theres 1+ in the item, not if there's more than one item in the list.
try:
inp = raw_input # Python 2.x
except NameError:
inp = input # Python 3.x
def describe(lst):
if not lst:
return "nothing"
elif len(lst)==1:
return "a {0}".format(lst[0])
else:
return 'a {0}, and a {1}'.format(', a '.join(lst[:-1]), lst[-1])
class Player(object):
"""A virtual player"""
def __init__(self, name, items=None, max_items=5):
super(Player,self).__init__()
self.name = name
self.max_items = max_items
self.items = list(items)[:max_items] if items else []
print("A new player named {0} has been created.".format(self.name))
def inventory(self):
if self.items:
print("Your pockets contain: {0}.".format(describe(self.items)))
else:
print("Your pockets are empty.")
def take(self, new_item):
if len(self.items) < self.max_items:
self.items.append(new_item)
print("You take the {0}.".format(new_item))
return True
else:
print("Your pockets are too full.")
return False
def drop(self, drop_item):
try:
self.items.remove(drop_item)
print("You drop the {0}.".format(drop_item))
return True
except ValueError:
print("You have no {0}!".format(drop_item))
return False
def main():
print("Welcome, adventurer! What is your name?")
char = Player(inp(), ['string', 'blue key', 'pocketknife'])
commands = ['go', 'take', 'drop', 'inv', 'help', 'quit']
roomItems = ['ball', 'apple', 'dragon']
while True:
print("You are in the Baron's antechamber. You see {0}.".format(describe(roomItems)))
cmd = [i.lower() for i in inp('> ').strip().split()]
verb = cmd[0]
if verb in commands:
if verb=='go':
dir = ' '.join(cmd[1:])
print('You try to go {0}, but a giant kangaroo kicks you back into the antechamber.'.format(dir))
elif verb=='take':
item = ' '.join(cmd[1:])
if item in roomItems and char.take(item):
roomItems.remove(item)
elif verb=='drop':
item = ' '.join(cmd[1:])
if char.drop(item):
roomItems.append(item)
elif verb=='inv':
char.inventory()
elif verb=='help':
print("I know the words {0}.".format(', '.join(commands)))
elif verb=='quit':
break
else:
print("I don't know how to '{0}'.".format(verb))
print('The Baron has decided! There is a grating noise - the floor drops away like a trapdoor, and {0} plummets into darkness. THE END!'.format(char.name))
if __name__=="__main__":
main()
inp("Press enter to exit.")
You are calling the attibute self._items in the constructor but self.items else-where.
Maybe that is your problem, otherwise you need to explain what your problem is more clearly.

Categories