简体   繁体   中英

Python write to txt file at specific line

I am creating a python stock system in ,which I need to allow a user to enter a product code and enter their quantity and the software checks a txt file. It checks whether the product is found and whether their is enough of them. I am stuck trying to make my code subtract the quantity needed from the total quantity in the text file. I only want to change the quantity of that one product. Any help will be appreciated. Thanks Ben

Edit:

I have to use txt as it is part of the design brief.

x = 10
y = 0
n = 1
data = [line.strip().split() for line in open("Untitled.txt")]
code = input("Please enter Product Code?")
quantity = input("How many of these do you need?")


for num in range(0,10):
    if data[x][0] == code:
        n = 0
        y = x
    x = x - 1

if n == 0:
    if data[y][3] >= quantity:
        print("Product in stock")

        old = int(data [y][3])
        quantity = int(quantity)
        new = old - quantity
        new = str(new)
        data[y][3] = new
    else:
        print("Product out of stock")
else:
    print("Product not found")

This is my txt file

Code        Description Price   Quantity
12345670    testitem    1.45    34
12345671    testitem    1.45    34  
12345672    testitem    1.45    34
12345673    testitem    1.45    34
12345674    testitem    1.45    34
12345675    testitem    1.45    34
12345676    testitem    1.45    34
12345677    testitem    1.45    34
12345678    testitem    1.45    34
12345679    testitem    1.45    34
12345680    testitem    1.45    34

tablib is an excellent tool for manipulating such data with you example (I changed the .txt by a csv file, tabulated separated)

test.csv

Code    Description Price   Quantity
12345670    testitem    1.45    34
12345671    testitem    1.45    34
12345672    testitem    1.45    34
12345673    testitem    1.45    34
12345674    testitem    1.45    34
12345675    testitem    1.45    34
12345676    testitem    1.45    34
12345677    testitem    1.45    34
12345678    testitem    1.45    34
12345679    testitem    1.45    34
12345680    testitem    1.45    34

stock.py

# coding=utf-8
#! /usr/bin/env python
from tablib import Dataset

# load data from the tsv
with open("./test.csv") as fin:
    imported_data = Dataset().load(fin.read())

code = input("Please enter Product Code?")
quantity = int(input("How many of these do you need?"))

# code is uniq find the first index
i = imported_data["Code"].index(code)
new_qt = int(imported_data[i][3]) - quantity
# tuple manipulation, so replace the line, item affection not possible
if new_qt >= 0:
    imported_data[i] = imported_data[i][:-1] + (str(new_qt),)
else:
    imported_data[i] = imported_data[i][:-1] + ("0",)

export = imported_data.tsv
# newline="" avoid add new lines 
with open("./test.csv", "w", newline="") as fout:
    fout.write(export)

All you need to do is do is this in reverse:

data = [line.strip().split() for line in open("Untitled.txt")]

so each line in data joined by "\\n" and each element in line joined by... a tab? (.split() without arguments could split by a few different characters)

new_text = "\n".join("\t".join(line) for line in data)

I see you are opening the file once for reading into data and one for r+ but it only needs to be opened for the line of code that it gets written to:

with open("Untitled.txt","w") as f:
    f.write(new_text)

Edit: just noticed you have a typo / mistake:

if data[y][3] ...:
    ...
    old = ...data [y][3]..
    ...
    data[1][3] = new

it is quite possible you just need to change the last 1 to y

If you are using Python2, you are compairing data[x][0] which type is str with potentially any kind of type for the input. Your code works well if the user types '12345670' (or any other product code between '' ). In Python3, it is ok.

Some other points:

  • You are opening the file twice. Just do it once and use the variable in your code after the opening.

  • Your for block is quite complicated imo. I would do this like for x in range(1, len(data)) but if you are fine like this, it is working.

  • Last one. You are not writing into file after that. You must write your data to the file to update it.

  • True last one. Maybe you should use some database if you want to store, access, and update your data.

Edit

For the write part, here is your code edited (credits to Tadhg McDonald-Jensen)

x = 10
y = 0
n = 1
edit = open("data.txt","r+")
data = [line.strip().split() for line in open("data.txt")]
code = input("Please enter Product Code?")
quantity = input("How many of these do you need?")

for num in range(0,10):
    if data[x][0] == code:
        n = 0
        y = x
    x = x - 1

if n == 0:
    if data[y][3] >= quantity:
        print("Product in stock")

        old = int(data [y][3])
        quantity = int(quantity)
        new = old - quantity
        new = str(new)
        data[y][3] = new
        with open("data.txt", "w") as f:
            new_text = "\n".join("\t".join(line) for line in data)
            f.write(new_text)
    else:
        print("Product out of stock")
else:
    print("Product not found")

Short answer: DON'T .

Medium answer: You should never change anything in the middle of a text file.

Long answer: The only foolproof way to change a text file is to write a new copy of the file with the change and rename it at the end when everything has been correctly writen to disk. That's what text editors do.

In your case, as the text file seems properly formatted with all lines being same length, you could try to process it as if it was a binary direct access file. But it only works if all fields keep same length all the time. Here are some reasons that could make it wrong:

  • you are using unicode characters encoded in utf8 - e and é seem equally long, but in utf8 e is one single byte (code 0x65) while é needs two bytes (0xC3 0xA9)
  • someone could edit the file with a text editor and inadvertently removes some characters from a field for example writing 1.5 instead of 1.50 => line is now shorter
  • someone could edit the file with a text editor and adds inadvertently some white spaces at an end of line => line is now longer ... and you cannot see it when looking at it in a text editor!

TL/DR: if you are required to use a text file for persisting your data, you must:

  • read everything at program start
  • keep everything in memory
  • flush everything to the disk file at program end and provide a way for your users to save their work (a command Save )

Alternatively, you could use a direct access private binary file or a database (sqlite is nicely integrated in Python) and just provide a text import/export functionnality.

Working code :

x = 10
y = 0
n = 1
data = [line.strip().split() for line in open("Untitled.txt")]
code = input("Please enter Product Code?")
quantity = input("How many of these do you need?")

for num in range(0,10):
    if data[x][0] == code:
        n = 0
        y = x
        print("Data ",data[x][0])
    x = x - 1

if n == 0:
    if data[y][3] >= quantity:
        print("Product in stock")

        old = int(data [y][3])
        quantity = int(quantity)
        new = old - quantity
        data[y][3] = str(new)
        print(data)
        file = open("Untitled.txt", "w")
        for item in data:
            print>>file, (', '.join(item))
        file.close();
    else:
        print("Product out of stock")
else:
    print("Product not found")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM