2016-01-21 36 views
0

我在这个格式的股票文件:如何附加一个文件,并采取了具体的行蟒蛇3

12345678,Fridge,1,50 
23456789,Car,2,50 
34567890,TV,20,50 

这是代码:

def main(): 
products = {} 
#This is the file directory being made. 
f = open('stockfile.txt') 
#This is my file being opened. 

for line in f: 


    # Need to strip to eliminate end of line character 
    line = line[:-1] 
    #This gets rid of the character which shows and end of line '\n' 
    row = line.split(',') 
    #The row is split by the comma 
    products[row[0]] = [row[1], row[2],row[3]] 
    #The products are equal to row 1 and row 2 and row 3. The GTIN is going to take the values of the product and price so GTIN 12345678 is going to correspond to Fridge and 1. 

print(products) 
total = 0 

print('Id  Description   Total') 
while True: 
    GTIN = input('Please input GTIN ') 
    if(GTIN not in products): 
     print('Sorry your code was invalid, try again:') 
     break 

    row = products[GTIN] 
    print(GTIN) 
    description = row[0] 
    value = row[1] 
    stock = row[2] 
    print(stock) 

    quantity = input('Please also input your quantity required: ') 
    row[2]= int(stock) - int(quantity) 
    products[row[2]] = row[2] 
    product_total= (int(quantity)*int(value)) 
    New_Stock = GTIN + ',' + description + ',' + value + ',' + str(products[row[2]]) 
    f = open('stockfile.txt','r') 
    lines = f.readlines() 
    f.close() 
    f = open("stockfile.txt","a") 
    for row in lines: 
     if((row + '\n') != (New_Stock + '\n')): 
      f.write(New_Stock) 
      f.close() 

    print('%20s%20s%20s' % (GTIN, description, product_total)) 

    total = total + product_total 

print('Total of the order is £%s' % total) 
print(products) 
main() 

但是,代码不更新股票。它应该做的是摆脱给定产品的先前库存,然后根据用户刚购买的数量进行更新。

我还没有到它,但一旦股票打零,我需要我的代码,然后告诉用户,我们已经缺货,需要一些新的股票。然后需要给用户留言以等待,直到我们进货,然后再显示补货的价格。

如果你有时间请你也可以做这个新的代码,但如果不是,你可以解释如何更新股票以及为什么我的代码不工作,谢谢。

回答

0

当你seek给定线路和呼叫write,以完全覆盖该行,而不会影响其他线路或在不经意间创造新的生产线,在你的股票每一行必须有一个固定的宽度。你如何确保固定宽度?通过给记录中的每个字段固定宽度。基本上,你选择每个字段可以有的最大字符数;在这里我要对所有字段假设8(虽然他们不能个个都相同),所以你的股票会以这种方式存储:

12344848, Fridge,  2,  50 
13738389,  TV,  5,  70 

如果继续下去这种方式,每一行都会有一个最大宽度这将使您能够找到该行的开头并完全覆盖它。尝试这种代码:

MAX_FIELD_LEN = 8 

def main(): 
    products = {} 
    product_location = {} 
    location = 0 
    # This is the file directory being made. 
    with open('stockfile.txt', 'r+') as f: 
     # This is my file being opened. 

     for line in f: 
      # keep track of each products location in file to overwrite with New_Stock 
      product_location[line.split(',')[0]] = location 
      location += len(line) 
      # Need to strip to eliminate end of line character 
      line = line[:-1] 
      # This gets rid of the character which shows and end of line '\n' 
      row = line.split(',') 
      # The row is split by the comma 
      products[row[0]] = [row[1], row[2], row[3]] 
      # The products are equal to row 1 and row 2 and row 3. The GTIN is going to take the values of the product and price so GTIN 12345678 is going to correspond to Fridge and 1. 

     print(products) 
     total = 0 

     while True: 
      GTIN = input('Please input GTIN: ') 
      # To terminate user input, they just need to press ENTER 
      if GTIN == "": 
       break 
      if (GTIN not in products): 
       print('Sorry your code was invalid, try again:') 
       break 

      row = products[GTIN] 
      description, value, stock = row 
      print('Stock data: ') 
      print('GTIN \t\tDesc. \t\tStock \t\tValue') 
      print(GTIN,'\t',description,'\t', stock, '\t', value) 

      quantity = input('Please also input your quantity required: ') 
      row[2] = str(int(stock) - int(quantity)) 
      product_total = int(quantity) * int(value) 
      for i in range(len(row)): 
       row[i] = row[i].rjust(MAX_FIELD_LEN) 
      New_Stock = GTIN.rjust(MAX_FIELD_LEN) + ',' + ','.join(row) + '\n' 
      #print(New_Stock, len(New_Stock)) 
      f.seek(product_location[GTIN]) 
      f.write(New_Stock) 
      print('You bought: {0} {1} \nCost: {2}'.format(GTIN, description, product_total)) 

      total = total + product_total 
     f.close() 
     print('Total of the order is £%s' % total) 

