HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Python 2.7 Payroll Calculator program

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
payrollprogramcalculatorpython

Problem

This is a calculator I'm working on. The ultimate goal is to calculate multiple payrolls before selecting to end the program, please review current version in that context. PSA: I'm a beginner.

def main():

    hours, rate = inputData()
    normal_hours, overtime_hours, overtime  = computePay (hours,rate)
    regular, total_pay  = preovertime_hours (hours, rate, overtime)
    displayPay  (rate, normal_hours, overtime_hours, regular, overtime, total_pay)

def inputData():

    name = raw_input('Name of employee: ')    
    hours = float (input('Now enter the hours worked please:'))
    rate = float (input('Now enter the pay rate:'))

    return hours, rate

def computePay (hours,rate):

    if hours  40:
        overtimerate = 1.5 * rate
        overtime = (hours-40) * overtimerate
    else:
        overtime = 0

    return normal_hours, overtime_hours, overtime

def preovertime_hours (hours, rate, overtime):

    regular = hours * rate
    total_pay = regular
    return regular, total_pay

def displayPay (rate, normal_hours, overtime_hours, regular, overtime, total_pay):

    print ("The amount to be paid to in this pay period is $" + format(total_pay, '.2f'))

main()

Solution

First off, there currently is no point in having name = raw_input('Name of employee: '),
as it is never used.

Generally it's safer to never use input. For example:

>>> hello, world = 'goodbye', 'logic'
>>> input()
hello + world
'goodbyelogic'


As you can see, input evaluates the input. Which is not very safe.
Lets say you have some special information that no-one should know about.
But you stored it in a variable.
We with our 'elite haxor skillz', we could find out that information.
for example:

>>> private_key = 'my super private key'
>>> input()
globals()['private_key']
'my super private key'


Bottom line input is bad, so bad that it got removed in Python3.
And so, I would recommend to always use raw_input, in Python2.

float (input('Now enter the hours worked please:'))


First as mentioned above, this should be raw_input,
but it is flimsy, say we input a.
float will error, and the program will exit.

Instead you can use a try except statement.

while True:
    try:
        float(input('Now enter the hours worked please:'))
        break
    except ValueError:
        pass


computePay is really good.
If you are ok with using turnery operators you can re-write it, but your way is probably best.
Except for overtimerate, that should be part of overtime.
If I were to re-write your code then it would be something like:

def computePay (hours,rate):
    normal_hours, overtime_hours = hours, 0 if hours  40 else 0
    return normal_hours, overtime_hours, overtime


preovertime_hours can just be a return statement.
You could even opt for it not to be a function.
I'm more inclined for the latter as it just returns hours rate, hours rate.
Also you should add it to computePay as it would fit better there.

In displayPay you may want to use str.format rather than format.
They're very similar, so to change to str.format you would do:

"The amount to be paid to in this pay period is ${:.2f}".format(total_pay)


As for main.
Due to all the changes above I personally would recommend that you change it to 3 function calls.
They are inputData, computePay and displayPay.
Whilst you could merge it all into one function and keep everything simple,
keeping IO away from logic is always good.

Overall your structure is pretty good. There are a lot of nice small functions.

Just to note, you should always have functions declared and used as function().
Note there is no space between the name and the brackets!

Also as some languages allow - in names,
it's always a good idea to put a space either side of operators.

You could 'wrap' your main() in a if __name__ in '__main__':.
This prevents your code running if it's not the main file.
(E.g. if someone imports your file into there code.)

But otherwise your code is good.

Just so you know currently almost all your code is dead code (It does nothing).
And so you could re-write main into:

def main():
    hours, rate = inputData()
    displayPay('', '', '', '', '', hours * rate)



The ultimate goal is to calculate multiple payrolls before selecting to end the program

If you want this you could make a while loop like the example above to fix float(input()).
A simple way to do this is to ask a question like 'Would you like to add another user? [y/n] '.
And exit on any input that is not 'y' or 'yes'.

As I'm not going to write it for you, the following is half the loop.

if input('Would you like to add another user? [y/n] ').lower() in ['y', 'yes']:
    main()

Code Snippets

>>> hello, world = 'goodbye', 'logic'
>>> input()
hello + world
'goodbyelogic'
>>> private_key = 'my super private key'
>>> input()
globals()['private_key']
'my super private key'
float (input('Now enter the hours worked please:'))
while True:
    try:
        float(input('Now enter the hours worked please:'))
        break
    except ValueError:
        pass
def computePay (hours,rate):
    normal_hours, overtime_hours = hours, 0 if hours < 40 else 40, hours - 40
    overtime = (hours - 40) * 1.5 * rate if hours > 40 else 0
    return normal_hours, overtime_hours, overtime

Context

StackExchange Code Review Q#109950, answer score: 4

Revisions (0)

No revisions yet.