Access attributes of objects in a list - python

I'm using a book called Python for Absolute Beginners and am doing a challenge in the book's chapter 8 (Software Objects). My code works but I want to add another capability to the code; What code do I need to add to feed/play/talk with a specific critter?
In choice #7 of my code (7 - Feed a specific critter), I have written some code but it doesn't work. How might I access/change the attributes of a specific object that the user selects?
Also, any feedback to improve/shorten the code?
# Critter Caretaker
# A virtual pet to care for
class Critter(object):
import random
"""A virtual pet"""
def __init__(self, name, hunger = random.randint(0,9), boredom = random.randint(0,11)):
self.name = name
self.hunger = hunger
self.boredom = boredom
def __pass_time(self):
self.hunger +=1
self.boredom +=1
def __str__(self):
m = "name is: {}, hunger is: {}, boredom is: {}".format(self.name, self.hunger,self.boredom)
return m
#property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness <5:
m = "happy"
elif 5 <= unhappiness <=10:
m = "okay"
elif 11 <= unhappiness <=15:
m = "frustrated"
else:
m= "mad"
return m
def talk(self):
print("I'm", self.name, "and I feel", self.mood, "now.\n")
self.__pass_time()
def eat(self, food=3):
print("Yummy! Thank you.")
self.hunger -=food
if self.hunger <0:
self.hunger = 0
self.__pass_time()
def play(self, fun=4):
print("That was fun! Thanks")
self.boredom -=fun
if self.boredom <0:
self.boredom = 0
self.__pass_time()
def main():
noc = []
noc.append(Critter("Chicken"))
print("An critter named Chicken has been created")
choice = None
while choice != "0":
print \
("""
Critter Caretaker
0 - Quit
1 - Listen to all your critters
2 - Feed all your critters
3 - Play with all your critters
4 - Create a new critter
5 - Show a list of critters
6 - Delete a critter
7 - Feed a specific critter
""")
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Good-bye.")
# listen to critters
elif choice == "1":
if len(noc) != 0:
i.talk()
else:
print("No critters exist")
# feed your critters
elif choice == "2":
if len(noc) != 0:
for i in noc:
print(i.name, "says:", end = " ")
i.eat()
# play with your critters
elif choice == "3":
if len(noc) != 0:
for i in noc:
print(i.name, "says:", end = " ")
i.play()
else:
print("No critter exists")
# Create a new critter
elif choice == "4":
noc.append(Critter(input("Enter a name for your new critter: ")))
# Show critters
elif choice =="5":
b = 0
if len(noc) != 0:
for i in noc:
b +=1
print(b, "." ,i.name)
else:
print("No critter exists")
# delete a critter
elif choice == "6":
a = int(input("Enter the serial number of critter you want to delete: "))
a = a -1
del noc[a]
# feed a specific critter
elif choice == "7":
sctd = input("Enter name of critter you want to feed: ")
if sctd in noc:
noc.eat()
else:
print("That critter doesn't exists")
# print attributes of critters
elif choice == "919":
for i in noc:
print(i)
else:
print("\nSorry, but", choice, "isn't valid.")
main()
("\n\nPress the enter key to exit.")

