Help Needed. Find the error

Hi - I’m writting the simple code below that should run a specific calculation if the user input value is above or below 40. When entering an h value of 45 and 10.5 for r, the final output should read ‘Pay 498.75’. My code is doing that but its not elegant at all and very messy. Can you pls tell me what I should be doing differently?

def computepay(h,r):
multi = hr
many = (40 * r)+(h-40)
(1.5*r)
if h < 40:
return multi
elif h > 40:
return many

hrs = input(“Enter Hours:”)
h = float(hrs)
rate = input(“Enter Rate:”)
r = float(rate)
p = computepay(h,r)
print(“Pay”,p)

Hi - I’m writting the simple code below that should run a specific
calculation if the user input value is above or below 40. When entering
an h value of 45 and 10.5 for r, the final output should read ‘Pay
498.75’. My code is doing that but its not elegant at all and very
messy. Can you pls tell me what I should be doing differently?

Remarks inline below:

def computepay(h,r):

I would use longer names, eg “hours” and “baserate”, for greater
clarity.

multi = hr
many = (40 * r)+(h-40)
(1.5*r)
if h < 40:
return multi
elif h > 40:
return many

You compute both results and then pick one of them to return. I’d just
put the computation inside the appropriate branch, for example:

if h < 40:
    return h*r

Your two branches do not cover all that cases; in particular, when h ==
40 neither fires.

Since you have only 2 cases, I would just use “else” and tweak the first
condition:

if h <= 40:
    return h*r
else:
    return (40 * r)+(h-40)*(1.5*r)

Further, since both branches do a return, you do not need the else:

if h <= 40:
    return h*r
return (40 * r)+(h-40)*(1.5*r)

The important thing here is that your function had some scope to just
“drop off the bottom” if none of the if-conditions matched. Even if you
have the conditions correct so that that never happened, it is much
safer to always end a chain like this with an “else:” to ensure that
you know that an outcome is always computed.

Also, your function uses a style called “early return”, where in some
paths through the code you return from the function immediately instead
of running to the end.

In small functions that is often a clean and readable way to do it.

In larger functions that can lead to mistakes because some return is
buried inside some larger logic chain. It of often desireable to not
return early for that reason, and instead just compute the answer and
always return at the end. For your function that would look like this:

if h <= 40:
    pay = h*r
else:
    pay = (40 * r)+(h-40)*(1.5*r)
return pay

This has the advantage that there’s eactly one return right at the
bottom where it is easy to find and examine. In larger programmes that
is often desireable, and is often a better way to frame things.

You can also drop all the brackets here:

pay = (40 * r)+(h-40)*(1.5*r)

if you think that is more readable - the default arithmetic precendence
will keep the same meaning. You only need brackts when you need to
control the grouping in a nondefault way, for example:

(3 + 2) * 7

to bind the 3+2 addition, which would otherwise bind the 2*7 as:

3 + 2 * 7

as:

3 + (2 * 7)

hrs = input(“Enter Hours:”)
h = float(hrs)
rate = input(“Enter Rate:”)
r = float(rate)
p = computepay(h,r)
print(“Pay”,p)

This bit all looks just fine to me.

Cheers,
Cameron Simpson cs@cskk.id.au

Thanks, Cameron! Truly Appreciated!