patternpythonModerate
Calculate shipping cost
Viewed 0 times
costcalculateshipping
Problem
Could I code differently to slim down the point of this Python source code? The point of the program is to get the user's total amount and add it to the shipping cost. The shipping cost is determined by both country (Canada or USA) and price of product: The shipping of a product that is $125.00 in Canada is $12.00.
input ('Please press "Enter" to begin')
while True: print('This will calculate shipping cost and your grand total.')
totalAmount = int(float(input('Enter your total amount: ').replace(',', '').replace(', '')))
Country = str(input('Type "Canada" for Canada and "USA" for USA: '))
usa = "USA"
canada = "Canada"
lessFifty = totalAmount = 50.01 and totalAmount = 100.01 and totalAmount <= 150
twoHundred = totalAmount
if Country == "USA":
if lessFifty:
print('Your shipping is: $6.00')
print('Your grand total is: ,totalAmount + 6)
elif fiftyHundred:
print('Your shipping is: $8.00')
print('Your grand total is: ,totalAmount + 8)
elif hundredFifty:
print('Your shipping is: $10.00')
print('Your grand total is: ,totalAmount + 10)
elif twoHundred:
print('Your shipping is free!')
print('Your grand total is: ,totalAmount)
if Country == "Canada":
if lessFifty:
print('Your shipping is: $8.00')
print('Your grand total is: ,totalAmount + 8)
elif fiftyHundred:
print('Your shipping is: $10.00')
print('Your grand total is: ,totalAmount + 10)
elif hundredFifty:
print('Your shipping is: $12.00')
print('Your grand total is: ,totalAmount + 12)
elif twoHundred:
print('Your shipping is free!')
print('Your grand total is: ,totalAmount)
endProgram = input ('Do you want to restart the program?')
if endProgram in ('no', 'No', 'NO', 'false', 'False', 'FALSE'):
breakSolution
I would not hard-code the fee logic, but instead store it as pure data. It's easier to maintain, even allowing to load it from a file.
Then, it boils down to a range-based lookup, which is quite classical (cf
In Python, we can perform such a search via
Separated core logic would look like :
Update
Here is a sample of "working application" using the helper function, assuming you have saved the code snippet above as
NB : I have dropped the exit part, since I don't like to type
Then, it boils down to a range-based lookup, which is quite classical (cf
HLOOKUP in spreadsheet software, with so called "approximate search").In Python, we can perform such a search via
bisect, relying on lexicographic order (and infinity as an unreachable upper bound).Separated core logic would look like :
from bisect import bisect
#For each country, list of (x,y) = (cost_threshold, fee)
#For first x such cost <= x, pick y for fee.
inf = float("inf")
shippingFees = { 'USA' : [ (50, 6), (100, 8), (150, 10), (inf, 0) ],
'CANADA' : [ (50, 8), (100, 10), (150, 12), (inf, 0) ]
}
#Make sure it is sorted (required for lookup via bisect)
#FIXME : Actually it would be better to assert it is already sorted,
# since an unsorted input might reveal a typo.
for fee in shippingFees.values() : fee.sort()
def getShippingFee(amount, country):
fees = shippingFees[country.upper()] #raise KeyError if not found.
idx = bisect(fees, (amount,) )
return fees[idx][1]Update
Here is a sample of "working application" using the helper function, assuming you have saved the code snippet above as
prices.py (which should be stored in a module, but that's another story).NB : I have dropped the exit part, since I don't like to type
no when I can hit CTRL+C.#!/usr/bin/python2
""" Your description here """
from prices import getShippingFee
print('This will calculate shipping cost and your grand total.')
while True:
#TODO : proper input processing, python3 compatible.
totalAmount = float(raw_input('Enter your total amount: ').replace(',', '').replace(', ''))
country = raw_input('Type "Canada" for Canada and "USA" for USA: ').strip().upper()
try : #TODO : proper country check.
shippingFee = getShippingFee(totalAmount, country)
grandTotal = totalAmount + shippingFee
if shippingFee :
print('Your shipping cost is: %.2f' % shippingFee)
else :
print('Your shipping is free!')
print('Your grand total is: %.2f' % grandTotal)
except KeyError :
print ("Sorry, we don't ship to this hostile country : %s" % country)Code Snippets
from bisect import bisect
#For each country, list of (x,y) = (cost_threshold, fee)
#For first x such cost <= x, pick y for fee.
inf = float("inf")
shippingFees = { 'USA' : [ (50, 6), (100, 8), (150, 10), (inf, 0) ],
'CANADA' : [ (50, 8), (100, 10), (150, 12), (inf, 0) ]
}
#Make sure it is sorted (required for lookup via bisect)
#FIXME : Actually it would be better to assert it is already sorted,
# since an unsorted input might reveal a typo.
for fee in shippingFees.values() : fee.sort()
def getShippingFee(amount, country):
fees = shippingFees[country.upper()] #raise KeyError if not found.
idx = bisect(fees, (amount,) )
return fees[idx][1]#!/usr/bin/python2
""" Your description here """
from prices import getShippingFee
print('This will calculate shipping cost and your grand total.')
while True:
#TODO : proper input processing, python3 compatible.
totalAmount = float(raw_input('Enter your total amount: ').replace(',', '').replace('$', ''))
country = raw_input('Type "Canada" for Canada and "USA" for USA: ').strip().upper()
try : #TODO : proper country check.
shippingFee = getShippingFee(totalAmount, country)
grandTotal = totalAmount + shippingFee
if shippingFee :
print('Your shipping cost is: %.2f' % shippingFee)
else :
print('Your shipping is free!')
print('Your grand total is: %.2f' % grandTotal)
except KeyError :
print ("Sorry, we don't ship to this hostile country : %s" % country)Context
StackExchange Code Review Q#21113, answer score: 10
Revisions (0)
No revisions yet.