1

In txt file, the data is written like this:

  • A1|Auditorium1|Prote G
  • A2|Auditorium1|Prote G

A1 stands for label of auditorium, Auditorium1 stands for description, Prote G stands for address. Now, I want to make function for replacing label of auditorium with new one. I wanted to use the inputs:

def label_change():
    label_old = input("Enter label u wanna change: ")
    label_new = input("Enter new one: ")
    with open("aud.txt","r") as f1:
        for i in f1.readlines():
            r = i.split("|")
            label = r[0]
            desc = r[1]
            adr = r[2]
            if label_old == label:
                label_new = label
                #now not sure how to continue

For example, If I input A1 as an old label and A5 as a new label, can I somehow replace A1 with A5 without deleting or changing description and address in my file? After this I tried opening file in 'w' mode, so i can write, but it deletes every line and 'a' mode adds whole line instead of changing wanted label. Is there any easier method?

3
  • label,desc,adr = i.split("|") - will throw error if your lines are malformed - same as your solution Commented Jun 5, 2018 at 5:23
  • do you want to write to a new file (keep the old one) or overwrite? Commented Jun 5, 2018 at 5:24
  • 1
    @Jonas I want to write in the same file, for example, just to replace A1 with A5 and to keep other parts of file untouched. Commented Jun 5, 2018 at 5:28

2 Answers 2

4

You just need to write back out to a file, you can open it in the same line as f1 and then use f2.write() to write a new line to it:

def label_change():
    label_old = input("Enter label u wanna change: ")
    label_new = input("Enter new one: ")
    with open("aud.txt","r") as f1, open("aud2.txt", "w") as f2:
        for i in f1.readlines():
            r = i.split("|")
            label = r[0]
            desc = r[1]
            adr = r[2]
            if label_old == label:
                label = label_new
            f2.write(label + "|" + desc + "|" + adr)

In order to write to the same file, you can save the contents to a list and the write:

def label_change():
    label_old = input("Enter label u wanna change: ")
    label_new = input("Enter new one: ")
    contents = []
    with open("aud.txt","r") as f1:
        for i in f1.readlines():
            r = i.split("|")
            label = r[0]
            desc = r[1]
            adr = r[2]
            if label_old == label:
                label = label_new
            contents.append(label + "|" + desc + "|" + adr)
    with open("aud.txt", "w") as f1:
        for line in contents:
            f1.write(line)
Sign up to request clarification or add additional context in comments.

5 Comments

You would have split that to 3-4 separate functions if you wrote real code, right?
Why would you? @EvgenyPogrebnyak
Some separation of responsibilities? The OP question is agnostic to input style, this can be factored out at least. Eg label_change(filename: str, old_label: str, new_label: str). I think putting this all together teaches bad coding style.
Yeah, you could definitely parameterize this function, but that is unnecessary if it's only ever called with these parameters. Nonetheless, I agree with your comment and would probably also do it that way if it were my project, but without any information about the rest of the code, it seems best to give an answer as similar as possible to the question. @EvgenyPogrebnyak
thanks for commenting. My feeling towards input()is generally very negative - it very commmon in assignments people try to solve, including asking on StackOverflow, but usually thier problem is outside the input(), so there is a better min working example of the stated problem possible. From my perspective, any answer that avoids input() is to the better.
1

You cannot easily modify a file in place, it is easier to write it new. If you only want to change one thing a time, this would work:

def label_change():
    label_old = input("Enter label u wanna change: ")
    label_new = input("Enter new one: ")
    with open("aud.txt","r") as f1, open("mod_aud.txt","w") as outFile:
        for i in f1.readlines():
            label,desc,adr = i.split("|") # decompose directly
            if label == label_old:
                label = label_new
        outFile.write('|'.join( [label,desc,adr] )

If you want to change multiple labels it is better to read all lines in, modify until you are happy and write all lines back out again.

You would have to hold your data in a list of lines - and could simply replace each line start with A1 with the same line but starting with A2

You can do the renaming / deletion in python as well:

import os
os.remove(someFileName) # delete a file (your old one)
os.rename(old_name, new_name)

As an afterthought:

You could easily omit the splitting part by using

for i in fi.readlines():
    if i.startswith(label_old):
        outFile.write(label_new + i[len(label_old):]) # string slicing
    else:
        outFile.write(i)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.