0

I am working on a project where i use a text file to store the data. I have a label for the user to enter the name and i want the user's name to be saved on line 41 of the file, which is the last line. I tried append but that just keeps adding a last line so if the user types another name it wont replace it but add another line. Can you please help me modify the code so it writes the name in line 41 of the text file and if there is already something on the text file, it just replaces line 41 based on the input. Until now i have this code but its not working i dont know why

def addUser(self):
        global name
        global splitname
        name = self.inputBox.text()
        splitname = name.split()
        print("Splitname {}".format(splitname))
        print(len(splitname))
        self.usernameLbl.setText(name)
        self.inputBox.clear()
        # self.congratulations()
        if name != "":
                if len(splitname) == 2:
                        with open('UpdatedCourseInfo.txt', 'r', encoding='utf-8') as f:
                                data1 = f.readlines()
                        data1[40]= [f'\n{splitname[0]}, {splitname[1]}, 0, None, None']
                        with open('UpdatedCourseInfo.txt', 'w', encoding='utf-8') as f:
                                f.writelines()
                        f.close()
                else:
                        with open('UpdatedCourseInfo.txt', 'r', encoding='utf-8') as f:
                                data1 = f.readlines()
                        data1[40]= [f'\n{splitname[0]}, 0, 0, None, None']
                        with open('UpdatedCourseInfo.txt', 'w', encoding='utf-8') as f:
                                f.writelines()
                        f.close()
        print(name)
        return name
eeeeee
  • 1
  • 2
  • You can't modify a line in a file. You must read the file into memory, modify the value, and write the whole thing back to the file. – Michael Ruth Nov 23 '22 at 05:07
  • I think, you forgot to add data to `writelines()` method. So you essentially need to do `f.writelines(data1)` and the line will be replaced. – keidakida Nov 23 '22 at 05:08
  • Does this answer your question? [Editing specific line in text file in Python](https://stackoverflow.com/questions/4719438/editing-specific-line-in-text-file-in-python) – Michael Ruth Nov 23 '22 at 05:08
  • @MichaelRuth, is that now what im doing in the if statement? – eeeeee Nov 23 '22 at 05:46
  • @keidakida i did that and its still crashing, after i enter the name it just crashes – eeeeee Nov 23 '22 at 05:48
  • Without a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) it's difficult to determine. Please provide such an example, with test input and expected output. – Michael Ruth Nov 23 '22 at 05:53

1 Answers1

0

Here you go:


# == Ignore this part ==========================================================
# `create_fake_course_info_file`,  `FakeInputBox` and `FakeUsernameLabel` are just
# placeholder classes to simulate the objects that `FakeCls.addUser` method
# interacts with.

def create_fake_course_info_file(filepath: str):
    """Create a fake file to test ``FakeCls`` class implementation.

    Function creates a text file, and populates it with 50 blank lines.

    Parameters
    ----------
    filepath : str
        Path to the file to be created.
    """
    print(f"Saving fake data to: {filepath}")
    with open(filepath, "w") as fh:
        fh.write("\n" * 50)


class FakeInputBox:
    """
    Mock class with necessary methods to run ``FakeCls.addUser`` method.
    """
    def __init__(self, text):
        self._text = text

    def text(self):
        return self._text

    def clear(self):
        self._text = ""


class FakeUsernameLabel:
    """
    Mock class with necessary methods to run ``FakeCls.addUser`` method.
    """
    def setText(self, text):
        self.text = text

# == Actual Code ===============================================================

class FakeCls:

    def __init__(self, name):

        self.inputBox = FakeInputBox(name)
        self.usernameLbl = FakeUsernameLabel()

    def addUser(self):

        global name
        global split_name

        name = self.inputBox.text()
        split_name = name.split()
        print(f"Split Name: {split_name} | Length: {len(split_name)}")
        self.usernameLbl.setText(name)
        self.inputBox.clear()

        # self.congratulations()

        if name != "":
            # Read current contents of the file and save each line of text as
            # an element in a list.
            with open("UpdatedCourseInfo.txt", mode="r", encoding="utf-8") as fh:
                data = fh.readlines()
                # Replace the 41st line with the user's name.
                if len(split_name) == 2:
                    data[40] = f"\n{split_name[0]}, {split_name[1]}, 0, None, None"
                else:
                    data[40] = f"\n{split_name[0]}, 0, 0, None, None"
            # Write the updated list to the file.
            with open("UpdatedCourseInfo.txt", mode="w", encoding="utf-8") as fh:
                fh.writelines(data)
        print(name)
        return name

Example

Here's the code in action:

enter image description here

Notes

I've made some changes to your original implementation, to make it a little bit cleaner and more "Pythonic". You can ignore the code inside the create_fake_course_info_file function, FakeInputBox and FakeUsernameLabel classes as they're only placeholders to your actual code that was not provided in the question.

Ingwersen_erik
  • 1,701
  • 1
  • 2
  • 9