In the branch for feeding a specific critter, you have the line noc.eat() -- noc is a list, which has no eat() method. You need to access the critter specified by the input, and call the eat() method on that object. Something like:
for c in noc:
if c.name == sctd:
c.eat()
break
(although there is an issue with this example if multiple critters match sctd -- solving that is something i'll leave to you)
an additional minor point of feedback on your code: a docstring should be the first statement inside the definition as per PEP 0257.

Just a small note is that I think the convention something like import random should probably be placed at the start rather than inside the class which also gets rid of the problem raised by #nthall which is that your docstring is currently not the first object.

Related

How do I apply the sellProduct method to each choice in the menu?

I don't understand why I can't connect the processSale method to the sellProduct method. I think that the classes and other methods don't need any change because I only followed the criterias that were given to me.
#candy machine
class CashRegister:
def __init__(self, cashOnHand = 500,):
if cashOnHand < 0:
self.cashOnHand = 500
else:
self.cashOnHand = cashOnHand
def currentBalance(self):
return self.cashOnHand
def acceptAmount(self, cashIn):
self.cashOnHand += cashIn
class Dispenser:
def __init__(self, numberOfItems = 50, productCost = 50):
if numberOfItems < 0:
self.numberOfItems = 50
else:
self.numberOfItems = numberOfItems
if productCost < 0:
self.productCost = 50
else:
self.productCost = productCost
def getCount(self):
return self.numberOfItems
def getProductCost(self):
return self.productCost
def makeSale(self):
self.numberOfItems -= 1
class MainProgram:
def showMenu(self):
global userInput
print("**** Welcome to Eros' Candy Shop ****")
print("To select an item enter")
print("""1 for Candy
2 for Chips
3 for Gum
4 for Cookies
0 to View Balance
9 to Exit""")
userInput = int(input("Enter your choice: "))
def sellProduct(self, useDispenser = Dispenser(), useRegister = CashRegister()):
try:
self.useDispenser = useDispenser
self.useRegister = useRegister
if self.useDispenser.getCount != 0:
print(f"It costs {self.useDispenser.getProductCost} cents")
cash = int(input("Please enter your payment: "))
change = cash - self.useDispenser.getProductCost
if change < 0:
print("Insufficient money!")
print(f"You need {self.useDispenser.getProductCost - cash} cents more")
return
else:
print(f"Your change is {change} cents")
self.useRegister.acceptAmount(self.useDispenser.getProductCost)
self.useDispenser.makeSale
return
elif self.useDispenser.getCount == 0:
print("The product you chose is sold out! Try the other itmes")
return
except ValueError:
print("You entered an incorrect value. Please use the numbers on the menu only")
def processSale(self):
Register = CashRegister()
Candy = Dispenser()
Chips = Dispenser()
Gum = Dispenser()
Cookies = Dispenser()
while True:
self.showMenu
if userInput == 1:
self.sellProduct(Candy, Register)
elif userInput == 2:
self.sellProduct(Chips, Register)
elif userInput == 3:
self.sellProduct(Gum, Register)
elif userInput == 4:
self.sellProduct(Cookies, Register)
elif userInput == 0:
print("Current Balance is" + str(Register.currentBalance))
elif userInput == 9:
break
mainProgram = MainProgram()
mainProgram.showMenu()
How do i use sellProduct method on userInput 1-4. I get confused when applying the properties of a class and how to connect them. Can you point out what mistakes I made and what other improvements I can do.
here are some points you can improve :
When you call your methods do not forget the parenthesis :
self.useDispenser.getCount()
self.useDispenser.getProductCost()
Create an infinite loop to continuously ask for input within showMenu and delete the one within processSale (for example):
def showMenu(self):
global userInput
userInput = 0
print("**** Welcome to Eros' Candy Shop ****")
while userInput != 9:
print("To select an item enter")
print(MENU)
userInput = int(input("Enter your choice: "))
if userInput < 9:
self.processSale()
But please update the whole program accordingly.
Hope it helps !

Text-based game stats

I'm working on a mini-project I'm doing for fun to practice python skills and I am stuck on a problem I can't seem to figure out. I have a function that gives me the default stats for every class in the game and I want it to change depending on what class/weapon I choose in the beginning. I am still trying to learn functions so any input will be valuable. So gameStat() is the default stats while gameStat() is the changed one.
import time
import random
inventory = []
def intro():
print("Hello for playing my game. It is a text based game that I am working on. \n")
print("I hope you enjoy playing it \n")
def chooseClass():
print("Please choose a class you would like to play as. Each class has a different background story to them")
print("-----------------------------------------------------------")
print("Please use the number given below to select them")
print("1: Priest\n" "2: Warrior\n" "3: Thief\n" "4: Ninja\n" "5: Pirate\n")
def classChosen(starterClass):
if starterClass == 1:
print("You have chosen Priest")
return "Priest"
elif starterClass == 2:
print("You have chosen Warrior")
return "Warrior"
elif starterClass ==3:
print("You have chosen Thief")
return "Thief"
elif starterClass ==4:
print("You have chosen Ninja")
return "Ninja"
elif starterClass ==5:
print("You have chosen Pirate")
return "Pirate"
else:
return None
def gameStat():
health = 100
mana = 100
strength = 5
magic = 5
exp = 0
baseStats(health,mana,strength,magic,exp)
def ChosenPriest(var):
if var == "Priest":
selectAns=""
selectAns=input("Would you like to know the backstory? \n:Please type 1 :Yes or 2 :No\n:")
if selectAns == 1:
print("INC")
#print("Since a child, you have been serving under the Church of Agathor.\n")
#print("You didn't have much of a choice because you had nowhere else to go.\n")
#print("You don't know who your parents are and the only thing the church would tell you that you suddenly appeared in front of the chruch with a gold cross.\n")
#print("You still have that cross til this day.\n")
#print("At the age of 16, everyone who serves for the lord will get their own holy weapon.\n")
#print("The weapon is used to fight off The Shadows. The Shadows are creatures created by the Shadow Lord, Gilmah.\n")
#print("Since the very beginning, Gilmah would rummaged through the land destorying and pillaging everything he sees.\n")
#print("One priest was able to seal him for thousands of years but he is soon to be awaken and he'll become stronger than ever.\n")
else:
print("Alright!")
def Weapons(weapon):
if weapon == 1:
print("You have chosen Magical Book!")
inventory.append("Magical Book")
return "Magical Book"
elif weapon == 2:
print("You have choosen a staff")
inventory.append("Staff")
return "Staff"
def baseStats(character,weapon):
if character == "Priest":
if weapon == "Magical Book":
mana=100
mana = mana + 50
return mana
elif weapon == "Staff":
magic=5
magic = magic + 5
return magic
#intro()
chooseClass()
userClass=None
while True:
try:
x=input("What class would you like to play?\n:")
if x>5 or x<1:
continue
else:
userClass=classChosen(x)
break
except NameError:
continue
character=ChosenPriest(userClass)
weapon=Weapons(input("What kind of holy weapon would you like to take? \n 1: Magical Book \n 2: Staff \n Use 1 or 2 to select your weapon! :"))
print(baseStats(character,weapon))
Thank you so much.
When you take any input it will be in string format to compare it with an integer you need to convert it to integer using int() function
I modified the code and it returns the value of "mana" or "magic" correctly
import time
import random
inventory = []
def intro():
print("Hello for playing my game. It is a text based game that I am working on. \n")
print("I hope you enjoy playing it \n")
def chooseClass():
print("Please choose a class you would like to play as. Each class has a different background story to them")
print("-----------------------------------------------------------")
print("Please use the number given below to select them")
print("1: Priest\n" "2: Warrior\n" "3: Thief\n" "4: Ninja\n" "5: Pirate\n")
def classChosen(starterClass):
if starterClass == 1:
print("You have chosen Priest")
return "Priest"
elif starterClass == 2:
print("You have chosen Warrior")
return "Warrior"
elif starterClass ==3:
print("You have chosen Thief")
return "Thief"
elif starterClass ==4:
print("You have chosen Ninja")
return "Ninja"
elif starterClass ==5:
print("You have chosen Pirate")
return "Pirate"
else:
return None
def gameStat():
health = 100
mana = 100
strength = 5
magic = 5
exp = 0
baseStats(health,mana,strength,magic,exp)
def ChosenPriest(var):
if var == "Priest":
selectAns=""
selectAns=int(input("Would you like to know the backstory? \n:Please type 1 :Yes or 2 :No\n:"))
if selectAns == 1:
print("INC")
#print("Since a child, you have been serving under the Church of Agathor.\n")
#print("You didn't have much of a choice because you had nowhere else to go.\n")
#print("You don't know who your parents are and the only thing the church would tell you that you suddenly appeared in front of the chruch with a gold cross.\n")
#print("You still have that cross til this day.\n")
#print("At the age of 16, everyone who serves for the lord will get their own holy weapon.\n")
#print("The weapon is used to fight off The Shadows. The Shadows are creatures created by the Shadow Lord, Gilmah.\n")
#print("Since the very beginning, Gilmah would rummaged through the land destorying and pillaging everything he sees.\n")
#print("One priest was able to seal him for thousands of years but he is soon to be awaken and he'll become stronger than ever.\n")
else:
print("Alright!")
def Weapons(weapon):
if weapon == 1:
print("You have chosen Magical Book!")
inventory.append("Magical Book")
return "Magical Book"
elif weapon == 2:
print("You have choosen a staff")
inventory.append("Staff")
return "Staff"
def baseStats(character,weapon):
if character == "Priest":
if weapon == "Magical Book":
mana=100
mana = mana + 50
return mana
elif weapon == "Staff":
magic=5
magic = magic + 5
return magic
#intro()
chooseClass()
userClass=None
while True:
try:
x=int(input("What class would you like to play?\n:"))
if x>5 or x<1:
continue
else:
userClass=classChosen(x)
break
except NameError:
continue
character=ChosenPriest(userClass)
weapon=Weapons(int(input("What kind of holy weapon would you like to take? \n 1: Magical Book \n 2: Staff \n Use 1 or 2 to select your weapon! :")))
print(baseStats(userClass,weapon))
In the gameState() function the baseStats takes 5 argument but when you defined baseStats it only takes two arguments character and weapon which is confusing.

How do I properly loop through a portion of code using methods in a class?

I am learning about classes in Python and tried to make a simple battle game. This code runs fine and as long as I print devin.battle() multiple times, but I want a while loop so that it will revert back to asking if the user would like to start a battle while also deducting the attack from the hit points.
start_battle = input("Would you like to start a battle? Y/N ===> ")
class People:
max_hit_points = 150
current_hit_points = 150
current_strength = 5
defence = 0
def __init__(self, name, current_hit_points):
self.name = name
self.current_hit_points
self.damage = 50
def battle(self):
if start_battle == "Y":
self.attacked()
elif start_battle == "N":
print("okay, nevermind then")
def attacked(self):
self.current_hit_points -= self.damage
print("You have been attacked")
if self.current_hit_points > 0:
print("Try again newb!")
else:
print("Your HP has reached 0, you are dead")
def __str__(self):
return f"{self. name} has {self.current_hit_points}HP remaining"
devin = People("Devin", 150)
devin.battle()
print(devin)
However, when I add one to the whole thing Python freezes up.
start_battle = input("Would you like to start a battle? Y/N ===> ")
class People:
max_hit_points = 150
current_hit_points = 150
current_strength = 5
defence = 0
def __init__(self, name, current_hit_points):
self.name = name
self.current_hit_points
self.damage = 50
while current_hit_points > 0:
def battle(self):
if start_battle == "Y":
self.attacked()
elif start_battle == "N":
print("okay, nevermind then")
def attacked(self):
self.current_hit_points -= self.damage
print("You have been attacked")
if self.current_hit_points > 0:
print("Try again newb!")
else:
print("Your HP has reached 0, you are dead")
def __str__(self):
return f"{self. name} has {self.current_hit_points}HP remaining"
continue
else:
print("You are dead")
devin = People("Devin", 150)
devin.battle()
print(devin)
If anyone can explain to me why its freezing up and how I can properly loop a battle, it would be greatly appreciated.
You have multiple issues here and its not super clear what you are trying to do but here is some direction according to your comment, make sure ot read the # code comments
class People:
max_hit_points = 150
current_hit_points = 150
current_strength = 5
defence = 0
def __init__(self, name, current_hit_points):
self.name = name
# you forgot to actually assign the hit points
self.current_hit_points = current_hit_points
self.damage = 50
def battle(self):
while self.current_hit_points > 0:
# you want to ask the user every round?
start_battle = input("Would you like to start a battle? Y/N ===> ")
if start_battle == "Y":
self.attacked()
# note that the user didnt get to attack back
# maybe print(self) here so the user can see his hp?
elif start_battle == "N":
print("okay, nevermind then")
break
else:
print("You are dead")
def attacked(self):
self.current_hit_points -= self.damage
print("You have been attacked")
if self.current_hit_points > 0:
print("Try again newb!")
else:
print("Your HP has reached 0, you are dead")
def __str__(self):
return f"{self. name} has {self.current_hit_points}HP remaining"
devin = People("Devin", 150)
devin.battle()
print(devin)

How do I print a specific message if the user inputs the same string twice in Python?

I am practicing my Python skills. I am currently on week 4 and stuck on doing a specific task. If a user enter the same string twice in my self.songs input I want to print a message saying "You can't enter the same song twice. Try again".
How can I do this? Also, is there a way for the user the use commas instead of white space to separate each string while inputing their favourite songs?
class User:
def __init__(self):
self.name = ''
self.songs = ()
self.movies = ()
self.sports = ()
def tops(self):
self.name = input("What's you're full name?:")
while True:
self.songs = input('Hi ' + self.name + ', what is your top 5 favorite songs?:').split()
if len(self.songs) > 5:
print('You entered more than 5 songs. Try again')
elif len(self.songs) < 5:
print('You entered less than 5 songs. Try again')
elif len(self.songs) == 5:
for song in self.songs:
print(song)
confirm_input = input('Do you confirm?')
if confirm_input == 'Yes':
print(type(self.songs))
print(self.songs)
break
elif confirm_input == 'No':
continue
quizUser = User()
quizUser.tops()
You may use a set to get unique element, then compare its length with the answer length
if len(set(self.songs)) != len(self.songs):
print("You can't enter the same song twice. Try again")
elif len(self.songs) > 5:
print('You entered more than 5 songs. Try again')
elif len(self.songs) < 5:
print('You entered less than 5 songs. Try again')
...
You can use set to get no same elements, and compare it's length with the normal list by using !=.
add this to your code:
elif len(set(self.songs)) != len(self.songs):
print('You can\'t enter the same song twice. Try again')
by the way, \' means escaping '.
The whole code:
class User:
def __init__(self):
self.name = ''
self.songs = ()
self.movies = ()
self.sports = ()
def tops(self):
self.name = input("What's you're full name?:")
while True:
self.songs = input('Hi ' + self.name + ', what is your top 5 favorite songs?:').split()
if len(self.songs) > 5:
print('You entered more than 5 songs. Try again')
elif len(self.songs) < 5:
print('You entered less than 5 songs. Try again')
elif len(self.songs) != len(set(self.songs)):
print('You can\'t enter the same song twice. Try again')
elif len(self.songs) == 5:
for song in self.songs:
print(song)
confirm_input = input('Do you confirm?')
if confirm_input == 'Yes':
print(type(self.songs))
print(self.songs)
break
elif confirm_input == 'No':
continue
quizUser = User()
quizUser.tops()
You can count the occurrence of each element and set the flag to 1 if a duplicate exists.
Following is the modified code:
class User:
def __init__(self):
self.name = ''
self.songs = ()
self.movies = ()
self.sports = ()
def tops(self):
self.name = input("What's you're full name?:")
while True:
########################################
#Flag variable to check if the repetition occured
flag = 0
self.songs = input('Hi ' + self.name + ', what is your top 5 favorite songs?:').split()
#Loop over the songs
for i in self.songs:
#Check the count of each song, if greater than 1 set flag variable to 1 and empty songs.
if self.songs.count(i)>1:
print("You can't enter the same song twice. Try again")
self.songs = ()
flag = 1
#Check if flag is 1, if true exit the current iteration
if flag == 1:
continue
#######################################
if len(self.songs) > 5:
print('You entered more than 5 songs. Try again')
elif len(self.songs) < 5:
print('You entered less than 5 songs. Try again')
elif len(self.songs) == 5:
for song in self.songs:
print(song)
confirm_input = input('Do you confirm?')
if confirm_input == 'Yes':
print(type(self.songs))
print(self.songs)
break
elif confirm_input == 'No':
continue
quizUser = User()
quizUser.tops()

want to improve simple python code

i am new to python programming. This is code that i want to improve
# Critter Caretaker
# A virtual pet to care for
class Critter(object):
"""A virtual pet"""
def __init__(self, name, hunger = 0, boredom = 0):
self.name = name
self.hunger = hunger
self.boredom = boredom
def __pass_time(self):
self.hunger += 1
self.boredom += 1
#property
def mood(self):
unhappiness = self.hunger + self.boredom
if unhappiness < 5:
m = "happy"
elif 5 <= unhappiness <= 10:
m = "okay"
elif 11 <= unhappiness <= 15:
m = "frustrated"
else:
m = "mad"
return m
def talk(self):
print("I'm", self.name, "and I feel", self.mood, "now.\n")
self.__pass_time()
def eat(self, food = 4):
print("Brruppp. Thank you.")
self.hunger -= food
if self.hunger < 0:
self.hunger = 0
self.__pass_time()
def play(self, fun = 4):
print("Wheee!")
self.boredom -= fun
if self.boredom < 0:
self.boredom = 0
self.__pass_time()
def __str__(self):
rep = "Attribut value is\n"
rep += str(self.hunger) + "\n" + str(self.boredom) + "\n"
return rep
def main():
crit_name = input("What do you want to name your critter?: ")
crit = Critter(crit_name)
choice = None
while choice != "0":
print \
("""
Critter Caretaker
0 - Quit
1 - Listen to your critter
2 - Feed your critter
3 - Play with your critter
""")
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Good-bye.")
# listen to your critter
elif choice == "1":
crit.talk()
# feed your critter
elif choice == "2":
crit.eat()
# play with your critter
elif choice == "3":
crit.play()
# secret option
elif choice == "!":
print(crit)
# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")
main()
("\n\nPress the enter key to exit.")
You see it is a puppet that show his mood and search of you to feed and play with him. Every time puppet talk, eat or play counter pass_time add 2 level up. Attribute food and fun have always the same number that directly affects mood. I want to make that user can enter amount of food and time that can affect mood of puppet. Why i cant do this
def eat(self, food):
print("Brruppp. Thank you.")
self.hunger -= food
if self.hunger < 0:
self.hunger = 0
self.__pass_time()
def play(self, fun):
print("Wheee!")
self.boredom -= fun
if self.boredom < 0:
self.boredom = 0
self.__pass_time()
and this
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Good-bye.")
# listen to your critter
elif choice == "1":
crit.talk()
# feed your critter
elif choice == "2":
food = int(input("How much food?: "))
crit.eat()
# play with your critter
elif choice == "3":
fun = int(input("How much time?: "))
crit.play()
# secret option
elif choice == "!":
print(crit)
# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")
You seem to be almost there if I understand your question right. Lets use the eat function as an example. You want to pass the food variable to the class function to use. If you want you can also add validation to check if that value entered is a number.
elif choice == "2":
food = int(input("How much food?: "))
crit.eat(food) # pass food in as a parameter

Categories

Resources