0

I am fairly new to file handling and csv files in Python.

Code

import csv
file1=open("Employee.csv","w",newline='\r\n')
empwriter=csv.writer(file1)
empwriter.writerow(["EmpID.","Name","MobNo."])
n=int(input("How many employee records do you want to add?:"))
for i in range(n):
    print("\nEmployee Record",(i+1))
    empid=input("Enter empID:")
    name=input("Enter Name:")
    mob=input("Enter Mobile No.:")
    emprec=[empid,name,mob]
    empwriter.writerow(emprec)
file1.close()

file2=open("Employee.csv","r+",newline='\r\n')
empreader=csv.reader(file2)
newwriter=csv.writer(file2)
check=input("\nEnter the empID to check:\n")
opt=int(input('''Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3Update the whole record\n\n'''))

if opt==1:
    for x in empreader:
        if x[0]==check:
            newname=input("Enter new name:")
            x[1]=newname
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)
elif opt==2:
    for x in empreader:
        if x[0]==check:
            newmob=input("Enter new Mobile No.:")
            x[2]=newmob
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)     
elif opt==3:
    for x in empreader:
        if x[0]==check:
            newname=input("Enter new name:")
            newmob=input("Enter new Mobile No.:")
            x[1]=newname
            x[2]=newmob
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)
file2.close()

I have in this code tried to

  1. enter records (empID, Name, MobNo.) by user and make a csv file.
  2. using empID find the desired record.
  3. update that record.
  4. display all records.

When I execute the code, the print statement inside the for loop gets executed before the if statement and gives me this output.

Output

How many employee records do you want to add?:3

Employee Record 1
Enter empID:001
Enter Name:John
Enter Mobile No.:1234567890

Employee Record 2
Enter empID:002
Enter Name:Jane
Enter Mobile No.:2345678901

Employee Record 3
Enter empID:003
Enter Name:Judy
Enter Mobile No.:4567890123

Enter the empID to check:
002
Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3.Update the whole record

2
['EmpID.', 'Name', 'MobNo.']
['001', 'John', '1234567890']
Enter new Mobile No.:1111222233
Record Updated Successfully!
 Updated record:
 ['002', 'Jane', '1111222233']
['002', 'Jane', '1111222233']

As you can see in the last few lines of the output. Print statement got executed before the if statement (or something similar).I actually want the output to display in the below given way...

Desired output

2
Enter new Mobile No.:1111222233
Record Updated Successfully!
 Updated record:
 ['002', 'Jane', '1111222233']
['EmpID.', 'Name', 'MobNo.']
['001', 'John', '1234567890']
['002', 'Jane', '1111222233']
['003', 'Judy', '4567890123']
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • you need to use another `for` loop to print the whole file, or store it in some array. – Mani Nov 12 '21 at 08:40
  • when i add ``` for rec in empreader: print(rec) ``` at the very end.. nothing changes.. If possible can u share a simple version of what u intend to say? – Flash-The-Programmer Nov 12 '21 at 09:40

1 Answers1

0

I can see what's happening, and why it's not what you expect.

Take a look at this block:

elif opt==2:
    for x in empreader:
        if x[0]==check:
            newmob=input("Enter new Mobile No.:")
            x[2]=newmob
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)  

What's actually happening is that, for every row x in empreader:

  1. the ID col, x[0], is being evaluated against the ID you entered, check. If it matches:
    1. you interrupt the loop, and step in to modify x
    2. write out the new value, newwriter.writerow(x)
    3. then you step out and...
  2. print your update, print(x)

Unless, x[0]==check is False, in which case x is just printed.

Think about (and test) what happens when you provide a non-existet ID for check... it'll never get into your "modify interface" and instead will just print every (unmodified) row in empreader.

What happens then, do you display an error message letting the user know they picked a bad ID?

This is a pretty big change, but I think it keeps the logic and your intent more clear... you're not making decisions in loops, which is very difficult. Take input and make decisions in a "flat" sequence:

import csv
import sys

# Get the employee ID
check=input("\nEnter the empID to check:\n")

# and check the ID in the employee records
emp_row = None
with open("Employee.csv","r",newline='\r\n') as f:
    empreader=csv.reader(f)

    for x in empreader:
        if x[0] == check:  # the employee ID matches
            emp_row = x[:]

if emp_row is None:
    print(f'Could not find employee ID {check}')
    sys.exit(0)  # or exit(1) to show it's an "error"

# Now you know you have a valid ID, because emp_row has data

opt=int(input('''Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3.Update the whole record\n\n'''))

if opt == 1:
    newname = input("Enter new name:")
    emp_row[1] = newname
# else if opt == 2:
#    ...
# else if opt ==3:
#    ...

# Now how do you overwrite the old row in Employee.csv with emp_row?
# Don't try to "modify" the original file as you're reading it, instead...
# Read from the old file, copying all the old rows, except for emp_row, to a new list

new_rows = []
with open('Employee.csv', 'r', newline='\r\n') as f_in:
    reader = csv.reader(f_in)
    header_row = next(reader)
    new_rows.append(header_row)

    for row in reader:
        if row[0] == check:
            new_rows.append(emp_row)
        else:
            new_rows.append(row)

# Then write your new_rows out
with open('Employee.csv', 'w', newline='\r\n') as f_out:
    writer = csv.writer(f_out)
    writer.writerows(new_rows)

I started with Employee.csv looking like this:

EmpID.,Name,MobNo.
001,John,1234567890
002,Jane,2345678901
003,Judy,4567890123

I ran that, and it looked like this:

% python3 main.py

Enter the empID to check:
002
Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3.Update the whole record

1
Enter new name:Alice

and Employee.csv now looks like:

EmpID.,Name,MobNo.

001,John,1234567890

002,Alice,2345678901

003,Judy,4567890123

(I'm on a Mac, so \r\n adding lines)

Zach Young
  • 10,137
  • 4
  • 32
  • 53
  • No errors occur and code executes itself (which it should not since the ID doesnt exist). and yes it printed every unmodified row in empreader as u said.. Thank u for explaining where I am going wrong but could u suggest what I do next? – Flash-The-Programmer Nov 12 '21 at 09:55
  • Just updated answer, it's a big change, but I think it'll be good for you as you develop and become a better programmer :) – Zach Young Nov 12 '21 at 10:24
  • 1
    Thanks a lot for taking time out and actually helping me. File handling is a fairly new topic for me and maybe because of that I am a bit slow in understanding what is really happening in each code. You adding comments and giving apt explanation really helps in understanding the logic behind, for which I am really grateful. I however have a small query.. Can u tell why have u used x[:] in the code-- emp_row = x[:] – Flash-The-Programmer Nov 12 '21 at 10:40
  • Hehe, I wondered if you'd catch that ;) In Python, lists are passed by reference, not by value, and that can lead to buggy surprises (https://stackoverflow.com/a/2612815/246801). I'm not sure it's totally necessary in this case, but I don't think it's wrong to make an **explicit list copy**. And, I'm glad the comments helped, cheers! – Zach Young Nov 12 '21 at 10:43
  • 1
    Ah yes to make an explicit list copy. I have only learnt to make it using .copy() method. Learning new things everyday :) Once again thank you very much :D – Flash-The-Programmer Nov 12 '21 at 10:49