Help with a program (im bad at python)

I’m currently learning (or trying to learn) Python. I gave myself a task to make a few simple programs and usually, my syntax errors are just missing brackets or miss-spelled variables. This one I can’t figure out for the life of me. It’s a simple “enter this amount and here’s your discount” type of vibe. If anyone could look over it and let me know what’s happening, it would be very appreciated. I believe it may just be a formatting error but knowing me I misplaced a character.

#Input
packages_purchasing = float(input('Enter the amount of packages you would like to purchase: ')
#Processing
if packages_purchasing < 0:
display = “Woah, looks like you are trying to sell us packages here! Please enter a positive integer.”

if packages_purchasing < 10:
display = “Looks like you aren’t buying enough to recieve a discount.”

if packages_purchasing >=10 and packages_purchasing <= 19:
discount = .10
elif packages_purchasing >=20 and packages_purchasing <= 49:
discount = .20
elif packages_purchasing >=50 and packages_purchasing <= 99:
discount = .30
elif packages_purchasing >=100:
discount = .40

package_price = 99
before_discount = package_price * packages_purchasing
discount_amount = before_discount * discount
after_discount = before_discount - discount_amount

display = “Cost of packages before discount: $” + format(before_discount, ‘,.2f’) +
"\nAmount of discount: " + format(discount_amount, ‘,.2f’) +
“\nTotal price with discount: $” + format(after_discount, ‘,.2f’)
#Output
print(display)

It would help a lot to know what errors you’re getting. Either syntax
errors, some exception during execution or simply incorrect answers. A
transcript of what happens and a description of what you wanted to
happen would help.

Lacking these, I’ll make some remarks inline below as they catch my eye:

#Input
packages_purchasing = float(input('Enter the amount of packages you would like to purchase: ')
#Processing
if packages_purchasing < 0:
    display = "Woah, looks like you are trying to sell us packages here! Please enter a positive integer."

if packages_purchasing < 10:
    display = "Looks like you aren't buying enough to recieve a discount."

I would be shaping these choices to preclude the rest of the code, eg:

if packages_purchasing < 0:
    display = "Woah, looks like you are trying to sell us packages here! Please enter a positive integer."
elif if packages_purchasing < 10:
    display = "Looks like you aren't buying enough to recieve a discount."
    discount = 0
else:
    ... the if/elif discount list below here, indented ...

Also note that I set the discount to 0 for the <10 case. That way you
could still perform the discount calculation and get a correct answer.

if packages_purchasing >=10 and packages_purchasing <= 19:

Python lets you group comparisons like this:

if 10 <= packages_purchasing <= 19:

which expresses a range more clearly. Also, I see that
packages_purchasing is a float. What if they enter 19.5 ?

Usually we write tests like this as:

if 10 <= packages_purchasing < 20:

i.e. incluside at one end (usually the lower end) and exclusive at the
upper. Combinained with the test for the next range:

if 20 <= packages_purchasing < 50:

you can see that there is no “gap” between 19 and 20. It also has the
advantage that you’re using the same values for the range bounds (20
in both cases, not 19 in one and 20 in the other). This is less hazard
prone.

    discount = .10
elif packages_purchasing >=20 and packages_purchasing <= 49:
    discount = .20
elif packages_purchasing >=50 and packages_purchasing <= 99:
    discount = .30
elif packages_purchasing >=100:

This last condition is redundant.Just use “else:”. In general, an
if/elif/elif/elif chain should usually end in an “else” to catch
everything which was not covered by an earlier condition.

In your code above, a packages_purchasing of 19.5 would have fallen
through all the conditions and been unhandled. An else will catch
that, even if your else looks like this:

else:
    raise RuntimeError("unhandled packages_purchasing value: %s" % packages_purchasing)

which I actually do a lot, because it will catch logic errors. We all
make them.

package_price = 99

Usually we put ‘constants’ like this at the top of the code where they
are easier to see.

before_discount = package_price * packages_purchasing
discount_amount = before_discount * discount
after_discount = before_discount - discount_amount

display = "Cost of packages before discount: $" + format(before_discount, ',.2f') + \
          "\nAmount of discount: " + format(discount_amount, ',.2f') + \
          "\nTotal price with discount: $" + format(after_discount, ',.2f')

Rather than using backslashes at the ends of lines you can also write
this using brackets:

display = (
    "Cost of packages before discount: $" + format(before_discount, ',.2f')
    + "\nAmount of discount: " + format(discount_amount, ',.2f')
    + "\nTotal price with discount: $" + format(after_discount, ',.2f')
)

Modern Python also lets you use a “format string” for this:

display = (
    f"Cost of packages before discount: ${before_discount:.2f}"
    + f"\nAmount of discount: {discount_amount:,.2f}"
    + f"\nTotal price with discount: ${after_discount:.2f"
)

I would include the newlines in each “line”:

display = (
    f"Cost of packages before discount: ${before_discount:.2f}\n"
    + f"Amount of discount: {discount_amount:,.2f}\n"
    + f"Total price with discount: ${after_discount:.2f"
)

And you can join strings together just by placing them next to each
other; the “+” is not required:

display = (
    f"Cost of packages before discount: ${before_discount:.2f}\n"
    f"Amount of discount: {discount_amount:,.2f}\n"
    f"Total price with discount: ${after_discount:.2f}"
)

Finally, in your current code you always set display to this long
string, even in the exceptional cases you start with
(packages_purchasing<0). Making this whole “apply the discount” branch
nested as suggested at the start will avoid that.

Cheers,
Cameron Simpson cs@cskk.id.au

Before I begin, it would be helpful if you put your code in a code snippet instead, so its easier to read and test the code out.

Moving on with your question:

  1. You’re right, you forgot an extra bracket at the end of line 2 (defining packages_purchasing). But don’t worry! Even I do make these mistakes occasionally, you just get better at spotting these mistakes
  2. You did not define “discount”. You can define variables inside an if statement, but what if packages_purchasing < 10? The code would skip the entire if statement from line 10 onwards and move to line 19 onwards. So currently, discount is not defined yet. Further down your code, however, discount is being used as a variable. Python does not know what discount is because it is undefined, so it outputs an error. Remember, whenever you want to assign a value to a variable in an if statement, make sure to define the variable outside the if statement just in case.

Here’s my updated code that works:

discount = 0 # you did not define discount
#Input
packages_purchasing = float(input('Enter the amount of packages you would like to purchase: ')) #< you forgot a bracket here
#Processing
if packages_purchasing < 0:
	display = "Woah, looks like you are trying to sell us packages here! Please enter a positive integer. "

if packages_purchasing < 10:
	display = "Looks like you aren’t buying enough to recieve a discount."

if packages_purchasing >=10 and packages_purchasing <= 19:
	discount = .10
elif packages_purchasing >=20 and packages_purchasing <= 49:
	discount = .20
elif packages_purchasing >=50 and packages_purchasing <= 99:
	discount = .30
elif packages_purchasing >=100:
	discount = .40

package_price = 99
before_discount = package_price * packages_purchasing
discount_amount = before_discount * discount
after_discount = before_discount - discount_amount

display = "Cost of packages before discount: $" + format(before_discount, ',.2f') + "\nAmount of discount: " + format(discount_amount, ',.2f') + "\nTotal price with discount: $" + format(after_discount, ',.2f')
#Output
print(display)

I hope I wasn’t too late to answer, and also hope this was not confusing, feel free to ask me anything to clarify.

Thank you so much!! This was the only issue and it ran smoothly after fixing.

1 Like