我是Python的新手,试图了解OOP。在我的程序中,我希望用户能够买卖股票,但是我正在努力实现此功能。对不起,如果问题不大。
用户类及其一个对象
class User:
def __init__(self, name, budget=None, stocks=None):
self.name = name
self.budget = budget or 1000
self.stocks = stocks or 0
def sell_stock(self):
if self.stocks != 0:
self.stocks -= 1
def buy_stock(self):
self.stocks += 1
u1 = User("Karin", stocks=9)
股票类别及其一个对象
class Stock:
def __init__(self, price, name, availability=None):
self.price = price
self.name = name
self.availability = availability or 1
s1 = Stock("200", "Netflix")
我想编写一个名为buy_stock()的方法,该方法将执行以下操作:
答案 0 :(得分:2)
class Stock:
def __init__(self, price, name, availability=1):
self.price = price
self.name = name
self.availability = availability
class User:
def __init__(self, name, budget=1000,):
self.name = name
self.budget = budget
self.stocks = []
def sell_stock(self, stock):
try:
self.stocks.remove(stock)
stock.availability += 1
self.budget += stock.price
print('{} has sold {} stock for {} dollars'.format(self.name, stock.name, stock.price))
except:
pass
def buy_stock(self, stock):
if self.budget - stock.price >= 0 and stock.availability >= 1:
self.stocks.append(stock)
stock.availability -= 1
self.budget -= stock.price
print('{} has bought {} stock for {} dollars'.format(self.name, stock.name, stock.price))
s1 = Stock(200, "Netflix")
s2 = Stock(300, "SomeStock", availability=2)
u1 = User("Karin", budget=10000)
u1.buy_stock(s2)
u1.sell_stock(s2)
u2 = User("Sam")
u2.buy_stock(s2)
u2.buy_stock(s1)
输出:
Karin has bought SomeStock stock for 300 dollars
Karin has sold SomeStock stock for 300 dollars
Sam has bought SomeStock stock for 300 dollars
Sam has bought Netflix stock for 200 dollars
购买物品时,必须确保该物品可用且有预算。我从构造函数中删除了股票参数以避免重复,并且只为逻辑buy_stock
提供一个来源。最后一点:您不需要or
键控,因为您可以在构造函数中设置默认值。
答案 1 :(得分:1)
要想在更现实的情况下考虑它,您将拥有一个Marketplace
对象,该对象包含其他用户可以从中购买股票的所有股票。
这样,将来的开发将相当容易可读和可扩展。
Marketplace
可以是一个单独的类,可以容纳其他库存对象的字典(如下面的示例所示),也可以是与数据库连接的类(如mongodb)。
选择哪一个取决于项目。
在此示例中,词典是使您前进的绝佳解决方案:
class User:
def __init__(self, name, budget=None, stocks=None):
self.name = name
self.budget = budget or 1000
self.stocks = stocks or 0
def __repr__(self):
# returns a represantion of the object
# so it's more informative of the state
# of this object
return "{} balance: {}".format(
self.name,
self.budget
)
def sells(self, stock_name, amount):
# Increase my budget by the amount of stocks I'm selling
# multiplied by its price.
self.budget += marketplace[stock_name].price * amount
# Send the stocks back into the market and remove them
# from my ownership
marketplace[stock_name].availability += amount
self.stocks -= amount
def buys(self, stock, amount):
# Lower my budget by the stock price
# multiplied by the amount of stock I'm buying
marketplace[stock].availability -= amount
self.budget -= marketplace[stock].price * amount
# Print out the transaction
print("{} has bought {} stock for {} dollars".format(
self.name,
stock,
marketplace[stock].price * amount
))
class Stock:
def __init__(self, price, name, availability=None):
self.price = price
self.name = name
self.availability = availability or 1
# In production like environmnet, you would not do this but would keep in
# mongodb or some other sql/nosql database
# For this example, a kind of javascript dict logic would be alright to use
marketplace = {
"Netflix": Stock(200, "Netflix", 100)
}
u1 = User("Karin", budget=1000, stocks=0)
u1.buys("Netflix", 10)
u1.sells("Netflix", 5)
答案 2 :(得分:1)
欢迎来到OOP的世界:)
您要尝试做的非常简单。由于您要尝试同时使用两个类,因此这表示应将其中一个类用作函数中的参数。即
class Stock:
# .... basic init function
# we need a function to return the value
# of this stock, and maybe take an argument
# for how many shares we want to value
# so let’s write a function to do that for us
def get_value(self, number_of_shares=1):
return (self.value * number_of_shares)
class User:
#.... basic init function
def buy_stock(self, stock, amount=1):
total_value = stock.get_value(amount)
self.budget = self.budget - total_value
self.stocks = self.stocks + amount
#display what happened
print(“{} bought {} shares of {} for {}”.format(self.name, amount, stock.name, total_value))
然后您可以在实践中写
输入:
# assuming Andrew is a user
# and my_stock is a stock worth $20 a share
Andrew.buy_stock(my_stock, 10)
输出:
Andrew bought 10 shares of my_stock for $200
但基本上,问题的答案是传递一个您希望成为您要使用的类的参数。因此,您既可以操纵调用该方法的User对象,也可以操纵传递到该方法中的库存对象。
答案 3 :(得分:1)
我认为应该这样做。另外,将股票价格的数据类型从字符串更改为整数(或之后进行类型转换)
class User:
def __init__(self, name, budget=None, stocks=None):
self.name = name
self.budget = budget or 1000
self.stocks = stocks or 0
def sell_stock(self):
if self.stocks != 0:
self.stocks -= 1
def buy_stock(self, stock):
self.budget - stock.price
stock.availability -= 1
self.stocks += 1
print("{} has bought {} stock for {} dollars".format(self.name,stock.name,stock.price))
class Stock:
def __init__(self, price, name, availability=None):
self.price = price
self.name = name
self.availability = availability or 1
s1 = Stock(200, "Netflix")
u1 = User("Karin", stocks=9)
u1.buy_stock(s1)
答案 4 :(得分:1)
您需要两种类型的对象:backup-inhibited
和Portfolio
。
Stock
可以有多个User
,并且在示例中仅由其名称表示。
对于更复杂的模型,您也将Portfolio
建模为对象;您还需要处理库存价格,佣金和其他成本的变化。
这是一个简化的示例,演示了对象之间的交互方式:
Transactions
class Stock:
def __init__(self, ticker, price):
assert price > 0
self.ticker = ticker
self.price = price
def __hash__(self):
return hash(self.ticker)
def __str__(self):
return self.ticker + ', $' + str(self.price) + ':'
class Portfolio:
def __init__(self, owner):
self.owner = owner
self.cash = 0
self.stocks = {} # a mapping of Stock --> quantity
def buy(self, stock, quantity):
if self.cash < stock.price * quantity:
print('Not enough cash to purchase ', quantity, stock)
else:
self.cash -= stock.price * quantity
try:
self.stocks[stock] += quantity
except KeyError:
self.stocks[stock] = quantity
def sell(self, stock, quantity):
assert quantity > 0
try:
if self.stocks[stock] < quantity:
print('Not enough', stock.ticker, 'inventory to sell', str(quantity), stock)
return
self.stocks[stock] -= quantity * stock.price
self.cash += quantity * stock.price
except KeyError:
print('No', stock.ticker, 'inventory to sell')
def __str__(self):
res = [self.owner, "'s Portfolio:\n"]
for stock, quantity in self.stocks.items():
res += [str(stock), ' ', str(quantity), ' -> ', '$', str(quantity*stock.price), '\n']
res += ['cash: ', '$', str(self.cash), '\n']
return ''.join(res)
goog = Stock('GOOG', 325)
alibaba = Stock('ALI', 12)
apple = Stock('AAPL', 42)
pfl = Portfolio('Karin')
pfl.cash = 10000
pfl.buy(goog, 10)
pfl.buy(alibaba, 100)
pfl.sell(apple, 100)
pfl.buy(apple, 10000)
pfl.sell(goog, 10000)
print()
print(pfl)
答案 5 :(得分:1)
可能是这样的事情(我并没有真正弄混“ User”类中的“ stocks”实例变量。我可能会抛弃它,而是维护一个Stock对象列表(您的库存数量就是该列表的长度)):
class User:
def __init__(self, name, budget=1000, stocks=0):
self.name = name
self.budget = budget
self.stocks = stocks
def sell_stock(self):
if self.stocks:
self.stocks -= 1
def buy_stock(self, stock, quantity=1):
try:
price = stock.request(quantity)
except RuntimeError as error:
raise error
else:
self.budget -= price
self.stocks += quantity
print(f"{self.name} bought ${price} worth of {stock.name} stocks")
class Stock:
def __init__(self, name, price, quantity_available=1):
self.name = name
self.price = price
self.quantity_available = quantity_available
def isAvailable(self):
return self.quantity_available > 0
def request(self, quantity_requested):
if not self.isAvailable():
raise RuntimeError(f"No more {self.name} stocks available")
elif self.quantity_available < quantity_requested:
raise RuntimeError(f"Requested too many {self.name} stocks")
else:
self.quantity_available -= quantity_requested
return self.price * quantity_requested
def main():
user = User("Karin")
stock = Stock("Netflix", 200, quantity_available=6)
user.buy_stock(stock, quantity=3)
user.buy_stock(stock, quantity=2)
user.buy_stock(stock, quantity=1)
user.buy_stock(stock, quantity=1)
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
输出:
Karin bought $600 worth of Netflix stocks
Karin bought $400 worth of Netflix stocks
Karin bought $200 worth of Netflix stocks
RuntimeError: No more Netflix stocks available