`pickle.load` throws `EOFError: Ran out of input` error

1k views Asked by At

I wrote this python-script and everytime I run it, it is supposed to input some details that it has to take in addEmployee() method. When I press Enter to submit all the information it throws the following error:

Traceback (most recent call last):
  File "C:\Users\ammar\PycharmProjects\pythonProject\main.py", line 122, in <module>
    menu()
  File "C:\Users\ammar\PycharmProjects\pythonProject\main.py", line 108, in menu
    addEmployee()
  File "C:\Users\ammar\PycharmProjects\pythonProject\main.py", line 35, in addEmployee
    employees = pickle.load(f)
                ^^^^^^^^^^^^^^
EOFError: Ran out of input

Process finished with exit code 1

Additional information: I'm using Pycharm to do this and I have made a text file called employees.txt in the same folder where this program is stored

I don't know how to fix this any help would be appreciated.

This is my script:
import datetime
import pickle

def addEmployee():
    fullName = input("Enter full name: ")
    employeeID = int(input("Enter employee ID: "))
    department = input("Enter department: ")
    doj = input("Enter date of joining (MM/DD/YYYY): ")
    salary = int(input("Enter annual salary: "))

    if len(fullName) == 0:
        print("Please enter full name.")
        return

    if not 10000 <= employeeID <= 99999:
        print("Employee ID should be in the range of 10000 and 99999.")
        return

    if department not in ["Marketing", "Finance", "Human Resource", "Technical"]:
        print("Department should be Marketing, Finance, Human Resource, or Technical.")
        return

    try:
        datetime.datetime.strptime(doj, "%m/%d/%Y")
    except ValueError:
        print("Invalid date of joining format.")
        return

    if not 30000 <= salary <= 200000:
        print("Salary should be in the range of 30000 and 200000.")
        return

    with open("employees.txt", "rb") as f:
        employees = pickle.load(f)
        if employeeID in employees:
            print("Employee with ID {} already exists.".format(employeeID))
            return

    employees.append({
        "fullName": fullName,
        "employeeID": employeeID,
        "department": department,
        "doj": doj,
        "salary": salary
    })

    with open("employees.txt", "wb") as f:
        pickle.dump(employees, f)

    print("Employee added successfully.")


def displayEmployees():
    with open("employees.txt", "rb") as f:
        employees = pickle.load(f)

    if len(employees) == 0:
        print("No employees found.")
        return

    print("Employees:")
    for employee in employees:
        print(employee)


def deleteEmployee():
    employeeID = int(input("Enter employee ID to delete: "))

    with open("employees.txt", "rb") as f:
        employees = pickle.load(f)
        if employeeID not in employees:
            print("Employee with ID {} does not exist.".format(employeeID))
            return

    employees.remove({"employeeID": employeeID})

    with open("employees.txt", "wb") as f:
        pickle.dump(employees, f)

    print("Employee deleted successfully.")


def updateEmployee():
    employeeID = int(input("Enter employee ID to update: "))

    with open("employees.txt", "rb") as f:
        employees = pickle.load(f)
        if employeeID not in employees:
            print("Employee with ID {} does not exist.".format(employeeID))
            return

    updatedSalary = None
    updatedDepartment = None

    print("What do you want to update?")


def menu():
    print("1 to Add Employee")
    print("2 to Delete Employee")
    print("3 to Update Employee")
    print("4 to Display Employees")
    print("5 to Exit")

    ch = int(input("Enter your Choice:"))
    if ch == 1:
        addEmployee()
    elif ch == 2:
        deleteEmployee()
    elif ch == 3:
        updateEmployee()
    elif ch == 4:
        displayEmployees()
    elif ch == 5:
        exit(0)
    else:
        print("Invalid Input")
        menu()


menu()

Thanks in advance!

2

There are 2 answers

3
Musabbir Arrafi On BEST ANSWER

You are facing EOFError: Ran out of input error because you're trying to load a generic .txt file as a .pkl object. The file name should be as employees.pkl. Here's your corrected code:

import datetime
import pickle
import os

