How to compare 2 objects from a class - python

I have created a class called Dog_card. With this, I created player_card and computer_card. I am trying to compare the same attribute from both of these objects. There are more values to each than friendliness, but I have removed them so it is easier to test. I keep getting the error:
NameError: name 'player_card' is not defined
Here is my code:
class Dog_card:
def __init__(self):
self.name = ""
self.friendliness = ""
def printing_card(self):
prnt_str = "Name: %s \nIntelligence: %s" %(self.name, self.friendliness)
return prnt_str
def printing_player_card():
player_card = Dog_card()
player_card.name = dogs_list_player[0]
player_card.friendliness = random.randint(1,101)
def printing_computer_card():
computer_card = Dog_card()
computer_card.name = dogs_list_computer[0]
def choose_category():
user_choice_category = input("Please choose a category: ")
if user_choice_category not in ["1", "2", "3", "4"]:
print("Please choose from the options above")
choose_category()
else:
if user_choice_category == "1":
if player_card.friendliness > computer_card.friendliness:
print("Player has won the round!")
elif player_card.friendliness == computer_card.friendliness:
print("It is a Draw!")
Any help would be appreciated

The problem is as it's stated in the error. Basically you are trying to use player_card when it is not defined inside the definition of choose_category(). I suggest you pass the value of player_card to the function like the following
def choose_category(player_card):
or you can define it as an attribute so that it can be accessed by the methods of the same class.

you need to initialize play_card before using it. Maybe you call printing_player_card in order to intnialize before, but as you don't return anything from that function, the created object and the variable player_card only lives in scope of the function. When that function finished, player_card object variable is unknown and the object is destroyed.
if you want player_card (as well as computer_card) survice its function, you need to return it an save it to a variable outside the function code.
Furthermore your function name "printing" is bad, as you don't print anything. You just initialize your object.
Maybe that's what you are aiming at.
class Dog_card:
def __init__(self, name, friendliness=1):
self.name = name
self.friendliness = friendliness
def __str__(self):
return "Name: %s \nIntelligence: %s" %(self.name, self.friendliness)
player_card = Dog_card(dogs_list_player[0], random.randint(1,101))
computer_card = Dog_card(dogs_list_copmuter[0])
def choose_category():
user_choice_category = input("Please choose a category: ")
if user_choice_category not in ["1", "2", "3", "4"]:
print("Please choose from the options above")
choose_category()
else:
if user_choice_category == "1":
if player_card.friendliness > computer_card.friendliness:
print("Player has won the round!")
elif player_card.friendliness == computer_card.friendliness:
print("It is a Draw!")

Related

method not working when i call it from another method for random name gen in python

I am creating a random name generator using OOP in python however i am very new to this concept which is why i am having so difficulties with accessing methods in other methods. I read a post on stack overflow which said to call a method inside another method in a class, you must add self.funcname(param) however i have already done this and it still does not work
class Rndm_nme_gen:
def __init__(self):
print("THE RANDOM NAME GENERATOR")
self.value = ""
self.range = 5
self.counter = 0
self.loop = True
self.names = []
self.loop2 = True
self.take_input()
def take_input(self):
while self.loop:
user_input = input("ENTER A NAME: ")
self.num_check(user_input)
if self.value == "true":
print("INVALID NAME")
loop = True
elif self.value == "false":
self.counter += 1
self.names.append(user_input)
if self.counter == 5:
self.loop = False
self.genname()
#i am trying to call this function but it is not working as i hoped it would
def num_check(self, string):
self.string = string
for char in self.string:
if char.isdigit():
self.value = "true"
else:
self.value = "false"
def genname(self):
while self.loop:
gen = input("TYPE ENTER TO GENERATE A NAME OR TYPE 'q' TO QUIT").strip().lower()
if gen == " " or gen == "":
num = random.randint(0, 5)
print("NAME : " + str(self.names[num]))
loop == True
elif gen == 'q':
quit()
else:
print("UNKNOWN COMMAND")
loop = True
user1 = Rndm_nme_gen()
In the initialisation method, i called the take_input function so it automatically runs and from that function, i attempted to run the code from the genname function however the program would simply end
If you would like to run the code to see how it works, feel free to do so
Expected output:
ENTER NAME FDSF
ENTER NAME dfsd
ENTER NAME sdfds
ENTER NAME sfdff
ENTER NAME sfdf
TYPE ENTER TO GENERATE A NAME OR TYPE 'q' TO QUIT
it does not say TYPE ENTER TO GENERATE A NAME OR TYPE 'q' TO QUIT when i run the program

