How to calculate minimum amount of coins for a monetary amount? - python-3.x

I have a homework assignment in which I have to calculate the minimum amount of coins required for an inputted monetary value.
I've been trying to wrap my head round the logic involved, but I can't quite grasp it. I copied most of it from this website, so if you could explain it to me, I'd be very grateful!
First I tried loads of if, else statements and I knew I had to use % (modulus). But it didn't really work.
n1=float(input("Enter a monetary amount: "))
n1=n1*100
pound=0
fiftyp=0
twentyp=0
tenp=0
onep=0
pound=n1/100
n1%=100
fiftyp=n1/50
n1%=50
twentyp=n1/20
n1%=20
tenp=n1/10
n1%=10
onep=n1
print(int(pound), int(fiftyp), int(twentyp), int(tenp), int(onep))
This code, however, doesn't work, probably due to rounding issues? For example, when inputted 2.30, it outputted 2 0 1 0 9, i.e. 2pounds twenty pence and nine pence, when it should be 2 0 1 1 0, i.e. 2pounds twenty pence, ten pence.
Again, if you could also help me understand how the bulk of the above code works, I'd be very grateful. Thank you in advance!

Related

How can I express easily a formula that has a lot of nesting Ifs

I want to express a formula that says if a number in a column is 50 to 99, then return 50. If 100-149, then return 100, 150-199, then return 150, etc, etc. I need a more concise way to do that for numbers that could reach 2000 (in 50 increments).
Right now my formula is =if(and >50 <100),50,if >100,100,true,0) or something like that, I can't see if right now.
There's probably a faster way, but here's what I would do:
Create a new column that rounds down to the nearest 50:
Assume the numbers are in Column A:
=CONCAT(FLOOR(A2,50),"-",IF(FLOOR(A2,100)-1<FLOOR(A2,50),FLOOR(A2,100)+99,FLOOR(A2,100)-1))
This will produce, for every row, the nearest 50 and nearest 100-1. Also, it allows you to go to 10,000, 50,000, 100,000 and never have to change this formula.
The only thing is adding another nested if for any number below 50, but that's up to you. Otherwise, it shows as 0-99 for any number under 50 and 50-99 for any number below 99 but above 50.
Edit
I found out, after all that work, that you just wanted it rounded down to the nearest 50. Just use =FLOOR(A2, 50)
Divide the number by 50, then multiply the integer of that by 50:
=INT(A1/50)*50
Or subtract half the number and use MROUND:
=MROUND(A1-25,50)

Error while Multiplying a u64 to u128 in Rust?

I want to multiply a u128 number with a u64 number. u64 will always be less than or equal to one. Amount is always greater than 1000000(1 million)
fn testing(amount:u128, starting_time:u64, ending_time:u64, duration:u64){
return amount*((ending_time - starting_time:u64)/duration)
}
Even if the number should return something like 500,000 it always returns zero unless the ((ending_time - starting_time:u64)/duration) equals 1 then the return value always amounts.
I want to give less weightage to someone if they enter the last to the lottery. Both starting and ending times are u64 because they are in UNIX timestamps.
Example: Let's say Alice entered the lottery at time 0. Same time the lottery was started. So Alice would get full weightage for the amount she deposited let's say she deposited 30000 so she will get 30000 tickets.
Bob entered the lottery halfway through the lottery means that whatever he deposits he will get half the weightage of the deposited amount. If he deposits 30000 he will get 15000 tickets.
The best solution I found is:
(amount/1000000) * (( ((end_time - start_time)*1000000 )/duration ) as u128)
I see 2 problems with your code:
You are trying to subtract 2 timestamps, but is that going to leave you with a timestamp? or a number? and if it is the number, is that in seconds or milliseconds or what? and does duration also represent seconds or milliseconds or is it another timestamp?
If all that code still makes sense, then you have a second problem:
Your expression: ending_time - starting_time)/duration, presumably you are expecting it to be a fraction between 0 & 1, right? well if all your variables are ints, then your result is going to be an int, which means guess what? no fraction.
You need to cast all that stuff to floats, or multiply the amount first so you don't have to worry about the fraction. Maybe try this:
return amount*(ending_time - starting_time)/duration;

How to code rule number 4 from Western Electric rule's for quality control charts

I am new to statistics. I have a problem at hand for which I need to code all the 4 rules of Western Electric rules for Quality control. I have been able to code the first one and second with the help of my peer, could anyone help me out in writing down rule number 4 - "NINE consecutive points fall on the same side of the centerline"
I have plotted rule 1 by getting the data below and above the threshold and then ran the matplotlib plot in single cell.
I am not able to get the data for rule number 4.
Even if no one answered it, it gave me enough motivation to workout a solution.
although I know my code is not optimal, please suggest me if I need any changes further.
temp_up=[]
temp_down=[]
for i in range(len(data)):
if arr_data[i] > y_mean:
temp_up.append(i)
else:
temp_down.append(i)
#now we have index values for both data above and below mean,
#we will now get the sequence of the index to know if there's any run of or greater than length 9
from itertools import groupby
from operator import itemgetter
d_up=[]
d_down=[]
for k, g in groupby(enumerate(temp_up), lambda ix : ix[0] - ix[1]):
t_up=(list(map(itemgetter(1), g)))
if len(t_up)>=9:#check if the length of the sequence is greater than or equal to 9
#get index to mark red for the data
for i in range(8, len(t_up), 1):
d_up.append(t_up[i])#index number of data points voilating number 4 rule (above mean)
for k, g in groupby(enumerate(temp_down), lambda ix : ix[0] - ix[1]):
t_down=(list(map(itemgetter(1), g)))
if len(t_down)>=9:#check if the length of the sequence is greater than or equal to 9
#print(t_down)
#get index to mark red for the data
for i in range(8, len(t_down), 1):
d_down.append(t_down[i])#index number of data points voilating number 4 rule (above mean)
data_above_r4 = pd.DataFrame(data.iloc[d_up])
Really late followup, but you could do something like "if minimum of previous 9 points and maximum of previous 9 points are both same side (> or <) mean, failure."
This shows the rolling min, rolling max should work similarly https://stackoverflow.com/a/33920859/18474867
Generate a "rolling min" and "rolling max" column for the last 9 rows, if anywhere they're both + or both -, flag it as a failure.

