1

Hello I am having trouble modifying lines of text using python. I am making a payroll app and I cannot get the modify method to work. I do not understand why the entry that I search for will not delete in the new files. I am copying the files over to a temp and then renaming the temp file but the old entry stays in.

def modEmp():
    empFile = open("employees.txt", 'r')
    empFile2= open("temp.txt",'w')
    line1 = empFile.readline().rstrip("\n")
    name = input("Enter in your employee name that you would like to modify\n")
    while line1 != '':
        line1 = line1.split(" ") #split line into list
        name = line1[0] + ' ' + line1[1]
        if name[0] == line1[0] and name[0] == line1[0]:
            print('Enter the modified entry:\n')
            list = [0] * 4
            list [0] = input('Enter first name:\n')
            list [1] = input('Enter last name:\n')
            list [2] = input('Enter pay rate:\n')
            list [3] = input('Enter hours worked:\n')
            empFile2.write(list[0] + ' ' + list[1] + ' ' + list[2] + ' ' + list[3] + "\n")

        else:
            empFile2.write(line1 + "\n")

        line1 = empFile.readline().rstrip("\n") 
    #Close file
    empFile.close()
    empFile2.close()
    os.remove('employees.txt')
    os.rename('temp.txt','employees.txt')
4
  • if name[0] == line1[0] and name[0] == line1[0]: This doesn't make sense!!?? Commented Jul 13, 2017 at 20:15
  • Fix your indentation... Commented Jul 13, 2017 at 20:15
  • 1
    name is a string, line1 is a list of string, therefore name[0] == line1[0] compares a character to a string, ie only works for people with 1-letter names ;-) Commented Jul 13, 2017 at 20:17
  • You also overwrite name so it doesn't matter what name they put in. Commented Jul 13, 2017 at 20:22

2 Answers 2

1

There are some serious issues with your code:

name = input("Enter in your employee name that you would like to modify\n")
...
    name = line1[0] + ' ' + line1[1]

You overwrite name before looking at it, so whatever they input doesn't matter.

As Hugh Bothwell pointed out:

line1 = line1.split(" ") #split line into list
    name = line1[0] + ' ' + line1[1]
    if name[0] == line1[0] and name[0] == line1[0]:

Tries to compare a string to the first character in that same string, which will only be True if name is a single character.

Instead, you want to do something like this: I've cleaned up a lot of the extra fluff by using with which handles closing the files for us and letting the built-in for element in list: loop:

I've also renamed your list variable as lst, as overwriting the built-in list variable is a recipe for errors.

def modEmp():
    with open("employees.txt", 'r') as empFile, open("temp.txt", "w") as empFile2:
        name = input("Enter in your employee name that you would like to modify\n")
        for line in empFile:
            if name in line:
                print('Enter the modified entry:\n')
                lst = []
                lst.append(input('Enter first name:\n'))
                lst.append(input('Enter last name:\n'))
                lst.append(input('Enter pay rate:\n'))
                lst.append(input('Enter hours worked:\n'))
                empFile2.write("{} {} {} {}\n".format(*lst))
            else:
                empFile2.write(line)

    # I highly encourage making a backup, as sooner or later
    # someone will mess it up
    os.rename('employees.txt', 'employees.bkp')
    os.rename('temp.txt','employees.txt')

Please note that, should you have more than one "bill" and you search for "bill", you will be prompted to change them both. Also, there is no abort for this function and it is destructive, so you lose whatever information was already stored for these employees. In a real payroll application, this would probably be disastrous.


Additionally, if you want to make it a little more reusable, instead of specifying four elements in a list, you can:

prompts = ["Enter first name:\n", 
           "Enter last name:\n", 
           "Enter pay rate:\n", 
           "Enter hours worked:\n"]
empFile2.write(" ".join(map(input, prompts)) + '\n')

Which will compile as many inputs as prompts and then store them space separated in the file as a line, although it's less obvious what you're doing.

Sign up to request clarification or add additional context in comments.

Comments

1

As mentioned in the comments, there are a few things wrong with your code...

It is good practice to use the with open(name) as f: syntax in a situation such as yours.

Here is a solution that I believe will solve your problem.

def modify():
    with open("employees.txt", 'r+') as employee_file:  # Opening file in read and write mode
        temp = employee_file.readlines()  # Get all lines
        employee_file.seek(0)  # Reset position in file

        name = input("Enter in your employee name that you would like to "
                     "modify\n")

        first, last = name.split(' ')  # Assuming this is what you intended

        for line in temp:
            # There's no reason to use a list here, and avoid using object names as variables
            if first in line and last in line:
                print('Enter the modified entry:\n')
                first_name = input('Enter first name:\n')
                last_name = input('Enter last name:\n')
                pay_rate = input('Enter pay rate:\n')
                hours = input('Enter hours worked:\n')

                line_to_write = ' '.join([first_name, last_name,
                                          pay_rate, hours])
                employee_file.write(line_to_write + "\n")
            else:
                employee_file.write(line + "\n")

        employee_file.truncate()

4 Comments

You're on the right track, but there still are some issues: write() takes a single argument: you must format the first_name, last_name,... prior to passing it to write. You must also insert the newline. Breaking the name into first/last then checking for each inclusion separately is extra work. Also, the default behavior of split() is to work on spaces, so it's unnecessary to specify it. I would encourage you in the future to run your code to verify it's accuracy.
@TemporalWolf Thanks for the reminder about write, and split - however, you don't have to insert a newline.
repl.it disagrees. file.write() does not insert a trailing newline for each call.
tutorialspoint.com/python/file_write.htm mislead me, you are correct.

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.