How to change this code to not printing unused coin=0? - python

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)

Related

Check if variable changes in for loop in Python

I have this code here and I'm looking for a way to check if min_score and max_score changes, and count how many times it changes. I can't seem to find a way to do it:
games = int(input())
score = list(input().split())
score = [int(x) for x in score]
for y in range(1, len(score) + 1):
min_score = (str(min(score[:y])) + " MIN")
max_score = (str(max(score[:y])) + " MAX")
print(min_score)
print(max_score)
This is a sample test case for reference:
9
10 5 20 20 4 5 2 25 1
First number is the size of the array, which in my code I never use because I make an array just from the string of numbers below ( in fact I don't even know why they give the size).
Basically I need to find how many times the max and min values change. I'm still a beginner in programming and I don't really know what to do..
you could just keep track of the lowest and highest number encountered and check if the current score is just below or above. A simple script could look like this:
scores = [10,5,20,20,4,5,2,25,1]
countChanges = 0
limitLow = float("inf")
limitHigh = -float("inf")
for s in scores:
if(s < limitLow):
countChanges += 1
limitLow = s
if(s > limitHigh):
countChanges += 1
limitHigh = s
print("current score: %3d limits: [%2d .. %2d] changes:%d" % (s, limitLow, limitHigh, countChanges))
spam = [10, 5, 20, 20, 4, 5, 2, 25, 1]
print(sum(n < min(spam[:idx]) for idx, n in enumerate(spam[1:], start=1)))
print(sum(n > max(spam[:idx]) for idx, n in enumerate(spam[1:], start=1)))
output
4
2
if you also want to account for initial value - add 1.
Looks like a hankerrank problem? They often give the length of the input to allow solutions without knowing about built-in methods like len().
Anyway,
You can initialise min and max to the first element of the array (if it exists, check the specification), or some suitably small and large values (again, check the possible values).
Then you can count the number of times min and max changes as you go.
Should be easy enough to adapt for the case that you just want to track any change, not min and max separately. It wasn't clear from your question.
scores = [10, 5, 20, 20, 4, 5, 2, 25, 1]
min_score = scores[0]
max_score = scores[0]
min_score_changes = 0
max_score_changes = 0
for score in scores:
if score < min_score:
min_score = score
min_score_changes += 1
if score > max_score:
max_score = score
max_score_changes += 1
I solved it like this after some thinking:
games = int(input())
score = list(input().split())
score = [int(x) for x in score]
min_score_list, max_score_list = [] , []
for y in range(1, len(score) + 1):
min_score = (min(score[:y]))
max_score = (max(score[:y]))
if min_score not in min_score_list:
min_score_list.append(min_score)
if max_score not in max_score_list:
max_score_list.append(max_score)
print((len(max_score_list) - 1), len(min_score_list) - 1)
I know it's not perfect code but at least I did myself :D

Is there a way to sort a dictionary by keys if the keys are numbers in python?

I was trying to make a code to help me a bit with statistics homework.
The code does work, but the output is very unreadable since it's not sorted by numbers. Is there any way to sort the numbers in here?
This is the code I have:
from time import sleep
numbers = {}
newList = []
total = 0
tempint = 0
keynum = 0
print("In this program you can input all the numbers given in a list, and you will get a result of how many numbers there are of any unique numbers, frequency, relavitve frequency and how many in total.")
sleep(2)
while True:
inp = input("Enter a number in the list (press enter to stop the program)")
if inp == '': break
if not f'{inp}' in numbers:
numbers[f'{inp}'] = [1]
else: numbers[f'{inp}'].append(1)
for key,value in numbers.items():
total += len(value)
for key,value in sorted(numbers.items()):
freq = len(value)
print(f'{key} - frequency: {freq}, relative frequency: {freq/total*100}%')
print(f'Total amount: {total}')
for key,value in numbers.items():
tempint += int(key)
keynum += 1
print(f'Unique numbers: {keynum}')
print(f'Average: {tempint/keynum}')
I want the output when I run the program look something like this:
1 - frequency: 2, relative frequency: 28.57142857142857%
2 - frequency: 1, relative frequency: 14.285714285714285%
3 - frequency: 3, relative frequency: 42.857142857142854%
4 - frequency: 1, relative frequency: 14.285714285714285%
Total amount: 7
Unique numbers: 4
Average: 2.5
So basically sorted by the numbers placed in the beginning of the line which represent keys in a dictionary.
I would appreciate any help.
You can use an OrderedDict to sort a dict by keys.

Trying to find how often a dice roll result occurs in a list of randomly rolled n-sided dice

I am trying to find the occurrences of each number for sides going 1 up to the number of sides on a dice roll. I would like the program to find the number of occurrences for each number that is in listRolls.
Example: if there were a 6 sided dice then it would be 1 up to 6 and the list would roll the dice x amount of times and I would like to find how many times the dice rolled a 1 so on and so forth.
I am new to python and trying to learn it! Any help would be appreciated!
import random
listRolls = []
# Randomly choose the number of sides of dice between 6 and 12
# Print out 'Will be using: x sides' variable = numSides
def main() :
global numSides
global numRolls
numSides = sides()
numRolls = rolls()
rollDice()
counterInputs()
listPrint()
def rolls() :
# for rolls in range(1):
###################################
## CHANGE 20, 50 to 200, 500 ##
##
x = (random.randint(20, 50))
print('Ran for: %s rounds' %(x))
print ('\n')
return x
def sides():
# for sides in range(1):
y = (random.randint(6, 12))
print ('\n')
print('Will be using: %s sides' %(y))
return y
def counterInputs() :
counters = [0] * (numSides + 1) # counters[0] is not used.
value = listRolls
# if value >= 1 and value <= numSides :
# counters[value] = counters[value] + 1
for i in range(1, len(counters)) :
print("%2d: %4d" % (i, value[i]))
print ('\n')
# Face value of die based on each roll (numRolls = number of times die is
thrown).
# numSides = number of faces)
def rollDice():
i = 0
while (i < numRolls):
x = (random.randint(1, numSides))
listRolls.append(x)
# print (x)
i = i + 1
# print ('Done')
def listPrint():
for i, item in enumerate(listRolls):
if (i+1)%13 == 0:
print(item)
else:
print(item,end=', ')
print ('\n')
main()
Fastest way (I know of) is using Counter() from collections (see bottom for dict-only replacement):
import random
from collections import Counter
# create our 6-sided dice
sides = range(1,7)
num_throws = 1000
# generates num_throws random values and counts them
counter = Counter(random.choices(sides, k = num_throws))
print (counter) # Counter({1: 181, 3: 179, 4: 167, 5: 159, 6: 159, 2: 155})
collections.Counter([iterable-or-mapping])) is a specialized dictionary that counts the occurences in the iterable you give it.
random.choices(population, weights=None, *, cum_weights=None, k=1) uses the given iterable (a range(1,7) == 1,2,3,4,5,6 and draws k things from it, returning them as list.
range(from,to[,steps]) generates a immutable sequence and makes random.choices perform even better then when using a list.
As more complete program including inputting facecount and throw-numbers with validation:
def inputNumber(text,minValue):
"""Ask for numeric input using 'text' - returns integer of minValue or more. """
rv = None
while not rv:
rv = input(text)
try:
rv = int(rv)
if rv < minValue:
raise ValueError
except:
rv = None
print("Try gain, number must be {} or more\n".format(minValue))
return rv
from collections import Counter
import random
sides = range(1,inputNumber("How many sides on the dice? [4+] ",4)+1)
num_throws = inputNumber("How many throws? [1+] ",1)
counter = Counter(random.choices(sides, k = num_throws))
print("")
for k in sorted(counter):
print ("Number {} occured {} times".format(k,counter[k]))
Output:
How many sides on the dice? [4+] 1
Try gain, number must be 4 or more
How many sides on the dice? [4+] a
Try gain, number must be 4 or more
How many sides on the dice? [4+] 5
How many throws? [1+] -2
Try gain, number must be 1 or more
How many throws? [1+] 100
Number 1 occured 22 times
Number 2 occured 20 times
Number 3 occured 22 times
Number 4 occured 23 times
Number 5 occured 13 times
You are using python 2.x way of formatting string output, read about format(..) and its format examples.
Take a look at the very good answers for validating input from user: Asking the user for input until they give a valid response
Replacement for Counter if you aren't allowed to use it:
# create a dict
d = {}
# iterate over all values you threw
for num in [1,2,2,3,2,2,2,2,2,1,2,1,5,99]:
# set a defaultvalue of 0 if key not exists
d.setdefault(num,0)
# increment nums value by 1
d[num]+=1
print(d) # {1: 3, 2: 8, 3: 1, 5: 1, 99: 1}
You could trim this down a bit using a dictionary. For stuff like dice I think a good option is to use random.choice and just draw from a list that you populate with the sides of the dice. So to start, we can gather rolls and sides from the user using input(). Next we can use the sides to generate our list that we pull from, you could use randint method in place of this, but for using choice we can make a list in range(1, sides+1). Next we can initiate a dictionary using dict and make a dictionary that has all the sides as keys with a value of 0. Now looks like this d = {1:0, 2:0...n+1:0}.From here now we can use a for loop to populate our dictionary adding 1 to whatever side is rolled. Another for loop will let us print out our dictionary. Bonus. I threw in a max function that takes the items in our dictionary and sorts them by their values and returns the largest tuple of (key, value). We can then print a most rolled statement.
from random import choice
rolls = int(input('Enter the amount of rolls: '))
sides = int(input('Enter the amound of sides: '))
die = list(range(1, sides+1))
d = dict((i,0) for i in die)
for i in range(rolls):
d[choice(die)] += 1
print('\nIn {} rolls, you rolled: '.format(rolls))
for i in d:
print('\tRolled {}: {} times'.format(i, d[i]))
big = max(d.items(), key=lambda x: x[1])
print('{} was rolled the most, for a total of {} times'.format(big[0], big[1]))
Enter the amount of rolls: 5
Enter the amound of sides: 5
In 5 rolls, you rolled:
Rolled 1: 1 times
Rolled 2: 2 times
Rolled 3: 1 times
Rolled 4: 1 times
Rolled 5: 0 times
2 was rolled the most, for a total of 2 times

Appending a dictionary value to a list in python

I'm having trouble appending the student dictionary value that coincides with key 'id' to a list. Any help is much appreciated!
students = list();
students.append( {'id':12345, 'first_name':'Alice',
'last_name':'Anderson','assignments':[('assignment_1',0),('assignment_2',2),
('assignment_3',3)]})
students.append({'id':22345, 'first_name':'John',
'last_name':'Sparks','assignments':[('assignment_1',2),('assignment_2',3),
('assignment_3',4)]})
students.append({'id':32345, 'first_name':'Taylor',
'last_name':'Mason','assignments':[('assignment_1',3),('assignment_2',2),
('assignment_3',3)]})
def return_passing(students):
grade_sum = 0
counter = 0
for s in students: #loop thru students
for assignment, grade in s['assignments']:
grade_sum += grade
counter += 1
average = grade_sum / counter
lst = list()
if average >= 2.0:
lst.append((s['id']))
return lst
return_passing(students)
print(return_passing(students))
You have several issues with initializing things at the wrong place, so they get reset. Explanations for those are in the comments:
def return_passing(students):
lst = [] # initialize lst here
for s in students: #loop thru students
grade_sum = 0 # reset these for each student
counter = 0
for assignment, grade in s['assignments']:
grade_sum += grade
counter += 1
# now that we have gone throug all assignments
# compute average
average = float(grade_sum) / counter # convert to float for precision
if average >= 2.0:
lst.append(s['id'])
return lst # return only after you've gone through all students

Python if condition for print or not print

Here is a basic math problem. I want to calculate least amount of banknotes to be paid.
Here is my code and working well.
total_payment = int(input("Please enter the total amount: "))
Dollar50 = int(total_payment // 50)
remaining_money = total_payment % 50
Dollar20 = int(remaining_money // 20)
remaining_money = remaining_money % 20
Dollar10 = int(remaining_money // 10)
remaining_money = remaining_money % 10
Dollar5 = int(remaining_money // 5)
remaining_money = remaining_money % 5
Dollar1 = int(remaining_money // 1)
print("We need {0} 50 dollar.".format(Dollar50))
print("We need {0} 20 dollar.".format(Dollar20))
print("We need {0} 10 dollar.".format(Dollar10))
print("We need {0} 5 dollar.".format(Dollar5))
print("We need {0} 1 dollar.".format(Dollar1))
But i want to print only if that type of banknote is used. For example if total amount is 101 dollar than program prints
We need 2 50 dollar.
We need 0 20 dollar.
We need 0 10 dollar.
We need 0 5 dollar.
We need 1 1 dollar.
But i dont want to print the ones with 0 value. I only want it to print
We need 2 50 dollar.
We need 1 1 dollar.
This was an example of my struggle. I can not code this kind of loops or conditions. Thank you very much for any help.
Instead of writing an if statement for all of these just zip them together and use a for loop:
counts = [Dollar50, Dollar20, Dollar10, Dollar5, Dollar1]
ammounts = [50, 20, 10, 5, 1]
for i, j in zip(counts, ammounts):
if i:
print("We need {} {} dollar.".format(i, j))
All you need is an if condition.
As an exercise, you should try to write DRY code. Using loops and lists would look like this
face_values = [50, 20, 10, 5, 1]
amounts = [0]*5
remaining_money = int(input("Please enter the total amount: "))
# While you have money left, calculate the next most 'dollar_value' you can use
i = 0 # This is an index over the 'dollars' list
while remaining_money > 0:
d = face_values[i]
amounts[i] = remaining_money // d
remaining_money %= d
i+=1
denomination = "dollar bill"
denomination_plural = denomination + "s"
# Iterate both values and amounts together and print them
for val, amount in zip(face_values, amounts):
if amount == 1: # Filter out any non-positive amounts so you don't show them
print("We need {} {} {}.".format(val, amount, denomination))
else if amount > 1:
print("We need {} {} {}.".format(val, amount, denomination_plural))
Use
if Dollar50:
print("We need {0} 50 dollar.".format(Dollar50))
if the value is 0, it won't print anything.
Speaking simplistically, just add an if statement around each print statement checking for a 0.
if Dollar50 != 0:
print("We need {0} 50 dollar.".format(Dollar50))
if Dollar20 != 0:
print("We need {0} 20 dollar.".format(Dollar20))
Continue that for each item.

Categories

Resources