Advance sorting in Excel

In our warehouse we have even/odd system of locations.
here is the example:
1-101-1
1-103-1
1-105-1
....
1-285-1
and
2-102-1
2-104-1
2-116-1
2-240-1
....
2-286-1
and have levels too
1-101-2
1-101-3
1-101-4
there have a lot of data, and I need sort like this:
example numbers:
1-101-1
2-130-1
1-131-1
1-150-2
2-132-3
3-229-5
4-262-1
4-286-5
7-267-1
5-239-1
6-270-1
7-267-3
I need sort like this:
1-101-1
2-130-1
1-131-1
2-132-3
4-286-5
4-262-1
3-229-5
5-239-1
6-270-1
7-267-1
7-267-1
point is first two numbers(1-101-1;2-102-1) goes from smallest to biggest, next two(3-285-1;4-286) goes from biggest to smallest and
5 - 6 goes again from smallest to biggest and with that system to the end
second thing for sort is middle number, that number will goes as first from smallest to biggest, then from biggest to smallest, and last number is level, that is same as level 1 but must be sorted as level one, or be near level 1 if there is 7-267-1 and 7-267-3
is there any solution? thanks
edit:
here is image for easier understanding because it is hard to explain
Thanks all for answers, especially Daniel who are an expert in Excel and understand what I need.
I mean there is not solution for sort like that without VBA, but Daniel show me that i was wrong. Thanks again.
That is what i need, but there are some errors, if you can help me with that
this is other example with other locations:
this is unsorted locations with formulas you give me
and this is sorted, but with bad order:
bad sort
and here is with errors:
errors
we have 120 rows, and numbers bigger then 99 display error, and number 22-250-1 goes in -25 in second row
I try formula with numbers you enter in this example, and i got same good sort as you, but after entering other places, there is some bad sort.
Welcome to StackOverflow!
I think I understand what is being requested. It's a bit difficult to explain but I'll give it a try.
The primary sorting is to be as follows:
If first digit is either 3 or 4, then it should be in descending order else ascending.
If the middle 3-digits are from a 3 or 4 numbered sequence (see #1 above), then the middle pair should be in descending order.
All sequences should be in ascending based on their final digit.
My solution breaks the sequence into distinct columns:
For example, create three columns: First, Second, Third.
Formula for First:
=INT(LEFT(A2, 1))
Formula for Second:
=INT(RIGHT(LEFT(A2,5), 3))
Formula for Third:
=INT(RIGHT(A2,1))
Next, we assign values for sorting these three fields:
Create a column labeled First_Sort_Pair:
=IF(OR(B2=1,B2=2),1,
IF(B2=3,3,
IF(B2=4,2,
IF(OR(B2=5,B2=6),4,
IF(OR(B2=7,B2=8),5,6)))))
Create a column labeled First_Sort:
=IF(OR(B2=3, B2=4), 2, 1)
Create a column labeled Second_Sort:
=IF(E2=4, 2, IF(E2=3, 3, 1))
Create a column labeled Sort_3_4:
=IF(OR(B2=3,B2=4),RANK(C2,C:C,0),)
You can now begin sorting:
[
Result:
You will now have your data sorted as intended:

If statment of a cell calculated using formula

My formula is giving me unexpected responses.
=IF(I5+H5=0,"Paid","Due")
see below
H I J k
-£34.40 £34.40 £0.00 Due
Cell H is calculated with this
=(SUM(F5+G5))*-1
See correct output with exact same formula on same worksheet
=IF(I3+H3=0,"Paid","Due")
H I J K
-£205.44 £205.44 £0.00 Paid
Cell H is calculated he same
=(SUM(F3+G3))*-1
Any ideas why the top calculation not correct but the bottom one is.
This is most likely the floating point issue. You should not compare floating point numbers directly with = because computers can't store the full decimal places. Just like if you divide 1 dollar by 3, you end up with .3333333333333 cents, well if you add 3 of those you don't necessarily get back 1 dollar, but slightly less due to the "lost" 3333's at the end. The proper way to compare is using a Delta threshold, meaning "how close" it needs to be.
so instead of
if (a+b=c,"paid", "due")
you would do
if(ABS(c-(a+b))<.01, "paid", "due")
so in that case .01 is the delta, or "how close" it has to be. It has to be within 1 cent. the formula literally means "if the absolute value of the difference between c and (a+b) is less than 1 cent, return paid, else return due. (of course, this will say due if they overpaid, so keep that in mind)
you should always do this.

Resources