0

I am trying to solve the following question:

Suppose the cover price of a book is $24.95, but bookstores get a 40% discount. Shipping costs $3 for the first copy and 75 cents for each additional copy. What is the total wholesale cost for 60 copies?

Old attempt with reference to Nic3500:

book = 24.95
discount_percentage = 0.4
shipping = 3.0
reduced_shipping = 0.75
quantity = 60

discount = book * discount_percentage
print(discount)
wholesale_price = book - discount
print(wholesale_price)
total_books = wholesale_price * quantity
print(total_books)
total_shipping = shipping + (reduced_shipping * quantity)
print(total_shipping)

cost = total_books + total_shipping

print('$', cost)

New attempt using decimal with reference to Michael Butscher:

from decimal import *

getcontext().prec = 2

book = Decimal(24.95)
discount_percentage = Decimal(0.4)
shipping = Decimal(3.0)
reduced_shipping = Decimal(0.75)
quantity = Decimal(60)

discount = book * discount_percentage
print(discount)
wholesale_price = book - Decimal(discount)
print(wholesale_price)
total_books = Decimal(wholesale_price) * quantity
print(total_books)
total_shipping = shipping + (reduced_shipping * (quantity - 1))
print(total_shipping)

cost = Decimal(total_books) + Decimal(total_shipping)

print('$', cost)

The problem however is the answer should be $945.45. Due to the issues with floating point numbers somewhere in the calculation I receive the wrong answer and use that. I have looked up using the decimal module but don't understand how I would apply it to my problem, any help is appreciated, thanks.

3
  • Basically replace numbers like 0.4 by Decimal('0.4') and keep the calculations as they are. Commented Aug 3, 2022 at 20:10
  • If I use the Decimal() function on all the operands and the getcontext().prec = 2 to use the 2 numbers after the decimal point I just receive 9.5E+2 which is the wrong answer? Commented Aug 3, 2022 at 20:23
  • If you tried using Decimal and ran into issues, you should show what you tried and ask that question! Commented Aug 3, 2022 at 20:39

2 Answers 2

1

The reason you should use decimals when dealing with money is that floating point numbers don't represent all decimal numbers correctly. See What Every Computer Scientist Should Know About Floating-Point Arithmetic

You only need to define your floating point numbers as Decimals. There is a difference between what you've saved in your variables, and what you display to the user. It is perfectly fine to store your data to much higher precision, and only display two digits.

When you do this, and fix the error in your equation that Nic pointed out, you get this

from decimal import Decimal

book = Decimal('24.95')
discount_percentage = Decimal('0.4')
shipping = Decimal('3.0')
reduced_shipping = Decimal('0.75')
quantity = 60

discount = book * discount_percentage
wholesale_price = book - discount
total_books = wholesale_price * quantity
total_shipping = shipping + (reduced_shipping * (quantity - 1))

cost = total_books + total_shipping

print(f'${cost:.2f}')

Which outputs $945.45

Notice I used an f-string to format the output to 2 decimal places. You can read more about the f-string syntax at https://realpython.com/python-f-strings/


The issue with setting decimal.getcontext().prec is that it limits the number of significant figures available for all decimal operations. 9.5e+2 is two significant digits

from decimal import Decimal, getcontext

getcontext().prec = 2
d1 = Decimal('1234.56')
d2 = d1 + 1
print(d2) # 1.2E+3

If you want to round the decimal to a fixed number of decimal places, use the quantize method:

TWO_DECIMALS = Decimal('0.01')
print(cost.quantize(TWO_DECIMALS)) # Prints 945.45
Sign up to request clarification or add additional context in comments.

Comments

0

Your calculation of the total_shipping is wrong. It says 1st copy at 3$, others at 0.75$. So you should have 3$ + (59 * 0.75$).

The other thing is you should round() your amounts, since we do not go below 2 digits precision for $.

Hence:

#!/usr/bin/python3

book = 24.95
discount_percentage = 0.4
shipping = 3.0
reduced_shipping = 0.75
quantity = 60

discount = round(book * discount_percentage,2)
print(discount)

wholesale_price = round(book - discount,2)
print(wholesale_price)

total_books = round(wholesale_price * quantity,2)
print(total_books)

total_shipping = round(shipping + (reduced_shipping * (quantity - 1)),2)
print(total_shipping)

cost = round(total_books + total_shipping,2)

print('$', cost)

Output:

9.98
14.97
898.2
47.25
$ 945.45

2 Comments

The question asks "how to apply Decimal", which this question doesn't address at all!
He looked into it and does not understand it, I proved it is not required. I am ok with my answer. And using decimal would not have fixed the logic error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.