0

I am trying to write a simple program that compares shipping costs. I have a default float value that is premium and two functions that check against it and gives the user the cheapest value based on the weight of their product.

My code is below:

premium_shipping = 125.00

def ground_shipping(weight):
  if weight <= 2.0 and weight >= 0:
    return float('{:.2f}'.format((weight * 1.50) + 20))
  elif weight > 2.0 and weight <= 6.0:
    return float('{:.2f}'.format((weight * 3.00) + 20))
  elif weight > 6.0 and weight <= 10.0:
    return float('{:.2f}'.format((weight * 4.00) + 20))
  elif weight > 10:
    return float('{:.2f}'.format((weight * 4.75) + 20))
  else:
    return "Your package doesn't weigh anything!"

def drone_shipping(weight):
  if weight <= 2.0 and weight >= 0:
    return float('{:.2f}'.format(weight * 4.50))
  elif weight > 2.0 and weight <= 6.0:
    return float('{:.2f}'.format(weight * 9.00))
  elif weight > 6.0 and weight <= 10.0:
    return float('{:.2f}'.format(weight * 12.00))
  elif weight > 10:
    return float('{:.2f}'.format(weight * 14.25))
  else:
    return "Your package doesn't weigh anything!"

def cheapest_shipping(weight):
  if ground_shipping(weight) < drone_shipping(weight) and ground_shipping(weight) < premium_shipping:
    return f'The cheapest shipping method is ground shipping. It would cost {ground_shipping(weight)} to ship your item.'
  elif drone_shipping(weight)  < ground_shipping(weight) and drone_shipping(weight) < premium_shipping:
    return f'The cheapest shipping method is drone shipping. It would cost {drone_shipping(weight)} to ship your item.'
  elif premium_shipping < ground_shipping(weight) and premium_shipping < drone_shipping(weight):
    return f'The cheapest shipping method is premium shipping. It would cost {premium_shipping} to ship your item.'
  else:
    return "Error. You have input an invalid weight."

print(ground_shipping(4.8))
# 34.4
print(cheapest_shipping(4.8))
# The cheapest shipping method is ground shipping. It would cost 34.4 to ship your item.
print(cheapest_shipping(41.5))

When I do this, I technically get my answer however I want it to be at 2 decimal places When I remove the float() from the two functions, the value I get back is to 2 decimal places but is a str. When I include the float() it returns my number as a float with 1 decimal place and I am unsure on how to change it to include 2 decimal points.

Thanks in advance!

drome845
  • 139
  • 1
  • 1
  • 8
  • 1
    Decimal places are a formatting concern. They make sense with `str`s; they don't make sense with `float`s. `1 == 1.0 == 1.00 == 1.0000000000`. (You might want to look into [the `decimal` module](https://docs.python.org/3/library/decimal.html?highlight=decimal#module-decimal), though.) – ChrisGPT was on strike Aug 18 '20 at 00:28
  • Does this answer your question? [Display a float with two decimal places in Python](https://stackoverflow.com/questions/6149006/display-a-float-with-two-decimal-places-in-python) – ChrisGPT was on strike Aug 18 '20 at 00:31
  • The `decimal` package can work well for monitary calculations because it stays decimal and you don't have to worry about loosing accuracy when converting to the binary float representation. – tdelaney Aug 18 '20 at 01:05

2 Answers2

1

There is no difference between the float values 2, 2.0, 2.00000000000000000, and 200e-2. If you want to present a float in a certain way, that's best done at formatting time, with any of (in order of preference):

>>> pi = 3.14159

>>> f"{pi:.2f}"           # f-strings, introduced in Python 3.6.
'3.14'

>>> "{:.2f}".format(pi)   # str.format, use f-strings in preference.
'3.14'

>>> "%.2f" % (pi)         # VERY old method, avoid if possible.
'3.14'

Provided you're using a recent enough version of Python, f-strings are the way to go. Unlike % and str.format(), they keep the data item localised to where it will be printed in the string so you don't have to go searching for it in the argument list. Contrast the following:

f"Hello, {name}, today is {dayOfWeek}"
"Hello, {}, today is {}".format(name, dayOfWeek)
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
0

You seem to have some confusion between what a float is and how it is displayed. A float is a binary number with 53 bits of decimal precision that can hold a wide variety of values. You can display a float however you want. For example:

 float('{:.2f}'.format(weight * 14.25))

Here you take a float value weight * 14.25, convert it to a string with two decimal places using the format method, and then back with the float function. This may or may not truncate the digits after the second decimal place, since most decimal fractions are not representable exactly in binary.

You display your values without the same consideration, however:

print(ground_shipping(4.8))

If you want to print this as a two-digit number, you should format it the same way as you did previously:

print(f'{ground_shipping(4.8):0.2f}')

OR

print('{:0.2f}'.format(ground_shipping(4.8)))
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • I updated the code to make the two functions floats and then formatted the premium_shipping variable in the elif comparison to have 2 decimal points. Your answer helped get me there so thank you! – drome845 Aug 18 '20 at 03:15