Can anyone help me out? My code print 0 every time input a different value; my code is supposed to print number of coins - cs50

In problem set6 I am required to ask user for an input( a float) and then use the input to calculate number of coin the use owe. In my code I used modulo function in a while to increment number of coin by one. Unfortunately I don't get the outcome I expected. Can anyone assist?
Below is my code
# ask the user for change owed
from cs50 import get_float
while True:
change = get_float("Change owed:")
if change > 0:
break
#compute quarter
coin = 0
while change % 0.25 >= 0.25:
change = change - 0.25
coin += 1
#compute dime
while change % 0.1 >= 0.1:
change = change - 1
coint += 1
#compute nickel
while change % 0.5 >= 0.5:
change = change - 0.5
coin += 1
#compute pennies
while change % 0.1 >= 0.1:
change = change - 0.1
coin += 1
print(coin)

in your code lines like:
change % 0.1 >= 0.1
always will be false, because any remainder after division change on some k is less than k.
Your coin always will be 0. Also try to think about order of while loops in your algo, seems it should be differ.

Related

Different output on Function on assesment (Hackerrank) (FIXED)

So, for this assessment on Hackerrank i need to calculate the ratios on given input. So i coded but whenever iam running this on my own shell it gives me the right output ,but in the compiler from Hackerrank it rounds the results up to a full integer.
Down below my own code. The test input =
6
-4 3 -9 0 4 1
My Code =
def plusMinus(arr):
array = []
positive_int = 0
negative_int = 0
zero_int = 0
total_int = 0
#removing the first int from input & appending the rest of the input to the empty array
for i in arr[1:]: ***Error was in this line of code. Removed the parameter "[1:]" and it gave me the right output***
array.append(i)
total_int = len(array)
#calcuting with every integer in array if positive or negative and counting them
for i in array:
if i >= 1:
positive_int +=1
elif i < 0:
negative_int +=1
elif i == 0:
zero_int +=1
#calculate the ratio of the negatives and positives integers
pos_ratio = positive_int / total_int
negative_ratio = negative_int / total_int
zero_ratio = zero_int / total_int
#format to six decimal places
formatted_pos_ratio = "{:.6f}".format(pos_ratio)
formatted_negative_ratio = "{:.6f}".format(negative_ratio)
formatted_zero_ratio = "{:.6f}".format(zero_ratio)
#printing out the ratio's
print(str(formatted_pos_ratio))
print(str(formatted_negative_ratio))
print(str(formatted_zero_ratio))
Output in Hackerrank Compiler =
0.600000
0.200000
0.200000
and in my own compiler its:
0.500000
0.333333
0.166667
What am i doing wrong? (Bear in mind, i just started coding so my code is most probably not the best way to solve this.)

How to set LpVariable and Objective Function in pulp for LPP as per the formula?

I want to calculate the Maximised value of the particular user based on his Interest | Popularity | both Interest and Popularity using following Linear Programming Problem(LPP) equation
using pulp package in python3.7.
I have 4 lists
INTEREST = [5,10,15,20,25]
POPULARITY = [4,8,12,16,20]
USER = [1,2,3,4,5]
cost = [2,4,6,8,10]
and 2 variable values as
e=0.5 ; e may take (0 or 1 or 0.5)
budget=20
and
i=0 to n ; n is length of the list
means, the summation want to perform for all list values.
Here, if e==0 means Interest will 0 ; if e==1 means Popularity will 0 ; if e==0.5 means Interest and Popularity will be consider for Max Value
Also xi takes 0 or 1; if xi==1 then the user will be consider else if xi==0 then the user will not be consider.
and my pulp code as below
from pulp import *
INTEREST = [5,10,15,20,25]
POPULARITY = [4,8,12,16,20]
USER = [1,2,3,4,5]
cost = [2,4,6,8,10]
e=0.5
budget=10
#PROBLEM VARIABLE
prob = LpProblem("MaxValue", LpMaximize)
# DECISION VARIABLE
int_vars = LpVariable.dicts("Interest", INTEREST,0,4,LpContinuous)
pop_vars = LpVariable.dicts("Popularity",
POPULARITY,0,4,LpContinuous)
user_vars = LpVariable.dicts("User",
USER,0,4,LpBinary)
#OBJECTIVE fUNCTION
prob += lpSum(USER(i)((INTEREST[i]*e for i in INTEREST) +
(POPULARITY[i]*(1-e) for i in POPULARITY)))
# CONSTRAINTS
prob += USER(i)cost(i) <= budget
#SOLVE
prob.solve()
print("Status : ",LpStatus[prob.status])
# PRINT OPTIMAL SOLUTION
print("The Max Value = ",value(prob.objective))
Now I am getting 2 errors as
1) line 714, in addInPlace for e in other:
2) line 23, in
prob += lpSum(INTEREST[i]e for i in INTEREST) +
lpSum(POPULARITY[i](1-e) for i in POPULARITY)
IndexError: list index out of range
What I did wrong in my code. Guide me to resolve this problem. Thanks in advance.
I think I finally understand what you are trying to achieve. I think the problem with your description is to do with terminology. In a linear program we reserve the term variable for those variables which we want to be selected or chosen as part of the optimisation.
If I understand your needs correctly your python variables e and budget would be considered parameters or constants of the linear program.
I believe this does what you want:
from pulp import *
import numpy as np
INTEREST = [5,10,15,20,25]
POPULARITY = [4,8,12,16,20]
COST = [2,4,6,8,10]
N = len(COST)
set_user = range(N)
e=0.5
budget=10
#PROBLEM VARIABLE
prob = LpProblem("MaxValue", LpMaximize)
# DECISION VARIABLE
x = LpVariable.dicts("user_selected", set_user, 0, 1, LpBinary)
# OBJECTIVE fUNCTION
prob += lpSum([x[i]*(INTEREST[i]*e + POPULARITY[i]*(1-e)) for i in set_user])
# CONSTRAINTS
prob += lpSum([x[i]*COST[i] for i in set_user]) <= budget
#SOLVE
prob.solve()
print("Status : ",LpStatus[prob.status])
# PRINT OPTIMAL SOLUTION
print("The Max Value = ",value(prob.objective))
# Show which users selected
x_soln = np.array([x[i].varValue for i in set_user])
print("user_vars: ")
print(x_soln)
Which should return the following, i.e. with these particular parameters only the last user is selected for inclusion - but this decision will change - for example if you increase the budget to 100 all users will be selected.
Status : Optimal
The Max Value = 22.5
user_vars:
[0. 0. 0. 0. 1.]

