Ceil and floor equivalent in Python 3 without Math module? - python

I need to ceil and floor 3/2 result (1.5) without using import math.
math.floor(3/2) => 3//2
math.ceil(3/2) => ?
OK, here is the problem:
to sum all numbers
15 + 45 + 15 + 45 + 15 ...
with N items.
sum = (n//2) * 5 + int(n/2) * 15

>>> 3/2
1.5
>>> 3//2 # floor
1
>>> -(-3//2) # ceil
2

Try
def ceil(n):
return int(-1 * n // 1 * -1)
def floor(n):
return int(n // 1)
I used int() to make the values integer. As ceiling and floor are a type of rounding, I thought integer is the appropriate type to return.
The integer division //, goes to the next whole number to the left on the number line. Therefore by using -1, I switch the direction around to get the ceiling, then use another * -1 to return to the original sign. The math is done from left to right.

I know this is old...but you can call those like this too:
>>> (3/2).__ceil__()
2
>>> (3/2).__floor__()
1
edit: this is for python 3.9 and above

Try:
def ceil(n):
res = int(n)
return res if res == n or n < 0 else res+1
def floor(n):
res = int(n)
return res if res == n or n >= 0 else res-1

try it like:
if a%b != 0:
print(int(a//b + 1))
else:
print(int(a/b))

Related

Reduce time /space complexity of simple loop

So basically if i have an iteration like this in python
Ive editted the question to include my full code
class Solution:
def myPow(self, x: float, n: int) -> float:
temp = [];
span = range(1,abs(n))
if n ==0:
return 1
if abs(n)==1:
temp.append(x)
else:
for y in span:
if y == 1:
temp = []
temp.append(x*x)
else:
temp.append(temp[-1] * x)
if(n < 0):
return 1/temp[-1]
else:
return temp[-1]
The problem link is : Pow(x,n)-leetcode
How can I modify this to conserve memory and time. Is there another data structure i can use. Im just learning python....
------------EDIT------------
ive modified the code to use a variable instead of a list for the temp data
class Solution:
def myPow(self, x: float, n: int) -> float:
span = range(1,abs(n))
if n ==0:
return 1
if abs(n)==1:
temp = x
else:
for y in span:
if y == 1:
temp = x*x
else:
temp = temp * x
if(n < 0):
return 1/temp
else:
return temp
I still have a problem with my time complexity.
Its working for many testcases, however when it trys to run with x = 0.00001 and n = 2147483647. The time limit issue arises
To reduce the time complexity you can divide the work each time by taking x to the power of 2 and dividing the exponent by two. This makes a logarithmic time algorithm since the exponent is halved at each step.
Consider the following examples:
10^8 = 10^(2*4) = (10^2)^4 = (10*10)^4
Now, there is one edge case. When the exponent is an odd number you can't integer divide it by 2. So in that case you need to multiply the results by the base one additional time.
The following is a direct recursive implementation of the above idea:
class Solution:
def myPow(self, x: float, n: int) -> float:
sign = -1 if n < 0 else 1
n = abs(n)
def helper(x, n):
if n == 1: return x
if n == 0: return 1
if n % 2 == 1:
return helper(x*x, n // 2) * x
else:
return helper(x*x, n // 2)
res = helper(x, n)
if sign == -1:
return 1/res
else:
return res
Note that we have taken abs of the exponent and stored the sign and deal with it at the end.
Instead of iterating from 1 to n, use divide-and-conquer: divide the exponent by 2 and use recursion to get that power, and then square that result. If n was odd, multiply one time more with x:
class Solution:
def myPow(self, x: float, n: int) -> float:
if n == 0:
return 1
if n == 1:
return x
if n < 0:
return self.myPow(1/x, -n)
temp = self.myPow(x, n // 2)
temp *= temp
if n % 2:
temp *= x
return temp
A simple naive solution might be:
def myPow(x: float, n: int) -> float:
## -----------------------
## if we have a negative n then invert x and take the absolute value of n
## -----------------------
if n < 0:
x = 1/x
n = -n
## -----------------------
retval = 1
for _ in range(n):
retval *= x
return retval
While this technically works, you will wait until the cows come home to get a result for:
x = 0.00001 and n = 2147483647
So we need to find a shortcut. Lets' consider 2^5. Our naïve method would calculate that as:
(((2 * 2) * 2) * 2) * 2 == 32
However, what might we observe about the problem if we group some stuff together in a different way:
(2 * 2) * (2 * 2) * 2 == 32
similarly:
((2 * 2) * (2 * 2) * 2) * ((2 * 2) * (2 * 2) * 2) == 32 * 32 = 1024
We might observe that we only technically need to calculate
(2 * 2) * (2 * 2) * 2 == 32
once and use it twice to get 2^10.
Similarly we only need to calcuate:
2 * 2 = 4
once and use it twice to get 2^5....
This suggests a recursion to me.
Let's modify our first attempt to use this divide and concur method.
def myPow2(x: float, n: int) -> float:
## -----------------------
## if we have a negative n then invert x and take the absolute value of n
## -----------------------
if n < 0:
x = 1/x
n = -n
## -----------------------
## -----------------------
## We only need to calculate approximately half the work and use it twice
## at any step.
## -----------------------
def _recurse(x, n):
if n == 0:
return 1
res = _recurse(x, n//2) # calculate it once
res = res * res # use it twice
return res * x if n % 2 else res # if n is odd, multiple by x one more time (see 2^5 above)
## -----------------------
return _recurse(x, n)
Now let's try:
print(myPow2(2.0, 0))
print(myPow2(2.0, 1))
print(myPow2(2.0, 5))
print(myPow2(2.1, 3))
print(myPow2(2.0, -2))
print(myPow2(0.00001, 2147483647))
That gives me:
1
2.0
32.0
9.261000000000001
0.25
0.0
If you have to loop, you have to lope and there is nothing that can be done. Loops in python are slow. That said you may not have to loop and if you do have to loop, it may be possible to push this loop to a highly optimised internal function. Tell us what you are trying to do (not how you think you have to do it, appending elements to a lis may or may not be needed). Always recall the two rules of program optimisation General Rule: Don't do it. Rule for experts: Don't do it yet. Make it work before you make it fast, who knows, it may be fast enough.

How to write 2**n - 1 as a recursive function?

I need a function that takes n and returns 2n - 1 . It sounds simple enough, but the function has to be recursive. So far I have just 2n:
def required_steps(n):
if n == 0:
return 1
return 2 * req_steps(n-1)
The exercise states: "You can assume that the parameter n is always a positive integer and greater than 0"
2**n -1 is also 1+2+4+...+2n-1 which can made into a single recursive function (without the second one to subtract 1 from the power of 2).
Hint: 1+2*(1+2*(...))
Solution below, don't look if you want to try the hint first.
This works if n is guaranteed to be greater than zero (as was actually promised in the problem statement):
def required_steps(n):
if n == 1: # changed because we need one less going down
return 1
return 1 + 2 * required_steps(n-1)
A more robust version would handle zero and negative values too:
def required_steps(n):
if n < 0:
raise ValueError("n must be non-negative")
if n == 0:
return 0
return 1 + 2 * required_steps(n-1)
(Adding a check for non-integers is left as an exercise.)
To solve a problem with a recursive approach you would have to find out how you can define the function with a given input in terms of the same function with a different input. In this case, since f(n) = 2 * f(n - 1) + 1, you can do:
def required_steps(n):
return n and 2 * required_steps(n - 1) + 1
so that:
for i in range(5):
print(required_steps(i))
outputs:
0
1
3
7
15
You can extract the really recursive part to another function
def f(n):
return required_steps(n) - 1
Or you can set a flag and define just when to subtract
def required_steps(n, sub=True):
if n == 0: return 1
return 2 * required_steps(n-1, False) - sub
>>> print(required_steps(10))
1023
Using an additional parameter for the result, r -
def required_steps (n = 0, r = 1):
if n == 0:
return r - 1
else:
return required_steps(n - 1, r * 2)
for x in range(6):
print(f"f({x}) = {required_steps(x)}")
# f(0) = 0
# f(1) = 1
# f(2) = 3
# f(3) = 7
# f(4) = 15
# f(5) = 31
You can also write it using bitwise left shift, << -
def required_steps (n = 0, r = 1):
if n == 0:
return r - 1
else:
return required_steps(n - 1, r << 1)
The output is the same
Have a placeholder to remember original value of n and then for the very first step i.e. n == N, return 2^n-1
n = 10
# constant to hold initial value of n
N = n
def required_steps(n, N):
if n == 0:
return 1
elif n == N:
return 2 * required_steps(n-1, N) - 1
return 2 * required_steps(n-1, N)
required_steps(n, N)
One way to get the offset of "-1" is to apply it in the return from the first function call using an argument with a default value, then explicitly set the offset argument to zero during the recursive calls.
def required_steps(n, offset = -1):
if n == 0:
return 1
return offset + 2 * required_steps(n-1,0)
On top of all the awesome answers given earlier, below will show its implementation with inner functions.
def outer(n):
k=n
def p(n):
if n==1:
return 2
if n==k:
return 2*p(n-1)-1
return 2*p(n-1)
return p(n)
n=5
print(outer(n))
Basically, it is assigning a global value of n to k and recursing through it with appropriate comparisons.

Python: Is there a way to print even numbers within an unknown range and without if statement?

I have a homework to do in Python class and was given this question:
Make a program that gets 2 numbers from the user, and prints all even
numbers in the range of those 2 numbers, you can only use as many for
statements as you want, but can't use another loops or if statement.
I understand that I need to use this code:
for num in range (x,y+1,2):
print (num)
but without any if statements, I can't check if the value x inserted is even or odd, and if the user inserted the number 5 as x, all the prints will be odd numbers.
I also tried to enter each number to a tuple or an array, but I still can't check if the first number is even to start printing.
def printEvenFor(x,y):
evenNumbers =[]
for i in range (x,y+1):
evenNumbers.append(i)
print (evenNumbers[::2])
or
def printEvenFor(x,y):
for i in range (x,y+1,2):
print(i,",")
I expect the output of printEvenFor(5,12) to be 6,8,10,12 but it is 5,7,9,11
You can make x even, by using floor division and then multiplication:
x = (x // 2) * 2
x will then be rounded to the previous even integer or stay the same if it was even before.
If you want to round it to the following even integer you need to do:
x = ((x + 1) // 2) * 2
This can be improved further by using shifting operators:
x = (x >> 1) << 1 #Alternative 1
x = ((x + 1) >> 1) << 1 #Alternative 2
Examples:
#Alternative 1
x = 9
x = (x >> 1) << 1
#x is now 8
#Alternative 2
x = 9
x = ((x + 1) >> 1) << 1
#x is now 10
The second one is probably more suitable for you
You can use reminder to get the correct range:
def print_event_for(min_, max_):
reminder = min_ % 2
for i in range(min_+reminder, max_+reminder, 2):
print(i)
print_event_for(5, 12)
Output:
6
8
10
12
one way is by using while, that takes the start and end range in
for each in range(int(input()),int(input())):
while each%2 == 0:
print (each)
break;
Try this:
x = x+x%2
for num in range (x,y+1,2):
print (num)
You can do it this way:
>>> for n in range((x + 1) // 2 * 2, y+1, 2):
print(n)
The first argument to range forces it to be the next even number if it is odd. The last argument goes up in twos.
The following function will do what you want. I use round to force the boundaries to be even in order to get start the range on an even number.
def print_even_between(x, y):
x = round(x / 2) * 2
y = round(y / 2) * 2
for i in range(x, y, 2):
print(i)
print(y)
Hacky but fun: multiplying strings with zero.
>>> low, high = int(input()), int(input())
5
13
>>> for n in range(low, high + 1):
... print('{}\n'.format(n)*(not n%2), end='')
...
6
8
10
12
Odd numbes are not printed because the string is multiplied with False (acting as zero).
def printEvenfor(x,y):
return list(range(((x+1) // 2) * 2,y+1, 2))
printEvenfor(9,16)

Calculating factorials with Python

EDIT: I know I can import factorials but I'm doing this as an exercise
Trying to get the factor of a given number with a function in Python.
For example:
factorial(4) = 4 * 3 * 2 * 1 = 24
def factorial(x):
n = x
while n >= 0:
x = n * (n - 1)
n -= 1
return x
try like this: to make your code work
def factorial(x):
n = 1 # this will store the factorial value
while x > 0:
n = n*x
x -= 1
return n
you got many advice on comments follow it
A good way of approaching this would be using recursion where a function calls itself. See Function for Factorial in Python
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
But in your case your return statement actually breaks out of the while loop. So if you pass in 5 you get 20 back which is obviously not 5! (5 factorial).
Instead, try this:
def factorial(x):
n = 1
while x > 1:
n *= x
x -= 1
return n
print (factorial(5))
But do have a go at the recursive approach.
If you really want to cheat try:
import math
math.factorial(n)
I present an even shorter code for recursive factorial calculation. Not sure if it is faster or slower than other approaches:
def fac(n):
return 1 if n==1 else n*fac(n-1)
fac(10)
3628800
def factorial(n):
total = 1
for num in range(2,n+1):
total *= num
return total
input:
n = 10
print(str(n) + "! = ", end = '')
def factorial(n):
'''
print factorial number in human way
'''
if n < 0:
return 'factorial() not defined for negative values'
if n == 0:
return 1
if n == 1:
print('', n, ' =', end = ' ')
return 1
else:
print('', n, '*', end = '')
return n * factorial(n - 1)
print(factorial(n))
output:
10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3628800

Round integer in python without using round()

I know that I can round to the closest multiple of 10 in python by using round(<int>, -1) Is there a way to do this without using this built in function?
Edit:
Thanks for the feedback!
The answer using divmod() was interesting because I had never used divmod before. Just in case anyone wants to know on CodingBat the solution used modulo as was suggested in the comments. Here it is in case anyone is interested.
def round10(num):
mod = num % 10
num -= mod
if mod >= 5: num += 10
return num
divide by 10, int, multiply by 10.
Actually, you can do it without any builtins using the // operator:
>>> def round(x):
... return (x//10)*10
...
>>> round(15.)
10.0
>>> round(25.)
20.0
Of course, this always rounds down. If you want to round up for values with a remainder greater than 5, you could use divmod:
def round(x):
n, remainder = divmod(x, 10)
if remainder >= 5:
n += 1
return n * 10
This rounds to the closest, not always up or always down:
def xround(n):
return (n + 5) // 10 * 10
Round down to the closest multiple of 10:
int(n / 10) * 10
Round up to the closest multiple of 10:
int((n + 10) / 10) * 10
Round to the closest multiple of ten:
(int(n / 10) + bool(n % 10 >= 5)) * 10
I have a function that rounds n to the nearest multiple of d:
def cm(n,d,o="+"):
p = d - (n % d)
m = n % d
nm = n - m
np = n + p
if p > m:
return nm
elif m > p:
return np
else:
if o == "+":
return np
else:
return nm
How to use:
use cm(number, near multiple wanted, preferred direction in special cases)
Examples:
cm(8,10) = 10
cm(6,4,"-") = 4 #special case (n % d == d - n % d)
cm(6,4,"+") = 8 #special case
cm(6,4) = 8

Categories

Resources