Given a positive integer change, a set of coins makes change for change if the sum of the values of the coins is change. We will use standard US Coin values: 1, 5, 10, 25.
I was asked to solve this coin change question with recursion function only(while and for loop are not allowed), and I am very struggling with it. Please help!
def next_smaller_coin(coin):
"""Returns the next smaller coin in order."""
if coin = 25:
return 10
elif coin = 10:
return 5
elif coin = 5:
return 1
def count_coins(change):
if change == 0:
return 1
elif change < 0:
return 0
else:
with_coin = count_coins(change - next_smaller_coin(coins))
wo_coin = count_coins(change)
return with_coin + wo_coin
I am learning Python through Codecademy, and I have run into a weird result in the "Sal's shipping" project.
What I am trying make python do, is tell me what shipping method is the cheapest. Here is a code sample:
print(cost_ground_shipping(4.8))
print(cheapest_shipping(4.8))
This gives me:
34.4
Premium shipping is the cheapest at $125
The problem here is, that premium shipping obviously is not cheaper at 125 dollars, as ground shipping is 34.4 dollars.
I am sorry that the code is a mess. In the tutorial video the guy uses specific techniques, that have not been covered in the course, which annoyed me, so I ignored it, as I did not want to completely rewrite my code.
Any answers are appreciated :)
Here is the full code:
def cost_ground_shipping(weight):
if weight <= 2:
return weight * 1.5 + 20
elif 6 >= weight:
return weight * 3. + 20
elif 10 >= weight:
return weight * 4. + 20
else:
return weight * 4.75 + 20
cost_premium_shipping = 125
def cost_drone_shipping(weight):
if weight <= 2:
return weight * 4.5
if 6 >= weight > 2:
return weight * 9.
if 10 >= weight > 6:
return weight * 12.
if weight > 10:
return weight * 14.25 + 20
def cheapest_shipping(weight):
if str(cost_ground_shipping(weight)) < str(cost_premium_shipping) and str(cost_ground_shipping(weight)) < str(cost_drone_shipping(weight)):
return "Ground shipping is the cheapest at $" + str(cost_ground_shipping(weight))
if str(cost_premium_shipping) < str(cost_ground_shipping(weight)) and str(cost_premium_shipping) < str(cost_drone_shipping(weight)):
return "Premium shipping is the cheapest at $" + str(cost_premium_shipping)
if str(cost_drone_shipping(weight)) < str(cost_ground_shipping(weight)) and str(cost_drone_shipping(weight)) < str(cost_premium_shipping):
return "Drone shipping is the cheapest at $" + str(cost_drone_shipping(weight))
print(cost_ground_shipping(4.8))
print(cheapest_shipping(4.8))
Jonathan, welcome to Stack Overflow.
In Python, similar to most programming languages, strings are also comparable and ordered (i.e the inequality operators have meaning).
def cheapest_shipping(weight):
if str(cost_ground_shipping(weight)) < str(cost_premium_shipping)..
..
if str(cost_premium_shipping) < str(cost_ground_shipping(weight))
You are inadvertently performing string comparisons here, i.e you are comparing the STRING "34.4" with "125". The computer interprets strings as sequence of characters and compares the ASCII codes of the characters sequentially. Since "1" has an ASCII code of 49 and "3" has the ASCII code 51, "1" is lesser than "3", and consequently "125" < "34.4". This is why you get the "wrong" answer.
Omit the str conversion functions when you want to compare numbers. Keep the str functions when you want to PRINT numbers.
# user input
num = int(input("Please enter engine size: "))
# calculations
if num <= 1000:
print("The motor tax for your vehicle is €150")
elif num >= 1001 <= 1200:
print("The motor tax for your vehicle is €175")
elif num >= 1201 <= 1400:
print("The motor tax for your vehicle is €200")
elif num >= 1401 <= 1600:
print("The motor tax for your vehicle is €250")
elif num >= 1601 <= 1800:
print("The motor tax for your vehicle is €300")
elif num >= 1801 <= 2000:
print("The motor tax for your vehicle is €350")
else:
print("The motor tax for your vehicle is €500")
I know I've probably made a stupid mistake here, I'm just hoping someone could point me in the right direction.
I'm trying to get python to print the relevant amount for each of the specified engine size.
Each time I run it with any amount greater than 1000 it will only give me the output of €175.
Thanks so much in advance!
This isn't doing what you want or expect it to be doing:
elif num >= 1001 <= 1200:
You should replace it with something like:
elif num in range(1001, 1201):
NOTE: to check <=, you need to have upper bound of range incremented by 1!
Otherwise, you could write what you originally had as:
elif 1001 <= num <= 1200:
Welcome to Stack Overflow!
i have updated the answer to PL200 to provide an answer to your question. This is a suggestion to improve a bit your code:
# Motor tax is based on ranges
if num <= 1000:
tax = 150
elif num <= 1200:
tax = 175
elif num <= 1400:
tax = 200
elif num <= 1600:
tax = 250
elif num <= 1800:
tax = 300
elif num <= 2000:
tax = 350
else:
tax = 500
print("The motor tax for your vehicle is €{}".format(tax))
You actually don't need 2 inequations because of the if / elif chain.
Or you could do even better to avoid a long if/elif:
def get_tax(num):
"""Return the vehicle tax based on ranges"""
# Ranges are stored as "maximum size" / "tax"
tax_ranges = (
(1000, 150),
(1200, 175),
(1400, 200),
(1600, 250),
(1800, 300),
(2000, 350),
)
default_tax = 500
for max_size, tax in tax_ranges:
if num <= max_size:
return tax
return default_tax
num = int(input("Please enter engine size: "))
print(f"The motor tax for your vehicle is {get_tax(num)}")
NOTE: I added a f-string at the end to print but it might not supported by your version of Python if you have a version earlier than 3.6. In that case, just replace {get_tax(num)} by "... {}".format(get_tax(num)) and remove the f before the string
The problem is from the MIT edX Python Course 6.00.1 Problem Set 1 Part C. Here are the problems. Scroll to part C. I'm aware that there are countless questions asked about the edX course but none of them have really helped me. Whenever I run my bisection search code, nothing happens. No error message, nothing. Could someone help me find the issue in my code? Sorry if code is horribly inefficient, very new to python and programming.
#Python script for finding optimal saving rate of monthly salary in order to purchase 1M house in 36 months
salary = float(input("Enter salary: "))
total_cost = 1000000
salary_raise = 0.07 #semiannual raise rate
down = 0.25 * total_cost #downpayment
steps = 0
r = 0.04 #annual investments returns
low = 0 #low parameter for bisection search
high = 10000 #high parameter
current_savings = 0
while (current_savings <= (down - 100)) or (current_savings >= (down + 100)):
current_savings = 0
monthly_salary = salary/12
guess_raw = (high + low)/2
guess = guess_raw/10000.0
months = 0
steps += 1
while months < 36: #Finds end amount of money after 36 months based on guess
months += 1
multiple = months%6
monthly_savings = monthly_salary * guess
current_savings = current_savings + monthly_savings + current_savings*r/12
if multiple == 0:
monthly_salary += salary_raise * monthly_salary
if (current_savings >= (down - 100)) and (current_savings <= (down + 100)): #If the guess is close enough, print the rate and number of steps taken
print ("Best savings rate: ",guess)
print ("Steps in bisection search: ",steps)
break
elif current_savings < (down - 100): #If the guess is low, set the low bound to the guess
if guess == 9999:
print ("It is not possible to pay the down payment in three years.")
break
else:
low = guess
elif current_savings > (down + 100): #If the guess is high, set the high bound to the guess
high = guess
I want to interate 1000 times over the following function to find out if you win or loose money in this game.
The game is designed as such that you throw a pair of dice and get money back or loose money. Let's say we start with 5 coins.
Throwing a 12 yields 1.5 coins.
Throwing an 11 yields 1 coins.
Throwing a 10 yields 0.5 coins.
Throwing a 9,8 or 7 yields nothing.
Throwing a 6,5,4,3,2 or 1 deducts 0.5 coins from your amount of coins.
This is what my implementation looks like so far:
def luckCalc():
amount = 5
# if 12 then 1/36 chance
if random.randrange(1,7) == 6 and random.randrange(1,7) == 6:
amount = amount + 1.5
# if 11 then 2/36 chance
elif (random.randrange(1,7) == 5 and random.randrange(1,7) == 6) or (random.randrange(1,7) == 6 and random.randrange(1,7) == 5):
amount = amount + 1
# if 10 then 3/36 chance
elif (random.randrange(1,7) == 5 and random.randrange(1,7) == 5) or (random.randrange(1,7) == 4 and random.randrange(1,7) == 6) or (random.randrange(1,7) == 6 and random.randrange(1,7) == 4):
amount = amount + 0.5
# if 9,8,7
# 4/36 + 5/36 + 6/36 chance
# 1+6, 2+5, 3+4, 4+3, 5+2, 6+1 chance
# 2+6, 3+5, 4+4, 5+3, 6+2 chance
# 3+6, 4+5, 5+4, 6+3 chance
# then no change in amount
# if 6,5,4,3,2,1
# chances...
# then amount -0.5
return amount
# Iterate over the dice throwing simulator and calculate total
total = 0.0
for a in range(1000):
total = total + luckCalc()
print (total)
I stopped coding towards the end of the function, because I recognised that there must be a more elegant solution on how to achieve this. Any interesting suggestions, what is this Monte Carlo I keep hearing about?
Each time you call random.randrange(1,7), you generate a new random number. Since you're testing a single "turn", roll twice:
def roll_die():
return random.randrange(1, 7)
total = roll_die() + roll_die()
And see if the sum is in a range:
def play_turn():
total = roll_die() + roll_die()
if total == 12:
return 1.5
elif total == 11:
return 1.0
elif total == 10:
return 0.5
elif total <= 6:
return -0.5
else: # total is 7, 8, or 9
return 0
Here's the result of 100,000 rounds:
>>> from collections import Counter
>>> counts = Counter(play_turn() for i in xrange(100000))
>>> counts
Counter({-0.5: 41823, 0: 41545, 0.5: 8361, 1.0: 5521, 1.5: 2750})
>>> probabilities = {score: count / 100000.0 for score, count in counts.items()}
>>> probabilities
{-0.5: 0.41823, 0: 0.41545, 0.5: 0.08361, 1.0: 0.05521, 1.5: 0.0275}
You can actually roll (ha!) everything you are doing into a single function:
from random import randrange
def play_game(rolls=1000, amount=5, n=6):
"""Play game 'rolls' times, starting with 'amount' on 'n'-sided dice."""
for i in range(rolls):
roll = randrange(1, n+1) + randrange(1, n+1)
if roll == 12:
amount += 1.5
elif roll == 11:
amount += 1
elif roll == 10:
amount += 0.5
elif roll < 7:
amount -= 0.5
return amount
I notice a few things in your code. First, for the 6-1 cases you're not actually subtracting 0.5 from the amount. Second, since you don't pass in the initial amount each loop you're adding between 5 and 6.5 to your total, which makes the total pretty pointless.
A more effective total would be to pass in the amount each time:
def luckCalc( amount ):
And then for your loop:
total = 5.0
for a in range(1000):
total = luckCalc(total)
Blender's answer, which just posted as I was writing this, is a great way to simplify your main function.
I personally like setting up my results table as an array (or a dictionary, but this suited my purpose better since every result was one of a small number of possible integers), with the index of each dice roll set to the value of the resulting change. See below.
import random
def luckCalc(coins=5):
diceroll = random.randint(1,6)+random.randint(1,6) #roll them bones
#here's that table I was talking about....
results_table = ['index 0 is blank',"you can't roll a one on two dice",-.5,-.5,-.5,-.5,-.5,0,0,0,.5,1,1.5]
coins += results_table[diceroll] #changes your coins value based on your roll (as an index of results_table)
if results_table[diceroll] > 0: #change the string if your result was + or -
result = "gained {}".format(results_table[diceroll])
else:
result = "lost {}".format(results_table[diceroll]*-1)
print("You {} coins, putting you at {}".format(result,coins)) #report back to the user
return coins #this is how you save your output
#CONSTANTS GO HERE -- YOU CAN CHANGE THESE TO CHANGE YOUR PROGRAM
STARTING_COINS = 5
HOW_MANY_ITERATIONS = 1000
#this way we don't modify a constant
coins = STARTING_COINS
#do it how many times?
for _ in range(HOW_MANY_ITERATIONS): #oh yeah that many times
coins = luckCalc(coins) #runs the function and saves the result back to coins
#report to the user your final result.
print("After {} rolls, your final total is {}".format(HOW_MANY_ITERATIONS,coins))