Custom Round Off Function not Working as Expected.
def roundOffToLowest(number, by): return number - (number % by) def roundOffToHighest(number, by): if number % by == 0: return number elif number % by > 0: return (number - (number % by)) + by def roundOffToAutomatically(number, by): a = roundOffToLowest(number, by) b = roundOffToHighest(number, by) if (number - a) > (number - b): return a elif (number - b) > (number - a): return b The 2 blocks are used for rounding off a number to either the closest or the farthest of a desired multiple. The 3rd one uses the other 2 to find out whether it should automatically be rounded off to the farthest or closest multiple. For example: roundOffToAutomatically(12, 5) will return 10.0, but roundOffToAutomatically(14,5) will return 15.0 This is where things get weird, if I type in roundOffToAutomatically(15.5, 10), I expect 20.0 but rather, I get the value 10.0 returned. Where does my code go wrong? Or is it just Python not able to deal with float values properly? I'd be really happy if I could fix this.
11/16/2019 3:22:57 PMAaryan Pandey
7 AnswersNew Answer
Not sure of this helps, but this works for me: def roundOffToLowest(number, by): return number - (number % by) def roundOffToHighest(number, by): if number % by == 0: return number elif number % by > 0: return (number - (number % by)) + by def roundOffToAutomatically(number, by): a = roundOffToLowest(number, by) b = roundOffToHighest(number, by) if a > b: return a elif b > a: return b print(int(roundOffToAutomatically(15.5,5))) I changed the if statements to be comparing a to b instead of comparing (number -a) to (number -b). I also told it to print as an integer since it would give 20.0 if you used a float as your number.
Hi, I suppose that you want to get the following: - if you give number 17.5, you expect to get 20 - if you give number 13.5, you expect to get 10 If this assumption is correct, the issue seems to be the logic with your if / elif statement. roundOffToLowest() and roundOffToHighest() are giving correct values back #[edited]: if abs(number - a) > abs(number - b): # <-------------- this seems to work return b elif abs(number - b) > abs(number - a): return a I have put the calculation behind the if / elif statement. So you can see, that both numbers 17.5 and 13.5 will be evaluated from if statement as True.
See my first post for the [edited] area.
Your code went wrong and returned 10.0 because of the if/elif part of roundOffToAutomatically: For (15.5, 10): a = 10.0, b = 20.0, so number - a = 5.5, number - b = -4.5. Since 5.5 > -4.5, the code in the if block was evaluated and returned a = 10.0. You want to round to the nearest multiple for the number given, so you want to return the multiple that is the shortest distance away from the number. The absolute value function is great for doing this easily and that is why Lothar's code works.
ZIAMI Your code compares the multiples to each other rather than comparing which is closer to the number to be rounded. It returned 20 because 20.0 > 10.0, not because 20.0 is a closer multiple of 10 to 15.5 than 10.0 is, as it should. So if you were to try it for 14.5 for example, it doesn't work.
Njeri: that actually makes perfect sense! It seemed to be working with 5 as the round off number but my mistake in not doing sufficient testing. I am still a beginner. This is how I learn, by having others with more experience point out my errors. So thank you!
ZIAMI No problem. I'm glad it was helpful.