Python Print objects in class - python

So I have list of objects in class and I need to print all different songs from one singer.
So far I have this code and I am not sure is it correct
Also I need to use recursion method
def allmusic(listofobjects, name):
nameandsurname=self.name
if(listofobjects.name==nameandsurname):
print(listofobjects.music)
return(listofobjects(music[1:]))
else:
return(listofobjects(name[1:]))
Also I need to print number of singers in that class and code I have is
def allmusic(listofobjects):
numberofsingers=0
for s in listofobjects:
numberofsingers+=1
return(listofobjects()[1:])
print(numberofsingers)

I think this is what you want. It recursively prints the all songs of a specific singer provided in the arguments. Here listOfMusic is the list of Music objects.
def PrintSinger(self, listOfMusic, name):
if(listOfMusic[0].nameOfSinger == name):
print(listOfMusic[0].music)
if(len(listOfMusic) == 1):
return
else:
return self.PrintSinger(listOfMusic[1:], name)

Related

Using __str__ & __repr__ Python methods to print a list from within a class method [duplicate]

This question already has answers here:
What is the difference between __str__ and __repr__?
(28 answers)
Closed 5 months ago.
Firstly, thank you for taking the time to consider my question - I've included a lot of code, I certainly appreciate your support!
I have written two classes:
PlayingCard and Deck
I would like to print the attribute [cards] form the method [shuffle_deck] from the class [Deck]. I have used the str magic method in the class which allows me to correctly output:
deck2 = Deck('♠') >
deck2.shuffle_deck() >
print(deck2)
but it does not work when I try to print a list directly from the method:
print(deck2.cards)
I've watched several youtube videos but am still struggling to understand why this is happening. I've read many posts on this forum, but I can't find a solution that particularly focuses on the contrast between printing the class object versus a list within a class method.
Once again, thank you for your help!
class PlayingCard():
def __init__(self,value,suit):
if value in ['2','3','4','5','6','7','8','9','10','J','Q','K','A'] or value in [2,3,4,5,6,7,8,9,10,'J','Q','K','A']:
self.rank = str(value)
else:
print("Invalid rank!")
raise Exception("Invalid rank!")
if suit in '♥♦♣♠':
self.suit = suit
else:
print('Invalid suit!')
raise Exception('Invalid suit!')
def get_rank(self):
return self.rank
def get_suit(self):
return self.suit
def __str__(self):
return self.rank+" of " +self.suit
class Deck():
ranks=[2,3,4,5,6,7,8,9,10,'J','Q','K','A']
deck_cards=[]
def __init__(self,suit = ['♥','♦','♣','♠']):
self.suits = suit
for rank in Deck.ranks:
for suit in self.suits:
card = PlayingCard(rank,suit)
Deck.deck_cards.append(card)
self.cards=[]
for card in Deck.deck_cards:
if card.get_suit() == suit:
self.cards.append(card)
def shuffle_deck(self):
random.shuffle(Deck.deck_cards)
def deal_card(self,count):
deal_cards = []
if count <= len(self.cards):
deal_cards = random.sample(self.cards,count)
for card in deal_cards:
self.cards.remove(card)
deal_card_str=''
for card in deal_cards:
deal_card_str += card.__str__()+", "
print(deal_card_str[:-2])
else:
print('Cannot deal '+str(count)+' cards. The deck only has '+str(len(self.cards))+' cards left!')
def __str__(self):
full_deck=''
for card in Deck.deck_cards:
full_deck += card.__str__()+", "
return full_deck[:-2]
deck2 = Deck('♠')
deck2.shuffle_deck()
print("I want to change this output to match the lower output", deck2.cards)
print("This is the correct format", deck2)```
It's not working because deck2.cards is a list, so you'll need to iterate through that, like this:
deck2 = Deck('♠')
deck2.shuffle_deck()
print("I want to change this output to match the lower output"
print("{:s}".format(', '.join(deck2.cards)))
print("This is the correct format", deck2)
(Similarly to what you've done in the Deck class). This makes sense because each PlayingCard is a class instance of a single card, so there is no way for it to store the information on multiple cards, except in the way that you've already done it. In other words, the str function of PlayingCard only has access to its own data.

How to print actual name of variable class type in function?

I'm trying to return variable name, but i keep getting this:
<classes.man.man object at (some numbers (as example:0x03BDCA50))>
Below is my code:
from classes.man import man
def competition(guy1, guy2, counter1=0, counter2=0):
.......................
some *ok* manipulations
.......................
if counter1>counter2:
return guy1
bob = man(172, 'green')
bib = man(190, 'brown')
print(competition(bob , bib ))
Epilogue
If anyone want to, explain please what I can write instead of __class__ in example below to get variable name.
def __repr__(self):
return self.__class__.__name__
Anyway, thank you for all of your support
There are different ways to approach your problem.
The simplest I can fathom is if you can change the class man, make it accept an optional name in its __init__ and store it in the instance. This should look like this:
class man:
def __init__(number, color, name="John Doe"):
self.name = name
# rest of your code here
That way in your function you could just do with:
return guy1.name
Additionnally, if you want to go an extra step, you could define a __str__ method in your class man so that when you pass it to str() or print(), it shows the name instead:
# Inside class man
def __str__(self):
return self.name
That way your function could just do:
return guy1
And when you print the return value of your function it actually prints the name.
If you cannot alter class man, here is an extremely convoluted and costly suggestion, that could probably break depending on context:
import inspect
def competition(guy1, guy2, counter1=0, counter2=0):
guy1_name = ""
guy2_name = ""
for name, value in inspect.stack()[-1].frame.f_locals.items():
if value is guy1:
guy1_name = name
elif value is guy2:
guy2_name = name
if counter1 > counter2:
return guy1_name
elif counter2 > counter2:
return guy1_name
else:
return "Noone"
Valentin's answer - the first part of it at least (adding a name attribute to man) - is of course the proper, obvious solution.
Now wrt/ the second part (the inspect.stack hack), it's brittle at best - the "variables names" we're interested in might not necessarily be defined in the first parent frame, and FWIW they could as well just come from a dict etc...
Also, it's definitly not the competition() function's responsability to care about this (don't mix domain layer with presentation layer, thanks), and it's totally useless since the caller code can easily solve this part by itself:
def competition(guy1, guy2, counter1=0, counter2=0):
.......................
some *ok* manipulations
.......................
if counter1>counter2:
return guy1
def main():
bob = man(172, 'green')
bib = man(190, 'brown')
winner = competition(bob, bib)
if winner is bob:
print("bob wins")
elif winner is bib:
print("bib wins")
else:
print("tie!")
Python prints the location of class objects in memory if they are passed to the print() function as default. If you want a prettier output for a class you need to define the __repr__(self) function for that class which should return a string that is printed if an object is passed to print(). Then you can just return guy1
__repr__ is the method that defines the name in your case.
By default it gives you the object type information. If you want to print more apt name then you should override the __repr__ method
Check below code for instance
class class_with_overrided_repr:
def __repr__(self):
return "class_with_overrided_repr"
class class_without_overrided_repr:
pass
x = class_with_overrided_repr()
print x # class_with_overrided_repr
x = class_without_overrided_repr()
print x # <__main__.class_without_overrided_repr instance at 0x7f06002aa368>
Let me know if this what you want?

How to call objects from a class in a function of another class

I want to use an object of a class in a function of another class. I know it's a really easy thing to solve, but I still can't figure it out.
I have the following class that is an object of players
class Players():
def __init__(self, name_player, surname, age, height, wheight):
self.name_player= name_player
self.surname = surname
self.age= age
self.height= height
self.wheight= wheight
def __repr__(self):
return "{}, {}, {}, {}, {} //".format(self.name_player,self.surname,self.age,self.height,self.wheight)
Then I have this class of teams
class Teams():
def __init__(self, name, points, goals_in_favour, goals_against):
self.name= name
self.points= points
self.goals_in_favour= goals_in_favour
self.goals_against= goals_against
def __repr__(self):
return "{} : {} : {}: {}".format(self.name,self.points,self.goals_in_favour,self.goals_against)
Now in the function 'ages' I want it to return a list of the players with an age less or equal to the one on the file. If I write 'i.Players.age' it sends me an error, which is the right way to spell it?
def ages(lists_teams,age):
list_players =""
return [list_players + i for i in list_teams if (i.Players.age <= age)]
(I have to write it in a list comprehension way).
Thanks a lot in advance.
To help you understand.
1.If list_teams is already an list of objects...you cannot call i.Players, because i here is already an object.
2.list_players="" you should change it to []...."" is not a list, you cannot add object on to it.
3.Try not use i for object, it is normally used to indicate an index..
def ages(list_teams,age):
list_players =[]
return [list_players + [player] for player in list_teams if (player.age <= age)]

Creating a list within an object (book/patron waitlist)

I have a homework assignment to create a "library" with a patron class and book class. This library should allow people to check out up to 3 books, and add a book to a patron's waitlist if the book is already checked out. Upon the books return, it should be automatically checked out to the first person on the waitlist. I can't seem to get the list to work. Here's my code:
class Patron(object):
def __init__(self,name,booksOut=0):
self._name=name
self._booksOut=booksOut
def getBooksOut(self):
return self._booksOut
def __str__(self):
result="Name: "+self._name+"\n"
result+="Books Out: "+str(self._booksOut)+"\n"
return result
class Book(object):
def __init__(self,title,author,owner=None):
self._title=title
self._author=author
self._owner=owner
self._queue=[] #Here is the empty list I'm using... but it doesn't seem to be working.
def setOwner(self,owner):
self._owner=owner
def getOwner(self):
return self._owner
def borrowMe(self, patron):
if self._owner != None:
return "This book is not available. You've been added to the queue.\n"
self._queue.append(patron)
print(str(self._queue)) #I can't even get the list to print, so I'm feeling like I didn't create it correctly
else:
if patron.getBooksOut()>=3:
return "You have too many books checked out!"
else:
self.setOwner(patron)
patron._booksOut+=1
return "You have successfully checked this book out."
def returnMe(self):
if len(self._queue)==0:
self.setOwner(None)
return "Your book has been returned."
else:
return "Your book has been given to: "+str(self._queue[0])
self.borrowMe(self._queue[0]) #Here is where I'm trying to automatically borrow the book to the first person in the waitlist
def __str__(self):
result="Title: "+self._title+"\n"
result+="Author: "+self._author+"\n"
if self._owner != None:
result+="Owner: "+str(self.getOwner())
else:
result+="Owner: None"
return result
def main():
"""Tests the Patron and Book classes."""
p1 = Patron("Ken")
p2 = Patron("Martin")
b1 = Book("Atonement", "McEwan")
b2 = Book("The March", "Doctorow")
b3 = Book("Beach Music", "Conroy")
b4 = Book("Thirteen Moons", "Frazier")
print(b1.borrowMe(p1))
print(b2.borrowMe(p1))
print(b3.borrowMe(p1))
print(b1.borrowMe(p2))
print(b4.borrowMe(p1))
print(p1)
print(b1)
print(b4)
print(b1.returnMe())
print(b2.returnMe())
print(b1)
print(b2)
I've #commented the parts containing the list creation (in the init for the book class) and where I tried to print the list to do some error checking (in the borrowMe method) and also where I am trying to automatically borrow the book to the first person on the waitlist/queue (in the returnMe method).
Any insight is appreciated.
if self._owner != None:
return "This book is not available. You've been added to the queue.\n"
self._queue.append(patron)
print(str(self._queue))
You are printing after return. Nothing will be executed after return. Change it to print. Also in Patron class, change __str__ to __repr__. Otherwise it will print a list of memory addresses. In addition, print(str(self._queue)) is redundant, you could print the list directly.

Use a list in different functions in python

I want to use a list throughout a program I am writing. Basically, it is a list full of tuples with information regarding different people, each person's information (name, phone, address, etc) is stored as in a tuple. I define this list through an initial function, but i need to use this in my interaction function as well as others.
My question is, is it possible for me to use this list without defining it as a global variable?
def load_friends(filename):
"""imports filename as a list of tuples using the import command"""
import csv
with open(filename, 'Ur')as filename:
friends_list = list(tuple(x) for x in csv.reader(filename, delimiter=','))
def add_friend(friend_info, friends_list):
"""appends the friend_info tupple to the list friends_list"""
new_list = friends_list.append(friends_info)
def interact():
"""interaction function: accepts user input commands"""
while True:
command = raw_input('Command: ')
I should also mention that there is a command to parse the use inputs to perform the functions. Would this affect the use of the list?
You could declare list inside the first function that calls it and return it from there, latter functions should receive this list as an argument then.
def func1():
my_list=[]
"""Do stuff
"""
return list
def func2(my_list):
"""Do stuff with my_list
"""
return
def func3(my_list):
"""Do stuff with my_list
"""
return
def main():
"""First we retrieve the list from func1,
func2/3 get it passed to them as an argument
"""
foo=func1
func2(foo)
func3(foo)
if __name__ == "__main__":
main()
You could do the following:
# you can define the list here, it's global but doesn't require the keyword
my_list_globally = []
def func1(the_list):
pass
def func2(the_list):
pass
def func3(the_list):
pass
# you can use a hub function to pass the list into things that need it
def main():
my_list = []
func1(my_list)
func2(my_list)
func3(my_list)
if __name__ == "__main__":
main()
I don't quite understand the last part of your question but one of those 2 ways will be what you need.
Yes. Pass the "list of friends" back and forth between functions as an argument.
load_friends() would become
def load_friends(filename):
import csv
with open(filename, 'Ur') as f:
return map(tuple, csv.reader(f, delimiter=","))
add_friend() is close, but that assignment to new_list is unnecessary, because list.append() mutates the existing list in place:
def add_friend(friend_info, friend_list):
friend_list.append(friend_info)
would suffice.
interact() would also have a friends_list argument.
def interact(friends_list):
#interaction stuff here...
and you could call it like so:
interact(load_friends("myfile.csv"))
Classes are useful for this kind of thing, and easy to use:
class PersInfo:
def setName(self, name):
self._name = name
def getName(self):
return self._name
def setNumber(self, number):
self._phNumber = number
def getNumber(self):
return self._phNumber
def setAddr(self, address):
self._address = address
def getAddr(self)
return self._address
def main():
# Read in data from your CSV Here
infoList = ([])
for person in person_list: # Assuming person is a tuple here
foo = PersInfo()
foo.setName(person[index1])
foo.setNumber(person[index2])
foo.setAddr(person[index3])
infoList.append(foo)
# To access the info...
for person in infoList:
print(person.getName())
print(person.getNumber())
print(person.getAddr())
You do end up with the list being "global," sort of. It is in the main() function, where the PersInfo objects are being instantiated. This may be more than you wanted, but in the long run it is a good way to organize your code and keep it readable.
Also, you could build the infoList I made directly where you are creating person_list.

Categories