Appending variables to Lists/Call list from another function - python

So I fixed the issues previous that were based on not having the list defined properly. Is it possible to organize the items in the list? Or is it always going to display the way it was added? If there is a way to update the list after being created and added to, how?
This is the main class file:
def storing():
the_item = Ch10b_retailItemClass.RetailItem("","","")
for count in range(3):
desc = input('What item would you like to inventory?\n')
unit = input('How many of them are in stock?\n')
price = input('What\'s the price for this item?\n')
the_item.set__desc(desc)
the_item.set__unit(unit)
the_item.set__price(price)
# I want to print the list as a whole.
print(the_item.list_function())
And this is my class being imported:
class RetailItem:
global inv
inv = []
# init function, getting us started and initializing variables?
def __init__(self, desc, unit, price):
self.__desc = desc
self.__unit = unit
self.__price = price
# functions that create temp place holders
def set__desc(self, desc):
self.__desc = desc
inv.append(desc)
def set__unit(self, unit):
self.__unit = unit
inv.append(unit)
def set__price(self, price):
self.__price = price
inv.append(price)
def list_function(self):
return inv

Related

Python - displaying data when using classes

I am looking to work out how to get the name of the budget to appear in the output - the code creates a list (name of budget and budget amount) and appends these as list items to a main list. I realise importing the Budget class to the app file is the way of accessing functionality but I am wondering how to extract the data created within the app file so the repr
def __repr__(self):
return f"The budget is {self.balance}."
can return the name of the budget in the list
I have two files: budget_app.py and another budget_class.py
The app file uses the exec function to append new items to a list
from budget_class import Budget
list = []
def createBudget():
list2 = []
addbudgetname = input("Name the budget:")
exec1 = f"{addbudgetname} = Budget({int(input('How much to add to budget:'))})"
exec(exec1)
exec2 = f"list2.append({addbudgetname})"
exec(exec2)
return(list2)
list.append(createBudget())
list.append(createBudget())
for item in list:
print(item)
The class file initializes the Budget
class Budget():
class Budget():
def __init__(self, balance):
self.balance = balance
def __repr__(self):
return f"The budget is {self.balance}."
I am trying to work out a way of getting the name of the budget to appear in the output, which is currently
How much to add to budget:60
Name the budget:apples
How much to add to budget:800
[The budget is 60.]
[The budget is 800.]
The class structure is suboptimal, I would suggest to make a complete refactor, something as the following:
class Budget():
def __init__(self, balance=0, name=None, list2=[] ):
self.balance = balance
self.name = name
self.list2 = list2
def createBudget(self):
self.name = input("Name the budget:")
self.list2.append(input("How much to add to budget:"))
def add_to_balance(self, to_add):
self.balance += to_add
def __repr__(self):
return f"The budget is {self.balance}. and the name {self.name}"
budget1 = Budget(0,'name1',[1,2])
budget2 = Budget(4,'name2',[1,5])
budged_list = [budget1,budget2]
Now you can instantiate the class directly with the arguments or add them with your input support, you can also print the name etc.

Python. How to define an Items object within my inventoryRead method and then Call the inventoryRead method

