使用FIFO

时间:2019-04-17 17:30:06

标签: python dictionary inventory-management

我正在尝试解决这个问题,并且我得到了类似这样的字典列表。 (这是“购买方法”中的词典)

[{'qty': 20, 'price': 2000.0, 'product': 'Computer', 'date': '2017-03-05'}, 
{'qty': 22, 'price': 5000.0, 'product': 'Computer', 'date': '2017-11-11'},
{'qty': 6, 'price': 1523.0, 'product': 'Computer', 'date': '2018-02-03'},
{'qty': 10, 'price': 1000.0, 'product': 'Computer', 'date': '2018-12-05'},
{'qty': 20, 'price': 2000.0, 'product': 'Computer', 'date': '2019-11-06'},
{'qty': 10, 'price': 1000.0, 'product': 'Computer', 'date': '2019-08-02'}
]

我正在尝试创建一个名为def sale(quantity, date):的方法,我想传递数量和日期,如果在销售日期之前有足够的库存,则可以出售该数量的产品。

例如如果我通过数量= 30并且日期= 2018-01-01,它应该允许我卖出,因为有可能由于足够的数量而卖出,此后,应根据剩余的数量和价格进行计算并将其添加到在字典清单上方。

例如在我们的情况下

{'qty': 12, 'price': 2000.0, 'product': 'Computer', 'date': '2018-01-01'}

,应该删除前2个字典,因为我们已经出售了它们! (就像库存FIFO一样)

这是我正在尝试执行的代码。但是,我遇到了错误,但没有得到想要的输出。还有其他可能性吗?我该如何运作?

import datetime
from collections import Counter

class Supplier:
    def add_supplier(self, name, address, email, contact_no):
        self.name = name
        self.address = address
        self.email = email
        self.contact_no = contact_no

class Product:
    def add_product(self, name):
    self.name = name

class Company(Supplier, Product):
    data_dict = []
    def purchase(self, product_obj, qty, price, date=datetime.date.today()):
    self.data_dict.append({'product': product_obj.name, 'qty': qty, 'price': price, 'date': str(date)})

    def sale(self, sell_qty, sell_date=datetime.date.today()):
        a = 0
        p = 0
        unit_val = 0
        new_price = 0
        newdict = (sorted(self.data_dict, key=lambda x: x['date']))

        for dt in newdict:
            a += dt['qty']
            p += dt['price']
            if sell_date > dt['date']:
                if sell_qty <= a:
                   unit_val = float(p / a)
                    new_price = unit_val * a
                    a -= sell_qty
                    self.data_dict.append({'product': product_obj.name, 'qty': a, 'price': new_price, 'date': str(sell_date)})
                    print("sold!")

            else:
                print("Sorry, not enough qty.\n")


C = Company()
PRODUCT_OBJ = Product()
PRODUCT_OBJ.add_product('Computer')

while True:

    option = int(input(" 1. You want to add stock of the product!\n2. Want to sell product?\n"))

    if option == 1:
        qty = int(input("Enter the qty of the product.\n"))
        price = float(input("Enter the price of the product.\n"))
        purchase_date = input("Enter purchase date.\n")
        C.purchase(PRODUCT_OBJ, qty, price, purchase_date)

    elif option == 2:
        qty = int(input("Enter the qty you wanna sell, pal!"))
        sale_date = input("Enter sell date.\n")
        C.sale(qty)

得到错误:

Traceback (most recent call last):
  File "G:/python/test.py", line 63, in <module>  C.sale(qty)
  File "G:/python/test.py", line 33, in sale if sell_date > dt['date']:
 TypeError: '>' not supported between instances of 'datetime.date' and 'str'

所需的输出:

[{'qty': 12, 'price': 2000.0, 'product': 'Computer', 'date': '2018-01-01'},
{'qty': 6, 'price': 1523.0, 'product': 'Computer', 'date': '2018-02-03'},
{'qty': 10, 'price': 1000.0, 'product': 'Computer', 'date': '2018-12-05'},
{'qty': 20, 'price': 2000.0, 'product': 'Computer', 'date': '2019-11-06'},
{'qty': 10, 'price': 1000.0, 'product': 'Computer', 'date': '2019-08-02'}
]