main() 

确保在TXT文件中的每个字段是宽恰好8个字符使用该程序时(不包括逗号)。如果要增加字段宽度,请相应地更改MAX_FIELD_LEN变量。您的TXT文件应该是这样的:

TXT FILE

+0

即使在添加之后,我仍然遇到同样的问题。 – HC123

+0

@ HC123你可以发布你的代码吗?以及你的文本文件,当你得到这个错误? – TisteAndii

+0

对不起,我似乎无法出于某种原因......请尝试将您的代码并入我的代码并将其与文件一起发布。我似乎无法出于某种原因发布信息。 @TisteAndii – HC123

0

在第几行要装载整个数据文件存储:

for line in f: 
    products[row[0]] = [row[1], row[2],row[3]] 

所以后来只是更新内存中的数据,并让用户输入一个特殊的命令:“保存”写全列表到您的文件。

你也可以捕获你的应用程序进程KILL信号,所以如果用户点击ctrl + c,你可以问问他是否想在退出前保存。

也许每隔几秒将列表的临时副本保存到文件中。

+0

你会怎么做@Loïc,你可能会显示一个代码? – HC123

0

如果您的客户打算多次运行此程序,我建议您使用shelve模块。将整个文件读入内存并重新写入,随着文本的增长,文本将变得效率低下。 Shelve在PC上创建永久文件(准确的说是3个文件)以存储您的数据。最重要的是,shelve会为您提供相同的dict界面,因此您只需在文件上拨打shelve.open()即可开始使用GTIN作为关键字访问/更新您的库存。它非常简单,只需看一下python手册。如果你真的想要一个文本文件,你可以有你的程序,遍历包含你的股票的文件(与字典相同)并将密钥(GTIN)和它们的值(你的股票数量)写入你打开的文本文件。通过这种方式,您可以轻松直观地访问记录,并且还可以在TXT文件中使用可读的格式。

0

以上使用搁置的建议听起来像是一个好主意,但如果您想保留文件原样但仅更新使用(大部分)代码更改记录(而不是每次重写整个文件) ,这似乎工作。

def main(): 
    products = {} 
    product_location = {} 
    location = 0 
    # This is the file directory being made. 
    with open('stockfile.txt', 'r+') as f: 
     # This is my file being opened. 

     for line in f: 
      # keep track of each products location in file to overwrite with New_Stock 
      product_location[line.split(',')[0]] = location 
      location += len(line) 
      # Need to strip to eliminate end of line character 
      line = line[:-1] 
      # The row is split by the comma 
      row = line.split(',') 
      products[row[0]] = [row[1], row[2], row[3]] 
      """ 
      The products are equal to row 1 and row 2 and row 3. The GTIN is going to take the values of the product and 
      price so GTIN 12345678 is going to correspond to Fridge and 1. 
      """ 

     print(sorted(products.items())) 
     total = 0 

     while True: 
      GTIN = input('\nPlease input GTIN or press [Enter] to quit:\n') 
      # To terminate user input, they just need to press ENTER 
      if GTIN == "": 
       break 
      if (GTIN not in products): 
       # Let the user continue with order after mistake in GTIN input 
       print('Sorry your code was invalid, try again:') 
       continue 

      row = products[GTIN] 
      print('GTIN:', GTIN) 
      description = row[0] 
      value = row[1] 
      stock = row[2] 
      stock_length = len(row[2]) 
      backorder = 0 
      print('In Stock:', stock) 

      quantity = input('Please also input your quantity required:\n') 
      if int(quantity) > int(stock): 
       row[2] = 0 
       backorder = int(quantity) - int(stock) 
       # TO DO 
       Backordered_Stock = GTIN + ',' + description + ',' + value + ',' + str(backorder) + '\n' 
      else: 
       row[2] = int(stock) - int(quantity) 
      products[row[2]] = row[2] 
      product_total = (int(quantity) * int(value)) 
      New_Stock = GTIN + ',' + description + ',' + value + ',' + str(products[row[2]]).rjust(stock_length) + '\n' 
      f.seek(product_location[GTIN]) 
      f.write(New_Stock) 
      print('Ordered - {0:>6} GTIN: {1:>10} Desc: {2:<20} at £{3:>6} Total value: £{4:>6} On backorder: {5:>4}'. 
       format(int(quantity), GTIN, description, int(value), product_total, backorder)) 

      total = total + product_total 

     print('Total of the order is £%s' % total) 

