python 2.7: round a float up to next even number - python

I would like to round up a float to the next even number.
Steps:
1) check if a number is odd or even
2) if odd, round up to next even number
I have step 1 ready, a function which checks if a give number is even or not:
def is_even(num):
if int(float(num) * 10) % 2 == 0:
return "True"
else:
return "False"
but I'm struggling with step 2....
Any advice?
Note: all floats will be positive.

There is no need for step 1. Just divide the value by 2, round up to the nearest integer, then multiply by 2 again:
import math
def round_up_to_even(f):
return math.ceil(f / 2.) * 2
Demo:
>>> import math
>>> def round_up_to_even(f):
... return math.ceil(f / 2.) * 2
...
>>> round_up_to_even(1.25)
2
>>> round_up_to_even(3)
4
>>> round_up_to_even(2.25)
4

a = 3.5654
b = 2.568
a = int(a) if ((int(a) % 2) == 0) else int(a) + 1
b = int(b) if ((int(b) % 2) == 0) else int(b) + 1
print a
print b
value of a after execution
a = 4
value of b after execution
b = 2

import math
def round_to_ceil_even(f):
if (math.floor(f)%2 == 0):
return math.floor(f)
else:
return math.floor(f)+1
def round_to_ceil_even(f):
if (math.floor(f)%2 == 0):
return int(f)
else:
return int(f+1)

Related

how to solve 3x+1 on python

from random import randrange
a = randrange(1, 9)
print (a)
if (a % 2) == 0:
y = a / 2
while True:
if (y % 2) == 0:
y = y / 2
print (y)
else:
b = (a * 3) + 1
while True:
if (b % 2) == 0:
b = b / 2
else:
b = (a * 3) + 1
print (b)
"I want to make a math problem solver in python that can find a random number
between 1 and 9. Then if it is odd so it multiply it with 3 and add 1 in it and if it
is even so it divide it by two and this process keep repeating. For example a number
computer choose is 7 so :
7*3 + 1 = 22
22/2 = 11
11*3 = 33
and so on.
It shouldn't stop until the answer is 0.Here is my code in which I tried but not sure where should I make it right?"
You have too many lines in there. You need to loop to stop repeating when the number becomes 1 (it will never become 0):
from random import randrange
a = randrange(1, 9)
while a != 1:
print(a)
if a % 2 == 0:
a = a // 2
else:
a = (a * 3) + 1
print(a)
You can use the following code to check for any number or any range of numbers. This code is created by using the recursive function approach.
def f(x): #creating a function
if x!=4:
a.append(x)
if x%2==0:
while x%2==0:
x=x/2
a.append(x)
x=3*x+1
f(x)
For checking a particular value, run this:
a=[]
f(2**100+1) #2 to the power 10, plus 1
a[-1]
For checking for a range of values, run this:
for i in range(1,100):
a=[]
f(i)
print(i, "gives output" ,a)
I call it impossible maths because never reaches zero, it just keeps on looping forever Collatz problem. But this function does that, it does not take any parameter.
import random as r
def impossible_math():
x = r.ran(1,9)
while x !=0:
if x%2 ==0:
x = x/2
print(x)
else:
x = (x*3)+1
print(x)
x = impossible_math()

How would I go about finding multiple integers at the same time, then executing a print command based off those integers