In my inventoryRead how can I properly define an Items object. Also, how do I run this method
Traceback (most recent call last):
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 7, in <module>
class Items:
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 34, in Items
inventoryRead('self')
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 24, in inventoryRead
item1 = Items()
NameError: name 'Items' is not defined
code
class Items:
# Constructor to initilize an item object
# An item has name, quantity, price, member price, and taxing status
def __init__(self, name, quantity, price, memPrice, taxStatus):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
def inventoryRead(self):
txt = ""
count = 0
f = open("inventory.txt", "r")
inList = []
item1 = Items()
print(item1)
for line in f.readlines():
item1.name = line[0:line.find(":")]
print(item1)
print(item1.name)
inList[count] = Items()
txt = line.next()
print(txt)
inventoryRead('self')
#arr = f.readlines()
#print(arr[0])
I think it would be smarter if you had an Item and a separate ItemMangager or Items class. I'm going to call it Items from now on.
Items would contain some store every Item in (for example) a list and Items loads them from the file, but also saves them to same.
You try to create an instance of the class you are currently in, the main way you would edit this file is through the self prefix you used before to modify this instances attributes.
The example I provide is done using a .txt file for storage to keep to your way of doing it, although it would probably be smarter to use an actual database module like sqlite, you should have a look into that.
#!/usr/bin/env python3
#Item holds one record of sth
class Item():
def __init__(self,name, quantity, price, memPrice, taxStatus):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
class Item_Manager:
def __init__(self):
self.items=[]
self.data_file_path="records.txt"
def load_data(self):
with open(self.data_file_path,"r") as f:
contents= f.read()
for i in contents.split("\n"): #splits every line into a new string
data=i.split(" ") #asuming every line has the attributes space-separated
item=Item(data[0],data[1],data[2],data[3],data[4])
self.items.append(item) #saving the new created Item instance in the mangagers items list
def save_data(self): #overwriting
with open(self.data_file_path,"w") as f:
for i in self.items: #i = item instance
f.write("{} {} {} {} {}".format(i.name,i.quantity,i.price,i.memPrice,i.taxStatus))
def create_item(self):
name=input("Name: ")
quantity= input("Quantity: ")
price=input("Price: ")
memPrice= input("MemPrice: ")
taxStat = input("Tax Status: ")
item=Item(name, quantity, price, memPrice, taxStat)
self.items.append(item)
def display_data(self):
for i in self.items:
print(i.name,i.quantity,i.price,i.memPrice,i.taxStatus)
Hope this helps, if you have any further questions, just comment under this.
There are two main issues here:
Your code is obviously faulty, see below, and
You have made some strange design choices.
Code Error:
Your error comes from line: inventoryRead('self')
This is wrong because:
you do not write self into a class method call. It is passed by itself.
Your method call is outside of context. It is not part of another method in the class, while it obiously isn't an attribute.
Sort off "working" version of your code would be:
class Items:
''' Constructor to initilize an item object
An item has name, quantity, price, member price, and taxing status'''
def __init__(self, name=None, quantity=0, price=0, memPrice=0, taxStatus=None): # fill the default values or you will have an error in inventory function
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
def inventoryRead(self):
txt = ""
count = 0
f = open("inventory.txt", "r")
inList = []
item1 = Items() # <-- works like this only if you have defaults in your __init__ definition
print(item1)
for line in f.readlines():
item1.name = line[0:line.find(":")]
print(item1)
print(item1.name)
inList[count] = Items()
txt = line.next()
print(txt)
items = Items()
items.inventoryRead()
This would work now but it surelly isn't what you want...
Design choice
You have an Item --> make it a class
You have an inventory? --> make it a class!
Manipulate your code from within Inventory
You should really read some examples and tutorials on python OOP, since it would seem you don't really feel comfortable with how it works.
Now for a quick working example:
#!/usr/bin/env python3
class Item:
def __init__(self,name, quantity=0, price=0, memPrice=0, taxStatus=0):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
class Inventory:
def __init__(self):
self.items = []
def inventoryRead(self):
# your function to collect items from file
if __name__ == '__main__':
inventory = Inventory()
inventory.inventoryRead()

How to pass the value of a variable of a class to another class?

I have an infinite loop that updates the currentPrice variable in the streamingPrice class, I need to use the value of this variable Trading class, the refresh function in Trading class is going to keep retrieving the value of the currentPrice every time it updates, then I'm going to perform a task on it. The stream and refresh functions have their own threads. How can I achieve that?
Currently I only get the initialized value of that variable
class streamingPrice():
def __init__(self):
self.currentPrice =0
def stream(self):
#Streaming live prices
api = API(access_token=userVals.key)
params = { "instruments": userVals.pair }
r = pricing.PricingStream(accountID=userVals.accountID, params=params)
rv = api.request(r)
for ticks in rv:
if('asks' in ticks):
self.setPrice(ticks['asks'][0]['price'])
def setPrice(self,price):
self.currentPrice = price
def getPrice(self):
return self.currentPrice
class Trading():
def refresh(self):
while(True):
#initialize data channel
self.highList, self.LowList, self.closeList = self.c.getData()
self.tradeCurrentPrice = self.sp.getPrice()
#Initialize Indicators
self.rolling_bands_low = self.s.ROLLING_BANDS_LOW(self.closeList)
self.rolling_bands_high = self.s.ROLLING_BANDS_HIGH(self.closeList)
self.stochostic_oscillator_k =
self.s.STOCHASTIC_OSCILLATOR_K(self.highList, self.LowList,
self.closeList)
self.stochostic_oscillator_d =
self.s.STOCHASTIC_OSCILLATOR_D(self.highList, self.LowList,
self.closeList)
self.tradeCurrentPrice = self.sp.getPrice() is wrong because you have not defined self.sp.
Based on your title I assume you want to do something like this:
sp = StreamingPrice()
trade = Trading(sp.currentPrice)
passing in the current price attribtue of the sp object into the new object.
Your Trading class will also need an __init__(self, price) method
there's also no need to create these methods:
def setPrice(self,price):
self.currentPrice = price
def getPrice(self):
return self.currentPrice
because you can achieve the same result doing this:
price = 3
sp = StreamingPrice()
sp.currentPrice = price

Python PNL OOP, how to use attribute from another class

