Python Question

How to change specified part of txt file in Python

I have txt file like this:

tw004:Galaxy S5:Samsung:Mobilni telefon:5
tw002:Galaxy S6:Samsung:Mobilni telefon:1
tw001:Huawei P8:Huawei:Mobilni telefon:4
tw003:Huawei P9:Huawei:Mobilni telefon:3

(where tw001 to tw004 is code of some devices and last part of a line is amount 5,1,4,3)

Now I'm trying to add amount to devices with specified code:

def add_devices():
device_file = open ('uredjaji.txt','r').readlines()
code = input("Enter device code: ")
for i in device_file:
device = i.strip("\n").split(":")
if code == device[0]:
device_file = open('uredjaji.txt', 'a')
amount = input("How many devices you are adding: ")
device[4] = int(device[4])
device[4] += int(amount)

My problem is that sum of specified device is just add to the end of txt file.
How to fix that?
(For example if I enter tw004 and add 3 sum 8 is just aded to tw003:Huawei P9:Huawei:Mobilni telefon:38)

Answer Source

First of all, don't open multiple file handles to the same file - that's a disaster waiting to happen.

Second, and more to the point, you need to remove the previous number before you add a new one - the way you're doing it is essentially just appending the data to the end of the file. You'll have to do a bit of seeking and truncating in order to achieve what you want, something like:

def add_devices():
    # no need to keep our files open while users provide their input
    code = input("Enter device code: ")
    amount = int(input("How many devices you are adding: "))
    # you might want to validate the amount before converting to integer, tho
    with open("uredjaji.txt", "r+") as f:
        current_position = 0  # keep track of our current position in the file
        line = f.readline()  # we need to do it manually for .tell() to work
        while line:
            # no need to parse the whole line to check for the code
            if line[:len(code) + 1] == code + ":":  # code found
                remaining_content =  # read the rest of the file first
        # seek back to the current line position
                f.truncate()  # delete the rest of the file, including the current line
                line = line.rstrip()  # clear out the whitespace at the end
                amount_index = line.rfind(":") + 1  # find the amount index position
                current_amount = int(line[amount_index:])  # get our amount
                # slice out the old amount, replace with the new:
                line = line[:amount_index] + str(current_amount + amount) + "\n"
                f.write(line)  # write it back to the file
                f.write(remaining_content)  # write the remaining content
                return  # done!
            current_position = f.tell()  # cache our current position
            line = f.readline()  # get the next line
    print("Invalid device code: {}".format(code))

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download