I was trying to write a function in python to print out all the overlapping movie interests.
I wanted to write this program as a little classes and objects exercise. So this is what it looks like, right now:
def main():
class Person:
def __init__(self, Film):
self.Film = Film
like_it = "Film" , "Movie"
def likes(self, Film):
if (Film in like_it):
return Film
else:
print("no movies in common")
Person1 = Person("Movie")
print(Person1.likes)
I wanted to initialize different People as objects in the class "Person". The Program doesn't see any mistakes, but prints nothing. What is wrong here? Where should I look?
Thank you so much for your help!!
You aren't passing Film as an argument in the likes method.
Working with Classes
class Person:
def __init__(self, Film):
self.Film = Film
like_it = "Film" , "Movie"
def likes(self):
if (self.film in like_it):
return self.film
else:
return "no movies in common" #we are returning string instead of printing
Person1 = Person("Movie")
print(Person1.likes()) #likes is a method that has to be called
References:
Object Oriented Programming with python
Further Reading:
Converting methods to property
Related
I am trying to do some simple stuff with OOP and Python, building some simple books service. I am trying to create class for Books, where each object will be a Book with attributes, that works, it is not the best, but good enough for now.
# Definition of class
class Books(object):
book_id = ""
book_title = ""
book_author = ""
book_year = ""
book_pub = ""
book_ac = ""
book_date = ""
Books = [book_id, book_title, book_author,
book_year, book_pub, book_ac, book_date]
# Set constructor
def __init__(self, book_id, book_title, book_author, book_year, book_pub, book_ac, book_date):
self.book_id = book_id
self.book_title = book_title
self.book_author = book_author
self.book_year = book_year
self.book_pub = book_pub
self.book_ac = book_ac
self.book_date = book_date
# Set attributes
def set_book_id(self, book_id):
self.book_id = book_id
def set_book_title(self, book_title):
self.book_title = book_title
def set_book_author(self, book_author):
self.book_author = book_author
def set_book_year(self, book_year):
self.book_year = book_year
def set_book_pub(self, book_pub):
self.book_pub = book_pub
def set_book_ac(self, book_ac):
self.book_ac = book_ac
def set_book_date(self, book_date):
self.book_date = book_date
# Show attributes
def show_book_id(self):
print(self.book_id)
def show_book_title(self):
print(self.book_title)
def show_book_author(self):
print(self.book_author)
def show_book_year(self):
print(self.book_year)
def show_book_pub(self):
print(self.book_pub)
def show_book_ac(self):
print(self.book_ac)
def show_book_date(self):
print(self.book_date)
# Show book
def show_book(self):
print(self.book_id)
print(self.book_title)
print(self.book_author)
print(self.book_year)
print(self.book_pub)
print(self.book_ac)
print(self.book_date)
Second Class is Booklist, which should hold the books inside and manage books inside, I am trying to create some basic methods as to create objects in Booklist automatically as I create Books object(this should work). Then I would like to operate with Booklist as with inherited methods from Books class to show the Books or etc.
# Definition of class
class BookList(Books):
listbook = []
# Set constructor
def __init__(self):
self.listbook = []
# Add book
def add_book(self, Books):
return self.listbook.append(Books)
# Show book
def show_books(self):
for b in self.listbook:
super().show_book(self)
# Search book
def search_book_by_id(self):
self.listbook = []
for Books in self.book_id:
if Books.book_id == id:
id.append(Books)
return id
Bellow are my tests, as I am still fighting with error like issues of parsing arguments-Expected one or more arguments from would anyone help here what would be the easiest please to use inherited method or to manipulate with inheritance for this use case please? Thank you
# Books defining
book1 = Books('1504234', 'Murders', 'Peter Jacob',
'2015', 'Ikaro', '5', '25.5.2015')
book2 = Books('1504231', 'Murders', 'Peter Jacob',
'2015', 'Ikaro', '5', '25.5.2015')
book3 = Books('1504232', 'Hiden language', 'Samuel Fellow',
'2005', 'Parik', '3', '21.4.2006')
book4 = Books('1504233', 'Saturday', 'Filp Sapko',
'2012', 'Satik', '4', '25.3.2012')
book1.show_book()
book1.set_book_title('New Murders')
book1.show_book()
book1.show_book_ac()
print("Booklist ******************************")
BookList.listbook.append(book1)
BookList.listbook.append(book2)
BookList.listbook.append(book3)
BookList.listbook.append(book4)
(Until here it works)Now the issue begins:
BookList.show_books()ERROR:
TypeError: show_books() missing 1 required positional argument: 'self'
Would anyone please tell me what I am doing wrong here?
Thank you very much!
Best Regards
To start with, I think you're imagining the structure of these classes a little wrong. The "Books" class shouldn't be the parent of "BookList" if you intend to use the super() method to access "show_books". Not to worry, you're almost there already
you only need to change it from this:
#Show book
def show_books(self):
for b in self.listbook:
super().show_book(self)
to this:
#Show book
def show_books(self):
for b in self.listbook:
b.show_book()
Your "search_book_by_id" method will also need to change from this:
#Search book
def search_book_by_id(self):
self.listbook = []
for Books in self.book_id:
if Books.book_id == id:
id.append(Books)
return id
to this:
#Search book
def search_book_by_id(self, id):
id_books = []
for b in self.listbook:
if b.book_id == id:
id_books.append(Books)
return id_books
Though I'm not sure exactly what that function was attempting before.
You also said you wanted the BookList class to automatically add books when you create them, there are far more complicated ways to link classes which I think you might not need, if all you need is for the Book class to live inside the BookList class, then I would suggest making a create_book function inside the BookList class that adds the book to the list once created, that way you only use one object. That would look something like this:
def create_book(self,book_id,book_title,book_author,book_year,book_pub,book_ac,book_date):
self.listbook.append(Books(book_id,book_title,book_author,book_year,book_pub,book_ac,book_date))
That's a pretty messy function, and you should probably look into better ways to handle objects with many attributes, checkout the #property decorator and look for other ways to store data than attributes, you can also use (*args, **kwargs) to really make things easy on the user of the function, but if you're very new to python, sometimes keeping things messy but simple is better to learn the basics with. Let me know if that helps or you need something else!
So I'm trying to create a program that resembles an auction, and so far I have created a class that takes in information about the person who is bidding, the bidder id, and the code (in that order in def(__init__(self...))) and here is what I have so far...
class Starter:
def __init__(self, startd, starterid, bidding):
self.startd = startd
self.starterid = starterid
self.bidding = bidding
and now, I'm trying to implement a new class, Bidding, where each auction is identified by an auction identifier.
The class has the following features:
• It can be created via Bidding(bidding), (bidding) is from class Starter btw for example,
bidtest = Auction('ewmzr')
creates an instance of Bidding with bidding identifier 'ewmzr'.
• The method beginbid(bidder_id) reflects the action of the bidder with bidder_id placing a
bid on this auction. That is to say, if a is an Bidding instance, the call to a.beginbid(starterid) places a bid from a bidder with starterid.
• If a is a Bidding instance, then a.price is the current price of this bidding, and a.winner
is the current winner of this bidding. Before anyone places a bid, a.winner is, by convention,
None.
Here is what I have so far...
class Starter:
def __init__(self, startd, starterid, bidding):
self.startd = startd
self.starterid = starterid
self.bidding = bidding
c = Starter(1, '8dac2b', 'ewmzr')
class Bidding:
def __init__(self,bidding):
self.bidding = self.bidding
def Beginbid(self,starterid):
return starterid
However, this doesn't work at all. I think I'm not understanding the concept of classes ig. Can someone please help me solve this issue?
It sounds like you want your bidding object to hold the id of the current highest bidder and that you want to give it an initial value of whoever started the bidding?
You could pass in the Starter object like this:
class Starter:
def __init__(self, startd, starterid):
self.startd = startd
self.starterid = starterid
class Bidding:
def __init__(self, starter):
self.current_bidder = starter.starterid
c = Starter(1, '8dac2b', 'ewmzr')
b = Bidding(c)
It would probably work better to directly store a reference to the current bidder rather than their ID though:
class Starter:
def __init__(self, startd, starterid):
self.startd = startd
self.starterid = starterid
class Bidding:
def __init__(self, starter):
self.current_bidder = starter
c = Starter(1, '8dac2b', 'ewmzr')
b = Bidding(c)
That way you don't need to be able to look up the object from its ID later.
If begin_bid is intended to update the current highest bidder then it simply looks like:
def begin_bid(self, bidder):
self.current_bidder = bidder
The other methods would be variations on a theme after that, updating or fetching instance variables.
Does this help at all?
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?
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.
pI am working on a bit of code that does nothing important, but one of the things I am trying to make it do is call a function from another class, and the class name is pulled out of a list and put into a variable. Mind you I have literally just learned python over the last 2 weeks, and barely know my way around how to program.
What I believe that this should do is when getattr() is called, it will pass the attribute 'run_question' that is contained in the respective class with the same name as what is in question_type, and then pass it onto 'running_question'. I know there are probably better ways to do what I am attempting, but I want to know why this method doesn't work how I think it should.
#! /usr/bin/python
rom random import randrange
class QuestionRunner(object):
def __init__(self):
##initialize score to zero
self.score = 0
##initialize class with the types of questions
self.questiontypes = ['Addition', 'Subtraction', 'Division', 'Multiplication']
##randomly selects question type from self.questiontypes list
def random_type(self):
type = self.questiontypes[randrange(0, 4)]
return type
##question function runner, runs question function from self
def run_questions(self):
try:
question_type = self.random_type()
running_question = getattr(question_type, 'run_question' )
except AttributeError:
print question_type
print "Attribute error:Attribute not found"
else: running_question()
class Question(object):
pass
class Multiplication(Question):
def run_question(self):
print "*"
class Division(Question):
def run_question(self):
print "/"
class Subtraction(Question):
def run_question(self):
print "-"
class Addition(Question):
def run_question(self):
print "+"
test = QuestionRunner()
test.run_questions()
This outputs:
[david#leonid mathtest] :( $ python mathtest.py
Division
Attribute error:Attribute not found
[david#leonid mathtest] :) $
Which indicates that I am not getting the run_question attribute as I expect.
I should note that when I put the functions into the QuestionRunner class in the following way, everything works as expected. The main reason I am using classes where it really isn't needed it to actually get a good grasp of how to make them do what I want.
#! /usr/bin/python
from random import randrange
class QuestionRunner(object):
def __init__(self):
##initialize score to zero
self.score = 0
##initialize class with the types of questions
self.questiontypes = ['addition', 'subtraction', 'division', 'multiplication']
##randomly selects question type from self.questiontypes list
def random_type(self):
type = self.questiontypes[randrange(0, 4)]
return type
##question function runner, runs question function from self
def run_questions(self):
try:
question_type = self.random_type()
running_question = getattr(self, question_type)
except AttributeError:
exit(1)
else: running_question()
def multiplication(self):
print "*"
def division(self):
print "/"
def addition(self):
print "+"
def subtraction(self):
print "-"
test = QuestionRunner()
test.run_questions()
Any help on why this isn't working would be great, and I appreciate it greatly.
Any help on why this isn't working would be great, and I appreciate it greatly.
Ah, I have found out the missing concept that was causing my logic to be faulty. I assumed that I could pass the name of an object to getattr, when in reality I have to pass the object itself.