Undertaking a task to Write a function power that accepts two arguments, a and b and calculates a raised to the power b.
Example
power(2, 3) => 8
Note: Don't use
2 ** 3
and don't use
Math.pow(2, 3)
I have tried this
def power(a,b):
return eval(((str(a)+"*")*b)[:-1])
And it works but seems to fail one test which is to return_1_when_exp_is_0
and i also get the error
Unhandled Exception: unexpected EOF while parsing (, line 0)
Please how do i solve this issue considering that i am new to python
This worked fine
def power(a,b):
if b == 0:
return 1
else:
return eval(((str(a)+"*")*b)[:-1])
Using eval is a terrible idea, but if you really wanted to then using join() would be a better way to create the string:
def power(a, b):
return eval('*'.join([str(a)]*b))
>>> power(2, 3)
8
If you add ['1'] to the front then the 0 exponent behaves properly:
def power(a, b):
return eval('*'.join(['1']+[str(a)]*b))
>>> power(2, 0)
1
However, this is simple to implement for integer exponents with a for loop:
def power(n, e):
t = 1
for _ in range(e):
t *= n
return t
>>> power(2, 3)
8
>>> power(2, 0)
1
You could also use functools.reduce() to do the same thing:
import functools as ft
import operator as op
def power(n, e):
return ft.reduce(op.mul, [n]*e, 1)
You can use a for loop
x=1
for i in range(b):
x=x*a
print(x)
def power(theNumber, thePower):
#basically, multiply the number for power times
try:
theNumber=int(theNumber)
thePower=int(thePower)
if theNumber == 0:
return 0
elif thePower == 0:
return 1
else:
return theNumber * power(theNumber,thePower-1)
except exception as err:
return 'Only digits are allowed as input'
You should avoid eval by all costs, especially when it's very simple to implement pure algorithmic efficient solution. Classic efficient algorithm is Exponentiation_by_squaring. Instead of computing and multiplying numbers n times, you can always divide it to squares to archive logarithmic* complexity.
For example, for calculating x^15:
x^15 = (x^7)*(x^7)*x
x^7 = (x^3)*(x^3)*x
x^3 = x*x*x
Thus taking 6 multiplications instead of 14.
def pow3(x, n):
r = 1
while n:
if n % 2 == 1:
r *= x
n -= 1
x *= x
n /= 2
return r
Source: https://helloacm.com/exponentiation-by-squaring/
Note: it was not mentioned in the question, but everything above considers N to be positive integer. If your question was also covering fractional or negative exponent, suggested approach will not work "as is".
* Of course depends on length of x and complexity of multiplying, see Wikipedia for detailed complexity analysis.
Also may be interesting to check out following questions: C solution or Python implementing pow() for exponentiation by squaring for very large integers
def power(a, b):
if b == 0:
return 1
else:
return a ** b
Related
I'm generating prime numbers from Fibonacci as follows (using Python, with mpmath and sympy for arbitrary precision):
from mpmath import *
def GCD(a,b):
while a:
a, b = fmod(b, a), a
return b
def generate(x):
mp.dps = round(x, int(log10(x))*-1)
if x == GCD(x, fibonacci(x-1)):
return True
if x == GCD(x, fibonacci(x+1)):
return True
return False
for x in range(1000, 2000)
if generate(x)
print(x)
It's a rather small algorithm but seemingly generates all primes (except for 5 somehow, but that's another question). I say seemingly because a very little percentage (0.5% under 1000 and 0.16% under 10K, getting less and less) isn't prime. For instance under 1000: 323, 377 and 442 are also generated. These numbers are not prime.
Is there something off in my script? I try to account for precision by relating the .dps setting to the number being calculated. Can it really be that Fibonacci and prime numbers are seemingly so related, but then when it's get detailed they aren't? :)
For this type of problem, you may want to look at the gmpy2 library. gmpy2 provides access to the GMP multiple-precision library which includes gcd() and fib() functions which calculate the greatest common divisor and the n-th fibonacci numbers quickly, and only using integer arithmetic.
Here is your program re-written to use gmpy2.
import gmpy2
def generate(x):
if x == gmpy2.gcd(x, gmpy2.fib(x-1)):
return True
if x == gmpy2.gcd(x, gmpy2.fib(x+1)):
return True
return False
for x in range(7, 2000):
if generate(x):
print(x)
You shouldn't be using any floating-point operations. You can calculate the GCD just using the builtin % (modulo) operator.
Update
As others have commented, you are checking for Fibonacci pseudoprimes. The actual test is slightly different than your code. Let's call the number being tested n. If n is divisible by 5, then the test passes if n evenly divides fib(n). If n divided by 5 leaves a remainder of either 1 or 4, then the test passes if n evenly divides fib(n-1). If n divided by 5 leaves a remainder of either 2 or 3, then the test passes if n evenly divides fib(n+1). Your code doesn't properly distinguish between the three cases.
If n evenly divides another number, say x, it leaves a remainder of 0. This is equivalent to x % n being 0. Calculating all the digits of the n-th Fibonacci number is not required. The test just cares about the remainder. Instead of calculating the Fibonacci number to full precision, you can calculate the remainder at each step. The following code calculates just the remainder of the Fibonacci numbers. It is based on the code given by #pts in Python mpmath not arbitrary precision?
def gcd(a,b):
while b:
a, b = b, a % b
return a
def fib_mod(n, m):
if n < 0:
raise ValueError
def fib_rec(n):
if n == 0:
return 0, 1
else:
a, b = fib_rec(n >> 1)
c = a * ((b << 1) - a)
d = b * b + a * a
if n & 1:
return d % m, (c + d) % m
else:
return c % m, d % m
return fib_rec(n)[0]
def is_fib_prp(n):
if n % 5 == 0:
return not fib_mod(n, n)
elif n % 5 == 1 or n % 5 == 4:
return not fib_mod(n-1, n)
else:
return not fib_mod(n+1, n)
It's written in pure Python and is very quick.
The sequence of numbers commonly known as the Fibonacci numbers is just a special case of a general Lucas sequence L(n) = p*L(n-1) - q*L(n-2). The usual Fibonacci numbers are generated by (p,q) = (1,-1). gmpy2.is_fibonacci_prp() accepts arbitrary values for p,q. gmpy2.is_fibonacci(1,-1,n) should match the results of the is_fib_pr(n) given above.
Disclaimer: I maintain gmpy2.
This isn't really a Python problem; it's a math/algorithm problem. You may want to ask it on the Math StackExchange instead.
Also, there is no need for any non-integer arithmetic whatsoever: you're computing floor(log10(x)) which can be done easily with purely integer math. Using arbitrary-precision math will greatly slow this algorithm down and may introduce some odd numerical errors too.
Here's a simple floor_log10(x) implementation:
from __future__ import division # if using Python 2.x
def floor_log10(x):
res = 0
if x < 1:
raise ValueError
while x >= 1:
x //= 10
res += 1
return res
This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 4 months ago.
Write a simple procedure, myLog(x, b), that computes the logarithm of a number x relative to a base b.n other words, myLog should return the largest power of b such that b to that power is still less than or equal to x.
x and b are both positive integers; b is an integer greater than or equal to 2. Your function should return an integer answer.
Do not use Python's log functions; instead, please use an iterative or recursive solution to this problem that uses simple arithmatic operators and conditional testing.
What is wrong in the below code? As they have not mentioned what to return when the condition fails, so had kept false
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
print str(count)
break
elif (ans > x):
print str(count-1)
break
count += 1
else:
return False
Since you haven't explained what problem you're trying to solve, all I can do is guess. But…
Your function never returns a number. If it succeeds, it prints out a number, then falls off the end of the function and returns None. If it fails, it returns False. And there's no other return anywhere in the code.
That's easy to fix: just return the value instead of print-ing it:
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
return count
elif (ans > x):
return count-1
count += 1
else:
return False
You can improve performance by doing ans *= b each time through the loop instead of ans = b ** count. If the numbers are huge, dividing x by b might be better—division is usually slower than multiplication, but getting out of the huge-number domain early might help more than avoiding division.
It's also got some style problems, like the unnecessary parentheses some (but not all) of your conditions.
And finally, you may want to consider writing a "test driver". For example:
repcount = 100
errcount = 0
for _ in range(repcount):
x = generate_nice_random_x()
b = generate_random_base()
log1, log2 = myLog(x, b), int(math.log(x, b))
if log1 != log2:
print('log({}, {}): {} != {}'.format(x, b, log1, log2))
errcount += 1
print('{}/{} errors'.format(errcount, repcount))
Start with a small repcount to make sure you don't spam the screen; when you're happier with it, use a much larger one. Meanwhile, I'll leave it to you to figure out a good domain to choose from for testing log functions.
This is a question on an exam, that is currently ongoing.MITx: 6.00.1x Introduction to Computer Science and Programming
I need to write a recursive function, dec2base(n, b), that returns a list of base b digits in the positive integer n. For example.
dec2base(120, 10) => [1,2,0] (1 * 10**2 + 2 * 10**1 + 0 * 10**0)
Currently I have.
def dec2base(n, b):
if n < 10:
return [n]
else:
return dec2base(n, b) + [n%b]
But when I run the program, it returns an infinite loop error. Any ideas?
You are not decrementing the value of n at any point in your method, so if you start with any value of n >=10, the loop never ends.
Another observation - the logic of "if n < 10 return [n]" seems not to make sense if b is not equal to 10. For instance, 9 < 10, but I'm assuming the value of dec2base(9,2) would not be [9]. It would be [1,0,0,1].
Okay, in any recursive function, there has to be some function that goes to zero in order to have something to stop. In this case, what you want is to really model the way you7 do it by hand:
divide by the radix (the base)
put the remainder in as a digite
recur using the same base, but the other part of the division. (The quotient.)
That is, if you are finding the hex value of 1000, you take
dec2base(1000,16):
if first parameter == 0, return, you're done
1000 mod 16 (=8) -> save the 8
dec2base(62, 16) -> recursion step
Now, obviously every time you make the recusion step, the first parameter is smaller, and if you think about it, that eventually must go to 0. So eventually it will terminate.
Here's a real simple version in Python:
result = ""
def dec2base(n,b):
global result
if n <= 0: return
result = str(n % b) + result # why am I prepending it?
dec2base( n // b, b)
if __name__ == '__main__':
dec2base(1000,8)
print result
Now, if the base is anything > 9 (say 16) you'll need to take care of translating values from 10 to 15 into alpha a-f, and this is purposefully not very elegant because I wanted it to lay out just like the example.
There's only a couple of tiny mistakes in your solution.
def dec2base(n, b):
if n < b: # so it will work for bases other than 10
return [n]
else:
return dec2base(n//b, b) + [n%b] # you're just missing "//b" here
You can simplify it slightly like this
def dec2base(n, b):
if not n:
return []
return dec2base(n//b, b) + [n%b]
Your calling dec2base(n, b) to infinity. If you call
dec2base(20, b)
Your function will continue to execute the 2nd branch of your if/else statement. You need to pass a reduced value to your recursive function call so that eventually, n < 10 will evaluate to True.
For an assignment we were asked to define a fibonacci function, which I accomplished with this:
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
However, I have seen recursive functions, such as the factorial function, defined in a one line return statement like so:
def factorial(n):
return n > 1 and n * factorial(n-1) or 1
So, I attempted to apply the same to my fibonacci function. After several attempts, I got it to work for all tested cases except when s = 0, in which case it returns False when it should return 0. Here is where I am:
def fibonacci(n):
return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
I understand that python evaluates 0 to False, so how would I have python return zero instead of False when n is 0 while maintaining the current length/structure of the code? Is that even possible?
Also, is this style of creating a function (recursive or otherwise) more or less desirable/pythonic than the textbook version? (I would imagine not just because of readability)
To be clear, I have satisfied the requirements for the assignment, and for personal knowledge only, I would like a clearer understanding of what is happening in the return statement.
The x and y or z idiom doesn't work if y is falsy. You can swap the condition to make it work nonetheless:
def fibonacci(n):
return n >= 2 and fibonacci(n-1) + fibonacci(n-2) or n
However, as of Python 2.5 (released 6 years ago), we have proper conditional expressions and don't need the and/or hack any longer:
def fibonacci(n):
return n if n < 2 else fibonacci(n-1) + fibonacci(n-2)
Now this has an exponential runtime complexity. If you want to be efficient, use the O(n) algorithm:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
Or even write a generator to yield all the numbers and only take as much as you need.
Perhaps this makes it clearer:
def fibonacci(n):
print ((n == 0 or n == 1) and n)
print (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
print 0 or False
print False or 0
How do I go about computing a factorial of an integer in Python?
The easiest way is to use math.factorial (available in Python 2.6 and above):
import math
math.factorial(1000)
If you want/have to write it yourself, you can use an iterative approach:
def factorial(n):
fact = 1
for num in range(2, n + 1):
fact *= num
return fact
or a recursive approach:
def factorial(n):
if n < 2:
return 1
else:
return n * factorial(n-1)
Note that the factorial function is only defined for positive integers, so you should also check that n >= 0 and that isinstance(n, int). If it's not, raise a ValueError or a TypeError respectively. math.factorial will take care of this for you.
On Python 2.6 and up, try:
import math
math.factorial(n)
Existing solution
The shortest and probably the fastest solution is:
from math import factorial
print factorial(1000)
Building your own
You can also build your own solution. Generally you have two approaches. The one that suits me best is:
from itertools import imap
def factorial(x):
return reduce(long.__mul__, imap(long, xrange(1, x + 1)))
print factorial(1000)
(it works also for bigger numbers, when the result becomes long)
The second way of achieving the same is:
def factorial(x):
result = 1
for i in xrange(2, x + 1):
result *= i
return result
print factorial(1000)
def factorial(n):
if n < 2:
return 1
return n * factorial(n - 1)
For performance reasons, please do not use recursion. It would be disastrous.
def fact(n, total=1):
while True:
if n == 1:
return total
n, total = n - 1, total * n
Check running results
cProfile.run('fact(126000)')
4 function calls in 5.164 seconds
Using the stack is convenient (like recursive call), but it comes at a cost: storing detailed information can take up a lot of memory.
If the stack is high, it means that the computer stores a lot of information about function calls.
The method only takes up constant memory (like iteration).
Or using a 'for' loop
def fact(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
Check running results
cProfile.run('fact(126000)')
4 function calls in 4.708 seconds
Or using the built-in function math
def fact(n):
return math.factorial(n)
Check running results
cProfile.run('fact(126000)')
5 function calls in 0.272 seconds
If you are using Python 2.5 or older, try
from operator import mul
def factorial(n):
return reduce(mul, range(1, n+1))
For newer versions of Python, there is factorial in the math module as given in other answers here.
def fact(n):
f = 1
for i in range(1, n + 1):
f *= i
return f
Another way to do it is to use np.prod shown below:
def factorial(n):
if n == 0:
return 1
else:
return np.prod(np.arange(1,n+1))
Non-recursive solution, no imports:
def factorial(x):
return eval(' * '.join(map(str, range(1, x + 1))))
You can also make it in one line recursively if you like it. It is just a matter of personal choice. Here we are using inline if else in Python, which is similar to the ternary operator in Java:
Expression1 ? Expression2 : Expression3
One line function call approach:
def factorial(n): return 1 if n == 0 else n * factorial(n-1)
One line lambda function approach:
(although it is not recommended to assign lambda functions directly to a name, as it is considered a bad practice and may bring inconsistency to your code. It's always good to know. See PEP8.)
factorial = lambda n: 1 if n == 0 else n * factorial(n-1)