2 个答案:

答案 0 :(得分:1)

@adrtam向您展示了如何解决您发布的错误。但是您的代码存在严重问题。我不会解决所有问题,但是这里有一些提示:

  • Supplieradd_supplier应该是__init__。您使用以下内容创建新的供应商:s = Supplier("foo", "bar", "baz@baz", "no")
  • Product类:同上
  • Company
    • 不应继承ProductSupplier(公司是产品还是供应商?不是)
    • 缺少一个__init__方法:data_dict当前是一个类字段,应该是一个实例字段
  • 避免使用诸如ap之类的名称:始终使用重要名称。
  • 在所需的输出中,没有理由在出售后将第一行的日期设置为“ 2018-01-01”
  • 喜欢用动词来命名您的方法(取决于上下文):sell而不是sale

现在,让我们看一下sell方法。我假设这是FIFO库存:您先出售首先购买的产品。 这是一个简单的想法:

  • 遍历行并求和可用数量。
  • 一旦数量足够,就退出循环
  • 然后删除浏览的行并修复最后浏览的行的数量。

示例代码(我假设数据总是按日期排序:要强制执行此操作,可以使用priority queue):

data = [{'qty': 20, 'price': 2000.0, 'product': 'Computer', 'date': '2017-03-05'},
    {'qty': 22, 'price': 5000.0, 'product': 'Computer', 'date': '2017-11-11'},
    {'qty': 6, 'price': 1523.0, 'product': 'Computer', 'date': '2018-02-03'},
    {'qty': 10, 'price': 1000.0, 'product': 'Computer', 'date': '2018-12-05'},
    {'qty': 20, 'price': 2000.0, 'product': 'Computer', 'date': '2019-11-06'},
    {'qty': 10, 'price': 1000.0, 'product': 'Computer', 'date': '2019-08-02'}]

wanted = {'qty': 30, 'date': '2018-01-01'}

def sell(wanted):
    global data # NEVER do this: just for the example
    assert wanted['qty'] > 0
    qty = 0
    for i, row in enumerate(data):
        # too late!
        if row['date'] > wanted['date']:
            raise Exception("Sorry, not enough qty. Operation cancelled")

        qty += row['qty']
        # we have enough Computers!
        if qty >= wanted['qty']:
            break
    else: # loop completes normally
        raise Exception("Sorry, not enough qty. Operation cancelled")

    remaining_qty_in_last_row = qty-wanted['qty']
    # copy of the last row with a new quantity + the remaining rows
    data = [{**row, 'qty':remaining_qty_in_last_row}] + data[i+1:]
    print ("Sold!")

for wanted in [{'qty': 30, 'date': '2018-01-01'}, {'qty': 30, 'date': '2018-01-01'}]:
    try:
         sell(wanted)
    except e:
         print(e)
    print ("data", data)

那只是算法的草图:您必须练习以提取正确的类和方法设计。

答案 1 :(得分:0)

让我们解决您发布的错误:

Traceback (most recent call last):
  File "G:/python/test.py", line 63, in <module>  C.sale(qty)
  File "G:/python/test.py", line 33, in sale if sell_date > dt['date']:
 TypeError: '>' not supported between instances of 'datetime.date' and 'str'

问题是您在日期时间对象中有sell_date,但是字典中的日期是字符串。您需要将它们转换为相同的类型才能进行比较。两种方法可以做到:

  1. 为您的日期时间对象设置一个固定格式的字符串,该字符串可以进行比较:

    if sell_date.strftime("%Y-%m-%d") > dt['date']:
    
  2. 将日期字符串解析为datetime对象:

    import datetime
    if sell_date > datetime.datetime.strptime(dt['date'], '%Y-%m-%d'):