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?
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!
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
I'm writing a script to find the moving average of different stocks. This script runs continuously, looping through my API call to add the current price to a list before averaging it. This works fine, however I'd like to be able to put this into a function to where the only input I need to give it is the name of the stock. I'd like this script to work for as many stocks as I want to specify, at the same time. That's where I run into issues because for each stock I have I need to have an empty list predefined that can hold the pricing information.
I've been trying to use the name of the stock to then create a related list, but as I now understand it it's not a great idea using one variable name to create another variable, so I'm not sure what to do. I believe the usual solution here would be to use a dictionary, but I'm a beginner to programming in general so I haven't figured out how to fit that into my situation. Any help would be greatly appreciated.
def sma(stock_name):
list_exists = stock_name + "_list" in locals() or stock_name + "_list" in globals()
if list_exists:
print()
else:
stock_name + "_list" = [] # Problem line, I would like for this to create a list called stock_name_list
stock_price = requests.get("myapi.com", params={"stock_name": stock_name, "bla bla": "blah"})
stock_name_list.append(stock_price)
When you have an operation based on a version of the data specific to that operation, that is usually a good time to think about using classes. This particular proposed class will encapsulate the name of a stock, the list of data specific to it, and perform sma on it:
class Stock:
n = 10
def __init__(self, name):
self.name = name
self.data = []
def sma(self):
stock_price = requests.get("myapi.com", params={"stock_name": self.stock_name, "bla bla": "blah"})
self.data.append(stock_price)
window = self.data[-n:]
return sum(window) / len(window)
Now you can maintain a dictionary of these objects. Any time you encounter a new stock, you just add an item to the dictionary:
stocks = {}
def sma(name):
stock = stocks.get(name)
if name is None: # None is what get returns when the key is missing
stock = Stock(name)
stocks[name] = stock
return stock.sma()
The nice thing is that you now have a dictionary of named datasets. If you want to add a different statistic, just add a method to the Stock class that implements it.
I defined a global sma function here that calls the eponymous method on the object it finds in your dictionary. You can carry encapsulation to an exterme by making the method perform the action of the function if called statically with a name instead of an instance. For example:
class Stock:
n = 10
named_stocks = {} # This is a class variable that replaces the global stocks
def __init__(self, name):
self.name = name
self.data = []
def sma(self):
if isinstance(self, str):
self = Stock.get_stock(self)
stock_price = requests.get("myapi.com", params={"stock_name": self.stock_name, "bla bla": "blah"})
self.data.append(stock_price)
window = self.data[-n:]
return sum(window) / len(window)
#classmethod
def get_stock(cls, name):
stock = cls.named_stocks.get(name)
if stock is None:
stock = cls(name)
cls.named_stocks[name] = stock
return stock
Now that there is a check for isinstance(self, str), you can call the sma method in one of two ways. You can all it directly on an instance, which knows its own name:
aapl = Stock('AAPL')
aapl.sma()
OR
Stock.get_stock('AAPL').sma()
Alternatively, you can call it on the class, and pass in a name:
Stock.sma('AAPL')
use defaultdict
from collections import defaultdict
stock_name_to_stock_prices = defaultdict(list)
stock_name_to_stock_prices['STOCK_NAME'].append(123.45)
In this example, it's working
hotels as a class variable no NameError
class Hotel():
"""""""""
this is hotel class file
"""
hotels = []
def __init__(self,number,hotel_name,city,total_number,empty_rooms):
self.number = number
self.hotel_name = hotel_name
self.city = city
self.total_number = total_number
self.empty_rooms = empty_rooms
Hotel.hotels.append([number,hotel_name,city,total_number,empty_rooms])
def list_hotels_in_city(self,city):
for i in hotels:
if city in i:
print "In ",city,": ",i[1],"hotel, available rooms :",i[4]
In the following example its not working
from twilio.rest import Client
class Notifications():
customers = []
def __init__(self,customer_name,number,message):
self.customer_name = customer_name
self.number = number
self.message = message
Notifications.customers.append([customer_name,number,message])
def send_text_message(self,customer_name):
for i in customers:
print "triggeredb"
inst = Notifications("ahmed","+00000000000","messagesample")
print "instance : ",inst.customers
inst.send_text_message("ahmed")
NameError: global name 'customers' is not defined
Update
for first example nothing called to show error
but issue solved for second example Thanks Tom Dalton , scharette and James
As I said in my comment, When you call for i in customers:, customers is not in scope of that function.
I just wanted to add also, that you use
Notifications.customers.append([customer_name,number,message])
but you also declare
customers = []
Note that the former is a class variable and will share the variable among Notifications instances. The latter represent an instance variable. If your goal is to have a customers list for every specific object, you should use self.customers.
So basically,
You want shared list between objects ?
for i in Notifications.customers:
You want specific list for every object ?
for i in self.customers:
I think it's very likely that when you ran your first example, you had a variable called hotels in your global (interpreter) scope. Thats why it's working. If I copy paste your example into my interpreter it fails with the same error message as your second code sample.
If your send_text_message function only accesses class variables (no instance variables) I would recommend making it a class method like this :
#classmethod
def send_text_message(cls, customer_name):
for i in cls.customers:
print "triggeredb"
That way you can access the class variables using the cls variable and won't have to repeat the class name in your function (which is nice, as if you change the class name - you won't have to go hunting through your code for repetitions).
I just started programming and I decided to use Python for my first attempts at coding, and I am now practicing with classes and objects.
I apologize if the question I am about to ask has been asked before, but I can't seem to find answers anywhere, so here it goes.
I have a file that contains a class. Below the full code I have written :
#class file
#class prodotti refers to "register" with products in stock and their prices
class Prodotti(): #class Prodotti() contains products from register and their relative specs
def __init__(self, nome="", #name of product
prezzo=0, #product price
quantità=0,): #stock quantity of product
self.nome=nome
self.prezzo=prezzo
self.quantità=quantità
def newproduct(self): #method appends new product and its specs to the end of this file
name=input("Inserire nuovo prodotto: ")
f=open("cassa3.py", "a")
f.write(name + "=Prodotti(nome='" + name + "', ")
price=input("Inserire prezzo prodotto: ")
f.write("prezzo=" + price + ", quantità=0)\n")
f.close()
def tellprice(self): #method should return price of object
inp=input("Di quale prodotto vuoi conoscere il prezzo? ") #asks user which product they want to know the price of
if inp=Prodotti():
print(inp.prezzo)
#class objects
#user can insert new products that are saved below
tortino=Prodotti(nome="Tortino al cioccolato", prezzo=3.4, quantità=0)
muffincioccolato =Prodotti(nome="Muffin al cioccolato", prezzo=1.8, quantità=0)
cupcake=Prodotti(nome='cupcake', prezzo=2, quantità=0)
In another file, saved in the same directory, I have the main program:
from cassa3 import Prodotti #file cassa3.py in same directory as this file
if __name__=="__main__":
P=Prodotti()
P.tellprice()
As you may tell from the code above, what I want method tellprice() to do is to ask the user what product they want to know the price of.
However, I just don't know how to make the user input correspond to a class object, so that I can access its attributes.
Can someone explain how i could manage to do that?
Thanks in advance.
Before you will be able to solve this issue, you will need to fix the design problem you have.
Your comment says # class Prodotti() contains products from register and their relative specs but it is not quite true. This class contains a single product with its name, price and quantity.
You will need to define another class (perhaps Register) that will actually store a list (or dictionary if product names are unique for efficient lookup, or whatever) of products (instances of Prodotti).
The tellprice method currently makes no sense. It simply creates a new instance of Prodotti and the if condition will never be True.
Also, it is highly suggested to use English names in code.
Consider the below example as a general guide:
class Product:
def __init__(self, name, price, quantity):
self.name = name
self.price = price
self.quantity = quantity
# (... some other methods ... )
class Register:
def __init__(self, products):
# this will store the products in a dictionary with products names as keys
# and Product instances as values for an efficient look up by tell_price
self.products = {product.name: product for product in products}
def tell_price(self):
name = input('Which product would you like to know the price of?')
# this will raise KeyError if user inputs a non-existing product name
# and should be caught, or use .get(...) instead
return self.products[name].price
apple = Product('apple', 1, 10)
banana = Product('banana', 2, 2)
register = Register([apple, banana])
print(register.tell_price())
# Which product would you like to know the price of?
>> apple
# 1
I wouldn't make your tellprice include user input.
def tellprice(self): #method should return price of object
return self.price
Then in main (this is significantly simplified):
inp = input("Di quale prodotto vuoi conoscere il prezzo? ")
print(inp.tellprice)
Obviously this assumes they put in the correct product name, so some way of indicating to the user that they're incorrect might be useful