I am planning to design a program to track profit and loss of my stock account, then I used Python and hope to solve it in a Object Oriented way.
Code:
class PNL(object):
stock_amount = {}
def __init__(self,cash,position):
self.cash = cash
self.position = position
def buy(self,Stock,amount):
pass
def sell(self,Stock,amount):
pass
def stock_amt(self,Stock):
if Stock().symbol not in stock_amount:
stock_amount[Stock().symbol] = 0
else:
return stock_amount
class Stock():
def __init__(self,symbol,timestamp,price):
self.symbol = symbol
self.time = timestamp
self.price = price
a = PNL(0,0)
APPL = []
APPL.append(Stock('APPL',0,10))
APPL.append(Stock('APPL',1,12))
a.stock_amt('APPL')
for stock in APPL:
if stock.time == 0:
print stock.price
But this doesn't work fine, anyone has idea on that?
Firstly you need to fix the class PNL, when you declare the methods with Stock, as its an argument/parameter, you'd better choose another name, or write it in lowercase to make difference with the class Stock.
Just think you will give an instance to these methods, no need to write the type, and by the way, no need to instantiate again the class inside the method by doing Stock().symbol, you'll give an instance, or directly the attribute symbol if you prefer.
Also, the stock_amount can be stored as a instance attribute, as below :
class PNL(object):
def __init__(self,cash,position):
self.cash = cash
self.position = position
self.stock_amount = {}
def buy(self,stock,amount):
pass
def sell(self,stock,amount):
pass
def stock_amt(self,stock):
if stock.symbol not in self.stock_amount:
self.stock_amount[stock.symbol] = 0
else:
return self.stock_amount
Then when you call your classes, i think you wanted to loop on the list APPL you've built (then just call a.stock_amt(stock_object_created) :
a = PNL(0,0)
APPL = []
APPL.append(Stock('APPL1',0,10))
APPL.append(Stock('APPL2',1,12))
for stock in APPL:
a.stock_amt(stock)
if stock.time == 0:
print stock.price
print a.stock_amount
#>>>10
#>>>{'APPL2': 0, 'APPL1': 0}

Python classes - help calling a method inside another class to update an attribute in an instance

Sorry if I'm vague in my question, first time posting on stackoverflow. I think I'm overlooking something really basic here, gone over several tutorials on classes but cannot for the life of me figure out where I'm going wrong. My code is the following:-
class catalogue(object):
def __init__(self, catalogueitem):
self.catalogueitem = catalogueitem
self.colors = []
self.stock = "No Stock"
def setStock(self, stock):
if self.stock == "No Stock":
self.stock = stock
class shop(object):
def __init__(self, items):
self.shopItems = []
for item in items:
self.shopItems.append(catalogue(item))
def setStock(self, stock, item="purse"):
self.shopItems.catalogue(item).setStock(stock)
newshop = shop( ["purse","handbag","wallet", "clutchbag"] )
newshop.setStock(10, "handbag")
Basically what I'm trying to do is call the method inside the class catalogue, from within the class shop, and update the item with a new stock value of 10 within the instance newshop. I think I'm lacking a basic understanding of how to do this, and I think I've overlooked something very basic, can anyone help me figure it out please?
Thanks
Betty
When you call
self.shopItems.catalogue(item).setStock(stock)
You're trying to call the methos catalogue of the object self.shopItems. The thing is, self.shopItems is a list. I think you should try with a code like this:
class catalogue(object):
def __init__(self, catalogueitem):
self.catalogueitem = catalogueitem
self.colors = []
self.stock = "No Stock"
def setStock(self, stock):
if self.stock == "No Stock":
self.stock = stock
class shop(object):
def __init__(self, items):
self.shopItems = []
for item in items:
self.shopItems.append(catalogue(item))
def setStock(self, stock, item="purse"):
c = catalogue(item) #Instance the catalogue class
c.setStock(stock) #Call the method setStock
self.shopitems.append(c) #this adds the items into the instance, but # the original objects created by __init__ are still there, i.e. they've not # updated just added.
newshop = shop( ["purse","handbag","wallet", "clutchbag"] )
newshop.setStock(10, "handbag")
Changed only the function setStock from shop class.
EDIT 1:
When you do self.shopItems = catalogue(item) you're overriding what you have
in the list. You should change that to:
self.shopItems.append(catalogue(item))
And call the method on the last element afterwars:
self.shopItems[-1].setStock(stock)
Result being:
def setStock(self, stock, item="purse"):
self.shopItems.append(catalogue(item))
self.shopItems[-1].setStock(stock)
EDIT 2:
Ok, to update the existent items you should first check if they exist, iterating through the list:
def setStock(self, stock, item="purse"):
c = catalogue(item) #Instance the catalogue class
c.setStock(stock) #Call the method setStock
index = -1
i = 0 #index
for shItem in self.shopItems:
if shItem.catalogueitem == item:
index = i #Saves the index to update
break #Breaks out of loop
i += 1
if index == -1:
self.shopitems.append(c) #index wasn't updated, the item is new
else:
self.shopitems[index] = (c) #replaces the item info
Firstly, you want to be able to look up shop items by name. An appropriate data structure to use for this is a dictionary (rather than a list). So, this changes the constructor for shop to:
def __init__(self, items):
self.shopItems = {}
for item in items:
self.shopItems[item] = catalogue(item)
Then, it is easy to update a shop item:
self.shopItems[item].setStock(stock)
Each shopItem is already a catalogue instance, so you can call setStock() on it directly. You should really check that there is such an item first, otherwise you will throw an exception. For example, if you call newshop.setStock(10, 'bag') -- there is no such item. You could protect against that as follows:
def setStock(self, stock, item="purse"):
if item not in self.shopItems:
self.shopItems[item] = catalogue(item)
self.shopItems[item].setStock(stock)

Categories

Resources