How to pass string as object name?

Here's how I finally solved the problem:
I created two lists, one containing the objects, the other containing the object names (strings). Then I write in the code to make sure that an object and its name are appended to the two lists at the same time. So that I can easily call an object with ObjectList[NameList.index(Name)], similarly with NameList[ObjectList.index(Object)] to call a name.
I don't know if it's the best solution. Maybe I'll find a better way to do this when I know more about python.
Thanks everyone for your help.
I've updated my code below.
I am trying to make a game that can take in user input, make new objects based on that input, and connect that object with an existing web of objects.
So I have the initial objects: Adam = Human("Male","God","God") and Eve = Human("Female", "God", "God")
But after Adam and Eve, I want to create objects like Josh = Human("Male", Adam, Eve), here the attributes of Josh becomes one string and two objects, instead of three strings. But if this worked, I can create a web of objects where every obect-child (except Adam and Eve) has object-parents.
If anyone has any suggestions on that, please let me know.
I want to pass an user-input string as the name of a new object of a certain class. I can't use eval() because it's dangerous. What can I do?
I am new to python3 and creating a little game just for practicing. I've created this class called "Human", and in the game users are supposed to input a name for a new Human.
I haven't tried much as none of the questions I found match my problem. I only know so far that I can't use eval() because it might cause trouble if things like eval("import") happened.
import random
# list of all humans
Humans = []
# creating the class Human
class Human:
global Humans
def __init__(self, gender, father, mother):
self.gender = gender
self.father = father
self.mother = mother
self.canHaveChild = False
Humans.append(self)
def growup(self):
self.canHaveChild = True
Adam = Human("Male", "God", "God")
Eve = Human("Female", "God", "God")
Humans.append(Adam)
Humans.append(Eve)
# creating the class SpiritualHuman
class SpiritualHuman:
def __init__(self, gend, stparent, ndparent):
self.stparent = stparent
self.ndparent = ndparent
self.gend = gend
self.canHaveChild = False
# haveChild function
def haveChild(Human1, Human2):
gender = ""
gen_pro = random.random()
if gen_pro < 0.5:
gender = "Female"
else:
gender = "Male"
if Human1.canHaveChild & Human2.canHavechild:
if (Human1.gender == "Male") & (Human2.gender == "Female"):
return Human(gender, Human1, Human2)
elif (Human1.gender == "Female") & (Human2.gender == "Male"):
return Human(gender, Human1, Human2)
elif (Human1.gender == "Male") & (Human2.gender == "Male"):
return SpiritualHuman("Yang", Human1, Human2)
else:
return SpiritualHuman("Yin", Human1, Human2)
else:
return "forbidden child"
# a list of all commands
command_list = ["who is the mother of", "who is the father of", "who is the child of", "have child named"]
# user input could be:
# "who is the mother of xxx"
# "who is the father of xxx"
# "who is the child of xxx and xxx"
# "xxx and xxx have child named xxx"
# user input function
def get_input():
command = input(":")
comsplit = command.split()
# check 1st command
if command_list[0] in command:
if comsplit[5] in str(Humans):
print("the mother of", comsplit[5], "is", Humans[str(Humans).index(comsplit[5])].mother())
else:
print(comsplit[5], "does not exist")
# check 2nd command
elif command_list[1] in command:
if comsplit[5] in str(Humans):
print("the father of", comsplit[5], "is", Humans[str(Humans).index(comsplit[5])].father())
else:
print(comsplit[5], "does not exist")
# check 3rd command
elif command_list[2] in command:
if comsplit[5] in str(Humans) and comsplit[7] in str(Humans):
for i in Humans:
if str(i.father()) in [comsplit[5], comsplit[7]] and str(i.mother()) in [comsplit[5], comsplit[7]]:
print(i, "is the child of", comsplit[5], "and", comsplit[7])
else:
print("they don't have a child")
else:
print("at least one of the parents you mentioned does not exist")
# check 4th command
elif command_list[3] in command:
if comsplit[0] in str(Humans) and comsplit[2] in str(Humans):
# here's where the problem is
# I want to use comsplit[7] as name for a new Human object
# how should I do it?
else:
print("at least one of them is not human")
elif command == "humans":
print(str(Humans))
else:
print("invalid command. If you need help, please type 'help'")
while(True):
get_input()
I don't know how to avoid errors, but I expect that if the user inputs:
Adam and Eve have child named Josh
the result should be that Josh is an object of class Human whose father is Adam and mother is Eve.
Use a dict containing your humans, with their names as keys:
# global dict, defined at the top of your code
humans = {}
def get_input():
command = input(":").split()
if len(command) == 1:
print(HUMANS) # well, don't know what this one is supposed to be...
elif len(command) > 1:
humans[command[1]] = Human(command[1])
humans[command[2]] = Human(command[2])
humans[command[0]] = haveChild(humans[command[1]], humans[command[2]])
Edit: I just read your comment, can't finish to answer right now, but in short, you must create your father and mother as humans before you can use them, so you need to change something in the way you create them...
The user will enter 2 humans objects with their attributes (gender,father,mother).The 2 objects will be passed to haveChild().Check my code
//import radom, it was missing from your code
import random
class Human:
def __init__(self, gender, father, mother):
self.gender = gender
self.father = father
self.mother = mother
self.canHaveChild = False
def growup(self):
self.canHaveChild = True
def haveChild(obj1, obj2):
gender = ""
gen_pro = random.random()
if gen_pro < 0.5:
gender = "Female"
else:
gender = "Male"
//obj1.canHaveChild & obj2.canHavechild, was throwing error
//'Human' object has no attribute 'canHavechild'
if obj1.canHaveChild and obj2.canHavechild:
if (obj1.gender == "Male") & (obj2.gender == "Female"):
return Human(gender, Human1, Human2)
elif (obj1.gender == "Female") & (obj2.gender == "Male"):
return Human(gender, mother, father)
elif (obj1.gender == "Male") & (obj2.gender == "Male"):
return SpiritualHuman("Yang", Human1, Human2)
else:
return SpiritualHuman("Yin", Human1, Human2)
else:
return "forbidden child"
def get_input():
print("Enter Human1 gender,father,mother")
command = input(":").split()
human1 = Human(command[0],command[1],command[2])
print("Enter Human2 gender,father,mother")
command = input(":").split()
human2 = Human(command[0],command[1],command[2])
haveChild(human1,human2)
# the problem above is, command[0] is an immutable (a string), I can't use it
# directly as the name of a new object
get_input()