main() 
+0

如果NewStock比当前行更长,最终可能会覆盖下一行的一部分,或者如果NewStock太短,可能会在同一行中获得额外的字符。这只适用于每条线具有固定长度的情况。没有任何方法可以有选择地更新文件,除了给记录中的每个字段设置一个固定的宽度,在必要时添加填充。 – TisteAndii

+0

代码工作,但由于某种原因,它停止工作...它现在提出这个: 产品[行[0]] = [行[1],行[2],行[3]] IndexError:list索引超出范围 – HC123

+0

由于某种原因代码停止工作? @TisteAndii – HC123

0
MAX_FIELD_LEN = 8 

def main(): 
    products = {} 
    product_location = {} 
    location = 0 
    # This is the file directory being made. 
    with open('stockfile.txt', 'r+') as f: 
    # This is my file being opened. 

    for line in f: 
     # keep track of each products location in file to overwrite with New_Stock 
     product_location[line.split(',')[0]] = location 
     location += len(line) 
     # Need to strip to eliminate end of line character 
     line = line[:-1] 
     # This gets rid of the character which shows and end of line '\n' 
     row = line.split(',') 
     # The row is split by the comma 
     products[row[0]] = [row[1], row[2], row[3]] 
     # The products are equal to row 1 and row 2 and row 3. The GTIN is going to take the values of the product and price so GTIN 12345678 is going to correspond to Fridge and 1. 

    print(products) 
    total = 0 

    while True: 
     GTIN = input('Please input GTIN: ') 
     # To terminate user input, they just need to press ENTER 
     if GTIN == "": 
      break 
     if (GTIN not in products): 
      print('Sorry your code was invalid, try again:') 
      break 

     row = products[GTIN] 
     description, value, stock = row 
     print('Stock data: ') 
     print('GTIN \t\tDesc. \t\tStock \t\tValue') 
     print(GTIN,'\t',description,'\t', stock, '\t', value) 

     quantity = input('Please also input your quantity required: ') 
     row[2] = str(int(stock) - int(quantity)) 
     product_total = int(quantity) * int(value) 
     for i in range(len(row)): 
      row[i] = row[i].rjust(MAX_FIELD_LEN) 
     New_Stock = GTIN.rjust(MAX_FIELD_LEN) + ',' + ','.join(row) + '\n' 
     #print(New_Stock, len(New_Stock)) 
     f.seek(product_location[GTIN]) 
     f.write(New_Stock) 
     print('You bought: {0} {1} \nCost: {2}'.format(GTIN, description, product_total)) 

     total = total + product_total 
    f.close() 
    print('Total of the order is £%s' % total) 

main() 

这是文本文件: 12345678, Fridge, 1, 50 23456789, Car, 2, 50 34567890, TV, 20, 50

是否有所作为,我在Mac桌面上,或者这样做是蟒蛇3.4.3?

+0

@ TisteAndii这是我运行时的代码,它是您发布的代码。 – HC123

+0

我认为你使用Mac很重要,因为pre-OSX Mac使用不同的行结尾。尝试用'\ r'替换New_Stock中的'\ n'(在'for'循环之后)(您也可以尝试'\ r \ n')。还要把行:'location + = len(line)'改为'location = f.tell()'和'line = line [: - 1]''line = line.rstrip() – TisteAndii