From the last couple of hours, I have been trying to debug this code.
Problem: Given a set of coins: 1, 5, 10, 21 and 25 write an algorithm that finds change for a given amount using the minimum possible number of coins.
Ex: if the amount is 63, it should return 3 [21, 21, 21]
My Code:
def change_rec_memo(change_list, amount, memo):
if amount in change_list:
memo[amount] = (1, [amount])
return 1, [amount]
if amount in memo:
return memo[amount]
mini, values, min_coin = None, [], None
for coin in change_list:
if amount - coin > 0:
count, sub_values = change_rec_memo(change_list, amount-coin, memo)
if mini is None:
mini = count
values = sub_values
min_coin = coin
if count < mini:
mini = count
values = sub_values
min_coin = coin
values.append(min_coin)
memo[amount] = (mini+1, values)
return mini+1, values
def main():
print change_rec_memo([1, 5, 10, 21, 25], 52, {})
The code seems to work fine for most of the cases, but fails for cases like 52, 63. It outputs the correct number of coins but the coin_listing contains extra coins.
Here is a Python Fiddle for it: https://pyfiddle.io/fiddle/08b3da45-0c0d-464a-b025-00d215bc4634/?i=true
there is one more readable and shorter example.and use stack variable(the parameter of recursive function)
import sys
#functools.lru_cache()
def change_rec_memo(change_list, amount, count):
if amount == 0:
return count
if len(change_list) == 0 or amount < 0:return sys.maxsize
if amount - change_list[-1] >= 0:
return min(change_rec_memo(change_list,amount - change_list[-1], count +1),change_rec_memo(change_list[:-1], amount, count))
else:
return change_rec_memo(change_list[:-1], amount, count)
print(change_rec_memo((1, 5, 10, 21, 25), 215,0))
Related
I am trying to build a function that after people entering the amount of money, it will show the minimum number of coins or notes that they need. But this there any methods for me to change it so that it will not print the name and the number of the unused coin? (as a beginner) Thanks for helping! (Will it be possible to deal with it by using for loop?)
Instead of keeping a variable for every demonmation, keep a dict and update key: val based on the denominations used. See the code
amount=int(input('Enter an amount: '))
denominations = dict()
print('Total number of notes/coins=')
if amount>=1000:
denominations['1000'] = amount//1000
amount%=1000
if amount>=500:
denominations['500'] = amount//500
amount= amount%500
if amount>=100:
denominations['100'] = amount//100
amount= amount%100
if amount>=50:
denominations['50'] = amount//50
amount= amount%50
if amount>=20:
denominations['20'] = amount//20
amount= amount%20
if amount>=10:
denominations['10'] = amount//10
amount= amount%10
if amount>=5:
denominations['5'] = amount//5
amount= amount%5
if amount>=2:
denominations['2'] = amount//2
amount= amount%2
if amount>=1:
denominations['1'] = amount//1
for key, val in denominations.items():
print(f"{key}: {val}")
Enter an amount: 523
Total number of notes/coins=
500: 1
20: 1
2: 1
1: 1
You can reduce the number of lines of code if you use a simple logic like shown below,
def find_denominations():
amount=int(input('Enter an amount: '))
denominations = dict()
DENOMINATIONS = [1000, 500, 100, 50, 20, 10, 5, 2, 1]
print('Total number of notes/coins=')
for d in DENOMINATIONS:
if amount >= d:
denominations[d] = amount // d
amount %= d
for key, val in denominations.items():
print(f"{key}: {val}")
A similiar implementation to Sreerams using a while loop instead a for loop:
amount = int(input("Enter an amount: "))
counter = amount
pos = 0
notes = [1000, 500, 100, 50, 20, 10, 5, 2, 1]
output = []
while counter > 0:
remainder = counter % notes[pos]
sub = counter - remainder
num = int(sub / notes[pos])
counter -= sub
output.append({notes[pos]: num})
pos += 1
print("Total number of notes/coins=")
for r in output:
for k,v in r.items():
if v > 0:
print("{}: {}".format(k, v))
Please note Sreerams code is superior to mine, it's easier to read and would be more performant at scale.
Loop can be used iterate through a list of notes and inside the loop, if any note is found to be counted, that can be printed.
notes=[1000,500,100,50,20,10,5,2,1]
amount=int(input('Enter an amount: '))
print('Total number of notes/coins=')
for notesAmount in notes:
if amount>=notesAmount:
notesCount=amount//notesAmount
amount%=notesAmount
if notesCount>0:
print(notesAmount, ":", notesCount)
im very new to python and cant figure out a basic matching game using lottery numbers.
i have 6 numbers. the first 5 numbers are between 1-49 and the last number is 1-7.
i cant seem to loop through where after it checks it, it generates another random number.
edited:
how do i remove duplicates from range(0,4)?
import random
def lottery(ticket):
count = 0
run = True
while count < 200:
lottoNum = sorted([random.randint(1,49) for x in range(5)])
lottoNum.append(random.randint(1,7))
if lottoNum != ticket:
count += 1
print(lottoNum)
else:
run = False
print(lottoNum, count)
lottery([11, 12, 36, 39, 46, 1])
You should move the lottoNum definition inside the while loop in order to update it every loop, like this:
import random
def lottery(ticket):
count = 0
while count < 1000:
lottoNum = [random.randint(1, 49) for x in range(6)]
lottoNum[-1] = random.randint(1, 7)
if lottoNum != ticket:
count += 1
print(lottoNum)
print(lottery([11, 12, 36, 39, 46, 1]))
With this correction, you allow 1000 attempts to the lottery function to guess the correct input, stored in ticket.
Moreover, you lottery function does not have a return statement (it returns nothing), so, in Python, such a function returns a value None. This is the reason why there is no point in printing the 'result' of the function in the line print(lottery([11, 12, 36, 39, 46, 1])): this print statement will print always None because your function lottery does not returns anything.
import random
def lottery(ticket):
"""
Compare lottery ticket against lottery draws and print how many draws have taken place
to match the ticket.
"""
count = 0
run = True
while run:
lotto_num = [random.randint(1, 49) for _ in range(6)]
lotto_num[-1] = random.randint(1, 7)
if lotto_num != ticket:
print(f"No match! Your ticket {ticket}, Lottery ticket {lotto_num}")
count += 1
else:
print(f"Match! Your ticket {ticket} lottery ticket {lotto_num}")
print(f"{count} draws")
run = False
lottery([11, 12, 36, 39, 46, 1])
It works fine when make my own input number. However, as I ignore main() to check the first function and find out the result print twice when n_item = 15.
def fun_function(n_items, cost_per_item=27, discount_percent=10, discount_threshold=20):
"""Return the total cost"""
cost = n_items * cost_per_item # line 1
if n_items > discount_threshold: # line 2
cost = cost * (1 - discount_percent / 100) # line 3
print('{} items cost ${:.2f}'.format(n_items, cost))
return cost
def main():
"""Compute and print the total cost of a number of items"""
n_items = int(input("Number of items? "))
fun_function(n_items, cost_per_item=27, discount_percent=10, discount_threshold=20)
# main()
cost = fun_function(5, 31, 15, 10)
print('5 items cost ${:.2f}'.format(cost))
cost = fun_function(15, 31, 15, 10)
print('15 items cost ${:.2f}'.format(cost))
>>>
5 items cost $155.00
15 items cost $395.25
15 items cost $395.25
You could put the print on the function where you always get a print
def fun_function(n_items, cost_per_item=27, discount_percent=10, discount_threshold=20):
"""Return the total cost"""
cost = n_items * cost_per_item # line 1
if n_items > discount_threshold: # line 2
cost = cost * (1 - discount_percent / 100) # line 3
return cost
def main():
"""Compute and print the total cost of a number of items"""
n_items = int(input("Number of items? "))
disc_threshold=10
cost = fun_function(n_items, cost_per_item=27, discount_percent=10, discount_threshold=disc_threshold)
if n_items > disc_threshold:
print('{} items cost ${:.2f}'.format(n_items, cost))
This way if you call:
cost = fun_function(5, 31, 15, 10)
cost = fun_function(15, 31, 15, 10)
>>>
5 items cost $155.00
15 items cost $395.25
You have to make a difference between the behaviour of your function and what you do out of it, like that print, which is not part of the function so it shouldnt be considered as "not expected behaviour".
---EDIT----
If you use the current implementetion written above and run main() and introduce 15, you'll get desired output.
I have the following code, but when i run it I get type 'NoneType'. I pinpointed to my "summation" variable being the one that has Nonetype, why is that? and how can i change it? I tried making into a float() but it did not work for me. Any insights would be welcome.
grades = [100, 100, 90, 40, 80, 100, 85, 70, 90, 65, 90, 85, 50.5]
def grades_sum(scores):
total = 0
for item in scores:
total = item + total
print total
grades_sum(grades)
def grade_average(grades):
summation = grades_sum(grades)
average = summation / float(len(grades))
return average
print grade_average(grades)
Change the print to a return.
def grades_sum(scores):
total = 0
for item in scores:
total = item + total
return total
Well summation just calls the function, nothing else, so it is equal to a NoneType or basically nothing. Change print total to return total to allow summation to be equal to whatever total is.
def grades_sum(scores):
total = 0
for item in scores:
total = item + total
return total
When you define grades_sum(), you don't return anything, you just print it. Change it to this:
def grades_sum(scores):
total = 0
for item in scores:
total = item + total
print total
return total
I have a function defined below that prints each integer in the list, and it works perfectly. What I would like to do is create a second function that would call on or reutilize the int_list() function to display a sum of the list that's been generated.
I am not sure if that has been inherently performed by the code itself - I am rather new to the Python syntax.
integer_list = [5, 10, 15, 20, 25, 30, 35, 40, 45]
def int_list(self):
for n in integer_list
index = 0
index += n
print index
In your code, you're setting index=0 in every loop, so it should be initialized before the for loop:
def int_list(grades): #list is passed to the function
summ = 0
for n in grades:
summ += n
print summ
output:
int_list([5, 10, 15, 20, 25, 30, 35, 40, 45])
5
15
30
50
75
105
140
180
225
To get the sum of a list of integers you have a few choices. Obviously the easiest way is sum, but I guess you want to learn how to do it yourself. Another way is to store the sum as you add it up:
def sumlist(alist):
"""Get the sum of a list of numbers."""
total = 0 # start with zero
for val in alist: # iterate over each value in the list
# (ignore the indices – you don't need 'em)
total += val # add val to the running total
return total # when you've exhausted the list, return the grand total
A third option is reduce, which is a function that itself takes a function and applies it to the running total and each consecutive argument.
def add(x,y):
"""Return the sum of x and y. (Actually this does the same thing as int.__add__)"""
print '--> %d + %d =>' % (x,y) # Illustrate what reduce is actually doing.
return x + y
total = reduce(add, [0,2,4,6,8,10,12])
--> 0 + 2 =>
--> 2 + 4 =>
--> 6 + 6 =>
--> 12 + 8 =>
--> 20 + 10 =>
--> 30 + 12 =>
print total
42
integer_list = [5, 10, 15, 20, 25, 30, 35, 40, 45] #this is your list
x=0 #in python count start with 0
for y in integer_list: #use for loop to get count
x+=y #start to count 5 to 45
print (x) #sum of the list
print ((x)/(len(integer_list))) #average
list = [5, 10, 15, 20, 25, 30, 35, 40, 45]
#counter
count = 0
total = 0
for number in list:
count += 1
total += number
#don'n need indent
print(total)
print(count)
# average
average = total / count
print(average)
You can used reduce function from functools module
from functools import module
s=reduce(lambda x,y:x+y, integer_list)
output
225