Textbook code bug - How to fix? save_emp_records.py

Trying to do this lab excerise, and getting the output below.

Expected output is:
Screenshot 2024-03-10 143957

When I compile and run: I get this output. What am I missing?
==== RESTART: G:/My Drive/MCC/ITC-111-30 Scripting/lab4/save_emp_records.py ====
How many employee records do you want to create? 4
Enter data for employee #1
Name: 3
ID number: 2
Department: 3

Employee records written to employees.txt.
Enter data for employee #2
Name: 23
ID number: 3
Department: 2
Traceback (most recent call last):
File “G:/My Drive/MCC/ITC-111-30 Scripting/lab4/save_emp_records.py”, line 34, in
main()
File “G:/My Drive/MCC/ITC-111-30 Scripting/lab4/save_emp_records.py”, line 21, in main
emp_file.write(f’{name}\n’)
ValueError: I/O operation on closed file.

# This program gets employee data from the user and
# saves it as records in the employee.txt file.
 
def main():
   # Get the number of employee records to create.
   num_emps = int(input('How many employee records ' +
                        'do you want to create? '))
 
   # Open a file for writing.
   emp_file = open('employees.txt', 'w')
 
   # Get each employee's data and write it to the file.
   for count in range(1, num_emps + 1):
       # Get the data for an employee.
       print(f'Enter data for employee #{count}')
       name = input('Name: ')
       id_num = input('ID number: ')
       dept = input('Department: ')

       # Write the data as a record to the file.
       emp_file.write(f'{name}\n')
       emp_file.write(f'{id_num}\n')
       emp_file.write(f'{dept}\n')

       # Display a blank line.
       print()

       # Close the file.
       emp_file.close()
       print('Employee records written to employees.txt.')

# Call the main function.
if __name__ == '__main__':
     main()

Think about where you open the file for writing, and where you close it. Have you finished writing to it when you close it, or will you make more emp_file.write calls after closing it?

1 Like

Also remember that indentation is relevant in python and if you copied this from the textbook, make sure you copied it correctly.

I changed the following lines and this seems to have worked.

OLD:
print(f'Enter data for employee #{count}')

New:
print('Enter data for employee #', count, sep='')

OLD
if __name__ == '__main__':

New

# comment out  - not needed
# if __name__ == '__main__':

Final code - Seems to work

# This program gets employee data from the user and
# saves it as records in the employee.txt file.

def main():
  # Get the number of employee records to create.
  num_emps = int(input('How many employee records ' + \
                       'do you want to create? '))

  # Open a file for writing.
  emp_file = open('employees.txt', 'w')

  # Get each employee's data and write it to the file.
  for count in range(1, num_emps + 1):
    # Get the data for an employee.
    print('Enter data for employee #', count, sep='')
    name = input('Name: ')
    id_num = input('ID number: ')
    dept = input('Department: ')

    # Write the data as a record to the file.
    emp_file.write(name + '\n')
    emp_file.write(id_num + '\n')
    emp_file.write(dept + '\n')

    # Display a blank line.
    print()

  # Close the file.
  emp_file.close()
  print('Employee records written to employees.txt.')

# Call the main function.
main()

That’s not the only thing you changed. These lines have nothing to do with the error you saw.

You also changed the indentation of this line:

  # Close the file.
  emp_file.close()

Which is what fixed the problem. Before, the file was closed in the for-loop, i.e. it closed after the first iteration, causing the write attempt in the second iteration to fail. Now, the file is closed outside the for-loop, i.e. after all writes are done.

1 Like

Thank you.

Just an fyi, you don’t need the following line of code if you are not expecting to import your module into another module:

if __name__ == '__main__':

Any code after this line will ONLY be executed if you run your module as the master module. If you import it into another module, and you run that other module, any code after this line will not be executed.
Generally, the code after this line is test code to verify the code above it.

Thank you.