Search code examples
pythonpython-3.xtext-filesreadlines

How to find and replace a line in a text file?


This is my database named myDB.txt:

28273139
iPhone
5.50
30
5
35
81413852
Book
1.50
43
10
55

The text file database follows the format

Product Code
Product Name
Price
Current Stock
Reorder Stock (the lowest the stock can go)
Target Stock

Now, the I want to update the iPhone data. This is the iPhone data.

28273139
iPhone
5.50
30
5
35

It uses the 8-digit product code to identify the product.

I have written the following code.

userCode = "28273139"
newstock = "29"

database = open('myDB.txt','r+')
while(str(userCode) not in next(database)):
    pass
else:
    for i in range(3):
        line = next(database)
        replace = line.replace(line,newstock)
        database.write(replace)

I want to change the 4th value of the list, the number 30 to the number 29, which I declared as the variable newstock. The program moves 3 lines down, since the format is the same for every product in the database and replaces the line with this new value.

The result I need from updating the iPhone data -

28273139
iPhone
5.50
29
5
35

However, this method doesn't work.
I receive an error every time.

AttributeError: 'str' object has no attribute 'readlines'

Can someone help fix my problem? Is the code I have written correct to produce the required result?


Solution

  • This is a lot easier when you configure your text file to be key:value pairs (like the dict construct in python, or values in another DB like SQL). Then you can simply set a sentinel value when the value is met, then unset when you've replaced the correct line.

    So, if changing the format of text to:

    ProductCode <value>
    ProductName <value>
    Price <value>
    CurrentStock <value>
    ReorderStock <value>
    Targetstock <value>
    

    Then you can do something like this:

    ProductCode = "28273139"
    NewStock = "29"
    SentinelValue = 0
    
    with open('myDB.txt', 'r+') as database:
      for line in database:
      (key, val) = line.split()
      if key == "ProductCode":
        if val == ProductCode:
          SentinelValue = 1
      if key != "ProductCode":
        if key == "CurrentStock":
          if SentinelValue == 1:
            line = line.replace(val, NewStock)
        print line
    

    It is a bit dirty and could surely be cleaned up, but it is much more verbose. Also, note that the space is important as it is used as the delimiter when splitting the lines.

    You may also notice I didn't write to the file: At least for me in python 2.7, there seems to be an issue where I can't replace a line of text, only append with f.write(). This code works and replaces to stdout, the workaround for writing to a file is to simply write all lines to a new file:

    ProductCode = "28273139"
    NewStock = "29"
    SentinelValue = 0
    fout = open('newDB.txt', 'w')
    
    with open('myDB.txt', 'r+') as database:
      for line in database:
      (key, val) = line.split()
      if key == "ProductCode":
        if val == ProductCode:
          SentinelValue = 1
      if key != "ProductCode":
        if key == "CurrentStock":
          if SentinelValue == 1:
            line = line.replace(val, NewStock)
        fout.write(line)
        print line
    

    You could then write logic to replace the files as needed. However, I would very much suggest looking at how to write and read from an actual SQL database. I hope this helps! ^^