How to properly use __repr__ when two classes are involved

I am working on some Python code where I create a basic ATM. The issue I am having is I am not able to get the result that I want its printing "<'function Account.balance at 0x012CBC90>" Instead of the actual balance number. So far I have only tested using jsmith. Feel free to call out any other issues that may cause a problem later.
class Account:
def __init__(self,user,pin,balance):
self.user = user
self.pin = pin
self.balance = int(balance)
def get_user(self):
return self.user
def get_pin(self):
return self.pin
def balance(self):
return int(self.balance)
def setBalance(self,newBalance):
self.balance = newBalance
def __repr__(self):
return str(self.user) + " " + str(self.pin) + " " + str(self.balance)
class ATM:
def withdraw(self,Person,amount):
result = Person - amount
return result
def check(self,Person):
Person = Account.balance
return str(Person)
def transfer(self,id1,id2):
pass
def __str__(self):
return self
def main():
Chase = ATM()
Database = []
Teron_Russell = Account("trussell",1738,0)
Joe_Smith = Account("jsmith",1010,1350)
print(Teron_Russell)
Database.append(Teron_Russell)
Database.append(Joe_Smith)
print("Welcome to the ATM")
id = input("Please enter your user ID: ")
pin = input("Enter your pin: ")
chosen = ""
for i in Database:
print("Test1")
name = Account.get_user(i)
print(name)
checkPin = Account.get_pin(i)
print(checkPin)
if id == name and pin == checkPin:
chosen = i
choice = input("What would you like to do. (Type 'Check','Withdraw','Transfer': ")
if(choice == "Check" or "check"):
print(Chase.check(chosen))
# if(choice == "Withdraw" or "withdraw"):
# wAmount = eval(input("How much would you like to Withdraw: "))
# # Chase.withdraw(Account.balance,)
# elif(choice == "Check" or "check"):
# Chase.check()
# else:
# print("Invalid Choice!")
if __name__ == "__main__":
main()
You named a variable and a method the same name, so the interpreter is confused on which one to use. Change the name of either the method or variable balance and you won't have this problem. Additionally, this isn't java, and you shouldn't use classes for no reason. Since you aren't using any instance variables, it is pointless to have all of those methods inside that class.

