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.
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)
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))
I wrote a function aveMean(die, numRolls, numTrials) which requires the following:
Blockquote
die, a Die
numRolls, numTrials, are positive ints
Calculates the expected mean value of the longest run of a number over numTrials runs of numRolls rolls.
Calls makeHistogram to produce a histogram of the longest runs for all the trials. There should be 10 bins in the histogram
Choose appropriate labels for the x and y axes.
Returns the mean calculated
Blockquote
Everything works fine, except:
the list has just one item
the items in the list are equal
or the numRolls are limited to one roll
This is how it should look like
You see that in 1.-3. there is always a little extra bar (barely visible) on the left side. How can I get rid of it? I read something about this is due to Python 3, but I didn't find out a solution.
Thanks!
P.S. I edited the code how to call the histogram and also the function that uses the call to create the histogram:
def getMeanAndStd(X):
mean = sum(X)/float(len(X))
tot = 0.0
for x in X:
tot += (x - mean)**2
std = (tot/len(X))**0.5
return mean, std
class Die(object):
def __init__(self, valList):
""" valList is not empty """
self.possibleVals = valList[:]
def roll(self):
return random.choice(self.possibleVals)
def makeHistogram(values, numBins, xLabel, yLabel, title=None):
pylab.hist(values, numBins)
pylab.xlabel(xLabel)
pylab.ylabel(yLabel)
if(title != None): pylab.title(title)
pylab.show()
def aveMean(die, numRolls, numTrials):
tries = die
testList, res = [], []
for i in range(numTrials):
count, tempCount, testList = 1, 1, []
for i in range(numRolls):
testList.append(tries.roll())
for i in range(1, numRolls):
if testList[i-1] == testList[i]:
count +=1
else:
if count > tempCount:
tempCount = count
count = 1
else:
count = 1
res.append(tempCount)
mean, std = getMeanAndStd(res)
makeHistogram(res, 10, 'Quantity of Consecutive Numbers', 'Consecutive Number per Run')
return round(mean, 3)
The Error Message I get is: Unsuccessfully called makeHistogram
def getAverage(die, numRolls, numTrials):
"""
- die, a Die
- numRolls, numTrials, are positive ints
- Calculates the expected mean value of the longest run of a number
over numTrials runs of numRolls rolls
- Calls makeHistogram to produce a histogram of the longest runs for all
the trials. There should be 10 bins in the histogram
- Choose appropriate labels for the x and y axes.
- Returns the mean calculated
"""
tries = die
testList, res = [], []
for i in range(numTrials):
count, tempCount, testList = 1, 1, []
for i in range(numRolls):
testList.append(tries.roll())
for i in range(1, numRolls):
if testList[i-1] == testList[i]:
count +=1
else:
count = 1
if count > tempCount:
tempCount = count
if count > tempCount:
tempCount = count
res.append(tempCount)
mean, std = getMeanAndStd(res)
makeHistogram(res, 10, 'Quantity of Consecutive Numbers', 'Consecutive Number per Run')
return round(mean, 3)
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