I am trying to create a program that will find every number with a square root, cube root, quarter root, and quintuple root under 2^60. Every time I run the command I get only every square number, which is what I programmed variable Num1 to be.
code:
Num = 1
Num1 = 1
while Num1 < 1152921504606846976:
Num += 2
Num1 += Num
Num2 = Num1 ** 0.5
Num3 = Num1 ** 0.33333333333333333333
Num4 = Num1 ** 0.25
Num5 = Num1 ** 0.2
if Num1 > Num:
float(Num2).is_integer()and float(Num3).is_integer()and float(Num4).is_integer() and float(Num5).is_integer()
print Num1
else:
null
Sorry for bad code I am REALLY new to this.
Num2 - Num5 are the answers of the number Num1 being rooted, and if they are all integers my goal is to have a print command give the original number, Num1
As Julien pointed out using floats in this probem is problematic due to the precision issues. Furthermore, you are doing an iteration until 2 ^ 60, which may be pretty slow.
Simple but slow approach
A simple approach would be generate all the integers that have square roots, then all the integers that have cubic roots, and so on. After that, do an intersection of all the numbers we generated so far.
That process can be done easily, we need to iterate from 1 until n^(1/k) to generate numbers that have kth-roots, if i^k is less or equal than our max number, then we have found an kth-root. The code:
def kth_roots(n, k):
i = 1
ans = []
while i ** k <= n:
ans.append(i ** k)
i += 1
return ans
n = 2 ** 60
two = kth_roots(n, 2)
three = kth_roots(n, 3)
four = kth_roots(n, 4)
five = kth_roots(n, 5)
answer = set(two) & set(three) & set(four) & set(five)
print(answer)
An approach based on divisibility
I will propose an answer asuming that you will have your maximum number expressed as a power in the form x ^ y.
Note that, a number will have an integer square root if it can be expressed as b ^ e, such that e is divisible by two, it will have a integer cube root if e is divisible by three, and so on. So a better approach, is to check which exponents will satisfy your conditions (divisibility by 2, 3, 4, and 5). Finally we must determine the value of b, we can brute force, and stop whenever it is greater than x ^ y.
In this way we do not have to play with float numbers that may be a headache here. Some code:
max_exp = 60
max_base = 2
maxm = max_base ** max_exp
ans = 0
e = 1
print(1) # Trivial case
while True:
if e % 2 == 0 and e % 3 == 0 and e % 4 == 0 and e % 5 == 0:
b = 2
flag = False
while b ** e <= maxm:
flag = True
print(b ** e)
b += 1
if flag is False:
break
e += 1
EDIT: As Hugh Bothwel mentioned, the divisibility check on the powers can be reduced to compute the LCM of [2,3,4,5], that would be 60, so any number a^60 have the mentioned integer roots. All that remains is to brute force the values of a. The code:
from fractions import gcd
def _lcm(x, y):
return (x * y) // gcd(x, y)
maxm = 2 ** 60
lcm = reduce(_lcm, [2, 3, 4, 5], 1)
a = 1
while a ** lcm <= maxm:
print(a ** lcm)
a += 1

Computing logarithm

I must write a function that computes the logarithm of a number x relative to a base b (rounded down if the answer is not an integer). I wrote this function but it's not working
def myLog(x, b):
result = 1
if b > x :
result -= 1
return result
elif x == b :
return result
else :
result += 1
b *= result
return myLog(x,b)
Why are you multiplying the base by result and changing the base? When you determine that the base fits into the input number, you should be dividing the number by the base. Since the division means the final number is 1 more, you add 1 to the result of the recursive call.
def myLog(x, b):
result = 1
if b > x:
result -= 1
return result
elif x == b:
return result
else:
x /= b
return 1 + myLog(x, b)
Example: myLog(32, 2):
32/2 = 16, add 1 to answer
16/2 = 8, add 1 to answer
...
answer = 5
Some of the code is unnecessary though, and I would further edit it to be this:
def myLog(x, b):
if b > x:
return 0
elif x == b:
return 1
else:
x /= b
return 1 + myLog(x, b)

How to see if a number ends in .0