Two trigonometry-based turtle codes not giving similar output

This is my first time posting a question.
I'm having trouble creating a code involving cosine, and I am not recieving the desired outcome. What is even more confusing is the fact that the two codes should be creating similar images (Explained later). Any ideas?
In the code below, these variables represent:
Y is a counter, making sure that the code only runs until the specified amount of radi is produced.
W is the colour randomly generated.
Z is the angle turn from 0 degrees. (The turtle's angle resets due to turtle.home).
Adjacent is the smallest length from centre to a line.
Radi is the amount of lines protruding from the centre.
def Triangle(Radi, Adjacent):
y = 0
if (Radi) % 1 == 0:
while (Radi) > y:
y = y + 1
w = randhex()
z = 360/(Radi)*y
turtle.left(z+30)
turtle.color(w)
if z > 300:
turtle.forward(Adjacent/math.cos(math.pi*(60 - (z - 300))/180))
elif z > 240:
turtle.forward(Adjacent/math.cos(math.pi*(z - 240)/180))
elif z > 180:
turtle.forward(Adjacent/math.cos(math.pi*(60 - (z - 180))/180))
elif z > 120:
turtle.forward(Adjacent/math.cos(math.pi*(z - 120)/180))
elif z > 60:
turtle.forward(Adjacent/math.cos(math.pi*(60 - (z - 60))/180))
else:
turtle.forward(Adjacent/math.cos(math.pi*z/180))
turtle.home()
Above is my first code which appears to work, giving these results when Triangle(100,180) is entered (Please note that randhex() is a custom function that generates random colours).
Triangle(100,180) results.
My apologies if my variable naming creativity is annoying.
In this code, counter represents 'y' and angle represents 'z' from the previous code
Here is my second code:
def Polygon(Radi, Adjacent, Sides):
counter = 0
if Sides % 1 != 0 or Sides == 2 or Sides <= 0:
print ("INVALID")
elif Sides == 1:
while Radi > counter:
counter = counter + 1
colour = randhex()
turn = 360/Radi*counter
turtle.left(turn)
turtle.color(colour)
turtle.forward(Adjacent)
turtle.home()
else:
while Radi > counter:
counter = counter + 1
colour = randhex()
turn = 360/Radi*counter
turtle.left(turn)
turtle.color(colour)
segment = str(counter/Radi*Sides*2)
position = segment.index('.')
test = int(segment[:position])
if test % 2 == 1:
length = Adjacent/math.cos(math.pi*(turn - (360 - 360/Sides*((test+1)/2)))/180)
turtle.forward(length)
else:
length = Adjacent/math.cos(math.pi*(180/Sides - (turn - (360 - 180/Sides*(test+1))))/180)
turtle.forward(length)
turtle.home()
Above is my second code, being the one I'm struggling with. Once again, apologies for my variable names being annoying and some of the maths not simplified. I find it easier to see how my ideas make sense when I leave them as they are. Below are my results for my second code after entering Polygon(180,100,3).
Polygon(180,100,3) results.
As you can see, it didn't go quite how I was planning.
I should also note that I tried substituting the numbers into the codes where one of the codes were giving a different line length. Sometimes they even went in an opposite direction (because the number came out negative). I did this on the Google calculator, but it seemed that both codes would give the same answer, but they corresponded to what the second code was outputing, not the first.
If you want me to explain anything leave a comment.
But if it turns out that my code is wrong (Which I believe), could you please point me to what I need to do instead.
I'd appreciate the help.
Your code is too complicated to debug. The unhelpful variable names, the lack of comments and excessively long equations make it hard to read.
If we consider the equation suggested in this answer to Is there an equation to describe regular polygons? then your original triangle code simplifies to:
import math
import turtle
def randhex():
""" substitute random color generator here """
return 'red'
def triangle(radii, adjacent):
if radii % 1 != 0: # only whole numbers (int or float) allowed
return
counter = 1
while counter <= radii:
angle = counter * (2 * math.pi / radii)
turtle.setheading(angle)
colour = randhex()
turtle.color(colour)
radius = adjacent / math.cos(angle % (math.pi / 1.5) - math.pi / 3)
turtle.forward(radius)
turtle.backward(radius)
counter += 1
turtle.radians() # avoid individual conversions, switch to radians
triangle(100, 180)
turtle.exitonclick()
And the general polygon solution can be achieved with just a few changes:
import math
import turtle
def randhex():
""" substitute random color generator here """
return 'red'
def polygon(radii, adjacent, sides):
if radii % 1 != 0: # only whole numbers (int or float) allowed
return
if sides % 1 != 0 or sides == 2 or sides <= 0:
return
counter = 1
while counter <= radii:
angle = counter * (2 * math.pi / radii)
turtle.setheading(angle)
colour = randhex()
turtle.color(colour)
if sides == 1: # special case, a circle
radius = adjacent
else:
radius = adjacent / math.cos(angle % (math.pi / (sides / 2)) - math.pi / sides)
turtle.forward(radius)
turtle.backward(radius)
counter += 1
turtle.radians() # avoid individual conversions, switch to radians
polygon(100, 180, 3)
turtle.exitonclick()
With polygon(100, 90, 5) looking like:

split a value into values in max, min range

I want to find an efficient algorithm to divide an integer number to some value in a max, min range. There should be as less values as possible.
For example:
max = 7, min = 3
then
8 = 4 + 4
9 = 4 + 5
16 = 5 + 5 + 6 (not 4 + 4 + 4 + 4)
EDIT
To make it more clear, let take an example. Assume that you have a bunch of apples and you want to pack them into baskets. Each basket can contain 3 to 7 apples, and you want the number of baskets to be used is as small as possible.
** I mentioned that the value should be evenly divided, but that's not so important. I am more concerned about less number of baskets.
This struck me as a fun problem so I had a go at hacking out a quick solution. I think this might be an interesting starting point, it'll either give you a valid solution with as few numbers as possible, or with numbers as similar to each other as possible, all within the bounds of the range defined by the min_bound and max_bound
number = int(input("Number: "))
min_bound = 3
max_bound = 7
def improve(solution):
solution = list(reversed(solution))
for i, num in enumerate(solution):
if i >= 2:
average = sum(solution[:i]) / i
if average.is_integer():
for x in range(i):
solution[x] = int(average)
break
return solution
def find_numbers(number, division, common_number):
extra_number = number - common_number * division
numbers_in_solution = [common_number] * division
if extra_number < min_bound and \
extra_number + common_number <= max_bound:
numbers_in_solution[-1] += extra_number
elif extra_number < min_bound or extra_number > max_bound:
return None
else:
numbers_in_solution.append(extra_number)
solution = improve(numbers_in_solution)
return solution
def tst(number):
try:
solution = None
for division in range(number//max_bound, number//min_bound + 1): # Reverse the order of this for numbers as close in value to each other as possible.
if round (number / division) in range(min_bound, max_bound + 1):
solution = find_numbers(number, division, round(number / division))
elif (number // division) in range(min_bound, max_bound + 1): # Rarely required but catches edge cases
solution = find_numbers(number, division, number // division)
if solution:
print(sum(solution), solution)
break
except ZeroDivisionError:
print("Solution is 1, your input is less than the max_bound")
tst(number)
for x in range(1,100):
tst(x)
This code is just to demonstrate an idea, I'm sure it could be tweaked for better performance.

using while loop to count how many doublings happen between two numbers

My task is to write a function that uses a while loop to count how many days(how many doublings) it takes for the population to go from a given initial size to a value greater than or equal to a given final size.
In addition, The answer should be zero if the final populations is less than or equal to the initial population.
My approach:
def num_doublings(initial_population, final_population):
days = 0
if final_population <= initial_population:
return 0
else:
while initial_population < final_population:
initial_population * 2
days = days + 1
return days
Testing:
ans = num_doublings(1, 8)
print(ans)
When i press enter, it tells me "executing command. please wait for results."
and i don't think it'll ever return something so i just discontinue the code from running.
So what am i doing wrong?
You are calling initial_population * 2, which does not modify the in-place variable. Instead try:
initial_population *= 2
Which is equivalent to:
initial_population = initial_population*2
Final Code:
def num_doublings(initial_population, final_population):
days = 0
if final_population <= initial_population:
return 0
else:
while initial_population < final_population:
initial_population *= 2 #Right here
days += 1 #Also changed this to be more concise
return days
Why this is an issue:
You are testing for if x < y, and if x is indeed less than y, and you do not modify either x or y, your while loop will run indefinitely.

Resources