def addEmployee():
    fullName = input("Enter full name: ")
    employeeID = int(input("Enter employee ID: "))
    department = input("Enter department: ")
    doj = input("Enter date of joining (MM/DD/YYYY): ")
    salary = int(input("Enter annual salary: "))

    if len(fullName) == 0:
        print("Please enter full name.")
        return

    if not 10000 <= employeeID <= 99999:
        print("Employee ID should be in the range of 10000 and 99999.")
        return

    if department not in ["Marketing", "Finance", "Human Resource", "Technical"]:
        print("Department should be Marketing, Finance, Human Resource, or Technical.")
        return

    try:
        datetime.datetime.strptime(doj, "%m/%d/%Y")
    except ValueError:
        print("Invalid date of joining format.")
        return

    if not 30000 <= salary <= 200000:
        print("Salary should be in the range of 30000 and 200000.")
        return
    
    if os.path.exists("employees.pkl") == False:
        employees = []
        with open("employees.pkl", "wb") as f:
            pickle.dump(employees, f)
            
    with open("employees.pkl", "rb") as f:
        employees = pickle.load(f)
        if employeeID in employees:
            print("Employee with ID1 {} already exists.".format(employeeID))
            return

    employees.append({
        "fullName": fullName,
        "employeeID": employeeID,
        "department": department,
        "doj": doj,
        "salary": salary
    })

    with open("employees.pkl", "wb") as f:
        pickle.dump(employees, f)

    print("Employee added successfully.")


def displayEmployees():
    with open("employees.pkl", "rb") as f:
        employees = pickle.load(f)

    if len(employees) == 0:
        print("No employees found.")
        return

    print("Employees:")
    for employee in employees:
        print(employee)


def deleteEmployee():
    employeeID = int(input("Enter employee ID to delete: "))

    with open("employees.pkl", "rb") as f:
        employees = pickle.load(f)
        if employeeID not in employees:
            print("Employee with ID {} does not exist.".format(employeeID))
            return

    employees.remove({"employeeID": employeeID})

    with open("employees.pkl", "wb") as f:
        pickle.dump(employees, f)

    print("Employee deleted successfully.")


def updateEmployee():
    employeeID = int(input("Enter employee ID to update: "))

    with open("employees.pkl", "rb") as f:
        employees = pickle.load(f)
        if employeeID not in employees:
            print("Employee with ID {} does not exist.".format(employeeID))
            return

    updatedSalary = None
    updatedDepartment = None

    print("What do you want to update?")


def menu():
    print("1 to Add Employee")
    print("2 to Delete Employee")
    print("3 to Update Employee")
    print("4 to Display Employees")
    print("5 to Exit")

    ch = int(input("Enter your Choice:"))
    if ch == 1:
        addEmployee()
    elif ch == 2:
        deleteEmployee()
    elif ch == 3:
        updateEmployee()
    elif ch == 4:
        displayEmployees()
    elif ch == 5:
        exit(0)
    else:
        print("Invalid Input")
        menu()
menu()

Output:

1 to Add Employee
2 to Delete Employee
3 to Update Employee
4 to Display Employees
5 to Exit
Enter your Choice:1
Enter full name: rafi
Enter employee ID: 10001
Enter department: Technical
Enter date of joining (MM/DD/YYYY): 12/12/1998
Enter annual salary: 40001
Employee added successfully.

Also, I've made a few modifications to the code. You don't have to manually create a .pkl file, the first time you are running the code. This block of code will create an empty pickle file when you're running the script for the first time. From then, new entries will be saved to this 'employees.pkl` file.

if os.path.exists("employees.pkl") == False:
    employees = []
    with open("employees.pkl", "wb") as f:
        pickle.dump(employees, f)
0
snakecharmerb On

There are (at least) two reasons for this error.

Firstly the file may be empty; secondly, the file pointer may be at the end of the file.

The following sample code demonstrates the behaviours, using an in-memory buffer rather than a file (the behaviour is the same for both).

>>> import io
>>> import pickle
>>>
>>> # Simulate an empty file.
>>> buf = io.BytesIO()
>>> # Try to load it.
>>> pickle.load(buf)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EOFError: Ran out of input
>>>
>>> # No error if the file contains pickled object.
>>> d = dict(a=1)
>>> pickle.dump(d, buf)
>>> # Rewind the file pointer to the beginning of the file.
>>> buf.seek(0)
0
>>> pickle.load(buf)
{'a': 1}
>>>
>>> # Try to load again without rewinding the file pointer.
>>> pickle.load(buf)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EOFError: Ran out of input

In the code in the question, the most likely cause is that the file is initially empty. You could try catching EOFError in cases where this is likely to be risk:

with open('employees.txt', 'rb') as f:
    try:
        employees = pickle.load(f)
    except EOFError:
        # Set employees to a suitable default value