This is my current code:
class gym():
def __init__(self,gymname):
self.gymname=gymname
self.memlist=[]
def regMem(self,obj):
if obj.ageMember()==True:
self.memlist.append(obj)
return True, "mem in!!!"
def printMem(self):
for n in self.memlist:
print(n)
class gymMember():
def __init__(self,fname,lname,age):
self.fname=fname
self.lname=lname
self.age=age
def __str__(self):
return(str(self.fname)+str(self.lname)+str(self.age))
def ageMember(self):
if self.age>=18:
return True
def printMemlist(self):
for n in self.memlist:
print(n)
yes='y'
while yes=="y":
g=gym("gym")
name=input('enter f name')
lname=input('enter l name')
age=int(input('enter age'))
n=gymMember(name,lname,age)
print(g.regMem(n))
g.printMem()
I'm trying to create multiple gymMember objects from the user input, but when I print the memlist out with all the gym members, only the most recent gym member appears, not the previous ones. My goal is to take the user input, create gymMember objects, and then store it in the container class gym with the list memlist:
enter f namejosh
enter l namelawmen
enter age23
(True, 'mem in!!!')
joshlawmen23
enter f nametory
enter l nameloome
enter age28
(True, 'mem in!!!')
toryloome28
enter f name
As you can see, only the most recent object shows when I print out the list. How can I fix this?
You had placed g=gym("EzGym") inside the while loop. At every iteration of the while loop, a new instance of gym class is created. When a new instance of gym is created, a new empty list is also created (see line 4: self.memlist=[]).
Therefore, you don't get the previously added gymMember instances when you do a printMem().
You can fix this by shifting g=gym('EzGym') outside of the while loop.
class gym():
def __init__(self,gymname):
self.gymname=gymname
self.memlist=[]
def regMem(self,obj):
if obj.ageMember()==True:
self.memlist.append(obj)
return True, "mem in!!!"
def printMem(self):
for n in self.memlist:
print(n)
class gymMember():
def __init__(self,fname,lname,age):
self.fname=fname
self.lname=lname
self.age=age
def __str__(self):
return(str(self.fname)+str(self.lname)+str(self.age))
def ageMember(self):
if self.age>=18:
return True
def printMemlist(self):
for n in self.memlist:
print(n)
yes='y'
g=gym("EzGym") # shift this line outside of the while loop
while yes=="y":
name=input('enter f name')
lname=input('enter l name')
age=int(input('enter age'))
n=gymMember(name,lname,age)
print(g.regMem(n))
g.printMem()
Related
Disregard the naming conventions as to what class is part of which it is just a test run.
I need some help with the OOP inheritance i have created a class of Students, Teachers, and the principal. My goal is for the principal to be able to add employees. The problem is i just want to use a for loop to get the names and then pass that method as an attribute for the principal object. i was able to do it with the class Input without the self parameter. can someone tell me
what is going on here and how can i fix this with self. i removed input from names so that my question wont get shut down
class Input:
def count():
cnt = []
for i in range(4):
name = ('Enter name here: ')
cnt.append(name)
return cnt
class Student:
def __init__(self,name,lastname):
self.name = name
self.lastname = lastname
class StudentCouncil(Student):
def __init__(self, name, lastname, tenure):
super().__init__(name,lastname)
self.tenure = tenure
class Principal(StudentCouncil):
def __init__(self, name, lastname, tenure,employees=None):
super().__init__(name,lastname,tenure)
if employees is None:
self.employees = []
else:
self.employees = employees
def display(self):
for names in self.employees:
print(names,end=' ')
count = Input.count()
tij = Principal('Mike','Thoma','3',count)
tij.display()
If the method takes a self parameter, you need to create an instance of the class. So it would be:
class Input:
def count(self):
cnt = []
for i in range(4):
name = input('Enter name here: ')
cnt.append(name)
return cnt
and then you would do:
myinput = Input()
count = myinput.count()
Your count() method doesn't use any attributes of self, so it doesn't currently need to be written this way. But you might want to redefine it like this:
class Input:
def __init__(self, howmany):
self.howmany = howman
def count(self):
return [input('Enter name here: ') for _ in range(self.howmany)]
myinput = Input(4)
count = myinput.count()
If count is all you want from Input, just make it a function:
def input_names():
cnt = []
for i in range(4):
name = ('Enter name here: ')
cnt.append(name)
return cnt
If you want a configurable Input type of some sort, then you want to run count on an instance of that, you need self:
class Input:
def count(self):
cnt = []
for i in range(self.num_names): # if we need some configuration
name = ('Enter name here: ')
cnt.append(name)
return cnt
Else, the kosher way to do this is to use the staticmethod decorator:
class Input:
#staticmethod
def count():
cnt = []
for i in range(4):
name = ('Enter name here: ')
cnt.append(name)
return cnt
Your current code will work as you use it currently, Input.count(), but if you instantiated an input, Input().count() would throw an exception. The staticmethod decorator ensures that this method is safe to call on either the class directly or on an instance of that class.
when I create a number of instances in the student class
the display method only displays the last entry
here is my code
class student:
def __init__(self):
self.usn= None
self.name=None
self.branch=None
self.phno=None
def read(self):
self.usn=input("enter the usn: ")
self.name=input("enter the name: ")
self.branch=input("enter the branch: ")
self.phno=input("enter the phno: ")
def display(self):
print(f'\n{self.usn} {self.name} {self.branch} {self.phno}\n')
print(f'\nusn %name branch phno\n')
n=int(input("enter number of students : "))
for i in range(n):
emp=student()
emp.read()
print("\nusn name branch phno\n")
for i in student():
emp[i].display()
The read method works well,I am able to enter many student records
but I have an issue with the display method which only prints the last student record
so I tried to iterate the loop but ended up with an error
for i in student():
emp[i].display()
TypeError: 'int' object is not iterable
so how do I iterate to retrieve all the objects
and get to display all the entered student records
You are using the same variable inside the for loop. on each iteration the last entered student get deleted and replaced with the new data. You should use an array (or any other suitable data structure for your use case) and add a new Student in the array on every iteration.
this code should work:
arr = list()
for i in range(n):
emp=student()
emp.read()
arr.append(emp)
You need a structure to hold all the objects of your class, for example, a list.
An empty list can be simply created with emp = [].
Then you can append your objects to the list with the method append().
So you have:
emp = [] #declare empty list
for i in range(n):
emp.append(student())
emp[i].read()
Then you can iterate directly over the list:
for x in emp:
x.display()
On each iteration, x will be the next object in the list
With the answers given by other users,I got the right output I wanted
Here is the code
class student:
def __init__(self):
self.usn= None
self.name=None
self.branch=None
self.phno=None
def read(self):
self.usn=input("enter the usn: ")
self.name=input("enter the name: ")
self.branch=input("enter the branch: ")
self.phno=input("enter the phno: ")
def display(self):
print(f'\n{self.usn} {self.name} {self.branch} {self.phno}\n')
n=int(input("enter number of students : "))
arr = list()
for i in range(n):
emp=student()
emp.read()
arr.append(emp)
for x in arr:
x.display()
I am doing a card game.
The class is called Card:
It can give a random value with the deal() method to display a random card from the numbers 1-13
The other file will import the file name that contains the Class Card. It will call the class 5 times and be able to store it by appending it on a list and displaying it in another def called display_hand
Here is the class file:
import random
class Card:
def __init__(self):
self.__value = 0
def deal(self):
self.__value = random.randint(1, 13)
def set_value(self, value):
self.__value = value
def get_value(self):
return self.__value
def find_face_value(self):
faces = ['Joker','Ace','Two','Three','Four','Five','Six',
'Seven','Eight','Nine','Ten','Jack','Queen','King']
return faces[self.__value]
def __str__(self):
return self.find_face_value()
The program is too big so this is the def for calling the function 5 times:
def deal_hand():
# Create an empty list to append the cards.
hand = []
deal_hand = classcard3.Card()
for i in range(1, 6):
deal_hand = classcard3.Card()
deal_hand.deal()
# Create a new object in memory and assign it to the
# hand variable
w = classcard3.Card(deal_hand)
# add it to the list
hand.append(w)
return hand
Here is the display function:
def display_hand(hand):
print ("The 5-card hand is: ")
for item in hand:
print(hand)
This is not showing anything except for the print inside the loop. How can I pass it to the display hand to show the cards?
This is the only thing that shows whenever I use the print function inside the loop. I'm trying to use it outside and I have no idea what I'm doing wrong. My apologies if I'm not explaining this too well. I'm a beginner at python and new to this website. Thanks
deal Four
deal Three
deal Five
deal Six
deal Queen
The only error that I'm getting from this is:
line 274, in deal_hand
w = classcard3.Card(deal_hand)
TypeError: __init__() takes 1 positional argument but 2 were given
This doesn't make sense, because I'm doing it just as the book says and is not willing to display the values
Am new to Python OOP. Please dont be harsh. Here is my code which calculates which is the fastest time of an athlete from a list and displays them. But When Running, I get this error:
z= add.mylist.min()
NameError: global name 'add' is not defined
My Code:
class Athlete:
def add(self):
list=[]
mylist=[]
for i in range(2):
self.name = raw_input("Enter name: ")
self.fastest_time = input("time: ")
list.append(self.name)
mylist.append(self.fastest_time)
print "Names: ",list
print "Fastest times: ",mylist
def display(self):
z= add.mylist.min()
w= add.mylist.index(z)
print "Minimum time: ",z
print "Name of athelte with fastest time: ",list[w]
x = Athlete()
x.add()
x.display()
You need to refer to methods on the instance with the self parameter. In addition, your add() method needs to return the mylist variable it generates, you cannot refer to method local variables as attributes on methods:
def display(self):
mylist = self.add()
z = min(mylist)
w = mylist.index(z)
def add(self):
list=[]
mylist=[]
for i in range(2):
self.name = raw_input("Enter name: ")
self.fastest_time = input("time: ")
list.append(self.name)
mylist.append(self.fastest_time)
print "Names: ",list
print "Fastest times: ",mylist
return mylist
That is what self is for, as a reference point to find instance attributes and other methods on the same object.
You may want to rename list to something that does not shadow the built-in type.
Martijn has already answered your question, so here are some remarks and code style tips:
New-style classes derive from object
You have both athlete names and their times, those belong together as key-value pairs in a dictionary instead of two separate lists
Don't use print statements inside class methods, a class method should return an object that you then can print
what if you have more then 2 athletes for which you want to enter the time? If you make the number of athletes an argument of your function, you can add a variable number of athlethes
give descriptive variable names (not mylist) and don't use names of builtin functions (like list) as variable name
variables that you want to use throughout your class can be initalized in an __init__method.
For printing, use the format function instead of using commas
use if __name__ == '__main__' so that your Python file can act as either reusable modules or as standalone program
Taking these into account, I would rewrite your code to something like this:
from collections import defaultdict
class Athlete(object): # see (1)
def __init__(self): # see (6)
self.athlete_times = defaultdict(str) # see (2)
def add_athletes_and_times(self, n): # see (4)
for i in range(n):
self.name = raw_input("Enter name: ")
self.fastest_time = input("time (in seconds): ")
self.athlete_times[self.fastest_time] = self.name
def get_fastest_time(self):
return min(self.athlete_times) # see (3)
if __name__ == '__main__': # see (8)
x = Athlete()
x.add_athletes_and_times(2)
for fast_time in x.athlete_times:
print "The fastest time of athlete {0} is {1} seconds.".format(
x.athlete_times[fast_time], fast_time) # see (7)
fastest_time = x.get_fastest_time()
print "The overall fastest time is: {0} seconds for athlete {1}.".format(
fastest_time, x.athlete_times[fastest_time])
For an online course in python, I'm making a basic text-based adventure game in python.
Right now, I have a rudimentary inventory system that works through booleans for if the user has an object or not, and integers for limited items, such as ammo and whatnot.
Here is the code for the inventory system
def Inventory(self): #The inventory for the game. I don't know how to program it properly, so this is my testing ground.
#This will hold the boolean values to if the player has the items or not. Another will be used to show the user the items
street_clothes = False
pistol = False
ammo = 0
phone = False
And this is the code where I am trying to modify the inventory function above
#Eric's apartment
def Eric_Apartment(self):
print "type in grab your gun"
action = raw_input("> ")
if action == "grab":
self.Inventory(CR97) = True
# self.CR97_ammo += 15
# print CR97_ammo
# print self.CR97_ammo
exit(1)
Attempting to run this program gets me this error:
python ex43.py
File "ex43.py", line 78
self.Inventory(CR97) = True
SyntaxError: can't assign to function call
Is there something else I'm supposed to do? I'm very new to python, and this is my first project on my own.
Here is the entire code, for reference
from sys import exit #allows the program to use the exit(1) code
from random import randint #allows the program to use a random number
class Game(object):
#quotes that pop up if the person dies, and also defines the start and self variables
def __init__(self, start):
self.quips = [
"You lose!"
]
self.start = start
def Inventory(self): #The inventory for the game.
#This will hold the boolean values to if the player has the items or not.
street_clothes = False
pistol = False
ammo = 0
phone = False
#this function launches the game, and helps with the room transfer
def play(self):
next = self.start
while True:
print "\n---------"
room = getattr(self, next)
next = room( )
#if the user dies, or fails at the game, this is the function that is ran
def death(self):
print self.quips[randint(0, len(self.quips)-1)]
exit(1)
#Welcome screen to the game
def welcome_screen(self):
print " place holder"
return 'intro_screen'
#Intro screen to the game
def intro_screen(self):
print "place holder"
action = raw_input("> Press any key to continue ")
return 'Eric_Apartment'
#Eric's apartment
def Eric_Apartment(self):
print "type in grab your gun"
action = raw_input("> ")
if action == "grab":
self.Inventory(CR97) = True
# self.CR97_ammo += 15
# print CR97_ammo
# print self.CR97_ammo
exit(1)
a_game = Game("welcome_screen")
a_game.play()
That's an amazingly perverse way to go about it. Why are you using a function to store data?
Just have a player object, with an inventory array.
I'd recommend using objects to model items too. Good use for for a class hierarchy. COuld have a base Item, with Subclasses SingleItem and StackableItem, etc.
Instead of using a function, try using a class -
class Player:
def __init__(self):
self.street_clothes = False
self.pistol = False
self.ammo = 0
self.phone = False
def give_street_clothes(self):
self.street_clothes = True
# etc
But personally, instead of using each item as a boolean, I'd use a list of items:
class Player:
def __init__(self):
self.inventory = []
# add code for ammo/pistol
def has_item(self, item):
return item in self.inventory
def give_item(self, item):
self.inventory.add(item)
def remove_item(self, item):
self.inventory.remove(item)
# etc