I am trying to run a test if the number ends in .0
I am running a program with numbers orders of magnitude apart so I can't estimate to a certain amount of digits. using % doesn't work either because then certain numbers are excluded. All the numbers in this program are floating point numbers so I need a way to check if it ends with .0, not with .00000000000001232 or something it has to end exactly in .0
The problem with the round function is that I am dealing with numbers of several orders of magnitude. I need something that checks if it has only 1 decimal after the . or something that checks if the that decimal is a 0.
code:
from myro import *
from math import *
def main():
z = 3
a = 2
b = 2
x = 3
y = 2 #starts at y = 3
lim = 25
c = (a**x + b**y)**(1.0/z)
resultnum = 0
while z <= lim:
while a <= lim:
while b <= lim:
while x <= lim:
while y <= lim:
y = y + 1
c = (a**x + b**y)**(1.0/z)
if float(int(c) + 1) != round(c, 6):
pass
else:
print str(a) + "^" + str(x) + " + " + str(b) + "^" + str(y) + " = " + str(int(c)+1) + "^" + str(z)
resultnum = resultnum + 1
print c
y = 3
x = x + 1
x = 3
b = b + 1
b = 3
a = a + 1
a = 3
z = z + 1
print z
print "code cycle complete"
print str(resultnum) + " results"
main()
>>> n1 = 2.0
>>> int(n1) == n1 and isinstance(n1, float)
True
>>> n1 = 2
>>> int(n1) == n1 and isinstance(n1, float)
False
>>> n1 = 2.01
>>> int(n1) == n1 and isinstance(n1, float)
False
>>> n1 = 1E1 #works for scientific notation as well
>>> int(n1) == n1 and isinstance(n1, float)
True
Python does this already. Going with what Python gives as a string might be what you want:
In [577]: def dot_zero(number):
.....: return str(number).endswith('.0')
.....:
In [578]: dot_zero(2.0)
Out[578]: True
In [579]: dot_zero(2)
Out[579]: False
In [580]: dot_zero(2.01)
Out[580]: False
EDIT
As pointed out by #jamylak this does not work for large numbers since the scientific notation used by str. Keeping the basic idea of conversion into a string, but also catering for large numbers, we end up with more verbose and admittedly rather ugly solution:
def dot_zero_string(number):
# tested and works with Python 3.3
split = str(number).split('e')
return len(split) == 2 or split[0].endswith('.0')
This is the solution in the answer from #AshwiniChaudhary
def dot_zero_inst(number):
return int(number) == number and isinstance(number, float)
Comparing different cases gives the same result:
numbers = [1, 1.0, 1000, 1000.0, 3e38, 1.5555555555555555555555e12,
1.5555555555555555555555e17, 0, 0.0]
numbers = numbers + [-number for number in numbers]
for number in numbers:
assert dot_zero_inst(number) == dot_zero_string(number)
Just to show another method, you can always split by the '.':
>>> num = 12.023
>>> str(num).split('.')[1] == '0'
False
>>> num = 12.0
>>> str(num).split('.')[1] == '0'
True
Note that this works because you said that all were floating points. This will provide an error num is an int
x = 26.5
b % math.floor(b) == 0
>>> False
x = 26.0
b % math.floor(b) == 0
>>> True
should also do it.

Sum of even integers from a to b in Python

