0

I'm aiming to display records of employees with a salary between 2 user inputted values (in a format specified in my function printTuple(data)). So far I use the function choice2() to open the file, read line by line in a for loop, convert the line (which is a string) to an int, then grab the index of the salary so I can compare it to the 2 inputted values (. After that I take the line as a variable in "record" and go to makeTuple to turn it into a tuple, and then finally print it in my desired format inside printTuple.

When I attempt to run the choice2 function I get an error: "local variable 'myTuple' referenced before assignment". However I need to change the myTuple value to an int before I can compare it with the values the user inputted, so I'm not sure how to fix this.

Here is my program:

def makeTuple (employee):

    myTuple = employee.split(" ")
    (payroll, salary, job_title, *othernames, surname) = myTuple
    return(myTuple)

def printTuple (data):

    employee_str = "{:<15} {:20} {:<10} {:<15} £{:>1}"
    print(employee_str.format(data[-1]+ ",", " ".join(data[3:-1]), data[0], data[2], data[1]))

def choice1():

    op_1 = str(input("Please enter a Pay Roll number: "))
    file = open(path)
    lines = file.readlines()
    for line in lines:
        if op_1 in line:
            record = line.strip()
    myTuple = makeTuple(record)
    printTuple(myTuple)

def choice2():

    op_2a = int(input("Please enter a lower bound for the Salary :"))
    op_2b = int(input("Please enter a higher bound for the Salary :"))

    file = open(path)
    lines = file.readlines()
    for line in lines:
        myTuple[0] = int(myTuple[0])
        if myTuple[0] >= op_2a and myTuple[0] <= op_2b:
            myTuple[0] = myTuple[0]
            record = line.strip()        
    myTuple = makeTuple(record)
    print(myTuple)

get_file = input(str("Please enter a filename: "))    
path = get_file + ".txt"

try:
    f = open(path)
except IOError:
    print('The file could not be opened.')
    exit()

for line in iter(f):
    record = line.strip()
    myTuple = makeTuple(record)
    printTuple(myTuple)


print("\n\nDisplay full details of an Employee with a given payroll number     enter:     '1'")
print("Display all employees with a salary within a specified range, enter:           '2'")
print("Display the first and last name of all employees with a job title,     enter:  '3'")
print("Quit Program:                                                              '4'")

choice = int(input("Choose an option from 1-4: "))

while choice != 1 and choice != 2 and choice != 3 and choice != 4:

    print("Incorrect Value, please choose a number from 1-4")
    print("\n\nDisplay full details of an Employee with a given payroll     number enter:     '1'")
    print("Display all employees with a salary within a specified range,     enter:       '2'")
    print("Display the first and last name of all employees with a job     title, enter:  '3'")
    print("Quit Program:                                                                  '4'")

    choice = int(input("Choose an option from 1-4: "))

if choice == 1:
choice1()
if choice == 2:
choice2()
if choice == 3:
choice3()
if choice == 4:
exit()

This is the text file I am reading from:

12345 55000 Consultant Bart Simpson
12346 25000 Teacher Ned Flanders
12347 20000 Secretary Lisa Simpson
12348 20000 Wizard Hermione Grainger
12349 30000 Wizard Harry Potter
12350 15000 Entertainer Herschel Shmoikel Krustofski
13123 75000 Consultant Zlatan Ibrahimovic
13124 150000 Manager Gareth Southgate
13125 75000 Manager Juergen Klopp
13126 35000 Lecturer Mike T Sanderson
13127 200000 Entertainer Adele Laurie Blue Adkins
13128 50 Timelord Peter Capaldi
13129 250000 Entertainer Edward Christopher Sheeran
13130 32000 Secretary Wilma Flintstone

Any help is appreciated, thanks in advance.

Sean2148
  • 365
  • 1
  • 3
  • 13
  • always put **full** error message (Traceback) in question (as text, not screenshot). There are other ufull informations – furas Dec 05 '17 at 22:28
  • use button `{}` to correctly format code. – furas Dec 05 '17 at 22:28
  • maybe you should use `global myTuple` in functions or use `return myTuple` and `def choice2(myTuple)` to get tuple from one function and use it in another function. – furas Dec 05 '17 at 22:30
  • 1
    what is the point of this line? `(payroll, salary, job_title, *othernames, surname) = myTuple` you never use `payroll`, `salary`, etc, and simply return `myTuple` – juanpa.arrivillaga Dec 05 '17 at 22:33
  • Please indent your code correctly so that we can actually see what you're doing. – Shadow Dec 05 '17 at 22:47
  • @juanpa.arrivillaga, it's part of the specification for the program, however I haven't figured out how to use these variables from outside that function – Sean2148 Dec 06 '17 at 00:57
  • @Sean2148 you cannot unless you return them from your function - they are local variables. – juanpa.arrivillaga Dec 06 '17 at 01:00
  • @Shadow I've looked up indenting and I don't see anything wrong? Please would you explain, thanks – Sean2148 Dec 06 '17 at 02:27

1 Answers1

1

Your error message (local variable myTuple referenced before assignment) points out the required solution. I have:

  • reordered (record = line.strip() and myTuple = makeTuple(record) to top of loop)
  • renamed some variables (myTuple is not very descriptive, and is actually a list anyway, better naming makes code much easier to read and reason about)
  • heavily commenting (I would not normally comment my own code this much, more as indications of what I have done and why)

Here is the updated code for choice2

def choice2():

    lower_bound = int(input("Please enter a lower bound for the Salary :"))  # Renamed for clarity
    upper_bound = int(input("Please enter a higher bound for the Salary :"))  # Renamed for clarity

    # The following two lines are repeated multiple times, you should probably read
    # the file once and store into a list (or better yet a dictionary
    # keyed with pay roll number) and pass it into the function.
    file = open(path)
    lines = file.readlines()

    for line in lines:
        record = line.strip()
        employee_details = makeTuple(record)  # Rename muTuple to employee_details
        # OR MORE SIMPLY employee_details = makeTuple(line.strip())

        # Now we have the variable we can work with it
        salary = int(employee_details[0])  # The only thing we do with the tuple is print it, so no need to modify it
        if salary >= lower_bound and salary <= upper_bound:
            # This does nothing, so deleted - myTuple[0] = myTuple[0]
            print(employee_details) # Or more likely you want to use your custom print function printTuple(employee_details)
Gavin
  • 1,070
  • 18
  • 24
  • Thank you for the help, I meant to use "myTuple[0] = myTuple[0]", as a way to convert it back from an int to a string, I think I meant to write "=str(myTuple]0]", but I'm not sure if that works anyway. – Sean2148 Dec 06 '17 at 02:40
  • You can convert to string that way, but I can't see what purpose that would serve as you don't use that variable again (from what I can see) – Gavin Dec 06 '17 at 02:43