-1

Hello StackOverflow community, I am very close to finishing the creation of a employee database program which implements a dictionary for storage. The issue I have been running into is that the initial Employee objects that are stored before the menu prompt are unable to be located. They exist in the database, but I cannot manipulate them at all with my code. Anything I add afterwards using the menu functions is able to be looked up or deleted. I'm not really sure what the issue is here. I tried making the dictionary global to no avail. The statements I use are nearly identical.

class Employee:
    def __init__(self, name, idNo, department, title):
        self.name = name
        self.idNo = idNo
        self.department = department
        self.title = title   

    def setName(newName):
        self.name = newName

    def setIDNo(newID):
        self.idNo = newID

    def setDepartment(newDept):
        self.department = newDept

    def setTitle(newTitle):
        self.title = newTitle

    def getName():
        return self.name

    def getIDNo():
        return self.idNo

    def getDepartment():
        return self.department

    def getTitle():
        return self.title

    def __str__(self):
         return "Name: {0} \nID number: {1} \nDepartment: {2} \nTitle: {3}\n".format(self.name, self.idNo, self.department, self.title)

def main():
    empDatabase = {}
    entry = input("Do You Want to Enter New Employee Information(Y/N): ")
    entry = entry.upper()
    if entry == 'Y':
       gate = True
       newName = input("Enter Employee Name: ")
       newID = input("Enter Employee ID Number: ")
       newDept = input("Enter Employee Department Name: ")
       newTitle = input("Enter Employee Job Title: ")
       empDatabase[newID] = Employee(newName, newID, newDept, newTitle)    
       another = input("Do You Want to Enter Another Employee Information(Y/N): ")
       another = another.upper()
       if another != 'Y':
          gate = False
       while gate == True:
          newName2 = input("Enter Employee Name: ")
          newID2 = input("Enter Employee ID Number: ")
          newDept2 = input("Enter Employee Department Name: ")
          newTitle2 = input("Enter Employee Job Title: ")
          empDatabase[newID2] = Employee(newName2, newID2, newDept2, newTitle2)
          another2 = input("Do You Want to Enter Another Employee Information(Y/N): ")
          another2 = another2.upper()
          if another2 != 'Y':
               gate = False
    boolGate = True
    while boolGate == True:
        print("\nPlease Select from the Following Menu: ")
        print("1. Look up an Employee in the Dictionary")
        print("2. Add a New Employee to the Dictionary")
        print("3. Delete an Employee from the Dictionary")
        print("4. Quit the Program")
        print()
        choice = eval(input("Please Enter a Number from the Menu: "))
        if choice == 1:
            idNo = eval(input("Please Enter the Employee ID You are Looking for: "))
            dic_lookup(idNo, empDatabase)
        elif choice == 2:
            empDatabase = dic_add(empDatabase)
        elif choice == 3:
            idNo = eval(input("Please Enter the Employee ID to Delete the Employee: "))
            dic_delete(idNo, empDatabase)
        else:
            boolGate = False
def dic_lookup(idNo, database):
    if idNo in database:
        print()
        print(database.get(idNo))
    else:
        print()
        print("This Employee ID is not Available in our Database")
def dic_add(database):
    print()
    addName = input("Enter New Employee Name: ")
    addID = eval(input("Enter New Employee ID Number: "))
    addDept = input("Enter New Employee Department Name: ")
    addTitle = input("Enter New Employee Job Title: ")
    database[addID] = Employee(addName, addID, addDept, addTitle)
    return database

def dic_delete(idNo, database):
    if idNo in database.keys():
        database.pop(idNo)
    else:
        print()
        print("Employee does not exist in database")
    return database  