This is my code:
def sum_even(a, b):
count = 0
for i in range(a, b, 1):
if(i % 2 == 0):
count += [i]
return count
An example I put was print(sum_even(3,7)) and the output is 0. I cannot figure out what is wrong.
Your indentation is off, it should be:
def sum_even(a, b):
count = 0
for i in range(a, b, 1):
if(i % 2 == 0):
count += i
return count
so that return count doesn't get scoped to your for loop (in which case it would return on the 1st iteration, causing it to return 0)
(And change [i] to i)
NOTE: another problem - you should be careful about using range:
>>> range(3,7)
[3, 4, 5, 6]
so if you were to do calls to:
sum_even(3,7)
sum_even(3,8)
right now, they would both output 10, which is incorrect for sum of even integers between 3 and 8, inclusive.
What you really want is probably this instead:
def sum_even(a, b):
return sum(i for i in range(a, b + 1) if i % 2 == 0)
Move the return statement out of the scope of the for loop (otherwise you will return on the first loop iteration).
Change count += [i] to count += i.
Also (not sure if you knew this), range(a, b, 1) will contain all the numbers from a to b - 1 (not b). Moreover, you don't need the 1 argument: range(a,b) will have the same effect. So to contain all the numbers from a to b you should use range(a, b+1).
Probably the quickest way to add all the even numbers from a to b is
sum(i for i in xrange(a, b + 1) if not i % 2)
You can make it far simpler than that, by properly using the step argument to the range function.
def sum_even(a, b):
return sum(range(a + a%2, b + 1, 2))
You don't need the loop; you can use simple algebra:
def sum_even(a, b):
if (a % 2 == 1):
a += 1
if (b % 2 == 1):
b -= 1
return a * (0.5 - 0.25 * a) + b * (0.25 * b + 0.5)
Edit:
As NPE pointed out, my original solution above uses floating-point maths. I wasn't too concerned, since the overhead of floating-point maths is negligible compared with the removal of the looping (e.g. if calling sum_even(10, 10000)). Furthermore, the calculations use (negative) powers of two, so shouldn't be subject by rounding errors.
Anyhow, with the simple trick of multiplying everything by 4 and then dividing again at the end we can use integers throughout, which is preferable.
def sum_even(a, b):
if (a % 2 == 1):
a += 1
if (b % 2 == 1):
b -= 1
return (a * (2 - a) + b * (2 + b)) // 4
I'd like you see how your loops work if b is close to 2^32 ;-)
As Matthew said there is no loop needed but he does not explain why.
The problem is just simple arithmetic sequence wiki. Sum of all items in such sequence is:
(a+b)
Sn = ------- * n
2
where 'a' is a first item, 'b' is last and 'n' is number if items.
If we make 'a' and b' even numbers we can easily solve given problem.
So making 'a' and 'b' even is just:
if ((a & 1)==1):
a = a + 1
if ((b & 1)==1):
b = b - 1
Now think how many items do we have between two even numbers - it is:
b-a
n = --- + 1
2
Put it into equation and you get:
a+b b-a
Sn = ----- * ( ------ + 1)
2 2
so your code looks like:
def sum_even(a,b):
if ((a & 1)==1):
a = a + 1
if ((b & 1)==1):
b = b - 1
return ((a+b)/2) * (1+((b-a)/2))
Of course you may add some code to prevent a be equal or bigger than b etc.
Indentation matters in Python. The code you write returns after the first item processed.
This might be a simple way of doing it using the range function.
the third number in range is a step number, i.e, 0, 2, 4, 6...100
sum = 0
for even_number in range(0,102,2):
sum += even_number
print (sum)
def sum_even(a,b):
count = 0
for i in range(a, b):
if(i % 2 == 0):
count += i
return count
Two mistakes here :
add i instead of [i]
you return the value directly at the first iteration. Move the return count out of the for loop
The sum of all the even numbers between the start and end number (inclusive).
def addEvenNumbers(start,end):
total = 0
if end%2==0:
for x in range(start,end):
if x%2==0:
total+=x
return total+end
else:
for x in range(start,end):
if x%2==0:
total+=x
return total
print addEvenNumbers(4,12)
little bit more fancy with advanced python feature.
def sum(a,b):
return a + b
def evensum(a,b):
a = reduce(sum,[x for x in range(a,b) if x %2 ==0])
return a
SUM of even numbers including min and max numbers:
def sum_evens(minimum, maximum):
sum=0
for i in range(minimum, maximum+1):
if i%2==0:
sum = sum +i
i= i+1
return sum
print(sum_evens(2, 6))
OUTPUT is : 12
sum_evens(2, 6) -> 12 (2 + 4 + 6 = 12)
List based approach,
Use b+1 if you want to include last value.
def sum_even(a, b):
even = [x for x in range (a, b) if x%2 ==0 ]
return sum(even)
print(sum_even(3,6))
4
[Program finished]
This will add up all your even values between 1 and 10 and output the answer which is stored in the variable x
x = 0
for i in range (1,10):
if i %2 == 0:
x = x+1
print(x)

Categories