Reputation: 13
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')
Upvotes: 1
Views: 164
Reputation: 690
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()
Upvotes: 1
Reputation: 7952
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.
Upvotes: 1