main()
notbob1
  • 1
  • 1
  • 1
  • Where do you load your existing employees? – Chen A. Oct 29 '17 at 17:28
  • Please fix your indentation, it's unclear which functions belong to the `Employee` class – Patrick Haugh Oct 29 '17 at 17:29
  • 1
    @Vinny the employees are stored in the dictionary empDatabase – notbob1 Oct 29 '17 at 17:32
  • @notbob1 You aren't storing any Employees before the menu prompts – Patrick Haugh Oct 29 '17 at 17:35
  • You shouldn't be using `eval` here. It can be dangerous, and it's not necessary for this task. And it's the main cause of your problem. – PM 2Ring Oct 29 '17 at 17:41
  • @PM2Ring actually I just solved my problem, I wasn't using eval for my ID input statements before calling the method – notbob1 Oct 29 '17 at 17:44
  • Get rid of all those `eval`s, and change your `choice` tests to `if choice == '1':`, `elif choice == '2':` Etc. The `eval`s are converting the input number strings into integers. So you enter the ID numbers into the dict as strings, but you then try to look them up as integers, which is why they can't be found. – PM 2Ring Oct 29 '17 at 17:45
  • An Employee ID Number is really a string, there's no need to convert it to integer, since you don't want to perform arithmetic on it. And if you _do_ need to convert numeric strings into actual integers you should use `int`, eg `int("42")`. – PM 2Ring Oct 29 '17 at 17:48
  • BTW, your class definition needs some repair work: most of those methods don't have a `self` arg. OTOH, in Python we don't normally use setter & getter methods, we access the attributes directly. So you can safely get rid of most of those methods, and your existing code isn't using them anyway. – PM 2Ring Oct 29 '17 at 17:49
  • 2
    I really can't stress strongly enough that you should avoid `eval` unless you _really_ need it, and you certainly don't need it here. For details, please see [Eval really is dangerous](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) by SO veteran Ned Batchelder. Of course, this is probably just a "toy" program, not intended for real-world use, so you don't need to worry that someone could enter a command to erase your hard drive instead of a valid ID number. But using `eval` for trivial stuff is definitely not a good practice. – PM 2Ring Oct 29 '17 at 17:54
  • @PM2Ring this is a toy program, but thank you for the programming tips. I had no idea that eval was that powerful of a statement – notbob1 Oct 29 '17 at 17:58
  • Your overall approach is poorly thought through. If you are creating a database, why not use an actual database like Postgres or MySQL? – Chris Johnson Oct 29 '17 at 18:32
  • 4
    The correct way to convert a string to an integer is with `int()`, not `eval()`. – Code-Apprentice Oct 29 '17 at 19:08
  • 3
    See also for instance [this example how an arbitrary system call can be made via `eval`](https://stackoverflow.com/a/37081082/5067311). You can't overestimate its threat. – Andras Deak -- Слава Україні Oct 29 '17 at 20:11

1 Answers1

0

I added a couple of print statements along the code. The first two elements were added initially, the third one was added using the menus. This is the output from the print:

{'1': <main.Employee object at 0x037FFDB0>, '2': <main.Employee object at 0x037FFE30>, 3: <main.Employee object at 0x037FFA30>}

As you can see the first two keys are string, the third one an integer.

If you modify your code (rows 45 and 55) to add integers keys to the dictionary:

empDatabase[int(newID)] = Employee(newName, newID, newDept, newTitle)
empDatabase[int(newID2)] = Employee(newName2, newID2, newDept2, newTitle2)

it seems to work fine.

AlePorro
  • 111
  • 1
  • 11
  • I just added eval to two of the statements asking for ID and it works perfectly. Who would've thought 2 missing functions would make a world of difference? – notbob1 Oct 29 '17 at 18:17
  • Yeah sorry I only noticed your comment after I had posted my answer. Hope it helped anyway, but it was good for me as an exercise in debugging! – AlePorro Oct 29 '17 at 18:42
  • 1
    The correct way to convert a string to an integer is with `int()`, not `eval()`. `eval()` will accept any executable code whereas `int()` will throw an error when the input is not a valid integer. – Code-Apprentice Oct 29 '17 at 19:08