Why is the module not callable

I have most of my program done however I keep getting the error and can't seem to figure out why it keeps doing so. I've also tried animal_list = Zoo.Zoo()
line 43, in addAnimal
animal_list = Zoo()
TypeError: 'module' object is not callable
here is some of my program
import Animal
import Zoo
def main():
#set user choice
choice = 0
while choice != "3":
display_menu()
#get user's choice
choice = str(input("What would you like to do? "))
#Perform selected choice
if choice.isalpha():
print("Please enter a numeical value")
elif choice == "1":
addAnimal()
and
#Add animal to list
def addAnimal():
atype = input("What type of animal would you like to create? ")
aname = input("What is the animal's name? ")
theAnimal = Animal.Animal(atype, aname)
theAnimal.set_animal_type(atype)
theAnimal.set_name(aname)
animal_list = Zoo()
animal_list.add_animal(theAnimal,Animal)
From looking at your other questions, your Zoo class is quite wrong.
Your Zoo class should be written like this:
class Zoo:
def __init__(self):
self.__animals = []
def add_animal(self, animals):
self.__animals.append(animal)
def show_animals(self):
size = len(self.__animals)
if size == 0:
print("There are no animals in your zoo!")
else:
return __animals
Instead you define methods like this:
def __init__(Animal):
and define variables like:
Animal.__animals = []
which simply don't make sense.
Your problem is that you used a module (Animal) instead of self. I have no idea where you might have gotten this idea, but you may want to peruse class definition in the Python documentation.

I keep getting a naming error when i try to run this piece of code (Python)

class game_type(object):
def __init__(self):
select_game = raw_input("Do you want to start the game? ")
if select_game.lower() == "yes":
player1_title = raw_input("What is Player 1's title? ").lower().title()
class dice_roll(object,game_type):
current_turn = 1
current_player = [player1_title,player2_title]
def __init__(self):
while game_won == False and p1_playing == True and p2_playing == True:
if raw_input("Type 'Roll' to start your turn %s" %current_player[current_turn]).lower() == "roll":
I keep getting an error which reads:
NameError: name 'player1_title' is not defined
I understand that title is a function so i did try using player1_name and player1_unam but these also returned the same error :(
can somebody please help
All answers are greatly appreciated
There are a number of things leading to the NameError.
For one, the __init__ method of game_type does not save any data. To assign instance variables you have to specify the class instance with self.. If you don't, you're just assigning local variables.
Secondly, you must explicitly call a parent class's __init__ function with super() if you are creating a new one in a child class and still want the effects of the parent's.
So basically, your code should be
# Class names should be CapCamelCase
class Game(object):
def __init__(self):
select_game = raw_input("Do you want to start the game? ")
if select_game.lower() == "yes":
self.player1_title = raw_input("What is Player 1's title? ").lower().title()
# Maybe you wanted this in DiceRoll?
self.player2_title = raw_input("What is Player 1's title? ").lower().title()
# If Game were a subclass of something, there would be no need to
# Declare DiceRoll a subclass of it as well
class DiceRoll(Game):
def __init__(self):
super(DiceRoll, self).__init__(self)
game_won = False
p1_playing = p2_playing = True
current_turn = 1
current_players = [self.player1_title, self.player2_title]
while game_won == False and p1_playing == True and p2_playing == True:
if raw_input("Type 'Roll' to start your turn %s" % current_players[current_turn]).lower() == "roll":
pass

Categories